Move the logic duplicated in multiple places to a central function.
Change-Id: I6a6a4656469c91dd62b0be716ec8367358f4a3e1
Reviewed-on: https://go-review.googlesource.com/c/go/+/639336
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Roland Shoemaker <roland@golang.org>
}
func (t *tester) fipsSupported() bool {
+ // Keep this in sync with [crypto/internal/fips140.Supported].
+
// Use GOFIPS140 or GOEXPERIMENT=boringcrypto, but not both.
if strings.Contains(goexperiment, "boringcrypto") {
return false
//go:build asan
-package check
+package fips140
const asanEnabled = true
--- /dev/null
+// Copyright 2024 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.
+
+// Keep in sync with notboring.go and crypto/internal/boring/boring.go.
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !msan && cgo
+
+package fips140
+
+const boringEnabled = true
"crypto/internal/fips140deps/byteorder"
"crypto/internal/fips140deps/godebug"
"io"
- "runtime"
"unsafe"
)
// true when [fips140.Enabled] is true, or init would have panicked.
var Verified bool
-// Supported reports whether the current GOOS/GOARCH is Supported at all.
-func Supported() bool {
- // See cmd/internal/obj/fips.go's EnableFIPS for commentary.
- switch {
- case runtime.GOARCH == "wasm",
- runtime.GOOS == "windows" && runtime.GOARCH == "386",
- runtime.GOOS == "windows" && runtime.GOARCH == "arm",
- runtime.GOOS == "aix":
- return false
- }
- return true
-}
-
// Linkinfo holds the go:fipsinfo symbol prepared by the linker.
// See cmd/link/internal/ld/fips.go for details.
//
return
}
- if asanEnabled {
- // ASAN disapproves of reading swaths of global memory below.
- // One option would be to expose runtime.asanunpoison through
- // crypto/internal/fips140deps and then call it to unpoison the range
- // before reading it, but it is unclear whether that would then cause
- // false negatives. For now, FIPS+ASAN doesn't need to work.
- // If this is made to work, also re-enable the test in check_test.go
- // and in cmd/dist/test.go.
- panic("fips140: cannot verify in asan mode")
- }
-
- if !Supported() {
- panic("fips140: unavailable on " + runtime.GOOS + "-" + runtime.GOARCH)
+ if err := fips140.Supported(); err != nil {
+ panic("fips140: " + err.Error())
}
if Linkinfo.Magic[0] != 0xff || string(Linkinfo.Magic[1:]) != fipsMagic || Linkinfo.Sum == zeroSum {
package fips140
-import "crypto/internal/fips140deps/godebug"
+import (
+ "crypto/internal/fips140deps/godebug"
+ "errors"
+ "runtime"
+)
var Enabled bool
}
}
+// Supported returns an error if FIPS 140-3 mode can't be enabled.
+func Supported() error {
+ // Keep this in sync with fipsSupported in cmd/dist/test.go.
+
+ // ASAN disapproves of reading swaths of global memory in fips140/check.
+ // One option would be to expose runtime.asanunpoison through
+ // crypto/internal/fips140deps and then call it to unpoison the range
+ // before reading it, but it is unclear whether that would then cause
+ // false negatives. For now, FIPS+ASAN doesn't need to work.
+ if asanEnabled {
+ return errors.New("FIPS 140-3 mode is incompatible with ASAN")
+ }
+
+ // See EnableFIPS in cmd/internal/obj/fips.go for commentary.
+ switch {
+ case runtime.GOARCH == "wasm",
+ runtime.GOOS == "windows" && runtime.GOARCH == "386",
+ runtime.GOOS == "windows" && runtime.GOARCH == "arm",
+ runtime.GOOS == "aix":
+ return errors.New("FIPS 140-3 mode is not supported on " + runtime.GOOS + "-" + runtime.GOARCH)
+ }
+
+ if boringEnabled {
+ return errors.New("FIPS 140-3 mode is incompatible with GOEXPERIMENT=boringcrypto")
+ }
+
+ return nil
+}
+
func Name() string {
return "Go Cryptographic Module"
}
//go:build !asan
-package check
+package fips140
const asanEnabled = false
--- /dev/null
+// Copyright 2024 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 && linux && (amd64 || arm64) && !android && !msan && cgo)
+
+package fips140
+
+const boringEnabled = false
package fipstest
import (
- "crypto/internal/boring"
+ "crypto/internal/fips140"
. "crypto/internal/fips140/check"
"crypto/internal/fips140/check/checktest"
"fmt"
"internal/abi"
- "internal/asan"
"internal/godebug"
"internal/testenv"
"os"
- "runtime"
"testing"
"unicode"
"unsafe"
const enableFIPSTest = true
func TestFIPSCheckVerify(t *testing.T) {
- if boring.Enabled {
- t.Skip("not testing fips140 with boringcrypto enabled")
- }
-
if Verified {
t.Logf("verified")
return
return
}
- if !Supported() {
- t.Skipf("skipping on %s-%s", runtime.GOOS, runtime.GOARCH)
- }
- if asan.Enabled {
- // Verification panics with asan; don't bother.
- t.Skipf("skipping with -asan")
+ if err := fips140.Supported(); err != nil {
+ t.Skipf("skipping: %v", err)
}
cmd := testenv.Command(t, os.Args[0], "-test.v", "-test.run=TestFIPSCheck")
return
}
- if !Supported() {
- t.Skipf("skipping on %s-%s", runtime.GOOS, runtime.GOARCH)
+ if err := fips140.Supported(); err != nil {
+ t.Skipf("skipping: %v", err)
}
// Check that the checktest symbols are initialized properly.