static BOOLEAN pairwiseConsistencyTest( CONTEXT_INFO *contextInfoPtr ) { const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo; DLP_PARAMS dlpParams; BYTE buffer[ 128 + 8 ]; int sigSize, status; assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) ); /* Generate a signature with the private key */ setDLPParams( &dlpParams, shaM, 20, buffer, 128 ); dlpParams.inLen2 = -999; status = capabilityInfoPtr->signFunction( contextInfoPtr, ( BYTE * ) &dlpParams, sizeof( DLP_PARAMS ) ); if( cryptStatusError( status ) ) return( FALSE ); /* Verify the signature with the public key */ sigSize = dlpParams.outLen; setDLPParams( &dlpParams, shaM, 20, NULL, 0 ); dlpParams.inParam2 = buffer; dlpParams.inLen2 = sigSize; status = capabilityInfoPtr->sigCheckFunction( contextInfoPtr, ( BYTE * ) &dlpParams, sizeof( DLP_PARAMS ) ); return( cryptStatusOK( status ) ? TRUE : FALSE ); }
static BOOLEAN pairwiseConsistencyTest( INOUT CONTEXT_INFO *contextInfoPtr, const BOOLEAN isGeneratedKey ) { const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo; DLP_PARAMS dlpParams; BYTE buffer[ ( CRYPT_MAX_PKCSIZE * 2 ) + 32 + 8 ]; int encrSize, status; assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) ); /* Encrypt with the public key. We */ memset( buffer, 0, CRYPT_MAX_PKCSIZE ); memcpy( buffer + 1, "abcde", 5 ); setDLPParams( &dlpParams, buffer, bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits ), buffer, ( CRYPT_MAX_PKCSIZE * 2 ) + 32 ); if( !isGeneratedKey ) { /* Force the use of a fixed k value for the encryption test to avoid having to go via the RNG */ dlpParams.inLen2 = -999; } status = capabilityInfoPtr->encryptFunction( contextInfoPtr, ( BYTE * ) &dlpParams, sizeof( DLP_PARAMS ) ); if( cryptStatusError( status ) ) return( FALSE ); /* Decrypt with the private key */ encrSize = dlpParams.outLen; setDLPParams( &dlpParams, buffer, encrSize, buffer, ( CRYPT_MAX_PKCSIZE * 2 ) + 32 ); status = capabilityInfoPtr->decryptFunction( contextInfoPtr, ( BYTE * ) &dlpParams, sizeof( DLP_PARAMS ) ); if( cryptStatusError( status ) ) return( FALSE ); return( !memcmp( buffer + 1, "abcde", 5 ) ); }
CHECK_RETVAL \ static int selfTest( void ) { CONTEXT_INFO contextInfo; PKC_INFO contextData, *pkcInfo = &contextData; const CAPABILITY_INFO *capabilityInfoPtr; DLP_PARAMS dlpParams; BYTE buffer[ ( CRYPT_MAX_PKCSIZE * 2 ) + 32 + 8 ]; int status; /* Initialise the key components */ status = staticInitContext( &contextInfo, CONTEXT_PKC, getElgamalCapability(), &contextData, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( status ); 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(); } capabilityInfoPtr = contextInfo.capabilityInfo; ENSURES( sanityCheckPKCInfo( pkcInfo ) ); /* Perform a test a sig generation/check and test en/decryption */ #if 0 /* See comment in sig.code */ memset( buffer, '*', 20 ); status = capabilityInfoPtr->signFunction( &contextInfoPtr, buffer, -1 ); if( !cryptStatusError( status ) ) { memmove( buffer + 20, buffer, status ); memset( buffer, '*', 20 ); status = capabilityInfoPtr->sigCheckFunction( &contextInfoPtr, buffer, 20 + status ); } if( status != CRYPT_OK ) status = CRYPT_ERROR_FAILED; #endif /* 0 */ status = capabilityInfoPtr->initKeyFunction( &contextInfo, NULL, 0 ); if( cryptStatusError( status ) || \ !pairwiseConsistencyTest( &contextInfo, FALSE ) ) { staticDestroyContext( &contextInfo ); return( CRYPT_ERROR_FAILED ); } /* Finally, make sure that the memory fault-detection is working */ pkcInfo->dlpParam_p.d[ 8 ] ^= 0x0011; memset( buffer, 0, CRYPT_MAX_PKCSIZE ); memcpy( buffer + 1, "abcde", 5 ); setDLPParams( &dlpParams, buffer, bitsToBytes( contextInfo.ctxPKC->keySizeBits ), buffer, ( CRYPT_MAX_PKCSIZE * 2 ) + 32 ); status = capabilityInfoPtr->encryptFunction( &contextInfo, ( BYTE * ) &dlpParams, sizeof( DLP_PARAMS ) ); if( cryptStatusOK( status ) ) { /* The fault-detection couldn't detect a bit-flip, there's a problem */ staticDestroyContext( &contextInfo ); return( CRYPT_ERROR_FAILED ); } /* Clean up */ staticDestroyContext( &contextInfo ); return( CRYPT_OK ); }