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 + -
显示快捷键?