Fix potential overflow in base64_encode
diff --git a/ChangeLog b/ChangeLog
index c9e48e2..187c1ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,13 @@
= 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.)
https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/
diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h
index 28a3a4c..18e8312 100644
--- a/include/mbedtls/base64.h
+++ b/include/mbedtls/base64.h
@@ -24,6 +24,7 @@
#define MBEDTLS_BASE64_H
#include <stddef.h>
+#include <limits.h>
#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 @@
* \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 16c254d..8c99538 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -85,15 +85,16 @@
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;