GNU bug report logs - #31834
[PATCH 1/2] gnu: OpenSSL 1.0.2: Fix CVE-2018-{0495,0732}.

Previous Next

Package: guix-patches;

Reported by: Leo Famulari <leo <at> famulari.name>

Date: Thu, 14 Jun 2018 20:44:02 UTC

Severity: normal

Tags: patch

Done: Leo Famulari <leo <at> famulari.name>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 31834 in the body.
You can then email your comments to 31834 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#31834; Package guix-patches. (Thu, 14 Jun 2018 20:44:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Leo Famulari <leo <at> famulari.name>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Thu, 14 Jun 2018 20:44:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Leo Famulari <leo <at> famulari.name>
To: guix-patches <at> gnu.org
Subject: [PATCH 1/2] gnu: OpenSSL 1.0.2: Fix CVE-2018-{0495,0732}.
Date: Thu, 14 Jun 2018 16:43:14 -0400
* gnu/packages/patches/openssl-1.0.2-CVE-2018-0495.patch,
gnu/packages/patches/openssl-1.0.2-CVE-2018-0732.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/tls.scm (openssl)[replacement]: New field.
(openssl/fixed): New variable.
---
 gnu/local.mk                                  |   2 +
 .../patches/openssl-1.0.2-CVE-2018-0495.patch | 215 ++++++++++++++++++
 .../patches/openssl-1.0.2-CVE-2018-0732.patch |  50 ++++
 gnu/packages/tls.scm                          |  10 +
 4 files changed, 277 insertions(+)
 create mode 100644 gnu/packages/patches/openssl-1.0.2-CVE-2018-0495.patch
 create mode 100644 gnu/packages/patches/openssl-1.0.2-CVE-2018-0732.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 01e071872..e9d572922 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -973,6 +973,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/openscenegraph-ffmpeg3.patch             \
   %D%/packages/patches/opensmtpd-fix-crash.patch		\
   %D%/packages/patches/openssl-runpath.patch			\
+  %D%/packages/patches/openssl-1.0.2-CVE-2018-0495.patch	\
+  %D%/packages/patches/openssl-1.0.2-CVE-2018-0732.patch	\
   %D%/packages/patches/openssl-1.1.0-c-rehash-in.patch		\
   %D%/packages/patches/openssl-c-rehash-in.patch		\
   %D%/packages/patches/orpheus-cast-errors-and-includes.patch	\
