summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2023-04-22 14:03:03 +0000
committerjsing <>2023-04-22 14:03:03 +0000
commit2afa30e89183897153850cee97c094af170d7743 (patch)
treea30ef699236e75ada54241b320937339bafe3542
parent70d17e06df21b481660d444234dc0f0047cfbb56 (diff)
downloadopenbsd-2afa30e89183897153850cee97c094af170d7743.tar.gz
openbsd-2afa30e89183897153850cee97c094af170d7743.tar.bz2
openbsd-2afa30e89183897153850cee97c094af170d7743.zip
Provide initial regress for BN_{asc,dec,hex}2bn()/BN_bn2{dec,hex}()
-rw-r--r--src/regress/lib/libcrypto/bn/Makefile3
-rw-r--r--src/regress/lib/libcrypto/bn/bn_convert.c590
2 files changed, 592 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/bn/Makefile b/src/regress/lib/libcrypto/bn/Makefile
index 9d9d77ae2d..1c2076b1f4 100644
--- a/src/regress/lib/libcrypto/bn/Makefile
+++ b/src/regress/lib/libcrypto/bn/Makefile
@@ -1,7 +1,8 @@
1# $OpenBSD: Makefile,v 1.31 2023/04/17 19:51:05 tb Exp $ 1# $OpenBSD: Makefile,v 1.32 2023/04/22 14:03:03 jsing Exp $
2 2
3PROGS += bn_add_sub 3PROGS += bn_add_sub
4PROGS += bn_cmp 4PROGS += bn_cmp
5PROGS += bn_convert
5PROGS += bn_gcd 6PROGS += bn_gcd
6PROGS += bn_general 7PROGS += bn_general
7PROGS += bn_isqrt 8PROGS += bn_isqrt
diff --git a/src/regress/lib/libcrypto/bn/bn_convert.c b/src/regress/lib/libcrypto/bn/bn_convert.c
new file mode 100644
index 0000000000..ea4cbda79d
--- /dev/null
+++ b/src/regress/lib/libcrypto/bn/bn_convert.c
@@ -0,0 +1,590 @@
1/* $OpenBSD: bn_convert.c,v 1.1 2023/04/22 14:03:03 jsing Exp $ */
2/*
3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <err.h>
19#include <string.h>
20
21#include <openssl/bn.h>
22
23/*
24 * Additional test coverage is needed for:
25 *
26 * - BN_bn2binpad()
27 * - BN_bn2lebinpad()
28 * - BN_lebin2bn()
29 * - BN_bn2mpi()/BN_mpi2bn()
30 * - BN_print()/BN_print_fp()
31 *
32 * - Invalid inputs to {asc,dec,hex,mpi}2bn
33 * - Zero padded inputs
34 */
35
36static void
37hexdump(const unsigned char *buf, size_t len)
38{
39 size_t i;
40
41 for (i = 1; i <= len; i++)
42 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
43
44 fprintf(stderr, "\n");
45}
46
47static int
48check_bin_output(size_t test_no, const char *label, const uint8_t *bin,
49 size_t bin_len, const BIGNUM *bn)
50{
51 uint8_t *out = NULL;
52 int out_len;
53 int ret;
54 int failed = 1;
55
56 out_len = BN_num_bytes(bn);
57 if (out_len != (int)bin_len) {
58 fprintf(stderr, "FAIL: Test %zu - BN_num_bytes() = %d, "
59 "want %zu\n", test_no, out_len, bin_len);
60 goto failure;
61 }
62 if ((out = malloc(out_len)) == NULL)
63 err(1, "malloc");
64 if ((ret = BN_bn2bin(bn, out)) != out_len) {
65 fprintf(stderr, "FAIL: BN_bn2bin() returned %d, "
66 "want %d\n", ret, out_len);
67 goto failure;
68 }
69 if (memcmp(out, bin, bin_len) != 0) {
70 fprintf(stderr, "FAIL: Test %zu - output from "
71 "BN_bn2bin() differs\n", test_no);
72 fprintf(stderr, "Got:\n");
73 hexdump(out, out_len);
74 fprintf(stderr, "Want:\n");
75 hexdump(bin, bin_len);
76 goto failure;
77 }
78
79 failed = 0;
80
81 failure:
82 free(out);
83
84 return failed;
85}
86
87struct bn_asc2bn_test {
88 const char *in;
89 const uint8_t bin[64];
90 size_t bin_len;
91 int neg;
92 int want_error;
93};
94
95static const struct bn_asc2bn_test bn_asc2bn_tests[] = {
96 {
97 .in = "",
98 .want_error = 1,
99 },
100 {
101 .in = "-",
102 .want_error = 1,
103 },
104 {
105 .in = "0",
106 .bin = { 0x00, },
107 .bin_len = 0,
108 .neg = 0,
109 },
110 {
111 .in = "0x0",
112 .bin = { 0x00, },
113 .bin_len = 0,
114 .neg = 0,
115 },
116 {
117 .in = "-0",
118 .bin = { 0x00, },
119 .bin_len = 0,
120 .neg = 0,
121 },
122 {
123 .in = "-0x0",
124 .bin = { 0x00, },
125 .bin_len = 0,
126 .neg = 0,
127 },
128 {
129 .in = "123456789",
130 .bin = { 0x07, 0x5b, 0xcd, 0x15, },
131 .bin_len = 4,
132 .neg = 0,
133 },
134 {
135 .in = "0123456789",
136 .bin = { 0x07, 0x5b, 0xcd, 0x15, },
137 .bin_len = 4,
138 .neg = 0,
139 },
140 {
141 .in = "-123456789",
142 .bin = { 0x07, 0x5b, 0xcd, 0x15, },
143 .bin_len = 4,
144 .neg = 1,
145 },
146 {
147 .in = "0X123456789",
148 .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, },
149 .bin_len = 5,
150 .neg = 0,
151 },
152 {
153 .in = "0x123456789",
154 .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, },
155 .bin_len = 5,
156 .neg = 0,
157 },
158 {
159 .in = "-0x123456789",
160 .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, },
161 .bin_len = 5,
162 .neg = 1,
163 },
164 {
165 .in = "abcdef123456789",
166 .want_error = 1,
167 },
168 {
169 .in = "0x000123456789abCdEf",
170 .bin = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
171 .bin_len = 8,
172 .neg = 0,
173 },
174};
175
176#define N_BN_ASC2BN_TESTS \
177 (sizeof(bn_asc2bn_tests) / sizeof(*bn_asc2bn_tests))
178
179static int
180test_bn_asc2bn(void)
181{
182 const struct bn_asc2bn_test *bat;
183 BIGNUM *bn = NULL;
184 size_t i;
185 int failed = 1;
186
187 for (i = 0; i < N_BN_ASC2BN_TESTS; i++) {
188 bat = &bn_asc2bn_tests[i];
189
190 BN_free(bn);
191 bn = NULL;
192
193 if (!BN_asc2bn(&bn, bat->in)) {
194 if (bat->want_error)
195 continue;
196 fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() failed\n", i);
197 goto failure;
198 }
199 if (bat->want_error) {
200 fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() succeeded "
201 "when it should have failed\n", i);
202 goto failure;
203 }
204
205 if (check_bin_output(i, "BN_asc2bn()", bat->bin, bat->bin_len,
206 bn) != 0)
207 goto failure;
208
209 if (BN_is_negative(bn) != bat->neg) {
210 fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() resulted "
211 "in negative %d, want %d", i, BN_is_negative(bn),
212 bat->neg);
213 goto failure;
214 }
215 }
216
217 failed = 0;
218
219 failure:
220 BN_free(bn);
221
222 return failed;
223}
224
225struct bn_convert_test {
226 const uint8_t bin[64];
227 size_t bin_len;
228 int neg;
229 const char *dec;
230 const char *hex;
231};
232
233static const struct bn_convert_test bn_convert_tests[] = {
234 {
235 .bin = { 0x0, },
236 .bin_len = 0,
237 .neg = 0,
238 .dec = "0",
239 .hex = "0",
240 },
241 {
242 .bin = { 0x1, },
243 .bin_len = 1,
244 .neg = 0,
245 .dec = "1",
246 .hex = "01",
247 },
248 {
249 .bin = { 0x7f, 0xff, 0xff, },
250 .bin_len = 3,
251 .neg = 0,
252 .dec = "8388607",
253 .hex = "7FFFFF",
254 },
255 {
256 .bin = { 0x7f, 0xff, 0xff, },
257 .bin_len = 3,
258 .neg = 1,
259 .dec = "-8388607",
260 .hex = "-7FFFFF",
261 },
262 {
263 .bin = { 0xff, 0xff, 0xff, 0xff, },
264 .bin_len = 4,
265 .neg = 0,
266 .dec = "4294967295",
267 .hex = "FFFFFFFF",
268 },
269 {
270 .bin = { 0xff, 0xff, 0xff, 0xff, },
271 .bin_len = 4,
272 .neg = 1,
273 .dec = "-4294967295",
274 .hex = "-FFFFFFFF",
275 },
276 {
277 .bin = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
278 .bin_len = 8,
279 .neg = 0,
280 .dec = "18446744069414584320",
281 .hex = "FFFFFFFF00000000",
282 },
283 {
284 .bin = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
285 .bin_len = 8,
286 .neg = 1,
287 .dec = "-18446744069414584320",
288 .hex = "-FFFFFFFF00000000",
289 },
290 {
291 .bin = { 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, },
292 .bin_len = 8,
293 .neg = 0,
294 .dec = "9223794255762391041",
295 .hex = "8001800180018001",
296 },
297 {
298 .bin = { 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, },
299 .bin_len = 8,
300 .neg = 1,
301 .dec = "-9223794255762391041",
302 .hex = "-8001800180018001",
303 },
304 {
305 .bin = { 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, },
306 .bin_len = 9,
307 .neg = 0,
308 .dec = "27670538329471942657",
309 .hex = "018001800180018001",
310 },
311 {
312 .bin = { 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, },
313 .bin_len = 9,
314 .neg = 1,
315 .dec = "-27670538329471942657",
316 .hex = "-018001800180018001",
317 },
318 {
319 .bin = {
320 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
321 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
322 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
323 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
324 },
325 .bin_len = 32,
326 .neg = 0,
327 .dec = "57895161181645529494837117048595051142566530671229791132691030063130991362047",
328 .hex = "7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF",
329 },
330 {
331 .bin = {
332 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
333 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
334 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
335 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
336 },
337 .bin_len = 32,
338 .neg = 1,
339 .dec = "-57895161181645529494837117048595051142566530671229791132691030063130991362047",
340 .hex = "-7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF",
341 },
342};
343
344#define N_BN_CONVERT_TESTS \
345 (sizeof(bn_convert_tests) / sizeof(*bn_convert_tests))
346
347static int
348test_bn_convert(void)
349{
350 const struct bn_convert_test *bct;
351 char *out_str = NULL;
352 BIGNUM *bn = NULL;
353 size_t i;
354 int failed = 1;
355
356 for (i = 0; i < N_BN_CONVERT_TESTS; i++) {
357 bct = &bn_convert_tests[i];
358
359 BN_free(bn);
360 if ((bn = BN_bin2bn(bct->bin, bct->bin_len, NULL)) == NULL) {
361 fprintf(stderr, "FAIL: BN_bin2bn() failed\n");
362 goto failure;
363 }
364 BN_set_negative(bn, bct->neg);
365
366 if (check_bin_output(i, "BN_bin2bn()", bct->bin, bct->bin_len,
367 bn) != 0)
368 goto failure;
369
370 free(out_str);
371 if ((out_str = BN_bn2dec(bn)) == NULL) {
372 fprintf(stderr, "FAIL: BN_bn2dec() failed\n");
373 goto failure;
374 }
375 if (strcmp(out_str, bct->dec) != 0) {
376 fprintf(stderr, "FAIL: Test %zu - BN_bn2dec() returned "
377 "'%s', want '%s'", i, out_str, bct->dec);
378 goto failure;
379 }
380
381 free(out_str);
382 if ((out_str = BN_bn2hex(bn)) == NULL) {
383 fprintf(stderr, "FAIL: BN_bn2hex() failed\n");
384 goto failure;
385 }
386 if (strcmp(out_str, bct->hex) != 0) {
387 fprintf(stderr, "FAIL: Test %zu - BN_bn2hex() returned "
388 "'%s', want '%s'", i, out_str, bct->hex);
389 goto failure;
390 }
391
392 if (BN_dec2bn(&bn, bct->dec) != (int)strlen(bct->dec)) {
393 fprintf(stderr, "FAIL: BN_dec2bn() failed\n");
394 goto failure;
395 }
396 if (BN_is_negative(bn) != bct->neg) {
397 fprintf(stderr, "FAIL: Test %zu - BN_dec2bn() resulted "
398 "in negative %d, want %d", i, BN_is_negative(bn),
399 bct->neg);
400 goto failure;
401 }
402
403 if (check_bin_output(i, "BN_dec2bn()", bct->bin, bct->bin_len,
404 bn) != 0)
405 goto failure;
406
407 if (BN_hex2bn(&bn, bct->hex) != (int)strlen(bct->hex)) {
408 fprintf(stderr, "FAIL: BN_hex2bn() failed\n");
409 goto failure;
410 }
411 if (BN_is_negative(bn) != bct->neg) {
412 fprintf(stderr, "FAIL: Test %zu - BN_hex2bn() resulted "
413 "in negative %d, want %d", i, BN_is_negative(bn),
414 bct->neg);
415 goto failure;
416 }
417
418 if (check_bin_output(i, "BN_hex2bn()", bct->bin, bct->bin_len,
419 bn) != 0)
420 goto failure;
421 }
422
423 failed = 0;
424
425 failure:
426 free(out_str);
427 BN_free(bn);
428
429 return failed;
430}
431
432static int
433test_bn_dec2bn(void)
434{
435 BIGNUM *bn = NULL;
436 BN_ULONG w;
437 int ret;
438 int failed = 1;
439
440 /* An empty string fails to parse. */
441 if (BN_dec2bn(&bn, "") != 0) {
442 fprintf(stderr, "FAIL: BN_dec2bn(_, \"\") succeeded\n");
443 goto failure;
444 }
445 if (bn != NULL) {
446 fprintf(stderr, "FAIL: BN_dec2bn(_, \"\") succeeded\n");
447 goto failure;
448 }
449
450 /* A minus sign parses as 0. */
451 if (BN_dec2bn(&bn, "-") != 1) {
452 fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") failed\n");
453 goto failure;
454 }
455 if (bn == NULL) {
456 fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") failed\n");
457 goto failure;
458 }
459 if (!BN_is_zero(bn)) {
460 fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") is non-zero\n");
461 goto failure;
462 }
463 if (BN_is_negative(bn)) {
464 fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") resulted in "
465 "negative zero\n");
466 goto failure;
467 }
468
469 /* Ensure that -0 results in 0. */
470 if (BN_dec2bn(&bn, "-0") != 2) {
471 fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") failed\n");
472 goto failure;
473 }
474 if (!BN_is_zero(bn)) {
475 fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") is non-zero\n");
476 goto failure;
477 }
478 if (BN_is_negative(bn)) {
479 fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") resulted in "
480 "negative zero\n");
481 goto failure;
482 }
483
484 /* BN_dec2bn() is the new atoi()... */
485 if ((ret = BN_dec2bn(&bn, "0123456789abcdef")) != 10) {
486 fprintf(stderr, "FAIL: BN_dec2bn() returned %d, want 10\n", ret);
487 goto failure;
488 }
489 if ((w = BN_get_word(bn)) != 0x75bcd15) {
490 fprintf(stderr, "FAIL: BN_dec2bn() resulted in %llx, want %llx\n",
491 (unsigned long long)w, 0x75bcd15ULL);
492 goto failure;
493 }
494
495 failed = 0;
496
497 failure:
498 BN_free(bn);
499
500 return failed;
501}
502
503static int
504test_bn_hex2bn(void)
505{
506 BIGNUM *bn = NULL;
507 BN_ULONG w;
508 int ret;
509 int failed = 1;
510
511 /* An empty string fails to parse. */
512 if (BN_hex2bn(&bn, "") != 0) {
513 fprintf(stderr, "FAIL: BN_hex2bn(_, \"\") succeeded\n");
514 goto failure;
515 }
516 if (bn != NULL) {
517 fprintf(stderr, "FAIL: BN_hex2bn(_, \"\") succeeded\n");
518 goto failure;
519 }
520
521 /* A minus sign parses as 0. */
522 if (BN_hex2bn(&bn, "-") != 1) {
523 fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") failed\n");
524 goto failure;
525 }
526 if (bn == NULL) {
527 fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") failed\n");
528 goto failure;
529 }
530 if (!BN_is_zero(bn)) {
531 fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") returned non-zero\n");
532 goto failure;
533 }
534 if (BN_is_negative(bn)) {
535 fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") returned negative zero\n");
536 goto failure;
537 }
538
539 /* Ensure that -0 results in 0. */
540 if (BN_hex2bn(&bn, "-0") != 2) {
541 fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") failed\n");
542 goto failure;
543 }
544 if (!BN_is_zero(bn)) {
545 fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") is non-zero\n");
546 goto failure;
547 }
548 if (BN_is_negative(bn)) {
549 fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") resulted in "
550 "negative zero\n");
551 goto failure;
552 }
553
554 /* BN_hex2bn() is the new atoi()... */
555 if ((ret = BN_hex2bn(&bn, "9abcdefz")) != 7) {
556 fprintf(stderr, "FAIL: BN_hex2bn() returned %d, want 7\n", ret);
557 goto failure;
558 }
559 if ((w = BN_get_word(bn)) != 0x9abcdef) {
560 fprintf(stderr, "FAIL: BN_hex2bn() resulted in %llx, want %llx\n",
561 (unsigned long long)w, 0x9abcdefULL);
562 goto failure;
563 }
564
565 /* A 0x prefix fails to parse without BN_asc2bn() (instead we get 0!). */
566 if (BN_hex2bn(&bn, "0x1") != 1) {
567 fprintf(stderr, "FAIL: BN_hex2bn() parsed a 0x prefix\n");
568 goto failure;
569 }
570
571 failed = 0;
572
573 failure:
574 BN_free(bn);
575
576 return failed;
577}
578
579int
580main(int argc, char **argv)
581{
582 int failed = 0;
583
584 failed |= test_bn_asc2bn();
585 failed |= test_bn_convert();
586 failed |= test_bn_dec2bn();
587 failed |= test_bn_hex2bn();
588
589 return failed;
590}