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.
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index 3666ffe..c0088db 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -236,6 +236,28 @@
#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
*
* \param ctx ECDSA context
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 826fefe..fdd0afb 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -289,22 +289,22 @@
/*
* 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 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 @@
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 );
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index b730953..8a96c02 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -142,7 +142,7 @@
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 @@
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 */