📄 ctx_dh.c
字号:
BN_init( &pkcInfo->dlpParam_y );
BN_init( &pkcInfo->dlpParam_x );
BN_init( &pkcInfo->dhParam_yPrime );
BN_init( &pkcInfo->tmp1 );
BN_init( &pkcInfo->tmp2 );
BN_init( &pkcInfo->tmp3 );
pkcInfo->bnCTX = BN_CTX_new();
BN_MONT_CTX_init( &pkcInfo->rsaParam_mont_p );
contextInfoPtr.capabilityInfo = capabilityInfoPtr;
initKeyWrite( &contextInfoPtr ); /* For calcKeyID() */
BN_bin2bn( dlpTestKey.p, dlpTestKey.pLen, &pkcInfo->dlpParam_p );
BN_bin2bn( dlpTestKey.g, dlpTestKey.gLen, &pkcInfo->dlpParam_g );
BN_bin2bn( dlpTestKey.q, dlpTestKey.qLen, &pkcInfo->dlpParam_q );
BN_bin2bn( dlpTestKey.y, dlpTestKey.yLen, &pkcInfo->dlpParam_y );
BN_bin2bn( dlpTestKey.x, dlpTestKey.xLen, &pkcInfo->dlpParam_x );
/* Perform the test key exchange on a block of data */
status = capabilityInfoPtr->initKeyFunction( &contextInfoPtr, NULL, 0 );
if( cryptStatusOK( status ) && \
!pairwiseConsistencyTest( &contextInfoPtr, FALSE ) )
status = CRYPT_ERROR;
/* Clean up */
BN_clear_free( &pkcInfo->dlpParam_p );
BN_clear_free( &pkcInfo->dlpParam_g );
BN_clear_free( &pkcInfo->dlpParam_q );
BN_clear_free( &pkcInfo->dlpParam_y );
BN_clear_free( &pkcInfo->dlpParam_x );
BN_clear_free( &pkcInfo->dhParam_yPrime );
BN_clear_free( &pkcInfo->tmp1 );
BN_clear_free( &pkcInfo->tmp2 );
BN_clear_free( &pkcInfo->tmp3 );
BN_CTX_free( pkcInfo->bnCTX );
BN_MONT_CTX_free( &pkcInfo->dlpParam_mont_p );
zeroise( &pkcInfoStorage, sizeof( PKC_INFO ) );
zeroise( &contextInfoPtr, sizeof( CONTEXT_INFO ) );
return( status );
}
/****************************************************************************
* *
* Diffie-Hellman Key Exchange Routines *
* *
****************************************************************************/
/* Perform phase 1 of Diffie-Hellman ("export"). We have to append the
distinguisher 'Fn' to the name since some systems already have 'encrypt'
and 'decrypt' in their standard headers */
static int encryptFn( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int noBytes )
{
PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
UNUSED( noBytes );
assert( noBytes == sizeof( KEYAGREE_PARAMS ) );
assert( !BN_is_zero( &pkcInfo->dlpParam_y ) );
/* y is generated either at keygen time for static DH or as a side-effect
of the implicit generation of the x value for ephemeral DH, so all we
have to do is copy it to the output */
keyAgreeParams->publicValueLen = \
BN_bn2bin( &pkcInfo->dlpParam_y,
keyAgreeParams->publicValue );
return( CRYPT_OK );
#if 0
BN_CTX *bnCTX;
if( ( bnCTX = BN_CTX_new() ) == NULL )
return( CRYPT_ERROR_MEMORY );
/* Export y = g^x mod p. There is no input data since x was set when the
DH values were loaded */
BN_mod_exp_mont( &pkcInfo->dlpParam_y, &pkcInfo->dlpParam_g,
&pkcInfo->dlpParam_x, &pkcInfo->dlpParam_p, bnCTX,
&pkcInfo->dlpParam_mont_p );
keyAgreeParams->publicValueLen = \
BN_bn2bin( &pkcInfo->dlpParam_y,
keyAgreeParams->publicValue );
BN_CTX_free( bnCTX );
return( ( status == -1 ) ? CRYPT_ERROR_FAILED : status );
#endif /* 0 */
}
/* Perform phase 2 of Diffie-Hellman ("import") */
static int decryptFn( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int noBytes )
{
KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
BIGNUM *z = &pkcInfo->tmp1;
const int length = bitsToBytes( pkcInfo->keySizeBits );
int i, bnStatus = BN_STATUS;
assert( noBytes == sizeof( KEYAGREE_PARAMS ) );
assert( keyAgreeParams->publicValue != NULL && \
keyAgreeParams->publicValueLen >= bitsToBytes( MIN_PKCSIZE_BITS ) );
/* Make sure that we're not being fed suspiciously short data
quantities */
for( i = 0; i < length; i++ )
if( keyAgreeParams->publicValue[ i ] )
break;
if( length - i < 56 )
return( CRYPT_ERROR_BADDATA );
/* The other party's y value will be stored with the key agreement info
rather than having been read in when we read the DH public key */
BN_bin2bn( keyAgreeParams->publicValue, keyAgreeParams->publicValueLen,
&pkcInfo->dhParam_yPrime );
/* Export z = y^x mod p. We need to use separate y and z values because
the bignum code can't handle modexp with the first two parameters the
same */
CK( BN_mod_exp_mont( z, &pkcInfo->dhParam_yPrime, &pkcInfo->dlpParam_x,
&pkcInfo->dlpParam_p, pkcInfo->bnCTX,
&pkcInfo->dlpParam_mont_p ) );
keyAgreeParams->wrappedKeyLen = BN_bn2bin( z, keyAgreeParams->wrappedKey );
return( getBnStatus( bnStatus ) );
}
/****************************************************************************
* *
* Key Management *
* *
****************************************************************************/
/* Load key components into an encryption context */
static int initKey( CONTEXT_INFO *contextInfoPtr, const void *key,
const int keyLength )
{
PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
int status;
#ifndef USE_FIPS140
/* Load the key component from the external representation into the
internal bignums unless we're doing an internal load */
if( key != NULL )
{
const CRYPT_PKCINFO_DLP *dhKey = ( CRYPT_PKCINFO_DLP * ) key;
contextInfoPtr->flags |= ( dhKey->isPublicKey ) ? \
CONTEXT_ISPUBLICKEY : CONTEXT_ISPRIVATEKEY;
BN_bin2bn( dhKey->p, bitsToBytes( dhKey->pLen ),
&pkcInfo->dlpParam_p );
BN_bin2bn( dhKey->g, bitsToBytes( dhKey->gLen ),
&pkcInfo->dlpParam_g );
BN_bin2bn( dhKey->q, bitsToBytes( dhKey->qLen ),
&pkcInfo->dlpParam_q );
BN_bin2bn( dhKey->y, bitsToBytes( dhKey->yLen ),
&pkcInfo->dlpParam_y );
if( !dhKey->isPublicKey )
BN_bin2bn( dhKey->x, bitsToBytes( dhKey->xLen ),
&pkcInfo->dlpParam_x );
contextInfoPtr->flags |= CONTEXT_PBO;
}
#endif /* USE_FIPS140 */
/* Complete the key checking and setup */
status = initDLPkey( contextInfoPtr, TRUE );
if( cryptStatusOK( status ) )
/* DH keys may follow PKCS #3 rather than X9.42, which means we can't
do extended checking using q, so if q is zero we denote it as a
PKCS #3 key. This is only permitted for DH keys, other key types
will fail the check if q = 0 */
status = checkDLPkey( contextInfoPtr,
BN_is_zero( &pkcInfo->dlpParam_q ) ? \
TRUE : FALSE );
if( cryptStatusOK( status ) )
status = calculateKeyID( contextInfoPtr );
return( status );
}
/* Generate a key into an encryption context */
static int generateKey( CONTEXT_INFO *contextInfoPtr, const int keySizeBits )
{
int status;
status = generateDLPkey( contextInfoPtr, keySizeBits, CRYPT_USE_DEFAULT,
TRUE );
if( cryptStatusOK( status ) &&
#ifndef USE_FIPS140
( contextInfoPtr->flags & CONTEXT_SIDECHANNELPROTECTION ) &&
#endif /* USE_FIPS140 */
!pairwiseConsistencyTest( contextInfoPtr, TRUE ) )
{
assert( NOTREACHED );
status = CRYPT_ERROR_FAILED;
}
if( cryptStatusOK( status ) )
status = calculateKeyID( contextInfoPtr );
return( status );
}
/****************************************************************************
* *
* Capability Access Routines *
* *
****************************************************************************/
static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
CRYPT_ALGO_DH, bitsToBytes( 0 ), "Diffie-Hellman",
bitsToBytes( MIN_PKCSIZE_BITS ), bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE,
selfTest, getDefaultInfo, NULL, NULL, initKey, generateKey, encryptFn, decryptFn
};
const CAPABILITY_INFO *getDHCapability( void )
{
return( &capabilityInfo );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -