Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:Update
openssl.24563
0001-crypto-bn-add-more-fixed-top-routines.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-crypto-bn-add-more-fixed-top-routines.patch of Package openssl.24563
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.2j/crypto/bn/bn_mod.c =================================================================== --- openssl-1.0.2j.orig/crypto/bn/bn_mod.c +++ openssl-1.0.2j/crypto/bn/bn_mod.c @@ -170,6 +170,70 @@ int BN_mod_sub(BIGNUM *r, const BIGNUM * } /* + * 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.2j/crypto/bn/bn_mont.c =================================================================== --- openssl-1.0.2j.orig/crypto/bn/bn_mont.c +++ openssl-1.0.2j/crypto/bn/bn_mont.c @@ -153,10 +153,10 @@ int BN_mod_mul_montgomery(BIGNUM *r, con bn_check_top(tmp); if (a == b) { - if (!BN_sqr(tmp, a, ctx)) + if (!bn_sqr_fixed_top(tmp, a, ctx)) goto err; } else { - if (!BN_mul(tmp, a, b, ctx)) + if (!bn_mul_fixed_top(tmp, a, b, ctx)) goto err; } /* reduce from aRR to aR */ @@ -180,6 +180,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; @@ -197,12 +198,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]; @@ -290,6 +289,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.2j/crypto/bn/bn_mul.c =================================================================== --- openssl-1.0.2j.orig/crypto/bn/bn_mul.c +++ openssl-1.0.2j/crypto/bn/bn_mul.c @@ -936,6 +936,16 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG * 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; @@ -1082,7 +1092,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; Index: openssl-1.0.2j/crypto/bn/bn_sqr.c =================================================================== --- openssl-1.0.2j.orig/crypto/bn/bn_sqr.c +++ openssl-1.0.2j/crypto/bn/bn_sqr.c @@ -66,6 +66,16 @@ */ 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; @@ -135,16 +145,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.2j/crypto/bn/bn.h =================================================================== --- openssl-1.0.2j.orig/crypto/bn/bn.h +++ openssl-1.0.2j/crypto/bn/bn.h @@ -583,6 +583,12 @@ int BN_mod_mul_montgomery(BIGNUM *r, con 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); @@ -774,6 +780,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 @@ -807,7 +823,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) @@ -825,6 +842,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)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor