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

📄 cryptctx.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
			{
			case MESSAGE_CTX_ENCRYPT:
				status = encryptData( contextInfoPtr, messageDataPtr, 
									  messageValue );
				assert( cryptStatusOK( status ) );
				break;

			case MESSAGE_CTX_DECRYPT:
				assert( contextInfoPtr->decryptFunction != NULL );

				assert( contextInfoPtr->type == CONTEXT_PKC || \
						( isStreamCipher( capabilityInfo->cryptAlgo ) || \
						  !needsIV( contextInfoPtr->ctxConv->mode ) ||
						  ( contextInfoPtr->flags & CONTEXT_IV_SET ) ) );
				status = contextInfoPtr->decryptFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				if( contextInfoPtr->type == CONTEXT_PKC )
					clearTempBignums( contextInfoPtr->ctxPKC );
				assert( cryptStatusOK( status ) );
				break;

			case MESSAGE_CTX_SIGN:
				assert( capabilityInfo->signFunction != NULL );

				status = capabilityInfo->signFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				clearTempBignums( contextInfoPtr->ctxPKC );
				assert( cryptStatusOK( status ) );
				break;

			case MESSAGE_CTX_SIGCHECK:
				assert( capabilityInfo->sigCheckFunction != NULL );
				status = capabilityInfo->sigCheckFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				clearTempBignums( contextInfoPtr->ctxPKC );
				break;

			case MESSAGE_CTX_HASH:
				assert( capabilityInfo->encryptFunction != NULL );
				assert( ( contextInfoPtr->type == CONTEXT_HASH && \
						  contextInfoPtr->ctxHash->hashInfo == \
								contextInfoPtr->storage + sizeof( HASH_INFO ) ) || \
						( contextInfoPtr->type == CONTEXT_MAC && \
						  contextInfoPtr->ctxMAC->macInfo == \
								contextInfoPtr->storage + sizeof( MAC_INFO ) ) );

				/* If we've already completed the hashing/MACing, we can't
				   continue */
				if( contextInfoPtr->flags & CONTEXT_HASH_DONE )
					return( CRYPT_ERROR_COMPLETE );

				status = capabilityInfo->encryptFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				if( messageValue > 0 )
					/* Usually the MAC initialisation happens when we load 
					   the key, but if we've deleted the MAC value to process 
					   another piece of data it'll happen on-demand, so we 
					   have to set the flag here */
					contextInfoPtr->flags |= CONTEXT_HASH_INITED;
				else
					/* Usually a hash of zero bytes is used to wrap up an
					   ongoing hash operation, however it can also be the 
					   only operation if a zero-byte string is being hashed.
					   To handle this we have to set the inited flag as well
					   as the done flag */
					contextInfoPtr->flags |= CONTEXT_HASH_DONE | \
											 CONTEXT_HASH_INITED;
				assert( cryptStatusOK( status ) );
				break;

			default:
				assert( NOTREACHED );
			}
		return( status );
		}

	/* Process messages that compare object properties or clone the object */
	if( message == MESSAGE_COMPARE )
		{
		const RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;

		assert( messageValue == MESSAGE_COMPARE_HASH || \
				messageValue == MESSAGE_COMPARE_KEYID || \
				messageValue == MESSAGE_COMPARE_KEYID_PGP || \
				messageValue == MESSAGE_COMPARE_KEYID_OPENPGP );

		switch( messageValue )
			{
			case MESSAGE_COMPARE_HASH:
				/* If it's a hash or MAC context, compare the hash value */
				if( !( contextInfoPtr->flags & CONTEXT_HASH_DONE ) )
					return( CRYPT_ERROR_INCOMPLETE );
				if( contextInfoPtr->type == CONTEXT_HASH && \
					msgData->length == capabilityInfo->blockSize && \
					!memcmp( msgData->data, contextInfoPtr->ctxHash->hash,
							 msgData->length ) )
					return( CRYPT_OK );
				if( contextInfoPtr->type == CONTEXT_MAC && \
					msgData->length == capabilityInfo->blockSize && \
					!memcmp( msgData->data, contextInfoPtr->ctxMAC->mac,
							 msgData->length ) )
					return( CRYPT_OK );
				break;

			case MESSAGE_COMPARE_KEYID:
				/* If it's a PKC context, compare the key ID */
				if( contextInfoPtr->type == CONTEXT_PKC && \
					msgData->length == KEYID_SIZE && \
					!memcmp( msgData->data, contextInfoPtr->ctxPKC->keyID,
							 KEYID_SIZE ) )
					return( CRYPT_OK );
				break;

			case MESSAGE_COMPARE_KEYID_PGP:
				/* If it's a PKC context, compare the PGP key ID */
				if( contextInfoPtr->type == CONTEXT_PKC && \
					msgData->length == PGP_KEYID_SIZE && \
					!memcmp( msgData->data, contextInfoPtr->ctxPKC->pgpKeyID,
							 PGP_KEYID_SIZE ) )
					return( CRYPT_OK );
				break;

			case MESSAGE_COMPARE_KEYID_OPENPGP:
				/* If it's a PKC context, compare the OpenPGP key ID */
				if( contextInfoPtr->type == CONTEXT_PKC && \
					contextInfoPtr->ctxPKC->openPgpKeyIDSet && \
					msgData->length == PGP_KEYID_SIZE && \
					!memcmp( msgData->data, contextInfoPtr->ctxPKC->openPgpKeyID,
							 PGP_KEYID_SIZE ) )
					return( CRYPT_OK );
				break;

			default:
				assert( NOTREACHED );
			}

		/* The comparison failed */
		return( CRYPT_ERROR );
		}

	/* Process messages that check a context */
	if( message == MESSAGE_CHECK )
		return( checkContext( contextInfoPtr, messageValue ) );

	/* Process internal notification messages */
	if( message == MESSAGE_CHANGENOTIFY )
		{
		switch( messageValue )
			{
			case MESSAGE_CHANGENOTIFY_STATUS:
				/* If the context is still busy and we're trying to reset 
				   its status from CRYPT_ERROR_TIMEOUT back to CRYPT_OK, set 
				   the abort flag to indicate that the operation which is 
				   keeping it busy should be cancelled, and return an error 
				   so that the busy status is maintained until the context 
				   has processed the abort */
				if( !( contextInfoPtr->flags & CONTEXT_ASYNC_DONE ) )
					{
					contextInfoPtr->flags |= CONTEXT_ASYNC_ABORT;
					return( CRYPT_ERROR_TIMEOUT );
					}

				/* The context finished whatever it was doing, we're back to 
				   normal */
				break;

			case MESSAGE_CHANGENOTIFY_STATE:
				/* State-change reflected down from the controlling cert 
				   object, this doesn't affect us */
				break;

			case MESSAGE_CHANGENOTIFY_OBJHANDLE:
				assert( contextInfoPtr->type == CONTEXT_CONV || \
						contextInfoPtr->type == CONTEXT_HASH || \
						contextInfoPtr->type == CONTEXT_MAC );
				assert( contextInfoPtr->objectHandle != \
						*( ( int * ) messageDataPtr ) );
				assert( contextInfoPtr->ctxConv != \
						( CONV_INFO * ) contextInfoPtr->storage );

				/* We've been cloned, update the object handle and internal 
				   state pointers */
				contextInfoPtr->objectHandle = *( ( int * ) messageDataPtr );
				initContextStorage( contextInfoPtr, 
						( contextInfoPtr->type == CONTEXT_CONV ) ? \
							sizeof( CONV_INFO ) : \
						( contextInfoPtr->type == CONTEXT_HASH ) ? \
							sizeof( HASH_INFO ) : sizeof( MAC_INFO ) );
				break;

			case MESSAGE_CHANGENOTIFY_OWNERHANDLE:
				/* The second stage of a cloning, update the owner handle */
				contextInfoPtr->ownerHandle = *( ( int * ) messageDataPtr );
				break;

			default:
				assert( NOTREACHED );
				return( CRYPT_ERROR );	/* Get rid of compiler warning */
			}

		return( CRYPT_OK );
		}

	/* Process object-specific messages */
	if( message == MESSAGE_CTX_GENKEY )
		{
		assert( contextInfoPtr->type == CONTEXT_CONV || \
				contextInfoPtr->type == CONTEXT_MAC ||
				contextInfoPtr->type == CONTEXT_PKC );
		assert( needsKey( contextInfoPtr ) );

		/* If it's a private key context, we need to have a key label set
		   before we can continue */
		if( contextInfoPtr->type == CONTEXT_PKC && \
			contextInfoPtr->labelSize <= 0 )
			{
			setErrorInfo( contextInfoPtr, CRYPT_CTXINFO_LABEL,
						  CRYPT_ERRTYPE_ATTR_ABSENT );
			return( CRYPT_ERROR_NOTINITED );
			}

		/* Generate a new key into the context */
		status = contextInfoPtr->generateKeyFunction( contextInfoPtr,
													  messageValue );
		if( cryptStatusOK( status ) )
			/* There's now a key loaded */
			contextInfoPtr->flags |= CONTEXT_KEY_SET | CONTEXT_EPHEMERAL;
		else
			/* If the status is OK_SPECIAL, it's an async keygen that has
			   begun, but that hasn't resulted in the context containing a 
			   key yet */
			if( status == OK_SPECIAL )
				status = CRYPT_OK;
		if( cryptStatusOK( status ) )
			{
			static const int actionFlags = \
				MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL ) | \
				MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, ACTION_PERM_ALL ) | \
				MK_ACTION_PERM( MESSAGE_CTX_SIGN, ACTION_PERM_ALL ) | \
				MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL ) | \
				MK_ACTION_PERM( MESSAGE_CTX_HASH, ACTION_PERM_ALL );

			/* There's a key loaded, disable further key generation.  The
			   kernel won't allow a keygen anyway once the object is in the 
			   high state, but taking this additional step can't hurt */
			status = krnlSendMessage( contextInfoPtr->objectHandle,
									  IMESSAGE_SETATTRIBUTE, 
									  ( void * ) &actionFlags,
									  CRYPT_IATTRIBUTE_ACTIONPERMS );
			}
		return( status );
		}
	if( message == MESSAGE_CTX_GENIV )
		{
		RESOURCE_DATA msgData;
		BYTE buffer[ CRYPT_MAX_IVSIZE ];

		assert( contextInfoPtr->type == CONTEXT_CONV );

		/* If it's not a conventional encryption context, or a mode that
		   doesn't use an IV, the generate IV operation is meaningless */
		if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
			isStreamCipher ( capabilityInfo->cryptAlgo ) )
			return( CRYPT_ERROR_NOTAVAIL );

		/* Generate a new IV and load it */
		setMessageData( &msgData, buffer, CRYPT_MAX_IVSIZE );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
		if( cryptStatusOK( status ) )
			status = capabilityInfo->initKeyParamsFunction( contextInfoPtr,
									buffer, CRYPT_USE_DEFAULT, CRYPT_MODE_NONE );
		return( status );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

/* Create an encryption context based on an encryption capability template.
   This is a common function called by devices to create a context once
   they've got the appropriate capability template */

int createContextFromCapability( CRYPT_CONTEXT *cryptContext,
								 const CRYPT_USER cryptOwner,
								 const CAPABILITY_INFO *capabilityInfoPtr,
								 const int objectFlags )
	{
	const CRYPT_ALGO_TYPE cryptAlgo = capabilityInfoPtr->cryptAlgo;
	const CONTEXT_TYPE contextType = \
		( ( cryptAlgo >= CRYPT_ALGO_FIRST_CONVENTIONAL ) && \
		  ( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL ) ) ? CONTEXT_CONV : \
		( ( cryptAlgo >= CRYPT_ALGO_FIRST_PKC ) && \
		  ( cryptAlgo <= CRYPT_ALGO_LAST_PKC ) ) ? CONTEXT_PKC : \
		( ( cryptAlgo >= CRYPT_ALGO_FIRST_HASH ) && \
		  ( cryptAlgo <= CRYPT_ALGO_LAST_HASH ) ) ? CONTEXT_HASH : CONTEXT_MAC;
	CONTEXT_INFO *contextInfoPtr;
	BOOLEAN useSideChannelProtection;
	const int createFlags = objectFlags | \
							( needsSecureMemory( contextType ) ? \
							CREATEOBJECT_FLAG_SECUREMALLOC : 0 );
	int actionFlags = 0, actionPerms = ACTION_PERM_ALL;
	int storageSize, stateStorageSize = 0, subType;
	int initStatus = CRYPT_OK, status;

	assert( cryptAlgo > CRYPT_ALGO_NONE && cryptAlgo < CRYPT_ALGO_LAST_MAC );

	/* Clear the return values */
	*cryptContext = CRYPT_ERROR;

	/* Get general config information */
	status = krnlSendMessage( cryptOwner, IMESSAGE_GETATTRIBUTE,
							  &useSideChannelProtection,
							  CRYPT_OPTION_MISC_SIDECHANNELPROTECTION );
	if( cryptStatusError( status ) )
		return( status );

	/* Set up subtype-specific information */
	switch( contextType )
		{
		case CONTEXT_CONV:
			subType = SUBTYPE_CTX_CONV;
			storageSize = sizeof( CONV_INFO );
			stateStorageSize = \
				capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_STATESIZE,
													NULL, 0 );
			if( capabilityInfoPtr->encryptFunction != NULL || \
				capabilityInfoPtr->encryptCBCFunction != NULL || \
				capabilityInfoPtr->encryptCFBFunction != NULL || \
				capabilityInfoPtr->encryptOFBFunction != NULL )
				actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT,
											   ACTION_PERM_ALL );
			if( capabilityInfoPtr->decryptFunction != NULL || \
				capabilityInfoPtr->decryptCBCFunction != NULL || \
				capabilityInfoPtr->decryptCFBFunction != NULL || \
				capabilityInfoPtr->decryptOFBFunction != NULL )
				actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_DECRYPT,
											   ACTION_PERM_ALL );
			actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_GENKEY, ACTION_PERM_ALL );
			break;

		case CONTEXT_PKC:
			subType = SUBTYPE_CTX_PKC;
			storageSize = sizeof( PKC_INFO );
			if( isDlpAlgo( cryptAlgo ) )
				/* The DLP-based PKC's have somewhat specialised usage
				   requirements so we don't allow direct access by users */
				actionPerms = ACTION_PERM_NONE_EXTERNAL;
			if( capabilityInfoPtr->encryptFunction != NULL )
				actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT,
											   actionPerms );
			if( capabilityInfoPtr->decryptFunction != NULL )
				actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_DECRYPT,
											   actionPerms );
			if( capabilityInfoPtr->signFunction != NULL )
				actionFlags |= MK_ACTION_PERM( M

⌨️ 快捷键说明

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