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

📄 cryptctx.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
		case CAPABILITY_INFO_KEYSIZE:
			return( getKeysize( varParam, constParam ) );

		case CAPABILITY_INFO_STATESIZE:
			return( 0 );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );
	}

/* Clear temporary bignum values used during PKC operations */

void clearTempBignums( PKC_INFO *pkcInfo )
	{
	BN_clear( &pkcInfo->tmp1 );
	BN_clear( &pkcInfo->tmp2 );
	BN_clear( &pkcInfo->tmp3 );
	BN_CTX_clear( &pkcInfo->bnCTX );
	}

/* Check that a context meets the given requirements */

#define checkActionPerm( action, perms ) \
		( MK_ACTION_PERM( ( action ), ACTION_PERM_ALL ) & ( perms ) )

static int checkContext( CONTEXT_INFO *contextInfoPtr,
						 const MESSAGE_CHECK_TYPE checkType )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	const CRYPT_ALGO_TYPE cryptAlgo = capabilityInfoPtr->cryptAlgo;
	int usageCount, actionPerms, status;

	/* Make sure that the object's usage count is still valid.  The usage
	   count is a type of meta-capability that overrides all other
	   capabilities in that an object with an expired usage count isn't
	   valid for anything no matter what the available capabilities are */
	status = krnlSendMessage( contextInfoPtr->objectHandle,
							  IMESSAGE_GETATTRIBUTE, &usageCount,
							  CRYPT_PROPERTY_USAGECOUNT );
	if( cryptStatusError( status ) || \
		( usageCount != CRYPT_UNUSED && usageCount <= 0 ) )
		return( exitError( contextInfoPtr, CRYPT_PROPERTY_USAGECOUNT,
						   CRYPT_ERRTYPE_ATTR_VALUE, CRYPT_ERROR_PERMISSION ) );

	/* Make sure that the object's action permissions allow the operation */
	status = krnlSendMessage( contextInfoPtr->objectHandle,
							  IMESSAGE_GETATTRIBUTE, &actionPerms,
							  CRYPT_IATTRIBUTE_ACTIONPERMS );
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_OBJECT );

	/* If it's a check for a key generation capability (which is algorithm-
	   type independent), we check it before performing any algorithm-
	   specific checks */
	if( checkType == MESSAGE_CHECK_KEYGEN )
		{
		if( contextInfoPtr->type == CONTEXT_HASH )
			return( CRYPT_ERROR_NOTAVAIL );	/* No key for hash algorithms */
		if( !needsKey( contextInfoPtr ) )
			return( exitErrorInited( contextInfoPtr, CRYPT_CTXINFO_KEY ) );
		return( ( capabilityInfoPtr->generateKeyFunction != NULL && \
				  !checkActionPerm( MESSAGE_CTX_GENKEY, actionPerms ) ) ? \
				CRYPT_OK : CRYPT_ARGERROR_OBJECT );
		}

	/* Perform general checks */
	if( contextInfoPtr->type != CONTEXT_HASH && needsKey( contextInfoPtr ) )
		return( exitErrorNotInited( contextInfoPtr, CRYPT_CTXINFO_KEY ) );

	/* Check for hash, MAC, and conventional encryption contexts */
	if( checkType == MESSAGE_CHECK_HASH )
		return( ( contextInfoPtr->type == CONTEXT_HASH && \
				  checkActionPerm( MESSAGE_CTX_HASH, actionPerms ) ) ? \
				CRYPT_OK : CRYPT_ARGERROR_OBJECT );
	if( checkType == MESSAGE_CHECK_MAC )
		return( ( contextInfoPtr->type == CONTEXT_MAC && \
				  checkActionPerm( MESSAGE_CTX_HASH, actionPerms ) ) ? \
				CRYPT_OK : CRYPT_ARGERROR_OBJECT );
	if( checkType == MESSAGE_CHECK_CRYPT )
		return( ( contextInfoPtr->type != CONTEXT_CONV && \
				  !checkActionPerm( MESSAGE_CTX_ENCRYPT, actionPerms ) ) ? \
				CRYPT_ARGERROR_OBJECT : CRYPT_OK );

	/* Make sure that it's a PKC context */
	if( contextInfoPtr->type != CONTEXT_PKC )
		return( CRYPT_ARGERROR_OBJECT );
	if( checkType == MESSAGE_CHECK_PKC )
		return( CRYPT_OK );

	/* Check for key-agreement algorithms */
	if( isKeyxAlgo( cryptAlgo ) )
		/* DH can never be used for encryption or signatures (if it is then
		   we call it Elgamal) and KEA is explicitly for key agreement only.
		   Note that the status of DH is a bit ambiguous in that every DH key
		   is both a public and private key since it's a key-agreement
		   algorithm, in order to avoid confusion in situations where we're
		   checking for real private keys we always denote a DH context as
		   key-agreement only without taking a side about whether it's a
		   public or private key */
		return( ( checkType == MESSAGE_CHECK_PKC_KA_EXPORT || \
				  checkType == MESSAGE_CHECK_PKC_KA_IMPORT ) ? \
				CRYPT_OK : CRYPT_ARGERROR_OBJECT );
	if( ( checkType == MESSAGE_CHECK_PKC_KA_EXPORT || \
		  checkType == MESSAGE_CHECK_PKC_KA_IMPORT ) )
		return( CRYPT_ARGERROR_OBJECT );	/* Must be a key agreement algorithm */

	/* Check that the algorithm complies and the capability is available */
	switch( checkType )
		{
		case MESSAGE_CHECK_PKC_ENCRYPT:
			if( cryptAlgo == CRYPT_ALGO_DSA )
				/* Must be an encryption algorithm */
				return( CRYPT_ARGERROR_OBJECT );
			if( capabilityInfoPtr->encryptFunction == NULL || \
				!checkActionPerm( MESSAGE_CTX_ENCRYPT, actionPerms ) )
				return( CRYPT_ARGERROR_OBJECT );
			break;

		case MESSAGE_CHECK_PKC_DECRYPT:
			if( cryptAlgo == CRYPT_ALGO_DSA )
				/* Must be an encryption algorithm */
				return( CRYPT_ARGERROR_OBJECT );
			if( capabilityInfoPtr->decryptFunction == NULL || \
				!checkActionPerm( MESSAGE_CTX_DECRYPT, actionPerms ) )
				return( CRYPT_ARGERROR_OBJECT );
			break;

		case MESSAGE_CHECK_PKC_SIGN:
			if( capabilityInfoPtr->signFunction == NULL || \
				!checkActionPerm( MESSAGE_CTX_SIGN, actionPerms ) )
				return( CRYPT_ARGERROR_OBJECT );
			break;

		case MESSAGE_CHECK_PKC_SIGCHECK:
			if( capabilityInfoPtr->sigCheckFunction == NULL || \
				!checkActionPerm( MESSAGE_CTX_SIGCHECK, actionPerms ) )
				return( CRYPT_ARGERROR_OBJECT );
			break;

		case MESSAGE_CHECK_CA:
			if( capabilityInfoPtr->signFunction == NULL && \
				capabilityInfoPtr->sigCheckFunction == NULL )
				return( CRYPT_ARGERROR_OBJECT );
			if( !checkActionPerm( MESSAGE_CTX_SIGN, actionPerms ) && \
				!checkActionPerm( MESSAGE_CTX_SIGCHECK, actionPerms ) )
				return( CRYPT_ARGERROR_OBJECT );
		}

	/* Check that it's a private key if this is required */
	if( ( checkType == MESSAGE_CHECK_PKC_PRIVATE || \
		  checkType == MESSAGE_CHECK_PKC_DECRYPT || \
		  checkType == MESSAGE_CHECK_PKC_SIGN ) && \
		( contextInfoPtr->flags & CONTEXT_ISPUBLICKEY ) )
		return( CRYPT_ARGERROR_OBJECT );

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*						Context Attribute Handling Functions				*
*																			*
****************************************************************************/

/* Handle data sent to or read from a context */

static int processGetAttribute( CONTEXT_INFO *contextInfoPtr,
								void *messageDataPtr, const int messageValue )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = contextInfoPtr->type;
	int *valuePtr = ( int * ) messageDataPtr, value;

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

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

		case CRYPT_CTXINFO_ALGO:
			*valuePtr = capabilityInfoPtr->cryptAlgo;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_MODE:
			assert( contextType == CONTEXT_CONV );
			*valuePtr = contextInfoPtr->ctxConv->mode;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYSIZE:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_PKC || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				value = contextInfoPtr->ctxConv->userKeyLength;
			else
				if( contextType == CONTEXT_MAC )
					value = contextInfoPtr->ctxMAC->userKeyLength;
				else
					value = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
			if( !value )
				/* If a key hasn't been loaded yet, we return the default
				   key size */
				value = capabilityInfoPtr->keySize;
			*valuePtr = value;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_BLOCKSIZE:
			if( contextType == CONTEXT_CONV && \
				( contextInfoPtr->ctxConv->mode == CRYPT_MODE_CFB || \
				  contextInfoPtr->ctxConv->mode == CRYPT_MODE_OFB ) )
				*valuePtr = 1;	/* Block cipher in stream mode */
			else
				*valuePtr = capabilityInfoPtr->blockSize;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_IVSIZE:
			assert( contextType == CONTEXT_CONV );
			if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
				isStreamCipher( capabilityInfoPtr->cryptAlgo ) )
				return( CRYPT_ERROR_NOTAVAIL );
			*valuePtr = capabilityInfoPtr->blockSize;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ALGO:
		case CRYPT_OPTION_KEYING_ALGO:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				value = contextInfoPtr->ctxConv->keySetupAlgorithm;
			else
				value = contextInfoPtr->ctxMAC->keySetupAlgorithm;
			if( !value )
				return( exitErrorNotInited( contextInfoPtr,
											CRYPT_CTXINFO_KEYING_ALGO ) );
			*valuePtr = value;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ITERATIONS:
		case CRYPT_OPTION_KEYING_ITERATIONS:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				value = contextInfoPtr->ctxConv->keySetupIterations;
			else
				value = contextInfoPtr->ctxMAC->keySetupIterations;
			if( !value )
				return( exitErrorNotInited( contextInfoPtr,
											CRYPT_CTXINFO_KEYING_ITERATIONS ) );
			*valuePtr = value;
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_KEYFEATURES:
			assert( contextType == CONTEXT_PKC );
			*valuePtr = ( contextInfoPtr->flags & CONTEXT_PBO ) ? 1 : 0;
