dev_sys.c

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

C
1,584
字号

		/* Hash the data at position n...n + 19 in the circular pool using
		   the surrounding data extracted previously */
		digestPtr = randomInfo->randomPool + hashIndex;
		for( i = 0; i < SHA_DIGEST_LENGTH / 4; i++ )
			{
			digestLong[ i ] = mgetBLong( digestPtr );
			}
		SHA1Transform( digestLong, dataBuffer );
		digestPtr = randomInfo->randomPool + hashIndex;
		for( i = 0; i < SHA_DIGEST_LENGTH / 4; i++ )
			{
			mputBLong( digestPtr, digestLong[ i ] );
			}
		}
#else
	for( hashIndex = 0; hashIndex < RANDOMPOOL_SIZE; hashIndex += SHA_DIGEST_LENGTH )
		{
		int dataBufIndex, poolIndex;

		/* If we're at the start of the pool then the first block we hash is
		   at the end of the pool, otherwise it's the block immediately
		   preceding the current one */
		poolIndex = hashIndex ? hashIndex - SHA_DIGEST_LENGTH : \
					RANDOMPOOL_SIZE - SHA_DIGEST_LENGTH;

		/* Copy SHA_DIGEST_LENGTH bytes from position n - 19...n - 1 in the
		   circular pool into the hash data buffer */
		for( dataBufIndex = 0; dataBufIndex < SHA_DIGEST_LENGTH; dataBufIndex++ )
			dataBuffer[ dataBufIndex ] = randomInfo->randomPool[ poolIndex++ ];

		/* Postconditions for chaining data copy */
		POST( dataBufIndex == SHA_DIGEST_LENGTH );	/* Got 20 bytes... */
		POST( poolIndex >= SHA_DIGEST_LENGTH && \
				poolIndex <= RANDOMPOOL_SIZE );		/* ...from within pool... */
		POST( !hashIndex || \
				hashIndex == poolIndex );			/* ...before current pos.*/

		/* Copy SHA_CBLOCK - SHA_DIGEST_LENGTH bytes from position n + 20...
		   n + 64 from the circular pool into the hash data buffer */
		poolIndex = hashIndex + SHA_DIGEST_LENGTH;
		while( dataBufIndex < SHA_CBLOCK )
			dataBuffer[ dataBufIndex++ ] = \
						randomInfo->randomPool[ poolIndex++ % RANDOMPOOL_SIZE ];

		/* Postconditions for state data copy */
		POST( dataBufIndex == SHA_CBLOCK );			/* Got remain.44 bytes... */
		POST( poolIndex == hashIndex + SHA_CBLOCK );/* ...after current pos.*/

		/* Hash the data at position n...n + 19 in the circular pool using
		   the surrounding data extracted previously */
		SHA1Transform( ( LONG * ) ( randomInfo->randomPool + hashIndex ),
					   ( LONG * ) dataBuffer );
		}
#endif /* _BIG_WORDS */
	zeroise( dataBuffer, sizeof( dataBuffer ) );

	/* Postconditions for pool mixing */
	POST( hashIndex >= RANDOMPOOL_SIZE );		/* Entire pool was mixed */
	FORALL( i, 0, sizeof( dataBuffer ), dataBuffer[ i ] == 0 );
												/* Temp.storage was cleared */

	/* Increment the mix count and move the write position back to the start
	   of the pool */
	if( randomInfo->randomPoolMixes < RANDOMPOOL_MIXES )
		randomInfo->randomPoolMixes++;
	randomInfo->randomPoolPos = 0;

	/* Postconditions for status update */
	POST( randomInfo->randomPoolMixes >= 1 );	/* Mixed at least once */
	POST( randomInfo->randomPoolPos == 0 );		/* Back to start of pool */
	}

/****************************************************************************
*																			*
*								ANSI X9.17 Generator						*
*																			*
****************************************************************************/

/* The ANSI X9.17 Annex C generator has a number of problems (besides just
   being slow) including a tiny internal state, use of fixed keys, no
   entropy update, revealing the internal state to an attacker whenever it
   generates output, and a horrible vulnerability to state compromise,
   however for FIPS 140 compliance we need to use an approved generator (even
   though Annex C is informative rather than normative and contains only "an
   example of a pseudorandom key and IV generator" so that it could be argued
   that any X9.17 3DES-based generator is permitted), which is why this
   generator appears here.

   In order to minimise the potential for damage we employ it as a post-
   processor for the pool (since X9.17 produces a 1-1 mapping, it can never
   make the output any worse), using as our timestamp input the main RNG
   output.  This is perfectly valid since X9.17 requires the use of DT, "a
   date/time vector which is updated on each key generation", a requirement
   which is met by the fastPoll() which is performed before the main pool is
   mixed.  The cryptlib representation of the date and time vector is as a
   hash of assorted incidental data and the date and time.

   The fact that 99.9999% of the value of the generator is coming from the,
   uhh, timestamp is as coincidental as the side effect of the engine cooling
   fan in the Brabham ground effect cars */

/* A structure to hold the keyscheduled DES keys */

typedef struct {
	Key_schedule desKey1;			/* The first DES key */
	Key_schedule desKey2;			/* The second DES key */
	Key_schedule desKey3;			/* The third DES key */
	} DES3_KEY;

/* The DES block size and size of the scheduled keys */

#define DES_KEYSIZE		sizeof( Key_schedule )
#define DES3_KEYSIZE	sizeof( DES3_KEY )

/* The size of the X9.17 generator key and seed */

#define X917_KEYSIZE	16			/* 112 bits for EDE 3DES */
#define X917_SEEDSIZE	X917_POOLSIZE

/* Initialise and shut down the X9.17 generator */

int initX917( RANDOM_INFO *randomInfo )
	{
	return( krnlMemalloc( &randomInfo->x917Key, DES3_KEYSIZE ) );
	}

void endX917( RANDOM_INFO *randomInfo )
	{
	if( randomInfo->x917Key != NULL )
		krnlMemfree( &randomInfo->x917Key );
	}

/* Set the X9.17 generator key */

void setKeyX917( RANDOM_INFO *randomInfo, const BYTE *key, const BYTE *seed )
	{
	DES3_KEY *des3Key = ( DES3_KEY * ) randomInfo->x917Key;

	/* Schedule the DES keys.  Rather than performing the third key schedule,
	   we just copy the first scheduled key into the third one */
	des_set_odd_parity( ( C_Block * ) key );
	des_set_odd_parity( ( C_Block * ) ( key + bitsToBytes( 64 ) ) );
	key_sched( ( des_cblock * ) key, des3Key->desKey1 );
	key_sched( ( des_cblock * ) ( key + bitsToBytes( 64 ) ),
			   des3Key->desKey2 );
	memcpy( des3Key->desKey3, des3Key->desKey1, DES_KEYSIZE );

	/* Set up the seed value V(0) */
	memcpy( randomInfo->x917Pool, seed, X917_POOLSIZE );

	/* We've initialised the generator and reset the cryptovariables, we're
	   ready to go */
	randomInfo->x917Inited = TRUE;
	randomInfo->x917Count = 0;
	}

/* Run the X9.17 generator over a block of data */

void generateX917( RANDOM_INFO *randomInfo, BYTE *data, const int length )
	{
	DES3_KEY *des3Key = ( DES3_KEY * ) randomInfo->x917Key;
	BYTE buffer[ X917_POOLSIZE ], *dataPtr = data;
	int i;

	/* Precondition: We're not asking for more data than the maximum needed
	   in any cryptlib operation (which in this case is the size of a
	   maximum-length PKC key), the generator has been initialised, and the
	   cryptovariables aren't past their use by date */
	PRE( length >= 1 && length <= CRYPT_MAX_PKCSIZE );
	PRE( randomInfo->x917Inited = TRUE );
	PRE( randomInfo->x917Count >= 0 && \
		 randomInfo->x917Count < X917_MAX_CYCLES );

	for( i = 0; i < length; i += X917_POOLSIZE )
		{
		const int bytesToCopy = min( length - i, X917_POOLSIZE );
		int j;
		ORIGINAL_INT_VAR( x917Count, randomInfo->x917Count );

		/* Precondition: We're processing from 1...X917_POOLSIZE bytes of
		   data */
		PRE( bytesToCopy >= 1 && bytesToCopy <= X917_POOLSIZE );

		/* Copy in as much timestamp (+ other assorted data) as we can from
		   the input */
		memcpy( buffer, dataPtr, bytesToCopy );

		/* Inner precondition: The local buffer contains the input data */
		FORALL( k, 0, bytesToCopy, buffer[ k ] == data[ i + k ] );

		/* out = Enc( Enc( time ) ^ V(n) ); */
		des_ecb3_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
						  des3Key->desKey1, des3Key->desKey2,
						  des3Key->desKey3, DES_ENCRYPT );
		for( j = 0; j < X917_POOLSIZE; j++ )
			randomInfo->x917Pool[ j ] ^= buffer[ j ];
		des_ecb3_encrypt( ( C_Block * ) randomInfo->x917Pool,
						  ( C_Block * ) randomInfo->x917Pool,
						  des3Key->desKey1, des3Key->desKey2,
						  des3Key->desKey3, DES_ENCRYPT );
		memcpy( dataPtr, randomInfo->x917Pool, bytesToCopy );

		/* Postcondition: The internal state has been copied to the output
		   (ick) */
		FORALL( k, 0, bytesToCopy, \
				data[ i + k ] == randomInfo->x917Pool[ k ] );

		/* V(n+1) = Enc( Enc( time ) ^ out ); */
		for( j = 0; j < X917_POOLSIZE; j++ )
			randomInfo->x917Pool[ j ] ^= buffer[ j ];
		des_ecb3_encrypt( ( C_Block * ) randomInfo->x917Pool,
						  ( C_Block * ) randomInfo->x917Pool,
						  des3Key->desKey1, des3Key->desKey2,
						  des3Key->desKey3, DES_ENCRYPT );

		/* Move on to the next block */
		dataPtr += bytesToCopy;
		randomInfo->x917Count++;

		/* Postcondition: We've processed one more block of data */
		POST( dataPtr == data + i + bytesToCopy );
		POST( randomInfo->x917Count == ORIGINAL_VALUE_VAR( x917Count ) + 1 );
		}

	/* Postcondition: We processed all of the data */
	POST( dataPtr == data + length );

	zeroise( buffer, X917_POOLSIZE );

	/* Postcondition: Nulla vestigia retrorsum */
	FORALL( i, 0, X917_POOLSIZE,
			buffer[ i ] == 0 );
	}

/****************************************************************************
*																			*
*					Device Init/Shutdown/Device Control Routines			*
*																			*
****************************************************************************/

/* Mechanisms supported by the system device.  These are sorted in order of
   frequency of use in order to make lookups a bit faster */

