From eff335d575e0949ba25b60a358f31461eab055fe Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 1 Feb 2019 16:41:30 +0000 Subject: [PATCH 1/6] Fix 1-byte buffer overflow in mbedtls_mpi_write_string() This can only occur for negative numbers. Fixes #2404. --- library/bignum.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/bignum.c b/library/bignum.c index f6e50b986..54ab7e3ec 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -572,7 +572,10 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, mbedtls_mpi_init( &T ); if( X->s == -1 ) + { *p++ = '-'; + buflen--; + } if( radix == 16 ) { From 249958bdb8b9599124d58f789b35b68d46104f1f Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 1 Feb 2019 16:42:48 +0000 Subject: [PATCH 2/6] Adapt ChangeLog --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index bae12c95c..4cf6a86bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,8 @@ Features https://sweet32.info/SWEET32_CCS16.pdf. Bugfix + * Fix 1-byte buffer overflow in mbedtls_mpi_write_string() when + used with negative inputs. Found by Guido Vranken in #2404. * Run the AD too long test only if MBEDTLS_CCM_ALT is not defined. Raised as a comment in #1996. * Fix returning the value 1 when mbedtls_ecdsa_genkey failed. From a277d4cc82d91b6b0b54131657e6568f52dd9995 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 4 Feb 2019 09:45:07 +0000 Subject: [PATCH 3/6] Improve documentation of mbedtls_mpi_write_string() --- library/bignum.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 54ab7e3ec..e9c3867a6 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -552,15 +552,20 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, if( radix < 2 || radix > 16 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - n = mbedtls_mpi_bitlen( X ); - if( radix >= 4 ) n >>= 1; - if( radix >= 16 ) n >>= 1; - /* - * Round up the buffer length to an even value to ensure that there is - * enough room for hexadecimal values that can be represented in an odd - * number of digits. - */ - n += 3 + ( ( n + 1 ) & 1 ); + n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */ + if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present + * `n`. If radix > 4, this might be a strict + * overapproximation of the number of + * radix-adic digits needed to present `n`. */ + if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to + * present `n`. */ + + n += 1; /* NULL termination */ + n += 1; /* Compensate for the divisions above, which round down `n` + * in case it's not even. */ + n += 1; /* Potential '-'-sign. */ + n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing, + * which always uses an even number of hex-digits. */ if( buflen < n ) { From f56da14408868744d1376f130aa0c7097b415423 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 6 Mar 2019 12:29:37 +0000 Subject: [PATCH 4/6] Add non-regression test for buffer overflow --- tests/suites/test_suite_mpi.data | 3 +++ tests/suites/test_suite_mpi.function | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data index 296064196..b8d7ad14c 100644 --- a/tests/suites/test_suite_mpi.data +++ b/tests/suites/test_suite_mpi.data @@ -19,6 +19,9 @@ mpi_read_write_string:16:"-20":10:"-32":100:0:0 Base test mpi_read_write_string #3 (Negative decimal) mpi_read_write_string:16:"-23":16:"-23":100:0:0 +Base test mpi_read_write_string #4 (Buffer just fits) +mpi_read_write_string:16:"-4":4:"-10":4:0:0 + Test mpi_read_write_string #1 (Invalid character) mpi_read_write_string:10:"a28":0:"":100:MBEDTLS_ERR_MPI_INVALID_CHARACTER:0 diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index 04dca0fcb..aa3c332bb 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -81,6 +81,8 @@ void mpi_read_write_string( int radix_X, char *input_X, int radix_A, mbedtls_mpi_init( &X ); + memset( str, '!', sizeof( str ) ); + TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read ); if( result_read == 0 ) { @@ -88,6 +90,7 @@ void mpi_read_write_string( int radix_X, char *input_X, int radix_A, if( result_write == 0 ) { TEST_ASSERT( strcasecmp( str, input_A ) == 0 ); + TEST_ASSERT( str[len] == '!' ); } } From 216e7385ef12af174f973787e8f27482f4bcf28a Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 6 Mar 2019 13:43:02 +0000 Subject: [PATCH 5/6] Fix typo --- library/bignum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum.c b/library/bignum.c index e9c3867a6..d142fe69b 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -560,7 +560,7 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to * present `n`. */ - n += 1; /* NULL termination */ + n += 1; /* Terminating null byte */ n += 1; /* Compensate for the divisions above, which round down `n` * in case it's not even. */ n += 1; /* Potential '-'-sign. */ From dc223cfdfa638d6fb02f14230274415d7ed5562a Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 6 Mar 2019 15:24:23 +0000 Subject: [PATCH 6/6] Fix ChangeLog entry ordering --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cf6a86bb..c14c31430 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,8 +8,6 @@ Features https://sweet32.info/SWEET32_CCS16.pdf. Bugfix - * Fix 1-byte buffer overflow in mbedtls_mpi_write_string() when - used with negative inputs. Found by Guido Vranken in #2404. * Run the AD too long test only if MBEDTLS_CCM_ALT is not defined. Raised as a comment in #1996. * Fix returning the value 1 when mbedtls_ecdsa_genkey failed. @@ -32,6 +30,8 @@ Bugfix * Fix private key DER output in the key_app_writer example. File contents were shifted by one byte, creating an invalid ASN.1 tag. Fixed by Christian Walther in #2239. + * Fix 1-byte buffer overflow in mbedtls_mpi_write_string() when + used with negative inputs. Found by Guido Vranken in #2404. Changes * Include configuration file in all header files that use configuration,