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

📄 dev_attr.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*					cryptlib Crypto Device Attribute Routines				*
*						Copyright Peter Gutmann 1997-2007					*
*																			*
****************************************************************************/

#include "crypt.h"
#ifdef INC_ALL
  #include "capabil.h"
  #include "device.h"
#else
  #include "device/capabil.h"
  #include "device/device.h"
#endif /* Compiler-specific includes */

/* When we get random data from a device we run the (practical) FIPS 140 
   tests over the output to make sure that it's really random, at least as 
   far as the tests can tell us.  If the data fails the test we get more and 
   try again.  The following value defines how many times we retry before 
   giving up.  In test runs, a count of 2 failures is reached every ~50,000 
   iterations, 5 is never reached (in fact with 1M tests, 3 is never 
   reached) */

#define NO_ENTROPY_FAILURES	5

/****************************************************************************
*																			*
*								Utility Routines							*
*																			*
****************************************************************************/

/* Exit after setting extended error information */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitError( INOUT DEVICE_INFO *deviceInfoPtr,
					  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus,
					  IN_ENUM( CRYPT_ERRTYPE ) const CRYPT_ERRTYPE_TYPE errorType, 
					  IN_ERROR const int status )
	{
	assert( isWritePtr( deviceInfoPtr, sizeof( DEVICE_INFO ) ) );

	REQUIRES( isAttribute( errorLocus ) || \
			  isInternalAttribute( errorLocus ) );
	REQUIRES( errorType > CRYPT_ERRTYPE_NONE && \
			  errorType < CRYPT_ERRTYPE_LAST );
	REQUIRES( cryptStatusError( status ) );

	setErrorInfo( deviceInfoPtr, errorLocus, errorType );
	return( status );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorInited( INOUT DEVICE_INFO *deviceInfoPtr,
							IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
	{
	assert( isWritePtr( deviceInfoPtr, sizeof( DEVICE_INFO ) ) );

	REQUIRES( isAttribute( errorLocus ) || \
			  isInternalAttribute( errorLocus ) );

	return( exitError( deviceInfoPtr, errorLocus, CRYPT_ERRTYPE_ATTR_PRESENT,
					   CRYPT_ERROR_INITED ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorNotFound( INOUT DEVICE_INFO *deviceInfoPtr,
							  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
	{
	assert( isWritePtr( deviceInfoPtr, sizeof( DEVICE_INFO ) ) );

	REQUIRES( isAttribute( errorLocus ) || \
			  isInternalAttribute( errorLocus ) );

	return( exitError( deviceInfoPtr, errorLocus, CRYPT_ERRTYPE_ATTR_ABSENT,
					   CRYPT_ERROR_NOTFOUND ) );
	}

/****************************************************************************
*																			*
*							Read a Random-data Attribute					*
*																			*
****************************************************************************/

/* Get a random data block with FIPS 140 checking */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int getRandomChecked( INOUT DEVICE_INFO *deviceInfoPtr, 
							 OUT_BUFFER_FIXED( length ) void *data,
							 IN_LENGTH_SHORT const int length,
							 INOUT_OPT MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
	{
	int i;

	assert( isWritePtr( deviceInfoPtr, sizeof( DEVICE_INFO ) ) );
	assert( isWritePtr( data, length ) );
	assert( messageExtInfo == NULL || \
			( isWritePtr( messageExtInfo, \
						  sizeof( MESSAGE_FUNCTION_EXTINFO ) ) ) );

	REQUIRES( length > 0 && length < MAX_INTLENGTH_SHORT );

	/* Get random data from the device and check it using the FIPS 140 
	   tests.  If it's less than 64 bits then we let it pass since the 
	   sample size is too small to be useful, samples this small are only 
	   ever drawn from the generator for use as padding with crypto keys 
	   that are always >= 64 bits which will themselves have been checked
	   when they were read, so a problem with the generator will be 
	   detected even if we don't check small samples */
	for( i = 0; i < NO_ENTROPY_FAILURES; i++ )
		{
		int status;

		status = deviceInfoPtr->getRandomFunction( deviceInfoPtr, 
										data, length, messageExtInfo );
		if( cryptStatusOK( status ) && \
			( length < 8 || checkEntropy( data, length ) ) )
			return( CRYPT_OK );
		}

	/* We couldn't get anything that passed the FIPS 140 tests, we can't
	   go any further */
	zeroise( data, length );
	assert( DEBUG_WARN );
	return( CRYPT_ERROR_RANDOM );
	}

/* Get a random data block with no zero bytes, for PKCS #1 padding */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int getRandomNonzero( INOUT DEVICE_INFO *deviceInfoPtr, 
							 OUT_BUFFER_FIXED( length ) void *data,
							 IN_LENGTH_SHORT const int length,
							 INOUT_OPT MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
	{
	BYTE randomBuffer[ 128 + 8 ], *outBuffer = data;
	int count, iterationCount, status = CRYPT_OK;

	assert( isWritePtr( deviceInfoPtr, sizeof( DEVICE_INFO ) ) );
	assert( isWritePtr( data, length ) );
	assert( messageExtInfo == NULL || \
			( isWritePtr( messageExtInfo, \
						  sizeof( MESSAGE_FUNCTION_EXTINFO ) ) ) );

	REQUIRES( length > 0 && length < MAX_INTLENGTH_SHORT );

	/* The extraction of data is a little complex because we don't know how 
	   much data we'll need (as a rule of thumb it'll be size + ( size / 256 ) 
	   bytes, but in a worst-case situation we could need to draw out 
	   megabytes of data), so we copy out 128 bytes worth at a time (a 
	   typical value for a 1K bit key) and keep going until we've filled the 
	   output requirements */
	for( count = 0, iterationCount = 0;
		 count < length && iterationCount < FAILSAFE_ITERATIONS_LARGE;
		 iterationCount++ )
		{
		int i;

		/* Copy as much as we can from the randomness pool.  We don't allow 
		   the device to be unlocked during this process since we may need
		   it again for further reads */
		status = getRandomChecked( deviceInfoPtr, randomBuffer, 128, NULL );
		if( cryptStatusError( status ) )
			break;
		for( i = 0; count < length && i < 128; i++ )
			{
			if( randomBuffer[ i ] != 0 )
				outBuffer[ count++ ] = randomBuffer[ i ];
			}
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	FORALL( i, 0, length, \
			( ( BYTE * ) data )[ i ] != 0 );
	zeroise( randomBuffer, 128 );
	if( cryptStatusError( status ) )
		zeroise( data, length );
	return( status );
	}

/****************************************************************************
*																			*
*								Get Attributes								*
*																			*
****************************************************************************/

/* Get a numeric/boolean attribute */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
int getDeviceAttribute( INOUT DEVICE_INFO *deviceInfoPtr,
						OUT_INT_Z int *valuePtr, 
						IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
						INOUT MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
	{
	assert( isWritePtr( deviceInfoPtr, sizeof( DEVICE_INFO ) ) );
	assert( isWritePtr( valuePtr, sizeof( int ) ) );
	assert( isWritePtr( messageExtInfo, \
			sizeof( MESSAGE_FUNCTION_EXTINFO ) ) );

	REQUIRES( isAttribute( attribute ) || \
			  isInternalAttribute( attribute ) );

	switch( attribute )
		{
		case CRYPT_ATTRIBUTE_ERRORTYPE:
			*valuePtr = deviceInfoPtr->errorType;
			return( CRYPT_OK );

		case CRYPT_ATTRIBUTE_ERRORLOCUS:
			*valuePtr = deviceInfoPtr->errorLocus;
			return( CRYPT_OK );

		case CRYPT_ATTRIBUTE_INT_ERRORCODE:
			{
			ERROR_INFO *errorInfo;

			switch( deviceInfoPtr->type )
				{
				case CRYPT_DEVICE_PKCS11:
					errorInfo = &deviceInfoPtr->devicePKCS11->errorInfo;
					break;

				case CRYPT_DEVICE_FORTEZZA:
					errorInfo = &deviceInfoPtr->deviceFortezza->errorInfo;
					break;

				case CRYPT_DEVICE_CRYPTOAPI:
					errorInfo = &deviceInfoPtr->deviceCryptoAPI->errorInfo;
					break;

				default:
					*valuePtr = CRYPT_OK;
					
					return( CRYPT_OK );
				}

⌨️ 快捷键说明

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