File openssl-bn_mod_add_fixed_top.patch of Package openssl.11276

From 3fc7a9b96cbed0c3da6f53c08e34d8d0c982745f Mon Sep 17 00:00:00 2001
From: Andy Polyakov <appro@openssl.org>
Date: Fri, 6 Jul 2018 15:55:34 +0200
Subject: [PATCH] ec/ecdsa_ossl.c: revert blinding in ECDSA signature.

Originally suggested solution for "Return Of the Hidden Number Problem"
is arguably too expensive. While it has marginal impact on slower
curves, none to ~6%, optimized implementations suffer real penalties.
Most notably sign with P-256 went more than 2 times[!] slower. Instead,
just implement constant-time BN_mod_add_quick.

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: David Benjamin <davidben@google.com>
(Merged from https://github.com/openssl/openssl/pull/6664)
---
 crypto/bn/bn_mod.c               | 66 ++++++++++++++++++++++++++---
 crypto/ec/ecdsa_ossl.c           | 71 ++++----------------------------
 crypto/include/internal/bn_int.h |  2 +
 3 files changed, 69 insertions(+), 70 deletions(-)

Index: openssl-1.0.1i/crypto/bn/bn_mod.c
===================================================================
--- openssl-1.0.1i.orig/crypto/bn/bn_mod.c
+++ openssl-1.0.1i/crypto/bn/bn_mod.c
@@ -146,15 +146,67 @@ 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 */
-int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *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_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+			 const BIGNUM *m)
 	{
-	if (!BN_uadd(r, a, b)) return 0;
-	if (BN_ucmp(r, m) >= 0)
-		return BN_usub(r, r, m);
+	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, mtop) == NULL)
+		return 0;
+	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->flags |= BN_FLG_FIXED_TOP;
+	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)
 	{
openSUSE Build Service is sponsored by