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

📄 cryptctx.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
			do
				{
				THREAD_SLEEP( 250 );	/* Wait 1/4s */
				krnlSendMessage( cryptContext, IMESSAGE_GETATTRIBUTE,
								 &status, CRYPT_IATTRIBUTE_STATUS );
				}
			while( status & OBJECT_FLAG_BUSY );

			getCheckInternalResource( cryptContext, contextInfoPtr, OBJECT_TYPE_CONTEXT );
			}
#endif /* 0 */

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

		/* Perform context-type-specific cleanup */
		if( contextType == CONTEXT_PKC )
			{
			PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;

			BN_clear_free( &pkcInfo->param1 );
			BN_clear_free( &pkcInfo->param2 );
			BN_clear_free( &pkcInfo->param3 );
			BN_clear_free( &pkcInfo->param4 );
			BN_clear_free( &pkcInfo->param5 );
			BN_clear_free( &pkcInfo->param6 );
			BN_clear_free( &pkcInfo->param7 );
			BN_clear_free( &pkcInfo->param8 );
			if( contextInfoPtr->flags & CONTEXT_SIDECHANNELPROTECTION )
				{
				BN_clear_free( &pkcInfo->blind1 );
				BN_clear_free( &pkcInfo->blind2 );
				}
			BN_clear_free( &pkcInfo->tmp1 );
			BN_clear_free( &pkcInfo->tmp2 );
			BN_clear_free( &pkcInfo->tmp3 );
			BN_MONT_CTX_free( &pkcInfo->montCTX1 );
			BN_MONT_CTX_free( &pkcInfo->montCTX2 );
			BN_MONT_CTX_free( &pkcInfo->montCTX3 );
			BN_CTX_free( &pkcInfo->bnCTX );
			if( pkcInfo->publicKeyInfo != NULL )
				clFree( "contextMessageFunction", pkcInfo->publicKeyInfo );
			}

		/* Delete the object itself */
		endVarStruct( contextInfoPtr, CONTEXT_INFO );
		if( needsSecureMemory( contextType ) )
			krnlMemfree( ( void ** ) &contextInfoPtr );
		else
			clFree( "contextMessageFunction", contextInfoPtr );

		return( CRYPT_OK );
		}

	/* Process attribute get/set/delete messages */
	if( isAttributeMessage( message ) )
		{
		if( message == MESSAGE_GETATTRIBUTE )
			return( processGetAttribute( contextInfoPtr, messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_GETATTRIBUTE_S )
			return( processGetAttributeS( contextInfoPtr, messageDataPtr,
										  messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE )
			return( processSetAttribute( contextInfoPtr, messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE_S )
			return( processSetAttributeS( contextInfoPtr, messageDataPtr,
										  messageValue ) );
		if( message == MESSAGE_DELETEATTRIBUTE )
			return( processDeleteAttribute( contextInfoPtr, messageValue ) );

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

	/* Process action messages */
	if( isActionMessage( message ) )
		{
		switch( message )
			{
			case MESSAGE_CTX_ENCRYPT:
				assert( contextInfoPtr->encryptFunction != NULL );

				if( contextInfoPtr->type == CONTEXT_CONV )
					{
					BYTE data[ 8 ];

					assert( isStreamCipher( capabilityInfo->cryptAlgo ) || \
							!needsIV( contextInfoPtr->ctxConv->mode ) ||
							( contextInfoPtr->flags & CONTEXT_IV_SET ) );

					if( messageValue >= 8 )
						memcpy( data, messageDataPtr, 8 );
					status = contextInfoPtr->encryptFunction( contextInfoPtr,
											messageDataPtr, messageValue );
					if( cryptStatusOK( status ) && messageValue >= 8 )
						{
						/* Check for a catastrophic failure of the
						   encryption.  This check unfortunately isn't 
						   completely foolproof for ciphers in CBC mode
						   because of the way the IV is applied to the
						   input.  For the CBC encryption operation:
					
							out = enc( in ^ IV )
						
						   if out == IV the operation turns into a no-op.
						   Consider the simple case where IV == in, so 
						   IV ^ in == 0.  Then out = enc( 0 ) == IV, with
						   the input appearing again at the output.  In fact 
						   this can occur during normal operation once every
						   2^32 blocks (for a 64-bit block cipher).  
						   Although the chances of this happening are fairly 
						   low (the collision would have to occur on the
						   first encrypted block in a message, since that's
						   the one we check), way may have to switch to
						   checking the first two blocks if we're using a
						   64-bit block cipher in CBC mode in order to
						   reduce false positives */
						if( !memcmp( data, messageDataPtr, 8 ) )
							{
							zeroise( messageDataPtr, messageValue );
							status = CRYPT_ERROR_FAILED;
							}
						zeroise( data, 8 );
						}
					}
				else
					{
					BYTE data[ 8 ];
					const BOOLEAN isDLP = \
								isDlpAlgo( capabilityInfo->cryptAlgo );
					const BOOLEAN isKeyx = \
								isKeyxAlgo( capabilityInfo->cryptAlgo );

					assert( contextInfoPtr->type == CONTEXT_PKC );
					assert( !isDLP ||
							( isKeyx && messageValue == sizeof( KEYAGREE_PARAMS ) ) || \
							( !isKeyx && messageValue == sizeof( DLP_PARAMS ) ) );

					if( !isKeyx )
						memcpy( data, isDLP ? \
								( ( DLP_PARAMS * ) messageDataPtr )->inParam1 : \
									messageDataPtr, 8 );
					status = contextInfoPtr->encryptFunction( contextInfoPtr,
											messageDataPtr, messageValue );
					if( cryptStatusOK( status ) && !isKeyx )
						{
						/* Check for a catastrophic failure of the
						   encryption */
						if( isDLP )
							{
							DLP_PARAMS *dlpParams = \
											( DLP_PARAMS * ) messageDataPtr;

							if( !memcmp( data, dlpParams->outParam, 8 ) )
								{
								zeroise( dlpParams->outParam, \
										 dlpParams->outLen );
								status = CRYPT_ERROR_FAILED;
								}
							}
						else
							if( !memcmp( data, messageDataPtr, 8 ) )
								{
								zeroise( messageDataPtr, messageValue );
								status = CRYPT_ERROR_FAILED;
								}
						zeroise( data, 8 );
						}
					clearTempBignums( contextInfoPtr->ctxPKC );
					}
				assert( cryptStatusOK( status ) );
				break;

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

				if( contextInfoPtr->type == CONTEXT_CONV )
					{
					assert( isStreamCipher( capabilityInfo->cryptAlgo ) || \
							!needsIV( contextInfoPtr->ctxConv->mode ) ||
							( contextInfoPtr->flags & CONTEXT_IV_SET ) );

					status = contextInfoPtr->decryptFunction( contextInfoPtr,
											messageDataPtr, messageValue );
					}
				else
					{
					/* Make sure that we're not trying to decrypt with a
					   public key.  The kernel doesn't know about subtypes,
					   so we have to perform the check at this level */
					if( contextInfoPtr->flags & CONTEXT_ISPUBLICKEY )
						return( CRYPT_ERROR_NOTAVAIL );
					status = contextInfoPtr->decryptFunction( contextInfoPtr,
											messageDataPtr, messageValue );
					clearTempBignums( contextInfoPtr->ctxPKC );
					}
				break;

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

				/* Make sure that we're not trying to decrypt with a public
				   key.  The kernel doesn't know about subtypes, so we have
				   to perform the check at this level */
				if( contextInfoPtr->flags & CONTEXT_ISPUBLICKEY )
					return( CRYPT_ERROR_NOTAVAIL );
				status = capabilityInfo->signFunction( contextInfoPtr,
											messageDataPtr, messageValue );
				clearTempBignums( contextInfoPtr->ctxPKC );
				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 );

				/* 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 )
					/* 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
					contextInfoPtr->flags |= CONTEXT_HASH_DONE;
				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 )
		{
		if( messageValue == CRYPT_IATTRIBUTE_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, reset the status
			   back to normal */
			return( CRYPT_OK );
			}

		if( messageValue == CRYPT_IATTRIBUTE_LOCKED )
			return( CRYPT_OK );

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

	/* 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 conte

⌨️ 快捷键说明

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