Skip to content

crypto/tls: permit TLS 1.3 in FIPS-mode #62373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/crypto/internal/boring/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ WORKDIR /boring
ENV LANG=C
ENV LANGUAGE=

# Following NIST submission draft dated July 3, 2021.
# Following NIST submission dated May 6, 2022.
# This corresponds to boringssl.googlesource.com/boringssl tag fips-20210429.
ENV ClangV=12
RUN apt-get update && \
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/internal/boring/LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ When building with GOEXPERIMENT=boringcrypto, the following applies.
The goboringcrypto_linux_amd64.syso object file is built
from BoringSSL source code by build/build.sh and is covered
by the BoringSSL license reproduced below and also at
https://boringssl.googlesource.com/boringssl/+/fips-20190808/LICENSE.
https://boringssl.googlesource.com/boringssl/+/fips-20210429/LICENSE.

BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
licensing. Files that are completely new have a Google copyright and an ISC
Expand Down
32 changes: 25 additions & 7 deletions src/crypto/internal/boring/aes.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,26 +228,44 @@ func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
if tagSize != gcmTagSize {
return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize)
}
return c.newGCM(false)
return c.newGCM(0)
}

// Copied from crypto/tls/common.go, but values don't actually matter here.
const (
VersionTLS12 = 0x0303
VersionTLS13 = 0x0304
)

func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) {
return c.(*aesCipher).newGCM(true)
return c.(*aesCipher).newGCM(VersionTLS12)
}

func NewGCMTLS13(c cipher.Block) (cipher.AEAD, error) {
return c.(*aesCipher).newGCM(VersionTLS13)
}

func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) {
func (c *aesCipher) newGCM(tlsVersion uint16) (cipher.AEAD, error) {
var aead *C.GO_EVP_AEAD
switch len(c.key) * 8 {
case 128:
if tls {
switch tlsVersion {
case VersionTLS12:
aead = C._goboringcrypto_EVP_aead_aes_128_gcm_tls12()
} else {
case VersionTLS13:
aead = C._goboringcrypto_EVP_aead_aes_128_gcm_tls13()
default:
// Not TLS.
aead = C._goboringcrypto_EVP_aead_aes_128_gcm()
}
case 256:
if tls {
switch tlsVersion {
case VersionTLS12:
aead = C._goboringcrypto_EVP_aead_aes_256_gcm_tls12()
} else {
case VersionTLS13:
aead = C._goboringcrypto_EVP_aead_aes_256_gcm_tls13()
default:
// Not TLS.
aead = C._goboringcrypto_EVP_aead_aes_256_gcm()
}
default:
Expand Down
2 changes: 2 additions & 0 deletions src/crypto/internal/boring/goboringcrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ void _goboringcrypto_EVP_AEAD_CTX_cleanup(GO_EVP_AEAD_CTX*);
int _goboringcrypto_EVP_AEAD_CTX_seal(const GO_EVP_AEAD_CTX*, uint8_t*, size_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t);
int _goboringcrypto_EVP_AEAD_CTX_open(const GO_EVP_AEAD_CTX*, uint8_t*, size_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t);
const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_128_gcm_tls12(void);
const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_128_gcm_tls13(void);
const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_256_gcm_tls12(void);
const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_256_gcm_tls13(void);
enum go_evp_aead_direction_t {
go_evp_aead_open = 0,
go_evp_aead_seal = 1
Expand Down
1 change: 1 addition & 0 deletions src/crypto/internal/boring/notboring.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: no

func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") }
func NewGCMTLS(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") }
func NewGCMTLS13(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") }

type PublicKeyECDSA struct{ _ int }
type PrivateKeyECDSA struct{ _ int }
Expand Down
11 changes: 8 additions & 3 deletions src/crypto/tls/boring.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@ func needFIPS() bool {

// fipsMinVersion replaces c.minVersion in FIPS-only mode.
func fipsMinVersion(c *Config) uint16 {
// FIPS requires TLS 1.2.
// FIPS required minimum of TLS 1.2 (see NIST SP 800-52).
return VersionTLS12
}

// fipsMaxVersion replaces c.maxVersion in FIPS-only mode.
func fipsMaxVersion(c *Config) uint16 {
// FIPS requires TLS 1.2.
return VersionTLS12
// FIPS required maximum of TLS 1.3 (see NIST SP 800-52).
return VersionTLS13
}

// default defaultFIPSCurvePreferences is the FIPS-allowed curves,
// in preference order (most preferable first).
// See NIST SP 800-186.
var defaultFIPSCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}

// fipsCurvePreferences replaces c.curvePreferences in FIPS-only mode.
Expand All @@ -49,7 +50,10 @@ func fipsCurvePreferences(c *Config) []CurveID {
}

// defaultCipherSuitesFIPS are the FIPS-allowed cipher suites.
// See NIST SP 800-52.
var defaultCipherSuitesFIPS = []uint16{
TLS_AES_128_GCM_SHA256,
TLS_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
Expand Down Expand Up @@ -77,6 +81,7 @@ func fipsCipherSuites(c *Config) []uint16 {

// fipsSupportedSignatureAlgorithms currently are a subset of
// defaultSupportedSignatureAlgorithms without Ed25519 and SHA-1.
// See FIPS 186-5.
var fipsSupportedSignatureAlgorithms = []SignatureScheme{
PSSWithSHA256,
PSSWithSHA384,
Expand Down
12 changes: 9 additions & 3 deletions src/crypto/tls/boring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,22 @@ func TestBoringServerProtocolVersion(t *testing.T) {
test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
test("VersionTLS12", VersionTLS12, "")
test("VersionTLS13", VersionTLS13, "client offered only unsupported versions")
test("VersionTLS13", VersionTLS13, "")
}

func isBoringVersion(v uint16) bool {
return v == VersionTLS12
switch v {
case VersionTLS12, VersionTLS13:
return true
}
return false
}

func isBoringCipherSuite(id uint16) bool {
switch id {
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
case TLS_AES_128_GCM_SHA256,
TLS_AES_256_GCM_SHA384,
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,
Expand Down
8 changes: 7 additions & 1 deletion src/crypto/tls/cipher_suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,13 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead {
if err != nil {
panic(err)
}
aead, err := cipher.NewGCM(aes)
var aead cipher.AEAD
if boring.Enabled {
aead, err = boring.NewGCMTLS13(aes)
} else {
boring.Unreachable()
aead, err = cipher.NewGCM(aes)
}
if err != nil {
panic(err)
}
Expand Down
1 change: 1 addition & 0 deletions src/crypto/x509/boring.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func boringAllowCert(c *Certificate) bool {

// The key must be RSA 2048, RSA 3072, RSA 4096,
// or ECDSA P-256, P-384, P-521.
// See FIPS 186-5 and NIST SP 800-186.
switch k := c.PublicKey.(type) {
default:
return false
Expand Down