in lib/FreeRTOS/network_transport/freertos_plus_tcp/using_mbedtls_pkcs11/using_mbedtls_pkcs11.c [675:766]
static int32_t privateKeySigningCallback( void * pvContext,
mbedtls_md_type_t xMdAlg,
const unsigned char * pucHash,
size_t xHashLen,
unsigned char * pucSig,
size_t * pxSigLen,
int32_t ( * piRng )( void *,
unsigned char *,
size_t ),
void * pvRng )
{
CK_RV xResult = CKR_OK;
int32_t lFinalResult = 0;
SSLContext_t * pxTLSContext = ( SSLContext_t * ) pvContext;
CK_MECHANISM xMech = { 0 };
CK_BYTE xToBeSigned[ 256 ];
CK_ULONG xToBeSignedLen = sizeof( xToBeSigned );
/* Unreferenced parameters. */
( void ) ( piRng );
( void ) ( pvRng );
( void ) ( xMdAlg );
/* Sanity check buffer length. */
if( xHashLen > sizeof( xToBeSigned ) )
{
xResult = CKR_ARGUMENTS_BAD;
}
/* Format the hash data to be signed. */
if( CKK_RSA == pxTLSContext->xKeyType )
{
xMech.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. */
xResult = vAppendSHA256AlgorithmIdentifierSequence( ( uint8_t * ) pucHash, xToBeSigned );
xToBeSignedLen = pkcs11RSA_SIGNATURE_INPUT_LENGTH;
}
else if( CKK_EC == pxTLSContext->xKeyType )
{
xMech.mechanism = CKM_ECDSA;
memcpy( xToBeSigned, pucHash, xHashLen );
xToBeSignedLen = xHashLen;
}
else
{
xResult = CKR_ARGUMENTS_BAD;
}
if( CKR_OK == xResult )
{
/* Use the PKCS#11 module to sign. */
xResult = pxTLSContext->pxP11FunctionList->C_SignInit( pxTLSContext->xP11Session,
&xMech,
pxTLSContext->xP11PrivateKey );
}
if( CKR_OK == xResult )
{
*pxSigLen = sizeof( xToBeSigned );
xResult = pxTLSContext->pxP11FunctionList->C_Sign( ( CK_SESSION_HANDLE ) pxTLSContext->xP11Session,
xToBeSigned,
xToBeSignedLen,
pucSig,
( CK_ULONG_PTR ) pxSigLen );
}
if( ( xResult == CKR_OK ) && ( CKK_EC == pxTLSContext->xKeyType ) )
{
/* 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( *pxSigLen != pkcs11ECDSA_P256_SIGNATURE_LENGTH )
{
xResult = CKR_FUNCTION_FAILED;
}
if( xResult == CKR_OK )
{
PKI_pkcs11SignatureTombedTLSSignature( pucSig, pxSigLen );
}
}
if( xResult != CKR_OK )
{
LogError( ( "Failed to sign message using PKCS #11 with error code %02X.", xResult ) );
}
return lFinalResult;
}