in platform/posix/transport/src/mbedtls_pkcs11_posix.c [665:761]
static int32_t privateKeySigningCallback( void * pContext,
mbedtls_md_type_t mdAlg,
const unsigned char * pHash,
size_t hashLen,
unsigned char * pSig,
size_t * pSigLen,
int32_t ( *pRng )( void *,
unsigned char *,
size_t ),
void * pRngContext )
{
CK_RV ret = CKR_OK;
int32_t result = 0;
MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context = ( MbedtlsPkcs11Context_t * ) pContext;
CK_MECHANISM mech = { 0 };
/* Buffer big enough to hold data to be signed. */
CK_BYTE toBeSigned[ 256 ];
CK_ULONG toBeSignedLen = sizeof( toBeSigned );
/* Unreferenced parameters. */
( void ) ( pRng );
( void ) ( pRngContext );
( void ) ( mdAlg );
assert( pContext != NULL );
assert( pHash != NULL );
assert( pSigLen != NULL );
/* Sanity check buffer length. */
if( hashLen > sizeof( toBeSigned ) )
{
ret = CKR_ARGUMENTS_BAD;
}
/* Format the hash data to be signed. */
if( pMbedtlsPkcs11Context->keyType == CKK_RSA )
{
mech.mechanism = CKM_RSA_PKCS;
/* mbedTLS expects hashed data without padding, but PKCS #11 C_Sign function performs a hash
* & sign if hash algorithm is specified. This helper function applies padding
* indicating data was hashed with SHA-256 while still allowing pre-hashed data to
* be provided. */
ret = vAppendSHA256AlgorithmIdentifierSequence( ( const uint8_t * ) pHash, toBeSigned );
toBeSignedLen = pkcs11RSA_SIGNATURE_INPUT_LENGTH;
}
else if( pMbedtlsPkcs11Context->keyType == CKK_EC )
{
mech.mechanism = CKM_ECDSA;
memcpy( toBeSigned, pHash, hashLen );
toBeSignedLen = hashLen;
}
else
{
ret = CKR_ARGUMENTS_BAD;
}
if( ret == CKR_OK )
{
/* Use the PKCS #11 module to sign. */
ret = pMbedtlsPkcs11Context->pP11FunctionList->C_SignInit( pMbedtlsPkcs11Context->p11Session,
&mech,
pMbedtlsPkcs11Context->p11PrivateKey );
}
if( ret == CKR_OK )
{
*pSigLen = sizeof( toBeSigned );
ret = pMbedtlsPkcs11Context->pP11FunctionList->C_Sign( pMbedtlsPkcs11Context->p11Session,
toBeSigned,
toBeSignedLen,
pSig,
( CK_ULONG_PTR ) pSigLen );
}
if( ( ret == CKR_OK ) && ( pMbedtlsPkcs11Context->keyType == CKK_EC ) )
{
/* PKCS #11 for P256 returns a 64-byte signature with 32 bytes for R and 32 bytes for S.
* This must be converted to an ASN.1 encoded array. */
if( *pSigLen != pkcs11ECDSA_P256_SIGNATURE_LENGTH )
{
ret = CKR_FUNCTION_FAILED;
}
if( ret == CKR_OK )
{
PKI_pkcs11SignatureTombedTLSSignature( pSig, pSigLen );
}
}
if( ret != CKR_OK )
{
LogError( ( "Failed to sign message using PKCS #11 with error code %lu.", ( unsigned long ) ret ) );
}
return result;
}