Source File
check.go
Belonging Package
crypto/internal/fips140/check
// 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.
// Package check implements the FIPS-140 load-time code+data verification.
// Every FIPS package providing cryptographic functionality except hmac and sha256
// must import crypto/internal/fips140/check, so that the verification happens
// before initialization of package global variables.
// The hmac and sha256 packages are used by this package, so they cannot import it.
// Instead, those packages must be careful not to change global variables during init.
// (If necessary, we could have check call a PostCheck function in those packages
// after the check has completed.)
package check
import (
)
// Enabled reports whether verification was enabled.
// If Enabled returns true, then verification succeeded,
// because if it failed the binary would have panicked at init time.
func () bool {
return enabled
}
var enabled bool // set when verification is enabled
var Verified bool // set when verification succeeds, for testing
// Supported reports whether the current GOOS/GOARCH is Supported at all.
func () 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.
//
//go:linkname Linkinfo go:fipsinfo
var Linkinfo struct {
Magic [16]byte
Sum [32]byte
Self uintptr
Sects [4]struct {
// Note: These must be unsafe.Pointer, not uintptr,
// or else checkptr panics about turning uintptrs
// into pointers into the data segment during
// go test -race.
Start unsafe.Pointer
End unsafe.Pointer
}
}
// "\xff"+fipsMagic is the expected linkinfo.Magic.
// We avoid writing that explicitly so that the string does not appear
// elsewhere in normal binaries, just as a precaution.
const fipsMagic = " Go fipsinfo \xff\x00"
var zeroSum [32]byte
func init() {
:= godebug.Value("#fips140")
enabled = != "" && != "off"
if !enabled {
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")
}
switch {
case "on", "only", "debug":
// ok
default:
panic("fips140: unknown GODEBUG setting fips140=" + )
}
if !Supported() {
panic("fips140: unavailable on " + runtime.GOOS + "-" + runtime.GOARCH)
}
if Linkinfo.Magic[0] != 0xff || string(Linkinfo.Magic[1:]) != fipsMagic || Linkinfo.Sum == zeroSum {
panic("fips140: no verification checksum found")
}
:= hmac.New(sha256.New, make([]byte, 32))
:= io.Writer()
/*
// Uncomment for debugging.
// Commented (as opposed to a const bool flag)
// to avoid import "os" in default builds.
f, err := os.Create("fipscheck.o")
if err != nil {
panic(err)
}
w = io.MultiWriter(h, f)
*/
.Write([]byte("go fips object v1\n"))
var [8]byte
for , := range Linkinfo.Sects {
:= uintptr(.End) - uintptr(.Start)
byteorder.BEPutUint64([:], uint64())
.Write([:])
.Write(unsafe.Slice((*byte)(.Start), ))
}
:= .Sum(nil)
if [32]byte() != Linkinfo.Sum {
panic("fips140: verification mismatch")
}
if == "debug" {
println("fips140: verified code+data")
}
Verified = true
}
The pages are generated with Golds v0.7.3-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |