Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/crypto/external/bsd/openssl/dist Security fixes:



details:   https://anonhg.NetBSD.org/src/rev/9ed953c5adca
branches:  trunk
changeset: 345027:9ed953c5adca
user:      christos <christos%NetBSD.org@localhost>
date:      Tue May 03 17:10:26 2016 +0000

description:
Security fixes:

  *) Prevent padding oracle in AES-NI CBC MAC check

     A MITM attacker can use a padding oracle attack to decrypt traffic
     when the connection uses an AES CBC cipher and the server support
     AES-NI.

     This issue was introduced as part of the fix for Lucky 13 padding
     attack (CVE-2013-0169). The padding check was rewritten to be in
     constant time by making sure that always the same bytes are read and
     compared against either the MAC or padding bytes. But it no longer
     checked that there was enough data to have both the MAC and padding
     bytes.

     This issue was reported by Juraj Somorovsky using TLS-Attacker.
     (CVE-2016-2107)
     [Kurt Roeckx]

  *) Fix EVP_EncodeUpdate overflow

     An overflow can occur in the EVP_EncodeUpdate() function which is used for
     Base64 encoding of binary data. If an attacker is able to supply very large
     amounts of input data then a length check can overflow resulting in a heap
     corruption.

     Internally to OpenSSL the EVP_EncodeUpdate() function is primarly used by
     the PEM_write_bio* family of functions. These are mainly used within the
     OpenSSL command line applications, so any application which processes data
     from an untrusted source and outputs it as a PEM file should be considered
     vulnerable to this issue. User applications that call these APIs directly
     with large amounts of untrusted data may also be vulnerable.

     This issue was reported by Guido Vranken.
     (CVE-2016-2105)
     [Matt Caswell]

  *) Fix EVP_EncryptUpdate overflow

     An overflow can occur in the EVP_EncryptUpdate() function. If an attacker
     is able to supply very large amounts of input data after a previous call to
     EVP_EncryptUpdate() with a partial block then a length check can overflow
     resulting in a heap corruption. Following an analysis of all OpenSSL
     internal usage of the EVP_EncryptUpdate() function all usage is one of two
     forms. The first form is where the EVP_EncryptUpdate() call is known to be
     the first called function after an EVP_EncryptInit(), and therefore that
     specific call must be safe. The second form is where the length passed to
     EVP_EncryptUpdate() can be seen from the code to be some small value and
     therefore there is no possibility of an overflow. Since all instances are
     one of these two forms, it is believed that there can be no overflows in
     internal code due to this problem. It should be noted that
     EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths.
     Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances
     of these calls have also been analysed too and it is believed there are no
     instances in internal usage where an overflow could occur.

     This issue was reported by Guido Vranken.
     (CVE-2016-2106)
     [Matt Caswell]

  *) Prevent ASN.1 BIO excessive memory allocation

     When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio()
     a short invalid encoding can casuse allocation of large amounts of memory
     potentially consuming excessive resources or exhausting memory.

     Any application parsing untrusted data through d2i BIO functions is
     affected. The memory based functions such as d2i_X509() are *not* affected.
     Since the memory based functions are used by the TLS library, TLS
     applications are not affected.

     This issue was reported by Brian Carpenter.
     (CVE-2016-2109)
     [Stephen Henson]

  *) EBCDIC overread

     ASN1 Strings that are over 1024 bytes can cause an overread in applications
     using the X509_NAME_oneline() function on EBCDIC systems. This could result
     in arbitrary stack data being returned in the buffer.

     This issue was reported by Guido Vranken.
     (CVE-2016-2176)
     [Matt Caswell]

  *) Modify behavior of ALPN to invoke callback after SNI/servername
     callback, such that updates to the SSL_CTX affect ALPN.
     [Todd Short]

  *) Remove LOW from the DEFAULT cipher list.  This removes singles DES from the
     default.
     [Kurt Roeckx]

  *) Only remove the SSLv2 methods with the no-ssl2-method option. When the
     methods are enabled and ssl2 is disabled the methods return NULL.
     [Kurt Roeckx]

