mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-29 00:04:17 +01:00
Remove potential timing leak in ecdsa_sign()
This commit is contained in:
parent
6b0d268bc9
commit
dd75c3183b
@ -2,6 +2,10 @@ PolarSSL ChangeLog (Sorted per branch, date)
|
|||||||
|
|
||||||
= PolarSSL 1.3 branch
|
= PolarSSL 1.3 branch
|
||||||
|
|
||||||
|
Security
|
||||||
|
* Avoid potential timing leak in ecdsa_sign() by blinding modular division.
|
||||||
|
(Found by Watson Ladd.)
|
||||||
|
|
||||||
Bugfix
|
Bugfix
|
||||||
* The length of various ClientKeyExchange messages was not properly checked.
|
* The length of various ClientKeyExchange messages was not properly checked.
|
||||||
* Some example server programs were not sending the close_notify alert.
|
* Some example server programs were not sending the close_notify alert.
|
||||||
|
@ -118,6 +118,9 @@ ecp_point;
|
|||||||
* short weierstrass, this subgroup is actually the whole curve, and its
|
* short weierstrass, this subgroup is actually the whole curve, and its
|
||||||
* cardinal is denoted by N.
|
* cardinal is denoted by N.
|
||||||
*
|
*
|
||||||
|
* In the case of Short Weierstrass curves, our code requires that N is an odd
|
||||||
|
* prime. (Use odd in ecp_mul() and prime in ecdsa_sign() for blinding.)
|
||||||
|
*
|
||||||
* In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
|
* In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
|
||||||
* the quantity actualy used in the formulas. Also, nbits is not the size of N
|
* the quantity actualy used in the formulas. Also, nbits is not the size of N
|
||||||
* but the required size for private keys.
|
* but the required size for private keys.
|
||||||
|
@ -99,17 +99,16 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s,
|
|||||||
const mpi *d, const unsigned char *buf, size_t blen,
|
const mpi *d, const unsigned char *buf, size_t blen,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
{
|
{
|
||||||
int ret, key_tries, sign_tries;
|
int ret, key_tries, sign_tries, blind_tries;
|
||||||
ecp_point R;
|
ecp_point R;
|
||||||
mpi k, e;
|
mpi k, e, t;
|
||||||
|
|
||||||
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
||||||
if( grp->N.p == NULL )
|
if( grp->N.p == NULL )
|
||||||
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
|
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
|
||||||
ecp_point_init( &R );
|
ecp_point_init( &R );
|
||||||
mpi_init( &k );
|
mpi_init( &k ); mpi_init( &e ); mpi_init( &t );
|
||||||
mpi_init( &e );
|
|
||||||
|
|
||||||
sign_tries = 0;
|
sign_tries = 0;
|
||||||
do
|
do
|
||||||
@ -138,10 +137,30 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s,
|
|||||||
MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
|
MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 6: compute s = (e + r * d) / k mod n
|
* Generate a random value to blind inv_mod in next step,
|
||||||
|
* avoiding a potential timing leak.
|
||||||
|
*/
|
||||||
|
blind_tries = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
size_t n_size = (grp->nbits + 7) / 8;
|
||||||
|
MPI_CHK( mpi_fill_random( &t, n_size, f_rng, p_rng ) );
|
||||||
|
MPI_CHK( mpi_shift_r( &t, 8 * n_size - grp->nbits ) );
|
||||||
|
|
||||||
|
/* See ecp_gen_keypair() */
|
||||||
|
if( ++blind_tries > 30 )
|
||||||
|
return( POLARSSL_ERR_ECP_RANDOM_FAILED );
|
||||||
|
}
|
||||||
|
while( mpi_cmp_int( &t, 1 ) < 0 ||
|
||||||
|
mpi_cmp_mpi( &t, &grp->N ) >= 0 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
|
||||||
*/
|
*/
|
||||||
MPI_CHK( mpi_mul_mpi( s, r, d ) );
|
MPI_CHK( mpi_mul_mpi( s, r, d ) );
|
||||||
MPI_CHK( mpi_add_mpi( &e, &e, s ) );
|
MPI_CHK( mpi_add_mpi( &e, &e, s ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &e, &e, &t ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &k, &k, &t ) );
|
||||||
MPI_CHK( mpi_inv_mod( s, &k, &grp->N ) );
|
MPI_CHK( mpi_inv_mod( s, &k, &grp->N ) );
|
||||||
MPI_CHK( mpi_mul_mpi( s, s, &e ) );
|
MPI_CHK( mpi_mul_mpi( s, s, &e ) );
|
||||||
MPI_CHK( mpi_mod_mpi( s, s, &grp->N ) );
|
MPI_CHK( mpi_mod_mpi( s, s, &grp->N ) );
|
||||||
@ -156,8 +175,7 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
ecp_point_free( &R );
|
ecp_point_free( &R );
|
||||||
mpi_free( &k );
|
mpi_free( &k ); mpi_free( &e ); mpi_free( &t );
|
||||||
mpi_free( &e );
|
|
||||||
|
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user