CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey )
{
CK_BBOOL xIsPrivate = ( CK_BBOOL ) CK_TRUE;
CK_OBJECT_HANDLE xPalHandle;
CK_BYTE_PTR pxLabel = NULL;
CK_ULONG xLabelLength = 0;
mbedtls_pk_type_t xKeyType;
P11Session_t * pxSession = prvSessionPointerFromHandle( hSession );
CK_RV xResult = prvCheckValidSessionAndModule( pxSession );
CK_BYTE_PTR pulKeyData = NULL;
CK_ULONG ulKeyDataLength = 0;
int32_t lMbedTLSResult = 0;
if( NULL == pMechanism )
{
LogError( ( "Failed to initialize sign operation. NULL pointer to "
"signing mechanism provided." ) );
xResult = CKR_ARGUMENTS_BAD;
}
if( ( xResult == CKR_OK ) && ( prvOperationActive( pxSession ) == ( CK_BBOOL ) CK_TRUE ) )
{
LogError( ( "Failed to initialize sign operation. Operation already active." ) );
xResult = CKR_OPERATION_ACTIVE;
}
if( xResult == CKR_OK )
{
prvFindObjectInListByHandle( hKey,
&xPalHandle,
&pxLabel,
&xLabelLength );
if( xPalHandle != CK_INVALID_HANDLE )
{
if( xResult != CKR_OK )
{
LogError( ( "Failed to initialize sign operation. Unable to "
"retrieve value of private key for signing 0x%0lX.", ( unsigned long int ) xResult ) );
xResult = CKR_KEY_HANDLE_INVALID;
}
}
else
{
LogDebug( ( "Could not find PKCS #11 PAL Handle." ) );
xResult = CKR_KEY_HANDLE_INVALID;
}
}
if( xResult == CKR_OK )
{
if( xIsPrivate != ( CK_BBOOL ) CK_TRUE )
{
LogError( ( "Failed to initialize sign operation. Sign operation "
"attempted with public key." ) );
xResult = CKR_KEY_TYPE_INCONSISTENT;
}
}
if( xResult == CKR_OK )
{
if( 0 == mbedtls_mutex_lock( &pxSession->xSignMutex ) )
{
if( ( pxSession->xSignKeyHandle == CK_INVALID_HANDLE ) || ( pxSession->xSignKeyHandle != hKey ) )
{
pxSession->xSignKeyHandle = CK_INVALID_HANDLE;
mbedtls_pk_free( &pxSession->xSignKey );
mbedtls_pk_init( &pxSession->xSignKey );
lMbedTLSResult = mbedtls_pk_parse_key( &pxSession->xSignKey, pulKeyData, ulKeyDataLength, NULL, 0 );
if( lMbedTLSResult != 0 )
{
LogError( ( "Failed to initialize sign operation. "
"mbedtls_pk_parse_key failed: mbed TLS error = %s : %s.",
mbedtlsHighLevelCodeOrDefault( lMbedTLSResult ),
mbedtlsLowLevelCodeOrDefault( lMbedTLSResult ) ) );
xResult = CKR_KEY_HANDLE_INVALID;
}
else
{
pxSession->xSignKeyHandle = hKey;
}
}
( void ) mbedtls_mutex_unlock( &pxSession->xSignMutex );
}
else
{
LogError( ( "Failed to initialize sign operation. Could not "
"take xSignMutex." ) );
xResult = CKR_CANT_LOCK;
}
}
if( xResult == CKR_OK )
{
xKeyType = mbedtls_pk_get_type( &pxSession->xSignKey );
if( pMechanism->mechanism == CKM_RSA_PKCS )
{
if( xKeyType != MBEDTLS_PK_RSA )
{
LogError( ( "Failed to initialize sign operation. Signing key "
"type (0x%0lX) does not match RSA mechanism.", ( unsigned long int ) xKeyType ) );
xResult = CKR_KEY_TYPE_INCONSISTENT;
}
}
else if( pMechanism->mechanism == CKM_ECDSA )
{
if( ( xKeyType != MBEDTLS_PK_ECDSA ) && ( xKeyType != MBEDTLS_PK_ECKEY ) )
{
LogError( ( "Failed to initialize sign operation. Signing key "
"type (0x%0lX) does not match ECDSA mechanism.", ( unsigned long int ) xKeyType ) );
xResult = CKR_KEY_TYPE_INCONSISTENT;
}
}
else
{
LogError( ( "Failed to initialize sign operation. Unsupported "
"mechanism type (0x%0lX).", ( unsigned long int ) pMechanism->mechanism ) );
xResult = CKR_MECHANISM_INVALID;
}
}
if( xResult == CKR_OK )
{
pxSession->xOperationSignMechanism = pMechanism->mechanism;
LogDebug( ( "Successfully started sign operation." ) );
}
return xResult;
}