diff options
author | Pauli <pauli@openssl.org> | 2021-07-05 11:01:59 +1000 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-07-07 19:12:48 +1000 |
commit | 105c83150f15af3f78ea0758859062842bdbe30e (patch) | |
tree | 2c1e1ea773116bea76651a767c1b478825997114 /crypto | |
parent | 0f71b1eb6c390e58059a4c4225bcbecac9aef2c7 (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)
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 3ba009a540..25514c05f1 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) |