summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2025-09-08 08:11:49 +0000
committertb <>2025-09-08 08:11:49 +0000
commit731703a848224f9ac266b1a4d87d2d47caf9c57d (patch)
tree99702660ce7c8d74dbe0f9726757ab74634f5fe5 /src
parent50734a3ae2c1320cf87d475e9d62636b532c8e90 (diff)
downloadopenbsd-731703a848224f9ac266b1a4d87d2d47caf9c57d.tar.gz
openbsd-731703a848224f9ac266b1a4d87d2d47caf9c57d.tar.bz2
openbsd-731703a848224f9ac266b1a4d87d2d47caf9c57d.zip
wycheproof: rework test selection
Since this has grown organically, the test selection has become a weird mix of globs, regexes and test variants and it is hard to reason about what is run and why. Instead, load all the json files from testvectors_v1/ and look at algorithm (almost always available) and test schema to figure out if we support it in libcrypto and the test harness. This separates the logic of the test runner better from the test selection. Also make it a fatal error if we don't explicitly skip an unknown algorithm.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go151
1 files changed, 82 insertions, 69 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index 4b0a4c587c..db31383bc8 100644
--- a/src/regress/lib/libcrypto/wycheproof/wycheproof.go
+++ b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
@@ -1,4 +1,4 @@
1/* $OpenBSD: wycheproof.go,v 1.188 2025/09/08 08:00:47 tb Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.189 2025/09/08 08:11:49 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018,2023 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018,2023 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2018,2019,2022-2025 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2018,2019,2022-2025 Theo Buehler <tb@openbsd.org>
@@ -84,7 +84,6 @@ import (
84 "math/big" 84 "math/big"
85 "os" 85 "os"
86 "path/filepath" 86 "path/filepath"
87 "regexp"
88 "runtime" 87 "runtime"
89 "strings" 88 "strings"
90 "sync" 89 "sync"
@@ -2752,14 +2751,28 @@ func testGroupFromTestVector(wtv *wycheproofTestVectorsV1) (wycheproofTestGroupR
2752 variant := Normal 2751 variant := Normal
2753 2752
2754 switch wtv.Algorithm { 2753 switch wtv.Algorithm {
2754 case "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512":
2755 return nil, Skip
2756 case "AEGIS128", "AEGIS128L", "AEGIS256":
2757 return nil, Skip
2758 case "AEAD-AES-SIV-CMAC":
2759 return nil, Skip
2755 case "AES-CBC-PKCS5": 2760 case "AES-CBC-PKCS5":
2756 return &wycheproofTestGroupAesCbcPkcs5{}, variant 2761 return &wycheproofTestGroupAesCbcPkcs5{}, variant
2757 case "AES-CCM", "AES-GCM": 2762 case "AES-CCM", "AES-GCM":
2758 return &wycheproofTestGroupAesAead{}, variant 2763 return &wycheproofTestGroupAesAead{}, variant
2759 case "AES-CMAC": 2764 case "AES-CMAC":
2760 return &wycheproofTestGroupAesCmac{}, variant 2765 return &wycheproofTestGroupAesCmac{}, variant
2766 case "AES-EAX", "AES-FF1", "AES-GCM-SIV", "AES-GMAC", "AES-KWP", "AES-SIV-CMAC", "AES-XTS":
2767 return nil, Skip
2761 case "AES-WRAP": 2768 case "AES-WRAP":
2762 return &wycheproofTestGroupKW{}, variant 2769 return &wycheproofTestGroupKW{}, variant
2770 case "ARIA-CBC-PKCS5", "ARIA-CCM", "ARIA-CMAC", "ARIA-GCM", "ARIA-KWP", "ARIA-WRAP":
2771 return nil, Skip
2772 case "ASCON128", "ASCON128A", "ASCON80PQ":
2773 return nil, Skip
2774 case "CAMELLIA-CBC-PKCS5", "CAMELLIA-CCM", "CAMELLIA-CMAC", "CAMELLIA-WRAP":
2775 return nil, Skip
2763 case "CHACHA20-POLY1305", "XCHACHA20-POLY1305": 2776 case "CHACHA20-POLY1305", "XCHACHA20-POLY1305":
2764 return &wycheproofTestGroupChaCha{}, variant 2777 return &wycheproofTestGroupChaCha{}, variant
2765 case "DSA": 2778 case "DSA":
@@ -2776,8 +2789,14 @@ func testGroupFromTestVector(wtv *wycheproofTestVectorsV1) (wycheproofTestGroupR
2776 if wtv.Schema == "ecdh_ecpoint_test_schema_v1.json" { 2789 if wtv.Schema == "ecdh_ecpoint_test_schema_v1.json" {
2777 variant = EcPoint 2790 variant = EcPoint
2778 } 2791 }
2792 if wtv.Schema == "ecdh_pem_test_schema_v1.json" {
2793 variant = Skip
2794 }
2779 return &wycheproofTestGroupECDH{}, variant 2795 return &wycheproofTestGroupECDH{}, variant
2780 case "ECDSA": 2796 case "ECDSA":
2797 if wtv.Schema == "ecdsa_bitcoin_verify_schema.json" {
2798 variant = Skip
2799 }
2781 if wtv.Schema == "ecdsa_p1363_verify_schema_v1.json" { 2800 if wtv.Schema == "ecdsa_p1363_verify_schema_v1.json" {
2782 variant = P1363 2801 variant = P1363
2783 } 2802 }
@@ -2788,6 +2807,21 @@ func testGroupFromTestVector(wtv *wycheproofTestVectorsV1) (wycheproofTestGroupR
2788 return &wycheproofTestGroupHkdf{}, variant 2807 return &wycheproofTestGroupHkdf{}, variant
2789 case "HMACSHA1", "HMACSHA224", "HMACSHA256", "HMACSHA384", "HMACSHA512", "HMACSHA512/224", "HMACSHA512/256", "HMACSHA3-224", "HMACSHA3-256", "HMACSHA3-384", "HMACSHA3-512": 2808 case "HMACSHA1", "HMACSHA224", "HMACSHA256", "HMACSHA384", "HMACSHA512", "HMACSHA512/224", "HMACSHA512/256", "HMACSHA3-224", "HMACSHA3-256", "HMACSHA3-384", "HMACSHA3-512":
2790 return &wycheproofTestGroupHmac{}, variant 2809 return &wycheproofTestGroupHmac{}, variant
2810 case "HMACSM3":
2811 return nil, Skip
2812 case "KMAC128", "KMAC256":
2813 return nil, Skip
2814 case "ML-DSA-44", "ML-DSA-65", "ML-DSA-87":
2815 return nil, Skip
2816 case "ML-KEM":
2817 return nil, Skip
2818 case "MORUS640", "MORUS1280":
2819 return nil, Skip
2820 case "PbeWithHmacSha1AndAes_128", "PbeWithHmacSha1AndAes_192", "PbeWithHmacSha1AndAes_256", "PbeWithHmacSha224AndAes_128", "PbeWithHmacSha224AndAes_192", "PbeWithHmacSha224AndAes_256", "PbeWithHmacSha256AndAes_128", "PbeWithHmacSha256AndAes_192", "PbeWithHmacSha256AndAes_256", "PbeWithHmacSha384AndAes_128", "PbeWithHmacSha384AndAes_192", "PbeWithHmacSha384AndAes_256", "PbeWithHmacSha512AndAes_128", "PbeWithHmacSha512AndAes_192", "PbeWithHmacSha512AndAes_256":
2821 return nil, Skip
2822
2823 case "PBKDF2-HMACSHA1", "PBKDF2-HMACSHA224", "PBKDF2-HMACSHA256", "PBKDF2-HMACSHA384", "PBKDF2-HMACSHA512":
2824 return nil, Skip
2791 case "PrimalityTest": 2825 case "PrimalityTest":
2792 return &wycheproofTestGroupPrimality{}, variant 2826 return &wycheproofTestGroupPrimality{}, variant
2793 case "RSAES-OAEP": 2827 case "RSAES-OAEP":
@@ -2798,16 +2832,32 @@ func testGroupFromTestVector(wtv *wycheproofTestVectorsV1) (wycheproofTestGroupR
2798 return &wycheproofTestGroupRsassa{}, variant 2832 return &wycheproofTestGroupRsassa{}, variant
2799 case "RSASSA-PKCS1-v1_5", "RSASig": 2833 case "RSASSA-PKCS1-v1_5", "RSASig":
2800 return &wycheproofTestGroupRSA{}, variant 2834 return &wycheproofTestGroupRSA{}, variant
2801 case "XDH", "X25519": 2835 case "SEED-CCM", "SEED-GCM", "SEED-WRAP":
2836 return nil, Skip
2837 case "SipHash-1-3", "SipHash-2-4", "SipHash-4-8", "SipHashX-2-4", "SipHashX-4-8":
2838 return nil, Skip
2839 case "SM4-CCM", "SM4-GCM":
2840 return nil, Skip
2841 case "VMAC-AES":
2842 return nil, Skip
2843 case "XDH":
2844 switch wtv.Schema {
2845 case "xdh_asn_comp_schema_v1.json", "xdh_jwk_comp_schema_v1.json", "xdh_pem_comp_schema_v1.json":
2846 variant = Skip
2847 case "xdh_comp_schema_v1.json":
2848 variant = Normal
2849 }
2802 return &wycheproofTestGroupX25519{}, variant 2850 return &wycheproofTestGroupX25519{}, variant
2803 default: 2851 default:
2804 return nil, Skip 2852 // XXX - JOSE tests don't set an Algorithm...
2853 if strings.HasPrefix(wtv.Schema, "json_web_") {
2854 return nil, Skip
2855 }
2856 return nil, Normal
2805 } 2857 }
2806} 2858}
2807 2859
2808func runTestVectors(path string) bool { 2860func runTestVectors(path string) bool {
2809 var algorithm string
2810 var testGroups []json.RawMessage
2811 b, err := ioutil.ReadFile(path) 2861 b, err := ioutil.ReadFile(path)
2812 if err != nil { 2862 if err != nil {
2813 log.Fatalf("Failed to read test vectors: %v", err) 2863 log.Fatalf("Failed to read test vectors: %v", err)
@@ -2816,25 +2866,26 @@ func runTestVectors(path string) bool {
2816 if err := json.Unmarshal(b, wtv); err != nil { 2866 if err := json.Unmarshal(b, wtv); err != nil {
2817 log.Fatalf("Failed to unmarshal JSON: %v", err) 2867 log.Fatalf("Failed to unmarshal JSON: %v", err)
2818 } 2868 }
2819 algorithm = wtv.Algorithm
2820 testGroups = wtv.TestGroups
2821 fmt.Printf("Loaded Wycheproof test vectors for %v with %d tests from %q\n", wtv.Algorithm, wtv.NumberOfTests, filepath.Base(path)) 2869 fmt.Printf("Loaded Wycheproof test vectors for %v with %d tests from %q\n", wtv.Algorithm, wtv.NumberOfTests, filepath.Base(path))
2822 2870
2823 success := true 2871 success := true
2824 for _, tg := range testGroups { 2872 for _, tg := range wtv.TestGroups {
2825 wtg, variant := testGroupFromTestVector(wtv) 2873 wtg, variant := testGroupFromTestVector(wtv)
2874 if variant == Skip {
2875 fmt.Printf("INFO: Skipping tests from \"%s\"\n", filepath.Base(path))
2876 return true
2877 }
2826 if wtg == nil { 2878 if wtg == nil {
2827 log.Printf("INFO: Unknown test vector algorithm %q", algorithm) 2879 log.Fatalf("INFO: Unknown test vector algorithm %qin \"%s\"", wtv.Algorithm, filepath.Base(path))
2828 return false
2829 } 2880 }
2830 if err := json.Unmarshal(tg, wtg); err != nil { 2881 if err := json.Unmarshal(tg, wtg); err != nil {
2831 log.Fatalf("Failed to unmarshal test groups JSON: %v", err) 2882 log.Fatalf("Failed to unmarshal test groups JSON: %v", err)
2832 } 2883 }
2833 testc.runTest(func() bool { 2884 testc.runTest(func() bool {
2834 return wtg.run(algorithm, variant) 2885 return wtg.run(wtv.Algorithm, variant)
2835 }) 2886 })
2836 } 2887 }
2837 for _ = range testGroups { 2888 for _ = range wtv.TestGroups {
2838 result := <-testc.resultCh 2889 result := <-testc.resultCh
2839 if !result { 2890 if !result {
2840 success = false 2891 success = false
@@ -2886,36 +2937,6 @@ func main() {
2886 os.Exit(0) 2937 os.Exit(0)
2887 } 2938 }
2888 2939
2889 tests := []struct {
2890 name string
2891 pattern string
2892 variant testVariant
2893 }{
2894 {"AES", "aes_[cg]*[^xv]_test.json", Normal}, // Skip AES-EAX, AES-GCM-SIV and AES-SIV-CMAC.
2895 {"AES-WRAP", "aes_wrap_test.json", Normal},
2896 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json", Normal},
2897 {"DSA", "dsa_*test.json", Normal},
2898 {"DSA", "dsa_*_p1363_test.json", P1363},
2899 {"EcCurveTest", "ec_prime_order_curves_test.json", Normal},
2900 {"ECDH", "ecdh_[^w_]*_test.json", Normal},
2901 {"ECDH EcPoint", "ecdh_*_ecpoint_test.json", EcPoint},
2902 {"ECDH webcrypto", "ecdh_*_webcrypto_test.json", Webcrypto},
2903 {"ECDSA", "ecdsa_[^w]*test.json", Normal},
2904 {"ECDSA P1363", "ecdsa_*_sha[1-9][1-9][1-9]_p1363_test.json", P1363},
2905 {"ECDSA shake", "ecdsa_*_shake*_test.json", Skip},
2906 {"EDDSA", "ed25519_test.json", Normal},
2907 {"ED448", "ed448_test.json", Skip},
2908 {"HKDF", "hkdf_sha*_test.json", Normal},
2909 {"HMAC", "hmac_sha*_test.json", Normal},
2910 {"Primality test", "primality_test.json", Normal},
2911 {"RSA", "rsa_*test.json", Normal},
2912 {"X25519", "x25519_test.json", Normal},
2913 {"X25519 ASN", "x25519_asn_test.json", Skip},
2914 {"X25519 JWK", "x25519_jwk_test.json", Skip},
2915 {"X25519 PEM", "x25519_pem_test.json", Skip},
2916 {"XCHACHA20-POLY1305", "xchacha20_poly1305_test.json", Normal},
2917 }
2918
2919 success := true 2940 success := true
2920 2941
2921 var wg sync.WaitGroup 2942 var wg sync.WaitGroup
@@ -2928,33 +2949,25 @@ func main() {
2928 2949
2929 testc = newTestCoordinator() 2950 testc = newTestCoordinator()
2930 2951
2931 skipNormal := regexp.MustCompile(`_(ecpoint|webcrypto|pem|bitcoin|shake\d{3}|gmac|p1363|sect\d{3}[rk]1|secp(160|192))_`) 2952 tvs, err := filepath.Glob(filepath.Join(path, "*.json"))
2932 2953 if err != nil {
2933 for _, test := range tests { 2954 log.Fatalf("Failed to glob test vectors: %v", err)
2934 tvs, err := filepath.Glob(filepath.Join(path, test.pattern)) 2955 }
2935 if err != nil { 2956 if len(tvs) == 0 {
2936 log.Fatalf("Failed to glob %v test vectors: %v", test.name, err) 2957 log.Fatalf("Failed to find test vectors at %q\n", path)
2937 } 2958 }
2938 if len(tvs) == 0 { 2959 for _, tv := range tvs {
2939 log.Fatalf("Failed to find %v test vectors at %q\n", test.name, path) 2960 wg.Add(1)
2940 } 2961 <-vectorsRateLimitCh
2941 for _, tv := range tvs { 2962 go func(tv string) {
2942 if test.variant == Skip || (test.variant == Normal && skipNormal.Match([]byte(tv))) { 2963 select {
2943 fmt.Printf("INFO: Skipping tests from \"%s\"\n", strings.TrimPrefix(tv, path+"/")) 2964 case resultCh <- runTestVectors(tv):
2944 continue 2965 default:
2966 log.Fatal("result channel is full")
2945 } 2967 }
2946 wg.Add(1) 2968 vectorsRateLimitCh <- true
2947 <-vectorsRateLimitCh 2969 wg.Done()
2948 go func(tv string) { 2970 }(tv)
2949 select {
2950 case resultCh <- runTestVectors(tv):
2951 default:
2952 log.Fatal("result channel is full")
2953 }
2954 vectorsRateLimitCh <- true
2955 wg.Done()
2956 }(tv)
2957 }
2958 } 2971 }
2959 2972
2960 wg.Wait() 2973 wg.Wait()