Browse Source

openssl package update

Signed-off-by: basebuilder_pel7x64builder0 <basebuilder@powerel.org>
master
basebuilder_pel7x64builder0 5 years ago
parent
commit
edd3a46315
  1. 2
      SOURCES/openssl-1.0.2i-fips.patch
  2. 20
      SOURCES/openssl-1.0.2k-cve-2017-3735.patch
  3. 896
      SOURCES/openssl-1.0.2k-cve-2018-0495.patch
  4. 24
      SOURCES/openssl-1.0.2k-cve-2018-0732.patch
  5. 148
      SOURCES/openssl-1.0.2k-cve-2018-0734.patch
  6. 274
      SOURCES/openssl-1.0.2k-cve-2018-0737.patch
  7. 217
      SOURCES/openssl-1.0.2k-cve-2018-0739.patch
  8. 305
      SOURCES/openssl-1.0.2k-cve-2018-5407.patch
  9. 38
      SOURCES/openssl-1.0.2k-cve-2019-1559.patch
  10. 1445
      SOURCES/openssl-1.0.2k-fix-9-lives.patch
  11. 167
      SOURCES/openssl-1.0.2k-fix-one-and-done.patch
  12. 57
      SOURCES/openssl-1.0.2k-name-sensitive.patch
  13. 18
      SOURCES/openssl-1.0.2k-rsa-check.patch
  14. 1368
      SOURCES/openssl-1.0.2k-s390x-update.patch
  15. 59
      SPECS/openssl.spec

2
SOURCES/openssl-1.0.2i-fips.patch

@ -997,7 +997,7 @@ diff -up openssl-1.0.2i/crypto/dsa/dsa.h.fips openssl-1.0.2i/crypto/dsa/dsa.h @@ -997,7 +997,7 @@ diff -up openssl-1.0.2i/crypto/dsa/dsa.h.fips openssl-1.0.2i/crypto/dsa/dsa.h
# define DSA_R_INVALID_DIGEST_TYPE 106
-# define DSA_R_INVALID_PARAMETERS 112
+# define DSA_R_INVALID_PARAMETERS 212
+# define DSA_R_KEY_SIZE_INVALID 113
+# define DSA_R_KEY_SIZE_INVALID 201
+# define DSA_R_KEY_SIZE_TOO_SMALL 110
# define DSA_R_MISSING_PARAMETERS 101
# define DSA_R_MODULUS_TOO_LARGE 103

