| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $Id: ecspecial.c,v 1.7 2004/12/03 02:08:37 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 create an EC keypair from a given curve, encrypt a * block of data with the public key and decrypt with the private key, * using the Elliptic Curve Encryption Scheme. */ #include "bsafe.h" #include "demoutil.h" /* in samples/common/include */ #include "bsfutil.h" /* in samples/common/include */ #include "ecutil.h" /* in samples/pkalg/ecc */ B_ALGORITHM_METHOD *EC_CHOOSER[] = { &AM_ECFP_KEY_GEN, &AM_ECF2POLY_KEY_GEN, &AM_ECFP_ENCRYPT, &AM_ECFP_DECRYPT, &AM_ECF2POLY_ENCRYPT, &AM_ECF2POLY_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 ecesMain #else #define MAIN main #endif int MAIN(int argc, char *argv[]) { int status; B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ ecKeyGen = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ ecesEncrypt = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ ecesDecrypt = (B_ALGORITHM_OBJ)NULL_PTR; B_KEY_OBJ publicKey = (B_KEY_OBJ)NULL_PTR; B_KEY_OBJ privateKey = (B_KEY_OBJ)NULL_PTR; /* We don't need a B_ALGORITHM_OBJ for the parameters since we * are using pre-defined curves. However, we still need the * information for these curves */ B_EC_PARAMS paramInfo; B_EC_SPECIAL_CURVE specialCurve; int fieldElementLen; unsigned char dataToEncrypt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; unsigned int dataToEncryptLen = sizeof(dataToEncrypt); unsigned char *encryptedData = NULL_PTR; unsigned char *decryptedData = NULL_PTR; unsigned int maxEncryptedDataLen, maxDecryptedDataLen; unsigned int outputLenUpdate, outputLenFinal, outputLenTotal; 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 ("EC Special Curve encryption and decryption example\n"); RSA_PrintMessage ("==================================================\n"); if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0) break; RSA_PrintMessage("\nGenerating an EC Key Pair using a Special Curve\n"); /* Create. */ if ((status = B_CreateAlgorithmObject (&ecKeyGen)) != 0) break; if ((status = B_CreateKeyObject (&publicKey)) != 0) break; if ((status = B_CreateKeyObject (&privateKey)) != 0) break; /* Set. */ /* Here is where you will define what curve you want to use. */ specialCurve.definedCurve = NIST_P192; fieldElementLen = 192; paramInfo.parameterInfoType = AI_ECSpecialCurve; paramInfo.parameterInfoValue = (POINTER)&specialCurve; if ((status = B_SetAlgorithmInfo (ecKeyGen, AI_ECKeyGen, (POINTER)¶mInfo)) != 0) break; /* Init. */ if ((status = B_GenerateInit (ecKeyGen, EC_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Generate. */ if ((status = B_GenerateKeypair (ecKeyGen, publicKey, privateKey, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Print out key information */ if ((status = RSA_PrintECKeyInfo ("Public Key", KI_ECPublicComponent, publicKey, 0)) != 0) break; if ((status = RSA_PrintECKeyInfo ("Private Key", KI_ECPrivateComponent, privateKey, 0)) != 0) break; /* EC encryption */ RSA_PrintMessage ("\nEncrypting Data...\n"); RSA_PrintBuf ("Data to Encrypt", dataToEncrypt, dataToEncryptLen); /* Create. */ if ((status = B_CreateAlgorithmObject (&ecesEncrypt)) != 0) break; /* Set. */ if ((status = B_SetAlgorithmInfo (ecesEncrypt, AI_EC_ES, NULL_PTR)) != 0) break; /* Init. */ if ((status = B_EncryptInit (ecesEncrypt, publicKey, EC_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Update. */ /* Allocate space to hold encrypted data */ maxEncryptedDataLen = 21 + (2 * fieldElementLen) + dataToEncryptLen; RSA_PrintMessage ("Expected size of encrypted data = %u bytes\n", maxEncryptedDataLen); encryptedData = T_malloc (maxEncryptedDataLen); if (encryptedData == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } if ((status = B_EncryptUpdate (ecesEncrypt, encryptedData, &outputLenUpdate, maxEncryptedDataLen, dataToEncrypt, dataToEncryptLen, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Final. */ if ((status = B_EncryptFinal (ecesEncrypt, encryptedData + outputLenUpdate, &outputLenFinal, maxEncryptedDataLen - outputLenUpdate, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; outputLenTotal = outputLenUpdate + outputLenFinal; RSA_PrintBuf ("Encrypted Data", encryptedData, outputLenTotal); /* EC decryption */ RSA_PrintMessage("\nDecrypting Data...\n"); /* Create. */ if ((status = B_CreateAlgorithmObject (&ecesDecrypt)) != 0) break; /* Set. */ if ((status = B_SetAlgorithmInfo (ecesDecrypt, AI_EC_ES, NULL_PTR)) != 0) break; /* Init. */ if ((status = B_DecryptInit (ecesDecrypt, privateKey, EC_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Update. */ /* Allocate space to hold decrypted data. * The decrypted data will be smaller than the ciphertext. */ maxDecryptedDataLen = outputLenTotal; RSA_PrintMessage ("Maximum size of decrypted data = %u bytes\n", maxDecryptedDataLen); decryptedData = T_malloc (maxDecryptedDataLen); if (decryptedData == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } if ((status = B_DecryptUpdate (ecesDecrypt, decryptedData, &outputLenUpdate, maxDecryptedDataLen, encryptedData, outputLenTotal, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* Final. */ if ((status = B_DecryptFinal (ecesDecrypt, decryptedData + outputLenUpdate, &outputLenFinal, maxDecryptedDataLen - outputLenUpdate, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; outputLenTotal = outputLenUpdate + outputLenFinal; RSA_PrintBuf ("Decrypted Data", decryptedData, outputLenTotal); if ((outputLenTotal == dataToEncryptLen) && (T_memcmp (dataToEncrypt, decryptedData, outputLenTotal)) == 0) { RSA_PrintMessage ("Success! "); RSA_PrintMessage ("Decrypted data matches the original data.\n"); } else { RSA_PrintMessage ("Decrypted data does not match the original data."); status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY; } } while (0); if (status != 0) RSA_PrintError ("ecspecial", status); /* Destroy all objects and free memory. */ B_DestroyAlgorithmObject (&ecesEncrypt); B_DestroyAlgorithmObject (&ecesDecrypt); B_DestroyKeyObject (&publicKey); B_DestroyKeyObject (&privateKey); if (encryptedData != NULL_PTR) { T_memset (encryptedData, 0, maxEncryptedDataLen); T_free (encryptedData); encryptedData = NULL_PTR; } if (decryptedData != NULL_PTR) { T_memset (decryptedData, 0, maxDecryptedDataLen); T_free (decryptedData); decryptedData = NULL_PTR; } return (status); } /* end main */