diff --git a/ChangeLog b/ChangeLog index 88e2bc92b..a63658b7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ mbed TLS ChangeLog (Sorted per branch, date) +Changes + * Clarify ECDSA documentation and improve the sample code to avoid + misunderstandings and potentially dangerous use of the API. Pointed out + by Jean-Philippe Aumasson. + + = mbed TLS x.x.x branch released xxxx-xx-xx Bugfix diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h index 52827d8d1..a277715b3 100644 --- a/include/mbedtls/ecdsa.h +++ b/include/mbedtls/ecdsa.h @@ -69,6 +69,10 @@ extern "C" { * \param f_rng RNG function * \param p_rng RNG parameter * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code */ @@ -89,6 +93,10 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, * \param blen Length of buf * \param md_alg MD algorithm used to hash the message * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code */ @@ -107,6 +115,10 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi * \param r First integer of the signature * \param s Second integer of the signature * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.4 step 3. + * * \return 0 if successful, * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code @@ -120,7 +132,7 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, * serialized as defined in RFC 4492 page 20. * (Not thread-safe to use same context in multiple threads) * - * \note The deterministice version (RFC 6979) is used if + * \note The deterministic version (RFC 6979) is used if * MBEDTLS_ECDSA_DETERMINISTIC is defined. * * \param ctx ECDSA context @@ -136,6 +148,10 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, * size of the curve used, plus 9 (eg. 73 bytes if a 256-bit * curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe. * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or * MBEDTLS_ERR_ASN1_XXX error code @@ -172,6 +188,10 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t * size of the curve used, plus 9 (eg. 73 bytes if a 256-bit * curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe. * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or * MBEDTLS_ERR_ASN1_XXX error code @@ -193,6 +213,10 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, * \param sig Signature to read and verify * \param slen Size of sig * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.4 step 3. + * * \return 0 if successful, * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid, * MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if the signature is diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c index 069d31202..c3ce56a0f 100644 --- a/programs/pkey/ecdsa.c +++ b/programs/pkey/ecdsa.c @@ -37,6 +37,7 @@ #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/ecdsa.h" +#include "mbedtls/sha256.h" #include #endif @@ -101,8 +102,10 @@ int main( int argc, char *argv[] ) mbedtls_ecdsa_context ctx_sign, ctx_verify; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; - unsigned char hash[] = "This should be the hash of a message."; - unsigned char sig[512]; + mbedtls_sha256_context sha256_ctx; + unsigned char message[100]; + unsigned char hash[32]; + unsigned char sig[MBEDTLS_ECDSA_MAX_LEN]; size_t sig_len; const char *pers = "ecdsa"; ((void) argv); @@ -110,8 +113,10 @@ int main( int argc, char *argv[] ) mbedtls_ecdsa_init( &ctx_sign ); mbedtls_ecdsa_init( &ctx_verify ); mbedtls_ctr_drbg_init( &ctr_drbg ); + mbedtls_sha256_init( &sha256_ctx ); - memset(sig, 0, sizeof( sig ) ); + memset( sig, 0, sizeof( sig ) ); + memset( message, 0x25, sizeof( message ) ); ret = 1; if( argc != 1 ) @@ -155,9 +160,23 @@ int main( int argc, char *argv[] ) dump_pubkey( " + Public key: ", &ctx_sign ); /* - * Sign some message hash + * Compute message hash */ - mbedtls_printf( " . Signing message..." ); + mbedtls_printf( " . Computing message hash..." ); + fflush( stdout ); + + mbedtls_sha256_starts( &sha256_ctx, 0 ); + mbedtls_sha256_update( &sha256_ctx, message, sizeof( message ) ); + mbedtls_sha256_finish( &sha256_ctx, hash ); + + mbedtls_printf( " ok\n" ); + + dump_buf( " + Hash: ", hash, sizeof( hash ) ); + + /* + * Sign message hash + */ + mbedtls_printf( " . Signing message hash..." ); fflush( stdout ); if( ( ret = mbedtls_ecdsa_write_signature( &ctx_sign, MBEDTLS_MD_SHA256, @@ -170,7 +189,6 @@ int main( int argc, char *argv[] ) } mbedtls_printf( " ok (signature length = %u)\n", (unsigned int) sig_len ); - dump_buf( " + Hash: ", hash, sizeof hash ); dump_buf( " + Signature: ", sig, sig_len ); /* @@ -224,6 +242,7 @@ exit: mbedtls_ecdsa_free( &ctx_sign ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); + mbedtls_sha256_free( &sha256_ctx ); return( ret ); }