mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-26 20:05:38 +01:00
Clarify the use of ECDSA API
In the ecdsa.c sample application we don't use hashing, we use ecdsa directly on a buffer containing plain text. Although the text explains that it should be the message hash it still can be confusing. Any misunderstandings here are potentially very dangerous, because ECDSA truncates the message hash if necessary and this can lead to trivial signature forgeries if the API is misused and the message is passed directly to the function without hashing. This commit adds a hash computation step to the ecdsa.c sample application and clarification to the doxygen documentation of the ECDSA functions involved.
This commit is contained in:
parent
bbcef7e2c5
commit
5d96a3dcde
@ -16,6 +16,11 @@ Bugfix
|
|||||||
(rsa_rsaes_pkcs1_v15_decrypt(), rsa_rsaes_oaep_decrypt).
|
(rsa_rsaes_pkcs1_v15_decrypt(), rsa_rsaes_oaep_decrypt).
|
||||||
Found by Laurent Simon.
|
Found by Laurent Simon.
|
||||||
|
|
||||||
|
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 1.3.19 branch released 2017-03-08
|
= mbed TLS 1.3.19 branch released 2017-03-08
|
||||||
|
|
||||||
Security
|
Security
|
||||||
|
@ -26,6 +26,23 @@
|
|||||||
|
|
||||||
#include "ecp.h"
|
#include "ecp.h"
|
||||||
#include "md.h"
|
#include "md.h"
|
||||||
|
/*
|
||||||
|
* RFC 4492 page 20:
|
||||||
|
*
|
||||||
|
* Ecdsa-Sig-Value ::= SEQUENCE {
|
||||||
|
* r INTEGER,
|
||||||
|
* s INTEGER
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Size is at most
|
||||||
|
* 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
|
||||||
|
* twice that + 1 (tag) + 2 (len) for the sequence
|
||||||
|
* (assuming ECP_MAX_BYTES is less than 126 for r and s,
|
||||||
|
* and less than 124 (total len <= 255) for the sequence)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/** Maximum size of an ECDSA signature in bytes */
|
||||||
|
#define POLARSSL_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + POLARSSL_ECP_MAX_BYTES ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief ECDSA context structure
|
* \brief ECDSA context structure
|
||||||
@ -58,6 +75,10 @@ extern "C" {
|
|||||||
* \param f_rng RNG function
|
* \param f_rng RNG function
|
||||||
* \param p_rng RNG parameter
|
* \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,
|
* \return 0 if successful,
|
||||||
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
||||||
*/
|
*/
|
||||||
@ -78,6 +99,10 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s,
|
|||||||
* \param blen Length of buf
|
* \param blen Length of buf
|
||||||
* \param md_alg MD algorithm used to hash the message
|
* \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,
|
* \return 0 if successful,
|
||||||
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
||||||
*/
|
*/
|
||||||
@ -96,6 +121,10 @@ int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s,
|
|||||||
* \param r First integer of the signature
|
* \param r First integer of the signature
|
||||||
* \param s Second 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,
|
* \return 0 if successful,
|
||||||
* POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid
|
* POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid
|
||||||
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
||||||
@ -121,6 +150,10 @@ int ecdsa_verify( ecp_group *grp,
|
|||||||
* size of the curve used, plus 7 (eg. 71 bytes if a 256-bit
|
* size of the curve used, plus 7 (eg. 71 bytes if a 256-bit
|
||||||
* curve is used).
|
* curve is used).
|
||||||
*
|
*
|
||||||
|
* \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,
|
* \return 0 if successful,
|
||||||
* or a POLARSSL_ERR_ECP, POLARSSL_ERR_MPI or
|
* or a POLARSSL_ERR_ECP, POLARSSL_ERR_MPI or
|
||||||
* POLARSSL_ERR_ASN1 error code
|
* POLARSSL_ERR_ASN1 error code
|
||||||
@ -168,6 +201,10 @@ int ecdsa_write_signature_det( ecdsa_context *ctx,
|
|||||||
* \param sig Signature to read and verify
|
* \param sig Signature to read and verify
|
||||||
* \param slen Size of sig
|
* \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,
|
* \return 0 if successful,
|
||||||
* POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
|
* POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
|
||||||
* POLARSSL_ERR_ECP_SIG_LEN_MISTMATCH if the signature is
|
* POLARSSL_ERR_ECP_SIG_LEN_MISTMATCH if the signature is
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "polarssl/entropy.h"
|
#include "polarssl/entropy.h"
|
||||||
#include "polarssl/ctr_drbg.h"
|
#include "polarssl/ctr_drbg.h"
|
||||||
#include "polarssl/ecdsa.h"
|
#include "polarssl/ecdsa.h"
|
||||||
|
#include "polarssl/sha256.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
@ -102,16 +103,20 @@ int main( int argc, char *argv[] )
|
|||||||
ecdsa_context ctx_sign, ctx_verify;
|
ecdsa_context ctx_sign, ctx_verify;
|
||||||
entropy_context entropy;
|
entropy_context entropy;
|
||||||
ctr_drbg_context ctr_drbg;
|
ctr_drbg_context ctr_drbg;
|
||||||
unsigned char hash[] = "This should be the hash of a message.";
|
sha256_context sha256_ctx;
|
||||||
unsigned char sig[512];
|
unsigned char message[100];
|
||||||
|
unsigned char hash[32];
|
||||||
|
unsigned char sig[POLARSSL_ECDSA_MAX_LEN];
|
||||||
size_t sig_len;
|
size_t sig_len;
|
||||||
const char *pers = "ecdsa";
|
const char *pers = "ecdsa";
|
||||||
((void) argv);
|
((void) argv);
|
||||||
|
|
||||||
ecdsa_init( &ctx_sign );
|
ecdsa_init( &ctx_sign );
|
||||||
ecdsa_init( &ctx_verify );
|
ecdsa_init( &ctx_verify );
|
||||||
|
sha256_init( &sha256_ctx );
|
||||||
|
|
||||||
memset(sig, 0, sizeof( sig ) );
|
memset( sig, 0, sizeof( sig ) );
|
||||||
|
memset( message, 0x25, sizeof( message ) );
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
if( argc != 1 )
|
if( argc != 1 )
|
||||||
@ -155,9 +160,24 @@ int main( int argc, char *argv[] )
|
|||||||
dump_pubkey( " + Public key: ", &ctx_sign );
|
dump_pubkey( " + Public key: ", &ctx_sign );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sign some message hash
|
* Compute message hash
|
||||||
*/
|
*/
|
||||||
polarssl_printf( " . Signing message..." );
|
polarssl_printf( " . Signing message..." );
|
||||||
|
polarssl_printf( " . Computing message hash..." );
|
||||||
|
fflush( stdout );
|
||||||
|
|
||||||
|
sha256_starts( &sha256_ctx, 0 );
|
||||||
|
sha256_update( &sha256_ctx, message, sizeof( message ) );
|
||||||
|
sha256_finish( &sha256_ctx, hash );
|
||||||
|
|
||||||
|
polarssl_printf( " ok\n" );
|
||||||
|
|
||||||
|
dump_buf( " + Hash: ", hash, sizeof( hash ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sign message hash
|
||||||
|
*/
|
||||||
|
polarssl_printf( " . Signing message hash..." );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
|
|
||||||
if( ( ret = ecdsa_write_signature( &ctx_sign,
|
if( ( ret = ecdsa_write_signature( &ctx_sign,
|
||||||
@ -170,7 +190,6 @@ int main( int argc, char *argv[] )
|
|||||||
}
|
}
|
||||||
polarssl_printf( " ok (signature length = %u)\n", (unsigned int) sig_len );
|
polarssl_printf( " ok (signature length = %u)\n", (unsigned int) sig_len );
|
||||||
|
|
||||||
dump_buf( " + Hash: ", hash, sizeof hash );
|
|
||||||
dump_buf( " + Signature: ", sig, sig_len );
|
dump_buf( " + Signature: ", sig, sig_len );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -233,6 +252,7 @@ exit:
|
|||||||
ecdsa_free( &ctx_sign );
|
ecdsa_free( &ctx_sign );
|
||||||
ctr_drbg_free( &ctr_drbg );
|
ctr_drbg_free( &ctr_drbg );
|
||||||
entropy_free( &entropy );
|
entropy_free( &entropy );
|
||||||
|
sha256_free( &sha256_ctx );
|
||||||
|
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user