lib_kea.c

来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 582 行 · 第 1/2 页

C
582
字号
                                    0xa9, 0xc5, 0xfa, 0xf6, 0xbe, 0xa1, 0xeb,
                                    0x6e, 0xf1, 0xde, 0x0d, 0x3f, 0x48, 0xc8,
                                    0x6b, 0xe2, 0x40, 0x8f, 0x80, 0x7e, 0x65,
                                    0x86, 0x22, 0xb9, 0xf3, 0x87, 0xe0, 0xf5,
                                    0x0f, 0xa5, 0x86, 0x8b, 0xf5, 0x29, 0xff,
                                    0x00, 0x8d, 0x3a, 0xd5, 0x5e, 0x9c, 0x43,
                                    0x66, 0xba, 0xd4, 0xae, 0x41, 0x90, 0xce,
                                    0xbc, 0x3a, 0xe5, 0x6f, 0x34, 0xbf, 0x70,
                                    0xb6, 0x3c, 0xa0, 0x21, 0xdd, 0x56, 0x30,
                                    0x05, 0xdb, 0xbc, 0x7e, 0x62, 0xbb, 0xcc,
                                    0xc9, 0x12, 0x7a, 0x36, 0x03, 0xbf, 0x00,
                                    0xbe, 0x8f, 0xce, 0x9b, 0xf4, 0x6b, 0xf5,
                                    0x38, 0x86, 0xc4, 0xa7, 0x61, 0x4b, 0x43,
                                    0xad, 0xfe, 0x72, 0x82, 0xef, 0xe4, 0xf9,
                                    0xc1, 0x46, 0xb7, 0x1e, 0x9f, 0x89, 0xd6,
                                    0x2b, 0xd3, 0xc7, 0xed, 0x7d, 0x12, 0x77,
                                    0x19, 0xeb, 0xf0, 0xe0, 0xf8, 0x79, 0xe0,
                                    0xd0, 0xd9 };

/*
  1024-bit w

  sum of shared DH keys

  */
const BYTE FAR_BSS wTestKEA[] = { 0x95, 0xb8, 0xc6, 0xe7, 0x76, 0xe0, 0xca,
                                  0xe7, 0x34, 0xf0, 0x99, 0xcc, 0xfe, 0x2b,
                                  0x90, 0xfd, 0x55, 0x0b, 0x44, 0x71, 0x2e,
                                  0x77, 0xc5, 0x5b, 0x54, 0x17, 0x50, 0x31,
                                  0x8e, 0xa6, 0x74, 0x81, 0xe1, 0xe4, 0x26,
                                  0xf9, 0x73, 0xc6, 0x6f, 0x78, 0x1e, 0x79,
                                  0x35, 0xca, 0x28, 0x9b, 0xe8, 0x0a, 0x41,
                                  0x1b, 0x7b, 0x8a, 0x15, 0xec, 0x8e, 0x41,
                                  0x07, 0xdb, 0xe4, 0xde, 0x60, 0xcf, 0x14,
                                  0xdf, 0x39, 0x50, 0x9c, 0x10, 0x15, 0x9f,
                                  0xbe, 0x69, 0xdf, 0x44, 0x2d, 0x03, 0x49,
                                  0x64, 0xcc, 0x47, 0xbe, 0x31, 0x63, 0xf6,
                                  0x0b, 0x55, 0x48, 0x1c, 0xb5, 0xe0, 0x2a,
                                  0x67, 0x9a, 0x07, 0xed, 0x85, 0x19, 0x81,
                                  0xa0, 0xd2, 0x87, 0x2c, 0xd0, 0xe0, 0x74,
                                  0x51, 0xa6, 0x9f, 0x69, 0x52, 0x0c, 0xac,
                                  0x13, 0x42, 0x38, 0x27, 0xd2, 0xed, 0x32,
                                  0x52, 0x13, 0xb3, 0x78, 0x97, 0x82, 0xca,
                                  0xf9, 0xa1 };

/*
  v1 = {0x95, 0xb8, 0xc6, 0xe7, 0x76, 0xe0, 0xca, 0xe7, 0x34, 0xf0,
  0xXX, 0xXX}

  v2 = {0x99, 0xcc, 0xfe, 0x2b, 0x90, 0xfd, 0x55, 0x0b, 0x44, 0x71,
  0xXX, 0xXX}

  v1 XOR pad = {0xe7, 0x49, 0x6e, 0x99, 0xe4, 0x62, 0x8b, 0x7f, 0x9f,
  0xfb, 0xXX, 0xXX}

  */

/*
  80-bit Skipjack key for user A

  */
const BYTE FAR_BSS sjkeyTestKEA[] = { 0x74, 0x08, 0x39, 0xde, 0xe8, 0x33,
                                      0xad, 0xd4, 0x6b, 0x41 };

/*
  Results for user B:
  (see above)

  */

/* int keaInitKey( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes ); */
/* int keaEncrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes ); */
int keaDecrypt( CRYPT_INFO *cryptInfo, BYTE *bufferT, BYTE *bufferU,
                BYTE *bufferSJK );

int keaSelfTest( void )
	{
	CRYPT_INFO cryptInfo1, cryptInfo2, cryptInfo3, cryptInfo4;
	CRYPT_PKCINFO_DLP *dhKey;
	CAPABILITY_INFO capabilityInfo = { CRYPT_ALGO_KEA, CRYPT_MODE_PKC, 
									0, NULL, NULL, 64, 128, 1024, 0, 
									NULL, NULL, NULL, NULL, NULL, NULL, NULL,
									NULL, NULL, NULL, NULL, CRYPT_ERROR };
	BYTE buffer1[ 128 ], buffer2[ 128 ], buffer3[ 128 ], buffer4[ 128 ];
	BYTE buffer5[ 10 ];
	BIGNUM *yr, *yrone, *p, *q;
	BN_CTX *bnCTX;
	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, primeTestKEA, 1024 );
	cryptSetComponent( dhKey->g, baseTestKEA, 1024 );

	/* certified public key Y of each user */
	memset( &cryptInfo1, 0, sizeof( CRYPT_INFO ) );
	cryptInfo1.ctxPKC.param1 = BN_new();
	cryptInfo1.ctxPKC.param2 = BN_new();
	cryptInfo1.ctxPKC.param3 = 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.capabilityInfo = &capabilityInfo;

	/* ephemeral public key R of each user */
	memset( &cryptInfo3, 0, sizeof( CRYPT_INFO ) );
	cryptInfo3.ctxPKC.param1 = BN_new();
	cryptInfo3.ctxPKC.param2 = BN_new();
	cryptInfo3.ctxPKC.param3 = BN_new();
	cryptInfo3.capabilityInfo = &capabilityInfo;
	memset( &cryptInfo4, 0, sizeof( CRYPT_INFO ) );
	cryptInfo4.ctxPKC.param1 = BN_new();
	cryptInfo4.ctxPKC.param2 = BN_new();
	cryptInfo4.ctxPKC.param3 = BN_new();
	cryptInfo4.capabilityInfo = &capabilityInfo;

	/* Load long term private keys x of each user */
	memset( buffer1, 0, 128 );
	memcpy( buffer1, xaTestKEA, 20 );
	memset( buffer2, 0, 128 );
	memcpy( buffer2, xbTestKEA, 20 );

	/* Exchange of certificates for DH public keys Y (step a.) */
	if( dhInitKey( &cryptInfo1 ) != CRYPT_OK ||
	    dhInitKey( &cryptInfo2 ) != CRYPT_OK ||
		cryptStatusError( dhEncrypt( &cryptInfo1, buffer1, 128 ) ) ||
		cryptStatusError( dhEncrypt( &cryptInfo2, buffer2, 128 ) ) )
		status = CRYPT_ERROR;

	/* Certificate validation would go here (step b.)
		see draft-ietf-pkix-ipki-kea-02.txt */

	/* Load ephemeral private keys r of each user */
	memset( buffer3, 0, 128 );
	memcpy( buffer3, raTestKEA, 20 );
	memset( buffer4, 0, 128 );
	memcpy( buffer4, rbTestKEA, 20 );

	/* Exchange of ephemeral public keys R (step c.) */
	if( dhInitKey( &cryptInfo3 ) != CRYPT_OK ||
		dhInitKey( &cryptInfo4 ) != CRYPT_OK ||
		cryptStatusError( dhEncrypt( &cryptInfo3, buffer3, 128 ) ) ||
		cryptStatusError( dhEncrypt( &cryptInfo4, buffer4, 128 ) ) )
		status = CRYPT_ERROR;

	/* Check that received public keys are in order q subgroup(s)
	   (step d.) */
	yr = BN_new();
	yrone = BN_new();
	q = BN_new();
	p = BN_new();
	BN_bin2bn( ( BYTE * ) subgroupOrderTestKEA, 20, q );
	BN_bin2bn( dhKey->p, 128, p );
	BN_bin2bn( buffer1, 128, yr );
	BN_mod_exp( yrone, yr, q, p, bnCTX );
	if( BN_cmp( yrone, BN_value_one() ) != 0 )
		status = CRYPT_ERROR;
	BN_bin2bn( buffer2, 128, yr );
	BN_mod_exp( yrone, yr, q, p, bnCTX );
	if( BN_cmp( yrone, BN_value_one() ) != 0 )
		status = CRYPT_ERROR;
	BN_bin2bn( buffer3, 128, yr );
	BN_mod_exp( yrone, yr, q, p, bnCTX );
	if( BN_cmp( yrone, BN_value_one() ) != 0 )
		status = CRYPT_ERROR;
	BN_bin2bn( buffer4, 128, yr );
	BN_mod_exp( yrone, yr, q, p, bnCTX );
	if( BN_cmp( yrone, BN_value_one() ) != 0 )
		status = CRYPT_ERROR;
	BN_clear_free( yr );
	BN_clear_free( yrone );
	BN_clear_free( q );

	/* Computation of shared keys tab, tba, uba, uab (steps e.,f.)
	   We also check that tab=tba and uba=uab */
	if( cryptStatusError( dhDecrypt( &cryptInfo3, buffer2,
									 CRYPT_USE_DEFAULT ) ) ||
		cryptStatusError( dhDecrypt( &cryptInfo2, buffer3,
									 CRYPT_USE_DEFAULT ) ) ||
		cryptStatusError( dhDecrypt( &cryptInfo4, buffer1,
									 CRYPT_USE_DEFAULT ) ) ||
		cryptStatusError( dhDecrypt( &cryptInfo1, buffer4,
									 CRYPT_USE_DEFAULT ) ) ||
		memcmp( buffer2, buffer3, 128 ) ||
		memcmp( buffer1, buffer4, 128 ) )
		status = CRYPT_ERROR;

	/* derive the Skipjack key from t and u (steps g. to i.) */
	if( keaDecrypt( &cryptInfo1, buffer2, buffer1, buffer5 ) )
		status = CRYPT_ERROR;

	/* did we end up with the correct Skipjack key ? */
	if( memcmp( buffer5, sjkeyTestKEA, 10 ) )
		status = CRYPT_ERROR;

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

	return( status );
	}

/* steps g. through i. of KEA
   receive shared DH keys t and u in 2 buffers,
   compute Skipjack key and store in the 3rd buffer */

int keaDecrypt( CRYPT_INFO *cryptInfo, BYTE *bufferT, BYTE *bufferU,
				BYTE *bufferSJK )
	{
	BIGNUM *bnT, *bnU;
	BN_CTX *bnCTX;
	const BYTE pad[] = { 0x72, 0xF1, 0xA8, 0x7E, 0x92, 0x82, 0x41, 0x98, 0xAB, 0x0B };
	int status = 0;

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

	/* step g. -- Move t and u from the buffers into bignums */
	bnT = BN_new();
	bnU = BN_new();
	BN_bin2bn( bufferT, 128, bnT );
	BN_bin2bn( bufferU, 128, bnU );
	zeroise( bufferT, 128 );	/* Clear buffer while data is in bignum */
	zeroise( bufferU, 128 );	/* ditto */

	/* set w = t + u mod p; we overwrite t with w */
	if( BN_add( bnT, bnT, bnU ) != 0 )
		status = CRYPT_ERROR_FAILED;
	BN_clear_free( bnU );
	if( BN_mod( bnT, bnT, cryptInfo->ctxPKC.dlpParam_p, bnCTX ) != 0 )
		status = CRYPT_ERROR_FAILED;

	/* abort if w == 0 */
	if( BN_is_zero( bnT ) )
		status = CRYPT_ERROR_FAILED;

	/* step h. -- Extract v_1 and v_2 from w;
		v_1 is the 80 MSB's of w and
		v_2 is the 80 next-most-significant bits of w, each big-endian */
	BN_rshift( bnT, bnT, (1024 - (80 + 80)) );
	BN_bn2bin( bnT, bufferT );
	BN_clear_free( bnT );

	/* XOR the pad into v_1 */
	bufferT[ 0 ] ^= pad[ 0 ];
	bufferT[ 1 ] ^= pad[ 1 ];
	bufferT[ 2 ] ^= pad[ 2 ];
	bufferT[ 3 ] ^= pad[ 3 ];
	bufferT[ 4 ] ^= pad[ 4 ];
	bufferT[ 5 ] ^= pad[ 5 ];
	bufferT[ 6 ] ^= pad[ 6 ];
	bufferT[ 7 ] ^= pad[ 7 ];
	bufferT[ 8 ] ^= pad[ 8 ];
	bufferT[ 9 ] ^= pad[ 9 ];

	/* Skipjack-encrypt the 64 MSB's of v_2 with v_1 XOR pad */
	skipjackEncrypt( (bufferT + 10), bufferT );

	/* XOR the 16 MSB's of the resulting ciphertext into the 16 LSB's of v_2 */
	bufferT[ 18 ] ^= bufferT[ 10 ];
	bufferT[ 19 ] ^= bufferT[ 11 ];

	/* Skipjack-encrypt the previous ciphertext with the same key as before;
	   the 80 bits starting at bufferT + 10 then contain the KEA Key */
	skipjackEncrypt( (bufferT + 10), bufferT );
	memcpy( bufferSJK, (bufferT + 10), 10 );
	zeroise( bufferT, 128 );

	return( status );
	}

⌨️ 快捷键说明

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