in source/core_pki_utils.c [131:210]
int8_t PKI_pkcs11SignatureTombedTLSSignature( uint8_t * pucSig,
size_t * pxSigLen )
{
int8_t xReturn = 0;
uint8_t * pucSigPtr = NULL;
uint8_t ucTemp[ 64 ] = { 0 }; /* A temporary buffer for the pre-formatted signature. */
if( ( pucSig == NULL ) || ( pxSigLen == NULL ) )
{
xReturn = FAILURE;
}
if( xReturn == 0 )
{
( void ) memcpy( ucTemp, pucSig, 64 );
/* The ASN.1 encoded signature has the format
* SEQUENCE LENGTH (of entire rest of signature)
* INTEGER LENGTH (of R component)
* INTEGER LENGTH (of S component)
*
* and a signature coming out of PKCS #11 C_Sign will have the format
* R[32] + S[32]
*/
pucSig[ 0 ] = 0x30; /* Sequence. */
pucSig[ 1 ] = 0x44; /* The minimum length the signature could be. */
pucSig[ 2 ] = 0x02; /* Integer. */
/*************** R Component. *******************/
/* If the first bit is one, pre-append a 00 byte.
* This prevents the number from being interpreted as negative. */
if( ( ucTemp[ 0 ] & 0x80UL ) == 0x80UL )
{
pucSig[ 1 ]++; /* Increment the length of the structure to account for the 0x00 pad. */
pucSig[ 3 ] = 0x21; /* Increment the length of the R value to account for the 0x00 pad. */
pucSig[ 4 ] = 0x0; /* Write the 0x00 pad. */
( void ) memcpy( &pucSig[ 5 ], ucTemp, 32 ); /* Copy the 32-byte R value. */
pucSigPtr = pucSig + 33; /* Increment the pointer to compensate for padded R length. */
}
else
{
pucSig[ 3 ] = 0x20; /* R length with be 32 bytes. */
( void ) memcpy( &pucSig[ 4 ], ucTemp, 32 ); /* Copy 32 bytes of R into the signature buffer. */
pucSigPtr = pucSig + 32; /* Increment the pointer for 32 byte R length. */
}
pucSigPtr += 4; /* Increment the pointer to offset the SEQUENCE, LENGTH, R-INTEGER, LENGTH. */
pucSigPtr[ 0 ] = 0x02; /* INTEGER tag for S. */
pucSigPtr += 1; /* Increment over S INTEGER tag. */
/******************* S Component. ****************/
/* If the first bit is one, pre-append a 00 byte.
* This prevents the number from being interpreted as negative. */
if( ( ucTemp[ 32 ] & 0x80UL ) == 0x80UL )
{
pucSig[ 1 ]++; /* Increment the length of the structure to account for the 0x00 pad. */
pucSigPtr[ 0 ] = 0x21; /* Increment the length of the S value to account for the 0x00 pad. */
pucSigPtr[ 1 ] = 0x00; /* Write the 0x00 pad. */
pucSigPtr += 2; /* pucSigPtr was pointing at the S-length. Increment by 2 to hop over length and 0 padding. */
( void ) memcpy( pucSigPtr, &ucTemp[ 32 ], 32 ); /* Copy the S value. */
}
else
{
pucSigPtr[ 0 ] = 0x20; /* S length will be 32 bytes. */
pucSigPtr++; /* Hop pointer over the length byte. */
( void ) memcpy( pucSigPtr, &ucTemp[ 32 ], 32 ); /* Copy the S value. */
}
/* The total signature length is the length of the R and S integers plus 2 bytes for
* the SEQUENCE and LENGTH wrapping the entire struct. */
*pxSigLen = pucSig[ 1 ] + 2UL;
}
return xReturn;
}