Skip to content

Commit

Permalink
move FIPS enabled logic to its own package
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Dec 12, 2024
1 parent c02ce9c commit cbc67db
Show file tree
Hide file tree
Showing 3 changed files with 327 additions and 183 deletions.
317 changes: 225 additions & 92 deletions patches/0002-Add-crypto-backend-foundation.patch
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,78 @@ Date: Thu, 30 Jun 2022 10:03:03 +0200
Subject: [PATCH] Add crypto backend foundation

---
src/crypto/aes/cipher.go | 2 +-
src/crypto/aes/cipher_asm.go | 2 +-
src/crypto/boring/boring.go | 2 +-
src/crypto/des/cipher.go | 7 +
src/crypto/dsa/dsa.go | 13 ++
src/crypto/ecdh/ecdh.go | 2 +-
src/crypto/ecdh/nist.go | 2 +-
src/crypto/ecdsa/boring.go | 4 +-
src/crypto/ecdsa/ecdsa.go | 4 +-
src/crypto/ecdsa/notboring.go | 2 +-
src/crypto/ed25519/boring.go | 71 +++++++
src/crypto/ed25519/ed25519.go | 75 ++++++-
src/crypto/ed25519/ed25519_test.go | 2 +-
src/crypto/ed25519/notboring.go | 16 ++
src/crypto/hmac/hmac.go | 2 +-
src/crypto/hmac/hmac_test.go | 2 +-
src/crypto/internal/backend/backend_test.go | 30 +++
src/crypto/internal/backend/bbig/big.go | 17 ++
src/crypto/internal/backend/common.go | 92 +++++++++
src/crypto/internal/backend/isrequirefips.go | 9 +
src/crypto/internal/backend/nobackend.go | 201 +++++++++++++++++++
src/crypto/internal/backend/norequirefips.go | 9 +
src/crypto/internal/backend/stub.s | 10 +
src/crypto/md5/md5.go | 7 +
src/crypto/md5/md5_test.go | 14 ++
src/crypto/purego_test.go | 2 +-
src/crypto/rand/rand.go | 2 +-
src/crypto/rand/rand_test.go | 2 +-
src/crypto/rc4/rc4.go | 18 ++
src/crypto/rsa/boring.go | 4 +-
src/crypto/rsa/notboring.go | 2 +-
src/crypto/rsa/pkcs1v15.go | 10 +-
src/crypto/rsa/pkcs1v15_test.go | 5 +
src/crypto/rsa/pss.go | 8 +-
src/crypto/rsa/rsa.go | 21 +-
src/crypto/rsa/rsa_test.go | 12 +-
src/crypto/sha1/sha1.go | 2 +-
src/crypto/sha1/sha1_test.go | 12 +-
src/crypto/sha256/sha256.go | 6 +-
src/crypto/sha256/sha256_test.go | 20 +-
src/crypto/sha512/sha512.go | 2 +-
src/crypto/sha512/sha512_test.go | 20 +-
src/crypto/tls/boring_test.go | 5 +
src/crypto/tls/cipher_suites.go | 2 +-
src/crypto/tls/handshake_client.go | 25 ++-
src/crypto/tls/handshake_server.go | 25 ++-
src/crypto/tls/handshake_server_tls13.go | 10 +
src/crypto/tls/key_schedule.go | 18 +-
src/crypto/tls/prf.go | 77 ++++---
src/crypto/tls/prf_test.go | 12 +-
src/crypto/x509/boring_test.go | 5 +
src/go/build/deps_test.go | 4 +
src/hash/boring_test.go | 5 +
src/hash/marshal_test.go | 5 +
src/hash/notboring_test.go | 5 +
src/net/smtp/smtp_test.go | 72 ++++---
src/runtime/runtime_boring.go | 5 +
57 files changed, 914 insertions(+), 106 deletions(-)
src/crypto/aes/cipher.go | 2 +-
src/crypto/aes/cipher_asm.go | 2 +-
src/crypto/boring/boring.go | 2 +-
src/crypto/des/cipher.go | 7 +
src/crypto/dsa/dsa.go | 13 ++
src/crypto/ecdh/ecdh.go | 2 +-
src/crypto/ecdh/nist.go | 2 +-
src/crypto/ecdsa/boring.go | 4 +-
src/crypto/ecdsa/ecdsa.go | 4 +-
src/crypto/ecdsa/notboring.go | 2 +-
src/crypto/ed25519/boring.go | 71 +++++++
src/crypto/ed25519/ed25519.go | 75 ++++++-
src/crypto/ed25519/ed25519_test.go | 2 +-
src/crypto/ed25519/notboring.go | 16 ++
src/crypto/hmac/hmac.go | 2 +-
src/crypto/hmac/hmac_test.go | 2 +-
src/crypto/internal/backend/backend_test.go | 30 +++
src/crypto/internal/backend/bbig/big.go | 17 ++
src/crypto/internal/backend/common.go | 68 ++++++
.../internal/backend/fips140/fips140.go | 55 +++++
.../internal/backend/fips140/isrequirefips.go | 10 +
.../internal/backend/fips140/norequirefips.go | 9 +
.../internal/backend/fips140/nosystemfips.go | 9 +
src/crypto/internal/backend/isrequirefips.go | 9 +
src/crypto/internal/backend/nobackend.go | 201 ++++++++++++++++++
src/crypto/internal/backend/norequirefips.go | 9 +
src/crypto/internal/backend/stub.s | 10 +
src/crypto/internal/boring/fipstls/tls.go | 7 +
src/crypto/md5/md5.go | 7 +
src/crypto/md5/md5_test.go | 14 ++
src/crypto/purego_test.go | 2 +-
src/crypto/rand/rand.go | 2 +-
src/crypto/rand/rand_test.go | 2 +-
src/crypto/rc4/rc4.go | 18 ++
src/crypto/rsa/boring.go | 4 +-
src/crypto/rsa/notboring.go | 2 +-
src/crypto/rsa/pkcs1v15.go | 10 +-
src/crypto/rsa/pkcs1v15_test.go | 5 +
src/crypto/rsa/pss.go | 8 +-
src/crypto/rsa/rsa.go | 21 +-
src/crypto/rsa/rsa_test.go | 12 +-
src/crypto/sha1/sha1.go | 2 +-
src/crypto/sha1/sha1_test.go | 12 +-
src/crypto/sha256/sha256.go | 6 +-
src/crypto/sha256/sha256_test.go | 20 +-
src/crypto/sha512/sha512.go | 2 +-
src/crypto/sha512/sha512_test.go | 20 +-
src/crypto/tls/boring_test.go | 5 +
src/crypto/tls/cipher_suites.go | 2 +-
src/crypto/tls/handshake_client.go | 25 ++-
src/crypto/tls/handshake_server.go | 25 ++-
src/crypto/tls/handshake_server_tls13.go | 10 +
src/crypto/tls/key_schedule.go | 18 +-
src/crypto/tls/prf.go | 77 +++++--
src/crypto/tls/prf_test.go | 12 +-
src/crypto/x509/boring_test.go | 5 +
src/go/build/deps_test.go | 11 +-
src/hash/boring_test.go | 5 +
src/hash/marshal_test.go | 5 +
src/hash/notboring_test.go | 5 +
src/net/smtp/smtp_test.go | 72 ++++---
src/runtime/runtime_boring.go | 5 +
62 files changed, 986 insertions(+), 107 deletions(-)
create mode 100644 src/crypto/ed25519/boring.go
create mode 100644 src/crypto/ed25519/notboring.go
create mode 100644 src/crypto/internal/backend/backend_test.go
create mode 100644 src/crypto/internal/backend/bbig/big.go
create mode 100644 src/crypto/internal/backend/common.go
create mode 100644 src/crypto/internal/backend/fips140/fips140.go
create mode 100644 src/crypto/internal/backend/fips140/isrequirefips.go
create mode 100644 src/crypto/internal/backend/fips140/norequirefips.go
create mode 100644 src/crypto/internal/backend/fips140/nosystemfips.go
create mode 100644 src/crypto/internal/backend/isrequirefips.go
create mode 100644 src/crypto/internal/backend/nobackend.go
create mode 100644 src/crypto/internal/backend/norequirefips.go
Expand Down Expand Up @@ -576,58 +585,34 @@ index 00000000000000..85bd3ed083f5b2
+}
diff --git a/src/crypto/internal/backend/common.go b/src/crypto/internal/backend/common.go
new file mode 100644
index 00000000000000..bc595e91024f11
index 00000000000000..07d965bf8b467c
--- /dev/null
+++ b/src/crypto/internal/backend/common.go
@@ -0,0 +1,92 @@
@@ -0,0 +1,68 @@
+// Copyright 2022 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 backend
+
+import (
+ "crypto/internal/backend/fips140"
+ "crypto/internal/boring/sig"
+ "internal/goexperiment"
+ "runtime"
+ "syscall"
+)
+
+func init() {
+ if v, r, ok := envGoFIPS(); ok && v == "1" {
+ if fips140.Enabled() {
+ if !Enabled {
+ if runtime.GOOS != "linux" && runtime.GOOS != "windows" {
+ panic("FIPS mode requested (" + r + ") but no crypto backend is supported on " + runtime.GOOS)
+ panic("FIPS mode requested (" + fips140.Message + ") but no crypto backend is supported on " + runtime.GOOS)
+ }
+ panic("FIPS mode requested (" + r + ") but no supported crypto backend is enabled")
+ panic("FIPS mode requested (" + fips140.Message + ") but no supported crypto backend is enabled")
+ }
+ }
+}
+
+func envGoFIPS() (value string, reason string, ok bool) {
+ // TODO: Decide which environment variable to use.
+ // See https://github.com/microsoft/go/issues/397.
+ var varName string
+ if value, ok = syscall.Getenv("GOFIPS"); ok {
+ varName = "GOFIPS"
+ } else if value, ok = syscall.Getenv("GOLANG_FIPS"); ok {
+ varName = "GOLANG_FIPS"
+ }
+ if isRequireFIPS {
+ if ok && value != "1" {
+ panic("the 'requirefips' build tag is enabled, but it conflicts " +
+ "with the detected env variable " +
+ varName + "=" + value +
+ " which would disable FIPS mode")
+ }
+ return "1", "requirefips tag set", true
+ }
+ if ok {
+ return value, "environment variable " + varName + "=1", true
+ }
+ return "", "", false
+}
+
+// Unreachable marks code that should be unreachable
+// when backend is in use.
+func Unreachable() {
Expand Down Expand Up @@ -672,6 +657,116 @@ index 00000000000000..bc595e91024f11
+ // Given the above reasons, we only support 2-prime RSA keys.
+ return primes == 2
+}
diff --git a/src/crypto/internal/backend/fips140/fips140.go b/src/crypto/internal/backend/fips140/fips140.go
new file mode 100644
index 00000000000000..c823b30099a3c3
--- /dev/null
+++ b/src/crypto/internal/backend/fips140/fips140.go
@@ -0,0 +1,55 @@
+// 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 fips140
+
+import "syscall"
+
+// Enabled reports whether FIPS 140 mode is enabled by using GOFIPS=1, GOLANG_FIPS=1,
+// the 'requirefips' build tag, or any other platform-specific mechanism.
+func Enabled() bool {
+ return enabled
+}
+
+var enabled bool
+
+// Disabled reports whether FIPS 140 mode is disabled by using GOFIPS=0 or GOLANG_FIPS=1.
+func Disabled() bool {
+ return disabled
+}
+
+var disabled bool
+
+// Message is a human-readable message about how [Enabled] was set.
+var Message string
+
+func init() {
+ // TODO: Decide which environment variable to use.
+ // See https://github.com/microsoft/go/issues/397.
+ var value string
+ var ok bool
+ if value, ok = syscall.Getenv("GOFIPS"); ok {
+ Message = "environment variable GOFIPS"
+ } else if value, ok = syscall.Getenv("GOLANG_FIPS"); ok {
+ Message = "environment variable GOLANG_FIPS"
+ } else if systemFIPSMode() {
+ Message = "system FIPS mode"
+ value = "1"
+ }
+ if value == "1" {
+ enabled = true
+ } else if value == "0" {
+ disabled = true
+ }
+ if isRequireFIPS {
+ if disabled {
+ panic("the 'requirefips' build tag is enabled, but it conflicts " +
+ "with the " + Message + "=" + value +
+ " which would disable FIPS mode")
+ }
+ Message = "requirefips tag set"
+ enabled = true
+ return
+ }
+}
\ No newline at end of file
diff --git a/src/crypto/internal/backend/fips140/isrequirefips.go b/src/crypto/internal/backend/fips140/isrequirefips.go
new file mode 100644
index 00000000000000..dc66b2e1b1c65b
--- /dev/null
+++ b/src/crypto/internal/backend/fips140/isrequirefips.go
@@ -0,0 +1,10 @@
+// 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 requirefips
+
+package backend
+package fips140
+
+const isRequireFIPS = true
\ No newline at end of file
diff --git a/src/crypto/internal/backend/fips140/norequirefips.go b/src/crypto/internal/backend/fips140/norequirefips.go
new file mode 100644
index 00000000000000..6f01b9a3524dee
--- /dev/null
+++ b/src/crypto/internal/backend/fips140/norequirefips.go
@@ -0,0 +1,9 @@
+// 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 !requirefips
+
+package fips140
+
+const isRequireFIPS = false
\ No newline at end of file
diff --git a/src/crypto/internal/backend/fips140/nosystemfips.go b/src/crypto/internal/backend/fips140/nosystemfips.go
new file mode 100644
index 00000000000000..9e12c6d5d2239c
--- /dev/null
+++ b/src/crypto/internal/backend/fips140/nosystemfips.go
@@ -0,0 +1,9 @@
+// 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 fips140
+
+func systemFIPSMode() bool {
+ return false
+}
diff --git a/src/crypto/internal/backend/isrequirefips.go b/src/crypto/internal/backend/isrequirefips.go
new file mode 100644
index 00000000000000..e5d7570d6d4363
Expand Down Expand Up @@ -925,6 +1020,30 @@ index 00000000000000..5e4b436554d44d
+// Having this assembly file keeps the go command
+// from complaining about the missing body
+// (because the implementation might be here).
diff --git a/src/crypto/internal/boring/fipstls/tls.go b/src/crypto/internal/boring/fipstls/tls.go
index b51f142fde8311..108b52d9d8fcb7 100644
--- a/src/crypto/internal/boring/fipstls/tls.go
+++ b/src/crypto/internal/boring/fipstls/tls.go
@@ -10,12 +10,19 @@
package fipstls

import (
+ "crypto/internal/backend/fips140"
"internal/stringslite"
"sync/atomic"
)

var required atomic.Bool

+func init() {
+ if fips140.Enabled() {
+ Force()
+ }
+}
+
// Force forces crypto/tls to restrict TLS configurations to FIPS-approved settings.
// By design, this call is impossible to undo (except in tests).
//
diff --git a/src/crypto/md5/md5.go b/src/crypto/md5/md5.go
index c984c3f4968598..229dd457f8d53c 100644
--- a/src/crypto/md5/md5.go
Expand Down Expand Up @@ -1977,10 +2096,22 @@ index 319ac61f49c994..1b2454dbaab264 100644
t.Helper()
k, err := rsa.GenerateKey(rand.Reader, size)
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index c6a2518f62ff3a..578b4d6f68504c 100644
index c6a2518f62ff3a..6c7229b41c825e 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -464,7 +464,9 @@ var depsRules = `
@@ -457,14 +457,20 @@ var depsRules = `
< crypto/internal/fips/hmac
< FIPS;

+ syscall < crypto/internal/backend/fips140;
+
NONE < crypto/internal/boring/sig, crypto/internal/boring/syso;
- sync/atomic < crypto/internal/boring/bcache, crypto/internal/boring/fipstls;
+ sync/atomic,
+ crypto/internal/backend/fips140
+ < crypto/internal/boring/bcache, crypto/internal/boring/fipstls;
crypto/internal/boring/sig, crypto/internal/boring/fipstls < crypto/tls/fipsonly;

# CRYPTO is core crypto algorithms - no cgo, fmt, net.
FIPS,
crypto/internal/boring/sig,
Expand All @@ -1990,15 +2121,17 @@ index c6a2518f62ff3a..578b4d6f68504c 100644
golang.org/x/sys/cpu,
hash, embed
< crypto
@@ -475,6 +477,7 @@ var depsRules = `
@@ -474,7 +480,9 @@ var depsRules = `

crypto/cipher,
crypto/internal/boring/bcache
+ crypto/internal/backend/fips140
< crypto/internal/boring
+ < crypto/internal/backend
< crypto/boring;

crypto/internal/alias, math/rand/v2
@@ -512,6 +515,7 @@ var depsRules = `
@@ -512,6 +520,7 @@ var depsRules = `
# CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok.
CRYPTO, FMT, math/big
< crypto/internal/boring/bbig
Expand Down
Loading

0 comments on commit cbc67db

Please sign in to comment.