📄 cryptctx.c
字号:
contextInfoPtr->labelSize ) );
case CRYPT_IATTRIBUTE_KEYID:
assert( contextType == CONTEXT_PKC );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->keyID,
KEYID_SIZE ) );
case CRYPT_IATTRIBUTE_KEYID_PGP:
assert( contextType == CONTEXT_PKC );
if( contextInfoPtr->capabilityInfo->cryptAlgo != CRYPT_ALGO_RSA )
return( CRYPT_ERROR_NOTFOUND );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->pgpKeyID,
PGP_KEYID_SIZE ) );
case CRYPT_IATTRIBUTE_KEYID_OPENPGP:
assert( contextType == CONTEXT_PKC );
assert( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA || \
contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->openPgpKeyID,
PGP_KEYID_SIZE ) );
#ifdef USE_KEA
case CRYPT_IATTRIBUTE_KEY_KEADOMAINPARAMS:
assert( contextType == CONTEXT_PKC );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->domainParamPtr,
contextInfoPtr->ctxPKC->domainParamSize ) );
case CRYPT_IATTRIBUTE_KEY_KEAPUBLICVALUE:
assert( contextType == CONTEXT_PKC );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicValuePtr,
contextInfoPtr->ctxPKC->publicValueSize ) );
#else
case CRYPT_IATTRIBUTE_KEY_KEADOMAINPARAMS:
case CRYPT_IATTRIBUTE_KEY_KEAPUBLICVALUE:
return( CRYPT_ERROR_NOTFOUND );
#endif /* USE_KEA */
case CRYPT_IATTRIBUTE_KEY_SPKI:
assert( contextType == CONTEXT_PKC );
assert( contextInfoPtr->flags & CONTEXT_KEY_SET );
if( contextInfoPtr->ctxPKC->publicKeyInfo != NULL )
/* If the data is available in pre-encoded form, copy it
out */
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicKeyInfo,
contextInfoPtr->ctxPKC->publicKeyInfoSize ) );
/* Drop through */
case CRYPT_IATTRIBUTE_KEY_SSH1:
case CRYPT_IATTRIBUTE_KEY_SSH2:
assert( contextType == CONTEXT_PKC );
assert( contextInfoPtr->flags & CONTEXT_KEY_SET );
/* Write the appropriately-formatted key data from the context */
sMemOpen( &stream, msgData->data, msgData->length );
status = contextInfoPtr->ctxPKC->writePublicKeyFunction( &stream,
contextInfoPtr,
( messageValue == CRYPT_IATTRIBUTE_KEY_SPKI ) ? \
KEYFORMAT_CERT : \
( messageValue == CRYPT_IATTRIBUTE_KEY_SSH1 ) ? \
KEYFORMAT_SSH1 : KEYFORMAT_SSH2, "public" );
if( cryptStatusOK( status ) )
msgData->length = stell( &stream );
sMemDisconnect( &stream );
return( status );
case CRYPT_IATTRIBUTE_PGPVALIDITY:
assert( contextType == CONTEXT_PKC );
*( ( time_t * ) msgData->data ) = \
contextInfoPtr->ctxPKC->pgpCreationTime;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processSetAttribute( CONTEXT_INFO *contextInfoPtr,
void *messageDataPtr, const int messageValue )
{
const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
const CONTEXT_TYPE contextType = contextInfoPtr->type;
const int value = *( ( int * ) messageDataPtr );
CRYPT_ALGO_TYPE *algoValuePtr;
int *valuePtr;
int status;
switch( messageValue )
{
case CRYPT_CTXINFO_MODE:
assert( contextType == CONTEXT_CONV );
/* If the mode isn't set to the initial default, it's already
been explicitly set and we can't change it again */
if( contextInfoPtr->ctxConv->mode != \
( isStreamCipher( capabilityInfoPtr->cryptAlgo ) ? \
CRYPT_MODE_OFB : CRYPT_MODE_CBC ) )
return( exitErrorInited( contextInfoPtr, CRYPT_CTXINFO_MODE ) );
/* Set the en/decryption mode */
assert( capabilityInfoPtr->initKeyParamsFunction != NULL );
return( capabilityInfoPtr->initKeyParamsFunction( contextInfoPtr,
NULL, 0, value ) );
case CRYPT_CTXINFO_KEYSIZE:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_PKC || \
contextType == CONTEXT_MAC );
assert( capabilityInfoPtr->getInfoFunction != NULL );
if( contextType == CONTEXT_CONV )
valuePtr = &contextInfoPtr->ctxConv->userKeyLength;
else
if( contextType == CONTEXT_MAC )
valuePtr = &contextInfoPtr->ctxMAC->userKeyLength;
else
valuePtr = &contextInfoPtr->ctxPKC->keySizeBits;
if( *valuePtr )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYSIZE ) );
/* Trim the user-supplied value to the correct shape, taking
into account various issues such as limitations with the
underlying crypto code/hardware and the (in)ability to export
overly long keys using short public keys */
status = capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE,
contextInfoPtr, value );
if( cryptStatusError( status ) )
return( status );
*valuePtr = ( contextType == CONTEXT_PKC ) ? \
bytesToBits( status ) : status;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_ALGO:
case CRYPT_OPTION_KEYING_ALGO:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
algoValuePtr = ( contextType == CONTEXT_CONV ) ? \
&contextInfoPtr->ctxConv->keySetupAlgorithm : \
&contextInfoPtr->ctxMAC->keySetupAlgorithm;
if( *algoValuePtr != CRYPT_ALGO_NONE )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ALGO ) );
*algoValuePtr = value;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_ITERATIONS:
case CRYPT_OPTION_KEYING_ITERATIONS:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
valuePtr = ( contextType == CONTEXT_CONV ) ? \
&contextInfoPtr->ctxConv->keySetupIterations : \
&contextInfoPtr->ctxMAC->keySetupIterations;
if( *valuePtr )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ITERATIONS ) );
*valuePtr = value;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_INITIALISED:
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_KEYSIZE:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_PKC || \
contextType == CONTEXT_MAC );
/* If the key is held outside the context (e.g. in a device), we
need to manually supply key-related information needed by the
context, which in this case is the key size. Once this is
set, there is (effectively) a key loaded, although the actual
keying values are held anderswhere */
switch( contextType )
{
case CONTEXT_CONV:
contextInfoPtr->ctxConv->userKeyLength = value;
break;
case CONTEXT_PKC:
if( !contextInfoPtr->labelSize )
/* PKC context must have a key label set */
return( exitErrorNotInited( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
contextInfoPtr->ctxPKC->keySizeBits = bytesToBits( value );
break;
case CONTEXT_MAC:
contextInfoPtr->ctxMAC->userKeyLength = value;
break;
default:
assert( NOTREACHED );
}
contextInfoPtr->flags |= CONTEXT_KEY_SET;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_DEVICEOBJECT:
#ifdef USE_DEVICES
contextInfoPtr->deviceObject = value;
#endif /* USE_DEVICES */
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processSetAttributeS( CONTEXT_INFO *contextInfoPtr,
void *messageDataPtr, const int messageValue )
{
const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
const CONTEXT_TYPE contextType = contextInfoPtr->type;
const RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
int status;
switch( messageValue )
{
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 ) );
memcpy( contextInfoPtr->ctxConv->salt, msgData->data,
msgData->length );
contextInfoPtr->ctxConv->saltLength = msgData->length;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->saltLength )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYING_SALT ) );
memcpy( contextInfoPtr->ctxMAC->salt, msgData->data,
msgData->length );
contextInfoPtr->ctxMAC->saltLength = msgData->length;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_VALUE:
{
MECHANISM_DERIVE_INFO mechanismInfo;
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
assert( needsKey( contextInfoPtr ) );
/* Set up various parameters if they're not already set. Since
there's only one MUST MAC algorithm for PKCS #5v2, we always
force the key derivation algorithm to this value to avoid
interop problems */
if( contextType == CONTEXT_CONV )
{
if( !contextInfoPtr->ctxConv->saltLength )
{
RESOURCE_DATA nonceMsgData;
setMessageData( &nonceMsgData, contextInfoPtr->ctxConv->salt,
PKCS5_SALT_SIZE );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_GETATTRIBUTE_S,
&nonceMsgData,
CRYPT_IATTRIBUTE_RANDOM_NONCE );
if( cryptStatusError( status ) )
return( status );
contextInfoPtr->ctxConv->saltLength = PKCS5_SALT_SIZE;
}
contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_HMAC_SHA;
setMechanismDeriveInfo( &mechanismInfo,
contextInfoPtr->ctxConv->userKey,
capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE,
contextInfoPtr,
contextInfoPtr->ctxConv->userKeyLength ),
msgData->data, msgData->length,
contextInfoPtr->ctxConv->keySetupAlgorithm,
contextInfoPtr->ctxConv->salt, contextInfoPtr->ctxConv->saltLength,
contextInfoPtr->ctxConv->keySetupIterations );
}
else
{
if( !contextInfoPtr->ctxMAC->saltLength )
{
RESOURCE_DATA nonceMsgData;
setMessageData( &nonceMsgData, contextInfoPtr->ctxMAC->salt,
PKCS5_SALT_SIZE );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_GETATTRIBUTE_S,
&nonceMsgData,
CRYPT_IATTRIBUTE_RANDOM_NONCE );
if( cryptStatusError( status ) )
return( status );
contextInfoPtr->ctxMAC->saltLength = PKCS5_SALT_SIZE;
}
contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_HMAC_SHA;
setMechanismDeriveInfo( &mechanismInfo,
contextInfoPtr->ctxMAC->userKey,
capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE,
contextInfoPtr,
contextInfoPtr->ctxMAC->userKeyLength ),
msgData->data, msgData->length,
contextInfoPtr->ctxConv->keySetupAlgorithm,
contextInfoPtr->ctxMAC->salt, contextInfoPtr->ctxMAC->saltLength,
contextInfoPtr->ctxMAC->keySetupIterations );
}
if( !mechanismInfo.iterations )
{
krnlSendMessage( contextInfoPtr->ownerHandle,
IMESSAGE_GETATTRIBUTE, &mechanismInfo.iterations,
CRYPT_OPTION_KEYING_ITERATIONS );
if( contextType == CONTEXT_CONV )
contextInfoPtr->ctxConv->keySetupIterations = \
mechanismInfo.iterations;
else
contextInfoPtr->ctxMAC->keySetupIterations = \
mechanismInfo.iterations;
}
/* Turn the user key into an encryption context key and load the
key into the context */
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_DERIVE, &mechanismInfo,
MECHANISM_PKCS5 );
if( cryptStatusOK( status ) )
status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
mechanismInfo.dataOut,
mechanismInfo.dataOutLength );
if( cryptStatusOK( status ) )
{
contextInfoPtr->flags |= CONTEXT_KEY_SET | CONTEXT_EPHEMERAL;
if( contextType == CONTEXT_MAC )
contextInfoPtr->flags |= CONTEXT_HASH_INITED;
}
return( status );
}
case CRYPT_CTXINFO_KEY:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
assert( needsKey( contextInfoPtr ) );
/* The kernel performs a general check on the size of this
attribute but doesn't know about context subtype-specific
limits, so we perform a context-specific check here */
if( msgData->length < capabilityInfoPtr->minKeySize || \
msgData->length > capabilityInfoPtr->maxKeySize )
return( CRYPT_ARGERROR_NUM1 );
/* Load the key into the context */
status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
msgData->data, msgData->length );
if( cryptStatusOK( status ) )
{
contextInfoPtr->flags |= CONTEXT_KEY_SET | CONTEXT_EPHEMERAL;
if( contextType == CONTEXT_MAC )
contextInfoPtr->flags |= CONTEXT_HASH_INITED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -