📄 ctx_dh.c
字号:
}
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 = extractBignum( &pkcInfo->dlpParam_p, dlpTestKey.p,
dlpTestKey.pLen, DLPPARAM_MIN_P,
DLPPARAM_MAX_P, NULL, TRUE );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->dlpParam_g, dlpTestKey.g,
dlpTestKey.gLen, DLPPARAM_MIN_G,
DLPPARAM_MAX_G, &pkcInfo->dlpParam_p,
FALSE );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->dlpParam_q, dlpTestKey.q,
dlpTestKey.qLen, DLPPARAM_MIN_Q,
DLPPARAM_MAX_Q, &pkcInfo->dlpParam_p,
FALSE );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->dlpParam_y, dlpTestKey.y,
dlpTestKey.yLen, DLPPARAM_MIN_Y,
DLPPARAM_MAX_Y, &pkcInfo->dlpParam_p,
FALSE );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->dlpParam_x, dlpTestKey.x,
dlpTestKey.xLen, DLPPARAM_MIN_X,
DLPPARAM_MAX_X, &pkcInfo->dlpParam_p,
FALSE );
if( cryptStatusError( status ) )
{
staticDestroyContext( &contextInfo );
retIntError();
}
/* Perform the test key exchange on a block of data */
status = contextInfo.capabilityInfo->initKeyFunction( &contextInfo, NULL, 0 );
if( cryptStatusOK( status ) && \
!pairwiseConsistencyTest( &contextInfo, FALSE ) )
status = CRYPT_ERROR_FAILED;
/* Clean up */
staticDestroyContext( &contextInfo );
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_ARG( 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 */
return( getBignumData( &pkcInfo->dlpParam_y,
keyAgreeParams->publicValue, CRYPT_MAX_PKCSIZE,
&keyAgreeParams->publicValueLen ) );
}
/* 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;
int bnStatus = BN_STATUS, status;
assert( noBytes == sizeof( KEYAGREE_PARAMS ) );
assert( keyAgreeParams->publicValue != NULL && \
keyAgreeParams->publicValueLen >= MIN_PKCSIZE );
/* 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 */
status = extractBignum( &pkcInfo->dhParam_yPrime,
keyAgreeParams->publicValue,
keyAgreeParams->publicValueLen,
DLPPARAM_MIN_Y, DLPPARAM_MAX_Y,
&pkcInfo->dlpParam_p, TRUE );
if( cryptStatusError( status ) )
return( status );
/* 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 ) );
if( bnStatusError( bnStatus ) )
return( getBnStatus( bnStatus ) );
return( getBignumData( z, keyAgreeParams->wrappedKey, CRYPT_MAX_PKCSIZE,
&keyAgreeParams->wrappedKeyLen ) );
}
/****************************************************************************
* *
* 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_FLAG_ISPUBLICKEY : CONTEXT_FLAG_ISPRIVATEKEY;
status = extractBignum( &pkcInfo->dlpParam_p, dhKey->p,
bitsToBytes( dhKey->pLen ),
DLPPARAM_MIN_P, DLPPARAM_MAX_P, NULL, TRUE );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->dlpParam_g, dhKey->g,
bitsToBytes( dhKey->gLen ),
DLPPARAM_MIN_G, DLPPARAM_MAX_G,
&pkcInfo->dlpParam_p, FALSE );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->dlpParam_q, dhKey->q,
bitsToBytes( dhKey->qLen ),
DLPPARAM_MIN_Q, DLPPARAM_MAX_Q,
&pkcInfo->dlpParam_p, FALSE );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->dlpParam_y, dhKey->y,
bitsToBytes( dhKey->yLen ),
DLPPARAM_MIN_Y, DLPPARAM_MAX_Y,
&pkcInfo->dlpParam_p, TRUE );
if( cryptStatusOK( status ) && !dhKey->isPublicKey )
status = extractBignum( &pkcInfo->dlpParam_x, dhKey->x,
bitsToBytes( dhKey->xLen ),
DLPPARAM_MIN_X, DLPPARAM_MAX_X,
&pkcInfo->dlpParam_p, FALSE );
contextInfoPtr->flags |= CONTEXT_FLAG_PBO;
if( cryptStatusError( status ) )
return( status );
}
#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 = pkcInfo->calculateKeyIDFunction( 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 );
if( cryptStatusOK( status ) &&
#ifndef USE_FIPS140
( contextInfoPtr->flags & CONTEXT_FLAG_SIDECHANNELPROTECTION ) &&
#endif /* USE_FIPS140 */
!pairwiseConsistencyTest( contextInfoPtr, TRUE ) )
{
assert( DEBUG_WARN );
status = CRYPT_ERROR_FAILED;
}
if( cryptStatusOK( status ) )
status = contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr );
return( status );
}
/****************************************************************************
* *
* Capability Access Routines *
* *
****************************************************************************/
static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
CRYPT_ALGO_DH, bitsToBytes( 0 ), "Diffie-Hellman", 14,
MIN_PKCSIZE, bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE,
selfTest, getDefaultInfo, NULL, NULL, initKey, generateKey, encryptFn, decryptFn
};
const CAPABILITY_INFO *getDHCapability( void )
{
return( &capabilityInfo );
}
#endif /* USE_DH */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -