Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>, Michael Tuexen <tuexen...
authorDr. Stephen Henson <steve@openssl.org>
Wed, 4 Jan 2012 23:52:26 +0000 (23:52 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 4 Jan 2012 23:52:26 +0000 (23:52 +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 176b6494538e7deb8174d9de3cbd08862490864d..6fd53f324042ea9120cadbe4a6028a98e391bd08 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 
  Changes between 1.0.0e and 1.0.0f [xx XXX xxxx]
 
 
  Changes between 1.0.0e and 1.0.0f [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]
+
   *) Clear bytes used for block padding of SSL 3.0 records.
      (CVE-2011-4576)
      [Adam Langley (Google)]
   *) Clear bytes used for block padding of SSL 3.0 records.
      (CVE-2011-4576)
      [Adam Langley (Google)]
index f66f33cf6395a7d2e88ea9a070ad978bf7572284..fdeaac88049134a5f274ee5f31f365606383f844 100644 (file)
@@ -383,6 +383,7 @@ dtls1_process_record(SSL *s)
        SSL3_RECORD *rr;
        unsigned int mac_size;
        unsigned char md[EVP_MAX_MD_SIZE];
        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);
 
 
        rr= &(s->s3->rrec);
@@ -417,13 +418,10 @@ dtls1_process_record(SSL *s)
        enc_err = s->method->ssl3_enc->enc(s,0);
        if (enc_err <= 0)
                {
        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
                }
 
 #ifdef TLS_DEBUG
@@ -453,7 +451,7 @@ printf("\n");
                        SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
                        goto f_err;
 #else
                        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) */
 #endif                 
                        }
                /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
@@ -464,17 +462,25 @@ printf("\n");
                        SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
                        goto f_err;
 #else
                        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;
                i=s->method->ssl3_enc->mac(s,md,0);
                if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
                        {
 #endif
                        }
                rr->length-=mac_size;
                i=s->method->ssl3_enc->mac(s,md,0);
                if (i < 0 || 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)
                {
        /* r->length is now just compressed */
        if (s->expand != NULL)
                {