📄 cryptctx.c
字号:
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;
}
return( status );
#ifndef USE_FIPS140
case CRYPT_CTXINFO_KEY_COMPONENTS:
return( setKeyComponents( contextInfoPtr, msgData->data,
msgData->length ) );
#endif /* USE_FIPS140 */
case CRYPT_CTXINFO_IV:
assert( contextType == CONTEXT_CONV );
/* If it's a mode that doesn't use an IV, the load IV operation
is meaningless */
if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
return( CRYPT_ERROR_NOTAVAIL );
/* Make sure that the data size is valid */
if( msgData->length != capabilityInfoPtr->blockSize )
return( CRYPT_ARGERROR_NUM1 );
/* Load the IV */
assert( capabilityInfoPtr->initKeyParamsFunction != NULL );
return( capabilityInfoPtr->initKeyParamsFunction( contextInfoPtr,
msgData->data, msgData->length, CRYPT_MODE_NONE ) );
case CRYPT_CTXINFO_LABEL:
if( contextInfoPtr->labelSize > 0 )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
/* Check any device object that the context is associated with
to ensure that nothing with that label already exists in the
device. For keysets the check for duplicates is performed
when the context is explicitly added to the keyset, but with
devices the context will be implicitly created within the
device at some future point that depends on the device (at
context creation, on key load/generation, or at some other
point). Because of this we perform a pre-emptive check for
duplicates to avoid a potentially confusing error condition
at some point in the future. In addition, we can't send the
message to the context because the kernel won't forward this
message type (sending a get-key message to a context doesn't
make sense) so we have to explicitly get the dependent device
and send the get-key directly to it */
if( contextType == CONTEXT_PKC )
{
CRYPT_HANDLE cryptHandle;
status = krnlSendMessage( contextInfoPtr->objectHandle,
IMESSAGE_GETDEPENDENT,
&cryptHandle, OBJECT_TYPE_DEVICE );
if( cryptStatusOK( status ) )
{
MESSAGE_KEYMGMT_INFO getkeyInfo;
setMessageKeymgmtInfo( &getkeyInfo,
CRYPT_KEYID_NAME, msgData->data,
msgData->length, NULL, 0,
KEYMGMT_FLAG_CHECK_ONLY );
status = krnlSendMessage( contextInfoPtr->objectHandle,
MESSAGE_KEY_GETKEY, &getkeyInfo,
KEYMGMT_ITEM_PUBLICKEY );
if( cryptStatusError( status ) )
{
setMessageKeymgmtInfo( &getkeyInfo,
CRYPT_KEYID_NAME, msgData->data,
msgData->length, NULL, 0,
KEYMGMT_FLAG_CHECK_ONLY );
status = krnlSendMessage( contextInfoPtr->objectHandle,
MESSAGE_KEY_GETKEY, &getkeyInfo,
KEYMGMT_ITEM_PRIVATEKEY );
}
if( cryptStatusOK( status ) )
/* We found something with this label already
present, we can't use it again */
return( CRYPT_ERROR_DUPLICATE );
}
}
/* Set the label */
memcpy( contextInfoPtr->label, msgData->data, msgData->length );
contextInfoPtr->labelSize = msgData->length;
return( CRYPT_OK );
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 );
assert( msgData->length == PGP_KEYID_SIZE );
memcpy( contextInfoPtr->ctxPKC->openPgpKeyID, msgData->data,
msgData->length );
contextInfoPtr->ctxPKC->openPgpKeyIDSet = TRUE;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_KEY_SPKI:
case CRYPT_IATTRIBUTE_KEY_PGP:
case CRYPT_IATTRIBUTE_KEY_SSH1:
case CRYPT_IATTRIBUTE_KEY_SSH2:
case CRYPT_IATTRIBUTE_KEY_SSL:
case CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL:
case CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL:
return( setKey( contextInfoPtr, messageValue, msgData->data,
msgData->length ) );
case CRYPT_IATTRIBUTE_PGPVALIDITY:
assert( contextType == CONTEXT_PKC );
contextInfoPtr->ctxPKC->pgpCreationTime = \
*( ( time_t * ) msgData->data );
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processDeleteAttribute( CONTEXT_INFO *contextInfoPtr,
const int messageValue )
{
const CONTEXT_TYPE contextType = contextInfoPtr->type;
switch( messageValue )
{
case CRYPT_CTXINFO_KEYING_ALGO:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( contextInfoPtr->ctxConv->keySetupAlgorithm == CRYPT_ALGO_NONE )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ALGO ) );
contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_NONE;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->keySetupAlgorithm == CRYPT_ALGO_NONE )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ALGO ) );
contextInfoPtr->ctxMAC->keySetupAlgorithm = CRYPT_ALGO_NONE;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_ITERATIONS:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( contextInfoPtr->ctxConv->keySetupIterations == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ITERATIONS ) );
contextInfoPtr->ctxConv->keySetupIterations = 0;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->keySetupIterations == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ITERATIONS ) );
contextInfoPtr->ctxMAC->keySetupIterations = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_SALT:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( contextInfoPtr->ctxConv->saltLength == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_SALT ) );
zeroise( contextInfoPtr->ctxConv->salt, CRYPT_MAX_HASHSIZE );
contextInfoPtr->ctxConv->saltLength = 0;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->saltLength == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_SALT ) );
zeroise( contextInfoPtr->ctxMAC->salt, CRYPT_MAX_HASHSIZE );
contextInfoPtr->ctxMAC->saltLength = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_IV:
assert( contextType == CONTEXT_CONV );
if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_IV ) );
contextInfoPtr->ctxConv->ivLength = \
contextInfoPtr->ctxConv->ivCount = 0;
contextInfoPtr->flags &= ~CONTEXT_IV_SET;
return( CRYPT_OK );
case CRYPT_CTXINFO_LABEL:
if( contextInfoPtr->labelSize == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
zeroise( contextInfoPtr->label, contextInfoPtr->labelSize );
contextInfoPtr->labelSize = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_HASHVALUE:
switch( contextType )
{
case CONTEXT_HASH:
zeroise( contextInfoPtr->ctxHash->hash, CRYPT_MAX_HASHSIZE );
break;
case CONTEXT_MAC:
zeroise( contextInfoPtr->ctxMAC->mac, CRYPT_MAX_HASHSIZE );
break;
default:
assert( NOTREACHED );
return( CRYPT_ERROR );
}
contextInfoPtr->flags &= ~( CONTEXT_HASH_INITED | \
CONTEXT_HASH_DONE );
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/****************************************************************************
* *
* Context Message Handler *
* *
****************************************************************************/
/* Handle a message sent to an encryption context */
static int contextMessageFunction( const void *objectInfoPtr,
const MESSAGE_TYPE message,
void *messageDataPtr,
const int messageValue )
{
CONTEXT_INFO *contextInfoPtr = ( CONTEXT_INFO * ) objectInfoPtr;
const CAPABILITY_INFO *capabilityInfo = contextInfoPtr->capabilityInfo;
int status;
/* Process destroy object messages */
if( message == MESSAGE_DESTROY )
{
const CONTEXT_TYPE contextType = contextInfoPtr->type;
#if 0 /* 9/12/02 We can never get here because we can't send a message to a
busy object any more */
/* If the context is busy, abort the async.operation. We do this by
setting the abort flag (which is OK, since the context is about to
be destroyed anyway) and then waiting for the busy flag to be
cleared */
contextInfoPtr->flags |= CONTEXT_ASYNC_ABORT;
krnlSendMessage( cryptContext, IMESSAGE_GETATTRIBUTE, &status,
CRYPT_IATTRIBUTE_STATUS );
if( status & OBJECT_FLAG_BUSY )
{
/* Unlock the object so that the background thread can access it.
Nothing else will get in because the object is in the
signalled state */
unlockResource( contextInfoPtr );
/* Wait awhile and check whether we've left the busy state */
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( 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 );
}
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 ) )
{
assert( message == MESSAGE_CTX_HASH || \
isWritePtr( messageDataPtr, messageValue ) );
switch( message )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -