Merge pull request #829 from mpg/ecp-gen-privkey-ct-compare-2.16-restricted

[Backport 2.16] Fix small timing side channel in ECDSA ephemeral key generation
This commit is contained in:
Manuel Pégourié-Gonnard 2021-06-07 09:10:15 +02:00 committed by GitHub
commit 449c177469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 6 deletions

View File

@ -0,0 +1,7 @@
Security
* Fix a potential side channel vulnerability in ECDSA ephemeral key generation.
An adversary who is capable of very precise timing measurements could
learn partial information about the leading bits of the nonce used for the
signature, allowing the recovery of the private key after observing a
large number of signature operations. This completes a partial fix in
Mbed TLS 2.16.4.

View File

@ -3059,6 +3059,11 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
{
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
size_t n_size;
#if defined(ECP_SHORTWEIERSTRASS)
mbedtls_mpi one;
mbedtls_mpi_init( &one );
#endif
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
@ -3099,7 +3104,10 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
{
/* SEC1 3.2.1: Generate d such that 1 <= n < N */
int count = 0;
unsigned cmp = 0;
unsigned lt_lower = 1, lt_upper = 0;
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &one, grp->N.n ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
/*
* Match the procedure given in RFC 6979 (deterministic ECDSA):
@ -3123,19 +3131,22 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
* such as secp224k1 are actually very close to the worst case.
*/
if( ++count > 30 )
return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
ret = mbedtls_mpi_lt_mpi_ct( d, &grp->N, &cmp );
if( ret != 0 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &grp->N, &lt_upper ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &one, &lt_lower ) );
}
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 );
while( lt_lower != 0 || lt_upper == 0 );
}
#endif /* ECP_SHORTWEIERSTRASS */
cleanup:
#if defined(ECP_SHORTWEIERSTRASS)
mbedtls_mpi_free( &one );
#endif
return( ret );
}