Merge remote-tracking branch 'public/pr/1959' into mbedtls-2.1
diff --git a/ChangeLog b/ChangeLog
index 8db46ee..cd00394 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,9 @@
      interoperability issues with BouncyCastle. Raised by milenamil in #1157.
    * Fix potential use-after-free in mbedtls_ssl_get_max_frag_len()
      and mbedtls_ssl_get_record_expansion() after a session reset. Fixes #1941.
+   * Fix a miscalculation of the maximum record expansion in
+     mbedtls_ssl_get_record_expansion() in case of CBC ciphersuites
+     in (D)TLS versions 1.1 or higher. Fixes #1914.
 
 = mbed TLS 2.1.14 branch released 2018-07-25
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 3ab482f..d5c1e62 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -6451,8 +6451,9 @@
 
 int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
 {
-    size_t transform_expansion;
+    size_t transform_expansion = 0;
     const mbedtls_ssl_transform *transform = ssl->transform_out;
+    unsigned block_size;
 
     if( transform == NULL )
         return( (int) mbedtls_ssl_hdr_len( ssl ) );
@@ -6471,8 +6472,25 @@
             break;
 
         case MBEDTLS_MODE_CBC:
-            transform_expansion = transform->maclen
-                      + mbedtls_cipher_get_block_size( &transform->cipher_ctx_enc );
+
+            block_size = mbedtls_cipher_get_block_size(
+                &transform->cipher_ctx_enc );
+
+            /* Expansion due to the addition of the MAC. */
+            transform_expansion += transform->maclen;
+
+            /* Expansion due to the addition of CBC padding;
+             * Theoretically up to 256 bytes, but we never use
+             * more than the block size of the underlying cipher. */
+            transform_expansion += block_size;
+
+            /* For TLS 1.1 or higher, an explicit IV is added
+             * after the record header. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+            if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+                transform_expansion += block_size;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
             break;
 
         default: