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

📄 lib_dh.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
	};

/* The structure for storing the DH public values */

typedef struct {
	const int baseLen; const BYTE base[ 1 ];
	const int primeLen; const BYTE *prime;
	} DH_PUBLIC_VALUES;

static const DH_PUBLIC_VALUES dhPublicValues[] = {
	{ 2, { 0x02 }, 512, prime512 },
	{ 2, { 0x02 }, 768, prime768 },
	{ 2, { 0x02 }, 1024, prime1024 },
	{ 2, { 0x02 }, 1280, prime1280 },
	{ 2, { 0x02 }, 1536, prime1536 },
	{ 2, { 0x02 }, 2048, prime2048 },
	{ 2, { 0x02 }, 3072, prime3072 },
	{ 2, { 0x02 }, 4096, prime4096 },
	{ 0, { 0 }, 0, NULL }
	};
#endif /* 0 */

/****************************************************************************
*																			*
*						Diffie-Hellman Self-test Routines					*
*																			*
****************************************************************************/

/* Test the Diffie-Hellman implementation using the sample key from FIPS 186.
   Because a lot of the high-level encryption routines don't exist yet, we
   cheat a bit and set up a dummy encryption context with just enough
   information for the following code to work */

typedef struct {
	int pLen; BYTE p[ 64 ];
	int qLen; BYTE q[ 20 ];
	int gLen; BYTE g[ 64 ];
	int xLen; BYTE x[ 20 ];
	int yLen; BYTE y[ 64 ];
	} DLP_PRIVKEY;

static const DLP_PRIVKEY dlpTestKey = {
	/* p */
	512,
	{ 0x8D, 0xF2, 0xA4, 0x94, 0x49, 0x22, 0x76, 0xAA,
	  0x3D, 0x25, 0x75, 0x9B, 0xB0, 0x68, 0x69, 0xCB,
	  0xEA, 0xC0, 0xD8, 0x3A, 0xFB, 0x8D, 0x0C, 0xF7,
	  0xCB, 0xB8, 0x32, 0x4F, 0x0D, 0x78, 0x82, 0xE5,
	  0xD0, 0x76, 0x2F, 0xC5, 0xB7, 0x21, 0x0E, 0xAF,
	  0xC2, 0xE9, 0xAD, 0xAC, 0x32, 0xAB, 0x7A, 0xAC,
	  0x49, 0x69, 0x3D, 0xFB, 0xF8, 0x37, 0x24, 0xC2,
	  0xEC, 0x07, 0x36, 0xEE, 0x31, 0xC8, 0x02, 0x91 },
	/* q */
	160,
	{ 0xC7, 0x73, 0x21, 0x8C, 0x73, 0x7E, 0xC8, 0xEE,
	  0x99, 0x3B, 0x4F, 0x2D, 0xED, 0x30, 0xF4, 0x8E,
	  0xDA, 0xCE, 0x91, 0x5F },
	/* g */
	512,
	{ 0x62, 0x6D, 0x02, 0x78, 0x39, 0xEA, 0x0A, 0x13,
	  0x41, 0x31, 0x63, 0xA5, 0x5B, 0x4C, 0xB5, 0x00,
	  0x29, 0x9D, 0x55, 0x22, 0x95, 0x6C, 0xEF, 0xCB,
	  0x3B, 0xFF, 0x10, 0xF3, 0x99, 0xCE, 0x2C, 0x2E,
	  0x71, 0xCB, 0x9D, 0xE5, 0xFA, 0x24, 0xBA, 0xBF,
	  0x58, 0xE5, 0xB7, 0x95, 0x21, 0x92, 0x5C, 0x9C,
	  0xC4, 0x2E, 0x9F, 0x6F, 0x46, 0x4B, 0x08, 0x8C,
	  0xC5, 0x72, 0xAF, 0x53, 0xE6, 0xD7, 0x88, 0x02 },
	/* y */
	160,
	{ 0x20, 0x70, 0xB3, 0x22, 0x3D, 0xBA, 0x37, 0x2F,
	  0xDE, 0x1C, 0x0F, 0xFC, 0x7B, 0x2E, 0x3B, 0x49,
	  0x8B, 0x26, 0x06, 0x14 },
	/* x */
	512,
	{ 0x19, 0x13, 0x18, 0x71, 0xD7, 0x5B, 0x16, 0x12,
	  0xA8, 0x19, 0xF2, 0x9D, 0x78, 0xD1, 0xB0, 0xD7,
	  0x34, 0x6F, 0x7A, 0xA7, 0x7B, 0xB6, 0x2A, 0x85,
	  0x9B, 0xFD, 0x6C, 0x56, 0x75, 0xDA, 0x9D, 0x21,
	  0x2D, 0x3A, 0x36, 0xEF, 0x16, 0x72, 0xEF, 0x66,
	  0x0B, 0x8C, 0x7C, 0x25, 0x5C, 0xC0, 0xEC, 0x74,
	  0x85, 0x8F, 0xBA, 0x33, 0xF4, 0x4C, 0x06, 0x69,
	  0x96, 0x30, 0xA7, 0x6B, 0x03, 0x0E, 0xE3, 0x33 }
	};

int dhInitKey( CRYPT_INFO *cryptInfo, const void *key, const int keyLength );
int dhEncrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes );
int dhDecrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes );

int dhSelfTest( void )
	{
	CRYPT_INFO cryptInfo1, cryptInfo2;
	CRYPT_PKCINFO_DLP *dhKey;
	KEYAGREE_PARAMS keyAgreeParams1, keyAgreeParams2;
	static const CAPABILITY_INFO capabilityInfo = { CRYPT_ALGO_DH, 0, NULL, 
													64, 128, 512, 0 };
	int status = CRYPT_OK;

	/* Set up the key components */
	if( ( dhKey = ( CRYPT_PKCINFO_DLP * ) malloc( sizeof( CRYPT_PKCINFO_DLP ) ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	cryptInitComponents( dhKey, CRYPT_KEYTYPE_PRIVATE );
	cryptSetComponent( dhKey->p, dlpTestKey.p, dlpTestKey.pLen );
	cryptSetComponent( dhKey->q, dlpTestKey.q, dlpTestKey.qLen );
	cryptSetComponent( dhKey->g, dlpTestKey.g, dlpTestKey.gLen );
	cryptSetComponent( dhKey->y, dlpTestKey.y, dlpTestKey.yLen );
	cryptSetComponent( dhKey->x, dlpTestKey.x, dlpTestKey.xLen );

	/* Initialise the BigNum information and components */
	cryptInitComponents( dhKey, CRYPT_UNUSED );
	memset( &cryptInfo1, 0, sizeof( CRYPT_INFO ) );
	cryptInfo1.ctxPKC.param1 = BN_new();
	cryptInfo1.ctxPKC.param2 = BN_new();
	cryptInfo1.ctxPKC.param3 = BN_new();
	cryptInfo1.ctxPKC.param4 = BN_new();
	cryptInfo1.ctxPKC.param5 = BN_new();
	cryptInfo1.capabilityInfo = &capabilityInfo;
	memset( &cryptInfo2, 0, sizeof( CRYPT_INFO ) );
	cryptInfo2.ctxPKC.param1 = BN_new();
	cryptInfo2.ctxPKC.param2 = BN_new();
	cryptInfo2.ctxPKC.param3 = BN_new();
	cryptInfo2.ctxPKC.param4 = BN_new();
	cryptInfo2.ctxPKC.param5 = BN_new();
	cryptInfo2.capabilityInfo = ( CAPABILITY_INFO * ) &capabilityInfo;

	/* Perform the test key exchange on a block of data */
	memset( &keyAgreeParams1, 0, sizeof( KEYAGREE_PARAMS ) );
	memset( &keyAgreeParams2, 0, sizeof( KEYAGREE_PARAMS ) );
#if 0	/* 18/10/99 Disabled until X9.42-compatible mechanism can be found */
	if( dhInitKey( &cryptInfo1, dhKey, 42 ) != CRYPT_OK ||
		dhInitKey( &cryptInfo2, dhKey, 43 ) != CRYPT_OK ||
		cryptStatusError( dhEncrypt( &cryptInfo1, ( BYTE * ) &keyAgreeParams1, 
									 CRYPT_USE_DEFAULT ) ) ||
		cryptStatusError( dhEncrypt( &cryptInfo2, ( BYTE * ) &keyAgreeParams2, 
									 CRYPT_USE_DEFAULT ) ) ||
		cryptStatusError( dhDecrypt( &cryptInfo1, ( BYTE * ) &keyAgreeParams2, 
									 CRYPT_USE_DEFAULT ) ) ||
		cryptStatusError( dhDecrypt( &cryptInfo2, ( BYTE * ) &keyAgreeParams1, 
									 CRYPT_USE_DEFAULT ) ) ||
		memcmp( keyAgreeParams1.wrappedKey, keyAgreeParams2.wrappedKey, 64 ) )
		status = CRYPT_ERROR;
#endif /* 0 */

	/* Clean up */
	cryptDestroyComponents( dhKey );
	BN_clear_free( cryptInfo1.ctxPKC.param1 );
	BN_clear_free( cryptInfo1.ctxPKC.param2 );
	BN_clear_free( cryptInfo1.ctxPKC.param3 );
	BN_clear_free( cryptInfo1.ctxPKC.param4 );
	BN_clear_free( cryptInfo1.ctxPKC.param5 );
	zeroise( &cryptInfo1, sizeof( CRYPT_INFO ) );
	BN_clear_free( cryptInfo2.ctxPKC.param1 );
	BN_clear_free( cryptInfo2.ctxPKC.param2 );
	BN_clear_free( cryptInfo2.ctxPKC.param3 );
	BN_clear_free( cryptInfo2.ctxPKC.param4 );
	BN_clear_free( cryptInfo2.ctxPKC.param5 );
	zeroise( &cryptInfo2, sizeof( CRYPT_INFO ) );
	free( dhKey );

	return( status );
	}

/****************************************************************************
*																			*
*							Init/Shutdown Routines							*
*																			*
****************************************************************************/

/* Not needed for the DH routines */

/****************************************************************************
*																			*
*						Diffie-Hellman Key Exchange Routines				*
*																			*
****************************************************************************/

/* Perform phase 1 of Diffie-Hellman ("export") */

int dhEncrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
	{
	KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
	BN_CTX *bnCTX;
	int status = CRYPT_OK;

	UNUSED( noBytes );

	/* Usually y is generated as a side-effect of the implicit generation of
	   the x value, so if y is already set we just return its value */
	if( !BN_is_zero( cryptInfo->ctxPKC.dlpParam_y ) )
		{
		keyAgreeParams->publicValueLen = \
							BN_bn2bin( cryptInfo->ctxPKC.dlpParam_y, 
									   keyAgreeParams->publicValue );
		return( CRYPT_OK );
		}

	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( cryptInfo->ctxPKC.dlpParam_y, cryptInfo->ctxPKC.dlpParam_g,
				cryptInfo->ctxPKC.dlpParam_x, cryptInfo->ctxPKC.dlpParam_p,
				bnCTX );
	keyAgreeParams->publicValueLen = \
							BN_bn2bin( cryptInfo->ctxPKC.dlpParam_y, 
									   keyAgreeParams->publicValue );
	BN_CTX_free( bnCTX );

	return( ( status == -1 ) ? CRYPT_ERROR_FAILED : status );
	}

/* Perform phase 2 of Diffie-Hellman ("import") */

int dhDecrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
	{
	KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
	BN_CTX *bnCTX;
	BIGNUM *z;
	const int length = bitsToBytes( cryptInfo->ctxPKC.keySizeBits );
	int i, status = CRYPT_OK;

	/* Make sure 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 );

	if( ( bnCTX = BN_CTX_new() ) == NULL )
		return( CRYPT_ERROR_MEMORY );

	/* The other parties 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, 
			   cryptInfo->ctxPKC.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 */
	z = BN_new();
	BN_mod_exp( z, cryptInfo->ctxPKC.dhParam_yPrime,
				cryptInfo->ctxPKC.dlpParam_x, cryptInfo->ctxPKC.dlpParam_p,
				bnCTX );
	keyAgreeParams->wrappedKeyLen = BN_bn2bin( z, keyAgreeParams->wrappedKey );
	BN_clear_free( z );

#if 0
	y = BN_new();
	BN_bin2bn( buffer, length, y );
	zeroise( buffer, length );	/* Clear buffer while data is in bignum */
	BN_mod_exp( y, y, cryptInfo->ctxPKC.dlpParam_x,
				cryptInfo->ctxPKC.dlpParam_p, bnCTX );
	length = BN_bn2bin( y, buffer );
	BN_clear_free( y );
#endif

	BN_CTX_free( bnCTX );

	return( ( status == -1 ) ? CRYPT_ERROR_FAILED : status );
	}

/****************************************************************************
*																			*
*						Diffie-Hellman Key Management Routines				*
*																			*
****************************************************************************/

/* Load DH public key components into an encryption context */

int dhInitKey( CRYPT_INFO *cryptInfo, const void *key, const int keyLength )
	{
	CRYPT_PKCINFO_DLP *dhKey = ( CRYPT_PKCINFO_DLP * ) key;
	int status;

	/* Load the key component from the external representation into the
	   internal BigNums unless we're doing an internal load */
	if( keyLength != sizeof( PKCINFO_LOADINTERNAL ) )
		{
		cryptInfo->ctxPKC.isPublicKey = dhKey->isPublicKey;

		BN_bin2bn( dhKey->p, bitsToBytes( dhKey->pLen ),
				   cryptInfo->ctxPKC.dlpParam_p );
		BN_bin2bn( dhKey->g, bitsToBytes( dhKey->gLen ),
				   cryptInfo->ctxPKC.dlpParam_g );
		BN_bin2bn( dhKey->q, bitsToBytes( dhKey->qLen ),
				   cryptInfo->ctxPKC.dlpParam_q );
		BN_bin2bn( dhKey->y, bitsToBytes( dhKey->yLen ),
				   cryptInfo->ctxPKC.dlpParam_y );
		if( !dhKey->isPublicKey )
			BN_bin2bn( dhKey->x, bitsToBytes( dhKey->xLen ),
					   cryptInfo->ctxPKC.dlpParam_x );
		else
			{
			/* If there's no x value present, generate one implicitly.  This
			   is needed because all DH keys are effectively private keys */
			status = generateDLPKey( cryptInfo, CRYPT_UNUSED, CRYPT_UNUSED, 
									 FALSE );
			if( cryptStatusError( status ) )
				return( status );
			}
		}

	/* Check the parameters and calculate the key ID */
	status = checkDLParams( cryptInfo, TRUE );
	if( cryptStatusError( status ) )
		return( status );
	cryptInfo->ctxPKC.keySizeBits = BN_num_bits( cryptInfo->ctxPKC.dlpParam_p );
	return( calculateKeyID( cryptInfo ) );
	}

/* Generate a Diffie-Hellman key into an encryption context */

int dhGenerateKey( CRYPT_INFO *cryptInfo, const int keySizeBits )
	{
	int status;

	status = generateDLPKey( cryptInfo, keySizeBits, CRYPT_USE_DEFAULT, 
							 TRUE );
	if( cryptStatusError( status ) )
		return( status );
	return( calculateKeyID( cryptInfo ) );
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -