internal: remove wycheproof tests Equivalent coverage using newer Wycheproof vectors has been added to the standard library, alongside the implementations under test. In the case where the algorithm doesn't exist in the stdlib, but is intended to be supported there one day (e.g. chacha20poly1305) we flip the relationship and run the Wycheproof tests from the stdlib on the vendored /x/crypto. As a result the legacy Wycheproof coverage in this repo can be removed. Change-Id: Ic07d559e42599b715906f5bcc39be10944a8dde4 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/758420 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Filippo Valsorda <filippo@golang.org> Auto-Submit: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: Roland Shoemaker <roland@golang.org>
diff --git a/internal/wycheproof/README.md b/internal/wycheproof/README.md deleted file mode 100644 index 8ae6c6c..0000000 --- a/internal/wycheproof/README.md +++ /dev/null
@@ -1,12 +0,0 @@ -This package runs a set of the Wycheproof tests provided by -https://github.com/google/wycheproof. - -The JSON test files live in -https://github.com/google/wycheproof/tree/master/testvectors -and are being fetched and cached at a pinned version every time -these tests are run. To change the version of the wycheproof -repository that is being used for testing, update wycheproofModVer. - -The structs for these tests are generated from the -schemas provided in https://github.com/google/wycheproof/tree/master/schemas -using https://github.com/a-h/generate. \ No newline at end of file
diff --git a/internal/wycheproof/aead_test.go b/internal/wycheproof/aead_test.go deleted file mode 100644 index 292d854..0000000 --- a/internal/wycheproof/aead_test.go +++ /dev/null
@@ -1,176 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "fmt" - "testing" - - "golang.org/x/crypto/chacha20poly1305" -) - -func TestAEAD(t *testing.T) { - // AeadTestVector - type AeadTestVector struct { - - // additional authenticated data - Aad string `json:"aad,omitempty"` - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // the ciphertext (without iv and tag) - Ct string `json:"ct,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // the nonce - Iv string `json:"iv,omitempty"` - - // the key - Key string `json:"key,omitempty"` - - // the plaintext - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // the authentication tag - Tag string `json:"tag,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // AeadTestGroup - type AeadTestGroup struct { - - // the IV size in bits - IvSize int `json:"ivSize,omitempty"` - - // the keySize in bits - KeySize int `json:"keySize,omitempty"` - - // the expected size of the tag in bits - TagSize int `json:"tagSize,omitempty"` - Tests []*AeadTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*AeadTestGroup `json:"testGroups,omitempty"` - } - - testSealOpen := func(t *testing.T, aead cipher.AEAD, tv *AeadTestVector, recoverBadNonce func()) { - defer recoverBadNonce() - - iv, tag, ct, msg, aad := decodeHex(tv.Iv), decodeHex(tv.Tag), decodeHex(tv.Ct), decodeHex(tv.Msg), decodeHex(tv.Aad) - - genCT := aead.Seal(nil, iv, msg, aad) - genMsg, err := aead.Open(nil, iv, genCT, aad) - if err != nil { - t.Errorf("failed to decrypt generated ciphertext: %s", err) - } - if !bytes.Equal(genMsg, msg) { - t.Errorf("unexpected roundtripped plaintext: got %x, want %x", genMsg, msg) - } - - ctWithTag := append(ct, tag...) - msg2, err := aead.Open(nil, iv, ctWithTag, aad) - wantPass := shouldPass(tv.Result, tv.Flags, nil) - if !wantPass && err == nil { - t.Error("decryption succeeded when it should've failed") - } else if wantPass { - if err != nil { - t.Fatalf("decryption failed: %s", err) - } - if !bytes.Equal(genCT, ctWithTag) { - t.Errorf("generated ciphertext doesn't match expected: got %x, want %x", genCT, ctWithTag) - } - if !bytes.Equal(msg, msg2) { - t.Errorf("decrypted ciphertext doesn't match expected: got %x, want %x", msg2, msg) - } - } - } - - vectors := map[string]func(*testing.T, []byte) cipher.AEAD{ - "aes_gcm_test.json": func(t *testing.T, key []byte) cipher.AEAD { - aesCipher, err := aes.NewCipher(key) - if err != nil { - t.Fatalf("failed to construct cipher: %s", err) - } - aead, err := cipher.NewGCM(aesCipher) - if err != nil { - t.Fatalf("failed to construct cipher: %s", err) - } - return aead - }, - "chacha20_poly1305_test.json": func(t *testing.T, key []byte) cipher.AEAD { - aead, err := chacha20poly1305.New(key) - if err != nil { - t.Fatalf("failed to construct cipher: %s", err) - } - return aead - }, - "xchacha20_poly1305_test.json": func(t *testing.T, key []byte) cipher.AEAD { - aead, err := chacha20poly1305.NewX(key) - if err != nil { - t.Fatalf("failed to construct cipher: %s", err) - } - return aead - }, - } - for file, cipherInit := range vectors { - var root Root - readTestVector(t, file, &root) - for _, tg := range root.TestGroups { - for _, tv := range tg.Tests { - testName := fmt.Sprintf("%s #%d", file, tv.TcId) - if tv.Comment != "" { - testName += fmt.Sprintf(" %s", tv.Comment) - } - t.Run(testName, func(t *testing.T) { - aead := cipherInit(t, decodeHex(tv.Key)) - testSealOpen(t, aead, tv, func() { - // A bad nonce causes a panic in AEAD.Seal and AEAD.Open, - // so should be recovered. Fail the test if it broke for - // some other reason. - if r := recover(); r != nil { - if tg.IvSize/8 == aead.NonceSize() { - t.Error("unexpected panic") - } - } - }) - }) - } - } - } -}
diff --git a/internal/wycheproof/aes_cbc_test.go b/internal/wycheproof/aes_cbc_test.go deleted file mode 100644 index 0a60fc3..0000000 --- a/internal/wycheproof/aes_cbc_test.go +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "crypto/aes" - "crypto/cipher" - "encoding/hex" - "fmt" - "testing" -) - -func TestAesCbc(t *testing.T) { - // IndCpaTestVector - type IndCpaTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // the raw ciphertext (without IV) - Ct string `json:"ct,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // the initialization vector - Iv string `json:"iv,omitempty"` - - // the key - Key string `json:"key,omitempty"` - - // the plaintext - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // IndCpaTestGroup - type IndCpaTestGroup struct { - - // the IV size in bits - IvSize int `json:"ivSize,omitempty"` - - // the keySize in bits - KeySize int `json:"keySize,omitempty"` - - // the expected size of the tag in bits - TagSize int `json:"tagSize,omitempty"` - Tests []*IndCpaTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*IndCpaTestGroup `json:"testGroups,omitempty"` - } - - var root Root - readTestVector(t, "aes_cbc_pkcs5_test.json", &root) - for _, tg := range root.TestGroups { - tests: - for _, tv := range tg.Tests { - block, err := aes.NewCipher(decodeHex(tv.Key)) - if err != nil { - t.Fatalf("#%d: %v", tv.TcId, err) - } - mode := cipher.NewCBCDecrypter(block, decodeHex(tv.Iv)) - ct := decodeHex(tv.Ct) - if len(ct)%aes.BlockSize != 0 { - panic(fmt.Sprintf("#%d: ciphertext is not a multiple of the block size", tv.TcId)) - } - mode.CryptBlocks(ct, ct) // decrypt the block in place - - // Skip the tests that are broken due to bad padding. Panic if there are any - // tests left that are invalid for some other reason in the future, to - // evaluate what to do with those tests. - for _, flag := range tv.Flags { - if flag == "BadPadding" { - continue tests - } - } - if !shouldPass(tv.Result, tv.Flags, nil) { - panic(fmt.Sprintf("#%d: found an invalid test that is broken for some reason other than bad padding", tv.TcId)) - } - - // Remove the PKCS#5 padding from the given ciphertext to validate it - padding := ct[len(ct)-1] - paddingNum := int(padding) - for i := paddingNum; i > 0; i-- { - if ct[len(ct)-i] != padding { // panic if the padding is unexpectedly bad - panic(fmt.Sprintf("#%d: bad padding at index=%d of %v", tv.TcId, i, ct)) - } - } - ct = ct[:len(ct)-paddingNum] - - if got, want := hex.EncodeToString(ct), tv.Msg; got != want { - t.Errorf("#%d, type: %s, comment: %q, decoded ciphertext not equal: %s, want %s", tv.TcId, tv.Result, tv.Comment, got, want) - } - } - } -}
diff --git a/internal/wycheproof/boring.go b/internal/wycheproof/boring.go deleted file mode 100644 index aefa3ab..0000000 --- a/internal/wycheproof/boring.go +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build boringcrypto - -package wycheproof - -const boringcryptoEnabled = true
diff --git a/internal/wycheproof/dsa_test.go b/internal/wycheproof/dsa_test.go deleted file mode 100644 index e554708..0000000 --- a/internal/wycheproof/dsa_test.go +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "crypto/dsa" - "testing" - - wdsa "golang.org/x/crypto/internal/wycheproof/internal/dsa" -) - -func TestDsa(t *testing.T) { - // AsnSignatureTestVector - type AsnSignatureTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // The message to sign - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // An ASN encoded signature for msg - Sig string `json:"sig,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // DsaPublicKey - type DsaPublicKey struct { - - // the generator of the multiplicative subgroup - G string `json:"g,omitempty"` - - // the key size in bits - KeySize int `json:"keySize,omitempty"` - - // the modulus p - P string `json:"p,omitempty"` - - // the order of the generator g - Q string `json:"q,omitempty"` - - // the key type - Type string `json:"type,omitempty"` - - // the public key value - Y string `json:"y,omitempty"` - } - - // DsaTestGroup - type DsaTestGroup struct { - - // unenocded DSA public key - Key *DsaPublicKey `json:"key,omitempty"` - - // DER encoded public key - KeyDer string `json:"keyDer,omitempty"` - - // Pem encoded public key - KeyPem string `json:"keyPem,omitempty"` - - // the hash function used for DSA - Sha string `json:"sha,omitempty"` - Tests []*AsnSignatureTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*DsaTestGroup `json:"testGroups,omitempty"` - } - - flagsShouldPass := map[string]bool{ - // An encoded ASN.1 integer missing a leading zero is invalid, but accepted by some implementations. - "NoLeadingZero": false, - } - - var root Root - readTestVector(t, "dsa_test.json", &root) - for _, tg := range root.TestGroups { - pub := decodePublicKey(tg.KeyDer).(*dsa.PublicKey) - h := parseHash(tg.Sha).New() - for _, sig := range tg.Tests { - h.Reset() - h.Write(decodeHex(sig.Msg)) - hashed := h.Sum(nil) - hashed = hashed[:pub.Q.BitLen()/8] // Truncate to the byte-length of the subgroup (Q) - got := wdsa.VerifyASN1(pub, hashed, decodeHex(sig.Sig)) - if want := shouldPass(sig.Result, sig.Flags, flagsShouldPass); got != want { - t.Errorf("tcid: %d, type: %s, comment: %q, wanted success: %t", sig.TcId, sig.Result, sig.Comment, want) - } - } - } -}
diff --git a/internal/wycheproof/ecdh_stdlib_test.go b/internal/wycheproof/ecdh_stdlib_test.go deleted file mode 100644 index 24a83e2..0000000 --- a/internal/wycheproof/ecdh_stdlib_test.go +++ /dev/null
@@ -1,140 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "bytes" - "crypto/ecdh" - "fmt" - "testing" -) - -func TestECDHStdLib(t *testing.T) { - type ECDHTestVector struct { - // A brief description of the test case - Comment string `json:"comment,omitempty"` - // A list of flags - Flags []string `json:"flags,omitempty"` - // the private key - Private string `json:"private,omitempty"` - // Encoded public key - Public string `json:"public,omitempty"` - // Test result - Result string `json:"result,omitempty"` - // The shared secret key - Shared string `json:"shared,omitempty"` - // Identifier of the test case - TcID int `json:"tcId,omitempty"` - } - - type ECDHTestGroup struct { - Curve string `json:"curve,omitempty"` - Tests []*ECDHTestVector `json:"tests,omitempty"` - } - - type Root struct { - TestGroups []*ECDHTestGroup `json:"testGroups,omitempty"` - } - - flagsShouldPass := map[string]bool{ - // We don't support compressed points. - "CompressedPoint": false, - // We don't support decoding custom curves. - "UnnamedCurve": false, - // WrongOrder and UnusedParam are only found with UnnamedCurve. - "WrongOrder": false, - "UnusedParam": false, - - // X25519 specific flags - "Twist": true, - "SmallPublicKey": false, - "LowOrderPublic": false, - "ZeroSharedSecret": false, - "NonCanonicalPublic": true, - } - - // curveToCurve is a map of all elliptic curves supported - // by crypto/elliptic, which can subsequently be parsed and tested. - curveToCurve := map[string]ecdh.Curve{ - "secp256r1": ecdh.P256(), - "secp384r1": ecdh.P384(), - "secp521r1": ecdh.P521(), - "curve25519": ecdh.X25519(), - } - - curveToKeySize := map[string]int{ - "secp256r1": 32, - "secp384r1": 48, - "secp521r1": 66, - "curve25519": 32, - } - - for _, f := range []string{ - "ecdh_secp256r1_ecpoint_test.json", - "ecdh_secp384r1_ecpoint_test.json", - "ecdh_secp521r1_ecpoint_test.json", - "x25519_test.json", - } { - var root Root - readTestVector(t, f, &root) - for _, tg := range root.TestGroups { - if _, ok := curveToCurve[tg.Curve]; !ok { - continue - } - for _, tt := range tg.Tests { - tg, tt := tg, tt - t.Run(fmt.Sprintf("%s/%d", tg.Curve, tt.TcID), func(t *testing.T) { - t.Logf("Type: %v", tt.Result) - t.Logf("Flags: %q", tt.Flags) - t.Log(tt.Comment) - - shouldPass := shouldPass(tt.Result, tt.Flags, flagsShouldPass) - - curve := curveToCurve[tg.Curve] - p := decodeHex(tt.Public) - pub, err := curve.NewPublicKey(p) - if err != nil { - if shouldPass { - t.Errorf("NewPublicKey: %v", err) - } - return - } - - privBytes := decodeHex(tt.Private) - if len(privBytes) != curveToKeySize[tg.Curve] { - t.Skipf("non-standard key size %d", len(privBytes)) - } - - priv, err := curve.NewPrivateKey(privBytes) - if err != nil { - if shouldPass { - t.Errorf("NewPrivateKey: %v", err) - } - return - } - - shared := decodeHex(tt.Shared) - x, err := priv.ECDH(pub) - if err != nil { - if tg.Curve == "curve25519" && !shouldPass { - // ECDH is expected to only return an error when using X25519, - // in all other cases an error is unexpected. - return - } - t.Fatalf("ECDH: %v", err) - } - - if bytes.Equal(shared, x) != shouldPass { - if shouldPass { - t.Errorf("ECDH = %x, want %x", shared, x) - } else { - t.Errorf("ECDH = %x, want anything else", shared) - } - } - }) - } - } - } -}
diff --git a/internal/wycheproof/ecdh_test.go b/internal/wycheproof/ecdh_test.go deleted file mode 100644 index a3918ba..0000000 --- a/internal/wycheproof/ecdh_test.go +++ /dev/null
@@ -1,163 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "bytes" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/x509" - "encoding/asn1" - "errors" - "fmt" - "testing" - - "golang.org/x/crypto/cryptobyte" - casn1 "golang.org/x/crypto/cryptobyte/asn1" -) - -func TestECDH(t *testing.T) { - type ECDHTestVector struct { - // A brief description of the test case - Comment string `json:"comment,omitempty"` - // A list of flags - Flags []string `json:"flags,omitempty"` - // the private key - Private string `json:"private,omitempty"` - // Encoded public key - Public string `json:"public,omitempty"` - // Test result - Result string `json:"result,omitempty"` - // The shared secret key - Shared string `json:"shared,omitempty"` - // Identifier of the test case - TcID int `json:"tcId,omitempty"` - } - - type ECDHTestGroup struct { - Curve string `json:"curve,omitempty"` - Tests []*ECDHTestVector `json:"tests,omitempty"` - } - - type Root struct { - TestGroups []*ECDHTestGroup `json:"testGroups,omitempty"` - } - - flagsShouldPass := map[string]bool{ - // ParsePKIXPublicKey doesn't support compressed points, but we test - // them against UnmarshalCompressed anyway. - "CompressedPoint": true, - // We don't support decoding custom curves. - "UnnamedCurve": false, - // WrongOrder and UnusedParam are only found with UnnamedCurve. - "WrongOrder": false, - "UnusedParam": false, - } - - // supportedCurves is a map of all elliptic curves supported - // by crypto/elliptic, which can subsequently be parsed and tested. - supportedCurves := map[string]bool{ - "secp224r1": true, - "secp256r1": true, - "secp384r1": true, - "secp521r1": true, - } - - var root Root - readTestVector(t, "ecdh_test.json", &root) - for _, tg := range root.TestGroups { - if !supportedCurves[tg.Curve] { - continue - } - for _, tt := range tg.Tests { - tg, tt := tg, tt - t.Run(fmt.Sprintf("%s/%d", tg.Curve, tt.TcID), func(t *testing.T) { - t.Logf("Type: %v", tt.Result) - t.Logf("Flags: %q", tt.Flags) - t.Log(tt.Comment) - - shouldPass := shouldPass(tt.Result, tt.Flags, flagsShouldPass) - - p := decodeHex(tt.Public) - pp, err := x509.ParsePKIXPublicKey(p) - if err != nil { - pp, err = decodeCompressedPKIX(p) - } - if err != nil { - if shouldPass { - t.Errorf("unexpected parsing error: %s", err) - } - return - } - pub := pp.(*ecdsa.PublicKey) - - priv := decodeHex(tt.Private) - shared := decodeHex(tt.Shared) - - x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, priv) - xBytes := make([]byte, (pub.Curve.Params().BitSize+7)/8) - got := bytes.Equal(shared, x.FillBytes(xBytes)) - - if want := shouldPass; got != want { - t.Errorf("wanted success %v, got %v", want, got) - } - }) - } - } -} - -func decodeCompressedPKIX(der []byte) (interface{}, error) { - s := cryptobyte.String(der) - var s1, s2 cryptobyte.String - var algoOID, namedCurveOID asn1.ObjectIdentifier - var pointDER []byte - if !s.ReadASN1(&s1, casn1.SEQUENCE) || !s.Empty() || - !s1.ReadASN1(&s2, casn1.SEQUENCE) || - !s2.ReadASN1ObjectIdentifier(&algoOID) || - !s2.ReadASN1ObjectIdentifier(&namedCurveOID) || !s2.Empty() || - !s1.ReadASN1BitStringAsBytes(&pointDER) || !s1.Empty() { - return nil, errors.New("failed to parse PKIX structure") - } - - if !algoOID.Equal(oidPublicKeyECDSA) { - return nil, errors.New("wrong algorithm OID") - } - namedCurve := namedCurveFromOID(namedCurveOID) - if namedCurve == nil { - return nil, errors.New("unsupported elliptic curve") - } - x, y := elliptic.UnmarshalCompressed(namedCurve, pointDER) - if x == nil { - return nil, errors.New("failed to unmarshal elliptic curve point") - } - pub := &ecdsa.PublicKey{ - Curve: namedCurve, - X: x, - Y: y, - } - return pub, nil -} - -var ( - oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} - oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} - oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} - oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} - oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} -) - -func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve { - switch { - case oid.Equal(oidNamedCurveP224): - return elliptic.P224() - case oid.Equal(oidNamedCurveP256): - return elliptic.P256() - case oid.Equal(oidNamedCurveP384): - return elliptic.P384() - case oid.Equal(oidNamedCurveP521): - return elliptic.P521() - } - return nil -}
diff --git a/internal/wycheproof/ecdsa_test.go b/internal/wycheproof/ecdsa_test.go deleted file mode 100644 index 80125ad..0000000 --- a/internal/wycheproof/ecdsa_test.go +++ /dev/null
@@ -1,105 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "crypto/ecdsa" - "math/big" - "testing" - - "golang.org/x/crypto/cryptobyte" - "golang.org/x/crypto/cryptobyte/asn1" -) - -func TestECDSA(t *testing.T) { - type ASNSignatureTestVector struct { - // A brief description of the test case - Comment string `json:"comment"` - // A list of flags - Flags []string `json:"flags"` - // The message to sign - Msg string `json:"msg"` - // Test result - Result string `json:"result"` - // An ASN.1 encoded signature for msg - Sig string `json:"sig"` - // Identifier of the test case - TcID int `json:"tcId"` - } - - type ECPublicKey struct { - // The EC group used by this public key - Curve interface{} `json:"curve"` - } - - type ECDSATestGroup struct { - // Unencoded EC public key - Key *ECPublicKey `json:"key"` - // DER encoded public key - KeyDER string `json:"keyDer"` - // the hash function used for ECDSA - SHA string `json:"sha"` - Tests []*ASNSignatureTestVector `json:"tests"` - } - - type Root struct { - TestGroups []*ECDSATestGroup `json:"testGroups"` - } - - flagsShouldPass := map[string]bool{ - // An encoded ASN.1 integer missing a leading zero is invalid, but - // accepted by some implementations. - "MissingZero": false, - // A signature using a weaker hash than the EC params is not a security - // risk, as long as the hash is secure. - // https://www.imperialviolet.org/2014/05/25/strengthmatching.html - "WeakHash": true, - } - - // supportedCurves is a map of all elliptic curves supported - // by crypto/elliptic, which can subsequently be parsed and tested. - supportedCurves := map[string]bool{ - "secp224r1": true, - "secp256r1": true, - "secp384r1": true, - "secp521r1": true, - } - - var root Root - readTestVector(t, "ecdsa_test.json", &root) - for _, tg := range root.TestGroups { - curve := tg.Key.Curve.(string) - if !supportedCurves[curve] { - continue - } - pub := decodePublicKey(tg.KeyDER).(*ecdsa.PublicKey) - h := parseHash(tg.SHA).New() - for _, sig := range tg.Tests { - h.Reset() - h.Write(decodeHex(sig.Msg)) - hashed := h.Sum(nil) - sigBytes := decodeHex(sig.Sig) - got := ecdsa.VerifyASN1(pub, hashed, sigBytes) - if want := shouldPass(sig.Result, sig.Flags, flagsShouldPass); got != want { - t.Errorf("tcid: %d, type: %s, comment: %q, VerifyASN1 wanted success: %t", sig.TcID, sig.Result, sig.Comment, want) - } - - var r, s big.Int - var inner cryptobyte.String - input := cryptobyte.String(sigBytes) - if !input.ReadASN1(&inner, asn1.SEQUENCE) || - !input.Empty() || - !inner.ReadASN1Integer(&r) || - !inner.ReadASN1Integer(&s) || - !inner.Empty() { - continue - } - got = ecdsa.Verify(pub, hashed, &r, &s) - if want := shouldPass(sig.Result, sig.Flags, flagsShouldPass); got != want { - t.Errorf("tcid: %d, type: %s, comment: %q, Verify wanted success: %t", sig.TcID, sig.Result, sig.Comment, want) - } - } - } -}
diff --git a/internal/wycheproof/eddsa_test.go b/internal/wycheproof/eddsa_test.go deleted file mode 100644 index a74f343..0000000 --- a/internal/wycheproof/eddsa_test.go +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "crypto/ed25519" - "testing" -) - -func TestEddsa(t *testing.T) { - // Jwk the private key in webcrypto format - type Jwk struct { - } - - // Key unencoded key pair - type Key struct { - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // SignatureTestVector - type SignatureTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // The message to sign - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // A signature for msg - Sig string `json:"sig,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // EddsaTestGroup - type EddsaTestGroup struct { - - // the private key in webcrypto format - Jwk *Jwk `json:"jwk,omitempty"` - - // unencoded key pair - Key *Key `json:"key,omitempty"` - - // Asn encoded public key - KeyDer string `json:"keyDer,omitempty"` - - // Pem encoded public key - KeyPem string `json:"keyPem,omitempty"` - Tests []*SignatureTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*EddsaTestGroup `json:"testGroups,omitempty"` - } - - var root Root - readTestVector(t, "eddsa_test.json", &root) - for _, tg := range root.TestGroups { - pub := decodePublicKey(tg.KeyDer).(ed25519.PublicKey) - for _, sig := range tg.Tests { - got := ed25519.Verify(pub, decodeHex(sig.Msg), decodeHex(sig.Sig)) - if want := shouldPass(sig.Result, sig.Flags, nil); got != want { - t.Errorf("tcid: %d, type: %s, comment: %q, wanted success: %t", sig.TcId, sig.Result, sig.Comment, want) - } - } - } -}
diff --git a/internal/wycheproof/hkdf_test.go b/internal/wycheproof/hkdf_test.go deleted file mode 100644 index 6b72e2c..0000000 --- a/internal/wycheproof/hkdf_test.go +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "bytes" - "io" - "testing" - - "golang.org/x/crypto/hkdf" -) - -func TestHkdf(t *testing.T) { - - // HkdfTestVector - type HkdfTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // the key (input key material) - Ikm string `json:"ikm,omitempty"` - - // additional information used in the key derivation - Info string `json:"info,omitempty"` - - // the generated bytes (output key material) - Okm string `json:"okm,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // the salt for the key derivation - Salt string `json:"salt,omitempty"` - - // the size of the output in bytes - Size int `json:"size,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // HkdfTestGroup - type HkdfTestGroup struct { - - // the size of the ikm in bits - KeySize int `json:"keySize,omitempty"` - Tests []*HkdfTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*HkdfTestGroup `json:"testGroups,omitempty"` - } - - fileHashAlgorithms := map[string]string{ - "hkdf_sha1_test.json": "SHA-1", - "hkdf_sha256_test.json": "SHA-256", - "hkdf_sha384_test.json": "SHA-384", - "hkdf_sha512_test.json": "SHA-512", - } - - for f := range fileHashAlgorithms { - var root Root - readTestVector(t, f, &root) - for _, tg := range root.TestGroups { - for _, tv := range tg.Tests { - h := parseHash(fileHashAlgorithms[f]).New - hkdf := hkdf.New(h, decodeHex(tv.Ikm), decodeHex(tv.Salt), decodeHex(tv.Info)) - key := make([]byte, tv.Size) - wantPass := shouldPass(tv.Result, tv.Flags, nil) - _, err := io.ReadFull(hkdf, key) - if (err == nil) != wantPass { - t.Errorf("tcid: %d, type: %s, comment: %q, wanted success: %t, got: %v", tv.TcId, tv.Result, tv.Comment, wantPass, err) - } - if err != nil { - continue // don't validate output text if reading failed - } - if got, want := key, decodeHex(tv.Okm); !bytes.Equal(got, want) { - t.Errorf("tcid: %d, type: %s, comment: %q, output bytes don't match", tv.TcId, tv.Result, tv.Comment) - } - } - } - } -}
diff --git a/internal/wycheproof/hmac_test.go b/internal/wycheproof/hmac_test.go deleted file mode 100644 index bcc56f2..0000000 --- a/internal/wycheproof/hmac_test.go +++ /dev/null
@@ -1,105 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "crypto/hmac" - "testing" -) - -func TestHMAC(t *testing.T) { - // MacTestVector - type MacTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // the key - Key string `json:"key,omitempty"` - - // the plaintext - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // the authentication tag - Tag string `json:"tag,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // MacTestGroup - type MacTestGroup struct { - - // the keySize in bits - KeySize int `json:"keySize,omitempty"` - - // the expected size of the tag in bits - TagSize int `json:"tagSize,omitempty"` - Tests []*MacTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*MacTestGroup `json:"testGroups,omitempty"` - } - - fileHashAlgs := map[string]string{ - "hmac_sha1_test.json": "SHA-1", - "hmac_sha224_test.json": "SHA-224", - "hmac_sha256_test.json": "SHA-256", - "hmac_sha384_test.json": "SHA-384", - "hmac_sha512_test.json": "SHA-512", - } - - for f := range fileHashAlgs { - var root Root - readTestVector(t, f, &root) - for _, tg := range root.TestGroups { - h := parseHash(fileHashAlgs[f]) - // Skip test vectors where the tag length does not equal the - // hash length, since crypto/hmac does not support generating - // these truncated tags. - if tg.TagSize/8 != h.Size() { - continue - } - for _, tv := range tg.Tests { - hm := hmac.New(h.New, decodeHex(tv.Key)) - hm.Write(decodeHex(tv.Msg)) - tag := hm.Sum(nil) - got := hmac.Equal(decodeHex(tv.Tag), tag) - if want := shouldPass(tv.Result, tv.Flags, nil); want != got { - t.Errorf("%s, tcid: %d, type: %s, comment: %q, unexpected result", f, tv.TcId, tv.Result, tv.Comment) - } - } - } - } -}
diff --git a/internal/wycheproof/internal/dsa/dsa.go b/internal/wycheproof/internal/dsa/dsa.go deleted file mode 100644 index 3101dfc..0000000 --- a/internal/wycheproof/internal/dsa/dsa.go +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package dsa provides an internal version of dsa.Verify -// that is used for the Wycheproof tests. -package dsa - -import ( - "crypto/dsa" - "math/big" - - "golang.org/x/crypto/cryptobyte" - "golang.org/x/crypto/cryptobyte/asn1" -) - -// VerifyASN1 verifies the ASN1 encoded signature, sig, of hash using the -// public key, pub. Its return value records whether the signature is valid. -func VerifyASN1(pub *dsa.PublicKey, hash, sig []byte) bool { - var ( - r, s = &big.Int{}, &big.Int{} - inner cryptobyte.String - ) - input := cryptobyte.String(sig) - if !input.ReadASN1(&inner, asn1.SEQUENCE) || - !input.Empty() || - !inner.ReadASN1Integer(r) || - !inner.ReadASN1Integer(s) || - !inner.Empty() { - return false - } - return dsa.Verify(pub, hash, r, s) -}
diff --git a/internal/wycheproof/notboring.go b/internal/wycheproof/notboring.go deleted file mode 100644 index 746af13..0000000 --- a/internal/wycheproof/notboring.go +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !boringcrypto - -package wycheproof - -const boringcryptoEnabled = false
diff --git a/internal/wycheproof/rsa_oaep_decrypt_test.go b/internal/wycheproof/rsa_oaep_decrypt_test.go deleted file mode 100644 index 19cc4fd..0000000 --- a/internal/wycheproof/rsa_oaep_decrypt_test.go +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "bytes" - "crypto/rsa" - "crypto/x509" - "fmt" - "testing" -) - -func TestRSAOAEPDecrypt(t *testing.T) { - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // RsaesOaepTestVector - type RsaesOaepTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // An encryption of msg - Ct string `json:"ct,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // The label used for the encryption - Label string `json:"label,omitempty"` - - // The encrypted message - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // RsaesOaepTestGroup - type RsaesOaepTestGroup struct { - - // The private exponent - D string `json:"d,omitempty"` - - // The public exponent - E string `json:"e,omitempty"` - - // the message generating function (e.g. MGF1) - Mgf string `json:"mgf,omitempty"` - - // The hash function used for the message generating function. - MgfSha string `json:"mgfSha,omitempty"` - - // The modulus of the key - N string `json:"n,omitempty"` - - // Pem encoded private key - PrivateKeyPem string `json:"privateKeyPem,omitempty"` - - // Pkcs 8 encoded private key. - PrivateKeyPkcs8 string `json:"privateKeyPkcs8,omitempty"` - - // The hash function for hashing the label. - Sha string `json:"sha,omitempty"` - Tests []*RsaesOaepTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*RsaesOaepTestGroup `json:"testGroups,omitempty"` - } - - // rsa.DecryptOAEP doesn't support using a different hash for the - // MGF and the label, so skip all of the test vectors that use - // these unbalanced constructions. rsa_oaep_misc_test.json contains - // both balanced and unbalanced constructions so in that case - // we just filter out any test groups where MgfSha != Sha - files := []string{ - "rsa_oaep_2048_sha1_mgf1sha1_test.json", - "rsa_oaep_2048_sha224_mgf1sha224_test.json", - "rsa_oaep_2048_sha256_mgf1sha256_test.json", - "rsa_oaep_2048_sha384_mgf1sha384_test.json", - "rsa_oaep_2048_sha512_mgf1sha512_test.json", - "rsa_oaep_3072_sha256_mgf1sha256_test.json", - "rsa_oaep_3072_sha512_mgf1sha512_test.json", - "rsa_oaep_4096_sha256_mgf1sha256_test.json", - "rsa_oaep_4096_sha512_mgf1sha512_test.json", - "rsa_oaep_misc_test.json", - } - - flagsShouldPass := map[string]bool{ - // rsa.DecryptOAEP happily supports small key sizes - "SmallModulus": true, - } - - for _, f := range files { - var root Root - readTestVector(t, f, &root) - for _, tg := range root.TestGroups { - if tg.MgfSha != tg.Sha { - continue - } - priv, err := x509.ParsePKCS8PrivateKey(decodeHex(tg.PrivateKeyPkcs8)) - if err != nil { - t.Fatalf("%s failed to parse PKCS #8 private key: %s", f, err) - } - hash := parseHash(tg.Sha) - for _, tv := range tg.Tests { - t.Run(fmt.Sprintf("%s #%d", f, tv.TcId), func(t *testing.T) { - wantPass := shouldPass(tv.Result, tv.Flags, flagsShouldPass) - plaintext, err := rsa.DecryptOAEP(hash.New(), nil, priv.(*rsa.PrivateKey), decodeHex(tv.Ct), decodeHex(tv.Label)) - if wantPass { - if err != nil { - t.Fatalf("comment: %s, expected success: %s", tv.Comment, err) - } - if !bytes.Equal(plaintext, decodeHex(tv.Msg)) { - t.Errorf("comment: %s, unexpected plaintext: got %x, want %s", tv.Comment, plaintext, tv.Msg) - } - } else if err == nil { - t.Errorf("comment: %s, expected failure", tv.Comment) - } - }) - } - } - } -}
diff --git a/internal/wycheproof/rsa_pss_test.go b/internal/wycheproof/rsa_pss_test.go deleted file mode 100644 index f2f9b6e..0000000 --- a/internal/wycheproof/rsa_pss_test.go +++ /dev/null
@@ -1,169 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "crypto/rsa" - "testing" -) - -func TestRsaPss(t *testing.T) { - // KeyJwk Public key in JWK format - type KeyJwk struct { - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // SignatureTestVector - type SignatureTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // The message to sign - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // A signature for msg - Sig string `json:"sig,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // RsassaPkcs1TestGroup - type RsassaPkcs1TestGroup struct { - - // The private exponent - D string `json:"d,omitempty"` - - // The public exponent - E string `json:"e,omitempty"` - - // ASN encoding of the sequence [n, e] - KeyAsn string `json:"keyAsn,omitempty"` - - // ASN encoding of the public key - KeyDer string `json:"keyDer,omitempty"` - - // Public key in JWK format - KeyJwk *KeyJwk `json:"keyJwk,omitempty"` - - // Pem encoded public key - KeyPem string `json:"keyPem,omitempty"` - - // the size of the modulus in bits - KeySize int `json:"keySize,omitempty"` - - // The modulus of the key - N string `json:"n,omitempty"` - - // The salt length - SLen int `json:"sLen,omitempty"` - - // the hash function used for the message - Sha string `json:"sha,omitempty"` - Tests []*SignatureTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*RsassaPkcs1TestGroup `json:"testGroups,omitempty"` - } - - flagsShouldPass := map[string]bool{ - // A signature using a weaker hash than the EC params is not a security risk, as long as the hash is secure. - // https://www.imperialviolet.org/2014/05/25/strengthmatching.html - "WeakHash": true, - } - - // filesOverrideToPassZeroSLen is a map of all test files - // and which TcIds that should be overridden to pass if the - // rsa.PSSOptions.SaltLength is zero. - // These tests expect a failure with a PSSOptions.SaltLength: 0 - // and a signature that uses a different salt length. However, - // a salt length of 0 is defined as rsa.PSSSaltLengthAuto which - // works deterministically to auto-detect the length when - // verifying, so these tests actually pass as they should. - filesOverrideToPassZeroSLen := map[string][]int{ - "rsa_pss_2048_sha1_mgf1_20_test.json": []int{46, 47}, - "rsa_pss_2048_sha256_mgf1_0_test.json": []int{67, 68}, - "rsa_pss_2048_sha256_mgf1_32_test.json": []int{67, 68}, - "rsa_pss_3072_sha256_mgf1_32_test.json": []int{67, 68}, - "rsa_pss_4096_sha256_mgf1_32_test.json": []int{67, 68}, - "rsa_pss_4096_sha512_mgf1_32_test.json": []int{136, 137}, - // "rsa_pss_misc_test.json": nil, // TODO: This ones seems to be broken right now, but can enable later on. - } - - if !boringcryptoEnabled { - // boringcrypto doesn't support the truncated SHA-512 hashes, so only - // test them if boringcrypto isn't enabled. - filesOverrideToPassZeroSLen["rsa_pss_2048_sha512_256_mgf1_28_test.json"] = []int{13, 14, 15} - filesOverrideToPassZeroSLen["rsa_pss_2048_sha512_256_mgf1_32_test.json"] = []int{13, 14} - } - - for f := range filesOverrideToPassZeroSLen { - var root Root - readTestVector(t, f, &root) - for _, tg := range root.TestGroups { - pub := decodePublicKey(tg.KeyDer).(*rsa.PublicKey) - ch := parseHash(tg.Sha) - h := ch.New() - opts := &rsa.PSSOptions{ - Hash: ch, - SaltLength: rsa.PSSSaltLengthAuto, - } - // Run all the tests twice: the first time with the salt length - // as PSSSaltLengthAuto, and the second time with the salt length - // explicitly set to tg.SLen. - for i := 0; i < 2; i++ { - for _, sig := range tg.Tests { - h.Reset() - h.Write(decodeHex(sig.Msg)) - hashed := h.Sum(nil) - err := rsa.VerifyPSS(pub, ch, hashed, decodeHex(sig.Sig), opts) - want := shouldPass(sig.Result, sig.Flags, flagsShouldPass) - if opts.SaltLength == 0 { - for _, id := range filesOverrideToPassZeroSLen[f] { - if sig.TcId == id { - want = true - break - } - } - } - if (err == nil) != want { - t.Errorf("file: %v, tcid: %d, type: %s, opts.SaltLength: %v, comment: %q, wanted success: %t", f, sig.TcId, sig.Result, opts.SaltLength, sig.Comment, want) - } - } - // Update opts.SaltLength for the second run of the tests. - opts.SaltLength = tg.SLen - } - } - } -}
diff --git a/internal/wycheproof/rsa_signature_test.go b/internal/wycheproof/rsa_signature_test.go deleted file mode 100644 index 3c31c22..0000000 --- a/internal/wycheproof/rsa_signature_test.go +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package wycheproof - -import ( - "crypto/rsa" - "testing" -) - -func TestRsa(t *testing.T) { - // KeyJwk Public key in JWK format - type KeyJwk struct { - } - - // Notes a description of the labels used in the test vectors - type Notes struct { - } - - // SignatureTestVector - type SignatureTestVector struct { - - // A brief description of the test case - Comment string `json:"comment,omitempty"` - - // A list of flags - Flags []string `json:"flags,omitempty"` - - // The message to sign - Msg string `json:"msg,omitempty"` - - // Test result - Result string `json:"result,omitempty"` - - // A signature for msg - Sig string `json:"sig,omitempty"` - - // Identifier of the test case - TcId int `json:"tcId,omitempty"` - } - - // RsassaPkcs1TestGroup - type RsassaPkcs1TestGroup struct { - - // The private exponent - D string `json:"d,omitempty"` - - // The public exponent - E string `json:"e,omitempty"` - - // ASN encoding of the sequence [n, e] - KeyAsn string `json:"keyAsn,omitempty"` - - // ASN encoding of the public key - KeyDer string `json:"keyDer,omitempty"` - - // Public key in JWK format - KeyJwk *KeyJwk `json:"keyJwk,omitempty"` - - // Pem encoded public key - KeyPem string `json:"keyPem,omitempty"` - - // the size of the modulus in bits - KeySize int `json:"keySize,omitempty"` - - // The modulus of the key - N string `json:"n,omitempty"` - - // the hash function used for the message - Sha string `json:"sha,omitempty"` - Tests []*SignatureTestVector `json:"tests,omitempty"` - Type interface{} `json:"type,omitempty"` - } - - // Root - type Root struct { - - // the primitive tested in the test file - Algorithm string `json:"algorithm,omitempty"` - - // the version of the test vectors. - GeneratorVersion string `json:"generatorVersion,omitempty"` - - // additional documentation - Header []string `json:"header,omitempty"` - - // a description of the labels used in the test vectors - Notes *Notes `json:"notes,omitempty"` - - // the number of test vectors in this test - NumberOfTests int `json:"numberOfTests,omitempty"` - Schema interface{} `json:"schema,omitempty"` - TestGroups []*RsassaPkcs1TestGroup `json:"testGroups,omitempty"` - } - - flagsShouldPass := map[string]bool{ - // Omitting the parameter field in an ASN encoded integer is a legacy behavior. - "MissingNull": false, - // Keys with a modulus less than 2048 bits are supported by crypto/rsa. - "SmallModulus": true, - // Small public keys are supported by crypto/rsa. - "SmallPublicKey": true, - } - - var root Root - readTestVector(t, "rsa_signature_test.json", &root) - for _, tg := range root.TestGroups { - pub := decodePublicKey(tg.KeyDer).(*rsa.PublicKey) - ch := parseHash(tg.Sha) - h := ch.New() - for _, sig := range tg.Tests { - h.Reset() - h.Write(decodeHex(sig.Msg)) - hashed := h.Sum(nil) - err := rsa.VerifyPKCS1v15(pub, ch, hashed, decodeHex(sig.Sig)) - want := shouldPass(sig.Result, sig.Flags, flagsShouldPass) - if (err == nil) != want { - t.Errorf("tcid: %d, type: %s, comment: %q, wanted success: %t", sig.TcId, sig.Result, sig.Comment, want) - } - } - } -}
diff --git a/internal/wycheproof/wycheproof_test.go b/internal/wycheproof/wycheproof_test.go deleted file mode 100644 index bbaae3b..0000000 --- a/internal/wycheproof/wycheproof_test.go +++ /dev/null
@@ -1,141 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package wycheproof runs a set of the Wycheproof tests -// provided by https://github.com/google/wycheproof. -package wycheproof - -import ( - "crypto" - "crypto/x509" - "encoding/hex" - "encoding/json" - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "testing" - - _ "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" -) - -const wycheproofModVer = "v0.0.0-20191219022705-2196000605e4" - -var wycheproofTestVectorsDir string - -func TestMain(m *testing.M) { - flag.Parse() - if flag.Lookup("test.short").Value.(flag.Getter).Get().(bool) { - log.Println("skipping test that downloads testdata via 'go mod download' in short mode") - os.Exit(0) - } - if _, err := exec.LookPath("go"); err != nil { - log.Printf("skipping test because 'go' command is unavailable: %v", err) - os.Exit(0) - } - if os.Getenv("GO_BUILDER_FLAKY_NET") != "" { - log.Printf("skipping test because GO_BUILDER_FLAKY_NET is set") - os.Exit(0) - } - - // Download the JSON test files from github.com/google/wycheproof - // using `go mod download -json` so the cached source of the testdata - // can be used in the following tests. - path := "github.com/google/wycheproof@" + wycheproofModVer - cmd := exec.Command("go", "mod", "download", "-json", path) - output, err := cmd.Output() - if err != nil { - log.Fatalf("failed to run `go mod download -json %s`, output: %s", path, output) - } - var dm struct { - Dir string // absolute path to cached source root directory - } - if err := json.Unmarshal(output, &dm); err != nil { - log.Fatal(err) - } - // Now that the module has been downloaded, use the absolute path of the - // cached source as the root directory for all tests going forward. - wycheproofTestVectorsDir = filepath.Join(dm.Dir, "testvectors") - os.Exit(m.Run()) -} - -func readTestVector(t *testing.T, f string, dest interface{}) { - b, err := os.ReadFile(filepath.Join(wycheproofTestVectorsDir, f)) - if err != nil { - t.Fatalf("failed to read json file: %v", err) - } - if err := json.Unmarshal(b, &dest); err != nil { - t.Fatalf("failed to unmarshal json file: %v", err) - } -} - -func decodeHex(s string) []byte { - b, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - return b -} - -func decodePublicKey(der string) interface{} { - d := decodeHex(der) - pub, err := x509.ParsePKIXPublicKey(d) - if err != nil { - panic(fmt.Sprintf("failed to parse DER encoded public key: %v", err)) - } - return pub -} - -func parseHash(h string) crypto.Hash { - switch h { - case "SHA-1": - return crypto.SHA1 - case "SHA-256": - return crypto.SHA256 - case "SHA-224": - return crypto.SHA224 - case "SHA-384": - return crypto.SHA384 - case "SHA-512": - return crypto.SHA512 - case "SHA-512/224": - return crypto.SHA512_224 - case "SHA-512/256": - return crypto.SHA512_256 - default: - panic(fmt.Sprintf("could not identify SHA hash algorithm: %q", h)) - } -} - -// shouldPass returns whether or not the test should pass. -// flagsShouldPass is a map associated with whether or not -// a flag for an "acceptable" result should pass. -// Every possible flag value that's associated with an -// "acceptable" result should be explicitly specified, -// otherwise the test will panic. -func shouldPass(result string, flags []string, flagsShouldPass map[string]bool) bool { - switch result { - case "valid": - return true - case "invalid": - return false - case "acceptable": - for _, flag := range flags { - pass, ok := flagsShouldPass[flag] - if !ok { - panic(fmt.Sprintf("unspecified flag: %q", flag)) - } - if !pass { - return false - } - } - return true // There are no flags, or all are meant to pass. - default: - panic(fmt.Sprintf("unexpected result: %v", result)) - } -}