[release-branch.go1.20] Revert "crypto/internal/boring: upgrade module to fips-20220613" +1

This reverts CL 553875 ("crypto/internal/boring: upgrade module to
fips-20220613") and CL 553876 ("crypto/tls: align FIPS-only mode with
BoringSSL policy").

Fixes #65322
Updates #65321
Updates #64717
Updates #62372

Change-Id: I0938b97e5b4904e6532448b8ae76e920d03d0508
Reviewed-on: https://go-review.googlesource.com/c/go/+/558796
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit 09b5de48e64e67db92b31eaca054c5d096e3c057)
Reviewed-on: https://go-review.googlesource.com/c/go/+/560276
diff --git a/src/crypto/internal/boring/Dockerfile b/src/crypto/internal/boring/Dockerfile
index 8fde5c0..58eb028 100644
--- a/src/crypto/internal/boring/Dockerfile
+++ b/src/crypto/internal/boring/Dockerfile
@@ -13,21 +13,15 @@
 ENV LANG=C
 ENV LANGUAGE=
 
-# Following NIST submission draft for In Progress module validation.
-# This corresponds to boringssl.googlesource.com/boringssl tag fips-20220613.
+# Following NIST submission draft dated July 3, 2021.
+# This corresponds to boringssl.googlesource.com/boringssl tag fips-20210429.
+ENV ClangV=12
 RUN apt-get update && \
-        apt-get install --no-install-recommends -y cmake xz-utils wget unzip ca-certificates python lsb-release software-properties-common gnupg
-
-# Install Clang.
-ENV ClangV=14
-RUN \
-	wget https://apt.llvm.org/llvm.sh && \
-	chmod +x llvm.sh && \
-	./llvm.sh $ClangV
+        apt-get install --no-install-recommends -y cmake xz-utils wget unzip ca-certificates clang-$ClangV python
 
 # Download, validate, unpack, build, and install Ninja.
-ENV NinjaV=1.10.1
-ENV NinjaH=a6b6f7ac360d4aabd54e299cc1d8fa7b234cd81b9401693da21221c62569a23e
+ENV NinjaV=1.10.2
+ENV NinjaH=ce35865411f0490368a8fc383f29071de6690cbadc27704734978221f25e2bed
 RUN \
 	wget https://github.com/ninja-build/ninja/archive/refs/tags/v$NinjaV.tar.gz && \
 	echo "$NinjaH v$NinjaV.tar.gz" >sha && sha256sum -c sha && \
@@ -39,9 +33,9 @@
 
 # Download, validate, unpack, and install Go.
 ARG GOARCH
-ENV GoV=1.18.1
-ENV GoHamd64=b3b815f47ababac13810fc6021eb73d65478e0b2db4b09d348eefad9581a2334
-ENV GoHarm64=56a91851c97fb4697077abbca38860f735c32b38993ff79b088dac46e4735633
+ENV GoV=1.16.5
+ENV GoHamd64=b12c23023b68de22f74c0524f10b753e7b08b1504cb7e417eccebdd3fae49061
+ENV GoHarm64=d5446b46ef6f36fdffa852f73dfbbe78c1ddf010b99fa4964944b9ae8b4d6799
 RUN \
 	eval GoH=\${GoH$GOARCH} && \
 	wget https://golang.org/dl/go$GoV.linux-$GOARCH.tar.gz && \
@@ -51,8 +45,8 @@
 	ln -s /usr/local/go/bin/go /usr/local/bin/
 
 # Download, validate, and unpack BoringCrypto.
-ENV BoringV=0c6f40132b828e92ba365c6b7680e32820c63fa7
-ENV BoringH=62f733289f2d677c2723f556aa58034c438f3a7bbca6c12b156538a88e38da8a
+ENV BoringV=853ca1ea1168dff08011e5d42d94609cc0ca2e27
+ENV BoringH=a4d069ccef6f3c7bc0c68de82b91414f05cb817494cd1ab483dcf3368883c7c2
 RUN \
 	wget https://commondatastorage.googleapis.com/chromium-boringssl-fips/boringssl-$BoringV.tar.xz && \
 	echo "$BoringH boringssl-$BoringV.tar.xz" >sha && sha256sum -c sha && \
