diff options
| author | tb <> | 2024-10-29 13:19:22 +0000 |
|---|---|---|
| committer | tb <> | 2024-10-29 13:19:22 +0000 |
| commit | cec251300be81e6d48aee6957347cff44a73a677 (patch) | |
| tree | a5866b63bf5fd94c8dee2299a8338b85afc61e45 /src | |
| parent | ce051cb967424d433f6c495f7c82b2a7204e2d4f (diff) | |
| download | openbsd-cec251300be81e6d48aee6957347cff44a73a677.tar.gz openbsd-cec251300be81e6d48aee6957347cff44a73a677.tar.bz2 openbsd-cec251300be81e6d48aee6957347cff44a73a677.zip | |
Split ec_key_test_point_encoding() into chunks of saner size
Diffstat (limited to 'src')
| -rw-r--r-- | src/regress/lib/libcrypto/ec/ec_asn1_test.c | 221 |
1 files changed, 172 insertions, 49 deletions
diff --git a/src/regress/lib/libcrypto/ec/ec_asn1_test.c b/src/regress/lib/libcrypto/ec/ec_asn1_test.c index 02796a25ed..54d99a7bba 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.22 2024/10/29 06:34:18 tb Exp $ */ | 1 | /* $OpenBSD: ec_asn1_test.c,v 1.23 2024/10/29 13:19:22 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> |
| @@ -2544,22 +2544,15 @@ static const struct ec_private_key { | |||
| 2544 | 2544 | ||
| 2545 | #define N_EC_PRIVATE_KEYS (sizeof(ec_private_keys) / sizeof(ec_private_keys[0])) | 2545 | #define N_EC_PRIVATE_KEYS (sizeof(ec_private_keys) / sizeof(ec_private_keys[0])) |
| 2546 | 2546 | ||
| 2547 | static int | 2547 | static EC_KEY * |
| 2548 | ec_group_check_private_key(const struct ec_private_key *key) | 2548 | ec_key_check_sanity(const struct ec_private_key *key) |
| 2549 | { | 2549 | { |
| 2550 | EC_KEY *ec_key = NULL, *ec_pub_key = NULL; | 2550 | EC_KEY *ec_key; |
| 2551 | const EC_GROUP *group; | ||
| 2552 | const EC_POINT *ec_public_point; | ||
| 2553 | EC_POINT *point = NULL; | ||
| 2554 | BIGNUM *hex_bn = NULL, *point_bn = NULL; | ||
| 2555 | const unsigned char *p; | 2551 | const unsigned char *p; |
| 2552 | unsigned char *der = NULL; | ||
| 2553 | int der_len = 0; | ||
| 2556 | unsigned int flags; | 2554 | unsigned int flags; |
| 2557 | unsigned char *der = NULL, *ostr = NULL; | ||
| 2558 | char *hex = NULL; | ||
| 2559 | int der_len = 0, hex_len = 0, ostr_len = 0; | ||
| 2560 | uint8_t form; | 2555 | uint8_t form; |
| 2561 | int rv; | ||
| 2562 | int failed = 1; | ||
| 2563 | 2556 | ||
| 2564 | p = key->der; | 2557 | p = key->der; |
| 2565 | if ((ec_key = d2i_ECPrivateKey(NULL, &p, key->der_len)) == NULL) { | 2558 | if ((ec_key = d2i_ECPrivateKey(NULL, &p, key->der_len)) == NULL) { |
| @@ -2582,6 +2575,7 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2582 | if (!EC_KEY_check_key(ec_key)) { | 2575 | if (!EC_KEY_check_key(ec_key)) { |
| 2583 | fprintf(stderr, "FAIL: EC_KEY_check_key() for %s\n", key->name); | 2576 | fprintf(stderr, "FAIL: EC_KEY_check_key() for %s\n", key->name); |
| 2584 | ERR_print_errors_fp(stderr); | 2577 | ERR_print_errors_fp(stderr); |
| 2578 | goto err; | ||
| 2585 | } | 2579 | } |
| 2586 | 2580 | ||
| 2587 | der = NULL; | 2581 | der = NULL; |
| @@ -2597,9 +2591,24 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2597 | freezero(der, der_len); | 2591 | freezero(der, der_len); |
| 2598 | der = NULL; | 2592 | der = NULL; |
| 2599 | 2593 | ||
| 2600 | /* | 2594 | return ec_key; |
| 2601 | * Check the outputs of EC_POINT_point2hex() and i2o_ECPublicKey(). | 2595 | |
| 2602 | */ | 2596 | err: |
| 2597 | EC_KEY_free(ec_key); | ||
| 2598 | freezero(der, der_len); | ||
| 2599 | |||
| 2600 | return NULL; | ||
| 2601 | } | ||
| 2602 | |||
| 2603 | static int | ||
| 2604 | ec_key_test_point_encoding(const struct ec_private_key *key, const EC_KEY *ec_key) | ||
| 2605 | { | ||
| 2606 | const EC_GROUP *group; | ||
| 2607 | const EC_POINT *ec_public_point; | ||
| 2608 | char *hex = NULL; | ||
| 2609 | unsigned char *ostr = NULL; | ||
| 2610 | int hex_len = 0, ostr_len = 0; | ||
| 2611 | int failed = 1; | ||
| 2603 | 2612 | ||
| 2604 | if ((group = EC_KEY_get0_group(ec_key)) == NULL) { | 2613 | if ((group = EC_KEY_get0_group(ec_key)) == NULL) { |
| 2605 | fprintf(stderr, "FAIL: EC_KEY_get0_group() for %s\n", key->name); | 2614 | fprintf(stderr, "FAIL: EC_KEY_get0_group() for %s\n", key->name); |
| @@ -2622,8 +2631,12 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2622 | goto err; | 2631 | goto err; |
| 2623 | } | 2632 | } |
| 2624 | 2633 | ||
| 2625 | freezero(ostr, ostr_len); | 2634 | if (compare_data(key->name, hex, hex_len, key->hex, hex_len) == -1) { |
| 2626 | ostr = NULL; | 2635 | fprintf(stderr, "FAIL: EC_POINT_point2hex() comparison for %s\n", |
| 2636 | key->name); | ||
| 2637 | goto err; | ||
| 2638 | } | ||
| 2639 | |||
| 2627 | if ((ostr_len = i2o_ECPublicKey(ec_key, &ostr)) <= 0) { | 2640 | if ((ostr_len = i2o_ECPublicKey(ec_key, &ostr)) <= 0) { |
| 2628 | fprintf(stderr, "FAIL: i2o_ECPublicKey for %s\n", key->name); | 2641 | fprintf(stderr, "FAIL: i2o_ECPublicKey for %s\n", key->name); |
| 2629 | goto err; | 2642 | goto err; |
| @@ -2635,9 +2648,36 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2635 | goto err; | 2648 | goto err; |
| 2636 | } | 2649 | } |
| 2637 | 2650 | ||
| 2651 | failed = 0; | ||
| 2652 | |||
| 2653 | err: | ||
| 2654 | free(hex); | ||
| 2655 | freezero(ostr, ostr_len); | ||
| 2656 | |||
| 2657 | return failed; | ||
| 2658 | } | ||
| 2659 | |||
| 2660 | static int | ||
| 2661 | ec_key_test_point_versus_bn(const struct ec_private_key *key, const EC_KEY *ec_key) | ||
| 2662 | { | ||
| 2663 | const EC_GROUP *group; | ||
| 2664 | const EC_POINT *ec_public_point; | ||
| 2665 | EC_POINT *point = NULL; | ||
| 2666 | BIGNUM *hex_bn = NULL, *point_bn = NULL; | ||
| 2667 | int rv; | ||
| 2668 | int failed = 1; | ||
| 2669 | |||
| 2670 | if ((group = EC_KEY_get0_group(ec_key)) == NULL) { | ||
| 2671 | fprintf(stderr, "FAIL: EC_KEY_get0_group() for %s\n", key->name); | ||
| 2672 | goto err; | ||
| 2673 | } | ||
| 2674 | if ((ec_public_point = EC_KEY_get0_public_key(ec_key)) == NULL) { | ||
| 2675 | fprintf(stderr, "FAIL: EC_KEY_get0_public_key() for %s\n", key->name); | ||
| 2676 | goto err; | ||
| 2677 | } | ||
| 2678 | |||
| 2638 | /* | 2679 | /* |
| 2639 | * Now compare the octet string placed into a bignum with what we got | 2680 | * Check that point2bn matches hex2bn. |
| 2640 | * from point2hex (what a wonderful idea). | ||
| 2641 | */ | 2681 | */ |
| 2642 | 2682 | ||
| 2643 | if ((point_bn = BN_new()) == NULL) | 2683 | if ((point_bn = BN_new()) == NULL) |
| @@ -2648,7 +2688,7 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2648 | goto err; | 2688 | goto err; |
| 2649 | } | 2689 | } |
| 2650 | 2690 | ||
| 2651 | if ((BN_hex2bn(&hex_bn, hex)) != hex_len) { | 2691 | if ((BN_hex2bn(&hex_bn, key->hex)) == 0) { |
| 2652 | fprintf(stderr, "FAIL: BN_hex2bn() for %s\n", key->name); | 2692 | fprintf(stderr, "FAIL: BN_hex2bn() for %s\n", key->name); |
| 2653 | goto err; | 2693 | goto err; |
| 2654 | } | 2694 | } |
| @@ -2660,12 +2700,10 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2660 | } | 2700 | } |
| 2661 | 2701 | ||
| 2662 | /* | 2702 | /* |
| 2663 | * And translate back to a point on the curve. | 2703 | * Translate back to a point on the curve. |
| 2664 | */ | 2704 | */ |
| 2665 | 2705 | ||
| 2666 | EC_POINT_free(point); | 2706 | if ((point = EC_POINT_hex2point(group, key->hex, NULL, NULL)) == NULL) { |
| 2667 | point = NULL; | ||
| 2668 | if ((point = EC_POINT_hex2point(group, hex, NULL, NULL)) == NULL) { | ||
| 2669 | fprintf(stderr, "FAIL: EC_POINT_hex2point() failed for %s\n", | 2707 | fprintf(stderr, "FAIL: EC_POINT_hex2point() failed for %s\n", |
| 2670 | key->name); | 2708 | key->name); |
| 2671 | goto err; | 2709 | goto err; |
| @@ -2710,8 +2748,8 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2710 | goto err; | 2748 | goto err; |
| 2711 | } | 2749 | } |
| 2712 | 2750 | ||
| 2713 | if (EC_POINT_hex2point(group, hex, point, NULL) == NULL) { | 2751 | if (EC_POINT_hex2point(group, key->hex, point, NULL) == NULL) { |
| 2714 | fprintf(stderr, "FAIL: EC_POINT_hex2point() failed for %s\n", | 2752 | fprintf(stderr, "FAIL: EC_POINT_hex2point() 2 failed for %s\n", |
| 2715 | key->name); | 2753 | key->name); |
| 2716 | goto err; | 2754 | goto err; |
| 2717 | } | 2755 | } |
| @@ -2723,15 +2761,31 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2723 | goto err; | 2761 | goto err; |
| 2724 | } | 2762 | } |
| 2725 | 2763 | ||
| 2726 | free(hex); | 2764 | failed = 0; |
| 2727 | hex = NULL; | ||
| 2728 | 2765 | ||
| 2729 | freezero(ostr, ostr_len); | 2766 | err: |
| 2730 | ostr = NULL; | 2767 | BN_free(hex_bn); |
| 2768 | BN_free(point_bn); | ||
| 2769 | EC_POINT_free(point); | ||
| 2731 | 2770 | ||
| 2732 | /* | 2771 | return failed; |
| 2733 | * Round trip the public key through i2o and o2i in compressed form. | 2772 | } |
| 2734 | */ | 2773 | |
| 2774 | static int | ||
| 2775 | ec_key_test_i2o_and_o2i(const struct ec_private_key *key, const EC_KEY *ec_key_orig) | ||
| 2776 | { | ||
| 2777 | EC_KEY *ec_key = NULL, *ec_pub_key = NULL; | ||
| 2778 | const unsigned char *p; | ||
| 2779 | unsigned char *ostr = NULL; | ||
| 2780 | int ostr_len = 0; | ||
| 2781 | uint8_t form; | ||
| 2782 | int rv; | ||
| 2783 | int failed = 1; | ||
| 2784 | |||
| 2785 | if ((ec_key = EC_KEY_dup(ec_key_orig)) == NULL) { | ||
| 2786 | fprintf(stderr, "FAIL: EC_KEY_dup failed for %s", key->name); | ||
| 2787 | goto err; | ||
| 2788 | } | ||
| 2735 | 2789 | ||
| 2736 | EC_KEY_set_conv_form(ec_key, POINT_CONVERSION_COMPRESSED); | 2790 | EC_KEY_set_conv_form(ec_key, POINT_CONVERSION_COMPRESSED); |
| 2737 | 2791 | ||
| @@ -2776,6 +2830,37 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2776 | goto err; | 2830 | goto err; |
| 2777 | } | 2831 | } |
| 2778 | 2832 | ||
| 2833 | failed = 0; | ||
| 2834 | |||
| 2835 | err: | ||
| 2836 | EC_KEY_free(ec_key); | ||
| 2837 | EC_KEY_free(ec_pub_key); | ||
| 2838 | freezero(ostr, ostr_len); | ||
| 2839 | |||
| 2840 | return failed; | ||
| 2841 | } | ||
| 2842 | |||
| 2843 | static int | ||
| 2844 | ec_key_test_hybrid_roundtrip(const struct ec_private_key *key, | ||
| 2845 | const EC_KEY *ec_key_orig) | ||
| 2846 | { | ||
| 2847 | EC_KEY *ec_key = NULL, *ec_pub_key = NULL; | ||
| 2848 | const unsigned char *p; | ||
| 2849 | unsigned char *der = NULL; | ||
| 2850 | int der_len = 0; | ||
| 2851 | unsigned int flags; | ||
| 2852 | int rv; | ||
| 2853 | uint8_t form; | ||
| 2854 | int failed = 1; | ||
| 2855 | |||
| 2856 | if ((ec_key = EC_KEY_new()) == NULL) | ||
| 2857 | errx(1, "EC_KEY_new()"); | ||
| 2858 | |||
| 2859 | if (EC_KEY_copy(ec_key, ec_key_orig) == NULL) { | ||
| 2860 | fprintf(stderr, "FAIL: failed to kopy EC_KEY for %s\n", key->name); | ||
| 2861 | goto err; | ||
| 2862 | } | ||
| 2863 | |||
| 2779 | EC_KEY_set_conv_form(ec_key, POINT_CONVERSION_HYBRID); | 2864 | EC_KEY_set_conv_form(ec_key, POINT_CONVERSION_HYBRID); |
| 2780 | EC_KEY_set_enc_flags(ec_key, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY); | 2865 | EC_KEY_set_enc_flags(ec_key, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY); |
| 2781 | 2866 | ||
| @@ -2785,15 +2870,21 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2785 | goto err; | 2870 | goto err; |
| 2786 | } | 2871 | } |
| 2787 | 2872 | ||
| 2873 | if ((ec_pub_key = EC_KEY_new()) == NULL) | ||
| 2874 | errx(1, "EC_KEY_new"); | ||
| 2875 | if (!EC_KEY_set_group(ec_pub_key, EC_KEY_get0_group(ec_key))) { | ||
| 2876 | fprintf(stderr, "FAIL: EC_KEY_set_group() for %s\n", key->name); | ||
| 2877 | goto err; | ||
| 2878 | } | ||
| 2879 | /* Change away from the default to see if it changed below. */ | ||
| 2880 | EC_KEY_set_conv_form(ec_pub_key, POINT_CONVERSION_COMPRESSED); | ||
| 2881 | |||
| 2788 | if ((flags = EC_KEY_get_enc_flags(ec_pub_key)) != 0) { | 2882 | if ((flags = EC_KEY_get_enc_flags(ec_pub_key)) != 0) { |
| 2789 | fprintf(stderr, "FAIL: EC_KEY_get_enc_flags() returned %x for %s\n", | 2883 | fprintf(stderr, "FAIL: EC_KEY_get_enc_flags() returned %x for %s\n", |
| 2790 | flags, key->name); | 2884 | flags, key->name); |
| 2791 | goto err; | 2885 | goto err; |
| 2792 | } | 2886 | } |
| 2793 | 2887 | ||
| 2794 | /* Clear the public key - this returns failure, but works. */ | ||
| 2795 | (void)EC_KEY_set_public_key(ec_pub_key, NULL); | ||
| 2796 | |||
| 2797 | p = der; | 2888 | p = der; |
| 2798 | if (d2i_ECPrivateKey(&ec_pub_key, &p, der_len) == NULL) { | 2889 | if (d2i_ECPrivateKey(&ec_pub_key, &p, der_len) == NULL) { |
| 2799 | fprintf(stderr, "FAIL: d2i_ECPrivateKey for public %s\n", key->name); | 2890 | fprintf(stderr, "FAIL: d2i_ECPrivateKey for public %s\n", key->name); |
| @@ -2822,12 +2913,26 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2822 | goto err; | 2913 | goto err; |
| 2823 | } | 2914 | } |
| 2824 | 2915 | ||
| 2825 | /* | 2916 | failed = 0; |
| 2826 | * Also tickle the ECParameters API a little bit. | ||
| 2827 | */ | ||
| 2828 | 2917 | ||
| 2918 | err: | ||
| 2919 | EC_KEY_free(ec_key); | ||
| 2920 | EC_KEY_free(ec_pub_key); | ||
| 2829 | freezero(der, der_len); | 2921 | freezero(der, der_len); |
| 2830 | der = NULL; | 2922 | |
| 2923 | return failed; | ||
| 2924 | } | ||
| 2925 | |||
| 2926 | static int | ||
| 2927 | ec_key_test_parameter_roundtrip(const struct ec_private_key *key, | ||
| 2928 | EC_KEY *ec_key) | ||
| 2929 | { | ||
| 2930 | EC_KEY *ec_pub_key = NULL; | ||
| 2931 | const unsigned char *p; | ||
| 2932 | unsigned char *der = NULL; | ||
| 2933 | int der_len = 0; | ||
| 2934 | int rv; | ||
| 2935 | int failed = 1; | ||
| 2831 | 2936 | ||
| 2832 | if ((der_len = i2d_ECParameters(ec_key, &der)) <= 0) { | 2937 | if ((der_len = i2d_ECParameters(ec_key, &der)) <= 0) { |
| 2833 | fprintf(stderr, "FAIL: i2d_ECParameters returned %d for %s\n", | 2938 | fprintf(stderr, "FAIL: i2d_ECParameters returned %d for %s\n", |
| @@ -2835,7 +2940,10 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2835 | goto err; | 2940 | goto err; |
| 2836 | } | 2941 | } |
| 2837 | 2942 | ||
| 2838 | /* Deliberately don't free ec_pub_key to see if we don't leak. */ | 2943 | /* See if we leak on reuse, whether the curve is right or not. */ |
| 2944 | if ((ec_pub_key = EC_KEY_new_by_curve_name(NID_secp256k1)) == NULL) | ||
| 2945 | errx(1, "EC_KEY_new_by_curve_name"); | ||
| 2946 | |||
| 2839 | p = der; | 2947 | p = der; |
| 2840 | if (d2i_ECParameters(&ec_pub_key, &p, der_len) == NULL) { | 2948 | if (d2i_ECParameters(&ec_pub_key, &p, der_len) == NULL) { |
| 2841 | fprintf(stderr, "FAIL: d2i_ECParameters for %s\n", key->name); | 2949 | fprintf(stderr, "FAIL: d2i_ECParameters for %s\n", key->name); |
| @@ -2852,17 +2960,32 @@ ec_group_check_private_key(const struct ec_private_key *key) | |||
| 2852 | failed = 0; | 2960 | failed = 0; |
| 2853 | 2961 | ||
| 2854 | err: | 2962 | err: |
| 2855 | EC_KEY_free(ec_key); | ||
| 2856 | EC_KEY_free(ec_pub_key); | 2963 | EC_KEY_free(ec_pub_key); |
| 2857 | |||
| 2858 | freezero(der, der_len); | 2964 | freezero(der, der_len); |
| 2859 | freezero(ostr, ostr_len); | ||
| 2860 | free(hex); | ||
| 2861 | 2965 | ||
| 2862 | BN_free(hex_bn); | 2966 | return failed; |
| 2863 | BN_free(point_bn); | 2967 | } |
| 2864 | 2968 | ||
| 2865 | EC_POINT_free(point); | 2969 | static int |
| 2970 | ec_group_check_private_key(const struct ec_private_key *key) | ||
| 2971 | { | ||
| 2972 | EC_KEY *ec_key = NULL; | ||
| 2973 | int failed = 0; | ||
| 2974 | |||
| 2975 | if ((ec_key = ec_key_check_sanity(key)) == NULL) { | ||
| 2976 | fprintf(stderr, "FAIL: ec_key_check_sanity() for %s\n", key->name); | ||
| 2977 | failed = 1; | ||
| 2978 | goto err; | ||
| 2979 | } | ||
| 2980 | |||
| 2981 | failed |= ec_key_test_point_encoding(key, ec_key); | ||
| 2982 | failed |= ec_key_test_point_versus_bn(key, ec_key); | ||
| 2983 | failed |= ec_key_test_i2o_and_o2i(key, ec_key); | ||
| 2984 | failed |= ec_key_test_hybrid_roundtrip(key, ec_key); | ||
| 2985 | failed |= ec_key_test_parameter_roundtrip(key, ec_key); | ||
| 2986 | |||
| 2987 | err: | ||
| 2988 | EC_KEY_free(ec_key); | ||
| 2866 | 2989 | ||
| 2867 | return failed; | 2990 | return failed; |
| 2868 | } | 2991 | } |
