From 11cdb0559e46dbe9301bd37a36d583e3d2fefd3b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 20 Nov 2018 16:47:47 +0100 Subject: [PATCH 1/3] mbedtls_mpi_write_binary: don't leak the exact size of the number In mbedtls_mpi_write_binary, avoid leaking the size of the number through timing or branches, if possible. More precisely, if the number fits in the output buffer based on its allocated size, the new code's trace doesn't depend on the value of the number. --- library/bignum.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 423e375fd..6e4ceeebf 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -321,6 +321,10 @@ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ) 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 */ @@ -704,19 +708,40 @@ cleanup: /* * 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 ) + { + /* 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 ); + } + } - if( buflen < n ) - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - - memset( buf, 0, buflen ); - - for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) - buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); + for( i = 0; i < bytes_to_copy; i++ ) + p[bytes_to_copy - i - 1] = GET_BYTE( X, i ); return( 0 ); } From 056f19c79f14414a7b3745d29825783dce3a85af Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 29 Nov 2018 12:45:01 +0100 Subject: [PATCH 2/3] Tweak RSA vulnerability changelog entry * Correct the list of authors. * Add the CVE number. * Improve the impact description. --- ChangeLog | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bb9ec04a..4f90d560b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,9 +5,10 @@ mbed TLS ChangeLog (Sorted per branch, date) Security * Fix timing variations and memory access variations in RSA PKCS#1 v1.5 decryption that could lead to a Bleichenbacher-style padding oracle - attack. In TLS, this affects RSA-based ciphersuites without DHE or - ECDHE. Reported by Yuval Yarom, Eyal Ronen, Adi Shamir, David Wong and - Daniel Genkin. + attack. In TLS, this affects servers that accept ciphersuites based on + RSA decryption (i.e. ciphersuites whose name contains RSA but not + (EC)DH(E)). Reported by Eyal Ronen, Robert Gillham, Daniel Genkin, Adi + Shamir, David Wong and Yuval Yarom. CVE-2018-19608 = mbed TLS 2.13.1 branch released 2018-09-06 From 50da016e5ce5eacdc7c41f55122ec8450f0b94c4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 29 Nov 2018 12:46:05 +0100 Subject: [PATCH 3/3] Add changelog entry for mbedtls_mpi_write_binary fix --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4f90d560b..5d2e8db18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,13 @@ Security RSA decryption (i.e. ciphersuites whose name contains RSA but not (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.13.1 branch released 2018-09-06