]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/dist: add GOFIPS140 setting
authorRuss Cox <rsc@golang.org>
Thu, 14 Nov 2024 07:31:46 +0000 (02:31 -0500)
committerGopher Robot <gobot@golang.org>
Tue, 19 Nov 2024 18:48:15 +0000 (18:48 +0000)
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 #70200.

Change-Id: Iafcb5a4207f00fae8bcd93e0184a63c72526abea
Reviewed-on: https://go-review.googlesource.com/c/go/+/629196
Reviewed-by: Michael Matloob <matloob@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/dist/build.go
src/cmd/dist/buildruntime.go
src/internal/buildcfg/cfg.go
src/internal/buildcfg/cfg_test.go
src/internal/cfg/cfg.go

index a75799c2e708eed9e4b9019a55fda97d557ddeae..1f467647f56143e98e00a950ae2a15d8759ba468 100644 (file)
@@ -46,6 +46,7 @@ var (
        gogcflags        string // For running built compiler
        goldflags        string
        goexperiment     string
+       gofips140        string
        workdir          string
        tooldir          string
        oldgoos          string
@@ -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"+
@@ -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,
index 3eec9133fd8ef0bab72137930846fa1ac9e102d0..73260246faa5a1fd8d325d38976eed358b000978 100644 (file)
@@ -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)
 }
index 76b74aa61be723fca0fa79092ad9d8f0567211fd..1d6dc0ff3c1e50b0637e983c38bf9b76772d435f 100644 (file)
@@ -34,6 +34,7 @@ var (
        GOWASM    = gowasm()
        ToolTags  = toolTags()
        GO_LDSO   = defaultGO_LDSO
+       GOFIPS140 = gofips140()
        Version   = version
 )
 
@@ -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
index d01cdd010961b4fe3c84eae2065ff3171493e07b..757270b7788f27c8805ba695dc4ddb49f977aac6 100644 (file)
@@ -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)
+               }
+       }
+}
index ca5ab50efdb36de1e61913f0b0727c9ddf5047ea..9329769721b7debfa20f3a2f04b6361939c7ea62 100644 (file)
@@ -44,6 +44,7 @@ const KnownEnv = `
        GOENV
        GOEXE
        GOEXPERIMENT
+       GOFIPS140
        GOFLAGS
        GOGCCFLAGS
        GOHOSTARCH