diff options
author | Pauli <pauli@openssl.org> | 2021-07-05 11:01:59 +1000 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-07-07 19:13:29 +1000 |
commit | f8fc0e35e0b1813af15887d42e17b7d5537bb86c (patch) | |
tree | f7644807d5b0c1dd1237734d23b2995ba0d44d87 /crypto | |
parent | f775b5c4857d1fef67f487c2ec6017b1f1c6eb19 (diff) |
bn: procduce correct sign for result of BN_mod()
There is a problem that appears when calling BN_div(a, c, a, b) with negative b.
In this case, the sign of the remainder c is incorrect. The problem only
occurs if the dividend and the quotient are the same BIGNUM.
Fixes #15982
Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/15991)
(cherry picked from commit 105c83150f15af3f78ea0758859062842bdbe30e)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/bn/bn_div.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c index 286d69c895..4a6889900e 100644 --- a/crypto/bn/bn_div.c +++ b/crypto/bn/bn_div.c @@ -268,7 +268,7 @@ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, BIGNUM *tmp, *snum, *sdiv, *res; BN_ULONG *resp, *wnum, *wnumtop; BN_ULONG d0, d1; - int num_n, div_n; + int num_n, div_n, num_neg; assert(divisor->top > 0 && divisor->d[divisor->top - 1] != 0); @@ -326,7 +326,8 @@ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, /* Setup quotient */ if (!bn_wexpand(res, loop)) goto err; - res->neg = (num->neg ^ divisor->neg); + num_neg = num->neg; + res->neg = (num_neg ^ divisor->neg); res->top = loop; res->flags |= BN_FLG_FIXED_TOP; resp = &(res->d[loop]); @@ -442,7 +443,7 @@ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, *--resp = q; } /* snum holds remainder, it's as wide as divisor */ - snum->neg = num->neg; + snum->neg = num_neg; snum->top = div_n; snum->flags |= BN_FLG_FIXED_TOP; if (rm != NULL) |