From 8eba6de59e2b06f23c214344423a5a618d1c9ffd Mon Sep 17 00:00:00 2001 From: Cesar Pereida Garcia Date: Wed, 16 Oct 2019 12:10:18 +0300 Subject: [PATCH] Unify BN_rshift design This commit aims at refactoring the `BN_rshift` by making it a wrapper around `bn_rshift_fixed_top`, in order to match the current design of `BN_lshift`, as suggested in the discussion at https://github.com/openssl/openssl/pull/10122#discussion_r332474277 . As described in the code, by refactoring this function, `BN_rshift` provides a constant-time behavior for sufficiently[!] zero-padded inputs under the following assumptions: `|n < BN_BITS2|` or `|n / BN_BITS2|` being non-secret. Notice that `BN_rshift` returns a canonical representation of the BIGNUM, if a `fixed_top` representation is required, the caller should call `bn_rshift_fixed_top` instead. Reviewed-by: Nicola Tuveri Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/10196) --- crypto/bn/bn_shift.c | 48 +++++--------------------------------------- 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/crypto/bn/bn_shift.c b/crypto/bn/bn_shift.c index b1f8dbd2d3..cdf66933e9 100644 --- a/crypto/bn/bn_shift.c +++ b/crypto/bn/bn_shift.c @@ -152,57 +152,19 @@ int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n) int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) { - int i, j, nw, lb, rb; - BN_ULONG *t, *f; - BN_ULONG l, tmp; - - bn_check_top(r); - bn_check_top(a); + int ret = 0; if (n < 0) { BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT); return 0; } - nw = n / BN_BITS2; - rb = n % BN_BITS2; - lb = BN_BITS2 - rb; - if (nw >= a->top || a->top == 0) { - BN_zero(r); - return 1; - } - i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2; - if (r != a) { - if (bn_wexpand(r, i) == NULL) - return 0; - r->neg = a->neg; - } else { - if (n == 0) - return 1; /* or the copying loop will go berserk */ - } - - f = &(a->d[nw]); - t = r->d; - j = a->top - nw; - r->top = i; + ret = bn_rshift_fixed_top(r, a, n); - if (rb == 0) { - for (i = j; i != 0; i--) - *(t++) = *(f++); - } else { - l = *(f++); - for (i = j - 1; i != 0; i--) { - tmp = (l >> rb) & BN_MASK2; - l = *(f++); - *(t++) = (tmp | (l << lb)) & BN_MASK2; - } - if ((l = (l >> rb) & BN_MASK2)) - *(t) = l; - } - if (!r->top) - r->neg = 0; /* don't allow negative zero */ + bn_correct_top(r); bn_check_top(r); - return 1; + + return ret; } /* -- 2.25.1