diff options
author | jsing <> | 2023-02-13 04:25:37 +0000 |
---|---|---|
committer | jsing <> | 2023-02-13 04:25:37 +0000 |
commit | 59402a8926d023550549cfdb576bcecdb23bb2bc (patch) | |
tree | 3f4664b9d6259b538a970687b222189d9d59afb5 /src | |
parent | b0f0ff7e648539633669f7fb4530b8d5fc901052 (diff) | |
download | openbsd-59402a8926d023550549cfdb576bcecdb23bb2bc.tar.gz openbsd-59402a8926d023550549cfdb576bcecdb23bb2bc.tar.bz2 openbsd-59402a8926d023550549cfdb576bcecdb23bb2bc.zip |
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 'src')
-rw-r--r-- | src/lib/libcrypto/bn/bn_add.c | 8 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_div.c | 7 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_mont.c | 8 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_mpi.c | 4 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_mul.c | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_print.c | 11 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_recp.c | 7 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_shift.c | 10 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_sqr.c | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_word.c | 9 |
10 files changed, 40 insertions, 36 deletions
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c index dc525db084..8ae9bbe854 100644 --- a/src/lib/libcrypto/bn/bn_add.c +++ b/src/lib/libcrypto/bn/bn_add.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_add.c,v 1.21 2023/02/02 18:39:26 jsing Exp $ */ | 1 | /* $OpenBSD: bn_add.c,v 1.22 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -381,7 +381,8 @@ BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | |||
381 | } | 381 | } |
382 | } | 382 | } |
383 | 383 | ||
384 | r->neg = r_neg; | 384 | BN_set_negative(r, r_neg); |
385 | |||
385 | return ret; | 386 | return ret; |
386 | } | 387 | } |
387 | 388 | ||
@@ -409,6 +410,7 @@ BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | |||
409 | } | 410 | } |
410 | } | 411 | } |
411 | 412 | ||
412 | r->neg = r_neg; | 413 | BN_set_negative(r, r_neg); |
414 | |||
413 | return ret; | 415 | return ret; |
414 | } | 416 | } |
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c index acacfb1a8c..7ada277402 100644 --- a/src/lib/libcrypto/bn/bn_div.c +++ b/src/lib/libcrypto/bn/bn_div.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_div.c,v 1.36 2023/01/31 06:08:23 jsing Exp $ */ | 1 | /* $OpenBSD: bn_div.c,v 1.37 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -338,10 +338,10 @@ BN_div_internal(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, | |||
338 | wnump = &(snum->d[num_n - 1]); | 338 | wnump = &(snum->d[num_n - 1]); |
339 | 339 | ||
340 | /* Setup to 'res' */ | 340 | /* Setup to 'res' */ |
341 | res->neg = (numerator->neg ^ divisor->neg); | ||
342 | if (!bn_wexpand(res, (loop + 1))) | 341 | if (!bn_wexpand(res, (loop + 1))) |
343 | goto err; | 342 | goto err; |
344 | res->top = loop - no_branch; | 343 | res->top = loop - no_branch; |
344 | BN_set_negative(res, numerator->neg ^ divisor->neg); | ||
345 | resp = &(res->d[loop - 1]); | 345 | resp = &(res->d[loop - 1]); |
346 | 346 | ||
347 | /* space for temp */ | 347 | /* space for temp */ |
@@ -414,8 +414,7 @@ BN_div_internal(BIGNUM *quotient, BIGNUM *remainder, const BIGNUM *numerator, | |||
414 | int neg = numerator->neg; | 414 | int neg = numerator->neg; |
415 | 415 | ||
416 | BN_rshift(remainder, snum, norm_shift); | 416 | BN_rshift(remainder, snum, norm_shift); |
417 | if (!BN_is_zero(remainder)) | 417 | BN_set_negative(remainder, neg); |
418 | remainder->neg = neg; | ||
419 | } | 418 | } |
420 | 419 | ||
421 | if (no_branch) | 420 | if (no_branch) |
diff --git a/src/lib/libcrypto/bn/bn_mont.c b/src/lib/libcrypto/bn/bn_mont.c index 6e3d3fa0c8..4f2d4548cc 100644 --- a/src/lib/libcrypto/bn/bn_mont.c +++ b/src/lib/libcrypto/bn/bn_mont.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_mont.c,v 1.36 2023/02/01 06:23:13 jsing Exp $ */ | 1 | /* $OpenBSD: bn_mont.c,v 1.37 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -413,9 +413,9 @@ BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | |||
413 | if (!bn_wexpand(r, num)) | 413 | if (!bn_wexpand(r, num)) |
414 | return (0); | 414 | return (0); |
415 | if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { | 415 | if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { |
416 | r->neg = a->neg^b->neg; | ||
417 | r->top = num; | 416 | r->top = num; |
418 | bn_correct_top(r); | 417 | bn_correct_top(r); |
418 | BN_set_negative(r, a->neg ^ b->neg); | ||
419 | return (1); | 419 | return (1); |
420 | } | 420 | } |
421 | } | 421 | } |
@@ -471,7 +471,7 @@ BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) | |||
471 | if (!bn_wexpand(r, max)) | 471 | if (!bn_wexpand(r, max)) |
472 | return (0); | 472 | return (0); |
473 | 473 | ||
474 | r->neg ^= n->neg; | 474 | BN_set_negative(r, r->neg ^ n->neg); |
475 | np = n->d; | 475 | np = n->d; |
476 | rp = r->d; | 476 | rp = r->d; |
477 | 477 | ||
@@ -497,7 +497,7 @@ BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) | |||
497 | if (!bn_wexpand(ret, nl)) | 497 | if (!bn_wexpand(ret, nl)) |
498 | return (0); | 498 | return (0); |
499 | ret->top = nl; | 499 | ret->top = nl; |
500 | ret->neg = r->neg; | 500 | BN_set_negative(ret, r->neg); |
501 | 501 | ||
502 | rp = ret->d; | 502 | rp = ret->d; |
503 | ap = &(r->d[nl]); | 503 | ap = &(r->d[nl]); |
diff --git a/src/lib/libcrypto/bn/bn_mpi.c b/src/lib/libcrypto/bn/bn_mpi.c index 9ad28b96c9..e3b9ba0dd9 100644 --- a/src/lib/libcrypto/bn/bn_mpi.c +++ b/src/lib/libcrypto/bn/bn_mpi.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_mpi.c,v 1.11 2022/11/26 16:08:51 tb Exp $ */ | 1 | /* $OpenBSD: bn_mpi.c,v 1.12 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -127,7 +127,7 @@ BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) | |||
127 | BN_free(a); | 127 | BN_free(a); |
128 | return (NULL); | 128 | return (NULL); |
129 | } | 129 | } |
130 | a->neg = neg; | 130 | BN_set_negative(a, neg); |
131 | if (neg) { | 131 | if (neg) { |
132 | BN_clear_bit(a, BN_num_bits(a) - 1); | 132 | BN_clear_bit(a, BN_num_bits(a) - 1); |
133 | } | 133 | } |
diff --git a/src/lib/libcrypto/bn/bn_mul.c b/src/lib/libcrypto/bn/bn_mul.c index bd679108db..38c01dad18 100644 --- a/src/lib/libcrypto/bn/bn_mul.c +++ b/src/lib/libcrypto/bn/bn_mul.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_mul.c,v 1.30 2023/01/23 12:17:57 jsing Exp $ */ | 1 | /* $OpenBSD: bn_mul.c,v 1.31 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1003,10 +1003,10 @@ BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | |||
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | rr->top = rn; | 1005 | rr->top = rn; |
1006 | rr->neg = a->neg ^ b->neg; | ||
1007 | |||
1008 | bn_correct_top(rr); | 1006 | bn_correct_top(rr); |
1009 | 1007 | ||
1008 | BN_set_negative(rr, a->neg ^ b->neg); | ||
1009 | |||
1010 | if (r != rr) | 1010 | if (r != rr) |
1011 | BN_copy(r, rr); | 1011 | BN_copy(r, rr); |
1012 | done: | 1012 | done: |
diff --git a/src/lib/libcrypto/bn/bn_print.c b/src/lib/libcrypto/bn/bn_print.c index 7251e4d831..7e0683b679 100644 --- a/src/lib/libcrypto/bn/bn_print.c +++ b/src/lib/libcrypto/bn/bn_print.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_print.c,v 1.37 2022/11/26 16:08:51 tb Exp $ */ | 1 | /* $OpenBSD: bn_print.c,v 1.38 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -251,7 +251,8 @@ BN_hex2bn(BIGNUM **bn, const char *a) | |||
251 | } | 251 | } |
252 | ret->top = h; | 252 | ret->top = h; |
253 | bn_correct_top(ret); | 253 | bn_correct_top(ret); |
254 | ret->neg = neg; | 254 | |
255 | BN_set_negative(ret, neg); | ||
255 | 256 | ||
256 | *bn = ret; | 257 | *bn = ret; |
257 | return (num); | 258 | return (num); |
@@ -317,9 +318,11 @@ BN_dec2bn(BIGNUM **bn, const char *a) | |||
317 | j = 0; | 318 | j = 0; |
318 | } | 319 | } |
319 | } | 320 | } |
320 | ret->neg = neg; | ||
321 | 321 | ||
322 | bn_correct_top(ret); | 322 | bn_correct_top(ret); |
323 | |||
324 | BN_set_negative(ret, neg); | ||
325 | |||
323 | *bn = ret; | 326 | *bn = ret; |
324 | return (num); | 327 | return (num); |
325 | 328 | ||
@@ -344,7 +347,7 @@ BN_asc2bn(BIGNUM **bn, const char *a) | |||
344 | return 0; | 347 | return 0; |
345 | } | 348 | } |
346 | if (*a == '-') | 349 | if (*a == '-') |
347 | (*bn)->neg = 1; | 350 | BN_set_negative(*bn, 1); |
348 | return 1; | 351 | return 1; |
349 | } | 352 | } |
350 | 353 | ||
diff --git a/src/lib/libcrypto/bn/bn_recp.c b/src/lib/libcrypto/bn/bn_recp.c index 150b588b48..117f8933bb 100644 --- a/src/lib/libcrypto/bn/bn_recp.c +++ b/src/lib/libcrypto/bn/bn_recp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_recp.c,v 1.17 2022/11/26 16:08:51 tb Exp $ */ | 1 | /* $OpenBSD: bn_recp.c,v 1.18 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -221,8 +221,9 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp, | |||
221 | } | 221 | } |
222 | #endif | 222 | #endif |
223 | 223 | ||
224 | r->neg = BN_is_zero(r) ? 0 : m->neg; | 224 | BN_set_negative(r, m->neg); |
225 | d->neg = m->neg^recp->N.neg; | 225 | BN_set_negative(d, m->neg ^ recp->N.neg); |
226 | |||
226 | ret = 1; | 227 | ret = 1; |
227 | 228 | ||
228 | err: | 229 | err: |
diff --git a/src/lib/libcrypto/bn/bn_shift.c b/src/lib/libcrypto/bn/bn_shift.c index 5fd6687076..eee3436702 100644 --- a/src/lib/libcrypto/bn/bn_shift.c +++ b/src/lib/libcrypto/bn/bn_shift.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_shift.c,v 1.20 2023/01/11 04:26:24 jsing Exp $ */ | 1 | /* $OpenBSD: bn_shift.c,v 1.21 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2022, 2023 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2022, 2023 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -83,10 +83,10 @@ bn_lshift(BIGNUM *r, const BIGNUM *a, int n) | |||
83 | } | 83 | } |
84 | 84 | ||
85 | r->top = count; | 85 | r->top = count; |
86 | r->neg = a->neg; | ||
87 | |||
88 | bn_correct_top(r); | 86 | bn_correct_top(r); |
89 | 87 | ||
88 | BN_set_negative(r, a->neg); | ||
89 | |||
90 | return 1; | 90 | return 1; |
91 | } | 91 | } |
92 | 92 | ||
@@ -139,10 +139,10 @@ bn_rshift(BIGNUM *r, const BIGNUM *a, int n) | |||
139 | *dst = *src >> rshift; | 139 | *dst = *src >> rshift; |
140 | 140 | ||
141 | r->top = count; | 141 | r->top = count; |
142 | r->neg = a->neg; | ||
143 | |||
144 | bn_correct_top(r); | 142 | bn_correct_top(r); |
145 | 143 | ||
144 | BN_set_negative(r, a->neg); | ||
145 | |||
146 | return 1; | 146 | return 1; |
147 | } | 147 | } |
148 | 148 | ||
diff --git a/src/lib/libcrypto/bn/bn_sqr.c b/src/lib/libcrypto/bn/bn_sqr.c index bd5f43bb93..5332d17f6b 100644 --- a/src/lib/libcrypto/bn/bn_sqr.c +++ b/src/lib/libcrypto/bn/bn_sqr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_sqr.c,v 1.24 2023/02/09 09:58:53 jsing Exp $ */ | 1 | /* $OpenBSD: bn_sqr.c,v 1.25 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -420,10 +420,10 @@ BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) | |||
420 | } | 420 | } |
421 | 421 | ||
422 | rr->top = rn; | 422 | rr->top = rn; |
423 | rr->neg = 0; | ||
424 | |||
425 | bn_correct_top(rr); | 423 | bn_correct_top(rr); |
426 | 424 | ||
425 | rr->neg = 0; | ||
426 | |||
427 | if (rr != r) | 427 | if (rr != r) |
428 | BN_copy(r, rr); | 428 | BN_copy(r, rr); |
429 | 429 | ||
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c index 7077d3ad7a..a44221c35f 100644 --- a/src/lib/libcrypto/bn/bn_word.c +++ b/src/lib/libcrypto/bn/bn_word.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_word.c,v 1.17 2023/01/28 16:33:34 jsing Exp $ */ | 1 | /* $OpenBSD: bn_word.c,v 1.18 2023/02/13 04:25:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -152,8 +152,7 @@ BN_add_word(BIGNUM *a, BN_ULONG w) | |||
152 | if (a->neg) { | 152 | if (a->neg) { |
153 | a->neg = 0; | 153 | a->neg = 0; |
154 | i = BN_sub_word(a, w); | 154 | i = BN_sub_word(a, w); |
155 | if (!BN_is_zero(a)) | 155 | BN_set_negative(a, 1); |
156 | a->neg=!(a->neg); | ||
157 | return (i); | 156 | return (i); |
158 | } | 157 | } |
159 | for (i = 0; w != 0 && i < a->top; i++) { | 158 | for (i = 0; w != 0 && i < a->top; i++) { |
@@ -190,13 +189,13 @@ BN_sub_word(BIGNUM *a, BN_ULONG w) | |||
190 | if (a->neg) { | 189 | if (a->neg) { |
191 | a->neg = 0; | 190 | a->neg = 0; |
192 | i = BN_add_word(a, w); | 191 | i = BN_add_word(a, w); |
193 | a->neg = 1; | 192 | BN_set_negative(a, 1); |
194 | return (i); | 193 | return (i); |
195 | } | 194 | } |
196 | 195 | ||
197 | if ((a->top == 1) && (a->d[0] < w)) { | 196 | if ((a->top == 1) && (a->d[0] < w)) { |
198 | a->d[0] = w - a->d[0]; | 197 | a->d[0] = w - a->d[0]; |
199 | a->neg = 1; | 198 | BN_set_negative(a, 1); |
200 | return (1); | 199 | return (1); |
201 | } | 200 | } |
202 | i = 0; | 201 | i = 0; |