#ifdef USE_DEVICES
			*valuePtr |= ( contextInfoPtr->deviceObject > 0 ) ? 2 : 0;
#endif /* USE_DEVICES */
			return( CRYPT_OK );

#ifdef USE_DEVICES
		case CRYPT_IATTRIBUTE_DEVICEOBJECT:
			if( contextInfoPtr->deviceObject < 0 )
				return( CRYPT_ERROR_NOTFOUND );
			*valuePtr = ( int ) contextInfoPtr->deviceObject;
			return( CRYPT_OK );
#else
		case CRYPT_IATTRIBUTE_DEVICEOBJECT:
			return( CRYPT_ERROR_NOTFOUND );
#endif /* USE_DEVICES */
		}

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

static int processGetAttributeS( CONTEXT_INFO *contextInfoPtr,
								 void *messageDataPtr, const int messageValue )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = contextInfoPtr->type;
	RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
	STREAM stream;
	int status;

	switch( messageValue )
		{
		case CRYPT_CTXINFO_NAME_ALGO:
			return( attributeCopy( msgData, capabilityInfoPtr->algoName,
								   strlen( capabilityInfoPtr->algoName ) ) );

		case CRYPT_CTXINFO_NAME_MODE:
			assert( contextType == CONTEXT_CONV );
			switch( contextInfoPtr->ctxConv->mode )
				{
				case CRYPT_MODE_ECB:
					return( attributeCopy( msgData, "ECB", 3 ) );
				case CRYPT_MODE_CBC:
					return( attributeCopy( msgData, "CBC", 3 ) );
				case CRYPT_MODE_CFB:
					return( attributeCopy( msgData, "CFB", 3 ) );
				case CRYPT_MODE_OFB:
					return( attributeCopy( msgData, "OFB", 3 ) );
				}
			assert( NOTREACHED );
			break;

		case CRYPT_CTXINFO_KEYING_SALT:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				{
				if( !contextInfoPtr->ctxConv->saltLength )
					return( exitErrorInited( contextInfoPtr,
											 CRYPT_CTXINFO_KEYING_SALT ) );
				return( attributeCopy( msgData, contextInfoPtr->ctxConv->salt,
									   contextInfoPtr->ctxConv->saltLength ) );
				}
			if( !contextInfoPtr->ctxMAC->saltLength )
				return( exitErrorInited( contextInfoPtr,
										 CRYPT_CTXINFO_KEYING_SALT ) );
			return( attributeCopy( msgData, contextInfoPtr->ctxMAC->salt,
								   contextInfoPtr->ctxMAC->saltLength ) );

		case CRYPT_CTXINFO_IV:
			assert( contextType == CONTEXT_CONV );
			if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
				isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
				return( CRYPT_ERROR_NOTAVAIL );
			if( !( contextInfoPtr->flags & CONTEXT_IV_SET ) )
				return( exitErrorNotInited( contextInfoPtr, CRYPT_CTXINFO_IV ) );
			return( attributeCopy( msgData, contextInfoPtr->ctxConv->iv,
								   contextInfoPtr->ctxConv->ivLength ) );

		case CRYPT_CTXINFO_HASHVALUE:
			assert( contextType == CONTEXT_HASH || \
					contextType == CONTEXT_MAC );
			if( !( contextInfoPtr->flags & CONTEXT_HASH_INITED ) )
				return( CRYPT_ERROR_NOTINITED );
			if( !( contextInfoPtr->flags & CONTEXT_HASH_DONE ) )
				return( CRYPT_ERROR_INCOMPLETE );
			return( attributeCopy( msgData, ( contextType == CONTEXT_HASH ) ? \
										contextInfoPtr->ctxHash->hash : \
										contextInfoPtr->ctxMAC->mac,
								   capabilityInfoPtr->blockSize ) );

		case CRYPT_CTXINFO_LABEL:
			if( !contextInfoPtr->labelSize )
				return( exitErrorNotInited( contextInfoPtr,
											CRYPT_CTXINFO_LABEL ) );
			return( attributeCopy( msgData, contextInfoPtr->label,

⌨️ 快捷键说明

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