diff --git a/src/crypto/internal/boring/LICENSE b/src/crypto/internal/boring/LICENSE
index 05b0963..38990bd 100644
--- a/src/crypto/internal/boring/LICENSE
+++ b/src/crypto/internal/boring/LICENSE
@@ -6,7 +6,7 @@
 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-20220613/LICENSE.
+https://boringssl.googlesource.com/boringssl/+/fips-20190808/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
diff --git a/src/crypto/internal/boring/README.md b/src/crypto/internal/boring/README.md
index 62106cd..ec02786 100644
--- a/src/crypto/internal/boring/README.md
+++ b/src/crypto/internal/boring/README.md
@@ -27,14 +27,13 @@
 
 	GOARCH=arm64 ./build.sh
 
-Both run using Docker.
-
+Both run on an x86 Debian Linux system using Docker.
 For the arm64 build to run on an x86 system, you need
 
 	apt-get install qemu-user-static qemu-binfmt-support
 
 to allow the x86 kernel to run arm64 binaries via QEMU.
 
-For the amd64 build to run on an Apple Silicon macOS, you need Rosetta 2.
-
 See build.sh for more details about the build.
+
+
diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go
index a85c468..6fae1d54 100644
--- a/src/crypto/internal/boring/aes.go
+++ b/src/crypto/internal/boring/aes.go
@@ -228,41 +228,26 @@
 	if tagSize != gcmTagSize {
 		return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize)
 	}
-	return c.newGCM(0)
+	return c.newGCM(false)
 }
 
-const (
-	VersionTLS12 = 0x0303
-	VersionTLS13 = 0x0304
-)
-
 func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) {
-	return c.(*aesCipher).newGCM(VersionTLS12)
+	return c.(*aesCipher).newGCM(true)
 }
 
