int8_t PKI_mbedTLSSignatureToPkcs11Signature()

in source/core_pki_utils.c [43:124]


int8_t PKI_mbedTLSSignatureToPkcs11Signature( uint8_t * pxSignaturePKCS,
                                              const uint8_t * pxMbedSignature )
{
    int8_t xReturn = 0;
    const uint8_t * pxNextLength = NULL;
    uint8_t ucSigComponentLength;

    if( ( pxSignaturePKCS == NULL ) || ( pxMbedSignature == NULL ) )
    {
        xReturn = FAILURE;
    }

    if( xReturn == 0 )
    {
        /* The signature has the format
         * SEQUENCE LENGTH (of entire rest of signature)
         *      INTEGER LENGTH  (of R component)
         *      INTEGER LENGTH  (of S component)
         */

        /* The 4th byte contains the length of the R component */
        ucSigComponentLength = pxMbedSignature[ 3 ];

        /* The new signature will be 64 bytes long (32 bytes for R, 32 bytes for S).
         * Zero this buffer out in case a component is shorter than 32 bytes. */
        ( void ) memset( pxSignaturePKCS, 0, 64 );

        /********* R Component. *********/

        /* R components are represented by mbedTLS as 33 bytes when the first bit is zero to avoid any sign confusion. */
        if( ucSigComponentLength == 33UL )
        {
            /* Chop off the leading zero.  The first 4 bytes were SEQUENCE, LENGTH, INTEGER, LENGTH, 0x00 padding.  */
            ( void ) memcpy( pxSignaturePKCS, &pxMbedSignature[ 5 ], 32 );
            /* SEQUENCE, LENGTH, INTEGER, LENGTH, leading zero, R, S's integer tag */
            pxNextLength = &pxMbedSignature[ 5U + 32U + 1U ];
        }
        else if( ucSigComponentLength <= 32UL )
        {
            /* The R component is 32 bytes or less.  Copy so that it is properly represented as a 32 byte value,
             * leaving leading 0 pads at beginning if necessary. */
            ( void ) memcpy( &pxSignaturePKCS[ 32UL - ucSigComponentLength ],  /* If the R component is less than 32 bytes, leave the leading zeros. */
                             &pxMbedSignature[ 4 ],                            /* SEQUENCE, LENGTH, INTEGER, LENGTH, (R component begins as the 5th byte) */
                             ucSigComponentLength );
            pxNextLength = &pxMbedSignature[ 4U + ucSigComponentLength + 1U ]; /* Move the pointer to get rid of
                                                                                * SEQUENCE, LENGTH, INTEGER, LENGTH, R Component, S integer tag. */
        }
        else
        {
            xReturn = FAILURE;
        }

        /********** S Component. ***********/

        if( xReturn != FAILURE )
        {
            /* Now pxNextLength is pointing to the length of the S component. */
            ucSigComponentLength = pxNextLength[ 0 ];

            if( ucSigComponentLength == 33UL )
            {
                ( void ) memcpy( &pxSignaturePKCS[ 32 ],
                                 &pxNextLength[ 2 ], /*LENGTH (of S component), 0x00 padding, S component is 3rd byte - we want to skip the leading zero. */
                                 32 );
            }
            else if( ucSigComponentLength <= 32UL )
            {
                /* The S component is 32 bytes or less.  Copy so that it is properly represented as a 32 byte value,
                 * leaving leading 0 pads at beginning if necessary. */
                ( void ) memcpy( &pxSignaturePKCS[ 64UL - ucSigComponentLength ],
                                 &pxNextLength[ 1 ],
                                 ucSigComponentLength );
            }
            else
            {
                xReturn = FAILURE;
            }
        }
    }

    return xReturn;
}