Fix potential overflow in base64_encode
diff --git a/ChangeLog b/ChangeLog
index 14ae034..651ee4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,9 @@
    * Fix potential double-free if ssl_set_psk() is called repeatedly on
      the same ssl_context object and some memory allocations fail.
      Found by Guido Vranken. Can not be forced remotely.
+   * Fix possible heap buffer overflow in base64_encode() when the input
+     buffer is 512MB or larger on 32-bit platforms.
+     Found by Guido Vranken. Not trigerrable remotely in TLS.
 
 = mbed TLS 1.3.13 reladsed 2015-09-17
 
diff --git a/include/polarssl/base64.h b/include/polarssl/base64.h
index 0f1e854..dd11bda 100644
--- a/include/polarssl/base64.h
+++ b/include/polarssl/base64.h
@@ -25,6 +25,7 @@
 #define POLARSSL_BASE64_H
 
 #include <stddef.h>
+#include <limits.h>
 
 #define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL               -0x002A  /**< Output buffer too small. */
 #define POLARSSL_ERR_BASE64_INVALID_CHARACTER              -0x002C  /**< Invalid character in input. */
@@ -44,6 +45,8 @@
  * \return         0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
  *                 *dlen 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 *dlen
diff --git a/library/base64.c b/library/base64.c
index 2f7bb14..c743511 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -91,15 +91,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;
+        *dlen = SIZE_T_MAX;
+        return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
     }
 
+    n *= 4;
+
     if( *dlen < n + 1 )
     {
         *dlen = n + 1;