-func NewGCMTLS13(c cipher.Block) (cipher.AEAD, error) {
-	return c.(*aesCipher).newGCM(VersionTLS13)
-}
-
-func (c *aesCipher) newGCM(tlsVersion uint16) (cipher.AEAD, error) {
+func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) {
 	var aead *C.GO_EVP_AEAD
 	switch len(c.key) * 8 {
 	case 128:
-		switch tlsVersion {
-		case VersionTLS12:
+		if tls {
 			aead = C._goboringcrypto_EVP_aead_aes_128_gcm_tls12()
-		case VersionTLS13:
-			aead = C._goboringcrypto_EVP_aead_aes_128_gcm_tls13()
-		default:
+		} else {
 			aead = C._goboringcrypto_EVP_aead_aes_128_gcm()
 		}
 	case 256:
-		switch tlsVersion {
-		case VersionTLS12:
+		if tls {
 			aead = C._goboringcrypto_EVP_aead_aes_256_gcm_tls12()
-		case VersionTLS13:
-			aead = C._goboringcrypto_EVP_aead_aes_256_gcm_tls13()
-		default:
+		} else {
 			aead = C._goboringcrypto_EVP_aead_aes_256_gcm()
 		}
 	default:
diff --git a/src/crypto/internal/boring/build-goboring.sh b/src/crypto/internal/boring/build-goboring.sh
index c43fad2..4938b5e 100755
--- a/src/crypto/internal/boring/build-goboring.sh
+++ b/src/crypto/internal/boring/build-goboring.sh
@@ -122,7 +122,7 @@
 awk -f boringh.awk goboringcrypto.h # writes goboringcrypto[01].h
 
 ls -l ../boringssl/include
-clang++ -fPIC -I../boringssl/include -O2 -o a.out  goboringcrypto.cc
+clang++ -std=c++11 -fPIC -I../boringssl/include -O2 -o a.out  goboringcrypto.cc
 ./a.out || exit 2
 
 # clang implements u128 % u128 -> u128 by calling __umodti3,
diff --git a/src/crypto/internal/boring/build.sh b/src/crypto/internal/boring/build.sh
index e202601..ec960d7 100755
--- a/src/crypto/internal/boring/build.sh
+++ b/src/crypto/internal/boring/build.sh
@@ -22,12 +22,6 @@
 buildargs=""
 case "$GOARCH" in
 amd64)
-	if ! docker run --rm -t amd64/ubuntu:focal uname -m >/dev/null 2>&1; then
-		echo "# Docker cannot run amd64 binaries."
-		exit 1
-	fi
-	platform="--platform linux/amd64"
-	buildargs="--build-arg ubuntu=amd64/ubuntu"
 	;;
 arm64)
 	if ! docker run --rm -t arm64v8/ubuntu:focal uname -m >/dev/null 2>&1; then
diff --git a/src/crypto/internal/boring/goboringcrypto.h b/src/crypto/internal/boring/goboringcrypto.h
index 3663a1b..2b11049 100644
--- a/src/crypto/internal/boring/goboringcrypto.h
+++ b/src/crypto/internal/boring/goboringcrypto.h
@@ -125,9 +125,7 @@
 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
diff --git a/src/crypto/internal/boring/notboring.go b/src/crypto/internal/boring/notboring.go
index e478791..1c5e4c7 100644
--- a/src/crypto/internal/boring/notboring.go
+++ b/src/crypto/internal/boring/notboring.go
@@ -50,7 +50,6 @@
 
 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 }
diff --git a/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso b/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
index b99e7f5..6cea789 100644
--- a/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
+++ b/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
Binary files differ
diff --git a/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso b/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso
index 143a47a..9659aa1 100644
--- a/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso
+++ b/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso
Binary files differ
diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go
index aad96b1..1827f76 100644
--- a/src/crypto/tls/boring.go
+++ b/src/crypto/tls/boring.go
@@ -6,10 +6,9 @@
 
 package tls
 
-import "crypto/internal/boring/fipstls"
-
-// The FIPS-only policies enforced here currently match BoringSSL's
-// ssl_policy_fips_202205.
+import (
+	"crypto/internal/boring/fipstls"
+)
 
 // needFIPS returns fipstls.Required(); it avoids a new import in common.go.
 func needFIPS() bool {
@@ -18,19 +17,19 @@
 
 // fipsMinVersion replaces c.minVersion in FIPS-only mode.
 func fipsMinVersion(c *Config) uint16 {
-	// FIPS requires TLS 1.2 or TLS 1.3.
+	// FIPS requires TLS 1.2.
 	return VersionTLS12
 }
 
 // fipsMaxVersion replaces c.maxVersion in FIPS-only mode.
 func fipsMaxVersion(c *Config) uint16 {
-	// FIPS requires TLS 1.2 or TLS 1.3.
-	return VersionTLS13
+	// FIPS requires TLS 1.2.
+	return VersionTLS12
 }
 
 // default defaultFIPSCurvePreferences is the FIPS-allowed curves,
 // in preference order (most preferable first).
-var defaultFIPSCurvePreferences = []CurveID{CurveP256, CurveP384}
+var defaultFIPSCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
 
 // fipsCurvePreferences replaces c.curvePreferences in FIPS-only mode.
 func fipsCurvePreferences(c *Config) []CurveID {
@@ -55,6 +54,8 @@
 	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_RSA_WITH_AES_128_GCM_SHA256,
+	TLS_RSA_WITH_AES_256_GCM_SHA384,
 }
 
 // fipsCipherSuites replaces c.cipherSuites in FIPS-only mode.
@@ -74,14 +75,8 @@
 	return list
 }
 
-// defaultCipherSuitesTLS13FIPS are the FIPS-allowed cipher suites for TLS 1.3.
-var defaultCipherSuitesTLS13FIPS = []uint16{
-	TLS_AES_128_GCM_SHA256,
-	TLS_AES_256_GCM_SHA384,
-}
-
 // fipsSupportedSignatureAlgorithms currently are a subset of
-// defaultSupportedSignatureAlgorithms without Ed25519, SHA-1, and P-521.
+// defaultSupportedSignatureAlgorithms without Ed25519 and SHA-1.
 var fipsSupportedSignatureAlgorithms = []SignatureScheme{
 	PSSWithSHA256,
 	PSSWithSHA384,
@@ -91,6 +86,7 @@
 	PKCS1WithSHA384,
 	ECDSAWithP384AndSHA384,
 	PKCS1WithSHA512,
+	ECDSAWithP521AndSHA512,
 }
 
 // supportedSignatureAlgorithms returns the supported signature algorithms.
diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go
index 96dfc93..ba68f35 100644
--- a/src/crypto/tls/boring_test.go
+++ b/src/crypto/tls/boring_test.go
@@ -25,31 +25,6 @@
 	"time"
 )
 