20
SOURCES/openssl-1.0.2k-cve-2017-3735.patch

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
diff -up openssl-1.0.2k/crypto/x509v3/v3_addr.c.overread openssl-1.0.2k/crypto/x509v3/v3_addr.c
--- openssl-1.0.2k/crypto/x509v3/v3_addr.c.overread 2017-01-26 14:22:04.000000000 +0100
+++ openssl-1.0.2k/crypto/x509v3/v3_addr.c 2018-06-18 13:49:30.001625137 +0200
@@ -130,10 +130,12 @@ static int length_from_afi(const unsigne
*/
unsigned int v3_addr_get_afi(const IPAddressFamily *f)
{
- return ((f != NULL &&
- f->addressFamily != NULL && f->addressFamily->data != NULL)
- ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1]))
- : 0);
+ if (f == NULL
+ || f->addressFamily == NULL
+ || f->addressFamily->data == NULL
+ || f->addressFamily->length < 2)
+ return 0;
+ return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1];
}
/*

896
SOURCES/openssl-1.0.2k-cve-2018-0495.patch

@ -0,0 +1,896 @@ @@ -0,0 +1,896 @@
diff -up openssl-1.0.2k/crypto/bn/bn_div.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_div.c
--- openssl-1.0.2k/crypto/bn/bn_div.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/bn/bn_div.c 2018-08-14 10:57:21.592518702 +0200
@@ -290,6 +290,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const
wnum.neg = 0;
wnum.d = &(snum->d[loop]);
wnum.top = div_n;
+ wnum.flags = BN_FLG_STATIC_DATA;
/*
* only needed when BN_ucmp messes up the values between top and max
*/
diff -up openssl-1.0.2k/crypto/bn/bn_exp.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_exp.c
--- openssl-1.0.2k/crypto/bn/bn_exp.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/bn/bn_exp.c 2018-08-14 10:57:21.596518798 +0200
@@ -466,17 +466,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
ret = 1;
goto err;
}
- if (!BN_to_montgomery(val[0], aa, mont, ctx))
+ if (!bn_to_mont_fixed_top(val[0], aa, mont, ctx))
goto err; /* 1 */
window = BN_window_bits_for_exponent_size(bits);
if (window > 1) {
- if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
+ if (!bn_mul_mont_fixed_top(d, val[0], val[0], mont, ctx))
goto err; /* 2 */
j = 1 << (window - 1);
for (i = 1; i < j; i++) {
if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
- !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
+ !bn_mul_mont_fixed_top(val[i], val[i - 1], d, mont, ctx))
goto err;
}
}
@@ -498,19 +498,15 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
for (i = 1; i < j; i++)
r->d[i] = (~m->d[i]) & BN_MASK2;
r->top = j;
- /*
- * Upper words will be zero if the corresponding words of 'm' were
- * 0xfff[...], so decrement r->top accordingly.
- */
- bn_correct_top(r);
+ r->flags |= BN_FLG_FIXED_TOP;
} else
#endif
- if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+ if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx))
goto err;
for (;;) {
if (BN_is_bit_set(p, wstart) == 0) {
if (!start) {
- if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
goto err;
}
if (wstart == 0)
@@ -541,12 +537,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
/* add the 'bytes above' */
if (!start)
for (i = 0; i < j; i++) {
- if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
goto err;
}
/* wvalue will be an odd number < 2^window */
- if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
+ if (!bn_mul_mont_fixed_top(r, r, val[wvalue >> 1], mont, ctx))
goto err;
/* move the 'window' down further */
@@ -556,6 +552,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
if (wstart < 0)
break;
}
+ /*
+ * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
+ * removes padding [if any] and makes return value suitable for public
+ * API consumer.
+ */
#if defined(SPARC_T4_MONT)
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
j = mont->N.top; /* borrow j */
@@ -674,7 +675,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBU
}
b->top = top;
- bn_correct_top(b);
+ b->flags |= BN_FLG_FIXED_TOP;
return 1;
}
@@ -841,16 +842,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
tmp.top = top;
} else
#endif
- if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
+ if (!bn_to_mont_fixed_top(&tmp, BN_value_one(), mont, ctx))
goto err;
/* prepare a^1 in Montgomery domain */
if (a->neg || BN_ucmp(a, m) >= 0) {
if (!BN_mod(&am, a, m, ctx))
goto err;
- if (!BN_to_montgomery(&am, &am, mont, ctx))
+ if (!bn_to_mont_fixed_top(&am, &am, mont, ctx))
goto err;
- } else if (!BN_to_montgomery(&am, a, mont, ctx))
+ } else if (!bn_to_mont_fixed_top(&am, a, mont, ctx))
goto err;
#if defined(SPARC_T4_MONT)
@@ -1117,14 +1118,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
* performance advantage of sqr over mul).
*/
if (window > 1) {
- if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &am, &am, mont, ctx))
goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
window))
goto err;
for (i = 3; i < numPowers; i++) {
/* Calculate a^i = a^(i-1) * a */
- if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &am, &tmp, mont, ctx))
goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
window))
@@ -1148,7 +1149,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
/* Scan the window, squaring the result as we go */
for (i = 0; i < window; i++, bits--) {
- if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx))
goto err;
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
}
@@ -1161,12 +1162,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
goto err;
/* Multiply the result into the intermediate result */
- if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
+ if (!bn_mul_mont_fixed_top(&tmp, &tmp, &am, mont, ctx))
goto err;
}
}
- /* Convert the final result from montgomery to standard format */
+ /*
+ * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
+ * removes padding [if any] and makes return value suitable for public
+ * API consumer.
+ */
#if defined(SPARC_T4_MONT)
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
am.d[0] = 1; /* borrow am */
diff -up openssl-1.0.2k/crypto/bn/bn.h.rohnp-fix openssl-1.0.2k/crypto/bn/bn.h
--- openssl-1.0.2k/crypto/bn/bn.h.rohnp-fix 2018-06-20 17:44:01.752387208 +0200
+++ openssl-1.0.2k/crypto/bn/bn.h 2018-08-14 10:57:21.592518702 +0200
@@ -702,6 +702,16 @@ BIGNUM *bn_dup_expand(const BIGNUM *a, i
/* We only need assert() when debugging */
# include <assert.h>
+/*
+ * The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with
+ * bn_correct_top, in other words such vectors are permitted to have zeros
+ * in most significant limbs. Such vectors are used internally to achieve
+ * execution time invariance for critical operations with private keys.
+ * It's BN_DEBUG-only flag, because user application is not supposed to
+ * observe it anyway. Moreover, optimizing compiler would actually remove
+ * all operations manipulating the bit in question in non-BN_DEBUG build.
+ */
+# define BN_FLG_FIXED_TOP 0x10000
# ifdef BN_DEBUG_RAND
/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
# ifndef RAND_pseudo_bytes
@@ -734,8 +744,10 @@ int RAND_pseudo_bytes(unsigned char *buf
do { \
const BIGNUM *_bnum2 = (a); \
if (_bnum2 != NULL) { \
- assert((_bnum2->top == 0) || \
- (_bnum2->d[_bnum2->top - 1] != 0)); \
+ int _top = _bnum2->top; \
+ assert((_top == 0) || \
+ (_bnum2->flags & BN_FLG_FIXED_TOP) || \
+ (_bnum2->d[_top - 1] != 0)); \
bn_pollute(_bnum2); \
} \
} while(0)
@@ -753,6 +765,7 @@ int RAND_pseudo_bytes(unsigned char *buf
# else /* !BN_DEBUG */
+# define BN_FLG_FIXED_TOP 0
# define bn_pollute(a)
# define bn_check_top(a)
# define bn_fix_top(a) bn_correct_top(a)
diff -up openssl-1.0.2k/crypto/bn/bn_lcl.h.rohnp-fix openssl-1.0.2k/crypto/bn/bn_lcl.h
--- openssl-1.0.2k/crypto/bn/bn_lcl.h.rohnp-fix 2018-06-20 17:44:01.748387114 +0200
+++ openssl-1.0.2k/crypto/bn/bn_lcl.h 2018-08-14 10:57:21.596518798 +0200
@@ -113,6 +113,7 @@
# define HEADER_BN_LCL_H
# include <openssl/bn.h>
+# include "bn_int.h"
#ifdef __cplusplus
extern "C" {
diff -up openssl-1.0.2k/crypto/bn/bn_lib.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_lib.c
--- openssl-1.0.2k/crypto/bn/bn_lib.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/bn/bn_lib.c 2018-08-14 10:57:21.592518702 +0200
@@ -290,8 +290,6 @@ static BN_ULONG *bn_expand_internal(cons
const BN_ULONG *B;
int i;
- bn_check_top(b);
-
if (words > (INT_MAX / (4 * BN_BITS2))) {
BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
return NULL;
@@ -425,8 +423,6 @@ BIGNUM *bn_dup_expand(const BIGNUM *b, i
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
- bn_check_top(b);
-
if (words > b->dmax) {
BN_ULONG *a = bn_expand_internal(b, words);
if (!a)
@@ -460,7 +456,6 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
assert(A == &(b->d[b->dmax]));
}
#endif
- bn_check_top(b);
return b;
}
@@ -572,6 +567,7 @@ void BN_clear(BIGNUM *a)
OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
a->top = 0;
a->neg = 0;
+ a->flags &= ~BN_FLG_FIXED_TOP;
}
BN_ULONG BN_get_word(const BIGNUM *a)
@@ -592,6 +588,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
a->neg = 0;
a->d[0] = w;
a->top = (w ? 1 : 0);
+ a->flags &= ~BN_FLG_FIXED_TOP;
bn_check_top(a);
return (1);
}
@@ -738,6 +735,7 @@ int BN_set_bit(BIGNUM *a, int n)
for (k = a->top; k < i + 1; k++)
a->d[k] = 0;
a->top = i + 1;
+ a->flags &= ~BN_FLG_FIXED_TOP;
}
a->d[i] |= (((BN_ULONG)1) << j);
diff -up openssl-1.0.2k/crypto/bn/bn_mod.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_mod.c
--- openssl-1.0.2k/crypto/bn/bn_mod.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/bn/bn_mod.c 2018-08-14 10:57:21.601518919 +0200
@@ -149,18 +149,73 @@ int BN_mod_add(BIGNUM *r, const BIGNUM *
/*
* BN_mod_add variant that may be used if both a and b are non-negative and
- * less than m
+ * less than m. The original algorithm was
+ *
+ * if (!BN_uadd(r, a, b))
+ * return 0;
+ * if (BN_ucmp(r, m) >= 0)
+ * return BN_usub(r, r, m);
+ *
+ * which is replaced with addition, subtracting modulus, and conditional
+ * move depending on whether or not subtraction borrowed.
*/
-int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
- const BIGNUM *m)
+int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m)
{
- if (!BN_uadd(r, a, b))
+ size_t i, ai, bi, mtop = m->top;
+ BN_ULONG storage[1024 / BN_BITS2];
+ BN_ULONG carry, temp, mask, *rp, *tp = storage;
+ const BN_ULONG *ap, *bp;
+
+ if (bn_wexpand(r, m->top) == NULL)
return 0;
- if (BN_ucmp(r, m) >= 0)
- return BN_usub(r, r, m);
+
+ if (mtop > sizeof(storage) / sizeof(storage[0])
+ && (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL)
+ return 0;
+
+ ap = a->d != NULL ? a->d : tp;
+ bp = b->d != NULL ? b->d : tp;
+
+ for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) {
+ mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1));
+ temp = ((ap[ai] & mask) + carry) & BN_MASK2;
+ carry = (temp < carry);
+
+ mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1));
+ tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2;
+ carry += (tp[i] < temp);
+
+ i++;
+ ai += (i - a->dmax) >> (8 * sizeof(i) - 1);
+ bi += (i - b->dmax) >> (8 * sizeof(i) - 1);
+ }
+ rp = r->d;
+ carry -= bn_sub_words(rp, tp, m->d, mtop);
+ for (i = 0; i < mtop; i++) {
+ rp[i] = (carry & tp[i]) | (~carry & rp[i]);
+ ((volatile BN_ULONG *)tp)[i] = 0;
+ }
+ r->top = mtop;
+ r->neg = 0;
+
+ if (tp != storage)
+ OPENSSL_free(tp);
+
return 1;
}
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m)
+{
+ int ret = bn_mod_add_fixed_top(r, a, b, m);
+
+ if (ret)
+ bn_correct_top(r);
+
+ return ret;
+}
+
int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
BN_CTX *ctx)
{
diff -up openssl-1.0.2k/crypto/bn/bn_mont.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_mont.c
--- openssl-1.0.2k/crypto/bn/bn_mont.c.rohnp-fix 2018-08-14 10:57:21.589518629 +0200
+++ openssl-1.0.2k/crypto/bn/bn_mont.c 2018-08-14 11:15:11.425320301 +0200
@@ -56,7 +56,7 @@
* [including the GNU Public Licence.]
*/
/* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -123,12 +123,23 @@
#define MONT_WORD /* use the faster word-based algorithm */
#ifdef MONT_WORD
-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
+static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
#endif
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_MONT_CTX *mont, BN_CTX *ctx)
{
+ int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx);
+
+ bn_correct_top(r);
+ bn_check_top(r);
+
+ return ret;
+}
+
+int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx)
+{
BIGNUM *tmp;
int ret = 0;
#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
@@ -140,8 +151,8 @@ int BN_mod_mul_montgomery(BIGNUM *r, con
if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
r->neg = a->neg ^ b->neg;
r->top = num;
- bn_correct_top(r);
- return (1);
+ r->flags |= BN_FLG_FIXED_TOP;
+ return 1;
}
}
#endif
@@ -161,13 +172,12 @@ int BN_mod_mul_montgomery(BIGNUM *r, con
}
/* reduce from aRR to aR */
#ifdef MONT_WORD
- if (!BN_from_montgomery_word(r, tmp, mont))
+ if (!bn_from_montgomery_word(r, tmp, mont))
goto err;
#else
if (!BN_from_montgomery(r, tmp, mont, ctx))
goto err;
#endif
- bn_check_top(r);
ret = 1;
err:
BN_CTX_end(ctx);
@@ -175,7 +185,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, con
}
#ifdef MONT_WORD
-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
+static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
{
BIGNUM *n;
BN_ULONG *ap, *np, *rp, n0, v, carry;
@@ -205,28 +215,16 @@ static int BN_from_montgomery_word(BIGNU
# endif
r->top = max;
+ r->flags |= BN_FLG_FIXED_TOP;
n0 = mont->n0[0];
-# ifdef BN_COUNT
- fprintf(stderr, "word BN_from_montgomery_word %d * %d\n", nl, nl);
-# endif
+ /*
+ * Add multiples of |n| to |r| until R = 2^(nl * BN_BITS2) divides it. On
+ * input, we had |r| < |n| * R, so now |r| < 2 * |n| * R. Note that |r|
+ * includes |carry| which is stored separately.
+ */
for (carry = 0, i = 0; i < nl; i++, rp++) {
-# ifdef __TANDEM
- {
- long long t1;
- long long t2;
- long long t3;
- t1 = rp[0] * (n0 & 0177777);
- t2 = 037777600000l;
- t2 = n0 & t2;
- t3 = rp[0] & 0177777;
- t2 = (t3 * t2) & BN_MASK2;
- t1 = t1 + t2;
- v = bn_mul_add_words(rp, np, nl, (BN_ULONG)t1);
- }
-# else
v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
-# endif
v = (v + carry + rp[nl]) & BN_MASK2;
carry |= (v != rp[nl]);
carry &= (v <= rp[nl]);
@@ -236,52 +234,27 @@ static int BN_from_montgomery_word(BIGNU
if (bn_wexpand(ret, nl) == NULL)
return (0);
ret->top = nl;
+ ret->flags |= BN_FLG_FIXED_TOP;
ret->neg = r->neg;
rp = ret->d;
- ap = &(r->d[nl]);
-# define BRANCH_FREE 1
-# if BRANCH_FREE
- {
- BN_ULONG *nrp;
- size_t m;
+ /*
+ * Shift |nl| words to divide by R. We have |ap| < 2 * |n|. Note that |ap|
+ * includes |carry| which is stored separately.
+ */
+ ap = &(r->d[nl]);
- v = bn_sub_words(rp, ap, np, nl) - carry;
- /*
- * if subtraction result is real, then trick unconditional memcpy
- * below to perform in-place "refresh" instead of actual copy.
- */
- m = (0 - (size_t)v);
- nrp =
- (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
-
- for (i = 0, nl -= 4; i < nl; i += 4) {
- BN_ULONG t1, t2, t3, t4;
-
- t1 = nrp[i + 0];
- t2 = nrp[i + 1];
- t3 = nrp[i + 2];
- ap[i + 0] = 0;
- t4 = nrp[i + 3];
- ap[i + 1] = 0;
- rp[i + 0] = t1;
- ap[i + 2] = 0;
- rp[i + 1] = t2;
- ap[i + 3] = 0;
- rp[i + 2] = t3;
- rp[i + 3] = t4;
- }
- for (nl += 4; i < nl; i++)
- rp[i] = nrp[i], ap[i] = 0;
+ carry -= bn_sub_words(rp, ap, np, nl);
+ /*
+ * |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note
+ * |carry| cannot be 1. That would imply the subtraction did not fit in
+ * |nl| words, and we know at most one subtraction is needed.
+ */
+ for (i = 0; i < nl; i++) {
+ rp[i] = (carry & ap[i]) | (~carry & rp[i]);
+ ap[i] = 0;
}
-# else
- if (bn_sub_words(rp, ap, np, nl) - carry)
- memcpy(rp, ap, nl * sizeof(BN_ULONG));
-# endif
- bn_correct_top(r);
- bn_correct_top(ret);
- bn_check_top(ret);
return (1);
}
@@ -295,8 +268,11 @@ int BN_from_montgomery(BIGNUM *ret, cons
BIGNUM *t;
BN_CTX_start(ctx);
- if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
- retn = BN_from_montgomery_word(ret, t, mont);
+ if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) {
+ retn = bn_from_montgomery_word(ret, t, mont);
+ bn_correct_top(ret);
+ bn_check_top(ret);
+ }
BN_CTX_end(ctx);
#else /* !MONT_WORD */
BIGNUM *t1, *t2;
@@ -334,6 +310,12 @@ int BN_from_montgomery(BIGNUM *ret, cons
return (retn);
}
+int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx)
+{
+ return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx);
+}
+
BN_MONT_CTX *BN_MONT_CTX_new(void)
{
BN_MONT_CTX *ret;
@@ -370,7 +352,7 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont)
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
- int ret = 0;
+ int i, ret = 0;
BIGNUM *Ri, *R;
if (BN_is_zero(mod))
@@ -382,6 +364,8 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, c
R = &(mont->RR); /* grab RR as a temp */
if (!BN_copy(&(mont->N), mod))
goto err; /* Set N */
+ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+ BN_set_flags(&(mont->N), BN_FLG_CONSTTIME);
mont->N.neg = 0;
#ifdef MONT_WORD
@@ -394,6 +378,9 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, c
tmod.dmax = 2;
tmod.neg = 0;
+ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+ BN_set_flags(&tmod, BN_FLG_CONSTTIME);
+
mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
# if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
@@ -496,6 +483,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, c
if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
goto err;
+ for (i = mont->RR.top, ret = mont->N.top; i < ret; i++)
+ mont->RR.d[i] = 0;
+ mont->RR.top = ret;
+ mont->RR.flags |= BN_FLG_FIXED_TOP;
+
ret = 1;
err:
BN_CTX_end(ctx);
diff -up openssl-1.0.2k/crypto/bn/bn_sqr.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_sqr.c
--- openssl-1.0.2k/crypto/bn/bn_sqr.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/bn/bn_sqr.c 2018-08-14 10:57:21.593518726 +0200
@@ -135,14 +135,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, B
}
rr->neg = 0;
- /*
- * If the most-significant half of the top word of 'a' is zero, then the
- * square of 'a' will max-1 words.
- */
- if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
- rr->top = max - 1;
- else
- rr->top = max;
+ rr->top = max;
+ bn_correct_top(rr);
if (r != rr && BN_copy(r, rr) == NULL)
goto err;
diff -up openssl-1.0.2k/crypto/bn_int.h.rohnp-fix openssl-1.0.2k/crypto/bn_int.h
--- openssl-1.0.2k/crypto/bn_int.h.rohnp-fix 2018-08-14 10:57:21.597518822 +0200
+++ openssl-1.0.2k/crypto/bn_int.h 2018-08-14 10:57:21.599518871 +0200
@@ -0,0 +1,13 @@
+/*
+ * Some BIGNUM functions assume most significant limb to be non-zero, which
+ * is customarily arranged by bn_correct_top. Output from below functions
+ * is not processed with bn_correct_top, and for this reason it may not be
+ * returned out of public API. It may only be passed internally into other
+ * functions known to support non-minimal or zero-padded BIGNUMs.
+ */
+int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx);
+int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx);
+int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m);
diff -up openssl-1.0.2k/crypto/dsa/dsa_ossl.c.rohnp-fix openssl-1.0.2k/crypto/dsa/dsa_ossl.c
--- openssl-1.0.2k/crypto/dsa/dsa_ossl.c.rohnp-fix 2018-06-20 17:44:02.153396702 +0200
+++ openssl-1.0.2k/crypto/dsa/dsa_ossl.c 2018-06-20 17:44:02.577406741 +0200
@@ -136,8 +136,7 @@ const DSA_METHOD *DSA_OpenSSL(void)
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
- BIGNUM m;
- BIGNUM xr;
+ BIGNUM *m, *blind, *blindm, *tmp;
BN_CTX *ctx = NULL;
int reason = ERR_R_BN_LIB;
DSA_SIG *ret = NULL;
@@ -156,9 +155,6 @@ static DSA_SIG *dsa_do_sign(const unsign
}
#endif
- BN_init(&m);
- BN_init(&xr);
-
if (!dsa->p || !dsa->q || !dsa->g) {
reason = DSA_R_MISSING_PARAMETERS;
goto err;
@@ -170,6 +166,14 @@ static DSA_SIG *dsa_do_sign(const unsign
ctx = BN_CTX_new();
if (ctx == NULL)
goto err;
+ BN_CTX_start(ctx);
+ m = BN_CTX_get(ctx);
+ blind = BN_CTX_get(ctx);
+ blindm = BN_CTX_get(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL)
+ goto err;
+
redo:
if ((dsa->kinv == NULL) || (dsa->r == NULL)) {
if (!DSA_sign_setup(dsa, ctx, &kinv, &r))
@@ -189,20 +193,52 @@ static DSA_SIG *dsa_do_sign(const unsign
* 4.2
*/
dlen = BN_num_bytes(dsa->q);
- if (BN_bin2bn(dgst, dlen, &m) == NULL)
+ if (BN_bin2bn(dgst, dlen, m) == NULL)
goto err;
- /* Compute s = inv(k) (m + xr) mod q */
- if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx))
- goto err; /* s = xr */
- if (!BN_add(s, &xr, &m))
- goto err; /* s = m + xr */
- if (BN_cmp(s, dsa->q) > 0)
- if (!BN_sub(s, s, dsa->q))
+ /*
+ * The normal signature calculation is:
+ *
+ * s := k^-1 * (m + r * priv_key) mod q
+ *
+ * We will blind this to protect against side channel attacks
+ *
+ * s := blind^-1 * k^-1 * (blind * m + blind * r * priv_key) mod q
+ */
+
+ /* Generate a blinding value */
+ do {
+ if (!BN_rand(blind, BN_num_bits(dsa->q) - 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 q */
+ if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx))
+ goto err;
+ if (!BN_mod_mul(tmp, tmp, r, dsa->q, ctx))
+ goto err;
+
+ /* blindm := blind * m mod q */
+ if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx))
+ goto err;
+
+ /* s : = (blind * priv_key * r) + (blind * m) mod q */
+ if (!BN_mod_add_quick(s, tmp, blindm, dsa->q))
+ goto err;
+
+ /* s := s * k^-1 mod q */
if (!BN_mod_mul(s, s, kinv, dsa->q, ctx))
goto err;
+ /* s:= s * blind^-1 mod q */
+ if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL)
+ goto err;
+ if (!BN_mod_mul(s, s, blind, dsa->q, ctx))
+ goto err;
+
/*
* Redo if r or s is zero as required by FIPS 186-3: this is very
* unlikely.
@@ -226,13 +262,12 @@ static DSA_SIG *dsa_do_sign(const unsign
BN_free(r);
BN_free(s);
}
- if (ctx != NULL)
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
BN_CTX_free(ctx);
- BN_clear_free(&m);
- BN_clear_free(&xr);
- if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
- BN_clear_free(kinv);
- return (ret);
+ }
+ BN_clear_free(kinv);
+ return ret;
}
static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
diff -up openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c.rohnp-fix openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c
--- openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c.rohnp-fix 2018-06-20 17:44:02.205397934 +0200
+++ openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c 2018-08-14 11:18:02.062439755 +0200
@@ -63,6 +63,7 @@
#ifdef OPENSSL_FIPS
# include <openssl/fips.h>
#endif
+#include "bn_int.h"
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
const BIGNUM *, const BIGNUM *,
@@ -98,6 +99,7 @@ static int ecdsa_sign_setup(EC_KEY *ecke
EC_POINT *tmp_point = NULL;
const EC_GROUP *group;
int ret = 0;
+ int order_bits;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
@@ -129,6 +131,13 @@ static int ecdsa_sign_setup(EC_KEY *ecke
goto err;
}
+ /* Preallocate space */
+ order_bits = BN_num_bits(order);
+ if (!BN_set_bit(k, order_bits)
+ || !BN_set_bit(r, order_bits)
+ || !BN_set_bit(X, order_bits))
+ goto err;
+
do {
/* get random k */
do
@@ -142,13 +151,19 @@ static int ecdsa_sign_setup(EC_KEY *ecke
/*
* We do not want timing information to leak the length of k, so we
* compute G*k using an equivalent scalar of fixed bit-length.
+ *
+ * We unconditionally perform both of these additions to prevent a
+ * small timing information leakage. We then choose the sum that is
+ * one bit longer than the order. This guarantees the code
+ * path used in the constant time implementations elsewhere.
+ *
+ * TODO: revisit the BN_copy aiming for a memory access agnostic
+ * conditional copy.
*/
-
- if (!BN_add(k, k, order))
+ if (!BN_add(r, k, order)
+ || !BN_add(X, r, order)
+ || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X))
goto err;
- if (BN_num_bits(k) <= BN_num_bits(order))
- if (!BN_add(k, k, order))
- goto err;
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
@@ -240,13 +255,14 @@ static ECDSA_SIG *ecdsa_do_sign(const un
EC_KEY *eckey)
{
int ok = 0, i;
- BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
+ BIGNUM *kinv = NULL, *s, *m = NULL, *order = NULL;
const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
ECDSA_SIG *ret;
ECDSA_DATA *ecdsa;
const BIGNUM *priv_key;
+ BN_MONT_CTX *mont_data;
#ifdef OPENSSL_FIPS
if (FIPS_selftest_failed()) {
@@ -272,7 +288,7 @@ static ECDSA_SIG *ecdsa_do_sign(const un
s = ret->s;
if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
- (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
+ (m = BN_new()) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -281,6 +297,8 @@ static ECDSA_SIG *ecdsa_do_sign(const un
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
+ mont_data = EC_GROUP_get_mont_data(group);
+
i = BN_num_bits(order);
/*
* Need to truncate digest if it is too long: first truncate whole bytes.
@@ -311,21 +329,33 @@ static ECDSA_SIG *ecdsa_do_sign(const un
}
}
- if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+ /*
+ * With only one multiplicant being in Montgomery domain
+ * multiplication yields real result without post-conversion.
+ * Also note that all operations but last are performed with
+ * zero-padded vectors. Last operation, BN_mod_mul_montgomery
+ * below, returns user-visible value with removed zero padding.
+ */
+ if (!bn_to_mont_fixed_top(s, ret->r, mont_data, ctx)
+ || !bn_mul_mont_fixed_top(s, s, priv_key, mont_data, ctx)) {
goto err;
}
- if (!BN_mod_add_quick(s, tmp, m, order)) {
+ if (!bn_mod_add_fixed_top(s, s, m, order)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
- if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
+ /*
+ * |s| can still be larger than modulus, because |m| can be. In
+ * such case we count on Montgomery reduction to tie it up.
+ */
+ if (!bn_to_mont_fixed_top(s, s, mont_data, ctx)
+ || !BN_mod_mul_montgomery(s, s, ckinv, mont_data, 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
+ * if kinv and r have been supplied by the caller don't
* generate new kinv and r values
*/
if (in_kinv != NULL && in_r != NULL) {
@@ -349,8 +379,6 @@ static ECDSA_SIG *ecdsa_do_sign(const un
BN_CTX_free(ctx);
if (m)
BN_clear_free(m);
- if (tmp)
- BN_clear_free(tmp);
if (order)
BN_free(order);
if (kinv)
diff -up openssl-1.0.2k/crypto/Makefile.rohnp-fix openssl-1.0.2k/crypto/Makefile
--- openssl-1.0.2k/crypto/Makefile.rohnp-fix 2018-06-20 17:44:02.467404137 +0200
+++ openssl-1.0.2k/crypto/Makefile 2018-08-14 10:57:21.595518774 +0200
@@ -45,7 +45,7 @@ SRC= $(LIBSRC)
EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
ossl_typ.h
HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h \
- constant_time_locl.h $(EXHEADER)
+ constant_time_locl.h bn_int.h $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)

24
SOURCES/openssl-1.0.2k-cve-2018-0732.patch

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
diff -up openssl-1.0.2k/crypto/dh/dh_key.c.large-dh openssl-1.0.2k/crypto/dh/dh_key.c
--- openssl-1.0.2k/crypto/dh/dh_key.c.large-dh 2018-06-18 13:46:24.268137362 +0200
+++ openssl-1.0.2k/crypto/dh/dh_key.c 2018-06-18 13:59:04.605497462 +0200
@@ -133,7 +133,7 @@ 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;
@@ -145,6 +145,11 @@ static int generate_key(DH *dh)
}
#endif
+ 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;

148
SOURCES/openssl-1.0.2k-cve-2018-0734.patch

@ -0,0 +1,148 @@ @@ -0,0 +1,148 @@
diff -up openssl-1.0.2k/crypto/dsa/dsa_ossl.c.dsa-signing openssl-1.0.2k/crypto/dsa/dsa_ossl.c
--- openssl-1.0.2k/crypto/dsa/dsa_ossl.c.dsa-signing 2019-02-08 10:53:17.825805336 +0100
+++ openssl-1.0.2k/crypto/dsa/dsa_ossl.c 2019-04-04 16:05:53.155386419 +0200
@@ -76,6 +76,8 @@ static int dsa_do_verify(const unsigned
DSA_SIG *sig, DSA *dsa);
static int dsa_init(DSA *dsa);
static int dsa_finish(DSA *dsa);
+static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
+ BN_CTX *ctx);
static DSA_METHOD openssl_dsa_meth = {
"OpenSSL DSA method",
@@ -275,7 +277,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
{
BN_CTX *ctx;
BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
+ BIGNUM l, m;
int ret = 0;
+ int q_bits;
if (!dsa->p || !dsa->q || !dsa->g) {
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
@@ -284,6 +288,8 @@ static int dsa_sign_setup(DSA *dsa, BN_C
BN_init(&k);
BN_init(&kq);
+ BN_init(&l);
+ BN_init(&m);
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL)
@@ -294,6 +300,13 @@ static int dsa_sign_setup(DSA *dsa, BN_C
if ((r = BN_new()) == NULL)
goto err;
+ /* Preallocate space */
+ q_bits = BN_num_bits(dsa->q) + sizeof(dsa->q->d[0]) * 16;
+ if (!BN_set_bit(&k, q_bits)
+ || !BN_set_bit(&l, q_bits)
+ || !BN_set_bit(&m, q_bits))
+ goto err;
+
/* Get random k */
do
if (!BN_rand_range(&k, dsa->q))
@@ -302,9 +315,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
BN_set_flags(&k, BN_FLG_CONSTTIME);
+ BN_set_flags(&l, BN_FLG_CONSTTIME);
}
-
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
CRYPTO_LOCK_DSA, dsa->p, ctx))
@@ -314,24 +327,23 @@ static int dsa_sign_setup(DSA *dsa, BN_C
/* Compute r = (g^k mod p) mod q */
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
- if (!BN_copy(&kq, &k))
- goto err;
-
- BN_set_flags(&kq, BN_FLG_CONSTTIME);
-
/*
* We do not want timing information to leak the length of k, so we
- * compute g^k using an equivalent exponent of fixed length. (This
- * is a kludge that we need because the BN_mod_exp_mont() does not
- * let us specify the desired timing behaviour.)
+ * compute G^k using an equivalent scalar of fixed bit-length.
+ *
+ * We unconditionally perform both of these additions to prevent a
+ * small timing information leakage. We then choose the sum that is
+ * one bit longer than the modulus.
+ *
+ * TODO: revisit the BN_copy aiming for a memory access agnostic
+ * conditional copy.
*/
-
- if (!BN_add(&kq, &kq, dsa->q))
+ if (!BN_add(&l, &k, dsa->q)
+ || !BN_add(&m, &l, dsa->q)
+ || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m))
goto err;
- if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) {
- if (!BN_add(&kq, &kq, dsa->q))
- goto err;
- }
+
+ BN_set_flags(&kq, BN_FLG_CONSTTIME);
K = &kq;
} else {
@@ -343,8 +355,8 @@ static int dsa_sign_setup(DSA *dsa, BN_C
if (!BN_mod(r, r, dsa->q, ctx))
goto err;
- /* Compute part of 's = inv(k) (m + xr) mod q' */
- if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL)
+ /* Compute part of 's = inv(k) (m + xr) mod q' */
+ if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL)
goto err;
if (*kinvp != NULL)
@@ -365,7 +377,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
BN_CTX_free(ctx);
BN_clear_free(&k);
BN_clear_free(&kq);
- return (ret);
+ BN_clear_free(&l);
+ BN_clear_free(&m);
+ return ret;
}
static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
@@ -491,3 +505,31 @@ static int dsa_finish(DSA *dsa)
BN_MONT_CTX_free(dsa->method_mont_p);
return (1);
}
+
+/*
+ * Compute the inverse of k modulo q.
+ * Since q is prime, Fermat's Little Theorem applies, which reduces this to
+ * mod-exp operation. Both the exponent and modulus are public information
+ * so a mod-exp that doesn't leak the base is sufficient. A newly allocated
+ * BIGNUM is returned which the caller must free.
+ */
+static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
+ BN_CTX *ctx)
+{
+ BIGNUM *res = NULL;
+ BIGNUM *r, e;
+
+ if ((r = BN_new()) == NULL)
+ return NULL;
+
+ BN_init(&e);
+
+ if (BN_set_word(r, 2)
+ && BN_sub(&e, q, r)
+ && BN_mod_exp_mont(r, k, &e, q, ctx, NULL))
+ res = r;
+ else
+ BN_free(r);
+ BN_free(&e);
+ return res;
+}

274
SOURCES/openssl-1.0.2k-cve-2018-0737.patch

@ -0,0 +1,274 @@ @@ -0,0 +1,274 @@
diff -up openssl-1.0.2k/crypto/rsa/rsa_gen.c.gen-timing openssl-1.0.2k/crypto/rsa/rsa_gen.c
--- openssl-1.0.2k/crypto/rsa/rsa_gen.c.gen-timing 2018-06-18 13:46:24.323138691 +0200
+++ openssl-1.0.2k/crypto/rsa/rsa_gen.c 2018-06-18 14:53:26.361975922 +0200
@@ -1,6 +1,6 @@
/* crypto/rsa/rsa_gen.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * Copyright (C) 2013 Red Hat, Inc.
+ * Copyright (C) 2013, 2018 Red Hat, Inc.
* All rights reserved.
*
* This package is an SSL implementation written
@@ -175,14 +175,13 @@ static int FIPS_rsa_builtin_keygen(RSA *
BN_GENCB *cb)
{
BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
- BIGNUM local_r0, local_d, local_p;
- BIGNUM *pr0, *d, *p;
BN_CTX *ctx = NULL;
int ok = -1;
int i;
int n = 0;
int test = 0;
int pbits = bits / 2;
+ unsigned long error = 0;
if (FIPS_selftest_failed()) {
FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_FIPS_SELFTEST_FAILED);
@@ -251,6 +250,12 @@ static int FIPS_rsa_builtin_keygen(RSA *
if (!BN_is_zero(rsa->p) && !BN_is_zero(rsa->q))
test = 1;
+ BN_set_flags(r0, BN_FLG_CONSTTIME);
+ BN_set_flags(r1, BN_FLG_CONSTTIME);
+ BN_set_flags(r2, BN_FLG_CONSTTIME);
+ BN_set_flags(rsa->p, BN_FLG_CONSTTIME);
+ BN_set_flags(rsa->q, BN_FLG_CONSTTIME);
+
retry:
/* generate p and q */
for (i = 0; i < 5 * pbits; i++) {
@@ -266,9 +271,9 @@ static int FIPS_rsa_builtin_keygen(RSA *
if (!BN_sub(r2, rsa->p, BN_value_one()))
goto err;
- if (!BN_gcd(r1, r2, rsa->e, ctx))
- goto err;
- if (BN_is_one(r1)) {
+ ERR_set_mark();
+ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
+ /* GCD == 1 since inverse exists */
int r;
r = BN_is_prime_fasttest_ex(rsa->p, pbits > 1024 ? 4 : 5, ctx, 0,
cb);
@@ -276,8 +281,16 @@ static int FIPS_rsa_builtin_keygen(RSA *
goto err;
if (r > 0)
break;
+ } else {
+ error = ERR_peek_last_error();
+ if (ERR_GET_LIB(error) == ERR_LIB_BN
+ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ /* GCD != 1 */
+ ERR_pop_to_mark();
+ } else {
+ goto err;
+ }
}
-
if (!BN_GENCB_call(cb, 2, n++))
goto err;
}
@@ -309,9 +322,9 @@ static int FIPS_rsa_builtin_keygen(RSA *
if (!BN_sub(r2, rsa->q, BN_value_one()))
goto err;
- if (!BN_gcd(r1, r2, rsa->e, ctx))
- goto err;
- if (BN_is_one(r1)) {
+ ERR_set_mark();
+ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
+ /* GCD == 1 since inverse exists */
int r;
r = BN_is_prime_fasttest_ex(rsa->q, pbits > 1024 ? 4 : 5, ctx, 0,
cb);
@@ -319,8 +332,16 @@ static int FIPS_rsa_builtin_keygen(RSA *
goto err;
if (r > 0)
break;
+ } else {
+ error = ERR_peek_last_error();
+ if (ERR_GET_LIB(error) == ERR_LIB_BN
+ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ /* GCD != 1 */
+ ERR_pop_to_mark();
+ } else {
+ goto err;
+ }
}
-
if (!BN_GENCB_call(cb, 2, n++))
goto err;
}
@@ -355,51 +376,44 @@ static int FIPS_rsa_builtin_keygen(RSA *
if (!BN_sub(r2, rsa->q, BN_value_one()))
goto err; /* q-1 */
+ /* note that computing gcd is not safe to timing attacks */
if (!BN_gcd(r0, r1, r2, ctx))
goto err;
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
- pr0 = &local_r0;
- BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
- } else
- pr0 = r0;
- if (!BN_div(r0, NULL, r1, pr0, ctx))
- goto err;
- if (!BN_mul(r0, r0, r2, ctx))
- goto err; /* lcm(p-1, q-1) */
-
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
- pr0 = &local_r0;
- BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
- } else
- pr0 = r0;
- if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx))
- goto err; /* d */
+
+ {
+ if (!BN_div(r0, NULL, r1, r0, ctx))
+ goto err;
+
+ if (!BN_mul(r0, r0, r2, ctx)) /* lcm(p-1, q-1) */
+ goto err;
+
+ if (!BN_mod_inverse(rsa->d, rsa->e, r0, ctx)) /* d */
+ goto err;
+ }
if (BN_num_bits(rsa->d) < pbits)
goto retry; /* d is too small */
- /* set up d for correct BN_FLG_CONSTTIME flag */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
- d = &local_d;
- BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- } else
- d = rsa->d;
+ {
+ BIGNUM *d = BN_new();
- /* calculate d mod (p-1) */
- if (!BN_mod(rsa->dmp1, d, r1, ctx))
- goto err;
+ if (d == NULL)
+ goto err;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- /* calculate d mod (q-1) */
- if (!BN_mod(rsa->dmq1, d, r2, ctx))
- goto err;
+ if (/* calculate d mod (p-1) */
+ !BN_mod(rsa->dmp1, d, r1, ctx)
+ /* calculate d mod (q-1) */
+ || !BN_mod(rsa->dmq1, d, r2, ctx)) {
+ BN_free(d);
+ goto err;
+ }
+ /* We MUST free d before any further use of rsa->d */
+ BN_free(d);
+ }
/* calculate inverse of q mod p */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
- p = &local_p;
- BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
- } else
- p = rsa->p;
- if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx))
+ if (!BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx))
goto err;
if (fips_rsa_pairwise_fail)
@@ -431,6 +445,17 @@ static int rsa_builtin_keygen(RSA *rsa,
BIGNUM *pr0, *d, *p;
int bitsp, bitsq, ok = -1, n = 0;
BN_CTX *ctx = NULL;
+ unsigned long error = 0;
+
+ /*
+ * When generating ridiculously small keys, we can get stuck
+ * continually regenerating the same prime values.
+ */
+ if (bits < 16) {
+ ok = 0; /* we set our own err */
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
#ifdef OPENSSL_FIPS
if (FIPS_module_mode()) {
@@ -483,45 +508,55 @@ static int rsa_builtin_keygen(RSA *rsa,
if (BN_copy(rsa->e, e_value) == NULL)
goto err;
+ BN_set_flags(rsa->p, BN_FLG_CONSTTIME);
+ BN_set_flags(rsa->q, BN_FLG_CONSTTIME);
+ BN_set_flags(r2, BN_FLG_CONSTTIME);
/* generate p and q */
for (;;) {
if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
goto err;
if (!BN_sub(r2, rsa->p, BN_value_one()))
goto err;
- if (!BN_gcd(r1, r2, rsa->e, ctx))
- goto err;
- if (BN_is_one(r1))
+ ERR_set_mark();
+ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
+ /* GCD == 1 since inverse exists */
break;
+ }
+ error = ERR_peek_last_error();
+ if (ERR_GET_LIB(error) == ERR_LIB_BN
+ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ /* GCD != 1 */
+ ERR_pop_to_mark();
+ } else {
+ goto err;
+ }
if (!BN_GENCB_call(cb, 2, n++))
goto err;
}
if (!BN_GENCB_call(cb, 3, 0))
goto err;
for (;;) {
- /*
- * When generating ridiculously small keys, we can get stuck
- * continually regenerating the same prime values. Check for this and
- * bail if it happens 3 times.
- */
- unsigned int degenerate = 0;
do {
if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
goto err;
if (!BN_sub(r2, rsa->q, rsa->p))
goto err;
- } while ((BN_ucmp(r2, r3) <= 0) && (++degenerate < 3));
- if (degenerate == 3) {
- ok = 0; /* we set our own err */
- RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
- goto err;
- }
+ } while (BN_ucmp(r2, r3) <= 0);
if (!BN_sub(r2, rsa->q, BN_value_one()))
goto err;
- if (!BN_gcd(r1, r2, rsa->e, ctx))
- goto err;
- if (BN_is_one(r1))
+ ERR_set_mark();
+ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
+ /* GCD == 1 since inverse exists */
break;
+ }
+ error = ERR_peek_last_error();
+ if (ERR_GET_LIB(error) == ERR_LIB_BN
+ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ /* GCD != 1 */
+ ERR_pop_to_mark();
+ } else {
+ goto err;
+ }
if (!BN_GENCB_call(cb, 2, n++))
goto err;
}

217
SOURCES/openssl-1.0.2k-cve-2018-0739.patch

@ -0,0 +1,217 @@ @@ -0,0 +1,217 @@
diff -up openssl-1.0.2k/crypto/asn1/asn1_err.c.asn1-recursive openssl-1.0.2k/crypto/asn1/asn1_err.c
--- openssl-1.0.2k/crypto/asn1/asn1_err.c.asn1-recursive 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/asn1/asn1_err.c 2018-06-18 15:08:18.333412753 +0200
@@ -279,6 +279,7 @@ static ERR_STRING_DATA ASN1_str_reasons[
{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"},
{ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"},
+ {ERR_REASON(ASN1_R_NESTED_TOO_DEEP), "nested too deep"},
{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"},
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"},
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"},
diff -up openssl-1.0.2k/crypto/asn1/asn1.h.asn1-recursive openssl-1.0.2k/crypto/asn1/asn1.h
--- openssl-1.0.2k/crypto/asn1/asn1.h.asn1-recursive 2018-06-18 13:46:23.857127431 +0200
+++ openssl-1.0.2k/crypto/asn1/asn1.h 2018-06-18 15:07:53.915826715 +0200
@@ -1365,6 +1365,7 @@ void ERR_load_ASN1_strings(void);
# define ASN1_R_MSTRING_NOT_UNIVERSAL 139
# define ASN1_R_MSTRING_WRONG_TAG 140
# define ASN1_R_NESTED_ASN1_STRING 197
+# define ASN1_R_NESTED_TOO_DEEP 219
# define ASN1_R_NON_HEX_CHARACTERS 141
# define ASN1_R_NOT_ASCII_FORMAT 190
# define ASN1_R_NOT_ENOUGH_DATA 142
diff -up openssl-1.0.2k/crypto/asn1/tasn_dec.c.asn1-recursive openssl-1.0.2k/crypto/asn1/tasn_dec.c
--- openssl-1.0.2k/crypto/asn1/tasn_dec.c.asn1-recursive 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/asn1/tasn_dec.c 2018-06-18 15:14:28.978308482 +0200
@@ -4,7 +4,7 @@
* 2000.
*/
/* ====================================================================
- * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -65,6 +65,14 @@
#include <openssl/buffer.h>
#include <openssl/err.h>
+/*
+ * Constructed types with a recursive definition (such as can be found in PKCS7)
+ * could eventually exceed the stack given malicious input with excessive
+ * recursion. Therefore we limit the stack depth. This is the maximum number of
+ * recursive invocations of asn1_item_embed_d2i().
+ */
+#define ASN1_MAX_CONSTRUCTED_NEST 30
+
static int asn1_check_eoc(const unsigned char **in, long len);
static int asn1_find_end(const unsigned char **in, long len, char inf);
@@ -81,11 +89,11 @@ static int asn1_check_tlen(long *olen, i
static int asn1_template_ex_d2i(ASN1_VALUE **pval,
const unsigned char **in, long len,
const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx);
+ ASN1_TLC *ctx, int depth);
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
const unsigned char **in, long len,
const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx);
+ ASN1_TLC *ctx, int depth);
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
const unsigned char **in, long len,
const ASN1_ITEM *it,
@@ -154,17 +162,16 @@ int ASN1_template_d2i(ASN1_VALUE **pval,
{
ASN1_TLC c;
asn1_tlc_clear_nc(&c);
- return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
+ return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0);
}
/*
* Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
* tag mismatch return -1 to handle OPTIONAL
*/
-
-int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
- const ASN1_ITEM *it,
- int tag, int aclass, char opt, ASN1_TLC *ctx)
+static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
+ long len, const ASN1_ITEM *it, int tag, int aclass,
+ char opt, ASN1_TLC *ctx, int depth)
{
const ASN1_TEMPLATE *tt, *errtt = NULL;
const ASN1_COMPAT_FUNCS *cf;
@@ -189,6 +196,11 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
else
asn1_cb = 0;
+ if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NESTED_TOO_DEEP);
+ goto err;
+ }
+
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates) {
@@ -204,7 +216,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
goto err;
}
return asn1_template_ex_d2i(pval, in, len,
- it->templates, opt, ctx);
+ it->templates, opt, ctx, depth);
}
return asn1_d2i_ex_primitive(pval, in, len, it,
tag, aclass, opt, ctx);
@@ -326,7 +338,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
/*
* We mark field as OPTIONAL so its absence can be recognised.
*/
- ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
+ ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth);
/* If field not present, try the next one */
if (ret == -1)
continue;
@@ -444,7 +456,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
* attempt to read in field, allowing each to be OPTIONAL
*/
- ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
+ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx,
+ depth);
if (!ret) {
errtt = seqtt;
goto err;
@@ -514,6 +527,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
return 0;
}
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+ return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0);
+}
+
/*
* Templates are handled with two separate functions. One handles any
* EXPLICIT tag and the other handles the rest.
@@ -522,7 +542,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
static int asn1_template_ex_d2i(ASN1_VALUE **val,
const unsigned char **in, long inlen,
const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx)
+ ASN1_TLC *ctx, int depth)
{
int flags, aclass;
int ret;
@@ -557,7 +577,7 @@ static int asn1_template_ex_d2i(ASN1_VAL
return 0;
}
/* We've found the field so it can't be OPTIONAL now */
- ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
+ ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth);
if (!ret) {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
return 0;
@@ -581,7 +601,7 @@ static int asn1_template_ex_d2i(ASN1_VAL
}
}
} else
- return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
+ return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth);
*in = p;
return 1;
@@ -594,7 +614,7 @@ static int asn1_template_ex_d2i(ASN1_VAL
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
const unsigned char **in, long len,
const ASN1_TEMPLATE *tt, char opt,
- ASN1_TLC *ctx)
+ ASN1_TLC *ctx, int depth)
{
int flags, aclass;
int ret;
@@ -665,14 +685,15 @@ static int asn1_template_noexp_d2i(ASN1_
break;
}
skfield = NULL;
- if (!ASN1_item_ex_d2i(&skfield, &p, len,
- ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
+ if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item),
+ -1, 0, 0, ctx, depth)) {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
}
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
+ ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item));
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -683,9 +704,8 @@ static int asn1_template_noexp_d2i(ASN1_
}
} else if (flags & ASN1_TFLG_IMPTAG) {
/* IMPLICIT tagging */
- ret = ASN1_item_ex_d2i(val, &p, len,
- ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
- ctx);
+ ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag,
+ aclass, opt, ctx, depth);
if (!ret) {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
goto err;
@@ -693,8 +713,9 @@ static int asn1_template_noexp_d2i(ASN1_
return -1;
} else {
/* Nothing special */
- ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
- -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
+ ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx,
+ depth);
if (!ret) {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
goto err;

305
SOURCES/openssl-1.0.2k-cve-2018-5407.patch

@ -0,0 +1,305 @@ @@ -0,0 +1,305 @@
diff -up openssl-1.0.2k/crypto/bn/bn_lib.c.ecc-ladder openssl-1.0.2k/crypto/bn/bn_lib.c
--- openssl-1.0.2k/crypto/bn/bn_lib.c.ecc-ladder 2019-02-06 12:58:50.575844123 +0100
+++ openssl-1.0.2k/crypto/bn/bn_lib.c 2019-02-08 10:48:53.529291777 +0100
@@ -877,6 +877,38 @@ void BN_consttime_swap(BN_ULONG conditio
a->top ^= t;
b->top ^= t;
+ t = (a->neg ^ b->neg) & condition;
+ a->neg ^= t;
+ b->neg ^= t;
+
+ /*-
+ * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention
+ * is actually to treat it as it's read-only data, and some (if not most)
+ * of it does reside in read-only segment. In other words observation of
+ * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal
+ * condition. It would either cause SEGV or effectively cause data
+ * corruption.
+ *
+ * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be
+ * preserved.
+ *
+ * BN_FLG_SECURE: must be preserved, because it determines how x->d was
+ * allocated and hence how to free it.
+ *
+ * BN_FLG_CONSTTIME: sufficient to mask and swap
+ *
+ * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on
+ * the data, so the d array may be padded with additional 0 values (i.e.
+ * top could be greater than the minimal value that it could be). We should
+ * be swapping it
+ */
+
+#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP)
+
+ t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition;
+ a->flags ^= t;
+ b->flags ^= t;
+
#define BN_CONSTTIME_SWAP(ind) \
do { \
t = (a->d[ind] ^ b->d[ind]) & condition; \
diff -up openssl-1.0.2k/crypto/ec/ec_mult.c.ecc-ladder openssl-1.0.2k/crypto/ec/ec_mult.c
--- openssl-1.0.2k/crypto/ec/ec_mult.c.ecc-ladder 2017-01-26 14:22:03.000000000 +0100
+++ openssl-1.0.2k/crypto/ec/ec_mult.c 2019-02-08 10:48:53.531291744 +0100
@@ -306,6 +306,224 @@ static signed char *compute_wNAF(const B
return r;
}
+#define EC_POINT_BN_set_flags(P, flags) do { \
+ BN_set_flags(&(P)->X, (flags)); \
+ BN_set_flags(&(P)->Y, (flags)); \
+ BN_set_flags(&(P)->Z, (flags)); \
+} while(0)
+
+/*-
+ * This functions computes (in constant time) a point multiplication over the
+ * EC group.
+ *
+ * At a high level, it is Montgomery ladder with conditional swaps.
+ *
+ * It performs either a fixed scalar point multiplication
+ * (scalar * generator)
+ * when point is NULL, or a generic scalar point multiplication
+ * (scalar * point)
+ * when point is not NULL.
+ *
+ * scalar should be in the range [0,n) otherwise all constant time bets are off.
+ *
+ * NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
+ * which of course are not constant time themselves.
+ *
+ * The product is stored in r.
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, const EC_POINT *point,
+ BN_CTX *ctx)
+{
+ int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
+ EC_POINT *s = NULL;
+ BIGNUM *k = NULL;
+ BIGNUM *lambda = NULL;
+ BIGNUM *cardinality = NULL;
+ BN_CTX *new_ctx = NULL;
+ int ret = 0;
+
+ if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+
+ BN_CTX_start(ctx);
+
+ s = EC_POINT_new(group);
+ if (s == NULL)
+ goto err;
+
+ if (point == NULL) {
+ if (!EC_POINT_copy(s, group->generator))
+ goto err;
+ } else {
+ if (!EC_POINT_copy(s, point))
+ goto err;
+ }
+
+ EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
+
+ cardinality = BN_CTX_get(ctx);
+ lambda = BN_CTX_get(ctx);
+ k = BN_CTX_get(ctx);
+ if (k == NULL || !BN_mul(cardinality, &group->order, &group->cofactor, ctx))
+ goto err;
+
+ /*
+ * Group cardinalities are often on a word boundary.
+ * So when we pad the scalar, some timing diff might
+ * pop if it needs to be expanded due to carries.
+ * So expand ahead of time.
+ */
+ cardinality_bits = BN_num_bits(cardinality);
+ group_top = cardinality->top;
+ if ((bn_wexpand(k, group_top + 2) == NULL)
+ || (bn_wexpand(lambda, group_top + 2) == NULL))
+ goto err;
+
+ if (!BN_copy(k, scalar))
+ goto err;
+
+ BN_set_flags(k, BN_FLG_CONSTTIME);
+
+ if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) {
+ /*-
+ * this is an unusual input, and we don't guarantee
+ * constant-timeness
+ */
+ if (!BN_nnmod(k, k, cardinality, ctx))
+ goto err;
+ }
+
+ if (!BN_add(lambda, k, cardinality))
+ goto err;
+ BN_set_flags(lambda, BN_FLG_CONSTTIME);
+ if (!BN_add(k, lambda, cardinality))
+ goto err;
+ /*
+ * lambda := scalar + cardinality
+ * k := scalar + 2*cardinality
+ */
+ kbit = BN_is_bit_set(lambda, cardinality_bits);
+ BN_consttime_swap(kbit, k, lambda, group_top + 2);
+
+ group_top = group->field.top;
+ if ((bn_wexpand(&s->X, group_top) == NULL)
+ || (bn_wexpand(&s->Y, group_top) == NULL)
+ || (bn_wexpand(&s->Z, group_top) == NULL)
+ || (bn_wexpand(&r->X, group_top) == NULL)
+ || (bn_wexpand(&r->Y, group_top) == NULL)
+ || (bn_wexpand(&r->Z, group_top) == NULL))
+ goto err;
+
+ /* top bit is a 1, in a fixed pos */
+ if (!EC_POINT_copy(r, s))
+ goto err;
+
+ EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
+
+ if (!EC_POINT_dbl(group, s, s, ctx))
+ goto err;
+
+ pbit = 0;
+
+#define EC_POINT_CSWAP(c, a, b, w, t) do { \
+ BN_consttime_swap(c, &(a)->X, &(b)->X, w); \
+ BN_consttime_swap(c, &(a)->Y, &(b)->Y, w); \
+ BN_consttime_swap(c, &(a)->Z, &(b)->Z, w); \
+ t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
+ (a)->Z_is_one ^= (t); \
+ (b)->Z_is_one ^= (t); \
+} while(0)
+
+ /*-
+ * The ladder step, with branches, is
+ *
+ * k[i] == 0: S = add(R, S), R = dbl(R)
+ * k[i] == 1: R = add(S, R), S = dbl(S)
+ *
+ * Swapping R, S conditionally on k[i] leaves you with state
+ *
+ * k[i] == 0: T, U = R, S
+ * k[i] == 1: T, U = S, R
+ *
+ * Then perform the ECC ops.
+ *
+ * U = add(T, U)
+ * T = dbl(T)
+ *
+ * Which leaves you with state
+ *
+ * k[i] == 0: U = add(R, S), T = dbl(R)
+ * k[i] == 1: U = add(S, R), T = dbl(S)
+ *
+ * Swapping T, U conditionally on k[i] leaves you with state
+ *
+ * k[i] == 0: R, S = T, U
+ * k[i] == 1: R, S = U, T
+ *
+ * Which leaves you with state
+ *
+ * k[i] == 0: S = add(R, S), R = dbl(R)
+ * k[i] == 1: R = add(S, R), S = dbl(S)
+ *
+ * So we get the same logic, but instead of a branch it's a
+ * conditional swap, followed by ECC ops, then another conditional swap.
+ *
+ * Optimization: The end of iteration i and start of i-1 looks like
+ *
+ * ...
+ * CSWAP(k[i], R, S)
+ * ECC
+ * CSWAP(k[i], R, S)
+ * (next iteration)
+ * CSWAP(k[i-1], R, S)
+ * ECC
+ * CSWAP(k[i-1], R, S)
+ * ...
+ *
+ * So instead of two contiguous swaps, you can merge the condition
+ * bits and do a single swap.
+ *
+ * k[i] k[i-1] Outcome
+ * 0 0 No Swap
+ * 0 1 Swap
+ * 1 0 Swap
+ * 1 1 No Swap
+ *
+ * This is XOR. pbit tracks the previous bit of k.
+ */
+
+ for (i = cardinality_bits - 1; i >= 0; i--) {
+ kbit = BN_is_bit_set(k, i) ^ pbit;
+ EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
+ if (!EC_POINT_add(group, s, r, s, ctx))
+ goto err;
+ if (!EC_POINT_dbl(group, r, r, ctx))
+ goto err;
+ /*
+ * pbit logic merges this cswap with that of the
+ * next iteration
+ */
+ pbit ^= kbit;
+ }
+ /* one final cswap to move the right value into r */
+ EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
+#undef EC_POINT_CSWAP
+
+ ret = 1;
+
+ err:
+ EC_POINT_free(s);
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+
+ return ret;
+}
+
+#undef EC_POINT_BN_set_flags
+
/*
* TODO: table should be optimised for the wNAF-based implementation,
* sometimes smaller windows will give better performance (thus the
@@ -365,6 +583,34 @@ int ec_wNAF_mul(const EC_GROUP *group, E
return EC_POINT_set_to_infinity(group, r);
}
+ if (!BN_is_zero(&group->order) && !BN_is_zero(&group->cofactor)) {
+ /*-
+ * Handle the common cases where the scalar is secret, enforcing a constant
+ * time scalar multiplication algorithm.
+ */
+ if ((scalar != NULL) && (num == 0)) {
+ /*-
+ * In this case we want to compute scalar * GeneratorPoint: this
+ * codepath is reached most prominently by (ephemeral) key generation
+ * of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH
+ * keygen/first half), where the scalar is always secret. This is why
+ * we ignore if BN_FLG_CONSTTIME is actually set and we always call the
+ * constant time version.
+ */
+ return ec_mul_consttime(group, r, scalar, NULL, ctx);
+ }
+ if ((scalar == NULL) && (num == 1)) {
+ /*-
+ * In this case we want to compute scalar * GenericPoint: this codepath
+ * is reached most prominently by the second half of ECDH, where the
+ * secret scalar is multiplied by the peer's public point. To protect
+ * the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and
+ * we always call the constant time version.
+ */
+ return ec_mul_consttime(group, r, scalars[0], points[0], ctx);
+ }
+ }
+
for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);

