Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>, Michael Tuexen <tuexen...
authorDr. Stephen Henson <steve@openssl.org>
Wed, 4 Jan 2012 19:10:16 +0000 (19:10 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 4 Jan 2012 19:10:16 +0000 (19:10 +0000)
Reviewed by: steve

Fix for DTLS plaintext recovery attack discovered by Nadhem Alfardan and
Kenny Paterson.

CHANGES
ssl/d1_pkt.c

diff --git a/CHANGES b/CHANGES
index cf32f605eb0d9eae17d5b1a3d9b2a35a88468324..d621d8435b95428c75a21ea32dd7e4b203639dbc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,20 @@
 
  Changes between 0.9.8r and 0.9.8s [xx XXX xxxx]
 
+  *) Nadhem Alfardan and Kenny Paterson have discovered an extension
+     of the Vaudenay padding oracle attack on CBC mode encryption
+     which enables an efficient plaintext recovery attack against
+     the OpenSSL implementation of DTLS. Their attack exploits timing
+     differences arising during decryption processing. A research
+     paper describing this attack can be found at:
+                  http://www.isg.rhul.ac.uk/~kp/dtls.pdf
+     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+     Security Group at Royal Holloway, University of London
+     (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
+     <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
+     for preparing the fix. (CVE-2011-4108)
+     [Robin Seggelmann, Michael Tuexen]
+
   *) Stop policy check failure freeing same buffer twice. (CVE-2011-4109)
      [Ben Laurie, Kasper <ekasper@google.com>]
 
index e4f47e98e6ea780e0ca5b2617e80abfeced7cd8c..83702e5309915334b57f28d576101b1d1fe47404 100644 (file)
@@ -335,6 +335,7 @@ dtls1_process_record(SSL *s)
     SSL3_RECORD *rr;
        unsigned int mac_size;
        unsigned char md[EVP_MAX_MD_SIZE];
+       int decryption_failed_or_bad_record_mac = 0;
 
 
        rr= &(s->s3->rrec);
@@ -369,13 +370,10 @@ dtls1_process_record(SSL *s)
        enc_err = s->method->ssl3_enc->enc(s,0);
        if (enc_err <= 0)
                {
-               /* decryption failed, silently discard message */
-               if (enc_err < 0)
-                       {
-                       rr->length = 0;
-                       s->packet_length = 0;
-                       }
-               goto err;
+               /* To minimize information leaked via timing, we will always
+                * perform all computations before discarding the message.
+                */
+               decryption_failed_or_bad_record_mac = 1;
                }
 
 #ifdef TLS_DEBUG
@@ -401,7 +399,7 @@ if (        (sess == NULL) ||
                        SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
                        goto f_err;
 #else
-                       goto err;
+                       decryption_failed_or_bad_record_mac = 1;
 #endif                 
                        }
                /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
@@ -412,17 +410,25 @@ if (      (sess == NULL) ||
                        SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
                        goto f_err;
 #else
-                       goto err;
+                       decryption_failed_or_bad_record_mac = 1;
 #endif
                        }
                rr->length-=mac_size;
                s->method->ssl3_enc->mac(s,md,0);
                if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
                        {
-                       goto err;
+                       decryption_failed_or_bad_record_mac = 1;
                        }
                }
 
+       if (decryption_failed_or_bad_record_mac)
+               {
+               /* decryption failed, silently discard message */
+               rr->length = 0;
+               s->packet_length = 0;
+               goto err;
+               }
+
        /* r->length is now just compressed */
        if (s->expand != NULL)
                {