Search
j0ke.net Open Build Service
>
Projects
>
home:netmax
:
monitoring
>
openssl1
> 0001-crypto-bn-add-more-fixed-top-routines.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File 0001-crypto-bn-add-more-fixed-top-routines.patch of Package openssl1
From 387d170b32ceeac450bfa50b81db9db9179dc880 Mon Sep 17 00:00:00 2001 From: Andy Polyakov <appro@openssl.org> Date: Fri, 10 Aug 2018 19:31:22 +0200 Subject: [PATCH 1/4] crypto/bn: add more fixed-top routines. Add bn_mul_fixed_top, bn_from_mont_fixed_top, bn_mod_sub_fixed_top. Switch to bn_{mul|sqr}_fixed_top in bn_mul_mont_fixed_top and remove memset in bn_from_montgomery_word. (cherry picked from commit fcc4ee09473cac511eca90faa003661c7786e4f9) Resolved conflicts: crypto/bn/bn_mod.c crypto/bn_int.h Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/6942) --- crypto/bn/bn_mod.c | 67 ++++++++++++++++++++++++++++++++++++++++++++- crypto/bn/bn_mont.c | 29 +++++++++++++------- crypto/bn/bn_mul.c | 12 +++++++- crypto/bn/bn_sqr.c | 12 +++++++- crypto/bn_int.h | 6 ++++ 5 files changed, 113 insertions(+), 13 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 @@ -162,6 +162,69 @@ int BN_mod_sub(BIGNUM *r, const BIGNUM * return BN_nnmod(r, r, m, ctx); } +/* + * BN_mod_sub variant that may be used if both a and b are non-negative, + * a is less than m, while b is of same bit width as m. It's implemented + * as subtraction followed by two conditional additions. + * + * 0 <= a < m + * 0 <= b < 2^w < 2*m + * + * after subtraction + * + * -2*m < r = a - b < m + * + * Thus it takes up to two conditional additions to make |r| positive. + */ +int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + size_t i, ai, bi, mtop = m->top; + BN_ULONG borrow, carry, ta, tb, mask, *rp; + const BN_ULONG *ap, *bp; + + if (bn_wexpand(r, m->top) == NULL) + return 0; + + rp = r->d; + ap = a->d != NULL ? a->d : rp; + bp = b->d != NULL ? b->d : rp; + + for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) { + mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); + ta = ap[ai] & mask; + + mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); + tb = bp[bi] & mask; + rp[i] = ta - tb - borrow; + if (ta != tb) + borrow = (ta < tb); + + i++; + ai += (i - a->dmax) >> (8 * sizeof(i) - 1); + bi += (i - b->dmax) >> (8 * sizeof(i) - 1); + } + ap = m->d; + for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { + ta = ((ap[i] & mask) + carry) & BN_MASK2; + carry = (ta < carry); + rp[i] = (rp[i] + ta) & BN_MASK2; + carry += (rp[i] < ta); + } + borrow -= carry; + for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { + ta = ((ap[i] & mask) + carry) & BN_MASK2; + carry = (ta < carry); + rp[i] = (rp[i] + ta) & BN_MASK2; + carry += (rp[i] < ta); + } + + r->top = mtop; + r->flags |= BN_FLG_FIXED_TOP; + r->neg = 0; + + return 1; +} /* BN_mod_sub variant that may be used if both a and b are non-negative * and less than m */ Index: openssl-1.0.1i/crypto/bn/bn_mont.c =================================================================== --- openssl-1.0.1i.orig/crypto/bn/bn_mont.c +++ openssl-1.0.1i/crypto/bn/bn_mont.c @@ -152,14 +152,13 @@ int BN_mod_mul_montgomery(BIGNUM *r, con if (tmp == NULL) goto err; bn_check_top(tmp); - if (a == b) - { - if (!BN_sqr(tmp,a,ctx)) goto err; - } - else - { - if (!BN_mul(tmp,a,b,ctx)) goto err; - } + if (a == b) { + if (!bn_sqr_fixed_top(tmp, a, ctx)) + goto err; + } else { + if (!bn_mul_fixed_top(tmp, a, b, ctx)) + goto err; + } /* reduce from aRR to aR */ #ifdef MONT_WORD if (!BN_from_montgomery_word(r,tmp,mont)) goto err; @@ -179,6 +178,7 @@ static int BN_from_montgomery_word(BIGNU BIGNUM *n; BN_ULONG *ap,*np,*rp,n0,v,carry; int nl,max,i; + unsigned int rtop; n= &(mont->N); nl=n->top; @@ -192,12 +192,10 @@ static int BN_from_montgomery_word(BIGNU rp=r->d; /* clear the top words of T */ -#if 1 - for (i=r->top; i<max; i++) /* memset? XXX */ - rp[i]=0; -#else - memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); -#endif + for (rtop = r->top, i = 0; i < max; i++) { + v = (BN_ULONG)0 - ((i - rtop) >> (8 * sizeof(rtop) - 1)); + rp[i] &= v; + } r->top=max; n0=mont->n0[0]; @@ -279,7 +277,18 @@ static int BN_from_montgomery_word(BIGNU int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) - { +{ + int retn; + retn = bn_from_mont_fixed_top(ret, a, mont, ctx); + bn_correct_top(ret); + bn_check_top(ret); + + return retn; +} + +int bn_from_mont_fixed_top(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) +{ int retn=0; #ifdef MONT_WORD BIGNUM *t; Index: openssl-1.0.1i/crypto/bn/bn_mul.c =================================================================== --- openssl-1.0.1i.orig/crypto/bn/bn_mul.c +++ openssl-1.0.1i/crypto/bn/bn_mul.c @@ -941,7 +941,17 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG * #endif /* BN_RECURSION */ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) - { +{ + int ret = bn_mul_fixed_top(r, a, b, ctx); + + bn_correct_top(r); + bn_check_top(r); + + return ret; +} + +int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ int ret=0; int top,al,bl; BIGNUM *rr; @@ -1092,7 +1102,7 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, c #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif - bn_correct_top(rr); + rr->flags |= BN_FLG_FIXED_TOP; if (r != rr) BN_copy(r,rr); ret=1; err: Index: openssl-1.0.1i/crypto/bn/bn_sqr.c =================================================================== --- openssl-1.0.1i.orig/crypto/bn/bn_sqr.c +++ openssl-1.0.1i/crypto/bn/bn_sqr.c @@ -63,7 +63,17 @@ /* r must not be a */ /* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) - { +{ + int ret = bn_sqr_fixed_top(r, a, ctx); + + bn_correct_top(r); + bn_check_top(r); + + return ret; +} + +int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) +{ int max,al; int ret = 0; BIGNUM *tmp,*rr; @@ -140,13 +150,11 @@ 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; - if (rr != r) BN_copy(r,rr); + rr->top = max; + rr->flags |= BN_FLG_FIXED_TOP; + if (r != rr && BN_copy(r, rr) == NULL) + goto err; + ret = 1; err: bn_check_top(rr); Index: openssl-1.0.1i/crypto/bn/bn.h =================================================================== --- openssl-1.0.1i.orig/crypto/bn/bn.h +++ openssl-1.0.1i/crypto/bn/bn.h @@ -581,6 +581,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_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, + const BIGNUM *m); +int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); void BN_MONT_CTX_free(BN_MONT_CTX *mont); int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx); BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from); @@ -747,6 +753,17 @@ 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 @@ -779,7 +796,8 @@ int RAND_pseudo_bytes(unsigned char *buf const BIGNUM *_bnum2 = (a); \ if (_bnum2 != NULL) { \ assert((_bnum2->top == 0) || \ - (_bnum2->d[_bnum2->top - 1] != 0)); \ + (_bnum2->flags & BN_FLG_FIXED_TOP) || \ + (_bnum2->d[_bnum2->top - 1] != 0)); \ bn_pollute(_bnum2); \ } \ } while(0) @@ -795,6 +813,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)