xref: /openbsd-src/regress/lib/libcrypto/bn/bn_convert.c (revision 5b7d9130dd621995378809e175740fcca36ec6d2)
1*5b7d9130Stb /*	$OpenBSD: bn_convert.c,v 1.9 2024/11/05 18:20:08 tb Exp $ */
2703277b6Sjsing /*
3703277b6Sjsing  * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4703277b6Sjsing  *
5703277b6Sjsing  * Permission to use, copy, modify, and distribute this software for any
6703277b6Sjsing  * purpose with or without fee is hereby granted, provided that the above
7703277b6Sjsing  * copyright notice and this permission notice appear in all copies.
8703277b6Sjsing  *
9703277b6Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10703277b6Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11703277b6Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12703277b6Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13703277b6Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14703277b6Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15703277b6Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16703277b6Sjsing  */
17703277b6Sjsing 
18703277b6Sjsing #include <err.h>
19703277b6Sjsing #include <string.h>
20703277b6Sjsing 
21703277b6Sjsing #include <openssl/bn.h>
22703277b6Sjsing 
23703277b6Sjsing /*
24703277b6Sjsing  * Additional test coverage is needed for:
25703277b6Sjsing  *
26703277b6Sjsing  * - BN_print()/BN_print_fp()
27703277b6Sjsing  *
28703277b6Sjsing  * - Invalid inputs to {asc,dec,hex,mpi}2bn
29703277b6Sjsing  * - Zero padded inputs
30703277b6Sjsing  */
31703277b6Sjsing 
32703277b6Sjsing static void
33703277b6Sjsing hexdump(const unsigned char *buf, size_t len)
34703277b6Sjsing {
35703277b6Sjsing 	size_t i;
36703277b6Sjsing 
37703277b6Sjsing 	for (i = 1; i <= len; i++)
38703277b6Sjsing 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
39703277b6Sjsing 
40703277b6Sjsing 	fprintf(stderr, "\n");
41703277b6Sjsing }
42703277b6Sjsing 
43703277b6Sjsing static int
44703277b6Sjsing check_bin_output(size_t test_no, const char *label, const uint8_t *bin,
45703277b6Sjsing     size_t bin_len, const BIGNUM *bn)
46703277b6Sjsing {
47703277b6Sjsing 	uint8_t *out = NULL;
48703277b6Sjsing 	int out_len;
49703277b6Sjsing 	int ret;
50703277b6Sjsing 	int failed = 1;
51703277b6Sjsing 
52703277b6Sjsing 	out_len = BN_num_bytes(bn);
53703277b6Sjsing 	if (out_len != (int)bin_len) {
548a60fc3bSjsing 		fprintf(stderr, "FAIL: Test %zu %s - BN_num_bytes() = %d, "
558a60fc3bSjsing 		    "want %zu\n", test_no, label, out_len, bin_len);
56703277b6Sjsing 		goto failure;
57703277b6Sjsing 	}
58*5b7d9130Stb 	if (out_len > 0 && (out = malloc(out_len)) == NULL)
59703277b6Sjsing 		err(1, "malloc");
60703277b6Sjsing 	if ((ret = BN_bn2bin(bn, out)) != out_len) {
618a60fc3bSjsing 		fprintf(stderr, "FAIL: Test %zu %s - BN_bn2bin() returned %d, "
628a60fc3bSjsing 		    "want %d\n", test_no, label, ret, out_len);
63703277b6Sjsing 		goto failure;
64703277b6Sjsing 	}
65703277b6Sjsing 	if (memcmp(out, bin, bin_len) != 0) {
668a60fc3bSjsing 		fprintf(stderr, "FAIL: Test %zu %s - output from "
678a60fc3bSjsing 		    "BN_bn2bin() differs\n", test_no, label);
68703277b6Sjsing 		fprintf(stderr, "Got:\n");
69703277b6Sjsing 		hexdump(out, out_len);
70703277b6Sjsing 		fprintf(stderr, "Want:\n");
71703277b6Sjsing 		hexdump(bin, bin_len);
72703277b6Sjsing 		goto failure;
73703277b6Sjsing 	}
74703277b6Sjsing 
75703277b6Sjsing 	failed = 0;
76703277b6Sjsing 
77703277b6Sjsing  failure:
78703277b6Sjsing 	free(out);
79703277b6Sjsing 
80703277b6Sjsing 	return failed;
81703277b6Sjsing }
82703277b6Sjsing 
83703277b6Sjsing struct bn_asc2bn_test {
84703277b6Sjsing 	const char *in;
85703277b6Sjsing 	const uint8_t bin[64];
86703277b6Sjsing 	size_t bin_len;
87703277b6Sjsing 	int neg;
88703277b6Sjsing 	int want_error;
89703277b6Sjsing };
90703277b6Sjsing 
91703277b6Sjsing static const struct bn_asc2bn_test bn_asc2bn_tests[] = {
92703277b6Sjsing 	{
93703277b6Sjsing 		.in = "",
94703277b6Sjsing 		.want_error = 1,
95703277b6Sjsing 	},
96703277b6Sjsing 	{
97703277b6Sjsing 		.in = "-",
98703277b6Sjsing 		.want_error = 1,
99703277b6Sjsing 	},
100703277b6Sjsing 	{
101703277b6Sjsing 		.in = "0",
102703277b6Sjsing 		.bin = { 0x00, },
103703277b6Sjsing 		.bin_len = 0,
104703277b6Sjsing 		.neg = 0,
105703277b6Sjsing 	},
106703277b6Sjsing 	{
107703277b6Sjsing 		.in = "0x0",
108703277b6Sjsing 		.bin = { 0x00, },
109703277b6Sjsing 		.bin_len = 0,
110703277b6Sjsing 		.neg = 0,
111703277b6Sjsing 	},
112703277b6Sjsing 	{
113703277b6Sjsing 		.in = "-0",
114703277b6Sjsing 		.bin = { 0x00, },
115703277b6Sjsing 		.bin_len = 0,
116703277b6Sjsing 		.neg = 0,
117703277b6Sjsing 	},
118703277b6Sjsing 	{
119703277b6Sjsing 		.in = "-0x0",
120703277b6Sjsing 		.bin = { 0x00, },
121703277b6Sjsing 		.bin_len = 0,
122703277b6Sjsing 		.neg = 0,
123703277b6Sjsing 	},
124703277b6Sjsing 	{
125703277b6Sjsing 		.in = "123456789",
126703277b6Sjsing 		.bin = { 0x07, 0x5b, 0xcd, 0x15, },
127703277b6Sjsing 		.bin_len = 4,
128703277b6Sjsing 		.neg = 0,
129703277b6Sjsing 	},
130703277b6Sjsing 	{
131703277b6Sjsing 		.in = "0123456789",
132703277b6Sjsing 		.bin = { 0x07, 0x5b, 0xcd, 0x15, },
133703277b6Sjsing 		.bin_len = 4,
134703277b6Sjsing 		.neg = 0,
135703277b6Sjsing 	},
136703277b6Sjsing 	{
137703277b6Sjsing 		.in = "-123456789",
138703277b6Sjsing 		.bin = { 0x07, 0x5b, 0xcd, 0x15, },
139703277b6Sjsing 		.bin_len = 4,
140703277b6Sjsing 		.neg = 1,
141703277b6Sjsing 	},
142703277b6Sjsing 	{
143703277b6Sjsing 		.in = "0X123456789",
144703277b6Sjsing 		.bin = { 0x01, 0x23, 0x45, 0x67, 0x89, },
145703277b6Sjsing 		.bin_len = 5,
146703277b6Sjsing 		.neg = 0,
147703277b6Sjsing 	},
148703277b6Sjsing 	{
149703277b6Sjsing 		.in = "0x123456789",
150703277b6Sjsing 		.bin = { 0x01, 0x23, 0x45, 0x67, 0x89, },
151703277b6Sjsing 		.bin_len = 5,
152703277b6Sjsing 		.neg = 0,
153703277b6Sjsing 	},
154703277b6Sjsing 	{
155703277b6Sjsing 		.in = "-0x123456789",
156703277b6Sjsing 		.bin = { 0x01, 0x23, 0x45, 0x67, 0x89, },
157703277b6Sjsing 		.bin_len = 5,
158703277b6Sjsing 		.neg = 1,
159703277b6Sjsing 	},
160703277b6Sjsing 	{
161703277b6Sjsing 		.in = "abcdef123456789",
162703277b6Sjsing 		.want_error = 1,
163703277b6Sjsing 	},
164703277b6Sjsing 	{
165703277b6Sjsing 		.in = "0x000123456789abCdEf",
166703277b6Sjsing 		.bin = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
167703277b6Sjsing 		.bin_len = 8,
168703277b6Sjsing 		.neg = 0,
169703277b6Sjsing 	},
170703277b6Sjsing };
171703277b6Sjsing 
172703277b6Sjsing #define N_BN_ASC2BN_TESTS \
173703277b6Sjsing     (sizeof(bn_asc2bn_tests) / sizeof(*bn_asc2bn_tests))
174703277b6Sjsing 
175703277b6Sjsing static int
176703277b6Sjsing test_bn_asc2bn(void)
177703277b6Sjsing {
178703277b6Sjsing 	const struct bn_asc2bn_test *bat;
179703277b6Sjsing 	BIGNUM *bn = NULL;
180703277b6Sjsing 	size_t i;
181703277b6Sjsing 	int failed = 1;
182703277b6Sjsing 
183703277b6Sjsing 	for (i = 0; i < N_BN_ASC2BN_TESTS; i++) {
184703277b6Sjsing 		bat = &bn_asc2bn_tests[i];
185703277b6Sjsing 
186703277b6Sjsing 		BN_free(bn);
187703277b6Sjsing 		bn = NULL;
188703277b6Sjsing 
189703277b6Sjsing 		if (!BN_asc2bn(&bn, bat->in)) {
190703277b6Sjsing 			if (bat->want_error)
191703277b6Sjsing 				continue;
192703277b6Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() failed\n", i);
193703277b6Sjsing 			goto failure;
194703277b6Sjsing 		}
195703277b6Sjsing 		if (bat->want_error) {
196703277b6Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() succeeded "
197703277b6Sjsing 			    "when it should have failed\n", i);
198703277b6Sjsing 			goto failure;
199703277b6Sjsing 		}
200703277b6Sjsing 
201703277b6Sjsing 		if (check_bin_output(i, "BN_asc2bn()", bat->bin, bat->bin_len,
202703277b6Sjsing 		    bn) != 0)
203703277b6Sjsing 			goto failure;
204703277b6Sjsing 
205703277b6Sjsing 		if (BN_is_negative(bn) != bat->neg) {
206703277b6Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_asc2bn() resulted "
207703277b6Sjsing 			    "in negative %d, want %d", i, BN_is_negative(bn),
208703277b6Sjsing 			    bat->neg);
209703277b6Sjsing 			goto failure;
210703277b6Sjsing 		}
211703277b6Sjsing 	}
212703277b6Sjsing 
2136230b673Stb 	/*
2146230b673Stb 	 * While it makes little sense to call BN_asc2bn() with a NULL bn,
2156230b673Stb 	 * check for consistent behavior.
2166230b673Stb 	 */
2176230b673Stb 	if (!BN_asc2bn(NULL, "1") || !BN_asc2bn(NULL, "-1") ||
2186230b673Stb 	    !BN_asc2bn(NULL, "0x1") || !BN_asc2bn(NULL, "-0x1")) {
2196230b673Stb 		fprintf(stderr, "FAIL: BN_asc2bn() with NULL BIGNUM failed\n");
2206230b673Stb 		goto failure;
2216230b673Stb 	}
2226230b673Stb 
223703277b6Sjsing 	failed = 0;
224703277b6Sjsing 
225703277b6Sjsing  failure:
226703277b6Sjsing 	BN_free(bn);
227703277b6Sjsing 
228703277b6Sjsing 	return failed;
229703277b6Sjsing }
230703277b6Sjsing 
231703277b6Sjsing struct bn_convert_test {
232703277b6Sjsing 	const uint8_t bin[64];
233703277b6Sjsing 	size_t bin_len;
234703277b6Sjsing 	int neg;
235703277b6Sjsing 	const char *dec;
236703277b6Sjsing 	const char *hex;
23771299374Sjsing 	const uint8_t mpi[64];
23871299374Sjsing 	int mpi_len;
239703277b6Sjsing };
240703277b6Sjsing 
241703277b6Sjsing static const struct bn_convert_test bn_convert_tests[] = {
242703277b6Sjsing 	{
243703277b6Sjsing 		.bin = { 0x0, },
244703277b6Sjsing 		.bin_len = 0,
245703277b6Sjsing 		.neg = 0,
246703277b6Sjsing 		.dec = "0",
247703277b6Sjsing 		.hex = "0",
24871299374Sjsing 		.mpi = { 0x00, 0x00, 0x00, 0x00, },
24971299374Sjsing 		.mpi_len = 4,
250703277b6Sjsing 	},
251703277b6Sjsing 	{
252703277b6Sjsing 		.bin = { 0x1, },
253703277b6Sjsing 		.bin_len = 1,
254703277b6Sjsing 		.neg = 0,
255703277b6Sjsing 		.dec = "1",
256703277b6Sjsing 		.hex = "01",
25771299374Sjsing 		.mpi = { 0x00, 0x00, 0x00, 0x01, 0x01, },
25871299374Sjsing 		.mpi_len = 5,
25971299374Sjsing 	},
26071299374Sjsing 	{
26171299374Sjsing 		.bin = { 0x1, },
26271299374Sjsing 		.bin_len = 1,
26371299374Sjsing 		.neg = 1,
26471299374Sjsing 		.dec = "-1",
26571299374Sjsing 		.hex = "-01",
26671299374Sjsing 		.mpi = { 0x00, 0x00, 0x00, 0x01, 0x81, },
26771299374Sjsing 		.mpi_len = 5,
268703277b6Sjsing 	},
269703277b6Sjsing 	{
270703277b6Sjsing 		.bin = { 0x7f, 0xff, 0xff, },
271703277b6Sjsing 		.bin_len = 3,
272703277b6Sjsing 		.neg = 0,
273703277b6Sjsing 		.dec = "8388607",
274703277b6Sjsing 		.hex = "7FFFFF",
275cdb6ef61Sjsing 		.mpi = { 0x00, 0x00, 0x00, 0x03, 0x7f, 0xff, 0xff, },
27671299374Sjsing 		.mpi_len = 7,
277703277b6Sjsing 	},
278703277b6Sjsing 	{
279703277b6Sjsing 		.bin = { 0x7f, 0xff, 0xff, },
280703277b6Sjsing 		.bin_len = 3,
281703277b6Sjsing 		.neg = 1,
282703277b6Sjsing 		.dec = "-8388607",
283703277b6Sjsing 		.hex = "-7FFFFF",
284cdb6ef61Sjsing 		.mpi = { 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, },
28571299374Sjsing 		.mpi_len = 7,
286703277b6Sjsing 	},
287703277b6Sjsing 	{
288cdb6ef61Sjsing 		.bin = { 0x01, 0x02, 0x03, 0x04, },
289cdb6ef61Sjsing 		.bin_len = 4,
290cdb6ef61Sjsing 		.neg = 0,
291cdb6ef61Sjsing 		.dec = "16909060",
292cdb6ef61Sjsing 		.hex = "01020304",
293cdb6ef61Sjsing 		.mpi = { 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, },
294cdb6ef61Sjsing 		.mpi_len = 8,
295cdb6ef61Sjsing 	},
296cdb6ef61Sjsing 	{
297cdb6ef61Sjsing 		.bin = { 0x04, 0x03, 0x02, 0x01, },
298cdb6ef61Sjsing 		.bin_len = 4,
299cdb6ef61Sjsing 		.neg = 0,
300cdb6ef61Sjsing 		.dec = "67305985",
301cdb6ef61Sjsing 		.hex = "04030201",
302cdb6ef61Sjsing 		.mpi = { 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x02, 0x01, },
303cdb6ef61Sjsing 		.mpi_len = 8,
304cdb6ef61Sjsing 	},
305cdb6ef61Sjsing 	{
306703277b6Sjsing 		.bin = { 0xff, 0xff, 0xff, 0xff, },
307703277b6Sjsing 		.bin_len = 4,
308703277b6Sjsing 		.neg = 0,
309703277b6Sjsing 		.dec = "4294967295",
310703277b6Sjsing 		.hex = "FFFFFFFF",
31171299374Sjsing 		.mpi = {
31271299374Sjsing 			0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0xff,
31371299374Sjsing 			0xff,
31471299374Sjsing 		 },
31571299374Sjsing 		.mpi_len = 9,
316703277b6Sjsing 	},
317703277b6Sjsing 	{
318703277b6Sjsing 		.bin = { 0xff, 0xff, 0xff, 0xff, },
319703277b6Sjsing 		.bin_len = 4,
320703277b6Sjsing 		.neg = 1,
321703277b6Sjsing 		.dec = "-4294967295",
322703277b6Sjsing 		.hex = "-FFFFFFFF",
32371299374Sjsing 		.mpi = {
32471299374Sjsing 			0x00, 0x00, 0x00, 0x05, 0x80, 0xff, 0xff, 0xff,
32571299374Sjsing 			0xff,
32671299374Sjsing 		 },
32771299374Sjsing 		.mpi_len = 9,
328703277b6Sjsing 	},
329703277b6Sjsing 	{
330703277b6Sjsing 		.bin = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
331703277b6Sjsing 		.bin_len = 8,
332703277b6Sjsing 		.neg = 0,
333703277b6Sjsing 		.dec = "18446744069414584320",
334703277b6Sjsing 		.hex = "FFFFFFFF00000000",
33571299374Sjsing 		.mpi = {
33671299374Sjsing 			0x00, 0x00, 0x00, 0x09, 0x00, 0xff, 0xff, 0xff,
33771299374Sjsing 			0xff, 0x00, 0x00, 0x00, 0x00,
33871299374Sjsing 		 },
33971299374Sjsing 		.mpi_len = 13,
340703277b6Sjsing 	},
341703277b6Sjsing 	{
342703277b6Sjsing 		.bin = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
343703277b6Sjsing 		.bin_len = 8,
344703277b6Sjsing 		.neg = 1,
345703277b6Sjsing 		.dec = "-18446744069414584320",
346703277b6Sjsing 		.hex = "-FFFFFFFF00000000",
34771299374Sjsing 		.mpi = {
34871299374Sjsing 			0x00, 0x00, 0x00, 0x09, 0x80, 0xff, 0xff, 0xff,
34971299374Sjsing 			0xff, 0x00, 0x00, 0x00, 0x00,
35071299374Sjsing 		 },
35171299374Sjsing 		.mpi_len = 13,
352703277b6Sjsing 	},
353703277b6Sjsing 	{
354703277b6Sjsing 		.bin = { 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, },
355703277b6Sjsing 		.bin_len = 8,
356703277b6Sjsing 		.neg = 0,
357703277b6Sjsing 		.dec = "9223794255762391041",
358703277b6Sjsing 		.hex = "8001800180018001",
35971299374Sjsing 		.mpi = {
36071299374Sjsing 			0x00, 0x00, 0x00, 0x09, 0x00, 0x80, 0x01, 0x80,
36171299374Sjsing 			0x01, 0x80, 0x01, 0x80, 0x01,
36271299374Sjsing 		 },
36371299374Sjsing 		.mpi_len = 13,
364703277b6Sjsing 	},
365703277b6Sjsing 	{
366703277b6Sjsing 		.bin = { 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, },
367703277b6Sjsing 		.bin_len = 8,
368703277b6Sjsing 		.neg = 1,
369703277b6Sjsing 		.dec = "-9223794255762391041",
370703277b6Sjsing 		.hex = "-8001800180018001",
37171299374Sjsing 		.mpi = {
37271299374Sjsing 			0x00, 0x00, 0x00, 0x09, 0x80, 0x80, 0x01, 0x80,
37371299374Sjsing 			0x01, 0x80, 0x01, 0x80, 0x01,
37471299374Sjsing 		 },
37571299374Sjsing 		.mpi_len = 13,
376703277b6Sjsing 	},
377703277b6Sjsing 	{
37871299374Sjsing 		.bin = {
37971299374Sjsing 			0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
38071299374Sjsing 			0x01,
38171299374Sjsing 		},
382703277b6Sjsing 		.bin_len = 9,
383703277b6Sjsing 		.neg = 0,
384703277b6Sjsing 		.dec = "27670538329471942657",
385703277b6Sjsing 		.hex = "018001800180018001",
38671299374Sjsing 		.mpi = {
38771299374Sjsing 			0x00, 0x00, 0x00, 0x09, 0x01, 0x80, 0x01, 0x80,
38871299374Sjsing 			0x01, 0x80, 0x01, 0x80, 0x01,
38971299374Sjsing 		 },
39071299374Sjsing 		.mpi_len = 13,
391703277b6Sjsing 	},
392703277b6Sjsing 	{
39371299374Sjsing 		.bin = {
39471299374Sjsing 			0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
39571299374Sjsing 			0x01,
39671299374Sjsing 		},
397703277b6Sjsing 		.bin_len = 9,
398703277b6Sjsing 		.neg = 1,
399703277b6Sjsing 		.dec = "-27670538329471942657",
400703277b6Sjsing 		.hex = "-018001800180018001",
40171299374Sjsing 		.mpi = {
40271299374Sjsing 			0x00, 0x00, 0x00, 0x09, 0x81, 0x80, 0x01, 0x80,
40371299374Sjsing 			0x01, 0x80, 0x01, 0x80, 0x01,
40471299374Sjsing 		 },
40571299374Sjsing 		.mpi_len = 13,
406703277b6Sjsing 	},
407703277b6Sjsing 	{
408703277b6Sjsing 		.bin = {
409703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
410703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
411703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
412703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
413703277b6Sjsing 		},
414703277b6Sjsing 		.bin_len = 32,
415703277b6Sjsing 		.neg = 0,
416703277b6Sjsing 		.dec = "57895161181645529494837117048595051142566530671229791132691030063130991362047",
417703277b6Sjsing 		.hex = "7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF",
41871299374Sjsing 		.mpi = {
41971299374Sjsing 			0x00, 0x00, 0x00, 0x20, 0x7f, 0xff, 0x7f, 0xff,
42071299374Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
42171299374Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
42271299374Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
42371299374Sjsing 			0x7f, 0xff, 0x7f, 0xff,
42471299374Sjsing 		 },
42571299374Sjsing 		.mpi_len = 36,
426703277b6Sjsing 	},
427703277b6Sjsing 	{
428703277b6Sjsing 		.bin = {
429703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
430703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
431703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
432703277b6Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
433703277b6Sjsing 		},
434703277b6Sjsing 		.bin_len = 32,
435703277b6Sjsing 		.neg = 1,
436703277b6Sjsing 		.dec = "-57895161181645529494837117048595051142566530671229791132691030063130991362047",
437703277b6Sjsing 		.hex = "-7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF",
43871299374Sjsing 		.mpi = {
43971299374Sjsing 			0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0x7f, 0xff,
44071299374Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
44171299374Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
44271299374Sjsing 			0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff,
44371299374Sjsing 			0x7f, 0xff, 0x7f, 0xff,
44471299374Sjsing 		 },
44571299374Sjsing 		.mpi_len = 36,
446703277b6Sjsing 	},
447703277b6Sjsing };
448703277b6Sjsing 
449703277b6Sjsing #define N_BN_CONVERT_TESTS \
450703277b6Sjsing     (sizeof(bn_convert_tests) / sizeof(*bn_convert_tests))
451703277b6Sjsing 
452703277b6Sjsing static int
453703277b6Sjsing test_bn_convert(void)
454703277b6Sjsing {
455703277b6Sjsing 	const struct bn_convert_test *bct;
45671299374Sjsing 	uint8_t *mpi_out = NULL;
457703277b6Sjsing 	char *out_str = NULL;
4587c149611Sjsing 	uint8_t lebin[64];
459703277b6Sjsing 	BIGNUM *bn = NULL;
46071299374Sjsing 	int mpi_len;
4617c149611Sjsing 	size_t i, j;
462703277b6Sjsing 	int failed = 1;
463703277b6Sjsing 
464703277b6Sjsing 	for (i = 0; i < N_BN_CONVERT_TESTS; i++) {
465703277b6Sjsing 		bct = &bn_convert_tests[i];
466703277b6Sjsing 
467703277b6Sjsing 		BN_free(bn);
468703277b6Sjsing 		if ((bn = BN_bin2bn(bct->bin, bct->bin_len, NULL)) == NULL) {
469703277b6Sjsing 			fprintf(stderr, "FAIL: BN_bin2bn() failed\n");
470703277b6Sjsing 			goto failure;
471703277b6Sjsing 		}
472703277b6Sjsing 		BN_set_negative(bn, bct->neg);
473703277b6Sjsing 
474703277b6Sjsing 		if (check_bin_output(i, "BN_bin2bn()", bct->bin, bct->bin_len,
475703277b6Sjsing 		    bn) != 0)
476703277b6Sjsing 			goto failure;
477703277b6Sjsing 
4787c149611Sjsing 		for (j = 0; j < bct->bin_len; j++)
4797c149611Sjsing 			lebin[j] = bct->bin[bct->bin_len - j - 1];
4807c149611Sjsing 
4817c149611Sjsing 		BN_free(bn);
4827c149611Sjsing 		if ((bn = BN_lebin2bn(lebin, bct->bin_len, NULL)) == NULL) {
4837c149611Sjsing 			fprintf(stderr, "FAIL: BN_lebin2bn() failed\n");
4847c149611Sjsing 			goto failure;
4857c149611Sjsing 		}
4867c149611Sjsing 		BN_set_negative(bn, bct->neg);
4877c149611Sjsing 
4887c149611Sjsing 		if (check_bin_output(i, "BN_lebin2bn()", bct->bin, bct->bin_len,
4897c149611Sjsing 		    bn) != 0)
4907c149611Sjsing 			goto failure;
4917c149611Sjsing 
492703277b6Sjsing 		free(out_str);
493703277b6Sjsing 		if ((out_str = BN_bn2dec(bn)) == NULL) {
494703277b6Sjsing 			fprintf(stderr, "FAIL: BN_bn2dec() failed\n");
495703277b6Sjsing 			goto failure;
496703277b6Sjsing 		}
497703277b6Sjsing 		if (strcmp(out_str, bct->dec) != 0) {
498703277b6Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_bn2dec() returned "
499703277b6Sjsing 			    "'%s', want '%s'", i, out_str, bct->dec);
500703277b6Sjsing 			goto failure;
501703277b6Sjsing 		}
502703277b6Sjsing 
503703277b6Sjsing 		free(out_str);
504703277b6Sjsing 		if ((out_str = BN_bn2hex(bn)) == NULL) {
505703277b6Sjsing 			fprintf(stderr, "FAIL: BN_bn2hex() failed\n");
506703277b6Sjsing 			goto failure;
507703277b6Sjsing 		}
508703277b6Sjsing 		if (strcmp(out_str, bct->hex) != 0) {
509703277b6Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_bn2hex() returned "
510703277b6Sjsing 			    "'%s', want '%s'", i, out_str, bct->hex);
511703277b6Sjsing 			goto failure;
512703277b6Sjsing 		}
513703277b6Sjsing 
51471299374Sjsing 		free(mpi_out);
5154086bd76Stb 		mpi_out = NULL;
51671299374Sjsing 
51771299374Sjsing 		if ((mpi_len = BN_bn2mpi(bn, NULL)) != bct->mpi_len) {
51871299374Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_bn2mpi() returned "
51971299374Sjsing 			    "%d, want %d", i, mpi_len, bct->mpi_len);
52071299374Sjsing 			goto failure;
52171299374Sjsing 		}
52271299374Sjsing 		if ((mpi_out = calloc(1, bct->mpi_len)) == NULL)
52371299374Sjsing 			goto failure;
52471299374Sjsing 		if ((mpi_len = BN_bn2mpi(bn, mpi_out)) != bct->mpi_len) {
52571299374Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_bn2mpi() returned "
52671299374Sjsing 			    "%d, want %d", i, mpi_len, bct->mpi_len);
52771299374Sjsing 			goto failure;
52871299374Sjsing 		}
52971299374Sjsing 		if (memcmp(mpi_out, bct->mpi, bct->mpi_len) != 0) {
53071299374Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_bn2mpi() "
53171299374Sjsing 			    "generated:\n", i);
53271299374Sjsing 			hexdump(mpi_out, bct->mpi_len);
53371299374Sjsing 			fprintf(stderr, "Want:\n");
53471299374Sjsing 			hexdump(bct->mpi, bct->mpi_len);
53571299374Sjsing 			goto failure;
53671299374Sjsing 		}
53771299374Sjsing 
538703277b6Sjsing 		if (BN_dec2bn(&bn, bct->dec) != (int)strlen(bct->dec)) {
539703277b6Sjsing 			fprintf(stderr, "FAIL: BN_dec2bn() failed\n");
540703277b6Sjsing 			goto failure;
541703277b6Sjsing 		}
542703277b6Sjsing 		if (BN_is_negative(bn) != bct->neg) {
543703277b6Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_dec2bn() resulted "
544703277b6Sjsing 			    "in negative %d, want %d", i, BN_is_negative(bn),
545703277b6Sjsing 			    bct->neg);
546703277b6Sjsing 			goto failure;
547703277b6Sjsing 		}
548703277b6Sjsing 		if (check_bin_output(i, "BN_dec2bn()", bct->bin, bct->bin_len,
549703277b6Sjsing 		    bn) != 0)
550703277b6Sjsing 			goto failure;
551703277b6Sjsing 
552703277b6Sjsing 		if (BN_hex2bn(&bn, bct->hex) != (int)strlen(bct->hex)) {
553703277b6Sjsing 			fprintf(stderr, "FAIL: BN_hex2bn() failed\n");
554703277b6Sjsing 			goto failure;
555703277b6Sjsing 		}
556703277b6Sjsing 		if (BN_is_negative(bn) != bct->neg) {
557703277b6Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_hex2bn() resulted "
558703277b6Sjsing 			    "in negative %d, want %d", i, BN_is_negative(bn),
559703277b6Sjsing 			    bct->neg);
560703277b6Sjsing 			goto failure;
561703277b6Sjsing 		}
562703277b6Sjsing 		if (check_bin_output(i, "BN_hex2bn()", bct->bin, bct->bin_len,
563703277b6Sjsing 		    bn) != 0)
564703277b6Sjsing 			goto failure;
56571299374Sjsing 
56671299374Sjsing 		if (BN_mpi2bn(bct->mpi, bct->mpi_len, bn) == NULL) {
56771299374Sjsing 			fprintf(stderr, "FAIL: BN_mpi2bn() failed\n");
56871299374Sjsing 			goto failure;
56971299374Sjsing 		}
57071299374Sjsing 		if (BN_is_negative(bn) != bct->neg) {
57171299374Sjsing 			fprintf(stderr, "FAIL: Test %zu - BN_mpi2bn() resulted "
57271299374Sjsing 			    "in negative %d, want %d", i, BN_is_negative(bn),
57371299374Sjsing 			    bct->neg);
57471299374Sjsing 			goto failure;
57571299374Sjsing 		}
57671299374Sjsing 		if (check_bin_output(i, "BN_mpi2bn()", bct->bin, bct->bin_len,
57771299374Sjsing 		    bn) != 0)
57871299374Sjsing 			goto failure;
579703277b6Sjsing 	}
580703277b6Sjsing 
581703277b6Sjsing 	failed = 0;
582703277b6Sjsing 
583703277b6Sjsing  failure:
5844086bd76Stb 	free(mpi_out);
585703277b6Sjsing 	free(out_str);
586703277b6Sjsing 	BN_free(bn);
587703277b6Sjsing 
588703277b6Sjsing 	return failed;
589703277b6Sjsing }
590703277b6Sjsing 
591703277b6Sjsing static int
592703277b6Sjsing test_bn_dec2bn(void)
593703277b6Sjsing {
594703277b6Sjsing 	BIGNUM *bn = NULL;
595703277b6Sjsing 	BN_ULONG w;
596703277b6Sjsing 	int ret;
597703277b6Sjsing 	int failed = 1;
598703277b6Sjsing 
5998a60fc3bSjsing 	/* An empty string fails to parse, as does NULL. */
600703277b6Sjsing 	if (BN_dec2bn(&bn, "") != 0) {
601703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"\") succeeded\n");
602703277b6Sjsing 		goto failure;
603703277b6Sjsing 	}
604703277b6Sjsing 	if (bn != NULL) {
605703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"\") succeeded\n");
606703277b6Sjsing 		goto failure;
607703277b6Sjsing 	}
6088a60fc3bSjsing 	if (BN_dec2bn(&bn, NULL) != 0) {
6098a60fc3bSjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, NULL) succeeded\n");
6108a60fc3bSjsing 		goto failure;
6118a60fc3bSjsing 	}
6128a60fc3bSjsing 	if (bn != NULL) {
6138a60fc3bSjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, NULL) succeeded\n");
6148a60fc3bSjsing 		goto failure;
6158a60fc3bSjsing 	}
616703277b6Sjsing 
617703277b6Sjsing 	/* A minus sign parses as 0. */
618703277b6Sjsing 	if (BN_dec2bn(&bn, "-") != 1) {
619703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") failed\n");
620703277b6Sjsing 		goto failure;
621703277b6Sjsing 	}
622703277b6Sjsing 	if (bn == NULL) {
623703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") failed\n");
624703277b6Sjsing 		goto failure;
625703277b6Sjsing 	}
626703277b6Sjsing 	if (!BN_is_zero(bn)) {
627703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") is non-zero\n");
628703277b6Sjsing 		goto failure;
629703277b6Sjsing 	}
630703277b6Sjsing 	if (BN_is_negative(bn)) {
631703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"-\") resulted in "
632703277b6Sjsing 		    "negative zero\n");
633703277b6Sjsing 		goto failure;
634703277b6Sjsing 	}
635703277b6Sjsing 
636703277b6Sjsing 	/* Ensure that -0 results in 0. */
637703277b6Sjsing 	if (BN_dec2bn(&bn, "-0") != 2) {
638703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") failed\n");
639703277b6Sjsing 		goto failure;
640703277b6Sjsing 	}
641703277b6Sjsing 	if (!BN_is_zero(bn)) {
642703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") is non-zero\n");
643703277b6Sjsing 		goto failure;
644703277b6Sjsing 	}
645703277b6Sjsing 	if (BN_is_negative(bn)) {
646703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn(_, \"-0\") resulted in "
647703277b6Sjsing 		    "negative zero\n");
648703277b6Sjsing 		goto failure;
649703277b6Sjsing 	}
650703277b6Sjsing 
651703277b6Sjsing 	/* BN_dec2bn() is the new atoi()... */
652703277b6Sjsing 	if ((ret = BN_dec2bn(&bn, "0123456789abcdef")) != 10) {
653703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn() returned %d, want 10\n", ret);
654703277b6Sjsing 		goto failure;
655703277b6Sjsing 	}
656703277b6Sjsing 	if ((w = BN_get_word(bn)) != 0x75bcd15) {
657703277b6Sjsing 		fprintf(stderr, "FAIL: BN_dec2bn() resulted in %llx, want %llx\n",
658703277b6Sjsing 		    (unsigned long long)w, 0x75bcd15ULL);
659703277b6Sjsing 		goto failure;
660703277b6Sjsing 	}
661703277b6Sjsing 
6628a60fc3bSjsing 	/* And we can call BN_dec2bn() without actually converting to a BIGNUM. */
6638a60fc3bSjsing 	if ((ret = BN_dec2bn(NULL, "0123456789abcdef")) != 10) {
6648a60fc3bSjsing 		fprintf(stderr, "FAIL: BN_dec2bn() returned %d, want 10\n", ret);
6658a60fc3bSjsing 		goto failure;
6668a60fc3bSjsing 	}
6678a60fc3bSjsing 
668703277b6Sjsing 	failed = 0;
669703277b6Sjsing 
670703277b6Sjsing  failure:
671703277b6Sjsing 	BN_free(bn);
672703277b6Sjsing 
673703277b6Sjsing 	return failed;
674703277b6Sjsing }
675703277b6Sjsing 
676703277b6Sjsing static int
677703277b6Sjsing test_bn_hex2bn(void)
678703277b6Sjsing {
679703277b6Sjsing 	BIGNUM *bn = NULL;
680703277b6Sjsing 	BN_ULONG w;
681703277b6Sjsing 	int ret;
682703277b6Sjsing 	int failed = 1;
683703277b6Sjsing 
6848a60fc3bSjsing 	/* An empty string fails to parse, as does NULL. */
685703277b6Sjsing 	if (BN_hex2bn(&bn, "") != 0) {
686703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"\") succeeded\n");
687703277b6Sjsing 		goto failure;
688703277b6Sjsing 	}
689703277b6Sjsing 	if (bn != NULL) {
690703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"\") succeeded\n");
691703277b6Sjsing 		goto failure;
692703277b6Sjsing 	}
6938a60fc3bSjsing 	if (BN_hex2bn(&bn, NULL) != 0) {
6948a60fc3bSjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, NULL) succeeded\n");
6958a60fc3bSjsing 		goto failure;
6968a60fc3bSjsing 	}
6978a60fc3bSjsing 	if (bn != NULL) {
6988a60fc3bSjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, NULL) succeeded\n");
6998a60fc3bSjsing 		goto failure;
7008a60fc3bSjsing 	}
701703277b6Sjsing 
702703277b6Sjsing 	/* A minus sign parses as 0. */
703703277b6Sjsing 	if (BN_hex2bn(&bn, "-") != 1) {
704703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") failed\n");
705703277b6Sjsing 		goto failure;
706703277b6Sjsing 	}
707703277b6Sjsing 	if (bn == NULL) {
708703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") failed\n");
709703277b6Sjsing 		goto failure;
710703277b6Sjsing 	}
711703277b6Sjsing 	if (!BN_is_zero(bn)) {
712703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") returned non-zero\n");
713703277b6Sjsing 		goto failure;
714703277b6Sjsing 	}
715703277b6Sjsing 	if (BN_is_negative(bn)) {
716703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"-\") returned negative zero\n");
717703277b6Sjsing 		goto failure;
718703277b6Sjsing 	}
719703277b6Sjsing 
720703277b6Sjsing 	/* Ensure that -0 results in 0. */
721703277b6Sjsing 	if (BN_hex2bn(&bn, "-0") != 2) {
722703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") failed\n");
723703277b6Sjsing 		goto failure;
724703277b6Sjsing 	}
725703277b6Sjsing 	if (!BN_is_zero(bn)) {
726703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") is non-zero\n");
727703277b6Sjsing 		goto failure;
728703277b6Sjsing 	}
729703277b6Sjsing 	if (BN_is_negative(bn)) {
730703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn(_, \"-0\") resulted in "
731703277b6Sjsing 		    "negative zero\n");
732703277b6Sjsing 		goto failure;
733703277b6Sjsing 	}
734703277b6Sjsing 
735703277b6Sjsing 	/* BN_hex2bn() is the new atoi()... */
736703277b6Sjsing 	if ((ret = BN_hex2bn(&bn, "9abcdefz")) != 7) {
737703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn() returned %d, want 7\n", ret);
738703277b6Sjsing 		goto failure;
739703277b6Sjsing 	}
740703277b6Sjsing 	if ((w = BN_get_word(bn)) != 0x9abcdef) {
741703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn() resulted in %llx, want %llx\n",
742703277b6Sjsing 		    (unsigned long long)w, 0x9abcdefULL);
743703277b6Sjsing 		goto failure;
744703277b6Sjsing 	}
745703277b6Sjsing 
746703277b6Sjsing 	/* A 0x prefix fails to parse without BN_asc2bn() (instead we get 0!). */
747703277b6Sjsing 	if (BN_hex2bn(&bn, "0x1") != 1) {
748703277b6Sjsing 		fprintf(stderr, "FAIL: BN_hex2bn() parsed a 0x prefix\n");
749703277b6Sjsing 		goto failure;
750703277b6Sjsing 	}
751703277b6Sjsing 
7528a60fc3bSjsing 	/* And we can call BN_hex2bn() without actually converting to a BIGNUM. */
7538a60fc3bSjsing 	if ((ret = BN_hex2bn(NULL, "9abcdefz")) != 7) {
7548a60fc3bSjsing 		fprintf(stderr, "FAIL: BN_hex2bn() returned %d, want 7\n", ret);
7558a60fc3bSjsing 		goto failure;
7568a60fc3bSjsing 	}
7578a60fc3bSjsing 
758703277b6Sjsing 	failed = 0;
759703277b6Sjsing 
760703277b6Sjsing  failure:
761703277b6Sjsing 	BN_free(bn);
762703277b6Sjsing 
763703277b6Sjsing 	return failed;
764703277b6Sjsing }
765703277b6Sjsing 
7667dd6eec6Sjsing static int
7677dd6eec6Sjsing test_bn_binpad(void)
7687dd6eec6Sjsing {
7697dd6eec6Sjsing 	const struct bn_convert_test *bct;
7707dd6eec6Sjsing 	BIGNUM *bn = NULL;
7717dd6eec6Sjsing 	uint8_t lebin[64];
7727dd6eec6Sjsing 	uint8_t buf[128];
7737dd6eec6Sjsing 	size_t i, j;
7747dd6eec6Sjsing 	int ret;
7757dd6eec6Sjsing 	int failed = 1;
7767dd6eec6Sjsing 
7777dd6eec6Sjsing 	for (i = 0; i < N_BN_CONVERT_TESTS; i++) {
7787dd6eec6Sjsing 		bct = &bn_convert_tests[i];
7797dd6eec6Sjsing 
7807dd6eec6Sjsing 		BN_free(bn);
7817dd6eec6Sjsing 		if ((bn = BN_bin2bn(bct->bin, bct->bin_len, NULL)) == NULL) {
7827dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bin2bn() failed\n");
7837dd6eec6Sjsing 			goto failure;
7847dd6eec6Sjsing 		}
7857dd6eec6Sjsing 		BN_set_negative(bn, bct->neg);
7867dd6eec6Sjsing 
7877dd6eec6Sjsing 		for (j = 0; j < bct->bin_len; j++)
7887dd6eec6Sjsing 			lebin[j] = bct->bin[bct->bin_len - j - 1];
7897dd6eec6Sjsing 
7907dd6eec6Sjsing 		if ((ret = BN_bn2binpad(bn, buf, bct->bin_len)) < 0) {
7917dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2binpad() failed\n");
7927dd6eec6Sjsing 			goto failure;
7937dd6eec6Sjsing 		}
7947dd6eec6Sjsing 		if ((size_t)ret != bct->bin_len) {
7957dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2binpad() = %d, want %zu\n",
7967dd6eec6Sjsing 			    ret, bct->bin_len);
7977dd6eec6Sjsing 			goto failure;
7987dd6eec6Sjsing 		}
7997dd6eec6Sjsing 		if (memcmp(buf, bct->bin, bct->bin_len) != 0) {
8007dd6eec6Sjsing 			fprintf(stderr, "FAIL: Test %zu - output from "
8017dd6eec6Sjsing 			    "BN_bn2binpad() differs\n", i);
8027dd6eec6Sjsing 			fprintf(stderr, "Got:\n");
8037dd6eec6Sjsing 			hexdump(buf, bct->bin_len);
8047dd6eec6Sjsing 			fprintf(stderr, "Want:\n");
8057dd6eec6Sjsing 			hexdump(bct->bin, bct->bin_len);
8067dd6eec6Sjsing 			goto failure;
8077dd6eec6Sjsing 		}
8087dd6eec6Sjsing 		if (bct->bin_len > 0) {
8097dd6eec6Sjsing 			if ((ret = BN_bn2binpad(bn, buf, bct->bin_len - 1)) != -1) {
8107dd6eec6Sjsing 				fprintf(stderr, "FAIL: BN_bn2binpad() succeeded "
8117dd6eec6Sjsing 				    "with truncation\n");
8127dd6eec6Sjsing 				goto failure;
8137dd6eec6Sjsing 			}
8147dd6eec6Sjsing 		}
8157dd6eec6Sjsing 		if ((ret = BN_bn2binpad(bn, buf, 128)) < 0) {
8167dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2binpad() failed\n");
8177dd6eec6Sjsing 			goto failure;
8187dd6eec6Sjsing 		}
8197dd6eec6Sjsing 		if (ret != 128) {
8207dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2binpad() = %d, want 128\n",
8217dd6eec6Sjsing 			    ret);
8227dd6eec6Sjsing 			goto failure;
8237dd6eec6Sjsing 		}
8247dd6eec6Sjsing 		if (memcmp(&buf[128 - bct->bin_len], bct->bin, bct->bin_len) != 0) {
8257dd6eec6Sjsing 			fprintf(stderr, "FAIL: Test %zu - output from "
8267dd6eec6Sjsing 			    "BN_bn2binpad() differs\n", i);
8277dd6eec6Sjsing 			fprintf(stderr, "Got:\n");
8287dd6eec6Sjsing 			hexdump(&buf[128 - bct->bin_len], bct->bin_len);
8297dd6eec6Sjsing 			fprintf(stderr, "Want:\n");
8307dd6eec6Sjsing 			hexdump(bct->bin, bct->bin_len);
8317dd6eec6Sjsing 			goto failure;
8327dd6eec6Sjsing 		}
8337dd6eec6Sjsing 		for (j = 0; j < 128 - bct->bin_len; j++) {
8347dd6eec6Sjsing 			if (buf[j] != 0) {
8357dd6eec6Sjsing 				fprintf(stderr, "FAIL: BN_bn2binpad() is not "
8367dd6eec6Sjsing 				    "zero padded\n");
8377dd6eec6Sjsing 				goto failure;
8387dd6eec6Sjsing 			}
8397dd6eec6Sjsing 		}
8407dd6eec6Sjsing 
8417dd6eec6Sjsing 		if ((ret = BN_bn2lebinpad(bn, buf, bct->bin_len)) < 0) {
8427dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2lebinpad() failed\n");
8437dd6eec6Sjsing 			goto failure;
8447dd6eec6Sjsing 		}
8457dd6eec6Sjsing 		if ((size_t)ret != bct->bin_len) {
8467dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2lebinpad() = %d, want %zu\n",
8477dd6eec6Sjsing 			    ret, bct->bin_len);
8487dd6eec6Sjsing 			goto failure;
8497dd6eec6Sjsing 		}
8507dd6eec6Sjsing 		if (memcmp(buf, lebin, bct->bin_len) != 0) {
8517dd6eec6Sjsing 			fprintf(stderr, "FAIL: Test %zu - output from "
8527dd6eec6Sjsing 			    "BN_bn2lebinpad() differs\n", i);
8537dd6eec6Sjsing 			fprintf(stderr, "Got:\n");
8547dd6eec6Sjsing 			hexdump(buf, bct->bin_len);
8557dd6eec6Sjsing 			fprintf(stderr, "Want:\n");
8567dd6eec6Sjsing 			hexdump(lebin, bct->bin_len);
8577dd6eec6Sjsing 			goto failure;
8587dd6eec6Sjsing 		}
8597dd6eec6Sjsing 		if (bct->bin_len > 0) {
8607dd6eec6Sjsing 			if ((ret = BN_bn2lebinpad(bn, buf, bct->bin_len - 1)) != -1) {
8617dd6eec6Sjsing 				fprintf(stderr, "FAIL: BN_bn2lebinpad() succeeded "
8627dd6eec6Sjsing 				    "with truncation\n");
8637dd6eec6Sjsing 				goto failure;
8647dd6eec6Sjsing 			}
8657dd6eec6Sjsing 		}
8667dd6eec6Sjsing 		if ((ret = BN_bn2lebinpad(bn, buf, 128)) < 0) {
8677dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2lebinpad() failed\n");
8687dd6eec6Sjsing 			goto failure;
8697dd6eec6Sjsing 		}
8707dd6eec6Sjsing 		if (ret != 128) {
8717dd6eec6Sjsing 			fprintf(stderr, "FAIL: BN_bn2lebinpad() = %d, want 128\n",
8727dd6eec6Sjsing 			    ret);
8737dd6eec6Sjsing 			goto failure;
8747dd6eec6Sjsing 		}
8757dd6eec6Sjsing 		if (memcmp(buf, lebin, bct->bin_len) != 0) {
8767dd6eec6Sjsing 			fprintf(stderr, "FAIL: Test %zu - output from "
8777dd6eec6Sjsing 			    "BN_bn2lebinpad() differs\n", i);
8787dd6eec6Sjsing 			fprintf(stderr, "Got:\n");
8797dd6eec6Sjsing 			hexdump(buf, bct->bin_len);
8807dd6eec6Sjsing 			fprintf(stderr, "Want:\n");
8817dd6eec6Sjsing 			hexdump(lebin, bct->bin_len);
8827dd6eec6Sjsing 			goto failure;
8837dd6eec6Sjsing 		}
8847dd6eec6Sjsing 		for (j = bct->bin_len; j < 128; j++) {
8857dd6eec6Sjsing 			if (buf[j] != 0) {
8867dd6eec6Sjsing 				fprintf(stderr, "FAIL: BN_bn2lebinpad() is not "
8877dd6eec6Sjsing 				    "zero padded\n");
8887dd6eec6Sjsing 				goto failure;
8897dd6eec6Sjsing 			}
8907dd6eec6Sjsing 		}
8917dd6eec6Sjsing 	}
8927dd6eec6Sjsing 
8937dd6eec6Sjsing 	failed = 0;
8947dd6eec6Sjsing 
8957dd6eec6Sjsing  failure:
8967dd6eec6Sjsing 	BN_free(bn);
8977dd6eec6Sjsing 
8987dd6eec6Sjsing 	return failed;
8997dd6eec6Sjsing }
9007dd6eec6Sjsing 
901703277b6Sjsing int
902703277b6Sjsing main(int argc, char **argv)
903703277b6Sjsing {
904703277b6Sjsing 	int failed = 0;
905703277b6Sjsing 
906703277b6Sjsing 	failed |= test_bn_asc2bn();
907703277b6Sjsing 	failed |= test_bn_convert();
908703277b6Sjsing 	failed |= test_bn_dec2bn();
909703277b6Sjsing 	failed |= test_bn_hex2bn();
9107dd6eec6Sjsing 	failed |= test_bn_binpad();
911703277b6Sjsing 
912703277b6Sjsing 	return failed;
913703277b6Sjsing }
914