From 5bad6afd8c72b2c3a6574dff01ca5f8f2f04800a Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Tue, 8 Jul 2014 17:51:29 +0200 Subject: [PATCH] Fix length checking for AEAD ciphersuites --- ChangeLog | 3 +++ library/ssl_tls.c | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83613b906..a174aebc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,9 @@ Security * Forbid sequence number wrapping * Prevent potential NULL pointer dereference in ssl_read_record() (found by TrustInSoft) + * Fix length checking for AEAD ciphersuites (found by Codenomicon). + It was possible to crash the server (and client) using crafted messages + when a GCM suite was chosen. Bugfix * Fixed X.509 hostname comparison (with non-regular characters) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4add6a280..bad3188b9 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1254,6 +1254,9 @@ static int ssl_decrypt_buf( ssl_context *ssl ) size_t dec_msglen; unsigned char add_data[13]; int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + unsigned char taglen = 16; + unsigned char explicit_iv_len = ssl->transform_in->ivlen - + ssl->transform_in->fixed_ivlen; #if defined(POLARSSL_AES_C) && defined(POLARSSL_GCM_C) if( ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_128_GCM_SHA256 || @@ -1261,11 +1264,16 @@ static int ssl_decrypt_buf( ssl_context *ssl ) ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 || ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ) { - dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen - - ssl->transform_in->fixed_ivlen ); - dec_msglen -= 16; - dec_msg = ssl->in_msg + ( ssl->transform_in->ivlen - - ssl->transform_in->fixed_ivlen ); + if( ssl->in_msglen < explicit_iv_len + taglen ) + { + SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " + "+ taglen (%d)", ssl->in_msglen, + explicit_iv_len, taglen ) ); + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } + dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; + + dec_msg = ssl->in_msg + explicit_iv_len; dec_msg_result = ssl->in_msg; ssl->in_msglen = dec_msglen;