File shim-update-openssl-1.0.2h.patch of Package shim

From 12cfe049c6b6bfce580737ef4da9556ecd07260a Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Thu, 21 Jul 2016 12:28:11 +0800
Subject: [PATCH 1/2] Update to openssl 1.0.2h

Signed-off-by: Gary Lin <glin@suse.com>
---
 Cryptlib/Include/openssl/comp.h                    |  4 +++
 Cryptlib/Include/openssl/conf.h                    | 12 ++++----
 Cryptlib/Include/openssl/opensslv.h                |  6 ++--
 Cryptlib/Include/openssl/pem.h                     |  1 +
 Cryptlib/Include/openssl/srp.h                     |  1 +
 Cryptlib/Include/openssl/ssl.h                     |  4 +--
 Cryptlib/Include/openssl/x509.h                    |  1 +
 Cryptlib/OpenSSL/crypto/asn1/a_bytes.c             |  4 +--
 Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c            | 36 ++++++++++++++++------
 Cryptlib/OpenSSL/crypto/asn1/a_type.c              |  2 --
 Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c            | 18 +++++------
 Cryptlib/OpenSSL/crypto/asn1/asn1_par.c            | 17 +++++++---
 Cryptlib/OpenSSL/crypto/asn1/t_x509.c              |  3 +-
 Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c            |  2 --
 Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c            |  2 --
 Cryptlib/OpenSSL/crypto/asn1/x_name.c              | 11 +++++++
 Cryptlib/OpenSSL/crypto/asn1/x_x509.c              | 16 ++++++++--
 Cryptlib/OpenSSL/crypto/bn/bn_prime.c              |  2 +-
 Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c              |  1 -
 Cryptlib/OpenSSL/crypto/evp/digest.c               |  4 ++-
 Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c  |  3 ++
 .../OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c     |  3 ++
 Cryptlib/OpenSSL/crypto/evp/encode.c               | 12 ++++++--
 Cryptlib/OpenSSL/crypto/evp/evp_enc.c              |  2 +-
 Cryptlib/OpenSSL/crypto/pem/pem_lib.c              |  2 +-
 Cryptlib/OpenSSL/crypto/pem/pem_pk8.c              |  2 +-
 Cryptlib/OpenSSL/crypto/pem/pvkfmt.c               |  7 +++++
 Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c          |  2 +-
 Cryptlib/OpenSSL/crypto/x509/x509_err.c            |  1 +
 Cryptlib/OpenSSL/crypto/x509/x509_obj.c            | 26 +++++++++++++---
 30 files changed, 145 insertions(+), 62 deletions(-)

diff --git a/Cryptlib/Include/openssl/comp.h b/Cryptlib/Include/openssl/comp.h
index 406c428..60a0734 100644
--- a/Cryptlib/Include/openssl/comp.h
+++ b/Cryptlib/Include/openssl/comp.h
@@ -4,6 +4,10 @@
 
 # include <openssl/crypto.h>
 
+# ifdef OPENSSL_NO_COMP
+#  error COMP is disabled.
+# endif
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
diff --git a/Cryptlib/Include/openssl/conf.h b/Cryptlib/Include/openssl/conf.h
index 41cf38e..c29e97d 100644
--- a/Cryptlib/Include/openssl/conf.h
+++ b/Cryptlib/Include/openssl/conf.h
@@ -135,9 +135,9 @@ char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
 long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
                      const char *name);
 void CONF_free(LHASH_OF(CONF_VALUE) *conf);
-#ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_FP_API
 int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
-#endif
+# endif
 int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
 
 void OPENSSL_config(const char *config_name);
@@ -176,9 +176,9 @@ STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,
 char *NCONF_get_string(const CONF *conf, const char *group, const char *name);
 int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
                        long *result);
-#ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_FP_API
 int NCONF_dump_fp(const CONF *conf, FILE *out);
-#endif
+# endif
 int NCONF_dump_bio(const CONF *conf, BIO *out);
 
 # if 0                          /* The following function has no error
@@ -192,10 +192,10 @@ long NCONF_get_number(CONF *conf, char *group, char *name);
 
 int CONF_modules_load(const CONF *cnf, const char *appname,
                       unsigned long flags);
-#ifndef OPENSSL_NO_STDIO
+# ifndef OPENSSL_NO_STDIO
 int CONF_modules_load_file(const char *filename, const char *appname,
                            unsigned long flags);
-#endif
+# endif
 void CONF_modules_unload(int all);
 void CONF_modules_finish(void);
 void CONF_modules_free(void);
diff --git a/Cryptlib/Include/openssl/opensslv.h b/Cryptlib/Include/openssl/opensslv.h
index 4334fd1..13fe440 100644
--- a/Cryptlib/Include/openssl/opensslv.h
+++ b/Cryptlib/Include/openssl/opensslv.h
@@ -30,11 +30,11 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-# define OPENSSL_VERSION_NUMBER  0x1000207fL
+# define OPENSSL_VERSION_NUMBER  0x1000208fL
 # ifdef OPENSSL_FIPS
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2g-fips  1 Mar 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2h-fips  3 May 2016"
 # else
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2g  1 Mar 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2h  3 May 2016"
 # endif
 # define OPENSSL_VERSION_PTEXT   " part of " OPENSSL_VERSION_TEXT
 
diff --git a/Cryptlib/Include/openssl/pem.h b/Cryptlib/Include/openssl/pem.h
index 87b0b6a..5df6ffd 100644
--- a/Cryptlib/Include/openssl/pem.h
+++ b/Cryptlib/Include/openssl/pem.h
@@ -515,6 +515,7 @@ int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                               char *kstr, int klen, pem_password_cb *cd,
                               void *u);
 #endif
+
 EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
 int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
 
diff --git a/Cryptlib/Include/openssl/srp.h b/Cryptlib/Include/openssl/srp.h
index 713fc54..4ed4bfe 100644
--- a/Cryptlib/Include/openssl/srp.h
+++ b/Cryptlib/Include/openssl/srp.h
@@ -122,6 +122,7 @@ int SRP_VBASE_free(SRP_VBASE *vb);
 #ifndef OPENSSL_NO_STDIO
 int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file);
 #endif
+
 /* This method ignores the configured seed and fails for an unknown user. */
 SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
 /* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/
diff --git a/Cryptlib/Include/openssl/ssl.h b/Cryptlib/Include/openssl/ssl.h
index 04d4007..5ef56fa 100644
--- a/Cryptlib/Include/openssl/ssl.h
+++ b/Cryptlib/Include/openssl/ssl.h
@@ -338,7 +338,7 @@ extern "C" {
  * The following cipher list is used by default. It also is substituted when
  * an application-defined cipher list string starts with 'DEFAULT'.
  */
-# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!aNULL:!eNULL:!SSLv2"
+# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2"
 /*
  * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
  * starts with a reasonable order, and all we have to do for DEFAULT is
@@ -2345,7 +2345,7 @@ const char *SSL_get_version(const SSL *s);
 /* This sets the 'default' SSL version that SSL_new() will create */
 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
 
-# ifndef OPENSSL_NO_SSL2
+# ifndef OPENSSL_NO_SSL2_METHOD
 const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
 const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
 const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
diff --git a/Cryptlib/Include/openssl/x509.h b/Cryptlib/Include/openssl/x509.h
index 99337b8..fc613ce 100644
--- a/Cryptlib/Include/openssl/x509.h
+++ b/Cryptlib/Include/openssl/x509.h
@@ -1305,6 +1305,7 @@ void ERR_load_X509_strings(void);
 # define X509_R_LOADING_CERT_DIR                          103
 # define X509_R_LOADING_DEFAULTS                          104
 # define X509_R_METHOD_NOT_SUPPORTED                      124
