📄 crypt.c
字号:
assert( msgData->length == PGP_KEYID_SIZE );
memcpy( cryptInfoPtr->ctxPKC.openPGPKeyID, msgData->data,
msgData->length );
cryptInfoPtr->ctxPKC.openPGPKeyIDSet = TRUE;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_PUBLICKEY:
assert( contextType == CONTEXT_PKC );
/* Copy the data in and set up any other information we may need
from it */
if( ( cryptInfoPtr->ctxPKC.publicKeyInfo = \
malloc( msgData->length ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memcpy( cryptInfoPtr->ctxPKC.publicKeyInfo, msgData->data,
msgData->length );
cryptInfoPtr->ctxPKC.publicKeyInfoSize = msgData->length;
return( calculateKeyID( cryptInfoPtr ) );
case CRYPT_IATTRIBUTE_SSH1_PUBLICKEY:
assert( contextType == CONTEXT_PKC );
/* Read the SSHv1-format key data directly into the context */
sMemConnect( &stream, msgData->data, msgData->length );
status = readSsh1PublicKey( &stream, cryptInfoPtr );
sMemDisconnect( &stream );
return( status );
case CRYPT_IATTRIBUTE_SSH2_PUBLICKEY:
assert( contextType == CONTEXT_PKC );
/* Read the SSHv2-format key data directly into the context */
sMemConnect( &stream, msgData->data, msgData->length );
status = readSsh2PublicKey( &stream, cryptInfoPtr );
sMemDisconnect( &stream );
return( status );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processDeleteAttribute( CRYPT_INFO *cryptInfoPtr,
const int messageValue )
{
const CONTEXT_TYPE contextType = cryptInfoPtr->type;
switch( messageValue )
{
case CRYPT_CTXINFO_KEYING_ALGO:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( !cryptInfoPtr->ctxConv.keySetupAlgorithm )
return( CRYPT_ERROR_NOTFOUND );
cryptInfoPtr->ctxConv.keySetupAlgorithm = CRYPT_ALGO_NONE;
return( CRYPT_OK );
}
if( !cryptInfoPtr->ctxMAC.keySetupAlgorithm )
return( CRYPT_ERROR_NOTFOUND );
cryptInfoPtr->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( !cryptInfoPtr->ctxConv.keySetupIterations )
return( CRYPT_ERROR_NOTFOUND );
cryptInfoPtr->ctxConv.keySetupIterations = 0;
return( CRYPT_OK );
}
if( !cryptInfoPtr->ctxMAC.keySetupIterations )
return( CRYPT_ERROR_NOTFOUND );
cryptInfoPtr->ctxMAC.keySetupIterations = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_SALT:
assert( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( !cryptInfoPtr->ctxConv.saltLength )
return( CRYPT_ERROR_NOTFOUND );
zeroise( cryptInfoPtr->ctxConv.salt, CRYPT_MAX_HASHSIZE );
cryptInfoPtr->ctxConv.saltLength = 0;
return( CRYPT_OK );
}
if( !cryptInfoPtr->ctxMAC.saltLength )
return( CRYPT_ERROR_NOTFOUND );
zeroise( cryptInfoPtr->ctxMAC.salt, CRYPT_MAX_HASHSIZE );
cryptInfoPtr->ctxMAC.saltLength = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_LABEL:
if( !cryptInfoPtr->labelSize )
return( CRYPT_ERROR_NOTFOUND );
zeroise( cryptInfoPtr->label, cryptInfoPtr->labelSize );
cryptInfoPtr->labelSize = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_HASHVALUE:
assert( contextType == CONTEXT_HASH || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_HASH )
{
cryptInfoPtr->capabilityInfo->initFunction( cryptInfoPtr );
zeroise( cryptInfoPtr->ctxHash.hash, CRYPT_MAX_HASHSIZE );
cryptInfoPtr->ctxHash.done = FALSE;
return( CRYPT_OK );
}
cryptInfoPtr->capabilityInfo->initFunction( cryptInfoPtr );
zeroise( cryptInfoPtr->ctxMAC.mac, CRYPT_MAX_HASHSIZE );
cryptInfoPtr->ctxMAC.done = FALSE;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/* Handle a message sent to an encryption context */
static int contextMessageFunction( const CRYPT_CONTEXT cryptContext,
const RESOURCE_MESSAGE_TYPE message,
void *messageDataPtr,
const int messageValue )
{
CRYPT_INFO *cryptInfoPtr;
int status;
getCheckInternalResource( cryptContext, cryptInfoPtr, OBJECT_TYPE_CONTEXT );
/* Process destroy object messages */
if( message == RESOURCE_MESSAGE_DESTROY )
{
const CONTEXT_TYPE contextType = cryptInfoPtr->type;
/* 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 */
cryptInfoPtr->doAbort = TRUE;
krnlSendMessage( cryptContext, RESOURCE_IMESSAGE_GETATTRIBUTE,
&status, CRYPT_IATTRIBUTE_STATUS );
if( status & OBJECT_FLAG_BUSY )
{
/* Unlock the object so the background thread can access it.
Nothing else will get in because the object is in the
signalled state */
unlockResource( cryptInfoPtr );
/* Wait awhile and check whether we've left the busy state */
do
{
#ifdef __WIN32__
Sleep( 250 ); /* Wait 1/4s */
#endif /* __WIN32__ */
krnlSendMessage( cryptContext, RESOURCE_IMESSAGE_GETATTRIBUTE,
&status, CRYPT_IATTRIBUTE_STATUS );
}
while( status & OBJECT_FLAG_BUSY );
getCheckInternalResource( cryptContext, cryptInfoPtr, OBJECT_TYPE_CONTEXT );
}
/* Perform any algorithm-specific shutdown */
if( cryptInfoPtr->capabilityInfo != NULL && \
cryptInfoPtr->keyingInfoInited && \
cryptInfoPtr->capabilityInfo->endFunction != NULL )
cryptInfoPtr->capabilityInfo->endFunction( cryptInfoPtr );
/* Perform context-type-specific cleanup */
if( contextType == CONTEXT_PKC )
{
if( cryptInfoPtr->ctxPKC.param1 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param1 );
if( cryptInfoPtr->ctxPKC.param2 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param2 );
if( cryptInfoPtr->ctxPKC.param3 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param3 );
if( cryptInfoPtr->ctxPKC.param4 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param4 );
if( cryptInfoPtr->ctxPKC.param5 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param5 );
if( cryptInfoPtr->ctxPKC.param6 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param6 );
if( cryptInfoPtr->ctxPKC.param7 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param7 );
if( cryptInfoPtr->ctxPKC.param8 != NULL )
BN_clear_free( cryptInfoPtr->ctxPKC.param8 );
if( cryptInfoPtr->ctxPKC.montCTX1 != NULL )
BN_MONT_CTX_free( cryptInfoPtr->ctxPKC.montCTX1 );
if( cryptInfoPtr->ctxPKC.montCTX2 != NULL )
BN_MONT_CTX_free( cryptInfoPtr->ctxPKC.montCTX2 );
if( cryptInfoPtr->ctxPKC.montCTX3 != NULL )
BN_MONT_CTX_free( cryptInfoPtr->ctxPKC.montCTX3 );
if( cryptInfoPtr->ctxPKC.publicKeyInfo != NULL )
free( cryptInfoPtr->ctxPKC.publicKeyInfo );
}
/* Zeroise the context-type-specific information */
cryptInfoPtr->capabilityInfo = NULL;
cryptInfoPtr->type = CONTEXT_NONE;
zeroise( &cryptInfoPtr->keyingInfo, sizeof( cryptInfoPtr->keyingInfo ) );
cryptInfoPtr->keyingInfoInited = FALSE;
/* Delete the objects locking variables and the object itself */
deleteResourceLock( cryptInfoPtr );
if( needsSecureMemory( contextType ) )
krnlMemfree( ( void ** ) &cryptInfoPtr );
else
{
zeroise( cryptInfoPtr, sizeof( CRYPT_INFO ) );
free( cryptInfoPtr );
}
return( CRYPT_OK );
}
/* Process attribute get/set/delete messages */
if( isAttributeMessage( message ) )
{
if( message == RESOURCE_MESSAGE_GETATTRIBUTE )
status = processGetAttribute( cryptInfoPtr, messageDataPtr,
messageValue );
if( message == RESOURCE_MESSAGE_GETATTRIBUTE_S )
status = processGetAttributeS( cryptInfoPtr, messageDataPtr,
messageValue );
if( message == RESOURCE_MESSAGE_SETATTRIBUTE )
status = processSetAttribute( cryptInfoPtr, messageDataPtr,
messageValue );
if( message == RESOURCE_MESSAGE_SETATTRIBUTE_S )
status = processSetAttributeS( cryptInfoPtr, messageDataPtr,
messageValue );
if( message == RESOURCE_MESSAGE_DELETEATTRIBUTE )
status = processDeleteAttribute( cryptInfoPtr, messageValue );
unlockResourceExit( cryptInfoPtr, status );
}
/* Process action messages */
if( isActionMessage( message ) )
{
const CAPABILITY_INFO *capabilityInfoPtr = cryptInfoPtr->capabilityInfo;
int ( *cryptFunction )( CRYPT_INFO *cryptInfoPtr, void *buffer, int length );
const BOOLEAN isDLP = isDlpAlgo( capabilityInfoPtr->cryptAlgo );
const BOOLEAN isKeyx = isKeyxAlgo( capabilityInfoPtr->cryptAlgo );
BYTE data[ 8 ];
switch( message )
{
case RESOURCE_MESSAGE_CTX_ENCRYPT:
if( cryptInfoPtr->type == CONTEXT_CONV )
{
assert( isStreamCipher( cryptInfoPtr->capabilityInfo->cryptAlgo ) || \
!needsIV( cryptInfoPtr->ctxConv.mode ) ||
cryptInfoPtr->ctxConv.ivSet );
switch( cryptInfoPtr->ctxConv.mode )
{
case CRYPT_MODE_ECB:
assert( !( messageValue % capabilityInfoPtr->blockSize ) );
cryptFunction = capabilityInfoPtr->encryptFunction;
break;
case CRYPT_MODE_CBC:
assert( !( messageValue % capabilityInfoPtr->blockSize ) );
cryptFunction = capabilityInfoPtr->encryptCBCFunction;
break;
case CRYPT_MODE_CFB:
cryptFunction = capabilityInfoPtr->encryptCFBFunction;
break;
case CRYPT_MODE_OFB:
cryptFunction = capabilityInfoPtr->encryptOFBFunction;
break;
default:
assert( NOTREACHED );
}
}
else
cryptFunction = capabilityInfoPtr->encryptFunction;
assert( cryptFunction != NULL );
assert( !isDLP ||
( isKeyx && messageValue == sizeof( KEYAGREE_PARAMS ) ) || \
( !isKeyx && messageValue == sizeof( DLP_PARAMS ) ) );
if( messageValue >= 8 && !isKeyx )
memcpy( data, isDLP ? \
( ( DLP_PARAMS * ) messageDataPtr )->inParam1 : \
messageDataPtr, 8 );
status = cryptFunction( cryptInfoPtr, messageDataPtr,
messageValue );
if( cryptStatusOK( status ) && messageValue >= 8 && !isKeyx )
{
/* Check for a catastrophic failure of the en/decryption */
if( !memcmp( data, isDLP ? \
( ( DLP_PARAMS * ) messageDataPtr )->outParam : \
messageDataPtr, 8 ) )
status = CRYPT_ERROR_FAILED;
zeroise( data, 8 );
assert( cryptStatusOK( status ) );
}
break;
case RESOURCE_MESSAGE_CTX_DECRYPT:
if( cryptInfoPtr->type == CONTEXT_CONV )
{
assert( isStreamCipher( cryptInfoPtr->capabilityInfo->cryptAlgo ) || \
!needsIV( cryptInfoPtr->ctxConv.mode ) ||
cryptInfoPtr->ctxConv.ivSet );
switch( cryptInfoPtr->ctxConv.mode )
{
case CRYPT_MODE_ECB:
assert( !( messageValue % capabilityInfoPtr->blockSize ) );
cryptFunction = capabilityInfoPtr->decryptFunction;
break;
case CRYPT_MODE_CBC:
assert( !( messageValue % capabilityInfoPtr->blockSize ) );
cryptFunction = capabilityInfoPtr->decryptCBCFunction;
break;
case CRYPT_MODE_CFB:
cryptFunction = capabilityInfoPtr->decryptCFBFunction;
break;
case CRYPT_MODE_OFB:
cryptFunction = capabilityInfoPtr->decryptOFBFunction;
break;
default:
assert( NOTREACHED );
}
}
else
cryptFunction = capabilityInfoPtr->decryptFunction;
assert( cryptFunction != NULL );
status = cryptFunction( cryptInfoPtr, messageDataPtr,
messageValue );
break;
case RESOURCE_MESSAGE_CTX_SIGN:
assert( capabilityInfoPtr->signFunction != NULL );
status = capabilityInfoPtr->signFunction( cryptInfoPtr,
messageDataPtr, messageValue );
break;
case RESOURCE_MESSAGE_CTX_SIGCHECK:
assert( capabilityInfoPtr->sigCheckFunction != NULL );
status = capabilityInfoPtr->sigCheckFunction( cryptInfoPtr,
messageDataPtr, messageValue );
break;
case RESOURCE_MESSAGE_CTX_HASH:
assert( capabilityInfoPtr->encryptFunction != NULL );
status = capabilityInfoPtr->encryptFunction( cryptInfoPtr,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -