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/lib/libcrypto/bn/bn_word.c | |
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 '')
-rw-r--r-- | src/lib/libcrypto/bn/bn_word.c | 9 |
1 files changed, 4 insertions, 5 deletions
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; |