basebuilder_pel7x64builder0
5 years ago
15 changed files with 5035 additions and 3 deletions
@ -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]; |
||||
} |
||||
|
||||
/* |
@ -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) |
||||
|
@ -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; |
@ -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; |
||||
+} |
@ -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; |
||||
} |
@ -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; |
@ -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); |
@ -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; |
File diff suppressed because it is too large
Load Diff
@ -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, |
@ -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()); |
||||
|
@ -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 */ |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue