diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2023-02-13 04:25:38 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2023-02-13 04:25:38 +0000 |
commit | 2638b3a748d0071540d72a2d82fd846197ae2398 (patch) | |
tree | fdfbcdb5f968389d2de8958571920d20c3952f06 /lib/libcrypto/bn | |
parent | 135c5eed65eb039b243101fed4d86c97ba8a44f7 (diff) |
Avoid negative zero.
Whenever setting negative to one (or when it could potentially be one),
always use BN_set_negative() since it checks for a zero valued bignum and
will not permit negative to be set in this case. Since BN_is_zero()
currently relies on top == 0, call BN_set_negative() after top has been
set (or bn_correct_top() has been called).
This fixes a long standing issue where -0 and +0 have been permitted,
however multiple code paths (such as BN_cmp()) fail to treat these as
equivalent.
Prompted by Guido Vranken who is adding negative zero fuzzing to oss-fuzz.
ok tb@
Diffstat (limited to 'lib/libcrypto/bn')
-rw-r--r-- | lib/libcrypto/bn/bn_add.c | 8 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_div.c | 7 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_mont.c | 8 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_mpi.c | 4 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_mul.c | 6 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_print.c | 11 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_recp.c | 7 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_shift.c | 10 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_sqr.c | 6 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_word.c | 9 |
10 files changed, 40 insertions, 36 deletions
diff --git a/lib/libcrypto/bn/bn_add.c b/lib/libcrypto/bn/bn_add.c index dc525db0840..8ae9bbe8546 100644 --- a/lib/libcrypto/bn/bn_add.c +++ b/lib/libcrypto/bn/bn_add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_add.c,v 1.21 2023/02/02 18:39:26 jsing Exp $ */ +/* $OpenBSD: bn_add.c,v 1.22 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -381,7 +381,8 @@ BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) } } - r->neg = r_neg; + BN_set_negative(r, r_neg); + return ret; } @@ -409,6 +410,7 @@ BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) } } - r->neg = r_neg; + BN_set_negative(r, r_neg); + return ret; } diff --git a/lib/libcrypto/bn/bn_div.c b/lib/libcrypto/bn/bn_div.c index acacfb1a8cb..7ada277402e 100644 --- a/lib/libcrypto/bn/bn_div.c +++ b/lib/libcrypto/bn/bn_div.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_div.c,v 1.36 2023/01/31 06:08:23 jsing Exp $ */ +/* $OpenBSD: bn_div.c,v 1.37 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -338,10 +338,10 @@ BN_div_internal(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, wnump = &(snum->d[num_n - 1]); /* Setup to 'res' */ - res->neg = (numerator->neg ^ divisor->neg); if (!bn_wexpand(res, (loop + 1))) goto err; res->top = loop - no_branch; + BN_set_negative(res, numerator->neg ^ divisor->neg); resp = &(res->d[loop - 1]); /* space for temp */ @@ -414,8 +414,7 @@ BN_div_internal(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, int neg = numerator->neg; BN_rshift(remainder, snum, norm_shift); - if (!BN_is_zero(remainder)) - remainder->neg = neg; + BN_set_negative(remainder, neg); } if (no_branch) diff --git a/lib/libcrypto/bn/bn_mont.c b/lib/libcrypto/bn/bn_mont.c index 6e3d3fa0c89..4f2d4548cc4 100644 --- a/lib/libcrypto/bn/bn_mont.c +++ b/lib/libcrypto/bn/bn_mont.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_mont.c,v 1.36 2023/02/01 06:23:13 jsing Exp $ */ +/* $OpenBSD: bn_mont.c,v 1.37 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -413,9 +413,9 @@ BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (!bn_wexpand(r, num)) return (0); if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { - r->neg = a->neg^b->neg; r->top = num; bn_correct_top(r); + BN_set_negative(r, a->neg ^ b->neg); return (1); } } @@ -471,7 +471,7 @@ BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) if (!bn_wexpand(r, max)) return (0); - r->neg ^= n->neg; + BN_set_negative(r, r->neg ^ n->neg); np = n->d; rp = r->d; @@ -497,7 +497,7 @@ BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) if (!bn_wexpand(ret, nl)) return (0); ret->top = nl; - ret->neg = r->neg; + BN_set_negative(ret, r->neg); rp = ret->d; ap = &(r->d[nl]); diff --git a/lib/libcrypto/bn/bn_mpi.c b/lib/libcrypto/bn/bn_mpi.c index 9ad28b96c9c..e3b9ba0dd9a 100644 --- a/lib/libcrypto/bn/bn_mpi.c +++ b/lib/libcrypto/bn/bn_mpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_mpi.c,v 1.11 2022/11/26 16:08:51 tb Exp $ */ +/* $OpenBSD: bn_mpi.c,v 1.12 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -127,7 +127,7 @@ BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) BN_free(a); return (NULL); } - a->neg = neg; + BN_set_negative(a, neg); if (neg) { BN_clear_bit(a, BN_num_bits(a) - 1); } diff --git a/lib/libcrypto/bn/bn_mul.c b/lib/libcrypto/bn/bn_mul.c index bd679108db2..38c01dad185 100644 --- a/lib/libcrypto/bn/bn_mul.c +++ b/lib/libcrypto/bn/bn_mul.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_mul.c,v 1.30 2023/01/23 12:17:57 jsing Exp $ */ +/* $OpenBSD: bn_mul.c,v 1.31 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1003,10 +1003,10 @@ BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) } rr->top = rn; - rr->neg = a->neg ^ b->neg; - bn_correct_top(rr); + BN_set_negative(rr, a->neg ^ b->neg); + if (r != rr) BN_copy(r, rr); done: diff --git a/lib/libcrypto/bn/bn_print.c b/lib/libcrypto/bn/bn_print.c index 7251e4d8319..7e0683b6792 100644 --- a/lib/libcrypto/bn/bn_print.c +++ b/lib/libcrypto/bn/bn_print.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_print.c,v 1.37 2022/11/26 16:08:51 tb Exp $ */ +/* $OpenBSD: bn_print.c,v 1.38 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -251,7 +251,8 @@ BN_hex2bn(BIGNUM **bn, const char *a) } ret->top = h; bn_correct_top(ret); - ret->neg = neg; + + BN_set_negative(ret, neg); *bn = ret; return (num); @@ -317,9 +318,11 @@ BN_dec2bn(BIGNUM **bn, const char *a) j = 0; } } - ret->neg = neg; bn_correct_top(ret); + + BN_set_negative(ret, neg); + *bn = ret; return (num); @@ -344,7 +347,7 @@ BN_asc2bn(BIGNUM **bn, const char *a) return 0; } if (*a == '-') - (*bn)->neg = 1; + BN_set_negative(*bn, 1); return 1; } diff --git a/lib/libcrypto/bn/bn_recp.c b/lib/libcrypto/bn/bn_recp.c index 150b588b48a..117f8933bbf 100644 --- a/lib/libcrypto/bn/bn_recp.c +++ b/lib/libcrypto/bn/bn_recp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_recp.c,v 1.17 2022/11/26 16:08:51 tb Exp $ */ +/* $OpenBSD: bn_recp.c,v 1.18 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -221,8 +221,9 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp, } #endif - r->neg = BN_is_zero(r) ? 0 : m->neg; - d->neg = m->neg^recp->N.neg; + BN_set_negative(r, m->neg); + BN_set_negative(d, m->neg ^ recp->N.neg); + ret = 1; err: diff --git a/lib/libcrypto/bn/bn_shift.c b/lib/libcrypto/bn/bn_shift.c index 5fd6687076c..eee34367022 100644 --- a/lib/libcrypto/bn/bn_shift.c +++ b/lib/libcrypto/bn/bn_shift.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_shift.c,v 1.20 2023/01/11 04:26:24 jsing Exp $ */ +/* $OpenBSD: bn_shift.c,v 1.21 2023/02/13 04:25:37 jsing Exp $ */ /* * Copyright (c) 2022, 2023 Joel Sing <jsing@openbsd.org> * @@ -83,10 +83,10 @@ bn_lshift(BIGNUM *r, const BIGNUM *a, int n) } r->top = count; - r->neg = a->neg; - bn_correct_top(r); + BN_set_negative(r, a->neg); + return 1; } @@ -139,10 +139,10 @@ bn_rshift(BIGNUM *r, const BIGNUM *a, int n) *dst = *src >> rshift; r->top = count; - r->neg = a->neg; - bn_correct_top(r); + BN_set_negative(r, a->neg); + return 1; } diff --git a/lib/libcrypto/bn/bn_sqr.c b/lib/libcrypto/bn/bn_sqr.c index bd5f43bb939..5332d17f6b2 100644 --- a/lib/libcrypto/bn/bn_sqr.c +++ b/lib/libcrypto/bn/bn_sqr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_sqr.c,v 1.24 2023/02/09 09:58:53 jsing Exp $ */ +/* $OpenBSD: bn_sqr.c,v 1.25 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -420,10 +420,10 @@ BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) } rr->top = rn; - rr->neg = 0; - bn_correct_top(rr); + rr->neg = 0; + if (rr != r) BN_copy(r, rr); diff --git a/lib/libcrypto/bn/bn_word.c b/lib/libcrypto/bn/bn_word.c index 7077d3ad7af..a44221c35f4 100644 --- a/lib/libcrypto/bn/bn_word.c +++ b/lib/libcrypto/bn/bn_word.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_word.c,v 1.17 2023/01/28 16:33:34 jsing Exp $ */ +/* $OpenBSD: bn_word.c,v 1.18 2023/02/13 04:25:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -152,8 +152,7 @@ BN_add_word(BIGNUM *a, BN_ULONG w) if (a->neg) { a->neg = 0; i = BN_sub_word(a, w); - if (!BN_is_zero(a)) - a->neg=!(a->neg); + BN_set_negative(a, 1); return (i); } for (i = 0; w != 0 && i < a->top; i++) { @@ -190,13 +189,13 @@ BN_sub_word(BIGNUM *a, BN_ULONG w) if (a->neg) { a->neg = 0; i = BN_add_word(a, w); - a->neg = 1; + BN_set_negative(a, 1); return (i); } if ((a->top == 1) && (a->d[0] < w)) { a->d[0] = w - a->d[0]; - a->neg = 1; + BN_set_negative(a, 1); return (1); } i = 0; |