xref: /openbsd-src/regress/lib/libcrypto/bn/bn_print.c (revision 6971d2f98a81eea59cb815ada7271c03b5ea93da)
1*6971d2f9Stb /*	$OpenBSD: bn_print.c,v 1.5 2023/07/27 06:41:39 tb Exp $ */
2f356d559Stb 
3f356d559Stb /*
4f356d559Stb  * Copyright (c) 2023 Theo Buehler <tb@openbsd.org>
5f356d559Stb  *
6f356d559Stb  * Permission to use, copy, modify, and distribute this software for any
7f356d559Stb  * purpose with or without fee is hereby granted, provided that the above
8f356d559Stb  * copyright notice and this permission notice appear in all copies.
9f356d559Stb  *
10f356d559Stb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11f356d559Stb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12f356d559Stb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13f356d559Stb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14f356d559Stb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15f356d559Stb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16f356d559Stb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17f356d559Stb  */
18f356d559Stb 
19f356d559Stb #include <err.h>
20f356d559Stb #include <stdio.h>
21f356d559Stb #include <string.h>
22f356d559Stb 
23f356d559Stb #include <openssl/asn1.h>
24f356d559Stb #include <openssl/bio.h>
25f356d559Stb #include <openssl/bn.h>
26f356d559Stb 
27f356d559Stb #include "bn_local.h"
28f356d559Stb 
29f356d559Stb #define BATIHDIDIDI "mana mana"
30f356d559Stb #define BUF_MEM_LEN 1024
31f356d559Stb 
32f356d559Stb static const char *pk = "040d305e1b159d03d0a17935b73a3c927aca151ccd62f39c"
33f356d559Stb 			"265c073de554faa3d6cc12eaf4145fe88e19ab2f2e48e6ac"
34f356d559Stb 			"184378acd037c3bdb2cd2ce647e21ae663b83d2e2f78c44f"
35f356d559Stb 			"dbf40fa4684c55726b951d4e18429578cc373c91e29b652b"
36f356d559Stb 			"29";
37f356d559Stb 
38f356d559Stb const struct print_test {
39f356d559Stb 	const char *desc;
40f356d559Stb 	const char *want;
41f356d559Stb } bn_print_tests[] = {
42f356d559Stb 	{
43f356d559Stb 		.desc = "zero",
44f356d559Stb 		.want = "    mana mana 0\n",
45f356d559Stb 	},
46f356d559Stb 	{
47f356d559Stb 		.desc = "minus one",
48f356d559Stb 		.want = "    mana mana 1 (0x1)\n",
49f356d559Stb 	},
50f356d559Stb 	{
51f356d559Stb 		.desc = "minus one",
52f356d559Stb 		.want = "    mana mana -1 (-0x1)\n",
53f356d559Stb 	},
54f356d559Stb #ifdef _LP64
55f356d559Stb 	{
56f356d559Stb 		.desc = "largest word",
57f356d559Stb 		.want = "    mana mana 18446744073709551615 "
58f356d559Stb 			"(0xffffffffffffffff)\n",
59f356d559Stb 	},
60f356d559Stb 	{
61f356d559Stb 		.desc = "smallest word",
62f356d559Stb 		.want = "    mana mana -18446744073709551615 "
63f356d559Stb 			"(-0xffffffffffffffff)\n",
64f356d559Stb 	},
65f356d559Stb 	{
66f356d559Stb 		.desc = "largest negative non-word",
67f356d559Stb 		.want = "    mana mana (Negative)\n"
68f356d559Stb 			"        01:00:00:00:00:00:00:00:00\n",
69f356d559Stb 	},
70f356d559Stb 	{
71f356d559Stb 		.desc = "smallest positive non-word",
72f356d559Stb 		.want = "    mana mana\n"
73f356d559Stb 			"        01:00:00:00:00:00:00:00:00\n",
74f356d559Stb 	},
75f356d559Stb #else
76f356d559Stb 	{
77f356d559Stb 		.desc = "largest word",
78f356d559Stb 		.want = "    mana mana 4294967295 (0xffffffff)\n",
79f356d559Stb 	},
80f356d559Stb 	{
81f356d559Stb 		.desc = "smallest word",
82f356d559Stb 		.want = "    mana mana -4294967295 (-0xffffffff)\n",
83f356d559Stb 	},
84f356d559Stb 	{
85f356d559Stb 		.desc = "largest negative non-word",
86f356d559Stb 		.want = "    mana mana (Negative)\n"
87f356d559Stb 			"        01:00:00:00:00\n",
88f356d559Stb 	},
89f356d559Stb 	{
90f356d559Stb 		.desc = "smallest positive non-word",
91f356d559Stb 		.want = "    mana mana\n"
92f356d559Stb 			"        01:00:00:00:00\n",
93f356d559Stb 	},
94f356d559Stb #endif
95f356d559Stb 	{
96f356d559Stb 		.desc = "some pubkey",
97f356d559Stb 		.want = "    mana mana\n"
98f356d559Stb 			"        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
99f356d559Stb 			"        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
100f356d559Stb 			"        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
101f356d559Stb 			"        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
102f356d559Stb 			"        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
103f356d559Stb 			"        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n"
104f356d559Stb 			"        3c:91:e2:9b:65:2b:29\n",
105f356d559Stb 	},
106f356d559Stb 	{
107f356d559Stb 		.desc = "negated pubkey",
108f356d559Stb 		.want = "    mana mana (Negative)\n"
109f356d559Stb 			"        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
110f356d559Stb 			"        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
111f356d559Stb 			"        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
112f356d559Stb 			"        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
113f356d559Stb 			"        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
114f356d559Stb 			"        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37:\n"
115f356d559Stb 			"        3c:91:e2:9b:65:2b:29\n",
116f356d559Stb 	},
117f356d559Stb 	{
118f356d559Stb 		.desc = "shifted negated pubkey",
119f356d559Stb 		.want = "    mana mana (Negative)\n"
120f356d559Stb 			"        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
121f356d559Stb 			"        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
122f356d559Stb 			"        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
123f356d559Stb 			"        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
124f356d559Stb 			"        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
125f356d559Stb 			"        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n",
126f356d559Stb 	},
127f356d559Stb 	{
128f356d559Stb 		.desc = "shifted pubkey",
129f356d559Stb 		.want = "    mana mana\n"
130f356d559Stb 			"        04:0d:30:5e:1b:15:9d:03:d0:a1:79:35:b7:3a:3c:\n"
131f356d559Stb 			"        92:7a:ca:15:1c:cd:62:f3:9c:26:5c:07:3d:e5:54:\n"
132f356d559Stb 			"        fa:a3:d6:cc:12:ea:f4:14:5f:e8:8e:19:ab:2f:2e:\n"
133f356d559Stb 			"        48:e6:ac:18:43:78:ac:d0:37:c3:bd:b2:cd:2c:e6:\n"
134f356d559Stb 			"        47:e2:1a:e6:63:b8:3d:2e:2f:78:c4:4f:db:f4:0f:\n"
135f356d559Stb 			"        a4:68:4c:55:72:6b:95:1d:4e:18:42:95:78:cc:37\n",
136f356d559Stb 	},
1370b88608eStb 	{
1380b88608eStb 		.desc = "high bit of first nibble is set",
1390b88608eStb 		.want = "    mana mana\n"
1400b88608eStb 			"        00:80:00:00:00:00:00:00:00:00\n",
1410b88608eStb 	},
142aaea8adaStb 	{
143*6971d2f9Stb 		/* XXX - this is incorrect and should be fixed. */
144aaea8adaStb 		.desc = "high bit of first nibble is set for negative number",
145aaea8adaStb 		.want = "    mana mana (Negative)\n"
146aaea8adaStb 			"        00:80:00:00:00:00:00:00:00:00\n",
147aaea8adaStb 	},
148f356d559Stb };
149f356d559Stb 
150f356d559Stb #define N_TESTCASES	(sizeof(bn_print_tests) / sizeof(bn_print_tests[0]))
151f356d559Stb 
152f356d559Stb static int
bn_print_testcase(const BIGNUM * bn,const struct print_test * test)153f356d559Stb bn_print_testcase(const BIGNUM *bn, const struct print_test *test)
154f356d559Stb {
155f356d559Stb 	BIO *bio;
156f356d559Stb 	char *got;
157f356d559Stb 	size_t want_len;
158f356d559Stb 	long got_len;
159f356d559Stb 	int failed = 1;
160f356d559Stb 
161f356d559Stb 	if ((bio = BIO_new(BIO_s_mem())) == NULL)
162f356d559Stb 		errx(1, "BIO_new");
163f356d559Stb 
164f356d559Stb 	if (!bn_printf(bio, bn, 4, "%s", BATIHDIDIDI))
165f356d559Stb 		errx(1, "bn_printf");
166f356d559Stb 
167f356d559Stb 	if ((got_len = BIO_get_mem_data(bio, &got)) < 0)
168f356d559Stb 		errx(1, "BIO_get_mem_data");
169f356d559Stb 
170f356d559Stb 	if ((want_len = strlen(test->want)) != (size_t)got_len) {
171f356d559Stb 		fprintf(stderr, "%s: want: %zu, got %ld\n",
172f356d559Stb 		    test->desc, want_len, got_len);
173f356d559Stb 		goto err;
174f356d559Stb 	}
175f356d559Stb 
176f356d559Stb 	if (strncmp(got, test->want, want_len) != 0) {
177f356d559Stb 		fprintf(stderr, "%s: strings differ\n", test->desc);
178f356d559Stb 		fprintf(stderr, "want: \"%s\"\ngot : \"%*s\"\n",
179f356d559Stb 		    test->want, (int)got_len, got);
180f356d559Stb 		goto err;
181f356d559Stb 	}
182f356d559Stb 
183f356d559Stb 	failed = 0;
184f356d559Stb  err:
185f356d559Stb 	BIO_free(bio);
186f356d559Stb 
187f356d559Stb 	return failed;
188f356d559Stb }
189f356d559Stb 
190f356d559Stb int
main(void)191f356d559Stb main(void)
192f356d559Stb {
193f356d559Stb 	const struct print_test *test;
194f356d559Stb 	size_t testcase = 0;
195f356d559Stb 	BIGNUM *bn;
196f356d559Stb 	int failed = 0;
197f356d559Stb 
198f356d559Stb 	/* zero */
199f356d559Stb 	if ((bn = BN_new()) == NULL)
200f356d559Stb 		errx(1, "BN_new");
201f356d559Stb 	if (testcase >= N_TESTCASES)
202f356d559Stb 		errx(1, "Too many tests");
203f356d559Stb 	test = &bn_print_tests[testcase++];
204f356d559Stb 	failed |= bn_print_testcase(bn, test);
205f356d559Stb 
206f356d559Stb 	/* one */
207f356d559Stb 	if (!BN_set_word(bn, 1))
208f356d559Stb 		errx(1, "BIO_set_word");
209f356d559Stb 	if (testcase >= N_TESTCASES)
210f356d559Stb 		errx(1, "Too many tests");
211f356d559Stb 	test = &bn_print_tests[testcase++];
212f356d559Stb 	failed |= bn_print_testcase(bn, test);
213f356d559Stb 
214f356d559Stb 	/* minus one */
215f356d559Stb 	BN_set_negative(bn, 1);
216f356d559Stb 	if (testcase >= N_TESTCASES)
217f356d559Stb 		errx(1, "Too many tests");
218f356d559Stb 	test = &bn_print_tests[testcase++];
219f356d559Stb 	failed |= bn_print_testcase(bn, test);
220f356d559Stb 
221f356d559Stb 	/* largest word */
222f356d559Stb 	if (!BN_set_word(bn, ~0))
223f356d559Stb 		errx(1, "BN_set_word");
224f356d559Stb 	if (testcase >= N_TESTCASES)
225f356d559Stb 		errx(1, "Too many tests");
226f356d559Stb 	test = &bn_print_tests[testcase++];
227f356d559Stb 	failed |= bn_print_testcase(bn, test);
228f356d559Stb 
229f356d559Stb 	/* smallest word */
230f356d559Stb 	BN_set_negative(bn, 1);
231f356d559Stb 	if (testcase >= N_TESTCASES)
232f356d559Stb 		errx(1, "Too many tests");
233f356d559Stb 	test = &bn_print_tests[testcase++];
234f356d559Stb 	failed |= bn_print_testcase(bn, test);
235f356d559Stb 
236f356d559Stb 	/* largest negative non-word */
237f356d559Stb 	if (!BN_sub_word(bn, 1))
238f356d559Stb 		errx(1, "ASN1_bn_print");
239f356d559Stb 	if (testcase >= N_TESTCASES)
240f356d559Stb 		errx(1, "Too many tests");
241f356d559Stb 	test = &bn_print_tests[testcase++];
242f356d559Stb 	failed |= bn_print_testcase(bn, test);
243f356d559Stb 
244f356d559Stb 	/* smallest positive non-word */
245f356d559Stb 	BN_set_negative(bn, 0);
246f356d559Stb 	if (testcase >= N_TESTCASES)
247f356d559Stb 		errx(1, "Too many tests");
248f356d559Stb 	test = &bn_print_tests[testcase++];
249f356d559Stb 	failed |= bn_print_testcase(bn, test);
250f356d559Stb 
251f356d559Stb 	/* some pubkey */
252f356d559Stb 	if (BN_hex2bn(&bn, pk) == 0)
253f356d559Stb 		errx(1, "BN_hex2bn");
254f356d559Stb 	if (testcase >= N_TESTCASES)
255f356d559Stb 		errx(1, "Too many tests");
256f356d559Stb 	test = &bn_print_tests[testcase++];
257f356d559Stb 	failed |= bn_print_testcase(bn, test);
258f356d559Stb 
259f356d559Stb 	/* negated pubkey */
260f356d559Stb 	BN_set_negative(bn, 1);
261f356d559Stb 	if (testcase >= N_TESTCASES)
262f356d559Stb 		errx(1, "Too many tests");
263f356d559Stb 	test = &bn_print_tests[testcase++];
264f356d559Stb 	failed |= bn_print_testcase(bn, test);
265f356d559Stb 
266f356d559Stb 	/* shifted negated pubkey */
267f356d559Stb 	if (!BN_rshift(bn, bn, 7 * 8))
268f356d559Stb 		errx(1, "BN_rshift");
269f356d559Stb 	if (testcase >= N_TESTCASES)
270f356d559Stb 		errx(1, "Too many tests");
271f356d559Stb 	test = &bn_print_tests[testcase++];
272f356d559Stb 	failed |= bn_print_testcase(bn, test);
273f356d559Stb 
274f356d559Stb 	/* shifted pubkey */
275f356d559Stb 	BN_set_negative(bn, 0);
276f356d559Stb 	if (testcase >= N_TESTCASES)
277f356d559Stb 		errx(1, "Too many tests");
278f356d559Stb 	test = &bn_print_tests[testcase++];
279f356d559Stb 	failed |= bn_print_testcase(bn, test);
280f356d559Stb 
2810b88608eStb 	/* high bit of first nibble is set. */
2820b88608eStb 	BN_zero(bn);
2830b88608eStb 	if (!BN_set_bit(bn, 71))
2840b88608eStb 		errx(1, "BN_set_bit");
2850b88608eStb 	if (testcase >= N_TESTCASES)
2860b88608eStb 		errx(1, "Too many tests");
2870b88608eStb 	test = &bn_print_tests[testcase++];
2880b88608eStb 	failed |= bn_print_testcase(bn, test);
2890b88608eStb 
290aaea8adaStb 	/* high bit of first nibble is set for negative number. */
291aaea8adaStb 	BN_set_negative(bn, 1);
292aaea8adaStb 	if (testcase >= N_TESTCASES)
293aaea8adaStb 		errx(1, "Too many tests");
294aaea8adaStb 	test = &bn_print_tests[testcase++];
295aaea8adaStb 	failed |= bn_print_testcase(bn, test);
296aaea8adaStb 
297f356d559Stb 	if (testcase != N_TESTCASES) {
298f356d559Stb 		warnx("Not all tests run");
299f356d559Stb 		failed |= 1;
300f356d559Stb 	}
301f356d559Stb 
30269421fdcStb 	BN_free(bn);
30369421fdcStb 
304f356d559Stb 	return failed;
305f356d559Stb }
306