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