diffstat:

 crypto/external/bsd/openssl/dist/apps/pkcs7.c                     |   12 +-
 crypto/external/bsd/openssl/dist/crypto/asn1/a_bytes.c            |    4 +-
 crypto/external/bsd/openssl/dist/crypto/asn1/asn1_lib.c           |   18 +-
 crypto/external/bsd/openssl/dist/crypto/asn1/asn1_par.c           |   17 +-
 crypto/external/bsd/openssl/dist/crypto/asn1/t_x509.c             |    3 +-
 crypto/external/bsd/openssl/dist/crypto/asn1/x_name.c             |   11 +
 crypto/external/bsd/openssl/dist/crypto/asn1/x_x509.c             |   16 +-
 crypto/external/bsd/openssl/dist/crypto/bn/asm/x86-mont.pl        |   15 +
 crypto/external/bsd/openssl/dist/crypto/bn/asm/x86_64-mont.pl     |   40 ++-
 crypto/external/bsd/openssl/dist/crypto/bn/asm/x86_64-mont5.pl    |   22 +
 crypto/external/bsd/openssl/dist/crypto/comp/comp.h               |    4 +
 crypto/external/bsd/openssl/dist/crypto/evp/digest.c              |    4 +-
 crypto/external/bsd/openssl/dist/crypto/evp/e_aes_cbc_hmac_sha1.c |    3 +
 crypto/external/bsd/openssl/dist/crypto/evp/encode.c              |   12 +-
 crypto/external/bsd/openssl/dist/crypto/pem/pem_lib.c             |    2 +-
 crypto/external/bsd/openssl/dist/crypto/pem/pvkfmt.c              |    7 +
 crypto/external/bsd/openssl/dist/crypto/x509/x509.h               |    1 +
 crypto/external/bsd/openssl/dist/crypto/x509/x509_err.c           |    1 +
 crypto/external/bsd/openssl/dist/crypto/x509/x509_obj.c           |   26 +-
 crypto/external/bsd/openssl/dist/doc/apps/ciphers.pod             |    2 +-
 crypto/external/bsd/openssl/dist/doc/crypto/EVP_EncodeInit.pod    |  127 ++++++++++
 crypto/external/bsd/openssl/dist/doc/crypto/evp.pod               |    5 +
 crypto/external/bsd/openssl/dist/ssl/s2_meth.c                    |   14 +-
 crypto/external/bsd/openssl/dist/test/testfipsssl                 |    8 +-
 crypto/external/bsd/openssl/dist/util/libeay.num                  |   18 +-
 25 files changed, 341 insertions(+), 51 deletions(-)

diffs (truncated from 851 to 300 lines):

diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/apps/pkcs7.c
--- a/crypto/external/bsd/openssl/dist/apps/pkcs7.c     Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/apps/pkcs7.c     Tue May 03 17:10:26 2016 +0000
@@ -235,12 +235,16 @@
         i = OBJ_obj2nid(p7->type);
         switch (i) {
         case NID_pkcs7_signed:
-            certs = p7->d.sign->cert;
-            crls = p7->d.sign->crl;
+            if (p7->d.sign != NULL) {
+                certs = p7->d.sign->cert;
+                crls = p7->d.sign->crl;
+            }
             break;
         case NID_pkcs7_signedAndEnveloped:
-            certs = p7->d.signed_and_enveloped->cert;
-            crls = p7->d.signed_and_enveloped->crl;
+            if (p7->d.signed_and_enveloped != NULL) {
+                certs = p7->d.signed_and_enveloped->cert;
+                crls = p7->d.signed_and_enveloped->crl;
+            }
             break;
         default:
             break;
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/asn1/a_bytes.c
--- a/crypto/external/bsd/openssl/dist/crypto/asn1/a_bytes.c    Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/asn1/a_bytes.c    Tue May 03 17:10:26 2016 +0000
@@ -200,13 +200,13 @@
     } else {
         if (len != 0) {
             if ((ret->length < len) || (ret->data == NULL)) {
-                if (ret->data != NULL)
-                    OPENSSL_free(ret->data);
                 s = (unsigned char *)OPENSSL_malloc((int)len + 1);
                 if (s == NULL) {
                     i = ERR_R_MALLOC_FAILURE;
                     goto err;
                 }
+                if (ret->data != NULL)
+                    OPENSSL_free(ret->data);
             } else
                 s = ret->data;
             memcpy(s, p, (int)len);
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/asn1/asn1_lib.c
--- a/crypto/external/bsd/openssl/dist/crypto/asn1/asn1_lib.c   Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/asn1/asn1_lib.c   Tue May 03 17:10:26 2016 +0000
@@ -63,7 +63,7 @@
 #include <openssl/asn1_mac.h>
 
 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
-                           int max);
+                           long max);
 static void asn1_put_length(unsigned char **pp, int length);
 const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT;
 
