From f73b718f172502651faa35d3a78edcf6c550f528 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Tue, 8 Jul 2014 18:30:44 +0200 Subject: [PATCH] Latest CBC padding check --- library/ssl_tls.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index bad3188b9..541e8d4ba 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1455,17 +1455,33 @@ static int ssl_decrypt_buf( ssl_context *ssl ) * TLSv1+: always check the padding up to the first failure * and fake check up to 256 bytes of padding */ - size_t pad_count = 0, fake_pad_count = 0; + size_t pad_count = 0, real_count = 1; size_t padding_idx = ssl->in_msglen - padlen - 1; - for( i = 1; i <= padlen; i++ ) - pad_count += ( ssl->in_msg[padding_idx + i] == padlen - 1 ); + /* + * Padding is guaranteed to be incorrect if: + * 1. padlen >= ssl->in_msglen + * + * 2. padding_idx >= 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 < SSL_MAX_CONTENT_LEN + + ssl->transform_in->maclen ); - for( ; i <= 256; i++ ) - fake_pad_count += ( ssl->in_msg[padding_idx + i] == padlen - 1 ); + padding_idx *= correct; + + for( i = 1; i <= 256; i++ ) + { + real_count &= ( i <= padlen ); + pad_count += real_count * + ( ssl->in_msg[padding_idx + i] == padlen - 1 ); + } correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ - correct &= ( pad_count + fake_pad_count < 512 ); /* Always 1 */ #if defined(POLARSSL_SSL_DEBUG_ALL) if( padlen > 0 && correct == 0)