int derivePKCS5( void *dummy, MECHANISM_DERIVE_INFO *mechanismInfo );
int deriveSSL( void *dummy, MECHANISM_DERIVE_INFO *mechanismInfo );
int deriveTLS( void *dummy, MECHANISM_DERIVE_INFO *mechanismInfo );
int deriveCMP( void *dummy, MECHANISM_DERIVE_INFO *mechanismInfo );
int derivePGP( void *dummy, MECHANISM_DERIVE_INFO *mechanismInfo );
int signPKCS1( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int sigcheckPKCS1( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int exportPKCS1( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int exportPKCS1PGP( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int importPKCS1( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int importPKCS1PGP( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int exportCMS( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int importCMS( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int exportPrivateKey( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );
int importPrivateKey( void *dummy, MECHANISM_WRAP_INFO *mechanismInfo );

static const MECHANISM_FUNCTION_INFO mechanismFunctions[] = {
	{ RESOURCE_MESSAGE_DEV_EXPORT, MECHANISM_PKCS1,
								( MECHANISM_FUNCTION ) exportPKCS1 },
	{ RESOURCE_MESSAGE_DEV_IMPORT, MECHANISM_PKCS1,
								( MECHANISM_FUNCTION ) importPKCS1 },
	{ RESOURCE_MESSAGE_DEV_EXPORT, MECHANISM_PKCS1_RAW,
								( MECHANISM_FUNCTION ) exportPKCS1 },
	{ RESOURCE_MESSAGE_DEV_IMPORT, MECHANISM_PKCS1_RAW,
								( MECHANISM_FUNCTION ) importPKCS1 },
	{ RESOURCE_MESSAGE_DEV_SIGN, MECHANISM_PKCS1,
								( MECHANISM_FUNCTION ) signPKCS1 },
	{ RESOURCE_MESSAGE_DEV_SIGCHECK, MECHANISM_PKCS1,
								( MECHANISM_FUNCTION ) sigcheckPKCS1 },
	{ RESOURCE_MESSAGE_DEV_EXPORT, MECHANISM_CMS,
								( MECHANISM_FUNCTION ) exportCMS },
	{ RESOURCE_MESSAGE_DEV_IMPORT, MECHANISM_CMS,
								( MECHANISM_FUNCTION ) importCMS },
	{ RESOURCE_MESSAGE_DEV_DERIVE, MECHANISM_PKCS5,
								( MECHANISM_FUNCTION ) derivePKCS5 },
	{ RESOURCE_MESSAGE_DEV_DERIVE, MECHANISM_SSL,
								( MECHANISM_FUNCTION ) deriveSSL },
	{ RESOURCE_MESSAGE_DEV_DERIVE, MECHANISM_TLS,
								( MECHANISM_FUNCTION ) deriveTLS },
	{ RESOURCE_MESSAGE_DEV_DERIVE, MECHANISM_CMP,
								( MECHANISM_FUNCTION ) deriveCMP },
	{ RESOURCE_MESSAGE_DEV_DERIVE, MECHANISM_PGP,
								( MECHANISM_FUNCTION ) derivePGP },
	{ RESOURCE_MESSAGE_DEV_EXPORT, MECHANISM_PRIVATEKEYWRAP,
								( MECHANISM_FUNCTION ) exportPrivateKey },
	{ RESOURCE_MESSAGE_DEV_IMPORT, MECHANISM_PRIVATEKEYWRAP,
								( MECHANISM_FUNCTION ) importPrivateKey },
	{ RESOURCE_MESSAGE_DEV_EXPORT, MECHANISM_PKCS1_PGP,
								( MECHANISM_FUNCTION ) exportPKCS1PGP },
	{ RESOURCE_MESSAGE_DEV_IMPORT, MECHANISM_PKCS1_PGP,
								( MECHANISM_FUNCTION ) importPKCS1PGP },
	{ RESOURCE_MESSAGE_NONE, MECHANISM_NONE, NULL }
	};

/* Object creation functions supported by the system device.  These are
   sorted in order of frequency of use in order to make lookups a bit
   faster */

int createContext( MESSAGE_CREATEOBJECT_INFO *createInfo,
				   const void *auxDataPtr, const int auxValue );
int createCertificate( MESSAGE_CREATEOBJECT_INFO *createInfo,
					   const void *auxDataPtr, const int auxValue );
int createEnvelope( MESSAGE_CREATEOBJECT_INFO *createInfo,
					const void *auxDataPtr, const int auxValue );
int createKeyset( MESSAGE_CREATEOBJECT_INFO *createInfo,
				  const void *auxDataPtr, const int auxValue );
int createDevice( MESSAGE_CREATEOBJECT_INFO *createInfo,
				  const void *auxDataPtr, const int auxValue );
int createSession( MESSAGE_CREATEOBJECT_INFO *createInfo,
				   const void *auxDataPtr, const int auxValue );
int createUser( MESSAGE_CREATEOBJECT_INFO *createInfo,
				const void *auxDataPtr, const int auxValue );

⌨️ 快捷键说明

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