diff --git a/ChangeLog b/ChangeLog index 8db46ee15..cd003940a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,9 @@ Bugfix 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 3ab482fa9..d5c1e625b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6451,8 +6451,9 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ) 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 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) 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: