Skip to content
/ go Public
forked from golang/go

Commit

Permalink
cmd/dist: add GOFIPS140 setting
Browse files Browse the repository at this point in the history
GOFIPS140 will be used to control whether to build binaries that
run in FIPS-140 mode by default, as well as which version of
crypto/internal/fips is used during a given build.
It is a target configuration variable analogous to
GOOS, GOARCH, CGO_ENABLED, and the like, so the
default value is recorded in the toolchain during make.bash.

This CL adds the GOFIPS140 setting to the build process
and records the default for use by cmd/go.

For golang#70200.

Change-Id: Iafcb5a4207f00fae8bcd93e0184a63c72526abea
Reviewed-on: https://go-review.googlesource.com/c/go/+/629196
Reviewed-by: Michael Matloob <[email protected]>
Auto-Submit: Russ Cox <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
  • Loading branch information
rsc authored and gopherbot committed Nov 19, 2024
1 parent 3a28cee commit 4d61704
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/cmd/dist/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var (
gogcflags string // For running built compiler
goldflags string
goexperiment string
gofips140 string
workdir string
tooldir string
oldgoos string
Expand Down Expand Up @@ -185,6 +186,12 @@ func xinit() {
}
goriscv64 = b

b = os.Getenv("GOFIPS140")
if b == "" {
b = "off"
}
gofips140 = b

if p := pathf("%s/src/all.bash", goroot); !isfile(p) {
fatalf("$GOROOT is not set correctly or not exported\n"+
"\tGOROOT=%s\n"+
Expand Down Expand Up @@ -247,6 +254,7 @@ func xinit() {
os.Setenv("GOPPC64", goppc64)
os.Setenv("GORISCV64", goriscv64)
os.Setenv("GOROOT", goroot)
os.Setenv("GOFIPS140", gofips140)

// Set GOBIN to GOROOT/bin. The meaning of GOBIN has drifted over time
// (see https://go.dev/issue/3269, https://go.dev/cl/183058,
Expand Down
1 change: 1 addition & 0 deletions src/cmd/dist/buildruntime.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func mkbuildcfg(file string) {
fmt.Fprintf(&buf, "const version = `%s`\n", findgoversion())
fmt.Fprintf(&buf, "const defaultGOOS = runtime.GOOS\n")
fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
fmt.Fprintf(&buf, "const defaultGOFIPS140 = `%s`\n", gofips140)

writefile(buf.String(), file, writeSkipSame)
}
Expand Down
42 changes: 42 additions & 0 deletions src/internal/buildcfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var (
GOWASM = gowasm()
ToolTags = toolTags()
GO_LDSO = defaultGO_LDSO
GOFIPS140 = gofips140()
Version = version
)

Expand Down Expand Up @@ -70,6 +71,47 @@ func goamd64() int {
return int(DefaultGOAMD64[len("v")] - '0')
}

func gofips140() string {
v := envOr("GOFIPS140", defaultGOFIPS140)
switch v {
case "off", "latest", "inprocess", "certified":
return v
}
if isFIPSVersion(v) {
return v
}
Error = fmt.Errorf("invalid GOFIPS140: must be off, latest, inprocess, certified, or vX.Y.Z")
return defaultGOFIPS140
}

// isFIPSVersion reports whether v is a valid FIPS version,
// of the form vX.Y.Z.
func isFIPSVersion(v string) bool {
if !strings.HasPrefix(v, "v") {
return false
}
v, ok := skipNum(v[len("v"):])
if !ok || !strings.HasPrefix(v, ".") {
return false
}
v, ok = skipNum(v[len("."):])
if !ok || !strings.HasPrefix(v, ".") {
return false
}
v, ok = skipNum(v[len("."):])
return ok && v == ""
}

// skipNum skips the leading text matching [0-9]+
// in s, returning the rest and whether such text was found.
func skipNum(s string) (rest string, ok bool) {
i := 0
for i < len(s) && '0' <= s[i] && s[i] <= '9' {
i++
}
return s[i:], i > 0
}

type GoarmFeatures struct {
Version int
SoftFloat bool
Expand Down
36 changes: 36 additions & 0 deletions src/internal/buildcfg/cfg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,39 @@ func TestGogoarchTags(t *testing.T) {
GOARCH = old_goarch
GOARM64 = old_goarm64
}

var goodFIPS = []string{
"v1.0.0",
"v1.0.1",
"v1.2.0",
"v1.2.3",
}

var badFIPS = []string{
"v1.0.0-fips",
"v1.0.0+fips",
"1.0.0",
"x1.0.0",
}

func TestIsFIPSVersion(t *testing.T) {
// good
for _, s := range goodFIPS {
if !isFIPSVersion(s) {
t.Errorf("isFIPSVersion(%q) = false, want true", s)
}
}
// truncated
const v = "v1.2.3"
for i := 0; i < len(v); i++ {
if isFIPSVersion(v[:i]) {
t.Errorf("isFIPSVersion(%q) = true, want false", v[:i])
}
}
// bad
for _, s := range badFIPS {
if isFIPSVersion(s) {
t.Errorf("isFIPSVersion(%q) = true, want false", s)
}
}
}
1 change: 1 addition & 0 deletions src/internal/cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const KnownEnv = `
GOENV
GOEXE
GOEXPERIMENT
GOFIPS140
GOFLAGS
GOGCCFLAGS
GOHOSTARCH
Expand Down

0 comments on commit 4d61704

Please sign in to comment.