mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-26 12:15: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,
|
const mbedtls_mpi *s, unsigned char *sig,
|
||||||
size_t *slen, size_t ssize );
|
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
|
* \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 *p = (unsigned char *) sig;
|
||||||
unsigned char *buf_ptr;
|
unsigned char *buf_ptr;
|
||||||
const unsigned char *end = sig + ssize;
|
const unsigned char *end = sig + ssize;
|
||||||
size_t len, bytes_skipped, i;
|
size_t len, bytes_skipped;
|
||||||
|
|
||||||
if( 2 * byte_len > bufsize )
|
if( 2 * byte_len > bufsize )
|
||||||
{
|
{
|
||||||
@ -335,10 +335,7 @@ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig,
|
|||||||
}
|
}
|
||||||
*buflen = len - bytes_skipped;
|
*buflen = len - bytes_skipped;
|
||||||
|
|
||||||
for( i = bytes_skipped; i < len; i++ )
|
memmove(buf_ptr, &p[bytes_skipped], *buflen);
|
||||||
{
|
|
||||||
buf_ptr[i - bytes_skipped] = p[i];
|
|
||||||
}
|
|
||||||
p += len;
|
p += len;
|
||||||
buf_ptr += *buflen;
|
buf_ptr += *buflen;
|
||||||
|
|
||||||
@ -358,11 +355,7 @@ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*buflen += len - bytes_skipped;
|
*buflen += len - bytes_skipped;
|
||||||
|
memmove(buf_ptr, &p[bytes_skipped], len - bytes_skipped);
|
||||||
for( i = bytes_skipped; i < len; i++ )
|
|
||||||
{
|
|
||||||
buf_ptr[i - bytes_skipped] = p[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return( ret );
|
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 );
|
memset( sig + len, 0, ssize - len );
|
||||||
*slen = 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 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,9 +191,7 @@ static int pkcs11_sign( void *ctx_arg,
|
|||||||
*/
|
*/
|
||||||
uint16_t byte_len = ( ( ctx->bit_length + 7 ) / 8 );
|
uint16_t byte_len = ( ( ctx->bit_length + 7 ) / 8 );
|
||||||
size_t sig_size = MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->bit_length );
|
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;
|
rv = CKR_OK;
|
||||||
if( ck_sig_len != 2 * byte_len )
|
if( ck_sig_len != 2 * byte_len )
|
||||||
{
|
{
|
||||||
@ -201,22 +199,15 @@ static int pkcs11_sign( void *ctx_arg,
|
|||||||
rv = CKR_GENERAL_ERROR;
|
rv = CKR_GENERAL_ERROR;
|
||||||
goto ecdsa_exit;
|
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 signature buffer is guaranteed to have enough room for
|
||||||
the encoded signature by the pk_sign interface. */
|
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;
|
rv = CKR_GENERAL_ERROR;
|
||||||
goto ecdsa_exit;
|
goto ecdsa_exit;
|
||||||
}
|
}
|
||||||
ecdsa_exit:
|
ecdsa_exit:
|
||||||
mbedtls_mpi_free( &r );
|
|
||||||
mbedtls_mpi_free( &s );
|
|
||||||
if( rv != CKR_OK )
|
if( rv != CKR_OK )
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user