Skip to content

Commit 386505a

Browse files
authored
Merge pull request #1503 from microsoft/dev/qmuntal/fips149deb
Prefer GODEBUG=fips140 over GOFIPS
1 parent 39300ba commit 386505a

File tree

5 files changed

+102
-57
lines changed

5 files changed

+102
-57
lines changed

eng/_util/cmd/run-builder/run-builder.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func main() {
147147
}
148148

149149
if *fipsMode {
150-
env("GOFIPS", "1")
150+
envAppend("GODEBUG", "fips140=on")
151151
// Enable system-wide FIPS if supported by the host platform.
152152
restore, err := enableSystemWideFIPS()
153153
if err != nil {
@@ -215,6 +215,15 @@ func env(key, value string) {
215215
}
216216
}
217217

218+
// envAppend appends a value to an env var and logs it.
219+
// Panics if it doesn't succeed.
220+
func envAppend(key, value string) {
221+
if v, ok := os.LookupEnv(key); ok {
222+
value = v + "," + value
223+
}
224+
env(key, value)
225+
}
226+
218227
func run(cmdline ...string) error {
219228
c := exec.Command(cmdline[0], cmdline[1:]...)
220229
c.Stdout = os.Stdout

eng/_util/cmd/run-builder/systemfips_fallback.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
//go:build !windows && !linux
4+
//go:build !windows
55

66
package main
77

eng/_util/cmd/run-builder/systemfips_linux.go

-31
This file was deleted.

patches/0003-Implement-crypto-internal-backend.patch

+45-21
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,26 @@ Subject: [PATCH] Implement crypto/internal/backend
77
.gitignore | 2 +
88
src/crypto/internal/backend/backend_test.go | 30 ++
99
src/crypto/internal/backend/backendgen.go | 20 +
10-
.../internal/backend/backendgen_test.go | 284 ++++++++++++++
10+
.../internal/backend/backendgen_test.go | 284 +++++++++++++
1111
src/crypto/internal/backend/bbig/big.go | 17 +
1212
.../internal/backend/bbig/big_boring.go | 12 +
1313
src/crypto/internal/backend/bbig/big_cng.go | 12 +
1414
.../internal/backend/bbig/big_darwin.go | 12 +
1515
.../internal/backend/bbig/big_openssl.go | 12 +
16-
src/crypto/internal/backend/boring_linux.go | 279 ++++++++++++++
16+
src/crypto/internal/backend/boring_linux.go | 279 +++++++++++++
1717
src/crypto/internal/backend/cng_windows.go | 336 ++++++++++++++++
1818
src/crypto/internal/backend/common.go | 59 +++
1919
src/crypto/internal/backend/darwin_darwin.go | 359 +++++++++++++++++
2020
src/crypto/internal/backend/fips140/boring.go | 11 +
2121
src/crypto/internal/backend/fips140/cng.go | 33 ++
2222
src/crypto/internal/backend/fips140/darwin.go | 11 +
23-
.../internal/backend/fips140/fips140.go | 55 +++
23+
.../internal/backend/fips140/fips140.go | 63 +++
2424
.../internal/backend/fips140/isrequirefips.go | 9 +
2525
.../internal/backend/fips140/norequirefips.go | 9 +
2626
.../backend/fips140/nosystemcrypto.go | 11 +
2727
.../internal/backend/fips140/openssl.go | 41 ++
28-
src/crypto/internal/backend/nobackend.go | 240 ++++++++++++
29-
src/crypto/internal/backend/openssl_linux.go | 360 ++++++++++++++++++
28+
src/crypto/internal/backend/nobackend.go | 240 +++++++++++
29+
src/crypto/internal/backend/openssl_linux.go | 377 ++++++++++++++++++
3030
src/crypto/internal/backend/stub.s | 10 +
3131
src/go/build/deps_test.go | 7 +-
3232
.../exp_allowcryptofallback_off.go | 9 +
@@ -45,7 +45,7 @@ Subject: [PATCH] Implement crypto/internal/backend
4545
...ckenderr_gen_requirefips_nosystemcrypto.go | 17 +
4646
.../backenderr_gen_systemcrypto_nobackend.go | 16 +
4747
src/runtime/runtime_boring.go | 5 +
48-
41 files changed, 2492 insertions(+), 1 deletion(-)
48+
41 files changed, 2517 insertions(+), 1 deletion(-)
4949
create mode 100644 src/crypto/internal/backend/backend_test.go
5050
create mode 100644 src/crypto/internal/backend/backendgen.go
5151
create mode 100644 src/crypto/internal/backend/backendgen_test.go
@@ -1676,27 +1676,32 @@ index 00000000000000..ef5af5d956163e
16761676
+}
16771677
diff --git a/src/crypto/internal/backend/fips140/fips140.go b/src/crypto/internal/backend/fips140/fips140.go
16781678
new file mode 100644
1679-
index 00000000000000..f54d39970319af
1679+
index 00000000000000..72f7a1644deedd
16801680
--- /dev/null
16811681
+++ b/src/crypto/internal/backend/fips140/fips140.go
1682-
@@ -0,0 +1,55 @@
1682+
@@ -0,0 +1,63 @@
16831683
+// Copyright 2024 The Go Authors. All rights reserved.
16841684
+// Use of this source code is governed by a BSD-style
16851685
+// license that can be found in the LICENSE file.
16861686
+
16871687
+package fips140
16881688
+
1689-
+import "syscall"
1689+
+import (
1690+
+ "internal/godebug"
1691+
+ "syscall"
1692+
+)
16901693
+
1691-
+// Enabled reports whether FIPS 140 mode is enabled by using GOFIPS=1, GOLANG_FIPS=1,
1694+
+var fips140GODEBUG = godebug.New("#fips140")
1695+
+
1696+
+// Enabled reports whether FIPS 140 mode is enabled by using GODEBUG, GOFIPS, GOLANG_FIPS,
16921697
+// the 'requirefips' build tag, or any other platform-specific mechanism.
16931698
+func Enabled() bool {
16941699
+ return enabled
16951700
+}
16961701
+
16971702
+var enabled bool
16981703
+
1699-
+// Disabled reports whether FIPS 140 mode is disabled by using GOFIPS=0 or GOLANG_FIPS=0.
1704+
+// Disabled reports whether FIPS 140 mode is disabled by using GOFIPS or GOLANG_FIPS.
17001705
+func Disabled() bool {
17011706
+ return disabled
17021707
+}
@@ -1709,9 +1714,12 @@ index 00000000000000..f54d39970319af
17091714
+func init() {
17101715
+ // TODO: Decide which environment variable to use.
17111716
+ // See https://github.com/microsoft/go/issues/397.
1712-
+ var value string
17131717
+ var ok bool
1714-
+ if value, ok = syscall.Getenv("GOFIPS"); ok {
1718+
+ value := fips140GODEBUG.Value()
1719+
+ if value == "on" || value == "only" || value == "debug" {
1720+
+ Message = "environment variable GODEBUG=fips140=" + value
1721+
+ value = "1"
1722+
+ } else if value, ok = syscall.Getenv("GOFIPS"); ok {
17151723
+ Message = "environment variable GOFIPS"
17161724
+ } else if value, ok = syscall.Getenv("GOLANG_FIPS"); ok {
17171725
+ Message = "environment variable GOLANG_FIPS"
@@ -1735,7 +1743,6 @@ index 00000000000000..f54d39970319af
17351743
+ return
17361744
+ }
17371745
+}
1738-
\ No newline at end of file
17391746
diff --git a/src/crypto/internal/backend/fips140/isrequirefips.go b/src/crypto/internal/backend/fips140/isrequirefips.go
17401747
new file mode 100644
17411748
index 00000000000000..b33d08c84e2dae
@@ -1787,7 +1794,7 @@ index 00000000000000..83691d7dd42d51
17871794
+}
17881795
diff --git a/src/crypto/internal/backend/fips140/openssl.go b/src/crypto/internal/backend/fips140/openssl.go
17891796
new file mode 100644
1790-
index 00000000000000..118efa3a492a7d
1797+
index 00000000000000..2d126bcfc053de
17911798
--- /dev/null
17921799
+++ b/src/crypto/internal/backend/fips140/openssl.go
17931800
@@ -0,0 +1,41 @@
@@ -1818,7 +1825,7 @@ index 00000000000000..118efa3a492a7d
18181825
+ // If there is an error reading we could either panic or assume FIPS is not enabled.
18191826
+ // Panicking would be too disruptive for apps that don't require FIPS.
18201827
+ // If an app wants to be 100% sure that is running in FIPS mode
1821-
+ // it should use boring.Enabled() or GOFIPS=1.
1828+
+ // it should use boring.Enabled() or GODEBUG=fips140=1.
18221829
+ return false
18231830
+ }
18241831
+ }
@@ -2080,10 +2087,10 @@ index 00000000000000..7c3a95c2c64a2d
20802087
+}
20812088
diff --git a/src/crypto/internal/backend/openssl_linux.go b/src/crypto/internal/backend/openssl_linux.go
20822089
new file mode 100644
2083-
index 00000000000000..5ddcf98ea682a5
2090+
index 00000000000000..0c4e0c9da6e1ce
20842091
--- /dev/null
20852092
+++ b/src/crypto/internal/backend/openssl_linux.go
2086-
@@ -0,0 +1,360 @@
2093+
@@ -0,0 +1,377 @@
20872094
+// Copyright 2017 The Go Authors. All rights reserved.
20882095
+// Use of this source code is governed by a BSD-style
20892096
+// license that can be found in the LICENSE file.
@@ -2150,12 +2157,29 @@ index 00000000000000..5ddcf98ea682a5
21502157
+ panic("opensslcrypto: can't initialize OpenSSL " + lcrypto + ": " + err.Error())
21512158
+ }
21522159
+ if fips140.Enabled() {
2153-
+ // Use openssl.FIPSCapable instead of openssl.FIPS because some providers, e.g. SCOSSL, are FIPS compliant
2154-
+ // even when FIPS mode is not enabled.
2160+
+ // Some distributions, e.g. Azure Linux 3, don't set the `fips=yes` property when running in FIPS mode,
2161+
+ // but they configure OpenSSL to use a FIPS-compliant provider (in the case of Azure Linux 3, the SCOSSL provider).
2162+
+ // In this cases, openssl.FIPS would return `false` and openssl.FIPSCapable would return `true`.
2163+
+ // We don't care about the `fips=yes` property as long as the provider is FIPS-compliant, so use
2164+
+ // openssl.FIPSCapable to determine whether FIPS mode is enabled.
21552165
+ if !openssl.FIPSCapable() {
2156-
+ panic("opensslcrypto: FIPS mode requested (" + fips140.Message + ") but not available in " + openssl.VersionText())
2166+
+ // This path can be reached for the following reasons:
2167+
+ // - In OpenSSL 1, the active engine doesn't support FIPS mode.
2168+
+ // - In OpenSSL 1, the active engine supports FIPS mode, but it is not enabled.
2169+
+ // - In OpenSSL 3, the provider used by default doesn't match the `fips=yes` query.
2170+
+ //
2171+
+ // A best-effort attempt is made to enable FIPS mode. It will only succeed if the following conditions are met:
2172+
+ // - In OpenSSL 1, the active engine supports FIPS mode and FIPS mode can be enabled.
2173+
+ // - In OpenSSL 3, there is an available provider that supports the `fips=yes` query.
2174+
+ //
2175+
+ // Note that this best effort is mainly to support test environments. FIPS-compliant production environments
2176+
+ // like Mariner 2 and Azure Linux 3 (when executed in kernel FIPS mode) will already be properly configured.
2177+
+ if err := openssl.SetFIPS(true); err != nil {
2178+
+ panic("opensslcrypto: FIPS mode requested (" + fips140.Message + ") but not available in " + openssl.VersionText() + ": " + err.Error())
2179+
+ }
21572180
+ }
21582181
+ } else if fips140.Disabled() {
2182+
+ // TODO: Remove this block when GOFIPS=0 is no longer supported.
21592183
+ if openssl.FIPS() {
21602184
+ panic("opensslcrypto: FIPS mode explicitly disabled (" + fips140.Message + ") but enabled in " + openssl.VersionText())
21612185
+ }

patches/0004-Use-crypto-backends.patch

+46-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Subject: [PATCH] Use crypto backends
66
---
77
src/cmd/api/boring_test.go | 2 +-
88
src/cmd/dist/build.go | 13 ++
9-
src/cmd/dist/test.go | 8 +-
9+
src/cmd/dist/test.go | 10 +-
1010
src/cmd/go/go_boring_test.go | 11 +-
1111
src/cmd/go/testdata/script/darwin_no_cgo.txt | 2 +
1212
.../go/testdata/script/gopath_std_vendor.txt | 9 +
@@ -38,6 +38,7 @@ Subject: [PATCH] Use crypto backends
3838
src/crypto/hmac/hmac_test.go | 2 +-
3939
src/crypto/internal/cryptotest/allocations.go | 2 +-
4040
.../internal/cryptotest/implementations.go | 2 +-
41+
src/crypto/internal/fips140test/check_test.go | 8 +-
4142
src/crypto/md5/md5.go | 10 +
4243
src/crypto/md5/md5_test.go | 16 ++
4344
src/crypto/pbkdf2/pbkdf2.go | 4 +
@@ -82,7 +83,7 @@ Subject: [PATCH] Use crypto backends
8283
src/net/smtp/smtp_test.go | 72 ++++---
8384
src/os/exec/exec_test.go | 9 +
8485
src/runtime/pprof/vminfo_darwin_test.go | 6 +
85-
78 files changed, 1110 insertions(+), 109 deletions(-)
86+
79 files changed, 1118 insertions(+), 111 deletions(-)
8687
create mode 100644 src/crypto/dsa/boring.go
8788
create mode 100644 src/crypto/dsa/notboring.go
8889
create mode 100644 src/crypto/ecdsa/badlinkname.go
@@ -132,9 +133,18 @@ index 1f467647f56143..4d770d7fc239e2 100644
132133
// No need to enable PGO for toolchain2.
133134
goInstall(toolenv(), goBootstrap, append([]string{"-pgo=off"}, toolchain...)...)
134135
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
135-
index 0c992118f4287b..3316bb52a61ff1 100644
136+
index 0c992118f4287b..d224514552fd63 100644
136137
--- a/src/cmd/dist/test.go
137138
+++ b/src/cmd/dist/test.go
139+
@@ -714,7 +714,7 @@ func (t *tester) registerTests() {
140+
})
141+
142+
// Check that all crypto packages compile (and test correctly, in longmode) with fips.
143+
- if t.fipsSupported() {
144+
+ if false { // Disable these tests, they don't work if CNG/OpenSSL FIPS mode is not enabled. We already have dedicated builders for this.
145+
// Test standard crypto packages with fips140=on.
146+
t.registerTest("GODEBUG=fips140=on go test crypto/...", &goTest{
147+
variant: "gofips140",
138148
@@ -1161,6 +1161,11 @@ func (t *tester) internalLink() bool {
139149
if goos == "windows" && goarch == "arm64" {
140150
return false
@@ -1155,6 +1165,39 @@ index 3fa730459050f6..1f28f12a6e7b4f 100644
11551165
"crypto/internal/impl"
11561166
"internal/goos"
11571167
"internal/testenv"
1168+
diff --git a/src/crypto/internal/fips140test/check_test.go b/src/crypto/internal/fips140test/check_test.go
1169+
index 6b0cd3f39e1695..aa586ed30454a2 100644
1170+
--- a/src/crypto/internal/fips140test/check_test.go
1171+
+++ b/src/crypto/internal/fips140test/check_test.go
1172+
@@ -5,6 +5,8 @@
1173+
package fipstest
1174+
1175+
import (
1176+
+ boring "crypto/internal/backend"
1177+
+ bfips140 "crypto/internal/backend/fips140"
1178+
"crypto/internal/fips140"
1179+
. "crypto/internal/fips140/check"
1180+
"crypto/internal/fips140/check/checktest"
1181+
@@ -18,7 +20,7 @@ import (
1182+
"unsafe"
1183+
)
1184+
1185+
-const enableFIPSTest = true
1186+
+const enableFIPSTest = boring.Enabled
1187+
1188+
func TestFIPSCheckVerify(t *testing.T) {
1189+
if Verified {
1190+
@@ -38,6 +40,10 @@ func TestFIPSCheckVerify(t *testing.T) {
1191+
t.Skipf("skipping: %v", err)
1192+
}
1193+
1194+
+ if !bfips140.Enabled() {
1195+
+ t.Skipf("skipping: FIPS is not enabled")
1196+
+ }
1197+
+
1198+
cmd := testenv.Command(t, os.Args[0], "-test.v", "-test.run=TestFIPSCheck")
1199+
cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=on")
1200+
out, err := cmd.CombinedOutput()
11581201
diff --git a/src/crypto/md5/md5.go b/src/crypto/md5/md5.go
11591202
index a0384e175f31bd..f7aa6da36f02de 100644
11601203
--- a/src/crypto/md5/md5.go

0 commit comments

Comments
 (0)