| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $Id: rc2.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 program encrypts & decrypts using RC2 in CBC mode. */ #include "bsafe.h" #include "demoutil.h" /* in samples/common/include */ #include "bsfutil.h" /* in samples/common/include */ #define BLOCK_SIZE 8 #define KEY_SIZE 24 B_ALGORITHM_METHOD *RC2_CHOOSER[] = { &AM_CBC_ENCRYPT, &AM_CBC_DECRYPT, &AM_RC2_ENCRYPT, &AM_RC2_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 rc2Main #else #define MAIN main #endif int MAIN(int argc, char *argv[]) { B_KEY_OBJ rc2Key = (B_KEY_OBJ)NULL_PTR; B_ALGORITHM_OBJ rc2Encrypter = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ rc2Decrypter = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR; unsigned char initVector[BLOCK_SIZE]; ITEM ivItem = {NULL, 0}, rc2KeyItem = {NULL, 0}; A_RC2_PARAMS rc2Params; B_BLK_CIPHER_W_FEEDBACK_PARAMS fbParams; unsigned char *dataToEncrypt = (unsigned char *)"Encrypt this sentence."; unsigned int dataToEncryptLen; unsigned char *encryptedData = NULL_PTR; unsigned int outputLenUpdate, outputLenFinal; unsigned int encryptedDataLen; unsigned char *decryptedData = NULL_PTR; unsigned int decryptedLenUpdate, decryptedLenFinal; unsigned int decryptedDataLen; 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; RSA_PrintMessage ("RC2 w/CBC Pad algorithm: Encryption phase\n"); RSA_PrintMessage ("==========================================\n"); dataToEncryptLen = T_strlen ((char *)dataToEncrypt) + 1; RSA_PrintBuf ("Data To Encrypt", dataToEncrypt, dataToEncryptLen); /* Initialize a random algorithm object using a procedure described in samples/common/include/bsfutil.h */ if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0) break; /* B_GenerateRandomBytes is called for 8 bytes, which is the block size. */ if ((status = B_GenerateRandomBytes (randomAlgorithm, initVector, sizeof (initVector), NULL)) != 0) break; RSA_PrintBuf ("Initialization Vector", initVector, sizeof (initVector)); /* Create an algorithm object. */ if ((status = B_CreateAlgorithmObject (&rc2Encrypter)) != 0) break; /* Set the algorithm to a type that does RC2 encryption. In this case AI_RC2_CBCPad. This algorithm type needs an 8-byte initialization vector (IV), and an effective key size in bits. Both are set by declaring a struct of type, A_RC2_CBC_PARAMS. The IV will be set with 8 random bytes, and the effective key bits will be set to 80. */ rc2Params.effectiveKeyBits = 80; ivItem.data = initVector; ivItem.len = sizeof (initVector); fbParams.encryptionMethodName = (unsigned char *)"rc2"; fbParams.encryptionParams = (POINTER)&rc2Params; fbParams.feedbackMethodName = (unsigned char *)"cbc"; fbParams.feedbackParams = (POINTER)&ivItem; fbParams.paddingMethodName = (unsigned char *)"pad"; fbParams.paddingParams = NULL_PTR; if ((status = B_SetAlgorithmInfo (rc2Encrypter, AI_FeedbackCipher, (POINTER)&fbParams)) != 0) break; /* Create a key object. */ if ((status = B_CreateKeyObject (&rc2Key)) != 0) break; /* Set the key object with a random 24-byte key */ rc2KeyItem.len = KEY_SIZE; rc2KeyItem.data = T_malloc (rc2KeyItem.len); if (rc2KeyItem.data == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } if ((status = B_GenerateRandomBytes (randomAlgorithm, rc2KeyItem.data, rc2KeyItem.len, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; RSA_PrintBuf ("RC2 Key Bytes", rc2KeyItem.data, rc2KeyItem.len); if ((status = B_SetKeyInfo (rc2Key, KI_Item, (POINTER)&rc2KeyItem)) != 0) break; /* Zeroize the memory and free it up immediately after setting the key for security reasons. */ if (rc2KeyItem.data != NULL_PTR) { T_memset (rc2KeyItem.data, 0, rc2KeyItem.len); T_free (rc2KeyItem.data); rc2KeyItem.data = NULL_PTR; rc2KeyItem.len = 0; } /* Init */ if ((status = B_EncryptInit (rc2Encrypter, rc2Key, RC2_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Update */ encryptedDataLen = dataToEncryptLen + BLOCK_SIZE; encryptedData = T_malloc (encryptedDataLen); if (encryptedData == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } if ((status = B_EncryptUpdate (rc2Encrypter, encryptedData, &outputLenUpdate, encryptedDataLen, dataToEncrypt, dataToEncryptLen, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Final */ if ((status = B_EncryptFinal (rc2Encrypter, encryptedData + outputLenUpdate, &outputLenFinal, encryptedDataLen - outputLenUpdate, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; encryptedDataLen = outputLenUpdate + outputLenFinal; RSA_PrintBuf ("EncryptedData", encryptedData, encryptedDataLen); RSA_PrintMessage ("\nRC2 w/CBC Pad algorithm: Decryption phase\n"); RSA_PrintMessage ("==========================================\n"); if ((status = B_CreateAlgorithmObject (&rc2Decrypter)) != 0) break; /* Use the same AI and initialization vector as for encryption */ if ((status = B_SetAlgorithmInfo (rc2Decrypter, AI_FeedbackCipher, (POINTER)&fbParams)) != 0) break; /* Use the same key as for encryption */ if ((status = B_DecryptInit (rc2Decrypter, rc2Key, RC2_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Set the buffer that will take the decrypted data to be the same size * as the encrypted data's buffer. With AI_RC2_CBCPad, there will be * fewer bytes in the decrypted data than in the encrypted data, since * Crypto-C will strip the padding. But we do not know how many, so for * simplicity, make the buffer the same size. */ decryptedDataLen = encryptedDataLen; decryptedData = T_malloc (decryptedDataLen); if ((status = (decryptedData == NULL_PTR)) != 0) break; if ((status = B_DecryptUpdate (rc2Decrypter, decryptedData, &decryptedLenUpdate, decryptedDataLen, encryptedData, encryptedDataLen, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; if ((status = B_DecryptFinal (rc2Decrypter, decryptedData + decryptedLenUpdate, &decryptedLenFinal, decryptedDataLen - decryptedLenUpdate, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; decryptedDataLen = decryptedLenUpdate + decryptedLenFinal; RSA_PrintBuf ("Decrypted Data", decryptedData, decryptedDataLen); if ((decryptedDataLen == dataToEncryptLen) && (T_memcmp (dataToEncrypt, decryptedData, decryptedDataLen)) == 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 ("rc2", status); /* Destroy the key and algorithm objects. */ B_DestroyKeyObject (&rc2Key); B_DestroyAlgorithmObject (&rc2Encrypter); B_DestroyAlgorithmObject (&randomAlgorithm); B_DestroyAlgorithmObject (&rc2Decrypter); /* Free up any memory allocated, 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_free (decryptedData); decryptedData = NULL_PTR; } if (rc2KeyItem.data != NULL_PTR) { T_free (rc2KeyItem.data); rc2KeyItem.data = NULL_PTR; rc2KeyItem.len = 0; } return (status); } /* end main */