Skip to content

Commit 6114b69

Browse files
FiloSottilegopherbot
authored andcommitted
crypto/tls: relax native FIPS 140-3 mode
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 <[email protected]> Reviewed-by: Junyang Shao <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]> Reviewed-by: Daniel McCarney <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent 59afdd3 commit 6114b69

File tree

5 files changed

+108
-8
lines changed

5 files changed

+108
-8
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
When [FIPS 140-3 mode](/doc/security/fips140) is enabled, Extended Master Secret
2-
is now required in TLS 1.2.
2+
is now required in TLS 1.2, and Ed25519 and X25519MLKEM768 are now allowed.

src/crypto/tls/defaults_boring.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5+
//go:build boringcrypto
6+
57
package tls
68

79
import (

src/crypto/tls/defaults_fips140.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !boringcrypto
6+
7+
package tls
8+
9+
import (
10+
"crypto/ecdsa"
11+
"crypto/ed25519"
12+
"crypto/elliptic"
13+
"crypto/rsa"
14+
"crypto/x509"
15+
)
16+
17+
// These FIPS 140-3 policies allow anything approved by SP 800-140C
18+
// and SP 800-140D, and tested as part of the Go Cryptographic Module.
19+
//
20+
// Notably, not SHA-1, 3DES, RC4, ChaCha20Poly1305, RSA PKCS #1 v1.5 key
21+
// transport, or TLS 1.0—1.1 (because we don't test its KDF).
22+
//
23+
// These are not default lists, but filters to apply to the default or
24+
// configured lists. Missing items are treated as if they were not implemented.
25+
//
26+
// They are applied when the fips140 GODEBUG is "on" or "only".
27+
28+
var (
29+
allowedSupportedVersionsFIPS = []uint16{
30+
VersionTLS12,
31+
VersionTLS13,
32+
}
33+
allowedCurvePreferencesFIPS = []CurveID{
34+
X25519MLKEM768,
35+
CurveP256,
36+
CurveP384,
37+
CurveP521,
38+
}
39+
allowedSupportedSignatureAlgorithmsFIPS = []SignatureScheme{
40+
PSSWithSHA256,
41+
ECDSAWithP256AndSHA256,
42+
Ed25519,
43+
PSSWithSHA384,
44+
PSSWithSHA512,
45+
PKCS1WithSHA256,
46+
PKCS1WithSHA384,
47+
PKCS1WithSHA512,
48+
ECDSAWithP384AndSHA384,
49+
ECDSAWithP521AndSHA512,
50+
}
51+
allowedCipherSuitesFIPS = []uint16{
52+
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
53+
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
54+
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
55+
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
56+
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
57+
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
58+
}
59+
allowedCipherSuitesTLS13FIPS = []uint16{
60+
TLS_AES_128_GCM_SHA256,
61+
TLS_AES_256_GCM_SHA384,
62+
}
63+
)
64+
65+
func isCertificateAllowedFIPS(c *x509.Certificate) bool {
66+
switch k := c.PublicKey.(type) {
67+
case *rsa.PublicKey:
68+
return k.N.BitLen() >= 2048
69+
case *ecdsa.PublicKey:
70+
return k.Curve == elliptic.P256() || k.Curve == elliptic.P384() || k.Curve == elliptic.P521()
71+
case ed25519.PublicKey:
72+
return true
73+
default:
74+
return false
75+
}
76+
}

src/crypto/tls/fips140_test.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package tls
77
import (
88
"crypto/ecdsa"
99
"crypto/elliptic"
10+
"crypto/internal/boring"
1011
"crypto/rand"
1112
"crypto/rsa"
1213
"crypto/x509"
@@ -109,16 +110,31 @@ func isFIPSCipherSuite(id uint16) bool {
109110
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
110111
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
111112
return true
112-
default:
113+
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
114+
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
115+
// Only for the native module.
116+
return !boring.Enabled
117+
}
118+
switch {
119+
case strings.Contains(name, "CHACHA20"):
120+
return false
121+
case strings.HasSuffix(name, "_SHA"): // SHA-1
113122
return false
123+
case strings.HasPrefix(name, "TLS_RSA"): // RSA kex
124+
return false
125+
default:
126+
panic("unknown cipher suite: " + name)
114127
}
115128
}
116129

117130
func isFIPSCurve(id CurveID) bool {
118131
switch id {
119132
case CurveP256, CurveP384, CurveP521:
120133
return true
121-
case X25519, X25519MLKEM768:
134+
case X25519MLKEM768:
135+
// Only for the native module.
136+
return !boring.Enabled
137+
case X25519:
122138
return false
123139
default:
124140
panic("unknown curve: " + id.String())
@@ -146,7 +162,10 @@ func isFIPSSignatureScheme(alg SignatureScheme) bool {
146162
PSSWithSHA384,
147163
PSSWithSHA512:
148164
return true
149-
case Ed25519, PKCS1WithSHA1, ECDSAWithSHA1:
165+
case Ed25519:
166+
// Only for the native module.
167+
return !boring.Enabled
168+
case PKCS1WithSHA1, ECDSAWithSHA1:
150169
return false
151170
default:
152171
panic("unknown signature scheme: " + alg.String())

src/crypto/tls/tls.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
//
88
// # FIPS 140-3 mode
99
//
10-
// When the program is in [FIPS 140-3 mode], this package behaves as if
11-
// only protocol versions, cipher suites, signature algorithms, and
12-
// key exchange algorithms approved by NIST SP 800-52r2 are implemented.
13-
// Others are silently ignored and not negotiated.
10+
// When the program is in [FIPS 140-3 mode], this package behaves as if only
11+
// SP 800-140C and SP 800-140D approved protocol versions, cipher suites,
12+
// signature algorithms, certificate public key types and sizes, and key
13+
// exchange and derivation algorithms were implemented. Others are silently
14+
// ignored and not negotiated, or rejected. This set may depend on the
15+
// algorithms supported by the FIPS 140-3 Go Cryptographic Module selected with
16+
// GOFIPS140, and may change across Go versions.
1417
//
1518
// [FIPS 140-3 mode]: https://go.dev/doc/security/fips140
1619
package tls

0 commit comments

Comments
 (0)