From eaa76f7e20dfbf79ffddf9bcad32c97321c54106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 18 Jun 2014 16:06:02 +0200 Subject: [PATCH] Fix computation of minlen for encrypted packets --- ChangeLog | 3 +++ library/ssl_tls.c | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 563aa54ab..ae1a57273 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,9 @@ Bugfix * Fix symlink command for cross compiling with CMake (found by Andre Heinecke) * Fix DER output of gen_key app (found by Gergely Budai) + * Very small packets were incorrectly rejected when truncated HMAC was in + use with some ciphersuites and versions (RC4 in all versions, CBC with + versions < TLS 1.1). = PolarSSL 1.3.7 released on 2014-05-02 Features diff --git a/library/ssl_tls.c b/library/ssl_tls.c index edfc575c1..ac2aca75c 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -521,7 +521,10 @@ int ssl_derive_keys( ssl_context *ssl ) transform->ivlen = 12; transform->fixed_ivlen = 4; - transform->minlen = 1; // FIXME + /* Minimum length is expicit IV + tag */ + transform->minlen = transform->ivlen - transform->fixed_ivlen + + ( transform->ciphersuite_info->flags & + POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16 ); } else { @@ -551,14 +554,38 @@ int ssl_derive_keys( ssl_context *ssl ) /* IV length */ transform->ivlen = cipher_info->iv_size; - /* Minimum length: FIXME */ - transform->minlen = transform->keylen; - if( transform->minlen < transform->maclen ) + /* Minimum length */ + if( cipher_info->mode == POLARSSL_MODE_STREAM ) + transform->minlen = transform->maclen; + else { - if( cipher_info->mode == POLARSSL_MODE_STREAM ) - transform->minlen = transform->maclen; + /* + * GenericBlockCipher: + * first multiple of blocklen greater than maclen + * + IV except for SSL3 and TLS 1.0 + */ + transform->minlen = transform->maclen + + cipher_info->block_size + - transform->maclen % cipher_info->block_size; + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 || + ssl->minor_ver == SSL_MINOR_VERSION_1 ) + ; /* No need to adjust minlen */ else - transform->minlen += transform->keylen; +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_2 || + ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + transform->minlen += transform->ivlen; + } + else +#endif + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } } }