| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $Id: multencr.c,v 1.5 2004/12/03 02:08:42 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 illustrates the process of calling B_EncryptUpdate multiple * times. The user is prompted for a file containing data to encrypt, * with the default being "infile.dat". It will read a specified number of * bytes from the file, encrypt it, then write the encrypted bytes out to an * output file, "encrfile.dat" by default, until the end of file is reached. * To get back the original data or plaintext, compile "multdecr.c" and * run. */ #include <stdio.h> #include "bsafe.h" #include "demoutil.h" /* in samples/common/include */ #define BLOCK_SIZE 0 /* RC4 is a stream cipher */ #define DEMO_UPDATE_SIZE 64 #define DEMO_UPDATE_OUTPUT_SIZE (DEMO_UPDATE_SIZE + BLOCK_SIZE) int GetDataFromFile PROTO_LIST ((FILE *, unsigned int, unsigned char *, unsigned int *, int *)); int AppendDataToFile PROTO_LIST ((FILE *, unsigned char *, unsigned int)); B_ALGORITHM_METHOD *DEMO_ALGORITHM_CHOOSER[] = { &AM_RC4_ENCRYPT, (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 multencrMain #else #define MAIN main #endif int MAIN(int argc, char *argv[]) { B_KEY_OBJ rc4Key = (B_KEY_OBJ)NULL_PTR; B_ALGORITHM_OBJ encryptionObject = (B_ALGORITHM_OBJ)NULL_PTR; static unsigned char rc4KeyData[10] = { 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 }; unsigned int rc4KeyDataLen = 10; ITEM rc4KeyItem = {NULL, 0}; FILE *inputFile = (FILE *)NULL_PTR; FILE *outputFile = (FILE *)NULL_PTR; unsigned char dataToEncrypt[DEMO_UPDATE_SIZE]; unsigned char blockOfEncryptedData[DEMO_UPDATE_OUTPUT_SIZE]; unsigned int dataToEncryptLen, totalBytesSoFar; unsigned int outputLenUpdate, outputLenFinal; unsigned int sizeToUpdate = DEMO_UPDATE_SIZE; int endFlag, status; char userInput[RSA_DEMO_MAX_LINE_LEN]; 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 ("RC4 algorithm - Multiple Updates\n"); RSA_PrintMessage ("================================\n"); RSA_PrintMessage ("Enter name of file containing data to encrypt\n"); if ((status = RSA_GetCommand (userInput, sizeof (userInput), "(default infile.dat)")) != 0) break; if (userInput[0] == '\0') T_strcpy (userInput, "infile.dat"); inputFile = fopen (userInput, "rb"); if (inputFile == (FILE *)NULL_PTR) { status = RSA_DEMO_E_FILE_IO; break; }; RSA_PrintMessage ("Enter name of file for storing encrypted data\n"); if ((status = RSA_GetCommand (userInput, sizeof (userInput), "(default encrfile.dat)")) != 0) break; if (userInput[0] == '\0') T_strcpy (userInput, "encrfile.dat"); outputFile = fopen (userInput, "wb"); if (outputFile == (FILE *)NULL_PTR) { status = RSA_DEMO_E_FILE_IO; break; } RSA_PrintMessage ("Encryption phase (calling Update multiple times)\n"); RSA_PrintMessage ("================================================\n"); totalBytesSoFar = 0; /* Create a key object. */ if ((status = B_CreateKeyObject (&rc4Key)) != 0) break; /* Set the key to be a RC4 key and set it to the rc4KeyData declared above. */ rc4KeyItem.data = rc4KeyData; rc4KeyItem.len = rc4KeyDataLen; if ((status = B_SetKeyInfo (rc4Key, KI_Item, (POINTER)&rc4KeyItem)) != 0) break; /* Create an algorithm object. */ if ((status = B_CreateAlgorithmObject (&encryptionObject)) != 0) break; /* Set the algorithm object for the RC4 operation */ if ((status = B_SetAlgorithmInfo (encryptionObject, AI_RC4, NULL)) != 0) break; /* Ready to encrypt. Use B_EncryptInit, B_EncryptUpdate and B_EncryptFinal */ if ((status = B_EncryptInit (encryptionObject, rc4Key, DEMO_ALGORITHM_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; while ((status = GetDataFromFile (inputFile, sizeToUpdate, dataToEncrypt, &dataToEncryptLen, &endFlag)) == 0) { RSA_PrintBuf ("Data To Encrypt", dataToEncrypt, dataToEncryptLen); if ((status = B_EncryptUpdate (encryptionObject, blockOfEncryptedData, &outputLenUpdate, DEMO_UPDATE_OUTPUT_SIZE, dataToEncrypt, dataToEncryptLen, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Save the encrypted data */ if ((status = AppendDataToFile (outputFile, blockOfEncryptedData, outputLenUpdate)) != 0) break; totalBytesSoFar += outputLenUpdate; if (endFlag == 1) break; } /* end while */ /* If there was an error in the above while loop, break out of the do-while construct. */ if (status != 0) break; /* Call B_EncryptFinal once after all Updates. */ if ((status = B_EncryptFinal (encryptionObject, blockOfEncryptedData, &outputLenFinal, DEMO_UPDATE_OUTPUT_SIZE, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Save the encrypted data */ if ((status = AppendDataToFile (outputFile, blockOfEncryptedData, outputLenFinal)) != 0) break; totalBytesSoFar += outputLenFinal; RSA_PrintMessage ("Total ciphertext length = %i\n", totalBytesSoFar); } while (0); if (status != 0) RSA_PrintError ("RC4 Encryption with multiple updates", status); /* Done with the key and algorithm objects, so destroy them. */ B_DestroyKeyObject (&rc4Key); B_DestroyAlgorithmObject (&encryptionObject); /* Free up any memory allocated, save it to a file or print it out first if you need to save it. */ T_memset (dataToEncrypt, 0, sizeof (dataToEncrypt)); if (inputFile != (FILE *)NULL_PTR) fclose (inputFile); if (outputFile != (FILE *)NULL_PTR) fclose (outputFile); return (status); } /* end main */ int GetDataFromFile(FILE *inputFile, unsigned int sizeToUpdate, unsigned char *dataToEncrypt, unsigned int *dataToEncryptLen, int *endFlag) { unsigned char dummy; do { *dataToEncryptLen = fread (dataToEncrypt, 1, sizeToUpdate, inputFile); if (*dataToEncryptLen == sizeToUpdate) /* Read exactly sizeToUpdate bytes, so reading one more will set end of file if there were exactly sizeToUpdate bytes in the file. */ fread (&dummy, 1, 1, inputFile); if (feof (inputFile)) { *endFlag = 1; fclose (inputFile); } else { *endFlag = 0; fseek (inputFile, -1, SEEK_CUR); } } while (0); return (0); } /* end GetDataFromFile */ int AppendDataToFile(FILE *outputFile, unsigned char *blockOfEncryptedData, unsigned int outputLenUpdate) { do { if (fwrite (blockOfEncryptedData, 1, outputLenUpdate, outputFile) < outputLenUpdate) { fclose (outputFile); } } while (0); return (0); } /* end AppendDataToFile */