From 1226dd7715f86898a45823c88b924047dcd1263a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 19 Jun 2018 15:57:50 +1000 Subject: [PATCH] CBC mode: Allow zero-length message fragments (100% padding) Fixes https://github.com/ARMmbed/mbedtls/issues/1632 --- ChangeLog | 5 +++++ library/ssl_tls.c | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index b56867cc6..de3bfc2b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,11 @@ Bugfix by Brendan Shanks. Part of a fix for #992. * Fix compilation error when MBEDTLS_ARC4_C is disabled and MBEDTLS_CIPHER_NULL_CIPHER is enabled. Found by TrinityTonic in #1719. + * Fix decryption of zero length messages (all padding) in some circumstances: + DTLS 1.0 and 1.2, and CBC ciphersuites using encrypt-then-MAC. Most often + seen when communicating with OpenSSL using TLS 1.0. Reported by @kFYatek + (#1632) and by Conor Murphy on the forum. Fix contributed by Espressif + Systems. Changes * Change the shebang line in Perl scripts to look up perl in the PATH. diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9774a771e..d751aa36b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1881,27 +1881,27 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) * and fake check up to 256 bytes of padding */ size_t pad_count = 0, real_count = 1; - size_t padding_idx = ssl->in_msglen - padlen - 1; + size_t padding_idx = ssl->in_msglen - padlen; /* * Padding is guaranteed to be incorrect if: - * 1. padlen >= ssl->in_msglen + * 1. padlen > ssl->in_msglen * - * 2. padding_idx >= MBEDTLS_SSL_MAX_CONTENT_LEN + + * 2. padding_idx > MBEDTLS_SSL_MAX_CONTENT_LEN + * ssl->transform_in->maclen * * In both cases we reset padding_idx to a safe value (0) to * prevent out-of-buffer reads. */ - correct &= ( ssl->in_msglen >= padlen + 1 ); - correct &= ( padding_idx < MBEDTLS_SSL_MAX_CONTENT_LEN + + correct &= ( padlen <= ssl->in_msglen ); + correct &= ( padding_idx <= MBEDTLS_SSL_MAX_CONTENT_LEN + ssl->transform_in->maclen ); padding_idx *= correct; - for( i = 1; i <= 256; i++ ) + for( i = 0; i < 256; i++ ) { - real_count &= ( i <= padlen ); + real_count &= ( i < padlen ); pad_count += real_count * ( ssl->in_msg[padding_idx + i] == padlen - 1 ); }