| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $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 */