-func allCipherSuitesIncludingTLS13() []uint16 {
-	s := allCipherSuites()
-	for _, suite := range cipherSuitesTLS13 {
-		s = append(s, suite.id)
-	}
-	return s
-}
-
-func isTLS13CipherSuite(id uint16) bool {
-	for _, suite := range cipherSuitesTLS13 {
-		if id == suite.id {
-			return true
-		}
-	}
-	return false
-}
-
-func generateKeyShare(group CurveID) keyShare {
-	key, err := generateECDHEKey(rand.Reader, group)
-	if err != nil {
-		panic(err)
-	}
-	return keyShare{group: group, data: key.PublicKey().Bytes()}
-}
-
 func TestBoringServerProtocolVersion(t *testing.T) {
 	test := func(name string, v uint16, msg string) {
 		t.Run(name, func(t *testing.T) {
@@ -58,11 +33,8 @@
 			clientHello := &clientHelloMsg{
 				vers:               v,
 				random:             make([]byte, 32),
-				cipherSuites:       allCipherSuitesIncludingTLS13(),
+				cipherSuites:       allCipherSuites(),
 				compressionMethods: []uint8{compressionNone},
-				supportedCurves:    defaultCurvePreferences,
-				keyShares:          []keyShare{generateKeyShare(CurveP256)},
-				supportedPoints:    []uint8{pointFormatUncompressed},
 				supportedVersions:  []uint16{v},
 			}
 			testClientHelloFailure(t, serverConfig, clientHello, msg)
@@ -76,25 +48,25 @@
 
 	fipstls.Force()
 	defer fipstls.Abandon()
-	test("VersionSSL30/fipstls", VersionSSL30, "client offered only unsupported versions")
-	test("VersionTLS10/fipstls", VersionTLS10, "client offered only unsupported versions")
-	test("VersionTLS11/fipstls", VersionTLS11, "client offered only unsupported versions")
-	test("VersionTLS12/fipstls", VersionTLS12, "")
-	test("VersionTLS13/fipstls", VersionTLS13, "")
+	test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
+	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")
 }
 
 func isBoringVersion(v uint16) bool {
-	return v == VersionTLS12 || v == VersionTLS13
+	return v == VersionTLS12
 }
 
 func isBoringCipherSuite(id uint16) bool {
 	switch id {
-	case TLS_AES_128_GCM_SHA256,
-		TLS_AES_256_GCM_SHA384,
-		TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+	case 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_256_GCM_SHA384,
+		TLS_RSA_WITH_AES_128_GCM_SHA256,
+		TLS_RSA_WITH_AES_256_GCM_SHA384:
 		return true
 	}
 	return false
@@ -102,7 +74,7 @@
 
 func isBoringCurve(id CurveID) bool {
 	switch id {
-	case CurveP256, CurveP384:
+	case CurveP256, CurveP384, CurveP521:
 		return true
 	}
 	return false
@@ -114,7 +86,7 @@
 			return suite.flags&suiteECSign == suiteECSign
 		}
 	}
-	return false // TLS 1.3 cipher suites are not tied to the signature algorithm.
+	panic(fmt.Sprintf("unknown cipher suite %#x", id))
 }
 
 func isBoringSignatureScheme(alg SignatureScheme) bool {
@@ -126,6 +98,7 @@
 		PKCS1WithSHA384,
 		ECDSAWithP384AndSHA384,
 		PKCS1WithSHA512,
+		ECDSAWithP521AndSHA512,
 		PSSWithSHA256,
 		PSSWithSHA384,
 		PSSWithSHA512:
@@ -136,9 +109,10 @@
 
 func TestBoringServerCipherSuites(t *testing.T) {
 	serverConfig := testConfig.Clone()
+	serverConfig.CipherSuites = allCipherSuites()
 	serverConfig.Certificates = make([]Certificate, 1)
 
-	for _, id := range allCipherSuitesIncludingTLS13() {
+	for _, id := range allCipherSuites() {
 		if isECDSA(id) {
 			serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
 			serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
@@ -147,19 +121,14 @@
 			serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
 		}
 		serverConfig.BuildNameToCertificate()
-		t.Run(fmt.Sprintf("suite=%s", CipherSuiteName(id)), func(t *testing.T) {
+		t.Run(fmt.Sprintf("suite=%#x", id), func(t *testing.T) {
 			clientHello := &clientHelloMsg{
 				vers:               VersionTLS12,
 				random:             make([]byte, 32),
 				cipherSuites:       []uint16{id},
 				compressionMethods: []uint8{compressionNone},
 				supportedCurves:    defaultCurvePreferences,
-				keyShares:          []keyShare{generateKeyShare(CurveP256)},
 				supportedPoints:    []uint8{pointFormatUncompressed},
-				supportedVersions:  []uint16{VersionTLS12},
-			}
-			if isTLS13CipherSuite(id) {
-				clientHello.supportedVersions = []uint16{VersionTLS13}
 			}
 
 			testClientHello(t, serverConfig, clientHello)
@@ -191,9 +160,7 @@
 				cipherSuites:       []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
 				compressionMethods: []uint8{compressionNone},
 				supportedCurves:    []CurveID{curveid},
-				keyShares:          []keyShare{generateKeyShare(curveid)},
 				supportedPoints:    []uint8{pointFormatUncompressed},
-				supportedVersions:  []uint16{VersionTLS12},
 			}
 
 			testClientHello(t, serverConfig, clientHello)
@@ -312,7 +279,7 @@
 	}
 
 	if !isBoringVersion(hello.vers) {
-		t.Errorf("client vers=%#x", hello.vers)
+		t.Errorf("client vers=%#x, want %#x (TLS 1.2)", hello.vers, VersionTLS12)
 	}
 	for _, v := range hello.supportedVersions {
 		if !isBoringVersion(v) {
diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go
index 197930d..04e6dfe 100644
--- a/src/crypto/tls/cipher_suites.go
+++ b/src/crypto/tls/cipher_suites.go
@@ -540,13 +540,7 @@
 	if err != nil {
 		panic(err)
 	}
-	var aead cipher.AEAD
-	if boring.Enabled {
-		aead, err = boring.NewGCMTLS13(aes)
-	} else {
-		boring.Unreachable()
-		aead, err = cipher.NewGCM(aes)
-	}
+	aead, err := cipher.NewGCM(aes)
 	if err != nil {
 		panic(err)
 	}
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index aee451a..0bb6a0a 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -129,9 +129,7 @@
 
 	var key *ecdh.PrivateKey
 	if hello.supportedVersions[0] == VersionTLS13 {
-		if needFIPS() {
-			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13FIPS...)
-		} else if hasAESGCMHardwareSupport {
+		if hasAESGCMHardwareSupport {
 			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
 		} else {
 			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index 87fe11d..4a86610 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -41,6 +41,10 @@
 func (hs *clientHandshakeStateTLS13) handshake() error {
 	c := hs.c
 
+	if needFIPS() {
+		return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+	}
+
 	// The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
 	// sections 4.1.2 and 4.1.3.
 	if c.handshakes > 0 {
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index 778972d..04abdcc 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -27,7 +27,6 @@
 )
 
 func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
-	t.Helper()
 	testClientHelloFailure(t, serverConfig, m, "")
 }
 
@@ -53,32 +52,23 @@
 	ctx := context.Background()
 	conn := Server(s, serverConfig)
 	ch, err := conn.readClientHello(ctx)
-	if err == nil && conn.vers == VersionTLS13 {
-		hs := serverHandshakeStateTLS13{
-			c:           conn,
-			ctx:         ctx,
-			clientHello: ch,
-		}
+	hs := serverHandshakeState{
+		c:           conn,
+		ctx:         ctx,
+		clientHello: ch,
+	}
+	if err == nil {
 		err = hs.processClientHello()
-	} else if err == nil {
-		hs := serverHandshakeState{
-			c:           conn,
-			ctx:         ctx,
-			clientHello: ch,
-		}
-		err = hs.processClientHello()
-		if err == nil {
-			err = hs.pickCipherSuite()
-		}
+	}
+	if err == nil {
+		err = hs.pickCipherSuite()
 	}
 	s.Close()
 	if len(expectedSubStr) == 0 {
 		if err != nil && err != io.EOF {
-			t.Helper()
 			t.Errorf("Got error: %s; expected to succeed", err)
 		}
 	} else if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
-		t.Helper()
 		t.Errorf("Got error: %v; expected to match substring '%s'", err, expectedSubStr)
 	}
 }
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
index bf592f2..b7b568c 100644
--- a/src/crypto/tls/handshake_server_tls13.go
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -44,6 +44,10 @@
 func (hs *serverHandshakeStateTLS13) handshake() error {
 	c := hs.c
 
+	if needFIPS() {
+		return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+	}
+
 	// For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
 	if err := hs.processClientHello(); err != nil {
 		return err
@@ -153,9 +157,6 @@
 	if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
 		preferenceList = defaultCipherSuitesTLS13NoAES
 	}
-	if needFIPS() {
-		preferenceList = defaultCipherSuitesTLS13FIPS
-	}
 	for _, suiteID := range preferenceList {
 		hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
 		if hs.suite != nil {
diff --git a/src/crypto/tls/notboring.go b/src/crypto/tls/notboring.go
index edccb44..7d85b39 100644
--- a/src/crypto/tls/notboring.go
+++ b/src/crypto/tls/notboring.go
@@ -18,5 +18,3 @@
 func fipsCipherSuites(c *Config) []uint16      { panic("fipsCipherSuites") }
 
 var fipsSupportedSignatureAlgorithms []SignatureScheme
-
-var defaultCipherSuitesTLS13FIPS []uint16
diff --git a/src/crypto/x509/boring.go b/src/crypto/x509/boring.go
index e6237e9..095b58c 100644
--- a/src/crypto/x509/boring.go
+++ b/src/crypto/x509/boring.go
@@ -22,7 +22,7 @@
 	}
 
 	// The key must be RSA 2048, RSA 3072, RSA 4096,
-	// or ECDSA P-256 or P-384.
+	// or ECDSA P-256, P-384, P-521.
 	switch k := c.PublicKey.(type) {
 	default:
 		return false
@@ -31,7 +31,7 @@
 			return false
 		}
 	case *ecdsa.PublicKey:
-		if k.Curve != elliptic.P256() && k.Curve != elliptic.P384() {
+		if k.Curve != elliptic.P256() && k.Curve != elliptic.P384() && k.Curve != elliptic.P521() {
 			return false
 		}
 	}