+# define X509_R_NAME_TOO_LONG                             134
 # define X509_R_NEWER_CRL_NOT_NEWER                       132
 # define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY              105
 # define X509_R_NO_CRL_NUMBER                             130
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_bytes.c b/Cryptlib/OpenSSL/crypto/asn1/a_bytes.c
index 12715a7..385b539 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_bytes.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_bytes.c
@@ -200,13 +200,13 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
     } 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 --git a/Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c b/Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c
index a1864b4..51b6f24 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c
@@ -141,6 +141,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
 #endif
 
 #define HEADER_SIZE   8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
 static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
 {
     BUF_MEM *b;
@@ -217,29 +218,44 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
             /* suck in c.slen bytes of data */
             want = c.slen;
             if (want > (len - off)) {
+                size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+
                 want -= (len - off);
                 if (want > INT_MAX /* BIO_read takes an int length */  ||
                     len + want < len) {
                     ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
                     goto err;
                 }
-                if (!BUF_MEM_grow_clean(b, len + want)) {
-                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
-                    goto err;
-                }
                 while (want > 0) {
-                    i = BIO_read(in, &(b->data[len]), want);
-                    if (i <= 0) {
-                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
-                                ASN1_R_NOT_ENOUGH_DATA);
+                    /*
+                     * Read content in chunks of increasing size
+                     * so we can return an error for EOF without
+                     * having to allocate the entire content length
+                     * in one go.
+                     */
+                    size_t chunk = want > chunk_max ? chunk_max : want;
+
+                    if (!BUF_MEM_grow_clean(b, len + chunk)) {
+                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
                         goto err;
                     }
+                    want -= chunk;
+                    while (chunk > 0) {
+                        i = BIO_read(in, &(b->data[len]), chunk);
+                        if (i <= 0) {
+                            ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+                                    ASN1_R_NOT_ENOUGH_DATA);
+                            goto err;
+                        }
                     /*
                      * This can't overflow because |len+want| didn't
                      * overflow.
                      */
-                    len += i;
-                    want -= i;
+                        len += i;
+                        chunk -= i;
+                    }
+                    if (chunk_max < INT_MAX/2)
+                        chunk_max *= 2;
                 }
             }
             if (off + c.slen < off) {
diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_type.c b/Cryptlib/OpenSSL/crypto/asn1/a_type.c
index af79530..bb166e8 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/a_type.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/a_type.c
@@ -126,9 +126,7 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
         result = 0;             /* They do not have content. */
         break;
     case V_ASN1_INTEGER:
-    case V_ASN1_NEG_INTEGER:
     case V_ASN1_ENUMERATED:
-    case V_ASN1_NEG_ENUMERATED:
     case V_ASN1_BIT_STRING:
     case V_ASN1_OCTET_STRING:
     case V_ASN1_SEQUENCE:
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
index 0b61fc9..874b1af 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c
@@ -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 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
     }
     *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 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
 }
 
 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 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
         *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 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
         return 0;
     *pp = p;
     *rl = (long)ret;
-    return (1);
+    return 1;
 }
 
 /*
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
index 0ca985a..e85e339 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_par.c
@@ -173,6 +173,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
         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 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
                 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 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
                         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 --git a/Cryptlib/OpenSSL/crypto/asn1/t_x509.c b/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
index 8aab551..8888396 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/t_x509.c
@@ -140,7 +140,8 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
             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 --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
index 5a50796..6bdcd5c 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c
@@ -901,9 +901,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
         break;
 
     case V_ASN1_INTEGER:
-    case V_ASN1_NEG_INTEGER:
     case V_ASN1_ENUMERATED:
-    case V_ASN1_NEG_ENUMERATED:
         tint = (ASN1_INTEGER **)pval;
         if (!c2i_ASN1_INTEGER(tint, &cont, len))
             goto err;
diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
index f04a689..f7f83e5 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c
@@ -611,9 +611,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
         break;
 
     case V_ASN1_INTEGER:
-    case V_ASN1_NEG_INTEGER:
     case V_ASN1_ENUMERATED:
-    case V_ASN1_NEG_ENUMERATED:
         /*
          * These are all have the same content format as ASN1_INTEGER
          */
diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_name.c b/Cryptlib/OpenSSL/crypto/asn1/x_name.c
index 737c426..a858c29 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_name.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_name.c
@@ -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 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
     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 --git a/Cryptlib/OpenSSL/crypto/asn1/x_x509.c b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
index e2cac83..e31e1e7 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c
@@ -201,10 +201,20 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
 
 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 --git a/Cryptlib/OpenSSL/crypto/bn/bn_prime.c b/Cryptlib/OpenSSL/crypto/bn/bn_prime.c
index e933ead..ad641c3 100644
--- a/Cryptlib/OpenSSL/crypto/bn/bn_prime.c
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_prime.c
@@ -172,7 +172,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
 
     mods = OPENSSL_malloc(sizeof(*mods) * NUMPRIMES);
     if (mods == NULL)
-	    goto err;
+        goto err;
     ctx = BN_CTX_new();
     if (ctx == NULL)
         goto err;
diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c b/Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c
index c6288f6..926be98 100644
--- a/Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c
+++ b/Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c
@@ -455,7 +455,6 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
     }
 #ifndef OPENSSL_NO_CMS
     else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
-
         unsigned char *Z = NULL;
         size_t Zlen = 0;
         if (!dctx->kdf_outlen || !dctx->kdf_oid)
diff --git a/Cryptlib/OpenSSL/crypto/evp/digest.c b/Cryptlib/OpenSSL/crypto/evp/digest.c
index f2643f3..5b642b2 100644
--- a/Cryptlib/OpenSSL/crypto/evp/digest.c
+++ b/Cryptlib/OpenSSL/crypto/evp/digest.c
@@ -212,8 +212,10 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
     }
 #endif
     if (ctx->digest != type) {
-        if (ctx->digest && ctx->digest->ctx_size)
+        if (ctx->digest && ctx->digest->ctx_size) {
             OPENSSL_free(ctx->md_data);
+            ctx->md_data = NULL;
+        }
         ctx->digest = type;
         if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
             ctx->update = type->update;
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c
index 8330964..6dfd590 100644
--- a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -60,6 +60,7 @@
 # include <openssl/sha.h>
 # include <openssl/rand.h>
 # include "modes_lcl.h"
+# include "constant_time_locl.h"
 
 # ifndef EVP_CIPH_FLAG_AEAD_CIPHER
 #  define EVP_CIPH_FLAG_AEAD_CIPHER       0x200000
@@ -578,6 +579,8 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
             maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
             maxpad &= 255;
 
+            ret &= constant_time_ge(maxpad, pad);
+
             inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
             mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
             inp_len &= mask;
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c
index 3780021..46c9d03 100644
--- a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c
@@ -60,6 +60,7 @@
 # include <openssl/sha.h>
 # include <openssl/rand.h>
 # include "modes_lcl.h"
+# include "constant_time_locl.h"
 
 # ifndef EVP_CIPH_FLAG_AEAD_CIPHER
 #  define EVP_CIPH_FLAG_AEAD_CIPHER       0x200000
@@ -589,6 +590,8 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx,
             maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
             maxpad &= 255;
 
+            ret &= constant_time_ge(maxpad, pad);
+
             inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1);
             mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
             inp_len &= mask;
diff --git a/Cryptlib/OpenSSL/crypto/evp/encode.c b/Cryptlib/OpenSSL/crypto/evp/encode.c
index c6abc4a..c6c775e 100644
--- a/Cryptlib/OpenSSL/crypto/evp/encode.c
+++ b/Cryptlib/OpenSSL/crypto/evp/encode.c
@@ -57,6 +57,7 @@
  */
 
 #include <stdio.h>
+#include <limits.h>
 #include "cryptlib.h"
 #include <openssl/evp.h>
 
