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

📄 cryptctx.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
	REQUIRES( message > MESSAGE_NONE && message < MESSAGE_LAST );
	REQUIRES( messageValue >= 0 && messageValue < MAX_INTLENGTH );

	/* Process destroy object messages */
	if( message == MESSAGE_DESTROY )
		{
		const CONTEXT_TYPE contextType = contextInfoPtr->type;

		REQUIRES( messageDataPtr == NULL && messageValue == 0 );

		/* Perform any algorithm-specific shutdown */
		if( capabilityInfo->endFunction != NULL )
			capabilityInfo->endFunction( contextInfoPtr );

		/* Perform context-type-specific cleanup */
		if( contextType == CONTEXT_PKC )
			freeContextBignums( contextInfoPtr->ctxPKC,
								contextInfoPtr->flags );

		return( CRYPT_OK );
		}

	/* Process attribute get/set/delete messages */
	if( isAttributeMessage( message ) )
		{
		REQUIRES( message == MESSAGE_GETATTRIBUTE || \
				  message == MESSAGE_GETATTRIBUTE_S || \
				  message == MESSAGE_SETATTRIBUTE || \
				  message == MESSAGE_SETATTRIBUTE_S || \
				  message == MESSAGE_DELETEATTRIBUTE );
		REQUIRES( isAttribute( messageValue ) || \
				  isInternalAttribute( messageValue ) );

		if( message == MESSAGE_GETATTRIBUTE )
			return( getContextAttribute( contextInfoPtr, 
										 ( int * ) messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_GETATTRIBUTE_S )
			return( getContextAttributeS( contextInfoPtr, 
										  ( MESSAGE_DATA * ) messageDataPtr,
										  messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE )
			{
			/* CRYPT_IATTRIBUTE_INITIALISED is purely a notification message 
			   with no parameters so we don't pass it down to the attribute-
			   handling code */
			if( messageValue == CRYPT_IATTRIBUTE_INITIALISED )
				return( CRYPT_OK );

			return( setContextAttribute( contextInfoPtr, 
										 *( ( int * ) messageDataPtr ),
										 messageValue ) );
			}
		if( message == MESSAGE_SETATTRIBUTE_S )
			{
			const MESSAGE_DATA *msgData = ( MESSAGE_DATA * ) messageDataPtr;

			return( setContextAttributeS( contextInfoPtr, msgData->data, 
										  msgData->length, messageValue ) );
			}
		if( message == MESSAGE_DELETEATTRIBUTE )
			return( deleteContextAttribute( contextInfoPtr, messageValue ) );

		retIntError();
		}

	/* Process action messages */
	if( isActionMessage( message ) )
		{
		assert( ( message == MESSAGE_CTX_HASH && \
				  ( messageValue == 0 || \
					isReadPtr( messageDataPtr, messageValue ) ) ) || \
				isWritePtr( messageDataPtr, messageValue ) );

		switch( message )
			{
			case MESSAGE_CTX_ENCRYPT:
				if( contextInfoPtr->type == CONTEXT_PKC )
					status = encryptDataPKC( contextInfoPtr, messageDataPtr, 
											 messageValue );
				else
					status = encryptDataConv( contextInfoPtr, messageDataPtr, 
											  messageValue );
				assert( cryptStatusOK( status ) );
				break;

			case MESSAGE_CTX_DECRYPT:
				REQUIRES( !needsKey( contextInfoPtr ) );
				REQUIRES( contextInfoPtr->type == CONTEXT_PKC || \
						  ( isStreamCipher( capabilityInfo->cryptAlgo ) || \
						    !needsIV( contextInfoPtr->ctxConv->mode ) ||
						    ( contextInfoPtr->flags & CONTEXT_FLAG_IV_SET ) ) );

				status = contextInfoPtr->decryptFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				if( contextInfoPtr->type == CONTEXT_PKC && \
					!( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
					clearTempBignums( contextInfoPtr->ctxPKC );
				assert( cryptStatusOK( status ) );
				break;

			case MESSAGE_CTX_SIGN:
				status = capabilityInfo->signFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
					clearTempBignums( contextInfoPtr->ctxPKC );
				assert( cryptStatusOK( status ) );
				break;

			case MESSAGE_CTX_SIGCHECK:
				status = capabilityInfo->sigCheckFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
					clearTempBignums( contextInfoPtr->ctxPKC );
				break;

			case MESSAGE_CTX_HASH:
				REQUIRES( ( 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_FLAG_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_FLAG_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_FLAG_HASH_DONE | \
											 CONTEXT_FLAG_HASH_INITED;
					}
				assert( cryptStatusOK( status ) );
				break;

			default:
				retIntError();
			}
		return( status );
		}

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

		assert( isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) );

		REQUIRES( 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_FLAG_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->pgp2KeyID,
							 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:
				retIntError();
			}

		/* 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_STATE:
				/* State-change reflected down from the controlling certificate 
				   object, this doesn't affect us */
				break;

			case MESSAGE_CHANGENOTIFY_OBJHANDLE:
				{
				const CRYPT_HANDLE iCryptHandle = *( ( int * ) messageDataPtr );

				REQUIRES( contextInfoPtr->type == CONTEXT_CONV || \
						  contextInfoPtr->type == CONTEXT_HASH || \
						  contextInfoPtr->type == CONTEXT_MAC );
				REQUIRES( contextInfoPtr->objectHandle != iCryptHandle );
				REQUIRES( contextInfoPtr->ctxConv != \
						  ( CONV_INFO * ) contextInfoPtr->storage );

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

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

			default:
				retIntError();
			}

		return( CRYPT_OK );
		}

	/* Process object-specific messages */
	if( message == MESSAGE_CTX_GENKEY )
		{
		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 );

		REQUIRES( contextInfoPtr->type == CONTEXT_CONV || \
				  contextInfoPtr->type == CONTEXT_MAC ||
				  contextInfoPtr->type == CONTEXT_PKC );
		REQUIRES( needsKey( contextInfoPtr ) );

		/* If it's a private key context or a persistent context we need to 
		   have a key label set before we can continue */
		if( ( ( contextInfoPtr->type == CONTEXT_PKC ) || \
			  ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ) && \
			contextInfoPtr->labelSize <= 0 )
			return( CRYPT_ERROR_NOTINITED );

		/* Generate a new key into the context */
		status = contextInfoPtr->generateKeyFunction( contextInfoPtr );
		if( cryptStatusError( status ) )
			return( status );

		/* There's now a key loaded, remember this and 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 */
		contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
		return( krnlSendMessage( contextInfoPtr->objectHandle,
								 IMESSAGE_SETATTRIBUTE, 
								 ( void * ) &actionFlags, 
								 CRYPT_IATTRIBUTE_ACTIONPERMS ) );
		}
	if( message == MESSAGE_CTX_GENIV )
		{
		MESSAGE_DATA msgData;
		BYTE iv[ CRYPT_MAX_IVSIZE + 8 ];
		const int ivSize = capabilityInfo->blockSize;

		REQUIRES( contextInfoPtr->type == CONTEXT_CONV );

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

⌨️ 快捷键说明

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