Merge remote-tracking branch 'restricted/pr/535' into development

This commit is contained in:
Simon Butcher 2018-11-29 16:54:51 +00:00
commit b9eb7866eb
2 changed files with 46 additions and 13 deletions

View file

@ -5,9 +5,17 @@ mbed TLS ChangeLog (Sorted per branch, date)
Security Security
* Fix timing variations and memory access variations in RSA PKCS#1 v1.5 * Fix timing variations and memory access variations in RSA PKCS#1 v1.5
decryption that could lead to a Bleichenbacher-style padding oracle decryption that could lead to a Bleichenbacher-style padding oracle
attack. In TLS, this affects RSA-based ciphersuites without DHE or attack. In TLS, this affects servers that accept ciphersuites based on
ECDHE. Reported by Yuval Yarom, Eyal Ronen, Adi Shamir, David Wong and RSA decryption (i.e. ciphersuites whose name contains RSA but not
Daniel Genkin. (EC)DH(E)). Reported by Eyal Ronen, Robert Gillham, Daniel Genkin, Adi
Shamir, David Wong and Yuval Yarom. CVE-2018-19608
* In mbedtls_mpi_write_binary(), don't leak the exact size of the number
via branching and memory access patterns. An attacker who could submit
a plaintext for RSA PKCS#1 v1.5 decryption but only observe the timing
of the decryption and not its result could nonetheless decrypt RSA
plaintexts and forge RSA signatures. Other asymmetric algorithms may
have been similarly vulnerable. Reported by Eyal Ronen, Robert Gillham,
Daniel Genkin, Adi Shamir, David Wong and Yuval Yarom.
= mbed TLS 2.14.0 branch released 2018-11-19 = mbed TLS 2.14.0 branch released 2018-11-19

View file

@ -321,6 +321,10 @@ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
} }
/* Get a specific byte, without range checks. */
#define GET_BYTE( X, i ) \
( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
/* /*
* Set a bit to a specific value of 0 or 1 * Set a bit to a specific value of 0 or 1
*/ */
@ -704,19 +708,40 @@ cleanup:
/* /*
* Export X into unsigned binary data, big endian * Export X into unsigned binary data, big endian
*/ */
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ) int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
unsigned char *buf, size_t buflen )
{ {
size_t i, j, n; size_t stored_bytes = X->n * ciL;
size_t bytes_to_copy;
unsigned char *p;
size_t i;
n = mbedtls_mpi_size( X ); if( stored_bytes < buflen )
{
if( buflen < n ) /* There is enough space in the output buffer. Write initial
* null bytes and record the position at which to start
* writing the significant bytes. In this case, the execution
* trace of this function does not depend on the value of the
* number. */
bytes_to_copy = stored_bytes;
p = buf + buflen - stored_bytes;
memset( buf, 0, buflen - stored_bytes );
}
else
{
/* The output buffer is smaller than the allocated size of X.
* However X may fit if its leading bytes are zero. */
bytes_to_copy = buflen;
p = buf;
for( i = bytes_to_copy; i < stored_bytes; i++ )
{
if( GET_BYTE( X, i ) != 0 )
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
}
}
memset( buf, 0, buflen ); for( i = 0; i < bytes_to_copy; i++ )
p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
return( 0 ); return( 0 );
} }