Improve sign/key_tries handling

(Unrelated to restartable work, just noticed while staring at the code.)

Checking at the end is inefficient as we might give up when we just generated
a valid signature or key.
This commit is contained in:
Manuel Pégourié-Gonnard 2017-04-21 13:19:43 +02:00
parent b90883dc1d
commit 675439620d
2 changed files with 20 additions and 21 deletions

View file

@ -252,6 +252,12 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
sign_tries = 0; sign_tries = 0;
do do
{ {
if( sign_tries++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
/* /*
* Steps 1-3: generate a suitable ephemeral keypair * Steps 1-3: generate a suitable ephemeral keypair
* and set r = xR mod n * and set r = xR mod n
@ -259,14 +265,14 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
key_tries = 0; key_tries = 0;
do do
{ {
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) );
if( key_tries++ > 10 ) if( key_tries++ > 10 )
{ {
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup; goto cleanup;
} }
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) );
} }
while( mbedtls_mpi_cmp_int( r, 0 ) == 0 ); while( mbedtls_mpi_cmp_int( r, 0 ) == 0 );
@ -303,12 +309,6 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
if( sign_tries++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
} }
while( mbedtls_mpi_cmp_int( s, 0 ) == 0 ); while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );

View file

@ -2531,14 +2531,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
* - keep the leftmost nbits bits of the generated octet string; * - keep the leftmost nbits bits of the generated octet string;
* - try until result is in the desired range. * - try until result is in the desired range.
* This also avoids any biais, which is especially important for ECDSA. * This also avoids any biais, which is especially important for ECDSA.
*/ *
do
{
MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
/*
* Each try has at worst a probability 1/2 of failing (the msb has * Each try has at worst a probability 1/2 of failing (the msb has
* a probability 1/2 of being 0, and then the result will be < N), * a probability 1/2 of being 0, and then the result will be < N),
* so after 30 tries failure probability is a most 2**(-30). * so after 30 tries failure probability is a most 2**(-30).
@ -2547,8 +2540,14 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
* since N starts with a lot of 1s in binary, but some curves * since N starts with a lot of 1s in binary, but some curves
* such as secp224k1 are actually very close to the worst case. * such as secp224k1 are actually very close to the worst case.
*/ */
do
{
if( ++count > 30 ) if( ++count > 30 )
return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
} }
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ); mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );