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)) - } -}