static int rc4Test( const BYTE *key, const int keySize, const BYTE *plaintext, const BYTE *ciphertext, const int length ) { const CAPABILITY_INFO *capabilityInfo = getRC4Capability(); CONTEXT_INFO contextInfo; CONV_INFO contextData; BYTE keyData[ RC4_EXPANDED_KEYSIZE + 8 ]; BYTE temp[ 512 + 8 ]; int status; staticInitContext( &contextInfo, CONTEXT_CONV, capabilityInfo, &contextData, sizeof( CONV_INFO ), keyData ); memcpy( temp, plaintext, length ); status = capabilityInfo->initKeyFunction( &contextInfo, key, keySize ); if( cryptStatusOK( status ) ) status = capabilityInfo->encryptOFBFunction( &contextInfo, temp, length ); staticDestroyContext( &contextInfo ); if( cryptStatusError( status ) || \ memcmp( ciphertext, temp, length ) ) return( CRYPT_ERROR_FAILED ); return( CRYPT_OK ); }
static int generateKeyComponents( CONTEXT_INFO *staticContextInfo, PKC_INFO *contextData, const CAPABILITY_INFO *capabilityInfoPtr, const int keySizeBits ) { int status; assert( isWritePtr( staticContextInfo, sizeof( CONTEXT_INFO ) ) ); assert( isWritePtr( contextData, sizeof( PKC_INFO ) ) ); assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) ); REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \ keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) ); /* Initialise a static context to generate the key into */ status = staticInitContext( staticContextInfo, CONTEXT_PKC, capabilityInfoPtr, contextData, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( status ); /* Generate a key into the static context */ status = capabilityInfoPtr->generateKeyFunction( staticContextInfo, keySizeBits ); if( cryptStatusError( status ) ) { staticDestroyContext( staticContextInfo ); return( status ); } return( CRYPT_OK ); }
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 initContext( INOUT CONTEXT_INFO *contextInfo, INOUT PKC_INFO *pkcInfo ) { int status; assert( isWritePtr( contextInfo, sizeof( CONTEXT_INFO ) ) ); assert( isWritePtr( pkcInfo, sizeof( PKC_INFO ) ) ); status = staticInitContext( contextInfo, CONTEXT_PKC, getRSACapability(), pkcInfo, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( status ); status = importBignum( &pkcInfo->rsaParam_n, rsaTestKey.n, rsaTestKey.nLen, RSAPARAM_MIN_N, RSAPARAM_MAX_N, NULL, KEYSIZE_CHECK_PKC ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->rsaParam_e, rsaTestKey.e, rsaTestKey.eLen, RSAPARAM_MIN_E, RSAPARAM_MAX_E, &pkcInfo->rsaParam_n, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->rsaParam_d, rsaTestKey.d, rsaTestKey.dLen, RSAPARAM_MIN_D, RSAPARAM_MAX_D, &pkcInfo->rsaParam_n, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->rsaParam_p, rsaTestKey.p, rsaTestKey.pLen, RSAPARAM_MIN_P, RSAPARAM_MAX_P, &pkcInfo->rsaParam_n, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->rsaParam_q, rsaTestKey.q, rsaTestKey.qLen, RSAPARAM_MIN_Q, RSAPARAM_MAX_Q, &pkcInfo->rsaParam_n, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->rsaParam_u, rsaTestKey.u, rsaTestKey.uLen, RSAPARAM_MIN_U, RSAPARAM_MAX_U, &pkcInfo->rsaParam_n, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->rsaParam_exponent1, rsaTestKey.e1, rsaTestKey.e1Len, RSAPARAM_MIN_EXP1, RSAPARAM_MAX_EXP1, &pkcInfo->rsaParam_n, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->rsaParam_exponent2, rsaTestKey.e2, rsaTestKey.e2Len, RSAPARAM_MIN_EXP2, RSAPARAM_MAX_EXP2, &pkcInfo->rsaParam_n, KEYSIZE_CHECK_NONE ); return( status ); }
CHECK_RETVAL \ static int selfTest( void ) { CONTEXT_INFO contextInfo; PKC_INFO contextData, *pkcInfo = &contextData; const CAPABILITY_INFO *capabilityInfoPtr; int status; /* Initialise the key components */ status = staticInitContext( &contextInfo, CONTEXT_PKC, getECDHCapability(), &contextData, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( CRYPT_ERROR_FAILED ); pkcInfo->curveType = CRYPT_ECCCURVE_P256; status = importBignum( &pkcInfo->eccParam_qx, ecdhTestKey.qx, ecdhTestKey.qxLen, ECCPARAM_MIN_QX, ECCPARAM_MAX_QX, NULL, KEYSIZE_CHECK_ECC ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->eccParam_qy, ecdhTestKey.qy, ecdhTestKey.qyLen, ECCPARAM_MIN_QY, ECCPARAM_MAX_QY, NULL, KEYSIZE_CHECK_NONE ); if( cryptStatusOK( status ) ) status = importBignum( &pkcInfo->eccParam_d, ecdhTestKey.d, ecdhTestKey.dLen, ECCPARAM_MIN_D, ECCPARAM_MAX_D, NULL, KEYSIZE_CHECK_NONE ); if( cryptStatusError( status ) ) { staticDestroyContext( &contextInfo ); retIntError(); } capabilityInfoPtr = contextInfo.capabilityInfo; /* Perform the test key exchange on a block of data */ status = capabilityInfoPtr->initKeyFunction( &contextInfo, NULL, 0 ); if( cryptStatusError( status ) || \ !pairwiseConsistencyTest( &contextInfo ) ) { staticDestroyContext( &contextInfo ); return( CRYPT_ERROR_FAILED ); } /* Clean up */ staticDestroyContext( &contextInfo ); return( CRYPT_OK ); }
static int selfTest( void ) { #if 0 /* ECB */ static const BYTE FAR_BSS mctECBKey[] = \ { 0x8D, 0x2E, 0x60, 0x36, 0x5F, 0x17, 0xC7, 0xDF, 0x10, 0x40, 0xD7, 0x50, 0x1B, 0x4A, 0x7B, 0x5A }; static const BYTE FAR_BSS mctECBPT[] = \ { 0x59, 0xB5, 0x08, 0x8E, 0x6D, 0xAD, 0xC3, 0xAD, 0x5F, 0x27, 0xA4, 0x60, 0x87, 0x2D, 0x59, 0x29 }; /* CBC */ static const BYTE FAR_BSS mctCBCKey[] = \ { 0x9D, 0xC2, 0xC8, 0x4A, 0x37, 0x85, 0x0C, 0x11, 0x69, 0x98, 0x18, 0x60, 0x5F, 0x47, 0x95, 0x8C }; static const BYTE FAR_BSS mctCBCIV[] = \ { 0x25, 0x69, 0x53, 0xB2, 0xFE, 0xAB, 0x2A, 0x04, 0xAE, 0x01, 0x80, 0xD8, 0x33, 0x5B, 0xBE, 0xD6 }; static const BYTE FAR_BSS mctCBCPT[] = \ { 0x2E, 0x58, 0x66, 0x92, 0xE6, 0x47, 0xF5, 0x02, 0x8E, 0xC6, 0xFA, 0x47, 0xA5, 0x5A, 0x2A, 0xAB }; /* OFB */ static const BYTE FAR_BSS mctOFBKey[] = \ { 0xB1, 0x1E, 0x4E, 0xCA, 0xE2, 0xE7, 0x1E, 0x14, 0x14, 0x5D, 0xD7, 0xDB, 0x26, 0x35, 0x65, 0x2F }; static const BYTE FAR_BSS mctOFBIV[] = \ { 0xAD, 0xD3, 0x2B, 0xF8, 0x20, 0x4C, 0x33, 0x33, 0x9C, 0x54, 0xCD, 0x58, 0x58, 0xEE, 0x0D, 0x13 }; static const BYTE FAR_BSS mctOFBPT[] = \ { 0x73, 0x20, 0x49, 0xE8, 0x9D, 0x74, 0xFC, 0xE7, 0xC5, 0xA4, 0x96, 0x64, 0x04, 0x86, 0x8F, 0xA6 }; /* CFB-128 */ static const BYTE FAR_BSS mctCFBKey[] = \ { 0x71, 0x15, 0x11, 0x93, 0x1A, 0x15, 0x62, 0xEA, 0x73, 0x29, 0x0A, 0x8B, 0x0A, 0x37, 0xA3, 0xB4 }; static const BYTE FAR_BSS mctCFBIV[] = \ { 0x9D, 0xCE, 0x23, 0xFD, 0x2D, 0xF5, 0x36, 0x0F, 0x79, 0x9C, 0xF1, 0x79, 0x84, 0xE4, 0x7C, 0x8D }; static const BYTE FAR_BSS mctCFBPT[] = \ { 0xF0, 0x66, 0xBE, 0x4B, 0xD6, 0x71, 0xEB, 0xC1, 0xC4, 0xCF, 0x3C, 0x00, 0x8E, 0xF2, 0xCF, 0x18 }; #endif /* 0 */ const CAPABILITY_INFO *capabilityInfo = getAESCapability(); BYTE keyData[ AES_EXPANDED_KEYSIZE + 8 ]; int i, status; /* The AES code requires 16-byte alignment for data structures, before we try anything else we make sure that the compiler voodoo required to handle this has worked */ if( aes_test_alignment_detection( 16 ) != EXIT_SUCCESS ) return( CRYPT_ERROR_FAILED ); for( i = 0; i < sizeof( testAES ) / sizeof( AES_TEST ); i++ ) { status = testCipher( capabilityInfo, keyData, testAES[ i ].key, testAES[ i ].keySize, testAES[ i ].plaintext, testAES[ i ].ciphertext ); if( cryptStatusError( status ) ) return( status ); } #if 0 /* OK */ staticInitContext( &contextInfo, CONTEXT_CONV, capabilityInfo, &contextData, sizeof( CONV_INFO ), keyData ); status = mct( &contextInfo, capabilityInfo, mctECBKey, 16, NULL, mctECBPT ); staticDestroyContext( &contextInfo ); if( cryptStatusError( status ) ) return( CRYPT_ERROR_FAILED ); #endif #if 0 /* OK */ staticInitContext( &contextInfo, CONTEXT_CONV, capabilityInfo, &contextData, sizeof( CONV_INFO ), keyData ); status = mct( &contextInfo, capabilityInfo, mctCBCKey, 16, mctCBCIV, mctCBCPT ); staticDestroyContext( &contextInfo ); if( cryptStatusError( status ) ) return( CRYPT_ERROR_FAILED ); #endif return( CRYPT_OK ); }
assert( isWritePtr( staticContextInfo, sizeof( CONTEXT_INFO ) ) ); assert( isWritePtr( contextData, sizeof( PKC_INFO ) ) ); assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) ); assert( isReadPtr( publicKeyData, publicKeyDataLength ) ); REQUIRES( ( isEccAlgo( capabilityInfoPtr->cryptAlgo ) && \ publicKeyDataLength >= MIN_PKCSIZE_ECCPOINT && \ publicKeyDataLength < MAX_INTLENGTH_SHORT ) || \ ( !isEccAlgo( capabilityInfoPtr->cryptAlgo ) && \ publicKeyDataLength >= MIN_PKCSIZE && \ publicKeyDataLength < MAX_INTLENGTH_SHORT ) ); /* Initialise a static context to read the key data into */ status = staticInitContext( staticContextInfo, CONTEXT_PKC, capabilityInfoPtr, contextData, sizeof( PKC_INFO ), NULL ); if( cryptStatusError( status ) ) return( status ); /* Read the key data into the static context and calculate the keyIDs. We can do this now that the data is in a native context rather than being present only in raw encoded form */ sMemConnect( &stream, publicKeyData, publicKeyDataLength ); status = contextData->readPublicKeyFunction( &stream, staticContextInfo, KEYFORMAT_CERT ); sMemDisconnect( &stream ); if( cryptStatusOK( status ) ) { staticContextInfo->flags |= CONTEXT_FLAG_ISPUBLICKEY; status = capabilityInfoPtr->initKeyFunction( staticContextInfo,
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 ); }