1
0
mirror of https://github.com/golang/go synced 2024-11-26 17:46:57 -07:00

Revert "crypto/internal/boring: upgrade module to fips-20220613" +1

This reverts commit 7383b2a4db
("crypto/internal/boring: upgrade module to fips-20220613") and commit
4106de901a ("crypto/tls: align FIPS-only
mode with BoringSSL policy").

Fixes #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>
This commit is contained in:
Filippo Valsorda 2024-01-26 23:22:45 +01:00 committed by Gopher Robot
parent b6d1eb750f
commit 09b5de48e6
19 changed files with 73 additions and 156 deletions

View File

@ -13,21 +13,15 @@ WORKDIR /boring
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 @@ RUN \
# 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 @@ RUN \
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 && \

View File

@ -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-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

View File

@ -27,14 +27,13 @@ syso/goboringcrypto_linux_arm64.syso is built with:
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.

View File

@ -228,41 +228,26 @@ func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
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:

View File

@ -122,7 +122,7 @@ awk -f boringx.awk goboringcrypto.h # writes goboringcrypto.x
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,

View File

@ -22,12 +22,6 @@ platform=""
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

View File

@ -125,9 +125,7 @@ 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

View File

@ -50,7 +50,6 @@ 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 }

View File

@ -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 @@ func needFIPS() bool {
// 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 @@ var defaultCipherSuitesFIPS = []uint16{
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 @@ func fipsCipherSuites(c *Config) []uint16 {
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 @@ var fipsSupportedSignatureAlgorithms = []SignatureScheme{
PKCS1WithSHA384,
ECDSAWithP384AndSHA384,
PKCS1WithSHA512,
ECDSAWithP521AndSHA512,
}
// supportedSignatureAlgorithms returns the supported signature algorithms.

View File

@ -25,31 +25,6 @@ import (
"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 @@ func TestBoringServerProtocolVersion(t *testing.T) {
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 @@ func TestBoringServerProtocolVersion(t *testing.T) {
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 isBoringCipherSuite(id uint16) bool {
func isBoringCurve(id CurveID) bool {
switch id {
case CurveP256, CurveP384:
case CurveP256, CurveP384, CurveP521:
return true
}
return false
@ -114,7 +86,7 @@ func isECDSA(id uint16) bool {
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 @@ func isBoringSignatureScheme(alg SignatureScheme) bool {
PKCS1WithSHA384,
ECDSAWithP384AndSHA384,
PKCS1WithSHA512,
ECDSAWithP521AndSHA512,
PSSWithSHA256,
PSSWithSHA384,
PSSWithSHA512:
@ -136,9 +109,10 @@ func isBoringSignatureScheme(alg SignatureScheme) bool {
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 @@ func TestBoringServerCipherSuites(t *testing.T) {
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 @@ func TestBoringServerCurves(t *testing.T) {
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 @@ func TestBoringClientHello(t *testing.T) {
}
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) {

View File

@ -556,13 +556,7 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead {
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)
}

View File

@ -139,9 +139,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) {
if len(hello.supportedVersions) == 1 {
hello.cipherSuites = nil
}
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...)

View File

@ -41,6 +41,10 @@ type clientHandshakeStateTLS13 struct {
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 {

View File

@ -27,7 +27,6 @@ import (
)
func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
t.Helper()
testClientHelloFailure(t, serverConfig, m, "")
}
@ -53,32 +52,23 @@ func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessa
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)
}
}

View File

@ -45,6 +45,10 @@ type serverHandshakeStateTLS13 struct {
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
@ -159,9 +163,6 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
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 {

View File

@ -18,5 +18,3 @@ func fipsCurvePreferences(c *Config) []CurveID { panic("fipsCurvePreferences") }
func fipsCipherSuites(c *Config) []uint16 { panic("fipsCipherSuites") }
var fipsSupportedSignatureAlgorithms []SignatureScheme
var defaultCipherSuitesTLS13FIPS []uint16

View File

@ -22,7 +22,7 @@ func boringAllowCert(c *Certificate) bool {
}
// 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 @@ func boringAllowCert(c *Certificate) bool {
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
}
}