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

📄 keyload.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
#endif /* USE_FIPS140 */

/* Load a key into a CONTEXT_INFO structure.  These functions are called by 
   the various higher-level functions that move a key into a context */

static int loadKeyConvFunction( CONTEXT_INFO *contextInfoPtr, 
								const void *key, const int keyLength )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;

	assert( contextInfoPtr->type == CONTEXT_CONV );

	/* If we don't need an IV, record it as being set */
	if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
		isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
		contextInfoPtr->flags |= CONTEXT_IV_SET;

	/* Perform the key setup */
	return( capabilityInfoPtr->initKeyFunction( contextInfoPtr, key, 
												keyLength ) );
	}

static int loadKeyPKCFunction( CONTEXT_INFO *contextInfoPtr, 
							   const void *key, const int keyLength )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	int status;

	assert( contextInfoPtr->type == CONTEXT_PKC );

#ifndef USE_FIPS140
	/* If we're loading from externally-supplied parameters, make sure that 
	   the parameters make sense */
	if( key != NULL )
		{
		status = checkPKCparams( capabilityInfoPtr->cryptAlgo, key );
		if( cryptStatusError( status ) )
			return( status );
		contextInfoPtr->flags |= 0x10;	/* Tell lib_kg to check params too */
		}
#endif /* USE_FIPS140 */

	/* Load the keying info */
	status = capabilityInfoPtr->initKeyFunction( contextInfoPtr, key, 
												 keyLength );
	clearTempBignums( contextInfoPtr->ctxPKC );
	return( status );
	}

static int loadKeyMacFunction( CONTEXT_INFO *contextInfoPtr, 
							   const void *key, const int keyLength )
	{
	assert( contextInfoPtr->type == CONTEXT_MAC );

	return( contextInfoPtr->capabilityInfo->initKeyFunction( contextInfoPtr, 
															 key, keyLength ) );
	}

/****************************************************************************
*																			*
*							Key Generation Functions						*
*																			*
****************************************************************************/

/* Threaded key generation for those OSes that support threads */

#ifdef USE_THREADS

void threadedKeygen( const THREAD_FUNCTION_PARAMS *threadParams )
	{
	CONTEXT_INFO *contextInfoPtr = threadParams->ptrParam;
	int busyStatus = CRYPT_ERROR_TIMEOUT;

	/* Mark the object as busy, perform the keygen, and set it back to non-
	   busy */
	krnlSendMessage( contextInfoPtr->objectHandle, IMESSAGE_SETATTRIBUTE,
					 &busyStatus, CRYPT_IATTRIBUTE_STATUS );
	contextInfoPtr->asyncStatus = \
		contextInfoPtr->capabilityInfo->generateKeyFunction( contextInfoPtr,
										contextInfoPtr->ctxPKC->keySizeBits );
	if( cryptStatusOK( contextInfoPtr->asyncStatus ) )
		contextInfoPtr->flags |= CONTEXT_KEY_SET;	/* There's now a key loaded */
	contextInfoPtr->flags &= ~CONTEXT_ASYNC_ABORT;
	contextInfoPtr->flags |= CONTEXT_ASYNC_DONE;
	clearTempBignums( contextInfoPtr->ctxPKC );
	krnlSendMessage( contextInfoPtr->objectHandle, IMESSAGE_SETATTRIBUTE,
					 MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
	}
#endif /* Threaded keygen function */

/* Generate a key into a CONTEXT_INFO structure.  This low-level function is
   called by both the normal and async keygen functions, which set the keygen
   up as required (the only time there's any real difference is for PKC
   keygen) */

static int generateKeyConvFunction( CONTEXT_INFO *contextInfoPtr, 
									const BOOLEAN isAsync )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	RESOURCE_DATA msgData;
	int keyLength, status;

	assert( contextInfoPtr->type == CONTEXT_CONV );

	/* Determine the best keysize for this algorithm */
	keyLength = capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE, 
									contextInfoPtr,
									contextInfoPtr->ctxConv->userKeyLength );
	if( cryptStatusError( keyLength ) )
		return( keyLength );

	/* If the context is implemented in a crypto device, it may have the
	   capability to generate the key itself so if there's a keygen function
	   present we call this to generate the key directly into the context
	   rather than generating it ourselves and loading it in.  Note that to
	   export this key we'll need to use an exporting context which is also
	   located in the device, since we can't access it externally */
	if( capabilityInfoPtr->generateKeyFunction != NULL )
		return( capabilityInfoPtr->generateKeyFunction( contextInfoPtr,
												bytesToBits( keyLength ) ) );

	/* Generate a random session key into the context.  We always use
	   synchronous key generation even if the user has called the async
	   function because it's quick enough that it doesn't make any
	   difference.  In addition we load the random data directly into the
	   pagelocked encryption context and pass that in as the key buffer -
	   loadKey() won't copy the data if src == dest */
	setMessageData( &msgData, contextInfoPtr->ctxConv->userKey, keyLength );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S, 
							  &msgData, CRYPT_IATTRIBUTE_RANDOM );
	if( cryptStatusError( status ) )
		return( status );
	return( contextInfoPtr->loadKeyFunction( contextInfoPtr, 
								contextInfoPtr->ctxConv->userKey, keyLength ) );
	}

static int generateKeyPKCFunction( CONTEXT_INFO *contextInfoPtr, 
								   const BOOLEAN isAsync )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	int keyLength, status;

	assert( contextInfoPtr->type == CONTEXT_PKC );

	/* Set up supplementary key information */
	contextInfoPtr->ctxPKC->pgpCreationTime = getApproxTime();

	/* Determine the best keysize for this algorithm */
	keyLength = capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE, 
						contextInfoPtr,
						bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits ) );
	if( cryptStatusError( keyLength ) )
		return( keyLength );

	/* Generate the key into the context.  If it's an async keygen and the OS
	   supports this, we set the context state for the async keygen and spawn 
	   the thread/process for the task */
#ifdef USE_THREADS
	if( isAsync )
		{
		contextInfoPtr->flags &= ~( CONTEXT_ASYNC_ABORT | CONTEXT_ASYNC_DONE );
		contextInfoPtr->asyncStatus = CRYPT_OK;
		contextInfoPtr->ctxPKC->keySizeBits = bytesToBits( keyLength );
		initThreadParams( &contextInfoPtr->ctxPKC->threadParams, 
						  contextInfoPtr, 0 );
		status = krnlDispatchThread( threadedKeygen, 
									 &contextInfoPtr->ctxPKC->threadParams, 
									 SEMAPHORE_NONE );
		if( cryptStatusOK( status ) )
			return( OK_SPECIAL );

		/* The async keygen failed, fall back to a standard keygen */
		}
#endif /* OSes with threads */
	status = capabilityInfoPtr->generateKeyFunction( contextInfoPtr,
												bytesToBits( keyLength ) );
	clearTempBignums( contextInfoPtr->ctxPKC );
	return( status );
	}

static int generateKeyMacFunction( CONTEXT_INFO *contextInfoPtr, 
								   const BOOLEAN isAsync )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	RESOURCE_DATA msgData;
	int keyLength, status;

	assert( contextInfoPtr->type == CONTEXT_MAC );

	/* Determine the best keysize for this algorithm */
	keyLength = capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE, 
									contextInfoPtr,
									contextInfoPtr->ctxMAC->userKeyLength );
	if( cryptStatusError( keyLength ) )
		return( keyLength );

	/* If the context is implemented in a crypto device, it may have the
	   capability to generate the key itself so if there's a keygen function
	   present we call this to generate the key directly into the context
	   rather than generating it ourselves and loading it in.  Note that to
	   export this key we'll need to use an exporting context which is also
	   located in the device, since we can't access it externally */
	if( capabilityInfoPtr->generateKeyFunction != NULL )
		return( capabilityInfoPtr->generateKeyFunction( contextInfoPtr,
												bytesToBits( keyLength ) ) );

	/* Generate a random session key into the context.  We always use
	   synchronous key generation even if the user has called the async
	   function because it's quick enough that it doesn't make any
	   difference.  In addition we load the random data directly into the
	   pagelocked encryption context and pass that in as the key buffer -
	   loadKey() won't copy the data if src == dest */
	setMessageData( &msgData, contextInfoPtr->ctxMAC->userKey, keyLength );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S, 
							  &msgData, CRYPT_IATTRIBUTE_RANDOM );
	if( cryptStatusError( status ) )
		return( status );
	return( contextInfoPtr->loadKeyFunction( contextInfoPtr, 
								contextInfoPtr->ctxMAC->userKey, keyLength ) );
	}

/****************************************************************************
*																			*
*							Context Access Routines							*
*																			*
****************************************************************************/

void initKeyHandling( CONTEXT_INFO *contextInfoPtr )
	{
	/* Set the access method pointers */
	switch( contextInfoPtr->type )
		{
		case CONTEXT_CONV:
			contextInfoPtr->loadKeyFunction = loadKeyConvFunction;
			contextInfoPtr->generateKeyFunction = generateKeyConvFunction;
			break;

		case CONTEXT_PKC:
			contextInfoPtr->loadKeyFunction = loadKeyPKCFunction;
			contextInfoPtr->generateKeyFunction = generateKeyPKCFunction;
			break;

		case CONTEXT_MAC:
			contextInfoPtr->loadKeyFunction = loadKeyMacFunction;
			contextInfoPtr->generateKeyFunction = generateKeyMacFunction;
			break;

		default:
			assert( NOTREACHED );
		}
	}

⌨️ 快捷键说明

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