diff --git a/config/versions.json b/config/versions.json index 6d8e0b2b8c..ce1d7487b3 100644 --- a/config/versions.json +++ b/config/versions.json @@ -1,5 +1,5 @@ { "github.com/golang-fips/go": "main", "github.com/golang-fips/openssl": "61a53ab338d5f1657c6fe5d856d24528bfdd731d", - "github.com/golang/go": "go1.23.8" + "github.com/golang/go": "go1.24.2" } diff --git a/patches/000-initial-setup.patch b/patches/000-initial-setup.patch deleted file mode 100644 index 278b2493a7..0000000000 --- a/patches/000-initial-setup.patch +++ /dev/null @@ -1,1448 +0,0 @@ -diff --git a/src/cmd/go/testdata/script/gopath_std_vendor.txt b/src/cmd/go/testdata/script/gopath_std_vendor.txt -index 4aaf46b5d0..c231e299d9 100644 ---- a/src/cmd/go/testdata/script/gopath_std_vendor.txt -+++ b/src/cmd/go/testdata/script/gopath_std_vendor.txt -@@ -21,11 +21,11 @@ go build . - - go list -deps -f '{{.ImportPath}} {{.Dir}}' . - stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack --! stdout $GOROOT[/\\]src[/\\]vendor -+! stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack - - go list -test -deps -f '{{.ImportPath}} {{.Dir}}' . - stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack --! stdout $GOROOT[/\\]src[/\\]vendor -+! stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack - - -- issue16333/issue16333.go -- - package vendoring17 -diff --git a/src/crypto/ecdh/ecdh_test.go b/src/crypto/ecdh/ecdh_test.go -index 10da95afbb..af6bcd86f4 100644 ---- a/src/crypto/ecdh/ecdh_test.go -+++ b/src/crypto/ecdh/ecdh_test.go -@@ -9,6 +9,7 @@ import ( - "crypto" - "crypto/cipher" - "crypto/ecdh" -+ "crypto/internal/boring" - "crypto/rand" - "crypto/sha256" - "encoding/hex" -@@ -442,6 +443,9 @@ func main() { - // implementations into the binary. This also guarantees that govulncheck can - // avoid warning about a curve-specific vulnerability if that curve is not used. - func TestLinker(t *testing.T) { -+ if boring.Enabled { -+ t.Skip("test doesn't make sense when building with external crypto backend") -+ } - if testing.Short() { - t.Skip("test requires running 'go build'") - } -diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go -index 08a0903eb1..61a4662036 100644 ---- a/src/crypto/ecdsa/ecdsa_test.go -+++ b/src/crypto/ecdsa/ecdsa_test.go -@@ -9,6 +9,8 @@ import ( - "bytes" - "compress/bzip2" - "crypto/elliptic" -+ "crypto/internal/backend/boringtest" -+ "crypto/internal/boring" - "crypto/internal/bigmod" - "crypto/rand" - "crypto/sha1" -@@ -36,8 +38,17 @@ func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) { - } - if testing.Short() { - tests = tests[:1] -+ } else if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ p224 := struct { -+ name string -+ curve elliptic.Curve -+ }{"P224", elliptic.P224()} -+ tests = append(tests, p224) - } - for _, test := range tests { -+ if boring.Enabled && !boringtest.Supports(t, "Curve"+test.name) { -+ t.Skip("unsupported test in FIPS mode") -+ } - curve := test.curve - t.Run(test.name, func(t *testing.T) { - t.Parallel() -@@ -235,7 +246,11 @@ func TestVectors(t *testing.T) { - - switch curve { - case "P-224": -- pub.Curve = elliptic.P224() -+ if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ pub.Curve = elliptic.P224() -+ } else { -+ pub.Curve = nil -+ } - case "P-256": - pub.Curve = elliptic.P256() - case "P-384": -diff --git a/src/crypto/ecdsa/equal_test.go b/src/crypto/ecdsa/equal_test.go -index 53ac8504c2..4371e31b1a 100644 ---- a/src/crypto/ecdsa/equal_test.go -+++ b/src/crypto/ecdsa/equal_test.go -@@ -10,6 +10,8 @@ import ( - "crypto/elliptic" - "crypto/rand" - "crypto/x509" -+ "crypto/internal/boring" -+ "crypto/internal/backend/boringtest" - "testing" - ) - -@@ -65,11 +67,13 @@ func testEqual(t *testing.T, c elliptic.Curve) { - } - - func TestEqual(t *testing.T) { -- t.Run("P224", func(t *testing.T) { testEqual(t, elliptic.P224()) }) -+ t.Run("P256", func(t *testing.T) { testEqual(t, elliptic.P256()) }) - if testing.Short() { - return - } -- t.Run("P256", func(t *testing.T) { testEqual(t, elliptic.P256()) }) -+ if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ t.Run("P224", func(t *testing.T) { testEqual(t, elliptic.P224()) }) -+ } - t.Run("P384", func(t *testing.T) { testEqual(t, elliptic.P384()) }) - t.Run("P521", func(t *testing.T) { testEqual(t, elliptic.P521()) }) - } -diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go -index 47c8698e2a..8b5c2cc9af 100644 ---- a/src/crypto/ed25519/ed25519_test.go -+++ b/src/crypto/ed25519/ed25519_test.go -@@ -321,6 +321,7 @@ func TestMalleability(t *testing.T) { - } - - func TestAllocations(t *testing.T) { -+ t.Skip("Allocations test broken with openssl linkage") - if boring.Enabled { - t.Skip("skipping allocations test with BoringCrypto") - } -diff --git a/src/crypto/ed25519/ed25519vectors_test.go b/src/crypto/ed25519/ed25519vectors_test.go -index f933f2800a..223ce04340 100644 ---- a/src/crypto/ed25519/ed25519vectors_test.go -+++ b/src/crypto/ed25519/ed25519vectors_test.go -@@ -72,6 +72,7 @@ func TestEd25519Vectors(t *testing.T) { - } - - func downloadEd25519Vectors(t *testing.T) []byte { -+ t.Skip("skipping test that downloads external data") - testenv.MustHaveExternalNetwork(t) - - // Create a temp dir and modcache subdir. -diff --git a/src/crypto/internal/backend/boringtest/config.go b/src/crypto/internal/backend/boringtest/config.go -new file mode 100644 -index 0000000000..6c8c00d11e ---- /dev/null -+++ b/src/crypto/internal/backend/boringtest/config.go -@@ -0,0 +1,46 @@ -+/* Test configuration package for OpenSSL FIPS -+ -+The FIPS mode behavior of OpenSSL varies between versions and distributions -+depending which version of the FIPS standard the library targets. Because -+the Go crypto tests can not reliably account for these behavioral differences, -+building golang-fips on a new distribution often results in test failures due to -+variations in things like supported crypto algorithms and key sizes. -+ -+The goal of this package is to implement a compile-time defined configuration -+for the behavior of OpenSSL, which is more easily configurable to run in different -+environments. The compile-time schema was chosen as the preferred method, because -+we don't want elements of the run-time environment to impact the result of the tests -+(for example, changes to the environment or config files). -+*/ -+ -+package boringtest -+ -+import ( -+ "testing" -+) -+ -+var testConfig map[string]bool -+ -+func init() { -+ testConfig = map[string]bool{ -+ "PKCSv1.5": false, -+ "SHA1": false, -+ // really this is anything < 2048 -+ "RSA1024": false, -+ "RSA4096LeafCert": true, -+ "RSA1024LeafCert": false, -+ "TLS13": true, -+ "CurveP224": true, -+ "CurveP256": true, -+ "CurveP384": true, -+ "CurveP521": true, -+ } -+} -+ -+func Supports(t *testing.T, key string) bool { -+ result, ok := testConfig[key] -+ if !ok { -+ return true -+ } -+ return result -+} -diff --git a/src/crypto/internal/backend/dummy.s b/src/crypto/internal/backend/dummy.s -new file mode 100644 -index 0000000000..e69de29bb2 ---- /dev/null -+++ b/src/crypto/internal/backend/dummy.s -@@ -0,0 +1,1 @@ -+//go:build linux && cgo && !android && !gocrypt && !cmd_go_bootstrap && !msan && !no_openssl && !purego -diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go -new file mode 100644 -index 0000000000..15c1ee8cbe ---- /dev/null -+++ b/src/crypto/internal/backend/nobackend.go -@@ -0,0 +1,163 @@ -+// Copyright 2017 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 !linux || !cgo || android || cmd_go_bootstrap || msan || no_openssl || purego -+// +build !linux !cgo android cmd_go_bootstrap msan no_openssl purego -+ -+package backend -+ -+import ( -+ "crypto" -+ "crypto/cipher" -+ "crypto/internal/boring/sig" -+ "math/big" -+ bbig "crypto/internal/boring" -+ "hash" -+ "io" -+) -+ -+var enabled = false -+ -+// Unreachable marks code that should be unreachable -+// when BoringCrypto is in use. It is a no-op without BoringCrypto. -+func Unreachable() { -+ // Code that's unreachable when using BoringCrypto -+ // is exactly the code we want to detect for reporting -+ // standard Go crypto. -+ sig.StandardCrypto() -+} -+ -+// UnreachableExceptTests marks code that should be unreachable -+// when BoringCrypto is in use. It is a no-op without BoringCrypto. -+func UnreachableExceptTests() {} -+ -+func ExecutingTest() bool { return false } -+ -+// This is a noop withotu BoringCrytpo. -+func PanicIfStrictFIPS(v interface{}) {} -+ -+type randReader int -+ -+func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not available") } -+ -+const RandReader = randReader(0) -+ -+func Enabled() bool { return false } -+func NewSHA1() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA224() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA256() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA384() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA512() hash.Hash { panic("boringcrypto: not available") } -+func SHA1(_ []byte) [20]byte { panic("boringcrypto: not available") } -+func SHA224(_ []byte) [28]byte { panic("boringcrypto: not available") } -+func SHA256(_ []byte) [32]byte { panic("boringcrypto: not available") } -+func SHA384(_ []byte) [48]byte { panic("boringcrypto: not available") } -+func SHA512(_ []byte) [64]byte { panic("boringcrypto: not available") } -+ -+func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: not available") } -+ -+func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") } -+ -+type PublicKeyECDSA struct{ _ int } -+type PrivateKeyECDSA struct{ _ int } -+ -+func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { -+ panic("boringcrypto: not available") -+} -+func GenerateKeyECDSA(curve string) (X, Y, D bbig.BigInt, err error) { -+ panic("boringcrypto: not available") -+} -+func NewPrivateKeyECDSA(curve string, X, Y, D bbig.BigInt) (*PrivateKeyECDSA, error) { -+ panic("boringcrypto: not available") -+} -+func NewPublicKeyECDSA(curve string, X, Y bbig.BigInt) (*PublicKeyECDSA, error) { -+ panic("boringcrypto: not available") -+} -+func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s bbig.BigInt, err error) { -+ panic("boringcrypto: not available") -+} -+func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func VerifyECDSA(pub *PublicKeyECDSA, hash, sig []byte) bool { -+ panic("boringcrypto: not available") -+} -+ -+type PublicKeyECDH struct{ _ int } -+type PrivateKeyECDH struct{ _ int } -+func (pc *PublicKeyECDH) Bytes() []byte { panic("boringcrypto: not available") } -+func (pc *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { panic("boringcrypto: not available") } -+ -+func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { -+ panic("boringcrypto: not available") -+} -+func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { -+ panic("boringcrypto: not available") -+} -+func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { -+ panic("boringcrypto: not available") -+} -+func SharedKeyECDH(priv *PrivateKeyECDH, peerPublicKey []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+ -+type PublicKeyRSA struct{ _ int } -+type PrivateKeyRSA struct{ _ int } -+ -+func DecryptRSAOAEP(h, h2 hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func EncryptRSAOAEP(h, h2 hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv bbig.BigInt, err error) { -+ panic("boringcrypto: not available") -+} -+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv bbig.BigInt) (*PrivateKeyRSA, error) { -+ panic("boringcrypto: not available") -+} -+func NewPublicKeyRSA(N, E bbig.BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") } -+func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { -+ panic("boringcrypto: not available") -+} -+func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { -+ panic("boringcrypto: not available") -+} -+ -+func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { -+ panic("boringcrypto: not available") -+} -+func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) { -+ panic("boringcrypto: not available") -+} -+func SupportsHKDF() bool { -+ panic("boringcrypto: not available") -+} -+func HashVerifyECDSA(pub *PublicKeyECDSA, msg []byte, r, s *big.Int, h crypto.Hash) bool { -+ panic("boringcrypto: not available") -+} -+func HashSignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (*big.Int, *big.Int, error) { -+ panic("boringcrypto: not available") -+} -diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -new file mode 100644 -index 0000000000..2087c555a4 ---- /dev/null -+++ b/src/crypto/internal/backend/openssl.go -@@ -0,0 +1,122 @@ -+// Copyright 2017 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 linux && cgo && !android && !gocrypt && !cmd_go_bootstrap && !msan && !no_openssl && !purego -+// +build linux,cgo,!android,!gocrypt,!cmd_go_bootstrap,!msan,!no_openssl,!purego -+ -+// Package openssl provides access to OpenSSLCrypto implementation functions. -+// Check the variable Enabled to find out whether OpenSSLCrypto is available. -+// If OpenSSLCrypto is not available, the functions in this package all panic. -+package backend -+ -+import ( -+ "os" -+ "github.com/golang-fips/openssl/v2" -+) -+ -+// Enabled controls whether FIPS crypto is enabled. -+var enabled bool -+ -+func init() { -+ enabled = openssl.FIPS() -+} -+ -+func Enabled() bool { -+ return enabled -+} -+ -+// Unreachable marks code that should be unreachable -+// when OpenSSLCrypto is in use. It panics only when -+// the system is in FIPS mode. -+func Unreachable() { -+ if Enabled() { -+ panic("opensslcrypto: invalid code execution") -+ } -+} -+ -+// ExecutingTest returns a boolean indicating if we're -+// executing under a test binary or not. -+func ExecutingTest() bool { -+ name := os.Args[0] -+ return hasSuffix(name, "_test") || hasSuffix(name, ".test") -+} -+ -+// Provided by runtime.crypto_backend_runtime_arg0 to avoid os import. -+func runtime_arg0() string -+ -+func hasSuffix(s, t string) bool { -+ return len(s) > len(t) && s[len(s)-len(t):] == t -+} -+ -+// UnreachableExceptTests marks code that should be unreachable -+// when OpenSSLCrypto is in use. It panics. -+func UnreachableExceptTests() { -+ name := runtime_arg0() -+ // If OpenSSLCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well. -+ if Enabled() && !hasSuffix(name, "_test") && !hasSuffix(name, ".test") { -+ println("opensslcrypto: unexpected code execution in", name) -+ panic("opensslcrypto: invalid code execution") -+ } -+} -+ -+ -+ -+const RandReader = openssl.RandReader -+ -+var NewGCMTLS = openssl.NewGCMTLS -+var NewSHA1 = openssl.NewSHA1 -+var NewSHA224 = openssl.NewSHA224 -+var NewSHA256 = openssl.NewSHA256 -+var NewSHA384 = openssl.NewSHA384 -+var NewSHA512 = openssl.NewSHA512 -+ -+var SHA1 = openssl.SHA1 -+var SHA224 = openssl.SHA224 -+var SHA256 = openssl.SHA256 -+var SHA384 = openssl.SHA384 -+var SHA512 = openssl.SHA512 -+ -+var NewHMAC = openssl.NewHMAC -+ -+var NewAESCipher = openssl.NewAESCipher -+ -+type PublicKeyECDSA = openssl.PublicKeyECDSA -+type PrivateKeyECDSA = openssl.PrivateKeyECDSA -+ -+var GenerateKeyECDSA = openssl.GenerateKeyECDSA -+var NewPrivateKeyECDSA = openssl.NewPrivateKeyECDSA -+var NewPublicKeyECDSA = openssl.NewPublicKeyECDSA -+var SignMarshalECDSA = openssl.SignMarshalECDSA -+var VerifyECDSA = openssl.VerifyECDSA -+var HashVerifyECDSA = openssl.HashVerifyECDSA -+var HashSignECDSA = openssl.HashSignECDSA -+ -+type PublicKeyECDH = openssl.PublicKeyECDH -+type PrivateKeyECDH = openssl.PrivateKeyECDH -+ -+var GenerateKeyECDH = openssl.GenerateKeyECDH -+var NewPrivateKeyECDH = openssl.NewPrivateKeyECDH -+var NewPublicKeyECDH = openssl.NewPublicKeyECDH -+var ECDH = openssl.ECDH -+ -+type PublicKeyRSA = openssl.PublicKeyRSA -+type PrivateKeyRSA = openssl.PrivateKeyRSA -+ -+var DecryptRSAOAEP = openssl.DecryptRSAOAEP -+var DecryptRSAPKCS1 = openssl.DecryptRSAPKCS1 -+var DecryptRSANoPadding = openssl.DecryptRSANoPadding -+var EncryptRSAOAEP = openssl.EncryptRSAOAEP -+var EncryptRSAPKCS1 = openssl.EncryptRSAPKCS1 -+var EncryptRSANoPadding = openssl.EncryptRSANoPadding -+var GenerateKeyRSA = openssl.GenerateKeyRSA -+var NewPrivateKeyRSA = openssl.NewPrivateKeyRSA -+var NewPublicKeyRSA = openssl.NewPublicKeyRSA -+var SignRSAPKCS1v15 = openssl.SignRSAPKCS1v15 -+var SignRSAPSS = openssl.SignRSAPSS -+var VerifyRSAPKCS1v15 = openssl.VerifyRSAPKCS1v15 -+var VerifyRSAPSS = openssl.VerifyRSAPSS -+ -+var ExtractHKDF = openssl.ExtractHKDF -+var ExpandHKDF = openssl.ExpandHKDF -+var SupportsHKDF = openssl.SupportsHKDF -diff --git a/src/crypto/internal/backend/bbig/big.go b/src/crypto/internal/backend/bbig/big.go -new file mode 100644 -index 0000000000..7fac1ec7e1 ---- /dev/null -+++ b/src/crypto/internal/backend/bbig/big.go -@@ -0,0 +1,15 @@ -+// Copyright 2022 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. -+ -+// This is a mirror of -+// https://github.com/golang/go/blob/36b87f273cc43e21685179dc1664ebb5493d26ae/src/crypto/internal/boring/bbig/big.go. -+ -+package bbig -+ -+import ( -+ "github.com/golang-fips/openssl/v2/bbig" -+) -+ -+var Enc = bbig.Enc -+var Dec = bbig.Dec -diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go -index dfa1eddc88..39a4fc184a 100644 ---- a/src/crypto/rsa/pkcs1v15_test.go -+++ b/src/crypto/rsa/pkcs1v15_test.go -@@ -7,6 +7,8 @@ package rsa_test - import ( - "bytes" - "crypto" -+ "crypto/internal/boring" -+ "crypto/internal/backend/boringtest" - "crypto/rand" - . "crypto/rsa" - "crypto/sha1" -@@ -54,6 +56,10 @@ var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{ - } - - func TestDecryptPKCS1v15(t *testing.T) { -+ if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -+ } -+ - decryptionFuncs := []func([]byte) ([]byte, error){ - func(ciphertext []byte) (plaintext []byte, err error) { - return DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext) -@@ -78,6 +84,10 @@ func TestDecryptPKCS1v15(t *testing.T) { - } - - func TestEncryptPKCS1v15(t *testing.T) { -+ if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -+ } -+ - random := rand.Reader - k := (rsaPrivateKey.N.BitLen() + 7) / 8 - -@@ -139,6 +149,10 @@ var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{ - } - - func TestEncryptPKCS1v15SessionKey(t *testing.T) { -+ if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -+ } -+ - for i, test := range decryptPKCS1v15SessionKeyTests { - key := []byte("FAIL") - err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, decodeBase64(test.in), key) -@@ -153,6 +167,10 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) { - } - - func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) { -+ if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -+ } -+ - for i, test := range decryptPKCS1v15SessionKeyTests { - plaintext, err := rsaPrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4}) - if err != nil { -@@ -192,7 +210,7 @@ type signPKCS1v15Test struct { - // - // `openssl rsautl -verify -inkey pk -in signature | hexdump -C` - var signPKCS1v15Tests = []signPKCS1v15Test{ -- {"Test.\n", "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e336ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"}, -+ {"Test.\n", "0c7c85d938862248846cba06b06ac9bfe752aafed3092c224f257855006aa35b43d101e6c8e59cbc4c20b07c81552963f189dea700e042d4b70c236a031a29a9273cc138e69dc1a5834491de4822d8cb6acf218789d2586cb0f3892236b0948ffaf8691f6fa04597caa45068f9be39b8ea8b5336a8c94e2696f872120778abcfea711e5fbf75f835f0f5204ccdd020013c2ceae25e9d1378a1d10cf86ca269eef48fee8ebb5e8dfb08f0c48d22d1a7162e080ec1f6e48541288aaaa1f2370f0688cf1786a32abed41df1d3b96b665794bf7a772743fc8b62d73901cea4569494c794a01ccc7dda0d42199f5b58739c0c0e280774b56ccf51993f5ea3d4954319"}, - } - - func TestSignPKCS1v15(t *testing.T) { -@@ -201,7 +219,7 @@ func TestSignPKCS1v15(t *testing.T) { - h.Write([]byte(test.in)) - digest := h.Sum(nil) - -- s, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.SHA1, digest) -+ s, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.SHA1, digest) - if err != nil { - t.Errorf("#%d %s", i, err) - } -@@ -221,7 +239,7 @@ func TestVerifyPKCS1v15(t *testing.T) { - - sig, _ := hex.DecodeString(test.out) - -- err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA1, digest, sig) -+ err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.SHA1, digest, sig) - if err != nil { - t.Errorf("#%d %s", i, err) - } -@@ -244,21 +262,25 @@ func TestUnpaddedSignature(t *testing.T) { - // - // Where "key" contains the RSA private key given at the bottom of this - // file. -- expectedSig := decodeBase64("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==") -+ expectedSig := decodeBase64("XgDn6nJdfL/gY3eq15l9Va41/nNkDrkTlxOZYHYeFaMOW+Z4BHTCZ1LhqNBXOBK9XEyHho6okpY4rqE1zTIVX/kCGJ+jS6VRgUsHcTcpvKBYZCW84yrjE360gkntzkGxUF9FaiOGzmJKwBm1UvFgFIaYlvF+PdU0H1trBvm/RYRU42xOQRY1U+MSXgruFfINE20vPTlAG22uJ2CELrZUDykQGnrDFsEP0UqyyyiqGqxHt8E7iNYC6+xhPPC/ato9Bev08nu/U/EGH2imifSoNz/IN6h3fQClHwk1a74bPrcRsmUAAHOX2X1VKxK7IruinU8iOyoG6oFuvT+QlMnWAw==") - -- sig, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.Hash(0), msg) -+ sig, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.Hash(0), msg) - if err != nil { - t.Fatalf("SignPKCS1v15 failed: %s", err) - } - if !bytes.Equal(sig, expectedSig) { - t.Fatalf("signature is not expected value: got %x, want %x", sig, expectedSig) - } -- if err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.Hash(0), msg, sig); err != nil { -+ if err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.Hash(0), msg, sig); err != nil { - t.Fatalf("signature failed to verify: %s", err) - } - } - - func TestShortSessionKey(t *testing.T) { -+ if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -+ } -+ - // This tests that attempting to decrypt a session key where the - // ciphertext is too small doesn't run outside the array bounds. - ciphertext, err := EncryptPKCS1v15(rand.Reader, &rsaPrivateKey.PublicKey, []byte{1}) -@@ -297,6 +319,35 @@ func parsePublicKey(s string) *PublicKey { - return k - } - -+ -+var boringRsaPrivateKey = parseKey(testingKey(`-----BEGIN RSA TESTING KEY----- -+MIIEogIBAAKCAQEAp5qgUIj096pw8U+AjcJucLWenR3oe+tEthXiAuqcYgslW5UU -+lMim34U/h7NbLvbG2KJ2chUsmLtuCFaoIe/YKW5DKm3SPytK/KCBsVa+MQ7zuF/1 -+ks5p7yBqFBl6QTekMzwskt/zyDIG9f3A+38akruHNBvUgYqwbWPx4ycclQ52GSev -+/Cfx0I68TGT5SwN/eCJ/ghq3iGAf0mX1bkVaW1seKbL49aAA94KnDCRdl813+S2R -+EPDf2tZwlT0JpZm5QtAqthonZjkjHocZNxhkKF3XWUntE/+l6R4A+CWZlC2vmUc1 -+hJTEraksy2JUIjxAaq//FnDpIEVG/N2ofmNpaQIDAQABAoIBAAYH7h9fwkLcNvqz -+8+oF9k/ndSjtr9UvstYDhRG6S/zKLmK0g1xUOQ7/fjj9lvkiZ6bZd74krWlkizHR -+HnU0KnjZLyEKeR+NSQI8q1YMi0T8JwB6MX3CIDU62x5UiV3p6OZwEqGJXf4U8MOu -+ySAzo2rmxRd2reeobC9Pgp98I47oeqaSRwFVZRPfKk5RvfI7KRmL58BAB0XS56PA -+PJ+3l0fB/oIV11iaBEKildxLDtrvlepQ2KPNf7Dpk0/CPRtS/jxyxIyML8tjR3F0 -+KuHplsRjTANyzW/aHddO1fnfnXsVo+0PzSPTHCbxKSu5XmChqsKoB1jM+/tJci4y -+ST5hUXUCgYEAzfA5XEMkR/NNJMfR+FBbdfpQ1b0wqH3qtWZx/tBjKC2Y0XnDQ8ZR -+SEWONLVZMRtTlJaHIPZ9i6anQRR5harrff0OpsKiJUGDout8ehE6eiN8ABWGNlCI -+AiLCerVJZMDcSuDU7xsdHVIdSxYh88Z9g54vUQ4214BG/G0Qm1emV3UCgYEA0FjP -+wq5cEGt9xDCg+oXk0bLm4Wn4FkabJH7M+oCosHHY9W1vgvv50bpNoAbaB5r1mlan -+T6gEtkQPB2juMTnuIwRL+kvOmSKqZGlAsyrq8smTuBUv7brbybkYN3Rg51KV6u1J -+vCdGpMYWHUNRkkQ88cr6iFPodYU+CzRR4ABif6UCgYBc0jDYb/7TW0tjD5mJJZcD -+xw5WOE7NMuvuVT1+T6jRvDOL/yjOzH1oaMle4npQEvQKHgrMBa2ymyv5vmPDprU7 -+9Sp8aW+yASR281MIpelIkePbGdiDdKrI46fqrPlmqzLfoRT4rKzjwVYouNIW0VlT -+UKIdE54OZegY8IOysL/t3QKBgDZnSnECiIW9G80UCaUBO3vKZGFuA1sFutMvzSSI -+XgQc5lNH7TtdwqESLdzgjSQ5QXK4t92j+P8DDI2Zx8DQ6K76G0DTdLImDCpGFZ/z -+UABvxIPn/GjuRyAIlhs852Tf+seqiHt6Igc6tmGTx4QTD3rvzrW0e1ncnhPc6Jg+ -+YXoFAoGARD9OPrd4J2N+nkSWif9VOuPHvOXEczwBDJbsAGrOW1kTbDStF0OIVOt0 -+Ukj+mnnL8ZNyVLgTrZDRfXvlA94EbPK5/rMAYwjMlXHP8R22ts3eDMNUdw0/Zl1g -+QOhL8wXZcdwHKsONy55kZHo8pmneqi9EnqqLGguLwx5WIMzWvZ8= -+-----END RSA TESTING KEY-----`)) -+ - func TestShortPKCS1v15Signature(t *testing.T) { - pub := parsePublicKey(`-----BEGIN RSA PUBLIC KEY----- - MEgCQQCd9BVzo775lkohasxjnefF1nCMcNoibqIWEVDe/K7M2GSoO4zlSQB+gkix -diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go -index cf03e3cb7e..1226149321 100644 ---- a/src/crypto/rsa/pss_test.go -+++ b/src/crypto/rsa/pss_test.go -@@ -9,6 +9,8 @@ import ( - "bytes" - "compress/bzip2" - "crypto" -+ boring "crypto/internal/backend" -+ "crypto/internal/backend/boringtest" - "crypto/rand" - . "crypto/rsa" - "crypto/sha1" -@@ -77,6 +79,9 @@ func TestEMSAPSS(t *testing.T) { - // TestPSSGolden tests all the test vectors in pss-vect.txt from - // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip - func TestPSSGolden(t *testing.T) { -+ if boring.Enabled && !boringtest.Supports(t, "SHA1") { -+ t.Skip("skipping PSS test with BoringCrypto: SHA-1 not allowed") -+ } - inFile, err := os.Open("testdata/pss-vect.txt.bz2") - if err != nil { - t.Fatalf("Failed to open input file: %s", err) -@@ -168,6 +173,10 @@ func TestPSSGolden(t *testing.T) { - // TestPSSOpenSSL ensures that we can verify a PSS signature from OpenSSL with - // the default options. OpenSSL sets the salt length to be maximal. - func TestPSSOpenSSL(t *testing.T) { -+ if boring.Enabled { -+ t.Skip("skipping PSS test with BoringCrypto: too short key") -+ } -+ - hash := crypto.SHA256 - h := hash.New() - h.Write([]byte("testing")) -@@ -195,10 +204,15 @@ func TestPSSNilOpts(t *testing.T) { - h.Write([]byte("testing")) - hashed := h.Sum(nil) - -+ // Shouldn't this check return value? - SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, nil) - } - - func TestPSSSigning(t *testing.T) { -+ if boring.Enabled && !boringtest.Supports(t, "SHA1") { -+ t.Skip("skipping PSS test with BoringCrypto: too short key") -+ } -+ - var saltLengthCombinations = []struct { - signSaltLength, verifySaltLength int - good bool -@@ -236,11 +250,15 @@ func TestPSSSigning(t *testing.T) { - } - } - --func TestPSS513(t *testing.T) { -+// This previously tested PSSSaltLengthAuto -+// We'll change the key here to 2048 bits to -+// make sure the functionality is still able -+// to test in boring mode. -+func TestPSS2048(t *testing.T) { - // See Issue 42741, and separately, RFC 8017: "Note that the octet length of - // EM will be one less than k if modBits - 1 is divisible by 8 and equal to - // k otherwise, where k is the length in octets of the RSA modulus n." -- key, err := GenerateKey(rand.Reader, 513) -+ key, err := GenerateKey(rand.Reader, 2048) - if err != nil { - t.Fatal(err) - } -@@ -294,7 +312,7 @@ func TestInvalidPSSSaltLength(t *testing.T) { - if _, err := SignPSS(rand.Reader, key, crypto.SHA256, digest[:], &PSSOptions{ - SaltLength: -2, - Hash: crypto.SHA256, -- }); err.Error() != InvalidSaltLenErr.Error() { -+ }); err.Error() != InvalidSaltLenErr.Error() && !strings.Contains(err.Error(), "RSA_sign_pss_mgf1 failed") { - t.Fatalf("SignPSS unexpected error: got %v, want %v", err, InvalidSaltLenErr) - } - -diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go -index 63bc8dad1a..ab56ccd1ed 100644 ---- a/src/crypto/rsa/rsa.go -+++ b/src/crypto/rsa/rsa.go -@@ -509,7 +509,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l - if err != nil { - return nil, err - } -- return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label) -+ return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label) - } - boring.UnreachableExceptTests() - -@@ -680,7 +680,7 @@ func decryptOAEP(hash, mgfHash hash.Hash, random io.Reader, priv *PrivateKey, ci - if err != nil { - return nil, err - } -- out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label) -+ out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label) - if err != nil { - return nil, ErrDecryption - } -diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go -index 3278a7ff30..b994daec19 100644 ---- a/src/crypto/rsa/rsa_test.go -+++ b/src/crypto/rsa/rsa_test.go -@@ -23,6 +23,8 @@ import ( - "testing" - ) - -+import "crypto/internal/backend/boringtest" -+ - func TestKeyGeneration(t *testing.T) { - for _, size := range []int{128, 1024, 2048, 3072} { - priv, err := GenerateKey(rand.Reader, size) -@@ -32,6 +34,10 @@ func TestKeyGeneration(t *testing.T) { - if bits := priv.N.BitLen(); bits != size { - t.Errorf("key too short (%d vs %d)", bits, size) - } -+ if boring.Enabled && size < 1024 { -+ t.Logf("skipping short key with BoringCrypto: %d", size) -+ continue -+ } - testKeyBasics(t, priv) - if testing.Short() { - break -@@ -114,6 +120,35 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { - t.Errorf("private exponent too large") - } - -+ if boring.Enabled { -+ // Cannot call encrypt/decrypt with raw RSA. PKCSv1.5 -+ // not supported in some configurations. Test with -+ // OAEP if possible (i.e., key size is equal to or -+ // longer than 2048 bits). -+ if bits := priv.N.BitLen(); boring.Enabled && bits < 2048 { -+ t.Logf("skipping short key with BoringCrypto: %d", bits) -+ return -+ } -+ sha256 := sha256.New() -+ -+ msg := []byte("hi!") -+ enc, err := EncryptOAEP(sha256, rand.Reader, &priv.PublicKey, msg, nil) -+ if err != nil { -+ t.Errorf("EncryptOAEP: %v", err) -+ return -+ } -+ -+ dec, err := DecryptOAEP(sha256, rand.Reader, priv, enc, nil) -+ if err != nil { -+ t.Errorf("DecryptOAEP: %v", err) -+ return -+ } -+ if !bytes.Equal(dec, msg) { -+ t.Errorf("got:%x want:%x (%+v)", dec, msg, priv) -+ } -+ return -+ } -+ - msg := []byte("hi!") - enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg) - if err != nil { -@@ -121,7 +156,7 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { - return - } - -- dec, err := DecryptPKCS1v15(nil, priv, enc) -+ dec, err := DecryptPKCS1v15(rand.Reader, priv, enc) - if err != nil { - t.Errorf("DecryptPKCS1v15: %v", err) - return -@@ -178,6 +213,9 @@ func TestEverything(t *testing.T) { - if bits := priv.N.BitLen(); bits != size { - t.Errorf("key too short (%d vs %d)", bits, size) - } -+ if boring.Enabled && size < 2048 { -+ t.Skip("skipping short key with BoringCrypto") -+ } - testEverything(t, priv) - }) - } -@@ -629,6 +667,10 @@ func TestEncryptOAEP(t *testing.T) { - n := new(big.Int) - for i, test := range testEncryptOAEPData { - n.SetString(test.modulus, 16) -+ if boring.Enabled { -+ t.Log("skipping test in FIPS mode due to short keys and unpadded RSA operations not allowed with FIPS") -+ continue -+ } - public := PublicKey{N: n, E: test.e} - - for j, message := range test.msgs { -@@ -652,6 +694,10 @@ func TestDecryptOAEP(t *testing.T) { - d := new(big.Int) - for i, test := range testEncryptOAEPData { - n.SetString(test.modulus, 16) -+ if boring.Enabled && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { -+ t.Logf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) -+ continue -+ } - d.SetString(test.d, 16) - private := new(PrivateKey) - private.PublicKey = PublicKey{N: n, E: test.e} -@@ -695,6 +741,10 @@ func Test2DecryptOAEP(t *testing.T) { - sha1 := crypto.SHA1 - sha256 := crypto.SHA256 - -+ if boring.Enabled && n.BitLen() < 2048 { -+ t.Skipf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) -+ } -+ - out, err := priv.Decrypt(random, in, &OAEPOptions{MGFHash: sha1, Hash: sha256}) - - if err != nil { -@@ -710,6 +760,10 @@ func TestEncryptDecryptOAEP(t *testing.T) { - d := new(big.Int) - for i, test := range testEncryptOAEPData { - n.SetString(test.modulus, 16) -+ if boring.Enabled && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { -+ t.Logf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) -+ continue -+ } - d.SetString(test.d, 16) - priv := new(PrivateKey) - priv.PublicKey = PublicKey{N: n, E: test.e} -diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go -index aad96b1c74..bbf3d38339 100644 ---- a/src/crypto/tls/boring.go -+++ b/src/crypto/tls/boring.go -@@ -6,7 +6,16 @@ - - package tls - --import "crypto/internal/boring/fipstls" -+import ( -+ boring "crypto/internal/backend" -+ "crypto/internal/boring/fipstls" -+) -+ -+func init() { -+ if boring.Enabled && !boring.ExecutingTest() { -+ fipstls.Force() -+ } -+} - - // needFIPS returns fipstls.Required(), which is not available without the - // boringcrypto build tag. -diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go -index ba68f355eb..7bfe3f9417 100644 ---- a/src/crypto/tls/boring_test.go -+++ b/src/crypto/tls/boring_test.go -@@ -9,6 +9,8 @@ package tls - import ( - "crypto/ecdsa" - "crypto/elliptic" -+ "crypto/internal/boring" -+ "crypto/internal/backend/boringtest" - "crypto/internal/boring/fipstls" - "crypto/rand" - "crypto/rsa" -@@ -44,7 +46,11 @@ func TestBoringServerProtocolVersion(t *testing.T) { - test(t, "VersionTLS10", VersionTLS10, "") - test(t, "VersionTLS11", VersionTLS11, "") - test(t, "VersionTLS12", VersionTLS12, "") -- test(t, "VersionTLS13", VersionTLS13, "") -+ if boring.Enabled && !boring.SupportsHKDF() { -+ test(t, "VersionTLS13", VersionTLS13, "client offered only unsupported versions") -+ } else { -+ test(t, "VersionTLS13", VersionTLS13, "") -+ } - - t.Run("fipstls", func(t *testing.T) { - fipstls.Force() -@@ -52,11 +58,13 @@ func TestBoringServerProtocolVersion(t *testing.T) { - test(t, "VersionTLS10", VersionTLS10, "supported versions") - test(t, "VersionTLS11", VersionTLS11, "supported versions") - test(t, "VersionTLS12", VersionTLS12, "") -- test(t, "VersionTLS13", VersionTLS13, "supported versions") -+ if boring.SupportsHKDF() { -+ test(t, "VersionTLS13/fipstls", VersionTLS13, "") -+ } - }) - } - - func isBoringVersion(v uint16) bool { -- return v == VersionTLS12 -+ return v == VersionTLS12 || (boring.SupportsHKDF() && v == VersionTLS13) - } - -@@ -226,7 +236,14 @@ func TestBoringServerSignatureAndHash(t *testing.T) { - // 1.3, and the ECDSA ones bind to the curve used. - serverConfig.MaxVersion = VersionTLS12 - -- clientErr, serverErr := boringHandshake(t, testConfig, serverConfig) -+ clientConfig := testConfig.Clone() -+ -+ if boring.Enabled { -+ serverConfig.Rand = boring.RandReader -+ clientConfig.Rand = boring.RandReader -+ } -+ -+ clientErr, serverErr := boringHandshake(t, clientConfig, serverConfig) - if clientErr != nil { - t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr) - } -@@ -315,15 +332,31 @@ func TestBoringCertAlgs(t *testing.T) { - R2 := boringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA) - - M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) -- M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA) -+ -+ // If OpenSSL supports P224, use the default upstream behavior, -+ // otherwise test with P384 -+ var M2_R1 *boringCertificate -+ if boringtest.Supports(t, "CurveP224") { -+ M2_R1 = boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA) -+ } else { -+ M2_R1 = boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P384()), R1, boringCertCA|boringCertFIPSOK) -+ } - - I_R1 := boringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK) -- I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK) -+ I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA) - I_M1 := boringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK) - I_M2 := boringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK) - - L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK) -- L2_I := boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf) -+ -+ -+ // Older versions of OpenSSL allow 1024 bit leaf certs -+ var L2_I *boringCertificate -+ if boringtest.Supports(t, "RSA1024LeafCert") { -+ L2_I = boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf) -+ } else { -+ L2_I = boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf|boringCertNotBoring) -+ } - - // client verifying server cert - testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) { -@@ -336,6 +369,11 @@ func TestBoringCertAlgs(t *testing.T) { - serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}} - serverConfig.BuildNameToCertificate() - -+ if boring.Enabled { -+ serverConfig.Rand = boring.RandReader -+ clientConfig.Rand = boring.RandReader -+ } -+ - clientErr, _ := boringHandshake(t, clientConfig, serverConfig) - - if (clientErr == nil) == ok { -@@ -362,6 +400,16 @@ func TestBoringCertAlgs(t *testing.T) { - serverConfig := testConfig.Clone() - serverConfig.ClientCAs = pool - serverConfig.ClientAuth = RequireAndVerifyClientCert -+ if boring.Enabled { -+ serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate} -+ serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey -+ serverConfig.BuildNameToCertificate() -+ } -+ -+ if boring.Enabled { -+ serverConfig.Rand = boring.RandReader -+ clientConfig.Rand = boring.RandReader -+ } - - _, serverErr := boringHandshake(t, clientConfig, serverConfig) - -@@ -384,8 +432,8 @@ func TestBoringCertAlgs(t *testing.T) { - // exhaustive test with computed answers. - r1pool := x509.NewCertPool() - r1pool.AddCert(R1.cert) -- testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true) -- testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true) -+ testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, !(L2_I.notBoring && boring.Enabled)) -+ testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, !(L2_I.notBoring && boring.Enabled)) - fipstls.Force() - testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false) - testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false) -@@ -406,7 +454,7 @@ func TestBoringCertAlgs(t *testing.T) { - leaf = L2_I - } - for i := 0; i < 64; i++ { -- reachable := map[string]bool{leaf.parentOrg: true} -+ reachable := map[string]bool{leaf.parentOrg: !(leaf.notBoring && boring.Enabled)} - reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK} - list := [][]byte{leaf.der} - listName := leaf.name -@@ -414,7 +462,7 @@ func TestBoringCertAlgs(t *testing.T) { - if cond != 0 { - list = append(list, c.der) - listName += "," + c.name -- if reachable[c.org] { -+ if reachable[c.org] && !(c.notBoring && boring.Enabled) { - reachable[c.parentOrg] = true - } - if reachableFIPS[c.org] && c.fipsOK { -@@ -438,7 +486,7 @@ func TestBoringCertAlgs(t *testing.T) { - if cond != 0 { - rootName += "," + c.name - pool.AddCert(c.cert) -- if reachable[c.org] { -+ if reachable[c.org] && !(c.notBoring && boring.Enabled) { - shouldVerify = true - } - if reachableFIPS[c.org] && c.fipsOK { -@@ -464,6 +512,7 @@ const ( - boringCertCA = iota - boringCertLeaf - boringCertFIPSOK = 0x80 -+ boringCertNotBoring = 0x100 - ) - - func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey { -@@ -490,6 +539,7 @@ type boringCertificate struct { - cert *x509.Certificate - key interface{} - fipsOK bool -+ notBoring bool - } - - func boringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate { -@@ -511,7 +561,7 @@ func boringCert(t *testing.T, name string, key interface{}, parent *boringCertif - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, - BasicConstraintsValid: true, - } -- if mode&^boringCertFIPSOK == boringCertLeaf { -+ if mode&^(boringCertFIPSOK|boringCertNotBoring) == boringCertLeaf { - tmpl.DNSNames = []string{"example.com"} - } else { - tmpl.IsCA = true -@@ -548,7 +598,8 @@ func boringCert(t *testing.T, name string, key interface{}, parent *boringCertif - } - - fipsOK := mode&boringCertFIPSOK != 0 -- return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK} -+ notBoring := mode&boringCertNotBoring != 0 -+ return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK, notBoring} - } - - // A self-signed test certificate with an RSA key of size 2048, for testing -diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go -index 04e6dfe018..b6ed936cd1 100644 ---- a/src/crypto/tls/cipher_suites.go -+++ b/src/crypto/tls/cipher_suites.go -@@ -354,6 +354,11 @@ var defaultCipherSuitesTLS13NoAES = []uint16{ - TLS_RSA_WITH_3DES_EDE_CBC_SHA: true, - } - -+var defaultFIPSCipherSuitesTLS13 = []uint16{ -+ TLS_AES_128_GCM_SHA256, -+ TLS_AES_256_GCM_SHA384, -+} -+ - var ( - hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ - hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL -diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go -index 5394d64ac6..db4e2dbf60 100644 ---- a/src/crypto/tls/common.go -+++ b/src/crypto/tls/common.go -@@ -12,6 +12,7 @@ import ( - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" -+ "crypto/internal/boring" - "crypto/rand" - "crypto/rsa" - "crypto/sha512" -@@ -994,6 +995,9 @@ const roleServer = false - func (c *Config) supportedVersions(isClient bool) []uint16 { - versions := make([]uint16, 0, len(supportedVersions)) - for _, v := range supportedVersions { -+ if boring.Enabled && !boring.SupportsHKDF() && v > VersionTLS12 { -+ continue -+ } - if needFIPS() && !slices.Contains(defaultSupportedVersionsFIPS, v) { - continue - } -diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go -index 22be38faff..d460eeb880 100644 ---- a/src/crypto/tls/handshake_client_test.go -+++ b/src/crypto/tls/handshake_client_test.go -@@ -2156,6 +2156,7 @@ func testBuffering(t *testing.T, version uint16) { - } - - func TestAlertFlushing(t *testing.T) { -+ t.Skip("unsupported in FIPS mode, different error returned") - c, s := localPipe(t) - done := make(chan bool) - -diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go -index ae8f80a7cf..30a8450f40 100644 ---- a/src/crypto/tls/key_schedule.go -+++ b/src/crypto/tls/key_schedule.go -@@ -7,6 +7,7 @@ package tls - import ( - "crypto/ecdh" - "crypto/hmac" - "crypto/internal/mlkem768" -+ "crypto/internal/boring" - "errors" - "fmt" -@@ -58,9 +59,20 @@ func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []by - panic(fmt.Errorf("failed to construct HKDF label: %s", err)) - } - out := make([]byte, length) -- n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out) -- if err != nil || n != length { -- panic("tls: HKDF-Expand-Label invocation failed unexpectedly") -+ if boring.Enabled { -+ reader, err := boring.ExpandHKDF(c.hash.New, secret, hkdfLabelBytes) -+ if err != nil { -+ panic("tls: HKDF-Expand-Label invocation failed unexpectedly") -+ } -+ n, err := reader.Read(out) -+ if err != nil || n != length { -+ panic("tls: HKDF-Expand-Label invocation failed unexpectedly") -+ } -+ } else { -+ n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out) -+ if err != nil || n != length { -+ panic("tls: HKDF-Expand-Label invocation failed unexpectedly") -+ } - } - return out - } -@@ -78,7 +90,15 @@ func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte { - if newSecret == nil { - newSecret = make([]byte, c.hash.Size()) - } -- return hkdf.Extract(c.hash.New, newSecret, currentSecret) -+ if boring.Enabled { -+ ikm, err := boring.ExtractHKDF(c.hash.New, newSecret, currentSecret) -+ if err != nil { -+ panic("tls: HKDF-Extract invocation failed unexpectedly") -+ } -+ return ikm -+ } else { -+ return hkdf.Extract(c.hash.New, newSecret, currentSecret) -+ } - } - - // nextTrafficSecret generates the next traffic secret, given the current one, -diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go -index 33fd0ed52b..102acda578 100644 ---- a/src/crypto/x509/boring_test.go -+++ b/src/crypto/x509/boring_test.go -@@ -10,6 +10,7 @@ import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/internal/boring/fipstls" -+ "crypto/internal/backend/boringtest" - "crypto/rand" - "crypto/rsa" - "crypto/x509/pkix" -@@ -58,7 +59,15 @@ func TestBoringAllowCert(t *testing.T) { - R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK) - - M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) -- M2_R1 := testBoringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA) -+ -+ var M2_R1 *boringCertificate -+ // If OpenSSL supports P224, use the default upstream behavior, -+ // otherwise test with P384 -+ if boringtest.Supports(t, "CurveP224") { -+ M2_R1 = testBoringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA) -+ } else { -+ M2_R1 = testBoringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P384()), R1, boringCertCA|boringCertFIPSOK) -+ } - - I_R1 := testBoringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK) - testBoringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK) -diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go -index 8846b00312..8734dd03c1 100644 ---- a/src/crypto/x509/x509_test.go -+++ b/src/crypto/x509/x509_test.go -@@ -12,6 +12,8 @@ import ( - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" -+ "crypto/internal/boring" -+ "crypto/internal/backend/boringtest" - "crypto/rand" - "crypto/rsa" - _ "crypto/sha256" -@@ -125,32 +127,54 @@ func TestParsePKIXPublicKey(t *testing.T) { - }) - } - -+// This public key is extracted from pemPrivateKey defined below with -+// the following command: -+// -+// openssl pkey -pubout -in key.pem -+// - var pemPublicKey = `-----BEGIN PUBLIC KEY----- --MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VoPN9PKUjKFLMwOge6+ --wnDi8sbETGIx2FKXGgqtAKpzmem53kRGEQg8WeqRmp12wgp74TGpkEXsGae7RS1k --enJCnma4fii+noGH7R0qKgHvPrI2Bwa9hzsH8tHxpyM3qrXslOmD45EH9SxIDUBJ --FehNdaPbLP1gFyahKMsdfxFJLUvbUycuZSJ2ZnIgeVxwm4qbSvZInL9Iu4FzuPtg --fINKcbbovy1qq4KvPIrXzhbY3PWDc6btxCf3SE0JdE1MCPThntB62/bLMSQ7xdDR --FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ --+QIDAQAB -+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp5qgUIj096pw8U+AjcJu -+cLWenR3oe+tEthXiAuqcYgslW5UUlMim34U/h7NbLvbG2KJ2chUsmLtuCFaoIe/Y -+KW5DKm3SPytK/KCBsVa+MQ7zuF/1ks5p7yBqFBl6QTekMzwskt/zyDIG9f3A+38a -+kruHNBvUgYqwbWPx4ycclQ52GSev/Cfx0I68TGT5SwN/eCJ/ghq3iGAf0mX1bkVa -+W1seKbL49aAA94KnDCRdl813+S2REPDf2tZwlT0JpZm5QtAqthonZjkjHocZNxhk -+KF3XWUntE/+l6R4A+CWZlC2vmUc1hJTEraksy2JUIjxAaq//FnDpIEVG/N2ofmNp -+aQIDAQAB - -----END PUBLIC KEY----- - ` - -+// This key is generated with the following command: -+// -+// openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem -+// openssl pkey -traditional -in key.pem > key-traditional.pem -+// - var pemPrivateKey = testingKey(` - -----BEGIN RSA TESTING KEY----- --MIICXAIBAAKBgQCxoeCUW5KJxNPxMp+KmCxKLc1Zv9Ny+4CFqcUXVUYH69L3mQ7v --IWrJ9GBfcaA7BPQqUlWxWM+OCEQZH1EZNIuqRMNQVuIGCbz5UQ8w6tS0gcgdeGX7 --J7jgCQ4RK3F/PuCM38QBLaHx988qG8NMc6VKErBjctCXFHQt14lerd5KpQIDAQAB --AoGAYrf6Hbk+mT5AI33k2Jt1kcweodBP7UkExkPxeuQzRVe0KVJw0EkcFhywKpr1 --V5eLMrILWcJnpyHE5slWwtFHBG6a5fLaNtsBBtcAIfqTQ0Vfj5c6SzVaJv0Z5rOd --7gQF6isy3t3w9IF3We9wXQKzT6q5ypPGdm6fciKQ8RnzREkCQQDZwppKATqQ41/R --vhSj90fFifrGE6aVKC1hgSpxGQa4oIdsYYHwMzyhBmWW9Xv/R+fPyr8ZwPxp2c12 --33QwOLPLAkEA0NNUb+z4ebVVHyvSwF5jhfJxigim+s49KuzJ1+A2RaSApGyBZiwS --rWvWkB471POAKUYt5ykIWVZ83zcceQiNTwJBAMJUFQZX5GDqWFc/zwGoKkeR49Yi --MTXIvf7Wmv6E++eFcnT461FlGAUHRV+bQQXGsItR/opIG7mGogIkVXa3E1MCQARX --AAA7eoZ9AEHflUeuLn9QJI/r0hyQQLEtrpwv6rDT1GCWaLII5HJ6NUFVf4TTcqxo --6vdM4QGKTJoO+SaCyP0CQFdpcxSAuzpFcKv0IlJ8XzS/cy+mweCMwyJ1PFEc4FX6 --wg/HcAJWY60xZTJDFN+Qfx8ZQvBEin6c2/h+zZi5IVY= -+MIIEogIBAAKCAQEAp5qgUIj096pw8U+AjcJucLWenR3oe+tEthXiAuqcYgslW5UU -+lMim34U/h7NbLvbG2KJ2chUsmLtuCFaoIe/YKW5DKm3SPytK/KCBsVa+MQ7zuF/1 -+ks5p7yBqFBl6QTekMzwskt/zyDIG9f3A+38akruHNBvUgYqwbWPx4ycclQ52GSev -+/Cfx0I68TGT5SwN/eCJ/ghq3iGAf0mX1bkVaW1seKbL49aAA94KnDCRdl813+S2R -+EPDf2tZwlT0JpZm5QtAqthonZjkjHocZNxhkKF3XWUntE/+l6R4A+CWZlC2vmUc1 -+hJTEraksy2JUIjxAaq//FnDpIEVG/N2ofmNpaQIDAQABAoIBAAYH7h9fwkLcNvqz -+8+oF9k/ndSjtr9UvstYDhRG6S/zKLmK0g1xUOQ7/fjj9lvkiZ6bZd74krWlkizHR -+HnU0KnjZLyEKeR+NSQI8q1YMi0T8JwB6MX3CIDU62x5UiV3p6OZwEqGJXf4U8MOu -+ySAzo2rmxRd2reeobC9Pgp98I47oeqaSRwFVZRPfKk5RvfI7KRmL58BAB0XS56PA -+PJ+3l0fB/oIV11iaBEKildxLDtrvlepQ2KPNf7Dpk0/CPRtS/jxyxIyML8tjR3F0 -+KuHplsRjTANyzW/aHddO1fnfnXsVo+0PzSPTHCbxKSu5XmChqsKoB1jM+/tJci4y -+ST5hUXUCgYEAzfA5XEMkR/NNJMfR+FBbdfpQ1b0wqH3qtWZx/tBjKC2Y0XnDQ8ZR -+SEWONLVZMRtTlJaHIPZ9i6anQRR5harrff0OpsKiJUGDout8ehE6eiN8ABWGNlCI -+AiLCerVJZMDcSuDU7xsdHVIdSxYh88Z9g54vUQ4214BG/G0Qm1emV3UCgYEA0FjP -+wq5cEGt9xDCg+oXk0bLm4Wn4FkabJH7M+oCosHHY9W1vgvv50bpNoAbaB5r1mlan -+T6gEtkQPB2juMTnuIwRL+kvOmSKqZGlAsyrq8smTuBUv7brbybkYN3Rg51KV6u1J -+vCdGpMYWHUNRkkQ88cr6iFPodYU+CzRR4ABif6UCgYBc0jDYb/7TW0tjD5mJJZcD -+xw5WOE7NMuvuVT1+T6jRvDOL/yjOzH1oaMle4npQEvQKHgrMBa2ymyv5vmPDprU7 -+9Sp8aW+yASR281MIpelIkePbGdiDdKrI46fqrPlmqzLfoRT4rKzjwVYouNIW0VlT -+UKIdE54OZegY8IOysL/t3QKBgDZnSnECiIW9G80UCaUBO3vKZGFuA1sFutMvzSSI -+XgQc5lNH7TtdwqESLdzgjSQ5QXK4t92j+P8DDI2Zx8DQ6K76G0DTdLImDCpGFZ/z -+UABvxIPn/GjuRyAIlhs852Tf+seqiHt6Igc6tmGTx4QTD3rvzrW0e1ncnhPc6Jg+ -+YXoFAoGARD9OPrd4J2N+nkSWif9VOuPHvOXEczwBDJbsAGrOW1kTbDStF0OIVOt0 -+Ukj+mnnL8ZNyVLgTrZDRfXvlA94EbPK5/rMAYwjMlXHP8R22ts3eDMNUdw0/Zl1g -+QOhL8wXZcdwHKsONy55kZHo8pmneqi9EnqqLGguLwx5WIMzWvZ8= - -----END RSA TESTING KEY----- - `) - -@@ -210,13 +234,13 @@ func bigFromHexString(s string) *big.Int { - - var rsaPrivateKey = &rsa.PrivateKey{ - PublicKey: rsa.PublicKey{ -- N: bigFromString("124737666279038955318614287965056875799409043964547386061640914307192830334599556034328900586693254156136128122194531292927142396093148164407300419162827624945636708870992355233833321488652786796134504707628792159725681555822420087112284637501705261187690946267527866880072856272532711620639179596808018872997"), -+ N: bigFromString("21158045964626271357192122217374656030758659027828186070945904292001900400536015683616588162432995042444433048358489684754391937856768687035719252953024200424710141144247332111111703450451053746470714834263970345645429072182468402024496704681563920755701016821908901551953007428010372679515325239834996680088335364047952157190852800612876331418656069309925009888436309603986985085994522668542367909534919143332035879812534342880780397552183153129074979881038274141387521146813437241354454755076987809231514974999721446583492285447433481905074857761363232069067710471781475338676103917736574576264372309657208790149481"), - E: 65537, - }, -- D: bigFromString("69322600686866301945688231018559005300304807960033948687567105312977055197015197977971637657636780793670599180105424702854759606794705928621125408040473426339714144598640466128488132656829419518221592374964225347786430566310906679585739468938549035854760501049443920822523780156843263434219450229353270690889"), -+ D: bigFromString("761340340511160175596965412196526886865993372482350730149506062172718946847796801591296809955561141932718681604153505639135828424412541864931030231418425021767439619656396706456340306422726055474229263742664572190035142125430003037585933958150329067887329644632294232035234749334047352968048823517110653841610552935776850272326662981899080407723586223365381844237920705656687458814241284694808178926597606445541251131238479373288091835422103855191540510255449923931942356040157416183921500123257314690876170989779091557025781299703525522541564460824444942813697278129203778499396891927458901143348340382342458724725"), - Primes: []*big.Int{ -- bigFromString("11405025354575369741595561190164746858706645478381139288033759331174478411254205003127028642766986913445391069745480057674348716675323735886284176682955723"), -- bigFromString("10937079261204603443118731009201819560867324167189758120988909645641782263430128449826989846631183550578761324239709121189827307416350485191350050332642639"), -+ bigFromString("144614845075019407477413542397453717313067325100413366253445573263534965103596714687177264872359318890824353359027245467187809258188745722502749049155303133577880462309749004261724896311777040275474974736908034246705034289232466323779271534051780280366551238605398407358839369487962557838147775245147196249973"), -+ bigFromString("146306182837940795154243491672545598732731521261772425577071902398494756400761181229877966908959767779942799478853764354255505873530749881845000716071915494302715554511619294255599209521952152229250381623079574375248555498847701822870266575429060940749806104053368129657146195126647000200158517816035847077797"), - }, - } - -@@ -629,6 +653,13 @@ func TestCreateSelfSignedCertificate(t *testing.T) { - extraExtensionData := []byte("extra extension") - - for _, test := range tests { -+ if boring.Enabled && test.sigAlgo.isRSAPSS() { -+ key, _ := test.priv.(*rsa.PrivateKey) -+ if key.PublicKey.N.BitLen() < 2048 { -+ t.Logf("skipping short key with BoringCrypto: %d", key.PublicKey.N.BitLen()) -+ continue -+ } -+ } - commonName := "test.example.com" - template := Certificate{ - SerialNumber: big.NewInt(1), -@@ -3607,11 +3638,19 @@ func TestParseRevocationList(t *testing.T) { - } - - func TestRevocationListCheckSignatureFrom(t *testing.T) { -- goodKey, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) -+ var testCurve elliptic.Curve -+ // If OpenSSL supports P224, use the default upstream behavior, -+ // otherwise test with P384 -+ if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ testCurve = elliptic.P224() -+ } else { -+ testCurve = elliptic.P384() -+ } -+ goodKey, err := ecdsa.GenerateKey(testCurve, rand.Reader) - if err != nil { - t.Fatalf("failed to generate test key: %s", err) - } -- badKey, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) -+ badKey, err := ecdsa.GenerateKey(testCurve, rand.Reader) - if err != nil { - t.Fatalf("failed to generate test key: %s", err) - } -diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go -index 08452c7b1d..0732db0662 100644 ---- a/src/go/build/deps_test.go -+++ b/src/go/build/deps_test.go -@@ -396,9 +396,11 @@ var depsRules = ` - < crypto/internal/alias - < crypto/cipher; - -- crypto/cipher, -+ fmt, crypto/cipher, - crypto/internal/boring/bcache - < crypto/internal/boring -+ < github.com/golang-fips/openssl/v2 -+ < crypto/internal/backend - < crypto/boring; - - crypto/internal/alias -@@ -427,11 +429,13 @@ var depsRules = ` - golang.org/x/crypto/sha3 - < CRYPTO; - -- CGO, fmt, net !< CRYPTO; -+ CGO, net !< CRYPTO; - - # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok. - CRYPTO, FMT, math/big -+ < github.com/golang-fips/openssl/v2/bbig - < crypto/internal/boring/bbig -+ < crypto/internal/backend/bbig - < crypto/rand - < crypto/internal/mlkem768 - < crypto/ed25519 -@@ -629,6 +633,7 @@ func listStdPkgs(goroot string) ([]string, error) { - } - - func TestDependencies(t *testing.T) { -+ t.Skip("openssl based toolchain has different dependencies than upstream") - if !testenv.HasSrc() { - // Tests run in a limited file system and we do not - // provide access to every source file. -@@ -671,7 +676,7 @@ var buildIgnore = []byte("\n//go:build ignore") - - func findImports(pkg string) ([]string, error) { - vpkg := pkg -- if strings.HasPrefix(pkg, "golang.org") { -+ if strings.HasPrefix(pkg, "golang.org") || strings.HasPrefix(pkg, "github.com") { - vpkg = "vendor/" + pkg - } - dir := filepath.Join(Default.GOROOT, "src", vpkg) -@@ -681,7 +686,7 @@ func findImports(pkg string) ([]string, error) { - } - var imports []string - var haveImport = map[string]bool{} -- if pkg == "crypto/internal/boring" { -+ if pkg == "crypto/internal/boring" || pkg == "github.com/golang-fips/openssl/v2" { - haveImport["C"] = true // kludge: prevent C from appearing in crypto/internal/boring imports - } - fset := token.NewFileSet() -diff --git a/src/runtime/runtime_boring.go b/src/runtime/runtime_boring.go -index 5a98b20253..dc25cdcfd5 100644 ---- a/src/runtime/runtime_boring.go -+++ b/src/runtime/runtime_boring.go -@@ -17,3 +17,8 @@ func boring_runtime_arg0() string { - - //go:linkname fipstls_runtime_arg0 crypto/internal/boring/fipstls.runtime_arg0 - func fipstls_runtime_arg0() string { return boring_runtime_arg0() } -+ -+//go:linkname crypto_backend_runtime_arg0 crypto/internal/backend.runtime_arg0 -+func crypto_backend_runtime_arg0() string { -+ return boring_runtime_arg0() -+} -\ No newline at end of file diff --git a/patches/002-strict-fips-runtime-detection.patch b/patches/002-strict-fips-runtime-detection.patch deleted file mode 100644 index cee04b23d6..0000000000 --- a/patches/002-strict-fips-runtime-detection.patch +++ /dev/null @@ -1,171 +0,0 @@ -diff --git a/src/crypto/internal/backend/hostfips.go b/src/crypto/internal/backend/hostfips.go -new file mode 100644 -index 0000000000..6fcd7139c6 ---- /dev/null -+++ b/src/crypto/internal/backend/hostfips.go -@@ -0,0 +1,21 @@ -+package backend -+ -+import ( -+ "fmt" -+ "os" -+) -+ -+func hostFIPSModeEnabled() bool { -+ // Look at /proc/sys/crypto/fips_enabled to see if FIPS mode is enabled. -+ // If it is, log an error and exit. -+ // If we run into an error reading that file because it doesn't exist, assume FIPS mode is not enabled. -+ data, err := os.ReadFile("/proc/sys/crypto/fips_enabled") -+ if err != nil { -+ if os.IsNotExist(err) { -+ return false -+ } -+ fmt.Fprintf(os.Stderr, "error reading /proc/sys/crypto/fips_enabled: %v\n", err) -+ os.Exit(1) -+ } -+ return len(data) > 0 && data[0] == '1' -+} -diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go -index a27da89d4d..e1a78a0db3 100644 ---- a/src/crypto/internal/backend/nobackend.go -+++ b/src/crypto/internal/backend/nobackend.go -@@ -17,6 +17,10 @@ import ( - "io" - ) - -+func init() { -+ strictFIPSNonCompliantBinaryCheck() -+} -+ - var enabled = false - - // Unreachable marks code that should be unreachable -@@ -43,13 +47,13 @@ func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not availab - - const RandReader = randReader(0) - --func Enabled() bool { return false } --func NewSHA1() hash.Hash { panic("boringcrypto: not available") } --func NewSHA224() hash.Hash { panic("boringcrypto: not available") } --func NewSHA256() hash.Hash { panic("boringcrypto: not available") } --func NewSHA384() hash.Hash { panic("boringcrypto: not available") } --func NewSHA512() hash.Hash { panic("boringcrypto: not available") } --func SHA1(_ []byte) [20]byte { panic("boringcrypto: not available") } -+func Enabled() bool { return false } -+func NewSHA1() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA224() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA256() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA384() hash.Hash { panic("boringcrypto: not available") } -+func NewSHA512() hash.Hash { panic("boringcrypto: not available") } -+func SHA1(_ []byte) [20]byte { panic("boringcrypto: not available") } - func SHA224(_ []byte) [28]byte { panic("boringcrypto: not available") } - func SHA256(_ []byte) [32]byte { panic("boringcrypto: not available") } - func SHA384(_ []byte) [48]byte { panic("boringcrypto: not available") } -@@ -86,7 +90,8 @@ func VerifyECDSA(pub *PublicKeyECDSA, hash, sig []byte) bool { - - type PublicKeyECDH struct{ _ int } - type PrivateKeyECDH struct{ _ int } --func (pc *PublicKeyECDH) Bytes() []byte { panic("boringcrypto: not available") } -+ -+func (pc *PublicKeyECDH) Bytes() []byte { panic("boringcrypto: not available") } - func (pc *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { panic("boringcrypto: not available") } - - func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { -diff --git a/src/crypto/internal/backend/not_strict_fips.go b/src/crypto/internal/backend/not_strict_fips.go -new file mode 100644 -index 0000000000..f8e8fd6869 ---- /dev/null -+++ b/src/crypto/internal/backend/not_strict_fips.go -@@ -0,0 +1,10 @@ -+//go:build !goexperiment.strictfipsruntime -+// +build !goexperiment.strictfipsruntime -+ -+package backend -+ -+func strictFIPSOpenSSLRuntimeCheck() { -+} -+ -+func strictFIPSNonCompliantBinaryCheck() { -+} -diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -index 45862eda3d..f431a7cdf4 100644 ---- a/src/crypto/internal/backend/openssl.go -+++ b/src/crypto/internal/backend/openssl.go -@@ -19,6 +19,7 @@ import ( - var enabled bool - - func init() { -+ strictFIPSOpenSSLRuntimeCheck() - enabled = openssl.FIPS() - } - -diff --git a/src/crypto/internal/backend/strict_fips.go b/src/crypto/internal/backend/strict_fips.go -new file mode 100644 -index 0000000000..894eeca942 ---- /dev/null -+++ b/src/crypto/internal/backend/strict_fips.go -@@ -0,0 +1,23 @@ -+//go:build goexperiment.strictfipsruntime -+// +build goexperiment.strictfipsruntime -+ -+package backend -+ -+import ( -+ "fmt" -+ "os" -+) -+ -+func strictFIPSOpenSSLRuntimeCheck() { -+ if hostFIPSModeEnabled() && !Enabled() { -+ fmt.Fprintln(os.Stderr, "FIPS mode is enabled, but the required OpenSSL backend is unavailable") -+ os.Exit(1) -+ } -+} -+ -+func strictFIPSNonCompliantBinaryCheck() { -+ if hostFIPSModeEnabled() { -+ fmt.Fprintln(os.Stderr, "FIPS mode is enabled, but this binary is not compiled with FIPS compliant mode enabled") -+ os.Exit(1) -+ } -+} -diff --git a/src/internal/goexperiment/exp_strictfipsruntime_off.go b/src/internal/goexperiment/exp_strictfipsruntime_off.go -new file mode 100644 -index 0000000000..73a676a18b ---- /dev/null -+++ b/src/internal/goexperiment/exp_strictfipsruntime_off.go -@@ -0,0 +1,9 @@ -+// Code generated by mkconsts.go. DO NOT EDIT. -+ -+//go:build !goexperiment.strictfipsruntime -+// +build !goexperiment.strictfipsruntime -+ -+package goexperiment -+ -+const StrictFIPSRuntime = false -+const StrictFIPSRuntimeInt = 0 -diff --git a/src/internal/goexperiment/exp_strictfipsruntime_on.go b/src/internal/goexperiment/exp_strictfipsruntime_on.go -new file mode 100644 -index 0000000000..0983612732 ---- /dev/null -+++ b/src/internal/goexperiment/exp_strictfipsruntime_on.go -@@ -0,0 +1,9 @@ -+// Code generated by mkconsts.go. DO NOT EDIT. -+ -+//go:build goexperiment.strictfipsruntime -+// +build goexperiment.strictfipsruntime -+ -+package goexperiment -+ -+const StrictFIPSRuntime = true -+const StrictFIPSRuntimeInt = 1 -diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go -index 02e744362c..4ac7f480cf 100644 ---- a/src/internal/goexperiment/flags.go -+++ b/src/internal/goexperiment/flags.go -@@ -100,4 +100,6 @@ type Flags struct { - // Requires that gotypesalias=1 is set with GODEBUG. - // This flag will be removed with Go 1.24. - AliasTypeParams bool -+ -+ StrictFIPSRuntime bool - } diff --git a/patches/003-init-openssl-v2-backend.patch b/patches/003-init-openssl-v2-backend.patch deleted file mode 100644 index 6fe9cb9bbd..0000000000 --- a/patches/003-init-openssl-v2-backend.patch +++ /dev/null @@ -1,96 +0,0 @@ -diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -index 49bb6da477..69e29d3528 100644 ---- a/src/crypto/internal/backend/openssl.go -+++ b/src/crypto/internal/backend/openssl.go -@@ -11,16 +11,64 @@ - package backend - - import ( -- "os" -+ "crypto/internal/boring/sig" - "github.com/golang-fips/openssl/v2" -+ "os" -+ "syscall" - ) - - // Enabled controls whether FIPS crypto is enabled. - var enabled bool - -+var knownVersions = [...]string{"3", "1.1", "11", "111", "1.0.2", "1.0.0", "10"} -+ - func init() { -- strictFIPSOpenSSLRuntimeCheck() -- enabled = openssl.FIPS() -+ version, _ := syscall.Getenv("GO_OPENSSL_VERSION_OVERRIDE") -+ if version == "" { -+ var fallbackVersion string -+ for _, v := range knownVersions { -+ exists, fips := openssl.CheckVersion(v) -+ if exists && fips { -+ version = v -+ break -+ } -+ if exists && fallbackVersion == "" { -+ fallbackVersion = v -+ } -+ } -+ if version == "" && fallbackVersion != "" { -+ version = fallbackVersion -+ } -+ } -+ if err := openssl.Init(version); err != nil { -+ panic("opensslcrypto: can't initialize OpenSSL " + version + ": " + err.Error()) -+ } -+ // 0: FIPS opt-out: abort the process if it is enabled and can't be disabled. -+ // 1: FIPS required: abort the process if it is not enabled and can't be enabled. -+ // other values: do not override OpenSSL configured FIPS mode. -+ var fips string -+ if v, ok := syscall.Getenv("GOLANG_FIPS"); ok { -+ fips = v -+ } else if hostFIPSModeEnabled() { -+ // System configuration can only force FIPS mode. -+ fips = "1" -+ } -+ switch fips { -+ case "0": -+ if openssl.FIPS() { -+ if err := openssl.SetFIPS(false); err != nil { -+ panic("opensslcrypto: can't disable FIPS mode for " + openssl.VersionText() + ": " + err.Error()) -+ } -+ } -+ case "1": -+ if !openssl.FIPS() { -+ if err := openssl.SetFIPS(true); err != nil { -+ panic("opensslcrypto: can't enable FIPS mode for " + openssl.VersionText() + ": " + err.Error()) -+ } -+ } -+ enabled = true -+ } -+ sig.BoringCrypto() - } - - func Enabled() bool { -@@ -61,8 +109,7 @@ func UnreachableExceptTests() { - } - } - -- -- - const RandReader = openssl.RandReader - -+var NewGCMTLS13 = openssl.NewGCMTLS13 - var NewGCMTLS = openssl.NewGCMTLS -diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go -index ac90ba299f..bd5ac1bcfa 100644 ---- a/src/crypto/internal/backend/nobackend.go -+++ b/src/crypto/internal/backend/nobackend.go -@@ -66,6 +66,9 @@ func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not a - type PublicKeyECDSA struct{ _ int } - type PrivateKeyECDSA struct{ _ int } - -+func NewGCMTLS13(c cipher.Block) (cipher.AEAD, error) { -+ panic("boringcrypto: not available") -+} - func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { - panic("boringcrypto: not available") - } diff --git a/patches/004-fixes.patch b/patches/004-fixes.patch deleted file mode 100644 index 36fe1d53ef..0000000000 --- a/patches/004-fixes.patch +++ /dev/null @@ -1,260 +0,0 @@ -diff --git a/api/go1.16.txt b/api/go1.16.txt -index e12a050939..e555bfdf5c 100644 ---- a/api/go1.16.txt -+++ b/api/go1.16.txt -@@ -8525,3 +8525,5 @@ pkg syscall (darwin-arm64-cgo), type WaitStatus uint32 - pkg syscall (darwin-arm64-cgo), var Stderr int - pkg syscall (darwin-arm64-cgo), var Stdin int - pkg syscall (darwin-arm64-cgo), var Stdout int -+pkg crypto/rsa, func GenerateKeyNotBoring(io.Reader, int) (*PrivateKey, error) -+pkg crypto/rsa, func GenerateMultiPrimeKeyNotBoring(io.Reader, int, int) (*PrivateKey, error) -diff --git a/src/crypto/rsa/boring_test.go b/src/crypto/rsa/boring_test.go -index 4e7fd9de4a..bd060c6a9d 100644 ---- a/src/crypto/rsa/boring_test.go -+++ b/src/crypto/rsa/boring_test.go -@@ -22,7 +22,7 @@ import ( - ) - - func TestBoringASN1Marshal(t *testing.T) { -- k, err := GenerateKey(rand.Reader, 128) -+ k, err := GenerateKey(rand.Reader, 3072) - if err != nil { - t.Fatal(err) - } -diff --git a/src/crypto/rsa/equal_test.go b/src/crypto/rsa/equal_test.go -index 90f4bf9475..688df68545 100644 ---- a/src/crypto/rsa/equal_test.go -+++ b/src/crypto/rsa/equal_test.go -@@ -13,7 +13,7 @@ import ( - ) - - func TestEqual(t *testing.T) { -- private, _ := rsa.GenerateKey(rand.Reader, 512) -+ private, _ := rsa.GenerateKey(rand.Reader, 2048) - public := &private.PublicKey - - if !public.Equal(public) { -@@ -41,7 +41,7 @@ func TestEqual(t *testing.T) { - t.Errorf("private key is not equal to itself after decoding: %v", private) - } - -- other, _ := rsa.GenerateKey(rand.Reader, 512) -+ other, _ := rsa.GenerateKey(rand.Reader, 2048) - if public.Equal(other.Public()) { - t.Errorf("different public keys are Equal") - } -diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go -index befd1612b5..afa25a737c 100644 ---- a/src/crypto/rsa/pss_test.go -+++ b/src/crypto/rsa/pss_test.go -@@ -301,7 +301,7 @@ func fromHex(hexStr string) []byte { - } - - func TestInvalidPSSSaltLength(t *testing.T) { -- key, err := GenerateKey(rand.Reader, 245) -+ key, err := GenerateKey(rand.Reader, 2048) - if err != nil { - t.Fatal(err) - } -diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go -index dd79dc5439..52f2ac347c 100644 ---- a/src/crypto/rsa/rsa.go -+++ b/src/crypto/rsa/rsa.go -@@ -264,6 +264,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { - return GenerateMultiPrimeKey(random, 2, bits) - } - -+ - // GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit - // size and the given random source. - // -@@ -284,6 +285,24 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { - // - // [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf - func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { -+ if boring.Enabled() && boring.IsStrictFIPSMode() && !(random == boring.RandReader && nprimes == 2 && -+ (bits == 2048 || bits == 3072 || bits == 4096)) { -+ return nil, errors.New("crypto/rsa: invalid primes or bits for boring") -+ } -+ return generateMultiPrimeKeyInternal(random, nprimes, bits) -+} -+ -+func GenerateKeyNotBoring(random io.Reader, bits int) (*PrivateKey, error) { -+ boring.UnreachableExceptTests() -+ return generateMultiPrimeKeyInternal(random, 2, bits) -+} -+ -+func GenerateMultiPrimeKeyNotBoring(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { -+ boring.UnreachableExceptTests() -+ return generateMultiPrimeKeyInternal(random, nprimes, bits) -+} -+ -+func generateMultiPrimeKeyInternal(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { - randutil.MaybeReadByte(random) - - if boring.Enabled() && random == boring.RandReader && nprimes == 2 && -@@ -324,6 +343,7 @@ func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey - return key, nil - } - -+ - priv := new(PrivateKey) - priv.E = 65537 - -diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go -index 4b7427e1ae..da8c104044 100644 ---- a/src/crypto/rsa/rsa_test.go -+++ b/src/crypto/rsa/rsa_test.go -@@ -26,7 +26,17 @@ import ( - import "crypto/internal/backend/boringtest" - - func TestKeyGeneration(t *testing.T) { -- for _, size := range []int{128, 1024, 2048, 3072} { -+ testKeys := []int{128, 1024} -+ if boring.Enabled() { -+ for _, size := range testKeys { -+ _, err := GenerateKey(rand.Reader, size) -+ if err == nil && boring.IsStrictFIPSMode() { -+ t.Errorf("Gener(%d): boring: bad accept", size) -+ } -+ } -+ testKeys = []int{2048, 3072} -+ } -+ for _, size := range testKeys { - priv, err := GenerateKey(rand.Reader, size) - if err != nil { - t.Errorf("GenerateKey(%d): %v", size, err) -@@ -53,7 +63,12 @@ func Test3PrimeKeyGeneration(t *testing.T) { - - priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size) - if err != nil { -+ if boring.IsStrictFIPSMode() { -+ return -+ } - t.Errorf("failed to generate key") -+ } else if boring.IsStrictFIPSMode() { -+ t.Errorf("bad accept in strictfipsmode") - } - testKeyBasics(t, priv) - } -@@ -66,12 +81,20 @@ func Test4PrimeKeyGeneration(t *testing.T) { - - priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size) - if err != nil { -+ if boring.IsStrictFIPSMode() { -+ return -+ } - t.Errorf("failed to generate key") -+ } else if boring.IsStrictFIPSMode() { -+ t.Errorf("bad accept in strictfipsmode") - } - testKeyBasics(t, priv) - } - - func TestNPrimeKeyGeneration(t *testing.T) { -+ if boring.Enabled() { -+ t.Skip("Not supported in boring mode") -+ } - primeSize := 64 - maxN := 24 - if testing.Short() { -@@ -206,7 +229,7 @@ func TestEverything(t *testing.T) { - size := size - t.Run(fmt.Sprintf("%d", size), func(t *testing.T) { - t.Parallel() -- priv, err := GenerateKey(rand.Reader, size) -+ priv, err := GenerateKeyNotBoring(rand.Reader, size) - if err != nil { - t.Errorf("GenerateKey(%d): %v", size, err) - } -diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go -index 49702f59ba..e7ae7fc5ca 100644 ---- a/src/crypto/tls/boring_test.go -+++ b/src/crypto/tls/boring_test.go -@@ -329,7 +329,7 @@ func TestBoringCertAlgs(t *testing.T) { - // Set up some roots, intermediate CAs, and leaf certs with various algorithms. - // X_Y is X signed by Y. - R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) -- R2 := boringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA) -+ R2 := boringCert(t, "R2", NotBoringRSAKey(t, 512), nil, boringCertCA) - - M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) - -@@ -353,9 +353,9 @@ func TestBoringCertAlgs(t *testing.T) { - // Older versions of OpenSSL allow 1024 bit leaf certs - var L2_I *boringCertificate - if boringtest.Supports(t, "RSA1024LeafCert") { -- L2_I = boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf) -+ L2_I = boringCert(t, "L2_I", NotBoringRSAKey(t, 1024), I_R1, boringCertLeaf) - } else { -- L2_I = boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf|boringCertNotBoring) -+ L2_I = boringCert(t, "L2_I", NotBoringRSAKey(t, 1024), I_R1, boringCertLeaf|boringCertNotBoring) - } - - // client verifying server cert -@@ -515,6 +515,15 @@ const ( - boringCertNotBoring = 0x100 - ) - -+func NotBoringRSAKey(t *testing.T, size int) *rsa.PrivateKey { -+ k, err := rsa.GenerateKeyNotBoring(rand.Reader, size) -+ if err != nil { -+ t.Fatal(err) -+ } -+ return k -+} -+ -+ - func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey { - k, err := rsa.GenerateKey(rand.Reader, size) - if err != nil { -diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go -index 07b3c7095e..88b69937be 100644 ---- a/src/crypto/x509/boring_test.go -+++ b/src/crypto/x509/boring_test.go -@@ -27,6 +27,14 @@ const ( - boringCertFIPSOK = 0x80 - ) - -+func notBoringRSAKey(t *testing.T, size int) *rsa.PrivateKey { -+ k, err := rsa.GenerateKeyNotBoring(rand.Reader, size) -+ if err != nil { -+ t.Fatal(err) -+ } -+ return k -+} -+ - func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey { - k, err := rsa.GenerateKey(rand.Reader, size) - if err != nil { -@@ -55,7 +63,7 @@ type boringCertificate struct { - - func TestBoringAllowCert(t *testing.T) { - R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) -- R2 := testBoringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA) -+ R2 := testBoringCert(t, "R2", notBoringRSAKey(t, 512), nil, boringCertCA) - R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK) - - M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) -@@ -78,7 +86,7 @@ func TestBoringAllowCert(t *testing.T) { - testBoringCert(t, "I_R3", I_R3.key, R3, boringCertCA|boringCertFIPSOK) - - testBoringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK) -- testBoringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf) -+ testBoringCert(t, "L2_I", notBoringRSAKey(t, 1024), I_R1, boringCertLeaf) - } - - func testBoringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate { -diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go -index 22a104f338..8f77ffda62 100644 ---- a/src/crypto/x509/x509_test.go -+++ b/src/crypto/x509/x509_test.go -@@ -2927,7 +2927,7 @@ func TestUnknownExtKey(t *testing.T) { - DNSNames: []string{"foo"}, - ExtKeyUsage: []ExtKeyUsage{ExtKeyUsage(-1)}, - } -- signer, err := rsa.GenerateKey(rand.Reader, 1024) -+ signer, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - t.Errorf("failed to generate key for TestUnknownExtKey") - } diff --git a/patches/005-fixes-2.patch b/patches/005-fixes-2.patch deleted file mode 100644 index 76b1cbdecf..0000000000 --- a/patches/005-fixes-2.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go -index ac90ba299f..88be5de522 100644 ---- a/src/crypto/internal/backend/nobackend.go -+++ b/src/crypto/internal/backend/nobackend.go -@@ -10,15 +10,15 @@ package backend - import ( - "crypto" - "crypto/cipher" -- "crypto/internal/boring/sig" -- "math/big" - bbig "crypto/internal/boring" -+ "crypto/internal/boring/sig" - "hash" - "io" -+ "math/big" - ) - - func init() { -- strictFIPSNonCompliantBinaryCheck() -+ strictFIPSNonCompliantBinaryCheck() - } - - var enabled = false -@@ -32,6 +32,10 @@ func Unreachable() { - sig.StandardCrypto() - } - -+func IsStrictFIPSMode() bool { -+ return false -+} -+ - // UnreachableExceptTests marks code that should be unreachable - // when BoringCrypto is in use. It is a no-op without BoringCrypto. - func UnreachableExceptTests() {} -diff --git a/src/crypto/internal/backend/not_strict_fips.go b/src/crypto/internal/backend/not_strict_fips.go -index f8e8fd6869..806b035aa8 100644 ---- a/src/crypto/internal/backend/not_strict_fips.go -+++ b/src/crypto/internal/backend/not_strict_fips.go -@@ -3,6 +3,8 @@ - - package backend - -+var isStrictFIPS bool = false -+ - func strictFIPSOpenSSLRuntimeCheck() { - } - -diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -index 69a1c2bd0c..0e9fec07b7 100644 ---- a/src/crypto/internal/backend/openssl.go -+++ b/src/crypto/internal/backend/openssl.go -@@ -71,6 +71,10 @@ func init() { - sig.BoringCrypto() - } - -+func IsStrictFIPSMode() bool { -+ return isStrictFIPS -+} -+ - func Enabled() bool { - return enabled - } -diff --git a/src/crypto/internal/backend/strict_fips.go b/src/crypto/internal/backend/strict_fips.go -index 894eeca942..c1bda67f12 100644 ---- a/src/crypto/internal/backend/strict_fips.go -+++ b/src/crypto/internal/backend/strict_fips.go -@@ -8,6 +8,8 @@ import ( - "os" - ) - -+var isStrictFIPS bool = true -+ - func strictFIPSOpenSSLRuntimeCheck() { - if hostFIPSModeEnabled() && !Enabled() { - fmt.Fprintln(os.Stderr, "FIPS mode is enabled, but the required OpenSSL backend is unavailable") diff --git a/patches/006-fixes-3.patch b/patches/006-fixes-3.patch deleted file mode 100644 index b2702ffcad..0000000000 --- a/patches/006-fixes-3.patch +++ /dev/null @@ -1,81 +0,0 @@ -diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -index 0e9fec07b7..07d7692277 100644 ---- a/src/crypto/internal/backend/openssl.go -+++ b/src/crypto/internal/backend/openssl.go -@@ -12,9 +12,11 @@ package backend - - import ( - "crypto/internal/boring/sig" -- "github.com/golang-fips/openssl/v2" -+ "fmt" - "os" - "syscall" -+ -+ "github.com/golang-fips/openssl/v2" - ) - - // Enabled controls whether FIPS crypto is enabled. -@@ -27,13 +29,14 @@ func init() { - if version == "" { - var fallbackVersion string - for _, v := range knownVersions { -- exists, fips := openssl.CheckVersion(v) -+ vv := fmt.Sprintf("libcrypto.so.%s", v) -+ exists, fips := openssl.CheckVersion(vv) - if exists && fips { -- version = v -+ version = vv - break - } - if exists && fallbackVersion == "" { -- fallbackVersion = v -+ fallbackVersion = vv - } - } - if version == "" && fallbackVersion != "" { -diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go -index e7ae7fc5ca..01d3c35f35 100644 ---- a/src/crypto/tls/boring_test.go -+++ b/src/crypto/tls/boring_test.go -@@ -7,6 +7,7 @@ - package tls - - import ( -+ "crypto" - "crypto/ecdsa" - "crypto/elliptic" - boring "crypto/internal/backend" -@@ -216,7 +217,10 @@ func TestBoringServerSignatureAndHash(t *testing.T) { - - testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash} - -- sigType, _, _ := typeAndHashFromSignatureScheme(sigHash) -+ sigType, hashFunc, _ := typeAndHashFromSignatureScheme(sigHash) -+ if hashFunc == crypto.SHA1 && !boringtest.Supports(t, "SHA1") { -+ t.Skip("unsupported in FIPS mode") -+ } - switch sigType { - case signaturePKCS1v15, signatureRSAPSS: - serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256} -@@ -329,7 +333,7 @@ func TestBoringCertAlgs(t *testing.T) { - // Set up some roots, intermediate CAs, and leaf certs with various algorithms. - // X_Y is X signed by Y. - R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) -- R2 := boringCert(t, "R2", NotBoringRSAKey(t, 512), nil, boringCertCA) -+ R2 := boringCert(t, "R2", NotBoringRSAKey(t, 2560), nil, boringCertCA) - - M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) - -diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go -index 88b69937be..38790b33af 100644 ---- a/src/crypto/x509/boring_test.go -+++ b/src/crypto/x509/boring_test.go -@@ -63,7 +63,7 @@ type boringCertificate struct { - - func TestBoringAllowCert(t *testing.T) { - R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) -- R2 := testBoringCert(t, "R2", notBoringRSAKey(t, 512), nil, boringCertCA) -+ R2 := testBoringCert(t, "R2", notBoringRSAKey(t, 2560), nil, boringCertCA) - R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK) - - M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) diff --git a/patches/007-fixes-4.patch b/patches/007-fixes-4.patch deleted file mode 100644 index 64935d1a43..0000000000 --- a/patches/007-fixes-4.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -index 07d7692277..8812475b92 100644 ---- a/src/crypto/internal/backend/openssl.go -+++ b/src/crypto/internal/backend/openssl.go -@@ -43,6 +43,9 @@ func init() { - version = fallbackVersion - } - } -+ if version == "" { -+ strictFIPSOpenSSLRuntimeCheck() -+ } - if err := openssl.Init(version); err != nil { - panic("opensslcrypto: can't initialize OpenSSL " + version + ": " + err.Error()) - } diff --git a/patches/008-fixes-5.patch b/patches/008-fixes-5.patch deleted file mode 100644 index d87ef9d8e5..0000000000 --- a/patches/008-fixes-5.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 6640803d938b82efd32da6459b8f1ee53df5a180 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Mon, 16 Oct 2023 12:22:50 +0900 -Subject: [PATCH] crypto/rsa: use SHA256 instead of SHA1 in PKCS#1 v1.5 tests - -This switches to unconditionally using SHA256 for PKCS#1 v1.5 signing -and verification in tests, to pacify errors in FIPS mode. - -Signed-off-by: Daiki Ueno ---- - src/crypto/rsa/pkcs1v15_test.go | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go -index 0853178e3ab7b..3db1e94ffff2b 100644 ---- a/src/crypto/rsa/pkcs1v15_test.go -+++ b/src/crypto/rsa/pkcs1v15_test.go -@@ -11,7 +11,6 @@ import ( - "crypto/internal/backend/boringtest" - "crypto/rand" - . "crypto/rsa" -- "crypto/sha1" - "crypto/sha256" - "crypto/x509" - "encoding/base64" -@@ -210,16 +209,16 @@ type signPKCS1v15Test struct { - // - // `openssl rsautl -verify -inkey pk -in signature | hexdump -C` - var signPKCS1v15Tests = []signPKCS1v15Test{ -- {"Test.\n", "0c7c85d938862248846cba06b06ac9bfe752aafed3092c224f257855006aa35b43d101e6c8e59cbc4c20b07c81552963f189dea700e042d4b70c236a031a29a9273cc138e69dc1a5834491de4822d8cb6acf218789d2586cb0f3892236b0948ffaf8691f6fa04597caa45068f9be39b8ea8b5336a8c94e2696f872120778abcfea711e5fbf75f835f0f5204ccdd020013c2ceae25e9d1378a1d10cf86ca269eef48fee8ebb5e8dfb08f0c48d22d1a7162e080ec1f6e48541288aaaa1f2370f0688cf1786a32abed41df1d3b96b665794bf7a772743fc8b62d73901cea4569494c794a01ccc7dda0d42199f5b58739c0c0e280774b56ccf51993f5ea3d4954319"}, -+ {"Test.\n", "0c7da2fe34372c9e433ca668b6edf4cd7f7eb29f11c11c44d99cb6dc6fe4344cc656075015de6d0249d25b6e01bf22276e9f97f6e64f5905ce96cfc69e3c30e3813eb80553b1e53993482b97c920d030e1daf6c5f11f532a166a4b4aea34c6f8ed5579ccf6bfd5e20250d1979e97c358363da8ae15a095f07e9c54bfb948a94a75a6c8a0cbe4b9970d780ddf49369b2f134915e9a8ccf20e7b07981d0b95978630ee754f20bad163cdcff8c56c9bc66fd1060961779f1554894597086477d15346955d1a1c67d9718c4d25d840cf83fe203fd4e5681fc388a0395b79b94b1ade281f3682fb08a02ed6fa209caf489e9ccf501a86e99a36737b241c1e8ab2c2a4"}, - } - - func TestSignPKCS1v15(t *testing.T) { - for i, test := range signPKCS1v15Tests { -- h := sha1.New() -+ h := sha256.New() - h.Write([]byte(test.in)) - digest := h.Sum(nil) - -- s, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.SHA1, digest) -+ s, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.SHA256, digest) - if err != nil { - t.Errorf("#%d %s", i, err) - } -@@ -233,13 +232,13 @@ func TestSignPKCS1v15(t *testing.T) { - - func TestVerifyPKCS1v15(t *testing.T) { - for i, test := range signPKCS1v15Tests { -- h := sha1.New() -+ h := sha256.New() - h.Write([]byte(test.in)) - digest := h.Sum(nil) - - sig, _ := hex.DecodeString(test.out) - -- err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.SHA1, digest, sig) -+ err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.SHA256, digest, sig) - if err != nil { - t.Errorf("#%d %s", i, err) - } diff --git a/patches/009-fixes-6.patch b/patches/009-fixes-6.patch deleted file mode 100644 index c28216cce5..0000000000 --- a/patches/009-fixes-6.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 662ae4c37854734b17b095a36e42a8bbbcd85338 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Mon, 16 Oct 2023 12:25:26 +0900 -Subject: [PATCH] crypto/x509: adjust tests to pass under FIPS - -This fixes the following issues: - - --- FAIL: TestImports (0.93s) - x509_test.go:1411: failed to run x509_test_import.go: exit status 1 - panic: failed to create certificate with basic imports: EVP_PKEY_sign_init failed - openssl error(s): - error:1C800069:Provider routines::invalid key length - providers/common/securitycheck.c:67 - - goroutine 1 [running]: - main.main() - /__w/go/go/go/src/crypto/x509/x509_test_import.go:41 +0x205 - exit status 2 - --- FAIL: TestDisableSHA1ForCertOnly (0.00s) - x509_test.go:3653: failed to generate test cert: EVP_PKEY_fromdata - openssl error(s): - -The former was using too short RSA key (512 bits), while the latter -should be skipped when SHA1 signatures are not supported. - -Signed-off-by: Daiki Ueno ---- - src/crypto/x509/x509_test.go | 3 +++ - src/crypto/x509/x509_test_import.go | 40 +++++++++++++++++++++++------ - 2 files changed, 35 insertions(+), 8 deletions(-) - -diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go -index 6621f1b8cc304..356528e69cc36 100644 ---- a/src/crypto/x509/x509_test.go -+++ b/src/crypto/x509/x509_test.go -@@ -3637,6 +3637,9 @@ func TestParseUniqueID(t *testing.T) { - } - - func TestDisableSHA1ForCertOnly(t *testing.T) { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -+ t.Skip("unsupported in FIPS mode") -+ } - t.Setenv("GODEBUG", "") - - tmpl := &Certificate{ -diff --git a/src/crypto/x509/x509_test_import.go b/src/crypto/x509/x509_test_import.go -index 2474e3d810edf..492cb0a87554c 100644 ---- a/src/crypto/x509/x509_test_import.go -+++ b/src/crypto/x509/x509_test_import.go -@@ -42,14 +42,38 @@ func main() { - } - } - --var pemPrivateKey = testingKey(`-----BEGIN RSA TESTING KEY----- --MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 --fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu --/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu --RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/ --EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A --IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS --tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V -+// This key is generated with the following command: -+// -+// openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem -+// openssl pkey -traditional -in key.pem > key-traditional.pem -+// -+var pemPrivateKey = testingKey(` -+-----BEGIN RSA TESTING KEY----- -+MIIEogIBAAKCAQEAp5qgUIj096pw8U+AjcJucLWenR3oe+tEthXiAuqcYgslW5UU -+lMim34U/h7NbLvbG2KJ2chUsmLtuCFaoIe/YKW5DKm3SPytK/KCBsVa+MQ7zuF/1 -+ks5p7yBqFBl6QTekMzwskt/zyDIG9f3A+38akruHNBvUgYqwbWPx4ycclQ52GSev -+/Cfx0I68TGT5SwN/eCJ/ghq3iGAf0mX1bkVaW1seKbL49aAA94KnDCRdl813+S2R -+EPDf2tZwlT0JpZm5QtAqthonZjkjHocZNxhkKF3XWUntE/+l6R4A+CWZlC2vmUc1 -+hJTEraksy2JUIjxAaq//FnDpIEVG/N2ofmNpaQIDAQABAoIBAAYH7h9fwkLcNvqz -+8+oF9k/ndSjtr9UvstYDhRG6S/zKLmK0g1xUOQ7/fjj9lvkiZ6bZd74krWlkizHR -+HnU0KnjZLyEKeR+NSQI8q1YMi0T8JwB6MX3CIDU62x5UiV3p6OZwEqGJXf4U8MOu -+ySAzo2rmxRd2reeobC9Pgp98I47oeqaSRwFVZRPfKk5RvfI7KRmL58BAB0XS56PA -+PJ+3l0fB/oIV11iaBEKildxLDtrvlepQ2KPNf7Dpk0/CPRtS/jxyxIyML8tjR3F0 -+KuHplsRjTANyzW/aHddO1fnfnXsVo+0PzSPTHCbxKSu5XmChqsKoB1jM+/tJci4y -+ST5hUXUCgYEAzfA5XEMkR/NNJMfR+FBbdfpQ1b0wqH3qtWZx/tBjKC2Y0XnDQ8ZR -+SEWONLVZMRtTlJaHIPZ9i6anQRR5harrff0OpsKiJUGDout8ehE6eiN8ABWGNlCI -+AiLCerVJZMDcSuDU7xsdHVIdSxYh88Z9g54vUQ4214BG/G0Qm1emV3UCgYEA0FjP -+wq5cEGt9xDCg+oXk0bLm4Wn4FkabJH7M+oCosHHY9W1vgvv50bpNoAbaB5r1mlan -+T6gEtkQPB2juMTnuIwRL+kvOmSKqZGlAsyrq8smTuBUv7brbybkYN3Rg51KV6u1J -+vCdGpMYWHUNRkkQ88cr6iFPodYU+CzRR4ABif6UCgYBc0jDYb/7TW0tjD5mJJZcD -+xw5WOE7NMuvuVT1+T6jRvDOL/yjOzH1oaMle4npQEvQKHgrMBa2ymyv5vmPDprU7 -+9Sp8aW+yASR281MIpelIkePbGdiDdKrI46fqrPlmqzLfoRT4rKzjwVYouNIW0VlT -+UKIdE54OZegY8IOysL/t3QKBgDZnSnECiIW9G80UCaUBO3vKZGFuA1sFutMvzSSI -+XgQc5lNH7TtdwqESLdzgjSQ5QXK4t92j+P8DDI2Zx8DQ6K76G0DTdLImDCpGFZ/z -+UABvxIPn/GjuRyAIlhs852Tf+seqiHt6Igc6tmGTx4QTD3rvzrW0e1ncnhPc6Jg+ -+YXoFAoGARD9OPrd4J2N+nkSWif9VOuPHvOXEczwBDJbsAGrOW1kTbDStF0OIVOt0 -+Ukj+mnnL8ZNyVLgTrZDRfXvlA94EbPK5/rMAYwjMlXHP8R22ts3eDMNUdw0/Zl1g -+QOhL8wXZcdwHKsONy55kZHo8pmneqi9EnqqLGguLwx5WIMzWvZ8= - -----END RSA TESTING KEY----- - `) - diff --git a/patches/010-fixes-7.patch b/patches/010-fixes-7.patch deleted file mode 100644 index bb9a9645e0..0000000000 --- a/patches/010-fixes-7.patch +++ /dev/null @@ -1,63 +0,0 @@ -diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go -index 3551b470ce..6f9573d066 100644 ---- a/src/crypto/x509/verify_test.go -+++ b/src/crypto/x509/verify_test.go -@@ -8,6 +8,7 @@ import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" -+ boring "crypto/internal/backend" - "crypto/rand" - "crypto/x509/pkix" - "encoding/asn1" -@@ -37,6 +38,8 @@ type verifyTest struct { - - errorCallback func(*testing.T, error) - expectedChains [][]string -+ -+ boringSkip bool - } - - var verifyTests = []verifyTest{ -@@ -143,6 +146,7 @@ var verifyTests = []verifyTest{ - // The StartCom root is not trusted by Windows when the default - // ServerAuth EKU is requested. - systemSkip: true, -+ boringSkip: true, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -155,6 +159,7 @@ var verifyTests = []verifyTest{ - roots: []string{startComRoot}, - currentTime: 1302726541, - keyUsages: []ExtKeyUsage{ExtKeyUsageAny}, -+ boringSkip: true, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -167,6 +172,7 @@ var verifyTests = []verifyTest{ - roots: []string{startComRoot}, - currentTime: 1302726541, - systemSkip: true, // see dnssec-exp test -+ boringSkip: true, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -228,6 +234,7 @@ var verifyTests = []verifyTest{ - roots: []string{globalSignRoot}, - currentTime: 1382387896, - dnsName: "secure.iddl.vt.edu", -+ boringSkip: true, - - expectedChains: [][]string{ - { -@@ -557,6 +564,9 @@ func TestGoVerify(t *testing.T) { - - for _, test := range verifyTests { - t.Run(test.name, func(t *testing.T) { -+ if test.boringSkip && boring.Enabled() { -+ t.Skip("skipping test with BoringCrypto") -+ } - testVerify(t, test, false) - }) - } diff --git a/patches/011-122-fixes.patch b/patches/011-122-fixes.patch deleted file mode 100644 index 2910b475e2..0000000000 --- a/patches/011-122-fixes.patch +++ /dev/null @@ -1,71 +0,0 @@ -diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go -index 3f88fbb3b8..dbd6e6600c 100644 ---- a/src/crypto/tls/boring_test.go -+++ b/src/crypto/tls/boring_test.go -@@ -75,7 +75,9 @@ func isBoringCipherSuite(id uint16) bool { - 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: -+ TLS_RSA_WITH_AES_256_GCM_SHA384, -+ TLS_AES_128_GCM_SHA256, -+ TLS_AES_256_GCM_SHA384, - return true - } - return false -@@ -351,7 +354,6 @@ func TestBoringCertAlgs(t *testing.T) { - - L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK) - -- - // Older versions of OpenSSL allow 1024 bit leaf certs - var L2_I *boringCertificate - if boringtest.Supports(t, "RSA1024LeafCert") { -@@ -513,7 +515,7 @@ func TestBoringCertAlgs(t *testing.T) { - const ( - boringCertCA = iota - boringCertLeaf -- boringCertFIPSOK = 0x80 -+ boringCertFIPSOK = 0x80 - boringCertNotBoring = 0x100 - ) - -@@ -525,7 +527,6 @@ func NotBoringRSAKey(t *testing.T, size int) *rsa.PrivateKey { - return k - } - -- - func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey { - k, err := rsa.GenerateKey(rand.Reader, size) - if err != nil { -diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go -index 2f59f6888c..a84cede1b0 100644 ---- a/src/crypto/tls/handshake_client_tls13.go -+++ b/src/crypto/tls/handshake_client_tls13.go -@@ -41,10 +41,10 @@ type clientHandshakeStateTLS13 struct { - func (hs *clientHandshakeStateTLS13) handshake() error { - c := hs.c - -- if needFIPS() { -+ if needFIPS() && !boring.SupportsHKDF() { - 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_tls13.go b/src/crypto/tls/handshake_server_tls13.go -index 21d798de37..816ca10858 100644 ---- a/src/crypto/tls/handshake_server_tls13.go -+++ b/src/crypto/tls/handshake_server_tls13.go -@@ -45,10 +45,6 @@ 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 diff --git a/patches/012-fixes.patch b/patches/012-fixes.patch deleted file mode 100644 index 0483736426..0000000000 --- a/patches/012-fixes.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go -index 3db1e94fff..0e38bbfbef 100644 ---- a/src/crypto/rsa/pkcs1v15_test.go -+++ b/src/crypto/rsa/pkcs1v15_test.go -@@ -246,6 +246,9 @@ func TestVerifyPKCS1v15(t *testing.T) { - } - - func TestOverlongMessagePKCS1v15(t *testing.T) { -+ if boring.Enabled() { -+ t.Skip("skipping test in boring mode") -+ } - ciphertext := decodeBase64("fjOVdirUzFoLlukv80dBllMLjXythIf22feqPrNo0YoIjzyzyoMFiLjAc/Y4krkeZ11XFThIrEvw\nkRiZcCq5ng==") - _, err := DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext) - if err == nil { -@@ -318,7 +321,6 @@ func parsePublicKey(s string) *PublicKey { - return k - } - -- - var boringRsaPrivateKey = parseKey(testingKey(`-----BEGIN RSA TESTING KEY----- - MIIEogIBAAKCAQEAp5qgUIj096pw8U+AjcJucLWenR3oe+tEthXiAuqcYgslW5UU - lMim34U/h7NbLvbG2KJ2chUsmLtuCFaoIe/YKW5DKm3SPytK/KCBsVa+MQ7zuF/1 diff --git a/patches/013-fixes.patch b/patches/013-fixes.patch deleted file mode 100644 index 4721911e34..0000000000 --- a/patches/013-fixes.patch +++ /dev/null @@ -1,66 +0,0 @@ -diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go -index 66252067f2..5be6dcea23 100644 ---- a/src/crypto/tls/boring.go -+++ b/src/crypto/tls/boring.go -@@ -22,2 +22,6 @@ func needFIPS() bool { - return fipstls.Required() - } -+func supportsHKDF() bool { -+ return boring.SupportsHKDF() -+} -+ -diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go -index 8943422ae0..10a4bc296c 100644 ---- a/src/crypto/tls/boring_test.go -+++ b/src/crypto/tls/boring_test.go -@@ -77,7 +77,7 @@ func isBoringCipherSuite(id uint16) bool { - TLS_RSA_WITH_AES_128_GCM_SHA256, - TLS_RSA_WITH_AES_256_GCM_SHA384, - TLS_AES_128_GCM_SHA256, -- TLS_AES_256_GCM_SHA384, -+ TLS_AES_256_GCM_SHA384: - return true - } - return false -diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go -index f016e01b4b..0ecdd6c1cc 100644 ---- a/src/crypto/tls/handshake_client.go -+++ b/src/crypto/tls/handshake_client.go -@@ -139,7 +141,9 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) { - if len(hello.supportedVersions) == 1 { - hello.cipherSuites = nil - } -- if hasAESGCMHardwareSupport { -+ if needFIPS() { -+ hello.cipherSuites = append(hello.cipherSuites, defaultFIPSCipherSuitesTLS13...) -+ } else 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 fb79939f56..e2c2e8842e 100644 ---- a/src/crypto/tls/handshake_client_tls13.go -+++ b/src/crypto/tls/handshake_client_tls13.go -@@ -41,7 +41,7 @@ type clientHandshakeStateTLS13 struct { - func (hs *clientHandshakeStateTLS13) handshake() error { - c := hs.c - -- if needFIPS() && !boring.SupportsHKDF() { -+ if needFIPS() && !supportsHKDF() { - return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode") - } - -diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go -index 816ca10858..90256aa27c 100644 ---- a/src/crypto/tls/handshake_server_tls13.go -+++ b/src/crypto/tls/handshake_server_tls13.go -@@ -159,6 +161,9 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error { - if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { - preferenceList = defaultCipherSuitesTLS13NoAES - } -+ if needFIPS() { -+ preferenceList = defaultFIPSCipherSuitesTLS13 -+ } - for _, suiteID := range preferenceList { - hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID) - if hs.suite != nil { diff --git a/patches/014-fix-RHEL-34924.patch b/patches/014-fix-RHEL-34924.patch deleted file mode 100644 index 6629f7e15d..0000000000 --- a/patches/014-fix-RHEL-34924.patch +++ /dev/null @@ -1,7 +0,0 @@ -diff --git a/src/crypto/tls/notboring.go b/src/crypto/tls/notboring.go -index fe2719485b..06bc933b0a 100644 ---- a/src/crypto/tls/notboring.go -+++ b/src/crypto/tls/notboring.go -@@ -16,1 +16,2 @@ func fipsMinVersion(c *Config) uint16 { panic("fipsMinVersion") } - func needFIPS() bool { return false } -+func supportsHKDF() bool { panic("supportsHKDF") } diff --git a/patches/015-add-hash-sign-verify.patch b/patches/015-add-hash-sign-verify.patch deleted file mode 100644 index a8c1a72fbb..0000000000 --- a/patches/015-add-hash-sign-verify.patch +++ /dev/null @@ -1,175 +0,0 @@ -diff --git a/src/crypto/ecdsa/ecdsa_hash_sign_verify.go b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go -new file mode 100644 -index 0000000000..977b21958f ---- /dev/null -+++ b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go -@@ -0,0 +1,96 @@ -+package ecdsa -+ -+import ( -+ "crypto" -+ "crypto/internal/randutil" -+ "errors" -+ "io" -+ "math/big" -+ -+ boring "crypto/internal/backend" -+ -+ "golang.org/x/crypto/cryptobyte" -+ "golang.org/x/crypto/cryptobyte/asn1" -+) -+ -+func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) (*big.Int, *big.Int, error) { -+ randutil.MaybeReadByte(rand) -+ -+ if boring.Enabled() { -+ sig, err := HashSignASN1(rand, priv, msg, h) -+ if err != nil { -+ return nil, nil, err -+ } -+ r, s := new(big.Int), new(big.Int) -+ var inner cryptobyte.String -+ input := cryptobyte.String(sig) -+ if !input.ReadASN1(&inner, asn1.SEQUENCE) || -+ !input.Empty() || -+ !inner.ReadASN1Integer(r) || -+ !inner.ReadASN1Integer(s) || -+ !inner.Empty() { -+ return nil, nil, errors.New("invalid ASN.1 from HashSignECDSA") -+ } -+ return r, s, nil -+ } -+ boring.UnreachableExceptTests() -+ -+ hash := h.New() -+ hash.Write(msg) -+ d := hash.Sum(nil) -+ -+ return Sign(rand, priv, d) -+} -+ -+func HashSignASN1(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) ([]byte, error) { -+ randutil.MaybeReadByte(rand) -+ -+ if boring.Enabled() { -+ b, err := boringPrivateKey(priv) -+ if err != nil { -+ return nil, err -+ } -+ return boring.HashSignECDSA(b, h, msg) -+ } -+ boring.UnreachableExceptTests() -+ -+ hash := h.New() -+ hash.Write(msg) -+ d := hash.Sum(nil) -+ -+ return SignASN1(rand, priv, d) -+} -+ -+func HashVerify(pub *PublicKey, msg []byte, r, s *big.Int, h crypto.Hash) bool { -+ if boring.Enabled() { -+ sig, err := encodeSignature(r.Bytes(), s.Bytes()) -+ if err != nil { -+ return false -+ } -+ return HashVerifyASN1(pub, h, msg, sig) -+ } -+ boring.UnreachableExceptTests() -+ -+ hash := h.New() -+ hash.Write(msg) -+ d := hash.Sum(nil) -+ -+ return Verify(pub, d, r, s) -+} -+ -+func HashVerifyASN1(pub *PublicKey, h crypto.Hash, msg, sig []byte) bool { -+ if boring.Enabled() { -+ bpk, err := boringPublicKey(pub) -+ if err != nil { -+ return false -+ } -+ return boring.HashVerifyECDSA(bpk, h, msg, sig) -+ } -+ boring.UnreachableExceptTests() -+ -+ hash := h.New() -+ hash.Write(msg) -+ d := hash.Sum(nil) -+ -+ return VerifyASN1(pub, d, sig) -+} -diff --git a/src/crypto/ecdsa/ecdsa_hashsignverify_test.go b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go -new file mode 100644 -index 0000000000..b73b03e975 ---- /dev/null -+++ b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go -@@ -0,0 +1,43 @@ -+package ecdsa -+ -+import ( -+ "crypto" -+ "crypto/elliptic" -+ boring "crypto/internal/backend" -+ "crypto/rand" -+ "testing" -+) -+ -+func testHashSignAndHashVerify(t *testing.T, c elliptic.Curve, tag string) { -+ priv, err := GenerateKey(c, rand.Reader) -+ if priv == nil { -+ t.Fatal(err) -+ } -+ -+ msg := []byte("testing") -+ h := crypto.SHA256 -+ hsm, err := HashSignASN1(rand.Reader, priv, msg, h) -+ if err != nil { -+ t.Errorf("%s: error signing: %s", tag, err) -+ return -+ } -+ -+ if !HashVerifyASN1(&priv.PublicKey, h, msg, hsm) { -+ t.Errorf("%s: Verify failed", tag) -+ } -+ -+ msg[0] ^= 0xff -+ if HashVerifyASN1(&priv.PublicKey, h, msg, hsm) { -+ t.Errorf("%s: Verify should not have succeeded", tag) -+ } -+} -+ -+func TestHashSignAndHashVerifyASN1(t *testing.T) { -+ testHashSignAndHashVerify(t, elliptic.P256(), "p256") -+ -+ if testing.Short() && !boring.Enabled() { -+ return -+ } -+ testHashSignAndHashVerify(t, elliptic.P384(), "p384") -+ testHashSignAndHashVerify(t, elliptic.P521(), "p521") -+} -diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go -index 5b0e356dff..e509805288 100644 ---- a/src/crypto/internal/backend/nobackend.go -+++ b/src/crypto/internal/backend/nobackend.go -@@ -14,7 +14,6 @@ import ( - "crypto/internal/boring/sig" - "hash" - "io" -- "math/big" - ) - - func init() { -@@ -167,9 +166,9 @@ func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, er - func SupportsHKDF() bool { - panic("boringcrypto: not available") - } --func HashVerifyECDSA(pub *PublicKeyECDSA, msg []byte, r, s *big.Int, h crypto.Hash) bool { -+func HashVerifyECDSA(pub *PublicKeyECDSA, h crypto.Hash, msg, sig []byte) bool { - panic("boringcrypto: not available") - } --func HashSignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (*big.Int, *big.Int, error) { -+func HashSignECDSA(priv *PrivateKeyECDSA, h crypto.Hash, msg []byte) ([]byte, error) { - panic("boringcrypto: not available") - } diff --git a/patches/017-fix-linkage.patch b/patches/017-fix-linkage.patch deleted file mode 100644 index 8138923ee7..0000000000 --- a/patches/017-fix-linkage.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go -index 32e59b446a..b55f29298b 100644 ---- a/src/cmd/dist/build.go -+++ b/src/cmd/dist/build.go -@@ -1309,7 +1309,9 @@ func toolenv() []string { - // we disable cgo to get static binaries for cmd/go and cmd/pprof, - // so that they work on systems without the same dynamic libraries - // as the original build system. -- env = append(env, "CGO_ENABLED=0") -+ // -+ // Setting CGO_ENABLED to 0 prevents cmd/go and the like from linking with vendored openssl symbols. -+ // env = append(env, "CGO_ENABLED=0") - } - if isRelease || os.Getenv("GO_BUILDER_NAME") != "" { - // Add -trimpath for reproducible builds of releases. diff --git a/patches/018-fix-std-crypto.patch b/patches/018-fix-std-crypto.patch deleted file mode 100644 index cf7595c21f..0000000000 --- a/patches/018-fix-std-crypto.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -index 3d3a9a36ee..b7a65a1f6e 100644 ---- a/src/crypto/internal/backend/openssl.go -+++ b/src/crypto/internal/backend/openssl.go -@@ -25,6 +25,21 @@ var enabled bool - var knownVersions = [...]string{"3", "1.1", "11", "111", "1.0.2", "1.0.0", "10"} - - func init() { -+ // 0: FIPS opt-out: abort the process if it is enabled and can't be disabled. -+ // 1: FIPS required: abort the process if it is not enabled and can't be enabled. -+ // other values: do not override OpenSSL configured FIPS mode. -+ var fips string -+ if v, ok := syscall.Getenv("GOLANG_FIPS"); ok { -+ fips = v -+ } else if hostFIPSModeEnabled() { -+ // System configuration can only force FIPS mode. -+ fips = "1" -+ } -+ -+ if fips != "1" { -+ return -+ } -+ - version, _ := syscall.Getenv("GO_OPENSSL_VERSION_OVERRIDE") - if version == "" { - var fallbackVersion string -@@ -49,16 +64,6 @@ func init() { - if err := openssl.Init(version); err != nil { - panic("opensslcrypto: can't initialize OpenSSL " + version + ": " + err.Error()) - } -- // 0: FIPS opt-out: abort the process if it is enabled and can't be disabled. -- // 1: FIPS required: abort the process if it is not enabled and can't be enabled. -- // other values: do not override OpenSSL configured FIPS mode. -- var fips string -- if v, ok := syscall.Getenv("GOLANG_FIPS"); ok { -- fips = v -- } else if hostFIPSModeEnabled() { -- // System configuration can only force FIPS mode. -- fips = "1" -- } - switch fips { - case "0": - if openssl.FIPS() { diff --git a/patches/019-fix-vendor-test.patch b/patches/019-fix-vendor-test.patch deleted file mode 100644 index 535db2bd2b..0000000000 --- a/patches/019-fix-vendor-test.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/src/go/build/vendor_test.go b/src/go/build/vendor_test.go -index 7f6237ffd5..fe552e5326 100644 ---- a/src/go/build/vendor_test.go -+++ b/src/go/build/vendor_test.go -@@ -22,6 +22,7 @@ var allowedPackagePrefixes = []string{ - "github.com/google/pprof", - "github.com/ianlancetaylor/demangle", - "rsc.io/markdown", -+ "github.com/golang-fips/openssl/v2", - } - - // Verify that the vendor directories contain only packages matching the list above. diff --git a/patches/020-fix-boring-tls.patch b/patches/020-fix-boring-tls.patch deleted file mode 100644 index 65c2e54507..0000000000 --- a/patches/020-fix-boring-tls.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go -index 6734dfe354..90d66bafcf 100644 ---- a/src/crypto/tls/boring_test.go -+++ b/src/crypto/tls/boring_test.go -@@ -36,6 +36,12 @@ func TestBoringServerProtocolVersion(t *testing.T) { - clientConfig := testConfig.Clone() - clientConfig.MinVersion = v - clientConfig.MaxVersion = v -+ if boring.Enabled() { -+ serverConfig.Certificates = []Certificate{{Certificate: [][]byte{testP256Certificate}, PrivateKey: testP256PrivateKey}} -+ serverConfig.CurvePreferences = defaultCurvePreferencesFIPS -+ clientConfig.Certificates = []Certificate{{Certificate: [][]byte{testP256Certificate}, PrivateKey: testP256PrivateKey}} -+ clientConfig.CurvePreferences = defaultCurvePreferencesFIPS -+ } - _, _, err := testHandshake(t, clientConfig, serverConfig) - if msg == "" { - if err != nil { -@@ -52,11 +58,13 @@ func TestBoringServerProtocolVersion(t *testing.T) { - }) - } - -- test(t, "VersionTLS10", VersionTLS10, "") -- test(t, "VersionTLS11", VersionTLS11, "") -- test(t, "VersionTLS12", VersionTLS12, "") -+ if !boring.Enabled() { -+ test(t, "VersionTLS10", VersionTLS10, "") -+ test(t, "VersionTLS11", VersionTLS11, "") -+ test(t, "VersionTLS12", VersionTLS12, "") -+ } - if boring.Enabled() && !boring.SupportsHKDF() { -- test(t, "VersionTLS13", VersionTLS13, "client offered only unsupported versions") -+ test(t, "VersionTLS13", VersionTLS13, "supported versions") - } else { - test(t, "VersionTLS13", VersionTLS13, "") - } -@@ -67,9 +75,9 @@ func TestBoringServerProtocolVersion(t *testing.T) { - test(t, "VersionTLS10", VersionTLS10, "supported versions") - test(t, "VersionTLS11", VersionTLS11, "supported versions") - test(t, "VersionTLS12", VersionTLS12, "") -- if boring.SupportsHKDF() { -- test(t, "VersionTLS13/fipstls", VersionTLS13, "") -- } -+ if boring.SupportsHKDF() { -+ test(t, "VersionTLS13/fipstls", VersionTLS13, "") -+ } - }) - } - -diff --git a/src/crypto/tls/defaults.go b/src/crypto/tls/defaults.go -index 9b28acdc2d..1733060948 100644 ---- a/src/crypto/tls/defaults.go -+++ b/src/crypto/tls/defaults.go -@@ -92,6 +92,7 @@ var defaultCipherSuitesTLS13NoAES = []uint16{ - - var defaultSupportedVersionsFIPS = []uint16{ - VersionTLS12, -+ VersionTLS13, - } - - // defaultCurvePreferencesFIPS are the FIPS-allowed curves, -diff --git a/src/crypto/tls/defaults.go b/src/crypto/tls/defaults.go -index 1733060948..82b462261c 100644 ---- a/src/crypto/tls/defaults.go -+++ b/src/crypto/tls/defaults.go -@@ -8,11 +8,18 @@ import ( - "internal/godebug" - "slices" - _ "unsafe" // for linkname -+ boring "crypto/internal/backend" - ) - - // Defaults are collected in this file to allow distributions to more easily patch - // them to apply local policies. - -+func init() { -+ if boring.Enabled() && supportsHKDF() { -+ defaultSupportedVersionsFIPS = append(defaultSupportedVersionsFIPS, VersionTLS13) -+ } -+} -+ - var tlskyber = godebug.New("tlskyber") - - func defaultCurvePreferences() []CurveID { -@@ -92,7 +99,6 @@ var defaultCipherSuitesTLS13NoAES = []uint16{ - - var defaultSupportedVersionsFIPS = []uint16{ - VersionTLS12, -- VersionTLS13, - } - - // defaultCurvePreferencesFIPS are the FIPS-allowed curves, diff --git a/patches/021-fix-index-error.patch b/patches/021-fix-index-error.patch deleted file mode 100644 index d32cc025f9..0000000000 --- a/patches/021-fix-index-error.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go -index e4ef45b882..9e2549847a 100644 ---- a/src/crypto/tls/handshake_client.go -+++ b/src/crypto/tls/handshake_client.go -@@ -149,7 +149,11 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, *keySharePrivateKeys, *echCon - hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...) - } - -- curveID := config.curvePreferences(maxVersion)[0] -+ curvePreferences := config.curvePreferences(maxVersion) -+ if len(curvePreferences) == 0 { -+ return nil, nil, nil, errors.New("tls: No allowed curves configured") -+ } -+ curveID := curvePreferences[0] - keyShareKeys = &keySharePrivateKeys{curveID: curveID} - if curveID == x25519Kyber768Draft00 { - keyShareKeys.ecdhe, err = generateECDHEKey(config.rand(), X25519) diff --git a/patches/022-openssl-negative-tests.patch b/patches/022-openssl-negative-tests.patch deleted file mode 100644 index a021292e28..0000000000 --- a/patches/022-openssl-negative-tests.patch +++ /dev/null @@ -1,1125 +0,0 @@ -diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go -index 06957f8c14..7803ae997f 100644 ---- a/src/crypto/ecdsa/ecdsa_test.go -+++ b/src/crypto/ecdsa/ecdsa_test.go -@@ -9,8 +9,8 @@ import ( - "bytes" - "compress/bzip2" - "crypto/elliptic" -- "crypto/internal/backend/boringtest" - boring "crypto/internal/backend" -+ "crypto/internal/backend/boringtest" - "crypto/internal/bigmod" - "crypto/rand" - "crypto/sha1" -@@ -46,9 +46,6 @@ func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) { - tests = append(tests, p224) - } - for _, test := range tests { -- if boring.Enabled() && !boringtest.Supports(t, "Curve"+test.name) { -- t.Skip("unsupported test in FIPS mode") -- } - curve := test.curve - t.Run(test.name, func(t *testing.T) { - t.Parallel() -diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go -index 1b99c68577..3e98ba3717 100644 ---- a/src/crypto/hmac/hmac.go -+++ b/src/crypto/hmac/hmac.go -@@ -132,6 +132,7 @@ func New(h func() hash.Hash, key []byte) hash.Hash { - if hm != nil { - return hm - } -+ panic("unrecognized hmac in FIPS mode") - // BoringCrypto did not recognize h, so fall through to standard Go code. - } - hm := new(hmac) -diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go -index 3898f7f12c..e412a29269 100644 ---- a/src/crypto/hmac/hmac_test.go -+++ b/src/crypto/hmac/hmac_test.go -@@ -13,6 +13,7 @@ import ( - "crypto/sha512" - "fmt" - "hash" -+ "strings" - "testing" - ) - -@@ -549,6 +550,16 @@ var hmacTests = []hmacTest{ - - func TestHMAC(t *testing.T) { - for i, tt := range hmacTests { -+ if boring.Enabled() && tt.size == sha1.New().Size() { -+ defer func() { -+ r := recover() -+ if s, ok := r.(string); ok { -+ if !strings.Contains(s, "unrecognized hmac in FIPS mode") { -+ panic(s) -+ } -+ } -+ }() -+ } - h := New(tt.hash, tt.key) - if s := h.Size(); s != tt.size { - t.Errorf("Size: got %v, want %v", s, tt.size) -@@ -623,6 +634,9 @@ func TestEqual(t *testing.T) { - - func TestHMACHash(t *testing.T) { - for i, test := range hmacTests { -+ if boring.Enabled() && test.size == sha1.New().Size() { -+ t.Skip("skipping test, negative assertion (failure mode) covered by TestHMAC") -+ } - baseHash := test.hash - key := test.key - -diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go -index 0e38bbfbef..a03aa1cb62 100644 ---- a/src/crypto/rsa/pkcs1v15_test.go -+++ b/src/crypto/rsa/pkcs1v15_test.go -@@ -17,6 +17,7 @@ import ( - "encoding/hex" - "encoding/pem" - "io" -+ "strings" - "testing" - "testing/quick" - ) -@@ -55,10 +56,6 @@ var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{ - } - - func TestDecryptPKCS1v15(t *testing.T) { -- if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -- t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -- } -- - decryptionFuncs := []func([]byte) ([]byte, error){ - func(ciphertext []byte) (plaintext []byte, err error) { - return DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext) -@@ -72,7 +69,14 @@ func TestDecryptPKCS1v15(t *testing.T) { - for i, test := range decryptPKCS1v15Tests { - out, err := decryptFunc(decodeBase64(test.in)) - if err != nil { -- t.Errorf("#%d error decrypting: %v", i, err) -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -+ if !strings.Contains(err.Error(), "decryption error") { -+ t.Fatalf("unexpected error in FIPS mode: %s", err.Error()) -+ } -+ continue -+ } else { -+ t.Errorf("#%d error decrypting: %v", i, err) -+ } - } - want := []byte(test.out) - if !bytes.Equal(out, want) { -@@ -83,10 +87,6 @@ func TestDecryptPKCS1v15(t *testing.T) { - } - - func TestEncryptPKCS1v15(t *testing.T) { -- if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -- t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -- } -- - random := rand.Reader - k := (rsaPrivateKey.N.BitLen() + 7) / 8 - -@@ -97,6 +97,11 @@ func TestEncryptPKCS1v15(t *testing.T) { - - ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in) - if err != nil { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -+ if strings.Contains(err.Error(), "invalid key length") { -+ return false -+ } -+ } - t.Errorf("error encrypting: %s", err) - return false - } -@@ -148,15 +153,16 @@ var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{ - } - - func TestEncryptPKCS1v15SessionKey(t *testing.T) { -- if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -- t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -- } -- - for i, test := range decryptPKCS1v15SessionKeyTests { - key := []byte("FAIL") - err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, decodeBase64(test.in), key) - if err != nil { -- t.Errorf("#%d error decrypting", i) -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -+ if strings.Contains(err.Error(), "invalid key length") { -+ continue -+ } -+ } -+ t.Errorf("#%d error decrypting: %#v", i, err) - } - want := []byte(test.out) - if !bytes.Equal(key, want) { -@@ -166,13 +172,14 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) { - } - - func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) { -- if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -- t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -- } -- - for i, test := range decryptPKCS1v15SessionKeyTests { - plaintext, err := rsaPrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4}) - if err != nil { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -+ if strings.Contains(err.Error(), "invalid key length") { -+ continue -+ } -+ } - t.Fatalf("#%d: error decrypting: %s", i, err) - } - if len(plaintext) != 4 { -@@ -246,9 +253,6 @@ func TestVerifyPKCS1v15(t *testing.T) { - } - - func TestOverlongMessagePKCS1v15(t *testing.T) { -- if boring.Enabled() { -- t.Skip("skipping test in boring mode") -- } - ciphertext := decodeBase64("fjOVdirUzFoLlukv80dBllMLjXythIf22feqPrNo0YoIjzyzyoMFiLjAc/Y4krkeZ11XFThIrEvw\nkRiZcCq5ng==") - _, err := DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext) - if err == nil { -@@ -279,14 +283,15 @@ func TestUnpaddedSignature(t *testing.T) { - } - - func TestShortSessionKey(t *testing.T) { -- if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -- t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") -- } -- - // This tests that attempting to decrypt a session key where the - // ciphertext is too small doesn't run outside the array bounds. - ciphertext, err := EncryptPKCS1v15(rand.Reader, &rsaPrivateKey.PublicKey, []byte{1}) - if err != nil { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -+ if strings.Contains(err.Error(), "invalid key length") { -+ return -+ } -+ } - t.Fatalf("Failed to encrypt short message: %s", err) - } - -diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go -index 42298618e4..3e24cd2b1d 100644 ---- a/src/crypto/rsa/pss_test.go -+++ b/src/crypto/rsa/pss_test.go -@@ -79,9 +79,6 @@ func TestEMSAPSS(t *testing.T) { - // TestPSSGolden tests all the test vectors in pss-vect.txt from - // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip - func TestPSSGolden(t *testing.T) { -- if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -- t.Skip("skipping PSS test with BoringCrypto: SHA-1 not allowed") -- } - inFile, err := os.Open("testdata/pss-vect.txt.bz2") - if err != nil { - t.Fatalf("Failed to open input file: %s", err) -@@ -162,6 +159,11 @@ func TestPSSGolden(t *testing.T) { - hashed = h.Sum(hashed[:0]) - - if err := VerifyPSS(key, hash, hashed, sig, opts); err != nil { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -+ if strings.Contains(err.Error(), "verification error") { -+ continue -+ } -+ } - t.Error(err) - } - default: -@@ -173,10 +175,6 @@ func TestPSSGolden(t *testing.T) { - // TestPSSOpenSSL ensures that we can verify a PSS signature from OpenSSL with - // the default options. OpenSSL sets the salt length to be maximal. - func TestPSSOpenSSL(t *testing.T) { -- if boring.Enabled() { -- t.Skip("skipping PSS test with BoringCrypto: too short key") -- } -- - hash := crypto.SHA256 - h := hash.New() - h.Write([]byte("testing")) -@@ -194,7 +192,11 @@ func TestPSSOpenSSL(t *testing.T) { - } - - if err := VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, nil); err != nil { -- t.Error(err) -+ if !boring.Enabled() { -+ t.Error(err) -+ } -+ } else if boring.Enabled() { -+ t.Error("expected error but received none") - } - } - -@@ -209,10 +211,6 @@ func TestPSSNilOpts(t *testing.T) { - } - - func TestPSSSigning(t *testing.T) { -- if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -- t.Skip("skipping PSS test with BoringCrypto: too short key") -- } -- - var saltLengthCombinations = []struct { - signSaltLength, verifySaltLength int - good bool -@@ -238,6 +236,12 @@ func TestPSSSigning(t *testing.T) { - opts.SaltLength = test.signSaltLength - sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts) - if err != nil { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -+ if strings.Contains(err.Error(), "invalid key length") { -+ continue -+ } -+ } -+ - t.Errorf("#%d: error while signing: %s", i, err) - continue - } -diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go -index ab4607b4a7..d160dccd43 100644 ---- a/src/crypto/rsa/rsa_test.go -+++ b/src/crypto/rsa/rsa_test.go -@@ -9,6 +9,7 @@ import ( - "bytes" - "crypto" - boring "crypto/internal/backend" -+ "crypto/internal/backend/boringtest" - "crypto/rand" - . "crypto/rsa" - "crypto/sha1" -@@ -17,14 +18,13 @@ import ( - "encoding/pem" - "flag" - "fmt" -- "internal/testenv" - "math/big" - "strings" - "testing" -+ -+ "internal/testenv" - ) - --import "crypto/internal/backend/boringtest" -- - func TestKeyGeneration(t *testing.T) { - testKeys := []int{128, 1024} - if boring.Enabled() { -@@ -92,9 +92,6 @@ func Test4PrimeKeyGeneration(t *testing.T) { - } - - func TestNPrimeKeyGeneration(t *testing.T) { -- if boring.Enabled() { -- t.Skip("Not supported in boring mode") -- } - primeSize := 64 - maxN := 24 - if testing.Short() { -@@ -144,19 +141,16 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { - } - - if boring.Enabled() { -- // Cannot call encrypt/decrypt with raw RSA. PKCSv1.5 -- // not supported in some configurations. Test with -- // OAEP if possible (i.e., key size is equal to or -- // longer than 2048 bits). -- if bits := priv.N.BitLen(); boring.Enabled() && bits < 2048 { -- t.Logf("skipping short key with BoringCrypto: %d", bits) -- return -- } - sha256 := sha256.New() - - msg := []byte("hi!") - enc, err := EncryptOAEP(sha256, rand.Reader, &priv.PublicKey, msg, nil) - if err != nil { -+ if bits := priv.N.BitLen(); bits < 2048 { -+ if strings.Contains(err.Error(), "invalid key length") || strings.Contains(err.Error(), "message too long for RSA key size") { -+ return -+ } -+ } - t.Errorf("EncryptOAEP: %v", err) - return - } -@@ -236,9 +233,6 @@ func TestEverything(t *testing.T) { - if bits := priv.N.BitLen(); bits != size { - t.Errorf("key too short (%d vs %d)", bits, size) - } -- if boring.Enabled() && size < 2048 { -- t.Skip("skipping short key with BoringCrypto") -- } - testEverything(t, priv) - }) - } -@@ -254,7 +248,11 @@ func testEverything(t *testing.T, priv *PrivateKey) { - if err == ErrMessageTooLong { - t.Log("key too small for EncryptPKCS1v15") - } else if err != nil { -- t.Errorf("EncryptPKCS1v15: %v", err) -+ if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") || strings.Contains(err.Error(), "EVP_PKEY_encrypt_init failed") { -+ t.Log("invalid key length in FIPS mode, ignoring...") -+ } else { -+ t.Errorf("EncryptPKCS1v15: %v", err) -+ } - } - if err == nil { - dec, err := DecryptPKCS1v15(nil, priv, enc) -@@ -275,7 +273,11 @@ func testEverything(t *testing.T, priv *PrivateKey) { - if err == ErrMessageTooLong { - t.Log("key too small for EncryptOAEP") - } else if err != nil { -- t.Errorf("EncryptOAEP: %v", err) -+ if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") || strings.Contains(err.Error(), "EVP_PKEY_encrypt_init failed") { -+ t.Log("invalid key length in FIPS mode, ignoring...") -+ } else { -+ t.Errorf("EncryptOAEP: %v", err) -+ } - } - if err == nil { - dec, err := DecryptOAEP(sha256.New(), nil, priv, enc, label) -@@ -292,7 +294,12 @@ func testEverything(t *testing.T, priv *PrivateKey) { - if err == ErrMessageTooLong { - t.Log("key too small for SignPKCS1v15") - } else if err != nil { -- t.Errorf("SignPKCS1v15: %v", err) -+ if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") || -+ strings.Contains(err.Error(), "EVP_PKEY_sign_init failed") { -+ t.Log("invalid key length in FIPS mode, ignoring...") -+ } else { -+ t.Errorf("SignPKCS1v15: %v", err) -+ } - } - if err == nil { - err = VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, hash[:], sig) -@@ -318,7 +325,13 @@ func testEverything(t *testing.T, priv *PrivateKey) { - if err == ErrMessageTooLong { - t.Log("key too small for SignPSS with PSSSaltLengthAuto") - } else if err != nil { -- t.Errorf("SignPSS: %v", err) -+ if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") || -+ strings.Contains(err.Error(), "EVP_PKEY_encrypt_init failed") || -+ strings.Contains(err.Error(), "EVP_PKEY_sign_init failed") { -+ t.Log("invalid key length in FIPS mode, ignoring...") -+ } else { -+ t.Errorf("SignPSS: %v", err) -+ } - } - if err == nil { - err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts) -@@ -344,7 +357,12 @@ func testEverything(t *testing.T, priv *PrivateKey) { - if err == ErrMessageTooLong { - t.Log("key too small for SignPSS with PSSSaltLengthEqualsHash") - } else if err != nil { -- t.Errorf("SignPSS: %v", err) -+ if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") || -+ strings.Contains(err.Error(), "EVP_PKEY_sign_init failed") { -+ t.Log("invalid key length in FIPS mode, ignoring...") -+ } else { -+ t.Errorf("SignPSS: %v", err) -+ } - } - if err == nil { - err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts) -@@ -774,13 +792,12 @@ func Test2DecryptOAEP(t *testing.T) { - sha1 := crypto.SHA1 - sha256 := crypto.SHA256 - -- if boring.Enabled() && n.BitLen() < 2048 { -- t.Skipf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) -- } -- - out, err := priv.Decrypt(random, in, &OAEPOptions{MGFHash: sha1, Hash: sha256}) - - if err != nil { -+ if boring.Enabled() && n.BitLen() < 2048 && strings.Contains(err.Error(), "decryption error") { -+ return -+ } - t.Errorf("error: %s", err) - } else if !bytes.Equal(out, msg) { - t.Errorf("bad result %#v (want %#v)", out, msg) -@@ -793,10 +810,6 @@ func TestEncryptDecryptOAEP(t *testing.T) { - d := new(big.Int) - for i, test := range testEncryptOAEPData { - n.SetString(test.modulus, 16) -- if boring.Enabled() && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { -- t.Logf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) -- continue -- } - d.SetString(test.d, 16) - priv := new(PrivateKey) - priv.PublicKey = PublicKey{N: n, E: test.e} -@@ -806,6 +819,14 @@ func TestEncryptDecryptOAEP(t *testing.T) { - label := []byte(fmt.Sprintf("hi#%d", j)) - enc, err := EncryptOAEP(sha256, rand.Reader, &priv.PublicKey, message.in, label) - if err != nil { -+ if boring.Enabled() && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { -+ // t.Logf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) -+ // continue -+ if strings.Contains(err.Error(), "invalid key length") { -+ // This is an expected failure -+ continue -+ } -+ } - t.Errorf("#%d,%d: EncryptOAEP: %v", i, j, err) - continue - } -@@ -824,22 +845,26 @@ func TestEncryptDecryptOAEP(t *testing.T) { - // testEncryptOAEPData contains a subset of the vectors from RSA's "Test vectors for RSA-OAEP". - var testEncryptOAEPData = []testEncryptOAEPStruct{ - // Key 1 -- {"a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb", -+ { -+ "a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb", - 65537, - "53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1", - []testEncryptOAEPMessage{ - // Example 1.1 - { -- []byte{0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, -+ []byte{ -+ 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, - 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23, 0x97, - 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, - 0xfe, 0x34, - }, -- []byte{0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, -+ []byte{ -+ 0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, - 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1, 0xdd, - 0xa0, 0xa5, 0xef, - }, -- []byte{0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, -+ []byte{ -+ 0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, - 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f, 0x7b, - 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, - 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb, 0x21, 0x69, 0x6d, -@@ -858,16 +883,19 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ - }, - // Example 1.2 - { -- []byte{0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, -+ []byte{ -+ 0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, - 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9, 0xba, - 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, - 0x9d, 0xd5, - }, -- []byte{0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, -+ []byte{ -+ 0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, - 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25, 0xfe, - 0x4f, 0xe3, 0x5f, - }, -- []byte{0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, -+ []byte{ -+ 0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, - 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf, 0xf8, - 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, - 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11, 0x65, 0x98, 0x8d, -@@ -886,7 +914,8 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ - }, - // Example 1.3 - { -- []byte{0xd9, 0x4a, 0xe0, 0x83, 0x2e, 0x64, 0x45, 0xce, -+ []byte{ -+ 0xd9, 0x4a, 0xe0, 0x83, 0x2e, 0x64, 0x45, 0xce, - 0x42, 0x33, 0x1c, 0xb0, 0x6d, 0x53, 0x1a, 0x82, 0xb1, - 0xdb, 0x4b, 0xaa, 0xd3, 0x0f, 0x74, 0x6d, 0xc9, 0x16, - 0xdf, 0x24, 0xd4, 0xe3, 0xc2, 0x45, 0x1f, 0xff, 0x59, -@@ -894,11 +923,13 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ - 0x46, 0xcf, 0x69, 0x9d, 0xfd, 0x81, 0x8c, 0x6e, 0x97, - 0xb0, 0x51, - }, -- []byte{0x25, 0x14, 0xdf, 0x46, 0x95, 0x75, 0x5a, 0x67, -+ []byte{ -+ 0x25, 0x14, 0xdf, 0x46, 0x95, 0x75, 0x5a, 0x67, - 0xb2, 0x88, 0xea, 0xf4, 0x90, 0x5c, 0x36, 0xee, 0xc6, - 0x6f, 0xd2, 0xfd, - }, -- []byte{0x42, 0x37, 0x36, 0xed, 0x03, 0x5f, 0x60, 0x26, -+ []byte{ -+ 0x42, 0x37, 0x36, 0xed, 0x03, 0x5f, 0x60, 0x26, - 0xaf, 0x27, 0x6c, 0x35, 0xc0, 0xb3, 0x74, 0x1b, 0x36, - 0x5e, 0x5f, 0x76, 0xca, 0x09, 0x1b, 0x4e, 0x8c, 0x29, - 0xe2, 0xf0, 0xbe, 0xfe, 0xe6, 0x03, 0x59, 0x5a, 0xa8, -@@ -918,22 +949,26 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ - }, - }, - // Key 10 -- {"ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb", -+ { -+ "ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb", - 65537, - "056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e79", - []testEncryptOAEPMessage{ - // Example 10.1 - { -- []byte{0x8b, 0xba, 0x6b, 0xf8, 0x2a, 0x6c, 0x0f, 0x86, -+ []byte{ -+ 0x8b, 0xba, 0x6b, 0xf8, 0x2a, 0x6c, 0x0f, 0x86, - 0xd5, 0xf1, 0x75, 0x6e, 0x97, 0x95, 0x68, 0x70, 0xb0, - 0x89, 0x53, 0xb0, 0x6b, 0x4e, 0xb2, 0x05, 0xbc, 0x16, - 0x94, 0xee, - }, -- []byte{0x47, 0xe1, 0xab, 0x71, 0x19, 0xfe, 0xe5, 0x6c, -+ []byte{ -+ 0x47, 0xe1, 0xab, 0x71, 0x19, 0xfe, 0xe5, 0x6c, - 0x95, 0xee, 0x5e, 0xaa, 0xd8, 0x6f, 0x40, 0xd0, 0xaa, - 0x63, 0xbd, 0x33, - }, -- []byte{0x53, 0xea, 0x5d, 0xc0, 0x8c, 0xd2, 0x60, 0xfb, -+ []byte{ -+ 0x53, 0xea, 0x5d, 0xc0, 0x8c, 0xd2, 0x60, 0xfb, - 0x3b, 0x85, 0x85, 0x67, 0x28, 0x7f, 0xa9, 0x15, 0x52, - 0xc3, 0x0b, 0x2f, 0xeb, 0xfb, 0xa2, 0x13, 0xf0, 0xae, - 0x87, 0x70, 0x2d, 0x06, 0x8d, 0x19, 0xba, 0xb0, 0x7f, -diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go -index 210bd9bc43..780814d126 100644 ---- a/src/crypto/x509/verify_test.go -+++ b/src/crypto/x509/verify_test.go -@@ -15,7 +15,6 @@ import ( - "encoding/pem" - "errors" - "fmt" -- "internal/testenv" - "math/big" - "os/exec" - "reflect" -@@ -25,6 +24,8 @@ import ( - "strings" - "testing" - "time" -+ -+ "internal/testenv" - ) - - type verifyTest struct { -@@ -40,8 +41,6 @@ type verifyTest struct { - - errorCallback func(*testing.T, error) - expectedChains [][]string -- -- boringSkip bool - } - - var verifyTests = []verifyTest{ -@@ -148,7 +147,16 @@ var verifyTests = []verifyTest{ - // The StartCom root is not trusted by Windows when the default - // ServerAuth EKU is requested. - systemSkip: true, -- boringSkip: true, -+ errorCallback: func(t *testing.T, err error) { -+ if boring.Enabled() { -+ if err == nil { -+ t.Fatal("expected an error to be returned in boring mode") -+ } -+ if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -+ t.Fatalf("unexpected error returned: %s", err.Error()) -+ } -+ } -+ }, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -161,7 +169,16 @@ var verifyTests = []verifyTest{ - roots: []string{startComRoot}, - currentTime: 1302726541, - keyUsages: []ExtKeyUsage{ExtKeyUsageAny}, -- boringSkip: true, -+ errorCallback: func(t *testing.T, err error) { -+ if boring.Enabled() { -+ if err == nil { -+ t.Fatal("expected an error to be returned in boring mode") -+ } -+ if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -+ t.Fatalf("unexpected error returned: %s", err.Error()) -+ } -+ } -+ }, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -174,7 +191,16 @@ var verifyTests = []verifyTest{ - roots: []string{startComRoot}, - currentTime: 1302726541, - systemSkip: true, // see dnssec-exp test -- boringSkip: true, -+ errorCallback: func(t *testing.T, err error) { -+ if boring.Enabled() { -+ if err == nil { -+ t.Fatal("expected an error to be returned in boring mode") -+ } -+ if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -+ t.Fatalf("unexpected error returned: %s", err.Error()) -+ } -+ } -+ }, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -236,7 +262,16 @@ var verifyTests = []verifyTest{ - roots: []string{globalSignRoot}, - currentTime: 1382387896, - dnsName: "secure.iddl.vt.edu", -- boringSkip: true, -+ errorCallback: func(t *testing.T, err error) { -+ if boring.Enabled() { -+ if err == nil { -+ t.Fatal("expected an error to be returned in boring mode") -+ } -+ if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -+ t.Fatalf("unexpected error returned: %s", err.Error()) -+ } -+ } -+ }, - - expectedChains: [][]string{ - { -@@ -566,8 +601,8 @@ func TestGoVerify(t *testing.T) { - - for _, test := range verifyTests { - t.Run(test.name, func(t *testing.T) { -- if test.boringSkip && boring.Enabled() { -- t.Skip("skipping test with BoringCrypto") -+ if boring.Enabled() && test.errorCallback != nil { -+ test.expectedChains = nil - } - testVerify(t, test, false) - }) -@@ -1595,6 +1630,7 @@ jP5cBaVl50t4qoCuVIE9cOucnxYXnI7X5HpXWvu8Pfxo4SwVjb1az8Fk5s8ZnxGe - fPB6Q3L/pKBe0SEe5GywpwtokPLB3lAygcuHbxp/1FlQ1NQZqq+vgXRIla26bNJf - IuYkJwt6w+LH/9HZgf8= - -----END CERTIFICATE-----` -+ - const selfSignedNoCommonNameWithOrgName = `-----BEGIN CERTIFICATE----- - MIIC+zCCAeOgAwIBAgIBADANBgkqhkiG9w0BAQsFADAaMQswCQYDVQQKEwJjYTEL - MAkGA1UEAxMCY2EwHhcNMTYwODI4MTgxMzQ4WhcNMjEwODI3MTgxMzQ4WjANMQsw -@@ -1613,6 +1649,7 @@ rD8cNkHf74v98KvBhcwBlDifVzmkWzMG6TL1EkRXUyLKiWgoTUFSkCDV927oXXMR - DKnszq+AVw+K8hbeV2A7GqT7YfeqOAvSbatTDnDtKOPmlCnQui8A149VgZzXv7eU - 29ssJSqjUPyp58dlV6ZuynxPho1QVZUOQgnJToXIQ3/5vIvJRXy52GJCs4/Gh/w= - -----END CERTIFICATE-----` -+ - const selfSignedNoCommonNameNoOrgName = `-----BEGIN CERTIFICATE----- - MIIC7jCCAdagAwIBAgIBADANBgkqhkiG9w0BAQsFADAaMQswCQYDVQQKEwJjYTEL - MAkGA1UEAxMCY2EwHhcNMTYwODI4MTgxOTQ1WhcNMjEwODI3MTgxOTQ1WjAAMIIB -@@ -1872,7 +1909,7 @@ func TestSystemRootsError(t *testing.T) { - } - - func TestSystemRootsErrorUnwrap(t *testing.T) { -- var err1 = errors.New("err1") -+ err1 := errors.New("err1") - err := SystemRootsError{Err: err1} - if !errors.Is(err, err1) { - t.Error("errors.Is failed, wanted success") -@@ -2628,21 +2665,21 @@ func TestEKUEnforcement(t *testing.T) { - { - name: "valid, full chain", - root: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, -- inters: []ekuDescs{ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}}, -+ inters: []ekuDescs{{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}}, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}, - }, - { - name: "valid, only leaf has EKU", - root: ekuDescs{}, -- inters: []ekuDescs{ekuDescs{}}, -+ inters: []ekuDescs{{}}, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}, - }, - { - name: "invalid, serverAuth not nested", - root: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageClientAuth}}, -- inters: []ekuDescs{ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}}, -+ inters: []ekuDescs{{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}}, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}, - err: "x509: certificate specifies an incompatible key usage", -@@ -2650,7 +2687,7 @@ func TestEKUEnforcement(t *testing.T) { - { - name: "valid, two EKUs, one path", - root: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, -- inters: []ekuDescs{ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}}, -+ inters: []ekuDescs{{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}}, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}, - }, -@@ -2658,10 +2695,10 @@ func TestEKUEnforcement(t *testing.T) { - name: "invalid, ladder", - root: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - inters: []ekuDescs{ -- ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}, -- ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageClientAuth}}, -- ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}, -- ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, -+ {EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}, -+ {EKUs: []ExtKeyUsage{ExtKeyUsageClientAuth}}, -+ {EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}}, -+ {EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - }, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}, -@@ -2670,14 +2707,14 @@ func TestEKUEnforcement(t *testing.T) { - { - name: "valid, intermediate has no EKU", - root: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, -- inters: []ekuDescs{ekuDescs{}}, -+ inters: []ekuDescs{{}}, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}, - }, - { - name: "invalid, intermediate has no EKU and no nested path", - root: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageClientAuth}}, -- inters: []ekuDescs{ekuDescs{}}, -+ inters: []ekuDescs{{}}, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth}, - err: "x509: certificate specifies an incompatible key usage", -@@ -2685,7 +2722,7 @@ func TestEKUEnforcement(t *testing.T) { - { - name: "invalid, intermediate has unknown EKU", - root: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, -- inters: []ekuDescs{ekuDescs{Unknown: []asn1.ObjectIdentifier{{1, 2, 3}}}}, -+ inters: []ekuDescs{{Unknown: []asn1.ObjectIdentifier{{1, 2, 3}}}}, - leaf: ekuDescs{EKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}}, - verifyEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}, - err: "x509: certificate specifies an incompatible key usage", -@@ -2800,7 +2837,6 @@ func TestVerifyEKURootAsLeaf(t *testing.T) { - } - }) - } -- - } - - func TestVerifyNilPubKey(t *testing.T) { -diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go -index d160dccd43..284995adf6 100644 ---- a/src/crypto/rsa/rsa_test.go -+++ b/src/crypto/rsa/rsa_test.go -@@ -104,6 +104,11 @@ func TestNPrimeKeyGeneration(t *testing.T) { - if err == nil { - testKeyBasics(t, priv) - } else { -+ if boring.Enabled() { -+ if strings.Contains(err.Error(), "invalid primes or bits for boring") { -+ continue -+ } -+ } - t.Errorf("failed to generate %d-prime key", n) - } - } -diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go -index 780814d126..b16184f32a 100644 ---- a/src/crypto/x509/verify_test.go -+++ b/src/crypto/x509/verify_test.go -@@ -9,6 +9,7 @@ import ( - "crypto/ecdsa" - "crypto/elliptic" - boring "crypto/internal/backend" -+ "crypto/internal/backend/boringtest" - "crypto/rand" - "crypto/x509/pkix" - "encoding/asn1" -@@ -170,7 +171,7 @@ var verifyTests = []verifyTest{ - currentTime: 1302726541, - keyUsages: []ExtKeyUsage{ExtKeyUsageAny}, - errorCallback: func(t *testing.T, err error) { -- if boring.Enabled() { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { - if err == nil { - t.Fatal("expected an error to be returned in boring mode") - } -diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go -index a03aa1cb62..8af84825a2 100644 ---- a/src/crypto/rsa/pkcs1v15_test.go -+++ b/src/crypto/rsa/pkcs1v15_test.go -@@ -255,7 +255,7 @@ func TestVerifyPKCS1v15(t *testing.T) { - func TestOverlongMessagePKCS1v15(t *testing.T) { - ciphertext := decodeBase64("fjOVdirUzFoLlukv80dBllMLjXythIf22feqPrNo0YoIjzyzyoMFiLjAc/Y4krkeZ11XFThIrEvw\nkRiZcCq5ng==") - _, err := DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext) -- if err == nil { -+ if err == nil && !boringtest.Supports(t, "PKCSv1.5") { - t.Error("RSA decrypted a message that was too long.") - } - } -diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go -index 3e24cd2b1d..c7efa8cea1 100644 ---- a/src/crypto/rsa/pss_test.go -+++ b/src/crypto/rsa/pss_test.go -@@ -195,7 +195,7 @@ func TestPSSOpenSSL(t *testing.T) { - if !boring.Enabled() { - t.Error(err) - } -- } else if boring.Enabled() { -+ } else if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { - t.Error("expected error but received none") - } - } -@@ -211,7 +211,7 @@ func TestPSSNilOpts(t *testing.T) { - } - - func TestPSSSigning(t *testing.T) { -- var saltLengthCombinations = []struct { -+ saltLengthCombinations := []struct { - signSaltLength, verifySaltLength int - good bool - }{ -diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go -index 284995adf6..4f7d8a0a71 100644 ---- a/src/crypto/rsa/rsa_test.go -+++ b/src/crypto/rsa/rsa_test.go -@@ -332,6 +332,8 @@ func testEverything(t *testing.T, priv *PrivateKey) { - } else if err != nil { - if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") || - strings.Contains(err.Error(), "EVP_PKEY_encrypt_init failed") || -+ strings.Contains(err.Error(), "data too large for key size") || -+ strings.Contains(err.Error(), "EVP_PKEY_sign failed") || - strings.Contains(err.Error(), "EVP_PKEY_sign_init failed") { - t.Log("invalid key length in FIPS mode, ignoring...") - } else { -@@ -363,6 +365,8 @@ func testEverything(t *testing.T, priv *PrivateKey) { - t.Log("key too small for SignPSS with PSSSaltLengthEqualsHash") - } else if err != nil { - if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") || -+ strings.Contains(err.Error(), "data too large for key size") || -+ strings.Contains(err.Error(), "EVP_PKEY_sign failed") || - strings.Contains(err.Error(), "EVP_PKEY_sign_init failed") { - t.Log("invalid key length in FIPS mode, ignoring...") - } else { -diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go -index b16184f32a..578d114f63 100644 ---- a/src/crypto/x509/verify_test.go -+++ b/src/crypto/x509/verify_test.go -@@ -147,17 +147,8 @@ var verifyTests = []verifyTest{ - - // The StartCom root is not trusted by Windows when the default - // ServerAuth EKU is requested. -- systemSkip: true, -- errorCallback: func(t *testing.T, err error) { -- if boring.Enabled() { -- if err == nil { -- t.Fatal("expected an error to be returned in boring mode") -- } -- if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -- t.Fatalf("unexpected error returned: %s", err.Error()) -- } -- } -- }, -+ systemSkip: true, -+ errorCallback: expectBoringError, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -170,16 +161,7 @@ var verifyTests = []verifyTest{ - roots: []string{startComRoot}, - currentTime: 1302726541, - keyUsages: []ExtKeyUsage{ExtKeyUsageAny}, -- errorCallback: func(t *testing.T, err error) { -- if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -- if err == nil { -- t.Fatal("expected an error to be returned in boring mode") -- } -- if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -- t.Fatalf("unexpected error returned: %s", err.Error()) -- } -- } -- }, -+ errorCallback: expectBoringError, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -192,16 +174,7 @@ var verifyTests = []verifyTest{ - roots: []string{startComRoot}, - currentTime: 1302726541, - systemSkip: true, // see dnssec-exp test -- errorCallback: func(t *testing.T, err error) { -- if boring.Enabled() { -- if err == nil { -- t.Fatal("expected an error to be returned in boring mode") -- } -- if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -- t.Fatalf("unexpected error returned: %s", err.Error()) -- } -- } -- }, -+ errorCallback: expectBoringError, - - expectedChains: [][]string{ - {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, -@@ -263,16 +236,7 @@ var verifyTests = []verifyTest{ - roots: []string{globalSignRoot}, - currentTime: 1382387896, - dnsName: "secure.iddl.vt.edu", -- errorCallback: func(t *testing.T, err error) { -- if boring.Enabled() { -- if err == nil { -- t.Fatal("expected an error to be returned in boring mode") -- } -- if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -- t.Fatalf("unexpected error returned: %s", err.Error()) -- } -- } -- }, -+ errorCallback: expectBoringError, - - expectedChains: [][]string{ - { -@@ -428,6 +392,17 @@ var verifyTests = []verifyTest{ - }, - } - -+func expectBoringError(t *testing.T, err error) { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -+ if err == nil { -+ t.Fatal("expected an error to be returned in boring mode") -+ } -+ if !strings.Contains(err.Error(), "certificate signed by unknown authority") { -+ t.Fatalf("unexpected error returned: %s", err.Error()) -+ } -+ } -+} -+ - func expectHostnameError(msg string) func(*testing.T, error) { - return func(t *testing.T, err error) { - if _, ok := err.(HostnameError); !ok { -@@ -602,7 +578,7 @@ func TestGoVerify(t *testing.T) { - - for _, test := range verifyTests { - t.Run(test.name, func(t *testing.T) { -- if boring.Enabled() && test.errorCallback != nil { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") && test.errorCallback != nil { - test.expectedChains = nil - } - testVerify(t, test, false) -diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go -index e412a29269..015f47fda0 100644 ---- a/src/crypto/hmac/hmac_test.go -+++ b/src/crypto/hmac/hmac_test.go -@@ -6,6 +6,7 @@ package hmac - - import ( - boring "crypto/internal/backend" -+ "crypto/internal/backend/boringtest" - "crypto/internal/cryptotest" - "crypto/md5" - "crypto/sha1" -@@ -549,17 +550,21 @@ var hmacTests = []hmacTest{ - } - - func TestHMAC(t *testing.T) { -- for i, tt := range hmacTests { -- if boring.Enabled() && tt.size == sha1.New().Size() { -- defer func() { -- r := recover() -- if s, ok := r.(string); ok { -+ var hsh hash.Hash -+ if boring.Enabled() { -+ defer func() { -+ r := recover() -+ if s, ok := r.(string); ok { -+ if (hsh == sha1.New() && !boringtest.Supports(t, "SHA1")) || hsh == md5.New() { - if !strings.Contains(s, "unrecognized hmac in FIPS mode") { - panic(s) - } - } -- }() -- } -+ } -+ }() -+ } -+ for i, tt := range hmacTests { -+ hsh = tt.hash() - h := New(tt.hash, tt.key) - if s := h.Size(); s != tt.size { - t.Errorf("Size: got %v, want %v", s, tt.size) -@@ -587,7 +592,7 @@ func TestHMAC(t *testing.T) { - - // Third and fourth iteration: make sure hmac works on - // hashes without MarshalBinary/UnmarshalBinary -- if j == 1 { -+ if j == 1 && !boring.Enabled() { // Skip in boring mode as the hash is obscured and won't be recognized. - h = New(func() hash.Hash { return justHash{tt.hash()} }, tt.key) - } - } -diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go -index 8af84825a2..840ddfd604 100644 ---- a/src/crypto/rsa/pkcs1v15_test.go -+++ b/src/crypto/rsa/pkcs1v15_test.go -@@ -97,7 +97,7 @@ func TestEncryptPKCS1v15(t *testing.T) { - - ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in) - if err != nil { -- if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") && rsaPrivateKey.Size() < 256 { - if strings.Contains(err.Error(), "invalid key length") { - return false - } -diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go -index c7efa8cea1..feae2663f6 100644 ---- a/src/crypto/rsa/pss_test.go -+++ b/src/crypto/rsa/pss_test.go -@@ -236,7 +236,7 @@ func TestPSSSigning(t *testing.T) { - opts.SaltLength = test.signSaltLength - sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts) - if err != nil { -- if boring.Enabled() && !boringtest.Supports(t, "SHA1") { -+ if boring.Enabled() && hash == crypto.SHA1 && !boringtest.Supports(t, "SHA1") { - if strings.Contains(err.Error(), "invalid key length") { - continue - } -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/evp.go b/src/vendor/github.com/golang-fips/openssl/v2/evp.go -index a9237a6a0c..19df5a1adb 100644 ---- a/src/vendor/github.com/golang-fips/openssl/v2/evp.go -+++ b/src/vendor/github.com/golang-fips/openssl/v2/evp.go -@@ -142,14 +145,17 @@ func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error - return pkey, nil - } - --type withKeyFunc func(func(C.GO_EVP_PKEY_PTR) C.int) C.int --type initFunc func(C.GO_EVP_PKEY_CTX_PTR) error --type cryptFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, *C.size_t, *C.uchar, C.size_t) error --type verifyFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, C.size_t, *C.uchar, C.size_t) error -+type ( -+ withKeyFunc func(func(C.GO_EVP_PKEY_PTR) C.int) C.int -+ initFunc func(C.GO_EVP_PKEY_CTX_PTR) error -+ cryptFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, *C.size_t, *C.uchar, C.size_t) error -+ verifyFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, C.size_t, *C.uchar, C.size_t) error -+) - - func setupEVP(withKey withKeyFunc, padding C.int, - h, mgfHash hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, -- init initFunc) (_ C.GO_EVP_PKEY_CTX_PTR, err error) { -+ init initFunc, -+) (_ C.GO_EVP_PKEY_CTX_PTR, err error) { - var ctx C.GO_EVP_PKEY_CTX_PTR - withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { - ctx = C.go_openssl_EVP_PKEY_CTX_new(pkey, nil) -@@ -272,8 +278,8 @@ func setupEVP(withKey withKeyFunc, padding C.int, - - func cryptEVP(withKey withKeyFunc, padding C.int, - h, mgfHash hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, -- init initFunc, crypt cryptFunc, in []byte) ([]byte, error) { -- -+ init initFunc, crypt cryptFunc, in []byte, -+) ([]byte, error) { - ctx, err := setupEVP(withKey, padding, h, mgfHash, label, saltLen, ch, init) - if err != nil { - return nil, err -@@ -295,8 +301,8 @@ func cryptEVP(withKey withKeyFunc, padding C.int, - func verifyEVP(withKey withKeyFunc, padding C.int, - h hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, - init initFunc, verify verifyFunc, -- sig, in []byte) error { -- -+ sig, in []byte, -+) error { - ctx, err := setupEVP(withKey, padding, h, nil, label, saltLen, ch, init) - if err != nil { - return err - diff --git a/patches/001-initial-openssl-for-fips.patch b/patches/fips.patch similarity index 70% rename from patches/001-initial-openssl-for-fips.patch rename to patches/fips.patch index 90ba240967..034b557083 100644 --- a/patches/001-initial-openssl-for-fips.patch +++ b/patches/fips.patch @@ -1,3 +1,9 @@ +commit 2134a7a6e0854a3bc997b5f1514ff926f597d247 +Author: Derek Parker +Date: Wed Apr 30 11:51:39 2025 -0700 + + fips.patch + diff --git a/src/cmd/api/boring_test.go b/src/cmd/api/boring_test.go index f0e3575637..a4139169b8 100644 --- a/src/cmd/api/boring_test.go @@ -19,20 +25,38 @@ index f0e3575637..a4139169b8 100644 + fmt.Printf("SKIP with !no_openssl enabled\n") os.Exit(0) } -diff --git a/src/crypto/aes/cipher.go b/src/crypto/aes/cipher.go -index cde2e45d2c..f7d5fe30d4 100644 ---- a/src/crypto/aes/cipher.go -+++ b/src/crypto/aes/cipher.go -@@ -7,7 +7,7 @@ package aes +diff --git a/src/cmd/go/testdata/script/gopath_std_vendor.txt b/src/cmd/go/testdata/script/gopath_std_vendor.txt +index 4aaf46b5d0..c231e299d9 100644 +--- a/src/cmd/go/testdata/script/gopath_std_vendor.txt ++++ b/src/cmd/go/testdata/script/gopath_std_vendor.txt +@@ -21,11 +21,11 @@ go build . + + go list -deps -f '{{.ImportPath}} {{.Dir}}' . + stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +-! stdout $GOROOT[/\\]src[/\\]vendor ++! stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack + + go list -test -deps -f '{{.ImportPath}} {{.Dir}}' . + stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +-! stdout $GOROOT[/\\]src[/\\]vendor ++! stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack + + -- issue16333/issue16333.go -- + package vendoring17 +diff --git a/src/crypto/aes/aes.go b/src/crypto/aes/aes.go +index 5bc2d13d67..0d9cd59772 100644 +--- a/src/crypto/aes/aes.go ++++ b/src/crypto/aes/aes.go +@@ -15,7 +15,7 @@ package aes + import ( "crypto/cipher" - "crypto/internal/alias" - "crypto/internal/boring" + boring "crypto/internal/backend" + "crypto/internal/fips140/aes" "strconv" ) - -@@ -39,7 +39,7 @@ func NewCipher(key []byte) (cipher.Block, error) { +@@ -41,7 +41,7 @@ func NewCipher(key []byte) (cipher.Block, error) { case 16, 24, 32: break } @@ -40,20 +64,7 @@ index cde2e45d2c..f7d5fe30d4 100644 + if boring.Enabled() { return boring.NewAESCipher(key) } - return newCipher(key) -diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go -index 3e5f589c2c..e9d3c0be11 100644 ---- a/src/crypto/aes/cipher_asm.go -+++ b/src/crypto/aes/cipher_asm.go -@@ -9,7 +9,7 @@ package aes - import ( - "crypto/cipher" - "crypto/internal/alias" -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "internal/cpu" - "internal/goarch" - ) + return aes.New(key) diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go index 097c37e343..47618fe3c6 100644 --- a/src/crypto/boring/boring.go @@ -117,8 +128,52 @@ index 0701628464..0000000000 -func TestNotBoring(t *testing.T) { - t.Error("goexperiment.boringcrypto and boringcrypto should be equivalent build tags") -} +diff --git a/src/crypto/cipher/ctr_aes_test.go b/src/crypto/cipher/ctr_aes_test.go +index 3394246778..c5d59f85ef 100644 +--- a/src/crypto/cipher/ctr_aes_test.go ++++ b/src/crypto/cipher/ctr_aes_test.go +@@ -14,7 +14,7 @@ import ( + "bytes" + "crypto/aes" + "crypto/cipher" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/cryptotest" + fipsaes "crypto/internal/fips140/aes" + "encoding/hex" +@@ -251,7 +251,7 @@ func TestCTR_AES_multiblock_overflow_IV(t *testing.T) { + + // Check that method XORKeyStreamAt works correctly. + func TestCTR_AES_multiblock_XORKeyStreamAt(t *testing.T) { +- if boring.Enabled { ++ if boring.Enabled() { + t.Skip("XORKeyStreamAt is not available in boring mode") + } + +diff --git a/src/crypto/cipher/gcm_test.go b/src/crypto/cipher/gcm_test.go +index ea2b4e29e2..6544a60fd6 100644 +--- a/src/crypto/cipher/gcm_test.go ++++ b/src/crypto/cipher/gcm_test.go +@@ -8,7 +8,7 @@ import ( + "bytes" + "crypto/aes" + "crypto/cipher" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/cryptotest" + "crypto/internal/fips140" + fipsaes "crypto/internal/fips140/aes" +@@ -727,7 +727,7 @@ func testGCMAEAD(t *testing.T, newCipher func(key []byte) cipher.Block) { + + // Test NewGCMWithRandomNonce. + t.Run("GCMWithRandomNonce", func(t *testing.T) { +- if _, ok := block.(*wrapper); ok || boring.Enabled { ++ if _, ok := block.(*wrapper); ok || boring.Enabled() { + t.Skip("NewGCMWithRandomNonce requires an AES block cipher") + } + cryptotest.TestAEAD(t, func() (cipher.AEAD, error) { return cipher.NewGCMWithRandomNonce(block) }) diff --git a/src/crypto/ecdh/ecdh.go b/src/crypto/ecdh/ecdh.go -index b7c26f91e5..0e6680fd04 100644 +index 231f1ea04c..cfa113e234 100644 --- a/src/crypto/ecdh/ecdh.go +++ b/src/crypto/ecdh/ecdh.go @@ -8,7 +8,7 @@ package ecdh @@ -127,32 +182,102 @@ index b7c26f91e5..0e6680fd04 100644 "crypto" - "crypto/internal/boring" + boring "crypto/internal/backend" + "crypto/internal/fips140/ecdh" "crypto/subtle" "errors" - "io" -@@ -167,7 +167,7 @@ func (k *PrivateKey) PublicKey() *PublicKey { - // (We can't return it anyhow.) - kpub, err := k.boring.PublicKey() - if err != nil { -- panic("boringcrypto: " + err.Error()) -+ panic("!no_openssl: " + err.Error()) - } - k.publicKey = &PublicKey{ - curve: k.curve, diff --git a/src/crypto/ecdh/ecdh_test.go b/src/crypto/ecdh/ecdh_test.go -index 60e76abadc..e0ea15465b 100644 +index 75d2480775..7255a69a18 100644 --- a/src/crypto/ecdh/ecdh_test.go +++ b/src/crypto/ecdh/ecdh_test.go -@@ -9,7 +9,7 @@ import ( +@@ -9,6 +9,7 @@ import ( "crypto" "crypto/cipher" "crypto/ecdh" -- "crypto/internal/boring" + boring "crypto/internal/backend" "crypto/rand" "crypto/sha256" "encoding/hex" -@@ -288,8 +288,8 @@ func TestNewPrivateKey(t *testing.T) { +@@ -37,6 +38,9 @@ var _ interface { + + func TestECDH(t *testing.T) { + testAllCurves(t, func(t *testing.T, curve ecdh.Curve) { ++ if boring.Enabled() && curve == ecdh.X25519() { ++ t.Skip("curve unsupported in FIPS mode, negative test included elsewhere") ++ } + aliceKey, err := curve.GenerateKey(rand.Reader) + if err != nil { + t.Fatal(err) +@@ -96,18 +100,29 @@ func (r *countingReader) Read(p []byte) (int, error) { + + func TestGenerateKey(t *testing.T) { + testAllCurves(t, func(t *testing.T, curve ecdh.Curve) { +- r := &countingReader{r: rand.Reader} ++ rand := rand.Reader ++ var r io.Reader = &countingReader{r: rand} ++ if boring.Enabled() { ++ rand = boring.RandReader ++ r = rand ++ } + k, err := curve.GenerateKey(r) + if err != nil { ++ if boring.Enabled() && curve == ecdh.X25519() && strings.Contains(err.Error(), "crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") { ++ t.Skip("expected error in FIPS mode") ++ } + t.Fatal(err) + } ++ if boring.Enabled() { ++ return // the rest of the assertion does not apply in boring mode ++ } + + // GenerateKey does rejection sampling. If the masking works correctly, + // the probability of a rejection is 1-ord(G)/2^ceil(log2(ord(G))), + // which for all curves is small enough (at most 2^-32, for P-256) that + // a bit flip is more likely to make this test fail than bad luck. + // Account for the extra MaybeReadByte byte, too. +- if got, expected := r.n, len(k.Bytes())+1; got > expected { ++ if got, expected := r.(*countingReader).n, len(k.Bytes())+1; got > expected { + t.Errorf("expected GenerateKey to consume at most %v bytes, got %v", expected, got) + } + }) +@@ -160,6 +175,9 @@ func TestVectors(t *testing.T) { + v := vectors[curve] + key, err := curve.NewPrivateKey(hexDecode(t, v.PrivateKey)) + if err != nil { ++ if boring.Enabled() && curve == ecdh.X25519() && strings.Contains(err.Error(), "crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") { ++ t.Skip("error expected in FIPS mode") ++ } + t.Fatal(err) + } + if !bytes.Equal(key.PublicKey().Bytes(), hexDecode(t, v.PublicKey)) { +@@ -208,6 +226,9 @@ func TestX25519Failure(t *testing.T) { + } + + func testX25519Failure(t *testing.T, private, public []byte) { ++ if boring.Enabled() { ++ t.Skip("X25519 not supported in FIPS mode") ++ } + priv, err := ecdh.X25519().NewPrivateKey(private) + if err != nil { + t.Fatal(err) +@@ -280,15 +301,26 @@ var invalidPrivateKeys = map[ecdh.Curve][]string{ + } + + func TestNewPrivateKey(t *testing.T) { ++ // Skip on RHEL 8 ++ if b, err := os.ReadFile("/etc/os-release"); err == nil { ++ if strings.Contains(string(b), "Red Hat Enterprise Linux 8") { ++ t.Skip("skipping on RHEL 8") ++ } ++ } ++ + testAllCurves(t, func(t *testing.T, curve ecdh.Curve) { + for _, input := range invalidPrivateKeys[curve] { + k, err := curve.NewPrivateKey(hexDecode(t, input)) + if err == nil { ++ if boring.Enabled() && (input == "01" || strings.Contains(input, "0101")) { ++ t.Skip("these keys are accepted by openssl") ++ continue ++ } t.Errorf("unexpectedly accepted %q", input) } else if k != nil { t.Error("PrivateKey was not nil on error") @@ -163,7 +288,7 @@ index 60e76abadc..e0ea15465b 100644 } } }) -@@ -349,8 +349,8 @@ func TestNewPublicKey(t *testing.T) { +@@ -348,8 +380,8 @@ func TestNewPublicKey(t *testing.T) { t.Errorf("unexpectedly accepted %q", input) } else if k != nil { t.Error("PublicKey was not nil on error") @@ -174,56 +299,128 @@ index 60e76abadc..e0ea15465b 100644 } } }) -@@ -441,7 +441,7 @@ func main() { +@@ -441,6 +473,7 @@ func main() { // implementations into the binary. This also guarantees that govulncheck can // avoid warning about a curve-specific vulnerability if that curve is not used. func TestLinker(t *testing.T) { -- if boring.Enabled { -+ if boring.Enabled() { - t.Skip("test doesn't make sense when building with external crypto backend") - } ++ t.Skip("skipping test in downstream fork, symbols will be different") if testing.Short() { + t.Skip("test requires running 'go build'") + } +@@ -473,7 +506,7 @@ func TestLinker(t *testing.T) { + // P256, but none for the other curves. + var consistent bool + nm := run(goBin, "tool", "nm", "hello.exe") +- for _, match := range regexp.MustCompile(`(?m)T (crypto/.*)$`).FindAllStringSubmatch(nm, -1) { ++ for _, match := range regexp.MustCompile(`(?m) (crypto/.*)$`).FindAllStringSubmatch(nm, -1) { + symbol := strings.ToLower(match[1]) + if strings.Contains(symbol, "p256") { + consistent = true +@@ -501,16 +534,27 @@ func TestMismatchedCurves(t *testing.T) { + for _, privCurve := range curves { + priv, err := privCurve.curve.GenerateKey(rand.Reader) + if err != nil { ++ if boring.Enabled() && privCurve.name == "X25519" && strings.Contains(err.Error(), "crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") { ++ t.Skip("error expected in FIPS mode") ++ } + t.Fatalf("failed to generate test key: %s", err) + } + ++ rand := rand.Reader ++ if boring.Enabled() { ++ rand = boring.RandReader ++ } ++ + for _, pubCurve := range curves { + if privCurve == pubCurve { + continue + } + t.Run(fmt.Sprintf("%s/%s", privCurve.name, pubCurve.name), func(t *testing.T) { +- pub, err := pubCurve.curve.GenerateKey(rand.Reader) ++ pub, err := pubCurve.curve.GenerateKey(rand) + if err != nil { ++ if boring.Enabled() && pubCurve.name == "X25519" && strings.Contains(err.Error(), "crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") { ++ t.Skip("error expected in FIPS mode") ++ } + t.Fatalf("failed to generate test key: %s", err) + } + expected := "crypto/ecdh: private key and public key curves do not match" diff --git a/src/crypto/ecdh/nist.go b/src/crypto/ecdh/nist.go -index b91e8f38a5..5912dfb234 100644 +index acef829894..ec916f8c60 100644 --- a/src/crypto/ecdh/nist.go +++ b/src/crypto/ecdh/nist.go -@@ -5,7 +5,7 @@ - package ecdh +@@ -6,7 +6,7 @@ package ecdh import ( + "bytes" - "crypto/internal/boring" + boring "crypto/internal/backend" - "crypto/internal/nistec" - "crypto/internal/randutil" + "crypto/internal/fips140/ecdh" + "crypto/internal/fips140only" "errors" -@@ -36,7 +36,7 @@ func (c *nistCurve[Point]) String() string { - var errInvalidPrivateKey = errors.New("crypto/ecdh: invalid private key") +@@ -26,7 +26,10 @@ func (c *nistCurve) String() string { + } - func (c *nistCurve[Point]) GenerateKey(rand io.Reader) (*PrivateKey, error) { + func (c *nistCurve) GenerateKey(rand io.Reader) (*PrivateKey, error) { - if boring.Enabled && rand == boring.RandReader { -+ if boring.Enabled() && rand == boring.RandReader { ++ if boring.Enabled() { ++ if rand != boring.RandReader { ++ return nil, errors.New("crypto/ecdh: invalid random source in FIPS 140-only mode") ++ } key, bytes, err := boring.GenerateKeyECDH(c.name) if err != nil { return nil, err -@@ -79,7 +79,7 @@ func (c *nistCurve[Point]) NewPrivateKey(key []byte) (*PrivateKey, error) { - if isZero(key) || !isLess(key, c.scalarOrder) { - return nil, errInvalidPrivateKey +@@ -43,6 +46,7 @@ func (c *nistCurve) GenerateKey(rand io.Reader) (*PrivateKey, error) { + } + return k, nil + } ++ boring.UnreachableExceptTests() + + if fips140only.Enabled && !fips140only.ApprovedRandomReader(rand) { + return nil, errors.New("crypto/ecdh: only crypto/rand.Reader is allowed in FIPS 140-only mode") +@@ -63,7 +67,7 @@ func (c *nistCurve) GenerateKey(rand io.Reader) (*PrivateKey, error) { + fips: privateKey.PublicKey(), + }, } - if boring.Enabled { + if boring.Enabled() { - bk, err := boring.NewPrivateKeyECDH(c.name, key) + bk, err := boring.NewPrivateKeyECDH(c.name, k.privateKey) if err != nil { return nil, err -@@ -173,7 +173,7 @@ func (c *nistCurve[Point]) NewPublicKey(key []byte) (*PublicKey, error) { +@@ -79,7 +83,7 @@ func (c *nistCurve) GenerateKey(rand io.Reader) (*PrivateKey, error) { + } + + func (c *nistCurve) NewPrivateKey(key []byte) (*PrivateKey, error) { +- if boring.Enabled { ++ if boring.Enabled() { + bk, err := boring.NewPrivateKeyECDH(c.name, key) + if err != nil { + return nil, errors.New("crypto/ecdh: invalid private key") +@@ -96,6 +100,7 @@ func (c *nistCurve) NewPrivateKey(key []byte) (*PrivateKey, error) { + } + return k, nil + } ++ boring.UnreachableExceptTests() + + fk, err := c.newPrivateKey(key) + if err != nil { +@@ -124,13 +129,14 @@ func (c *nistCurve) NewPublicKey(key []byte) (*PublicKey, error) { curve: c, - publicKey: append([]byte{}, key...), + publicKey: bytes.Clone(key), } - if boring.Enabled { + if boring.Enabled() { bk, err := boring.NewPublicKeyECDH(c.name, k.publicKey) + if err != nil { + return nil, errors.New("crypto/ecdh: invalid public key") + } + k.boring = bk + } else { ++ boring.UnreachableExceptTests() + fk, err := c.newPublicKey(key) if err != nil { return nil, err -@@ -196,7 +196,7 @@ func (c *nistCurve[Point]) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, e +@@ -148,9 +154,10 @@ func (c *nistCurve) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) { // only be the result of a scalar multiplication if one of the inputs is the // zero scalar or the point at infinity. @@ -231,7 +428,51 @@ index b91e8f38a5..5912dfb234 100644 + if boring.Enabled() { return boring.ECDH(local.boring, remote.boring) } ++ boring.UnreachableExceptTests() + return c.sharedSecret(local.fips, remote.fips) + } + +diff --git a/src/crypto/ecdh/x25519.go b/src/crypto/ecdh/x25519.go +index 81dca5d3a4..928a32b06d 100644 +--- a/src/crypto/ecdh/x25519.go ++++ b/src/crypto/ecdh/x25519.go +@@ -6,8 +6,8 @@ package ecdh + + import ( + "bytes" ++ boring "crypto/internal/backend" + "crypto/internal/fips140/edwards25519/field" +- "crypto/internal/fips140only" + "crypto/internal/randutil" + "errors" + "io" +@@ -35,7 +35,7 @@ func (c *x25519Curve) String() string { + } + + func (c *x25519Curve) GenerateKey(rand io.Reader) (*PrivateKey, error) { +- if fips140only.Enabled { ++ if boring.Enabled() { + return nil, errors.New("crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") + } + key := make([]byte, x25519PrivateKeySize) +@@ -47,7 +47,7 @@ func (c *x25519Curve) GenerateKey(rand io.Reader) (*PrivateKey, error) { + } + + func (c *x25519Curve) NewPrivateKey(key []byte) (*PrivateKey, error) { +- if fips140only.Enabled { ++ if boring.Enabled() { + return nil, errors.New("crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") + } + if len(key) != x25519PrivateKeySize { +@@ -67,7 +67,7 @@ func (c *x25519Curve) NewPrivateKey(key []byte) (*PrivateKey, error) { + } + func (c *x25519Curve) NewPublicKey(key []byte) (*PublicKey, error) { +- if fips140only.Enabled { ++ if boring.Enabled() { + return nil, errors.New("crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") + } + if len(key) != x25519PublicKeySize { diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go index 275c60b4de..58f0034b18 100644 --- a/src/crypto/ecdsa/boring.go @@ -254,20 +495,20 @@ index 275c60b4de..58f0034b18 100644 "math/big" ) diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go -index 2179b01e8e..5bc6f63025 100644 +index cb308b41e9..998cacf3be 100644 --- a/src/crypto/ecdsa/ecdsa.go +++ b/src/crypto/ecdsa/ecdsa.go -@@ -31,8 +31,8 @@ import ( +@@ -20,8 +20,8 @@ import ( + "crypto" "crypto/ecdh" "crypto/elliptic" - "crypto/internal/bigmod" - "crypto/internal/boring" - "crypto/internal/boring/bbig" + boring "crypto/internal/backend" + "crypto/internal/backend/bbig" - "crypto/internal/nistec" - "crypto/internal/randutil" - "crypto/sha512" + "crypto/internal/fips140/ecdsa" + "crypto/internal/fips140hash" + "crypto/internal/fips140only" @@ -162,7 +162,7 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) { randutil.MaybeReadByte(rand) @@ -277,7 +518,7 @@ index 2179b01e8e..5bc6f63025 100644 x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name) if err != nil { return nil, err -@@ -260,7 +260,7 @@ var errNoAsm = errors.New("no assembly implementation available") +@@ -211,7 +211,7 @@ var errNoAsm = errors.New("no assembly implementation available") func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { randutil.MaybeReadByte(rand) @@ -286,7 +527,7 @@ index 2179b01e8e..5bc6f63025 100644 b, err := boringPrivateKey(priv) if err != nil { return nil, err -@@ -471,7 +471,7 @@ func (zr) Read(dst []byte) (n int, err error) { +@@ -326,7 +326,7 @@ func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) { // The inputs are not considered confidential, and may leak through timing side // channels, or if an attacker has control of part of the inputs. func VerifyASN1(pub *PublicKey, hash, sig []byte) bool { @@ -295,68 +536,165 @@ index 2179b01e8e..5bc6f63025 100644 key, err := boringPublicKey(pub) if err != nil { return false -diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go -index 71082bf503..06957f8c14 100644 ---- a/src/crypto/ecdsa/ecdsa_test.go -+++ b/src/crypto/ecdsa/ecdsa_test.go -@@ -10,7 +10,7 @@ import ( - "compress/bzip2" - "crypto/elliptic" - "crypto/internal/backend/boringtest" -- "crypto/internal/boring" +diff --git a/src/crypto/ecdsa/ecdsa_hash_sign_verify.go b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go +new file mode 100644 +index 0000000000..ac7fed39f0 +--- /dev/null ++++ b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go +@@ -0,0 +1,100 @@ ++// Copyright 2017 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. ++ ++package ecdsa ++ ++import ( ++ "crypto" ++ "crypto/internal/randutil" ++ "errors" ++ "io" ++ "math/big" ++ + boring "crypto/internal/backend" - "crypto/internal/bigmod" - "crypto/rand" - "crypto/sha1" -@@ -38,7 +38,7 @@ func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) { - } - if testing.Short() { - tests = tests[:1] -- } else if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ } else if !boring.Enabled() || boringtest.Supports(t, "CurveP224") { - p224 := struct { - name string - curve elliptic.Curve -@@ -46,7 +46,7 @@ func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) { - tests = append(tests, p224) - } - for _, test := range tests { -- if boring.Enabled && !boringtest.Supports(t, "Curve"+test.name) { -+ if boring.Enabled() && !boringtest.Supports(t, "Curve"+test.name) { - t.Skip("unsupported test in FIPS mode") - } - curve := test.curve -@@ -246,7 +246,7 @@ func TestVectors(t *testing.T) { - - switch curve { - case "P-224": -- if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ if !boring.Enabled() || boringtest.Supports(t, "CurveP224") { - pub.Curve = elliptic.P224() - } else { - pub.Curve = nil -diff --git a/src/crypto/ecdsa/equal_test.go b/src/crypto/ecdsa/equal_test.go -index 4371e31b1a..5ef62abe37 100644 ---- a/src/crypto/ecdsa/equal_test.go -+++ b/src/crypto/ecdsa/equal_test.go -@@ -10,7 +10,7 @@ import ( - "crypto/elliptic" - "crypto/rand" - "crypto/x509" -- "crypto/internal/boring" ++ ++ "golang.org/x/crypto/cryptobyte" ++ "golang.org/x/crypto/cryptobyte/asn1" ++) ++ ++func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) (*big.Int, *big.Int, error) { ++ randutil.MaybeReadByte(rand) ++ ++ if boring.Enabled() { ++ sig, err := HashSignASN1(rand, priv, msg, h) ++ if err != nil { ++ return nil, nil, err ++ } ++ r, s := new(big.Int), new(big.Int) ++ var inner cryptobyte.String ++ input := cryptobyte.String(sig) ++ if !input.ReadASN1(&inner, asn1.SEQUENCE) || ++ !input.Empty() || ++ !inner.ReadASN1Integer(r) || ++ !inner.ReadASN1Integer(s) || ++ !inner.Empty() { ++ return nil, nil, errors.New("invalid ASN.1 from HashSignECDSA") ++ } ++ return r, s, nil ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return Sign(rand, priv, d) ++} ++ ++func HashSignASN1(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) ([]byte, error) { ++ randutil.MaybeReadByte(rand) ++ ++ if boring.Enabled() { ++ b, err := boringPrivateKey(priv) ++ if err != nil { ++ return nil, err ++ } ++ return boring.HashSignECDSA(b, h, msg) ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return SignASN1(rand, priv, d) ++} ++ ++func HashVerify(pub *PublicKey, msg []byte, r, s *big.Int, h crypto.Hash) bool { ++ if boring.Enabled() { ++ sig, err := encodeSignature(r.Bytes(), s.Bytes()) ++ if err != nil { ++ return false ++ } ++ return HashVerifyASN1(pub, h, msg, sig) ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return Verify(pub, d, r, s) ++} ++ ++func HashVerifyASN1(pub *PublicKey, h crypto.Hash, msg, sig []byte) bool { ++ if boring.Enabled() { ++ bpk, err := boringPublicKey(pub) ++ if err != nil { ++ return false ++ } ++ return boring.HashVerifyECDSA(bpk, h, msg, sig) ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return VerifyASN1(pub, d, sig) ++} +diff --git a/src/crypto/ecdsa/ecdsa_hashsignverify_test.go b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go +new file mode 100644 +index 0000000000..fee2a2dd2f +--- /dev/null ++++ b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go +@@ -0,0 +1,47 @@ ++// Copyright 2017 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. ++ ++package ecdsa ++ ++import ( ++ "crypto" ++ "crypto/elliptic" + boring "crypto/internal/backend" - "crypto/internal/backend/boringtest" - "testing" - ) -@@ -71,7 +71,7 @@ func TestEqual(t *testing.T) { - if testing.Short() { - return - } -- if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ if !boring.Enabled() || boringtest.Supports(t, "CurveP224") { - t.Run("P224", func(t *testing.T) { testEqual(t, elliptic.P224()) }) - } - t.Run("P384", func(t *testing.T) { testEqual(t, elliptic.P384()) }) ++ "crypto/rand" ++ "testing" ++) ++ ++func testHashSignAndHashVerify(t *testing.T, c elliptic.Curve, tag string) { ++ priv, err := GenerateKey(c, rand.Reader) ++ if priv == nil { ++ t.Fatal(err) ++ } ++ ++ msg := []byte("testing") ++ h := crypto.SHA256 ++ hsm, err := HashSignASN1(rand.Reader, priv, msg, h) ++ if err != nil { ++ t.Errorf("%s: error signing: %s", tag, err) ++ return ++ } ++ ++ if !HashVerifyASN1(&priv.PublicKey, h, msg, hsm) { ++ t.Errorf("%s: Verify failed", tag) ++ } ++ ++ msg[0] ^= 0xff ++ if HashVerifyASN1(&priv.PublicKey, h, msg, hsm) { ++ t.Errorf("%s: Verify should not have succeeded", tag) ++ } ++} ++ ++func TestHashSignAndHashVerifyASN1(t *testing.T) { ++ testHashSignAndHashVerify(t, elliptic.P256(), "p256") ++ ++ if testing.Short() && !boring.Enabled() { ++ return ++ } ++ testHashSignAndHashVerify(t, elliptic.P384(), "p384") ++ testHashSignAndHashVerify(t, elliptic.P521(), "p521") ++} diff --git a/src/crypto/ecdsa/notboring.go b/src/crypto/ecdsa/notboring.go index 039bd82ed2..21a35b760c 100644 --- a/src/crypto/ecdsa/notboring.go @@ -381,30 +719,30 @@ index 039bd82ed2..21a35b760c 100644 - panic("boringcrypto: not available") + panic("!no_openssl: not available") } -diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go -index 883184fa75..a735212a1e 100644 ---- a/src/crypto/ed25519/ed25519_test.go -+++ b/src/crypto/ed25519/ed25519_test.go -@@ -9,7 +9,7 @@ import ( +diff --git a/src/crypto/hkdf/hkdf_test.go b/src/crypto/hkdf/hkdf_test.go +index 57d90f88e9..39b467799b 100644 +--- a/src/crypto/hkdf/hkdf_test.go ++++ b/src/crypto/hkdf/hkdf_test.go +@@ -6,7 +6,7 @@ package hkdf + + import ( "bytes" - "compress/gzip" - "crypto" - "crypto/internal/boring" + boring "crypto/internal/backend" - "crypto/rand" - "crypto/sha512" - "encoding/hex" -@@ -320,7 +320,7 @@ func TestMalleability(t *testing.T) { + "crypto/internal/fips140" + "crypto/md5" + "crypto/sha1" +@@ -378,7 +378,7 @@ func benchmarkHKDF(hasher func() hash.Hash, block int, b *testing.B) { + } - func TestAllocations(t *testing.T) { - t.Skip("Allocations test broken with openssl linkage") + func TestFIPSServiceIndicator(t *testing.T) { - if boring.Enabled { + if boring.Enabled() { - t.Skip("skipping allocations test with BoringCrypto") + t.Skip("in BoringCrypto mode HMAC is not from the Go FIPS module") } - testenv.SkipIfOptimizationOff(t) + diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go -index 46ec81b8c5..1b99c68577 100644 +index 554c8c9b78..cdf97d8f81 100644 --- a/src/crypto/hmac/hmac.go +++ b/src/crypto/hmac/hmac.go @@ -22,7 +22,7 @@ timing side-channels: @@ -413,10 +751,10 @@ index 46ec81b8c5..1b99c68577 100644 import ( - "crypto/internal/boring" + boring "crypto/internal/backend" - "crypto/subtle" - "hash" - ) -@@ -127,7 +127,7 @@ func (h *hmac) Reset() { + "crypto/internal/fips140/hmac" + "crypto/internal/fips140hash" + "crypto/internal/fips140only" +@@ -37,7 +37,7 @@ import ( // the returned Hash does not implement [encoding.BinaryMarshaler] // or [encoding.BinaryUnmarshaler]. func New(h func() hash.Hash, key []byte) hash.Hash { @@ -449,33 +787,572 @@ index 7accad7632..3898f7f12c 100644 } sha := sha256.New() defer func() { -diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go -deleted file mode 100644 -index 8819f576f4..0000000000 ---- a/src/crypto/internal/boring/aes.go -+++ /dev/null -@@ -1,385 +0,0 @@ --// Copyright 2017 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 && linux && (amd64 || arm64) && !android && !msan -- --package boring -- --/* -- --#include "goboringcrypto.h" -- --// These wrappers allocate out_len on the C stack, and check that it matches the expected --// value, to avoid having to pass a pointer from Go, which would escape to the heap. -- --int EVP_AEAD_CTX_seal_wrapper(const GO_EVP_AEAD_CTX *ctx, uint8_t *out, -- size_t exp_out_len, -- const uint8_t *nonce, size_t nonce_len, -- const uint8_t *in, size_t in_len, -- const uint8_t *ad, size_t ad_len) { -- size_t out_len; +diff --git a/src/crypto/internal/backend/bbig/big.go b/src/crypto/internal/backend/bbig/big.go +new file mode 100644 +index 0000000000..5652398605 +--- /dev/null ++++ b/src/crypto/internal/backend/bbig/big.go +@@ -0,0 +1,15 @@ ++// Copyright 2022 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. ++ ++// This is a mirror of ++// https://github.com/golang/go/blob/36b87f273cc43e21685179dc1664ebb5493d26ae/src/crypto/internal/boring/bbig/big.go. ++ ++package bbig ++ ++import ( ++ "github.com/golang-fips/openssl/v2/bbig" ++) ++ ++var Enc = bbig.Enc ++var Dec = bbig.Dec +diff --git a/src/crypto/internal/backend/boringtest/config.go b/src/crypto/internal/backend/boringtest/config.go +new file mode 100644 +index 0000000000..4b6c7adba6 +--- /dev/null ++++ b/src/crypto/internal/backend/boringtest/config.go +@@ -0,0 +1,50 @@ ++// Copyright 2017 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. ++ ++/* Test configuration package for OpenSSL FIPS ++ ++The FIPS mode behavior of OpenSSL varies between versions and distributions ++depending which version of the FIPS standard the library targets. Because ++the Go crypto tests can not reliably account for these behavioral differences, ++building golang-fips on a new distribution often results in test failures due to ++variations in things like supported crypto algorithms and key sizes. ++ ++The goal of this package is to implement a compile-time defined configuration ++for the behavior of OpenSSL, which is more easily configurable to run in different ++environments. The compile-time schema was chosen as the preferred method, because ++we don't want elements of the run-time environment to impact the result of the tests ++(for example, changes to the environment or config files). ++*/ ++ ++package boringtest ++ ++import ( ++ "testing" ++) ++ ++var testConfig map[string]bool ++ ++func init() { ++ testConfig = map[string]bool{ ++ "PKCSv1.5": false, ++ "SHA1": false, ++ // really this is anything < 2048 ++ "RSA1024": false, ++ "RSA4096LeafCert": true, ++ "RSA1024LeafCert": false, ++ "TLS13": true, ++ "CurveP224": true, ++ "CurveP256": true, ++ "CurveP384": true, ++ "CurveP521": true, ++ } ++} ++ ++func Supports(t *testing.T, key string) bool { ++ result, ok := testConfig[key] ++ if !ok { ++ return true ++ } ++ return result ++} +diff --git a/src/crypto/internal/backend/dummy.s b/src/crypto/internal/backend/dummy.s +new file mode 100644 +index 0000000000..1247294947 +--- /dev/null ++++ b/src/crypto/internal/backend/dummy.s +@@ -0,0 +1,5 @@ ++// Copyright 2017 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 linux && cgo && !android && !gocrypt && !cmd_go_bootstrap && !msan && !no_openssl && !purego +diff --git a/src/crypto/internal/backend/hostfips.go b/src/crypto/internal/backend/hostfips.go +new file mode 100644 +index 0000000000..aa21cd4db9 +--- /dev/null ++++ b/src/crypto/internal/backend/hostfips.go +@@ -0,0 +1,25 @@ ++// Copyright 2017 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. ++ ++package backend ++ ++import ( ++ "fmt" ++ "os" ++) ++ ++func hostFIPSModeEnabled() bool { ++ // Look at /proc/sys/crypto/fips_enabled to see if FIPS mode is enabled. ++ // If it is, log an error and exit. ++ // If we run into an error reading that file because it doesn't exist, assume FIPS mode is not enabled. ++ data, err := os.ReadFile("/proc/sys/crypto/fips_enabled") ++ if err != nil { ++ if os.IsNotExist(err) { ++ return false ++ } ++ fmt.Fprintf(os.Stderr, "error reading /proc/sys/crypto/fips_enabled: %v\n", err) ++ os.Exit(1) ++ } ++ return len(data) > 0 && data[0] == '1' ++} +diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go +new file mode 100644 +index 0000000000..95c2cdc10e +--- /dev/null ++++ b/src/crypto/internal/backend/nobackend.go +@@ -0,0 +1,174 @@ ++// Copyright 2017 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 !linux || !cgo || android || cmd_go_bootstrap || msan || no_openssl || purego ++// +build !linux !cgo android cmd_go_bootstrap msan no_openssl purego ++ ++package backend ++ ++import ( ++ "crypto" ++ "crypto/cipher" ++ bbig "crypto/internal/boring" ++ "crypto/internal/boring/sig" ++ "hash" ++ "io" ++) ++ ++func init() { ++ strictFIPSNonCompliantBinaryCheck() ++} ++ ++var enabled = false ++ ++// Unreachable marks code that should be unreachable ++// when BoringCrypto is in use. It is a no-op without BoringCrypto. ++func Unreachable() { ++ // Code that's unreachable when using BoringCrypto ++ // is exactly the code we want to detect for reporting ++ // standard Go crypto. ++ sig.StandardCrypto() ++} ++ ++func IsStrictFIPSMode() bool { ++ return false ++} ++ ++// UnreachableExceptTests marks code that should be unreachable ++// when BoringCrypto is in use. It is a no-op without BoringCrypto. ++func UnreachableExceptTests() {} ++ ++func ExecutingTest() bool { return false } ++ ++// This is a noop withotu BoringCrytpo. ++func PanicIfStrictFIPS(v interface{}) {} ++ ++type randReader int ++ ++func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not available") } ++ ++const RandReader = randReader(0) ++ ++func Enabled() bool { return false } ++func NewSHA1() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA224() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA256() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA384() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA512() hash.Hash { panic("boringcrypto: not available") } ++func SHA1(_ []byte) [20]byte { panic("boringcrypto: not available") } ++func SHA224(_ []byte) [28]byte { panic("boringcrypto: not available") } ++func SHA256(_ []byte) [32]byte { panic("boringcrypto: not available") } ++func SHA384(_ []byte) [48]byte { panic("boringcrypto: not available") } ++func SHA512(_ []byte) [64]byte { panic("boringcrypto: not available") } ++ ++func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: not available") } ++ ++func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") } ++ ++type PublicKeyECDSA struct{ _ int } ++type PrivateKeyECDSA struct{ _ int } ++ ++func NewGCMTLS13(c cipher.Block) (cipher.AEAD, error) { ++ panic("boringcrypto: not available") ++} ++func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { ++ panic("boringcrypto: not available") ++} ++func GenerateKeyECDSA(curve string) (X, Y, D bbig.BigInt, err error) { ++ panic("boringcrypto: not available") ++} ++func NewPrivateKeyECDSA(curve string, X, Y, D bbig.BigInt) (*PrivateKeyECDSA, error) { ++ panic("boringcrypto: not available") ++} ++func NewPublicKeyECDSA(curve string, X, Y bbig.BigInt) (*PublicKeyECDSA, error) { ++ panic("boringcrypto: not available") ++} ++func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s bbig.BigInt, err error) { ++ panic("boringcrypto: not available") ++} ++func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func VerifyECDSA(pub *PublicKeyECDSA, hash, sig []byte) bool { ++ panic("boringcrypto: not available") ++} ++ ++type PublicKeyECDH struct{ _ int } ++type PrivateKeyECDH struct{ _ int } ++ ++func (pc *PublicKeyECDH) Bytes() []byte { panic("boringcrypto: not available") } ++func (pc *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { panic("boringcrypto: not available") } ++ ++func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { ++ panic("boringcrypto: not available") ++} ++func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { ++ panic("boringcrypto: not available") ++} ++func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { ++ panic("boringcrypto: not available") ++} ++func SharedKeyECDH(priv *PrivateKeyECDH, peerPublicKey []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++ ++type PublicKeyRSA struct{ _ int } ++type PrivateKeyRSA struct{ _ int } ++ ++func DecryptRSAOAEP(h, h2 hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func EncryptRSAOAEP(h, h2 hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv bbig.BigInt, err error) { ++ panic("boringcrypto: not available") ++} ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv bbig.BigInt) (*PrivateKeyRSA, error) { ++ panic("boringcrypto: not available") ++} ++func NewPublicKeyRSA(N, E bbig.BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") } ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { ++ panic("boringcrypto: not available") ++} ++func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { ++ panic("boringcrypto: not available") ++} ++ ++func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) { ++ panic("boringcrypto: not available") ++} ++func SupportsHKDF() bool { ++ panic("boringcrypto: not available") ++} ++func HashVerifyECDSA(pub *PublicKeyECDSA, h crypto.Hash, msg, sig []byte) bool { ++ panic("boringcrypto: not available") ++} ++func HashSignECDSA(priv *PrivateKeyECDSA, h crypto.Hash, msg []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} +diff --git a/src/crypto/internal/backend/not_strict_fips.go b/src/crypto/internal/backend/not_strict_fips.go +new file mode 100644 +index 0000000000..e27a631383 +--- /dev/null ++++ b/src/crypto/internal/backend/not_strict_fips.go +@@ -0,0 +1,16 @@ ++// Copyright 2017 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 !goexperiment.strictfipsruntime ++// +build !goexperiment.strictfipsruntime ++ ++package backend ++ ++var isStrictFIPS bool = false ++ ++func strictFIPSOpenSSLRuntimeCheck() { ++} ++ ++func strictFIPSNonCompliantBinaryCheck() { ++} +diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go +new file mode 100644 +index 0000000000..ddf8f1886c +--- /dev/null ++++ b/src/crypto/internal/backend/openssl.go +@@ -0,0 +1,177 @@ ++// Copyright 2017 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 linux && cgo && !android && !gocrypt && !cmd_go_bootstrap && !msan && !no_openssl && !purego ++// +build linux,cgo,!android,!gocrypt,!cmd_go_bootstrap,!msan,!no_openssl,!purego ++ ++// Package openssl provides access to OpenSSLCrypto implementation functions. ++// Check the variable Enabled to find out whether OpenSSLCrypto is available. ++// If OpenSSLCrypto is not available, the functions in this package all panic. ++package backend ++ ++import ( ++ "crypto/internal/boring/sig" ++ "fmt" ++ "os" ++ "syscall" ++ ++ "github.com/golang-fips/openssl/v2" ++) ++ ++// Enabled controls whether FIPS crypto is enabled. ++var enabled bool ++ ++var knownVersions = [...]string{"3", "1.1", "11", "111", "1.0.2", "1.0.0", "10"} ++ ++func init() { ++ version, _ := syscall.Getenv("GO_OPENSSL_VERSION_OVERRIDE") ++ if version == "" { ++ var fallbackVersion string ++ for _, v := range knownVersions { ++ vv := fmt.Sprintf("libcrypto.so.%s", v) ++ exists, fips := openssl.CheckVersion(vv) ++ if exists && fips { ++ version = vv ++ break ++ } ++ if exists && fallbackVersion == "" { ++ fallbackVersion = vv ++ } ++ } ++ if version == "" && fallbackVersion != "" { ++ version = fallbackVersion ++ } ++ } ++ if version == "" { ++ strictFIPSOpenSSLRuntimeCheck() ++ } ++ if err := openssl.Init(version); err != nil { ++ panic("opensslcrypto: can't initialize OpenSSL " + version + ": " + err.Error()) ++ } ++ // 0: FIPS opt-out: abort the process if it is enabled and can't be disabled. ++ // 1: FIPS required: abort the process if it is not enabled and can't be enabled. ++ // other values: do not override OpenSSL configured FIPS mode. ++ var fips string ++ if v, ok := syscall.Getenv("GOLANG_FIPS"); ok { ++ fips = v ++ } else if hostFIPSModeEnabled() { ++ // System configuration can only force FIPS mode. ++ fips = "1" ++ } ++ switch fips { ++ case "0": ++ if openssl.FIPS() { ++ if err := openssl.SetFIPS(false); err != nil { ++ panic("opensslcrypto: can't disable FIPS mode for " + openssl.VersionText() + ": " + err.Error()) ++ } ++ } ++ case "1": ++ if !openssl.FIPS() { ++ if err := openssl.SetFIPS(true); err != nil { ++ panic("opensslcrypto: can't enable FIPS mode for " + openssl.VersionText() + ": " + err.Error()) ++ } ++ } ++ enabled = true ++ } ++ sig.BoringCrypto() ++} ++ ++func IsStrictFIPSMode() bool { ++ return isStrictFIPS ++} ++ ++func Enabled() bool { ++ return enabled ++} ++ ++// Unreachable marks code that should be unreachable ++// when OpenSSLCrypto is in use. It panics only when ++// the system is in FIPS mode. ++func Unreachable() { ++ if Enabled() { ++ panic("opensslcrypto: invalid code execution") ++ } ++} ++ ++// ExecutingTest returns a boolean indicating if we're ++// executing under a test binary or not. ++func ExecutingTest() bool { ++ name := os.Args[0] ++ return hasSuffix(name, "_test") || hasSuffix(name, ".test") ++} ++ ++func hasSuffix(s, t string) bool { ++ return len(s) > len(t) && s[len(s)-len(t):] == t ++} ++ ++// UnreachableExceptTests marks code that should be unreachable ++// when OpenSSLCrypto is in use. It panics. ++func UnreachableExceptTests() { ++ name := os.Args[0] ++ // If OpenSSLCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well. ++ if Enabled() && !hasSuffix(name, "_test") && !hasSuffix(name, ".test") { ++ println("opensslcrypto: unexpected code execution in", name) ++ panic("opensslcrypto: invalid code execution") ++ } ++} ++ ++const RandReader = openssl.RandReader ++ ++var NewGCMTLS13 = openssl.NewGCMTLS13 ++var NewGCMTLS = openssl.NewGCMTLS ++var NewSHA1 = openssl.NewSHA1 ++var NewSHA224 = openssl.NewSHA224 ++var NewSHA256 = openssl.NewSHA256 ++var NewSHA384 = openssl.NewSHA384 ++var NewSHA512 = openssl.NewSHA512 ++ ++var SHA1 = openssl.SHA1 ++var SHA224 = openssl.SHA224 ++var SHA256 = openssl.SHA256 ++var SHA384 = openssl.SHA384 ++var SHA512 = openssl.SHA512 ++ ++var NewHMAC = openssl.NewHMAC ++ ++var NewAESCipher = openssl.NewAESCipher ++ ++type PublicKeyECDSA = openssl.PublicKeyECDSA ++type PrivateKeyECDSA = openssl.PrivateKeyECDSA ++ ++var GenerateKeyECDSA = openssl.GenerateKeyECDSA ++var NewPrivateKeyECDSA = openssl.NewPrivateKeyECDSA ++var NewPublicKeyECDSA = openssl.NewPublicKeyECDSA ++var SignMarshalECDSA = openssl.SignMarshalECDSA ++var VerifyECDSA = openssl.VerifyECDSA ++var HashVerifyECDSA = openssl.HashVerifyECDSA ++var HashSignECDSA = openssl.HashSignECDSA ++ ++type PublicKeyECDH = openssl.PublicKeyECDH ++type PrivateKeyECDH = openssl.PrivateKeyECDH ++ ++var GenerateKeyECDH = openssl.GenerateKeyECDH ++var NewPrivateKeyECDH = openssl.NewPrivateKeyECDH ++var NewPublicKeyECDH = openssl.NewPublicKeyECDH ++var ECDH = openssl.ECDH ++ ++type PublicKeyRSA = openssl.PublicKeyRSA ++type PrivateKeyRSA = openssl.PrivateKeyRSA ++ ++var DecryptRSAOAEP = openssl.DecryptRSAOAEP ++var DecryptRSAPKCS1 = openssl.DecryptRSAPKCS1 ++var DecryptRSANoPadding = openssl.DecryptRSANoPadding ++var EncryptRSAOAEP = openssl.EncryptRSAOAEP ++var EncryptRSAPKCS1 = openssl.EncryptRSAPKCS1 ++var EncryptRSANoPadding = openssl.EncryptRSANoPadding ++var GenerateKeyRSA = openssl.GenerateKeyRSA ++var NewPrivateKeyRSA = openssl.NewPrivateKeyRSA ++var NewPublicKeyRSA = openssl.NewPublicKeyRSA ++var SignRSAPKCS1v15 = openssl.SignRSAPKCS1v15 ++var SignRSAPSS = openssl.SignRSAPSS ++var VerifyRSAPKCS1v15 = openssl.VerifyRSAPKCS1v15 ++var VerifyRSAPSS = openssl.VerifyRSAPSS ++ ++var ExtractHKDF = openssl.ExtractHKDF ++var ExpandHKDF = openssl.ExpandHKDF ++var SupportsHKDF = openssl.SupportsHKDF +diff --git a/src/crypto/internal/backend/strict_fips.go b/src/crypto/internal/backend/strict_fips.go +new file mode 100644 +index 0000000000..cd5bd34b33 +--- /dev/null ++++ b/src/crypto/internal/backend/strict_fips.go +@@ -0,0 +1,29 @@ ++// Copyright 2017 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 goexperiment.strictfipsruntime ++// +build goexperiment.strictfipsruntime ++ ++package backend ++ ++import ( ++ "fmt" ++ "os" ++) ++ ++var isStrictFIPS bool = true ++ ++func strictFIPSOpenSSLRuntimeCheck() { ++ if hostFIPSModeEnabled() && !Enabled() { ++ fmt.Fprintln(os.Stderr, "FIPS mode is enabled, but the required OpenSSL backend is unavailable") ++ os.Exit(1) ++ } ++} ++ ++func strictFIPSNonCompliantBinaryCheck() { ++ if hostFIPSModeEnabled() { ++ fmt.Fprintln(os.Stderr, "FIPS mode is enabled, but this binary is not compiled with FIPS compliant mode enabled") ++ os.Exit(1) ++ } ++} +diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go +deleted file mode 100644 +index d18ed5cdc5..0000000000 +--- a/src/crypto/internal/boring/aes.go ++++ /dev/null +@@ -1,400 +0,0 @@ +-// Copyright 2017 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 && linux && (amd64 || arm64) && !android && !msan +- +-package boring +- +-/* +- +-#include "goboringcrypto.h" +- +-// These wrappers allocate out_len on the C stack, and check that it matches the expected +-// value, to avoid having to pass a pointer from Go, which would escape to the heap. +- +-int EVP_AEAD_CTX_seal_wrapper(const GO_EVP_AEAD_CTX *ctx, uint8_t *out, +- size_t exp_out_len, +- const uint8_t *nonce, size_t nonce_len, +- const uint8_t *in, size_t in_len, +- const uint8_t *ad, size_t ad_len) { +- size_t out_len; - int ok = _goboringcrypto_EVP_AEAD_CTX_seal(ctx, out, &out_len, exp_out_len, - nonce, nonce_len, in, in_len, ad, ad_len); - if (out_len != exp_out_len) { @@ -685,26 +1562,41 @@ index 8819f576f4..0000000000 - if tagSize != gcmTagSize { - return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize) - } -- return c.newGCM(false) +- return c.newGCM(0) -} - +-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: - 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: - aead = C._goboringcrypto_EVP_aead_aes_256_gcm() - } - default: @@ -842,10 +1734,10 @@ index 8819f576f4..0000000000 -} diff --git a/src/crypto/internal/boring/boring.go b/src/crypto/internal/boring/boring.go deleted file mode 100644 -index 90cf1edb75..0000000000 +index 6dfc6ed5f5..0000000000 --- a/src/crypto/internal/boring/boring.go +++ /dev/null -@@ -1,123 +0,0 @@ +@@ -1,130 +0,0 @@ -// Copyright 2017 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. @@ -864,6 +1756,7 @@ index 90cf1edb75..0000000000 -import ( - "crypto/internal/boring/sig" - _ "crypto/internal/boring/syso" +- "crypto/internal/fips140" - "internal/stringslite" - "math/bits" - "unsafe" @@ -879,6 +1772,12 @@ index 90cf1edb75..0000000000 - sig.BoringCrypto() -} - +-func init() { +- if fips140.Enabled { +- panic("boringcrypto: cannot use GODEBUG=fips140 with GOEXPERIMENT=boringcrypto") +- } +-} +- -// Unreachable marks code that should be unreachable -// when BoringCrypto is in use. It panics. -func Unreachable() { @@ -1010,10 +1909,10 @@ index 83bbbd3404..0000000000 - UnreachableExceptTests() -} diff --git a/src/crypto/internal/boring/doc.go b/src/crypto/internal/boring/doc.go -index 091e0d641e..ca24813149 100644 +index 091e0d641e..f83dc83ced 100644 --- a/src/crypto/internal/boring/doc.go +++ b/src/crypto/internal/boring/doc.go -@@ -7,13 +7,10 @@ +@@ -7,13 +7,9 @@ // If BoringCrypto is not available, the functions in this package all panic. package boring @@ -1029,13 +1928,12 @@ index 091e0d641e..ca24813149 100644 // Conversion between BigInt and *big.Int is in crypto/internal/boring/bbig. -type BigInt []uint +type BigInt = openssl.BigInt -+ diff --git a/src/crypto/internal/boring/ecdh.go b/src/crypto/internal/boring/ecdh.go deleted file mode 100644 -index 6a5d174c16..0000000000 +index ff29eb17b1..0000000000 --- a/src/crypto/internal/boring/ecdh.go +++ /dev/null -@@ -1,224 +0,0 @@ +@@ -1,237 +0,0 @@ -// Copyright 2022 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. @@ -1073,8 +1971,8 @@ index 6a5d174c16..0000000000 -} - -func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { -- if len(bytes) < 1 { -- return nil, errors.New("NewPublicKeyECDH: missing key") +- if len(bytes) != 1+2*curveSize(curve) { +- return nil, errors.New("NewPublicKeyECDH: wrong key length") - } - - nid, err := curveNID(curve) @@ -1109,6 +2007,10 @@ index 6a5d174c16..0000000000 -func (k *PublicKeyECDH) Bytes() []byte { return k.bytes } - -func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { +- if len(bytes) != curveSize(curve) { +- return nil, errors.New("NewPrivateKeyECDH: wrong key length") +- } +- - nid, err := curveNID(curve) - if err != nil { - return nil, err @@ -1172,6 +2074,15 @@ index 6a5d174c16..0000000000 -} - -func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { +- // Make sure priv and pub are not garbage collected while we are in a cgo +- // call. +- // +- // The call to xCoordBytesECDH should prevent priv from being collected, but +- // include this in case the code is reordered and there is a subsequent call +- // cgo call after that point. +- defer runtime.KeepAlive(priv) +- defer runtime.KeepAlive(pub) +- - group := C._goboringcrypto_EC_KEY_get0_group(priv.key) - if group == nil { - return nil, fail("EC_KEY_get0_group") @@ -1438,36 +2349,6 @@ index 2adfdb2c9f..0000000000 - } - return bnToBig(bx), bnToBig(by), bnToBig(bd), nil -} -diff --git a/src/crypto/internal/boring/fipstls/stub.s b/src/crypto/internal/boring/fipstls/stub.s -index f2e5a503ea..65918a480e 100644 ---- a/src/crypto/internal/boring/fipstls/stub.s -+++ b/src/crypto/internal/boring/fipstls/stub.s -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --//go:build boringcrypto -+//go:build !no_openssl - - // runtime_arg0 is declared in tls.go without a body. - // It's provided by package runtime, -diff --git a/src/crypto/internal/boring/fipstls/tls.go b/src/crypto/internal/boring/fipstls/tls.go -index b51f142fde..cd19b69020 100644 ---- a/src/crypto/internal/boring/fipstls/tls.go -+++ b/src/crypto/internal/boring/fipstls/tls.go -@@ -2,10 +2,10 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --//go:build boringcrypto -+//go:build !no_openssl - - // Package fipstls allows control over whether crypto/tls requires FIPS-approved settings. --// This package only exists with GOEXPERIMENT=boringcrypto, but the effects are independent -+// This package only exists with GOEXPERIMENT=!no_openssl, but the effects are independent - // of the use of BoringCrypto. - package fipstls - diff --git a/src/crypto/internal/boring/hmac.go b/src/crypto/internal/boring/hmac.go deleted file mode 100644 index ae926da695..0000000000 @@ -1629,10 +2510,10 @@ index ae926da695..0000000000 -} diff --git a/src/crypto/internal/boring/notboring.go b/src/crypto/internal/boring/notboring.go deleted file mode 100644 -index 361dec9672..0000000000 +index 02bc468a0d..0000000000 --- a/src/crypto/internal/boring/notboring.go +++ /dev/null -@@ -1,122 +0,0 @@ +@@ -1,123 +0,0 @@ -// Copyright 2017 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. @@ -1685,6 +2566,7 @@ index 361dec9672..0000000000 - -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 } @@ -1787,7 +2669,7 @@ index 556b98a112..0000000000 -const RandReader = randReader(0) diff --git a/src/crypto/internal/boring/rsa.go b/src/crypto/internal/boring/rsa.go deleted file mode 100644 -index 5ca86aa042..0000000000 +index a7fb1b5608..0000000000 --- a/src/crypto/internal/boring/rsa.go +++ /dev/null @@ -1,379 +0,0 @@ @@ -2045,7 +2927,7 @@ index 5ca86aa042..0000000000 - return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen) -} - --var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative") +-var invalidSaltLenErr = errors.New("crypto/rsa: invalid PSS salt length") - -func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { - md := cryptoHashToMD(h) @@ -2172,10 +3054,10 @@ index 5ca86aa042..0000000000 -} diff --git a/src/crypto/internal/boring/sha.go b/src/crypto/internal/boring/sha.go deleted file mode 100644 -index a49c119738..0000000000 +index d58cb3981a..0000000000 --- a/src/crypto/internal/boring/sha.go +++ /dev/null -@@ -1,599 +0,0 @@ +@@ -1,578 +0,0 @@ -// Copyright 2017 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. @@ -2237,6 +3119,7 @@ index a49c119738..0000000000 -import ( - "errors" - "hash" +- "internal/byteorder" - "unsafe" -) - @@ -2337,17 +3220,20 @@ index a49c119738..0000000000 -) - -func (h *sha1Hash) MarshalBinary() ([]byte, error) { +- return h.AppendBinary(make([]byte, 0, sha1MarshaledSize)) +-} +- +-func (h *sha1Hash) AppendBinary(b []byte) ([]byte, error) { - d := (*sha1Ctx)(unsafe.Pointer(&h.ctx)) -- b := make([]byte, 0, sha1MarshaledSize) - b = append(b, sha1Magic...) -- b = appendUint32(b, d.h[0]) -- b = appendUint32(b, d.h[1]) -- b = appendUint32(b, d.h[2]) -- b = appendUint32(b, d.h[3]) -- b = appendUint32(b, d.h[4]) +- b = byteorder.BEAppendUint32(b, d.h[0]) +- b = byteorder.BEAppendUint32(b, d.h[1]) +- b = byteorder.BEAppendUint32(b, d.h[2]) +- b = byteorder.BEAppendUint32(b, d.h[3]) +- b = byteorder.BEAppendUint32(b, d.h[4]) - b = append(b, d.x[:d.nx]...) -- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -- b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) +- b = append(b, make([]byte, len(d.x)-int(d.nx))...) +- b = byteorder.BEAppendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) - return b, nil -} - @@ -2463,38 +3349,44 @@ index a49c119738..0000000000 -} - -func (h *sha224Hash) MarshalBinary() ([]byte, error) { +- return h.AppendBinary(make([]byte, 0, marshaledSize256)) +-} +- +-func (h *sha224Hash) AppendBinary(b []byte) ([]byte, error) { - d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) -- b := make([]byte, 0, marshaledSize256) - b = append(b, magic224...) -- b = appendUint32(b, d.h[0]) -- b = appendUint32(b, d.h[1]) -- b = appendUint32(b, d.h[2]) -- b = appendUint32(b, d.h[3]) -- b = appendUint32(b, d.h[4]) -- b = appendUint32(b, d.h[5]) -- b = appendUint32(b, d.h[6]) -- b = appendUint32(b, d.h[7]) +- b = byteorder.BEAppendUint32(b, d.h[0]) +- b = byteorder.BEAppendUint32(b, d.h[1]) +- b = byteorder.BEAppendUint32(b, d.h[2]) +- b = byteorder.BEAppendUint32(b, d.h[3]) +- b = byteorder.BEAppendUint32(b, d.h[4]) +- b = byteorder.BEAppendUint32(b, d.h[5]) +- b = byteorder.BEAppendUint32(b, d.h[6]) +- b = byteorder.BEAppendUint32(b, d.h[7]) - b = append(b, d.x[:d.nx]...) -- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -- b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) +- b = append(b, make([]byte, len(d.x)-int(d.nx))...) +- b = byteorder.BEAppendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) - return b, nil -} - -func (h *sha256Hash) MarshalBinary() ([]byte, error) { +- return h.AppendBinary(make([]byte, 0, marshaledSize256)) +-} +- +-func (h *sha256Hash) AppendBinary(b []byte) ([]byte, error) { - d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) -- b := make([]byte, 0, marshaledSize256) - b = append(b, magic256...) -- b = appendUint32(b, d.h[0]) -- b = appendUint32(b, d.h[1]) -- b = appendUint32(b, d.h[2]) -- b = appendUint32(b, d.h[3]) -- b = appendUint32(b, d.h[4]) -- b = appendUint32(b, d.h[5]) -- b = appendUint32(b, d.h[6]) -- b = appendUint32(b, d.h[7]) +- b = byteorder.BEAppendUint32(b, d.h[0]) +- b = byteorder.BEAppendUint32(b, d.h[1]) +- b = byteorder.BEAppendUint32(b, d.h[2]) +- b = byteorder.BEAppendUint32(b, d.h[3]) +- b = byteorder.BEAppendUint32(b, d.h[4]) +- b = byteorder.BEAppendUint32(b, d.h[5]) +- b = byteorder.BEAppendUint32(b, d.h[6]) +- b = byteorder.BEAppendUint32(b, d.h[7]) - b = append(b, d.x[:d.nx]...) -- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -- b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) +- b = append(b, make([]byte, len(d.x)-int(d.nx))...) +- b = byteorder.BEAppendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) - return b, nil -} - @@ -2640,38 +3532,44 @@ index a49c119738..0000000000 -) - -func (h *sha384Hash) MarshalBinary() ([]byte, error) { +- return h.AppendBinary(make([]byte, 0, marshaledSize512)) +-} +- +-func (h *sha384Hash) AppendBinary(b []byte) ([]byte, error) { - d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) -- b := make([]byte, 0, marshaledSize512) - b = append(b, magic384...) -- b = appendUint64(b, d.h[0]) -- b = appendUint64(b, d.h[1]) -- b = appendUint64(b, d.h[2]) -- b = appendUint64(b, d.h[3]) -- b = appendUint64(b, d.h[4]) -- b = appendUint64(b, d.h[5]) -- b = appendUint64(b, d.h[6]) -- b = appendUint64(b, d.h[7]) +- b = byteorder.BEAppendUint64(b, d.h[0]) +- b = byteorder.BEAppendUint64(b, d.h[1]) +- b = byteorder.BEAppendUint64(b, d.h[2]) +- b = byteorder.BEAppendUint64(b, d.h[3]) +- b = byteorder.BEAppendUint64(b, d.h[4]) +- b = byteorder.BEAppendUint64(b, d.h[5]) +- b = byteorder.BEAppendUint64(b, d.h[6]) +- b = byteorder.BEAppendUint64(b, d.h[7]) - b = append(b, d.x[:d.nx]...) -- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -- b = appendUint64(b, d.nl>>3|d.nh<<61) +- b = append(b, make([]byte, len(d.x)-int(d.nx))...) +- b = byteorder.BEAppendUint64(b, d.nl>>3|d.nh<<61) - return b, nil -} - -func (h *sha512Hash) MarshalBinary() ([]byte, error) { +- return h.AppendBinary(make([]byte, 0, marshaledSize512)) +-} +- +-func (h *sha512Hash) AppendBinary(b []byte) ([]byte, error) { - d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) -- b := make([]byte, 0, marshaledSize512) - b = append(b, magic512...) -- b = appendUint64(b, d.h[0]) -- b = appendUint64(b, d.h[1]) -- b = appendUint64(b, d.h[2]) -- b = appendUint64(b, d.h[3]) -- b = appendUint64(b, d.h[4]) -- b = appendUint64(b, d.h[5]) -- b = appendUint64(b, d.h[6]) -- b = appendUint64(b, d.h[7]) +- b = byteorder.BEAppendUint64(b, d.h[0]) +- b = byteorder.BEAppendUint64(b, d.h[1]) +- b = byteorder.BEAppendUint64(b, d.h[2]) +- b = byteorder.BEAppendUint64(b, d.h[3]) +- b = byteorder.BEAppendUint64(b, d.h[4]) +- b = byteorder.BEAppendUint64(b, d.h[5]) +- b = byteorder.BEAppendUint64(b, d.h[6]) +- b = byteorder.BEAppendUint64(b, d.h[7]) - b = append(b, d.x[:d.nx]...) -- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -- b = appendUint64(b, d.nl>>3|d.nh<<61) +- b = append(b, make([]byte, len(d.x)-int(d.nx))...) +- b = byteorder.BEAppendUint64(b, d.nl>>3|d.nh<<61) - return b, nil -} - @@ -2731,65 +3629,124 @@ index a49c119738..0000000000 - return nil -} - --func appendUint64(b []byte, x uint64) []byte { -- var a [8]byte -- putUint64(a[:], x) -- return append(b, a[:]...) --} -- --func appendUint32(b []byte, x uint32) []byte { -- var a [4]byte -- putUint32(a[:], x) -- return append(b, a[:]...) --} -- -func consumeUint64(b []byte) ([]byte, uint64) { -- _ = b[7] -- x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | -- uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 -- return b[8:], x +- return b[8:], byteorder.BEUint64(b) -} - -func consumeUint32(b []byte) ([]byte, uint32) { -- _ = b[3] -- x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 -- return b[4:], x --} -- --func putUint64(x []byte, s uint64) { -- _ = x[7] -- x[0] = byte(s >> 56) -- x[1] = byte(s >> 48) -- x[2] = byte(s >> 40) -- x[3] = byte(s >> 32) -- x[4] = byte(s >> 24) -- x[5] = byte(s >> 16) -- x[6] = byte(s >> 8) -- x[7] = byte(s) --} -- --func putUint32(x []byte, s uint32) { -- _ = x[3] -- x[0] = byte(s >> 24) -- x[1] = byte(s >> 16) -- x[2] = byte(s >> 8) -- x[3] = byte(s) --} -diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go -index 40fce36314..c30be35635 100644 ---- a/src/crypto/rand/rand_unix.go -+++ b/src/crypto/rand/rand_unix.go -@@ -10,7 +10,7 @@ +- return b[4:], byteorder.BEUint32(b) +-} +diff --git a/src/crypto/internal/cryptotest/allocations.go b/src/crypto/internal/cryptotest/allocations.go +index 70055af70b..9d9204ff45 100644 +--- a/src/crypto/internal/cryptotest/allocations.go ++++ b/src/crypto/internal/cryptotest/allocations.go +@@ -5,7 +5,7 @@ + package cryptotest + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "internal/asan" + "internal/msan" + "internal/race" +@@ -17,8 +17,14 @@ import ( + // SkipTestAllocations skips the test if there are any factors that interfere + // with allocation optimizations. + func SkipTestAllocations(t *testing.T) { ++ // Our distribution has a dynamic `boring.Enabled()` implemented as a function, as ++ // opposed to the upstream approach using a constant. This means the compiler cannot ++ // optimize away a path of the branch checking `if boring.Enabled()` so the CPU will ++ // end up doing some speculative execution. This results in an allocation that ends ++ // up being discarded as that path is not followed. ++ t.Skip("skipping allocations test due to speculative execution") + // Go+BoringCrypto uses cgo. +- if boring.Enabled { ++ if boring.Enabled() { + t.Skip("skipping allocations test with BoringCrypto") + } + +diff --git a/src/crypto/internal/cryptotest/implementations.go b/src/crypto/internal/cryptotest/implementations.go +index 3fa7304590..aecb344e01 100644 +--- a/src/crypto/internal/cryptotest/implementations.go ++++ b/src/crypto/internal/cryptotest/implementations.go +@@ -5,7 +5,7 @@ + package cryptotest + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/impl" + "internal/goos" + "internal/testenv" +@@ -17,7 +17,7 @@ import ( + // are no alternative implementations for pkg, f is invoked directly once. + func TestAllImplementations(t *testing.T, pkg string, f func(t *testing.T)) { + // BoringCrypto bypasses the multiple Go implementations. +- if boring.Enabled { ++ if boring.Enabled() { + f(t) + return + } +diff --git a/src/crypto/internal/hpke/hpke_test.go b/src/crypto/internal/hpke/hpke_test.go +index 51beeed212..62c1378c31 100644 +--- a/src/crypto/internal/hpke/hpke_test.go ++++ b/src/crypto/internal/hpke/hpke_test.go +@@ -16,6 +16,8 @@ import ( + "crypto/ecdh" + _ "crypto/sha256" + _ "crypto/sha512" ++ ++ boring "crypto/internal/backend" + ) + + func mustDecodeHex(t *testing.T, in string) []byte { +@@ -94,6 +96,9 @@ func TestRFC9180Vectors(t *testing.T) { + pubKeyBytes := mustDecodeHex(t, setup["pkRm"]) + pub, err := ParseHPKEPublicKey(uint16(kemID), pubKeyBytes) + if err != nil { ++ if boring.Enabled() && strings.Contains(vector.Name, "X25519") && strings.Contains(err.Error(), "crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") { ++ t.Skip("error is expected in FIPS mode") ++ } + t.Fatal(err) + } + +diff --git a/src/crypto/pbkdf2/pbkdf2_test.go b/src/crypto/pbkdf2/pbkdf2_test.go +index eb0ed14e24..78322dedf8 100644 +--- a/src/crypto/pbkdf2/pbkdf2_test.go ++++ b/src/crypto/pbkdf2/pbkdf2_test.go +@@ -6,7 +6,7 @@ package pbkdf2_test + + import ( + "bytes" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/fips140" + "crypto/pbkdf2" + "crypto/sha1" +@@ -186,7 +186,7 @@ func BenchmarkHMACSHA256(b *testing.B) { + } + + func TestPBKDF2ServiceIndicator(t *testing.T) { +- if boring.Enabled { ++ if boring.Enabled() { + t.Skip("in BoringCrypto mode PBKDF2 is not from the Go FIPS module") + } + +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +index 1ca16caa95..1df790ef7d 100644 +--- a/src/crypto/rand/rand.go ++++ b/src/crypto/rand/rand.go +@@ -7,7 +7,7 @@ package rand import ( - "crypto/internal/boring" + boring "crypto/internal/backend" - "errors" - "io" - "os" -@@ -23,7 +23,7 @@ import ( - const urandomDevice = "/dev/urandom" + "crypto/internal/fips140" + "crypto/internal/fips140/drbg" + "crypto/internal/sysrand" +@@ -31,7 +31,7 @@ import ( + var Reader io.Reader func init() { - if boring.Enabled { @@ -2819,7 +3776,7 @@ index b9f9d3154f..85c2a45848 100644 "math/big" ) diff --git a/src/crypto/rsa/boring_test.go b/src/crypto/rsa/boring_test.go -index 2234d079f0..4e7fd9de4a 100644 +index 838fcc1244..fa50352a3f 100644 --- a/src/crypto/rsa/boring_test.go +++ b/src/crypto/rsa/boring_test.go @@ -2,7 +2,7 @@ @@ -2831,6 +3788,73 @@ index 2234d079f0..4e7fd9de4a 100644 // Note: Can run these tests against the non-BoringCrypto // version of the code by using "CGO_ENABLED=0 go test". +diff --git a/src/crypto/rsa/fips.go b/src/crypto/rsa/fips.go +index 8373c125ae..15fb35fc7f 100644 +--- a/src/crypto/rsa/fips.go ++++ b/src/crypto/rsa/fips.go +@@ -6,7 +6,7 @@ package rsa + + import ( + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/fips140/rsa" + "crypto/internal/fips140hash" + "crypto/internal/fips140only" +@@ -70,7 +70,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, + hash = opts.Hash + } + +- if boring.Enabled && rand == boring.RandReader { ++ if boring.Enabled() && rand == boring.RandReader { + bkey, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -133,7 +133,7 @@ func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts + return err + } + +- if boring.Enabled { ++ if boring.Enabled() { + bkey, err := boringPublicKey(pub) + if err != nil { + return err +@@ -197,7 +197,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l + + defer hash.Reset() + +- if boring.Enabled && random == boring.RandReader { ++ if boring.Enabled() && random == boring.RandReader { + hash.Reset() + k := pub.Size() + if len(msg) > k-2*hash.Size()-2 { +@@ -250,7 +250,7 @@ func decryptOAEP(hash, mgfHash hash.Hash, priv *PrivateKey, ciphertext []byte, l + return nil, err + } + +- if boring.Enabled { ++ if boring.Enabled() { + k := priv.Size() + if len(ciphertext) > k || + k < hash.Size()*2+2 { +@@ -312,7 +312,7 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ + return nil, err + } + +- if boring.Enabled { ++ if boring.Enabled() { + bkey, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -355,7 +355,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) + return err + } + +- if boring.Enabled { ++ if boring.Enabled() { + bkey, err := boringPublicKey(pub) + if err != nil { + return err diff --git a/src/crypto/rsa/notboring.go b/src/crypto/rsa/notboring.go index 2abc043640..a83be6dfdb 100644 --- a/src/crypto/rsa/notboring.go @@ -2856,19 +3880,19 @@ index 2abc043640..a83be6dfdb 100644 + panic("!no_openssl: not available") } diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go -index 2f958022f9..37ae624b61 100644 +index f1e4ef48a4..1c1bc3869f 100644 --- a/src/crypto/rsa/pkcs1v15.go +++ b/src/crypto/rsa/pkcs1v15.go -@@ -7,7 +7,7 @@ package rsa +@@ -5,7 +5,7 @@ + package rsa + import ( - "bytes" - "crypto" - "crypto/internal/boring" + boring "crypto/internal/backend" + "crypto/internal/fips140/rsa" + "crypto/internal/fips140only" "crypto/internal/randutil" - "crypto/subtle" - "errors" -@@ -50,7 +50,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro +@@ -55,7 +55,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro return nil, ErrMessageTooLong } @@ -2877,7 +3901,7 @@ index 2f958022f9..37ae624b61 100644 bkey, err := boringPublicKey(pub) if err != nil { return nil, err -@@ -70,7 +70,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro +@@ -75,7 +75,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro em[len(em)-len(msg)-1] = 0 copy(mm, msg) @@ -2886,7 +3910,7 @@ index 2f958022f9..37ae624b61 100644 var bkey *boring.PublicKeyRSA bkey, err = boringPublicKey(pub) if err != nil { -@@ -95,7 +95,7 @@ func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]b +@@ -104,7 +104,7 @@ func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]b return nil, err } @@ -2895,8 +3919,8 @@ index 2f958022f9..37ae624b61 100644 bkey, err := boringPrivateKey(priv) if err != nil { return nil, err -@@ -189,7 +189,7 @@ func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, - return +@@ -203,7 +203,7 @@ func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, + return 0, nil, 0, err } - if boring.Enabled { @@ -2904,206 +3928,283 @@ index 2f958022f9..37ae624b61 100644 var bkey *boring.PrivateKeyRSA bkey, err = boringPrivateKey(priv) if err != nil { -@@ -293,7 +293,7 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ - return nil, err - } - -- if boring.Enabled { -+ if boring.Enabled() { - bkey, err := boringPrivateKey(priv) - if err != nil { - return nil, err -@@ -343,7 +343,7 @@ func pkcs1v15ConstructEM(pub *PublicKey, hash crypto.Hash, hashed []byte) ([]byt - // The inputs are not considered confidential, and may leak through timing side - // channels, or if an attacker has control of part of the inputs. - func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error { -- if boring.Enabled { -+ if boring.Enabled() { - bkey, err := boringPublicKey(pub) - if err != nil { - return err diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go -index 39a4fc184a..0853178e3a 100644 +index c65552cd93..4b0588542e 100644 --- a/src/crypto/rsa/pkcs1v15_test.go +++ b/src/crypto/rsa/pkcs1v15_test.go -@@ -7,7 +7,7 @@ package rsa_test +@@ -7,6 +7,7 @@ package rsa_test import ( "bytes" "crypto" -- "crypto/internal/boring" + boring "crypto/internal/backend" - "crypto/internal/backend/boringtest" "crypto/rand" . "crypto/rsa" -@@ -56,7 +56,7 @@ var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{ - } - - func TestDecryptPKCS1v15(t *testing.T) { -- if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { - t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") - } - -@@ -84,7 +84,7 @@ func TestDecryptPKCS1v15(t *testing.T) { - } - - func TestEncryptPKCS1v15(t *testing.T) { -- if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { - t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") - } + "crypto/sha1" +@@ -16,6 +17,8 @@ import ( + "encoding/hex" + "encoding/pem" + "io" ++ "os" ++ "strings" + "testing" + "testing/quick" + ) +@@ -69,6 +72,16 @@ func TestDecryptPKCS1v15(t *testing.T) { + for i, test := range decryptPKCS1v15Tests { + out, err := decryptFunc(decodeBase64(test.in)) + if err != nil { ++ // The actual underlying error is: ++ // err: EVP_PKEY_decrypt_init failed ++ // openssl error(s): ++ // error:1C800069:Provider routines::invalid key length ++ // providers/common/securitycheck.c:67 ++ // ++ // However the Go code masks this error intentionally. ++ if boring.Enabled() && strings.Contains(err.Error(), "crypto/rsa: decryption error") { ++ continue // expected error in FIPS mode ++ } + t.Errorf("#%d error decrypting: %v", i, err) + } + want := []byte(test.out) +@@ -90,6 +103,11 @@ func TestEncryptPKCS1v15(t *testing.T) { -@@ -149,7 +149,7 @@ var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{ + ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in) + if err != nil { ++ if boring.Enabled() && rsaPrivateKey.Size() < 256 { ++ if strings.Contains(err.Error(), "invalid key length") { ++ return true // This error is expected in FIPS mode ++ } ++ } + t.Errorf("error encrypting: %s", err) + return false + } +@@ -141,6 +159,9 @@ var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{ } func TestEncryptPKCS1v15SessionKey(t *testing.T) { -- if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { - t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") - } - -@@ -167,7 +167,7 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("PKCS#1 v1.5 not supported in FIPS mode") ++ } + t.Setenv("GODEBUG", "rsa1024min=0") + for i, test := range decryptPKCS1v15SessionKeyTests { + key := []byte("FAIL") +@@ -156,6 +177,9 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) { } func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) { -- if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { - t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") - } ++ if boring.Enabled() { ++ t.Skip("PKCS#1 v1.5 not supported in FIPS mode") ++ } + t.Setenv("GODEBUG", "rsa1024min=0") + for i, test := range decryptPKCS1v15SessionKeyTests { + plaintext, err := test512Key.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4}) +@@ -208,6 +232,9 @@ func TestSignPKCS1v15(t *testing.T) { -@@ -277,7 +277,7 @@ func TestUnpaddedSignature(t *testing.T) { - } + s, err := SignPKCS1v15(nil, test512Key, crypto.SHA1, digest) + if err != nil { ++ if boring.Enabled() && strings.Contains(err.Error(), "invalid key length") { ++ continue // expected error in FIPS mode ++ } + t.Errorf("#%d %s", i, err) + } - func TestShortSessionKey(t *testing.T) { -- if boring.Enabled && !boringtest.Supports(t, "PKCSv1.5") { -+ if boring.Enabled() && !boringtest.Supports(t, "PKCSv1.5") { - t.Skip("skipping PKCS#1 v1.5 encryption test with BoringCrypto") - } +@@ -229,12 +256,29 @@ func TestVerifyPKCS1v15(t *testing.T) { -diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go -index e996e7aaa3..8f3334bbe5 100644 ---- a/src/crypto/rsa/pss.go -+++ b/src/crypto/rsa/pss.go -@@ -9,7 +9,7 @@ package rsa - import ( - "bytes" - "crypto" -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "errors" - "hash" - "io" -@@ -214,7 +214,7 @@ func signPSSWithSalt(priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([ - return nil, err + err := VerifyPKCS1v15(&test512Key.PublicKey, crypto.SHA1, digest, sig) + if err != nil { ++ // The actual underlying error is: ++ // err: EVP_PKEY_verify_init failed ++ // openssl error(s): ++ // error:1C800069:Provider routines::invalid key length ++ // providers/common/securitycheck.c:67 ++ // ++ // However the Go code masks this error intentionally. ++ if boring.Enabled() && strings.Contains(err.Error(), "crypto/rsa: verification error") { ++ continue // expected error in FIPS mode ++ } + t.Errorf("#%d %s", i, err) + } } + } -- if boring.Enabled { + func TestOverlongMessagePKCS1v15(t *testing.T) { ++ // Skip on RHEL 8 ++ if b, err := os.ReadFile("/etc/os-release"); err == nil { ++ if strings.Contains(string(b), "Red Hat Enterprise Linux 8") { ++ t.Skip("skipping on RHEL 8") ++ } ++ } ++ + t.Setenv("GODEBUG", "rsa1024min=0") + ciphertext := decodeBase64("fjOVdirUzFoLlukv80dBllMLjXythIf22feqPrNo0YoIjzyzyoMFiLjAc/Y4krkeZ11XFThIrEvw\nkRiZcCq5ng==") + _, err := DecryptPKCS1v15(nil, test512Key, ciphertext) +@@ -244,6 +288,9 @@ func TestOverlongMessagePKCS1v15(t *testing.T) { + } + + func TestUnpaddedSignature(t *testing.T) { + if boring.Enabled() { - bkey, err := boringPrivateKey(priv) - if err != nil { - return nil, err -@@ -296,7 +296,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, - // well-specified number of random bytes is included in the signature, in a - // well-specified way. ++ t.Skip("test not applicable in FIPS mode") ++ } + t.Setenv("GODEBUG", "rsa1024min=0") -- if boring.Enabled && rand == boring.RandReader { -+ if boring.Enabled() && rand == boring.RandReader { - bkey, err := boringPrivateKey(priv) - if err != nil { - return nil, err -@@ -342,7 +342,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, - // The inputs are not considered confidential, and may leak through timing side - // channels, or if an attacker has control of part of the inputs. - func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error { -- if boring.Enabled { + msg := []byte("Thu Dec 19 18:06:16 EST 2013\n") +@@ -268,6 +315,9 @@ func TestUnpaddedSignature(t *testing.T) { + } + + func TestShortSessionKey(t *testing.T) { + if boring.Enabled() { - bkey, err := boringPublicKey(pub) - if err != nil { - return err ++ t.Skip("test not applicable in FIPS mode") ++ } + // This tests that attempting to decrypt a session key where the + // ciphertext is too small doesn't run outside the array bounds. + ciphertext, err := EncryptPKCS1v15(rand.Reader, &rsaPrivateKey.PublicKey, []byte{1}) diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go -index 4ad20c1c9a..7acfe125e2 100644 +index e03f4ab066..2a18d7a553 100644 --- a/src/crypto/rsa/pss_test.go +++ b/src/crypto/rsa/pss_test.go -@@ -79,7 +79,7 @@ func TestEMSAPSS(t *testing.T) { - // TestPSSGolden tests all the test vectors in pss-vect.txt from - // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip - func TestPSSGolden(t *testing.T) { -- if boring.Enabled && !boringtest.Supports(t, "SHA1") { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { - t.Skip("skipping PSS test with BoringCrypto: SHA-1 not allowed") - } - inFile, err := os.Open("testdata/pss-vect.txt.bz2") -@@ -173,7 +173,7 @@ func TestPSSGolden(t *testing.T) { +@@ -8,6 +8,7 @@ import ( + "bufio" + "compress/bzip2" + "crypto" ++ boring "crypto/internal/backend" + "crypto/internal/fips140" + "crypto/rand" + . "crypto/rsa" +@@ -104,6 +105,15 @@ func TestPSSGolden(t *testing.T) { + hashed = h.Sum(hashed[:0]) + + if err := VerifyPSS(key, hash, hashed, sig, opts); err != nil { ++ // The real error error is: ++ // error:1C8000AE:Provider routines::digest not allowed ++ // providers/implementations/signature/rsa_sig.c:321 ++ // pss_test.go:108: crypto/rsa: verification error ++ // ++ // But the Go code hides it. Either way it's expected to not support SHA1 in FIPS mode. ++ if boring.Enabled() && strings.Contains(err.Error(), "crypto/rsa: verification error") { ++ continue ++ } + t.Error(err) + } + default: +@@ -115,6 +125,9 @@ func TestPSSGolden(t *testing.T) { // TestPSSOpenSSL ensures that we can verify a PSS signature from OpenSSL with // the default options. OpenSSL sets the salt length to be maximal. func TestPSSOpenSSL(t *testing.T) { -- if boring.Enabled { + if boring.Enabled() { - t.Skip("skipping PSS test with BoringCrypto: too short key") ++ t.Skip("test is not applicable in FIPS mode") ++ } + t.Setenv("GODEBUG", "rsa1024min=0") + + hash := crypto.SHA256 +@@ -161,38 +174,62 @@ func TestPSSSigning(t *testing.T) { + {42, PSSSaltLengthAuto, true, true}, + // In FIPS mode, PSSSaltLengthAuto is capped at PSSSaltLengthEqualsHash. + {PSSSaltLengthAuto, PSSSaltLengthEqualsHash, false, true}, ++ // {PSSSaltLengthEqualsHash, PSSSaltLengthEqualsHash, false, true}, + {PSSSaltLengthAuto, 106, true, false}, ++ // {PSSSaltLengthEqualsHash, 32, false, true}, + {PSSSaltLengthAuto, 20, false, true}, + {PSSSaltLengthAuto, -2, false, false}, } -@@ -209,7 +209,7 @@ func TestPSSNilOpts(t *testing.T) { ++ if boring.Enabled() { ++ saltLengthCombinations[7] = struct { ++ signSaltLength, verifySaltLength int ++ good, fipsGood bool ++ }{PSSSaltLengthEqualsHash, PSSSaltLengthEqualsHash, false, true} ++ saltLengthCombinations[9] = struct { ++ signSaltLength, verifySaltLength int ++ good, fipsGood bool ++ }{PSSSaltLengthEqualsHash, 32, false, true} ++ } ++ + hash := crypto.SHA1 ++ if boring.Enabled() { ++ hash = crypto.SHA256 ++ } + h := hash.New() + h.Write([]byte("testing")) + hashed := h.Sum(nil) + var opts PSSOptions + ++ key := rsaPrivateKey ++ if boring.Enabled() { ++ key = test2048Key ++ } ++ + for i, test := range saltLengthCombinations { + opts.SaltLength = test.signSaltLength +- sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts) ++ sig, err := SignPSS(rand.Reader, key, hash, hashed, &opts) + if err != nil { + t.Errorf("#%d: error while signing: %s", i, err) + continue + } + + opts.SaltLength = test.verifySaltLength +- err = VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, &opts) ++ err = VerifyPSS(&key.PublicKey, hash, hashed, sig, &opts) + good := test.good +- if fips140.Enabled { ++ if fips140.Enabled || boring.Enabled() { + good = test.fipsGood + } + if (err == nil) != good { +- t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err) ++ t.Errorf("#%d: bad result, wanted: %t, got: %s", i, good, err) + } + } } - func TestPSSSigning(t *testing.T) { -- if boring.Enabled && !boringtest.Supports(t, "SHA1") { -+ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { - t.Skip("skipping PSS test with BoringCrypto: too short key") + func TestPSS513(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not applicable in FIPS mode") ++ } + // See Issue 42741, and separately, RFC 8017: "Note that the octet length of + // EM will be one less than k if modBits - 1 is divisible by 8 and equal to + // k otherwise, where k is the length in octets of the RSA modulus n." +@@ -247,11 +284,13 @@ func TestInvalidPSSSaltLength(t *testing.T) { + } + + digest := sha256.Sum256([]byte("message")) ++ // We don't check the specific error here, because crypto/rsa and crypto/internal/boring ++ // return different errors, so we just check that _an error_ was returned. + if _, err := SignPSS(rand.Reader, key, crypto.SHA256, digest[:], &PSSOptions{ + SaltLength: -2, + Hash: crypto.SHA256, +- }); err.Error() != "crypto/rsa: invalid PSS salt length" { +- t.Fatalf("SignPSS unexpected error: got %v, want %v", err, "crypto/rsa: invalid PSS salt length") ++ }); err == nil { ++ t.Fatal("SignPSS unexpected success") } + // We don't check the specific error here, because crypto/rsa and crypto/internal/boring diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go -index 4d78d1eaaa..725dc563f6 100644 +index 95bb4becd2..7b01e0b8b6 100644 --- a/src/crypto/rsa/rsa.go +++ b/src/crypto/rsa/rsa.go -@@ -27,8 +27,8 @@ package rsa +@@ -42,8 +42,8 @@ package rsa + import ( "crypto" - "crypto/internal/bigmod" - "crypto/internal/boring" - "crypto/internal/boring/bbig" + boring "crypto/internal/backend" + "crypto/internal/backend/bbig" - "crypto/internal/randutil" - "crypto/rand" - "crypto/subtle" -@@ -297,7 +297,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { - func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { - randutil.MaybeReadByte(random) + "crypto/internal/fips140/bigmod" + "crypto/internal/fips140/rsa" + "crypto/internal/fips140only" +@@ -280,7 +280,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { + return nil, err + } -- if boring.Enabled && random == boring.RandReader && nprimes == 2 && -+ if boring.Enabled() && random == boring.RandReader && nprimes == 2 && +- if boring.Enabled && random == boring.RandReader && ++ if boring.Enabled() && random == boring.RandReader && (bits == 2048 || bits == 3072 || bits == 4096) { bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits) if err != nil { -@@ -528,7 +528,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l - return nil, ErrMessageTooLong - } - -- if boring.Enabled && random == boring.RandReader { -+ if boring.Enabled() && random == boring.RandReader { - bkey, err := boringPublicKey(pub) - if err != nil { - return nil, err -@@ -557,7 +557,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l - mgf1XOR(db, hash, seed) - mgf1XOR(seed, hash, db) - -- if boring.Enabled { -+ if boring.Enabled() { - var bkey *boring.PublicKeyRSA - bkey, err = boringPublicKey(pub) - if err != nil { -@@ -718,7 +718,7 @@ func decryptOAEP(hash, mgfHash hash.Hash, random io.Reader, priv *PrivateKey, ci - return nil, ErrDecryption - } - -- if boring.Enabled { -+ if boring.Enabled() { - bkey, err := boringPrivateKey(priv) - if err != nil { - return nil, err diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go -index 437e0c219d..e6b5e266a8 100644 +index 73b0c3749e..f6749c8463 100644 --- a/src/crypto/rsa/rsa_test.go +++ b/src/crypto/rsa/rsa_test.go @@ -8,7 +8,7 @@ import ( @@ -3112,89 +4213,161 @@ index 437e0c219d..e6b5e266a8 100644 "crypto" - "crypto/internal/boring" + boring "crypto/internal/backend" + "crypto/internal/cryptotest" "crypto/rand" . "crypto/rsa" - "crypto/sha1" -@@ -34,7 +34,7 @@ func TestKeyGeneration(t *testing.T) { - if bits := priv.N.BitLen(); bits != size { - t.Errorf("key too short (%d vs %d)", bits, size) - } -- if boring.Enabled && size < 1024 { -+ if boring.Enabled() && size < 1024 { - t.Logf("skipping short key with BoringCrypto: %d", size) - continue - } -@@ -120,12 +120,12 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { - t.Errorf("private exponent too large") +@@ -36,8 +36,19 @@ func TestKeyGeneration(t *testing.T) { + if err == nil { + t.Errorf("GenerateKey(%d) succeeded without GODEBUG", size) + } ++ if boring.Enabled() { ++ if err != nil { ++ if strings.Contains(err.Error(), "invalid key length") { ++ t.Errorf("unexpected error in FIPS mode %#v", err) ++ } ++ } ++ return ++ } + t.Setenv("GODEBUG", "rsa1024min=0") + } ++ if boring.Enabled() && size == 1024 { ++ t.Skip("we've already tested the proper error is returned with smaller keys") ++ } + priv, err := GenerateKey(rand.Reader, size) + if err != nil { + t.Errorf("GenerateKey(%d): %v", size, err) +@@ -51,11 +62,17 @@ func TestKeyGeneration(t *testing.T) { + } + + func Test3PrimeKeyGeneration(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not applicable in FIPS mode") ++ } + size := 1024 + if testing.Short() { + t.Setenv("GODEBUG", "rsa1024min=0") + size = 256 } ++ if boring.Enabled() { ++ size = 2048 ++ } -- if boring.Enabled { + priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size) + if err != nil { +@@ -65,11 +82,17 @@ func Test3PrimeKeyGeneration(t *testing.T) { + } + + func Test4PrimeKeyGeneration(t *testing.T) { + if boring.Enabled() { - // Cannot call encrypt/decrypt with raw RSA. PKCSv1.5 - // not supported in some configurations. Test with - // OAEP if possible (i.e., key size is equal to or - // longer than 2048 bits). -- if bits := priv.N.BitLen(); boring.Enabled && bits < 2048 { -+ if bits := priv.N.BitLen(); boring.Enabled() && bits < 2048 { - t.Logf("skipping short key with BoringCrypto: %d", bits) - return - } -@@ -167,7 +167,7 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { ++ t.Skip("test not applicable in FIPS mode") ++ } + size := 1024 + if testing.Short() { + t.Setenv("GODEBUG", "rsa1024min=0") + size = 256 + } ++ if boring.Enabled() { ++ size = 2048 ++ } + + priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size) + if err != nil { +@@ -79,6 +102,9 @@ func Test4PrimeKeyGeneration(t *testing.T) { } - func TestAllocations(t *testing.T) { -- if boring.Enabled { + func TestNPrimeKeyGeneration(t *testing.T) { + if boring.Enabled() { - t.Skip("skipping allocations test with BoringCrypto") ++ t.Skip("test not applicable to FIPS mode") ++ } + t.Setenv("GODEBUG", "rsa1024min=0") + primeSize := 64 + maxN := 24 +@@ -127,6 +153,9 @@ func TestTinyKeyGeneration(t *testing.T) { + } + + func TestGnuTLSKey(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not applicable in FIPS mode") ++ } + t.Setenv("GODEBUG", "rsa1024min=0") + // This is a key generated by `certtool --generate-privkey --bits 128`. + // It's such that de ≢ 1 mod φ(n), but is congruent mod the order of +@@ -150,6 +179,10 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { + msg := []byte("hi!") + enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg) + if err != nil { ++ if boring.Enabled() && (strings.Contains(err.Error(), "illegal or unsupported padding mode") || strings.Contains(err.Error(), "invalid padding mode")) { ++ // This error is expected in FIPS mode ++ return ++ } + t.Errorf("EncryptPKCS1v15: %v", err) + return } - testenv.SkipIfOptimizationOff(t) -@@ -213,7 +213,7 @@ func TestEverything(t *testing.T) { - if bits := priv.N.BitLen(); bits != size { - t.Errorf("key too short (%d vs %d)", bits, size) - } -- if boring.Enabled && size < 2048 { -+ if boring.Enabled() && size < 2048 { - t.Skip("skipping short key with BoringCrypto") - } - testEverything(t, priv) -@@ -677,7 +677,7 @@ func TestEncryptOAEP(t *testing.T) { - n := new(big.Int) - for i, test := range testEncryptOAEPData { - n.SetString(test.modulus, 16) -- if boring.Enabled { -+ if boring.Enabled() { - t.Log("skipping test in FIPS mode due to short keys and unpadded RSA operations not allowed with FIPS") - continue - } -@@ -704,7 +704,7 @@ func TestDecryptOAEP(t *testing.T) { - d := new(big.Int) - for i, test := range testEncryptOAEPData { - n.SetString(test.modulus, 16) -- if boring.Enabled && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { -+ if boring.Enabled() && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { - t.Logf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) - continue - } -@@ -751,7 +751,7 @@ func Test2DecryptOAEP(t *testing.T) { - sha1 := crypto.SHA1 - sha256 := crypto.SHA256 +@@ -189,6 +222,10 @@ func TestAllocations(t *testing.T) { + var allFlag = flag.Bool("all", false, "test all key sizes up to 2048") -- if boring.Enabled && n.BitLen() < 2048 { -+ if boring.Enabled() && n.BitLen() < 2048 { - t.Skipf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) + func TestEverything(t *testing.T) { ++ if boring.Enabled() { ++ testEverything(t, test2048Key) ++ return ++ } + if testing.Short() { + // Skip key generation, but still test real sizes. + for _, key := range []*PrivateKey{test1024Key, test2048Key} { +@@ -232,6 +269,10 @@ func testEverything(t *testing.T, priv *PrivateKey) { + if err == ErrMessageTooLong { + t.Log("key too small for EncryptPKCS1v15") + } else if err != nil { ++ if boring.Enabled() && (strings.Contains(err.Error(), "illegal or unsupported padding mode") || strings.Contains(err.Error(), "invalid padding mode")) { ++ // OpenSSL 3 does not support this padding mode in FIPS ++ return ++ } + t.Errorf("EncryptPKCS1v15: %v", err) } + if err == nil { +@@ -831,6 +872,10 @@ func TestDecryptOAEP(t *testing.T) { + private.D = d -@@ -770,7 +770,7 @@ func TestEncryptDecryptOAEP(t *testing.T) { - d := new(big.Int) - for i, test := range testEncryptOAEPData { - n.SetString(test.modulus, 16) -- if boring.Enabled && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { -+ if boring.Enabled() && !boringtest.Supports(t, "RSA1024") && n.BitLen() < 2048 { - t.Logf("skipping encryption tests with BoringCrypto: too short key: %d", n.BitLen()) - continue - } + for j, message := range test.msgs { ++ if private.Size() < 256 && boring.Enabled() { ++ // Skip these tests in FIPS mode ++ continue ++ } + out, err := DecryptOAEP(sha1, nil, private, message.out, nil) + if err != nil { + t.Errorf("#%d,%d error: %s", i, j, err) +@@ -853,6 +898,9 @@ func TestDecryptOAEP(t *testing.T) { + } + + func Test2DecryptOAEP(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant in FIPS mode") ++ } + random := rand.Reader + + msg := []byte{0xed, 0x36, 0x90, 0x8d, 0xbe, 0xfc, 0x35, 0x40, 0x70, 0x4f, 0xf5, 0x9d, 0x6e, 0xc2, 0xeb, 0xf5, 0x27, 0xae, 0x65, 0xb0, 0x59, 0x29, 0x45, 0x25, 0x8c, 0xc1, 0x91, 0x22} +@@ -892,6 +940,10 @@ func TestEncryptDecryptOAEP(t *testing.T) { + label := []byte(fmt.Sprintf("hi#%d", j)) + enc, err := EncryptOAEP(sha256, rand.Reader, &priv.PublicKey, message.in, label) + if err != nil { ++ if priv.Size() < 256 && boring.Enabled() && strings.Contains(err.Error(), "invalid key length") { ++ // This error is expected with small key sizes in FIPS mode. ++ continue ++ } + t.Errorf("#%d,%d: EncryptOAEP: %v", i, j, err) + continue + } +@@ -1066,7 +1118,7 @@ v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs + /5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00 + -----END RSA TESTING KEY-----`)) + t.Setenv("GODEBUG", "rsa1024min=0") +- if boring.Enabled { ++ if boring.Enabled() { + t.Skip("BoringCrypto mode returns the wrong error from SignPSS") + } + testEverything(t, k) diff --git a/src/crypto/sha1/sha1.go b/src/crypto/sha1/sha1.go -index c0742b9d83..2541e14323 100644 +index d2ffaac0ae..a077e1cd6d 100644 --- a/src/crypto/sha1/sha1.go +++ b/src/crypto/sha1/sha1.go @@ -10,7 +10,7 @@ package sha1 @@ -3203,19 +4376,19 @@ index c0742b9d83..2541e14323 100644 "crypto" - "crypto/internal/boring" + boring "crypto/internal/backend" + "crypto/internal/fips140only" "errors" "hash" - "internal/byteorder" -@@ -103,7 +103,7 @@ func (d *digest) Reset() { - // implements [encoding.BinaryMarshaler] and [encoding.BinaryUnmarshaler] to - // marshal and unmarshal the internal state of the hash. +@@ -108,7 +108,7 @@ func (d *digest) Reset() { + // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal + // state of the hash. func New() hash.Hash { - if boring.Enabled { + if boring.Enabled() { return boring.NewSHA1() } d := new(digest) -@@ -250,7 +250,7 @@ func (d *digest) constSum() [Size]byte { +@@ -266,7 +266,7 @@ func (d *digest) constSum() [Size]byte { // Sum returns the SHA-1 checksum of the data. func Sum(data []byte) [Size]byte { @@ -3223,9 +4396,9 @@ index c0742b9d83..2541e14323 100644 + if boring.Enabled() { return boring.SHA1(data) } - var d digest + if fips140only.Enabled { diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go -index 634ab9de1b..79a248913d 100644 +index 9d707b7cde..74b206d623 100644 --- a/src/crypto/sha1/sha1_test.go +++ b/src/crypto/sha1/sha1_test.go @@ -8,7 +8,7 @@ package sha1 @@ -3245,8 +4418,8 @@ index 634ab9de1b..79a248913d 100644 + if boring.Enabled() { continue } - io.WriteString(c, g.in[0:len(g.in)/2]) -@@ -146,7 +146,7 @@ func TestBlockSize(t *testing.T) { + io.WriteString(c, g.in[:len(g.in)/2]) +@@ -158,7 +158,7 @@ func TestBlockSize(t *testing.T) { // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match. func TestBlockGeneric(t *testing.T) { @@ -3255,17 +4428,8 @@ index 634ab9de1b..79a248913d 100644 t.Skip("BoringCrypto doesn't expose digest") } for i := 1; i < 30; i++ { // arbitrary factor -@@ -219,7 +219,7 @@ func TestLargeHashes(t *testing.T) { - } - - func TestAllocations(t *testing.T) { -- if boring.Enabled { -+ if boring.Enabled() { - t.Skip("BoringCrypto doesn't allocate the same way as stdlib") - } - in := []byte("hello, world!") diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go -index 68244fd63b..975fdfa6cc 100644 +index 069938a22d..ec5e84285a 100644 --- a/src/crypto/sha256/sha256.go +++ b/src/crypto/sha256/sha256.go @@ -8,7 +8,7 @@ package sha256 @@ -3274,10 +4438,10 @@ index 68244fd63b..975fdfa6cc 100644 "crypto" - "crypto/internal/boring" + boring "crypto/internal/backend" - "errors" + "crypto/internal/fips140/sha256" "hash" - "internal/byteorder" -@@ -143,7 +143,7 @@ func (d *digest) Reset() { + ) +@@ -32,7 +32,7 @@ const BlockSize = 64 // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal // state of the hash. func New() hash.Hash { @@ -3285,17 +4449,17 @@ index 68244fd63b..975fdfa6cc 100644 + if boring.Enabled() { return boring.NewSHA256() } - d := new(digest) -@@ -153,7 +153,7 @@ func New() hash.Hash { - - // New224 returns a new hash.Hash computing the SHA224 checksum. + return sha256.New() +@@ -43,7 +43,7 @@ func New() hash.Hash { + // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal + // state of the hash. func New224() hash.Hash { - if boring.Enabled { + if boring.Enabled() { return boring.NewSHA224() } - d := new(digest) -@@ -246,7 +246,7 @@ func (d *digest) checkSum() [Size]byte { + return sha256.New224() +@@ -51,7 +51,7 @@ func New224() hash.Hash { // Sum256 returns the SHA256 checksum of the data. func Sum256(data []byte) [Size]byte { @@ -3303,8 +4467,8 @@ index 68244fd63b..975fdfa6cc 100644 + if boring.Enabled() { return boring.SHA256(data) } - var d digest -@@ -257,7 +257,7 @@ func Sum256(data []byte) [Size]byte { + h := New() +@@ -63,7 +63,7 @@ func Sum256(data []byte) [Size]byte { // Sum224 returns the SHA224 checksum of the data. func Sum224(data []byte) [Size224]byte { @@ -3312,40 +4476,9 @@ index 68244fd63b..975fdfa6cc 100644 + if boring.Enabled() { return boring.SHA224(data) } - var d digest -diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go -index d91f01e9ba..afdb2685ca 100644 ---- a/src/crypto/sha256/sha256_test.go -+++ b/src/crypto/sha256/sha256_test.go -@@ -8,7 +8,7 @@ package sha256 - - import ( - "bytes" -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "crypto/internal/cryptotest" - "crypto/rand" - "encoding" -@@ -218,7 +218,7 @@ func TestBlockSize(t *testing.T) { - - // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match. - func TestBlockGeneric(t *testing.T) { -- if boring.Enabled { -+ if boring.Enabled() { - t.Skip("BoringCrypto doesn't expose digest") - } - gen, asm := New().(*digest), New().(*digest) -@@ -295,7 +295,7 @@ func TestLargeHashes(t *testing.T) { - } - - func TestAllocations(t *testing.T) { -- if boring.Enabled { -+ if boring.Enabled() { - t.Skip("BoringCrypto doesn't allocate the same way as stdlib") - } - in := []byte("hello, world!") + h := New224() diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go -index dde83625f7..79b401b136 100644 +index 1435eac1f5..a1f4da66c3 100644 --- a/src/crypto/sha512/sha512.go +++ b/src/crypto/sha512/sha512.go @@ -12,7 +12,7 @@ package sha512 @@ -3354,28 +4487,28 @@ index dde83625f7..79b401b136 100644 "crypto" - "crypto/internal/boring" + boring "crypto/internal/backend" - "errors" + "crypto/internal/fips140/sha512" "hash" - "internal/byteorder" -@@ -203,7 +203,7 @@ func consumeUint64(b []byte) ([]byte, uint64) { - - // New returns a new hash.Hash computing the SHA-512 checksum. + ) +@@ -47,7 +47,7 @@ const ( + // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal + // state of the hash. func New() hash.Hash { - if boring.Enabled { + if boring.Enabled() { return boring.NewSHA512() } - d := &digest{function: crypto.SHA512} -@@ -227,7 +227,7 @@ func New512_256() hash.Hash { - - // New384 returns a new hash.Hash computing the SHA-384 checksum. + return sha512.New() +@@ -74,7 +74,7 @@ func New512_256() hash.Hash { + // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal + // state of the hash. func New384() hash.Hash { - if boring.Enabled { + if boring.Enabled() { return boring.NewSHA384() } - d := &digest{function: crypto.SHA384} -@@ -338,7 +338,7 @@ func (d *digest) checkSum() [Size]byte { + return sha512.New384() +@@ -82,7 +82,7 @@ func New384() hash.Hash { // Sum512 returns the SHA512 checksum of the data. func Sum512(data []byte) [Size]byte { @@ -3383,8 +4516,8 @@ index dde83625f7..79b401b136 100644 + if boring.Enabled() { return boring.SHA512(data) } - d := digest{function: crypto.SHA512} -@@ -349,7 +349,7 @@ func Sum512(data []byte) [Size]byte { + h := New() +@@ -94,7 +94,7 @@ func Sum512(data []byte) [Size]byte { // Sum384 returns the SHA384 checksum of the data. func Sum384(data []byte) [Size384]byte { @@ -3392,171 +4525,9 @@ index dde83625f7..79b401b136 100644 + if boring.Enabled() { return boring.SHA384(data) } - d := digest{function: crypto.SHA384} -diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go -index a1ff571383..ece4cf72eb 100644 ---- a/src/crypto/sha512/sha512_test.go -+++ b/src/crypto/sha512/sha512_test.go -@@ -8,7 +8,7 @@ package sha512 - - import ( - "bytes" -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "crypto/internal/cryptotest" - "crypto/rand" - "encoding" -@@ -824,7 +824,7 @@ func TestBlockSize(t *testing.T) { - - // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match. - func TestBlockGeneric(t *testing.T) { -- if boring.Enabled { -+ if boring.Enabled() { - t.Skip("BoringCrypto doesn't expose digest") - } - gen, asm := New().(*digest), New().(*digest) -@@ -894,7 +894,7 @@ func TestLargeHashes(t *testing.T) { - } - - func TestAllocations(t *testing.T) { -- if boring.Enabled { -+ if boring.Enabled() { - t.Skip("BoringCrypto doesn't allocate the same way as stdlib") - } - in := []byte("hello, world!") -diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go -index 7780631527..4142faa0eb 100644 ---- a/src/crypto/tls/boring.go -+++ b/src/crypto/tls/boring.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --//go:build boringcrypto -+//go:build !no_openssl - - package tls - -@@ -12,13 +12,13 @@ import ( - ) - - func init() { -- if boring.Enabled && !boring.ExecutingTest() { -+ if boring.Enabled() && !boring.ExecutingTest() { - fipstls.Force() - } - } - - // needFIPS returns fipstls.Required(), which is not available without the --// boringcrypto build tag. -+// !no_openssl build tag. - func needFIPS() bool { - return fipstls.Required() - } -diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go -index d70ed9c076..59def234e1 100644 ---- a/src/crypto/tls/boring_test.go -+++ b/src/crypto/tls/boring_test.go -@@ -2,14 +2,14 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --//go:build boringcrypto -+//go:build !no_openssl - - package tls - - import ( - "crypto/ecdsa" - "crypto/elliptic" -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "crypto/internal/backend/boringtest" - "crypto/internal/boring/fipstls" - "crypto/rand" -@@ -54,7 +54,7 @@ func TestBoringServerProtocolVersion(t *testing.T) { - test(t, "VersionTLS10", VersionTLS10, "") - test(t, "VersionTLS11", VersionTLS11, "") - test(t, "VersionTLS12", VersionTLS12, "") -- if boring.Enabled && !boring.SupportsHKDF() { -+ if boring.Enabled() && !boring.SupportsHKDF() { - test(t, "VersionTLS13", VersionTLS13, "client offered only unsupported versions") - } else { - test(t, "VersionTLS13", VersionTLS13, "") -@@ -245,7 +245,7 @@ func TestBoringServerSignatureAndHash(t *testing.T) { - - clientConfig := testConfig.Clone() - -- if boring.Enabled { -+ if boring.Enabled() { - serverConfig.Rand = boring.RandReader - clientConfig.Rand = boring.RandReader - } -@@ -376,7 +376,7 @@ func TestBoringCertAlgs(t *testing.T) { - serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}} - serverConfig.BuildNameToCertificate() - -- if boring.Enabled { -+ if boring.Enabled() { - serverConfig.Rand = boring.RandReader - clientConfig.Rand = boring.RandReader - } -@@ -407,13 +407,13 @@ func TestBoringCertAlgs(t *testing.T) { - serverConfig := testConfig.Clone() - serverConfig.ClientCAs = pool - serverConfig.ClientAuth = RequireAndVerifyClientCert -- if boring.Enabled { -+ if boring.Enabled() { - serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate} - serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey - serverConfig.BuildNameToCertificate() - } - -- if boring.Enabled { -+ if boring.Enabled() { - serverConfig.Rand = boring.RandReader - clientConfig.Rand = boring.RandReader - } -@@ -439,8 +439,8 @@ func TestBoringCertAlgs(t *testing.T) { - // exhaustive test with computed answers. - r1pool := x509.NewCertPool() - r1pool.AddCert(R1.cert) -- testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, !(L2_I.notBoring && boring.Enabled)) -- testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, !(L2_I.notBoring && boring.Enabled)) -+ testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, !(L2_I.notBoring && boring.Enabled())) -+ testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, !(L2_I.notBoring && boring.Enabled())) - fipstls.Force() - testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false) - testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false) -@@ -461,7 +461,7 @@ func TestBoringCertAlgs(t *testing.T) { - leaf = L2_I - } - for i := 0; i < 64; i++ { -- reachable := map[string]bool{leaf.parentOrg: !(leaf.notBoring && boring.Enabled)} -+ reachable := map[string]bool{leaf.parentOrg: !(leaf.notBoring && boring.Enabled())} - reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK} - list := [][]byte{leaf.der} - listName := leaf.name -@@ -469,7 +469,7 @@ func TestBoringCertAlgs(t *testing.T) { - if cond != 0 { - list = append(list, c.der) - listName += "," + c.name -- if reachable[c.org] && !(c.notBoring && boring.Enabled) { -+ if reachable[c.org] && !(c.notBoring && boring.Enabled()) { - reachable[c.parentOrg] = true - } - if reachableFIPS[c.org] && c.fipsOK { -@@ -493,7 +493,7 @@ func TestBoringCertAlgs(t *testing.T) { - if cond != 0 { - rootName += "," + c.name - pool.AddCert(c.cert) -- if reachable[c.org] && !(c.notBoring && boring.Enabled) { -+ if reachable[c.org] && !(c.notBoring && boring.Enabled()) { - shouldVerify = true - } - if reachableFIPS[c.org] && c.fipsOK { + h := New384() diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go -index 58b3dae14b..29948c59a5 100644 +index 01d6568828..6cae8be568 100644 --- a/src/crypto/tls/cipher_suites.go +++ b/src/crypto/tls/cipher_suites.go @@ -10,7 +10,7 @@ import ( @@ -3565,10 +4536,10 @@ index 58b3dae14b..29948c59a5 100644 "crypto/hmac" - "crypto/internal/boring" + boring "crypto/internal/backend" + fipsaes "crypto/internal/fips140/aes" + "crypto/internal/fips140/aes/gcm" "crypto/rc4" - "crypto/sha1" - "crypto/sha256" -@@ -432,7 +432,7 @@ func macSHA1(key []byte) hash.Hash { +@@ -427,7 +427,7 @@ func macSHA1(key []byte) hash.Hash { h := sha1.New // The BoringCrypto SHA1 does not have a constant-time // checksum function, so don't try to use it. @@ -3577,7 +4548,7 @@ index 58b3dae14b..29948c59a5 100644 h = newConstantTimeHash(h) } return hmac.New(h, key) -@@ -524,7 +524,7 @@ func aeadAESGCM(key, noncePrefix []byte) aead { +@@ -519,7 +519,7 @@ func aeadAESGCM(key, noncePrefix []byte) aead { panic(err) } var aead cipher.AEAD @@ -3586,164 +4557,427 @@ index 58b3dae14b..29948c59a5 100644 aead, err = boring.NewGCMTLS(aes) } else { boring.Unreachable() +@@ -553,7 +553,7 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead { + panic(err) + } + var aead cipher.AEAD +- if boring.Enabled { ++ if boring.Enabled() { + aead, err = boring.NewGCMTLS13(aes) + } else { + boring.Unreachable() diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go -index 9b398ffd68..0b5e6848b8 100644 +index d6942d2ef1..c89121131e 100644 --- a/src/crypto/tls/common.go +++ b/src/crypto/tls/common.go -@@ -12,7 +12,7 @@ import ( +@@ -12,6 +12,7 @@ import ( "crypto/ecdsa" "crypto/ed25519" "crypto/elliptic" -- "crypto/internal/boring" + boring "crypto/internal/backend" "crypto/rand" "crypto/rsa" "crypto/sha512" -@@ -1089,7 +1089,7 @@ var tls10server = godebug.New("tls10server") +@@ -1138,6 +1139,9 @@ var tls10server = godebug.New("tls10server") func (c *Config) supportedVersions(isClient bool) []uint16 { versions := make([]uint16, 0, len(supportedVersions)) for _, v := range supportedVersions { -- if boring.Enabled && !boring.SupportsHKDF() && v > VersionTLS12 { + if boring.Enabled() && !boring.SupportsHKDF() && v > VersionTLS12 { ++ continue ++ } + if fips140tls.Required() && !slices.Contains(defaultSupportedVersionsFIPS, v) { continue } - if needFIPS() && !slices.Contains(defaultSupportedVersionsFIPS, v) { +diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go +index c0396e7579..85e6f18e32 100644 +--- a/src/crypto/tls/handshake_client_tls13.go ++++ b/src/crypto/tls/handshake_client_tls13.go +@@ -9,6 +9,7 @@ import ( + "context" + "crypto" + "crypto/hmac" ++ boring "crypto/internal/backend" + "crypto/internal/fips140/hkdf" + "crypto/internal/fips140/mlkem" + "crypto/internal/fips140/tls13" +@@ -45,6 +46,10 @@ type clientHandshakeStateTLS13 struct { + // handshake requires hs.c, hs.hello, hs.serverHello, hs.keyShareKeys, and, + // optionally, hs.session, hs.earlySecret and hs.binderKey to be set. + func (hs *clientHandshakeStateTLS13) handshake() error { ++ if boring.Enabled() && !boring.SupportsHKDF() { ++ return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode") ++ } ++ + c := hs.c + + // The server must not select TLS 1.3 in a renegotiation. See RFC 8446, +diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go +index 76fff6974e..c121172b79 100644 +--- a/src/crypto/tls/handshake_server_tls13.go ++++ b/src/crypto/tls/handshake_server_tls13.go +@@ -9,6 +9,7 @@ import ( + "context" + "crypto" + "crypto/hmac" ++ boring "crypto/internal/backend" + "crypto/internal/fips140/hkdf" + "crypto/internal/fips140/mlkem" + "crypto/internal/fips140/tls13" +@@ -63,6 +64,9 @@ type serverHandshakeStateTLS13 struct { + } + + func (hs *serverHandshakeStateTLS13) handshake() error { ++ if boring.Enabled() && !boring.SupportsHKDF() { ++ return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode") ++ } + c := hs.c + + // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2. diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go -index 118678019a..dded8f6560 100644 +index 38d6d3f7be..d0338ca246 100644 --- a/src/crypto/tls/key_schedule.go +++ b/src/crypto/tls/key_schedule.go -@@ -8,7 +8,7 @@ import ( +@@ -7,6 +7,7 @@ package tls + import ( "crypto/ecdh" "crypto/hmac" - "crypto/internal/mlkem768" -- "crypto/internal/boring" + boring "crypto/internal/backend" + "crypto/internal/fips140/mlkem" + "crypto/internal/fips140/tls13" "errors" - "fmt" - "hash" -@@ -62,7 +62,7 @@ func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []by - panic(fmt.Errorf("failed to construct HKDF label: %s", err)) +@@ -20,13 +21,13 @@ import ( + // nextTrafficSecret generates the next traffic secret, given the current one, + // according to RFC 8446, Section 7.2. + func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte { +- return tls13.ExpandLabel(c.hash.New, trafficSecret, "traffic upd", nil, c.hash.Size()) ++ return expandLabel(c.hash.New, trafficSecret, "traffic upd", nil, c.hash.Size()) + } + + // trafficKey generates traffic keys according to RFC 8446, Section 7.3. + func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) { +- key = tls13.ExpandLabel(c.hash.New, trafficSecret, "key", nil, c.keyLen) +- iv = tls13.ExpandLabel(c.hash.New, trafficSecret, "iv", nil, aeadNonceLength) ++ key = expandLabel(c.hash.New, trafficSecret, "key", nil, c.keyLen) ++ iv = expandLabel(c.hash.New, trafficSecret, "iv", nil, aeadNonceLength) + return + } + +@@ -34,7 +35,7 @@ func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) { + // to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey + // selection. + func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte { +- finishedKey := tls13.ExpandLabel(c.hash.New, baseKey, "finished", nil, c.hash.Size()) ++ finishedKey := expandLabel(c.hash.New, baseKey, "finished", nil, c.hash.Size()) + verifyData := hmac.New(c.hash.New, finishedKey) + verifyData.Write(transcript.Sum(nil)) + return verifyData.Sum(nil) +@@ -97,3 +98,11 @@ func curveIDForCurve(curve ecdh.Curve) (CurveID, bool) { + return 0, false } - out := make([]byte, length) -- if boring.Enabled { + } ++ ++// expandLabel returns the value of tls13.ExpandLabel with the given arguments. ++func expandLabel(newFunc func() hash.Hash, secret []byte, label string, context []byte, length int) []byte { + if boring.Enabled() { - reader, err := boring.ExpandHKDF(c.hash.New, secret, hkdfLabelBytes) ++ panic("implement me") ++ } ++ return tls13.ExpandLabel(newFunc, secret, label, context, length) ++} +diff --git a/src/crypto/x509/pkcs8_test.go b/src/crypto/x509/pkcs8_test.go +index d0328800bc..825eb9dad7 100644 +--- a/src/crypto/x509/pkcs8_test.go ++++ b/src/crypto/x509/pkcs8_test.go +@@ -10,6 +10,7 @@ import ( + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" ++ boring "crypto/internal/backend" + "crypto/rsa" + "encoding/hex" + "reflect" +@@ -111,6 +112,9 @@ func TestPKCS8(t *testing.T) { + } + privKey, err := ParsePKCS8PrivateKey(derBytes) if err != nil { - panic("tls: HKDF-Expand-Label invocation failed unexpectedly") -@@ -93,7 +93,7 @@ func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte { - if newSecret == nil { - newSecret = make([]byte, c.hash.Size()) ++ if boring.Enabled() && strings.Contains(test.name, "X25519") && strings.Contains(err.Error(), "crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") { ++ t.Skip("error expected in FIPS mode") ++ } + t.Errorf("%s: failed to decode PKCS#8: %s", test.name, err) + continue + } +diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go +index f67f40778b..141f1996fe 100644 +--- a/src/crypto/x509/x509_test.go ++++ b/src/crypto/x509/x509_test.go +@@ -12,6 +12,7 @@ import ( + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" ++ boring "crypto/internal/backend" + "crypto/rand" + "crypto/rsa" + _ "crypto/sha256" +@@ -39,7 +40,7 @@ import ( + ) + + func TestParsePKCS1PrivateKey(t *testing.T) { +- block, _ := pem.Decode([]byte(pemPrivateKey)) ++ block, _ := pem.Decode([]byte(pemPrivateKeySmall)) + priv, err := ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + t.Errorf("Failed to parse private key: %s", err) +@@ -116,6 +117,9 @@ func testParsePKIXPublicKey(t *testing.T, pemBytes string) (pub any) { + block, _ := pem.Decode([]byte(pemBytes)) + pub, err := ParsePKIXPublicKey(block.Bytes) + if err != nil { ++ if boring.Enabled() && pemBytes == pemX25519Key && strings.Contains(err.Error(), "crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode") { ++ t.Skip("error is expected in FIPS mode") ++ } + t.Fatalf("Failed to parse public key: %s", err) } -- if boring.Enabled { -+ if boring.Enabled() { - ikm, err := boring.ExtractHKDF(c.hash.New, newSecret, currentSecret) - if err != nil { - panic("tls: HKDF-Extract invocation failed unexpectedly") -diff --git a/src/crypto/tls/notboring.go b/src/crypto/tls/notboring.go -index bdbc32e05b..2be319c7f1 100644 ---- a/src/crypto/tls/notboring.go -+++ b/src/crypto/tls/notboring.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. --//go:build !boringcrypto -+//go:build no_openssl +@@ -165,7 +169,7 @@ FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ + -----END PUBLIC KEY----- + ` - package tls +-var pemPrivateKey = testingKey(` ++var pemPrivateKeySmall = testingKey(` + -----BEGIN RSA TESTING KEY----- + MIICXAIBAAKBgQCxoeCUW5KJxNPxMp+KmCxKLc1Zv9Ny+4CFqcUXVUYH69L3mQ7v + IWrJ9GBfcaA7BPQqUlWxWM+OCEQZH1EZNIuqRMNQVuIGCbz5UQ8w6tS0gcgdeGX7 +@@ -183,6 +187,37 @@ wg/HcAJWY60xZTJDFN+Qfx8ZQvBEin6c2/h+zZi5IVY= + -----END RSA TESTING KEY----- + `) -diff --git a/src/crypto/x509/boring.go b/src/crypto/x509/boring.go -index 095b58c315..ac06591ea8 100644 ---- a/src/crypto/x509/boring.go -+++ b/src/crypto/x509/boring.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. ++// openssl genrsa -traditional 2048 (OpenSSL 3.2.2 4 Jun 2024) ++var pemPrivateKey = testingKey(` ++-----BEGIN RSA TESTING KEY----- ++MIIEowIBAAKCAQEAgpIIlBFwSB+Jul1ocZIZDvj77ReiJ+0DyidcpkYJQPPbZU9i ++lmbRcn9cSME6fEz+nZUqVrwwOGxWJU+IRrkNcStIC7dkCua8mzrUgALDTKnGJQme ++QPbyRik0VOgA5X0KNkBKsKUYhN1RH/xh0I6WqViyScYNsBPvMbLOcA/1zC7s8kQz ++iHGXmSK7HkZQHN5l0M3kySL1R66f5KcPsRjS6JGTv/uB2EbzNh9Yeh05aJfXnAya ++2lokIM1MapPo4UG6rhx8R58PXyNOwF5ohmOIxywVQz6unZdVCeDLF++esxsDhUjH ++SDBjjFkcIeTaYeAp0Y6SCpsGZ+SUu6i6HJ5gvwIDAQABAoIBAA9i/CXOxEeLh+Rx ++W3x+tftAthdjgJVp5ddtugpSGIcR9ZnDuB93MFlozsw4ERdSz3JsgJfGB3yur5wn +++iwzZHUgn5XZ3601MaatURtgt/kRzKrSrlaDg1tnQaZ7zJc+m/R2sRaN7gzCM+ws ++Bq7YDsMYE7KD51sHjllx88fa6aFM/0HBKuQC4UrT3rxuKzb6qow2sI5jWHPtO0if ++iQTDs9LpSGveboJVe/gQDju3cL61QuPIQ9/9p8bsOTemOsGBD5aurF/NIkHf4le+ ++oj4y5qKqyNbZhbDdDWuzDvgFweZJXiMy2fSkJNbZXtNirK4suNf53ZALNSn1QG4Q ++s8vfGzkCgYEAuEioKyWj2+f5MYJpJFNDziMMS4yU8e/BZptyNz7UnrCg0mWsbHyY ++SAng+AzhpkiO4NTwH3ee4mbTJZy3qGT8IoYws2v61pJeG2poRJ6fkTnUW5bahTYv ++x8mdcLk/B8QAVKvyElNjVycBqOVQXbIJdyI+nZlVtaesJTMm9x4aPcMCgYEAtWIp ++fGWpdaCdvB208QL8j0vc8/4TEsgCdumUyXQhxvF2/huILzicucXZdxL7c6E+pLxV ++RoGsg4FtVdhR+q9kST1b420+H/jRqCklgj/Vku4Nyf6E9ce1CrC3re7CSwYzCFRA ++OkKYbVHxdx9+LSuh06TH7ouQhVFT1gP6Uxn/tVUCgYAAvsJ3UjKka/609YsJS5Dl ++n3yoPYxIoiiNCqnekVF4xswPrbuRwLs451lSh3LOIlL5k8LYzboFvlayOzz+4FGo ++rhQ6VYBxJ6xbvgVn6aBJjQtPx39gtIRi8WzCjO01UdSSgxN6gX3QV2cJUMwPZO3m ++3muUZY9UKbZnfBp3O1bt0wKBgQCxMiyFMmvSVg7Cb+MMcHZ7Jwm780J+3pZJxPdt ++tt4olExDAnKQbyXs9rPz979evu+Lz9EfCB+YeSBu9N1hoWa/hgn2rAo9Ab8QIOJb ++1DC5UYZ3BwatdWQQBYPrj4yP7oZ8ZJI6WETAx4S1cza4uh9lu1z2VbHiDAly0oAC ++HywH4QKBgDSg66rVqZfN22kVThTszWBLgXY/uVAHlE5qollBdTw7obCcPOAY7w28 ++XOk9V9bdV9D07/OlNN+3gl222KxaJxyxVg5aYBxNwofdKCPEv8RYSEFBNS64tvs9 ++XPe2gKtZTb/pzmpwayz7iPXTVBwVrhY3qAb+N+ciEvlqJ0Dhrm2L ++-----END RSA TESTING KEY----- ++`) ++ + // pemEd25519Key is the example from RFC 8410, Section 4. + var pemEd25519Key = ` + -----BEGIN PUBLIC KEY----- +@@ -1457,6 +1492,7 @@ func TestParsePEMCRL(t *testing.T) { + } --//go:build boringcrypto -+//go:build !no_openssl + func TestImports(t *testing.T) { ++ t.Skip("skipping as this fork includes a modified set of imports") + if testing.Short() { + t.Skip("skipping in -short mode") + } +@@ -1837,6 +1873,9 @@ func TestNoAuthorityKeyIdInSelfSignedCert(t *testing.T) { + } - package x509 + func TestNoSubjectKeyIdInCert(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + template := &Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ +@@ -2405,6 +2444,9 @@ func TestAdditionFieldsInGeneralSubtree(t *testing.T) { + } -diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go -index 102acda578..07b3c7095e 100644 ---- a/src/crypto/x509/boring_test.go -+++ b/src/crypto/x509/boring_test.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. + func TestEmptySerialNumber(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + template := Certificate{ + DNSNames: []string{"example.com"}, + } +@@ -2436,6 +2478,9 @@ func TestEmptySerialNumber(t *testing.T) { + } --//go:build boringcrypto -+//go:build !no_openssl + func TestEmptySubject(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + template := Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"example.com"}, +@@ -3715,6 +3760,9 @@ func TestParseUniqueID(t *testing.T) { + } - package x509 + func TestDisableSHA1ForCertOnly(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + t.Setenv("GODEBUG", "") -diff --git a/src/crypto/x509/notboring.go b/src/crypto/x509/notboring.go -index c83a7272c9..0c7dea2f1f 100644 ---- a/src/crypto/x509/notboring.go -+++ b/src/crypto/x509/notboring.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. + tmpl := &Certificate{ +@@ -4028,6 +4076,9 @@ func TestDuplicateAttributesCSR(t *testing.T) { + } --//go:build !boringcrypto -+//go:build no_openssl + func TestCertificateOIDPoliciesGODEBUG(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + t.Setenv("GODEBUG", "x509usepolicies=0") - package x509 + template := Certificate{ +@@ -4066,6 +4117,9 @@ func TestCertificateOIDPoliciesGODEBUG(t *testing.T) { + } -diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go -index bd9df3ce9b..ce1e19bfd2 100644 ---- a/src/crypto/x509/x509_test.go -+++ b/src/crypto/x509/x509_test.go -@@ -12,7 +12,7 @@ import ( - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "crypto/internal/backend/boringtest" - "crypto/rand" - "crypto/rsa" -@@ -656,7 +656,7 @@ func TestCreateSelfSignedCertificate(t *testing.T) { - extraExtensionData := []byte("extra extension") - - for _, test := range tests { -- if boring.Enabled && test.sigAlgo.isRSAPSS() { -+ if boring.Enabled() && test.sigAlgo.isRSAPSS() { - key, _ := test.priv.(*rsa.PrivateKey) - if key.PublicKey.N.BitLen() < 2048 { - t.Logf("skipping short key with BoringCrypto: %d", key.PublicKey.N.BitLen()) -@@ -3721,7 +3721,7 @@ func TestRevocationListCheckSignatureFrom(t *testing.T) { - var testCurve elliptic.Curve - // If OpenSSL supports P224, use the default upstream behavior, - // otherwise test with P384 -- if !boring.Enabled || boringtest.Supports(t, "CurveP224") { -+ if !boring.Enabled() || boringtest.Supports(t, "CurveP224") { - testCurve = elliptic.P224() - } else { - testCurve = elliptic.P384() + func TestCertificatePolicies(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + if x509usepolicies.Value() == "0" { + t.Skip("test relies on default x509usepolicies GODEBUG") + } +@@ -4123,6 +4177,9 @@ func TestGob(t *testing.T) { + } + + func TestRejectCriticalAKI(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + template := Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{CommonName: "Cert"}, +@@ -4148,6 +4205,9 @@ func TestRejectCriticalAKI(t *testing.T) { + } + + func TestRejectCriticalAIA(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + template := Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{CommonName: "Cert"}, +@@ -4173,6 +4233,9 @@ func TestRejectCriticalAIA(t *testing.T) { + } + + func TestRejectCriticalSKI(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("test not relevant for openssl backend") ++ } + template := Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{CommonName: "Cert"}, diff --git a/src/go.mod b/src/go.mod -index 96513ccfc9..fdda1666e3 100644 +index cc6d24c806..17a030d3d4 100644 --- a/src/go.mod +++ b/src/go.mod -@@ -3,6 +3,7 @@ module std - go 1.23 +@@ -8,6 +8,7 @@ require ( + ) require ( -+ github.com/golang-fips/openssl/v2 v2.0.3 - golang.org/x/crypto v0.23.1-0.20240603234054-0b431c7de36a - golang.org/x/net v0.25.1-0.20250304182835-b70a9e3eaa27 ++ github.com/golang-fips/openssl/v2 v2.0.4-0.20240925082504-4fb8ffc9b3b8 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect ) diff --git a/src/go.sum b/src/go.sum -index 7d2f0b01d5..3b53e3b089 100644 +index 7301ae09c4..3c0fd6eb0c 100644 --- a/src/go.sum +++ b/src/go.sum -@@ -1,3 +1,5 @@ +@@ -1,3 +1,7 @@ +github.com/golang-fips/openssl/v2 v2.0.3 h1:9+J2R0BQio6Jz8+dPZf/0ylISByl0gZWjTEKm+J+y7Y= +github.com/golang-fips/openssl/v2 v2.0.3/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= - golang.org/x/crypto v0.23.1-0.20240603234054-0b431c7de36a h1:37MIv+iGfwMYzWJECGyrPCtd5nuqcciRUeJfkNCkCf0= - golang.org/x/crypto v0.23.1-0.20240603234054-0b431c7de36a/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= - golang.org/x/net v0.25.1-0.20250304182835-b70a9e3eaa27 h1:BLroQt2NWk69+mgdbJFxbd1Y6nc8r9UCc/iPQ0FgpNs= ++github.com/golang-fips/openssl/v2 v2.0.4-0.20240925082504-4fb8ffc9b3b8 h1:OlLgcP8q2BFCR/MmtJcnY7fsbj8FfMYnvCpYthwHMYA= ++github.com/golang-fips/openssl/v2 v2.0.4-0.20240925082504-4fb8ffc9b3b8/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= + golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= + golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= + golang.org/x/net v0.32.1-0.20250304185419-76f9bf3279ef h1:oQtTn7aH5kyi7dPmG2Eot3aG1XBwnkrX+zIq+lNeZeM= +diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go +index e3e01077c1..2e324f15a0 100644 +--- a/src/go/build/deps_test.go ++++ b/src/go/build/deps_test.go +@@ -799,6 +799,14 @@ func listStdPkgs(goroot string) ([]string, error) { + } + + func TestDependencies(t *testing.T) { ++ // We have actually fixed this test in the past, updating the ++ // dependency graph described above to ensure this test is ++ // happy with our changes. However, this can be difficult to ++ // keep valid over time, and for our distribution specifically, ++ // this test provides dubious benefits. So, let's just skip this ++ // test downstream. ++ t.Skip("This distribution uses different dependencies") ++ + testenv.MustHaveSource(t) + + ctxt := Default +diff --git a/src/go/build/vendor_test.go b/src/go/build/vendor_test.go +index 7f6237ffd5..d006aa3592 100644 +--- a/src/go/build/vendor_test.go ++++ b/src/go/build/vendor_test.go +@@ -22,6 +22,8 @@ var allowedPackagePrefixes = []string{ + "github.com/google/pprof", + "github.com/ianlancetaylor/demangle", + "rsc.io/markdown", ++ "rsc.io/markdown", ++ "github.com/golang-fips/openssl/v2", + } + + // Verify that the vendor directories contain only packages matching the list above. +diff --git a/src/internal/goexperiment/exp_strictfipsruntime_off.go b/src/internal/goexperiment/exp_strictfipsruntime_off.go +new file mode 100644 +index 0000000000..73a676a18b +--- /dev/null ++++ b/src/internal/goexperiment/exp_strictfipsruntime_off.go +@@ -0,0 +1,9 @@ ++// Code generated by mkconsts.go. DO NOT EDIT. ++ ++//go:build !goexperiment.strictfipsruntime ++// +build !goexperiment.strictfipsruntime ++ ++package goexperiment ++ ++const StrictFIPSRuntime = false ++const StrictFIPSRuntimeInt = 0 +diff --git a/src/internal/goexperiment/exp_strictfipsruntime_on.go b/src/internal/goexperiment/exp_strictfipsruntime_on.go +new file mode 100644 +index 0000000000..0983612732 +--- /dev/null ++++ b/src/internal/goexperiment/exp_strictfipsruntime_on.go +@@ -0,0 +1,9 @@ ++// Code generated by mkconsts.go. DO NOT EDIT. ++ ++//go:build goexperiment.strictfipsruntime ++// +build goexperiment.strictfipsruntime ++ ++package goexperiment ++ ++const StrictFIPSRuntime = true ++const StrictFIPSRuntimeInt = 1 +diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go +index 948ed5c802..f19c3b043a 100644 +--- a/src/internal/goexperiment/flags.go ++++ b/src/internal/goexperiment/flags.go +@@ -128,4 +128,6 @@ type Flags struct { + + // Synctest enables the testing/synctest package. + Synctest bool ++ ++ StrictFIPSRuntime bool + } diff --git a/src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml b/src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml new file mode 100644 index 0000000000..aed2e22df2 @@ -4601,10 +5835,10 @@ index 0000000000..72f7aebfc1 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/des.go b/src/vendor/github.com/golang-fips/openssl/v2/des.go new file mode 100644 -index 0000000000..71b13333a2 +index 0000000000..c98a276ec3 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/des.go -@@ -0,0 +1,113 @@ +@@ -0,0 +1,114 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -4640,27 +5874,22 @@ index 0000000000..71b13333a2 + if len(key) != 8 { + return nil, errors.New("crypto/des: invalid key size") + } -+ c, err := newEVPCipher(key, cipherDES) -+ if err != nil { -+ return nil, err -+ } -+ // Should always be true for stock OpenSSL. -+ if loadCipher(cipherDES, cipherModeCBC) == nil { -+ return &desCipherWithoutCBC{c}, nil -+ } -+ return &desCipher{c}, nil ++ return newDESCipher(key, cipherDES) +} + +func NewTripleDESCipher(key []byte) (cipher.Block, error) { + if len(key) != 24 { + return nil, errors.New("crypto/des: invalid key size") + } -+ c, err := newEVPCipher(key, cipherDES3) ++ return newDESCipher(key, cipherDES3) ++} ++ ++func newDESCipher(key []byte, kind cipherKind) (cipher.Block, error) { ++ c, err := newEVPCipher(key, kind) + if err != nil { + return nil, err + } -+ // Should always be true for stock OpenSSL. -+ if loadCipher(cipherDES, cipherModeCBC) != nil { ++ if loadCipher(kind, cipherModeCBC) == nil { + return &desCipherWithoutCBC{c}, nil + } + return &desCipher{c}, nil @@ -4681,46 +5910,406 @@ index 0000000000..71b13333a2 + return c.blockSize +} + -+func (c *desCipher) Encrypt(dst, src []byte) { -+ if err := c.encrypt(dst, src); err != nil { -+ // crypto/des expects that the panic message starts with "crypto/des: ". -+ panic("crypto/des: " + err.Error()) ++func (c *desCipher) Encrypt(dst, src []byte) { ++ if err := c.encrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } ++} ++ ++func (c *desCipher) Decrypt(dst, src []byte) { ++ if err := c.decrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } ++} ++ ++func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpEncrypt) ++} ++ ++func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpDecrypt) ++} ++ ++type desCipherWithoutCBC struct { ++ *evpCipher ++} ++ ++func (c *desCipherWithoutCBC) BlockSize() int { ++ return c.blockSize ++} ++ ++func (c *desCipherWithoutCBC) Encrypt(dst, src []byte) { ++ if err := c.encrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } ++} ++ ++func (c *desCipherWithoutCBC) Decrypt(dst, src []byte) { ++ if err := c.decrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/dsa.go b/src/vendor/github.com/golang-fips/openssl/v2/dsa.go +new file mode 100644 +index 0000000000..875533a50f +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/dsa.go +@@ -0,0 +1,348 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "runtime" ++ "unsafe" ++) ++ ++var ( ++ OSSL_PKEY_PARAM_FFC_PBITS = C.CString("pbits") ++ OSSL_PKEY_PARAM_FFC_QBITS = C.CString("qbits") ++ OSSL_PKEY_PARAM_FFC_P = C.CString("p") ++ OSSL_PKEY_PARAM_FFC_Q = C.CString("q") ++ OSSL_PKEY_PARAM_FFC_G = C.CString("g") ++) ++ ++// SupportsDSA returns true if the OpenSSL library supports DSA. ++func SupportsDSA() bool { ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_DSA, nil) ++ if ctx == nil { ++ return false ++ } ++ C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ return true ++} ++ ++// DSAParameters contains the DSA parameters. ++type DSAParameters struct { ++ P, Q, G BigInt ++} ++ ++// PrivateKeyDSA represents a DSA private key. ++type PrivateKeyDSA struct { ++ DSAParameters ++ X, Y BigInt ++ ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} ++ ++func (k *PrivateKeyDSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PrivateKeyDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} ++ ++// PublicKeyDSA represents a DSA public key. ++type PublicKeyDSA struct { ++ DSAParameters ++ Y BigInt ++ ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} ++ ++func (k *PublicKeyDSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PublicKeyDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} ++ ++// GenerateDSAParameters generates a set of DSA parameters. ++func GenerateDSAParameters(l, n int) (DSAParameters, error) { ++ // The DSA parameters are generated by creating a new DSA key and ++ // extracting the domain parameters from it. ++ ++ // Generate a new DSA key context and set the known parameters. ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_DSA, nil) ++ if ctx == nil { ++ return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_new_id failed") ++ } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ if C.go_openssl_EVP_PKEY_paramgen_init(ctx) != 1 { ++ return DSAParameters{}, newOpenSSLError("EVP_PKEY_paramgen_init failed") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_DSA, -1, C.GO_EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, C.int(l), nil) != 1 { ++ return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_DSA, -1, C.GO_EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, C.int(n), nil) != 1 { ++ return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ var pkey C.GO_EVP_PKEY_PTR ++ if C.go_openssl_EVP_PKEY_paramgen(ctx, &pkey) != 1 { ++ return DSAParameters{}, newOpenSSLError("EVP_PKEY_paramgen failed") ++ } ++ defer C.go_openssl_EVP_PKEY_free(pkey) ++ ++ // Extract the domain parameters from the generated key. ++ var p, q, g C.GO_BIGNUM_PTR ++ switch vMajor { ++ case 1: ++ dsa := getDSA(pkey) ++ if vMinor == 0 { ++ C.go_openssl_DSA_get0_pqg_backport(dsa, &p, &q, &g) ++ } else { ++ C.go_openssl_DSA_get0_pqg(dsa, &p, &q, &g) ++ } ++ case 3: ++ defer func() { ++ C.go_openssl_BN_free(p) ++ C.go_openssl_BN_free(q) ++ C.go_openssl_BN_free(g) ++ }() ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_P, &p) != 1 || ++ C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_Q, &q) != 1 || ++ C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_G, &g) != 1 { ++ return DSAParameters{}, newOpenSSLError("EVP_PKEY_get_bn_param") ++ } ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ ++ return DSAParameters{ ++ P: bnToBig(p), ++ Q: bnToBig(q), ++ G: bnToBig(g), ++ }, nil ++} ++ ++// NewPrivateKeyDSA creates a new DSA private key from the given parameters. ++func NewPrivateKeyDSA(params DSAParameters, x, y BigInt) (*PrivateKeyDSA, error) { ++ if x == nil || y == nil { ++ panic("x and y must not be nil") ++ } ++ pkey, err := newDSA(params, x, y) ++ if err != nil { ++ return nil, err ++ } ++ k := &PrivateKeyDSA{params, x, y, pkey} ++ runtime.SetFinalizer(k, (*PrivateKeyDSA).finalize) ++ return k, nil ++} ++ ++// NewPublicKeyDSA creates a new DSA public key from the given parameters. ++func NewPublicKeyDSA(params DSAParameters, y BigInt) (*PublicKeyDSA, error) { ++ if y == nil { ++ panic("y must not be nil") ++ } ++ pkey, err := newDSA(params, nil, y) ++ if err != nil { ++ return nil, err + } ++ k := &PublicKeyDSA{params, y, pkey} ++ runtime.SetFinalizer(k, (*PublicKeyDSA).finalize) ++ return k, nil +} + -+func (c *desCipher) Decrypt(dst, src []byte) { -+ if err := c.decrypt(dst, src); err != nil { -+ // crypto/des expects that the panic message starts with "crypto/des: ". -+ panic("crypto/des: " + err.Error()) ++// GenerateKeyDSA generates a new private DSA key using the given parameters. ++func GenerateKeyDSA(params DSAParameters) (*PrivateKeyDSA, error) { ++ pkey, err := newDSA(params, nil, nil) ++ if err != nil { ++ return nil, err ++ } ++ var x, y C.GO_BIGNUM_PTR ++ switch vMajor { ++ case 1: ++ dsa := getDSA(pkey) ++ if vMinor == 0 { ++ C.go_openssl_DSA_get0_key_backport(dsa, &y, &x) ++ } else { ++ C.go_openssl_DSA_get0_key(dsa, &y, &x) ++ } ++ case 3: ++ defer func() { ++ C.go_openssl_BN_clear_free(x) ++ C.go_openssl_BN_free(y) ++ }() ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &y) != 1 || ++ C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &x) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_get_bn_param") ++ } ++ default: ++ panic(errUnsupportedVersion()) + } ++ k := &PrivateKeyDSA{params, bnToBig(x), bnToBig(y), pkey} ++ runtime.SetFinalizer(k, (*PrivateKeyDSA).finalize) ++ return k, nil +} + -+func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { -+ return c.newCBC(iv, cipherOpEncrypt) ++// SignDSA signs a hash (which should be the result of hashing a larger message). ++func SignDSA(priv *PrivateKeyDSA, hash []byte) ([]byte, error) { ++ return evpSign(priv.withKey, 0, 0, 0, hash) +} + -+func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { -+ return c.newCBC(iv, cipherOpDecrypt) ++// VerifyDSA verifiessig using the public key, pub. ++func VerifyDSA(pub *PublicKeyDSA, hash []byte, sig []byte) bool { ++ return evpVerify(pub.withKey, 0, 0, 0, sig, hash) == nil +} + -+type desCipherWithoutCBC struct { -+ *evpCipher ++func newDSA(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { ++ switch vMajor { ++ case 1: ++ return newDSA1(params, x, y) ++ case 3: ++ return newDSA3(params, x, y) ++ default: ++ panic(errUnsupportedVersion()) ++ } +} + -+func (c *desCipherWithoutCBC) BlockSize() int { -+ return c.blockSize ++func newDSA1(params DSAParameters, x, y BigInt) (pkey C.GO_EVP_PKEY_PTR, err error) { ++ checkMajorVersion(1) ++ ++ dsa := C.go_openssl_DSA_new() ++ if dsa == nil { ++ return nil, newOpenSSLError("DSA_new failed") ++ } ++ defer func() { ++ if pkey == nil { ++ C.go_openssl_DSA_free(dsa) ++ } ++ }() ++ ++ p, q, g := bigToBN(params.P), bigToBN(params.Q), bigToBN(params.G) ++ var ret C.int ++ if vMinor == 0 { ++ ret = C.go_openssl_DSA_set0_pqg_backport(dsa, p, q, g) ++ } else { ++ ret = C.go_openssl_DSA_set0_pqg(dsa, p, q, g) ++ } ++ if ret != 1 { ++ C.go_openssl_BN_free(p) ++ C.go_openssl_BN_free(q) ++ C.go_openssl_BN_free(g) ++ return nil, newOpenSSLError("DSA_set0_pqg failed") ++ } ++ if y != nil { ++ pub, priv := bigToBN(y), bigToBN(x) ++ if vMinor == 0 { ++ ret = C.go_openssl_DSA_set0_key_backport(dsa, pub, priv) ++ } else { ++ ret = C.go_openssl_DSA_set0_key(dsa, pub, priv) ++ } ++ if ret != 1 { ++ C.go_openssl_BN_free(pub) ++ C.go_openssl_BN_clear_free(priv) ++ return nil, newOpenSSLError("DSA_set0_key failed") ++ } ++ } else { ++ if C.go_openssl_DSA_generate_key(dsa) != 1 { ++ return nil, newOpenSSLError("DSA_generate_key failed") ++ } ++ } ++ pkey = C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_DSA, unsafe.Pointer(dsa)) != 1 { ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ return pkey, nil +} + -+func (c *desCipherWithoutCBC) Encrypt(dst, src []byte) { -+ c.encrypt(dst, src) ++func newDSA3(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { ++ checkMajorVersion(3) ++ ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") ++ } ++ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) ++ p, q, g := bigToBN(params.P), bigToBN(params.Q), bigToBN(params.G) ++ defer func() { ++ C.go_openssl_BN_free(p) ++ C.go_openssl_BN_free(q) ++ C.go_openssl_BN_free(g) ++ }() ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 || ++ C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1 || ++ C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g) != 1 { ++ ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ } ++ selection := C.int(C.GO_EVP_PKEY_KEYPAIR) ++ if y != nil { ++ pub := bigToBN(y) ++ defer C.go_openssl_BN_free(pub) ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub) != 1 { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ } ++ if x == nil { ++ selection = C.int(C.GO_EVP_PKEY_PUBLIC_KEY) ++ } ++ } ++ if x != nil { ++ priv := bigToBN(x) ++ defer C.go_openssl_BN_clear_free(priv) ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1 { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ } ++ } ++ bldparams := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ if bldparams == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_to_param") ++ } ++ defer C.go_openssl_OSSL_PARAM_free(bldparams) ++ pkey, err := newEvpFromParams(C.GO_EVP_PKEY_DSA, selection, bldparams) ++ if err != nil { ++ return nil, err ++ } ++ if y != nil { ++ return pkey, nil ++ } ++ // pkey doesn't contain the public component, but the crypto/dsa package ++ // expects it to be always there. Generate a new key using pkey as domain ++ // parameters placeholder. ++ defer C.go_openssl_EVP_PKEY_free(pkey) ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_from_pkey(nil, pkey, nil) ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new_from_pkey") ++ } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ if C.go_openssl_EVP_PKEY_keygen_init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_keygen_init") ++ } ++ var gkey C.GO_EVP_PKEY_PTR ++ if C.go_openssl_EVP_PKEY_keygen(ctx, &gkey) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_keygen") ++ } ++ return gkey, nil +} + -+func (c *desCipherWithoutCBC) Decrypt(dst, src []byte) { -+ c.decrypt(dst, src) ++// getDSA returns the DSA from pkey. ++// If pkey does not contain an DSA it panics. ++// The returned key should not be freed. ++func getDSA(pkey C.GO_EVP_PKEY_PTR) (key C.GO_DSA_PTR) { ++ if vMajor == 1 && vMinor == 0 { ++ if key0 := C.go_openssl_EVP_PKEY_get0(pkey); key0 != nil { ++ key = C.GO_DSA_PTR(key0) ++ } ++ } else { ++ key = C.go_openssl_EVP_PKEY_get0_DSA(pkey) ++ } ++ if key == nil { ++ panic("pkey does not contain an DSA") ++ } ++ return key +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ec.go b/src/vendor/github.com/golang-fips/openssl/v2/ec.go new file mode 100644 -index 0000000000..eac2f8bbee +index 0000000000..5c253f7eec --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ec.go @@ -0,0 +1,59 @@ @@ -4732,11 +6321,11 @@ index 0000000000..eac2f8bbee +import "C" + +var ( -+ paramPubKey = C.CString("pub") -+ paramPrivKey = C.CString("priv") -+ paramGroup = C.CString("group") -+ paramECPubX = C.CString("qx") -+ paramECPubY = C.CString("qy") ++ OSSL_PKEY_PARAM_PUB_KEY = C.CString("pub") ++ OSSL_PKEY_PARAM_PRIV_KEY = C.CString("priv") ++ OSSL_PKEY_PARAM_GROUP_NAME = C.CString("group") ++ OSSL_PKEY_PARAM_EC_PUB_X = C.CString("qx") ++ OSSL_PKEY_PARAM_EC_PUB_Y = C.CString("qy") +) + +func curveNID(curve string) (C.int, error) { @@ -4785,10 +6374,10 @@ index 0000000000..eac2f8bbee +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ecdh.go b/src/vendor/github.com/golang-fips/openssl/v2/ecdh.go new file mode 100644 -index 0000000000..a1e627eff4 +index 0000000000..3f31937b76 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ecdh.go -@@ -0,0 +1,323 @@ +@@ -0,0 +1,331 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -4840,6 +6429,11 @@ index 0000000000..a1e627eff4 + if err != nil { + return nil, err + } ++ if vMajor == 3 { ++ if err := validateECPrivateKey(pkey); err != nil { ++ return nil, err ++ } ++ } + k := &PrivateKeyECDH{pkey, curve, false} + runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) + return k, nil @@ -4918,9 +6512,8 @@ index 0000000000..a1e627eff4 +} + +func newECDHPkey1(nid C.int, bytes []byte, isPrivate bool) (pkey C.GO_EVP_PKEY_PTR, err error) { -+ if vMajor != 1 { -+ panic("incorrect vMajor version") -+ } ++ checkMajorVersion(1) ++ + key := C.go_openssl_EC_KEY_new_by_curve_name(nid) + if key == nil { + return nil, newOpenSSLError("EC_KEY_new_by_curve_name") @@ -4957,15 +6550,14 @@ index 0000000000..a1e627eff4 +} + +func newECDHPkey3(nid C.int, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, error) { -+ if vMajor != 3 { -+ panic("incorrect vMajor version") -+ } ++ checkMajorVersion(3) ++ + bld := C.go_openssl_OSSL_PARAM_BLD_new() + if bld == nil { + return nil, newOpenSSLError("OSSL_PARAM_BLD_new") + } + defer C.go_openssl_OSSL_PARAM_BLD_free(bld) -+ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramGroup, C.go_openssl_OBJ_nid2sn(nid), 0) ++ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, C.go_openssl_OBJ_nid2sn(nid), 0) + var selection C.int + if isPrivate { + priv := C.go_openssl_BN_bin2bn(base(bytes), C.int(len(bytes)), nil) @@ -4973,14 +6565,14 @@ index 0000000000..a1e627eff4 + return nil, newOpenSSLError("BN_bin2bn") + } + defer C.go_openssl_BN_clear_free(priv) -+ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, paramPrivKey, priv) != 1 { ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1 { + return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") + } + selection = C.GO_EVP_PKEY_KEYPAIR + } else { + cbytes := C.CBytes(bytes) + defer C.free(cbytes) -+ C.go_openssl_OSSL_PARAM_BLD_push_octet_string(bld, paramPubKey, cbytes, C.size_t(len(bytes))) ++ C.go_openssl_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, cbytes, C.size_t(len(bytes))) + selection = C.GO_EVP_PKEY_PUBLIC_KEY + } + params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) @@ -4988,7 +6580,12 @@ index 0000000000..a1e627eff4 + return nil, newOpenSSLError("OSSL_PARAM_BLD_to_param") + } + defer C.go_openssl_OSSL_PARAM_free(params) -+ return newEvpFromParams(C.GO_EVP_PKEY_EC, selection, params) ++ pkey, err := newEvpFromParams(C.GO_EVP_PKEY_EC, selection, params) ++ if err != nil { ++ return nil, err ++ } ++ ++ return pkey, nil +} + +// deriveEcdhPublicKey sets the raw public key of pkey by deriving it from @@ -5026,7 +6623,7 @@ index 0000000000..a1e627eff4 + } + case 3: + var priv C.GO_BIGNUM_PTR -+ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramPrivKey, &priv) != 1 { ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv) != 1 { + return newOpenSSLError("EVP_PKEY_get_bn_param") + } + defer C.go_openssl_BN_clear_free(priv) @@ -5091,7 +6688,7 @@ index 0000000000..a1e627eff4 + return nil, nil, newOpenSSLError("EC_KEY_get0_private_key") + } + case 3: -+ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramPrivKey, &priv) != 1 { ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv) != 1 { + return nil, nil, newOpenSSLError("EVP_PKEY_get_bn_param") + } + defer C.go_openssl_BN_clear_free(priv) @@ -5114,10 +6711,10 @@ index 0000000000..a1e627eff4 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go b/src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go new file mode 100644 -index 0000000000..46b16abf48 +index 0000000000..be7e9455f4 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go -@@ -0,0 +1,217 @@ +@@ -0,0 +1,215 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -5160,8 +6757,8 @@ index 0000000000..46b16abf48 + +var errUnknownCurve = errors.New("openssl: unknown elliptic curve") + -+func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) { -+ pkey, err := newECDSAKey(curve, X, Y, nil) ++func NewPublicKeyECDSA(curve string, x, y BigInt) (*PublicKeyECDSA, error) { ++ pkey, err := newECDSAKey(curve, x, y, nil) + if err != nil { + return nil, err + } @@ -5170,8 +6767,8 @@ index 0000000000..46b16abf48 + return k, nil +} + -+func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error) { -+ pkey, err := newECDSAKey(curve, X, Y, D) ++func NewPrivateKeyECDSA(curve string, x, y, d BigInt) (*PrivateKeyECDSA, error) { ++ pkey, err := newECDSAKey(curve, x, y, d) + if err != nil { + return nil, err + } @@ -5180,7 +6777,7 @@ index 0000000000..46b16abf48 + return k, nil +} + -+func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) { ++func GenerateKeyECDSA(curve string) (x, y, d BigInt, err error) { + // Generate the private key. + pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve) + if err != nil { @@ -5211,9 +6808,9 @@ index 0000000000..46b16abf48 + // Get Z. We don't need to free it, get0 does not increase the reference count. + bd = C.go_openssl_EC_KEY_get0_private_key(key) + case 3: -+ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramECPubX, &bx) != 1 || -+ C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramECPubY, &by) != 1 || -+ C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramPrivKey, &bd) != 1 { ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &bx) != 1 || ++ C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &by) != 1 || ++ C.go_openssl_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bd) != 1 { + return nil, nil, nil, newOpenSSLError("EVP_PKEY_get_bn_param") + } + defer C.go_openssl_BN_clear_free(bd) @@ -5241,7 +6838,7 @@ index 0000000000..46b16abf48 + return evpHashVerify(pub.withKey, h, msg, sig) == nil +} + -+func newECDSAKey(curve string, X, Y, D BigInt) (C.GO_EVP_PKEY_PTR, error) { ++func newECDSAKey(curve string, x, y, d BigInt) (C.GO_EVP_PKEY_PTR, error) { + nid, err := curveNID(curve) + if err != nil { + return nil, err @@ -5252,10 +6849,10 @@ index 0000000000..46b16abf48 + C.go_openssl_BN_free(by) + C.go_openssl_BN_clear_free(bd) + }() -+ bx = bigToBN(X) -+ by = bigToBN(Y) -+ bd = bigToBN(D) -+ if bx == nil || by == nil || (D != nil && bd == nil) { ++ bx = bigToBN(x) ++ by = bigToBN(y) ++ bd = bigToBN(d) ++ if bx == nil || by == nil || (d != nil && bd == nil) { + return nil, newOpenSSLError("BN_lebin2bn failed") + } + switch vMajor { @@ -5269,9 +6866,8 @@ index 0000000000..46b16abf48 +} + +func newECDSAKey1(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (pkey C.GO_EVP_PKEY_PTR, err error) { -+ if vMajor != 1 { -+ panic("incorrect vMajor version") -+ } ++ checkMajorVersion(1) ++ + key := C.go_openssl_EC_KEY_new_by_curve_name(nid) + if key == nil { + return nil, newOpenSSLError("EC_KEY_new_by_curve_name failed") @@ -5291,9 +6887,8 @@ index 0000000000..46b16abf48 +} + +func newECDSAKey3(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (C.GO_EVP_PKEY_PTR, error) { -+ if vMajor != 3 { -+ panic("incorrect vMajor version") -+ } ++ checkMajorVersion(3) ++ + // Create the encoded public key public key from bx and by. + pubBytes, err := generateAndEncodeEcPublicKey(nid, func(group C.GO_EC_GROUP_PTR) (C.GO_EC_POINT_PTR, error) { + pt := C.go_openssl_EC_POINT_new(group) @@ -5315,13 +6910,13 @@ index 0000000000..46b16abf48 + return nil, newOpenSSLError("OSSL_PARAM_BLD_new") + } + defer C.go_openssl_OSSL_PARAM_BLD_free(bld) -+ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramGroup, C.go_openssl_OBJ_nid2sn(nid), 0) ++ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, C.go_openssl_OBJ_nid2sn(nid), 0) + cbytes := C.CBytes(pubBytes) + defer C.free(cbytes) -+ C.go_openssl_OSSL_PARAM_BLD_push_octet_string(bld, paramPubKey, cbytes, C.size_t(len(pubBytes))) ++ C.go_openssl_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, cbytes, C.size_t(len(pubBytes))) + var selection C.int + if bd != nil { -+ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, paramPrivKey, bd) != 1 { ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, bd) != 1 { + return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") + } + selection = C.GO_EVP_PKEY_KEYPAIR @@ -5561,10 +7156,10 @@ index 0000000000..f74bd8f8d7 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/evp.go b/src/vendor/github.com/golang-fips/openssl/v2/evp.go new file mode 100644 -index 0000000000..a9237a6a0c +index 0000000000..2ac5c5889c --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/evp.go -@@ -0,0 +1,471 @@ +@@ -0,0 +1,510 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -5583,19 +7178,43 @@ index 0000000000..a9237a6a0c +// cacheMD is a cache of crypto.Hash to GO_EVP_MD_PTR. +var cacheMD sync.Map + ++// hashFuncHash calls fn() and returns its result. ++// If fn() panics, the panic is recovered and returned as an error. ++// This is used to avoid aborting the program when calling ++// an unsupported hash function. It is the caller's responsibility ++// to check the returned value. ++func hashFuncHash(fn func() hash.Hash) (h hash.Hash, err error) { ++ defer func() { ++ r := recover() ++ if r == nil { ++ return ++ } ++ h = nil ++ switch e := r.(type) { ++ case error: ++ err = e ++ case string: ++ err = errors.New(e) ++ default: ++ err = errors.New("unsupported panic") ++ } ++ }() ++ return fn(), nil ++} ++ +// hashToMD converts a hash.Hash implementation from this package to a GO_EVP_MD_PTR. +func hashToMD(h hash.Hash) C.GO_EVP_MD_PTR { + var ch crypto.Hash + switch h.(type) { -+ case *sha1Hash: ++ case *sha1Hash, *sha1Marshal: + ch = crypto.SHA1 -+ case *sha224Hash: ++ case *sha224Hash, *sha224Marshal: + ch = crypto.SHA224 -+ case *sha256Hash: ++ case *sha256Hash, *sha256Marshal: + ch = crypto.SHA256 -+ case *sha384Hash: ++ case *sha384Hash, *sha384Marshal: + ch = crypto.SHA384 -+ case *sha512Hash: ++ case *sha512Hash, *sha512Marshal: + ch = crypto.SHA512 + case *sha3_224Hash: + ch = crypto.SHA3_224 @@ -6036,6 +7655,21 @@ index 0000000000..a9237a6a0c + } + return pkey, nil +} ++ ++func validateECPrivateKey(pkey C.GO_EVP_PKEY_PTR) error { ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_from_pkey(nil, pkey, nil) ++ if ctx == nil { ++ return newOpenSSLError("EVP_PKEY_CTX_new_from_pkey") ++ } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ // if C.go_openssl_EVP_PKEY_param_check(ctx) != 1 { ++ // return newOpenSSLError("EVP_PKEY_param_check") ++ // } ++ if C.go_openssl_EVP_PKEY_private_check(ctx) != 1 { ++ return newOpenSSLError("EVP_PKEY_private_check") ++ } ++ return nil ++} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c new file mode 100644 index 0000000000..1e428d5269 @@ -6262,10 +7896,10 @@ index 0000000000..1e428d5269 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h new file mode 100644 -index 0000000000..e488bf2014 +index 0000000000..a50caa3d82 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h -@@ -0,0 +1,255 @@ +@@ -0,0 +1,259 @@ +// This header file describes the OpenSSL ABI as built for use in Go. + +#include // size_t @@ -6296,6 +7930,10 @@ index 0000000000..e488bf2014 +int go_openssl_thread_setup(void); +void go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch); +const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void); ++void go_openssl_DSA_get0_pqg_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *p, GO_BIGNUM_PTR *q, GO_BIGNUM_PTR *g); ++int go_openssl_DSA_set0_pqg_backport(GO_DSA_PTR d, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g); ++void go_openssl_DSA_get0_key_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *pub_key, GO_BIGNUM_PTR *priv_key); ++int go_openssl_DSA_set0_key_backport(GO_DSA_PTR d, GO_BIGNUM_PTR pub_key, GO_BIGNUM_PTR priv_key); + +// Define pointers to all the used OpenSSL functions. +// Calling C function pointers from Go is currently not supported. @@ -6524,10 +8162,10 @@ index 0000000000..e488bf2014 \ No newline at end of file diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hash.go b/src/vendor/github.com/golang-fips/openssl/v2/hash.go new file mode 100644 -index 0000000000..646b4ce295 +index 0000000000..6fd3a51890 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/hash.go -@@ -0,0 +1,793 @@ +@@ -0,0 +1,1041 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -6540,6 +8178,7 @@ index 0000000000..646b4ce295 + "hash" + "runtime" + "strconv" ++ "sync" + "unsafe" +) + @@ -6640,18 +8279,50 @@ index 0000000000..646b4ce295 + return +} + ++var isMarshallableCache sync.Map ++ ++// isHashMarshallable returns true if the memory layout of cb ++// is known by this library and can therefore be marshalled. ++func isHashMarshallable(ch crypto.Hash) bool { ++ if vMajor == 1 { ++ return true ++ } ++ if v, ok := isMarshallableCache.Load(ch); ok { ++ return v.(bool) ++ } ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ return false ++ } ++ prov := C.go_openssl_EVP_MD_get0_provider(md) ++ if prov == nil { ++ return false ++ } ++ cname := C.go_openssl_OSSL_PROVIDER_get0_name(prov) ++ if cname == nil { ++ return false ++ } ++ name := C.GoString(cname) ++ // We only know the memory layout of the built-in providers. ++ // See evpHash.hashState for more details. ++ marshallable := name == "default" || name == "fips" ++ isMarshallableCache.Store(ch, marshallable) ++ return marshallable ++} ++ +// evpHash implements generic hash methods. +type evpHash struct { + ctx C.GO_EVP_MD_CTX_PTR + // ctx2 is used in evpHash.sum to avoid changing + // the state of ctx. Having it here allows reusing the + // same allocated object multiple times. -+ ctx2 C.GO_EVP_MD_CTX_PTR -+ size int -+ blockSize int ++ ctx2 C.GO_EVP_MD_CTX_PTR ++ size int ++ blockSize int ++ marshallable bool +} + -+func newEvpHash(ch crypto.Hash, size, blockSize int) *evpHash { ++func newEvpHash(ch crypto.Hash) *evpHash { + md := cryptoHashToMD(ch) + if md == nil { + panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) @@ -6662,11 +8333,13 @@ index 0000000000..646b4ce295 + panic(newOpenSSLError("EVP_DigestInit_ex")) + } + ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ blockSize := int(C.go_openssl_EVP_MD_get_block_size(md)) + h := &evpHash{ -+ ctx: ctx, -+ ctx2: ctx2, -+ size: size, -+ blockSize: blockSize, ++ ctx: ctx, ++ ctx2: ctx2, ++ size: ch.Size(), ++ blockSize: blockSize, ++ marshallable: isHashMarshallable(ch), + } + runtime.SetFinalizer(h, (*evpHash).finalize) + return h @@ -6725,11 +8398,42 @@ index 0000000000..646b4ce295 + runtime.KeepAlive(h) +} + ++// clone returns a new evpHash object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *evpHash) clone() (*evpHash, error) { ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_MD_CTX_new") ++ } ++ if C.go_openssl_EVP_MD_CTX_copy_ex(ctx, h.ctx) != 1 { ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ return nil, newOpenSSLError("EVP_MD_CTX_copy") ++ } ++ ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ if ctx2 == nil { ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ return nil, newOpenSSLError("EVP_MD_CTX_new") ++ } ++ cloned := &evpHash{ ++ ctx: ctx, ++ ctx2: ctx2, ++ size: h.size, ++ blockSize: h.blockSize, ++ marshallable: h.marshallable, ++ } ++ runtime.SetFinalizer(cloned, (*evpHash).finalize) ++ return cloned, nil ++} ++ +// hashState returns a pointer to the internal hash structure. +// +// The EVP_MD_CTX memory layout has changed in OpenSSL 3 +// and the property holding the internal structure is no longer md_data but algctx. +func (h *evpHash) hashState() unsafe.Pointer { ++ if !h.marshallable { ++ panic("openssl: hash state is not marshallable") ++ } + switch vMajor { + case 1: + // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. @@ -6758,7 +8462,7 @@ index 0000000000..646b4ce295 +// encoding.BinaryUnmarshaler. +func NewMD4() hash.Hash { + return &md4Hash{ -+ evpHash: newEvpHash(crypto.MD4, 16, 64), ++ evpHash: newEvpHash(crypto.MD4), + } +} + @@ -6772,11 +8476,24 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *md4Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &md4Hash{evpHash: c}, nil ++} ++ +// NewMD5 returns a new MD5 hash. +func NewMD5() hash.Hash { -+ return &md5Hash{ -+ evpHash: newEvpHash(crypto.MD5, 16, 64), ++ h := md5Hash{evpHash: newEvpHash(crypto.MD5)} ++ if h.marshallable { ++ return &md5Marshal{h} + } ++ return &h +} + +// md5State layout is taken from @@ -6798,29 +8515,32 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *md5Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &md5Hash{evpHash: c}, nil ++} ++ +const ( + md5Magic = "md5\x01" + md5MarshaledSize = len(md5Magic) + 4*4 + 64 + 8 +) + -+func (h *md5Hash) MarshalBinary() ([]byte, error) { -+ d := (*md5State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/md5: can't retrieve hash state") -+ } -+ b := make([]byte, 0, md5MarshaledSize) -+ b = append(b, md5Magic...) -+ b = appendUint32(b, d.h[0]) -+ b = appendUint32(b, d.h[1]) -+ b = appendUint32(b, d.h[2]) -+ b = appendUint32(b, d.h[3]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return b, nil ++type md5Marshal struct { ++ md5Hash ++} ++ ++func (h *md5Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, md5MarshaledSize) ++ return h.AppendBinary(buf) +} + -+func (h *md5Hash) UnmarshalBinary(b []byte) error { ++func (h *md5Marshal) UnmarshalBinary(b []byte) error { + if len(b) < len(md5Magic) || string(b[:len(md5Magic)]) != md5Magic { + return errors.New("crypto/md5: invalid hash state identifier") + } @@ -6844,11 +8564,30 @@ index 0000000000..646b4ce295 + return nil +} + ++func (h *md5Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/md5: can't retrieve hash state") ++ } ++ ++ buf = append(buf, md5Magic...) ++ buf = appendUint32(buf, d.h[0]) ++ buf = appendUint32(buf, d.h[1]) ++ buf = appendUint32(buf, d.h[2]) ++ buf = appendUint32(buf, d.h[3]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return buf, nil ++} ++ +// NewSHA1 returns a new SHA1 hash. +func NewSHA1() hash.Hash { -+ return &sha1Hash{ -+ evpHash: newEvpHash(crypto.SHA1, 20, 64), ++ h := sha1Hash{evpHash: newEvpHash(crypto.SHA1)} ++ if h.marshallable { ++ return &sha1Marshal{h} + } ++ return &h +} + +type sha1Hash struct { @@ -6861,6 +8600,17 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha1Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha1Hash{evpHash: c}, nil ++} ++ +// sha1State layout is taken from +// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34. +type sha1State struct { @@ -6875,25 +8625,16 @@ index 0000000000..646b4ce295 + sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 +) + -+func (h *sha1Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha1State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha1: can't retrieve hash state") -+ } -+ b := make([]byte, 0, sha1MarshaledSize) -+ b = append(b, sha1Magic...) -+ b = appendUint32(b, d.h[0]) -+ b = appendUint32(b, d.h[1]) -+ b = appendUint32(b, d.h[2]) -+ b = appendUint32(b, d.h[3]) -+ b = appendUint32(b, d.h[4]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return b, nil ++type sha1Marshal struct { ++ sha1Hash ++} ++ ++func (h *sha1Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, sha1MarshaledSize) ++ return h.AppendBinary(buf) +} + -+func (h *sha1Hash) UnmarshalBinary(b []byte) error { ++func (h *sha1Marshal) UnmarshalBinary(b []byte) error { + if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { + return errors.New("crypto/sha1: invalid hash state identifier") + } @@ -6918,11 +8659,30 @@ index 0000000000..646b4ce295 + return nil +} + ++func (h *sha1Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha1: can't retrieve hash state") ++ } ++ buf = append(buf, sha1Magic...) ++ buf = appendUint32(buf, d.h[0]) ++ buf = appendUint32(buf, d.h[1]) ++ buf = appendUint32(buf, d.h[2]) ++ buf = appendUint32(buf, d.h[3]) ++ buf = appendUint32(buf, d.h[4]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return buf, nil ++} ++ +// NewSHA224 returns a new SHA224 hash. +func NewSHA224() hash.Hash { -+ return &sha224Hash{ -+ evpHash: newEvpHash(crypto.SHA224, 224/8, 64), ++ h := sha224Hash{evpHash: newEvpHash(crypto.SHA224)} ++ if h.marshallable { ++ return &sha224Marshal{h} + } ++ return &h +} + +type sha224Hash struct { @@ -6935,11 +8695,24 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha224Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha224Hash{evpHash: c}, nil ++} ++ +// NewSHA256 returns a new SHA256 hash. +func NewSHA256() hash.Hash { -+ return &sha256Hash{ -+ evpHash: newEvpHash(crypto.SHA256, 256/8, 64), ++ h := sha256Hash{evpHash: newEvpHash(crypto.SHA256)} ++ if h.marshallable { ++ return &sha256Marshal{h} + } ++ return &h +} + +type sha256Hash struct { @@ -6952,6 +8725,17 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha256Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha256Hash{evpHash: c}, nil ++} ++ +const ( + magic224 = "sha\x02" + magic256 = "sha\x03" @@ -6967,49 +8751,25 @@ index 0000000000..646b4ce295 + nx uint32 +} + -+func (h *sha224Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha256State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") -+ } -+ b := make([]byte, 0, marshaledSize256) -+ b = append(b, magic224...) -+ b = appendUint32(b, d.h[0]) -+ b = appendUint32(b, d.h[1]) -+ b = appendUint32(b, d.h[2]) -+ b = appendUint32(b, d.h[3]) -+ b = appendUint32(b, d.h[4]) -+ b = appendUint32(b, d.h[5]) -+ b = appendUint32(b, d.h[6]) -+ b = appendUint32(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return b, nil -+} -+ -+func (h *sha256Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha256State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") -+ } -+ b := make([]byte, 0, marshaledSize256) -+ b = append(b, magic256...) -+ b = appendUint32(b, d.h[0]) -+ b = appendUint32(b, d.h[1]) -+ b = appendUint32(b, d.h[2]) -+ b = appendUint32(b, d.h[3]) -+ b = appendUint32(b, d.h[4]) -+ b = appendUint32(b, d.h[5]) -+ b = appendUint32(b, d.h[6]) -+ b = appendUint32(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return b, nil -+} -+ -+func (h *sha224Hash) UnmarshalBinary(b []byte) error { ++type sha224Marshal struct { ++ sha224Hash ++} ++ ++type sha256Marshal struct { ++ sha256Hash ++} ++ ++func (h *sha224Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, marshaledSize256) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha256Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, marshaledSize256) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha224Marshal) UnmarshalBinary(b []byte) error { + if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { + return errors.New("crypto/sha256: invalid hash state identifier") + } @@ -7037,7 +8797,7 @@ index 0000000000..646b4ce295 + return nil +} + -+func (h *sha256Hash) UnmarshalBinary(b []byte) error { ++func (h *sha256Marshal) UnmarshalBinary(b []byte) error { + if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { + return errors.New("crypto/sha256: invalid hash state identifier") + } @@ -7065,11 +8825,53 @@ index 0000000000..646b4ce295 + return nil +} + ++func (h *sha224Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ buf = append(buf, magic224...) ++ buf = appendUint32(buf, d.h[0]) ++ buf = appendUint32(buf, d.h[1]) ++ buf = appendUint32(buf, d.h[2]) ++ buf = appendUint32(buf, d.h[3]) ++ buf = appendUint32(buf, d.h[4]) ++ buf = appendUint32(buf, d.h[5]) ++ buf = appendUint32(buf, d.h[6]) ++ buf = appendUint32(buf, d.h[7]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return buf, nil ++} ++ ++func (h *sha256Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ buf = append(buf, magic256...) ++ buf = appendUint32(buf, d.h[0]) ++ buf = appendUint32(buf, d.h[1]) ++ buf = appendUint32(buf, d.h[2]) ++ buf = appendUint32(buf, d.h[3]) ++ buf = appendUint32(buf, d.h[4]) ++ buf = appendUint32(buf, d.h[5]) ++ buf = appendUint32(buf, d.h[6]) ++ buf = appendUint32(buf, d.h[7]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return buf, nil ++} ++ +// NewSHA384 returns a new SHA384 hash. +func NewSHA384() hash.Hash { -+ return &sha384Hash{ -+ evpHash: newEvpHash(crypto.SHA384, 384/8, 128), ++ h := sha384Hash{evpHash: newEvpHash(crypto.SHA384)} ++ if h.marshallable { ++ return &sha384Marshal{h} + } ++ return &h +} + +type sha384Hash struct { @@ -7082,11 +8884,24 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha384Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha384Hash{evpHash: c}, nil ++} ++ +// NewSHA512 returns a new SHA512 hash. +func NewSHA512() hash.Hash { -+ return &sha512Hash{ -+ evpHash: newEvpHash(crypto.SHA512, 512/8, 128), ++ h := sha512Hash{evpHash: newEvpHash(crypto.SHA512)} ++ if h.marshallable { ++ return &sha512Marshal{h} + } ++ return &h +} + +type sha512Hash struct { @@ -7099,6 +8914,17 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha512Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha512Hash{evpHash: c}, nil ++} ++ +// sha512State layout is taken from +// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95. +type sha512State struct { @@ -7116,49 +8942,25 @@ index 0000000000..646b4ce295 + marshaledSize512 = len(magic512) + 8*8 + 128 + 8 +) + -+func (h *sha384Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ b := make([]byte, 0, marshaledSize512) -+ b = append(b, magic384...) -+ b = appendUint64(b, d.h[0]) -+ b = appendUint64(b, d.h[1]) -+ b = appendUint64(b, d.h[2]) -+ b = appendUint64(b, d.h[3]) -+ b = appendUint64(b, d.h[4]) -+ b = appendUint64(b, d.h[5]) -+ b = appendUint64(b, d.h[6]) -+ b = appendUint64(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, d.nl>>3|d.nh<<61) -+ return b, nil -+} -+ -+func (h *sha512Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ b := make([]byte, 0, marshaledSize512) -+ b = append(b, magic512...) -+ b = appendUint64(b, d.h[0]) -+ b = appendUint64(b, d.h[1]) -+ b = appendUint64(b, d.h[2]) -+ b = appendUint64(b, d.h[3]) -+ b = appendUint64(b, d.h[4]) -+ b = appendUint64(b, d.h[5]) -+ b = appendUint64(b, d.h[6]) -+ b = appendUint64(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, d.nl>>3|d.nh<<61) -+ return b, nil -+} -+ -+func (h *sha384Hash) UnmarshalBinary(b []byte) error { ++type sha384Marshal struct { ++ sha384Hash ++} ++ ++type sha512Marshal struct { ++ sha512Hash ++} ++ ++func (h *sha384Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, marshaledSize512) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha512Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, marshaledSize512) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha384Marshal) UnmarshalBinary(b []byte) error { + if len(b) < len(magic512) { + return errors.New("crypto/sha512: invalid hash state identifier") + } @@ -7189,7 +8991,7 @@ index 0000000000..646b4ce295 + return nil +} + -+func (h *sha512Hash) UnmarshalBinary(b []byte) error { ++func (h *sha512Marshal) UnmarshalBinary(b []byte) error { + if len(b) < len(magic512) { + return errors.New("crypto/sha512: invalid hash state identifier") + } @@ -7220,10 +9022,50 @@ index 0000000000..646b4ce295 + return nil +} + ++func (h *sha384Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ buf = append(buf, magic384...) ++ buf = appendUint64(buf, d.h[0]) ++ buf = appendUint64(buf, d.h[1]) ++ buf = appendUint64(buf, d.h[2]) ++ buf = appendUint64(buf, d.h[3]) ++ buf = appendUint64(buf, d.h[4]) ++ buf = appendUint64(buf, d.h[5]) ++ buf = appendUint64(buf, d.h[6]) ++ buf = appendUint64(buf, d.h[7]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, d.nl>>3|d.nh<<61) ++ return buf, nil ++} ++ ++func (h *sha512Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ buf = append(buf, magic512...) ++ buf = appendUint64(buf, d.h[0]) ++ buf = appendUint64(buf, d.h[1]) ++ buf = appendUint64(buf, d.h[2]) ++ buf = appendUint64(buf, d.h[3]) ++ buf = appendUint64(buf, d.h[4]) ++ buf = appendUint64(buf, d.h[5]) ++ buf = appendUint64(buf, d.h[6]) ++ buf = appendUint64(buf, d.h[7]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, d.nl>>3|d.nh<<61) ++ return buf, nil ++} ++ +// NewSHA3_224 returns a new SHA3-224 hash. +func NewSHA3_224() hash.Hash { + return &sha3_224Hash{ -+ evpHash: newEvpHash(crypto.SHA3_224, 224/8, 64), ++ evpHash: newEvpHash(crypto.SHA3_224), + } +} + @@ -7237,10 +9079,21 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_224Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_224Hash{evpHash: c}, nil ++} ++ +// NewSHA3_256 returns a new SHA3-256 hash. +func NewSHA3_256() hash.Hash { + return &sha3_256Hash{ -+ evpHash: newEvpHash(crypto.SHA3_256, 256/8, 64), ++ evpHash: newEvpHash(crypto.SHA3_256), + } +} + @@ -7254,10 +9107,21 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_256Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_256Hash{evpHash: c}, nil ++} ++ +// NewSHA3_384 returns a new SHA3-384 hash. +func NewSHA3_384() hash.Hash { + return &sha3_384Hash{ -+ evpHash: newEvpHash(crypto.SHA3_384, 384/8, 128), ++ evpHash: newEvpHash(crypto.SHA3_384), + } +} + @@ -7271,10 +9135,21 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_384Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_384Hash{evpHash: c}, nil ++} ++ +// NewSHA3_512 returns a new SHA3-512 hash. +func NewSHA3_512() hash.Hash { + return &sha3_512Hash{ -+ evpHash: newEvpHash(crypto.SHA3_512, 512/8, 128), ++ evpHash: newEvpHash(crypto.SHA3_512), + } +} + @@ -7288,6 +9163,17 @@ index 0000000000..646b4ce295 + return append(in, h.out[:]...) +} + ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_512Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_512Hash{evpHash: c}, nil ++} ++ +// appendUint64 appends x into b as a big endian byte sequence. +func appendUint64(b []byte, x uint64) []byte { + return append(b, @@ -7323,10 +9209,10 @@ index 0000000000..646b4ce295 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go new file mode 100644 -index 0000000000..61cf483fed +index 0000000000..51a05a8a72 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go -@@ -0,0 +1,174 @@ +@@ -0,0 +1,193 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -7341,17 +9227,36 @@ index 0000000000..61cf483fed + "unsafe" +) + ++// SupprtHKDF reports whether the current OpenSSL version supports HKDF. +func SupportsHKDF() bool { -+ return versionAtOrAbove(1, 1, 1) ++ switch vMajor { ++ case 1: ++ return versionAtOrAbove(1, 1, 1) ++ case 3: ++ // Some OpenSSL 3 providers don't support HKDF or don't support it via ++ // the EVP_PKEY API, which is the one we use. ++ // See https://github.com/golang-fips/openssl/issues/189. ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil) ++ if ctx == nil { ++ return false ++ } ++ C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ return true ++ default: ++ panic(errUnsupportedVersion()) ++ } +} + -+func newHKDF(h func() hash.Hash, mode C.int) (*hkdf, error) { ++func newHKDF(fh func() hash.Hash, mode C.int) (*hkdf, error) { + if !SupportsHKDF() { + return nil, errUnsupportedVersion() + } + -+ ch := h() -+ md := hashToMD(ch) ++ h, err := hashFuncHash(fh) ++ if err != nil { ++ return nil, err ++ } ++ md := hashToMD(h) + if md == nil { + return nil, errors.New("unsupported hash function") + } @@ -7388,7 +9293,7 @@ index 0000000000..61cf483fed + } + } + -+ c := &hkdf{ctx: ctx, hashLen: ch.Size()} ++ c := &hkdf{ctx: ctx, hashLen: h.Size()} + ctx = nil + + runtime.SetFinalizer(c, (*hkdf).finalize) @@ -7503,10 +9408,10 @@ index 0000000000..61cf483fed +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hmac.go b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go new file mode 100644 -index 0000000000..ef8116ce66 +index 0000000000..80e45cd65c --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go -@@ -0,0 +1,238 @@ +@@ -0,0 +1,276 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -7520,20 +9425,15 @@ index 0000000000..ef8116ce66 + "unsafe" +) + -+var paramDigest = C.CString("digest") -+ -+var ( -+ fetchHMACOnce sync.Once -+ evpHMAC C.GO_EVP_MAC_PTR -+) ++var OSSL_MAC_PARAM_DIGEST = C.CString("digest") + +// NewHMAC returns a new HMAC using OpenSSL. +// The function h must return a hash implemented by +// OpenSSL (for example, h could be openssl.NewSHA256). +// If h is not recognized, NewHMAC returns nil. -+func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { -+ ch := h() -+ md := hashToMD(ch) ++func NewHMAC(fh func() hash.Hash, key []byte) hash.Hash { ++ h, _ := hashFuncHash(fh) ++ md := hashToMD(h) + if md == nil { + return nil + } @@ -7547,14 +9447,29 @@ index 0000000000..ef8116ce66 + key = make([]byte, C.GO_EVP_MAX_MD_SIZE) + } + ++ hmac := &opensslHMAC{ ++ size: h.Size(), ++ blockSize: h.BlockSize(), ++ } ++ + switch vMajor { + case 1: -+ return newHMAC1(key, ch, md) ++ ctx := newHMAC1(key, md) ++ if ctx.ctx == nil { ++ return nil ++ } ++ hmac.ctx1 = ctx + case 3: -+ return newHMAC3(key, ch, md) ++ ctx := newHMAC3(key, md) ++ if ctx.ctx == nil { ++ return nil ++ } ++ hmac.ctx3 = ctx + default: + panic(errUnsupportedVersion()) + } ++ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) ++ return hmac +} + +// hmacCtx3 is used for OpenSSL 1. @@ -7576,7 +9491,7 @@ index 0000000000..ef8116ce66 + sum []byte +} + -+func newHMAC1(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { ++func newHMAC1(key []byte, md C.GO_EVP_MD_PTR) hmacCtx1 { + ctx := hmacCtxNew() + if ctx == nil { + panic("openssl: EVP_MAC_CTX_new failed") @@ -7584,42 +9499,76 @@ index 0000000000..ef8116ce66 + if C.go_openssl_HMAC_Init_ex(ctx, unsafe.Pointer(&key[0]), C.int(len(key)), md, nil) == 0 { + panic(newOpenSSLError("HMAC_Init_ex failed")) + } -+ hmac := &opensslHMAC{ -+ size: h.Size(), -+ blockSize: h.BlockSize(), -+ ctx1: hmacCtx1{ctx}, -+ } -+ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) -+ return hmac ++ return hmacCtx1{ctx} +} + -+func newHMAC3(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { -+ fetchHMACOnce.Do(func() { -+ name := C.CString("HMAC") -+ evpHMAC = C.go_openssl_EVP_MAC_fetch(nil, name, nil) -+ C.free(unsafe.Pointer(name)) -+ }) -+ if evpHMAC == nil { ++var hmacDigestsSupported sync.Map ++var fetchHMAC3 = sync.OnceValue(func() C.GO_EVP_MAC_PTR { ++ name := C.CString("HMAC") ++ mac := C.go_openssl_EVP_MAC_fetch(nil, name, nil) ++ C.free(unsafe.Pointer(name)) ++ if mac == nil { + panic("openssl: HMAC not supported") + } -+ ctx := C.go_openssl_EVP_MAC_CTX_new(evpHMAC) -+ if ctx == nil { -+ panic("openssl: EVP_MAC_CTX_new failed") -+ } -+ digest := C.go_openssl_EVP_MD_get0_name(md) ++ return mac ++}) ++ ++func buildHMAC3Params(digest *C.char) C.GO_OSSL_PARAM_PTR { + bld := C.go_openssl_OSSL_PARAM_BLD_new() + if bld == nil { + panic(newOpenSSLError("OSSL_PARAM_BLD_new")) + } + defer C.go_openssl_OSSL_PARAM_BLD_free(bld) -+ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramDigest, digest, 0) -+ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_MAC_PARAM_DIGEST, digest, 0) ++ return C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++} ++ ++func isHMAC3DigestSupported(digest string) bool { ++ if v, ok := hmacDigestsSupported.Load(digest); ok { ++ return v.(bool) ++ } ++ ctx := C.go_openssl_EVP_MAC_CTX_new(fetchHMAC3()) ++ if ctx == nil { ++ panic(newOpenSSLError("EVP_MAC_CTX_new")) ++ } ++ defer C.go_openssl_EVP_MAC_CTX_free(ctx) ++ ++ cdigest := C.CString(digest) ++ defer C.free(unsafe.Pointer(cdigest)) ++ params := buildHMAC3Params(cdigest) ++ if params == nil { ++ panic(newOpenSSLError("OSSL_PARAM_BLD_to_param")) ++ } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ ++ supported := C.go_openssl_EVP_MAC_CTX_set_params(ctx, params) != 0 ++ hmacDigestsSupported.Store(digest, supported) ++ return supported ++} ++ ++func newHMAC3(key []byte, md C.GO_EVP_MD_PTR) hmacCtx3 { ++ digest := C.go_openssl_EVP_MD_get0_name(md) ++ if !isHMAC3DigestSupported(C.GoString(digest)) { ++ // The digest is not supported by the HMAC provider. ++ // Don't panic here so the Go standard library to ++ // fall back to the Go implementation. ++ // See https://github.com/golang-fips/openssl/issues/153. ++ return hmacCtx3{} ++ } ++ params := buildHMAC3Params(digest) + if params == nil { + panic(newOpenSSLError("OSSL_PARAM_BLD_to_param")) + } + defer C.go_openssl_OSSL_PARAM_free(params) ++ ++ ctx := C.go_openssl_EVP_MAC_CTX_new(fetchHMAC3()) ++ if ctx == nil { ++ panic(newOpenSSLError("EVP_MAC_CTX_new")) ++ } ++ + if C.go_openssl_EVP_MAC_init(ctx, base(key), C.size_t(len(key)), params) == 0 { -+ panic(newOpenSSLError("EVP_MAC_init failed")) ++ C.go_openssl_EVP_MAC_CTX_free(ctx) ++ panic(newOpenSSLError("EVP_MAC_init")) + } + var hkey []byte + if vMinor == 0 && vPatch <= 2 { @@ -7631,13 +9580,7 @@ index 0000000000..ef8116ce66 + hkey = make([]byte, len(key)) + copy(hkey, key) + } -+ hmac := &opensslHMAC{ -+ size: h.Size(), -+ blockSize: h.BlockSize(), -+ ctx3: hmacCtx3{ctx, hkey}, -+ } -+ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) -+ return hmac ++ return hmacCtx3{ctx, hkey} +} + +func (h *opensslHMAC) Reset() { @@ -7896,10 +9839,10 @@ index 0000000000..3778e21227 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/openssl.go b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go new file mode 100644 -index 0000000000..691bb16f72 +index 0000000000..1562cee268 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go -@@ -0,0 +1,419 @@ +@@ -0,0 +1,434 @@ +//go:build !cmd_go_bootstrap + +// Package openssl provides access to OpenSSL cryptographic functions. @@ -7979,6 +9922,13 @@ index 0000000000..691bb16f72 + return errors.New("openssl: OpenSSL version: " + utoa(vMajor) + "." + utoa(vMinor) + "." + utoa(vPatch)) +} + ++// checkMajorVersion panics if the current major version is not expected. ++func checkMajorVersion(expected uint) { ++ if vMajor != expected { ++ panic("openssl: incorrect major version (" + strconv.Itoa(int(vMajor)) + "), expected " + strconv.Itoa(int(expected))) ++ } ++} ++ +type fail string + +func (e fail) Error() string { return "openssl: " + string(e) + " failed" } @@ -8013,6 +9963,14 @@ index 0000000000..691bb16f72 + } +} + ++// isProviderAvailable checks if the provider with the given name is available. ++// This function is used in export_test.go, but must be defined here as test files can't access C functions. ++func isProviderAvailable(name string) bool { ++ providerName := C.CString(name) ++ defer C.free(unsafe.Pointer(providerName)) ++ return C.go_openssl_OSSL_PROVIDER_available(nil, providerName) == 1 ++} ++ +// SetFIPS enables or disables FIPS mode. +// +// For OpenSSL 3, the `fips` provider is loaded if enabled is true, @@ -8192,7 +10150,7 @@ index 0000000000..691bb16f72 +func (z BigInt) byteSwap() { + for i, d := range z { + var n uint = 0 -+ for j := 0; j < wordBytes; j++ { ++ for j := range wordBytes { + n |= uint(byte(d)) << (8 * (wordBytes - j - 1)) + d >>= 8 + } @@ -8294,7 +10252,7 @@ index 0000000000..691bb16f72 + if pad < 0 { + return errors.New("openssl: destination buffer too small") + } -+ for i := 0; i < pad; i++ { ++ for i := range pad { + to[i] = 0 + } + if int(C.go_openssl_BN_bn2bin(bn, base(to[pad:]))) != n { @@ -8319,12 +10277,123 @@ index 0000000000..691bb16f72 +func versionAtOrAbove(major, minor, patch uint) bool { + return vMajor > major || (vMajor == major && vMinor > minor) || (vMajor == major && vMinor == minor && vPatch >= patch) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/params.go b/src/vendor/github.com/golang-fips/openssl/v2/params.go +new file mode 100644 +index 0000000000..867f81b007 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/params.go +@@ -0,0 +1,105 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "runtime" ++ "unsafe" ++) ++ ++var ( ++ // KDF parameters ++ _OSSL_KDF_PARAM_DIGEST = C.CString("digest") ++ _OSSL_KDF_PARAM_SECRET = C.CString("secret") ++ _OSSL_KDF_PARAM_SEED = C.CString("seed") ++) ++ ++// paramBuilder is a helper for building OSSL_PARAMs. ++// If an error occurs when adding a new parameter, ++// subsequent calls to add parameters are ignored ++// and build() will return the error. ++type paramBuilder struct { ++ bld C.GO_OSSL_PARAM_BLD_PTR ++ pinner runtime.Pinner ++ ++ err error ++} ++ ++// newParamBuilder creates a new paramBuilder. ++func newParamBuilder() (*paramBuilder, error) { ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") ++ } ++ pb := ¶mBuilder{bld: bld} ++ runtime.SetFinalizer(pb, (*paramBuilder).finalize) ++ return pb, nil ++} ++ ++// finalize frees the builder. ++func (b *paramBuilder) finalize() { ++ if b.bld != nil { ++ b.pinner.Unpin() ++ C.go_openssl_OSSL_PARAM_BLD_free(b.bld) ++ b.bld = nil ++ } ++} ++ ++// check is used internally to enforce invariants and should not be called by users of paramBuilder. ++// Returns true if it's ok to add parameters to the builder or build it. ++// Returns false if there has been an error while adding a parameter. ++// Panics if the paramBuilder has been freed, e.g. if it has already been built. ++func (b *paramBuilder) check() bool { ++ if b.err != nil { ++ return false ++ } ++ if b.bld == nil { ++ panic("openssl: paramBuilder has been freed") ++ } ++ return true ++} ++ ++// build creates an OSSL_PARAM from the builder. ++// The returned OSSL_PARAM must be freed with OSSL_PARAM_free. ++// If an error occurred while adding parameters, the error is returned ++// and the OSSL_PARAM is nil. Once build() is called, the builder is finalized ++// and cannot be reused. ++func (b *paramBuilder) build() (C.GO_OSSL_PARAM_PTR, error) { ++ defer b.finalize() ++ if !b.check() { ++ return nil, b.err ++ } ++ param := C.go_openssl_OSSL_PARAM_BLD_to_param(b.bld) ++ if param == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_build") ++ } ++ return param, nil ++} ++ ++// addUTF8String adds a NUL-terminated UTF-8 string to the builder. ++// size should not include the terminating NUL byte. If size is zero, then it will be calculated. ++func (b *paramBuilder) addUTF8String(name *C.char, value *C.char, size C.size_t) { ++ if !b.check() { ++ return ++ } ++ // OSSL_PARAM_BLD_push_utf8_string calculates the size if it is zero. ++ if C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(b.bld, name, value, size) != 1 { ++ b.err = newOpenSSLError("OSSL_PARAM_BLD_push_utf8_string(" + C.GoString(name) + ")") ++ } ++} ++ ++// addOctetString adds an octet string to the builder. ++// The value is pinned and will be unpinned when the builder is freed. ++func (b *paramBuilder) addOctetString(name *C.char, value []byte) { ++ if !b.check() { ++ return ++ } ++ if len(value) != 0 { ++ b.pinner.Pin(&value[0]) ++ } ++ if C.go_openssl_OSSL_PARAM_BLD_push_octet_string(b.bld, name, unsafe.Pointer(sbase(value)), C.size_t(len(value))) != 1 { ++ b.err = newOpenSSLError("OSSL_PARAM_BLD_push_octet_string(" + C.GoString(name) + ")") ++ } ++} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go new file mode 100644 -index 0000000000..a895eab2d5 +index 0000000000..7f19197a2c --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go -@@ -0,0 +1,28 @@ +@@ -0,0 +1,32 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -8336,8 +10405,12 @@ index 0000000000..a895eab2d5 + "hash" +) + -+func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) ([]byte, error) { -+ md := hashToMD(h()) ++func PBKDF2(password, salt []byte, iter, keyLen int, fh func() hash.Hash) ([]byte, error) { ++ h, err := hashFuncHash(fh) ++ if err != nil { ++ return nil, err ++ } ++ md := hashToMD(h) + if md == nil { + return nil, errors.New("unsupported hash function") + } @@ -8353,6 +10426,98 @@ index 0000000000..a895eab2d5 + } + return out, nil +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/port_dsa.c b/src/vendor/github.com/golang-fips/openssl/v2/port_dsa.c +new file mode 100644 +index 0000000000..5a948eafdb +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/port_dsa.c +@@ -0,0 +1,85 @@ ++// The following is a partial backport of crypto/dsa/dsa_lockl.h ++// and crypto/dsa/dsa_lib.c, commit cbc8a839959418d8a2c2e3ec6bdf394852c9501e ++// on the OpenSSL_1_1_0-stable branch. Only pqg and key getters/setters ++// are backported. ++ ++#include "goopenssl.h" ++ ++struct dsa_st ++{ ++ int _ignored0; ++ long _ignored1; ++ int _ignored2; ++ GO_BIGNUM_PTR p; ++ GO_BIGNUM_PTR q; ++ GO_BIGNUM_PTR g; ++ GO_BIGNUM_PTR pub_key; ++ GO_BIGNUM_PTR priv_key; ++ // The following members are not used by our backport, ++ // so we don't define them here. ++}; ++ ++void go_openssl_DSA_get0_pqg_backport(const GO_DSA_PTR dsa, ++ GO_BIGNUM_PTR *p, GO_BIGNUM_PTR *q, GO_BIGNUM_PTR *g) ++{ ++ const struct dsa_st *d = dsa; ++ if (p != NULL) ++ *p = d->p; ++ if (q != NULL) ++ *q = d->q; ++ if (g != NULL) ++ *g = d->g; ++} ++ ++int go_openssl_DSA_set0_pqg_backport(GO_DSA_PTR dsa, ++ GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g) ++{ ++ struct dsa_st *d = dsa; ++ if ((d->p == NULL && p == NULL) ++ || (d->q == NULL && q == NULL) ++ || (d->g == NULL && g == NULL)) ++ return 0; ++ ++ if (p != NULL) { ++ go_openssl_BN_free(d->p); ++ d->p = p; ++ } ++ if (q != NULL) { ++ go_openssl_BN_free(d->q); ++ d->q = q; ++ } ++ if (g != NULL) { ++ go_openssl_BN_free(d->g); ++ d->g = g; ++ } ++ ++ return 1; ++} ++ ++void go_openssl_DSA_get0_key_backport(const GO_DSA_PTR dsa, ++ GO_BIGNUM_PTR *pub_key, GO_BIGNUM_PTR *priv_key) ++{ ++ const struct dsa_st *d = dsa; ++ if (pub_key != NULL) ++ *pub_key = d->pub_key; ++ if (priv_key != NULL) ++ *priv_key = d->priv_key; ++} ++ ++int go_openssl_DSA_set0_key_backport(GO_DSA_PTR dsa, GO_BIGNUM_PTR pub_key, GO_BIGNUM_PTR priv_key) ++{ ++ struct dsa_st *d = dsa; ++ if (d->pub_key == NULL && pub_key == NULL) ++ return 0; ++ ++ if (pub_key != NULL) { ++ go_openssl_BN_free(d->pub_key); ++ d->pub_key = pub_key; ++ } ++ if (priv_key != NULL) { ++ go_openssl_BN_free(d->priv_key); ++ d->priv_key = priv_key; ++ } ++ ++ return 1; ++} +\ No newline at end of file diff --git a/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c new file mode 100644 index 0000000000..50d49b1f10 @@ -8585,10 +10750,10 @@ index 0000000000..f88150591e +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rsa.go b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go new file mode 100644 -index 0000000000..f28d323adc +index 0000000000..4e45b02d88 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go -@@ -0,0 +1,435 @@ +@@ -0,0 +1,443 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -8605,14 +10770,14 @@ index 0000000000..f28d323adc +) + +var ( -+ paramRSA_N = C.CString("n") -+ paramRSA_E = C.CString("e") -+ paramRSA_D = C.CString("d") -+ paramRSA_P = C.CString("rsa-factor1") -+ paramRSA_Q = C.CString("rsa-factor2") -+ paramRSA_Dp = C.CString("rsa-exponent1") -+ paramRSA_Dq = C.CString("rsa-exponent2") -+ paramRSA_Qinv = C.CString("rsa-coefficient1") ++ OSSL_PKEY_PARAM_RSA_N = C.CString("n") ++ OSSL_PKEY_PARAM_RSA_E = C.CString("e") ++ OSSL_PKEY_PARAM_RSA_D = C.CString("d") ++ OSSL_PKEY_PARAM_RSA_FACTOR1 = C.CString("rsa-factor1") ++ OSSL_PKEY_PARAM_RSA_FACTOR2 = C.CString("rsa-factor2") ++ OSSL_PKEY_PARAM_RSA_EXPONENT1 = C.CString("rsa-exponent1") ++ OSSL_PKEY_PARAM_RSA_EXPONENT2 = C.CString("rsa-exponent2") ++ OSSL_PKEY_PARAM_RSA_COEFFICIENT1 = C.CString("rsa-coefficient1") +) + +func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { @@ -8664,14 +10829,14 @@ index 0000000000..f28d323adc + C.go_openssl_BN_clear(tmp) + return true + } -+ if !(setBigInt(&N, paramRSA_N) && -+ setBigInt(&E, paramRSA_E) && -+ setBigInt(&D, paramRSA_D) && -+ setBigInt(&P, paramRSA_P) && -+ setBigInt(&Q, paramRSA_Q) && -+ setBigInt(&Dp, paramRSA_Dp) && -+ setBigInt(&Dq, paramRSA_Dq) && -+ setBigInt(&Qinv, paramRSA_Qinv)) { ++ if !(setBigInt(&N, OSSL_PKEY_PARAM_RSA_N) && ++ setBigInt(&E, OSSL_PKEY_PARAM_RSA_E) && ++ setBigInt(&D, OSSL_PKEY_PARAM_RSA_D) && ++ setBigInt(&P, OSSL_PKEY_PARAM_RSA_FACTOR1) && ++ setBigInt(&Q, OSSL_PKEY_PARAM_RSA_FACTOR2) && ++ setBigInt(&Dp, OSSL_PKEY_PARAM_RSA_EXPONENT1) && ++ setBigInt(&Dq, OSSL_PKEY_PARAM_RSA_EXPONENT2) && ++ setBigInt(&Qinv, OSSL_PKEY_PARAM_RSA_COEFFICIENT1)) { + return bad(err) + } + default: @@ -8685,7 +10850,7 @@ index 0000000000..f28d323adc + _pkey C.GO_EVP_PKEY_PTR +} + -+func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { ++func NewPublicKeyRSA(n, e BigInt) (*PublicKeyRSA, error) { + var pkey C.GO_EVP_PKEY_PTR + switch vMajor { + case 1: @@ -8693,7 +10858,7 @@ index 0000000000..f28d323adc + if key == nil { + return nil, newOpenSSLError("RSA_new failed") + } -+ if !rsaSetKey(key, N, E, nil) { ++ if !rsaSetKey(key, n, e, nil) { + return nil, fail("RSA_set0_key") + } + pkey = C.go_openssl_EVP_PKEY_new() @@ -8708,7 +10873,7 @@ index 0000000000..f28d323adc + } + case 3: + var err error -+ if pkey, err = newRSAKey3(false, N, E, nil, nil, nil, nil, nil, nil); err != nil { ++ if pkey, err = newRSAKey3(false, n, e, nil, nil, nil, nil, nil, nil); err != nil { + return nil, err + } + default: @@ -8736,7 +10901,7 @@ index 0000000000..f28d323adc + _pkey C.GO_EVP_PKEY_PTR +} + -+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) { ++func NewPrivateKeyRSA(n, e, d, p, q, dp, dq, qinv BigInt) (*PrivateKeyRSA, error) { + var pkey C.GO_EVP_PKEY_PTR + switch vMajor { + case 1: @@ -8744,16 +10909,16 @@ index 0000000000..f28d323adc + if key == nil { + return nil, newOpenSSLError("RSA_new failed") + } -+ if !rsaSetKey(key, N, E, D) { ++ if !rsaSetKey(key, n, e, d) { + return nil, fail("RSA_set0_key") + } -+ if P != nil && Q != nil { -+ if !rsaSetFactors(key, P, Q) { ++ if p != nil && q != nil { ++ if !rsaSetFactors(key, p, q) { + return nil, fail("RSA_set0_factors") + } + } -+ if Dp != nil && Dq != nil && Qinv != nil { -+ if !rsaSetCRTParams(key, Dp, Dq, Qinv) { ++ if dp != nil && dq != nil && qinv != nil { ++ if !rsaSetCRTParams(key, dp, dq, qinv) { + return nil, fail("RSA_set0_crt_params") + } + } @@ -8769,7 +10934,7 @@ index 0000000000..f28d323adc + } + case 3: + var err error -+ if pkey, err = newRSAKey3(true, N, E, D, P, Q, Dp, Dq, Qinv); err != nil { ++ if pkey, err = newRSAKey3(true, n, e, d, p, q, dp, dq, qinv); err != nil { + return nil, err + } + default: @@ -8925,7 +11090,7 @@ index 0000000000..f28d323adc +func rsaSetKey(key C.GO_RSA_PTR, n, e, d BigInt) bool { + if vMajor == 1 && vMinor == 0 { + r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) -+ //r.d and d will be nil for public keys. ++ // r.d and d will be nil for public keys. + if (r.n == nil && n == nil) || + (r.e == nil && e == nil) { + return false @@ -8967,8 +11132,7 @@ index 0000000000..f28d323adc + } + return C.go_openssl_RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == 1 +} -+ -+func newRSAKey3(isPriv bool, N, E, D, P, Q, Dp, Dq, Qinv BigInt) (C.GO_EVP_PKEY_PTR, error) { ++func newRSAKey3(isPriv bool, n, e, d, p, q, dp, dq, qinv BigInt) (C.GO_EVP_PKEY_PTR, error) { + // Construct the parameters. + bld := C.go_openssl_OSSL_PARAM_BLD_new() + if bld == nil { @@ -8976,7 +11140,7 @@ index 0000000000..f28d323adc + } + defer C.go_openssl_OSSL_PARAM_BLD_free(bld) + -+ type bigIntParam struct{ ++ type bigIntParam struct { + name *C.char + num BigInt + } @@ -8984,19 +11148,28 @@ index 0000000000..f28d323adc + comps := make([]bigIntParam, 0, 8) + + required := [...]bigIntParam{ -+ {paramRSA_N, N}, {paramRSA_E, E}, {paramRSA_D, D}, ++ {OSSL_PKEY_PARAM_RSA_N, n}, {OSSL_PKEY_PARAM_RSA_E, e}, {OSSL_PKEY_PARAM_RSA_D, d}, + } + comps = append(comps, required[:]...) + -+ // OpenSSL 3.0 and 3.1 required all the precomputed values if -+ // P and Q are present. See: -+ // https://github.com/openssl/openssl/pull/22334 -+ if P != nil && Q != nil && Dp != nil && Dq != nil && Qinv != nil { -+ precomputed := [...]bigIntParam{ -+ {paramRSA_P, P}, {paramRSA_Q, Q}, -+ {paramRSA_Dp, Dp}, {paramRSA_Dq, Dq}, {paramRSA_Qinv, Qinv}, ++ if p != nil && q != nil { ++ allPrecomputedExists := dp != nil && dq != nil && qinv != nil ++ // The precomputed values should only be passed if P and Q are present ++ // and every precomputed value is present. (If any precomputed value is ++ // missing, don't pass any of them.) ++ // ++ // In OpenSSL 3.0 and 3.1, we must also omit P and Q if any precomputed ++ // value is missing. See https://github.com/openssl/openssl/pull/22334 ++ if vMinor >= 2 || allPrecomputedExists { ++ comps = append(comps, bigIntParam{OSSL_PKEY_PARAM_RSA_FACTOR1, p}, bigIntParam{OSSL_PKEY_PARAM_RSA_FACTOR2, q}) ++ } ++ if allPrecomputedExists { ++ comps = append(comps, ++ bigIntParam{OSSL_PKEY_PARAM_RSA_EXPONENT1, dp}, ++ bigIntParam{OSSL_PKEY_PARAM_RSA_EXPONENT2, dq}, ++ bigIntParam{OSSL_PKEY_PARAM_RSA_COEFFICIENT1, qinv}, ++ ) + } -+ comps = append(comps, precomputed[:]...) + } + + for _, comp := range comps { @@ -9026,10 +11199,10 @@ index 0000000000..f28d323adc +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/shims.h b/src/vendor/github.com/golang-fips/openssl/v2/shims.h new file mode 100644 -index 0000000000..99656f0cf2 +index 0000000000..79afa627c4 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/shims.h -@@ -0,0 +1,371 @@ +@@ -0,0 +1,396 @@ +#include // size_t +#include // uint64_t + @@ -9051,9 +11224,10 @@ index 0000000000..99656f0cf2 + GO_EVP_PKEY_TLS1_PRF = 1021, + GO_EVP_PKEY_HKDF = 1036, + GO_EVP_PKEY_ED25519 = 1087, ++ GO_EVP_PKEY_DSA = 116, + /* This is defined differently in OpenSSL 3 (1 << 11), but in our + * code it is only used in OpenSSL 1. -+ */ ++ */ + GO1_EVP_PKEY_OP_DERIVE = (1 << 10), + GO_EVP_MAX_MD_SIZE = 64, + @@ -9108,7 +11282,9 @@ index 0000000000..99656f0cf2 + GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS = 0x1003, + GO_EVP_PKEY_CTRL_RSA_MGF1_MD = 0x1005, + GO_EVP_PKEY_CTRL_RSA_OAEP_MD = 0x1009, -+ GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL = 0x100A ++ GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL = 0x100A, ++ GO_EVP_PKEY_CTRL_DSA_PARAMGEN_BITS = 0x1001, ++ GO_EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS = 0x1002 +}; + +typedef void* GO_OPENSSL_INIT_SETTINGS_PTR; @@ -9134,6 +11310,9 @@ index 0000000000..99656f0cf2 +typedef void* GO_OSSL_PARAM_PTR; +typedef void* GO_CRYPTO_THREADID_PTR; +typedef void* GO_EVP_SIGNATURE_PTR; ++typedef void* GO_DSA_PTR; ++typedef void* GO_EVP_KDF_PTR; ++typedef void* GO_EVP_KDF_CTX_PTR; + +// #include +typedef void* GO_MD5_CTX_PTR; @@ -9190,6 +11369,7 @@ index 0000000000..99656f0cf2 +// #include +// #include +// #include ++// #include +// #if OPENSSL_VERSION_NUMBER >= 0x30000000L +// #include +// #include @@ -9222,13 +11402,17 @@ index 0000000000..99656f0cf2 +DEFINEFUNC_3_0(int, EVP_default_properties_enable_fips, (GO_OSSL_LIB_CTX_PTR libctx, int enable), (libctx, enable)) \ +DEFINEFUNC_3_0(int, OSSL_PROVIDER_available, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ +DEFINEFUNC_3_0(GO_OSSL_PROVIDER_PTR, OSSL_PROVIDER_load, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ ++DEFINEFUNC_3_0(const char *, OSSL_PROVIDER_get0_name, (const GO_OSSL_PROVIDER_PTR prov), (prov)) \ +DEFINEFUNC_3_0(GO_EVP_MD_PTR, EVP_MD_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ +DEFINEFUNC_3_0(void, EVP_MD_free, (GO_EVP_MD_PTR md), (md)) \ +DEFINEFUNC_3_0(const char *, EVP_MD_get0_name, (const GO_EVP_MD_PTR md), (md)) \ ++DEFINEFUNC_3_0(const GO_OSSL_PROVIDER_PTR, EVP_MD_get0_provider, (const GO_EVP_MD_PTR md), (md)) \ ++DEFINEFUNC_RENAMED_3_0(int, EVP_MD_get_block_size, EVP_MD_block_size, (const GO_EVP_MD_PTR md), (md)) \ +DEFINEFUNC(int, RAND_bytes, (unsigned char *arg0, int arg1), (arg0, arg1)) \ +DEFINEFUNC_RENAMED_1_1(GO_EVP_MD_CTX_PTR, EVP_MD_CTX_new, EVP_MD_CTX_create, (void), ()) \ +DEFINEFUNC_RENAMED_1_1(void, EVP_MD_CTX_free, EVP_MD_CTX_destroy, (GO_EVP_MD_CTX_PTR ctx), (ctx)) \ +DEFINEFUNC(int, EVP_MD_CTX_copy, (GO_EVP_MD_CTX_PTR out, const GO_EVP_MD_CTX_PTR in), (out, in)) \ ++DEFINEFUNC(int, EVP_MD_CTX_copy_ex, (GO_EVP_MD_CTX_PTR out, const GO_EVP_MD_CTX_PTR in), (out, in)) \ +DEFINEFUNC(int, EVP_Digest, (const void *data, size_t count, unsigned char *md, unsigned int *size, const GO_EVP_MD_PTR type, GO_ENGINE_PTR impl), (data, count, md, size, type, impl)) \ +DEFINEFUNC(int, EVP_DigestInit_ex, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR impl), (ctx, type, impl)) \ +DEFINEFUNC(int, EVP_DigestInit, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type), (ctx, type)) \ @@ -9312,8 +11496,12 @@ index 0000000000..99656f0cf2 +DEFINEFUNC(int, EVP_PKEY_verify, (GO_EVP_PKEY_CTX_PTR ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sig, siglen, tbs, tbslen)) \ +DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new, (GO_EVP_PKEY_PTR arg0, GO_ENGINE_PTR arg1), (arg0, arg1)) \ +DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new_id, (int id, GO_ENGINE_PTR e), (id, e)) \ ++DEFINEFUNC_3_0(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new_from_pkey, (GO_OSSL_LIB_CTX_PTR libctx, GO_EVP_PKEY_PTR pkey, const char *propquery), (libctx, pkey, propquery)) \ ++DEFINEFUNC(int, EVP_PKEY_paramgen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC(int, EVP_PKEY_paramgen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ +DEFINEFUNC(int, EVP_PKEY_keygen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ +DEFINEFUNC(int, EVP_PKEY_keygen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_private_check, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ +DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ +DEFINEFUNC(int, EVP_PKEY_CTX_ctrl, (GO_EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2), (ctx, keytype, optype, cmd, p1, p2)) \ +DEFINEFUNC(int, EVP_PKEY_decrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ @@ -9328,6 +11516,7 @@ index 0000000000..99656f0cf2 +DEFINEFUNC(int, EVP_PKEY_derive, (GO_EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t *keylen), (ctx, key, keylen)) \ +DEFINEFUNC_LEGACY_1_0(void*, EVP_PKEY_get0, (GO_EVP_PKEY_PTR pkey), (pkey)) \ +DEFINEFUNC_LEGACY_1_1(GO_EC_KEY_PTR, EVP_PKEY_get0_EC_KEY, (GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC_LEGACY_1_1(GO_DSA_PTR, EVP_PKEY_get0_DSA, (GO_EVP_PKEY_PTR pkey), (pkey)) \ +DEFINEFUNC_3_0(int, EVP_PKEY_fromdata_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ +DEFINEFUNC_3_0(int, EVP_PKEY_fromdata, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *pkey, int selection, GO_OSSL_PARAM_PTR params), (ctx, pkey, selection, params)) \ +DEFINEFUNC_3_0(int, EVP_PKEY_set1_encoded_public_key, (GO_EVP_PKEY_PTR pkey, const unsigned char *pub, size_t publen), (pkey, pub, publen)) \ @@ -9372,6 +11561,7 @@ index 0000000000..99656f0cf2 +DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP_PTR group), (group)) \ +DEFINEFUNC_3_0(GO_EVP_MAC_PTR, EVP_MAC_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ +DEFINEFUNC_3_0(GO_EVP_MAC_CTX_PTR, EVP_MAC_CTX_new, (GO_EVP_MAC_PTR arg0), (arg0)) \ ++DEFINEFUNC_3_0(int, EVP_MAC_CTX_set_params, (GO_EVP_MAC_CTX_PTR ctx, const GO_OSSL_PARAM_PTR params), (ctx, params)) \ +DEFINEFUNC_3_0(void, EVP_MAC_CTX_free, (GO_EVP_MAC_CTX_PTR arg0), (arg0)) \ +DEFINEFUNC_3_0(GO_EVP_MAC_CTX_PTR, EVP_MAC_CTX_dup, (const GO_EVP_MAC_CTX_PTR arg0), (arg0)) \ +DEFINEFUNC_3_0(int, EVP_MAC_init, (GO_EVP_MAC_CTX_PTR ctx, const unsigned char *key, size_t keylen, const GO_OSSL_PARAM_PTR params), (ctx, key, keylen, params)) \ @@ -9393,14 +11583,22 @@ index 0000000000..99656f0cf2 +DEFINEFUNC_LEGACY_1(int, EVP_PKEY_set1_EC_KEY, (GO_EVP_PKEY_PTR pkey, GO_EC_KEY_PTR key), (pkey, key)) \ +DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set0_rsa_oaep_label, (GO_EVP_PKEY_CTX_PTR ctx, void *label, int len), (ctx, label, len)) \ +DEFINEFUNC(int, PKCS5_PBKDF2_HMAC, (const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const GO_EVP_MD_PTR digest, int keylen, unsigned char *out), (pass, passlen, salt, saltlen, iter, digest, keylen, out)) \ -+DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set_tls1_prf_md, (GO_EVP_PKEY_CTX_PTR arg0, const GO_EVP_MD_PTR arg1), (arg0, arg1)) \ -+DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set1_tls1_prf_secret, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC_3_0(int, EVP_PKEY_CTX_add1_tls1_prf_seed, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ +DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_public_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len), (pkey, pub, len)) \ +DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_private_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t *len), (pkey, priv, len)) \ +DEFINEFUNC_3_0(GO_EVP_SIGNATURE_PTR, EVP_SIGNATURE_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ +DEFINEFUNC_3_0(void, EVP_SIGNATURE_free, (GO_EVP_SIGNATURE_PTR signature), (signature)) \ -+ ++DEFINEFUNC_LEGACY_1(GO_DSA_PTR, DSA_new, (void), ()) \ ++DEFINEFUNC_LEGACY_1(void, DSA_free, (GO_DSA_PTR r), (r)) \ ++DEFINEFUNC_LEGACY_1(int, DSA_generate_key, (GO_DSA_PTR a), (a)) \ ++DEFINEFUNC_LEGACY_1_1(void, DSA_get0_pqg, (const GO_DSA_PTR d, const GO_BIGNUM_PTR *p, const GO_BIGNUM_PTR *q, const GO_BIGNUM_PTR *g), (d, p, q, g)) \ ++DEFINEFUNC_LEGACY_1_1(int, DSA_set0_pqg, (GO_DSA_PTR d, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g), (d, p, q, g)) \ ++DEFINEFUNC_LEGACY_1_1(void, DSA_get0_key, (const GO_DSA_PTR d, const GO_BIGNUM_PTR *pub_key, const GO_BIGNUM_PTR *priv_key), (d, pub_key, priv_key)) \ ++DEFINEFUNC_LEGACY_1_1(int, DSA_set0_key, (GO_DSA_PTR d, GO_BIGNUM_PTR pub_key, GO_BIGNUM_PTR priv_key), (d, pub_key, priv_key)) \ ++DEFINEFUNC_3_0(GO_EVP_KDF_PTR, EVP_KDF_fetch, (GO_OSSL_LIB_CTX_PTR libctx, const char *algorithm, const char *properties), (libctx, algorithm, properties)) \ ++DEFINEFUNC_3_0(void, EVP_KDF_free, (GO_EVP_KDF_PTR kdf), (kdf)) \ ++DEFINEFUNC_3_0(GO_EVP_KDF_CTX_PTR, EVP_KDF_CTX_new, (GO_EVP_KDF_PTR kdf), (kdf)) \ ++DEFINEFUNC_3_0(void, EVP_KDF_CTX_free, (GO_EVP_KDF_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC_3_0(int, EVP_KDF_derive, (GO_EVP_KDF_CTX_PTR ctx, unsigned char *key, size_t keylen, const GO_OSSL_PARAM_PTR params), (ctx, key, keylen, params)) diff --git a/src/vendor/github.com/golang-fips/openssl/v2/thread_setup.go b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup.go new file mode 100644 index 0000000000..5e0da7e362 @@ -9433,10 +11631,10 @@ index 0000000000..98d12f82a2 +extern volatile unsigned int go_openssl_threads_cleaned_up; diff --git a/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c new file mode 100644 -index 0000000000..53ea9d03d7 +index 0000000000..c837f9cb4d --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c -@@ -0,0 +1,61 @@ +@@ -0,0 +1,64 @@ +//go:build unix + +#include "goopenssl.h" @@ -9467,8 +11665,11 @@ index 0000000000..53ea9d03d7 + // per-thread error state, so this function is guaranteed to be executed at + // least once on any thread with associated error state. The thread-local + // variable needs to be set to a non-NULL value so that the destructor will -+ // be called when the thread exits. The actual value does not matter. -+ (void) pthread_setspecific(destructor_key, (void*)1); ++ // be called when the thread exits. ++ // The actual value does not matter, but should be a pointer with a valid size. ++ // See https://github.com/golang-fips/openssl/pull/162 ++ static char stub; ++ (void) pthread_setspecific(destructor_key, &stub); +} + +static void cleanup_thread_state(void *ignored) @@ -9570,10 +11771,10 @@ index 0000000000..93281d6cff +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go new file mode 100644 -index 0000000000..5de62f95a7 +index 0000000000..f342f221ea --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go -@@ -0,0 +1,104 @@ +@@ -0,0 +1,160 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -9584,20 +11785,28 @@ index 0000000000..5de62f95a7 + "crypto" + "errors" + "hash" ++ "sync" + "unsafe" +) + +func SupportsTLS1PRF() bool { -+ return vMajor > 1 || -+ (vMajor >= 1 && vMinor >= 1) ++ switch vMajor { ++ case 1: ++ return vMinor >= 1 ++ case 3: ++ _, err := fetchTLS1PRF3() ++ return err == nil ++ default: ++ panic(errUnsupportedVersion()) ++ } +} + +// TLS1PRF implements the TLS 1.0/1.1 pseudo-random function if h is nil, +// else it implements the TLS 1.2 pseudo-random function. +// The pseudo-random number will be written to result and will be of length len(result). -+func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { ++func TLS1PRF(result, secret, label, seed []byte, fh func() hash.Hash) error { + var md C.GO_EVP_MD_PTR -+ if h == nil { ++ if fh == nil { + // TLS 1.0/1.1 PRF doesn't allow to specify the hash function, + // it always uses MD5SHA1. If h is nil, then assume + // that the caller wants to use TLS 1.0/1.1 PRF. @@ -9605,12 +11814,30 @@ index 0000000000..5de62f95a7 + // function is MD5SHA1. + md = cryptoHashToMD(crypto.MD5SHA1) + } else { -+ md = hashToMD(h()) ++ h, err := hashFuncHash(fh) ++ if err != nil { ++ return err ++ } ++ md = hashToMD(h) + } + if md == nil { + return errors.New("unsupported hash function") + } + ++ switch vMajor { ++ case 1: ++ return tls1PRF1(result, secret, label, seed, md) ++ case 3: ++ return tls1PRF3(result, secret, label, seed, md) ++ default: ++ return errUnsupportedVersion() ++ } ++} ++ ++// tls1PRF1 implements TLS1PRF for OpenSSL 1 using the EVP_PKEY API. ++func tls1PRF1(result, secret, label, seed []byte, md C.GO_EVP_MD_PTR) error { ++ checkMajorVersion(1) ++ + ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_TLS1_PRF, nil) + if ctx == nil { + return newOpenSSLError("EVP_PKEY_CTX_new_id") @@ -9622,48 +11849,29 @@ index 0000000000..5de62f95a7 + if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { + return newOpenSSLError("EVP_PKEY_derive_init") + } -+ switch vMajor { -+ case 3: -+ if C.go_openssl_EVP_PKEY_CTX_set_tls1_prf_md(ctx, md) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_set1_tls1_prf_secret(ctx, -+ base(secret), C.int(len(secret))) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, -+ base(label), C.int(len(label))) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, -+ base(seed), C.int(len(seed))) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") -+ } -+ case 1: -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -+ C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_TLS_MD, -+ 0, unsafe.Pointer(md)) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -+ C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_TLS_SECRET, -+ C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -+ C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_TLS_SEED, -+ C.int(len(label)), unsafe.Pointer(base(label))) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -+ C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_TLS_SEED, -+ C.int(len(seed)), unsafe.Pointer(base(seed))) != 1 { -+ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") -+ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_MD, ++ 0, unsafe.Pointer(md)) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_SECRET, ++ C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_SEED, ++ C.int(len(label)), unsafe.Pointer(base(label))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_SEED, ++ C.int(len(seed)), unsafe.Pointer(base(seed))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") + } + outLen := C.size_t(len(result)) + if C.go_openssl_EVP_PKEY_derive_wrapper(ctx, base(result), outLen).result != 1 { @@ -9678,15 +11886,64 @@ index 0000000000..5de62f95a7 + } + return nil +} ++ ++// fetchTLS1PRF3 fetches the TLS1-PRF KDF algorithm. ++// It is safe to call this function concurrently. ++// The returned EVP_KDF_PTR shouldn't be freed. ++var fetchTLS1PRF3 = sync.OnceValues(func() (C.GO_EVP_KDF_PTR, error) { ++ checkMajorVersion(3) ++ ++ name := C.CString("TLS1-PRF") ++ kdf := C.go_openssl_EVP_KDF_fetch(nil, name, nil) ++ C.free(unsafe.Pointer(name)) ++ if kdf == nil { ++ return nil, newOpenSSLError("EVP_KDF_fetch") ++ } ++ return kdf, nil ++}) ++ ++// tls1PRF3 implements TLS1PRF for OpenSSL 3 using the EVP_KDF API. ++func tls1PRF3(result, secret, label, seed []byte, md C.GO_EVP_MD_PTR) error { ++ checkMajorVersion(3) ++ ++ kdf, err := fetchTLS1PRF3() ++ if err != nil { ++ return err ++ } ++ ctx := C.go_openssl_EVP_KDF_CTX_new(kdf) ++ if ctx == nil { ++ return newOpenSSLError("EVP_KDF_CTX_new") ++ } ++ defer C.go_openssl_EVP_KDF_CTX_free(ctx) ++ ++ bld, err := newParamBuilder() ++ if err != nil { ++ return err ++ } ++ bld.addUTF8String(_OSSL_KDF_PARAM_DIGEST, C.go_openssl_EVP_MD_get0_name(md), 0) ++ bld.addOctetString(_OSSL_KDF_PARAM_SECRET, secret) ++ bld.addOctetString(_OSSL_KDF_PARAM_SEED, label) ++ bld.addOctetString(_OSSL_KDF_PARAM_SEED, seed) ++ params, err := bld.build() ++ if err != nil { ++ return err ++ } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ ++ if C.go_openssl_EVP_KDF_derive(ctx, base(result), C.size_t(len(result)), params) != 1 { ++ return newOpenSSLError("EVP_KDF_derive") ++ } ++ return nil ++} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index 1c88c1299f..dce93f02ca 100644 +index 7ca8e34908..bf66a1cd19 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,7 @@ -+# github.com/golang-fips/openssl/v2 v2.0.3 -+## explicit; go 1.20 ++# github.com/golang-fips/openssl/v2 v2.0.4-0.20240925082504-4fb8ffc9b3b8 ++## explicit; go 1.22 +github.com/golang-fips/openssl/v2 +github.com/golang-fips/openssl/v2/bbig - # golang.org/x/crypto v0.23.1-0.20240603234054-0b431c7de36a - ## explicit; go 1.18 + # golang.org/x/crypto v0.30.0 + ## explicit; go 1.20 golang.org/x/crypto/chacha20 diff --git a/scripts/apply-initial-patch.sh b/scripts/apply-initial-patch.sh deleted file mode 100755 index ced2b3b984..0000000000 --- a/scripts/apply-initial-patch.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -ex - -# Apply the initial patch. This patch is basic and shouldn't accrue many -# conflicts over time so it should be safe to apply. -git apply -v ../patches/000-initial-setup.patch -# Add the initial changes to the index so the later diff ignores them. -git add . -git commit -m phase1 diff --git a/scripts/create-secondary-patch.sh b/scripts/create-secondary-patch.sh deleted file mode 100755 index e7b683ddf6..0000000000 --- a/scripts/create-secondary-patch.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -set -ex - -# Apply some manual substitutions with sed. These changes will likely introduce -# merge conflicts if this was a patch, so we do them here instead and generate a patch -# after. -GO_SOURCES=src/crypto/**/*.go -sed -i -e "s/boring\.Enabled/boring\.Enabled()/g" ${GO_SOURCES} -sed -i -e "s/\"crypto\/internal\/boring\"/boring \"crypto\/internal\/backend\"/g" ${GO_SOURCES} -sed -i -e "s/\"crypto\/internal\/boring\/bbig\"/\"crypto\/internal\/backend\/bbig\"/g" ${GO_SOURCES} -sed -i -e "s/const boringEnabled/var boringEnabled/g" ${GO_SOURCES} -sed -i -e "s/\!boringcrypto/no_openssl/g" ${GO_SOURCES} -sed -i -e "s/boringcrypto/!no_openssl/g" ${GO_SOURCES} -sed -i -e "s/boringcrypto/!no_openssl/g" src/crypto/internal/boring/fipstls/*.* -sed -i -e "s/boringcrypto/!no_openssl/g" src/cmd/api/*.* -# revert this back to fix the api test -sed -i -e "s/\!no_openssl/boringcrypto/g" src/crypto/boring/boring.go - -# Remove the crypto/internal/boring code as we're replacing it with the openssl backend code. -rm -rf src/crypto/internal/boring/*.go -#rm -rf src/crypto/internal/boring/bbig -rm src/crypto/boring/notboring_test.go -rm src/crypto/boring/boring_test.go -echo """// Copyright 2017 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. - -// Package boring provides access to BoringCrypto implementation functions. -// Check the constant Enabled to find out whether BoringCrypto is available. -// If BoringCrypto is not available, the functions in this package all panic. -package boring - -import \"github.com/golang-fips/openssl/v2\" - -// A BigInt is the raw words from a BigInt. -// This definition allows us to avoid importing math/big. -// Conversion between BigInt and *big.Int is in crypto/internal/boring/bbig. -type BigInt = openssl.BigInt -""" >src/crypto/internal/boring/doc.go - -# Add new openssl backend to module and vendor it. -export GOROOT=$(pwd) -cd src -SCRIPT_DIR=$(readlink -f $(dirname $0)) -CONFIG_DIR=$(readlink -f $(dirname $0)/../config) -OPENSSL_FIPS_REF=$(../bin/go run ${SCRIPT_DIR}/versions.go ${CONFIG_DIR}/versions.json \ - github.com/golang-fips/openssl) -../bin/go get github.com/golang-fips/openssl/v2@${OPENSSL_FIPS_REF} - -replace="${1}" -if [ -n "${replace}" ]; then - go mod edit -replace github.com/golang-fips/openssl/v2="${replace}" -fi -../bin/go mod tidy -../bin/go mod vendor - -# Generate the final patch. -git add . -git diff --cached --binary >../../patches/001-initial-openssl-for-fips.patch diff --git a/scripts/full-initialize-repo.sh b/scripts/full-initialize-repo.sh index 9661f2d955..3f11e7a63c 100755 --- a/scripts/full-initialize-repo.sh +++ b/scripts/full-initialize-repo.sh @@ -17,7 +17,7 @@ if [[ -d "${GO_DIR}" ]]; then exit 1 fi -${SCRIPT_DIR}/setup-initial-patch.sh $@ +${SCRIPT_DIR}/setup-go-submodule.sh $@ set -ex pushd ${GO_DIR} diff --git a/scripts/setup-initial-patch.sh b/scripts/setup-initial-patch.sh deleted file mode 100755 index 3478a9810e..0000000000 --- a/scripts/setup-initial-patch.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -set -ex - -ROOT=$(pwd) - -# Function to clean things up if any portion of the script fails. -function cleanup() { - # shellcheck disable=SC2181 - if [ "0" != "${?}" ]; then - cd "${ROOT}" - git reset go - rm -rf go - fi -} -trap cleanup EXIT - -function usage() { - echo "Sets up new Go version for FIPS support. If you provide the flag -r you can specify a replacement for the openssl-fips backend." -} - -replacement="" - -while getopts "r:" o; do - case "${o}" in - r) - replacement=${OPTARG} - ;; - *) - usage - ;; - esac -done -shift $((OPTIND-1)) - -./scripts/setup-go-submodule.sh "${1}" - -# Enter the submodule directory. -cd ./go -ORIGINAL_GIT_SHA=$(git rev-parse HEAD) -echo $replacement - -# Build the Go toolchain before applying patches. This allows us to use this toolchain in later steps -# when running `go mod` commands. -pushd ./src -./make.bash -popd - -"${ROOT}"/scripts/apply-initial-patch.sh -"${ROOT}"/scripts/create-secondary-patch.sh "${replacement}" - -# Clean things up again after we've generated the patch. -git reset --hard "${ORIGINAL_GIT_SHA}"