summaryrefslogtreecommitdiff
path: root/src/regress/lib/libcrypto/ec/ec_asn1_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libcrypto/ec/ec_asn1_test.c')
-rw-r--r--src/regress/lib/libcrypto/ec/ec_asn1_test.c321
1 files changed, 199 insertions, 122 deletions
diff --git a/src/regress/lib/libcrypto/ec/ec_asn1_test.c b/src/regress/lib/libcrypto/ec/ec_asn1_test.c
index 03358e69ca..50e6304baf 100644
--- a/src/regress/lib/libcrypto/ec/ec_asn1_test.c
+++ b/src/regress/lib/libcrypto/ec/ec_asn1_test.c
@@ -1,7 +1,7 @@
1/* $OpenBSD: ec_asn1_test.c,v 1.32 2025/03/08 20:09:35 tb Exp $ */ 1/* $OpenBSD: ec_asn1_test.c,v 1.36 2025/07/23 07:42:33 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2024, 2025 Theo Buehler <tb@openbsd.org>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -17,12 +17,17 @@
17 */ 17 */
18 18
19#include <err.h> 19#include <err.h>
20#include <stdio.h>
21#include <stdint.h>
22#include <stdlib.h>
20#include <string.h> 23#include <string.h>
21 24
22#include <openssl/bio.h> 25#include <openssl/bio.h>
26#include <openssl/bn.h>
23#include <openssl/ec.h> 27#include <openssl/ec.h>
24#include <openssl/err.h> 28#include <openssl/err.h>
25#include <openssl/objects.h> 29#include <openssl/objects.h>
30#include <openssl/sha.h>
26 31
27#include "ec_local.h" 32#include "ec_local.h"
28 33
@@ -1281,126 +1286,6 @@ static const struct ec_private_key {
1281 }, 1286 },
1282 }, 1287 },
1283 { 1288 {
1284 .name = "prime239v1",
1285 .der_len = 115,
1286 .der = {
1287 0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x6e,
1288 0x26, 0x5e, 0xde, 0x5b, 0x67, 0xd6, 0x38, 0x52,
1289 0xe7, 0x1e, 0x8d, 0x44, 0xb1, 0xfb, 0xf8, 0xaf,
1290 0xf9, 0x94, 0x2c, 0xe2, 0x0d, 0xa8, 0x5f, 0x03,
1291 0x67, 0x53, 0x7b, 0x8b, 0x2e, 0xa0, 0x0a, 0x06,
1292 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
1293 0x04, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x33,
1294 0xc6, 0xe5, 0x8a, 0xc1, 0x8b, 0x7c, 0x96, 0x19,
1295 0xc9, 0xe1, 0x54, 0x7f, 0x81, 0x9e, 0x59, 0x62,
1296 0xec, 0xc0, 0x1e, 0xe5, 0x53, 0xd5, 0xae, 0x6b,
1297 0xd3, 0xe0, 0x09, 0x07, 0xc5, 0x27, 0x81, 0xa6,
1298 0x8d, 0x39, 0x8e, 0xfe, 0x01, 0xc2, 0x1d, 0xda,
1299 0xde, 0x7b, 0xdc, 0x76, 0x27, 0x17, 0xf9, 0x6f,
1300 0xe3, 0x04, 0xef, 0x5d, 0x65, 0x75, 0x98, 0x7f,
1301 0x2d, 0xd0, 0x68,
1302 },
1303 .hex = "0433C6E58AC18B7C"
1304 "9619C9E1547F819E"
1305 "5962ECC01EE553D5"
1306 "AE6BD3E00907C527"
1307 "81A68D398EFE01C2"
1308 "1DDADE7BDC762717"
1309 "F96FE304EF5D6575"
1310 "987F2DD068",
1311 .oct_len = 61,
1312 .oct = {
1313 0x04, 0x33, 0xc6, 0xe5, 0x8a, 0xc1, 0x8b, 0x7c,
1314 0x96, 0x19, 0xc9, 0xe1, 0x54, 0x7f, 0x81, 0x9e,
1315 0x59, 0x62, 0xec, 0xc0, 0x1e, 0xe5, 0x53, 0xd5,
1316 0xae, 0x6b, 0xd3, 0xe0, 0x09, 0x07, 0xc5, 0x27,
1317 0x81, 0xa6, 0x8d, 0x39, 0x8e, 0xfe, 0x01, 0xc2,
1318 0x1d, 0xda, 0xde, 0x7b, 0xdc, 0x76, 0x27, 0x17,
1319 0xf9, 0x6f, 0xe3, 0x04, 0xef, 0x5d, 0x65, 0x75,
1320 0x98, 0x7f, 0x2d, 0xd0, 0x68,
1321 },
1322 },
1323 {
1324 .name = "prime239v2",
1325 .der_len = 115,
1326 .der = {
1327 0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x30,
1328 0x2f, 0x01, 0x10, 0xe9, 0x09, 0x15, 0xdd, 0xe3,
1329 0xdd, 0xae, 0xcb, 0x9d, 0x3a, 0x58, 0x92, 0x02,
1330 0x1e, 0x6e, 0x02, 0x57, 0xa8, 0x36, 0x0b, 0x20,
1331 0x0b, 0x7e, 0xf4, 0xad, 0x0b, 0xa0, 0x0a, 0x06,
1332 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
1333 0x05, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x3c,
1334 0x10, 0x27, 0x7b, 0xac, 0xdf, 0x86, 0xc9, 0x4f,
1335 0xf8, 0x39, 0x87, 0x02, 0x39, 0xaf, 0x41, 0xbc,
1336 0x4b, 0x67, 0xd8, 0x5e, 0x04, 0x96, 0x84, 0xb5,
1337 0x60, 0x50, 0x48, 0x6a, 0x20, 0x1d, 0x2b, 0x7e,
1338 0x9f, 0xaf, 0xf8, 0x8e, 0x7e, 0xa4, 0xcd, 0x00,
1339 0xad, 0xb1, 0xad, 0x22, 0x69, 0x32, 0x10, 0x6c,
1340 0xe0, 0xcc, 0xdd, 0x45, 0xd8, 0xa6, 0x29, 0x2f,
1341 0xad, 0x6b, 0xf9,
1342 },
1343 .hex = "043C10277BACDF86"
1344 "C94FF839870239AF"
1345 "41BC4B67D85E0496"
1346 "84B56050486A201D"
1347 "2B7E9FAFF88E7EA4"
1348 "CD00ADB1AD226932"
1349 "106CE0CCDD45D8A6"
1350 "292FAD6BF9",
1351 .oct_len = 61,
1352 .oct = {
1353 0x04, 0x3c, 0x10, 0x27, 0x7b, 0xac, 0xdf, 0x86,
1354 0xc9, 0x4f, 0xf8, 0x39, 0x87, 0x02, 0x39, 0xaf,
1355 0x41, 0xbc, 0x4b, 0x67, 0xd8, 0x5e, 0x04, 0x96,
1356 0x84, 0xb5, 0x60, 0x50, 0x48, 0x6a, 0x20, 0x1d,
1357 0x2b, 0x7e, 0x9f, 0xaf, 0xf8, 0x8e, 0x7e, 0xa4,
1358 0xcd, 0x00, 0xad, 0xb1, 0xad, 0x22, 0x69, 0x32,
1359 0x10, 0x6c, 0xe0, 0xcc, 0xdd, 0x45, 0xd8, 0xa6,
1360 0x29, 0x2f, 0xad, 0x6b, 0xf9,
1361 },
1362 },
1363 {
1364 .name = "prime239v3",
1365 .der_len = 115,
1366 .der = {
1367 0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x26,
1368 0x3f, 0x23, 0x4c, 0xe7, 0xbd, 0xa8, 0xe4, 0xfe,
1369 0x7c, 0xf6, 0x18, 0x6a, 0xb2, 0xa6, 0x39, 0x15,
1370 0x6d, 0x72, 0xe8, 0x9e, 0x3f, 0x0f, 0x10, 0x1e,
1371 0xe5, 0xdf, 0xac, 0xe8, 0x2f, 0xa0, 0x0a, 0x06,
1372 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
1373 0x06, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x37,
1374 0xba, 0x07, 0x7f, 0xd9, 0x46, 0x5a, 0x33, 0x03,
1375 0x31, 0x77, 0x38, 0xef, 0xee, 0xcc, 0x3d, 0xe1,
1376 0xaa, 0x57, 0xe3, 0x8d, 0xb7, 0xcd, 0xe3, 0x01,
1377 0xf4, 0xd6, 0x75, 0x49, 0x72, 0x61, 0x4c, 0xbf,
1378 0xc0, 0x1f, 0x8b, 0x5f, 0x98, 0x9b, 0xa7, 0xe5,
1379 0x6a, 0xb7, 0xfe, 0x63, 0xdb, 0xb0, 0x40, 0xcb,
1380 0x26, 0x81, 0x2a, 0x91, 0x14, 0x0f, 0xc7, 0x31,
1381 0x13, 0x78, 0x16,
1382 },
1383 .hex = "0437BA077FD9465A"
1384 "3303317738EFEECC"
1385 "3DE1AA57E38DB7CD"
1386 "E301F4D675497261"
1387 "4CBFC01F8B5F989B"
1388 "A7E56AB7FE63DBB0"
1389 "40CB26812A91140F"
1390 "C731137816",
1391 .oct_len = 61,
1392 .oct = {
1393 0x04, 0x37, 0xba, 0x07, 0x7f, 0xd9, 0x46, 0x5a,
1394 0x33, 0x03, 0x31, 0x77, 0x38, 0xef, 0xee, 0xcc,
1395 0x3d, 0xe1, 0xaa, 0x57, 0xe3, 0x8d, 0xb7, 0xcd,
1396 0xe3, 0x01, 0xf4, 0xd6, 0x75, 0x49, 0x72, 0x61,
1397 0x4c, 0xbf, 0xc0, 0x1f, 0x8b, 0x5f, 0x98, 0x9b,
1398 0xa7, 0xe5, 0x6a, 0xb7, 0xfe, 0x63, 0xdb, 0xb0,
1399 0x40, 0xcb, 0x26, 0x81, 0x2a, 0x91, 0x14, 0x0f,
1400 0xc7, 0x31, 0x13, 0x78, 0x16,
1401 },
1402 },
1403 {
1404 .name = "prime256v1", 1289 .name = "prime256v1",
1405 .der_len = 121, 1290 .der_len = 121,
1406 .der = { 1291 .der = {
@@ -2468,6 +2353,197 @@ ec_group_check_private_keys(void)
2468 return failed; 2353 return failed;
2469} 2354}
2470 2355
2356static void
2357ec_group_sha1_bignum(BIGNUM *out, const BIGNUM *in)
2358{
2359 char md[SHA_DIGEST_LENGTH];
2360 unsigned char *bin;
2361 size_t bin_len;
2362
2363 if (BN_num_bytes(in) <= 0)
2364 errx(1, "%s: invalid bignum", __func__);
2365
2366 bin_len = BN_num_bytes(in);
2367 if ((bin = calloc(1, bin_len)) == NULL)
2368 err(1, "calloc");
2369 if (BN_bn2bin(in, bin) <= 0)
2370 errx(1, "BN_bn2bin");
2371
2372 SHA1(bin, bin_len, md);
2373 free(bin);
2374
2375 if (BN_bin2bn(md, sizeof(md), out) == NULL)
2376 errx(1, "BN_bin2bn");
2377}
2378
2379static int
2380ec_group_check_seed(const EC_builtin_curve *curve, BN_CTX *ctx)
2381{
2382 EC_GROUP *group = NULL;
2383 BIGNUM *p, *a, *b, *pow2, *r, *seed_bn, *w;
2384 const unsigned char *seed;
2385 size_t seed_len;
2386 int i, g, h, s, t;
2387 int failed = 1;
2388
2389 if ((group = EC_GROUP_new_by_curve_name(curve->nid)) == NULL)
2390 errx(1, "EC_GROUP_new_by_curve_name");
2391
2392 BN_CTX_start(ctx);
2393
2394 if ((p = BN_CTX_get(ctx)) == NULL)
2395 errx(1, "p = BN_CTX_get()");
2396 if ((a = BN_CTX_get(ctx)) == NULL)
2397 errx(1, "a = BN_CTX_get()");
2398 if ((b = BN_CTX_get(ctx)) == NULL)
2399 errx(1, "b = BN_CTX_get()");
2400 if ((r = BN_CTX_get(ctx)) == NULL)
2401 errx(1, "r = BN_CTX_get()");
2402 if ((pow2 = BN_CTX_get(ctx)) == NULL)
2403 errx(1, "pow2 = BN_CTX_get()");
2404 if ((seed_bn = BN_CTX_get(ctx)) == NULL)
2405 errx(1, "seed_bn = BN_CTX_get()");
2406 if ((w = BN_CTX_get(ctx)) == NULL)
2407 errx(1, "w = BN_CTX_get()");
2408
2409 /*
2410 * If the curve has a seed, verify that its parameters a and b have
2411 * been selected using that seed, loosely following X9.62, F.3.4.b.
2412 * Otherwise there's nothing to do.
2413 */
2414 if ((seed = EC_GROUP_get0_seed(group)) == NULL)
2415 goto done;
2416 seed_len = EC_GROUP_get_seed_len(group);
2417
2418 /*
2419 * This isn't a requirement but happens to be the case for NIST
2420 * curves - the only built-in curves that have a seed.
2421 */
2422 if (seed_len != SHA_DIGEST_LENGTH) {
2423 fprintf(stderr, "%s FAIL: unexpected seed length. "
2424 "want %d, got %zu\n", __func__, SHA_DIGEST_LENGTH, seed_len);
2425 goto err;
2426 }
2427
2428 /* Seed length in bits, per F.3.3.b. */
2429 g = 8 * seed_len;
2430
2431 /*
2432 * Prepare to build the verifiably random element r of GFp by
2433 * concatenating the SHA-1 of modifications of the seed as a number.
2434 */
2435 if (BN_bin2bn(seed, seed_len, seed_bn) == NULL)
2436 errx(1, "BN_bin2bn");
2437
2438 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
2439 errx(1, "EC_GROUP_get_curve");
2440
2441 t = BN_num_bits(p); /* bit length needed. */
2442 s = (t - 1) / 160; /* number of SHA-1 fitting in bit length. */
2443 h = t - 160 * s; /* remaining number of bits in r. */
2444
2445 /*
2446 * Steps 1 - 3: compute hash of the seed and take h - 1 rightmost bits.
2447 */
2448
2449 ec_group_sha1_bignum(r, seed_bn);
2450 BN_zero(pow2);
2451 if (!BN_set_bit(pow2, h - 1))
2452 errx(1, "BN_set_bit");
2453 if (!BN_mod(r, r, pow2, ctx))
2454 errx(1, "BN_nnmod");
2455
2456 /*
2457 * Steps 4 - 6: for i from 1 to s do Wi = SHA-1(SEED + i mod 2^g),
2458 * With W0 = r as already computed, let r = W0 || W1 || ... || Ws.
2459 */
2460
2461 BN_zero(pow2);
2462 if (!BN_set_bit(pow2, g))
2463 errx(1, "BN_set_bit");
2464
2465 for (i = 0; i < s; i++) {
2466 /*
2467 * This is a bit silly since the seed isn't going to have all
2468 * its bits set, so BN_add_word(seed_bn, 1) would do, but for
2469 * the sake of correctness...
2470 */
2471 if (!BN_mod_add(seed_bn, seed_bn, BN_value_one(), pow2, ctx))
2472 errx(1, "BN_mod_add");
2473
2474 ec_group_sha1_bignum(w, seed_bn);
2475
2476 if (!BN_lshift(r, r, 8 * SHA_DIGEST_LENGTH))
2477 errx(1, "BN_lshift");
2478 if (!BN_add(r, r, w))
2479 errx(1, "BN_add");
2480 }
2481
2482 /*
2483 * Step 7: check that r * b^2 == a^3 (mod p)
2484 */
2485
2486 /* Compute r = r * b^2 (mod p). */
2487 if (!BN_mod_sqr(b, b, p, ctx))
2488 errx(1, "BN_mod_sqr");
2489 if (!BN_mod_mul(r, r, b, p, ctx))
2490 errx(1, "BN_mod_mul");
2491
2492 /* Compute a = a^3 (mod p). */
2493 if (!BN_mod_sqr(b, a, p, ctx))
2494 errx(1, "BN_mod_sqr");
2495 if (!BN_mod_mul(a, a, b, p, ctx))
2496 errx(1, "BN_mod_mul");
2497
2498 /*
2499 * XXX - this assumes that a, b, p >= 0, so the results are in [0, p).
2500 * This is currently enforced in the EC code.
2501 */
2502 if (BN_cmp(r, a) != 0) {
2503 fprintf(stderr, "FAIL: %s verification failed for %s\nr * b^2:\t",
2504 __func__, curve->comment);
2505 BN_print_fp(stderr, r);
2506 fprintf(stderr, "\na^3:\t\t");
2507 BN_print_fp(stderr, a);
2508 fprintf(stderr, "\n");
2509 goto err;
2510 }
2511
2512 done:
2513 failed = 0;
2514
2515 err:
2516 BN_CTX_end(ctx);
2517 EC_GROUP_free(group);
2518
2519 return failed;
2520}
2521
2522static int
2523ec_group_check_seeds(void)
2524{
2525 BN_CTX *ctx = NULL;
2526 EC_builtin_curve *all_curves = NULL;
2527 size_t curve_id, ncurves;
2528 int failed = 0;
2529
2530 if ((ctx = BN_CTX_new()) == NULL)
2531 errx(1, "BN_CTX_new");
2532
2533 ncurves = EC_get_builtin_curves(NULL, 0);
2534 if ((all_curves = calloc(ncurves, sizeof(*all_curves))) == NULL)
2535 err(1, "calloc builtin curves");
2536 EC_get_builtin_curves(all_curves, ncurves);
2537
2538 for (curve_id = 0; curve_id < ncurves; curve_id++)
2539 failed |= ec_group_check_seed(&all_curves[curve_id], ctx);
2540
2541 free(all_curves);
2542 BN_CTX_free(ctx);
2543
2544 return failed;
2545}
2546
2471int 2547int
2472main(int argc, char **argv) 2548main(int argc, char **argv)
2473{ 2549{
@@ -2479,6 +2555,7 @@ main(int argc, char **argv)
2479 failed |= ec_group_roundtrip_builtin_curves(); 2555 failed |= ec_group_roundtrip_builtin_curves();
2480 failed |= ec_group_non_builtin_curves(); 2556 failed |= ec_group_non_builtin_curves();
2481 failed |= ec_group_check_private_keys(); 2557 failed |= ec_group_check_private_keys();
2558 failed |= ec_group_check_seeds();
2482 2559
2483 return failed; 2560 return failed;
2484} 2561}