From b8ea0db3aebf6ec9b1f3720759897d97bc2fcd48 Mon Sep 17 00:00:00 2001 From: Leo Famulari Date: Thu, 14 Jun 2018 16:26:57 -0400 Subject: [PATCH] gnu: OpenSSL 1.0.2: Fix CVE-2018-{0495,0732}. * 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 2856186595..be3b2e31dd 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -975,6 +975,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 0000000000..2d54ed03b9 --- /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 +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 +--- + 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 0000000000..50b95306a5 --- /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 +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 + +(cherry picked from commit 91f7361f47b082ae61ffe1a7b17bb2adf213c7fe) + +Reviewed-by: Tim Hudson +Reviewed-by: Matt Caswell +(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 35134025b8..69edd32582 100644 --- a/gnu/packages/tls.scm +++ b/gnu/packages/tls.scm @@ -260,6 +260,7 @@ (define-public gnutls/dane (define-public openssl (package (name "openssl") + (replacement openssl/fixed) (version "1.0.2o") (source (origin (method url-fetch) @@ -396,6 +397,15 @@ (define-public openssl (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)