summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2021-07-05 11:01:59 +1000
committerPauli <pauli@openssl.org>2021-07-07 19:13:29 +1000
commitf8fc0e35e0b1813af15887d42e17b7d5537bb86c (patch)
treef7644807d5b0c1dd1237734d23b2995ba0d44d87 /crypto
parentf775b5c4857d1fef67f487c2ec6017b1f1c6eb19 (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.c7
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)