Merge pull request #820 from gilles-peskine-arm/mpi_fill_random-constant_time_comparison-development-restricted

Fix small timing side channel in ECDSA ephemeral key generation
This commit is contained in:
Manuel Pégourié-Gonnard 2021-06-07 09:09:55 +02:00 committed by GitHub
commit 6f1dbe615c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 3 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.20.0.

View file

@ -2466,9 +2466,10 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
{
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
int count;
unsigned cmp = 0;
unsigned lt_lower = 1, lt_upper = 0;
size_t n_bits = mbedtls_mpi_bitlen( N );
size_t n_bytes = ( n_bits + 7 ) / 8;
mbedtls_mpi lower_bound;
if( min < 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
@ -2494,10 +2495,14 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
*/
count = ( n_bytes > 4 ? 30 : 250 );
mbedtls_mpi_init( &lower_bound );
/* Ensure that target MPI has exactly the same number of limbs
* as the upper bound, even if the upper bound has leading zeros.
* This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
/*
* Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
@ -2518,11 +2523,13 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &cmp ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, &lt_lower ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &lt_upper ) );
}
while( mbedtls_mpi_cmp_int( X, min ) < 0 || cmp != 1 );
while( lt_lower != 0 || lt_upper == 0 );
cleanup:
mbedtls_mpi_free( &lower_bound );
return( ret );
}