@@ -131,7 +131,7 @@
     }
     *ptag = tag;
     *pclass = xclass;
-    if (!asn1_get_length(&p, &inf, plength, (int)max))
+    if (!asn1_get_length(&p, &inf, plength, max))
         goto err;
 
     if (inf && !(ret & V_ASN1_CONSTRUCTED))
@@ -159,14 +159,14 @@
 }
 
 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
-                           int max)
+                           long max)
 {
     const unsigned char *p = *pp;
     unsigned long ret = 0;
-    unsigned int i;
+    unsigned long i;
 
     if (max-- < 1)
-        return (0);
+        return 0;
     if (*p == 0x80) {
         *inf = 1;
         ret = 0;
@@ -175,15 +175,11 @@
         *inf = 0;
         i = *p & 0x7f;
         if (*(p++) & 0x80) {
-            if (i > sizeof(long))
+            if (i > sizeof(ret) || max < (long)i)
                 return 0;
-            if (max-- == 0)
-                return (0);
             while (i-- > 0) {
                 ret <<= 8L;
                 ret |= *(p++);
-                if (max-- == 0)
-                    return (0);
             }
         } else
             ret = i;
@@ -192,7 +188,7 @@
         return 0;
     *pp = p;
     *rl = (long)ret;
-    return (1);
+    return 1;
 }
 
 /*
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/asn1/asn1_par.c
--- a/crypto/external/bsd/openssl/dist/crypto/asn1/asn1_par.c   Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/asn1/asn1_par.c   Tue May 03 17:10:26 2016 +0000
@@ -173,6 +173,8 @@
         if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
             goto end;
         if (j & V_ASN1_CONSTRUCTED) {
+            const unsigned char *sp;
+
             ep = p + len;
             if (BIO_write(bp, "\n", 1) <= 0)
                 goto end;
@@ -182,6 +184,7 @@
                 goto end;
             }
             if ((j == 0x21) && (len == 0)) {
+                sp = p;
                 for (;;) {
                     r = asn1_parse2(bp, &p, (long)(tot - p),
                                     offset + (p - *pp), depth + 1,
@@ -190,19 +193,25 @@
                         ret = 0;
                         goto end;
                     }
-                    if ((r == 2) || (p >= tot))
+                    if ((r == 2) || (p >= tot)) {
+                        len = p - sp;
                         break;
+                    }
                 }
-            } else
+            } else {
+                long tmp = len;
+
                 while (p < ep) {
-                    r = asn1_parse2(bp, &p, (long)len,
-                                    offset + (p - *pp), depth + 1,
+                    sp = p;
+                    r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1,
                                     indent, dump);
                     if (r == 0) {
                         ret = 0;
                         goto end;
                     }
+                    tmp -= p - sp;
                 }
+            }
         } else if (xclass != 0) {
             p += len;
             if (BIO_write(bp, "\n", 1) <= 0)
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/asn1/t_x509.c
--- a/crypto/external/bsd/openssl/dist/crypto/asn1/t_x509.c     Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/asn1/t_x509.c     Tue May 03 17:10:26 2016 +0000
@@ -140,7 +140,8 @@
             goto err;
 
         bs = X509_get_serialNumber(x);
-        if (bs->length <= (int)sizeof(long)) {
+        if (bs->length < (int)sizeof(long)
+            || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) {
             l = ASN1_INTEGER_get(bs);
             if (bs->type == V_ASN1_NEG_INTEGER) {
                 l = -l;
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/asn1/x_name.c
--- a/crypto/external/bsd/openssl/dist/crypto/asn1/x_name.c     Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/asn1/x_name.c     Tue May 03 17:10:26 2016 +0000
@@ -66,6 +66,13 @@
 typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
 DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
 
+/*
+ * Maximum length of X509_NAME: much larger than anything we should
+ * ever see in practice.
+ */
+
+#define X509_NAME_MAX (1024 * 1024)
+
 static int x509_name_ex_d2i(ASN1_VALUE **val,
                             const unsigned char **in, long len,
                             const ASN1_ITEM *it,
@@ -192,6 +199,10 @@
     int i, j, ret;
     STACK_OF(X509_NAME_ENTRY) *entries;
     X509_NAME_ENTRY *entry;
+    if (len > X509_NAME_MAX) {
+        ASN1err(ASN1_F_X509_NAME_EX_D2I, ASN1_R_TOO_LONG);
+        return 0;
+    }
     q = p;
 
     /* Get internal representation of Name */
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/asn1/x_x509.c
--- a/crypto/external/bsd/openssl/dist/crypto/asn1/x_x509.c     Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/asn1/x_x509.c     Tue May 03 17:10:26 2016 +0000
@@ -201,9 +201,19 @@
 
 int i2d_X509_AUX(X509 *a, unsigned char **pp)
 {
-    int length;
+    int length, tmplen;
+    unsigned char *start = pp != NULL ? *pp : NULL;
     length = i2d_X509(a, pp);
-    if (a)
-        length += i2d_X509_CERT_AUX(a->aux, pp);
+    if (length < 0 || a == NULL)
+        return length;
+
+    tmplen = i2d_X509_CERT_AUX(a->aux, pp);
+    if (tmplen < 0) {
+        if (start != NULL)
+            *pp = start;
+        return tmplen;
+    }
+    length += tmplen;
+
     return length;
 }
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/bn/asm/x86-mont.pl
--- a/crypto/external/bsd/openssl/dist/crypto/bn/asm/x86-mont.pl        Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/bn/asm/x86-mont.pl        Tue May 03 17:10:26 2016 +0000
@@ -85,6 +85,21 @@
 
        &and    ("esp",-64);            # align to cache line
 
+       # Some OSes, *cough*-dows, insist on stack being "wired" to
+       # physical memory in strictly sequential manner, i.e. if stack
+       # allocation spans two pages, then reference to farmost one can
+       # be punishable by SEGV. But page walking can do good even on
+       # other OSes, because it guarantees that villain thread hits
+       # the guard page before it can make damage to innocent one...
+       &mov    ("eax","ebp");
+       &sub    ("eax","esp");
+       &and    ("eax",-4096);
+&set_label("page_walk");
+       &mov    ("edx",&DWP(0,"esp","eax"));
+       &sub    ("eax",4096);
+       &data_byte(0x2e);
+       &jnc    (&label("page_walk"));
+
        ################################# load argument block...
        &mov    ("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
        &mov    ("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
diff -r 275865247a5a -r 9ed953c5adca crypto/external/bsd/openssl/dist/crypto/bn/asm/x86_64-mont.pl
--- a/crypto/external/bsd/openssl/dist/crypto/bn/asm/x86_64-mont.pl     Tue May 03 13:47:58 2016 +0000
+++ b/crypto/external/bsd/openssl/dist/crypto/bn/asm/x86_64-mont.pl     Tue May 03 17:10:26 2016 +0000
@@ -91,6 +91,20 @@
 
        mov     %r11,8(%rsp,$num,8)     # tp[num+1]=%rsp
 .Lmul_body:
+       # Some OSes, *cough*-dows, insist on stack being "wired" to
+       # physical memory in strictly sequential manner, i.e. if stack
+       # allocation spans two pages, then reference to farmost one can
+       # be punishable by SEGV. But page walking can do good even on
+       # other OSes, because it guarantees that villain thread hits
+       # the guard page before it can make damage to innocent one...
+       sub     %rsp,%r11
+       and     \$-4096,%r11
+.Lmul_page_walk:
+       mov     (%rsp,%r11),%r10
+       sub     \$4096,%r11
+       .byte   0x66,0x2e               # predict non-taken
+       jnc     .Lmul_page_walk
+
        mov     $bp,%r12                # reassign $bp
 ___
                $bp="%r12";
@@ -296,6 +310,14 @@
 
        mov     %r11,8(%rsp,$num,8)     # tp[num+1]=%rsp
 .Lmul4x_body:
+       sub     %rsp,%r11
+       and     \$-4096,%r11
+.Lmul4x_page_walk:
+       mov     (%rsp,%r11),%r10
+       sub     \$4096,%r11
+       .byte   0x2e                    # predict non-taken
+       jnc     .Lmul4x_page_walk
+
        mov     $rp,16(%rsp,$num,8)     # tp[num+2]=$rp
        mov     %rdx,%r12               # reassign $bp
 ___
@@ -707,6 +729,7 @@
 .align 16
 bn_sqr4x_mont:
 .Lsqr4x_enter:
+       mov     %rsp,%rax
        push    %rbx
        push    %rbp
        push    %r12
@@ -715,12 +738,23 @@
        push    %r15
 



Home | Main Index | Thread Index | Old Index