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

📄 dev_sys.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
static const CREATEOBJECT_FUNCTION_INFO createObjectFunctions[] = {
	{ OBJECT_TYPE_CONTEXT, createContext },
	{ OBJECT_TYPE_CERTIFICATE, createCertificate },
	{ OBJECT_TYPE_ENVELOPE, createEnvelope },
	{ OBJECT_TYPE_KEYSET, createKeyset },
	{ OBJECT_TYPE_DEVICE, createDevice },
	{ OBJECT_TYPE_SESSION, createSession },
	{ OBJECT_TYPE_USER, createUser },
	{ OBJECT_TYPE_NONE, NULL }
	};

/* Initialise and shut down the system device */

static void shutdownFunction( DEVICE_INFO *deviceInfo )
	{
	/* Call any special-case shutdown functions */
	endRandomPolling();
	endX917( deviceInfo->randomInfo );

	/* Delete the random data pool */
	if( deviceInfo->randomInfo != NULL )
		krnlMemfree( ( void ** ) &deviceInfo->randomInfo );
	}

static int initFunction( DEVICE_INFO *deviceInfo, const char *name,
						 const int nameLength )
	{
	STATIC_FN void initCapabilities( void );
	int status;

	UNUSED( name );

	/* Set up the random data pool */
	if( ( status = krnlMemalloc( ( void ** ) &deviceInfo->randomInfo,
								 sizeof( RANDOM_INFO ) ) ) != CRYPT_OK )
		return( status );
	initRandomPool( deviceInfo->randomInfo );
	if( ( status = initX917( deviceInfo->randomInfo ) ) != CRYPT_OK )
		{
		krnlMemfree( ( void ** ) &deviceInfo->randomInfo );
		return( status );
		}
	initRandomPolling();

	/* Set up the capability information for this device and mark it as
	   active */
	initCapabilities();
	deviceInfo->flags = DEVICE_ACTIVE | DEVICE_LOGGEDIN;

	return( CRYPT_OK );
	}

/* Handle device control functions */

static int controlFunction( DEVICE_INFO *deviceInfo,
							const CRYPT_ATTRIBUTE_TYPE type,
							const void *data1, const int data1Length,
							const void *data2, const int data2Length )
	{
	RANDOM_INFO *randomInfo = deviceInfo->randomInfo;
	BYTE *buffer = ( BYTE * ) data1;
	int count = data1Length;

	assert( type == CRYPT_IATTRIBUTE_RANDOM || \
			type == CRYPT_IATTRIBUTE_RANDOM_QUALITY || \
			type == CRYPT_IATTRIBUTE_SELFTEST );

	/* Handle random data management */
	if( type == CRYPT_IATTRIBUTE_RANDOM )
		{
		/* Mix the incoming data into the pool.  This operation is resistant
		   to chosen- and known-input attacks because the pool contents are
		   unknown to an attacker, so XOR'ing in known data won't help them.
		   In an attacker could determine pool contents by observing the
		   generator output (which is defeated by the postprocessing), we'd
		   have to perform an extra input mixing operation to defeat these
		   attacks */
		while( count-- )
			{
			if( randomInfo->randomPoolPos > RANDOMPOOL_SIZE - 1 )
				mixRandomPool( randomInfo );
			randomInfo->randomPool[ randomInfo->randomPoolPos++ ] ^= *buffer++;
			}

		return( CRYPT_OK );
		}
	if( type == CRYPT_IATTRIBUTE_RANDOM_QUALITY )
		{
		if( randomInfo->randomQuality < 100 )
			randomInfo->randomQuality += data1Length;
		return( CRYPT_OK );
		}

	/* Handle algorithm self-test */
	if( type == CRYPT_IATTRIBUTE_SELFTEST )
		{
		const CAPABILITY_INFO *capabilityInfoPtr = deviceInfo->capabilityInfo;

		while( capabilityInfoPtr != NULL )
			{
			const CRYPT_ALGO cryptAlgo = capabilityInfoPtr->cryptAlgo;
			int status;

			assert( capabilityInfoPtr->selfTestFunction != NULL );

			/* Perform the self-test for this algorithm type and skip to the
			   next algorithm */
			status = capabilityInfoPtr->selfTestFunction();
			if( cryptStatusError( status ) )
				return( status );
			while( capabilityInfoPtr != NULL && \
				   capabilityInfoPtr->cryptAlgo == cryptAlgo )
				capabilityInfoPtr = capabilityInfoPtr->next;
			}

		return( CRYPT_OK );
		}

	/* Anything else isn't handled */
	return( CRYPT_ARGERROR_VALUE );
	}

