diff --git a/go-fips-1.21.yaml b/go-fips-1.21.yaml new file mode 100644 index 00000000000..498e7444d01 --- /dev/null +++ b/go-fips-1.21.yaml @@ -0,0 +1,104 @@ +package: + name: go-fips-1.21 + version: 1.21.1 + epoch: 0 + description: "the Go programming language with OpenSSL cryptography" + copyright: + - license: BSD-3-Clause + dependencies: + provides: + - go-fips=${{package.version}}-${{package.epoch}} + runtime: + - build-base + - bash + - binutils-gold # Needed for cgo linking due to upstream issue #15696 which forces use of the gold linker. + - openssl-dev # Needed for building against cryptographic packages. + - '!go-1.21' + +environment: + contents: + packages: + - busybox + - ca-certificates-bundle + - build-base + - bash + - openssl-dev + # We always use the equivalent non-FIPS branch of Go to build this. + - go~1.21 + +pipeline: + - uses: fetch + with: + uri: https://go.dev/dl/go${{package.version}}.src.tar.gz + expected-sha256: bfa36bf75e9a1e9cbbdb9abcf9d1707e479bd3a07880a8ae3564caee5711cb99 + strip-components: 0 + + - working-directory: /home/build/go + pipeline: + - uses: patch + with: + patches: /home/build/000-initial-setup.patch + - uses: patch + with: + patches: /home/build/001-initial-openssl-for-fips.patch + - uses: patch + with: + patches: /home/build/0003-openssl-fips-unconditionally-use-openssl-backend.patch + - uses: patch + with: + patches: /home/build/0004-boring-always-enable-access-to-boring.Enabled-functi.patch + + - runs: | + cd go/src + ./make.bash -v + + - runs: | + cd go + + mkdir -p "${{targets.destdir}}"/usr/bin "${{targets.destdir}}"/usr/lib/go/bin "${{targets.destdir}}"/usr/share/doc/go + + for bin in go gofmt; do + install -Dm755 bin/$bin "${{targets.destdir}}"/usr/lib/go/bin/$bin + ln -s /usr/lib/go/bin/$bin "${{targets.destdir}}"/usr/bin/ + done + + cp -a pkg lib "${{targets.destdir}}"/usr/lib/go/ + cp -r doc misc "${{targets.destdir}}"/usr/share/doc/go + cp -a src "${{targets.destdir}}"/usr/lib/go/ + + rm -rf "${{targets.destdir}}"/usr/lib/go/pkg/obj + rm -rf "${{targets.destdir}}"/usr/lib/go/pkg/bootstrap + rm -rf "${{targets.destdir}}"/usr/lib/go/pkg/tool/*/api + rm -rf "${{targets.destdir}}"/usr/lib/go/pkg/*/cmd + rm -rf "${{targets.destdir}}"/usr/lib/go/pkg/tool/*/api + rm -rf "${{targets.destdir}}"/usr/lib/go/pkg/tool/*/go_bootstrap + rm -rf "${{targets.destdir}}"/usr/lib/go/src/cmd/dist/dist + + # Remove tests from /usr/lib/go/src, not needed at runtime + find "${{targets.destdir}}"/usr/lib/go/src \( -type f -a -name "*_test.go" \) \ + -exec rm -rf \{\} \+ + find "${{targets.destdir}}"/usr/lib/go/src \( -type d -a -name "testdata" \) \ + -exec rm -rf \{\} \+ + find "${{targets.destdir}}"/usr/lib/go/src \( -type f -a -name "*.rc" \) \ + -exec rm -rf \{\} \+ + find "${{targets.destdir}}"/usr/lib/go/src \( -type f -a -name "*.bat" \) \ + -exec rm -rf \{\} \+ + + - uses: strip + +subpackages: + - name: "go-fips-1.21-doc" + description: "go documentation" + pipeline: + - runs: | + mkdir -p "${{targets.subpkgdir}}"/usr/share + mv "${{targets.destdir}}"/usr/share/doc "${{targets.subpkgdir}}"/usr/share/ + +update: + enabled: true + shared: true + github: + identifier: golang/go + strip-prefix: go + tag-filter: go1.21 + use-tag: true diff --git a/go-fips-1.21/000-initial-setup.patch b/go-fips-1.21/000-initial-setup.patch new file mode 100644 index 00000000000..bbf7230ee66 --- /dev/null +++ b/go-fips-1.21/000-initial-setup.patch @@ -0,0 +1,1699 @@ +diff --git a/api/go1.19.txt b/api/go1.19.txt +index f31d633af9..e078f4aee1 100644 +--- a/api/go1.19.txt ++++ b/api/go1.19.txt +@@ -290,6 +290,8 @@ pkg sync/atomic, type Uint64 struct #50860 + pkg sync/atomic, type Uintptr struct #50860 + pkg time, method (Duration) Abs() Duration #51414 + pkg time, method (Time) ZoneBounds() (Time, Time) #50062 ++pkg crypto/ecdsa, func HashSign(io.Reader, *PrivateKey, []uint8, crypto.Hash) (*big.Int, *big.Int, error) #000000 ++pkg crypto/ecdsa, func HashVerify(*PublicKey, []uint8, *big.Int, *big.Int, crypto.Hash) bool #000000 + pkg crypto/x509, func ParseCRL //deprecated #50674 + pkg crypto/x509, func ParseDERCRL //deprecated #50674 + pkg crypto/x509, method (*Certificate) CheckCRLSignature //deprecated #50674 +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_hashsignverify.go b/src/crypto/ecdsa/ecdsa_hashsignverify.go +new file mode 100644 +index 0000000000..37f3a18223 +--- /dev/null ++++ b/src/crypto/ecdsa/ecdsa_hashsignverify.go +@@ -0,0 +1,45 @@ ++package ecdsa ++ ++import ( ++ "crypto" ++ "crypto/internal/boring" ++ "crypto/internal/randutil" ++ "math/big" ++ "io" ++) ++ ++func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) (*big.Int, *big.Int, error) { ++ randutil.MaybeReadByte(rand) ++ ++ if boring.Enabled { ++ b, err := boringPrivateKey(priv) ++ if err != nil { ++ return nil, nil, err ++ } ++ return boring.HashSignECDSA(b, msg, h) ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return Sign(rand, priv, d) ++} ++ ++func HashVerify(pub *PublicKey, msg []byte, r, s *big.Int, h crypto.Hash) bool { ++ if boring.Enabled { ++ bpk, err := boringPublicKey(pub) ++ if err != nil { ++ return false ++ } ++ return boring.HashVerifyECDSA(bpk, msg, r, s, h) ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return Verify(pub, d, r, s) ++} +diff --git a/src/crypto/ecdsa/ecdsa_hashsignverify_test.go b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go +new file mode 100644 +index 0000000000..d12ba2f441 +--- /dev/null ++++ b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go +@@ -0,0 +1,42 @@ ++package ecdsa ++ ++import ( ++ "crypto" ++ "crypto/internal/boring" ++ "crypto/elliptic" ++ "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 ++ r, s, err := HashSign(rand.Reader, priv, msg, h) ++ if err != nil { ++ t.Errorf("%s: error signing: %s", tag, err) ++ return ++ } ++ ++ if !HashVerify(&priv.PublicKey, msg, r, s, h) { ++ t.Errorf("%s: Verify failed", tag) ++ } ++ ++ msg[0] ^= 0xff ++ if HashVerify(&priv.PublicKey, msg, r, s, h) { ++ t.Errorf("%s: Verify should not have succeeded", tag) ++ } ++} ++func TestHashSignAndHashVerify(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/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/bbig/big.go b/src/crypto/internal/backend/bbig/big.go +new file mode 100644 +index 0000000000..c0800df578 +--- /dev/null ++++ b/src/crypto/internal/backend/bbig/big.go +@@ -0,0 +1,38 @@ ++// 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 crypto/internal/boring/bbig/big.go. ++ ++package bbig ++ ++import ( ++ "math/big" ++ "unsafe" ++ ++ "github.com/golang-fips/openssl-fips/openssl" ++) ++ ++func Enc(b *big.Int) openssl.BigInt { ++ if b == nil { ++ return nil ++ } ++ x := b.Bits() ++ if len(x) == 0 { ++ return openssl.BigInt{} ++ } ++ // TODO: Use unsafe.Slice((*uint)(&x[0]), len(x)) once go1.16 is no longer supported. ++ return (*(*[]uint)(unsafe.Pointer(&x)))[:len(x)] ++} ++ ++func Dec(b openssl.BigInt) *big.Int { ++ if b == nil { ++ return nil ++ } ++ if len(b) == 0 { ++ return new(big.Int) ++ } ++ // TODO: Use unsafe.Slice((*uint)(&b[0]), len(b)) once go1.16 is no longer supported. ++ x := (*(*[]big.Word)(unsafe.Pointer(&b)))[:len(b)] ++ return new(big.Int).SetBits(x) ++} +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 +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 ++// +build !linux !cgo android cmd_go_bootstrap msan no_openssl ++ ++package backend ++ ++import ( ++ "crypto" ++ "crypto/cipher" ++ "crypto/internal/boring/sig" ++ "math/big" ++ "github.com/golang-fips/openssl-fips/openssl" ++ "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 openssl.BigInt, err error) { ++ panic("boringcrypto: not available") ++} ++func NewPrivateKeyECDSA(curve string, X, Y, D openssl.BigInt) (*PrivateKeyECDSA, error) { ++ panic("boringcrypto: not available") ++} ++func NewPublicKeyECDSA(curve string, X, Y openssl.BigInt) (*PublicKeyECDSA, error) { ++ panic("boringcrypto: not available") ++} ++func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s openssl.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 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 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 openssl.BigInt, err error) { ++ panic("boringcrypto: not available") ++} ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv openssl.BigInt) (*PrivateKeyRSA, error) { ++ panic("boringcrypto: not available") ++} ++func NewPublicKeyRSA(N, E openssl.BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") } ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, msgHashed bool) ([]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, msgHashed bool) 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,106 @@ ++// 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 ++// +build linux,cgo,!android,!gocrypt,!cmd_go_bootstrap,!msan,!no_openssl ++ ++// 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 ( ++ "github.com/golang-fips/openssl-fips/openssl" ++) ++ ++// Enabled controls whether FIPS crypto is enabled. ++var Enabled = openssl.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") ++ } ++} ++ ++// 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") ++ } ++} ++ ++var ExecutingTest = openssl.ExecutingTest ++ ++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/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, 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, 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 1827f76458..140b1a3dd8 100644 +--- a/src/crypto/tls/boring.go ++++ b/src/crypto/tls/boring.go +@@ -8,8 +8,15 @@ package tls + + import ( + "crypto/internal/boring/fipstls" ++ boring "crypto/internal/backend" + ) + ++func init() { ++ if boring.Enabled && !boring.ExecutingTest() { ++ fipstls.Force() ++ } ++} ++ + // needFIPS returns fipstls.Required(); it avoids a new import in common.go. + func needFIPS() bool { + return fipstls.Required() +@@ -17,14 +24,18 @@ func needFIPS() bool { + + // fipsMinVersion replaces c.minVersion in FIPS-only mode. + func fipsMinVersion(c *Config) uint16 { +- // FIPS requires TLS 1.2. ++ // FIPS requires TLS 1.2 or later. + return VersionTLS12 + } + + // fipsMaxVersion replaces c.maxVersion in FIPS-only mode. + func fipsMaxVersion(c *Config) uint16 { +- // FIPS requires TLS 1.2. +- return VersionTLS12 ++ // FIPS requires TLS 1.2 or later. ++ if boring.SupportsHKDF() { ++ return VersionTLS13 ++ } else { ++ return VersionTLS12 ++ } + } + + // default defaultFIPSCurvePreferences is the FIPS-allowed curves, +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("VersionTLS10", VersionTLS10, "") + test("VersionTLS11", VersionTLS11, "") + test("VersionTLS12", VersionTLS12, "") +- test("VersionTLS13", VersionTLS13, "") ++ if boring.Enabled && !boring.SupportsHKDF() { ++ test("VersionTLS13", VersionTLS13, "client offered only unsupported versions") ++ } else { ++ test("VersionTLS13", VersionTLS13, "") ++ } + + fipstls.Force() + defer fipstls.Abandon() +@@ -52,11 +58,13 @@ func TestBoringServerProtocolVersion(t *testing.T) { + test("VersionTLS10", VersionTLS10, "client offered only unsupported versions") + test("VersionTLS11", VersionTLS11, "client offered only unsupported versions") + test("VersionTLS12", VersionTLS12, "") +- test("VersionTLS13", VersionTLS13, "client offered only unsupported versions") ++ if boring.SupportsHKDF() { ++ test("VersionTLS13", VersionTLS13, "") ++ } + } + + func isBoringVersion(v uint16) bool { +- return v == VersionTLS12 ++ return v == VersionTLS12 || (boring.SupportsHKDF() && v == VersionTLS13) + } + + func isBoringCipherSuite(id uint16) bool { +@@ -66,7 +74,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 +@@ -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_AES_256_GCM_SHA384, + } + ++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() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) { + continue + } +diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go +index 63d86b9f3a..a8ee915041 100644 +--- a/src/crypto/tls/handshake_client.go ++++ b/src/crypto/tls/handshake_client.go +@@ -127,7 +127,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_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/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go +index 4a8661085e..87fe11de5c 100644 +--- a/src/crypto/tls/handshake_client_tls13.go ++++ b/src/crypto/tls/handshake_client_tls13.go +@@ -41,10 +41,6 @@ type clientHandshakeStateTLS13 struct { + func (hs *clientHandshakeStateTLS13) handshake() error { + c := hs.c + +- if needFIPS() { +- return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode") +- } +- + // The server must not select TLS 1.3 in a renegotiation. See RFC 8446, + // sections 4.1.2 and 4.1.3. + if c.handshakes > 0 { +diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go +index b7b568cd84..af75e7dbe0 100644 +--- a/src/crypto/tls/handshake_server_tls13.go ++++ b/src/crypto/tls/handshake_server_tls13.go +@@ -44,10 +44,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/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/boring" + "errors" + "fmt" + "hash" +@@ -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-fips/openssl ++ < crypto/internal/backend + < crypto/boring; + + crypto/internal/alias +@@ -427,11 +429,13 @@ var depsRules = ` + crypto/sha512 + < 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-fips/openssl/bbig + < crypto/internal/boring/bbig ++ < crypto/internal/backend/bbig + < crypto/rand + < crypto/ed25519 + < encoding/asn1 +@@ -629,6 +633,7 @@ func listStdPkgs(goroot string) ([]string, error) { + } + + func TestDependencies(t *testing.T) { ++ t.Skip("openssl-fips 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-fips/openssl" { + haveImport["C"] = true // kludge: prevent C from appearing in crypto/internal/boring imports + } + fset := token.NewFileSet() +diff --git a/src/runtime/pprof/proto_test.go b/src/runtime/pprof/proto_test.go +index 780b481de8..63db9e9ed7 100644 +--- a/src/runtime/pprof/proto_test.go ++++ b/src/runtime/pprof/proto_test.go +@@ -15,6 +15,7 @@ import ( + "os/exec" + "reflect" + "runtime" ++ "strconv" + "strings" + "testing" + "unsafe" +@@ -95,11 +96,15 @@ func testPCs(t *testing.T) (addr1, addr2 uint64, map1, map2 *profile.Mapping) { + // region of memory. + t.Skipf("need 2 or more mappings, got %v", len(mprof.Mapping)) + } +- addr1 = mprof.Mapping[0].Start ++ addr1 = findAddrInExecutableSection(t, mmap, mprof.Mapping[0]) + map1 = mprof.Mapping[0] ++ map1.Offset = (addr1 - map1.Start) + map1.Offset ++ map1.Start = addr1 + map1.BuildID, _ = elfBuildID(map1.File) +- addr2 = mprof.Mapping[1].Start ++ addr2 = findAddrInExecutableSection(t, mmap, mprof.Mapping[1]) + map2 = mprof.Mapping[1] ++ map2.Offset = (addr2 - map2.Start) + map2.Offset ++ map2.Start = addr2 + map2.BuildID, _ = elfBuildID(map2.File) + case "windows": + addr1 = uint64(abi.FuncPCABIInternal(f1)) +@@ -145,6 +150,29 @@ func testPCs(t *testing.T) (addr1, addr2 uint64, map1, map2 *profile.Mapping) { + return + } + ++func findAddrInExecutableSection(t *testing.T, mmap []byte, m *profile.Mapping) uint64 { ++ mappings := strings.Split(string(mmap), "\n") ++ for _, mapping := range mappings { ++ parts := strings.Fields(mapping) ++ if len(parts) < 6 { ++ continue ++ } ++ if !strings.Contains(parts[1], "x") { ++ continue ++ } ++ addr, err := strconv.ParseUint(strings.Split(parts[0], "-")[0], 16, 64) ++ if err != nil { ++ t.Fatal(err) ++ } ++ if addr >= m.Start && addr < m.Limit { ++ return addr ++ } ++ } ++ ++ t.Error("could not find executable section in /proc/self/maps") ++ return 0 ++} ++ + func TestConvertCPUProfile(t *testing.T) { + addr1, addr2, map1, map2 := testPCs(t) + +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 \ No newline at end of file diff --git a/go-fips-1.21/0003-openssl-fips-unconditionally-use-openssl-backend.patch b/go-fips-1.21/0003-openssl-fips-unconditionally-use-openssl-backend.patch new file mode 100644 index 00000000000..7738f7d05e2 --- /dev/null +++ b/go-fips-1.21/0003-openssl-fips-unconditionally-use-openssl-backend.patch @@ -0,0 +1,54 @@ +From ed1dac0a0a4bd86b2ea50bbb1dbea3b2ff6a05f8 Mon Sep 17 00:00:00 2001 +From: Ariadne Conill +Date: Mon, 18 Sep 2023 13:13:49 -0700 +Subject: [PATCH 3/5] openssl-fips: unconditionally use openssl backend + +Signed-off-by: Ariadne Conill +--- + .../openssl-fips/openssl/openssl.go | 22 +++---------------- + 1 file changed, 3 insertions(+), 19 deletions(-) + +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go +index e93b042e5e..6da12da6b2 100644 +--- a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go +@@ -72,11 +72,8 @@ func init() { + // Initialize the OpenSSL library. + C._goboringcrypto_OPENSSL_setup() + +- // Check to see if the system is running in FIPS mode, if so +- // enable "boring" mode to call into OpenSSL for FIPS compliance. +- if fipsModeEnabled() { +- enableBoringFIPSMode() +- } ++ // Switch to OpenSSL crypto backend. ++ enableBoringFIPSMode() + } + + func openSSLVersion() uint64 { +@@ -96,21 +93,8 @@ func enableBoringFIPSMode() { + } + + func fipsModeEnabled() bool { +- // Due to the way providers work in openssl 3, the FIPS methods are not +- // necessarily going to be available for us to load based on the GOLANG_FIPS +- // environment variable alone. For now, we must rely on the config to tell +- // us if the provider is configured and active. + fipsConfigured := C._goboringcrypto_FIPS_mode() == fipsOn +- openSSLVersion := openSSLVersion() +- if openSSLVersion >= OPENSSL_VERSION_3_0_0 { +- if !fipsConfigured && os.Getenv("GOLANG_FIPS") == "1" { +- panic("GOLANG_FIPS=1 specified but OpenSSL FIPS provider is not configured") +- } +- return fipsConfigured +- +- } else { +- return os.Getenv("GOLANG_FIPS") == "1" || fipsConfigured +- } ++ return fipsConfigured + } + + var randstub bool +-- +2.39.2 (Apple Git-143) + diff --git a/go-fips-1.21/0004-boring-always-enable-access-to-boring.Enabled-functi.patch b/go-fips-1.21/0004-boring-always-enable-access-to-boring.Enabled-functi.patch new file mode 100644 index 00000000000..37b0bec4e51 --- /dev/null +++ b/go-fips-1.21/0004-boring-always-enable-access-to-boring.Enabled-functi.patch @@ -0,0 +1,33 @@ +From 50d7c545876bd29e1f434de5f9e766e947b58d3b Mon Sep 17 00:00:00 2001 +From: Ariadne Conill +Date: Mon, 18 Sep 2023 13:16:30 -0700 +Subject: [PATCH 4/5] boring: always enable access to boring.Enabled() function + +Signed-off-by: Ariadne Conill +--- + src/crypto/boring/boring.go | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go +index 47618fe3c6..e171df3871 100644 +--- a/src/crypto/boring/boring.go ++++ b/src/crypto/boring/boring.go +@@ -2,15 +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 +- + // Package boring exposes functions that are only available when building with + // Go+BoringCrypto. This package is available on all targets as long as the + // Go+BoringCrypto toolchain is used. Use the Enabled function to determine + // whether the BoringCrypto core is actually in use. +-// +-// Any time the Go+BoringCrypto toolchain is used, the "boringcrypto" build tag +-// is satisfied, so that applications can tag files that use this package. + package boring + + import boring "crypto/internal/backend" +-- +2.39.2 (Apple Git-143) + diff --git a/go-fips-1.21/001-initial-openssl-for-fips.patch b/go-fips-1.21/001-initial-openssl-for-fips.patch new file mode 100644 index 00000000000..4eabc2402cf --- /dev/null +++ b/go-fips-1.21/001-initial-openssl-for-fips.patch @@ -0,0 +1,7178 @@ +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 ++++ b/src/cmd/api/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. + +-//go:build boringcrypto ++//go:build !no_openssl + + package main + +@@ -12,6 +12,6 @@ import ( + ) + + func init() { +- fmt.Printf("SKIP with boringcrypto enabled\n") ++ 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 183c1697c8..abe85b5ad3 100644 +--- a/src/crypto/aes/cipher.go ++++ b/src/crypto/aes/cipher.go +@@ -7,7 +7,7 @@ package aes + import ( + "crypto/cipher" + "crypto/internal/alias" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "strconv" + ) + +@@ -38,7 +38,7 @@ func NewCipher(key []byte) (cipher.Block, error) { + case 16, 24, 32: + break + } +- if boring.Enabled { ++ 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 90031c5e2c..e80e82c82b 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" + ) +diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go +index 097c37e343..47618fe3c6 100644 +--- a/src/crypto/boring/boring.go ++++ b/src/crypto/boring/boring.go +@@ -13,9 +13,9 @@ + // is satisfied, so that applications can tag files that use this package. + package boring + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // Enabled reports whether BoringCrypto handles supported crypto operations. + func Enabled() bool { +- return boring.Enabled ++ return boring.Enabled() + } +diff --git a/src/crypto/boring/boring_test.go b/src/crypto/boring/boring_test.go +deleted file mode 100644 +index 33e5f1b37e..0000000000 +--- a/src/crypto/boring/boring_test.go ++++ /dev/null +@@ -1,22 +0,0 @@ +-// Copyright 2020 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 +- +-package boring_test +- +-import ( +- "crypto/boring" +- "runtime" +- "testing" +-) +- +-func TestEnabled(t *testing.T) { +- supportedPlatform := runtime.GOOS == "linux" && (runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64") +- if supportedPlatform && !boring.Enabled() { +- t.Error("Enabled returned false on a supported platform") +- } else if !supportedPlatform && boring.Enabled() { +- t.Error("Enabled returned true on an unsupported platform") +- } +-} +diff --git a/src/crypto/boring/notboring_test.go b/src/crypto/boring/notboring_test.go +deleted file mode 100644 +index ffe18e9109..0000000000 +--- a/src/crypto/boring/notboring_test.go ++++ /dev/null +@@ -1,14 +0,0 @@ +-// Copyright 2020 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.boringcrypto && !boringcrypto) || (!goexperiment.boringcrypto && boringcrypto) +-// +build goexperiment.boringcrypto,!boringcrypto !goexperiment.boringcrypto,boringcrypto +- +-package boring_test +- +-import "testing" +- +-func TestNotBoring(t *testing.T) { +- t.Error("goexperiment.boringcrypto and boringcrypto should be equivalent build tags") +-} +diff --git a/src/crypto/ecdh/ecdh.go b/src/crypto/ecdh/ecdh.go +index b86f521787..5b48335c69 100644 +--- a/src/crypto/ecdh/ecdh.go ++++ b/src/crypto/ecdh/ecdh.go +@@ -8,7 +8,7 @@ package ecdh + + import ( + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "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 af6bcd86f4..cc111c5564 100644 +--- a/src/crypto/ecdh/ecdh_test.go ++++ b/src/crypto/ecdh/ecdh_test.go +@@ -9,7 +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) { + t.Errorf("unexpectedly accepted %q", input) + } else if k != nil { + t.Error("PrivateKey was not nil on error") +- } else if strings.Contains(err.Error(), "boringcrypto") { +- t.Errorf("boringcrypto error leaked out: %v", err) ++ } else if strings.Contains(err.Error(), "!no_openssl") { ++ t.Errorf("!no_openssl error leaked out: %v", err) + } + } + }) +@@ -349,8 +349,8 @@ func TestNewPublicKey(t *testing.T) { + t.Errorf("unexpectedly accepted %q", input) + } else if k != nil { + t.Error("PublicKey was not nil on error") +- } else if strings.Contains(err.Error(), "boringcrypto") { +- t.Errorf("boringcrypto error leaked out: %v", err) ++ } else if strings.Contains(err.Error(), "!no_openssl") { ++ t.Errorf("!no_openssl error leaked out: %v", err) + } + } + }) +@@ -443,7 +443,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") + } + if testing.Short() { +diff --git a/src/crypto/ecdh/nist.go b/src/crypto/ecdh/nist.go +index 01354fa2cf..a7f1d9eced 100644 +--- a/src/crypto/ecdh/nist.go ++++ b/src/crypto/ecdh/nist.go +@@ -5,7 +5,7 @@ + package ecdh + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/nistec" + "crypto/internal/randutil" + "encoding/binary" +@@ -36,7 +36,7 @@ func (c *nistCurve[Point]) String() string { + var errInvalidPrivateKey = errors.New("crypto/ecdh: invalid private key") + + func (c *nistCurve[Point]) GenerateKey(rand io.Reader) (*PrivateKey, error) { +- if boring.Enabled && rand == boring.RandReader { ++ if boring.Enabled() && rand == boring.RandReader { + 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 + } +- if boring.Enabled { ++ if boring.Enabled() { + bk, err := boring.NewPrivateKeyECDH(c.name, key) + if err != nil { + return nil, err +@@ -173,7 +173,7 @@ func (c *nistCurve[Point]) NewPublicKey(key []byte) (*PublicKey, error) { + curve: c, + publicKey: append([]byte{}, key...), + } +- if boring.Enabled { ++ if boring.Enabled() { + bk, err := boring.NewPublicKeyECDH(c.name, k.publicKey) + if err != nil { + return nil, err +@@ -196,7 +196,7 @@ func (c *nistCurve[Point]) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, e + // only be the result of a scalar multiplication if one of the inputs is the + // zero scalar or the point at infinity. + +- if boring.Enabled { ++ if boring.Enabled() { + return boring.ECDH(local.boring, remote.boring) + } + +diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go +index 275c60b4de..58f0034b18 100644 +--- a/src/crypto/ecdsa/boring.go ++++ b/src/crypto/ecdsa/boring.go +@@ -2,13 +2,13 @@ + // 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 ecdsa + + import ( +- "crypto/internal/boring" +- "crypto/internal/boring/bbig" ++ boring "crypto/internal/backend" ++ "crypto/internal/backend/bbig" + "crypto/internal/boring/bcache" + "math/big" + ) +diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go +index e1503779ae..00953a453a 100644 +--- a/src/crypto/ecdsa/ecdsa.go ++++ b/src/crypto/ecdsa/ecdsa.go +@@ -27,8 +27,8 @@ import ( + "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" +@@ -158,7 +158,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) + +- if boring.Enabled && rand == boring.RandReader { ++ if boring.Enabled() && rand == boring.RandReader { + x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name) + if err != nil { + return nil, err +@@ -256,7 +256,7 @@ var errNoAsm = errors.New("no assembly implementation available") + func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { + randutil.MaybeReadByte(rand) + +- if boring.Enabled && rand == boring.RandReader { ++ if boring.Enabled() && rand == boring.RandReader { + b, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -466,7 +466,7 @@ func (zr) Read(dst []byte) (n int, err error) { + // VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the + // public key, pub. Its return value records whether the signature is valid. + func VerifyASN1(pub *PublicKey, hash, sig []byte) bool { +- if boring.Enabled { ++ if boring.Enabled() { + key, err := boringPublicKey(pub) + if err != nil { + return false +diff --git a/src/crypto/ecdsa/ecdsa_hashsignverify.go b/src/crypto/ecdsa/ecdsa_hashsignverify.go +index 37f3a18223..51e3b49cdc 100644 +--- a/src/crypto/ecdsa/ecdsa_hashsignverify.go ++++ b/src/crypto/ecdsa/ecdsa_hashsignverify.go +@@ -2,7 +2,7 @@ package ecdsa + + import ( + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/randutil" + "math/big" + "io" +@@ -11,7 +11,7 @@ import ( + func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) (*big.Int, *big.Int, error) { + randutil.MaybeReadByte(rand) + +- if boring.Enabled { ++ if boring.Enabled() { + b, err := boringPrivateKey(priv) + if err != nil { + return nil, nil, err +@@ -28,7 +28,7 @@ func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) (*big + } + + func HashVerify(pub *PublicKey, msg []byte, r, s *big.Int, h crypto.Hash) bool { +- if boring.Enabled { ++ if boring.Enabled() { + bpk, err := boringPublicKey(pub) + if err != nil { + return false +diff --git a/src/crypto/ecdsa/ecdsa_hashsignverify_test.go b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go +index d12ba2f441..6334a56496 100644 +--- a/src/crypto/ecdsa/ecdsa_hashsignverify_test.go ++++ b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go +@@ -2,7 +2,7 @@ package ecdsa + + import ( + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/elliptic" + "crypto/rand" + "testing" +@@ -34,7 +34,7 @@ func testHashSignAndHashVerify(t *testing.T, c elliptic.Curve, tag string) { + func TestHashSignAndHashVerify(t *testing.T) { + testHashSignAndHashVerify(t, elliptic.P256(), "p256") + +- if testing.Short() && !boring.Enabled { ++ if testing.Short() && !boring.Enabled() { + return + } + testHashSignAndHashVerify(t, elliptic.P384(), "p384") +diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go +index 61a4662036..80e484842b 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" ++ 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" ++ 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()) }) +diff --git a/src/crypto/ecdsa/notboring.go b/src/crypto/ecdsa/notboring.go +index 039bd82ed2..21a35b760c 100644 +--- a/src/crypto/ecdsa/notboring.go ++++ b/src/crypto/ecdsa/notboring.go +@@ -2,15 +2,15 @@ + // 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 ecdsa + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func boringPublicKey(*PublicKey) (*boring.PublicKeyECDSA, error) { +- panic("boringcrypto: not available") ++ panic("!no_openssl: not available") + } + func boringPrivateKey(*PrivateKey) (*boring.PrivateKeyECDSA, error) { +- 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 8b5c2cc9af..ebbb1c0c07 100644 +--- a/src/crypto/ed25519/ed25519_test.go ++++ b/src/crypto/ed25519/ed25519_test.go +@@ -9,7 +9,7 @@ import ( + "bytes" + "compress/gzip" + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/rand" + "crypto/sha512" + "encoding/hex" +@@ -322,7 +322,7 @@ func TestMalleability(t *testing.T) { + + func TestAllocations(t *testing.T) { + t.Skip("Allocations test broken with openssl linkage") +- if boring.Enabled { ++ if boring.Enabled() { + t.Skip("skipping allocations test with BoringCrypto") + } + testenv.SkipIfOptimizationOff(t) +diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go +index 35b9d5a17a..5697756a27 100644 +--- a/src/crypto/hmac/hmac.go ++++ b/src/crypto/hmac/hmac.go +@@ -22,7 +22,7 @@ timing side-channels: + package hmac + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/subtle" + "hash" + ) +@@ -127,7 +127,7 @@ func (h *hmac) Reset() { + // the returned Hash does not implement encoding.BinaryMarshaler + // or encoding.BinaryUnmarshaler. + func New(h func() hash.Hash, key []byte) hash.Hash { +- if boring.Enabled { ++ if boring.Enabled() { + hm := boring.NewHMAC(h, key) + if hm != nil { + return hm +diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go +index 55415abf02..0edd7a6003 100644 +--- a/src/crypto/hmac/hmac_test.go ++++ b/src/crypto/hmac/hmac_test.go +@@ -6,7 +6,7 @@ package hmac + + import ( + "bytes" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" +@@ -584,8 +584,8 @@ func TestHMAC(t *testing.T) { + } + + func TestNonUniqueHash(t *testing.T) { +- if boring.Enabled { +- t.Skip("hash.Hash provided by boringcrypto are not comparable") ++ if boring.Enabled() { ++ t.Skip("hash.Hash provided by !no_openssl are not comparable") + } + 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 6fae1d54f8..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 && !cmd_go_bootstrap && !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) { +- return 0; +- } +- return ok; +-}; +- +-int EVP_AEAD_CTX_open_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_open(ctx, out, &out_len, exp_out_len, +- nonce, nonce_len, in, in_len, ad, ad_len); +- if (out_len != exp_out_len) { +- return 0; +- } +- return ok; +-}; +- +-*/ +-import "C" +-import ( +- "bytes" +- "crypto/cipher" +- "errors" +- "runtime" +- "strconv" +- "unsafe" +-) +- +-type aesKeySizeError int +- +-func (k aesKeySizeError) Error() string { +- return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) +-} +- +-const aesBlockSize = 16 +- +-type aesCipher struct { +- key []byte +- enc C.GO_AES_KEY +- dec C.GO_AES_KEY +-} +- +-type extraModes interface { +- // Copied out of crypto/aes/modes.go. +- NewCBCEncrypter(iv []byte) cipher.BlockMode +- NewCBCDecrypter(iv []byte) cipher.BlockMode +- NewCTR(iv []byte) cipher.Stream +- NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) +-} +- +-var _ extraModes = (*aesCipher)(nil) +- +-func NewAESCipher(key []byte) (cipher.Block, error) { +- c := &aesCipher{key: bytes.Clone(key)} +- // Note: 0 is success, contradicting the usual BoringCrypto convention. +- if C._goboringcrypto_AES_set_decrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.dec) != 0 || +- C._goboringcrypto_AES_set_encrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.enc) != 0 { +- return nil, aesKeySizeError(len(key)) +- } +- return c, nil +-} +- +-func (c *aesCipher) BlockSize() int { return aesBlockSize } +- +-func (c *aesCipher) Encrypt(dst, src []byte) { +- if inexactOverlap(dst, src) { +- panic("crypto/cipher: invalid buffer overlap") +- } +- if len(src) < aesBlockSize { +- panic("crypto/aes: input not full block") +- } +- if len(dst) < aesBlockSize { +- panic("crypto/aes: output not full block") +- } +- C._goboringcrypto_AES_encrypt( +- (*C.uint8_t)(unsafe.Pointer(&src[0])), +- (*C.uint8_t)(unsafe.Pointer(&dst[0])), +- &c.enc) +-} +- +-func (c *aesCipher) Decrypt(dst, src []byte) { +- if inexactOverlap(dst, src) { +- panic("crypto/cipher: invalid buffer overlap") +- } +- if len(src) < aesBlockSize { +- panic("crypto/aes: input not full block") +- } +- if len(dst) < aesBlockSize { +- panic("crypto/aes: output not full block") +- } +- C._goboringcrypto_AES_decrypt( +- (*C.uint8_t)(unsafe.Pointer(&src[0])), +- (*C.uint8_t)(unsafe.Pointer(&dst[0])), +- &c.dec) +-} +- +-type aesCBC struct { +- key *C.GO_AES_KEY +- mode C.int +- iv [aesBlockSize]byte +-} +- +-func (x *aesCBC) BlockSize() int { return aesBlockSize } +- +-func (x *aesCBC) CryptBlocks(dst, src []byte) { +- if inexactOverlap(dst, src) { +- panic("crypto/cipher: invalid buffer overlap") +- } +- if len(src)%aesBlockSize != 0 { +- panic("crypto/cipher: input not full blocks") +- } +- if len(dst) < len(src) { +- panic("crypto/cipher: output smaller than input") +- } +- if len(src) > 0 { +- C._goboringcrypto_AES_cbc_encrypt( +- (*C.uint8_t)(unsafe.Pointer(&src[0])), +- (*C.uint8_t)(unsafe.Pointer(&dst[0])), +- C.size_t(len(src)), x.key, +- (*C.uint8_t)(unsafe.Pointer(&x.iv[0])), x.mode) +- } +-} +- +-func (x *aesCBC) SetIV(iv []byte) { +- if len(iv) != aesBlockSize { +- panic("cipher: incorrect length IV") +- } +- copy(x.iv[:], iv) +-} +- +-func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { +- x := &aesCBC{key: &c.enc, mode: C.GO_AES_ENCRYPT} +- copy(x.iv[:], iv) +- return x +-} +- +-func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { +- x := &aesCBC{key: &c.dec, mode: C.GO_AES_DECRYPT} +- copy(x.iv[:], iv) +- return x +-} +- +-type aesCTR struct { +- key *C.GO_AES_KEY +- iv [aesBlockSize]byte +- num C.uint +- ecount_buf [16]C.uint8_t +-} +- +-func (x *aesCTR) XORKeyStream(dst, src []byte) { +- if inexactOverlap(dst, src) { +- panic("crypto/cipher: invalid buffer overlap") +- } +- if len(dst) < len(src) { +- panic("crypto/cipher: output smaller than input") +- } +- if len(src) == 0 { +- return +- } +- C._goboringcrypto_AES_ctr128_encrypt( +- (*C.uint8_t)(unsafe.Pointer(&src[0])), +- (*C.uint8_t)(unsafe.Pointer(&dst[0])), +- C.size_t(len(src)), x.key, (*C.uint8_t)(unsafe.Pointer(&x.iv[0])), +- &x.ecount_buf[0], &x.num) +-} +- +-func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { +- x := &aesCTR{key: &c.enc} +- copy(x.iv[:], iv) +- return x +-} +- +-type aesGCM struct { +- ctx C.GO_EVP_AEAD_CTX +- aead *C.GO_EVP_AEAD +-} +- +-const ( +- gcmBlockSize = 16 +- gcmTagSize = 16 +- gcmStandardNonceSize = 12 +-) +- +-type aesNonceSizeError int +- +-func (n aesNonceSizeError) Error() string { +- return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n)) +-} +- +-type noGCM struct { +- cipher.Block +-} +- +-func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { +- if nonceSize != gcmStandardNonceSize && tagSize != gcmTagSize { +- return nil, errors.New("crypto/aes: GCM tag and nonce sizes can't be non-standard at the same time") +- } +- // Fall back to standard library for GCM with non-standard nonce or tag size. +- if nonceSize != gcmStandardNonceSize { +- return cipher.NewGCMWithNonceSize(&noGCM{c}, nonceSize) +- } +- if tagSize != gcmTagSize { +- return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize) +- } +- return c.newGCM(false) +-} +- +-func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { +- return c.(*aesCipher).newGCM(true) +-} +- +-func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) { +- var aead *C.GO_EVP_AEAD +- switch len(c.key) * 8 { +- case 128: +- if tls { +- aead = C._goboringcrypto_EVP_aead_aes_128_gcm_tls12() +- } else { +- aead = C._goboringcrypto_EVP_aead_aes_128_gcm() +- } +- case 256: +- if tls { +- aead = C._goboringcrypto_EVP_aead_aes_256_gcm_tls12() +- } else { +- aead = C._goboringcrypto_EVP_aead_aes_256_gcm() +- } +- default: +- // Fall back to standard library for GCM with non-standard key size. +- return cipher.NewGCMWithNonceSize(&noGCM{c}, gcmStandardNonceSize) +- } +- +- g := &aesGCM{aead: aead} +- if C._goboringcrypto_EVP_AEAD_CTX_init(&g.ctx, aead, (*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.size_t(len(c.key)), C.GO_EVP_AEAD_DEFAULT_TAG_LENGTH, nil) == 0 { +- return nil, fail("EVP_AEAD_CTX_init") +- } +- // Note: Because of the finalizer, any time g.ctx is passed to cgo, +- // that call must be followed by a call to runtime.KeepAlive(g), +- // to make sure g is not collected (and finalized) before the cgo +- // call returns. +- runtime.SetFinalizer(g, (*aesGCM).finalize) +- if g.NonceSize() != gcmStandardNonceSize { +- panic("boringcrypto: internal confusion about nonce size") +- } +- if g.Overhead() != gcmTagSize { +- panic("boringcrypto: internal confusion about tag size") +- } +- +- return g, nil +-} +- +-func (g *aesGCM) finalize() { +- C._goboringcrypto_EVP_AEAD_CTX_cleanup(&g.ctx) +-} +- +-func (g *aesGCM) NonceSize() int { +- return int(C._goboringcrypto_EVP_AEAD_nonce_length(g.aead)) +-} +- +-func (g *aesGCM) Overhead() int { +- return int(C._goboringcrypto_EVP_AEAD_max_overhead(g.aead)) +-} +- +-// base returns the address of the underlying array in b, +-// being careful not to panic when b has zero length. +-func base(b []byte) *C.uint8_t { +- if len(b) == 0 { +- return nil +- } +- return (*C.uint8_t)(unsafe.Pointer(&b[0])) +-} +- +-func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { +- if len(nonce) != gcmStandardNonceSize { +- panic("cipher: incorrect nonce length given to GCM") +- } +- if uint64(len(plaintext)) > ((1<<32)-2)*aesBlockSize || len(plaintext)+gcmTagSize < len(plaintext) { +- panic("cipher: message too large for GCM") +- } +- if len(dst)+len(plaintext)+gcmTagSize < len(dst) { +- panic("cipher: message too large for buffer") +- } +- +- // Make room in dst to append plaintext+overhead. +- n := len(dst) +- for cap(dst) < n+len(plaintext)+gcmTagSize { +- dst = append(dst[:cap(dst)], 0) +- } +- dst = dst[:n+len(plaintext)+gcmTagSize] +- +- // Check delayed until now to make sure len(dst) is accurate. +- if inexactOverlap(dst[n:], plaintext) { +- panic("cipher: invalid buffer overlap") +- } +- +- outLen := C.size_t(len(plaintext) + gcmTagSize) +- ok := C.EVP_AEAD_CTX_seal_wrapper( +- &g.ctx, +- (*C.uint8_t)(unsafe.Pointer(&dst[n])), outLen, +- base(nonce), C.size_t(len(nonce)), +- base(plaintext), C.size_t(len(plaintext)), +- base(additionalData), C.size_t(len(additionalData))) +- runtime.KeepAlive(g) +- if ok == 0 { +- panic(fail("EVP_AEAD_CTX_seal")) +- } +- return dst[:n+int(outLen)] +-} +- +-var errOpen = errors.New("cipher: message authentication failed") +- +-func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { +- if len(nonce) != gcmStandardNonceSize { +- panic("cipher: incorrect nonce length given to GCM") +- } +- if len(ciphertext) < gcmTagSize { +- return nil, errOpen +- } +- if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize { +- return nil, errOpen +- } +- +- // Make room in dst to append ciphertext without tag. +- n := len(dst) +- for cap(dst) < n+len(ciphertext)-gcmTagSize { +- dst = append(dst[:cap(dst)], 0) +- } +- dst = dst[:n+len(ciphertext)-gcmTagSize] +- +- // Check delayed until now to make sure len(dst) is accurate. +- if inexactOverlap(dst[n:], ciphertext) { +- panic("cipher: invalid buffer overlap") +- } +- +- outLen := C.size_t(len(ciphertext) - gcmTagSize) +- ok := C.EVP_AEAD_CTX_open_wrapper( +- &g.ctx, +- base(dst[n:]), outLen, +- base(nonce), C.size_t(len(nonce)), +- base(ciphertext), C.size_t(len(ciphertext)), +- base(additionalData), C.size_t(len(additionalData))) +- runtime.KeepAlive(g) +- if ok == 0 { +- return nil, errOpen +- } +- return dst[:n+int(outLen)], nil +-} +- +-func anyOverlap(x, y []byte) bool { +- return len(x) > 0 && len(y) > 0 && +- uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && +- uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) +-} +- +-func inexactOverlap(x, y []byte) bool { +- if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { +- return false +- } +- return anyOverlap(x, y) +-} +diff --git a/src/crypto/internal/boring/bbig/big.go b/src/crypto/internal/boring/bbig/big.go +deleted file mode 100644 +index 5ce46972b3..0000000000 +--- a/src/crypto/internal/boring/bbig/big.go ++++ /dev/null +@@ -1,33 +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. +- +-package bbig +- +-import ( +- "crypto/internal/boring" +- "math/big" +- "unsafe" +-) +- +-func Enc(b *big.Int) boring.BigInt { +- if b == nil { +- return nil +- } +- x := b.Bits() +- if len(x) == 0 { +- return boring.BigInt{} +- } +- return unsafe.Slice((*uint)(&x[0]), len(x)) +-} +- +-func Dec(b boring.BigInt) *big.Int { +- if b == nil { +- return nil +- } +- if len(b) == 0 { +- return new(big.Int) +- } +- x := unsafe.Slice((*big.Word)(&b[0]), len(b)) +- return new(big.Int).SetBits(x) +-} +diff --git a/src/crypto/internal/boring/boring.go b/src/crypto/internal/boring/boring.go +deleted file mode 100644 +index 102380a839..0000000000 +--- a/src/crypto/internal/boring/boring.go ++++ /dev/null +@@ -1,126 +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 && !cmd_go_bootstrap && !msan +- +-package boring +- +-/* +-// goboringcrypto_linux_amd64.syso references pthread functions. +-#cgo LDFLAGS: "-pthread" +- +-#include "goboringcrypto.h" +-*/ +-import "C" +-import ( +- "crypto/internal/boring/sig" +- _ "crypto/internal/boring/syso" +- "math/bits" +- "unsafe" +-) +- +-const available = true +- +-func init() { +- C._goboringcrypto_BORINGSSL_bcm_power_on_self_test() +- if C._goboringcrypto_FIPS_mode() != 1 { +- panic("boringcrypto: not in FIPS mode") +- } +- sig.BoringCrypto() +-} +- +-// Unreachable marks code that should be unreachable +-// when BoringCrypto is in use. It panics. +-func Unreachable() { +- panic("boringcrypto: invalid code execution") +-} +- +-// provided by runtime 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 BoringCrypto is in use. It panics. +-func UnreachableExceptTests() { +- name := runtime_arg0() +- // If BoringCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well. +- if !hasSuffix(name, "_test") && !hasSuffix(name, ".test") { +- println("boringcrypto: unexpected code execution in", name) +- panic("boringcrypto: invalid code execution") +- } +-} +- +-type fail string +- +-func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" } +- +-func wbase(b BigInt) *C.uint8_t { +- if len(b) == 0 { +- return nil +- } +- return (*C.uint8_t)(unsafe.Pointer(&b[0])) +-} +- +-const wordBytes = bits.UintSize / 8 +- +-func bigToBN(x BigInt) *C.GO_BIGNUM { +- return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil) +-} +- +-func bytesToBN(x []byte) *C.GO_BIGNUM { +- return C._goboringcrypto_BN_bin2bn((*C.uint8_t)(&x[0]), C.size_t(len(x)), nil) +-} +- +-func bnToBig(bn *C.GO_BIGNUM) BigInt { +- x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes) +- if C._goboringcrypto_BN_bn2le_padded(wbase(x), C.size_t(len(x)*wordBytes), bn) == 0 { +- panic("boringcrypto: bignum conversion failed") +- } +- return x +-} +- +-func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool { +- if *bnp != nil { +- C._goboringcrypto_BN_free(*bnp) +- *bnp = nil +- } +- if b == nil { +- return true +- } +- bn := bigToBN(b) +- if bn == nil { +- return false +- } +- *bnp = bn +- return true +-} +- +-// noescape hides a pointer from escape analysis. noescape is +-// the identity function but escape analysis doesn't think the +-// output depends on the input. noescape is inlined and currently +-// compiles down to zero instructions. +-// USE CAREFULLY! +-// +-//go:nosplit +-func noescape(p unsafe.Pointer) unsafe.Pointer { +- x := uintptr(p) +- return unsafe.Pointer(x ^ 0) +-} +- +-var zero byte +- +-// addr converts p to its base addr, including a noescape along the way. +-// If p is nil, addr returns a non-nil pointer, so that the result can always +-// be dereferenced. +-// +-//go:nosplit +-func addr(p []byte) *byte { +- if len(p) == 0 { +- return &zero +- } +- return (*byte)(noescape(unsafe.Pointer(&p[0]))) +-} +diff --git a/src/crypto/internal/boring/boring_test.go b/src/crypto/internal/boring/boring_test.go +deleted file mode 100644 +index 83bbbd3404..0000000000 +--- a/src/crypto/internal/boring/boring_test.go ++++ /dev/null +@@ -1,34 +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. +- +-// Most functionality in this package is tested by replacing existing code +-// and inheriting that code's tests. +- +-package boring +- +-import "testing" +- +-// Test that func init does not panic. +-func TestInit(t *testing.T) {} +- +-// Test that Unreachable panics. +-func TestUnreachable(t *testing.T) { +- defer func() { +- if Enabled { +- if err := recover(); err == nil { +- t.Fatal("expected Unreachable to panic") +- } +- } else { +- if err := recover(); err != nil { +- t.Fatalf("expected Unreachable to be a no-op") +- } +- } +- }() +- Unreachable() +-} +- +-// Test that UnreachableExceptTests does not panic (this is a test). +-func TestUnreachableExceptTests(t *testing.T) { +- UnreachableExceptTests() +-} +diff --git a/src/crypto/internal/boring/doc.go b/src/crypto/internal/boring/doc.go +deleted file mode 100644 +index 6060fe5951..0000000000 +--- a/src/crypto/internal/boring/doc.go ++++ /dev/null +@@ -1,19 +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. +- +-// 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 +- +-// Enabled reports whether BoringCrypto is available. +-// When enabled is false, all functions in this package panic. +-// +-// BoringCrypto is only available on linux/amd64 systems. +-const Enabled = available +- +-// 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 []uint +diff --git a/src/crypto/internal/boring/ecdh.go b/src/crypto/internal/boring/ecdh.go +deleted file mode 100644 +index 8f46d8146f..0000000000 +--- a/src/crypto/internal/boring/ecdh.go ++++ /dev/null +@@ -1,224 +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. +- +-//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan +- +-package boring +- +-// #include "goboringcrypto.h" +-import "C" +-import ( +- "errors" +- "runtime" +- "unsafe" +-) +- +-type PublicKeyECDH struct { +- curve string +- key *C.GO_EC_POINT +- group *C.GO_EC_GROUP +- bytes []byte +-} +- +-func (k *PublicKeyECDH) finalize() { +- C._goboringcrypto_EC_POINT_free(k.key) +-} +- +-type PrivateKeyECDH struct { +- curve string +- key *C.GO_EC_KEY +-} +- +-func (k *PrivateKeyECDH) finalize() { +- C._goboringcrypto_EC_KEY_free(k.key) +-} +- +-func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { +- if len(bytes) < 1 { +- return nil, errors.New("NewPublicKeyECDH: missing key") +- } +- +- nid, err := curveNID(curve) +- if err != nil { +- return nil, err +- } +- +- group := C._goboringcrypto_EC_GROUP_new_by_curve_name(nid) +- if group == nil { +- return nil, fail("EC_GROUP_new_by_curve_name") +- } +- defer C._goboringcrypto_EC_GROUP_free(group) +- key := C._goboringcrypto_EC_POINT_new(group) +- if key == nil { +- return nil, fail("EC_POINT_new") +- } +- ok := C._goboringcrypto_EC_POINT_oct2point(group, key, (*C.uint8_t)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes)), nil) != 0 +- if !ok { +- C._goboringcrypto_EC_POINT_free(key) +- return nil, errors.New("point not on curve") +- } +- +- k := &PublicKeyECDH{curve, key, group, append([]byte(nil), bytes...)} +- // Note: Because of the finalizer, any time k.key is passed to cgo, +- // that call must be followed by a call to runtime.KeepAlive(k), +- // to make sure k is not collected (and finalized) before the cgo +- // call returns. +- runtime.SetFinalizer(k, (*PublicKeyECDH).finalize) +- return k, nil +-} +- +-func (k *PublicKeyECDH) Bytes() []byte { return k.bytes } +- +-func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { +- nid, err := curveNID(curve) +- if err != nil { +- return nil, err +- } +- key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) +- if key == nil { +- return nil, fail("EC_KEY_new_by_curve_name") +- } +- b := bytesToBN(bytes) +- ok := b != nil && C._goboringcrypto_EC_KEY_set_private_key(key, b) != 0 +- if b != nil { +- C._goboringcrypto_BN_free(b) +- } +- if !ok { +- C._goboringcrypto_EC_KEY_free(key) +- return nil, fail("EC_KEY_set_private_key") +- } +- k := &PrivateKeyECDH{curve, key} +- // Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive. +- runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) +- return k, nil +-} +- +-func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { +- defer runtime.KeepAlive(k) +- +- group := C._goboringcrypto_EC_KEY_get0_group(k.key) +- if group == nil { +- return nil, fail("EC_KEY_get0_group") +- } +- kbig := C._goboringcrypto_EC_KEY_get0_private_key(k.key) +- if kbig == nil { +- return nil, fail("EC_KEY_get0_private_key") +- } +- pt := C._goboringcrypto_EC_POINT_new(group) +- if pt == nil { +- return nil, fail("EC_POINT_new") +- } +- if C._goboringcrypto_EC_POINT_mul(group, pt, kbig, nil, nil, nil) == 0 { +- C._goboringcrypto_EC_POINT_free(pt) +- return nil, fail("EC_POINT_mul") +- } +- bytes, err := pointBytesECDH(k.curve, group, pt) +- if err != nil { +- C._goboringcrypto_EC_POINT_free(pt) +- return nil, err +- } +- pub := &PublicKeyECDH{k.curve, pt, group, bytes} +- // Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive. +- runtime.SetFinalizer(pub, (*PublicKeyECDH).finalize) +- return pub, nil +-} +- +-func pointBytesECDH(curve string, group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]byte, error) { +- out := make([]byte, 1+2*curveSize(curve)) +- n := C._goboringcrypto_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, (*C.uint8_t)(unsafe.Pointer(&out[0])), C.size_t(len(out)), nil) +- if int(n) != len(out) { +- return nil, fail("EC_POINT_point2oct") +- } +- return out, nil +-} +- +-func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { +- group := C._goboringcrypto_EC_KEY_get0_group(priv.key) +- if group == nil { +- return nil, fail("EC_KEY_get0_group") +- } +- privBig := C._goboringcrypto_EC_KEY_get0_private_key(priv.key) +- if privBig == nil { +- return nil, fail("EC_KEY_get0_private_key") +- } +- pt := C._goboringcrypto_EC_POINT_new(group) +- if pt == nil { +- return nil, fail("EC_POINT_new") +- } +- defer C._goboringcrypto_EC_POINT_free(pt) +- if C._goboringcrypto_EC_POINT_mul(group, pt, nil, pub.key, privBig, nil) == 0 { +- return nil, fail("EC_POINT_mul") +- } +- out, err := xCoordBytesECDH(priv.curve, group, pt) +- if err != nil { +- return nil, err +- } +- return out, nil +-} +- +-func xCoordBytesECDH(curve string, group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]byte, error) { +- big := C._goboringcrypto_BN_new() +- defer C._goboringcrypto_BN_free(big) +- if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, big, nil, nil) == 0 { +- return nil, fail("EC_POINT_get_affine_coordinates_GFp") +- } +- return bigBytesECDH(curve, big) +-} +- +-func bigBytesECDH(curve string, big *C.GO_BIGNUM) ([]byte, error) { +- out := make([]byte, curveSize(curve)) +- if C._goboringcrypto_BN_bn2bin_padded((*C.uint8_t)(&out[0]), C.size_t(len(out)), big) == 0 { +- return nil, fail("BN_bn2bin_padded") +- } +- return out, nil +-} +- +-func curveSize(curve string) int { +- switch curve { +- default: +- panic("crypto/internal/boring: unknown curve " + curve) +- case "P-256": +- return 256 / 8 +- case "P-384": +- return 384 / 8 +- case "P-521": +- return (521 + 7) / 8 +- } +-} +- +-func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { +- nid, err := curveNID(curve) +- if err != nil { +- return nil, nil, err +- } +- key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) +- if key == nil { +- return nil, nil, fail("EC_KEY_new_by_curve_name") +- } +- if C._goboringcrypto_EC_KEY_generate_key_fips(key) == 0 { +- C._goboringcrypto_EC_KEY_free(key) +- return nil, nil, fail("EC_KEY_generate_key_fips") +- } +- +- group := C._goboringcrypto_EC_KEY_get0_group(key) +- if group == nil { +- C._goboringcrypto_EC_KEY_free(key) +- return nil, nil, fail("EC_KEY_get0_group") +- } +- b := C._goboringcrypto_EC_KEY_get0_private_key(key) +- if b == nil { +- C._goboringcrypto_EC_KEY_free(key) +- return nil, nil, fail("EC_KEY_get0_private_key") +- } +- bytes, err := bigBytesECDH(curve, b) +- if err != nil { +- C._goboringcrypto_EC_KEY_free(key) +- return nil, nil, err +- } +- +- k := &PrivateKeyECDH{curve, key} +- // Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive. +- runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) +- return k, bytes, 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 3bf1471fb0..d6c5ca736d 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/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 @@ + package rand + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "errors" + "io" + "os" +@@ -23,7 +23,7 @@ import ( + const urandomDevice = "/dev/urandom" + + func init() { +- if boring.Enabled { ++ if boring.Enabled() { + Reader = boring.RandReader + return + } +diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go +index b9f9d3154f..85c2a45848 100644 +--- a/src/crypto/rsa/boring.go ++++ b/src/crypto/rsa/boring.go +@@ -2,13 +2,13 @@ + // 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 rsa + + import ( +- "crypto/internal/boring" +- "crypto/internal/boring/bbig" ++ boring "crypto/internal/backend" ++ "crypto/internal/backend/bbig" + "crypto/internal/boring/bcache" + "math/big" + ) +diff --git a/src/crypto/rsa/boring_test.go b/src/crypto/rsa/boring_test.go +index 2234d079f0..4e7fd9de4a 100644 +--- a/src/crypto/rsa/boring_test.go ++++ b/src/crypto/rsa/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. + +-//go:build boringcrypto ++//go:build !no_openssl + + // 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/notboring.go b/src/crypto/rsa/notboring.go +index 2abc043640..a83be6dfdb 100644 +--- a/src/crypto/rsa/notboring.go ++++ b/src/crypto/rsa/notboring.go +@@ -2,15 +2,15 @@ + // 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 rsa + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func boringPublicKey(*PublicKey) (*boring.PublicKeyRSA, error) { +- panic("boringcrypto: not available") ++ panic("!no_openssl: not available") + } + func boringPrivateKey(*PrivateKey) (*boring.PrivateKeyRSA, error) { +- panic("boringcrypto: not available") ++ panic("!no_openssl: not available") + } +diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go +index 55fea1ab93..d6eaf7cea8 100644 +--- a/src/crypto/rsa/pkcs1v15.go ++++ b/src/crypto/rsa/pkcs1v15.go +@@ -6,7 +6,7 @@ package rsa + + import ( + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/internal/randutil" + "crypto/subtle" + "errors" +@@ -49,7 +49,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro + 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 +@@ -69,7 +69,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro + em[len(em)-len(msg)-1] = 0 + copy(mm, msg) + +- if boring.Enabled { ++ if boring.Enabled() { + var bkey *boring.PublicKeyRSA + bkey, err = boringPublicKey(pub) + if err != nil { +@@ -94,7 +94,7 @@ func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]b + return nil, err + } + +- if boring.Enabled { ++ if boring.Enabled() { + bkey, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -188,7 +188,7 @@ func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, + return + } + +- if boring.Enabled { ++ if boring.Enabled() { + var bkey *boring.PrivateKeyRSA + bkey, err = boringPrivateKey(priv) + if err != nil { +@@ -296,12 +296,12 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ + return nil, ErrMessageTooLong + } + +- if boring.Enabled { ++ if boring.Enabled() { + bkey, err := boringPrivateKey(priv) + if err != nil { + return nil, err + } +- return boring.SignRSAPKCS1v15(bkey, hash, hashed) ++ return boring.SignRSAPKCS1v15(bkey, hash, hashed, true) + } + + // EM = 0x00 || 0x01 || PS || 0x00 || T +@@ -322,12 +322,12 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ + // returning a nil error. If hash is zero then hashed is used directly. This + // isn't advisable except for interoperability. + 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 + } +- if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil { ++ if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig, hash != crypto.Hash(0)); err != nil { + return ErrVerification + } + return nil +diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go +index 39a4fc184a..0853178e3a 100644 +--- a/src/crypto/rsa/pkcs1v15_test.go ++++ b/src/crypto/rsa/pkcs1v15_test.go +@@ -7,7 +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") + } + +@@ -149,7 +149,7 @@ 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) { + } + + 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") + } + +@@ -277,7 +277,7 @@ func TestUnpaddedSignature(t *testing.T) { + } + + 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") + } + +diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go +index 3a377cc9db..ce78a13d6f 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 + } + +- if boring.Enabled { ++ 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. + +- if boring.Enabled && rand == boring.RandReader { ++ if boring.Enabled() && rand == boring.RandReader { + bkey, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -339,7 +339,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, + // argument may be nil, in which case sensible defaults are used. opts.Hash is + // ignored. + func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error { +- if boring.Enabled { ++ if boring.Enabled() { + bkey, err := boringPublicKey(pub) + if err != nil { + return err +diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go +index 1226149321..befd1612b5 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) { + // 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") + } + +@@ -209,7 +209,7 @@ func TestPSSNilOpts(t *testing.T) { + } + + 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") + } + +diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go +index ad860d7f0c..86f700bee2 100644 +--- a/src/crypto/rsa/rsa.go ++++ b/src/crypto/rsa/rsa.go +@@ -28,8 +28,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" +@@ -294,7 +294,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { + func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { + randutil.MaybeReadByte(random) + +- if boring.Enabled && random == boring.RandReader && nprimes == 2 && ++ if boring.Enabled() && random == boring.RandReader && nprimes == 2 && + (bits == 2048 || bits == 3072 || bits == 4096) { + bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits) + if err != nil { +@@ -529,7 +529,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 +@@ -558,7 +558,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 { +@@ -719,7 +719,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 b994daec19..4b7427e1ae 100644 +--- a/src/crypto/rsa/rsa_test.go ++++ b/src/crypto/rsa/rsa_test.go +@@ -8,7 +8,7 @@ import ( + "bufio" + "bytes" + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "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") + } + +- if boring.Enabled { ++ 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) { + } + + func TestAllocations(t *testing.T) { +- if boring.Enabled { ++ if boring.Enabled() { + t.Skip("skipping allocations test with BoringCrypto") + } + 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) +@@ -667,7 +667,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 + } +@@ -694,7 +694,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 + } +@@ -741,7 +741,7 @@ func Test2DecryptOAEP(t *testing.T) { + sha1 := crypto.SHA1 + sha256 := crypto.SHA256 + +- 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()) + } + +@@ -760,7 +760,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 + } +diff --git a/src/crypto/sha1/boring.go b/src/crypto/sha1/boring.go +index b5786d1bf4..9bd03f3940 100644 +--- a/src/crypto/sha1/boring.go ++++ b/src/crypto/sha1/boring.go +@@ -12,11 +12,11 @@ + package sha1 + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "hash" + ) + +-const boringEnabled = boring.Enabled ++var boringEnabled = boring.Enabled() + + func boringNewSHA1() hash.Hash { return boring.NewSHA1() } + +diff --git a/src/crypto/sha1/notboring.go b/src/crypto/sha1/notboring.go +index 42ef87937f..c1a3205539 100644 +--- a/src/crypto/sha1/notboring.go ++++ b/src/crypto/sha1/notboring.go +@@ -11,10 +11,10 @@ import ( + "hash" + ) + +-const boringEnabled = false ++var boringEnabled = false + +-func boringNewSHA1() hash.Hash { panic("boringcrypto: not available") } ++func boringNewSHA1() hash.Hash { panic("!no_openssl: not available") } + + func boringUnreachable() {} + +-func boringSHA1([]byte) [20]byte { panic("boringcrypto: not available") } ++func boringSHA1([]byte) [20]byte { panic("!no_openssl: not available") } +diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go +index 85ed126091..71f4b46663 100644 +--- a/src/crypto/sha1/sha1_test.go ++++ b/src/crypto/sha1/sha1_test.go +@@ -8,7 +8,7 @@ package sha1 + + import ( + "bytes" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/rand" + "encoding" + "fmt" +@@ -78,7 +78,7 @@ func TestGolden(t *testing.T) { + io.WriteString(c, g.in[len(g.in)/2:]) + sum = c.Sum(nil) + case 3: +- if boring.Enabled { ++ if boring.Enabled() { + continue + } + io.WriteString(c, g.in[0:len(g.in)/2]) +@@ -145,7 +145,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") + } + for i := 1; i < 30; i++ { // arbitrary factor +@@ -218,7 +218,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 2deafbc9fc..282c326b32 100644 +--- a/src/crypto/sha256/sha256.go ++++ b/src/crypto/sha256/sha256.go +@@ -8,7 +8,7 @@ package sha256 + + import ( + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "encoding/binary" + "errors" + "hash" +@@ -148,7 +148,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.NewSHA256() + } + d := new(digest) +@@ -158,7 +158,7 @@ func New() hash.Hash { + + // New224 returns a new hash.Hash computing the SHA224 checksum. + func New224() hash.Hash { +- if boring.Enabled { ++ if boring.Enabled() { + return boring.NewSHA224() + } + d := new(digest) +@@ -251,7 +251,7 @@ func (d *digest) checkSum() [Size]byte { + + // Sum256 returns the SHA256 checksum of the data. + func Sum256(data []byte) [Size]byte { +- if boring.Enabled { ++ if boring.Enabled() { + return boring.SHA256(data) + } + var d digest +@@ -262,7 +262,7 @@ func Sum256(data []byte) [Size]byte { + + // Sum224 returns the SHA224 checksum of the data. + func Sum224(data []byte) [Size224]byte { +- if boring.Enabled { ++ 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 7304678346..a073d31119 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/rand" + "encoding" + "fmt" +@@ -217,7 +217,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) +@@ -294,7 +294,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/sha512/sha512.go b/src/crypto/sha512/sha512.go +index 9ae1b3aae2..e56eedb201 100644 +--- a/src/crypto/sha512/sha512.go ++++ b/src/crypto/sha512/sha512.go +@@ -12,7 +12,7 @@ package sha512 + + import ( + "crypto" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "encoding/binary" + "errors" + "hash" +@@ -206,7 +206,7 @@ func consumeUint64(b []byte) ([]byte, uint64) { + + // New returns a new hash.Hash computing the SHA-512 checksum. + func New() hash.Hash { +- if boring.Enabled { ++ if boring.Enabled() { + return boring.NewSHA512() + } + d := &digest{function: crypto.SHA512} +@@ -230,7 +230,7 @@ func New512_256() hash.Hash { + + // New384 returns a new hash.Hash computing the SHA-384 checksum. + func New384() hash.Hash { +- if boring.Enabled { ++ if boring.Enabled() { + return boring.NewSHA384() + } + d := &digest{function: crypto.SHA384} +@@ -341,7 +341,7 @@ func (d *digest) checkSum() [Size]byte { + + // Sum512 returns the SHA512 checksum of the data. + func Sum512(data []byte) [Size]byte { +- if boring.Enabled { ++ if boring.Enabled() { + return boring.SHA512(data) + } + d := digest{function: crypto.SHA512} +@@ -352,7 +352,7 @@ func Sum512(data []byte) [Size]byte { + + // Sum384 returns the SHA384 checksum of the data. + func Sum384(data []byte) [Size384]byte { +- if boring.Enabled { ++ 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 921cdbb7bb..a35165bcbf 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/rand" + "encoding" + "encoding/hex" +@@ -823,7 +823,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) +@@ -893,7 +893,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 140b1a3dd8..fe6fa96d28 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,7 +12,7 @@ import ( + ) + + func init() { +- if boring.Enabled && !boring.ExecutingTest() { ++ if boring.Enabled() && !boring.ExecutingTest() { + fipstls.Force() + } + } +diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go +index 7bfe3f9417..49702f59ba 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" +@@ -46,7 +46,7 @@ func TestBoringServerProtocolVersion(t *testing.T) { + test("VersionTLS10", VersionTLS10, "") + test("VersionTLS11", VersionTLS11, "") + test("VersionTLS12", VersionTLS12, "") +- if boring.Enabled && !boring.SupportsHKDF() { ++ if boring.Enabled() && !boring.SupportsHKDF() { + test("VersionTLS13", VersionTLS13, "client offered only unsupported versions") + } else { + test("VersionTLS13", VersionTLS13, "") +@@ -238,7 +238,7 @@ func TestBoringServerSignatureAndHash(t *testing.T) { + + clientConfig := testConfig.Clone() + +- if boring.Enabled { ++ if boring.Enabled() { + serverConfig.Rand = boring.RandReader + clientConfig.Rand = boring.RandReader + } +@@ -369,7 +369,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 + } +@@ -400,13 +400,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 + } +@@ -432,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}, !(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) +@@ -454,7 +454,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 +@@ -462,7 +462,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 { +@@ -486,7 +486,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 { +diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go +index 669208bb86..15a44e8cf6 100644 +--- a/src/crypto/tls/cipher_suites.go ++++ b/src/crypto/tls/cipher_suites.go +@@ -10,7 +10,7 @@ import ( + "crypto/cipher" + "crypto/des" + "crypto/hmac" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/rc4" + "crypto/sha1" + "crypto/sha256" +@@ -422,7 +422,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. +- if !boring.Enabled { ++ if !boring.Enabled() { + h = newConstantTimeHash(h) + } + return hmac.New(h, key) +@@ -514,7 +514,7 @@ func aeadAESGCM(key, noncePrefix []byte) aead { + panic(err) + } + var aead cipher.AEAD +- if boring.Enabled { ++ if boring.Enabled() { + aead, err = boring.NewGCMTLS(aes) + } else { + boring.Unreachable() +diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go +index 5edbd19995..a72d4855c1 100644 +--- a/src/crypto/tls/common.go ++++ b/src/crypto/tls/common.go +@@ -12,7 +12,7 @@ import ( + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/rand" + "crypto/rsa" + "crypto/sha512" +@@ -1032,7 +1032,7 @@ 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 { ++ if boring.Enabled() && !boring.SupportsHKDF() && v > VersionTLS12 { + continue + } + if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) { +diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go +index e7a360fdd4..9ea9eed2fb 100644 +--- a/src/crypto/tls/key_schedule.go ++++ b/src/crypto/tls/key_schedule.go +@@ -7,7 +7,7 @@ package tls + import ( + "crypto/ecdh" + "crypto/hmac" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "errors" + "fmt" + "hash" +@@ -60,7 +60,7 @@ func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []by + panic(fmt.Errorf("failed to construct HKDF label: %s", err)) + } + out := make([]byte, length) +- if boring.Enabled { ++ if boring.Enabled() { + reader, err := boring.ExpandHKDF(c.hash.New, secret, hkdfLabelBytes) + if err != nil { + panic("tls: HKDF-Expand-Label invocation failed unexpectedly") +@@ -91,7 +91,7 @@ func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte { + if newSecret == nil { + newSecret = make([]byte, c.hash.Size()) + } +- 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 7d85b39c59..fe2719485b 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 + + package tls + +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. + +-//go:build boringcrypto ++//go:build !no_openssl + + package x509 + +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. + +-//go:build boringcrypto ++//go:build !no_openssl + + package x509 + +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. + +-//go:build !boringcrypto ++//go:build no_openssl + + package x509 + +diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go +index 0c2cbf3182..e01c24292e 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" +@@ -653,7 +653,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()) +@@ -3716,7 +3716,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() +diff --git a/src/go.mod b/src/go.mod +index 25829e17f2..e19ef07e84 100644 +--- a/src/go.mod ++++ b/src/go.mod +@@ -3,6 +3,7 @@ module std + go 1.21 + + require ( ++ github.com/golang-fips/openssl-fips v0.0.0-20230801192317-b175be2ccd46 + golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d + golang.org/x/net v0.12.1-0.20230712162946-57553cbff163 + ) +diff --git a/src/go.sum b/src/go.sum +index e474b8be31..0dab3e78f9 100644 +--- a/src/go.sum ++++ b/src/go.sum +@@ -1,3 +1,5 @@ ++github.com/golang-fips/openssl-fips v0.0.0-20230801192317-b175be2ccd46 h1:1oaM7kpYYlqwc6sIROINgj5fUW4CGZGEBwfzIc+TnJI= ++github.com/golang-fips/openssl-fips v0.0.0-20230801192317-b175be2ccd46/go.mod h1:V2IU8imz/VkScnIbTOrdYsZ5R88ZFypCE0LzhRJ3HsI= + golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d h1:LiA25/KWKuXfIq5pMIBq1s5hz3HQxhJJSu/SUGlD+SM= + golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= + golang.org/x/net v0.12.1-0.20230712162946-57553cbff163 h1:1EDKNuaCsog7zGLEml1qRuO4gt23jORUQX2f0IKZ860= +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/LICENSE b/src/vendor/github.com/golang-fips/openssl-fips/LICENSE +new file mode 100644 +index 0000000000..97e8515401 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/LICENSE +@@ -0,0 +1,20 @@ ++The MIT License (MIT) ++ ++Copyright (c) 2022 The Golang FIPS Authors ++ ++Permission is hereby granted, free of charge, to any person obtaining a copy of ++this software and associated documentation files (the "Software"), to deal in ++the Software without restriction, including without limitation the rights to ++use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ++the Software, and to permit persons to whom the Software is furnished to do so, ++subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in all ++copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ++FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ++COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ No newline at end of file +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/aes.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/aes.go +new file mode 100644 +index 0000000000..079fc3c4ad +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/aes.go +@@ -0,0 +1,516 @@ ++// 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 && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto/cipher" ++ "errors" ++ "runtime" ++ "strconv" ++ "unsafe" ++) ++ ++type aesKeySizeError int ++ ++func (k aesKeySizeError) Error() string { ++ return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) ++} ++ ++const aesBlockSize = 16 ++ ++type aesCipher struct { ++ key []byte ++ enc_ctx *C.EVP_CIPHER_CTX ++ dec_ctx *C.EVP_CIPHER_CTX ++ cipher *C.EVP_CIPHER ++} ++ ++type extraModes interface { ++ // Copied out of crypto/aes/modes.go. ++ NewCBCEncrypter(iv []byte) cipher.BlockMode ++ NewCBCDecrypter(iv []byte) cipher.BlockMode ++ NewCTR(iv []byte) cipher.Stream ++ NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) ++ ++ // Invented for BoringCrypto. ++ NewGCMTLS() (cipher.AEAD, error) ++} ++ ++var _ extraModes = (*aesCipher)(nil) ++ ++func NewAESCipher(key []byte) (cipher.Block, error) { ++ c := &aesCipher{key: make([]byte, len(key))} ++ copy(c.key, key) ++ ++ switch len(c.key) * 8 { ++ case 128: ++ c.cipher = C._goboringcrypto_EVP_aes_128_ecb() ++ case 192: ++ c.cipher = C._goboringcrypto_EVP_aes_192_ecb() ++ case 256: ++ c.cipher = C._goboringcrypto_EVP_aes_256_ecb() ++ default: ++ return nil, errors.New("crypto/cipher: Invalid key size") ++ } ++ ++ runtime.SetFinalizer(c, (*aesCipher).finalize) ++ ++ return c, nil ++} ++ ++func (c *aesCipher) finalize() { ++ if c.enc_ctx != nil { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.enc_ctx) ++ } ++ if c.dec_ctx != nil { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.dec_ctx) ++ } ++} ++ ++func (c *aesCipher) BlockSize() int { return aesBlockSize } ++ ++func (c *aesCipher) Encrypt(dst, src []byte) { ++ if inexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src) < aesBlockSize { ++ panic("crypto/aes: input not full block") ++ } ++ if len(dst) < aesBlockSize { ++ panic("crypto/aes: output not full block") ++ } ++ ++ if c.enc_ctx == nil { ++ c.enc_ctx = C._goboringcrypto_EVP_CIPHER_CTX_new() ++ if c.enc_ctx == nil { ++ panic("cipher: unable to create EVP cipher ctx") ++ } ++ ++ k := (*C.uchar)(unsafe.Pointer(&c.key[0])) ++ ++ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(c.enc_ctx, c.cipher, nil, k, nil, C.GO_AES_ENCRYPT) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++ } ++ ++ outlen := C.int(0) ++ C._goboringcrypto_EVP_CipherUpdate(c.enc_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize)) ++ runtime.KeepAlive(c) ++} ++ ++func (c *aesCipher) Decrypt(dst, src []byte) { ++ if inexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src) < aesBlockSize { ++ panic("crypto/aes: input not full block") ++ } ++ if len(dst) < aesBlockSize { ++ panic("crypto/aes: output not full block") ++ } ++ if c.dec_ctx == nil { ++ c.dec_ctx = C._goboringcrypto_EVP_CIPHER_CTX_new() ++ if c.dec_ctx == nil { ++ panic("cipher: unable to create EVP cipher ctx") ++ } ++ ++ k := (*C.uchar)(unsafe.Pointer(&c.key[0])) ++ ++ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(c.dec_ctx, c.cipher, nil, k, nil, C.GO_AES_DECRYPT) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++ } ++ // Workaround - padding detection is broken but we don't need it ++ // since we check for full blocks ++ if C._goboringcrypto_EVP_CIPHER_CTX_set_padding(c.dec_ctx, 0) != 1 { ++ panic("crypto/cipher: could not disable cipher padding") ++ } ++ outlen := C.int(0) ++ C._goboringcrypto_EVP_CipherUpdate(c.dec_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize)) ++ runtime.KeepAlive(c) ++} ++ ++type aesCBC struct { ++ key []byte ++ mode C.int ++ iv [aesBlockSize]byte ++ ctx *C.EVP_CIPHER_CTX ++} ++ ++func (x *aesCBC) BlockSize() int { return aesBlockSize } ++ ++func (x *aesCBC) CryptBlocks(dst, src []byte) { ++ if inexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src)%aesBlockSize != 0 { ++ panic("crypto/cipher: input not full blocks") ++ } ++ if len(dst) < len(src) { ++ panic("crypto/cipher: output smaller than input") ++ } ++ if len(src) > 0 { ++ outlen := C.int(0) ++ // Workaround - padding detection is broken but we don't need it ++ // since we check for full blocks ++ if C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { ++ panic("crypto/cipher: could not disable cipher padding") ++ } ++ if C._goboringcrypto_EVP_CipherUpdate( ++ x.ctx, ++ base(dst), &outlen, ++ base(src), C.int(len(src)), ++ ) != 1 { ++ panic("crypto/cipher: CipherUpdate failed") ++ } ++ runtime.KeepAlive(x) ++ } ++} ++ ++func (x *aesCBC) SetIV(iv []byte) { ++ if len(iv) != aesBlockSize { ++ panic("cipher: incorrect length IV") ++ } ++ copy(x.iv[:], iv) ++ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, nil, nil, nil, (*C.uchar)(unsafe.Pointer(&x.iv[0])), -1) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++} ++ ++func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ x := &aesCBC{key: c.key, mode: C.GO_AES_ENCRYPT} ++ copy(x.iv[:], iv) ++ ++ x.ctx = C._goboringcrypto_EVP_CIPHER_CTX_new() ++ if x.ctx == nil { ++ panic("cipher: unable to create EVP cipher ctx") ++ } ++ ++ k := (*C.uchar)(unsafe.Pointer(&x.key[0])) ++ vec := (*C.uchar)(unsafe.Pointer(&x.iv[0])) ++ ++ var cipher *C.EVP_CIPHER ++ switch len(c.key) * 8 { ++ case 128: ++ cipher = C._goboringcrypto_EVP_aes_128_cbc() ++ case 192: ++ cipher = C._goboringcrypto_EVP_aes_192_cbc() ++ case 256: ++ cipher = C._goboringcrypto_EVP_aes_256_cbc() ++ default: ++ panic("crypto/boring: unsupported key length") ++ } ++ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, cipher, nil, k, vec, x.mode) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++ ++ runtime.SetFinalizer(x, (*aesCBC).finalize) ++ ++ return x ++} ++ ++func (c *aesCBC) finalize() { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++} ++ ++func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ x := &aesCBC{key: c.key, mode: C.GO_AES_DECRYPT} ++ copy(x.iv[:], iv) ++ ++ x.ctx = C._goboringcrypto_EVP_CIPHER_CTX_new() ++ if x.ctx == nil { ++ panic("cipher: unable to create EVP cipher ctx") ++ } ++ ++ k := (*C.uchar)(unsafe.Pointer(&x.key[0])) ++ vec := (*C.uchar)(unsafe.Pointer(&x.iv[0])) ++ ++ var cipher *C.EVP_CIPHER ++ switch len(c.key) * 8 { ++ case 128: ++ cipher = C._goboringcrypto_EVP_aes_128_cbc() ++ case 192: ++ cipher = C._goboringcrypto_EVP_aes_192_cbc() ++ case 256: ++ cipher = C._goboringcrypto_EVP_aes_256_cbc() ++ default: ++ panic("crypto/boring: unsupported key length") ++ } ++ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, cipher, nil, k, vec, x.mode) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++ if C.int(1) != C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) { ++ panic("cipher: unable to set padding") ++ } ++ ++ runtime.SetFinalizer(x, (*aesCBC).finalize) ++ return x ++} ++ ++type aesCTR struct { ++ key []byte ++ iv [aesBlockSize]byte ++ ctx *C.EVP_CIPHER_CTX ++ num C.uint ++ ecount_buf [16]C.uint8_t ++} ++ ++func (x *aesCTR) XORKeyStream(dst, src []byte) { ++ if inexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(dst) < len(src) { ++ panic("crypto/cipher: output smaller than input") ++ } ++ if len(src) == 0 { ++ return ++ } ++ C._goboringcrypto_EVP_AES_ctr128_enc( ++ x.ctx, ++ (*C.uint8_t)(unsafe.Pointer(&src[0])), ++ (*C.uint8_t)(unsafe.Pointer(&dst[0])), ++ C.size_t(len(src))) ++ runtime.KeepAlive(x) ++} ++ ++func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { ++ x := &aesCTR{key: c.key} ++ copy(x.iv[:], iv) ++ ++ x.ctx = C._goboringcrypto_EVP_CIPHER_CTX_new() ++ if x.ctx == nil { ++ panic("cipher: unable to create EVP cipher ctx") ++ } ++ ++ k := (*C.uchar)(unsafe.Pointer(&x.key[0])) ++ vec := (*C.uchar)(unsafe.Pointer(&x.iv[0])) ++ ++ switch len(c.key) * 8 { ++ case 128: ++ if C.int(1) != C._goboringcrypto_EVP_EncryptInit_ex(x.ctx, C._goboringcrypto_EVP_aes_128_ctr(), nil, k, vec) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++ case 192: ++ if C.int(1) != C._goboringcrypto_EVP_EncryptInit_ex(x.ctx, C._goboringcrypto_EVP_aes_192_ctr(), nil, k, vec) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++ case 256: ++ if C.int(1) != C._goboringcrypto_EVP_EncryptInit_ex(x.ctx, C._goboringcrypto_EVP_aes_256_ctr(), nil, k, vec) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++ } ++ ++ runtime.SetFinalizer(x, (*aesCTR).finalize) ++ ++ return x ++} ++ ++func (c *aesCTR) finalize() { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++} ++ ++type aesGCM struct { ++ key []byte ++ tls bool ++} ++ ++const ( ++ gcmBlockSize = 16 ++ gcmTagSize = 16 ++ gcmStandardNonceSize = 12 ++) ++ ++type aesNonceSizeError int ++ ++func (n aesNonceSizeError) Error() string { ++ return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n)) ++} ++ ++type noGCM struct { ++ cipher.Block ++} ++ ++func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { ++ if !ExecutingTest() || IsStrictFips() { ++ if nonceSize != gcmStandardNonceSize { ++ return nil, errors.New("crypto/aes: GCM nonce size can't be non-standard") ++ } ++ if tagSize != gcmTagSize { ++ return nil, errors.New("crypto/aes: GCM tag size can't be non-standard") ++ } ++ } else { ++ // Be more lenient if we're running via a test binary so that ++ // we don't have to be as invasive with skipping tests in the standard ++ // library. ++ if nonceSize != gcmStandardNonceSize && tagSize != gcmTagSize { ++ return nil, errors.New("crypto/aes: GCM tag and nonce sizes can't be non-standard at the same time") ++ } ++ // Fall back to standard library for GCM with non-standard nonce or tag size. ++ if nonceSize != gcmStandardNonceSize { ++ return cipher.NewGCMWithNonceSize(&noGCM{c}, nonceSize) ++ } ++ if tagSize != gcmTagSize { ++ return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize) ++ } ++ } ++ return c.newGCM(false) ++} ++ ++// NewGCMTLS returns a GCM cipher specific to TLS ++// and should not be used for non-TLS purposes. ++func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { ++ return c.(*aesCipher).NewGCMTLS() ++} ++ ++func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) { ++ return c.newGCM(true) ++} ++ ++func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) { ++ keyLen := len(c.key) * 8 ++ ++ if keyLen != 128 && keyLen != 256 { ++ if ExecutingTest() { ++ // Fall back to standard library for GCM with non-standard key size. ++ return cipher.NewGCMWithNonceSize(&noGCM{c}, gcmStandardNonceSize) ++ } ++ // Return error for GCM with non-standard key size. ++ return nil, fail("GCM invoked with non-standard key size") ++ } ++ ++ g := &aesGCM{key: c.key, tls: tls} ++ if g.NonceSize() != gcmStandardNonceSize { ++ panic("boringcrypto: internal confusion about nonce size") ++ } ++ if g.Overhead() != gcmTagSize { ++ panic("boringcrypto: internal confusion about tag size") ++ } ++ ++ return g, nil ++} ++ ++func (g *aesGCM) NonceSize() int { ++ return gcmStandardNonceSize ++} ++ ++func (g *aesGCM) Overhead() int { ++ return gcmTagSize ++} ++ ++// base returns the address of the underlying array in b, ++// being careful not to panic when b has zero length. ++func base(b []byte) *C.uint8_t { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uint8_t)(unsafe.Pointer(&b[0])) ++} ++ ++func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { ++ if len(nonce) != gcmStandardNonceSize { ++ panic("cipher: incorrect nonce length given to GCM") ++ } ++ if uint64(len(plaintext)) > ((1<<32)-2)*aesBlockSize || len(plaintext)+gcmTagSize < len(plaintext) { ++ panic("cipher: message too large for GCM") ++ } ++ if len(dst)+len(plaintext)+gcmTagSize < len(dst) { ++ panic("cipher: message too large for buffer") ++ } ++ ++ // Make room in dst to append plaintext+overhead. ++ n := len(dst) ++ for cap(dst) < n+len(plaintext)+gcmTagSize { ++ dst = append(dst[:cap(dst)], 0) ++ } ++ dst = dst[:n+len(plaintext)+gcmTagSize] ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if inexactOverlap(dst[n:], plaintext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ var ciphertextLen C.size_t ++ ++ if ok := C._goboringcrypto_EVP_CIPHER_CTX_seal( ++ (*C.uint8_t)(unsafe.Pointer(&dst[n])), ++ base(nonce), base(additionalData), C.size_t(len(additionalData)), ++ base(plaintext), C.size_t(len(plaintext)), &ciphertextLen, ++ base(g.key), C.int(len(g.key)*8)); ok != 1 { ++ panic("boringcrypto: EVP_CIPHER_CTX_seal fail") ++ } ++ runtime.KeepAlive(g) ++ ++ if ciphertextLen != C.size_t(len(plaintext)+gcmTagSize) { ++ panic("boringcrypto: [seal] internal confusion about GCM tag size") ++ } ++ return dst[:n+int(ciphertextLen)] ++} ++ ++var errOpen = errors.New("cipher: message authentication failed") ++ ++func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { ++ if len(nonce) != gcmStandardNonceSize { ++ panic("cipher: incorrect nonce length given to GCM") ++ } ++ if len(ciphertext) < gcmTagSize { ++ return nil, errOpen ++ } ++ if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize { ++ return nil, errOpen ++ } ++ ++ // Make room in dst to append ciphertext without tag. ++ n := len(dst) ++ for cap(dst) < n+len(ciphertext)-gcmTagSize { ++ dst = append(dst[:cap(dst)], 0) ++ } ++ dst = dst[:n+len(ciphertext)-gcmTagSize] ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if inexactOverlap(dst[n:], ciphertext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ tag := ciphertext[len(ciphertext)-gcmTagSize:] ++ ++ var outLen C.size_t ++ ++ ok := C._goboringcrypto_EVP_CIPHER_CTX_open( ++ base(ciphertext), C.int(len(ciphertext)-gcmTagSize), ++ base(additionalData), C.int(len(additionalData)), ++ base(tag), base(g.key), C.int(len(g.key)*8), ++ base(nonce), C.int(len(nonce)), ++ base(dst[n:]), &outLen) ++ runtime.KeepAlive(g) ++ if ok == 0 { ++ // Zero output buffer on error. ++ for i := range dst { ++ dst[i] = 0 ++ } ++ return nil, errOpen ++ } ++ if outLen != C.size_t(len(ciphertext)-gcmTagSize) { ++ panic("boringcrypto: [open] internal confusion about GCM tag size") ++ } ++ return dst[:n+int(outLen)], nil ++} ++ ++func anyOverlap(x, y []byte) bool { ++ return len(x) > 0 && len(y) > 0 && ++ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && ++ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) ++} ++ ++func inexactOverlap(x, y []byte) bool { ++ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { ++ return false ++ } ++ return anyOverlap(x, y) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/doc.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/doc.go +new file mode 100644 +index 0000000000..cdc7f6a47b +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/doc.go +@@ -0,0 +1,17 @@ ++// 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 openssl provides access to OpenSSL implementation functions. ++package openssl ++ ++// Enabled returns whether or not the boring package is enabled. When ++// the boring package is enabled that means FIPS mode is enabled. ++func Enabled() bool { ++ return enabled ++} ++ ++// 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 []uint +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdh.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdh.go +new file mode 100644 +index 0000000000..56adf47bf6 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdh.go +@@ -0,0 +1,213 @@ ++// 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 && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++ "runtime" ++ "unsafe" ++) ++ ++var ( ++ paramPrivKey = C.CString("priv") ++) ++ ++type PublicKeyECDH struct { ++ _pkey *C.GO_EVP_PKEY ++ bytes []byte ++ ++ // priv is only set when PublicKeyECDH is derived from a private key, ++ // in which case priv's finalizer is responsible for freeing _pkey. ++ // This ensures priv is not finalized while the public key is alive, ++ // which could cause use-after-free and double-free behavior. ++ // ++ // We could avoid this altogether by using EVP_PKEY_up_ref ++ // when instantiating a derived public key, unfortunately ++ // it is not available on OpenSSL 1.0.2. ++ priv *PrivateKeyECDH ++} ++ ++func (k *PublicKeyECDH) finalize() { ++ if k.priv == nil { ++ C._goboringcrypto_EVP_PKEY_free(k._pkey) ++ } ++} ++ ++type PrivateKeyECDH struct { ++ _pkey *C.GO_EVP_PKEY ++ curve string ++ hasPublicKey bool ++} ++ ++func (k *PrivateKeyECDH) finalize() { ++ C._goboringcrypto_EVP_PKEY_free(k._pkey) ++} ++ ++func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { ++ if len(bytes) < 1 { ++ return nil, errors.New("NewPublicKeyECDH: missing key") ++ } ++ pkey, err := newECDHPkey(curve, bytes, false) ++ if err != nil { ++ return nil, err ++ } ++ k := &PublicKeyECDH{pkey, append([]byte(nil), bytes...), nil} ++ runtime.SetFinalizer(k, (*PublicKeyECDH).finalize) ++ return k, nil ++} ++ ++func (k *PublicKeyECDH) Bytes() []byte { return k.bytes } ++ ++func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { ++ pkey, err := newECDHPkey(curve, bytes, true) ++ if err != nil { ++ return nil, err ++ } ++ k := &PrivateKeyECDH{pkey, curve, false} ++ runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) ++ return k, nil ++} ++ ++func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { ++ defer runtime.KeepAlive(k) ++ if !k.hasPublicKey { ++ err := deriveEcdhPublicKey(k._pkey, k.curve) ++ if err != nil { ++ return nil, err ++ } ++ k.hasPublicKey = true ++ } ++ var bytes []byte ++ var cbytes *C.uchar ++ ++ n := C._goboringcrypto_EVP_PKEY_get1_encoded_ecdh_public_key(k._pkey, &cbytes) ++ if n == 0 { ++ return nil, NewOpenSSLError("EVP_PKEY_get1_encoded_ecdh_public_key") ++ } ++ bytes = C.GoBytes(unsafe.Pointer(cbytes), C.int(n)) ++ C.free(unsafe.Pointer(cbytes)) ++ ++ pub := &PublicKeyECDH{k._pkey, bytes, k} ++ runtime.SetFinalizer(pub, (*PublicKeyECDH).finalize) ++ return pub, nil ++} ++ ++func newECDHPkey(curve string, bytes []byte, isPrivate bool) (*C.GO_EVP_PKEY, error) { ++ nid, err := curveNID(curve) ++ if err != nil { ++ return nil, err ++ } ++ ++ var isPrivateValue C.int ++ if isPrivate { ++ isPrivateValue = 1 ++ } else { ++ if len(bytes) > 0 && bytes[0] != 0x04 { ++ return nil, errors.New("crypto/ecdh: point is compressed") ++ } else if len(bytes) == 1 && bytes[0] == 0x00 { ++ return nil, errors.New("crypto/ecdh: point at infinity") ++ } ++ } ++ ++ key := C._goboringcrypto_EVP_PKEY_new_for_ecdh(nid, base(bytes), C.size_t(len(bytes)), isPrivateValue) ++ if key == nil { ++ return nil, NewOpenSSLError("EVP_PKEY_new_for_ecdh") ++ } ++ return key, nil ++} ++ ++// deriveEcdhPublicKey sets the raw public key of pkey by deriving it from ++// the raw private key. ++func deriveEcdhPublicKey(pkey *C.GO_EVP_PKEY, curve string) error { ++ nid, _ := curveNID(curve) ++ if C._goboringcrypto_EVP_PKEY_set_ecdh_public_key_from_private(pkey, nid) != 1 { ++ return NewOpenSSLError("EVP_PKEY_set_ecdh_public_key_from_private") ++ } ++ return nil ++} ++ ++func encodeEcPoint(group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]byte, error) { ++ // Get encoded point size. ++ n := C._goboringcrypto_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, nil, 0, nil) ++ if n == 0 { ++ return nil, NewOpenSSLError("EC_POINT_point2oct") ++ } ++ // Encode point into bytes. ++ bytes := make([]byte, n) ++ n = C._goboringcrypto_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, base(bytes), n, nil) ++ if n == 0 { ++ return nil, NewOpenSSLError("EC_POINT_point2oct") ++ } ++ return bytes, nil ++} ++ ++func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { ++ defer runtime.KeepAlive(priv) ++ defer runtime.KeepAlive(pub) ++ ctx := C._goboringcrypto_EVP_PKEY_CTX_new(priv._pkey, nil) ++ if ctx == nil { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_new") ++ } ++ defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx) ++ if C._goboringcrypto_EVP_PKEY_derive_init(ctx) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_derive_init") ++ } ++ if C._goboringcrypto_EVP_PKEY_derive_set_peer_ex(ctx, pub._pkey, 1) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_derive_set_peer_ex") ++ } ++ var outLen C.size_t ++ if C._goboringcrypto_EVP_PKEY_derive(ctx, nil, &outLen) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_derive_init") ++ } ++ out := make([]byte, outLen) ++ if C._goboringcrypto_EVP_PKEY_derive(ctx, base(out), &outLen) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_derive_init") ++ } ++ return out, nil ++} ++ ++func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { ++ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve) ++ if err != nil { ++ return nil, nil, err ++ } ++ var k *PrivateKeyECDH ++ defer func() { ++ if k == nil { ++ C._goboringcrypto_EVP_PKEY_free(pkey) ++ } ++ }() ++ var priv *C.GO_BIGNUM ++ if openSSLVersion() < OPENSSL_VERSION_3_0_0 { ++ key := getECKey(pkey) ++ priv = C._goboringcrypto_EC_KEY_get0_private_key(key) ++ if priv == nil { ++ return nil, nil, NewOpenSSLError("EC_KEY_get0_private_key") ++ } ++ } else { ++ if C._goboringcrypto_EVP_PKEY_get_bn_param(pkey, paramPrivKey, &priv) != 1 { ++ return nil, nil, NewOpenSSLError("EVP_PKEY_get_bn_param") ++ } ++ defer C._goboringcrypto_BN_free(priv) ++ } ++ // We should not leak bit length of the secret scalar in the key. ++ // For this reason, we use BN_bn2binpad instead of BN_bn2bin with fixed length. ++ // The fixed length is the order of the large prime subgroup of the curve, ++ // returned by EVP_PKEY_get_bits, which is generally the upper bound for ++ // generating a private ECDH key. ++ bits := C._goboringcrypto_EVP_PKEY_get_bits(pkey) ++ bytes := make([]byte, (bits+7)/8) ++ if C._goboringcrypto_BN_bn2binpad(priv, base(bytes), C.int(len(bytes))) == 0 { ++ return nil, nil, NewOpenSSLError("BN_bn2binpad") ++ } ++ k = &PrivateKeyECDH{pkey, curve, true} ++ runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) ++ return k, bytes, nil ++} +diff --git a/src/crypto/internal/boring/ecdsa.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdsa.go +similarity index 60% +rename from src/crypto/internal/boring/ecdsa.go +rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdsa.go +index e15f3682c7..5e1e789da0 100644 +--- a/src/crypto/internal/boring/ecdsa.go ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdsa.go +@@ -2,19 +2,24 @@ + // 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 && !cmd_go_bootstrap && !msan ++//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl + +-package boring ++package openssl + +-// #include "goboringcrypto.h" ++// #include "goopenssl.h" + import "C" + import ( ++ "crypto" ++ "encoding/asn1" + "errors" ++ "math/big" + "runtime" ++ "unsafe" + ) + + type ecdsaSignature struct { +- R, S BigInt ++ R, S *big.Int + } + + type PrivateKeyECDSA struct { +@@ -34,11 +39,15 @@ func (k *PublicKeyECDSA) finalize() { + } + + var errUnknownCurve = errors.New("boringcrypto: unknown elliptic curve") ++var errUnsupportedCurve = errors.New("boringcrypto: unsupported elliptic curve") + + func curveNID(curve string) (C.int, error) { + switch curve { + case "P-224": +- return C.GO_NID_secp224r1, nil ++ if ExecutingTest() { ++ return C.GO_NID_secp224r1, nil ++ } ++ return 0, errUnsupportedCurve + case "P-256": + return C.GO_NID_X9_62_prime256v1, nil + case "P-384": +@@ -70,13 +79,13 @@ func newECKey(curve string, X, Y BigInt) (*C.GO_EC_KEY, error) { + } + key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) + if key == nil { +- return nil, fail("EC_KEY_new_by_curve_name") ++ return nil, NewOpenSSLError("EC_KEY_new_by_curve_name failed") + } + group := C._goboringcrypto_EC_KEY_get0_group(key) + pt := C._goboringcrypto_EC_POINT_new(group) + if pt == nil { + C._goboringcrypto_EC_KEY_free(key) +- return nil, fail("EC_POINT_new") ++ return nil, NewOpenSSLError("EC_POINT_new failed") + } + bx := bigToBN(X) + by := bigToBN(Y) +@@ -91,7 +100,7 @@ func newECKey(curve string, X, Y BigInt) (*C.GO_EC_KEY, error) { + C._goboringcrypto_EC_POINT_free(pt) + if !ok { + C._goboringcrypto_EC_KEY_free(key) +- return nil, fail("EC_POINT_set_affine_coordinates_GFp") ++ return nil, NewOpenSSLError("EC_POINT_free failed") + } + return key, nil + } +@@ -108,7 +117,7 @@ func NewPrivateKeyECDSA(curve string, X, Y BigInt, D BigInt) (*PrivateKeyECDSA, + } + if !ok { + C._goboringcrypto_EC_KEY_free(key) +- return nil, fail("EC_KEY_set_private_key") ++ return nil, NewOpenSSLError("EC_KEY_set_private_key failed") + } + k := &PrivateKeyECDSA{key} + // Note: Because of the finalizer, any time k.key is passed to cgo, +@@ -119,19 +128,55 @@ func NewPrivateKeyECDSA(curve string, X, Y BigInt, D BigInt) (*PrivateKeyECDSA, + return k, nil + } + ++func HashSignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (*big.Int, *big.Int, error) { ++ size := C._goboringcrypto_ECDSA_size(priv.key) ++ sig := make([]byte, size) ++ var sigLen C.size_t ++ md := cryptoHashToMD(h) ++ if md == nil { ++ panic("boring: invalid hash") ++ } ++ if C._goboringcrypto_ECDSA_sign(md, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 { ++ return nil, nil, NewOpenSSLError("ECDSA_sign failed") ++ } ++ runtime.KeepAlive(priv) ++ sig = sig[:sigLen] ++ var esig ecdsaSignature ++ if _, err := asn1.Unmarshal(sig, &esig); err != nil { ++ return nil, nil, err ++ } ++ return esig.R, esig.S, nil ++} ++ + func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { + size := C._goboringcrypto_ECDSA_size(priv.key) + sig := make([]byte, size) + var sigLen C.uint +- if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), base(sig), &sigLen, priv.key) == 0 { +- return nil, fail("ECDSA_sign") ++ ok := C._goboringcrypto_internal_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) > 0 ++ if !ok { ++ return nil, NewOpenSSLError(("ECDSA_sign failed")) + } ++ + runtime.KeepAlive(priv) + return sig[:sigLen], nil + } + + func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool { +- ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), base(sig), C.size_t(len(sig)), pub.key) != 0 ++ ok := C._goboringcrypto_internal_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), pub.key) > 0 ++ runtime.KeepAlive(pub) ++ return ok ++} ++ ++func HashVerifyECDSA(pub *PublicKeyECDSA, msg []byte, r, s *big.Int, h crypto.Hash) bool { ++ md := cryptoHashToMD(h) ++ if md == nil { ++ panic("boring: invalid hash") ++ } ++ sig, err := asn1.Marshal(ecdsaSignature{r, s}) ++ if err != nil { ++ return false ++ } ++ ok := C._goboringcrypto_ECDSA_verify(md, base(msg), C.size_t(len(msg)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), pub.key) > 0 + runtime.KeepAlive(pub) + return ok + } +@@ -143,30 +188,30 @@ func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) { + } + key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) + if key == nil { +- return nil, nil, nil, fail("EC_KEY_new_by_curve_name") ++ return nil, nil, nil, NewOpenSSLError("EC_KEY_new_by_curve_name failed") + } + defer C._goboringcrypto_EC_KEY_free(key) +- if C._goboringcrypto_EC_KEY_generate_key_fips(key) == 0 { +- return nil, nil, nil, fail("EC_KEY_generate_key_fips") ++ if C._goboringcrypto_EC_KEY_generate_key(key) == 0 { ++ return nil, nil, nil, NewOpenSSLError("EC_KEY_generate_key failed") + } + group := C._goboringcrypto_EC_KEY_get0_group(key) + pt := C._goboringcrypto_EC_KEY_get0_public_key(key) + bd := C._goboringcrypto_EC_KEY_get0_private_key(key) + if pt == nil || bd == nil { +- return nil, nil, nil, fail("EC_KEY_get0_private_key") ++ return nil, nil, nil, NewOpenSSLError("EC_KEY_get0_private_key failed") + } + bx := C._goboringcrypto_BN_new() + if bx == nil { +- return nil, nil, nil, fail("BN_new") ++ return nil, nil, nil, NewOpenSSLError("BN_new failed") + } + defer C._goboringcrypto_BN_free(bx) + by := C._goboringcrypto_BN_new() + if by == nil { +- return nil, nil, nil, fail("BN_new") ++ return nil, nil, nil, NewOpenSSLError("BN_new failed") + } + defer C._goboringcrypto_BN_free(by) + if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 { +- return nil, nil, nil, fail("EC_POINT_get_affine_coordinates_GFp") ++ return nil, nil, nil, NewOpenSSLError("EC_POINT_get_affine_coordinates_GFp failed") + } + return bnToBig(bx), bnToBig(by), bnToBig(bd), nil + } +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/evp.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/evp.go +new file mode 100644 +index 0000000000..46d2bdd068 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/evp.go +@@ -0,0 +1,51 @@ ++//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++ ++func generateEVPPKey(id C.int, bits int, curve string) (*C.GO_EVP_PKEY, error) { ++ if (bits == 0 && curve == "") || (bits != 0 && curve != "") { ++ return nil, fail("incorrect generateEVPPKey parameters") ++ } ++ ctx := C._goboringcrypto_EVP_PKEY_CTX_new_id(id, nil) ++ if ctx == nil { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_new_id failed") ++ } ++ defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx) ++ if C._goboringcrypto_EVP_PKEY_keygen_init(ctx) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_keygen_init failed") ++ } ++ if bits != 0 { ++ if C._goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS, C.int(bits), nil) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ if curve != "" { ++ nid, err := curveNID(curve) ++ if err != nil { ++ return nil, err ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, nil) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ var pkey *C.GO_EVP_PKEY ++ if C._goboringcrypto_EVP_PKEY_keygen(ctx, &pkey) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_keygen failed") ++ } ++ return pkey, nil ++} ++ ++// getECKey returns the EC_KEY from pkey. ++// If pkey does not contain an EC_KEY it panics. ++// The returned key should not be freed. ++func getECKey(pkey *C.GO_EVP_PKEY) (key *C.GO_EC_KEY) { ++ key = C._goboringcrypto_EVP_PKEY_get0_EC_KEY(pkey) ++ if key == nil { ++ panic("pkey does not contain an EC_KEY") ++ } ++ return key ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/goopenssl.h b/src/vendor/github.com/golang-fips/openssl-fips/openssl/goopenssl.h +new file mode 100644 +index 0000000000..a900b3f9e7 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/goopenssl.h +@@ -0,0 +1,1099 @@ ++// 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. ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++// This header file describes the OpenSSL ABI as built for use in Go. ++ ++#include // size_t ++#include // uint8_t ++#include // memset ++ ++#include ++ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++#define OPENSSL_DLSYM_CALL(handle, func) dlsym(handle, func) ++#else ++#define __USE_GNU ++#define OPENSSL_DLSYM_CALL(handle, func) dlvsym(handle, func, "OPENSSL_3.0.0") ++#endif ++ ++#include ++ ++#define unlikely(x) __builtin_expect(!!(x), 0) ++#define DEFINEFUNC(ret, func, args, argscall) \ ++ typedef ret(*_goboringcrypto_PTR_##func) args; \ ++ static _goboringcrypto_PTR_##func _g_##func = 0; \ ++ static inline ret _goboringcrypto_##func args \ ++ { \ ++ if (unlikely(!_g_##func)) \ ++ { \ ++ _g_##func = OPENSSL_DLSYM_CALL(handle, #func); \ ++ } \ ++ return _g_##func argscall; \ ++ } ++ ++#define DEFINEFUNCINTERNAL(ret, func, args, argscall) \ ++ typedef ret(*_goboringcrypto_internal_PTR_##func) args; \ ++ static _goboringcrypto_internal_PTR_##func _g_internal_##func = 0; \ ++ static inline ret _goboringcrypto_internal_##func args \ ++ { \ ++ if (unlikely(!_g_internal_##func)) \ ++ { \ ++ _g_internal_##func = OPENSSL_DLSYM_CALL(handle, #func); \ ++ } \ ++ return _g_internal_##func argscall; \ ++ } ++ ++#define DEFINEMACRO(ret, func, args, argscall) \ ++ static inline ret _goboringcrypto_##func args \ ++ { \ ++ return func argscall; \ ++ } ++ ++ ++static void* handle; ++static void* ++_goboringcrypto_DLOPEN_OPENSSL(void) ++{ ++ if (handle) ++ { ++ return handle; ++ } ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ handle = dlopen("libcrypto.so.10", RTLD_NOW | RTLD_GLOBAL); ++#elif OPENSSL_VERSION_NUMBER < 0x30000000L ++ handle = dlopen("libcrypto.so.1.1", RTLD_NOW | RTLD_GLOBAL); ++#else ++ handle = dlopen("libcrypto.so.3", RTLD_NOW | RTLD_GLOBAL); ++#endif ++ return handle; ++} ++ ++#include ++#include ++ ++DEFINEFUNCINTERNAL(void, OPENSSL_init, (void), ()) ++ ++static unsigned long _goboringcrypto_internal_OPENSSL_VERSION_NUMBER(void) { ++ return OPENSSL_VERSION_NUMBER; ++} ++ ++static void ++_goboringcrypto_OPENSSL_setup(void) { ++ _goboringcrypto_internal_OPENSSL_init(); ++} ++ ++#include ++DEFINEFUNCINTERNAL(void, ERR_print_errors_fp, (FILE* fp), (fp)) ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++DEFINEFUNCINTERNAL(unsigned long, ERR_get_error_line_data, ++ (const char **file, int *line, const char **data, int *flags), ++ (file, line, data, flags)) ++static inline unsigned long ++_goboringcrypto_internal_ERR_get_error_all(const char **file, int *line, const char **func, const char **data, int *flags) ++{ ++ unsigned long e = _goboringcrypto_internal_ERR_get_error_line_data(file, line, data, flags); ++ if (e == 0 && func != NULL) { ++ *func = "unknown"; ++ } ++ return e; ++} ++#else ++DEFINEFUNCINTERNAL(unsigned long, ERR_get_error_all, ++ (const char **file, int *line, const char **func, const char **data, int *flags), ++ (file, line, func, data, flags)) ++#endif ++DEFINEFUNCINTERNAL(void, ERR_error_string_n, (unsigned long e, unsigned char *buf, size_t len), (e, buf, len)) ++ ++#include ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++DEFINEFUNC(int, CRYPTO_num_locks, (void), ()) ++#else ++static inline int ++_goboringcrypto_CRYPTO_num_locks(void) { ++ return CRYPTO_num_locks(); /* defined as macro */ ++} ++#endif ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++DEFINEFUNC(void, CRYPTO_set_id_callback, (unsigned long (*id_function)(void)), (id_function)) ++#else ++static inline void ++_goboringcrypto_CRYPTO_set_id_callback(unsigned long (*id_function)(void)) { ++ CRYPTO_set_id_callback(id_function); /* defined as macro */ ++} ++#endif ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++DEFINEFUNC(void, CRYPTO_set_locking_callback, ++ (void (*locking_function)(int mode, int n, const char *file, int line)), ++ (locking_function)) ++#else ++static inline void ++_goboringcrypto_CRYPTO_set_locking_callback(void (*locking_function)(int mode, int n, const char *file, int line)) { ++ CRYPTO_set_locking_callback(locking_function); /* defined as macro */ ++} ++#endif ++ ++int _goboringcrypto_OPENSSL_thread_setup(void); ++ ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++DEFINEFUNC(int, FIPS_mode, (void), ()) ++DEFINEFUNC(int, FIPS_mode_set, (int r), (r)) ++#else ++DEFINEFUNC(int, EVP_default_properties_is_fips_enabled, (OSSL_LIB_CTX *libctx), (libctx)) ++static inline int _goboringcrypto_FIPS_mode(void) { ++ return _goboringcrypto_EVP_default_properties_is_fips_enabled(NULL); ++} ++#endif ++ ++#include ++ ++DEFINEFUNC(int, RAND_set_rand_method, (const RAND_METHOD *rand), (rand)) ++DEFINEFUNC(const RAND_METHOD*, RAND_get_rand_method, (void), ()) ++DEFINEFUNC(int, RAND_bytes, (uint8_t * arg0, size_t arg1), (arg0, arg1)) ++ ++int _goboringcrypto_stub_openssl_rand(void); ++int _goboringcrypto_restore_openssl_rand(void); ++int fbytes(unsigned char *buf, int num); ++ ++ ++#include ++ ++enum ++{ ++ GO_NID_md5_sha1 = NID_md5_sha1, ++ ++ GO_NID_secp224r1 = NID_secp224r1, ++ GO_NID_X9_62_prime256v1 = NID_X9_62_prime256v1, ++ GO_NID_secp384r1 = NID_secp384r1, ++ GO_NID_secp521r1 = NID_secp521r1, ++ ++ GO_NID_sha224 = NID_sha224, ++ GO_NID_sha256 = NID_sha256, ++ GO_NID_sha384 = NID_sha384, ++ GO_NID_sha512 = NID_sha512, ++}; ++ ++#include ++ ++typedef SHA_CTX GO_SHA_CTX; ++ ++DEFINEFUNC(int, SHA1_Init, (GO_SHA_CTX * arg0), (arg0)) ++DEFINEFUNC(int, SHA1_Update, (GO_SHA_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, SHA1_Final, (uint8_t * arg0, GO_SHA_CTX *arg1), (arg0, arg1)) ++ ++typedef SHA256_CTX GO_SHA256_CTX; ++ ++DEFINEFUNC(int, SHA224_Init, (GO_SHA256_CTX * arg0), (arg0)) ++DEFINEFUNC(int, SHA224_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, SHA224_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1)) ++ ++DEFINEFUNC(int, SHA256_Init, (GO_SHA256_CTX * arg0), (arg0)) ++DEFINEFUNC(int, SHA256_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, SHA256_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1)) ++ ++typedef SHA512_CTX GO_SHA512_CTX; ++DEFINEFUNC(int, SHA384_Init, (GO_SHA512_CTX * arg0), (arg0)) ++DEFINEFUNC(int, SHA384_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, SHA384_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1)) ++ ++DEFINEFUNC(int, SHA512_Init, (GO_SHA512_CTX * arg0), (arg0)) ++DEFINEFUNC(int, SHA512_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, SHA512_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1)) ++ ++#include ++ ++typedef EVP_MD GO_EVP_MD; ++DEFINEFUNC(const GO_EVP_MD *, EVP_md4, (void), ()) ++DEFINEFUNC(const GO_EVP_MD *, EVP_md5, (void), ()) ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha1, (void), ()) ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha224, (void), ()) ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha256, (void), ()) ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha384, (void), ()) ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha512, (void), ()) ++DEFINEFUNC(const GO_EVP_MD *, EVP_md_null, (void), ()) ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++DEFINEFUNCINTERNAL(int, EVP_MD_type, (const GO_EVP_MD *arg0), (arg0)) ++DEFINEFUNCINTERNAL(int, EVP_MD_size, (const GO_EVP_MD *arg0), (arg0)) ++static inline int ++_goboringcrypto_EVP_MD_get_size(const GO_EVP_MD *arg0) ++{ ++ return _goboringcrypto_internal_EVP_MD_size(arg0); ++} ++#else ++DEFINEFUNCINTERNAL(int, EVP_MD_get_type, (const GO_EVP_MD *arg0), (arg0)) ++DEFINEFUNC(int, EVP_MD_get_size, (const GO_EVP_MD *arg0), (arg0)) ++#endif ++DEFINEFUNCINTERNAL(const GO_EVP_MD*, EVP_md5_sha1, (void), ()) ++ ++# include ++DEFINEFUNCINTERNAL(int, MD5_Init, (MD5_CTX *c), (c)) ++DEFINEFUNCINTERNAL(int, MD5_Update, (MD5_CTX *c, const void *data, size_t len), (c, data, len)) ++DEFINEFUNCINTERNAL(int, MD5_Final, (unsigned char *md, MD5_CTX *c), (md, c)) ++ ++static inline int ++_goboringcrypto_EVP_MD_type(const GO_EVP_MD *md) { ++#if OPENSSL_VERSION_NUMBER < 0x30000000L ++ return _goboringcrypto_internal_EVP_MD_type(md); ++#else ++ return _goboringcrypto_internal_EVP_MD_get_type(md); ++#endif ++} ++ ++const GO_EVP_MD* _goboringcrypto_backport_EVP_md5_sha1(void); ++static inline const GO_EVP_MD* ++_goboringcrypto_EVP_md5_sha1(void) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ return _goboringcrypto_backport_EVP_md5_sha1(); ++#else ++ return _goboringcrypto_internal_EVP_md5_sha1(); ++#endif ++} ++ ++#include ++ ++typedef HMAC_CTX GO_HMAC_CTX; ++ ++DEFINEFUNC(int, HMAC_Init_ex, ++ (GO_HMAC_CTX * arg0, const void *arg1, int arg2, const GO_EVP_MD *arg3, ENGINE *arg4), ++ (arg0, arg1, arg2, arg3, arg4)) ++DEFINEFUNC(int, HMAC_Update, (GO_HMAC_CTX * arg0, const uint8_t *arg1, size_t arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, HMAC_Final, (GO_HMAC_CTX * arg0, uint8_t *arg1, unsigned int *arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(size_t, HMAC_CTX_copy, (GO_HMAC_CTX *dest, GO_HMAC_CTX *src), (dest, src)) ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++DEFINEFUNCINTERNAL(void, HMAC_CTX_cleanup, (GO_HMAC_CTX * arg0), (arg0)) ++static inline void ++_goboringcrypto_HMAC_CTX_free(HMAC_CTX *ctx) { ++ if (ctx != NULL) { ++ _goboringcrypto_internal_HMAC_CTX_cleanup(ctx); ++ free(ctx); ++ } ++} ++#else ++DEFINEFUNC(void, HMAC_CTX_free, (GO_HMAC_CTX * arg0), (arg0)) ++#endif ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++static inline size_t ++_goboringcrypto_HMAC_size(const GO_HMAC_CTX* arg0) { ++ return _goboringcrypto_EVP_MD_get_size(arg0->md); ++} ++#else ++DEFINEFUNCINTERNAL(const EVP_MD*, HMAC_CTX_get_md, (const GO_HMAC_CTX* ctx), (ctx)) ++static inline size_t ++_goboringcrypto_HMAC_size(const GO_HMAC_CTX* arg0) { ++ const EVP_MD* md; ++ md = _goboringcrypto_internal_HMAC_CTX_get_md(arg0); ++ return _goboringcrypto_EVP_MD_get_size(md); ++} ++#endif ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++DEFINEFUNCINTERNAL(void, HMAC_CTX_init, (GO_HMAC_CTX * arg0), (arg0)) ++static inline GO_HMAC_CTX* ++_goboringcrypto_HMAC_CTX_new(void) { ++ GO_HMAC_CTX* ctx = malloc(sizeof(GO_HMAC_CTX)); ++ if (ctx != NULL) ++ _goboringcrypto_internal_HMAC_CTX_init(ctx); ++ return ctx; ++} ++#else ++DEFINEFUNC(GO_HMAC_CTX*, HMAC_CTX_new, (void), ()) ++#endif ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++static inline int ++_goboringcrypto_HMAC_CTX_reset(GO_HMAC_CTX* ctx) { ++ _goboringcrypto_internal_HMAC_CTX_cleanup(ctx); ++ _goboringcrypto_internal_HMAC_CTX_init(ctx); ++ return 0; ++} ++#else ++DEFINEFUNC(int, HMAC_CTX_reset, (GO_HMAC_CTX * arg0), (arg0)) ++#endif ++ ++int _goboringcrypto_HMAC_CTX_copy_ex(GO_HMAC_CTX *dest, const GO_HMAC_CTX *src); ++ ++#include ++#include ++ ++DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, (void), ()) ++DEFINEFUNC(int, EVP_CIPHER_CTX_set_padding, (EVP_CIPHER_CTX *x, int padding), (x, padding)) ++DEFINEFUNC(int, EVP_CipherInit_ex, ++ (EVP_CIPHER_CTX * ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc), ++ (ctx, type, impl, key, iv, enc)) ++DEFINEFUNC(int, EVP_CipherUpdate, ++ (EVP_CIPHER_CTX * ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), ++ (ctx, out, outl, in, inl)) ++ ++void _goboringcrypto_EVP_AES_ctr128_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len); ++ ++int _goboringcrypto_EVP_AES_encrypt(EVP_CIPHER_CTX *ctx, const uint8_t *in, size_t in_len, uint8_t *out); ++ ++enum ++{ ++ GO_AES_ENCRYPT = 1, ++ GO_AES_DECRYPT = 0 ++}; ++void _goboringcrypto_EVP_AES_cbc_encrypt(EVP_CIPHER_CTX *ctx, const uint8_t *arg0, uint8_t *arg1, size_t arg2, const uint8_t *a, const int arg5); ++DEFINEFUNC(void, AES_cbc_encrypt, ++ (const unsigned char *in, unsigned char *out, ++ size_t length, const AES_KEY *key, ++ unsigned char *ivec, const int enc), ++ (in, out, length, key, ivec, enc)) ++ ++void EVP_AES_cbc_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len); ++ ++void EVP_AES_cbc_dec(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len); ++ ++typedef ENGINE GO_ENGINE; ++ ++#include ++ ++typedef BN_CTX GO_BN_CTX; ++typedef BIGNUM GO_BIGNUM; ++ ++DEFINEFUNC(GO_BIGNUM *, BN_new, (void), ()) ++DEFINEFUNC(void, BN_free, (GO_BIGNUM * arg0), (arg0)) ++DEFINEFUNC(void, BN_clear_free, (GO_BIGNUM * arg0), (arg0)) ++DEFINEFUNC(int, BN_set_word, (BIGNUM *a, BN_ULONG w), (a, w)) ++DEFINEFUNC(unsigned int, BN_num_bits, (const GO_BIGNUM *arg0), (arg0)) ++DEFINEFUNC(int, BN_is_negative, (const GO_BIGNUM *arg0), (arg0)) ++DEFINEFUNC(GO_BIGNUM *, BN_bin2bn, (const uint8_t *arg0, size_t arg1, GO_BIGNUM *arg2), (arg0, arg1, arg2)) ++ ++static inline int ++_goboringcrypto_BN_num_bytes(const GO_BIGNUM* a) { ++ return ((_goboringcrypto_BN_num_bits(a)+7)/8); ++} ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++DEFINEFUNC(GO_BIGNUM *, BN_lebin2bn, (const unsigned char *s, int len, GO_BIGNUM *ret), (s, len, ret)) ++DEFINEFUNC(int, BN_bn2lebinpad, (const GO_BIGNUM *a, unsigned char *to, int tolen), (a, to, tolen)) ++DEFINEFUNC(int, BN_bn2binpad, (const GO_BIGNUM *a, unsigned char *to, int tolen), (a, to, tolen)) ++#else ++DEFINEFUNCINTERNAL(int, BN_bn2bin, (const GO_BIGNUM *a, unsigned char *to), (a, to)) ++ ++static inline GO_BIGNUM * ++_goboringcrypto_BN_lebin2bn(const unsigned char *s, int len, GO_BIGNUM *ret) ++{ ++ unsigned char *copy; ++ size_t i; ++ GO_BIGNUM *result; ++ ++ copy = malloc(len); ++ if (!copy) ++ return NULL; ++ for (i = 0; i < len; i++) ++ copy[i] = s[len - i - 1]; ++ ++ result = _goboringcrypto_BN_bin2bn(copy, len, ret); ++ free(copy); ++ return result; ++} ++ ++static inline int ++_goboringcrypto_BN_bn2binpad(const GO_BIGNUM *a, unsigned char *to, int tolen) ++{ ++ int size = _goboringcrypto_BN_num_bytes(a); ++ int i; ++ ++ if (size > tolen) ++ return -1; ++ ++ memset(to, 0, tolen - size); ++ if (_goboringcrypto_internal_BN_bn2bin(a, to + tolen - size) != size) ++ return -1; ++ ++ return tolen; ++} ++ ++static inline int ++_goboringcrypto_BN_bn2lebinpad(const GO_BIGNUM *a, unsigned char *to, int tolen) ++{ ++ int size = _goboringcrypto_BN_bn2binpad(a, to, tolen); ++ int i; ++ ++ if (size != tolen) ++ return -1; ++ ++ /* reverse bytes */ ++ for (i = 0; i < tolen / 2; i++) { ++ unsigned char tmp; ++ ++ tmp = to[i]; ++ to[i] = to[tolen - i - 1]; ++ to[tolen - i - 1] = tmp; ++ } ++ ++ return tolen; ++} ++#endif ++ ++#include ++ ++enum { ++ GO_EVP_PKEY_EC = EVP_PKEY_EC, ++}; ++ ++typedef EC_GROUP GO_EC_GROUP; ++ ++DEFINEFUNC(GO_EC_GROUP *, EC_GROUP_new_by_curve_name, (int arg0), (arg0)) ++DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP * arg0), (arg0)) ++ ++typedef EC_POINT GO_EC_POINT; ++ ++DEFINEFUNC(GO_EC_POINT *, EC_POINT_new, (const GO_EC_GROUP *arg0), (arg0)) ++DEFINEFUNC(void, EC_POINT_free, (GO_EC_POINT * arg0), (arg0)) ++DEFINEFUNC(int, EC_POINT_get_affine_coordinates_GFp, ++ (const GO_EC_GROUP *arg0, const GO_EC_POINT *arg1, GO_BIGNUM *arg2, GO_BIGNUM *arg3, GO_BN_CTX *arg4), ++ (arg0, arg1, arg2, arg3, arg4)) ++DEFINEFUNC(int, EC_POINT_set_affine_coordinates_GFp, ++ (const GO_EC_GROUP *arg0, GO_EC_POINT *arg1, const GO_BIGNUM *arg2, const GO_BIGNUM *arg3, GO_BN_CTX *arg4), ++ (arg0, arg1, arg2, arg3, arg4)) ++ ++typedef EC_KEY GO_EC_KEY; ++ ++DEFINEFUNC(GO_EC_KEY *, EC_KEY_new, (void), ()) ++DEFINEFUNC(GO_EC_KEY *, EC_KEY_new_by_curve_name, (int arg0), (arg0)) ++DEFINEFUNC(void, EC_KEY_free, (GO_EC_KEY * arg0), (arg0)) ++DEFINEFUNC(const GO_EC_GROUP *, EC_KEY_get0_group, (const GO_EC_KEY *arg0), (arg0)) ++DEFINEFUNC(int, EC_KEY_set_group, (GO_EC_KEY *arg0, const EC_GROUP *arg1), (arg0, arg1)) ++DEFINEFUNC(int, EC_KEY_generate_key, (GO_EC_KEY * arg0), (arg0)) ++DEFINEFUNC(int, EC_KEY_set_private_key, (GO_EC_KEY * arg0, const GO_BIGNUM *arg1), (arg0, arg1)) ++DEFINEFUNC(int, EC_KEY_set_public_key, (GO_EC_KEY * arg0, const GO_EC_POINT *arg1), (arg0, arg1)) ++DEFINEFUNC(const GO_BIGNUM *, EC_KEY_get0_private_key, (const GO_EC_KEY *arg0), (arg0)) ++DEFINEFUNC(const GO_EC_POINT *, EC_KEY_get0_public_key, (const GO_EC_KEY *arg0), (arg0)) ++DEFINEFUNC(size_t, EC_POINT_point2oct, (const GO_EC_GROUP *group, const GO_EC_POINT *p, point_conversion_form_t form, unsigned char *buf, size_t len, GO_BN_CTX *ctx), (group, p, form, buf, len, ctx)) ++DEFINEFUNC(int, EC_POINT_oct2point, (const GO_EC_GROUP *group, GO_EC_POINT *p, const unsigned char *buf, size_t len, GO_BN_CTX *ctx), (group, p, buf, len, ctx)) ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++DEFINEFUNC(int, EC_KEY_oct2key, (GO_EC_KEY *arg0, const unsigned char *arg1, size_t arg2, BN_CTX *arg3), (arg0, arg1, arg2, arg3)) ++#else ++static inline int ++_goboringcrypto_EC_KEY_oct2key(GO_EC_KEY *eckey, const unsigned char *buf, size_t len, BN_CTX *ctx) ++{ ++ const GO_EC_GROUP *group = _goboringcrypto_EC_KEY_get0_group(eckey); ++ GO_EC_POINT *pubkey; ++ int ret = 1; ++ ++ pubkey = _goboringcrypto_EC_POINT_new(group); ++ if (!pubkey) ++ return 0; ++ ++ if (_goboringcrypto_EC_POINT_oct2point(group, pubkey, buf, len, ctx) != 1 || ++ _goboringcrypto_EC_KEY_set_public_key(eckey, pubkey) != 1) ++ ret = 0; ++ ++ _goboringcrypto_EC_POINT_free(pubkey); ++ return ret; ++} ++#endif ++ ++// TODO: EC_KEY_check_fips? ++ ++#include ++ ++typedef ECDSA_SIG GO_ECDSA_SIG; ++ ++DEFINEFUNC(GO_ECDSA_SIG *, ECDSA_SIG_new, (void), ()) ++DEFINEFUNC(void, ECDSA_SIG_free, (GO_ECDSA_SIG * arg0), (arg0)) ++DEFINEFUNC(GO_ECDSA_SIG *, ECDSA_do_sign, (const uint8_t *arg0, size_t arg1, const GO_EC_KEY *arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, ECDSA_do_verify, (const uint8_t *arg0, size_t arg1, const GO_ECDSA_SIG *arg2, GO_EC_KEY *arg3), (arg0, arg1, arg2, arg3)) ++DEFINEFUNC(size_t, ECDSA_size, (const GO_EC_KEY *arg0), (arg0)) ++ ++DEFINEFUNCINTERNAL(int, ECDSA_sign, ++ (int type, const unsigned char *dgst, size_t dgstlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey), ++ (type, dgst, dgstlen, sig, siglen, eckey)) ++ ++DEFINEFUNCINTERNAL(int, ECDSA_verify, ++ (int type, const unsigned char *dgst, size_t dgstlen, const unsigned char *sig, unsigned int siglen, EC_KEY *eckey), ++ (type, dgst, dgstlen, sig, siglen, eckey)) ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++DEFINEFUNC(EVP_MD_CTX*, EVP_MD_CTX_create, (void), ()) ++#else ++DEFINEFUNCINTERNAL(EVP_MD_CTX*, EVP_MD_CTX_new, (void), ()) ++static inline EVP_MD_CTX* _goboringcrypto_EVP_MD_CTX_create(void) { ++ return _goboringcrypto_internal_EVP_MD_CTX_new(); ++} ++#endif ++ ++DEFINEFUNCINTERNAL(int, EVP_PKEY_assign, ++ (EVP_PKEY *pkey, int type, void *eckey), ++ (pkey, type, eckey)) ++ ++static inline int ++_goboringcrypto_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, GO_EC_KEY *eckey) { ++ return _goboringcrypto_internal_EVP_PKEY_assign(pkey, EVP_PKEY_EC, (char *)(eckey)); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *rsa) { ++ return _goboringcrypto_internal_EVP_PKEY_assign(pkey, EVP_PKEY_RSA, (char *)(rsa)); ++} ++ ++DEFINEFUNC(int, EVP_DigestSignInit, ++ (EVP_MD_CTX* ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey), ++ (ctx, pctx, type, e, pkey)) ++ ++DEFINEFUNC(int, EVP_DigestUpdate, ++ (EVP_MD_CTX* ctx, const void *d, size_t cnt), ++ (ctx, d, cnt)) ++DEFINEFUNC(int, EVP_DigestSignFinal, ++ (EVP_MD_CTX* ctx, unsigned char *sig, size_t *siglen), ++ (ctx, sig, siglen)) ++ ++DEFINEFUNC(int, EVP_DigestVerifyInit, ++ (EVP_MD_CTX* ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey), ++ (ctx, pctx, type, e, pkey)) ++DEFINEFUNC(int, EVP_DigestVerifyFinal, ++ (EVP_MD_CTX* ctx, const uint8_t *sig, unsigned int siglen), ++ (ctx, sig, siglen)) ++ ++typedef RSA GO_RSA; ++int _goboringcrypto_EVP_sign(EVP_MD* md, EVP_PKEY_CTX *ctx, const uint8_t *msg, size_t msgLen, uint8_t *sig, size_t *slen, EVP_PKEY *eckey); ++int _goboringcrypto_EVP_sign_raw(EVP_MD *md, EVP_PKEY_CTX *ctx, const uint8_t *msg, ++ size_t msgLen, uint8_t *sig, size_t *slen, ++ GO_RSA *key); ++ ++int _goboringcrypto_EVP_verify(EVP_MD* md, EVP_PKEY_CTX *ctx, const uint8_t *msg, size_t msgLen, const uint8_t *sig, unsigned int slen, EVP_PKEY *key); ++int _goboringcrypto_EVP_verify_raw(const uint8_t *msg, size_t msgLen, ++ const uint8_t *sig, unsigned int slen, ++ GO_RSA *key); ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++DEFINEFUNCINTERNAL(void, EVP_MD_CTX_destroy, (EVP_MD_CTX *ctx), (ctx)) ++static inline void _goboringcrypto_EVP_MD_CTX_free(EVP_MD_CTX *ctx) { ++ return _goboringcrypto_internal_EVP_MD_CTX_destroy(ctx); ++} ++#else ++DEFINEFUNC(void, EVP_MD_CTX_free, (EVP_MD_CTX *ctx), (ctx)) ++#endif ++ ++int _goboringcrypto_ECDSA_sign(EVP_MD *md, const uint8_t *arg1, size_t arg2, uint8_t *arg3, size_t *arg4, GO_EC_KEY *arg5); ++int _goboringcrypto_ECDSA_verify(EVP_MD *md, const uint8_t *arg1, size_t arg2, const uint8_t *arg3, unsigned int arg4, GO_EC_KEY *arg5); ++ ++#include ++ ++// Note: order of struct fields here is unchecked. ++typedef BN_GENCB GO_BN_GENCB; ++ ++int _goboringcrypto_EVP_RSA_sign(EVP_MD* md, const uint8_t *msg, unsigned int msgLen, uint8_t *sig, size_t *slen, RSA *rsa); ++int _goboringcrypto_EVP_RSA_verify(EVP_MD* md, const uint8_t *msg, unsigned int msgLen, const uint8_t *sig, unsigned int slen, GO_RSA *rsa); ++ ++DEFINEFUNC(GO_RSA *, RSA_new, (void), ()) ++DEFINEFUNC(void, RSA_free, (GO_RSA * arg0), (arg0)) ++DEFINEFUNC(int, RSA_private_encrypt, ++ (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding), ++ (flen, from, to, rsa, padding)) ++DEFINEFUNC(int, RSA_public_decrypt, ++ (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding), ++ (flen, from, to, rsa, padding)) ++DEFINEFUNC(int, RSA_sign, ++ (int arg0, const uint8_t *arg1, unsigned int arg2, uint8_t *arg3, unsigned int *arg4, GO_RSA *arg5), ++ (arg0, arg1, arg2, arg3, arg4, arg5)) ++DEFINEFUNC(int, RSA_verify, ++ (int arg0, const uint8_t *arg1, unsigned int arg2, const uint8_t *arg3, unsigned int arg4, GO_RSA *arg5), ++ (arg0, arg1, arg2, arg3, arg4, arg5)) ++DEFINEFUNC(int, RSA_generate_key_ex, ++ (GO_RSA * arg0, int arg1, GO_BIGNUM *arg2, GO_BN_GENCB *arg3), ++ (arg0, arg1, arg2, arg3)) ++ ++DEFINEFUNCINTERNAL(int, RSA_set0_factors, ++ (GO_RSA * rsa, GO_BIGNUM *p, GO_BIGNUM *q), ++ (rsa, p, q)) ++ ++static inline int ++_goboringcrypto_RSA_set0_factors(GO_RSA * r, GO_BIGNUM *p, GO_BIGNUM *q) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ /* If the fields p and q in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->p == NULL && p == NULL) ++ || (r->q == NULL && q == NULL)) ++ return 0; ++ ++ if (p != NULL) { ++ _goboringcrypto_BN_clear_free(r->p); ++ r->p = p; ++ } ++ if (q != NULL) { ++ _goboringcrypto_BN_clear_free(r->q); ++ r->q = q; ++ } ++ ++ return 1; ++#else ++ return _goboringcrypto_internal_RSA_set0_factors(r, p, q); ++#endif ++} ++ ++DEFINEFUNCINTERNAL(int, RSA_set0_crt_params, ++ (GO_RSA * rsa, GO_BIGNUM *dmp1, GO_BIGNUM *dmp2, GO_BIGNUM *iqmp), ++ (rsa, dmp1, dmp2, iqmp)) ++ ++static inline int ++_goboringcrypto_RSA_set0_crt_params(GO_RSA * r, GO_BIGNUM *dmp1, GO_BIGNUM *dmq1, GO_BIGNUM *iqmp) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->dmp1 == NULL && dmp1 == NULL) ++ || (r->dmq1 == NULL && dmq1 == NULL) ++ || (r->iqmp == NULL && iqmp == NULL)) ++ return 0; ++ ++ if (dmp1 != NULL) { ++ _goboringcrypto_BN_clear_free(r->dmp1); ++ r->dmp1 = dmp1; ++ } ++ if (dmq1 != NULL) { ++ _goboringcrypto_BN_clear_free(r->dmq1); ++ r->dmq1 = dmq1; ++ } ++ if (iqmp != NULL) { ++ _goboringcrypto_BN_clear_free(r->iqmp); ++ r->iqmp = iqmp; ++ } ++ ++ return 1; ++#else ++ return _goboringcrypto_internal_RSA_set0_crt_params(r, dmp1, dmq1, iqmp); ++#endif ++} ++ ++DEFINEFUNCINTERNAL(void, RSA_get0_crt_params, ++ (const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp), ++ (r, dmp1, dmq1, iqmp)) ++static inline void ++_goboringcrypto_RSA_get0_crt_params(const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ if (dmp1 != NULL) ++ *dmp1 = r->dmp1; ++ if (dmq1 != NULL) ++ *dmq1 = r->dmq1; ++ if (iqmp != NULL) ++ *iqmp = r->iqmp; ++#else ++ _goboringcrypto_internal_RSA_get0_crt_params(r, dmp1, dmq1, iqmp); ++#endif ++} ++ ++ ++DEFINEFUNCINTERNAL(int, RSA_set0_key, ++ (GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d), ++ (r, n, e, d)) ++static inline int ++_goboringcrypto_RSA_set0_key(GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ /* If the fields n and e in r are NULL, the corresponding input ++ * parameters MUST be non-NULL for n and e. d may be ++ * left NULL (in case only the public key is used). ++ */ ++ if ((r->n == NULL && n == NULL) ++ || (r->e == NULL && e == NULL)) ++ return 0; ++ ++ if (n != NULL) { ++ _goboringcrypto_BN_free(r->n); ++ r->n = n; ++ } ++ if (e != NULL) { ++ _goboringcrypto_BN_free(r->e); ++ r->e = e; ++ } ++ if (d != NULL) { ++ _goboringcrypto_BN_clear_free(r->d); ++ r->d = d; ++ } ++ ++ return 1; ++#else ++ return _goboringcrypto_internal_RSA_set0_key(r, n, e, d); ++#endif ++} ++ ++DEFINEFUNCINTERNAL(void, RSA_get0_factors, ++ (const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q), ++ (rsa, p, q)) ++static inline void ++_goboringcrypto_RSA_get0_factors(const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ if (p) ++ *p = rsa->p; ++ if (q) ++ *q = rsa->q; ++#else ++ _goboringcrypto_internal_RSA_get0_factors(rsa, p, q); ++#endif ++} ++ ++DEFINEFUNCINTERNAL(void, RSA_get0_key, ++ (const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d), ++ (rsa, n, e, d)) ++static inline void ++_goboringcrypto_RSA_get0_key(const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ if (n) ++ *n = rsa->n; ++ if (e) ++ *e = rsa->e; ++ if (d) ++ *d = rsa->d; ++#else ++ _goboringcrypto_internal_RSA_get0_key(rsa, n, e, d); ++#endif ++} ++ ++int _goboringcrypto_RSA_generate_key_fips(GO_RSA *, int, GO_BN_GENCB *); ++enum ++{ ++ GO_RSA_PKCS1_PADDING = 1, ++ GO_RSA_NO_PADDING = 3, ++ GO_RSA_PKCS1_OAEP_PADDING = 4, ++ GO_RSA_PKCS1_PSS_PADDING = 6, ++}; ++ ++enum { ++ GO_RSA_PSS_SALTLEN_AUTO = -2, ++ GO_RSA_PSS_SALTLEN_DIGEST = -1, ++}; ++ ++int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *, unsigned int *out_len, uint8_t *out, unsigned int max_out, const uint8_t *in, unsigned int in_len, GO_EVP_MD *md, const GO_EVP_MD *mgf1_md, int salt_len); ++ ++int _goboringcrypto_RSA_verify_pss_mgf1(GO_RSA *, const uint8_t *msg, unsigned int msg_len, GO_EVP_MD *md, const GO_EVP_MD *mgf1_md, int salt_len, const uint8_t *sig, unsigned int sig_len); ++ ++DEFINEFUNC(unsigned int, RSA_size, (const GO_RSA *arg0), (arg0)) ++DEFINEFUNC(int, RSA_check_key, (const GO_RSA *arg0), (arg0)) ++ ++DEFINEFUNC(int, EVP_EncryptInit_ex, ++ (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv), ++ (ctx, type, impl, key, iv)) ++DEFINEFUNC(int, EVP_EncryptUpdate, ++ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), ++ (ctx, out, outl, in, inl)) ++DEFINEFUNC(int, EVP_EncryptFinal_ex, ++ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl), ++ (ctx, out, outl)) ++ ++DEFINEFUNC(int, EVP_DecryptInit_ex, ++ (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv), ++ (ctx, type, impl, key, iv)) ++DEFINEFUNC(int, EVP_DecryptUpdate, ++ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), ++ (ctx, out, outl, in, inl)) ++DEFINEFUNC(int, EVP_DecryptFinal_ex, ++ (EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl), ++ (ctx, outm, outl)) ++ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_gcm, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_cbc, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ctr, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ecb, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_cbc, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ctr, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ecb, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_gcm, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_cbc, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ctr, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ecb, (void), ()) ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_gcm, (void), ()) ++ ++DEFINEFUNC(void, EVP_CIPHER_CTX_free, (EVP_CIPHER_CTX* arg0), (arg0)) ++DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) ++ ++int _goboringcrypto_EVP_CIPHER_CTX_seal( ++ uint8_t *out, uint8_t *nonce, ++ uint8_t *aad, size_t aad_len, ++ uint8_t *plaintext, size_t plaintext_len, ++ size_t *ciphertext_len, uint8_t *key, int key_size); ++ ++int _goboringcrypto_EVP_CIPHER_CTX_open( ++ uint8_t *ciphertext, int ciphertext_len, ++ uint8_t *aad, int aad_len, ++ uint8_t *tag, uint8_t *key, int key_size, ++ uint8_t *nonce, int nonce_len, ++ uint8_t *plaintext, size_t *plaintext_len); ++ ++typedef EVP_PKEY GO_EVP_PKEY; ++ ++DEFINEFUNC(GO_EVP_PKEY *, EVP_PKEY_new, (void), ()) ++DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY * arg0), (arg0)) ++DEFINEFUNC(int, EVP_PKEY_set1_RSA, (GO_EVP_PKEY * arg0, GO_RSA *arg1), (arg0, arg1)) ++DEFINEFUNC(int, EVP_PKEY_set1_EC_KEY, (GO_EVP_PKEY * arg0, GO_EC_KEY *arg1), (arg0, arg1)) ++DEFINEFUNC(int, EVP_PKEY_verify, ++ (EVP_PKEY_CTX *ctx, const unsigned char *sig, unsigned int siglen, const unsigned char *tbs, size_t tbslen), ++ (ctx, sig, siglen, tbs, tbslen)) ++ ++typedef EVP_PKEY_CTX GO_EVP_PKEY_CTX; ++ ++DEFINEFUNC(GO_EVP_PKEY_CTX *, EVP_PKEY_CTX_new, (GO_EVP_PKEY * arg0, ENGINE *arg1), (arg0, arg1)) ++DEFINEFUNC(GO_EVP_PKEY_CTX *, EVP_PKEY_CTX_new_id, (int arg0, ENGINE *arg1), (arg0, arg1)) ++DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX * arg0), (arg0)) ++DEFINEFUNC(int, EVP_PKEY_CTX_ctrl, ++ (EVP_PKEY_CTX * ctx, int keytype, int optype, int cmd, int p1, void *p2), ++ (ctx, keytype, optype, cmd, p1, p2)) ++DEFINEFUNCINTERNAL(int, RSA_pkey_ctx_ctrl, ++ (EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2), ++ (ctx, optype, cmd, p1, p2)) ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(GO_EVP_PKEY_CTX* ctx, int pad) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL); ++#else ++ return _goboringcrypto_internal_RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL); ++#endif ++} ++ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen) ++{ ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l); ++} ++#else ++DEFINEFUNC(int, EVP_PKEY_CTX_set0_rsa_oaep_label, ++ (GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen), ++ (ctx, l, llen)) ++#endif ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(GO_EVP_PKEY_CTX *ctx, const GO_EVP_MD *md) ++{ ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(GO_EVP_PKEY_CTX * arg0, int arg1) { ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(arg0, EVP_PKEY_RSA, ++ (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), ++ EVP_PKEY_CTRL_RSA_PSS_SALTLEN, ++ arg1, NULL); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, (void *)md); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(GO_EVP_PKEY_CTX * ctx, const GO_EVP_MD *md) { ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, ++ EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, ++ EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md); ++} ++ ++DEFINEFUNC(int, EVP_PKEY_decrypt, ++ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, size_t *arg2, const uint8_t *arg3, size_t arg4), ++ (arg0, arg1, arg2, arg3, arg4)) ++DEFINEFUNC(int, EVP_PKEY_encrypt, ++ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, size_t *arg2, const uint8_t *arg3, size_t arg4), ++ (arg0, arg1, arg2, arg3, arg4)) ++DEFINEFUNC(int, EVP_PKEY_decrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) ++DEFINEFUNC(int, EVP_PKEY_encrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) ++DEFINEFUNC(int, EVP_PKEY_sign_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) ++DEFINEFUNC(int, EVP_PKEY_verify_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) ++DEFINEFUNC(int, EVP_PKEY_sign, ++ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, size_t *arg2, const uint8_t *arg3, size_t arg4), ++ (arg0, arg1, arg2, arg3, arg4)) ++ ++DEFINEFUNC(int, EVP_PKEY_derive_init, (GO_EVP_PKEY_CTX *arg0), (arg0)) ++DEFINEFUNC(int, EVP_PKEY_derive, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, size_t *arg2), (arg0, arg1, arg2)) ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++DEFINEFUNC(int, EVP_PKEY_derive_set_peer_ex, (GO_EVP_PKEY_CTX *arg0, GO_EVP_PKEY *arg1, int arg2), (arg0, arg1, arg2)); ++#else ++DEFINEFUNCINTERNAL(int, EVP_PKEY_derive_set_peer, (EVP_PKEY_CTX *ctx, EVP_PKEY *peer), (ctx, peer)) ++# if OPENSSL_VERSION_NUMBER >= 0x10100000L ++DEFINEFUNC(int, EVP_PKEY_public_check, (EVP_PKEY_CTX *arg0), (arg0)) ++ ++static inline int ++_goboringcrypto_EVP_PKEY_derive_set_peer_ex(GO_EVP_PKEY_CTX *ctx, GO_EVP_PKEY *key, int validate) ++{ ++ EVP_PKEY_CTX *check_ctx = _goboringcrypto_EVP_PKEY_CTX_new(key, NULL); ++ if (check_ctx == NULL) { ++ return -1; ++ } ++ int ok = _goboringcrypto_EVP_PKEY_public_check(check_ctx); ++ _goboringcrypto_EVP_PKEY_CTX_free(check_ctx); ++ if (ok != 1) { ++ return -1; ++ } ++ return _goboringcrypto_internal_EVP_PKEY_derive_set_peer(ctx, key); ++} ++# else ++static inline int ++_goboringcrypto_EVP_PKEY_derive_set_peer_ex(GO_EVP_PKEY_CTX *ctx, GO_EVP_PKEY *key, int validate) ++{ ++ /* No way to validate public key in OpenSSL 1.0.2 */ ++ (void)validate; ++ return _goboringcrypto_internal_EVP_PKEY_derive_set_peer(ctx, key); ++} ++# endif ++#endif ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10101000L ++#include ++ ++enum { ++ GO_EVP_PKEY_HKDF = EVP_PKEY_HKDF, ++}; ++ ++enum { ++ GO_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY, ++ GO_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY, ++}; ++ ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++DEFINEFUNC(int, EVP_PKEY_CTX_set_hkdf_mode, (GO_EVP_PKEY_CTX *arg0, int arg1), (arg0, arg1)) ++DEFINEFUNC(int, EVP_PKEY_CTX_set_hkdf_md, (GO_EVP_PKEY_CTX *arg0, const GO_EVP_MD *arg1), (arg0, arg1)) ++DEFINEFUNC(int, EVP_PKEY_CTX_set1_hkdf_salt, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, EVP_PKEY_CTX_set1_hkdf_key, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2), (arg0, arg1, arg2)) ++DEFINEFUNC(int, EVP_PKEY_CTX_add1_hkdf_info, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2), (arg0, arg1, arg2)) ++enum { ++ GO_EVP_PKEY_KEYPAIR = EVP_PKEY_KEYPAIR, ++ GO_EVP_PKEY_PUBLIC_KEY = EVP_PKEY_PUBLIC_KEY, ++}; ++ ++#else ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_hkdf_mode(GO_EVP_PKEY_CTX *pctx, int mode) ++{ ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, ++ EVP_PKEY_CTRL_HKDF_MODE, mode, NULL); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_hkdf_md(GO_EVP_PKEY_CTX *pctx, const GO_EVP_MD *md) ++{ ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, ++ EVP_PKEY_CTRL_HKDF_MD, 0, (void *)(md)); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set1_hkdf_salt(GO_EVP_PKEY_CTX *pctx, unsigned char *salt, int saltlen) ++{ ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, ++ EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)(salt)); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set1_hkdf_key(GO_EVP_PKEY_CTX *pctx, unsigned char *key, int keylen) ++{ ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, ++ EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)(key)); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_add1_hkdf_info(GO_EVP_PKEY_CTX *pctx, unsigned char *info, int infolen) ++{ ++ return _goboringcrypto_EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, ++ EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)(info)); ++} ++// These symbols are not present in older versions of OpenSSL but we define them here ++// to fix compilation errors. ++enum { ++ GO_EVP_PKEY_KEYPAIR, ++ GO_EVP_PKEY_PUBLIC_KEY, ++}; ++ ++#endif ++ ++ ++#else ++ ++/* As HKDF is not supported in earlier OpenSSL versions than 1.1.1 and ++ * fallback implementation cannot be provided in a FIPS compliant ++ * manner, we only provide stub definitions of the above symbols. At ++ * run-time, HKDF operations in hkdf.go (see newHKDF) will return an ++ * error depending on the OpenSSL version. ++ */ ++ ++enum { ++ GO_EVP_PKEY_HKDF, ++}; ++ ++enum { ++ GO_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY, ++ GO_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY, ++}; ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_hkdf_mode(GO_EVP_PKEY_CTX *arg0, int arg1) ++{ ++ return -1; ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_hkdf_md(GO_EVP_PKEY_CTX *arg0, const GO_EVP_MD *arg1) ++{ ++ return -1; ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set1_hkdf_salt(GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2) ++{ ++ return -1; ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set1_hkdf_key(GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2) ++{ ++ return -1; ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_add1_hkdf_info(GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2) ++{ ++ return -1; ++} ++#endif ++ ++enum { ++ GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, ++ GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS = EVP_PKEY_CTRL_RSA_KEYGEN_BITS, ++}; ++ ++DEFINEFUNC(int, EC_POINT_mul, (const GO_EC_GROUP *group, GO_EC_POINT *r, const GO_BIGNUM *n, const GO_EC_POINT *q, const GO_BIGNUM *m, GO_BN_CTX *ctx), (group, r, n, q, m, ctx)) ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++DEFINEFUNC(int, EVP_PKEY_get_bits, (const GO_EVP_PKEY *pkey), (pkey)); ++#else ++DEFINEFUNCINTERNAL(int, EVP_PKEY_bits, (const GO_EVP_PKEY *pkey), (pkey)); ++static int ++_goboringcrypto_EVP_PKEY_get_bits(const GO_EVP_PKEY *pkey) ++{ ++ return _goboringcrypto_internal_EVP_PKEY_bits(pkey); ++} ++#endif ++DEFINEFUNC(int, EVP_PKEY_get_bn_param, (const GO_EVP_PKEY *pkey, const char *key_name, GO_BIGNUM **bn), (pkey, key_name, bn)) ++DEFINEFUNC(int, EVP_PKEY_keygen_init, (GO_EVP_PKEY_CTX *ctx), (ctx)) ++DEFINEFUNC(int, EVP_PKEY_keygen, (GO_EVP_PKEY_CTX *ctx, GO_EVP_PKEY **ppkey), (ctx, ppkey)) ++ ++// This is not used when running against openssl < 3. ++enum { ++ GO_POINT_CONVERSION_UNCOMPRESSED = 4, ++}; ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++DEFINEFUNC(int, EVP_PKEY_set1_encoded_public_key, (GO_EVP_PKEY *pkey, const unsigned char *pub, size_t publen), (pkey, pub, publen)) ++DEFINEFUNC(size_t, EVP_PKEY_get1_encoded_public_key, (GO_EVP_PKEY *pkey, unsigned char **ppub), (pkey, ppub)) ++ ++DEFINEFUNC(const GO_EC_KEY *, EVP_PKEY_get0_EC_KEY, (const GO_EVP_PKEY *pkey), (pkey)) ++#else ++DEFINEFUNCINTERNAL(void *, EVP_PKEY_get0, (const GO_EVP_PKEY *pkey), (pkey)) ++static const GO_EC_KEY * ++_goboringcrypto_EVP_PKEY_get0_EC_KEY(const GO_EVP_PKEY *pkey) ++{ ++ return _goboringcrypto_internal_EVP_PKEY_get0(pkey); ++} ++#endif ++ ++GO_EVP_PKEY *_goboringcrypto_EVP_PKEY_new_for_ecdh(int nid, const uint8_t *bytes, size_t len, int is_private); ++size_t _goboringcrypto_EVP_PKEY_get1_encoded_ecdh_public_key(GO_EVP_PKEY *pkey, unsigned char **result); ++int _goboringcrypto_EVP_PKEY_set_ecdh_public_key_from_private(GO_EVP_PKEY *pkey, int nid); +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/hkdf.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hkdf.go +new file mode 100644 +index 0000000000..2e21224264 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hkdf.go +@@ -0,0 +1,108 @@ ++// 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 && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "hash" ++ "io" ++ "runtime" ++) ++ ++type hkdf struct { ++ ctx *C.GO_EVP_PKEY_CTX ++} ++ ++func SupportsHKDF() bool { ++ return openSSLVersion() >= OPENSSL_VERSION_1_1_1 ++} ++ ++func newHKDF(h func() hash.Hash, mode C.int) (*hkdf, error) { ++ if openSSLVersion() < OPENSSL_VERSION_1_1_1 { ++ return nil, NewOpenSSLError("HKDF is not supported") ++ } ++ ++ ch := h() ++ md := hashToMD(ch) ++ if md == nil { ++ return nil, NewOpenSSLError("Unknown hash algorithm") ++ } ++ ++ ctx := C._goboringcrypto_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil) ++ if ctx == nil { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_new_id failed") ++ } ++ c := &hkdf{ctx: ctx} ++ runtime.SetFinalizer(c, (*hkdf).finalize) ++ defer runtime.KeepAlive(c) ++ ++ if C._goboringcrypto_EVP_PKEY_derive_init(ctx) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_derive_init failed") ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set_hkdf_mode(ctx, mode) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode failed") ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set_hkdf_md(ctx, md) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_set_hkdf_md failed") ++ } ++ ++ return c, nil ++} ++ ++func (c *hkdf) finalize() { ++ if c.ctx != nil { ++ C._goboringcrypto_EVP_PKEY_CTX_free(c.ctx) ++ } ++} ++ ++func (c *hkdf) Read(p []byte) (int, error) { ++ defer runtime.KeepAlive(c) ++ ++ outLen := C.size_t(len(p)) ++ if C._goboringcrypto_EVP_PKEY_derive(c.ctx, base(p), &outLen) != 1 { ++ return 0, NewOpenSSLError("EVP_PKEY_derive failed") ++ } ++ return int(outLen), nil ++} ++ ++func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { ++ c, err := newHKDF(h, C.GO_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) ++ if err != nil { ++ return nil, err ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, base(secret), C.int(len(secret))) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key failed") ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set1_hkdf_salt(c.ctx, base(salt), C.int(len(salt))) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt failed") ++ } ++ var outLen C.size_t ++ if C._goboringcrypto_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_derive_init failed") ++ } ++ out := make([]byte, outLen) ++ if C._goboringcrypto_EVP_PKEY_derive(c.ctx, base(out), &outLen) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_derive failed") ++ } ++ return out[:outLen], nil ++} ++ ++func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) { ++ c, err := newHKDF(h, C.GO_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) ++ if err != nil { ++ return nil, err ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, base(pseudorandomKey), C.int(len(pseudorandomKey))) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key failed") ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_add1_hkdf_info(c.ctx, base(info), C.int(len(info))) != 1 { ++ return nil, NewOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info failed") ++ } ++ return c, nil ++} +diff --git a/src/crypto/internal/boring/hmac.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hmac.go +similarity index 69% +rename from src/crypto/internal/boring/hmac.go +rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/hmac.go +index 6241a65f5f..6f001777ae 100644 +--- a/src/crypto/internal/boring/hmac.go ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hmac.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 && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan ++//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl + +-package boring ++package openssl + +-// #include "goboringcrypto.h" ++// #include "goopenssl.h" + import "C" + import ( +- "bytes" + "crypto" + "hash" + "runtime" +@@ -67,13 +67,25 @@ func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { + return nil + } + +- // Note: Could hash down long keys here using EVP_Digest. +- hkey := bytes.Clone(key) ++ var hkey []byte ++ if key != nil && len(key) > 0 { ++ // Note: Could hash down long keys here using EVP_Digest. ++ hkey = make([]byte, len(key)) ++ copy(hkey, key) ++ } else { ++ // This is supported in BoringSSL/Standard lib and as such ++ // we must support it here. When using HMAC with a null key ++ // HMAC_Init will try and reuse the key from the ctx. This is ++ // not the bahavior previously implemented, so as a workaround ++ // we pass an "empty" key. ++ hkey = make([]byte, C.EVP_MAX_MD_SIZE) ++ } + hmac := &boringHMAC{ + md: md, + size: ch.Size(), + blockSize: ch.BlockSize(), + key: hkey, ++ ctx: C._goboringcrypto_HMAC_CTX_new(), + } + hmac.Reset() + return hmac +@@ -81,8 +93,8 @@ func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { + + type boringHMAC struct { + md *C.GO_EVP_MD +- ctx C.GO_HMAC_CTX +- ctx2 C.GO_HMAC_CTX ++ ctx *C.GO_HMAC_CTX ++ ctx2 *C.GO_HMAC_CTX + size int + blockSize int + key []byte +@@ -91,9 +103,7 @@ type boringHMAC struct { + } + + func (h *boringHMAC) Reset() { +- if h.needCleanup { +- C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx) +- } else { ++ if !h.needCleanup { + h.needCleanup = true + // Note: Because of the finalizer, any time h.ctx is passed to cgo, + // that call must be followed by a call to runtime.KeepAlive(h), +@@ -101,13 +111,13 @@ func (h *boringHMAC) Reset() { + // call returns. + runtime.SetFinalizer(h, (*boringHMAC).finalize) + } +- C._goboringcrypto_HMAC_CTX_init(&h.ctx) ++ C._goboringcrypto_HMAC_CTX_reset(h.ctx) + +- if C._goboringcrypto_HMAC_Init(&h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md) == 0 { ++ if C._goboringcrypto_HMAC_Init_ex(h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md, nil) == 0 { + panic("boringcrypto: HMAC_Init failed") + } +- if int(C._goboringcrypto_HMAC_size(&h.ctx)) != h.size { +- println("boringcrypto: HMAC size:", C._goboringcrypto_HMAC_size(&h.ctx), "!=", h.size) ++ if int(C._goboringcrypto_HMAC_size(h.ctx)) != h.size { ++ println("boringcrypto: HMAC size:", C._goboringcrypto_HMAC_size(h.ctx), "!=", h.size) + panic("boringcrypto: HMAC size mismatch") + } + runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. +@@ -115,12 +125,12 @@ func (h *boringHMAC) Reset() { + } + + func (h *boringHMAC) finalize() { +- C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx) ++ C._goboringcrypto_HMAC_CTX_free(h.ctx) + } + + func (h *boringHMAC) Write(p []byte) (int, error) { + if len(p) > 0 { +- C._goboringcrypto_HMAC_Update(&h.ctx, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p))) ++ C._goboringcrypto_HMAC_Update(h.ctx, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p))) + } + runtime.KeepAlive(h) + return len(p), nil +@@ -143,11 +153,11 @@ func (h *boringHMAC) Sum(in []byte) []byte { + // that Sum has no effect on the underlying stream. + // In particular it is OK to Sum, then Write more, then Sum again, + // and the second Sum acts as if the first didn't happen. +- C._goboringcrypto_HMAC_CTX_init(&h.ctx2) +- if C._goboringcrypto_HMAC_CTX_copy_ex(&h.ctx2, &h.ctx) == 0 { ++ h.ctx2 = C._goboringcrypto_HMAC_CTX_new() ++ if C._goboringcrypto_HMAC_CTX_copy_ex(h.ctx2, h.ctx) == 0 { + panic("boringcrypto: HMAC_CTX_copy_ex failed") + } +- C._goboringcrypto_HMAC_Final(&h.ctx2, (*C.uint8_t)(unsafe.Pointer(&h.sum[0])), nil) +- C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx2) ++ C._goboringcrypto_HMAC_Final(h.ctx2, (*C.uint8_t)(unsafe.Pointer(&h.sum[0])), nil) ++ C._goboringcrypto_HMAC_CTX_free(h.ctx2) + return append(in, h.sum...) + } +diff --git a/src/crypto/internal/boring/notboring.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/notboring.go +similarity index 63% +rename from src/crypto/internal/boring/notboring.go +rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/notboring.go +index 1c5e4c742d..2fa4a38e44 100644 +--- a/src/crypto/internal/boring/notboring.go ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/notboring.go +@@ -2,32 +2,34 @@ + // 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 && !cmd_go_bootstrap && !msan && cgo) ++//go:build !linux || !cgo || android || cmd_go_bootstrap || msan || no_openssl ++// +build !linux !cgo android cmd_go_bootstrap msan no_openssl + +-package boring ++package openssl + + import ( + "crypto" + "crypto/cipher" +- "crypto/internal/boring/sig" + "hash" ++ "io" + ) + +-const available = false ++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") } +@@ -40,16 +42,9 @@ 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") } +-func NewGCMTLS(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") } + + type PublicKeyECDSA struct{ _ int } + type PrivateKeyECDSA struct{ _ int } +@@ -63,17 +58,39 @@ func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error) + func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) { + panic("boringcrypto: not available") + } +-func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { ++func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s BigInt, err error) { + panic("boringcrypto: not available") + } +-func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool { ++func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s BigInt, h crypto.Hash) 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 NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { ++ panic("boringcrypto: not available") ++} ++func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { ++ panic("boringcrypto: not available") ++} ++func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { ++ panic("boringcrypto: not available") ++} ++func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { + panic("boringcrypto: not available") + } + + type PublicKeyRSA struct{ _ int } + type PrivateKeyRSA struct{ _ int } + +-func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { + panic("boringcrypto: not available") + } + func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { +@@ -82,7 +99,7 @@ func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { + func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { + panic("boringcrypto: not available") + } +-func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { + panic("boringcrypto: not available") + } + func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { +@@ -98,25 +115,23 @@ func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error + panic("boringcrypto: not available") + } + func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") } +-func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, msgHashed bool) ([]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 { ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, msgHashed bool) error { + panic("boringcrypto: not available") + } + func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { + panic("boringcrypto: not available") + } + +-type PublicKeyECDH struct{} +-type PrivateKeyECDH struct{} ++func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { ++ panic("boringcrypto: not available") ++} + +-func ECDH(*PrivateKeyECDH, *PublicKeyECDH) ([]byte, error) { panic("boringcrypto: not available") } +-func GenerateKeyECDH(string) (*PrivateKeyECDH, []byte, error) { panic("boringcrypto: not available") } +-func NewPrivateKeyECDH(string, []byte) (*PrivateKeyECDH, error) { panic("boringcrypto: not available") } +-func NewPublicKeyECDH(string, []byte) (*PublicKeyECDH, error) { panic("boringcrypto: not available") } +-func (*PublicKeyECDH) Bytes() []byte { panic("boringcrypto: not available") } +-func (*PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { panic("boringcrypto: not available") } ++func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) { ++ panic("boringcrypto: not available") ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go +new file mode 100644 +index 0000000000..e93b042e5e +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go +@@ -0,0 +1,288 @@ ++// 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 && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl ++ ++package openssl ++ ++/* ++#cgo LDFLAGS: -ldl ++ ++#include "goopenssl.h" ++*/ ++import "C" ++import ( ++ "encoding/binary" ++ "errors" ++ "fmt" ++ "math/bits" ++ "os" ++ "runtime" ++ "unsafe" ++) ++ ++const ( ++ fipsOn = C.int(1) ++ fipsOff = C.int(0) ++) ++ ++const GoStrictFipsEnv = "GOLANG_STRICT_FIPS" ++ ++const ( ++ OPENSSL_VERSION_1_1_0 = uint64(C.ulong(0x10100000)) ++ OPENSSL_VERSION_1_1_1 = uint64(C.ulong(0x10101000)) ++ OPENSSL_VERSION_3_0_0 = uint64(C.ulong(0x30000000)) ++) ++ ++// Enabled controls whether FIPS crypto is enabled. ++var enabled = false ++ ++// When this variable is true, the go crypto API will panic when a caller ++// tries to use the API in a non-compliant manner. When this is false, the ++// go crypto API will allow existing go crypto APIs to be used even ++// if they aren't FIPS compliant. However, all the underlying crypto operations ++// will still be done by OpenSSL. ++var strictFIPS = false ++ ++var nativeEndian binary.ByteOrder ++ ++func init() { ++ runtime.LockOSThread() ++ defer runtime.UnlockOSThread() ++ ++ buf := [2]byte{} ++ *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD) ++ ++ switch buf { ++ case [2]byte{0xCD, 0xAB}: ++ nativeEndian = binary.LittleEndian ++ case [2]byte{0xAB, 0xCD}: ++ nativeEndian = binary.BigEndian ++ default: ++ panic("Could not determine native endianness.") ++ } ++ ++ // Check if we can `dlopen` OpenSSL ++ if C._goboringcrypto_DLOPEN_OPENSSL() == C.NULL { ++ return ++ } ++ ++ // Initialize the OpenSSL library. ++ C._goboringcrypto_OPENSSL_setup() ++ ++ // Check to see if the system is running in FIPS mode, if so ++ // enable "boring" mode to call into OpenSSL for FIPS compliance. ++ if fipsModeEnabled() { ++ enableBoringFIPSMode() ++ } ++} ++ ++func openSSLVersion() uint64 { ++ return uint64(C._goboringcrypto_internal_OPENSSL_VERSION_NUMBER()) ++} ++ ++func enableBoringFIPSMode() { ++ enabled = true ++ ++ if os.Getenv(GoStrictFipsEnv) == "1" { ++ strictFIPS = true ++ } ++ ++ if C._goboringcrypto_OPENSSL_thread_setup() != 1 { ++ panic("boringcrypto: OpenSSL thread setup failed") ++ } ++} ++ ++func fipsModeEnabled() bool { ++ // Due to the way providers work in openssl 3, the FIPS methods are not ++ // necessarily going to be available for us to load based on the GOLANG_FIPS ++ // environment variable alone. For now, we must rely on the config to tell ++ // us if the provider is configured and active. ++ fipsConfigured := C._goboringcrypto_FIPS_mode() == fipsOn ++ openSSLVersion := openSSLVersion() ++ if openSSLVersion >= OPENSSL_VERSION_3_0_0 { ++ if !fipsConfigured && os.Getenv("GOLANG_FIPS") == "1" { ++ panic("GOLANG_FIPS=1 specified but OpenSSL FIPS provider is not configured") ++ } ++ return fipsConfigured ++ ++ } else { ++ return os.Getenv("GOLANG_FIPS") == "1" || fipsConfigured ++ } ++} ++ ++var randstub bool ++ ++func RandStubbed() bool { ++ return randstub ++} ++ ++func StubOpenSSLRand() { ++ if !randstub { ++ randstub = true ++ C._goboringcrypto_stub_openssl_rand() ++ } ++} ++ ++func RestoreOpenSSLRand() { ++ if randstub { ++ randstub = false ++ C._goboringcrypto_restore_openssl_rand() ++ } ++} ++ ++func hasSuffix(s, t string) bool { ++ return len(s) > len(t) && s[len(s)-len(t):] == t ++} ++ ++func PanicIfStrictFIPS(msg string) { ++ if IsStrictFips() { ++ panic(msg) ++ } ++} ++ ++func IsStrictFips() bool { ++ return os.Getenv(GoStrictFipsEnv) == "1" || strictFIPS ++} ++ ++func NewOpenSSLError(msg string) error { ++ var e C.ulong ++ message := fmt.Sprintf("\n%v\nopenssl error(s):", msg) ++ for { ++ var buf [256]C.char ++ var file, fnc, data *C.char ++ var line, flags C.int ++ e = C._goboringcrypto_internal_ERR_get_error_all(&file, &line, &fnc, &data, &flags) ++ if e == 0 { ++ break ++ } ++ ++ C._goboringcrypto_internal_ERR_error_string_n(e, (*C.uchar)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) ++ message = fmt.Sprintf( ++ "%v\nfile: %v\nline: %v\nfunction: %v\nflags: %v\nerror string: %s\n", ++ message, C.GoString(file), line, C.GoString(fnc), flags, C.GoString(&(buf[0]))) ++ ++ } ++ return errors.New(message) ++} ++ ++// Unreachable marks code that should be unreachable ++// when FIPS mode. It panics only when ++// the system is in FIPS mode. ++func Unreachable() { ++ if Enabled() { ++ panic("openssl: invalid code execution") ++ } ++} ++ ++// UnreachableExceptTests marks code that should be unreachable ++// when FIPS mode is active. It panics only when the system is in FIPS mode ++// and not executing under tests. ++func UnreachableExceptTests() { ++ name := os.Args[0] ++ if Enabled() && !ExecutingTest() { ++ println("openssl: unexpected code execution in", name) ++ panic("openssl: 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") ++} ++ ++type fail string ++ ++func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" } ++ ++const wordBytes = bits.UintSize / 8 ++ ++// Reverse each limb of z. ++func (z BigInt) byteSwap() { ++ for i, d := range z { ++ var n uint = 0 ++ for j := 0; j < wordBytes; j++ { ++ n |= uint(byte(d)) << (8 * (wordBytes - j - 1)) ++ d >>= 8 ++ } ++ z[i] = n ++ } ++} ++ ++func wbase(b BigInt) *C.uint8_t { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uint8_t)(unsafe.Pointer(&b[0])) ++} ++ ++func bigToBN(x BigInt) *C.GO_BIGNUM { ++ if nativeEndian == binary.BigEndian { ++ z := make(BigInt, len(x)) ++ copy(z, x) ++ z.byteSwap() ++ x = z ++ } ++ // Limbs are always ordered in LSB first, so we can safely apply ++ // BN_lebin2bn regardless of host endianness. ++ return C._goboringcrypto_BN_lebin2bn(wbase(x), C.int(len(x)*wordBytes), nil) ++} ++ ++func bnToBig(bn *C.GO_BIGNUM) BigInt { ++ x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes) ++ // Limbs are always ordered in LSB first, so we can safely apply ++ // BN_bn2lebinpad regardless of host endianness. ++ if C._goboringcrypto_BN_bn2lebinpad(bn, wbase(x), C.int(len(x)*wordBytes)) == 0 { ++ panic("boringcrypto: bignum conversion failed") ++ } ++ if nativeEndian == binary.BigEndian { ++ x.byteSwap() ++ } ++ return x ++} ++ ++func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool { ++ if *bnp != nil { ++ C._goboringcrypto_BN_free(*bnp) ++ *bnp = nil ++ } ++ if b == nil { ++ return true ++ } ++ bn := bigToBN(b) ++ if bn == nil { ++ return false ++ } ++ *bnp = bn ++ return true ++} ++ ++// noescape hides a pointer from escape analysis. noescape is ++// the identity function but escape analysis doesn't think the ++// output depends on the input. noescape is inlined and currently ++// compiles down to zero instructions. ++// USE CAREFULLY! ++// ++//go:nosplit ++func noescape(p unsafe.Pointer) unsafe.Pointer { ++ x := uintptr(p) ++ return unsafe.Pointer(x ^ 0) ++} ++ ++var zero byte ++ ++// addr converts p to its base addr, including a noescape along the way. ++// If p is nil, addr returns a non-nil pointer, so that the result can always ++// be dereferenced. ++// ++//go:nosplit ++func addr(p []byte) *byte { ++ if len(p) == 0 { ++ return &zero ++ } ++ return (*byte)(noescape(unsafe.Pointer(&p[0]))) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_ecdsa_signature.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_ecdsa_signature.c +new file mode 100644 +index 0000000000..714d18f1e8 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_ecdsa_signature.c +@@ -0,0 +1,46 @@ ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++ ++int _goboringcrypto_ECDSA_sign(EVP_MD *md, const uint8_t *msg, size_t msgLen, ++ uint8_t *sig, size_t *slen, ++ GO_EC_KEY *eckey) { ++ int result; ++ EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); ++ if (!key) { ++ return 0; ++ } ++ if (!_goboringcrypto_EVP_PKEY_set1_EC_KEY(key, eckey)) { ++ result = 0; ++ goto err; ++ } ++ result = _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key); ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; ++} ++ ++int _goboringcrypto_ECDSA_verify(EVP_MD *md, const uint8_t *msg, size_t msgLen, ++ const uint8_t *sig, unsigned int slen, ++ GO_EC_KEY *eckey) { ++ ++ int result; ++ EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); ++ if (!key) { ++ return 0; ++ } ++ if (!_goboringcrypto_EVP_PKEY_set1_EC_KEY(key, eckey)) { ++ result = 0; ++ goto err; ++ } ++ ++ result = _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key); ++ ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_evp.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_evp.c +new file mode 100644 +index 0000000000..24a9615108 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_evp.c +@@ -0,0 +1,140 @@ ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++ ++int _goboringcrypto_EVP_sign(EVP_MD *md, EVP_PKEY_CTX *ctx, const uint8_t *msg, ++ size_t msgLen, uint8_t *sig, size_t *slen, ++ EVP_PKEY *key) { ++ EVP_MD_CTX *mdctx = NULL; ++ int ret = 0; ++ ++ if (!(mdctx = _goboringcrypto_EVP_MD_CTX_create())) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_DigestSignInit(mdctx, &ctx, md, NULL, key)) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_DigestUpdate(mdctx, msg, msgLen)) ++ goto err; ++ ++ /* Obtain the signature length */ ++ if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, NULL, slen)) ++ goto err; ++ /* Obtain the signature */ ++ if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, sig, slen)) ++ goto err; ++ ++ /* Success */ ++ ret = 1; ++ ++err: ++ if (mdctx) ++ _goboringcrypto_EVP_MD_CTX_free(mdctx); ++ ++ return ret; ++} ++ ++int _goboringcrypto_EVP_sign_raw(EVP_MD *md, EVP_PKEY_CTX *ctx, const uint8_t *msg, ++ size_t msgLen, uint8_t *sig, size_t *slen, ++ GO_RSA *rsa_key) { ++ int ret = 0; ++ GO_EVP_PKEY *pk = _goboringcrypto_EVP_PKEY_new(); ++ if (!pk) ++ return 0; ++ ++ if (!(_goboringcrypto_EVP_PKEY_set1_RSA(pk, rsa_key))) ++ goto err; ++ ++ if (!ctx && !(ctx = _goboringcrypto_EVP_PKEY_CTX_new(pk, NULL))) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_PKEY_sign_init(ctx)) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_PKEY_sign(ctx, sig, slen, msg, msgLen)) ++ goto err; ++ ++ /* Success */ ++ ret = 1; ++ ++err: ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (pk) ++ _goboringcrypto_EVP_PKEY_free(pk); ++ ++ return ret; ++} ++ ++int _goboringcrypto_EVP_verify(EVP_MD *md, EVP_PKEY_CTX *ctx, ++ const uint8_t *msg, size_t msgLen, ++ const uint8_t *sig, unsigned int slen, ++ EVP_PKEY *key) { ++ EVP_MD_CTX *mdctx = NULL; ++ int ret = 0; ++ ++ if (!(mdctx = _goboringcrypto_EVP_MD_CTX_create())) ++ goto err; ++ if (1 != _goboringcrypto_EVP_DigestVerifyInit(mdctx, &ctx, md, NULL, key)) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_DigestUpdate(mdctx, msg, msgLen)) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_DigestVerifyFinal(mdctx, sig, slen)) { ++ goto err; ++ } ++ ++ /* Success */ ++ ret = 1; ++ ++err: ++ if (mdctx) ++ _goboringcrypto_EVP_MD_CTX_free(mdctx); ++ ++ return ret; ++} ++ ++int _goboringcrypto_EVP_verify_raw(const uint8_t *msg, size_t msgLen, ++ const uint8_t *sig, unsigned int slen, ++ GO_RSA *rsa_key) { ++ ++ int ret = 0; ++ EVP_PKEY_CTX *ctx; ++ GO_EVP_PKEY *pk = _goboringcrypto_EVP_PKEY_new(); ++ if (!pk) ++ return 0; ++ ++ if (!(_goboringcrypto_EVP_PKEY_set1_RSA(pk, rsa_key))) ++ goto err; ++ ++ if (!(ctx = _goboringcrypto_EVP_PKEY_CTX_new(pk, NULL))) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_PKEY_verify_init(ctx)) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_PKEY_verify(ctx, sig, slen, msg, msgLen)) ++ goto err; ++ ++ /* Success */ ++ ret = 1; ++ ++err: ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (pk) ++ _goboringcrypto_EVP_PKEY_free(pk); ++ ++ return ret; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_lock_setup.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_lock_setup.c +new file mode 100644 +index 0000000000..49d40a7486 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_lock_setup.c +@@ -0,0 +1,49 @@ ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++#include ++#include ++#include ++#include ++#include ++ ++#define _GNU_SOURCE ++#include ++ ++#define MUTEX_TYPE pthread_mutex_t ++#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) ++#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) ++#define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) ++#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) ++#define THREAD_ID pthread_self() ++ ++/* This array will store all of the mutexes available to OpenSSL. */ ++static MUTEX_TYPE *mutex_buf = NULL; ++ ++static void locking_function(int mode, int n, const char *file, int line) { ++ if (mode & CRYPTO_LOCK) ++ MUTEX_LOCK(mutex_buf[n]); ++ else ++ MUTEX_UNLOCK(mutex_buf[n]); ++} ++ ++static unsigned long id_function(void) { ++ return ((unsigned long)syscall(__NR_gettid)); ++} ++ ++int _goboringcrypto_OPENSSL_thread_setup(void) { ++ int i; ++ ++ mutex_buf = malloc(_goboringcrypto_CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); ++ if (!mutex_buf) ++ return 0; ++ for (i = 0; i < _goboringcrypto_CRYPTO_num_locks(); i++) ++ MUTEX_SETUP(mutex_buf[i]); ++ _goboringcrypto_CRYPTO_set_id_callback(id_function); ++ _goboringcrypto_CRYPTO_set_locking_callback(locking_function); ++ return 1; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_aead_gcm.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_aead_gcm.c +new file mode 100644 +index 0000000000..7eb645ef21 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_aead_gcm.c +@@ -0,0 +1,171 @@ ++// This file contains a port of the BoringSSL AEAD interface. ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++#include ++ ++int _goboringcrypto_EVP_CIPHER_CTX_seal(uint8_t *out, uint8_t *iv, uint8_t *aad, ++ size_t aad_len, uint8_t *plaintext, ++ size_t plaintext_len, ++ size_t *ciphertext_len, uint8_t *key, ++ int key_size) { ++ ++ EVP_CIPHER_CTX *ctx; ++ int len; ++ int ret; ++ ++ if (plaintext_len == 0) { ++ plaintext = ""; ++ } ++ ++ if (aad_len == 0) { ++ aad = ""; ++ } ++ ++ // Create and initialise the context. ++ if (!(ctx = _goboringcrypto_EVP_CIPHER_CTX_new())) { ++ goto err; ++ } ++ ++ switch (key_size) { ++ case 128: ++ if (!_goboringcrypto_EVP_EncryptInit_ex( ++ ctx, _goboringcrypto_EVP_aes_128_gcm(), NULL, NULL, NULL)) { ++ goto err; ++ } ++ break; ++ case 256: ++ if (!_goboringcrypto_EVP_EncryptInit_ex( ++ ctx, _goboringcrypto_EVP_aes_256_gcm(), NULL, NULL, NULL)) { ++ goto err; ++ } ++ break; ++ default: ++ goto err; ++ } ++ ++ // Initialize IV. ++ if (!_goboringcrypto_EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL)) { ++ goto err; ++ } ++ if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, ++ 0)) { ++ goto err; ++ } ++ if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, ++ iv)) { ++ goto err; ++ } ++ if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) { ++ goto err; ++ } ++ ++ // Provide AAD data. ++ if (!_goboringcrypto_EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) { ++ goto err; ++ } ++ ++ if (!_goboringcrypto_EVP_EncryptUpdate(ctx, out, &len, plaintext, ++ plaintext_len)) { ++ goto err; ++ } ++ *ciphertext_len = len; ++ ++ if (!_goboringcrypto_EVP_EncryptFinal_ex(ctx, out + len, &len)) { ++ goto err; ++ } ++ *ciphertext_len += len; ++ ++ if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, ++ out + (*ciphertext_len))) { ++ goto err; ++ } ++ *ciphertext_len += 16; ++ ret = 1; ++ ++err: ++ _goboringcrypto_EVP_CIPHER_CTX_free(ctx); ++ ++ if (ret > 0) { ++ return ret; ++ } else { ++ return 0; ++ } ++} ++ ++int _goboringcrypto_EVP_CIPHER_CTX_open(uint8_t *ciphertext, int ciphertext_len, ++ uint8_t *aad, int aad_len, uint8_t *tag, ++ uint8_t *key, int key_size, uint8_t *iv, ++ int iv_len, uint8_t *plaintext, ++ size_t *plaintext_len) { ++ ++ EVP_CIPHER_CTX *ctx; ++ int len; ++ int ret; ++ ++ if (aad_len == 0) { ++ aad = ""; ++ } ++ ++ // Create and initialise the context. ++ if (!(ctx = _goboringcrypto_EVP_CIPHER_CTX_new())) ++ return 0; ++ ++ switch (key_size) { ++ case 128: ++ if (!_goboringcrypto_EVP_DecryptInit_ex( ++ ctx, _goboringcrypto_EVP_aes_128_gcm(), NULL, NULL, NULL)) { ++ goto err; ++ } ++ break; ++ case 256: ++ if (!_goboringcrypto_EVP_DecryptInit_ex( ++ ctx, _goboringcrypto_EVP_aes_256_gcm(), NULL, NULL, NULL)) { ++ goto err; ++ } ++ break; ++ } ++ ++ // Initialize key and nonce. ++ if (!_goboringcrypto_EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) { ++ goto err; ++ } ++ ++ // Provide any AAD data. ++ if (!_goboringcrypto_EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) { ++ goto err; ++ } ++ ++ // Provide the message to be decrypted, and obtain the plaintext output. ++ if (!_goboringcrypto_EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ++ ciphertext_len)) { ++ goto err; ++ } ++ *plaintext_len = len; ++ ++ // Set expected tag value. Works in OpenSSL 1.0.1d and later. ++ if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, ++ tag)) { ++ goto err; ++ } ++ ++ // Finalise the decryption. A positive return value indicates success, ++ // anything else is a failure - the plaintext is not trustworthy. ++ ret = _goboringcrypto_EVP_DecryptFinal_ex(ctx, plaintext + len, &len); ++ ++err: ++ _goboringcrypto_EVP_CIPHER_CTX_free(ctx); ++ ++ if (ret > 0) { ++ // Success ++ *plaintext_len += len; ++ return ret; ++ } else { ++ // Verify failed ++ return 0; ++ } ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c +new file mode 100644 +index 0000000000..df4ebe3297 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c +@@ -0,0 +1,13 @@ ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++ ++void _goboringcrypto_EVP_AES_ctr128_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, ++ uint8_t *out, size_t in_len) { ++ int len; ++ _goboringcrypto_EVP_EncryptUpdate(ctx, out, &len, in, in_len); ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ecdh.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ecdh.c +new file mode 100644 +index 0000000000..8205b040c5 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ecdh.c +@@ -0,0 +1,342 @@ ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++ ++static GO_EC_POINT * ++public_key_from_private(const GO_EC_GROUP *group, const GO_BIGNUM *priv) ++{ ++ // OpenSSL does not expose any method to generate the public ++ // key from the private key [1], so we have to calculate it here. ++ // [1] https://github.com/openssl/openssl/issues/18437#issuecomment-1144717206 ++ GO_EC_POINT *point; ++ ++ point = _goboringcrypto_EC_POINT_new(group); ++ if (!point) ++ return NULL; ++ ++ if (_goboringcrypto_EC_POINT_mul(group, point, priv, NULL, NULL, NULL) != 1) { ++ _goboringcrypto_EC_POINT_free(point); ++ return NULL; ++ } ++ ++ return point; ++} ++ ++static size_t ++encode_point(const GO_EC_GROUP *group, const GO_EC_POINT *point, ++ unsigned char **result) ++{ ++ size_t len; ++ ++ len = _goboringcrypto_EC_POINT_point2oct(group, point, ++ GO_POINT_CONVERSION_UNCOMPRESSED, ++ NULL, 0, NULL); ++ if (!len) ++ return 0; ++ ++ *result = malloc(len); ++ if (!*result) ++ return 0; ++ ++ len = _goboringcrypto_EC_POINT_point2oct(group, point, ++ GO_POINT_CONVERSION_UNCOMPRESSED, ++ *result, len, NULL); ++ if (!len) { ++ free(*result); ++ return 0; ++ } ++ ++ return len; ++} ++ ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++ ++DEFINEFUNCINTERNAL(const char *, OBJ_nid2sn, (int n), (n)) ++DEFINEFUNCINTERNAL(OSSL_PARAM_BLD *, OSSL_PARAM_BLD_new, (void), ()) ++DEFINEFUNCINTERNAL(int, OSSL_PARAM_BLD_push_octet_string, ++ (OSSL_PARAM_BLD *bld, const char *key, const void *buf, size_t bsize), ++ (bld, key, buf, bsize)) ++DEFINEFUNCINTERNAL(int, OSSL_PARAM_BLD_push_utf8_string, ++ (OSSL_PARAM_BLD *bld, const char *key, const char *buf, size_t bsize), ++ (bld, key, buf, bsize)) ++DEFINEFUNCINTERNAL(OSSL_PARAM *, OSSL_PARAM_BLD_to_param, (OSSL_PARAM_BLD *bld), (bld)) ++DEFINEFUNCINTERNAL(void, OSSL_PARAM_BLD_free, (OSSL_PARAM_BLD *bld), (bld)) ++DEFINEFUNCINTERNAL(void, OSSL_PARAM_free, (OSSL_PARAM *params), (params)) ++DEFINEFUNCINTERNAL(int, OSSL_PARAM_BLD_push_BN, ++ (OSSL_PARAM_BLD *bld, const char *key, const BIGNUM *bn), ++ (bld, key, bn)) ++DEFINEFUNCINTERNAL(int, EVP_PKEY_fromdata_init, (GO_EVP_PKEY_CTX *ctx), (ctx)) ++DEFINEFUNCINTERNAL(int, EVP_PKEY_fromdata, (GO_EVP_PKEY_CTX *ctx, GO_EVP_PKEY **pkey, int selection, OSSL_PARAM params[]), (ctx, pkey, selection, params)) ++ ++GO_EVP_PKEY * ++_goboringcrypto_EVP_PKEY_new_for_ecdh(int nid, const uint8_t *bytes, size_t len, int is_private) ++{ ++ OSSL_PARAM_BLD *bld; ++ const char *group_name; ++ OSSL_PARAM *params = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *result = NULL; ++ int selection; ++ ++ /* EVP_PKEY_fromdata in earlier 3.0 releases does not check ++ * that the given point is on the curve. We do that manually ++ * with EC_POINT_oct2point. ++ */ ++ if (!is_private) { ++ EC_GROUP *group; ++ EC_POINT *point; ++ int ok; ++ ++ group = _goboringcrypto_EC_GROUP_new_by_curve_name(nid); ++ if (!group) ++ return NULL; ++ ++ point = _goboringcrypto_EC_POINT_new(group); ++ if (!point) { ++ _goboringcrypto_EC_GROUP_free(group); ++ return NULL; ++ } ++ ++ ok = _goboringcrypto_EC_POINT_oct2point(group, point, bytes, len, NULL); ++ ++ _goboringcrypto_EC_POINT_free(point); ++ _goboringcrypto_EC_GROUP_free(group); ++ ++ if (!ok) ++ return NULL; ++ } ++ ++ bld = _goboringcrypto_internal_OSSL_PARAM_BLD_new(); ++ if (bld == NULL) ++ return NULL; ++ ++ group_name = _goboringcrypto_internal_OBJ_nid2sn(nid); ++ if (!_goboringcrypto_internal_OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, strlen(group_name))) ++ goto err; ++ ++ if (is_private) { ++ BIGNUM *priv; ++ ++ priv = _goboringcrypto_BN_bin2bn(bytes, len, NULL); ++ if (!priv) ++ goto err; ++ ++ if (!_goboringcrypto_internal_OSSL_PARAM_BLD_push_BN(bld, "priv", priv)) { ++ _goboringcrypto_BN_clear_free(priv); ++ goto err; ++ } ++ ++ params = _goboringcrypto_internal_OSSL_PARAM_BLD_to_param(bld); ++ if (!params) { ++ _goboringcrypto_BN_clear_free(priv); ++ goto err; ++ } ++ ++ _goboringcrypto_BN_clear_free(priv); ++ selection = GO_EVP_PKEY_KEYPAIR; ++ } else { ++ if (!_goboringcrypto_internal_OSSL_PARAM_BLD_push_octet_string(bld, "pub", bytes, len)) ++ goto err; ++ ++ params = _goboringcrypto_internal_OSSL_PARAM_BLD_to_param(bld); ++ if (!params) ++ goto err; ++ ++ selection = GO_EVP_PKEY_PUBLIC_KEY; ++ } ++ ++ ctx = _goboringcrypto_EVP_PKEY_CTX_new_id(GO_EVP_PKEY_EC, NULL); ++ if (!ctx) ++ goto err; ++ ++ if (_goboringcrypto_internal_EVP_PKEY_fromdata_init(ctx) != 1) ++ goto err; ++ ++ if (_goboringcrypto_internal_EVP_PKEY_fromdata(ctx, &result, selection, ¶ms[0]) != 1) ++ goto err; ++ ++err: ++ _goboringcrypto_internal_OSSL_PARAM_BLD_free(bld); ++ _goboringcrypto_internal_OSSL_PARAM_free(params); ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ return result; ++} ++ ++DEFINEFUNCINTERNAL(void, CRYPTO_free, (void *addr, const char *file, int line), (addr, file, line)) ++ ++size_t ++_goboringcrypto_EVP_PKEY_get1_encoded_ecdh_public_key(GO_EVP_PKEY *pkey, ++ unsigned char **result) ++{ ++ unsigned char *res; ++ size_t len; ++ ++ len = _goboringcrypto_EVP_PKEY_get1_encoded_public_key(pkey, &res); ++ if (!len) ++ return 0; ++ ++ *result = malloc(len); ++ if (!*result) { ++ _goboringcrypto_internal_CRYPTO_free(res, __FILE__, __LINE__); ++ return 0; ++ } ++ memcpy(*result, res, len); ++ _goboringcrypto_internal_CRYPTO_free(res, __FILE__, __LINE__); ++ return len; ++} ++ ++int ++_goboringcrypto_EVP_PKEY_set_ecdh_public_key_from_private(GO_EVP_PKEY *pkey, int nid) ++{ ++ GO_BIGNUM *priv = NULL; ++ GO_EC_GROUP *group = NULL; ++ GO_EC_POINT *point = NULL; ++ size_t len; ++ unsigned char *pub = NULL; ++ int result = 0; ++ ++ if (_goboringcrypto_EVP_PKEY_get_bn_param(pkey, "priv", &priv) != 1) ++ return 0; ++ ++ group = _goboringcrypto_EC_GROUP_new_by_curve_name(nid); ++ if (!group) ++ goto err; ++ ++ point = public_key_from_private(group, priv); ++ if (!point) ++ goto err; ++ ++ len = encode_point(group, point, &pub); ++ if (!len) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_set1_encoded_public_key(pkey, pub, len) != 1) ++ goto err; ++ ++ result = 1; ++ ++err: ++ _goboringcrypto_EC_GROUP_free(group); ++ _goboringcrypto_EC_POINT_free(point); ++ _goboringcrypto_BN_free(priv); ++ free(pub); ++ return result; ++} ++ ++#else ++ ++GO_EVP_PKEY * ++_goboringcrypto_EVP_PKEY_new_for_ecdh(int nid, const uint8_t *bytes, size_t len, int is_private) ++{ ++ GO_EVP_PKEY *result = NULL; ++ GO_EC_KEY *key = NULL; ++ ++ key = _goboringcrypto_EC_KEY_new_by_curve_name(nid); ++ if (!key) ++ goto err; ++ ++ if (is_private) { ++ BIGNUM *priv; ++ ++ priv = _goboringcrypto_BN_bin2bn(bytes, len, NULL); ++ if (!priv) ++ goto err; ++ if (_goboringcrypto_EC_KEY_set_private_key(key, priv) != 1) { ++ _goboringcrypto_BN_clear_free(priv); ++ goto err; ++ } ++ _goboringcrypto_BN_clear_free(priv); ++ } else { ++ const EC_GROUP *group = _goboringcrypto_EC_KEY_get0_group(key); ++ EC_POINT *pub; ++ ++ pub = _goboringcrypto_EC_POINT_new(group); ++ if (!pub) { ++ goto err; ++ } ++ if (_goboringcrypto_EC_POINT_oct2point(group, pub, bytes, len, NULL) != 1) { ++ _goboringcrypto_EC_POINT_free(pub); ++ goto err; ++ } ++ if (_goboringcrypto_EC_KEY_set_public_key(key, pub) != 1) { ++ _goboringcrypto_EC_POINT_free(pub); ++ goto err; ++ } ++ _goboringcrypto_EC_POINT_free(pub); ++ } ++ ++ result = _goboringcrypto_EVP_PKEY_new(); ++ if (!result) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_assign_EC_KEY(result, key) != 1) { ++ _goboringcrypto_EVP_PKEY_free(result); ++ result = NULL; ++ goto err; ++ } ++ key = NULL; ++ ++err: ++ _goboringcrypto_EC_KEY_free(key); ++ return result; ++} ++ ++size_t ++_goboringcrypto_EVP_PKEY_get1_encoded_ecdh_public_key(GO_EVP_PKEY *pkey, ++ unsigned char **result) ++{ ++ const GO_EC_KEY *key; ++ const GO_EC_POINT *point; ++ const GO_EC_GROUP *group; ++ size_t len; ++ ++ key = _goboringcrypto_EVP_PKEY_get0_EC_KEY(pkey); ++ if (!key) ++ return 0; ++ ++ point = _goboringcrypto_EC_KEY_get0_public_key(key); ++ if (!point) ++ return 0; ++ ++ group = _goboringcrypto_EC_KEY_get0_group(key); ++ if (!group) ++ return 0; ++ ++ return encode_point(group, point, result); ++} ++ ++int ++_goboringcrypto_EVP_PKEY_set_ecdh_public_key_from_private(GO_EVP_PKEY *pkey, int nid) ++{ ++ GO_EC_KEY *key; ++ const GO_BIGNUM *priv; ++ const GO_EC_GROUP *group; ++ GO_EC_POINT *point; ++ ++ key = (GO_EC_KEY *)_goboringcrypto_EVP_PKEY_get0_EC_KEY(pkey); ++ if (!key) ++ return 0; ++ ++ priv = _goboringcrypto_EC_KEY_get0_private_key(key); ++ if (!priv) ++ return 0; ++ ++ group = _goboringcrypto_EC_KEY_get0_group(key); ++ point = public_key_from_private(group, priv); ++ if (!point) ++ return 0; ++ ++ if (_goboringcrypto_EC_KEY_set_public_key(key, point) != 1) { ++ _goboringcrypto_EC_POINT_free(point); ++ return 0; ++ } ++ ++ _goboringcrypto_EC_POINT_free(point); ++ return 1; ++} ++ ++#endif +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_evp_md5_sha1.c +new file mode 100644 +index 0000000000..2eedd5b8c6 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_evp_md5_sha1.c +@@ -0,0 +1,90 @@ ++// This file contains a backport of the EVP_md5_sha1 method. ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++// The following is a partial backport of crypto/evp/m_md5_sha1.c, ++// commit cbc8a839959418d8a2c2e3ec6bdf394852c9501e on the ++// OpenSSL_1_1_0-stable branch. The ctrl function has been removed. ++ ++#include "goopenssl.h" ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++// New in OpenSSL 1.1. ++static inline void * ++_goboringcrypto_internal_EVP_MD_CTX_md_data(EVP_MD_CTX *ctx) { ++ return ctx->md_data; ++} ++ ++/* ++ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ ++#if !defined(OPENSSL_NO_MD5) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct md5_sha1_ctx { ++ MD5_CTX md5; ++ SHA_CTX sha1; ++}; ++ ++static int _goboringcrypto_internal_init(EVP_MD_CTX *ctx) { ++ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); ++ if (!_goboringcrypto_internal_MD5_Init(&mctx->md5)) ++ return 0; ++ return _goboringcrypto_SHA1_Init(&mctx->sha1); ++} ++ ++static int _goboringcrypto_internal_update(EVP_MD_CTX *ctx, const void *data, ++ size_t count) { ++ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); ++ if (!_goboringcrypto_internal_MD5_Update(&mctx->md5, data, count)) ++ return 0; ++ return _goboringcrypto_SHA1_Update(&mctx->sha1, data, count); ++} ++ ++static int _goboringcrypto_internal_final(EVP_MD_CTX *ctx, unsigned char *md) { ++ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); ++ if (!_goboringcrypto_internal_MD5_Final(md, &mctx->md5)) ++ return 0; ++ return _goboringcrypto_SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); ++} ++ ++// Change: Removed: ++// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) ++ ++static const EVP_MD md5_sha1_md = { ++ NID_md5_sha1, ++ NID_md5_sha1, ++ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, ++ 0, ++ _goboringcrypto_internal_init, ++ _goboringcrypto_internal_update, ++ _goboringcrypto_internal_final, ++ NULL, ++ NULL, ++ EVP_PKEY_NULL_method, // Change: inserted ++ MD5_CBLOCK, ++ sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), ++ NULL, // Change: was ctrl ++}; ++ ++// Change: Apply name mangling. ++const GO_EVP_MD *_goboringcrypto_backport_EVP_md5_sha1(void) { ++ return &md5_sha1_md; ++} ++#endif ++#endif +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_hmac.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_hmac.c +new file mode 100644 +index 0000000000..362d9e532e +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_hmac.c +@@ -0,0 +1,16 @@ ++// This file contains HMAC portability wrappers. ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++ ++// Not in OpenSSL 1.1. However, HMAC_CTX_copy expects an initialized ++// target in OpenSSL 1.1. ++int _goboringcrypto_HMAC_CTX_copy_ex(GO_HMAC_CTX *dest, ++ const GO_HMAC_CTX *src) { ++ // HMAC_CTX_copy lacks the const qualifier for the second parameter. ++ return _goboringcrypto_HMAC_CTX_copy(dest, (GO_HMAC_CTX *)src); ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_rsa.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_rsa.c +new file mode 100644 +index 0000000000..bf39656b45 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_rsa.c +@@ -0,0 +1,219 @@ ++// This file contains RSA portability wrappers. ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++ ++// Only in BoringSSL. ++int _goboringcrypto_RSA_generate_key_fips(GO_RSA *rsa, int size, ++ GO_BN_GENCB *cb) { ++ // BoringSSL's RSA_generate_key_fips hard-codes e to 65537. ++ BIGNUM *e = _goboringcrypto_BN_new(); ++ if (e == NULL) ++ return 0; ++ int ret = _goboringcrypto_BN_set_word(e, RSA_F4) && ++ _goboringcrypto_RSA_generate_key_ex(rsa, size, e, cb); ++ _goboringcrypto_BN_free(e); ++ return ret; ++} ++ ++int _goboringcrypto_RSA_digest_and_sign_pss_mgf1( ++ GO_RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, ++ const uint8_t *in, size_t in_len, EVP_MD *md, const EVP_MD *mgf1_md, ++ int salt_len) { ++ EVP_PKEY_CTX *ctx; ++ unsigned int siglen; ++ ++ int ret = 0; ++ EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); ++ if (!key) { ++ goto err; ++ } ++ if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) ++ goto err; ++ ctx = _goboringcrypto_EVP_PKEY_CTX_new(key, NULL /* no engine */); ++ if (!ctx) ++ goto err; ++ ++ EVP_MD_CTX *mdctx = NULL; ++ if (!(mdctx = _goboringcrypto_EVP_MD_CTX_create())) ++ goto err; ++ ++ if (1 != _goboringcrypto_EVP_DigestSignInit(mdctx, &ctx, md, NULL, key)) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, ++ RSA_PKCS1_PSS_PADDING) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) ++ goto err; ++ if (mgf1_md) ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) ++ goto err; ++ if (1 != _goboringcrypto_EVP_DigestUpdate(mdctx, in, in_len)) ++ goto err; ++ ++ /* Obtain the signature length */ ++ if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, NULL, out_len)) ++ goto err; ++ /* Obtain the signature */ ++ if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, out, out_len)) ++ goto err; ++ ++ ret = 1; ++ ++err: ++ if (mdctx) ++ _goboringcrypto_EVP_MD_CTX_free(mdctx); ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (key) ++ _goboringcrypto_EVP_PKEY_free(key); ++ ++ return ret; ++} ++ ++int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_len, ++ uint8_t *out, unsigned int max_out, ++ const uint8_t *in, unsigned int in_len, ++ EVP_MD *md, const EVP_MD *mgf1_md, ++ int salt_len) { ++ EVP_PKEY_CTX *ctx; ++ EVP_PKEY *pkey; ++ size_t siglen; ++ ++ int ret = 0; ++ pkey = _goboringcrypto_EVP_PKEY_new(); ++ if (!pkey) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0) ++ goto err; ++ ++ ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */); ++ if (!ctx) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, ++ RSA_PKCS1_PSS_PADDING) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) ++ goto err; ++ if (mgf1_md) ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) ++ goto err; ++ /* Determine buffer length */ ++ if (_goboringcrypto_EVP_PKEY_sign(ctx, NULL, &siglen, in, in_len) <= 0) ++ goto err; ++ ++ if (max_out < siglen) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_sign(ctx, out, &siglen, in, in_len) <= 0) ++ goto err; ++ ++ *out_len = siglen; ++ ret = 1; ++ ++err: ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (pkey) ++ _goboringcrypto_EVP_PKEY_free(pkey); ++ ++ return ret; ++} ++ ++int _goboringcrypto_RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, ++ unsigned int msg_len, EVP_MD *md, ++ const EVP_MD *mgf1_md, int salt_len, ++ const uint8_t *sig, ++ unsigned int sig_len) { ++ EVP_PKEY_CTX *ctx; ++ EVP_PKEY *pkey; ++ ++ int ret = 0; ++ ++ pkey = _goboringcrypto_EVP_PKEY_new(); ++ if (!pkey) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0) ++ goto err; ++ ++ ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */); ++ if (!ctx) ++ goto err; ++ ++ if (_goboringcrypto_EVP_PKEY_verify_init(ctx) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, ++ RSA_PKCS1_PSS_PADDING) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) ++ goto err; ++ if (mgf1_md) ++ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) ++ goto err; ++ if (_goboringcrypto_EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len) <= 0) ++ goto err; ++ ++ ret = 1; ++ ++err: ++ if (ctx) ++ _goboringcrypto_EVP_PKEY_CTX_free(ctx); ++ if (pkey) ++ _goboringcrypto_EVP_PKEY_free(pkey); ++ ++ return ret; ++} ++ ++int _goboringcrypto_EVP_RSA_sign(EVP_MD *md, const uint8_t *msg, ++ unsigned int msgLen, uint8_t *sig, ++ size_t *slen, RSA *rsa) { ++ int result; ++ EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); ++ if (!key) { ++ return 0; ++ } ++ if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) { ++ result = 0; ++ goto err; ++ } ++ result = _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key); ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; ++} ++ ++int _goboringcrypto_EVP_RSA_verify(EVP_MD *md, const uint8_t *msg, ++ unsigned int msgLen, const uint8_t *sig, ++ unsigned int slen, GO_RSA *rsa) { ++ int result; ++ EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new(); ++ if (!key) { ++ return 0; ++ } ++ if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) { ++ result = 0; ++ goto err; ++ } ++ result = _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key); ++err: ++ _goboringcrypto_EVP_PKEY_free(key); ++ return result; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_stub_rand.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_stub_rand.c +new file mode 100644 +index 0000000000..22bd865a35 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_stub_rand.c +@@ -0,0 +1,45 @@ ++// +build linux ++// +build !android ++// +build !no_openssl ++// +build !cmd_go_bootstrap ++// +build !msan ++ ++#include "goopenssl.h" ++#include ++ ++static RAND_METHOD fake_rand; ++static const RAND_METHOD *old_rand; ++ ++int _goboringcrypto_stub_openssl_rand(void) { ++ /* save old rand method */ ++ if ((old_rand = _goboringcrypto_RAND_get_rand_method()) == NULL) ++ return 0; ++ ++ fake_rand.seed = old_rand->seed; ++ fake_rand.cleanup = old_rand->cleanup; ++ fake_rand.add = old_rand->add; ++ fake_rand.status = old_rand->status; ++ /* use own random function */ ++ fake_rand.bytes = fbytes; ++ fake_rand.pseudorand = old_rand->bytes; ++ /* set new RAND_METHOD */ ++ if (!_goboringcrypto_RAND_set_rand_method(&fake_rand)) ++ return 0; ++ return 1; ++} ++ ++int _goboringcrypto_restore_openssl_rand(void) { ++ if (!_goboringcrypto_RAND_set_rand_method(old_rand)) ++ return 0; ++ else ++ return 1; ++} ++ ++int fbytes(unsigned char *buf, int num) { ++ // return old_rand->bytes(buf, num); ++ int i; ++ for (i = 0; i < num; i++) { ++ buf[i] = 1; ++ } ++ return 1; ++} +diff --git a/src/crypto/internal/boring/rand.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rand.go +similarity index 71% +rename from src/crypto/internal/boring/rand.go +rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/rand.go +index 7639c01909..b3668b8823 100644 +--- a/src/crypto/internal/boring/rand.go ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rand.go +@@ -2,11 +2,12 @@ + // 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 && !cmd_go_bootstrap && !msan ++//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl + +-package boring ++package openssl + +-// #include "goboringcrypto.h" ++// #include "goopenssl.h" + import "C" + import "unsafe" + +@@ -16,7 +17,7 @@ func (randReader) Read(b []byte) (int, error) { + // Note: RAND_bytes should never fail; the return value exists only for historical reasons. + // We check it even so. + if len(b) > 0 && C._goboringcrypto_RAND_bytes((*C.uint8_t)(unsafe.Pointer(&b[0])), C.size_t(len(b))) == 0 { +- return 0, fail("RAND_bytes") ++ return 0, NewOpenSSLError("RAND_bytes") + } + return len(b), nil + } +diff --git a/src/crypto/internal/boring/rsa.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rsa.go +similarity index 52% +rename from src/crypto/internal/boring/rsa.go +rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/rsa.go +index fa693ea319..75ba7a8a59 100644 +--- a/src/crypto/internal/boring/rsa.go ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rsa.go +@@ -2,15 +2,15 @@ + // 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 && !cmd_go_bootstrap && !msan ++//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl + +-package boring ++package openssl + +-// #include "goboringcrypto.h" ++// #include "goopenssl.h" + import "C" + import ( + "crypto" +- "crypto/subtle" + "errors" + "hash" + "runtime" +@@ -25,12 +25,12 @@ func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { + + key := C._goboringcrypto_RSA_new() + if key == nil { +- return bad(fail("RSA_new")) ++ return bad(NewOpenSSLError("RSA_new failed")) + } + defer C._goboringcrypto_RSA_free(key) + + if C._goboringcrypto_RSA_generate_key_fips(key, C.int(bits), nil) == 0 { +- return bad(fail("RSA_generate_key_fips")) ++ return bad(NewOpenSSLError("RSA_generate_key_fips failed")) + } + + var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM +@@ -48,12 +48,12 @@ type PublicKeyRSA struct { + func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { + key := C._goboringcrypto_RSA_new() + if key == nil { +- return nil, fail("RSA_new") +- } +- if !bigToBn(&key.n, N) || +- !bigToBn(&key.e, E) { +- return nil, fail("BN_bin2bn") ++ return nil, NewOpenSSLError("RSA_new failed") + } ++ var n, e *C.GO_BIGNUM ++ n = bigToBN(N) ++ e = bigToBN(E) ++ C._goboringcrypto_RSA_set0_key(key, n, e, nil) + k := &PublicKeyRSA{_key: key} + runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) + return k, nil +@@ -79,17 +79,23 @@ type PrivateKeyRSA struct { + func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) { + key := C._goboringcrypto_RSA_new() + if key == nil { +- return nil, fail("RSA_new") ++ return nil, NewOpenSSLError("RSA_new failed") + } +- if !bigToBn(&key.n, N) || +- !bigToBn(&key.e, E) || +- !bigToBn(&key.d, D) || +- !bigToBn(&key.p, P) || +- !bigToBn(&key.q, Q) || +- !bigToBn(&key.dmp1, Dp) || +- !bigToBn(&key.dmq1, Dq) || +- !bigToBn(&key.iqmp, Qinv) { +- return nil, fail("BN_bin2bn") ++ var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM ++ n = bigToBN(N) ++ e = bigToBN(E) ++ d = bigToBN(D) ++ C._goboringcrypto_RSA_set0_key(key, n, e, d) ++ if P != nil && Q != nil { ++ p = bigToBN(P) ++ q = bigToBN(Q) ++ C._goboringcrypto_RSA_set0_factors(key, p, q) ++ } ++ if Dp != nil && Dq != nil && Qinv != nil { ++ dp = bigToBN(Dp) ++ dq = bigToBN(Dq) ++ qinv = bigToBN(Qinv) ++ C._goboringcrypto_RSA_set0_crt_params(key, dp, dq, qinv) + } + k := &PrivateKeyRSA{_key: key} + runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) +@@ -109,7 +115,7 @@ func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { + } + + func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, +- padding C.int, h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash, ++ padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash, + init func(*C.GO_EVP_PKEY_CTX) C.int) (pkey *C.GO_EVP_PKEY, ctx *C.GO_EVP_PKEY_CTX, err error) { + defer func() { + if err != nil { +@@ -126,7 +132,7 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, + + pkey = C._goboringcrypto_EVP_PKEY_new() + if pkey == nil { +- return nil, nil, fail("EVP_PKEY_new") ++ return nil, nil, NewOpenSSLError("EVP_PKEY_new failed") + } + if withKey(func(key *C.GO_RSA) C.int { + return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key) +@@ -135,43 +141,47 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, + } + ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil) + if ctx == nil { +- return nil, nil, fail("EVP_PKEY_CTX_new") ++ return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_new failed") + } + if init(ctx) == 0 { +- return nil, nil, fail("EVP_PKEY_operation_init") ++ return nil, nil, NewOpenSSLError("EVP_PKEY_operation_init failed") + } + if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 0 { +- return nil, nil, fail("EVP_PKEY_CTX_set_rsa_padding") ++ return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_set_rsa_padding failed") + } + if padding == C.GO_RSA_PKCS1_OAEP_PADDING { + md := hashToMD(h) + if md == nil { + return nil, nil, errors.New("crypto/rsa: unsupported hash function") + } +- mgfMD := hashToMD(mgfHash) +- if mgfMD == nil { +- return nil, nil, errors.New("crypto/rsa: unsupported hash function") +- } + if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) == 0 { +- return nil, nil, fail("EVP_PKEY_set_rsa_oaep_md") +- } +- if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgfMD) == 0 { +- return nil, nil, fail("EVP_PKEY_set_rsa_mgf1_md") ++ return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_oaep_md failed") + } + // ctx takes ownership of label, so malloc a copy for BoringCrypto to free. +- clabel := (*C.uint8_t)(C._goboringcrypto_OPENSSL_malloc(C.size_t(len(label)))) +- if clabel == nil { +- return nil, nil, fail("OPENSSL_malloc") ++ var clabel *C.uint8_t ++ clabel = nil ++ // OpenSSL 1.1.1 does not take ownership of the label if the length is zero. ++ // Depending on the malloc implementation, if clabel is allocated with malloc(0), ++ // metadata for the size-zero allocation is never cleaned up, which is a memory leak. ++ // As such, we must only allocate clabel if the label is of non zero length. ++ if (len(label) > 0) || (openSSLVersion() > OPENSSL_VERSION_3_0_0) { ++ clabel = (*C.uint8_t)(C.malloc(C.size_t(len(label)))) ++ if clabel == nil { ++ return nil, nil, fail("OPENSSL_malloc") ++ } ++ copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) + } +- copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) +- if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.size_t(len(label))) == 0 { +- return nil, nil, fail("EVP_PKEY_CTX_set0_rsa_oaep_label") ++ if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) != 1 { ++ if clabel != nil { ++ C.free(unsafe.Pointer(clabel)) ++ } ++ return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") + } + } + if padding == C.GO_RSA_PKCS1_PSS_PADDING { + if saltLen != 0 { + if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, C.int(saltLen)) == 0 { +- return nil, nil, fail("EVP_PKEY_set_rsa_pss_saltlen") ++ return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_pss_saltlen failed") + } + } + md := cryptoHashToMD(ch) +@@ -179,7 +189,7 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, + return nil, nil, errors.New("crypto/rsa: unsupported hash function") + } + if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) == 0 { +- return nil, nil, fail("EVP_PKEY_set_rsa_mgf1_md") ++ return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_mgf1_md failed") + } + } + +@@ -187,12 +197,12 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, + } + + func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int, +- padding C.int, h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash, ++ padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash, + init func(*C.GO_EVP_PKEY_CTX) C.int, + crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.size_t, *C.uint8_t, C.size_t) C.int, + in []byte) ([]byte, error) { + +- pkey, ctx, err := setupRSA(withKey, padding, h, mgfHash, label, saltLen, ch, init) ++ pkey, ctx, err := setupRSA(withKey, padding, h, label, saltLen, ch, init) + if err != nil { + return nil, err + } +@@ -201,37 +211,37 @@ func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int, + + var outLen C.size_t + if crypt(ctx, nil, &outLen, base(in), C.size_t(len(in))) == 0 { +- return nil, fail("EVP_PKEY_decrypt/encrypt") ++ return nil, NewOpenSSLError("EVP_PKEY_decrypt/encrypt failed") + } + out := make([]byte, outLen) +- if crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))) == 0 { +- return nil, fail("EVP_PKEY_decrypt/encrypt") ++ if crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))) <= 0 { ++ return nil, NewOpenSSLError("EVP_PKEY_decrypt/encrypt failed") + } + return out[:outLen], nil + } + +-func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { +- return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, 0, 0, decryptInit, decrypt, ciphertext) ++func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, decryptInit, decrypt, ciphertext) + } + +-func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { +- return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, 0, 0, encryptInit, encrypt, msg) ++func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, encryptInit, encrypt, msg) + } + + func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { +- return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, 0, 0, decryptInit, decrypt, ciphertext) ++ return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, decryptInit, decrypt, ciphertext) + } + + func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { +- return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, 0, 0, encryptInit, encrypt, msg) ++ return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, encryptInit, encrypt, msg) + } + + func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { +- return cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, 0, 0, decryptInit, decrypt, ciphertext) ++ return cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, decryptInit, decrypt, ciphertext) + } + + func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { +- return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, 0, 0, encryptInit, encrypt, msg) ++ return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, encryptInit, encrypt, msg) + } + + // These dumb wrappers work around the fact that cgo functions cannot be used as values directly. +@@ -252,6 +262,10 @@ func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uin + return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen) + } + ++// These should match crypto/rsa/pss.go ++const saltLengthAuto = 0 ++const saltLengthEqualsHash = -1 ++ + var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative") + + func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { +@@ -259,27 +273,24 @@ func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) + if md == nil { + return nil, errors.New("crypto/rsa: unsupported hash function") + } +- +- // A salt length of -2 is valid in BoringSSL, but not in crypto/rsa, so reject +- // it, and lengths < -2, before we convert to the BoringSSL sentinel values. +- if saltLen <= -2 { +- return nil, invalidSaltLenErr ++ switch saltLen { ++ case saltLengthAuto: ++ saltLen = C.GO_RSA_PSS_SALTLEN_AUTO ++ case saltLengthEqualsHash: ++ saltLen = C.GO_RSA_PSS_SALTLEN_DIGEST ++ default: ++ // If we get here saltLen is either > 0 or < -1, in the ++ // latter case we fail out. ++ if saltLen <= 0 { ++ return nil, invalidSaltLenErr ++ } + } +- +- // BoringSSL uses sentinel salt length values like we do, but the values don't +- // fully match what we use. We both use -1 for salt length equal to hash length, +- // but BoringSSL uses -2 to mean maximal size where we use 0. In the latter +- // case convert to the BoringSSL version. +- if saltLen == 0 { +- saltLen = -2 +- } +- + var out []byte +- var outLen C.size_t ++ var outLen C.uint + if priv.withKey(func(key *C.GO_RSA) C.int { + out = make([]byte, C._goboringcrypto_RSA_size(key)) +- return C._goboringcrypto_RSA_sign_pss_mgf1(key, &outLen, base(out), C.size_t(len(out)), +- base(hashed), C.size_t(len(hashed)), md, nil, C.int(saltLen)) ++ return C._goboringcrypto_RSA_sign_pss_mgf1(key, &outLen, base(out), C.uint(len(out)), ++ base(hashed), C.uint(len(hashed)), md, nil, C.int(saltLen)) + }) == 0 { + return nil, fail("RSA_sign_pss_mgf1") + } +@@ -292,88 +303,133 @@ func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen + if md == nil { + return errors.New("crypto/rsa: unsupported hash function") + } +- +- // A salt length of -2 is valid in BoringSSL, but not in crypto/rsa, so reject +- // it, and lengths < -2, before we convert to the BoringSSL sentinel values. +- if saltLen <= -2 { +- return invalidSaltLenErr ++ switch saltLen { ++ case saltLengthAuto: ++ saltLen = C.GO_RSA_PSS_SALTLEN_AUTO ++ case saltLengthEqualsHash: ++ saltLen = C.GO_RSA_PSS_SALTLEN_DIGEST ++ default: ++ // If we get here saltLen is either > 0 or < -1, in the ++ // latter case we fail out. ++ if saltLen <= 0 { ++ return invalidSaltLenErr ++ } + } +- +- // BoringSSL uses sentinel salt length values like we do, but the values don't +- // fully match what we use. We both use -1 for salt length equal to hash length, +- // but BoringSSL uses -2 to mean maximal size where we use 0. In the latter +- // case convert to the BoringSSL version. +- if saltLen == 0 { +- saltLen = -2 +- } +- + if pub.withKey(func(key *C.GO_RSA) C.int { +- return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.size_t(len(hashed)), +- md, nil, C.int(saltLen), base(sig), C.size_t(len(sig))) ++ return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.uint(len(hashed)), ++ md, nil, C.int(saltLen), base(sig), C.uint(len(sig))) + }) == 0 { + return fail("RSA_verify_pss_mgf1") + } + return nil + } + +-func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { +- if h == 0 { +- // No hashing. ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte, msgIsHashed bool) ([]byte, error) { ++ if h == 0 && ExecutingTest() { ++ return signRSAPKCS1v15Raw(priv, msg, C._goboringcrypto_EVP_md_null()) ++ } ++ ++ md := cryptoHashToMD(h) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h))) ++ } ++ ++ if msgIsHashed { + var out []byte +- var outLen C.size_t ++ var outLen C.uint ++ PanicIfStrictFIPS("You must provide a raw unhashed message for PKCS1v15 signing and use HashSignPKCS1v15 instead of SignPKCS1v15") ++ nid := C._goboringcrypto_EVP_MD_type(md) + if priv.withKey(func(key *C.GO_RSA) C.int { + out = make([]byte, C._goboringcrypto_RSA_size(key)) +- return C._goboringcrypto_RSA_sign_raw(key, &outLen, base(out), C.size_t(len(out)), +- base(hashed), C.size_t(len(hashed)), C.GO_RSA_PKCS1_PADDING) ++ return C._goboringcrypto_RSA_sign(nid, base(msg), C.uint(len(msg)), base(out), &outLen, key) + }) == 0 { +- return nil, fail("RSA_sign_raw") ++ return nil, NewOpenSSLError("RSA_sign") + } ++ runtime.KeepAlive(priv) + return out[:outLen], nil + } + ++ var out []byte ++ var outLen C.size_t ++ ++ if priv.withKey(func(key *C.GO_RSA) C.int { ++ return C._goboringcrypto_EVP_RSA_sign(md, base(msg), C.uint(len(msg)), base(out), &outLen, key) ++ }) == 0 { ++ return nil, NewOpenSSLError("RSA_sign") ++ } ++ return out[:outLen], nil ++} ++ ++func signRSAPKCS1v15Raw(priv *PrivateKeyRSA, msg []byte, md *C.GO_EVP_MD) ([]byte, error) { ++ var out []byte ++ var outLen C.size_t ++ PanicIfStrictFIPS("You must provide a raw unhashed message for PKCS1v15 signing and use HashSignPKCS1v15 instead of SignPKCS1v15") ++ ++ if priv.withKey(func(key *C.GO_RSA) C.int { ++ out = make([]byte, C._goboringcrypto_RSA_size(key)) ++ outLen = C.size_t(len(out)) ++ return C._goboringcrypto_EVP_sign_raw(md, nil, base(msg), ++ C.size_t(len(msg)), base(out), &outLen, key) ++ }) == 0 { ++ return nil, NewOpenSSLError("RSA_sign") ++ } ++ runtime.KeepAlive(priv) ++ return out[:outLen], nil ++} ++ ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte, msgIsHashed bool) error { ++ if h == 0 && ExecutingTest() { ++ return verifyRSAPKCS1v15Raw(pub, msg, sig) ++ } ++ + md := cryptoHashToMD(h) + if md == nil { +- return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h))) ++ return errors.New("crypto/rsa: unsupported hash function") + } +- nid := C._goboringcrypto_EVP_MD_type(md) +- var out []byte +- var outLen C.uint +- if priv.withKey(func(key *C.GO_RSA) C.int { +- out = make([]byte, C._goboringcrypto_RSA_size(key)) +- return C._goboringcrypto_RSA_sign(nid, base(hashed), C.uint(len(hashed)), +- base(out), &outLen, key) ++ ++ if pub.withKey(func(key *C.GO_RSA) C.int { ++ size := int(C._goboringcrypto_RSA_size(key)) ++ if len(sig) < size { ++ return 0 ++ } ++ return 1 + }) == 0 { +- return nil, fail("RSA_sign") ++ return errors.New("crypto/rsa: verification error") + } +- return out[:outLen], nil +-} + +-func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { +- if h == 0 { +- var out []byte +- var outLen C.size_t ++ if msgIsHashed { ++ PanicIfStrictFIPS("You must provide a raw unhashed message for PKCS1v15 verification and use HashVerifyPKCS1v15 instead of VerifyPKCS1v15") ++ nid := C._goboringcrypto_EVP_MD_type(md) + if pub.withKey(func(key *C.GO_RSA) C.int { +- out = make([]byte, C._goboringcrypto_RSA_size(key)) +- return C._goboringcrypto_RSA_verify_raw(key, &outLen, base(out), +- C.size_t(len(out)), base(sig), C.size_t(len(sig)), C.GO_RSA_PKCS1_PADDING) ++ return C._goboringcrypto_RSA_verify(nid, base(msg), C.uint(len(msg)), base(sig), C.uint(len(sig)), key) + }) == 0 { +- return fail("RSA_verify") +- } +- if subtle.ConstantTimeCompare(hashed, out[:outLen]) != 1 { +- return fail("RSA_verify") ++ return NewOpenSSLError("RSA_verify failed") + } + return nil + } +- md := cryptoHashToMD(h) +- if md == nil { +- return errors.New("crypto/rsa: unsupported hash function") ++ ++ if pub.withKey(func(key *C.GO_RSA) C.int { ++ return C._goboringcrypto_EVP_RSA_verify(md, base(msg), C.uint(len(msg)), base(sig), C.uint(len(sig)), key) ++ }) == 0 { ++ return NewOpenSSLError("RSA_verify failed") ++ } ++ return nil ++} ++ ++func verifyRSAPKCS1v15Raw(pub *PublicKeyRSA, msg, sig []byte) error { ++ if pub.withKey(func(key *C.GO_RSA) C.int { ++ size := int(C._goboringcrypto_RSA_size(key)) ++ if len(sig) < size { ++ return 0 ++ } ++ return 1 ++ }) == 0 { ++ return errors.New("crypto/rsa: verification error") + } +- nid := C._goboringcrypto_EVP_MD_type(md) + if pub.withKey(func(key *C.GO_RSA) C.int { +- return C._goboringcrypto_RSA_verify(nid, base(hashed), C.size_t(len(hashed)), +- base(sig), C.size_t(len(sig)), key) ++ return C._goboringcrypto_EVP_verify_raw(base(msg), C.size_t(len(msg)), base(sig), C.uint(len(sig)), key) + }) == 0 { +- return fail("RSA_verify") ++ return NewOpenSSLError("RSA_verify failed") + } + return nil + } +diff --git a/src/crypto/internal/boring/sha.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/sha.go +similarity index 78% +rename from src/crypto/internal/boring/sha.go +rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/sha.go +index cf82f3f64f..0b55cedc91 100644 +--- a/src/crypto/internal/boring/sha.go ++++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/sha.go +@@ -2,12 +2,13 @@ + // 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 && !cmd_go_bootstrap && !msan ++//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl ++// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl + +-package boring ++package openssl + + /* +-#include "goboringcrypto.h" ++#include "goopenssl.h" + + int + _goboringcrypto_gosha1(void *p, size_t n, void *out) +@@ -17,7 +18,6 @@ _goboringcrypto_gosha1(void *p, size_t n, void *out) + return _goboringcrypto_SHA1_Update(&ctx, p, n) && + _goboringcrypto_SHA1_Final(out, &ctx); + } +- + int + _goboringcrypto_gosha224(void *p, size_t n, void *out) + { +@@ -26,7 +26,6 @@ _goboringcrypto_gosha224(void *p, size_t n, void *out) + return _goboringcrypto_SHA224_Update(&ctx, p, n) && + _goboringcrypto_SHA224_Final(out, &ctx); + } +- + int + _goboringcrypto_gosha256(void *p, size_t n, void *out) + { +@@ -35,7 +34,6 @@ _goboringcrypto_gosha256(void *p, size_t n, void *out) + return _goboringcrypto_SHA256_Update(&ctx, p, n) && + _goboringcrypto_SHA256_Final(out, &ctx); + } +- + int + _goboringcrypto_gosha384(void *p, size_t n, void *out) + { +@@ -44,7 +42,6 @@ _goboringcrypto_gosha384(void *p, size_t n, void *out) + return _goboringcrypto_SHA384_Update(&ctx, p, n) && + _goboringcrypto_SHA384_Final(out, &ctx); + } +- + int + _goboringcrypto_gosha512(void *p, size_t n, void *out) + { +@@ -53,7 +50,6 @@ _goboringcrypto_gosha512(void *p, size_t n, void *out) + return _goboringcrypto_SHA512_Update(&ctx, p, n) && + _goboringcrypto_SHA512_Final(out, &ctx); + } +- + */ + import "C" + import ( +@@ -126,31 +122,24 @@ type sha1Ctx struct { + nx uint32 + } + +-func (h *sha1Hash) noescapeCtx() *C.GO_SHA_CTX { +- return (*C.GO_SHA_CTX)(noescape(unsafe.Pointer(&h.ctx))) +-} +- +-func (h *sha1Hash) Reset() { +- C._goboringcrypto_SHA1_Init(h.noescapeCtx()) +-} +- +-func (h *sha1Hash) Size() int { return 20 } +-func (h *sha1Hash) BlockSize() int { return 64 } +-func (h *sha1Hash) Sum(dst []byte) []byte { return h.sum(dst) } ++func (h *sha1Hash) Reset() { C._goboringcrypto_SHA1_Init(&h.ctx) } ++func (h *sha1Hash) Size() int { return 20 } ++func (h *sha1Hash) BlockSize() int { return 64 } ++func (h *sha1Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } + + func (h *sha1Hash) Write(p []byte) (int, error) { +- if len(p) > 0 && C._goboringcrypto_SHA1_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 { ++ if len(p) > 0 && C._goboringcrypto_SHA1_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { + panic("boringcrypto: SHA1_Update failed") + } + return len(p), nil + } + +-func (h0 *sha1Hash) sum(dst []byte) []byte { ++func (h0 *sha1Hash) sum() []byte { + h := *h0 // make copy so future Write+Sum is valid +- if C._goboringcrypto_SHA1_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 { ++ if C._goboringcrypto_SHA1_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { + panic("boringcrypto: SHA1_Final failed") + } +- return append(dst, h.out[:]...) ++ return h.out[:] + } + + const ( +@@ -207,30 +196,24 @@ type sha224Hash struct { + out [224 / 8]byte + } + +-func (h *sha224Hash) noescapeCtx() *C.GO_SHA256_CTX { +- return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx))) +-} +- +-func (h *sha224Hash) Reset() { +- C._goboringcrypto_SHA224_Init(h.noescapeCtx()) +-} +-func (h *sha224Hash) Size() int { return 224 / 8 } +-func (h *sha224Hash) BlockSize() int { return 64 } +-func (h *sha224Hash) Sum(dst []byte) []byte { return h.sum(dst) } ++func (h *sha224Hash) Reset() { C._goboringcrypto_SHA224_Init(&h.ctx) } ++func (h *sha224Hash) Size() int { return 224 / 8 } ++func (h *sha224Hash) BlockSize() int { return 64 } ++func (h *sha224Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } + + func (h *sha224Hash) Write(p []byte) (int, error) { +- if len(p) > 0 && C._goboringcrypto_SHA224_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 { ++ if len(p) > 0 && C._goboringcrypto_SHA224_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { + panic("boringcrypto: SHA224_Update failed") + } + return len(p), nil + } + +-func (h0 *sha224Hash) sum(dst []byte) []byte { ++func (h0 *sha224Hash) sum() []byte { + h := *h0 // make copy so future Write+Sum is valid +- if C._goboringcrypto_SHA224_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 { ++ if C._goboringcrypto_SHA224_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { + panic("boringcrypto: SHA224_Final failed") + } +- return append(dst, h.out[:]...) ++ return h.out[:] + } + + // NewSHA256 returns a new SHA256 hash. +@@ -245,30 +228,24 @@ type sha256Hash struct { + out [256 / 8]byte + } + +-func (h *sha256Hash) noescapeCtx() *C.GO_SHA256_CTX { +- return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx))) +-} +- +-func (h *sha256Hash) Reset() { +- C._goboringcrypto_SHA256_Init(h.noescapeCtx()) +-} +-func (h *sha256Hash) Size() int { return 256 / 8 } +-func (h *sha256Hash) BlockSize() int { return 64 } +-func (h *sha256Hash) Sum(dst []byte) []byte { return h.sum(dst) } ++func (h *sha256Hash) Reset() { C._goboringcrypto_SHA256_Init(&h.ctx) } ++func (h *sha256Hash) Size() int { return 256 / 8 } ++func (h *sha256Hash) BlockSize() int { return 64 } ++func (h *sha256Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } + + func (h *sha256Hash) Write(p []byte) (int, error) { +- if len(p) > 0 && C._goboringcrypto_SHA256_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 { ++ if len(p) > 0 && C._goboringcrypto_SHA256_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { + panic("boringcrypto: SHA256_Update failed") + } + return len(p), nil + } + +-func (h0 *sha256Hash) sum(dst []byte) []byte { ++func (h0 *sha256Hash) sum() []byte { + h := *h0 // make copy so future Write+Sum is valid +- if C._goboringcrypto_SHA256_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 { ++ if C._goboringcrypto_SHA256_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { + panic("boringcrypto: SHA256_Final failed") + } +- return append(dst, h.out[:]...) ++ return h.out[:] + } + + const ( +@@ -382,30 +359,24 @@ type sha384Hash struct { + out [384 / 8]byte + } + +-func (h *sha384Hash) noescapeCtx() *C.GO_SHA512_CTX { +- return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx))) +-} +- +-func (h *sha384Hash) Reset() { +- C._goboringcrypto_SHA384_Init(h.noescapeCtx()) +-} +-func (h *sha384Hash) Size() int { return 384 / 8 } +-func (h *sha384Hash) BlockSize() int { return 128 } +-func (h *sha384Hash) Sum(dst []byte) []byte { return h.sum(dst) } ++func (h *sha384Hash) Reset() { C._goboringcrypto_SHA384_Init(&h.ctx) } ++func (h *sha384Hash) Size() int { return 384 / 8 } ++func (h *sha384Hash) BlockSize() int { return 128 } ++func (h *sha384Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } + + func (h *sha384Hash) Write(p []byte) (int, error) { +- if len(p) > 0 && C._goboringcrypto_SHA384_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 { ++ if len(p) > 0 && C._goboringcrypto_SHA384_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { + panic("boringcrypto: SHA384_Update failed") + } + return len(p), nil + } + +-func (h0 *sha384Hash) sum(dst []byte) []byte { ++func (h0 *sha384Hash) sum() []byte { + h := *h0 // make copy so future Write+Sum is valid +- if C._goboringcrypto_SHA384_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 { ++ if C._goboringcrypto_SHA384_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { + panic("boringcrypto: SHA384_Final failed") + } +- return append(dst, h.out[:]...) ++ return h.out[:] + } + + // NewSHA512 returns a new SHA512 hash. +@@ -420,30 +391,24 @@ type sha512Hash struct { + out [512 / 8]byte + } + +-func (h *sha512Hash) noescapeCtx() *C.GO_SHA512_CTX { +- return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx))) +-} +- +-func (h *sha512Hash) Reset() { +- C._goboringcrypto_SHA512_Init(h.noescapeCtx()) +-} +-func (h *sha512Hash) Size() int { return 512 / 8 } +-func (h *sha512Hash) BlockSize() int { return 128 } +-func (h *sha512Hash) Sum(dst []byte) []byte { return h.sum(dst) } ++func (h *sha512Hash) Reset() { C._goboringcrypto_SHA512_Init(&h.ctx) } ++func (h *sha512Hash) Size() int { return 512 / 8 } ++func (h *sha512Hash) BlockSize() int { return 128 } ++func (h *sha512Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } + + func (h *sha512Hash) Write(p []byte) (int, error) { +- if len(p) > 0 && C._goboringcrypto_SHA512_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 { ++ if len(p) > 0 && C._goboringcrypto_SHA512_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { + panic("boringcrypto: SHA512_Update failed") + } + return len(p), nil + } + +-func (h0 *sha512Hash) sum(dst []byte) []byte { ++func (h0 *sha512Hash) sum() []byte { + h := *h0 // make copy so future Write+Sum is valid +- if C._goboringcrypto_SHA512_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 { ++ if C._goboringcrypto_SHA512_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { + panic("boringcrypto: SHA512_Final failed") + } +- return append(dst, h.out[:]...) ++ return h.out[:] + } + + type sha512Ctx struct { +diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt +index 2b5f965f8f..25143a6ab0 100644 +--- a/src/vendor/modules.txt ++++ b/src/vendor/modules.txt +@@ -1,3 +1,6 @@ ++# github.com/golang-fips/openssl-fips v0.0.0-20230801192317-b175be2ccd46 ++## explicit; go 1.18 ++github.com/golang-fips/openssl-fips/openssl + # golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d + ## explicit; go 1.17 + golang.org/x/crypto/chacha20 \ No newline at end of file diff --git a/go-fips-1.21/002-strict-fips-runtime-detection.patch b/go-fips-1.21/002-strict-fips-runtime-detection.patch new file mode 100644 index 00000000000..df6d0a4198b --- /dev/null +++ b/go-fips-1.21/002-strict-fips-runtime-detection.patch @@ -0,0 +1,152 @@ +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 15c1ee8cbe..efb7555948 100644 +--- a/src/crypto/internal/backend/nobackend.go ++++ b/src/crypto/internal/backend/nobackend.go +@@ -11,12 +11,17 @@ import ( + "crypto" + "crypto/cipher" + "crypto/internal/boring/sig" +- "math/big" +- "github.com/golang-fips/openssl-fips/openssl" + "hash" + "io" ++ "math/big" ++ ++ "github.com/golang-fips/openssl-fips/openssl" + ) + ++func init() { ++ strictFIPSNonCompliantBinaryCheck() ++} ++ + var enabled = false + + // Unreachable marks code that should be unreachable +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 2087c555a4..3e5ee01efc 100644 +--- a/src/crypto/internal/backend/openssl.go ++++ b/src/crypto/internal/backend/openssl.go +@@ -14,6 +14,10 @@ import ( + "github.com/golang-fips/openssl-fips/openssl" + ) + ++func init() { ++ strictFIPSOpenSSLRuntimeCheck() ++} ++ + // Enabled controls whether FIPS crypto is enabled. + var Enabled = openssl.Enabled + +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 { + // CacheProg adds support to cmd/go to use a child process to implement + // the build cache; see https://github.com/golang/go/issues/59719. + CacheProg bool ++ ++ StrictFIPSRuntime bool + } \ No newline at end of file