⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctx_dh.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -