]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: relax native FIPS 140-3 mode
authorFilippo Valsorda <filippo@golang.org>
Wed, 19 Feb 2025 11:29:31 +0000 (12:29 +0100)
committerGopher Robot <gobot@golang.org>
Thu, 13 Mar 2025 20:33:22 +0000 (13:33 -0700)
We are going to stick to BoringSSL's policy for Go+BoringCrypto, but
when using the native FIPS 140-3 module we can allow Ed25519, ML-KEM,
and P-521.

NIST SP 800-52r2 is stricter, but it only applies to some entities, so
they can restrict the profile with Config.

Fixes #71757

Change-Id: I6a6a4656eb02e56d079f0a22f98212275a40a679
Reviewed-on: https://go-review.googlesource.com/c/go/+/650576
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: David Chase <drchase@google.com>
doc/next/6-stdlib/99-minor/crypto/tls/fips.md
src/crypto/tls/defaults_boring.go
src/crypto/tls/defaults_fips140.go [new file with mode: 0644]
src/crypto/tls/fips140_test.go
src/crypto/tls/tls.go

index 8a81688af6c884c46546eb8cab41ad9dbced05c6..0f0c9459cee0c246b8b4c6f52fc9d27d1cbb2301 100644 (file)
@@ -1,2 +1,2 @@
 When [FIPS 140-3 mode](/doc/security/fips140) is enabled, Extended Master Secret
-is now required in TLS 1.2.
+is now required in TLS 1.2, and Ed25519 and X25519MLKEM768 are now allowed.
index 8356ee6932aa00142255ca449172517cb7896ad5..96406acfca0f5434e8e03d4af97c7c8b865822c5 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build boringcrypto
+
 package tls
 
 import (
diff --git a/src/crypto/tls/defaults_fips140.go b/src/crypto/tls/defaults_fips140.go
new file mode 100644 (file)
index 0000000..472bb80
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2025 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 !boringcrypto
+
+package tls
+
+import (
+       "crypto/ecdsa"
+       "crypto/ed25519"
+       "crypto/elliptic"
+       "crypto/rsa"
+       "crypto/x509"
+)
+
+// These FIPS 140-3 policies allow anything approved by SP 800-140C
+// and SP 800-140D, and tested as part of the Go Cryptographic Module.
+//
+// Notably, not SHA-1, 3DES, RC4, ChaCha20Poly1305, RSA PKCS #1 v1.5 key
+// transport, or TLS 1.0—1.1 (because we don't test its KDF).
+//
+// These are not default lists, but filters to apply to the default or
+// configured lists. Missing items are treated as if they were not implemented.
+//
+// They are applied when the fips140 GODEBUG is "on" or "only".
+
+var (
+       allowedSupportedVersionsFIPS = []uint16{
+               VersionTLS12,
+               VersionTLS13,
+       }
+       allowedCurvePreferencesFIPS = []CurveID{
+               X25519MLKEM768,
+               CurveP256,
+               CurveP384,
+               CurveP521,
+       }
+       allowedSupportedSignatureAlgorithmsFIPS = []SignatureScheme{
+               PSSWithSHA256,
+               ECDSAWithP256AndSHA256,
+               Ed25519,
+               PSSWithSHA384,
+               PSSWithSHA512,
+               PKCS1WithSHA256,
+               PKCS1WithSHA384,
+               PKCS1WithSHA512,
+               ECDSAWithP384AndSHA384,
+               ECDSAWithP521AndSHA512,
+       }
+       allowedCipherSuitesFIPS = []uint16{
+               TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+               TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+               TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+               TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+               TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+               TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+       }
+       allowedCipherSuitesTLS13FIPS = []uint16{
+               TLS_AES_128_GCM_SHA256,
+               TLS_AES_256_GCM_SHA384,
+       }
+)
+
+func isCertificateAllowedFIPS(c *x509.Certificate) bool {
+       switch k := c.PublicKey.(type) {
+       case *rsa.PublicKey:
+               return k.N.BitLen() >= 2048
+       case *ecdsa.PublicKey:
+               return k.Curve == elliptic.P256() || k.Curve == elliptic.P384() || k.Curve == elliptic.P521()
+       case ed25519.PublicKey:
+               return true
+       default:
+               return false
+       }
+}
index 9ea32a6d9a25450167574c077e2f65a1e92da01e..c22ad485ccdae561c45c16a7a3119471aff6de15 100644 (file)
@@ -7,6 +7,7 @@ package tls
 import (
        "crypto/ecdsa"
        "crypto/elliptic"
+       "crypto/internal/boring"
        "crypto/rand"
        "crypto/rsa"
        "crypto/x509"
@@ -109,8 +110,20 @@ func isFIPSCipherSuite(id uint16) bool {
                TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
                return true
-       default:
+       case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+               TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+               // Only for the native module.
+               return !boring.Enabled
+       }
+       switch {
+       case strings.Contains(name, "CHACHA20"):
+               return false
+       case strings.HasSuffix(name, "_SHA"): // SHA-1
                return false
+       case strings.HasPrefix(name, "TLS_RSA"): // RSA kex
+               return false
+       default:
+               panic("unknown cipher suite: " + name)
        }
 }
 
@@ -118,7 +131,10 @@ func isFIPSCurve(id CurveID) bool {
        switch id {
        case CurveP256, CurveP384, CurveP521:
                return true
-       case X25519, X25519MLKEM768:
+       case X25519MLKEM768:
+               // Only for the native module.
+               return !boring.Enabled
+       case X25519:
                return false
        default:
                panic("unknown curve: " + id.String())
@@ -146,7 +162,10 @@ func isFIPSSignatureScheme(alg SignatureScheme) bool {
                PSSWithSHA384,
                PSSWithSHA512:
                return true
-       case Ed25519, PKCS1WithSHA1, ECDSAWithSHA1:
+       case Ed25519:
+               // Only for the native module.
+               return !boring.Enabled
+       case PKCS1WithSHA1, ECDSAWithSHA1:
                return false
        default:
                panic("unknown signature scheme: " + alg.String())
index c64201abc1f406fef5d12ef7572c5a661151069c..a0fd8e835da7ae01ece0e996e8860d6df6490234 100644 (file)
@@ -7,10 +7,13 @@
 //
 // # FIPS 140-3 mode
 //
-// When the program is in [FIPS 140-3 mode], this package behaves as if
-// only protocol versions, cipher suites, signature algorithms, and
-// key exchange algorithms approved by NIST SP 800-52r2 are implemented.
-// Others are silently ignored and not negotiated.
+// When the program is in [FIPS 140-3 mode], this package behaves as if only
+// SP 800-140C and SP 800-140D approved protocol versions, cipher suites,
+// signature algorithms, certificate public key types and sizes, and key
+// exchange and derivation algorithms were implemented. Others are silently
+// ignored and not negotiated, or rejected. This set may depend on the
+// algorithms supported by the FIPS 140-3 Go Cryptographic Module selected with
+// GOFIPS140, and may change across Go versions.
 //
 // [FIPS 140-3 mode]: https://go.dev/doc/security/fips140
 package tls