diff --git a/gnu/packages/patches/openssl-1.0.2-CVE-2018-0495.patch b/gnu/packages/patches/openssl-1.0.2-CVE-2018-0495.patch
new file mode 100644
index 000000000..2d54ed03b
--- /dev/null
+++ b/gnu/packages/patches/openssl-1.0.2-CVE-2018-0495.patch
@@ -0,0 +1,215 @@
+Fix CVE-2018-0495:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0495
+https://www.nccgroup.trust/us/our-research/technical-advisory-return-of-the-hidden-number-problem/
+
+Patch copied from upstream source repository:
+
+https://github.com/openssl/openssl/commit/949ff36623eafc3523a9f91784992965018ffb05
+
+From 949ff36623eafc3523a9f91784992965018ffb05 Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt <at> openssl.org>
+Date: Fri, 25 May 2018 12:10:13 +0100
+Subject: [PATCH] Add blinding to an ECDSA signature
+
+Keegan Ryan (NCC Group) has demonstrated a side channel attack on an
+ECDSA signature operation. During signing the signer calculates:
+
+s:= k^-1 * (m + r * priv_key) mod order
+
+The addition operation above provides a sufficient signal for a
+flush+reload attack to derive the private key given sufficient signature
+operations.
+
+As a mitigation (based on a suggestion from Keegan) we add blinding to
+the operation so that:
+
+s := k^-1 * blind^-1 (blind * m + blind * r * priv_key) mod order
+
+Since this attack is a localhost side channel only no CVE is assigned.
+
+Reviewed-by: Rich Salz <rsalz <at> openssl.org>
+---
+ CHANGES                  |  4 ++
+ crypto/ecdsa/ecdsatest.c |  9 ++++-
+ crypto/ecdsa/ecs_ossl.c  | 82 ++++++++++++++++++++++++++++++++--------
+ 3 files changed, 79 insertions(+), 16 deletions(-)
+
+diff --git a/crypto/ecdsa/ecdsatest.c b/crypto/ecdsa/ecdsatest.c
+index 0f301f86d9..a130fc9117 100644
+--- a/crypto/ecdsa/ecdsatest.c
++++ b/crypto/ecdsa/ecdsatest.c
+@@ -137,7 +137,7 @@ int restore_rand(void)
+         return 1;
+ }
+ 
+-static int fbytes_counter = 0;
++static int fbytes_counter = 0, use_fake = 0;
+ static const char *numbers[8] = {
+     "651056770906015076056810763456358567190100156695615665659",
+     "6140507067065001063065065565667405560006161556565665656654",
+@@ -158,6 +158,11 @@ int fbytes(unsigned char *buf, int num)
+     int ret;
+     BIGNUM *tmp = NULL;
+ 
++    if (use_fake == 0)
++        return old_rand->bytes(buf, num);
++
++    use_fake = 0;
++
+     if (fbytes_counter >= 8)
+         return 0;
+     tmp = BN_new();
+@@ -199,11 +204,13 @@ int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
+     /* create the key */
+     if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
+         goto x962_int_err;
++    use_fake = 1;
+     if (!EC_KEY_generate_key(key))
+         goto x962_int_err;
+     BIO_printf(out, ".");
+     (void)BIO_flush(out);
+     /* create the signature */
++    use_fake = 1;
+     signature = ECDSA_do_sign(digest, 20, key);
+     if (signature == NULL)
+         goto x962_int_err;
+diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c
+index 16d4f59b9b..1d37551803 100644
+--- a/crypto/ecdsa/ecs_ossl.c
++++ b/crypto/ecdsa/ecs_ossl.c
+@@ -252,6 +252,7 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
+ {
+     int ok = 0, i;
+     BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
++    BIGNUM *blind = NULL, *blindm = NULL;
+     const BIGNUM *ckinv;
+     BN_CTX *ctx = NULL;
+     const EC_GROUP *group;
+@@ -269,14 +270,25 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
+     }
+ 
+     ret = ECDSA_SIG_new();
+-    if (!ret) {
++    if (ret == NULL) {
+         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+         return NULL;
+     }
+     s = ret->s;
+ 
+-    if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
+-        (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
++    ctx = BN_CTX_new();
++    if (ctx == NULL) {
++        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
++        goto err;
++    }
++
++    BN_CTX_start(ctx);
++    order = BN_CTX_get(ctx);
++    tmp = BN_CTX_get(ctx);
++    m = BN_CTX_get(ctx);
++    blind = BN_CTX_get(ctx);
++    blindm = BN_CTX_get(ctx);
++    if (blindm == NULL) {
+         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+         goto err;
+     }
+@@ -315,26 +327,70 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
+             }
+         }
+ 
+-        if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
++        /*
++         * The normal signature calculation is:
++         *
++         *   s := k^-1 * (m + r * priv_key) mod order
++         *
++         * We will blind this to protect against side channel attacks
++         *
++         *   s := k^-1 * blind^-1 * (blind * m + blind * r * priv_key) mod order
++         */
++
++        /* Generate a blinding value */
++        do {
++            if (!BN_rand(blind, BN_num_bits(order) - 1, -1, 0))
++                goto err;
++        } while (BN_is_zero(blind));
++        BN_set_flags(blind, BN_FLG_CONSTTIME);
++        BN_set_flags(blindm, BN_FLG_CONSTTIME);
++        BN_set_flags(tmp, BN_FLG_CONSTTIME);
++
++        /* tmp := blind * priv_key * r mod order */
++        if (!BN_mod_mul(tmp, blind, priv_key, order, ctx)) {
++            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
++            goto err;
++        }
++        if (!BN_mod_mul(tmp, tmp, ret->r, order, ctx)) {
++            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
++            goto err;
++        }
++
++        /* blindm := blind * m mod order */
++        if (!BN_mod_mul(blindm, blind, m, order, ctx)) {
++            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
++            goto err;
++        }
++
++        /* s : = (blind * priv_key * r) + (blind * m) mod order */
++        if (!BN_mod_add_quick(s, tmp, blindm, order)) {
++            ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
++            goto err;
++        }
++
++        /* s:= s * blind^-1 mod order */
++        if (BN_mod_inverse(blind, blind, order, ctx) == NULL) {
+             ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+             goto err;
+         }
+-        if (!BN_mod_add_quick(s, tmp, m, order)) {
++        if (!BN_mod_mul(s, s, blind, order, ctx)) {
+             ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+             goto err;
+         }
++
++        /* s := s * k^-1 mod order */
+         if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
+             ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+             goto err;
+         }
++
+         if (BN_is_zero(s)) {
+             /*
+              * if kinv and r have been supplied by the caller don't to
+              * generate new kinv and r values
+              */
+             if (in_kinv != NULL && in_r != NULL) {
+-                ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
+-                         ECDSA_R_NEED_NEW_SETUP_VALUES);
++                ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
+                 goto err;
+             }
+         } else
+@@ -349,15 +405,11 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
+         ECDSA_SIG_free(ret);
+         ret = NULL;
+     }
+-    if (ctx)
++    if (ctx != NULL) {
++        BN_CTX_end(ctx);
+         BN_CTX_free(ctx);
+-    if (m)
+-        BN_clear_free(m);
+-    if (tmp)
+-        BN_clear_free(tmp);
+-    if (order)
+-        BN_free(order);
+-    if (kinv)
++    }
++    if (kinv != NULL)
+         BN_clear_free(kinv);
+     return ret;
+ }
+-- 
+2.17.1
+
diff --git a/gnu/packages/patches/openssl-1.0.2-CVE-2018-0732.patch b/gnu/packages/patches/openssl-1.0.2-CVE-2018-0732.patch
new file mode 100644
index 000000000..50b95306a
--- /dev/null
+++ b/gnu/packages/patches/openssl-1.0.2-CVE-2018-0732.patch
@@ -0,0 +1,50 @@
+Fix CVE-2018-0732:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0732
+
+Patch copied from upstream source repository:
+
+https://github.com/openssl/openssl/commit/3984ef0b72831da8b3ece4745cac4f8575b19098
+
+From 3984ef0b72831da8b3ece4745cac4f8575b19098 Mon Sep 17 00:00:00 2001
+From: Guido Vranken <guidovranken <at> gmail.com>
+Date: Mon, 11 Jun 2018 19:38:54 +0200
+Subject: [PATCH] Reject excessively large primes in DH key generation.
+
+CVE-2018-0732
+
+Signed-off-by: Guido Vranken <guidovranken <at> gmail.com>
+
+(cherry picked from commit 91f7361f47b082ae61ffe1a7b17bb2adf213c7fe)
+
+Reviewed-by: Tim Hudson <tjh <at> openssl.org>
+Reviewed-by: Matt Caswell <matt <at> openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/6457)
+---
+ crypto/dh/dh_key.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
+index 387558f146..f235e0d682 100644
+--- a/crypto/dh/dh_key.c
++++ b/crypto/dh/dh_key.c
+@@ -130,10 +130,15 @@ static int generate_key(DH *dh)
+     int ok = 0;
+     int generate_new_key = 0;
+     unsigned l;
+-    BN_CTX *ctx;
++    BN_CTX *ctx = NULL;
+     BN_MONT_CTX *mont = NULL;
+     BIGNUM *pub_key = NULL, *priv_key = NULL;
+ 
++    if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
++        DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE);
++        return 0;
++    }
++
+     ctx = BN_CTX_new();
+     if (ctx == NULL)
+         goto err;
+-- 
+2.17.1
+
diff --git a/gnu/packages/tls.scm b/gnu/packages/tls.scm
index a934a5087..a582fb152 100644
--- a/gnu/packages/tls.scm
+++ b/gnu/packages/tls.scm
@@ -255,6 +255,7 @@ required structures.")
 (define-public openssl
   (package
    (name "openssl")
+   (replacement openssl/fixed)
    (version "1.0.2o")
    (source (origin
              (method url-fetch)
@@ -391,6 +392,15 @@ required structures.")
    (license license:openssl)
    (home-page "https://www.openssl.org/")))
 
+(define openssl/fixed
+  (package
+    (inherit openssl)
+    (source (origin
+              (inherit (package-source openssl))
+              (patches (append (origin-patches (package-source openssl))
+                               (search-patches "openssl-1.0.2-CVE-2018-0495.patch"
+                                               "openssl-1.0.2-CVE-2018-0732.patch")))))))
+
 (define-public openssl-next
   (package
     (inherit openssl)
-- 
2.17.1





Reply sent to Leo Famulari <leo <at> famulari.name>:
You have taken responsibility. (Mon, 18 Jun 2018 16:08:02 GMT) Full text and rfc822 format available.

Notification sent to Leo Famulari <leo <at> famulari.name>:
bug acknowledged by developer. (Mon, 18 Jun 2018 16:08:02 GMT) Full text and rfc822 format available.

Message #10 received at 31834-done <at> debbugs.gnu.org (full text, mbox):

From: Leo Famulari <leo <at> famulari.name>
To: 31834-done <at> debbugs.gnu.org
Subject: RE: gnu: OpenSSL 1.0.2: Fix CVE-2018-{0495,0732}.
Date: Mon, 18 Jun 2018 12:07:00 -0400
[Message part 1 (text/plain, inline)]
Pushed as b8ea0db3aebf6ec9b1f3720759897d97bc2fcd48
[signature.asc (application/pgp-signature, inline)]

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 17 Jul 2018 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 5 years and 284 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.