File openssl-bn_mul_mont_fixed_top.patch of Package compat-openssl098.11471

From 71883868ea5b33416ae8283bcc38dd2d97e5006b Mon Sep 17 00:00:00 2001
From: Andy Polyakov <appro@openssl.org>
Date: Fri, 6 Jul 2018 15:13:15 +0200
Subject: [PATCH] bn/bn_{mont|exp}.c: switch to zero-padded intermediate
 vectors.

Note that exported functions maintain original behaviour, so that
external callers won't observe difference. While internally we can
now perform Montogomery multiplication on fixed-length vectors, fixed
at modulus size. The new functions, bn_to_mont_fixed_top and
bn_mul_mont_fixed_top, are declared in bn_int.h, because one can use
them even outside bn, e.g. in RSA, DSA, ECDSA...

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: David Benjamin <davidben@google.com>
(Merged from https://github.com/openssl/openssl/pull/6662)
---
 crypto/bn/bn_exp.c               | 47 ++++++++++++++++++--------------
 crypto/bn/bn_lcl.h               |  3 +-
 crypto/bn/bn_mont.c              | 45 ++++++++++++++++++++++--------
 crypto/bn_int.h | 12 ++++++++
 4 files changed, 74 insertions(+), 33 deletions(-)

Index: openssl-0.9.8j/crypto/bn/bn_exp.c
===================================================================
--- openssl-0.9.8j.orig/crypto/bn/bn_exp.c
+++ openssl-0.9.8j/crypto/bn/bn_exp.c
@@ -432,18 +432,19 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
 		ret = 1;
 		goto err;
 		}
-	if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */
+	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)) goto err; /* 2 */
+		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;
 			}
 		}
@@ -455,14 +456,15 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
 	wstart=bits-1;	/* The top bit of the window */
 	wend=0;		/* The bottom bit of the window */
 
-	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+	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) break;
@@ -493,12 +495,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
 		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 */
@@ -507,6 +509,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
 		start=0;
 		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 (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
 	ret=1;
 err:
@@ -591,7 +598,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBU
      }
 
 	b->top = top;
-	bn_correct_top(b);
+	b->flags |= BN_FLG_FIXED_TOP;
 	return 1;
 	}	
 
@@ -690,7 +697,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
  	/* Initialize the intermediate result. Do this early to save double conversion,
 	 * once each for a^0 and intermediate result.
 	 */
- 	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+ 	if (!bn_to_mont_fixed_top(r,BN_value_one(),mont,ctx)) goto err;
 	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, window)) goto err;
 
 	/* Initialize computeTemp as a^1 with montgomery precalcs */
@@ -706,7 +713,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
 		}
 	else
 		aa=a;
-	if (!BN_to_montgomery(am,aa,mont,ctx)) goto err;
+	if (!bn_to_mont_fixed_top(am,aa,mont,ctx)) goto err;
 	if (!BN_copy(computeTemp, am)) goto err;
 	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, window)) goto err;
 
@@ -720,7 +727,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
 		for (i=2; i<numPowers; i++)
 			{
 			/* Calculate a^i = a^(i-1) * a */
-			if (!BN_mod_mul_montgomery(computeTemp,am,computeTemp,mont,ctx))
+			if (!bn_mul_mont_fixed_top(computeTemp,am,computeTemp,mont,ctx))
 				goto err;
 			if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i, window)) goto err;
 			}
@@ -759,7 +766,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
             wvalue=bn_get_bits(p,bits+1);
             /* Square the result window-size times */
             for (i = 0; i < window; i++)
-			if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))	goto err;
+			if (!bn_mul_mont_fixed_top(r,r,r,mont,ctx))	goto err;
 
 		/* Fetch the appropriate pre-computed value from the pre-buf
              * (the index is masked now so that only the actual window
@@ -770,10 +777,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
 		if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(computeTemp, top, powerbuf, wvalue&wmask, window)) goto err;
 
  		/* Multiply the result into the intermediate result */
- 		if (!BN_mod_mul_montgomery(r,r,computeTemp,mont,ctx)) goto err;
+ 		if (!bn_mul_mont_fixed_top(r,r,computeTemp,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 (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
 	ret=1;
 err:
Index: openssl-0.9.8j/crypto/bn/bn_mont.c
===================================================================
--- openssl-0.9.8j.orig/crypto/bn/bn_mont.c
+++ openssl-0.9.8j/crypto/bn/bn_mont.c
@@ -137,7 +137,7 @@
 #endif
 
 #ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
-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
 
 
@@ -145,6 +145,15 @@ static int BN_from_montgomery_word(BIGNU
 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)
@@ -161,7 +170,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, con
 			{
 			r->neg = a->neg^b->neg;
 			r->top = num;
-			bn_correct_top(r);
+			r->flags |= BN_FLG_FIXED_TOP;
 			return(1);
 			}
 		}
@@ -182,11 +191,10 @@ int BN_mod_mul_montgomery(BIGNUM *r, con
 		}
 	/* reduce from aRR to aR */
 #ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
-	if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
+	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);
@@ -194,7 +202,7 @@ err:
 	}
 
 #ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
-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,*nrp;
@@ -231,7 +239,7 @@ static int BN_from_montgomery_word(BIGNU
 #endif
 
 #ifdef BN_COUNT
-	fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
+	fprintf(stderr,"word bnrom_montgomery_word %d * %d\n",nl,nl);
 #endif
 	for (i=0; i<nl; i++)
 		{
@@ -344,8 +352,11 @@ int bn_from_mont_fixed_top(BIGNUM *ret,
 	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);
 	return retn;
 	}
@@ -546,6 +557,12 @@ int BN_from_montgomery(BIGNUM *ret, cons
 	}
 #endif /* MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
 
+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;
@@ -586,7 +603,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;
 
 	BN_CTX_start(ctx);
@@ -690,6 +707,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, c
 	if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
 	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);
Index: openssl-0.9.8j/crypto/bn/bn.h
===================================================================
--- openssl-0.9.8j.orig/crypto/bn/bn.h
+++ openssl-0.9.8j/crypto/bn/bn.h
@@ -300,7 +300,8 @@ struct bignum_st
 struct bn_mont_ctx_st
 	{
 	int ri;        /* number of bits in R */
-	BIGNUM RR;     /* used to convert to montgomery form */
+	BIGNUM RR;     /* used to convert to montgomery form,
+			  possibly zero-padded */
 	BIGNUM N;      /* The modulus */
 	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
 	                * (Ni is only stored for bignum algorithm) */
@@ -554,6 +555,12 @@ int BN_mod_mul_montgomery(BIGNUM *r,cons
 int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
 	BN_MONT_CTX *mont, BN_CTX *ctx);
 int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
+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);
 int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
 			   BN_CTX *ctx);
 int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
openSUSE Build Service is sponsored by