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

📄 ctx_dh.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

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 + -