@@ -151,13 +152,13 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
                       const unsigned char *in, int inl)
 {
     int i, j;
-    unsigned int total = 0;
+    size_t total = 0;
 
     *outl = 0;
     if (inl <= 0)
         return;
     OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
-    if ((ctx->num + inl) < ctx->length) {
+    if (ctx->length - ctx->num > inl) {
         memcpy(&(ctx->enc_data[ctx->num]), in, inl);
         ctx->num += inl;
         return;
@@ -174,7 +175,7 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
         *out = '\0';
         total = j + 1;
     }
-    while (inl >= ctx->length) {
+    while (inl >= ctx->length && total <= INT_MAX) {
         j = EVP_EncodeBlock(out, in, ctx->length);
         in += ctx->length;
         inl -= ctx->length;
@@ -183,6 +184,11 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
         *out = '\0';
         total += j + 1;
     }
+    if (total > INT_MAX) {
+        /* Too much output data! */
+        *outl = 0;
+        return;
+    }
     if (inl != 0)
         memcpy(&(ctx->enc_data[0]), in, inl);
     ctx->num = inl;
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_enc.c b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
index 65f0e02..7d7be24 100644
--- a/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
@@ -347,7 +347,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     bl = ctx->cipher->block_size;
     OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
     if (i != 0) {
-        if (i + inl < bl) {
+        if (bl - i > inl) {
             memcpy(&(ctx->buf[i]), in, inl);
             ctx->buf_len += inl;
             *outl = 0;
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_lib.c b/Cryptlib/OpenSSL/crypto/pem/pem_lib.c
index 5525efd..e25cc68 100644
--- a/Cryptlib/OpenSSL/crypto/pem/pem_lib.c
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_lib.c
@@ -348,7 +348,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
 
     if (enc != NULL) {
         objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
-        if (objstr == NULL) {
+        if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) {
             PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
             goto err;
         }
diff --git a/Cryptlib/OpenSSL/crypto/pem/pem_pk8.c b/Cryptlib/OpenSSL/crypto/pem/pem_pk8.c
index fe465cc..9edca4d 100644
--- a/Cryptlib/OpenSSL/crypto/pem/pem_pk8.c
+++ b/Cryptlib/OpenSSL/crypto/pem/pem_pk8.c
@@ -69,12 +69,12 @@
 static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
                       int nid, const EVP_CIPHER *enc,
                       char *kstr, int klen, pem_password_cb *cb, void *u);
-
 #ifndef OPENSSL_NO_FP_API
 static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
                          int nid, const EVP_CIPHER *enc,
                          char *kstr, int klen, pem_password_cb *cb, void *u);
 #endif
+
 /*
  * These functions write a private key in PKCS#8 format: it is a "drop in"
  * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
diff --git a/Cryptlib/OpenSSL/crypto/pem/pvkfmt.c b/Cryptlib/OpenSSL/crypto/pem/pvkfmt.c
index 82d4527..6186446 100644
--- a/Cryptlib/OpenSSL/crypto/pem/pvkfmt.c
+++ b/Cryptlib/OpenSSL/crypto/pem/pvkfmt.c
@@ -131,6 +131,10 @@ static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
 # define MS_PVKMAGIC             0xb0b5f11eL
 /* Salt length for PVK files */
 # define PVK_SALTLEN             0x10
+/* Maximum length in PVK header */
+# define PVK_MAX_KEYLEN          102400
+/* Maximum salt length */
+# define PVK_MAX_SALTLEN         10240
 
 static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
                          unsigned int bitlen, int ispub);
@@ -644,6 +648,9 @@ static int do_PVK_header(const unsigned char **in, unsigned int length,
     *psaltlen = read_ledword(&p);
     *pkeylen = read_ledword(&p);
 
+    if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN)
+        return 0;
+
     if (is_encrypted && !*psaltlen) {
         PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
         return 0;
diff --git a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c
index 0bc3d43..e75c4b2 100644
--- a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c
@@ -64,7 +64,6 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-
 #define BUFFERSIZE 4096
 
 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
@@ -596,6 +595,7 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
             break;
         }
     }
+
 err:
     OPENSSL_free(buf);
     BIO_free_all(tmpmem);
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_err.c b/Cryptlib/OpenSSL/crypto/x509/x509_err.c
index 43cde18..1e779fe 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_err.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_err.c
@@ -151,6 +151,7 @@ static ERR_STRING_DATA X509_str_reasons[] = {
     {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"},
     {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"},
     {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"},
+    {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"},
     {ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"},
     {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
      "no cert set for us to verify"},
diff --git a/Cryptlib/OpenSSL/crypto/x509/x509_obj.c b/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
index d317f3a..3de3ac7 100644
--- a/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
+++ b/Cryptlib/OpenSSL/crypto/x509/x509_obj.c
@@ -63,6 +63,13 @@
 #include <openssl/x509.h>
 #include <openssl/buffer.h>
 
+/*
+ * Limit to ensure we don't overflow: much greater than
+ * anything enountered in practice.
+ */
+
+#define NAME_ONELINE_MAX    (1024 * 1024)
+
 char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
 {
     X509_NAME_ENTRY *ne;
@@ -86,6 +93,8 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
             goto err;
         b->data[0] = '\0';
         len = 200;
+    } else if (len == 0) {
+        return NULL;
     }
     if (a == NULL) {
         if (b) {
@@ -110,6 +119,10 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
 
         type = ne->value->type;
         num = ne->value->length;
+        if (num > NAME_ONELINE_MAX) {
+            X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+            goto end;
+        }
         q = ne->value->data;
 #ifdef CHARSET_EBCDIC
         if (type == V_ASN1_GENERALSTRING ||
@@ -117,8 +130,9 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
             type == V_ASN1_PRINTABLESTRING ||
             type == V_ASN1_TELETEXSTRING ||
             type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) {
-            ascii2ebcdic(ebcdic_buf, q, (num > sizeof ebcdic_buf)
-                         ? sizeof ebcdic_buf : num);
+            if (num > (int)sizeof(ebcdic_buf))
+                num = sizeof(ebcdic_buf);
+            ascii2ebcdic(ebcdic_buf, q, num);
             q = ebcdic_buf;
         }
 #endif
@@ -154,6 +168,10 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
 
         lold = l;
         l += 1 + l1 + 1 + l2;
+        if (l > NAME_ONELINE_MAX) {
+            X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+            goto end;
+        }
         if (b != NULL) {
             if (!BUF_MEM_grow(b, l + 1))
                 goto err;
@@ -206,7 +224,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
     return (p);
  err:
     X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
-    if (b != NULL)
-        BUF_MEM_free(b);
+ end:
+    BUF_MEM_free(b);
     return (NULL);
 }
-- 
2.9.2


From 7d7b9e9bfc6730eb5aa608d7901e36468ace2361 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Thu, 21 Jul 2016 12:32:45 +0800
Subject: [PATCH 2/2] Update the CryptLib

Update to the edk2 commit 8ff7187cfd998d2b6db43075a4a7908281b6da00

Signed-off-by: Gary Lin <glin@suse.com>
---
 Cryptlib/Pk/CryptPkcs7Verify.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Cryptlib/Pk/CryptPkcs7Verify.c b/Cryptlib/Pk/CryptPkcs7Verify.c
index 559610d..efa3796 100644
--- a/Cryptlib/Pk/CryptPkcs7Verify.c
+++ b/Cryptlib/Pk/CryptPkcs7Verify.c
@@ -10,7 +10,7 @@
   WrapPkcs7Data(), Pkcs7GetSigners(), Pkcs7Verify() will get UEFI Authenticated
   Variable and will do basic check for data structure.
 
-Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -489,6 +489,8 @@ Pkcs7GetCertificatesList (
   OldBuf         = NULL;
   Signers        = NULL;
 
+  ZeroMem (&CertCtx, sizeof (CertCtx));
+
   //
   // Parameter Checking
   //
-- 
2.9.2