| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $Id: rsaoaep.c,v 1.7 2004/12/03 02:08:38 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 will generate a RSA keypair, encrypt with the public key, * then decrypt with the private key -- i.e. digital envelope using * AI_PKCS_OAEP_RSAPublic and AI_PKCS_OAEP_RSAPrivate to encrypt and * decrypt randomly generated data using OAEP as defined in PKCS #1 v2. * * The Optimal Asymmetric Encryption Padding (OAEP) scheme is used as a * superior padding scheme to thrwart certain attacks against the protocols * using digital envelopes. * * 19NOV98 JAG v4.1.1 */ #include "bsafe.h" #include "demoutil.h" /* in samples/common/include */ #include "bsfutil.h" /* in samples/common/include */ #include "rsautil.h" /* in samples/pkalg/rsa */ #define RSA_MODULUS_BITS 1024 /* PKCS #1 OAEP has 42 bytes of padding */ #define BLOCK_OVERHEAD 42 B_ALGORITHM_METHOD *DEMO_ALGORITHM_CHOOSER[] = { &AM_RSA_ENCRYPT, &AM_RSA_DECRYPT, &AM_RSA_CRT_ENCRYPT, &AM_RSA_CRT_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 rsaoaepMain #else #define MAIN main #endif int MAIN(int argc, char *argv[]) { /* Random algorithm objects. */ B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR; /* Public and private key objects. */ B_KEY_OBJ publicKey = (B_KEY_OBJ)NULL_PTR; B_KEY_OBJ privateKey = (B_KEY_OBJ)NULL_PTR; /* Encryption and decryption objects. */ B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ rsaDecryptor = (B_ALGORITHM_OBJ)NULL_PTR; unsigned char *dataToEncrypt = NULL_PTR; unsigned int dataToEncryptLen = 0; unsigned char *encryptedData = NULL_PTR, *decryptedData = NULL_PTR; unsigned char *updateBuffer = NULL_PTR; unsigned int encryptedDataLen = 0, decryptedDataLen = 0; unsigned int updateBufferLen = 0; unsigned int blockSize = 0, blockPayload = 0; 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 ("RSA PKCS #1 V2 Encryption With OAEP Example\n"); RSA_PrintMessage ("===========================================\n"); /* Determine the encryption block size, and the payload (data) that we * can encrypt in each block. */ blockSize = (RSA_MODULUS_BITS + 7) / 8; blockPayload = blockSize - BLOCK_OVERHEAD; /* Encrypted data is allocated to the max message size. */ dataToEncrypt = T_malloc (blockPayload); dataToEncryptLen = blockPayload; encryptedData = T_malloc (blockSize); updateBuffer = T_malloc (blockSize); /* Decrypted data is allocated to the padded max message size. */ decryptedData = T_malloc (blockPayload); if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0) break; /* For more information on generating RSA keypairs, see the following * function in samples/pkalg/rsa/rsautil.c */ if ((status = RSA_CreateRSAKeypair (&publicKey, &privateKey, RSA_MODULUS_BITS, randomAlgorithm)) != 0) break; /* For this example, we'll envelope some randomly generated bytes. */ if ((status = B_GenerateRandomBytes (randomAlgorithm, dataToEncrypt, dataToEncryptLen, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; RSA_PrintBuf ("Data to Encrypt and Pad", dataToEncrypt, dataToEncryptLen); RSA_PrintMessage ("\nPerforming PKCS V2 Encryption\n"); RSA_PrintMessage ("=============================\n"); /* Create an Algorithm Object */ if ((status = B_CreateAlgorithmObject (&rsaEncryptor)) != 0) break; /* Set the algorithm object to AI_PKCS_OAEP_RSAPublic */ if ((status = B_SetAlgorithmInfo (rsaEncryptor, AI_PKCS_OAEP_RSAPublic, NULL_PTR)) != 0) break; /* Init -- encrypt with the recipient's public key */ if ((status = B_EncryptInit (rsaEncryptor, publicKey, DEMO_ALGORITHM_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Update */ if ((status = B_EncryptUpdate (rsaEncryptor, encryptedData, &updateBufferLen, blockSize, dataToEncrypt, dataToEncryptLen, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Final */ if ((status = B_EncryptFinal (rsaEncryptor, encryptedData, &encryptedDataLen, blockSize, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; encryptedDataLen += updateBufferLen; RSA_PrintBuf ("Encrypted Data with Padding", encryptedData, encryptedDataLen); RSA_PrintMessage ("\nPerforming PKCS V2 Decryption\n"); RSA_PrintMessage ("=============================\n"); /* Create an Algorithm Object */ if ((status = B_CreateAlgorithmObject (&rsaDecryptor)) != 0) break; /* Set the algorithm object to AI_PKCS_OAEP_RSAPublic */ if ((status = B_SetAlgorithmInfo (rsaDecryptor, AI_PKCS_OAEP_RSAPrivate, NULL_PTR)) != 0) break; /* Init */ if ((status = B_DecryptInit (rsaDecryptor, privateKey, DEMO_ALGORITHM_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Update */ updateBufferLen = 0; if ((status = B_DecryptUpdate (rsaDecryptor, updateBuffer, &updateBufferLen, blockPayload, encryptedData, encryptedDataLen, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Final */ if ((status = B_DecryptFinal (rsaDecryptor, decryptedData, &decryptedDataLen, blockPayload, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; decryptedDataLen += updateBufferLen; RSA_PrintBuf ("Decrypted Data", decryptedData, decryptedDataLen); /* The decrypted data should match the plaintext data that was * originally generated. If they match, the envelope verified * correctly. */ 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 ("rsaoaep", status); /* Destroy */ B_DestroyAlgorithmObject (&randomAlgorithm); B_DestroyKeyObject (&privateKey); B_DestroyKeyObject (&publicKey); B_DestroyAlgorithmObject (&rsaDecryptor); B_DestroyAlgorithmObject (&rsaEncryptor); /* Free the memory used by these objects. The T_ functions are * defined in tstdlib.c included in the samples/common/source * directory with Crypto-C. Also zero out the sensitive data for * security precautions. */ if (dataToEncrypt != NULL_PTR) { T_memset(dataToEncrypt, 0, dataToEncryptLen); T_free(dataToEncrypt); } if (encryptedData != NULL_PTR) T_free(encryptedData); if (updateBuffer != NULL_PTR) T_free(updateBuffer); if (decryptedData != NULL_PTR) { T_memset(decryptedData, 0, decryptedDataLen); T_free(decryptedData); } return (status); } /* end main */