From f356d55941f0d0cfa55df0cb88103d73ceef9a84 Mon Sep 17 00:00:00 2001 From: tb Date: Thu, 6 Jul 2023 15:08:54 +0000 Subject: [PATCH] Add regress coverage for bn_printf This must be one of the ugliest tests I've ever written, but I can't think of a better way of doing it. --- regress/lib/libcrypto/bn/Makefile | 4 +- regress/lib/libcrypto/bn/bn_print.c | 280 ++++++++++++++++++++++++++++ 2 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 regress/lib/libcrypto/bn/bn_print.c diff --git a/regress/lib/libcrypto/bn/Makefile b/regress/lib/libcrypto/bn/Makefile index 1b4d68b9841..1072f587e7d 100644 --- a/regress/lib/libcrypto/bn/Makefile +++ b/regress/lib/libcrypto/bn/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.33 2023/06/03 21:20:29 tb Exp $ +# $OpenBSD: Makefile,v 1.34 2023/07/06 15:08:54 tb Exp $ PROGS += bn_add_sub PROGS += bn_cmp @@ -12,6 +12,7 @@ PROGS += bn_mod_sqrt PROGS += bn_mont PROGS += bn_mul_div PROGS += bn_primes +PROGS += bn_print PROGS += bn_rand_interval PROGS += bn_shift PROGS += bn_test @@ -22,6 +23,7 @@ PROGS += bn_word STATIC_LINK += bn_gcd STATIC_LINK += bn_isqrt STATIC_LINK += bn_mod_exp +STATIC_LINK += bn_print STATIC_LINK += bn_rand_interval STATIC_LINK += bn_test diff --git a/regress/lib/libcrypto/bn/bn_print.c b/regress/lib/libcrypto/bn/bn_print.c new file mode 100644 index 00000000000..a19fa84cbc4 --- /dev/null +++ b/regress/lib/libcrypto/bn/bn_print.c @@ -0,0 +1,280 @@ +/* $OpenBSD: bn_print.c,v 1.1 2023/07/06 15:08:54 tb Exp $ */ + +/* + * Copyright (c) 2023 Theo Buehler + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +#include "bn_local.h" + +#define BATIHDIDIDI "mana mana" +#define BUF_MEM_LEN 1024 + +static const char *pk = "040d305e1b159d03d0a17935b73a3c927aca151ccd62f39c" + "265c073de554faa3d6cc12eaf4145fe88e19ab2f2e48e6ac" + "184378acd037c3bdb2cd2ce647e21ae663b83d2e2f78c44f" + "dbf40fa4684c55726b951d4e18429578cc373c91e29b652b" + "29"; + +const struct print_test { + const char *desc; + const char *want; +} bn_print_tests[] = { + { + .desc = "zero", + .want = " mana mana 0\n", + }, + { + .desc = "minus one", + .want = " mana mana 1 (0x1)\n", + }, + { + .desc = "minus one", + .want = " mana mana -1 (-0x1)\n", + }, +#ifdef _LP64 + { + .desc = "largest word", + .want = " mana mana 18446744073709551615 " + "(0xffffffffffffffff)\n", + }, + { + .desc = "smallest word", + .want = " mana mana -18446744073709551615 " + "(-0xffffffffffffffff)\n", + }, + { + .desc = "largest negative non-word", + .want = " mana mana (Negative)\n" + " 01:00:00:00:00:00:00:00:00\n", + }, + { + .desc = "smallest positive non-word", + .want = " mana mana\n" + " 01:00:00:00:00:00:00:00:00\n", + }, +#else + { + .desc = "largest word", + .want = " mana mana 4294967295 (0xffffffff)\n", + }, + { + .desc = "smallest word", + .want = " mana mana -4294967295 (-0xffffffff)\n", + }, + { + .desc = "largest negative non-word", + .want = " mana mana (Negative)\n" + " 01:00:00:00:00\n", + }, + { + .desc = "smallest positive non-word", + .want = " mana mana\n" + " 01:00:00:00:00\n", + }, +#endif + { + .desc = "some pubkey", + .want = " mana mana\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n" + " 3c:91:e2:9b:65:2b:29\n", + }, + { + .desc = "negated pubkey", + .want = " mana mana (Negative)\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n" + " 3c:91:e2:9b:65:2b:29\n", + }, + { + .desc = "shifted negated pubkey", + .want = " mana mana (Negative)\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n", + }, + { + .desc = "shifted pubkey", + .want = " mana mana\n" + " 04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n" + " 92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n" + " fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n" + " 48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n" + " 47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n" + " a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n", + }, +}; + +#define N_TESTCASES (sizeof(bn_print_tests) / sizeof(bn_print_tests[0])) + +static int +bn_print_testcase(const BIGNUM *bn, const struct print_test *test) +{ + BIO *bio; + char *got; + size_t want_len; + long got_len; + int failed = 1; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new"); + + if (!bn_printf(bio, bn, 4, "%s", BATIHDIDIDI)) + errx(1, "bn_printf"); + + if ((got_len = BIO_get_mem_data(bio, &got)) < 0) + errx(1, "BIO_get_mem_data"); + + if ((want_len = strlen(test->want)) != (size_t)got_len) { + fprintf(stderr, "%s: want: %zu, got %ld\n", + test->desc, want_len, got_len); + goto err; + } + + if (strncmp(got, test->want, want_len) != 0) { + fprintf(stderr, "%s: strings differ\n", test->desc); + fprintf(stderr, "want: \"%s\"\ngot : \"%*s\"\n", + test->want, (int)got_len, got); + goto err; + } + + failed = 0; + err: + BIO_free(bio); + + return failed; +} + +int +main(void) +{ + const struct print_test *test; + size_t testcase = 0; + BIO *bio; + BIGNUM *bn; + int failed = 0; + + if ((bio = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL) + errx(1, "BIO_new_fp"); + + /* zero */ + if ((bn = BN_new()) == NULL) + errx(1, "BN_new"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* one */ + if (!BN_set_word(bn, 1)) + errx(1, "BIO_set_word"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* minus one */ + BN_set_negative(bn, 1); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* largest word */ + if (!BN_set_word(bn, ~0)) + errx(1, "BN_set_word"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* smallest word */ + BN_set_negative(bn, 1); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* largest negative non-word */ + if (!BN_sub_word(bn, 1)) + errx(1, "ASN1_bn_print"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* smallest positive non-word */ + BN_set_negative(bn, 0); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* some pubkey */ + if (BN_hex2bn(&bn, pk) == 0) + errx(1, "BN_hex2bn"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* negated pubkey */ + BN_set_negative(bn, 1); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* shifted negated pubkey */ + if (!BN_rshift(bn, bn, 7 * 8)) + errx(1, "BN_rshift"); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + /* shifted pubkey */ + BN_set_negative(bn, 0); + if (testcase >= N_TESTCASES) + errx(1, "Too many tests"); + test = &bn_print_tests[testcase++]; + failed |= bn_print_testcase(bn, test); + + if (testcase != N_TESTCASES) { + warnx("Not all tests run"); + failed |= 1; + } + + return failed; +} -- 2.20.1