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

📄 ctx_attr.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*																			*
*				cryptlib Encryption Context Attribute Routines				*
*						Copyright Peter Gutmann 1992-2008					*
*																			*
****************************************************************************/

#define PKC_CONTEXT		/* Indicate that we're working with PKC contexts */
#include "crypt.h"
#ifdef INC_ALL
  #include "context.h"
  #include "asn1.h"
#else
  #include "context/context.h"
  #include "misc/asn1.h"
#endif /* Compiler-specific includes */

/****************************************************************************
*																			*
*								Utility Functions							*
*																			*
****************************************************************************/

/* Exit after setting extended error information */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitError( INOUT CONTEXT_INFO *contextInfoPtr,
					  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus,
					  IN_ENUM( CRYPT_ERRTYPE ) const CRYPT_ERRTYPE_TYPE errorType, 
					  IN_ERROR const int status )
	{
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( isAttribute( errorLocus ) || \
			  isInternalAttribute( errorLocus ) );
	REQUIRES( errorType > CRYPT_ERRTYPE_NONE && \
			  errorType < CRYPT_ERRTYPE_LAST );
	REQUIRES( cryptStatusError( status ) );

	setErrorInfo( contextInfoPtr, errorLocus, errorType );
	return( status );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorInited( INOUT CONTEXT_INFO *contextInfoPtr,
							IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
	{
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( isAttribute( errorLocus ) || \
			  isInternalAttribute( errorLocus ) );

	return( exitError( contextInfoPtr, errorLocus, 
					   CRYPT_ERRTYPE_ATTR_PRESENT, CRYPT_ERROR_INITED ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorNotInited( INOUT CONTEXT_INFO *contextInfoPtr,
							   IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
	{
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( isAttribute( errorLocus ) || \
			  isInternalAttribute( errorLocus ) );

	return( exitError( contextInfoPtr, errorLocus, 
					   CRYPT_ERRTYPE_ATTR_ABSENT, CRYPT_ERROR_NOTINITED ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorNotFound( INOUT CONTEXT_INFO *contextInfoPtr,
							  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
	{
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( isAttribute( errorLocus ) || \
			  isInternalAttribute( errorLocus ) );

	return( exitError( contextInfoPtr, errorLocus, 
					   CRYPT_ERRTYPE_ATTR_ABSENT, CRYPT_ERROR_NOTFOUND ) );
	}

/****************************************************************************
*																			*
*								Get Attributes								*
*																			*
****************************************************************************/

/* Get a numeric/boolean attribute */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int getContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
						 OUT_INT_Z int *valuePtr, 
						 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = contextInfoPtr->type;
	int value;

	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
	assert( isWritePtr( valuePtr, sizeof( int ) ) );

	REQUIRES( isAttribute( attribute ) || \
			  isInternalAttribute( attribute ) );

	/* Clear return value */
	*valuePtr = 0;

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

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

		case CRYPT_OPTION_MISC_SIDECHANNELPROTECTION:
			*valuePtr = ( contextInfoPtr->flags & \
						  CONTEXT_FLAG_SIDECHANNELPROTECTION ) ? 1 : 0;
						/* This is actually a protection level rather than a 
						   boolean value, although internally it's stored as
						   a boolean flag */
			return( CRYPT_OK );

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

		case CRYPT_CTXINFO_MODE:
			REQUIRES( contextType == CONTEXT_CONV );

			*valuePtr = contextInfoPtr->ctxConv->mode;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYSIZE:
			switch( contextType )
				{
				case CONTEXT_CONV:
					value = contextInfoPtr->ctxConv->userKeyLength;
					break;

				case CONTEXT_PKC:
					value = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
					break;

				case CONTEXT_MAC:
					value = contextInfoPtr->ctxMAC->userKeyLength;
					break;

				default:
					retIntError();
				}
			if( value <= 0 )
				{
				/* 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:
			REQUIRES( 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:
			switch( contextType )
				{
				case CONTEXT_CONV:
					value = contextInfoPtr->ctxConv->keySetupAlgorithm;
					break;

				case CONTEXT_MAC:
					value = contextInfoPtr->ctxMAC->keySetupAlgorithm;
					break;

				default:
					retIntError();
				}
			if( value <= 0 )
				return( exitErrorNotInited( contextInfoPtr,
											CRYPT_CTXINFO_KEYING_ALGO ) );
			*valuePtr = value;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ITERATIONS:
		case CRYPT_OPTION_KEYING_ITERATIONS:
			switch( contextType )
				{
				case CONTEXT_CONV:
					value = contextInfoPtr->ctxConv->keySetupIterations;
					break;

				case CONTEXT_MAC:
					value = contextInfoPtr->ctxMAC->keySetupIterations;
					break;

				default:
					retIntError();
				}
			if( value <= 0 )
				return( exitErrorNotInited( contextInfoPtr,
											CRYPT_CTXINFO_KEYING_ITERATIONS ) );
			*valuePtr = value;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_PERSISTENT:
			*valuePtr = ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ? \
						TRUE : FALSE;
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_KEYFEATURES:
			REQUIRES( contextType == CONTEXT_PKC );

			*valuePtr = ( contextInfoPtr->flags & CONTEXT_FLAG_PBO ) ? 1 : 0;
#ifdef USE_DEVICES
			*valuePtr |= isHandleRangeValid( contextInfoPtr->deviceObject ) ? 2 : 0;
#endif /* USE_DEVICES */
			return( CRYPT_OK );

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

	retIntError();
	}

/* Get a string attribute */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int getContextAttributeS( INOUT CONTEXT_INFO *contextInfoPtr,
						  INOUT MESSAGE_DATA *msgData, 
						  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = contextInfoPtr->type;
	int status;

	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
	assert( isWritePtr( msgData, sizeof( MESSAGE_DATA ) ) );

	REQUIRES( isAttribute( attribute ) || \
			  isInternalAttribute( attribute ) );

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

		case CRYPT_CTXINFO_NAME_MODE:
			REQUIRES( 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 ) );
				}
			retIntError();

		case CRYPT_CTXINFO_KEYING_SALT:
			REQUIRES( contextType == CONTEXT_CONV || \
					  contextType == CONTEXT_MAC );

			if( contextType == CONTEXT_CONV )
				{
				if( contextInfoPtr->ctxConv->saltLength <= 0 )
					return( exitErrorInited( contextInfoPtr,
											 CRYPT_CTXINFO_KEYING_SALT ) );
				return( attributeCopy( msgData, contextInfoPtr->ctxConv->salt,
									   contextInfoPtr->ctxConv->saltLength ) );
				}
			if( contextInfoPtr->ctxMAC->saltLength <= 0 )
				return( exitErrorInited( contextInfoPtr,
										 CRYPT_CTXINFO_KEYING_SALT ) );
			return( attributeCopy( msgData, contextInfoPtr->ctxMAC->salt,
								   contextInfoPtr->ctxMAC->saltLength ) );

		case CRYPT_CTXINFO_IV:
			REQUIRES( contextType == CONTEXT_CONV );

			if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
				isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
				return( CRYPT_ERROR_NOTAVAIL );
			if( !( contextInfoPtr->flags & CONTEXT_FLAG_IV_SET ) )
				return( exitErrorNotInited( contextInfoPtr, CRYPT_CTXINFO_IV ) );
			return( attributeCopy( msgData, contextInfoPtr->ctxConv->iv,
								   contextInfoPtr->ctxConv->ivLength ) );

⌨️ 快捷键说明

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