Expose ecdsa_signature_to_asn1

Expose ecdsa_signature_to_asn1 in the API. It's useful when converting
between RFC 4492 format and other representations that might be used
in external crypto processors.
This commit is contained in:
Gilles Peskine 2017-11-02 17:14:18 +01:00 committed by Andrzej Kurek
parent 9a8bb67935
commit bce41d373a
3 changed files with 38 additions and 13 deletions

View file

@ -235,6 +235,28 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief Convert a signature from numbers to ASN.1
*
* \param r First number of the signature
* \param s Second number of the signature
* \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 ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t *slen,
size_t ssize );
/**
* \brief Read and verify an ECDSA signature
*

View file

@ -289,22 +289,22 @@ cleanup:
/*
* Convert a signature (given by context) to ASN.1
*/
static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t *slen )
int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t *slen, size_t ssize )
{
int ret;
unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
unsigned char *p = buf + sizeof( buf );
unsigned char *p = sig + ssize;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, sig, s ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, sig, r ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
memcpy( sig, p, len );
memmove( sig, p, len );
memset( sig + len, 0, ssize - len );
*slen = len;
return( 0 );
@ -321,6 +321,7 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
{
int ret;
mbedtls_mpi r, s;
const size_t ssize = MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->grp.pbits );
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
@ -338,7 +339,7 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
hash, hlen, f_rng, p_rng ) );
#endif
MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen, ssize ) );
cleanup:
mbedtls_mpi_free( &r );

View file

@ -142,7 +142,7 @@ void ecdsa_write_read_random( int id )
rnd_pseudo_info rnd_info;
unsigned char hash[32];
unsigned char sig[200];
size_t sig_len, i;
size_t sig_len, max_sig_len, i;
mbedtls_ecdsa_init( &ctx );
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
@ -162,8 +162,10 @@ void ecdsa_write_read_random( int id )
TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
sig, sig_len ) == 0 );
/* check we didn't write past the announced length */
for( i = sig_len; i < sizeof( sig ); i++ )
/* check we didn't write past the maximum length */
max_sig_len = MBEDTLS_ECDSA_MAX_SIG_LEN( ctx.grp.pbits );
TEST_ASSERT( sig_len <= max_sig_len );
for( i = max_sig_len; i < sizeof( sig ); i++ )
TEST_ASSERT( sig[i] == 0x2a );
/* try verification with invalid length */