diff options
author | tb <> | 2024-10-29 13:19:22 +0000 |
---|---|---|
committer | tb <> | 2024-10-29 13:19:22 +0000 |
commit | 16ff4ccc2611ac3387e5353ab9ca88ecb4a47734 (patch) | |
tree | a5866b63bf5fd94c8dee2299a8338b85afc61e45 /src | |
parent | 70850c047f141cf86dd9dc4ed010b2a352b5036b (diff) | |
download | openbsd-16ff4ccc2611ac3387e5353ab9ca88ecb4a47734.tar.gz openbsd-16ff4ccc2611ac3387e5353ab9ca88ecb4a47734.tar.bz2 openbsd-16ff4ccc2611ac3387e5353ab9ca88ecb4a47734.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 | } |