38
SOURCES/openssl-1.0.2k-cve-2019-1559.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
diff -up openssl-1.0.2k/ssl/d1_pkt.c.padding-oracle openssl-1.0.2k/ssl/d1_pkt.c
--- openssl-1.0.2k/ssl/d1_pkt.c.padding-oracle 2017-01-26 14:22:04.000000000 +0100
+++ openssl-1.0.2k/ssl/d1_pkt.c 2019-04-05 10:39:08.574409987 +0200
@@ -1290,6 +1290,7 @@ int dtls1_read_bytes(SSL *s, int type, u
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
SSL_CTX_remove_session(s->session_ctx, s->session);
+ s->state = SSL_ST_ERR;
return (0);
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
diff -up openssl-1.0.2k/ssl/s3_pkt.c.padding-oracle openssl-1.0.2k/ssl/s3_pkt.c
--- openssl-1.0.2k/ssl/s3_pkt.c.padding-oracle 2017-01-26 14:22:04.000000000 +0100
+++ openssl-1.0.2k/ssl/s3_pkt.c 2019-04-05 10:40:35.838894197 +0200
@@ -1495,6 +1495,7 @@ int ssl3_read_bytes(SSL *s, int type, un
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
SSL_CTX_remove_session(s->session_ctx, s->session);
+ s->state = SSL_ST_ERR;
return (0);
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
@@ -1714,9 +1715,12 @@ int ssl3_send_alert(SSL *s, int level, i
* protocol_version alerts */
if (desc < 0)
return -1;
- /* If a fatal one, remove from cache */
- if ((level == 2) && (s->session != NULL))
- SSL_CTX_remove_session(s->session_ctx, s->session);
+ /* If a fatal one, remove from cache and go into the error state */
+ if (level == SSL3_AL_FATAL) {
+ if (s->session != NULL)
+ SSL_CTX_remove_session(s->session_ctx, s->session);
+ s->state = SSL_ST_ERR;
+ }
s->s3->alert_dispatch = 1;
s->s3->send_alert[0] = level;

1445
SOURCES/openssl-1.0.2k-fix-9-lives.patch

File diff suppressed because it is too large Load Diff

167
SOURCES/openssl-1.0.2k-fix-one-and-done.patch

@ -0,0 +1,167 @@ @@ -0,0 +1,167 @@
diff -up openssl-1.0.2k/crypto/bn/bn_exp.c.one-and-done openssl-1.0.2k/crypto/bn/bn_exp.c
--- openssl-1.0.2k/crypto/bn/bn_exp.c.one-and-done 2019-04-04 16:46:21.287257363 +0200
+++ openssl-1.0.2k/crypto/bn/bn_exp.c 2019-04-04 16:45:32.875130057 +0200
@@ -579,7 +579,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
return (ret);
}
-#if defined(SPARC_T4_MONT)
static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos)
{
BN_ULONG ret = 0;
@@ -598,7 +597,6 @@ static BN_ULONG bn_get_bits(const BIGNUM
return ret & BN_MASK2;
}
-#endif
/*
* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific
@@ -697,7 +695,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
const BIGNUM *m, BN_CTX *ctx,
BN_MONT_CTX *in_mont)
{
- int i, bits, ret = 0, window, wvalue;
+ int i, bits, ret = 0, window, wvalue, wmask, window0;
int top;
BN_MONT_CTX *mont = NULL;
@@ -945,20 +943,27 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
top /= 2;
bn_flip_t4(np, mont->N.d, top);
- bits--;
- for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ /*
+ * The exponent may not have a whole number of fixed-size windows.
+ * To simplify the main loop, the initial window has between 1 and
+ * full-window-size bits such that what remains is always a whole
+ * number of windows
+ */
+ window0 = (bits - 1) % 5 + 1;
+ wmask = (1 << window0) - 1;
+ bits -= window0;
+ wvalue = bn_get_bits(p, bits) & wmask;
bn_gather5_t4(tmp.d, top, powerbuf, wvalue);
/*
* Scan the exponent one window at a time starting from the most
* significant bits.
*/
- while (bits >= 0) {
+ while (bits > 0) {
if (bits < stride)
- stride = bits + 1;
+ stride = bits;
bits -= stride;
- wvalue = bn_get_bits(p, bits + 1);
+ wvalue = bn_get_bits(p, bits);
if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
continue;
@@ -1066,32 +1071,36 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
bn_scatter5(tmp.d, top, powerbuf, i);
}
# endif
- bits--;
- for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ /*
+ * The exponent may not have a whole number of fixed-size windows.
+ * To simplify the main loop, the initial window has between 1 and
+ * full-window-size bits such that what remains is always a whole
+ * number of windows
+ */
+ window0 = (bits - 1) % 5 + 1;
+ wmask = (1 << window0) - 1;
+ bits -= window0;
+ wvalue = bn_get_bits(p, bits) & wmask;
bn_gather5(tmp.d, top, powerbuf, wvalue);
/*
* Scan the exponent one window at a time starting from the most
* significant bits.
*/
- if (top & 7)
- while (bits >= 0) {
- for (wvalue = 0, i = 0; i < 5; i++, bits--)
- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
-
+ if (top & 7) {
+ while (bits > 0) {
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top,
- wvalue);
+ bn_get_bits5(p->d, bits -= 5));
+ }
} else {
- while (bits >= 0) {
- wvalue = bn_get_bits5(p->d, bits - 4);
- bits -= 5;
- bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+ while (bits > 0) {
+ bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top,
+ bn_get_bits5(p->d, bits -= 5));
}
}
@@ -1133,28 +1142,45 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
}
}
- bits--;
- for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ /*
+ * The exponent may not have a whole number of fixed-size windows.
+ * To simplify the main loop, the initial window has between 1 and
+ * full-window-size bits such that what remains is always a whole
+ * number of windows
+ */
+ window0 = (bits - 1) % window + 1;
+ wmask = (1 << window0) - 1;
+ bits -= window0;
+ wvalue = bn_get_bits(p, bits) & wmask;
if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,
window))
goto err;
+ wmask = (1 << window) - 1;
/*
* Scan the exponent one window at a time starting from the most
* significant bits.
*/
- while (bits >= 0) {
- wvalue = 0; /* The 'value' of the window */
+ while (bits > 0) {
- /* Scan the window, squaring the result as we go */
- for (i = 0; i < window; i++, bits--) {
+ /* Square the result window-size times */
+ for (i = 0; i < window; i++)
if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx))
goto err;
- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
- }
/*
+ * Get a window's worth of bits from the exponent
+ * This avoids calling BN_is_bit_set for each bit, which
+ * is not only slower but also makes each bit vulnerable to
+ * EM (and likely other) side-channel attacks like One&Done
+ * (for details see "One&Done: A Single-Decryption EM-Based
+ * Attack on OpenSSL's Constant-Time Blinded RSA" by M. Alam,
+ * H. Khan, M. Dey, N. Sinha, R. Callan, A. Zajic, and
+ * M. Prvulovic, in USENIX Security'18)
+ */
+ bits -= window;
+ wvalue = bn_get_bits(p, bits) & wmask;
+ /*
* Fetch the appropriate pre-computed value from the pre-buf
*/
if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue,

57
SOURCES/openssl-1.0.2k-name-sensitive.patch

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
diff -up openssl-1.0.2k/ssl/ssl_cert.c.name-sensitive openssl-1.0.2k/ssl/ssl_cert.c
--- openssl-1.0.2k/ssl/ssl_cert.c.name-sensitive 2017-01-26 14:22:04.000000000 +0100
+++ openssl-1.0.2k/ssl/ssl_cert.c 2018-06-18 13:43:12.452502627 +0200
@@ -855,9 +855,33 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx,
return (add_client_CA(&(ctx->client_CA), x));
}
-static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
+static int xname_cmp(const X509_NAME *a, const X509_NAME *b)
{
- return (X509_NAME_cmp(*a, *b));
+ unsigned char *abuf = NULL, *bbuf = NULL;
+ int alen, blen, ret;
+
+ /* X509_NAME_cmp() itself casts away constness in this way, so
+ * assume it's safe:
+ */
+ alen = i2d_X509_NAME((X509_NAME *)a, &abuf);
+ blen = i2d_X509_NAME((X509_NAME *)b, &bbuf);
+
+ if (alen < 0 || blen < 0)
+ ret = -2;
+ else if (alen != blen)
+ ret = alen - blen;
+ else /* alen == blen */
+ ret = memcmp(abuf, bbuf, alen);
+
+ OPENSSL_free(abuf);
+ OPENSSL_free(bbuf);
+
+ return ret;
+}
+
+static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
+{
+ return xname_cmp(*a, *b);
}
#ifndef OPENSSL_NO_STDIO
@@ -876,7 +900,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_
X509_NAME *xn = NULL;
STACK_OF(X509_NAME) *ret = NULL, *sk;
- sk = sk_X509_NAME_new(xname_cmp);
+ sk = sk_X509_NAME_new(xname_sk_cmp);
in = BIO_new(BIO_s_file_internal());
@@ -948,7 +972,7 @@ int SSL_add_file_cert_subjects_to_stack(
int ret = 1;
int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b);
- oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
+ oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp);
in = BIO_new(BIO_s_file_internal());

18
SOURCES/openssl-1.0.2k-rsa-check.patch

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
diff -up openssl-1.0.2k/crypto/rsa/rsa_gen.c.rsa-check openssl-1.0.2k/crypto/rsa/rsa_gen.c
--- openssl-1.0.2k/crypto/rsa/rsa_gen.c.rsa-check 2019-02-06 12:58:50.570844207 +0100
+++ openssl-1.0.2k/crypto/rsa/rsa_gen.c 2019-02-06 13:10:57.058468214 +0100
@@ -94,11 +94,11 @@ int fips_check_rsa(RSA *rsa)
/* Perform pairwise consistency signature test */
if (!fips_pkey_signature_test(pk, tbs, -1,
- NULL, 0, EVP_sha1(),
+ NULL, 0, EVP_sha256(),
EVP_MD_CTX_FLAG_PAD_PKCS1, NULL)
- || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(),
+ || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha256(),
EVP_MD_CTX_FLAG_PAD_X931, NULL)
- || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(),
+ || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha256(),
EVP_MD_CTX_FLAG_PAD_PSS, NULL))
goto err;
/* Now perform pairwise consistency encrypt/decrypt test */

1368
SOURCES/openssl-1.0.2k-s390x-update.patch

File diff suppressed because it is too large Load Diff

59
SPECS/openssl.spec

@ -16,14 +16,14 @@ @@ -16,14 +16,14 @@

# Arches on which we need to prevent arch conflicts on opensslconf.h, must
# also be handled in opensslconf-new.h.
%define multilib_arches %{ix86} ia64 %{mips} ppc %{power64} s390 s390x sparcv9 sparc64 x86_64
%define multilib_arches %{ix86} ia64 %{mips} ppc ppc64 ppc64le s390 s390x sparcv9 sparc64 x86_64

%global _performance_build 1

Summary: Utilities from the general purpose cryptography library with TLS implementation
Name: openssl
Version: 1.0.2k
Release: 12%{?dist}
Release: 19%{?dist}
Epoch: 1
# We have to remove certain patented algorithms from the openssl source
# tarball with the hobble-openssl script which is included below.
@ -87,6 +87,7 @@ Patch96: openssl-1.0.2e-speed-doc.patch @@ -87,6 +87,7 @@ Patch96: openssl-1.0.2e-speed-doc.patch
Patch97: openssl-1.0.2k-no-ssl2.patch
Patch98: openssl-1.0.2k-long-hello.patch
Patch99: openssl-1.0.2k-fips-randlock.patch
Patch106: openssl-1.0.2k-rsa-check.patch
# Backported fixes including security fixes
Patch80: openssl-1.0.2e-wrap-pad.patch
Patch81: openssl-1.0.2a-padlock64.patch
@ -97,6 +98,18 @@ Patch85: openssl-1.0.2k-req-x509.patch @@ -97,6 +98,18 @@ Patch85: openssl-1.0.2k-req-x509.patch
Patch86: openssl-1.0.2k-cve-2017-3736.patch
Patch87: openssl-1.0.2k-cve-2017-3737.patch
Patch88: openssl-1.0.2k-cve-2017-3738.patch
Patch89: openssl-1.0.2k-s390x-update.patch
Patch100: openssl-1.0.2k-name-sensitive.patch
Patch101: openssl-1.0.2k-cve-2017-3735.patch
Patch102: openssl-1.0.2k-cve-2018-0732.patch
Patch103: openssl-1.0.2k-cve-2018-0737.patch
Patch104: openssl-1.0.2k-cve-2018-0739.patch
Patch105: openssl-1.0.2k-cve-2018-0495.patch
Patch107: openssl-1.0.2k-cve-2018-5407.patch
Patch108: openssl-1.0.2k-cve-2018-0734.patch
Patch109: openssl-1.0.2k-cve-2019-1559.patch
Patch110: openssl-1.0.2k-fix-one-and-done.patch
Patch111: openssl-1.0.2k-fix-9-lives.patch

