static int32_t privateKeySigningCallback()

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;
}