diff --git a/ChangeLog b/ChangeLog index 2aa7a2182..c527e0603 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,13 @@ Changes = mbed TLS 2.1.1 released 2015-09-17 +Security + * Fix possible heap buffer overflow in base64_encoded() when the input + buffer is 512MB or larger on 32-bit platforms. + Found by Guido Vranken. Not trigerrable remotely in TLS. + += mbed TLS 2.1.1 released 2015-09-17 + Security * Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5 signatures. (Found by Florian Weimer, Red Hat.) diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h index 28a3a4c59..18e83120b 100644 --- a/include/mbedtls/base64.h +++ b/include/mbedtls/base64.h @@ -24,6 +24,7 @@ #define MBEDTLS_BASE64_H #include +#include #define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ #define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ @@ -44,6 +45,8 @@ extern "C" { * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. * *olen is always updated to reflect the amount * of data that has (or would have) been written. + * If that length cannot be represented, then no data is + * written to the buffer and *olen is set to SIZE_T_MAX. * * \note Call this function with dlen = 0 to obtain the * required buffer size in *olen diff --git a/library/base64.c b/library/base64.c index e468e2cbc..fc44c15ae 100644 --- a/library/base64.c +++ b/library/base64.c @@ -85,15 +85,16 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, return( 0 ); } - n = ( slen << 3 ) / 6; + n = slen / 3 + ( slen % 3 != 0 ); - switch( ( slen << 3 ) - ( n * 6 ) ) + if( n > ( SIZE_T_MAX - 1 ) / 4 ) { - case 2: n += 3; break; - case 4: n += 2; break; - default: break; + *olen = SIZE_T_MAX; + return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); } + n *= 4; + if( dlen < n + 1 ) { *olen = n + 1; diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data index 3b66da165..da99ffa87 100644 --- a/tests/suites/test_suite_base64.data +++ b/tests/suites/test_suite_base64.data @@ -1,23 +1,41 @@ -Test case mbedtls_base64_encode #1 -mbedtls_base64_encode:"":"":1000:0 +Test case mbedtls_base64_encode #1 buffer just right +mbedtls_base64_encode:"":"":0:0 -Test case mbedtls_base64_encode #2 -mbedtls_base64_encode:"f":"Zg==":1000:0 +Test case mbedtls_base64_encode #2 buffer just right +mbedtls_base64_encode:"f":"Zg==":5:0 -Test case mbedtls_base64_encode #3 -mbedtls_base64_encode:"fo":"Zm8=":1000:0 +Test case mbedtls_base64_encode #2 buffer too small +mbedtls_base64_encode:"f":"Zg==":4:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -Test case mbedtls_base64_encode #4 -mbedtls_base64_encode:"foo":"Zm9v":1000:0 +Test case mbedtls_base64_encode #3 buffer just right +mbedtls_base64_encode:"fo":"Zm8=":5:0 -Test case mbedtls_base64_encode #5 -mbedtls_base64_encode:"foob":"Zm9vYg==":1000:0 +Test case mbedtls_base64_encode #3 buffer too small +mbedtls_base64_encode:"fo":"Zm8=":4:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -Test case mbedtls_base64_encode #6 -mbedtls_base64_encode:"fooba":"Zm9vYmE=":1000:0 +Test case mbedtls_base64_encode #4 buffer just right +mbedtls_base64_encode:"foo":"Zm9v":5:0 -Test case mbedtls_base64_encode #7 -mbedtls_base64_encode:"foobar":"Zm9vYmFy":1000:0 +Test case mbedtls_base64_encode #4 buffer too small +mbedtls_base64_encode:"foo":"Zm9v":4:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL + +Test case mbedtls_base64_encode #5 buffer just right +mbedtls_base64_encode:"foob":"Zm9vYg==":9:0 + +Test case mbedtls_base64_encode #5 buffer too small +mbedtls_base64_encode:"foob":"Zm9vYg==":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL + +Test case mbedtls_base64_encode #6 buffer just right +mbedtls_base64_encode:"fooba":"Zm9vYmE=":9:0 + +Test case mbedtls_base64_encode #6 buffer too small +mbedtls_base64_encode:"fooba":"Zm9vYmE=":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL + +Test case mbedtls_base64_encode #7 buffer just right +mbedtls_base64_encode:"foobar":"Zm9vYmFy":9:0 + +Test case mbedtls_base64_encode #7 buffer too small +mbedtls_base64_encode:"foobar":"Zm9vYmFy":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL Test case mbedtls_base64_decode #1 mbedtls_base64_decode:"":"":0 @@ -40,12 +58,6 @@ mbedtls_base64_decode:"Zm9vYmE=":"fooba":0 Test case mbedtls_base64_decode #7 mbedtls_base64_decode:"Zm9vYmFy":"foobar":0 -Base64 encode (buffer size just right) -mbedtls_base64_encode:"foobar":"Zm9vYmFy":9:0 - -Base64 encode (buffer size too small) -mbedtls_base64_encode:"foobar":"":8:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL - Base64 decode (Illegal character) mbedtls_base64_decode:"zm#=":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER