mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-22 13:25:41 +01:00
ECDSA: Add mbedtls_raw_ecdsa_signature_to_asn1 without MPI usage
Refactor mbedtls_ecdsa_signature_to_raw to allow overlapping buffers
This commit is contained in:
parent
dfedd825c8
commit
b91a393a31
@ -280,6 +280,29 @@ int mbedtls_ecdsa_signature_to_asn1( const mbedtls_mpi *r,
|
||||
const mbedtls_mpi *s, unsigned char *sig,
|
||||
size_t *slen, size_t ssize );
|
||||
|
||||
/**
|
||||
* \brief Convert a signature from a raw representation to ASN.1
|
||||
*
|
||||
* \param r First number of the signature
|
||||
* \param s Second number of the signature
|
||||
* \param num_len Length of each number in bytes
|
||||
* \param sig Buffer that will hold the signature
|
||||
* \param slen Length of the signature written
|
||||
* \param ssize Size of the sig buffer
|
||||
*
|
||||
* \note The size of the buffer \c ssize should be at least
|
||||
* `MBEDTLS_ECDSA_MAX_SIG_LEN(grp->pbits)` bytes long if
|
||||
* the signature was produced from curve \c grp,
|
||||
* otherwise this function will return an error.
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* or a MBEDTLS_ERR_MPI_XXX or MBEDTLS_ERR_ASN1_XXX error code
|
||||
*
|
||||
*/
|
||||
int mbedtls_raw_ecdsa_signature_to_asn1(const unsigned char *r,
|
||||
const unsigned char *s, uint16_t num_len,
|
||||
unsigned char *sig, size_t *slen, size_t ssize );
|
||||
|
||||
/**
|
||||
* \brief Read and verify an ECDSA signature
|
||||
*
|
||||
|
@ -298,7 +298,7 @@ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig,
|
||||
unsigned char *p = (unsigned char *) sig;
|
||||
unsigned char *buf_ptr;
|
||||
const unsigned char *end = sig + ssize;
|
||||
size_t len, bytes_skipped, i;
|
||||
size_t len, bytes_skipped;
|
||||
|
||||
if( 2 * byte_len > bufsize )
|
||||
{
|
||||
@ -335,10 +335,7 @@ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig,
|
||||
}
|
||||
*buflen = len - bytes_skipped;
|
||||
|
||||
for( i = bytes_skipped; i < len; i++ )
|
||||
{
|
||||
buf_ptr[i - bytes_skipped] = p[i];
|
||||
}
|
||||
memmove(buf_ptr, &p[bytes_skipped], *buflen);
|
||||
p += len;
|
||||
buf_ptr += *buflen;
|
||||
|
||||
@ -358,11 +355,7 @@ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig,
|
||||
}
|
||||
|
||||
*buflen += len - bytes_skipped;
|
||||
|
||||
for( i = bytes_skipped; i < len; i++ )
|
||||
{
|
||||
buf_ptr[i - bytes_skipped] = p[i];
|
||||
}
|
||||
memmove(buf_ptr, &p[bytes_skipped], len - bytes_skipped);
|
||||
|
||||
return( ret );
|
||||
}
|
||||
@ -388,6 +381,76 @@ int mbedtls_ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
|
||||
memset( sig + len, 0, ssize - len );
|
||||
*slen = len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_raw_ecdsa_signature_to_asn1( const unsigned char *r,
|
||||
const unsigned char *s, uint16_t num_len,
|
||||
unsigned char *sig, size_t *slen, size_t ssize )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *p = sig + ssize;
|
||||
size_t total_len = 0;
|
||||
size_t padding_len = 0;
|
||||
|
||||
/*
|
||||
* Step 1: write S
|
||||
*/
|
||||
memmove( p - num_len, s, num_len );
|
||||
p -= num_len;
|
||||
total_len += num_len;
|
||||
if( *p & 0x80 )
|
||||
{
|
||||
if( p - sig < 1 )
|
||||
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--p = 0x00;
|
||||
padding_len += 1;
|
||||
}
|
||||
total_len += padding_len;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_len( &p, sig,
|
||||
num_len + padding_len ) );
|
||||
MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_tag( &p, sig,
|
||||
MBEDTLS_ASN1_INTEGER ) );
|
||||
|
||||
padding_len = 0;
|
||||
|
||||
/*
|
||||
* Step 2: write R
|
||||
*/
|
||||
memmove( p - num_len, r, num_len );
|
||||
p -= num_len;
|
||||
total_len += num_len;
|
||||
if( *p & 0x80 )
|
||||
{
|
||||
if( p - sig < 1 )
|
||||
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
*--p = 0x00;
|
||||
padding_len += 1;
|
||||
}
|
||||
total_len += padding_len;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_len( &p, sig,
|
||||
num_len + padding_len ) );
|
||||
MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_tag( &p, sig,
|
||||
MBEDTLS_ASN1_INTEGER ) );
|
||||
|
||||
/*
|
||||
* Step 3: write rest of the data
|
||||
*/
|
||||
MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_len( &p, sig, total_len ) );
|
||||
MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_tag( &p, sig,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
|
||||
|
||||
/*
|
||||
* Step 4: move to the beginning of the buffer, zeroize the rest
|
||||
*/
|
||||
memmove( sig, p, total_len );
|
||||
memset( sig + total_len, 0, ssize - total_len );
|
||||
*slen = total_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -191,9 +191,7 @@ static int pkcs11_sign( void *ctx_arg,
|
||||
*/
|
||||
uint16_t byte_len = ( ( ctx->bit_length + 7 ) / 8 );
|
||||
size_t sig_size = MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->bit_length );
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init( &r );
|
||||
mbedtls_mpi_init( &s );
|
||||
|
||||
rv = CKR_OK;
|
||||
if( ck_sig_len != 2 * byte_len )
|
||||
{
|
||||
@ -201,22 +199,15 @@ static int pkcs11_sign( void *ctx_arg,
|
||||
rv = CKR_GENERAL_ERROR;
|
||||
goto ecdsa_exit;
|
||||
}
|
||||
if( mbedtls_mpi_read_binary( &r, sig, byte_len ) != 0 ||
|
||||
mbedtls_mpi_read_binary( &s, sig + byte_len, byte_len ) != 0 )
|
||||
{
|
||||
rv = CKR_HOST_MEMORY;
|
||||
goto ecdsa_exit;
|
||||
}
|
||||
|
||||
/* The signature buffer is guaranteed to have enough room for
|
||||
the encoded signature by the pk_sign interface. */
|
||||
if( mbedtls_ecdsa_signature_to_asn1( &r, &s, sig, sig_len, sig_size ) != 0 )
|
||||
if( mbedtls_raw_ecdsa_signature_to_asn1( sig, sig + byte_len, byte_len, sig, sig_len, sig_size ) != 0 )
|
||||
{
|
||||
rv = CKR_GENERAL_ERROR;
|
||||
goto ecdsa_exit;
|
||||
}
|
||||
ecdsa_exit:
|
||||
mbedtls_mpi_free( &r );
|
||||
mbedtls_mpi_free( &s );
|
||||
if( rv != CKR_OK )
|
||||
goto exit;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user