static BOOLEAN pairwiseConsistencyTest( INOUT CONTEXT_INFO *contextInfoPtr ) { CONTEXT_INFO checkContextInfo; PKC_INFO *sourcePkcInfo = contextInfoPtr->ctxPKC; PKC_INFO contextData, *pkcInfo = &contextData; KEYAGREE_PARAMS keyAgreeParams1, keyAgreeParams2; const CAPABILITY_INFO *capabilityInfoPtr; int bnStatus = BN_STATUS, status; assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) ); /* The DH pairwise check is a bit more complex than the one for the other algorithms because there's no matched public/private key pair, so we have to load a second DH key to use for key agreement with the first one */ status = staticInitContext( &checkContextInfo, CONTEXT_PKC, getDHCapability(), &contextData, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( FALSE ); CKPTR( BN_copy( &pkcInfo->dlpParam_p, &sourcePkcInfo->dlpParam_p ) ); CKPTR( BN_copy( &pkcInfo->dlpParam_g, &sourcePkcInfo->dlpParam_g ) ); CKPTR( BN_copy( &pkcInfo->dlpParam_q, &sourcePkcInfo->dlpParam_q ) ); CKPTR( BN_copy( &pkcInfo->dlpParam_y, &sourcePkcInfo->dlpParam_y ) ); CKPTR( BN_copy( &pkcInfo->dlpParam_x, &sourcePkcInfo->dlpParam_x ) ); if( bnStatusError( bnStatus ) ) { staticDestroyContext( &checkContextInfo ); return( getBnStatus( bnStatus ) ); } /* Perform the pairwise test using the check key */ capabilityInfoPtr = checkContextInfo.capabilityInfo; memset( &keyAgreeParams1, 0, sizeof( KEYAGREE_PARAMS ) ); memset( &keyAgreeParams2, 0, sizeof( KEYAGREE_PARAMS ) ); status = capabilityInfoPtr->initKeyFunction( &checkContextInfo, NULL, 0 ); if( cryptStatusOK( status ) ) status = capabilityInfoPtr->encryptFunction( contextInfoPtr, ( BYTE * ) &keyAgreeParams1, sizeof( KEYAGREE_PARAMS ) ); if( cryptStatusOK( status ) ) status = capabilityInfoPtr->encryptFunction( &checkContextInfo, ( BYTE * ) &keyAgreeParams2, sizeof( KEYAGREE_PARAMS ) ); if( cryptStatusOK( status ) ) status = capabilityInfoPtr->decryptFunction( contextInfoPtr, ( BYTE * ) &keyAgreeParams2, sizeof( KEYAGREE_PARAMS ) ); if( cryptStatusOK( status ) ) status = capabilityInfoPtr->decryptFunction( &checkContextInfo, ( BYTE * ) &keyAgreeParams1, sizeof( KEYAGREE_PARAMS ) ); if( cryptStatusError( status ) || \ keyAgreeParams1.wrappedKeyLen != keyAgreeParams2.wrappedKeyLen || \ memcmp( keyAgreeParams1.wrappedKey, keyAgreeParams2.wrappedKey, keyAgreeParams1.wrappedKeyLen ) ) status = CRYPT_ERROR_FAILED; /* Clean up */ staticDestroyContext( &checkContextInfo ); return( cryptStatusOK( status ) ? TRUE : FALSE ); }
CHECK_RETVAL \ static int selfTest( void ) { CONTEXT_INFO contextInfo; PKC_INFO contextData, *pkcInfo = &contextData; int status; /* Initialise the key components */ status = staticInitContext( &contextInfo, CONTEXT_PKC, getDHCapability(), &contextData, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( CRYPT_ERROR_FAILED ); status = importBignum( &pkcInfo->dlpParam_p, dlpTestKey.p, dlpTestKey.pLen, DLPPARAM_MIN_P, DLPPARAM_MAX_P, NULL, KEYSIZE_CHECK_PKC ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->dlpParam_g, dlpTestKey.g, dlpTestKey.gLen, DLPPARAM_MIN_G, DLPPARAM_MAX_G, &pkcInfo->dlpParam_p, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->dlpParam_q, dlpTestKey.q, dlpTestKey.qLen, DLPPARAM_MIN_Q, DLPPARAM_MAX_Q, &pkcInfo->dlpParam_p, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->dlpParam_y, dlpTestKey.y, dlpTestKey.yLen, DLPPARAM_MIN_Y, DLPPARAM_MAX_Y, &pkcInfo->dlpParam_p, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->dlpParam_x, dlpTestKey.x, dlpTestKey.xLen, DLPPARAM_MIN_X, DLPPARAM_MAX_X, &pkcInfo->dlpParam_p, KEYSIZE_CHECK_NONE ); if( cryptStatusError( status ) ) { staticDestroyContext( &contextInfo ); retIntError(); } ENSURES( sanityCheckPKCInfo( pkcInfo ) ); /* Perform the test key exchange on a block of data */ status = contextInfo.capabilityInfo->initKeyFunction( &contextInfo, NULL, 0 ); if( cryptStatusOK( status ) && \ !pairwiseConsistencyTest( &contextInfo ) ) status = CRYPT_ERROR_FAILED; /* Clean up */ staticDestroyContext( &contextInfo ); return( status ); }
static int dlpGenerateComponents( CRYPT_PKCINFO_DLP *dlpKeyInfo, const int keySizeBits, const CRYPT_ALGO_TYPE cryptAlgo ) { CONTEXT_INFO staticContextInfo; PKC_INFO contextData, *pkcInfo = &contextData; int length, status; assert( isWritePtr( dlpKeyInfo, sizeof( CRYPT_PKCINFO_DLP ) ) ); REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \ keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) ); REQUIRES( cryptAlgo == CRYPT_ALGO_DH || \ cryptAlgo == CRYPT_ALGO_DSA || \ cryptAlgo == CRYPT_ALGO_ELGAMAL ); /* Clear return value */ cryptInitComponents( dlpKeyInfo, FALSE ); /* Generate the key components */ switch( cryptAlgo ) { #ifdef USE_DH case CRYPT_ALGO_DH: status = generateKeyComponents( &staticContextInfo, &contextData, getDHCapability(), keySizeBits ); break; #endif /* USE_DH */ #ifdef USE_DSA case CRYPT_ALGO_DSA: status = generateKeyComponents( &staticContextInfo, &contextData, getDSACapability(), keySizeBits ); break; #endif /* USE_DSA */ #ifdef USE_ELGAMAL case CRYPT_ALGO_ELGAMAL: status = generateKeyComponents( &staticContextInfo, &contextData, getElgamalCapability(), keySizeBits ); break; #endif /* USE_ELGAMAL */ default: retIntError(); } if( cryptStatusError( status ) ) return( status ); /* Extract the newly-generated key components for the caller to use */ dlpKeyInfo->pLen = BN_num_bits( &pkcInfo->dlpParam_p ); length = BN_bn2bin( &pkcInfo->dlpParam_p, dlpKeyInfo->p ); ENSURES( length == bitsToBytes( dlpKeyInfo->pLen ) ); dlpKeyInfo->gLen = BN_num_bits( &pkcInfo->dlpParam_g ); length = BN_bn2bin( &pkcInfo->dlpParam_g, dlpKeyInfo->g ); ENSURES( length == bitsToBytes( dlpKeyInfo->gLen ) ); dlpKeyInfo->qLen = BN_num_bits( &pkcInfo->dlpParam_q ); length = BN_bn2bin( &pkcInfo->dlpParam_q, dlpKeyInfo->q ); ENSURES( length == bitsToBytes( dlpKeyInfo->qLen ) ); dlpKeyInfo->yLen = BN_num_bits( &pkcInfo->dlpParam_y ); length = BN_bn2bin( &pkcInfo->dlpParam_y, dlpKeyInfo->y ); ENSURES( length == bitsToBytes( dlpKeyInfo->yLen ) ); dlpKeyInfo->xLen = BN_num_bits( &pkcInfo->dlpParam_x ); length = BN_bn2bin( &pkcInfo->dlpParam_x, dlpKeyInfo->x ); ENSURES( length == bitsToBytes( dlpKeyInfo->xLen ) ); staticDestroyContext( &staticContextInfo ); return( status ); }