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