crypto/internal/fips140test: make TestCASTFailures standalone

We want it to work even when fips140test.test is cross-compiled and
moved to a different machine. Also, make it log more.

Change-Id: I6a6a46566712f05f6b551ecde75672baf2c0fc6b
Reviewed-on: https://go-review.googlesource.com/c/go/+/644644
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
Filippo Valsorda 2025-01-27 13:02:27 +01:00 committed by Gopher Robot
parent 3e0f9e3973
commit 19f779dd4f
1 changed files with 49 additions and 16 deletions

View File

@ -13,6 +13,7 @@ import (
"io/fs" "io/fs"
"os" "os"
"regexp" "regexp"
"slices"
"strings" "strings"
"testing" "testing"
@ -34,7 +35,35 @@ import (
_ "crypto/internal/fips140/tls13" _ "crypto/internal/fips140/tls13"
) )
func findAllCASTs(t *testing.T) map[string]struct{} { var allCASTs = []string{
"AES-CBC",
"CTR_DRBG",
"CounterKDF",
"DetECDSA P-256 SHA2-512 sign",
"ECDH PCT",
"ECDSA P-256 SHA2-512 sign and verify",
"ECDSA PCT",
"Ed25519 sign and verify",
"Ed25519 sign and verify PCT",
"HKDF-SHA2-256",
"HMAC-SHA2-256",
"KAS-ECC-SSC P-256",
"ML-KEM PCT",
"ML-KEM PCT",
"ML-KEM PCT",
"ML-KEM PCT",
"ML-KEM-768",
"PBKDF2",
"RSA sign and verify PCT",
"RSASSA-PKCS-v1.5 2048-bit sign and verify",
"SHA2-256",
"SHA2-512",
"TLSv1.2-SHA2-256",
"TLSv1.3-SHA2-256",
"cSHAKE128",
}
func TestAllCASTs(t *testing.T) {
testenv.MustHaveSource(t) testenv.MustHaveSource(t)
// Ask "go list" for the location of the crypto/internal/fips140 tree, as it // Ask "go list" for the location of the crypto/internal/fips140 tree, as it
@ -48,7 +77,7 @@ func findAllCASTs(t *testing.T) map[string]struct{} {
t.Logf("FIPS module directory: %s", fipsDir) t.Logf("FIPS module directory: %s", fipsDir)
// Find all invocations of fips140.CAST or fips140.PCT. // Find all invocations of fips140.CAST or fips140.PCT.
allCASTs := make(map[string]struct{}) var foundCASTs []string
castRe := regexp.MustCompile(`fips140\.(CAST|PCT)\("([^"]+)"`) castRe := regexp.MustCompile(`fips140\.(CAST|PCT)\("([^"]+)"`)
if err := fs.WalkDir(os.DirFS(fipsDir), ".", func(path string, d fs.DirEntry, err error) error { if err := fs.WalkDir(os.DirFS(fipsDir), ".", func(path string, d fs.DirEntry, err error) error {
if err != nil { if err != nil {
@ -62,14 +91,17 @@ func findAllCASTs(t *testing.T) map[string]struct{} {
return err return err
} }
for _, m := range castRe.FindAllSubmatch(data, -1) { for _, m := range castRe.FindAllSubmatch(data, -1) {
allCASTs[string(m[2])] = struct{}{} foundCASTs = append(foundCASTs, string(m[2]))
} }
return nil return nil
}); err != nil { }); err != nil {
t.Fatalf("WalkDir: %v", err) t.Fatalf("WalkDir: %v", err)
} }
return allCASTs slices.Sort(foundCASTs)
if !slices.Equal(foundCASTs, allCASTs) {
t.Errorf("AllCASTs is out of date. Found CASTs: %#v", foundCASTs)
}
} }
// TestConditionals causes the conditional CASTs and PCTs to be invoked. // TestConditionals causes the conditional CASTs and PCTs to be invoked.
@ -127,28 +159,29 @@ UjmopwKBgAqB2KYYMUqAOvYcBnEfLDmyZv9BTVNHbR2lKkMYqv5LlvDaBxVfilE0
} }
func TestCASTFailures(t *testing.T) { func TestCASTFailures(t *testing.T) {
moduleStatus(t)
testenv.MustHaveExec(t) testenv.MustHaveExec(t)
allCASTs := findAllCASTs(t) for _, name := range allCASTs {
if len(allCASTs) == 0 {
t.Fatal("no CASTs found")
}
for name := range allCASTs {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
// Don't parallelize if running in verbose mode, to produce a less
// confusing recoding for the validation lab.
if !testing.Verbose() {
t.Parallel() t.Parallel()
}
t.Logf("CAST/PCT succeeded: %s", name)
t.Logf("Testing CAST/PCT failure...")
cmd := testenv.Command(t, testenv.Executable(t), "-test.run=TestConditionals", "-test.v") cmd := testenv.Command(t, testenv.Executable(t), "-test.run=TestConditionals", "-test.v")
cmd = testenv.CleanCmdEnv(cmd)
cmd.Env = append(cmd.Env, fmt.Sprintf("GODEBUG=failfipscast=%s,fips140=on", name)) cmd.Env = append(cmd.Env, fmt.Sprintf("GODEBUG=failfipscast=%s,fips140=on", name))
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err == nil {
t.Error(err)
} else {
t.Logf("CAST/PCT %s failed and caused the program to exit or the test to fail", name)
t.Logf("%s", out) t.Logf("%s", out)
if err == nil {
t.Fatal("Test did not fail as expected")
} }
if strings.Contains(string(out), "completed successfully") { if strings.Contains(string(out), "completed successfully") {
t.Errorf("CAST/PCT %s failure did not stop the program", name) t.Errorf("CAST/PCT %s failure did not stop the program", name)
} else {
t.Logf("CAST/PCT %s failed as expected and caused the program to exit", name)
} }
}) })
} }