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 <nic.tuv@gmail.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10196)
This commit is contained in:
Cesar Pereida Garcia 2019-10-16 12:10:18 +03:00 committed by Nicola Tuveri
parent cd32a0f589
commit 8eba6de59e

View File

@ -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 */
}
ret = bn_rshift_fixed_top(r, a, n);
f = &(a->d[nw]);
t = r->d;
j = a->top - nw;
r->top = i;
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;
}
/*