RSA BSAFE Crypto-C

Cryptographic Components for C

Search

feedback.c

/* $Id: feedback.c,v 1.6 2004/12/03 02:08:41 sparki Exp $ */
/*
 * Copyright (C) 1998-2004 RSA Security Inc.
 *
 * This file shall only be used to demonstrate how to interface to an
 * RSA Security Inc. licensed development product.
 *
 * You have a royalty-free right to use, reproduce and distribute this
 * demonstration file, provided that you agree that RSA Security Inc.
 * has no warranty, implied or otherwise, or liability for this
 * demonstration file (including any modified version).  This software
 * is provided "as is" without warranties or representations of any
 * kind. RSA Security disclaims all conditions and warranties, statutory
 * and otherwise, both express and implied, with respect to the software,
 * its quality and performance, including but not limited to, all
 * implied warranties of merchantability, fitness for a particular
 * purpose, title and noninfringement of third party rights. Without
 * limiting the foregoing, RSA Security does not warrant that the
 * software is error-free or that errors in the product will be
 * corrected. You agree that RSA Security shall not be liable for any
 * direct, indirect, incidental, special, consequential, punitive or
 * other damages whatsoever resulting from your use of this software
 * or any modified version.
 *
 *
 */

/*  This sample demonstrates how to encrypt and decrypt data using 
    the Data Encryption Standard (DES) algorithm in Cipher Block Chaining (CBC) mode */

#include "bsafe.h"
#include "demoutil.h"  /* in samples/common/include */

B_ALGORITHM_METHOD *FEEDBACK_CHOOSER[] = {
  &AM_CBC_ENCRYPT,
  &AM_CBC_DECRYPT,
  &AM_DES_ENCRYPT,
  &AM_DES_DECRYPT,
  (B_ALGORITHM_METHOD *)NULL_PTR
/* This will fix a problem that the IA64 compiler finds when *
 * seeing a short chooser list */
#ifdef IA64_FORCE_LARGE
                IA64_FORCE_LARGE
#endif
};



#ifdef CRYPTOC_APP
#define MAIN feedbackMain
#else
#define MAIN main
#endif

int MAIN(int argc, char *argv[])
{
  B_KEY_OBJ desKey = (B_KEY_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ encryptionObject = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ decryptionObject = (B_ALGORITHM_OBJ)NULL_PTR;

  unsigned char initVector[] = {
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
  };
  unsigned char desKeyData[] = {
    0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88
  };

  ITEM ivItem = {NULL, 0};

  B_BLK_CIPHER_W_FEEDBACK_PARAMS fbParams;

  unsigned char *dataToEncrypt = (unsigned char *)"Encrypt this sentence.";
  unsigned int dataToEncryptLen, encryptedDataLen, decryptedDataLen = 0;
  unsigned int outputLenUpdate, outputLenFinal;

  unsigned char *encryptedData = NULL_PTR;
  unsigned char *decryptedData = NULL_PTR;
  /* outputLenTotal is the sum of the encryptions outputLenUpdate
     and outputLenFinal.  The encrypter should send this information
     along with the encrypted data. */
  unsigned int outputLenTotal;
  int status;

  do {
    /* The RSA_* demo code utilities are described in
       common/include/demoutil.h.  This procedure simply checks the
       command-line arguments for input or output options. */
    if ((status = RSA_SetOptions (argc, argv)) != 0)
      break;

    /*  Find out how many bytes to encrypt. */
    dataToEncryptLen = T_strlen ((char *)dataToEncrypt);

    RSA_PrintMessage ("Feedback Cipher:  DES Encryption/Decryption\n");
    RSA_PrintMessage ("===========================================\n\n");

    RSA_PrintMessage ("Encryption phase:\n");
    RSA_PrintMessage ("=================\n");
    RSA_PrintBuf ("Data To Encrypt", dataToEncrypt, dataToEncryptLen);

    /*  Allocate a buffer that is at least 8 bytes longer than the
        length of the input buffer to hold padding.  */
    encryptedDataLen = dataToEncryptLen + 8;
    encryptedData = T_malloc (encryptedDataLen);
    if (encryptedData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    /*  Create a key object. */
    if ((status = B_CreateKeyObject (&desKey)) != 0)
      break;

    /*  Set the key to be a DES key and set it to the desKeyData declared
        above. */
    if ((status = B_SetKeyInfo (desKey, KI_DES8Strong,
                                (unsigned char *)desKeyData)) != 0)
      break;

    /*  Create an algorithm object. */
    if ((status = B_CreateAlgorithmObject (&encryptionObject)) != 0)
      break;

    /*  Set the algorithm to a type that does DES encryption in CBC mode.
     */
    ivItem.data = initVector;
    ivItem.len = 8;

    fbParams.encryptionMethodName = (unsigned char *)"des";
    fbParams.encryptionParams = NULL_PTR;
    fbParams.feedbackMethodName = (unsigned char *)"cbc";
    fbParams.feedbackParams = (POINTER)&ivItem;
    fbParams.paddingMethodName = (unsigned char *)"pad";
    fbParams.paddingParams = NULL_PTR;

    if ((status = B_SetAlgorithmInfo (encryptionObject, AI_FeedbackCipher,
                                      (POINTER)&fbParams)) != 0)
      break;

    /*  Ready to encrypt. Use B_EncryptInit, B_EncryptUpdate
        and B_EncryptFinal.  */
    if ((status = B_EncryptInit (encryptionObject, desKey, FEEDBACK_CHOOSER,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    if ((status = B_EncryptUpdate (encryptionObject, encryptedData,
                                   &outputLenUpdate, encryptedDataLen,
                                   dataToEncrypt, dataToEncryptLen,
                                   (B_ALGORITHM_OBJ)NULL_PTR,
                                   (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    RSA_PrintMessage ("outputLenUpdate = %i\n", outputLenUpdate);

    if ((status = B_EncryptFinal (encryptionObject,
                                  encryptedData + outputLenUpdate,
                                  &outputLenFinal,
                                  encryptedDataLen - outputLenUpdate,
                                  (B_ALGORITHM_OBJ)NULL_PTR,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    RSA_PrintMessage ("outputLenFinal = %i\n", outputLenFinal);

    outputLenTotal = outputLenUpdate + outputLenFinal;
    RSA_PrintMessage ("Total length of encrypted data = %i\n", outputLenTotal);

    RSA_PrintBuf ("Encrypted Data", encryptedData, outputLenTotal);

    /* Decrypt the data */
        RSA_PrintMessage ("\nDecryption phase\n");
    RSA_PrintMessage ("================\n");

    if ((status = B_CreateAlgorithmObject (&decryptionObject)) != 0)
      break;

    if ((status = B_SetAlgorithmInfo (decryptionObject, AI_FeedbackCipher,
                                      (POINTER)&fbParams)) != 0)
      break;

    if ((status = B_DecryptInit (decryptionObject, desKey, FEEDBACK_CHOOSER,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    decryptedDataLen = encryptedDataLen;
    decryptedData = T_malloc (decryptedDataLen);
    if (decryptedData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    if ((status = B_DecryptUpdate (decryptionObject, decryptedData,
                                   &outputLenUpdate, decryptedDataLen,
                                   encryptedData, outputLenTotal,
                                   (B_ALGORITHM_OBJ)NULL_PTR,
                                   (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    RSA_PrintMessage ("outputLenUpdate = %i\n", outputLenUpdate);

    if ((status = B_DecryptFinal (decryptionObject,
                                  decryptedData + outputLenUpdate,
                                  &outputLenFinal,
                                  decryptedDataLen - outputLenUpdate,
                                  (B_ALGORITHM_OBJ)NULL_PTR,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    RSA_PrintMessage ("outputLenFinal = %i\n", outputLenFinal);

    outputLenTotal = outputLenUpdate + outputLenFinal;
    RSA_PrintMessage ("Total length of decrypted data = %i\n", outputLenTotal);

    RSA_PrintBuf ("Decrypted Data", decryptedData, outputLenTotal);

    if ((outputLenTotal == dataToEncryptLen) &&
        (T_memcmp (dataToEncrypt, decryptedData, outputLenTotal)) == 0) {
      RSA_PrintMessage ("Success!  ");
      RSA_PrintMessage ("The decrypted data matches the original data.\n");
    } else {
      RSA_PrintMessage ("The decrypted data does not match the original data.");
      status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY;
    }
  } while (0);

  if (status != 0)
    RSA_PrintError ("feedback", status);

  /*  Destroy the key and algorithm objects.  */
  B_DestroyKeyObject (&desKey);
  B_DestroyAlgorithmObject (&encryptionObject);
  B_DestroyAlgorithmObject (&decryptionObject);

  /*  Free up any memory allocated and zeroize any sensitive memory.
      Save it to a file or print it out first if you need to save it.  */
  if (encryptedData != NULL_PTR) {
    T_free (encryptedData);
    encryptedData = NULL_PTR;
  }

  if (decryptedData != NULL_PTR) {
    T_memset (decryptedData, 0, decryptedDataLen);
    T_free (decryptedData);
    decryptedData = NULL_PTR;
  }

  return (status);
} /*  end main  */

Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 068-001001-6210-001-000 - 6.2.1