summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2024-10-16 23:49:49 +0000
committertb <>2024-10-16 23:49:49 +0000
commita48647b52107fb4841167823522dcefbc307b626 (patch)
tree0353297dc65d1ddcd3f53190018fc56507b90f65 /src
parent8831aa1eb95f59bd490da67b63d9e7cded4cedfc (diff)
downloadopenbsd-a48647b52107fb4841167823522dcefbc307b626.tar.gz
openbsd-a48647b52107fb4841167823522dcefbc307b626.tar.bz2
openbsd-a48647b52107fb4841167823522dcefbc307b626.zip
Implement Wei25519 to exercise some more elliptic curve code
This provides a non-trivial non-builtin curve that is unlikely to ever become a builtin curve. This exercises the cofactor guessing code and and ensures that things work as far as they can with a custom OID. The main reason for adding it is to have a "real-world" example for an upcoming check that EC parameters represent a builtin curve.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/ec/ec_asn1_test.c285
1 files changed, 284 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/ec/ec_asn1_test.c b/src/regress/lib/libcrypto/ec/ec_asn1_test.c
index 467fd17bc8..cc0f0f46f4 100644
--- a/src/regress/lib/libcrypto/ec/ec_asn1_test.c
+++ b/src/regress/lib/libcrypto/ec/ec_asn1_test.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_asn1_test.c,v 1.4 2024/10/14 13:16:06 tb Exp $ */ 1/* $OpenBSD: ec_asn1_test.c,v 1.5 2024/10/16 23:49:49 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 Theo Buehler <tb@openbsd.org>
@@ -21,6 +21,7 @@
21 21
22#include <openssl/bio.h> 22#include <openssl/bio.h>
23#include <openssl/ec.h> 23#include <openssl/ec.h>
24#include <openssl/err.h>
24#include <openssl/objects.h> 25#include <openssl/objects.h>
25 26
26const uint8_t ec_secp256r1_pkparameters_named_curve[] = { 27const uint8_t ec_secp256r1_pkparameters_named_curve[] = {
@@ -339,6 +340,287 @@ ec_group_roundtrip_builtin_curves(void)
339 return failed; 340 return failed;
340} 341}
341 342
343/*
344 * From draft-ietf-lwig-curve-representation-23, Appendix E.3
345 */
346
347static const struct {
348 const char *oid;
349 const char *sn;
350 const char *ln;
351 const char *p;
352 const char *a;
353 const char *b;
354 const char *order;
355 const char *cofactor;
356 const char *x;
357 const char *y;
358} wei25519 = {
359 .oid = "1.3.101.108",
360 .sn = "Wei25519",
361 .p = "7fffffff" "ffffffff" "ffffffff" "ffffffff"
362 "ffffffff" "ffffffff" "ffffffff" "ffffffed",
363 .a = "2aaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
364 "aaaaaaaa" "aaaaaaaa" "aaaaaa98" "4914a144",
365 .b = "7b425ed0" "97b425ed" "097b425e" "d097b425"
366 "ed097b42" "5ed097b4" "260b5e9c" "7710c864",
367 .x = "2aaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
368 "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaad245a",
369 .y = "20ae19a1" "b8a086b4" "e01edd2c" "7748d14c"
370 "923d4d7e" "6d7c61b2" "29e9c5a2" "7eced3d9",
371 .order = "10000000" "00000000" "00000000" "00000000"
372 "14def9de" "a2f79cd6" "5812631a" "5cf5d3ed",
373 .cofactor = "8",
374};
375
376const uint8_t ec_wei25519_pkparameters_named_curve[] = {
377 0x06, 0x03, 0x2b, 0x65, 0x6c,
378};
379
380const uint8_t ec_wei25519_pkparameters_parameters[] = {
381 0x30, 0x81, 0xde, 0x02, 0x01, 0x01, 0x30, 0x2b,
382 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
383 0x01, 0x02, 0x20, 0x7f, 0xff, 0xff, 0xff, 0xff,
384 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
385 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
386 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
387 0xff, 0xff, 0xed, 0x30, 0x44, 0x04, 0x20, 0x2a,
388 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
389 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
390 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
391 0xaa, 0xaa, 0x98, 0x49, 0x14, 0xa1, 0x44, 0x04,
392 0x20, 0x7b, 0x42, 0x5e, 0xd0, 0x97, 0xb4, 0x25,
393 0xed, 0x09, 0x7b, 0x42, 0x5e, 0xd0, 0x97, 0xb4,
394 0x25, 0xed, 0x09, 0x7b, 0x42, 0x5e, 0xd0, 0x97,
395 0xb4, 0x26, 0x0b, 0x5e, 0x9c, 0x77, 0x10, 0xc8,
396 0x64, 0x04, 0x41, 0x04, 0x2a, 0xaa, 0xaa, 0xaa,
397 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
398 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
399 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
400 0xaa, 0xad, 0x24, 0x5a, 0x20, 0xae, 0x19, 0xa1,
401 0xb8, 0xa0, 0x86, 0xb4, 0xe0, 0x1e, 0xdd, 0x2c,
402 0x77, 0x48, 0xd1, 0x4c, 0x92, 0x3d, 0x4d, 0x7e,
403 0x6d, 0x7c, 0x61, 0xb2, 0x29, 0xe9, 0xc5, 0xa2,
404 0x7e, 0xce, 0xd3, 0xd9, 0x02, 0x20, 0x10, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xde,
407 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6, 0x58, 0x12,
408 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed, 0x02, 0x01,
409 0x08,
410};
411
412static int
413ec_weierstrass25519(void)
414{
415 EC_GROUP *group = NULL, *new_group = NULL;
416 EC_POINT *generator = NULL;
417 BN_CTX *ctx = NULL;
418 BIGNUM *p, *a, *b;
419 BIGNUM *order, *cofactor, *guessed_cofactor, *x, *y;
420 const unsigned char *pder;
421 unsigned char *der = NULL;
422 long error;
423 int der_len = 0;
424 int nid;
425 int failed = 1;
426
427 ERR_clear_error();
428 if ((ctx = BN_CTX_new()) == NULL)
429 goto err;
430 BN_CTX_start(ctx);
431
432 if ((nid = OBJ_create(wei25519.oid, wei25519.sn, NULL)) == NID_undef) {
433 fprintf(stderr, "FAIL: %s OBJ_create(wei25519)\n", __func__);
434 goto err;
435 }
436
437 if ((p = BN_CTX_get(ctx)) == NULL)
438 errx(1, "BN_CTX_get");
439 if ((a = BN_CTX_get(ctx)) == NULL)
440 errx(1, "BN_CTX_get");
441 if ((b = BN_CTX_get(ctx)) == NULL)
442 errx(1, "BN_CTX_get");
443 if ((order = BN_CTX_get(ctx)) == NULL)
444 errx(1, "BN_CTX_get");
445 if ((cofactor = BN_CTX_get(ctx)) == NULL)
446 errx(1, "BN_CTX_get");
447 if ((guessed_cofactor = BN_CTX_get(ctx)) == NULL)
448 errx(1, "BN_CTX_get");
449 if ((x = BN_CTX_get(ctx)) == NULL)
450 errx(1, "BN_CTX_get");
451 if ((y = BN_CTX_get(ctx)) == NULL)
452 errx(1, "BN_CTX_get");
453
454 if (BN_hex2bn(&p, wei25519.p) == 0)
455 errx(1, "BN_hex2bn(p)");
456 if (BN_hex2bn(&a, wei25519.a) == 0)
457 errx(1, "BN_hex2bn(a)");
458 if (BN_hex2bn(&b, wei25519.b) == 0)
459 errx(1, "BN_hex2bn(b)");
460
461 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
462 fprintf(stderr, "FAIL: %s EC_GROUP_new_curve_GFp", __func__);
463 goto err;
464 }
465
466 if (BN_hex2bn(&x, wei25519.x) == 0)
467 errx(1, "BN_hex2bn(x)");
468 if (BN_hex2bn(&x, wei25519.x) == 0)
469 errx(1, "BN_hex2bn(x)");
470 if (BN_hex2bn(&y, wei25519.y) == 0)
471 errx(1, "BN_hex2bn(y)");
472
473 if ((generator = EC_POINT_new(group)) == NULL)
474 errx(1, "EC_POINT_new()");
475
476 if (!EC_POINT_set_affine_coordinates(group, generator, x, y, ctx)) {
477 fprintf(stderr, "FAIL: %s EC_POINT_set_affine_coordinates", __func__);
478 ERR_print_errors_fp(stderr);
479 goto err;
480 }
481
482 if (BN_hex2bn(&order, wei25519.order) == 0)
483 errx(1, "BN_hex2bn(order)");
484 if (BN_hex2bn(&cofactor, wei25519.cofactor) == 0)
485 errx(1, "BN_hex2bn(cofactor)");
486
487 /* Don't set cofactor to exercise the cofactor guessing code. */
488 if (!EC_GROUP_set_generator(group, generator, order, NULL)) {
489 fprintf(stderr, "FAIL: %s EC_GROUP_set_generator\n", __func__);
490 ERR_print_errors_fp(stderr);
491 goto err;
492 }
493
494 if (!EC_GROUP_get_cofactor(group, guessed_cofactor, ctx)) {
495 fprintf(stderr, "FAIL: %s EC_GROUP_get_cofactor\n", __func__);
496 ERR_print_errors_fp(stderr);
497 goto err;
498 }
499
500 if (BN_cmp(cofactor, guessed_cofactor) != 0) {
501 fprintf(stderr, "FAIL: %s cofactor: want ", __func__);
502 BN_print_fp(stderr, cofactor);
503 fprintf(stderr, ", got ");
504 BN_print_fp(stderr, guessed_cofactor);
505 fprintf(stderr, "\n");
506 goto err;
507 }
508
509 if (!EC_GROUP_check(group, ctx)) {
510 fprintf(stderr, "FAIL: %s EC_GROUP_check\n", __func__);
511 ERR_print_errors_fp(stderr);
512 goto err;
513 }
514
515 /* Explicit curve parameter encoding should work without NID set. */
516 if (EC_GROUP_get_curve_name(group) != NID_undef) {
517 fprintf(stderr, "FAIL: %s unexpected curve name %d\n", __func__,
518 EC_GROUP_get_curve_name(group));
519 ERR_print_errors_fp(stderr);
520 goto err;
521 }
522
523 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
524
525 der = NULL;
526 if ((der_len = i2d_ECPKParameters(group, &der)) <= 0) {
527 fprintf(stderr, "FAIL: %s i2d_ECPKParameters (explicit)\n", __func__);
528 ERR_print_errors_fp(stderr);
529 goto err;
530 }
531
532 if (compare_data("Weierstrass 25519 explicit", der, der_len,
533 ec_wei25519_pkparameters_parameters,
534 sizeof(ec_wei25519_pkparameters_parameters)) == -1)
535 goto err;
536
537 freezero(der, der_len);
538 der = NULL;
539
540 EC_GROUP_set_curve_name(group, nid);
541 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
542
543 der = NULL;
544 if ((der_len = i2d_ECPKParameters(group, &der)) <= 0) {
545 fprintf(stderr, "FAIL: %s i2d_ECPKParameters (named)\n", __func__);
546 ERR_print_errors_fp(stderr);
547 goto err;
548 }
549
550 if (compare_data("Weierstrass 25519 named curve", der, der_len,
551 ec_wei25519_pkparameters_named_curve,
552 sizeof(ec_wei25519_pkparameters_named_curve)) == -1)
553 goto err;
554
555 freezero(der, der_len);
556 der = NULL;
557
558 /* At this point we should have no error on the stack. */
559 if (ERR_peek_last_error() != 0) {
560 fprintf(stderr, "FAIL: %s unexpected error %lu\n", __func__,
561 ERR_peek_last_error());
562 goto err;
563 }
564
565 pder = ec_wei25519_pkparameters_named_curve;
566 der_len = sizeof(ec_wei25519_pkparameters_named_curve);
567 if ((new_group = d2i_ECPKParameters(NULL, &pder, der_len)) != NULL) {
568 fprintf(stderr, "FAIL: %s managed to decode unknown named curve\n",
569 __func__);
570 goto err;
571 }
572
573 error = ERR_get_error();
574 if (ERR_GET_REASON(error) != EC_R_UNKNOWN_GROUP) {
575 fprintf(stderr, "FAIL: %s unexpected error: want %d, got %d\n",
576 __func__, EC_R_UNKNOWN_GROUP, ERR_GET_REASON(error));
577 goto err;
578 }
579
580 ERR_clear_error();
581 pder = ec_wei25519_pkparameters_parameters;
582 der_len = sizeof(ec_wei25519_pkparameters_parameters);
583
584#if 0
585 if ((new_group = d2i_ECPKParameters(NULL, &pder, der_len)) != NULL) {
586 fprintf(stderr, "FAIL: %s managed to decode non-builtin parameters\n",
587 __func__);
588 goto err;
589 }
590
591 error = ERR_peek_last_error();
592 if (ERR_GET_REASON(error) != EC_R_PKPARAMETERS2GROUP_FAILURE) {
593 fprintf(stderr, "FAIL: %s unexpected error: want %d, got %d\n",
594 __func__, EC_R_UNKNOWN_GROUP, ERR_GET_REASON(error));
595 goto err;
596 }
597#else
598 if ((new_group = d2i_ECPKParameters(NULL, &pder, der_len)) == NULL) {
599 fprintf(stderr, "FAIL: %s d2i_ECPKParameters(Wei25519)\n", __func__);
600 goto err;
601 }
602 if (EC_GROUP_cmp(group, new_group, ctx) != 0) {
603 fprintf(stderr, "FAIL: %s Weierstrass groups do not match!\n",
604 __func__);
605 goto err;
606 }
607#endif
608
609 failed = 0;
610
611 err:
612 BN_CTX_end(ctx);
613 BN_CTX_free(ctx);
614
615 EC_GROUP_free(group);
616 EC_GROUP_free(new_group);
617 EC_POINT_free(generator);
618
619 freezero(der, der_len);
620
621 return failed;
622}
623
342int 624int
343main(int argc, char **argv) 625main(int argc, char **argv)
344{ 626{
@@ -348,6 +630,7 @@ main(int argc, char **argv)
348 failed |= ec_group_pkparameters_parameters_test(); 630 failed |= ec_group_pkparameters_parameters_test();
349 failed |= ec_group_pkparameters_correct_padding_test(); 631 failed |= ec_group_pkparameters_correct_padding_test();
350 failed |= ec_group_roundtrip_builtin_curves(); 632 failed |= ec_group_roundtrip_builtin_curves();
633 failed |= ec_weierstrass25519();
351 634
352 return (failed); 635 return (failed);
353} 636}