/****************************************************************************
*																			*
*						 	Misc.Device Interface Routines					*
*																			*
****************************************************************************/

/* Get a block of random data from the randomness pool in such a way that
   compromise of the data doesn't compromise the pool, and vice versa.  This
   is done by performing the (one-way) pool mixing operation on the pool, and
   on a transformed version of the pool which becomes the key.  The
   transformed version of the pool from which the key data will be drawn is
   then further processed by running each 64-bit block through the X9.17
   generator.  As an additional precaution the key data is folded in half to
   ensure that not even a hashed or encrypted form of the previous contents
   is available.  No pool data ever leaves the pool.

   This function performs a more paranoid version of the FIPS 140 continuous
   test on both the main pool contents and the X9.17 generator output which
   will detect stuck-at faults and short cycles in the output.  In addition
   the higher-level message handler applies the FIPS 140 statistical tests
   to the output and will retry the get if the output fails the tests (this
   is performed at the higher level because it's then applied to all
   randomness sources used by cryptlib, not just the built-in one).

   Since the pool output is folded to mask the output, the output from each
   round of mixing is only half the pool size as defined below */

#define RANDOM_OUTPUTSIZE	( RANDOMPOOL_SIZE / 2 )

static int getRandomFunction( DEVICE_INFO *deviceInfo, void *buffer,
							  const int length )
	{
	RANDOM_INFO *randomInfo = deviceInfo->randomInfo;
	RANDOM_INFO exportedRandomInfo;
	BYTE *bufPtr = buffer;
	int count;

	/* Clear the return value and make sure we fail the FIPS 140 tests on
	   the output if there's a problem */
	zeroise( buffer, length );

	/* 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 */
	PRE( length >= 1 && length <= CRYPT_MAX_PKCSIZE );

	/* Perform a failsafe check to make sure there's data available, this
	   should only ever be called once per app because after the first
	   blocking poll the programmer of the calling app will make sure there's
	   a slow poll done earlier on */
	if( randomInfo->randomQuality < 100 )
		slowPoll();

	/* Make sure any background randomness-gathering process has finished.
	   Since the background poll will be injecting new data into the device,
	   we have to unlock it to avoid deadlock */
	unlockResource( deviceInfo );
	waitforRandomCompletion();
	lockResource( deviceInfo );

	/* If we still can't get any random information, let the user know */
	if( randomInfo->randomQuality < 100 )
		return( CRYPT_ERROR_RANDOM );

	/* If the process has forked, we need to restart the generator output
	   process, but we can't determine this until after we've already
	   produced the output.  If we do need to restart, we do it from this
	   point */
restartPoint:

	/* Keep producing RANDOMPOOL_OUTPUTSIZE bytes of output until the request
	   is satisfied */
	for( count = 0; count < length; count += RANDOM_OUTPUTSIZE )
		{
		LONG sample, x917Sample;
		const int outputBytes = min( length - count, RANDOM_OUTPUTSIZE );
		int noRandomRetries, i;
		ORIGINAL_PTR( bufPtr );

		/* Precondition for output quantity: Either we're on the last output
		   block or we're producing the maximum-size output quantity, and
		   we're never trying to use more than half the pool contents */
		PRE( length - count < RANDOM_OUTPUTSIZE || \
			 outputBytes == RANDOM_OUTPUTSIZE );
		PRE( outputBytes <= RANDOMPOOL_SIZE / 2 );

		/* Prepare to get data from the randomness pool.  Before we do this,
		   we perform a final quick poll of the system to get any last bit of
		   entropy, and mix the entire pool.  If the pool hasn't been
		   sufficiently mixed, we iterate until we've reached the minimum mix
		   count */
		do
			{
			fastPoll();
			mixRandomPool( randomInfo );
			randomInfo->randomPoolMixes++;
			}
		while( randomInfo->randomPoolMixes < RANDOMPOOL_MIXES );

		/* If the X9.17 generator cryptovariables haven't been initialised
		   yet or have reached their use-by date, set the generator key and
		   seed from the pool contents, then mix the pool and crank the
		   generator twice to obscure the data which was used */
		if( !randomInfo->x917Inited || \
			randomInfo->x917Count >= X917_MAX_CYCLES )
			{
			setKeyX917( randomInfo, randomInfo->randomPool,
						randomInfo->randomPool + X917_KEYSIZE );
			mixRandomPool( randomInfo );
			generateX917( randomInfo, randomInfo->randomPool,
						  RANDOMPOOL_ALLOCSIZE );
			mixRandomPool( randomInfo );
			generateX917( randomInfo, randomInfo->randomPool,
						  RANDOMPOOL_ALLOCSIZE );
			}

		/* Precondition for drawing output from the generator: The pool is
		   sufficiently mixed, there's enough entropy present, and the X9.17
		   postprocessor is ready for use */
		PRE( randomInfo->randomPoolMixes >= RANDOMPOOL_MIXES );
		PRE( randomInfo->randomQuality >= 100 );
		PRE( randomInfo->x917Inited );

		for( noRandomRetries = 0; noRandomRetries < RANDOMPOOL_RETRIES;
			 noRandomRetries++ )
			{
			const BYTE *samplePtr = randomInfo->randomPool;
			const BYTE *x917SamplePtr = exportedRandomInfo.randomPool;
			BOOLEAN repeatedOutput = FALSE;

			/* Initialise the copy of the random pool being used to generate
			   the key and copy the main pool information across,
			   transforming it as we go by flipping all the bits */
			initRandomPool( &exportedRandomInfo );
			for( i = 0; i < RANDOMPOOL_ALLOCSIZE; i++ )
				exportedRandomInfo.randomPool[ i ] = \
									randomInfo->randomPool[ i ] ^ 0xFF;

			/* Postcondition for the bit-flipping: The two pools differ, and
			   the difference is in the flipped bits */
			POST( memcmp( randomInfo->randomPool,
						  exportedRandomInfo.randomPool,
						  RANDOMPOOL_ALLOCSIZE ) );
			FORALL( i, 0, RANDOMPOOL_ALLOCSIZE, \
					randomInfo->randomPool[ i ] == \
							( exportedRandomInfo.randomPool[ i ] ^ 0xFF ) );

			/* Mix the original and key pools so that neither can be
			   recovered from the other */
			mixRandomPool( randomInfo );
			mixRandomPool( &exportedRandomInfo );

			/* Postcondition for the mixing: The two pools differ, and the
			   difference is more than just the bit flipping (this has a
			   1e-12 chance of a false positive and even that's only in the
			   debug version) */
			POST( memcmp( randomInfo->randomPool,
						  exportedRandomInfo.randomPool,
						  RANDOMPOOL_ALLOCSIZE ) );
			POST( randomInfo->randomPool[ 0 ] != \
				  ( exportedRandomInfo.randomPool[ 0 ] ^ 0xFF ) ||
				  randomInfo->randomPool[ 8 ] != \
				  ( exportedRandomInfo.randomPool[ 8 ] ^ 0xFF ) ||
				  randomInfo->randomPool[ 16 ] != \
				  ( exportedRandomInfo.randomPool[ 16 ] ^ 0xFF ) ||
				  randomInfo->randomPool[ 24 ] != \
				  ( exportedRandomInfo.randomPool[ 24 ] ^ 0xFF ) ||
				  randomInfo->randomPool[ 32 ] != \
				  ( exportedRandomInfo.randomPool[ 32 ] ^ 0xFF ) );

			/* Precondition for sampling the output: It's a sample from the
			   start of the pool */
			PRE( samplePtr == randomInfo->randomPool );
			PRE( x917SamplePtr == exportedRandomInfo.randomPool );

			/* Check for stuck-at faults by comparing a short sample from the
			   current output with samples from the previous
			   RANDOMPOOL_SAMPLES outputs */
			sample = mgetLong( samplePtr );
			for( i = 0; i < RANDOMPOOL_SAMPLES; i++ )
				if( randomInfo->prevOutput[ i ] == sample )
					{
					repeatedOutput = TRUE;
					break;
					}
			if( repeatedOutput )
				continue;	/* We're repeating previous output, try again */
			repeatedOutput = FALSE;

			/* Process the exported pool with the X9.17 generator */
			generateX917( randomInfo, exportedRandomInfo.randomPool,
						  RANDOMPOOL_ALLOCSIZE );

			/* Check for stuck-at faults in the X9.17 generator by comparing
			   a short sample from the current output with samples from the

⌨️ 快捷键说明

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