License: OpenSSL
Group: System Environment/Libraries
@ -216,6 +229,7 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/ @@ -216,6 +229,7 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/
%patch97 -p1 -b .no-ssl2
%patch98 -p1 -b .long-hello
%patch99 -p1 -b .randlock
%patch106 -p1 -b .rsa-check

%patch80 -p1 -b .wrap
%patch81 -p1 -b .padlock64
@ -226,6 +240,18 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/ @@ -226,6 +240,18 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/
%patch86 -p1 -b .mont5-carry
%patch87 -p1 -b .ssl-err
%patch88 -p1 -b .rsaz-overflow
%patch89 -p1 -b .s390x-update
%patch100 -p1 -b .name-sensitive
%patch101 -p1 -b .overread
%patch102 -p1 -b .large-dh
%patch103 -p1 -b .gen-timing
%patch104 -p1 -b .asn1-recursive
%patch105 -p1 -b .rohnp-fix
%patch107 -p1 -b .ecc-ladder
%patch108 -p1 -b .dsa-signing
%patch109 -p1 -b .padding-oracle
%patch110 -p1 -b .one-and-done
%patch111 -p1 -b .9-lives

sed -i 's/SHLIB_VERSION_NUMBER "1.0.0"/SHLIB_VERSION_NUMBER "%{version}"/' crypto/opensslv.h

