📄 ctx_attr.c
字号:
/****************************************************************************
* *
* 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 + -