| RSA BSAFE Crypto-C |
Cryptographic Components for C |
| Search |
/* $Id: ecdh.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 demonstrate the EC Diffie-Hellman key agreement * scheme where two parties exchange public values to agree upon * a shared secret key. */ #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_DH_CHOOSER[] = { &AM_ECFP_DH_KEY_AGREE, &AM_ECF2POLY_DH_KEY_AGREE, (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 ecdhMain #else #define MAIN main #endif int MAIN(int argc, char *argv[]) { int status; char userInput[RSA_DEMO_MAX_LINE_LEN]; B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ alice = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ bob = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ ecParamsObj = (B_ALGORITHM_OBJ)NULL_PTR; B_EC_PARAMS commonECParams; A_EC_PARAMS *cryptocECParams; A_EC_PARAMS ecParams = {0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 0, 0}; unsigned int fieldElementLen, maxPhase1Len, maxPhase2Len; unsigned char *alicePublicValue = NULL_PTR; unsigned char *bobPublicValue = NULL_PTR; unsigned int alicePublicValueLen, bobPublicValueLen; unsigned char *aliceSecretValue = NULL_PTR; unsigned char *bobSecretValue = NULL_PTR; unsigned int aliceSecretValueLen, bobSecretValueLen; ITEM aTableItem = {NULL, 0}; 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 Diffie-Hellman Key Agreement Algorithm\n"); RSA_PrintMessage ("=========================================\n"); if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0) break; if ((status = RSA_GetCommand (userInput, sizeof (userInput), "Generate new parameters (y/n)")) != 0) break; if ((userInput[0] == 'y') || (userInput[0] == 'Y')) { if ((status = RSA_CreateECParamsObject (&ecParamsObj, randomAlgorithm)) != 0) break; } else { if ((status = RSA_CreateECParamsObject (&ecParamsObj, NULL)) != 0) break; } if ((status = RSA_PrintECParamInfo (ecParamsObj, AI_ECParameters)) != 0) break; /* Create an algorithm object */ if ((status = B_CreateAlgorithmObject (&alice)) != 0) break; if ((status = B_CreateAlgorithmObject (&bob)) != 0) break; /* Set algorithm object to AI_EC_DHKeyAgree */ /* First get the EC parameters that Alice and Bob will have in common */ if ((status = B_GetAlgorithmInfo ((POINTER *)&cryptocECParams, ecParamsObj, AI_ECParameters)) != 0) break; if ((status = RSA_AllocAndCopyECParamInfo (&ecParams, cryptocECParams)) != 0) break; commonECParams.parameterInfoType = AI_ECParameters; commonECParams.parameterInfoValue = (POINTER)&ecParams; /* Provide Alice and Bob with the same EC parameters */ if ((status = B_SetAlgorithmInfo (alice, AI_EC_DHKeyAgree, (POINTER)&commonECParams)) != 0) break; if ((status = B_SetAlgorithmInfo (bob, AI_EC_DHKeyAgree, (POINTER)&commonECParams)) != 0) break; if ((status = RSA_GetCommand (userInput, sizeof (userInput), "Generate accelerator tables (y/n)")) != 0) break; if ((userInput[0] == 'y') || (userInput[0] == 'Y')) { if ((status = RSA_BuildAccelTable (&aTableItem, ecParamsObj)) != 0) break; /* Alice and Bob can also optionally receive the acceleration tables * corresponding with the EC parameters they have. */ if ((status = B_SetAlgorithmInfo (alice, AI_ECAcceleratorTable, (POINTER)&aTableItem)) != 0) break; if ((status = B_SetAlgorithmInfo (bob, AI_ECAcceleratorTable, (POINTER)&aTableItem)) != 0) break; } /* Initialize key agreement protocol */ if ((status = B_KeyAgreeInit (alice, (B_KEY_OBJ)NULL_PTR, EC_DH_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; if ((status = B_KeyAgreeInit (bob, (B_KEY_OBJ)NULL_PTR, EC_DH_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; /* The largest size of phase 1 output we can get is one byte larger * than twice the field element size. For phase 2, the size of the * output should be the same as the field element size. (See * Library Reference Manual entry on AI_EC_DHKeyAgree for more details) */ fieldElementLen = (ecParams.fieldElementBits + 7) / 8; RSA_PrintMessage ("EC Parameters: Field element length = %u bytes\n", fieldElementLen); maxPhase1Len = (fieldElementLen * 2) + 1; maxPhase2Len = fieldElementLen; /* Phase 1 */ RSA_PrintMessage ("\nKey Agreement -- Phase 1\n"); RSA_PrintMessage ("========================\n"); alicePublicValue = T_malloc (maxPhase1Len); if (alicePublicValue == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } bobPublicValue = T_malloc (maxPhase1Len); if (bobPublicValue == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } if ((status = B_KeyAgreePhase1 (alice, alicePublicValue, &alicePublicValueLen, maxPhase1Len, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; RSA_PrintBuf ("Alice's public value", alicePublicValue, alicePublicValueLen); if ((status = B_KeyAgreePhase1 (bob, bobPublicValue, &bobPublicValueLen, maxPhase1Len, randomAlgorithm, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; RSA_PrintBuf ("Bob's public value", bobPublicValue, bobPublicValueLen); /* Phase 2 */ RSA_PrintMessage ("\nKey Agreement -- Phase 2\n"); RSA_PrintMessage ("========================\n"); aliceSecretValue = T_malloc (maxPhase2Len); if (aliceSecretValue == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } bobSecretValue = T_malloc (maxPhase2Len); if (bobSecretValue == NULL_PTR) { status = RSA_DEMO_E_ALLOC; break; } if ((status = B_KeyAgreePhase2 (alice, aliceSecretValue, &aliceSecretValueLen, maxPhase2Len, bobPublicValue, bobPublicValueLen, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; RSA_PrintBuf ("Value derived by Alice", aliceSecretValue, aliceSecretValueLen); if ((status = B_KeyAgreePhase2 (bob, bobSecretValue, &bobSecretValueLen, maxPhase2Len, alicePublicValue, alicePublicValueLen, (A_SURRENDER_CTX *)NULL_PTR)) != 0) break; RSA_PrintBuf ("Value derived by Bob", bobSecretValue, bobSecretValueLen); /* Alice and Bob should derive the same secret value */ if ((aliceSecretValueLen == bobSecretValueLen) && (T_memcmp (aliceSecretValue, bobSecretValue, aliceSecretValueLen)) == 0) { RSA_PrintMessage ("Success! "); RSA_PrintMessage ("Alice and Bob's secret keys agree.\n"); } else { RSA_PrintMessage ("Alice and Bob do not have matching secret values."); status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY; } } while(0); if (status != 0) RSA_PrintError ("ecdh", status); RSA_FreeECParamInfo (&ecParams); if (aTableItem.data != NULL) { T_memset (aTableItem.data, 0, aTableItem.len); T_free (aTableItem.data); } if (alicePublicValue != NULL_PTR) T_free (alicePublicValue); if (bobPublicValue != NULL_PTR) T_free (bobPublicValue); if (aliceSecretValue != NULL_PTR) T_free (aliceSecretValue); if (bobSecretValue != NULL_PTR) T_free (bobSecretValue); B_DestroyAlgorithmObject (&randomAlgorithm); B_DestroyAlgorithmObject (&alice); B_DestroyAlgorithmObject (&bob); return (status); } /* end main */