@ -525,6 +551,35 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.* @@ -525,6 +551,35 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.*
%postun libs -p /sbin/ldconfig

%changelog
* Tue Apr 9 2019 Tomáš Mráz <tmraz@redhat.com> 1.0.2k-19
- close the RSA decryption 9 lives of Bleichenbacher cat
timing side channel (#1649568)

* Fri Apr 5 2019 Tomáš Mráz <tmraz@redhat.com> 1.0.2k-18
- fix CVE-2018-0734 - DSA signature local timing side channel
- fix CVE-2019-1559 - 0-byte record padding oracle
- close the RSA decryption One & done EM side channel (#1619558)

* Wed Feb 6 2019 Tomáš Mráz <tmraz@redhat.com> 1.0.2k-17
- use SHA-256 in FIPS RSA pairwise key check
- fix CVE-2018-5407 (and CVE-2018-0735) - EC signature local
timing side-channel key extraction

* Tue Aug 14 2018 Tomáš Mráz <tmraz@redhat.com> 1.0.2k-16
- fix CVE-2018-0495 - ROHNP - Key Extraction Side Channel on DSA, ECDSA
- fix incorrect error message on FIPS DSA parameter generation (#1603597)

* Tue Jun 19 2018 Tomáš Mráz <tmraz@redhat.com> 1.0.2k-14
- ppc64le is not multilib architecture (#1585004)

* Mon Jun 18 2018 Tomáš Mráz <tmraz@redhat.com> 1.0.2k-13
- add S390x assembler updates
- make CA name list comparison function case sensitive (#1548401)
- fix CVE-2017-3735 - possible one byte overread with X.509 IPAdressFamily
- fix CVE-2018-0732 - large prime DH DoS of TLS client
- fix CVE-2018-0737 - RSA key generation cache timing vulnerability
- fix CVE-2018-0739 - stack overflow parsing recursive ASN.1 structure

* Wed Dec 13 2017 Tomáš Mráz <tmraz@redhat.com> 1.0.2k-12
- fix CVE-2017-3737 - incorrect handling of fatal error state
- fix CVE-2017-3738 - AVX2 Montgomery multiplication bug with 1024 bit modulus

Loading…
Cancel
Save