diff --git a/.gitmodules b/.gitmodules index 0139ca3bce..ca8540f295 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ [submodule "go"] path = go url = https://github.com/golang/go.git - branch = release-branch.go1.20 diff --git a/config/versions.json b/config/versions.json index 1c7ce26c52..ec4b80231b 100644 --- a/config/versions.json +++ b/config/versions.json @@ -1,5 +1,5 @@ { "github.com/golang-fips/go": "main", - "github.com/golang-fips/openssl-fips": "b175be2ccd46683a51cba60a9a2087b09593317d", + "github.com/golang-fips/openssl": "41b6eb24da2819f9ebf7818b82a0da94dc3ae309", "github.com/golang/go": "go1.21.4" -} +} \ No newline at end of file diff --git a/patches/000-initial-setup.patch b/patches/000-initial-setup.patch index 8268a1cc5d..31a7d73a39 100644 --- a/patches/000-initial-setup.patch +++ b/patches/000-initial-setup.patch @@ -1,16 +1,3 @@ -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 @@ -51,105 +38,6 @@ index 10da95afbb..af6bcd86f4 100644 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 @@ -247,50 +135,6 @@ index f933f2800a..223ce04340 100644 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 @@ -366,7 +210,7 @@ index 0000000000..15c1ee8cbe + "crypto/cipher" + "crypto/internal/boring/sig" + "math/big" -+ "github.com/golang-fips/openssl-fips/openssl" ++ bbig "crypto/internal/boring" + "hash" + "io" +) @@ -419,16 +263,16 @@ index 0000000000..15c1ee8cbe +func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { + panic("boringcrypto: not available") +} -+func GenerateKeyECDSA(curve string) (X, Y, D openssl.BigInt, err error) { ++func GenerateKeyECDSA(curve string) (X, Y, D bbig.BigInt, err error) { + panic("boringcrypto: not available") +} -+func NewPrivateKeyECDSA(curve string, X, Y, D openssl.BigInt) (*PrivateKeyECDSA, error) { ++func NewPrivateKeyECDSA(curve string, X, Y, D bbig.BigInt) (*PrivateKeyECDSA, error) { + panic("boringcrypto: not available") +} -+func NewPublicKeyECDSA(curve string, X, Y openssl.BigInt) (*PublicKeyECDSA, error) { ++func NewPublicKeyECDSA(curve string, X, Y bbig.BigInt) (*PublicKeyECDSA, error) { + panic("boringcrypto: not available") +} -+func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s openssl.BigInt, err error) { ++func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s bbig.BigInt, err error) { + panic("boringcrypto: not available") +} +func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { @@ -462,7 +306,7 @@ index 0000000000..15c1ee8cbe +type PublicKeyRSA struct{ _ int } +type PrivateKeyRSA struct{ _ int } + -+func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++func DecryptRSAOAEP(h, h2 hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { @@ -471,7 +315,7 @@ index 0000000000..15c1ee8cbe +func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { + panic("boringcrypto: not available") +} -+func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++func EncryptRSAOAEP(h, h2 hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { @@ -480,20 +324,20 @@ index 0000000000..15c1ee8cbe +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) { ++func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv bbig.BigInt, err error) { + panic("boringcrypto: not available") +} -+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv openssl.BigInt) (*PrivateKeyRSA, error) { ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv bbig.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) { ++func NewPublicKeyRSA(N, E bbig.BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") } ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { + panic("boringcrypto: not available") +} -+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, msgHashed bool) error { ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { + panic("boringcrypto: not available") +} +func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { @@ -520,7 +364,7 @@ new file mode 100644 index 0000000000..2087c555a4 --- /dev/null +++ b/src/crypto/internal/backend/openssl.go -@@ -0,0 +1,106 @@ +@@ -0,0 +1,122 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. @@ -534,11 +378,20 @@ index 0000000000..2087c555a4 +package backend + +import ( -+ "github.com/golang-fips/openssl-fips/openssl" ++ "os" ++ "github.com/golang-fips/openssl/v2" +) + +// Enabled controls whether FIPS crypto is enabled. -+var Enabled = openssl.Enabled ++var enabled bool ++ ++func init() { ++ enabled = openssl.FIPS() ++} ++ ++func Enabled() bool { ++ return enabled ++} + +// Unreachable marks code that should be unreachable +// when OpenSSLCrypto is in use. It panics only when @@ -549,6 +402,13 @@ index 0000000000..2087c555a4 + } +} + ++// ExecutingTest returns a boolean indicating if we're ++// executing under a test binary or not. ++func ExecutingTest() bool { ++ name := os.Args[0] ++ return hasSuffix(name, "_test") || hasSuffix(name, ".test") ++} ++ +// Provided by runtime.crypto_backend_runtime_arg0 to avoid os import. +func runtime_arg0() string + @@ -567,7 +427,7 @@ index 0000000000..2087c555a4 + } +} + -+var ExecutingTest = openssl.ExecutingTest ++ + +const RandReader = openssl.RandReader + @@ -627,6 +487,27 @@ index 0000000000..2087c555a4 +var ExtractHKDF = openssl.ExtractHKDF +var ExpandHKDF = openssl.ExpandHKDF +var SupportsHKDF = openssl.SupportsHKDF +diff --git a/src/crypto/internal/backend/bbig/big.go b/src/crypto/internal/backend/bbig/big.go +new file mode 100644 +index 0000000000..7fac1ec7e1 +--- /dev/null ++++ b/src/crypto/internal/backend/bbig/big.go +@@ -0,0 +1,15 @@ ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++// This is a mirror of ++// https://github.com/golang/go/blob/36b87f273cc43e21685179dc1664ebb5493d26ae/src/crypto/internal/boring/bbig/big.go. ++ ++package bbig ++ ++import ( ++ "github.com/golang-fips/openssl/v2/bbig" ++) ++ ++var Enc = bbig.Enc ++var Dec = bbig.Dec diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go index dfa1eddc88..39a4fc184a 100644 --- a/src/crypto/rsa/pkcs1v15_test.go @@ -862,7 +743,7 @@ index 63bc8dad1a..ab56ccd1ed 100644 return nil, err } - return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label) -+ return boring.EncryptRSAOAEP(hash, bkey, msg, label) ++ return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label) } boring.UnreachableExceptTests() @@ -871,7 +752,7 @@ index 63bc8dad1a..ab56ccd1ed 100644 return nil, err } - out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label) -+ out, err := boring.DecryptRSAOAEP(hash, bkey, ciphertext, label) ++ out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label) if err != nil { return nil, ErrDecryption } @@ -1577,7 +1458,7 @@ index 08452c7b1d..0732db0662 100644 + fmt, crypto/cipher, crypto/internal/boring/bcache < crypto/internal/boring -+ < github.com/golang-fips/openssl-fips/openssl ++ < github.com/golang-fips/openssl/v2 + < crypto/internal/backend < crypto/boring; @@ -1591,7 +1472,7 @@ index 08452c7b1d..0732db0662 100644 # 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 ++ < github.com/golang-fips/openssl/v2/bbig < crypto/internal/boring/bbig + < crypto/internal/backend/bbig < crypto/rand @@ -1601,7 +1482,7 @@ index 08452c7b1d..0732db0662 100644 } func TestDependencies(t *testing.T) { -+ t.Skip("openssl-fips based toolchain has different dependencies than upstream") ++ t.Skip("openssl based toolchain has different dependencies than upstream") if !testenv.HasSrc() { // Tests run in a limited file system and we do not // provide access to every source file. @@ -1619,7 +1500,7 @@ index 08452c7b1d..0732db0662 100644 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" { ++ if pkg == "crypto/internal/boring" || pkg == "github.com/golang-fips/openssl/v2" { haveImport["C"] = true // kludge: prevent C from appearing in crypto/internal/boring imports } fset := token.NewFileSet() diff --git a/patches/001-initial-openssl-for-fips.patch b/patches/001-initial-openssl-for-fips.patch index 36e3861900..b73b5a6542 100644 --- a/patches/001-initial-openssl-for-fips.patch +++ b/patches/001-initial-openssl-for-fips.patch @@ -5,15 +5,15 @@ index f0e3575637..a4139169b8 100644 @@ -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") @@ -31,7 +31,7 @@ index 183c1697c8..abe85b5ad3 100644 + boring "crypto/internal/backend" "strconv" ) - + @@ -38,7 +38,7 @@ func NewCipher(key []byte) (cipher.Block, error) { case 16, 24, 32: break @@ -61,10 +61,10 @@ index 097c37e343..47618fe3c6 100644 @@ -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 @@ -123,7 +123,7 @@ 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" @@ -190,7 +190,7 @@ index 01354fa2cf..a7f1d9eced 100644 +++ b/src/crypto/ecdh/nist.go @@ -5,7 +5,7 @@ package ecdh - + import ( - "crypto/internal/boring" + boring "crypto/internal/backend" @@ -199,7 +199,7 @@ index 01354fa2cf..a7f1d9eced 100644 "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 { @@ -227,12 +227,12 @@ index 01354fa2cf..a7f1d9eced 100644 @@ -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 @@ -240,12 +240,12 @@ index 275c60b4de..58f0034b18 100644 @@ -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" @@ -272,7 +272,7 @@ index e1503779ae..00953a453a 100644 @@ -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) @@ -281,7 +281,7 @@ index e1503779ae..00953a453a 100644 @@ -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) @@ -296,59 +296,6 @@ index e1503779ae..00953a453a 100644 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 @@ -381,7 +328,7 @@ index 61a4662036..80e484842b 100644 } curve := test.curve @@ -246,7 +246,7 @@ func TestVectors(t *testing.T) { - + switch curve { case "P-224": - if !boring.Enabled || boringtest.Supports(t, "CurveP224") { @@ -418,15 +365,15 @@ index 039bd82ed2..21a35b760c 100644 @@ -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") @@ -449,7 +396,7 @@ index 8b5c2cc9af..ebbb1c0c07 100644 "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 { @@ -463,7 +410,7 @@ index 35b9d5a17a..5697756a27 100644 +++ b/src/crypto/hmac/hmac.go @@ -22,7 +22,7 @@ timing side-channels: package hmac - + import ( - "crypto/internal/boring" + boring "crypto/internal/backend" @@ -484,7 +431,7 @@ 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" @@ -494,7 +441,7 @@ index 55415abf02..0edd7a6003 100644 "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") @@ -894,45 +841,6 @@ index 6fae1d54f8..0000000000 - } - 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 @@ -1106,30 +1014,26 @@ index 83bbbd3404..0000000000 - UnreachableExceptTests() -} diff --git a/src/crypto/internal/boring/doc.go b/src/crypto/internal/boring/doc.go -deleted file mode 100644 -index 6060fe5951..0000000000 +index 6060fe5951..ca24813149 100644 --- 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 -- ++++ b/src/crypto/internal/boring/doc.go +@@ -7,13 +7,10 @@ + // 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. ++import "github.com/golang-fips/openssl/v2" + + // A BigInt is the raw words from a BigInt. + // This definition allows us to avoid importing math/big. + // Conversion between BigInt and *big.Int is in crypto/internal/boring/bbig. -type BigInt []uint ++type BigInt = openssl.BigInt ++ diff --git a/src/crypto/internal/boring/ecdh.go b/src/crypto/internal/boring/ecdh.go deleted file mode 100644 index 8f46d8146f..0000000000 @@ -1360,6 +1264,184 @@ index 8f46d8146f..0000000000 - runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) - return k, bytes, nil -} +diff --git a/src/crypto/internal/boring/ecdsa.go b/src/crypto/internal/boring/ecdsa.go +deleted file mode 100644 +index e15f3682c7..0000000000 +--- a/src/crypto/internal/boring/ecdsa.go ++++ /dev/null +@@ -1,172 +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" +-import "C" +-import ( +- "errors" +- "runtime" +-) +- +-type ecdsaSignature struct { +- R, S BigInt +-} +- +-type PrivateKeyECDSA struct { +- key *C.GO_EC_KEY +-} +- +-func (k *PrivateKeyECDSA) finalize() { +- C._goboringcrypto_EC_KEY_free(k.key) +-} +- +-type PublicKeyECDSA struct { +- key *C.GO_EC_KEY +-} +- +-func (k *PublicKeyECDSA) finalize() { +- C._goboringcrypto_EC_KEY_free(k.key) +-} +- +-var errUnknownCurve = errors.New("boringcrypto: unknown elliptic curve") +- +-func curveNID(curve string) (C.int, error) { +- switch curve { +- case "P-224": +- return C.GO_NID_secp224r1, nil +- case "P-256": +- return C.GO_NID_X9_62_prime256v1, nil +- case "P-384": +- return C.GO_NID_secp384r1, nil +- case "P-521": +- return C.GO_NID_secp521r1, nil +- } +- return 0, errUnknownCurve +-} +- +-func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) { +- key, err := newECKey(curve, X, Y) +- if err != nil { +- return nil, err +- } +- k := &PublicKeyECDSA{key} +- // 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, (*PublicKeyECDSA).finalize) +- return k, nil +-} +- +-func newECKey(curve string, X, Y BigInt) (*C.GO_EC_KEY, 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") +- } +- 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") +- } +- bx := bigToBN(X) +- by := bigToBN(Y) +- ok := bx != nil && by != nil && C._goboringcrypto_EC_POINT_set_affine_coordinates_GFp(group, pt, bx, by, nil) != 0 && +- C._goboringcrypto_EC_KEY_set_public_key(key, pt) != 0 +- if bx != nil { +- C._goboringcrypto_BN_free(bx) +- } +- if by != nil { +- C._goboringcrypto_BN_free(by) +- } +- C._goboringcrypto_EC_POINT_free(pt) +- if !ok { +- C._goboringcrypto_EC_KEY_free(key) +- return nil, fail("EC_POINT_set_affine_coordinates_GFp") +- } +- return key, nil +-} +- +-func NewPrivateKeyECDSA(curve string, X, Y BigInt, D BigInt) (*PrivateKeyECDSA, error) { +- key, err := newECKey(curve, X, Y) +- if err != nil { +- return nil, err +- } +- bd := bigToBN(D) +- ok := bd != nil && C._goboringcrypto_EC_KEY_set_private_key(key, bd) != 0 +- if bd != nil { +- C._goboringcrypto_BN_free(bd) +- } +- if !ok { +- C._goboringcrypto_EC_KEY_free(key) +- return nil, fail("EC_KEY_set_private_key") +- } +- k := &PrivateKeyECDSA{key} +- // 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, (*PrivateKeyECDSA).finalize) +- return k, 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") +- } +- 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 +- runtime.KeepAlive(pub) +- return ok +-} +- +-func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) { +- nid, err := curveNID(curve) +- if err != nil { +- return nil, nil, nil, err +- } +- key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) +- if key == nil { +- return nil, nil, nil, fail("EC_KEY_new_by_curve_name") +- } +- 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") +- } +- 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") +- } +- bx := C._goboringcrypto_BN_new() +- if bx == nil { +- return nil, nil, nil, fail("BN_new") +- } +- defer C._goboringcrypto_BN_free(bx) +- by := C._goboringcrypto_BN_new() +- if by == nil { +- return nil, nil, nil, fail("BN_new") +- } +- 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 bnToBig(bx), bnToBig(by), bnToBig(bd), nil +-} diff --git a/src/crypto/internal/boring/fipstls/stub.s b/src/crypto/internal/boring/fipstls/stub.s index f2e5a503ea..65918a480e 100644 --- a/src/crypto/internal/boring/fipstls/stub.s @@ -1367,10 +1449,10 @@ index f2e5a503ea..65918a480e 100644 @@ -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 @@ -1380,113 +1462,1420 @@ index 3bf1471fb0..d6c5ca736d 100644 @@ -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" + +diff --git a/src/crypto/internal/boring/hmac.go b/src/crypto/internal/boring/hmac.go +deleted file mode 100644 +index 6241a65f5f..0000000000 +--- a/src/crypto/internal/boring/hmac.go ++++ /dev/null +@@ -1,153 +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" +-import "C" +-import ( +- "bytes" +- "crypto" +- "hash" +- "runtime" +- "unsafe" +-) +- +-// hashToMD converts a hash.Hash implementation from this package +-// to a BoringCrypto *C.GO_EVP_MD. +-func hashToMD(h hash.Hash) *C.GO_EVP_MD { +- switch h.(type) { +- case *sha1Hash: +- return C._goboringcrypto_EVP_sha1() +- case *sha224Hash: +- return C._goboringcrypto_EVP_sha224() +- case *sha256Hash: +- return C._goboringcrypto_EVP_sha256() +- case *sha384Hash: +- return C._goboringcrypto_EVP_sha384() +- case *sha512Hash: +- return C._goboringcrypto_EVP_sha512() +- } +- return nil +-} +- +-// cryptoHashToMD converts a crypto.Hash +-// to a BoringCrypto *C.GO_EVP_MD. +-func cryptoHashToMD(ch crypto.Hash) *C.GO_EVP_MD { +- switch ch { +- case crypto.MD5: +- return C._goboringcrypto_EVP_md5() +- case crypto.MD5SHA1: +- return C._goboringcrypto_EVP_md5_sha1() +- case crypto.SHA1: +- return C._goboringcrypto_EVP_sha1() +- case crypto.SHA224: +- return C._goboringcrypto_EVP_sha224() +- case crypto.SHA256: +- return C._goboringcrypto_EVP_sha256() +- case crypto.SHA384: +- return C._goboringcrypto_EVP_sha384() +- case crypto.SHA512: +- return C._goboringcrypto_EVP_sha512() +- } +- return nil +-} +- +-// NewHMAC returns a new HMAC using BoringCrypto. +-// The function h must return a hash implemented by +-// BoringCrypto (for example, h could be boring.NewSHA256). +-// If h is not recognized, NewHMAC returns nil. +-func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { +- ch := h() +- md := hashToMD(ch) +- if md == nil { +- return nil +- } +- +- // Note: Could hash down long keys here using EVP_Digest. +- hkey := bytes.Clone(key) +- hmac := &boringHMAC{ +- md: md, +- size: ch.Size(), +- blockSize: ch.BlockSize(), +- key: hkey, +- } +- hmac.Reset() +- return hmac +-} +- +-type boringHMAC struct { +- md *C.GO_EVP_MD +- ctx C.GO_HMAC_CTX +- ctx2 C.GO_HMAC_CTX +- size int +- blockSize int +- key []byte +- sum []byte +- needCleanup bool +-} +- +-func (h *boringHMAC) Reset() { +- if h.needCleanup { +- C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx) +- } else { +- 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), +- // to make sure h is not collected (and finalized) before the cgo +- // call returns. +- runtime.SetFinalizer(h, (*boringHMAC).finalize) +- } +- C._goboringcrypto_HMAC_CTX_init(&h.ctx) +- +- if C._goboringcrypto_HMAC_Init(&h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md) == 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) +- panic("boringcrypto: HMAC size mismatch") +- } +- runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. +- h.sum = nil +-} +- +-func (h *boringHMAC) finalize() { +- C._goboringcrypto_HMAC_CTX_cleanup(&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))) +- } +- runtime.KeepAlive(h) +- return len(p), nil +-} +- +-func (h *boringHMAC) Size() int { +- return h.size +-} +- +-func (h *boringHMAC) BlockSize() int { +- return h.blockSize +-} +- +-func (h *boringHMAC) Sum(in []byte) []byte { +- if h.sum == nil { +- size := h.Size() +- h.sum = make([]byte, size) +- } +- // Make copy of context because Go hash.Hash mandates +- // 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 { +- 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) +- return append(in, h.sum...) +-} +diff --git a/src/crypto/internal/boring/notboring.go b/src/crypto/internal/boring/notboring.go +deleted file mode 100644 +index 1c5e4c742d..0000000000 +--- a/src/crypto/internal/boring/notboring.go ++++ /dev/null +@@ -1,122 +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 && cgo) +- +-package boring +- +-import ( +- "crypto" +- "crypto/cipher" +- "crypto/internal/boring/sig" +- "hash" +-) +- +-const available = 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() {} +- +-type randReader int +- +-func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not available") } +- +-const RandReader = randReader(0) +- +-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") } +-func NewGCMTLS(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") } +- +-type PublicKeyECDSA struct{ _ int } +-type PrivateKeyECDSA struct{ _ int } +- +-func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) { +- panic("boringcrypto: not available") +-} +-func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error) { +- panic("boringcrypto: not available") +-} +-func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) { +- panic("boringcrypto: not available") +-} +-func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { +- panic("boringcrypto: not available") +-} +-func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool { +- 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) { +- 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, mgfHash 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 BigInt, err error) { +- panic("boringcrypto: not available") +-} +-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) { +- panic("boringcrypto: not available") +-} +-func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { +- panic("boringcrypto: not available") +-} +-func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { +- panic("boringcrypto: not available") +-} +-func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { +- panic("boringcrypto: not available") +-} +- +-type PublicKeyECDH struct{} +-type PrivateKeyECDH struct{} +- +-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") } +diff --git a/src/crypto/internal/boring/rand.go b/src/crypto/internal/boring/rand.go +deleted file mode 100644 +index 7639c01909..0000000000 +--- a/src/crypto/internal/boring/rand.go ++++ /dev/null +@@ -1,24 +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" +-import "C" +-import "unsafe" +- +-type randReader int +- +-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 len(b), nil +-} +- +-const RandReader = randReader(0) +diff --git a/src/crypto/internal/boring/rsa.go b/src/crypto/internal/boring/rsa.go +deleted file mode 100644 +index fa693ea319..0000000000 +--- a/src/crypto/internal/boring/rsa.go ++++ /dev/null +@@ -1,379 +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" +-import "C" +-import ( +- "crypto" +- "crypto/subtle" +- "errors" +- "hash" +- "runtime" +- "strconv" +- "unsafe" +-) +- +-func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { +- bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { +- return nil, nil, nil, nil, nil, nil, nil, nil, e +- } +- +- key := C._goboringcrypto_RSA_new() +- if key == nil { +- return bad(fail("RSA_new")) +- } +- 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")) +- } +- +- var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM +- C._goboringcrypto_RSA_get0_key(key, &n, &e, &d) +- C._goboringcrypto_RSA_get0_factors(key, &p, &q) +- C._goboringcrypto_RSA_get0_crt_params(key, &dp, &dq, &qinv) +- return bnToBig(n), bnToBig(e), bnToBig(d), bnToBig(p), bnToBig(q), bnToBig(dp), bnToBig(dq), bnToBig(qinv), nil +-} +- +-type PublicKeyRSA struct { +- // _key MUST NOT be accessed directly. Instead, use the withKey method. +- _key *C.GO_RSA +-} +- +-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") +- } +- k := &PublicKeyRSA{_key: key} +- runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) +- return k, nil +-} +- +-func (k *PublicKeyRSA) finalize() { +- C._goboringcrypto_RSA_free(k._key) +-} +- +-func (k *PublicKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { +- // Because of the finalizer, any time _key is passed to cgo, that call must +- // be followed by a call to runtime.KeepAlive, to make sure k is not +- // collected (and finalized) before the cgo call returns. +- defer runtime.KeepAlive(k) +- return f(k._key) +-} +- +-type PrivateKeyRSA struct { +- // _key MUST NOT be accessed directly. Instead, use the withKey method. +- _key *C.GO_RSA +-} +- +-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") +- } +- 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") +- } +- k := &PrivateKeyRSA{_key: key} +- runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) +- return k, nil +-} +- +-func (k *PrivateKeyRSA) finalize() { +- C._goboringcrypto_RSA_free(k._key) +-} +- +-func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { +- // Because of the finalizer, any time _key is passed to cgo, that call must +- // be followed by a call to runtime.KeepAlive, to make sure k is not +- // collected (and finalized) before the cgo call returns. +- defer runtime.KeepAlive(k) +- return f(k._key) +-} +- +-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, +- 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 { +- if pkey != nil { +- C._goboringcrypto_EVP_PKEY_free(pkey) +- pkey = nil +- } +- if ctx != nil { +- C._goboringcrypto_EVP_PKEY_CTX_free(ctx) +- ctx = nil +- } +- } +- }() +- +- pkey = C._goboringcrypto_EVP_PKEY_new() +- if pkey == nil { +- return nil, nil, fail("EVP_PKEY_new") +- } +- if withKey(func(key *C.GO_RSA) C.int { +- return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key) +- }) == 0 { +- return nil, nil, fail("EVP_PKEY_set1_RSA") +- } +- ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil) +- if ctx == nil { +- return nil, nil, fail("EVP_PKEY_CTX_new") +- } +- if init(ctx) == 0 { +- return nil, nil, fail("EVP_PKEY_operation_init") +- } +- if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 0 { +- return nil, nil, fail("EVP_PKEY_CTX_set_rsa_padding") +- } +- 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") +- } +- // 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") +- } +- 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 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") +- } +- } +- md := cryptoHashToMD(ch) +- if md == nil { +- 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 pkey, ctx, nil +-} +- +-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, +- 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) +- if err != nil { +- return nil, err +- } +- defer C._goboringcrypto_EVP_PKEY_free(pkey) +- defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx) +- +- 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") +- } +- 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") +- } +- 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 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 DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { +- return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, 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) +-} +- +-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) +-} +- +-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) +-} +- +-// These dumb wrappers work around the fact that cgo functions cannot be used as values directly. +- +-func decryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int { +- return C._goboringcrypto_EVP_PKEY_decrypt_init(ctx) +-} +- +-func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int { +- return C._goboringcrypto_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen) +-} +- +-func encryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int { +- return C._goboringcrypto_EVP_PKEY_encrypt_init(ctx) +-} +- +-func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int { +- return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen) +-} +- +-var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative") +- +-func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { +- md := cryptoHashToMD(h) +- 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 +- } +- +- // 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 +- 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)) +- }) == 0 { +- return nil, fail("RSA_sign_pss_mgf1") +- } +- +- return out[:outLen], nil +-} +- +-func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { +- md := cryptoHashToMD(h) +- 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 +- } +- +- // 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))) +- }) == 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. +- var out []byte +- var outLen C.size_t +- 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) +- }) == 0 { +- return nil, fail("RSA_sign_raw") +- } +- return out[:outLen], nil +- } +- +- md := cryptoHashToMD(h) +- if md == nil { +- return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h))) +- } +- 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) +- }) == 0 { +- return nil, fail("RSA_sign") +- } +- 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 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) +- }) == 0 { +- return fail("RSA_verify") +- } +- if subtle.ConstantTimeCompare(hashed, out[:outLen]) != 1 { +- return fail("RSA_verify") +- } +- return nil +- } +- md := cryptoHashToMD(h) +- if md == nil { +- return errors.New("crypto/rsa: unsupported hash function") +- } +- 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) +- }) == 0 { +- return fail("RSA_verify") +- } +- return nil +-} +diff --git a/src/crypto/internal/boring/sha.go b/src/crypto/internal/boring/sha.go +deleted file mode 100644 +index cf82f3f64f..0000000000 +--- a/src/crypto/internal/boring/sha.go ++++ /dev/null +@@ -1,599 +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" +- +-int +-_goboringcrypto_gosha1(void *p, size_t n, void *out) +-{ +- GO_SHA_CTX ctx; +- _goboringcrypto_SHA1_Init(&ctx); +- return _goboringcrypto_SHA1_Update(&ctx, p, n) && +- _goboringcrypto_SHA1_Final(out, &ctx); +-} +- +-int +-_goboringcrypto_gosha224(void *p, size_t n, void *out) +-{ +- GO_SHA256_CTX ctx; +- _goboringcrypto_SHA224_Init(&ctx); +- return _goboringcrypto_SHA224_Update(&ctx, p, n) && +- _goboringcrypto_SHA224_Final(out, &ctx); +-} +- +-int +-_goboringcrypto_gosha256(void *p, size_t n, void *out) +-{ +- GO_SHA256_CTX ctx; +- _goboringcrypto_SHA256_Init(&ctx); +- return _goboringcrypto_SHA256_Update(&ctx, p, n) && +- _goboringcrypto_SHA256_Final(out, &ctx); +-} +- +-int +-_goboringcrypto_gosha384(void *p, size_t n, void *out) +-{ +- GO_SHA512_CTX ctx; +- _goboringcrypto_SHA384_Init(&ctx); +- return _goboringcrypto_SHA384_Update(&ctx, p, n) && +- _goboringcrypto_SHA384_Final(out, &ctx); +-} +- +-int +-_goboringcrypto_gosha512(void *p, size_t n, void *out) +-{ +- GO_SHA512_CTX ctx; +- _goboringcrypto_SHA512_Init(&ctx); +- return _goboringcrypto_SHA512_Update(&ctx, p, n) && +- _goboringcrypto_SHA512_Final(out, &ctx); +-} +- +-*/ +-import "C" +-import ( +- "errors" +- "hash" +- "unsafe" +-) +- +-// NOTE: The cgo calls in this file are arranged to avoid marking the parameters as escaping. +-// To do that, we call noescape (including via addr). +-// We must also make sure that the data pointer arguments have the form unsafe.Pointer(&...) +-// so that cgo does not annotate them with cgoCheckPointer calls. If it did that, it might look +-// beyond the byte slice and find Go pointers in unprocessed parts of a larger allocation. +-// To do both of these simultaneously, the idiom is unsafe.Pointer(&*addr(p)), +-// where addr returns the base pointer of p, substituting a non-nil pointer for nil, +-// and applying a noescape along the way. +-// This is all to preserve compatibility with the allocation behavior of the non-boring implementations. +- +-func SHA1(p []byte) (sum [20]byte) { +- if C._goboringcrypto_gosha1(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 { +- panic("boringcrypto: SHA1 failed") +- } +- return +-} +- +-func SHA224(p []byte) (sum [28]byte) { +- if C._goboringcrypto_gosha224(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 { +- panic("boringcrypto: SHA224 failed") +- } +- return +-} +- +-func SHA256(p []byte) (sum [32]byte) { +- if C._goboringcrypto_gosha256(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 { +- panic("boringcrypto: SHA256 failed") +- } +- return +-} +- +-func SHA384(p []byte) (sum [48]byte) { +- if C._goboringcrypto_gosha384(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 { +- panic("boringcrypto: SHA384 failed") +- } +- return +-} +- +-func SHA512(p []byte) (sum [64]byte) { +- if C._goboringcrypto_gosha512(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 { +- panic("boringcrypto: SHA512 failed") +- } +- return +-} +- +-// NewSHA1 returns a new SHA1 hash. +-func NewSHA1() hash.Hash { +- h := new(sha1Hash) +- h.Reset() +- return h +-} +- +-type sha1Hash struct { +- ctx C.GO_SHA_CTX +- out [20]byte +-} +- +-type sha1Ctx struct { +- h [5]uint32 +- nl, nh uint32 +- x [64]byte +- 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) 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 { +- panic("boringcrypto: SHA1_Update failed") +- } +- return len(p), nil +-} +- +-func (h0 *sha1Hash) sum(dst []byte) []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 { +- panic("boringcrypto: SHA1_Final failed") +- } +- return append(dst, h.out[:]...) +-} +- +-const ( +- sha1Magic = "sha\x01" +- sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 +-) +- +-func (h *sha1Hash) MarshalBinary() ([]byte, error) { +- d := (*sha1Ctx)(unsafe.Pointer(&h.ctx)) +- b := make([]byte, 0, sha1MarshaledSize) +- b = append(b, sha1Magic...) +- b = appendUint32(b, d.h[0]) +- b = appendUint32(b, d.h[1]) +- b = appendUint32(b, d.h[2]) +- b = appendUint32(b, d.h[3]) +- b = appendUint32(b, d.h[4]) +- b = append(b, d.x[:d.nx]...) +- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero +- b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) +- return b, nil +-} +- +-func (h *sha1Hash) UnmarshalBinary(b []byte) error { +- if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { +- return errors.New("crypto/sha1: invalid hash state identifier") +- } +- if len(b) != sha1MarshaledSize { +- return errors.New("crypto/sha1: invalid hash state size") +- } +- d := (*sha1Ctx)(unsafe.Pointer(&h.ctx)) +- b = b[len(sha1Magic):] +- b, d.h[0] = consumeUint32(b) +- b, d.h[1] = consumeUint32(b) +- b, d.h[2] = consumeUint32(b) +- b, d.h[3] = consumeUint32(b) +- b, d.h[4] = consumeUint32(b) +- b = b[copy(d.x[:], b):] +- b, n := consumeUint64(b) +- d.nl = uint32(n << 3) +- d.nh = uint32(n >> 29) +- d.nx = uint32(n) % 64 +- return nil +-} +- +-// NewSHA224 returns a new SHA224 hash. +-func NewSHA224() hash.Hash { +- h := new(sha224Hash) +- h.Reset() +- return h +-} +- +-type sha224Hash struct { +- ctx C.GO_SHA256_CTX +- 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) 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 { +- panic("boringcrypto: SHA224_Update failed") +- } +- return len(p), nil +-} +- +-func (h0 *sha224Hash) sum(dst []byte) []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 { +- panic("boringcrypto: SHA224_Final failed") +- } +- return append(dst, h.out[:]...) +-} +- +-// NewSHA256 returns a new SHA256 hash. +-func NewSHA256() hash.Hash { +- h := new(sha256Hash) +- h.Reset() +- return h +-} +- +-type sha256Hash struct { +- ctx C.GO_SHA256_CTX +- 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) 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 { +- panic("boringcrypto: SHA256_Update failed") +- } +- return len(p), nil +-} +- +-func (h0 *sha256Hash) sum(dst []byte) []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 { +- panic("boringcrypto: SHA256_Final failed") +- } +- return append(dst, h.out[:]...) +-} +- +-const ( +- magic224 = "sha\x02" +- magic256 = "sha\x03" +- marshaledSize256 = len(magic256) + 8*4 + 64 + 8 +-) +- +-type sha256Ctx struct { +- h [8]uint32 +- nl, nh uint32 +- x [64]byte +- nx uint32 +-} +- +-func (h *sha224Hash) MarshalBinary() ([]byte, error) { +- d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) +- b := make([]byte, 0, marshaledSize256) +- b = append(b, magic224...) +- b = appendUint32(b, d.h[0]) +- b = appendUint32(b, d.h[1]) +- b = appendUint32(b, d.h[2]) +- b = appendUint32(b, d.h[3]) +- b = appendUint32(b, d.h[4]) +- b = appendUint32(b, d.h[5]) +- b = appendUint32(b, d.h[6]) +- b = appendUint32(b, d.h[7]) +- b = append(b, d.x[:d.nx]...) +- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero +- b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) +- return b, nil +-} +- +-func (h *sha256Hash) MarshalBinary() ([]byte, error) { +- d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) +- b := make([]byte, 0, marshaledSize256) +- b = append(b, magic256...) +- b = appendUint32(b, d.h[0]) +- b = appendUint32(b, d.h[1]) +- b = appendUint32(b, d.h[2]) +- b = appendUint32(b, d.h[3]) +- b = appendUint32(b, d.h[4]) +- b = appendUint32(b, d.h[5]) +- b = appendUint32(b, d.h[6]) +- b = appendUint32(b, d.h[7]) +- b = append(b, d.x[:d.nx]...) +- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero +- b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) +- return b, nil +-} +- +-func (h *sha224Hash) UnmarshalBinary(b []byte) error { +- if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { +- return errors.New("crypto/sha256: invalid hash state identifier") +- } +- if len(b) != marshaledSize256 { +- return errors.New("crypto/sha256: invalid hash state size") +- } +- d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) +- b = b[len(magic224):] +- b, d.h[0] = consumeUint32(b) +- b, d.h[1] = consumeUint32(b) +- b, d.h[2] = consumeUint32(b) +- b, d.h[3] = consumeUint32(b) +- b, d.h[4] = consumeUint32(b) +- b, d.h[5] = consumeUint32(b) +- b, d.h[6] = consumeUint32(b) +- b, d.h[7] = consumeUint32(b) +- b = b[copy(d.x[:], b):] +- b, n := consumeUint64(b) +- d.nl = uint32(n << 3) +- d.nh = uint32(n >> 29) +- d.nx = uint32(n) % 64 +- return nil +-} +- +-func (h *sha256Hash) UnmarshalBinary(b []byte) error { +- if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { +- return errors.New("crypto/sha256: invalid hash state identifier") +- } +- if len(b) != marshaledSize256 { +- return errors.New("crypto/sha256: invalid hash state size") +- } +- d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) +- b = b[len(magic256):] +- b, d.h[0] = consumeUint32(b) +- b, d.h[1] = consumeUint32(b) +- b, d.h[2] = consumeUint32(b) +- b, d.h[3] = consumeUint32(b) +- b, d.h[4] = consumeUint32(b) +- b, d.h[5] = consumeUint32(b) +- b, d.h[6] = consumeUint32(b) +- b, d.h[7] = consumeUint32(b) +- b = b[copy(d.x[:], b):] +- b, n := consumeUint64(b) +- d.nl = uint32(n << 3) +- d.nh = uint32(n >> 29) +- d.nx = uint32(n) % 64 +- return nil +-} +- +-// NewSHA384 returns a new SHA384 hash. +-func NewSHA384() hash.Hash { +- h := new(sha384Hash) +- h.Reset() +- return h +-} +- +-type sha384Hash struct { +- ctx C.GO_SHA512_CTX +- 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) 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 { +- panic("boringcrypto: SHA384_Update failed") +- } +- return len(p), nil +-} +- +-func (h0 *sha384Hash) sum(dst []byte) []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 { +- panic("boringcrypto: SHA384_Final failed") +- } +- return append(dst, h.out[:]...) +-} +- +-// NewSHA512 returns a new SHA512 hash. +-func NewSHA512() hash.Hash { +- h := new(sha512Hash) +- h.Reset() +- return h +-} +- +-type sha512Hash struct { +- ctx C.GO_SHA512_CTX +- 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) 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 { +- panic("boringcrypto: SHA512_Update failed") +- } +- return len(p), nil +-} +- +-func (h0 *sha512Hash) sum(dst []byte) []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 { +- panic("boringcrypto: SHA512_Final failed") +- } +- return append(dst, h.out[:]...) +-} +- +-type sha512Ctx struct { +- h [8]uint64 +- nl, nh uint64 +- x [128]byte +- nx uint32 +-} +- +-const ( +- magic384 = "sha\x04" +- magic512_224 = "sha\x05" +- magic512_256 = "sha\x06" +- magic512 = "sha\x07" +- marshaledSize512 = len(magic512) + 8*8 + 128 + 8 +-) +- +-func (h *sha384Hash) MarshalBinary() ([]byte, error) { +- d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) +- b := make([]byte, 0, marshaledSize512) +- b = append(b, magic384...) +- b = appendUint64(b, d.h[0]) +- b = appendUint64(b, d.h[1]) +- b = appendUint64(b, d.h[2]) +- b = appendUint64(b, d.h[3]) +- b = appendUint64(b, d.h[4]) +- b = appendUint64(b, d.h[5]) +- b = appendUint64(b, d.h[6]) +- b = appendUint64(b, d.h[7]) +- b = append(b, d.x[:d.nx]...) +- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero +- b = appendUint64(b, d.nl>>3|d.nh<<61) +- return b, nil +-} +- +-func (h *sha512Hash) MarshalBinary() ([]byte, error) { +- d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) +- b := make([]byte, 0, marshaledSize512) +- b = append(b, magic512...) +- b = appendUint64(b, d.h[0]) +- b = appendUint64(b, d.h[1]) +- b = appendUint64(b, d.h[2]) +- b = appendUint64(b, d.h[3]) +- b = appendUint64(b, d.h[4]) +- b = appendUint64(b, d.h[5]) +- b = appendUint64(b, d.h[6]) +- b = appendUint64(b, d.h[7]) +- b = append(b, d.x[:d.nx]...) +- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero +- b = appendUint64(b, d.nl>>3|d.nh<<61) +- return b, nil +-} +- +-func (h *sha384Hash) UnmarshalBinary(b []byte) error { +- if len(b) < len(magic512) { +- return errors.New("crypto/sha512: invalid hash state identifier") +- } +- if string(b[:len(magic384)]) != magic384 { +- return errors.New("crypto/sha512: invalid hash state identifier") +- } +- if len(b) != marshaledSize512 { +- return errors.New("crypto/sha512: invalid hash state size") +- } +- d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) +- b = b[len(magic512):] +- b, d.h[0] = consumeUint64(b) +- b, d.h[1] = consumeUint64(b) +- b, d.h[2] = consumeUint64(b) +- b, d.h[3] = consumeUint64(b) +- b, d.h[4] = consumeUint64(b) +- b, d.h[5] = consumeUint64(b) +- b, d.h[6] = consumeUint64(b) +- b, d.h[7] = consumeUint64(b) +- b = b[copy(d.x[:], b):] +- b, n := consumeUint64(b) +- d.nl = n << 3 +- d.nh = n >> 61 +- d.nx = uint32(n) % 128 +- return nil +-} +- +-func (h *sha512Hash) UnmarshalBinary(b []byte) error { +- if len(b) < len(magic512) { +- return errors.New("crypto/sha512: invalid hash state identifier") +- } +- if string(b[:len(magic512)]) != magic512 { +- return errors.New("crypto/sha512: invalid hash state identifier") +- } +- if len(b) != marshaledSize512 { +- return errors.New("crypto/sha512: invalid hash state size") +- } +- d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) +- b = b[len(magic512):] +- b, d.h[0] = consumeUint64(b) +- b, d.h[1] = consumeUint64(b) +- b, d.h[2] = consumeUint64(b) +- b, d.h[3] = consumeUint64(b) +- b, d.h[4] = consumeUint64(b) +- b, d.h[5] = consumeUint64(b) +- b, d.h[6] = consumeUint64(b) +- b, d.h[7] = consumeUint64(b) +- b = b[copy(d.x[:], b):] +- b, n := consumeUint64(b) +- d.nl = n << 3 +- d.nh = n >> 61 +- d.nx = uint32(n) % 128 +- return nil +-} +- +-func appendUint64(b []byte, x uint64) []byte { +- var a [8]byte +- putUint64(a[:], x) +- return append(b, a[:]...) +-} +- +-func appendUint32(b []byte, x uint32) []byte { +- var a [4]byte +- putUint32(a[:], x) +- return append(b, a[:]...) +-} +- +-func consumeUint64(b []byte) ([]byte, uint64) { +- _ = b[7] +- x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | +- uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 +- return b[8:], x +-} +- +-func consumeUint32(b []byte) ([]byte, uint32) { +- _ = b[3] +- x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 +- return b[4:], x +-} +- +-func putUint64(x []byte, s uint64) { +- _ = x[7] +- x[0] = byte(s >> 56) +- x[1] = byte(s >> 48) +- x[2] = byte(s >> 40) +- x[3] = byte(s >> 32) +- x[4] = byte(s >> 24) +- x[5] = byte(s >> 16) +- x[6] = byte(s >> 8) +- x[7] = byte(s) +-} +- +-func putUint32(x []byte, s uint32) { +- _ = x[3] +- x[0] = byte(s >> 24) +- x[1] = byte(s >> 16) +- x[2] = byte(s >> 8) +- x[3] = byte(s) +-} +diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go +index 40fce36314..c30be35635 100644 +--- a/src/crypto/rand/rand_unix.go ++++ b/src/crypto/rand/rand_unix.go +@@ -10,7 +10,7 @@ + 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..8524c02547 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) @@ -1495,7 +2884,7 @@ index 55fea1ab93..d6eaf7cea8 100644 @@ -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 @@ -1504,7 +2893,7 @@ index 55fea1ab93..d6eaf7cea8 100644 @@ -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) @@ -1513,28 +2902,22 @@ index 55fea1ab93..d6eaf7cea8 100644 @@ -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 [ +@@ -296,7 +296,7 @@ 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 [ +@@ -322,7 +322,7 @@ 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 { @@ -1543,12 +2926,6 @@ index 55fea1ab93..d6eaf7cea8 100644 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 @@ -1564,49 +2941,49 @@ index 39a4fc184a..0853178e3a 100644 . "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 @@ -1623,7 +3000,7 @@ index 3a377cc9db..ce78a13d6f 100644 @@ -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) @@ -1632,7 +3009,7 @@ index 3a377cc9db..ce78a13d6f 100644 @@ -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) @@ -1668,18 +3045,18 @@ index 1226149321..befd1612b5 100644 + 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 +index f0aef1f542..e6bf6a5e88 100644 --- a/src/crypto/rsa/rsa.go +++ b/src/crypto/rsa/rsa.go @@ -28,8 +28,8 @@ package rsa @@ -1696,7 +3073,7 @@ index ad860d7f0c..86f700bee2 100644 @@ -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) { @@ -1705,7 +3082,7 @@ index ad860d7f0c..86f700bee2 100644 @@ -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) @@ -1714,7 +3091,7 @@ index ad860d7f0c..86f700bee2 100644 @@ -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 @@ -1723,7 +3100,7 @@ index ad860d7f0c..86f700bee2 100644 @@ -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) @@ -1754,7 +3131,7 @@ index b994daec19..4b7427e1ae 100644 @@ -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 @@ -1768,7 +3145,7 @@ index b994daec19..4b7427e1ae 100644 } @@ -167,7 +167,7 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { } - + func TestAllocations(t *testing.T) { - if boring.Enabled { + if boring.Enabled() { @@ -1805,12 +3182,12 @@ index b994daec19..4b7427e1ae 100644 @@ -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 { @@ -1826,18 +3203,18 @@ index b5786d1bf4..9bd03f3940 100644 +++ 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 @@ -1845,15 +3222,15 @@ index 42ef87937f..c1a3205539 100644 @@ -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 @@ -1861,7 +3238,7 @@ 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" @@ -1879,7 +3256,7 @@ index 85ed126091..71f4b46663 100644 } 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 { @@ -1889,7 +3266,7 @@ index 85ed126091..71f4b46663 100644 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() { @@ -1901,7 +3278,7 @@ 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" @@ -1919,7 +3296,7 @@ index 2deafbc9fc..282c326b32 100644 } 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 { @@ -1928,7 +3305,7 @@ index 2deafbc9fc..282c326b32 100644 } 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 { @@ -1937,7 +3314,7 @@ index 2deafbc9fc..282c326b32 100644 } 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 { @@ -1950,7 +3327,7 @@ 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" @@ -1959,7 +3336,7 @@ index 7304678346..a073d31119 100644 "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 { @@ -1969,7 +3346,7 @@ index 7304678346..a073d31119 100644 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() { @@ -1981,7 +3358,7 @@ 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" @@ -1990,7 +3367,7 @@ index 9ae1b3aae2..e56eedb201 100644 "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 { @@ -1999,7 +3376,7 @@ index 9ae1b3aae2..e56eedb201 100644 } 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 { @@ -2008,7 +3385,7 @@ index 9ae1b3aae2..e56eedb201 100644 } 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 { @@ -2017,7 +3394,7 @@ index 9ae1b3aae2..e56eedb201 100644 } 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 { @@ -2030,7 +3407,7 @@ 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" @@ -2039,7 +3416,7 @@ index 921cdbb7bb..a35165bcbf 100644 "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 { @@ -2049,7 +3426,7 @@ index 921cdbb7bb..a35165bcbf 100644 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() { @@ -2063,15 +3440,15 @@ index 140b1a3dd8..fe6fa96d28 100644 @@ -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() { @@ -2085,12 +3462,12 @@ index 7bfe3f9417..49702f59ba 100644 @@ -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" @@ -2109,9 +3486,9 @@ index 7bfe3f9417..49702f59ba 100644 } 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 @@ -2120,7 +3497,7 @@ index 7bfe3f9417..49702f59ba 100644 @@ -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 @@ -2136,7 +3513,7 @@ index 7bfe3f9417..49702f59ba 100644 serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey serverConfig.BuildNameToCertificate() } - + - if boring.Enabled { + if boring.Enabled() { serverConfig.Rand = boring.RandReader @@ -2271,12 +3648,12 @@ index 7d85b39c59..fe2719485b 100644 @@ -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 @@ -2284,12 +3661,12 @@ index 095b58c315..ac06591ea8 100644 @@ -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 @@ -2297,12 +3674,12 @@ index 102acda578..07b3c7095e 100644 @@ -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 @@ -2310,12 +3687,12 @@ index c83a7272c9..0c7dea2f1f 100644 @@ -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 @@ -2331,7 +3708,7 @@ index 0c2cbf3182..e01c24292e 100644 "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() { @@ -2348,66 +3725,844 @@ index 0c2cbf3182..e01c24292e 100644 } else { testCurve = elliptic.P384() diff --git a/src/go.mod b/src/go.mod -index 3b24053b94..c4bc3c1e96 100644 +index 3b24053b94..d5cf5c74f9 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 ++ github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28 golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d golang.org/x/net v0.12.1-0.20231027154334-5ca955b1789c ) diff --git a/src/go.sum b/src/go.sum -index caf8ff010d..16a5d8c7da 100644 +index caf8ff010d..611d232a43 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= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28 h1:tFlW5hU9m5kkVIShxa1FFNLe9gwoygZFHw/d/60VE7s= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= 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.20231027154334-5ca955b1789c h1:d+VvAxu4S13DWtf73R5eY//VaCk3aUcVdyYjM1SX7zw= -diff --git a/src/vendor/github.com/golang-fips/openssl-fips/LICENSE b/src/vendor/github.com/golang-fips/openssl-fips/LICENSE +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml b/src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml +new file mode 100644 +index 0000000000..aed2e22df2 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml +@@ -0,0 +1,9 @@ ++# ++# GitLeaks Repo Specific Configuration ++# ++# This allowlist is used to ignore false positives during secret scans. ++ ++[allowlist] ++paths = [ ++ 'ecdh_test.go', ++] +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/LICENSE b/src/vendor/github.com/golang-fips/openssl/v2/LICENSE +new file mode 100644 +index 0000000000..97e8515401 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/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/v2/README.md b/src/vendor/github.com/golang-fips/openssl/v2/README.md +new file mode 100644 +index 0000000000..ba6289ecff +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/README.md +@@ -0,0 +1,66 @@ ++# Go OpenSSL bindings for FIPS compliance ++ ++[![Go Reference](https://pkg.go.dev/badge/github.com/golang-fips/openssl.svg)](https://pkg.go.dev/github.com/golang-fips/openssl) ++ ++The `openssl` package implements Go crypto primitives using OpenSSL shared libraries and cgo. When configured correctly, OpenSSL can be executed in FIPS mode, making the `openssl` package FIPS compliant. ++ ++The `openssl` package is designed to be used as a drop-in replacement for the [boring](https://pkg.go.dev/crypto/internal/boring) package in order to facilitate integrating `openssl` inside a forked Go toolchain. ++ ++## Disclaimer ++ ++A program directly or indirectly using this package in FIPS mode can claim it is using a FIPS-certified cryptographic module (OpenSSL), but it can't claim the program as a whole is FIPS certified without passing the certification process, nor claim it is FIPS compliant without ensuring all crypto APIs and workflows are implemented in a FIPS-compliant manner. ++ ++## Background ++ ++FIPS 140-2 is a U.S. government computer security standard used to approve cryptographic modules. FIPS compliance may come up when working with U.S. government and other regulated industries. ++ ++### Go FIPS compliance ++ ++The Go `crypto` package is not FIPS certified, and the Go team has stated that it won't be, e.g. in [golang/go/issues/21734](https://github.com/golang/go/issues/21734#issuecomment-326980213) Adam Langley says: ++ ++> The status of FIPS 140 for Go itself remains "no plans, basically zero chance". ++ ++On the other hand, Google maintains a branch that uses cgo and BoringSSL to implement various crypto primitives: https://github.com/golang/go/blob/dev.boringcrypto/README.boringcrypto.md. As BoringSSL is FIPS 140-2 certified, an application using that branch is more likely to be FIPS 140-2 compliant, yet Google does not provide any liability about the suitability of this code in relation to the FIPS 140-2 standard. ++ ++## Features ++ ++### Multiple OpenSSL versions supported ++ ++The `openssl` package has support for multiple OpenSSL versions, namely 1.0.2, 1.1.0, 1.1.1 and 3.0.x. ++ ++All supported OpenSSL versions pass a small set of automatic tests that ensure they can be built and that there are no major regressions. ++These tests do not validate the cryptographic correctness of the `openssl` package. ++ ++On top of that, the [golang-fips Go fork](https://github.com/golang-fips/go) -maintained by Red Hat- and the [Microsoft Go fork](https://github.com/microsoft/go), tests a subset of the supported OpenSSL versions when integrated with the Go `crypto` package. ++These tests are much more exhaustive and validate a specific OpenSSL version can produce working applications. ++ ++### Building without OpenSSL headers ++ ++The `openssl` package does not use any symbol from the OpenSSL headers. There is no need that have them installed to build an application which imports this library. ++ ++The CI tests in this repository verify that all the functions and constants defined in our headers match the ones in the OpenSSL headers for every supported OpenSSL version. ++ ++### Portable OpenSSL ++ ++The OpenSSL bindings are implemented in such a way that the OpenSSL version available when building a program does not have to match with the OpenSSL version used when running it. ++In fact, OpenSSL doesn't need to be present on the builder. ++For example, using the `openssl` package and `go build .` on a Windows host with `GOOS=linux` can produce a program that successfully runs on Linux and uses OpenSSL. ++ ++This feature does not require any additional configuration, but it only works with OpenSSL versions known and supported by the Go toolchain that integrates the `openssl` package. ++ ++## Limitations ++ ++- Only Unix, Unix-like and Windows platforms are supported. ++- The build must set `CGO_ENABLED=1`. ++ ++## Acknowledgements ++ ++The work done to support FIPS compatibility mode leverages code and ideas from other open-source projects: ++ ++- All crypto stubs are a mirror of Google's [dev.boringcrypto branch](https://github.com/golang/go/tree/dev.boringcrypto) and the release branch ports of that branch. ++- The mapping between BoringSSL and OpenSSL APIs is taken from the former [Red Hat Go fork](https://pagure.io/go). ++- The portable OpenSSL implementation is ported from Microsoft's [.NET runtime](https://github.com/dotnet/runtime) cryptography module. ++ ++## Code of Conduct ++ ++This project adopts the Go code of conduct: https://go.dev/conduct. +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/aes.go b/src/vendor/github.com/golang-fips/openssl/v2/aes.go +new file mode 100644 +index 0000000000..1fc11f00cd +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/aes.go +@@ -0,0 +1,90 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto/cipher" ++ "errors" ++) ++ ++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) { ++ var kind cipherKind ++ switch len(key) * 8 { ++ case 128: ++ kind = cipherAES128 ++ case 192: ++ kind = cipherAES192 ++ case 256: ++ kind = cipherAES256 ++ default: ++ return nil, errors.New("crypto/aes: invalid key size") ++ } ++ c, err := newEVPCipher(key, kind) ++ if err != nil { ++ return nil, err ++ } ++ return &aesCipher{c}, nil ++} ++ ++// 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() ++} ++ ++type aesCipher struct { ++ *evpCipher ++} ++ ++func (c *aesCipher) BlockSize() int { ++ return c.blockSize ++} ++ ++func (c *aesCipher) Encrypt(dst, src []byte) { ++ if err := c.encrypt(dst, src); err != nil { ++ // crypto/aes expects that the panic message starts with "crypto/aes: ". ++ panic("crypto/aes: " + err.Error()) ++ } ++} ++ ++func (c *aesCipher) Decrypt(dst, src []byte) { ++ if err := c.decrypt(dst, src); err != nil { ++ // crypto/aes expects that the panic message starts with "crypto/aes: ". ++ panic("crypto/aes: " + err.Error()) ++ } ++} ++ ++func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpEncrypt) ++} ++ ++func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpDecrypt) ++} ++ ++func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { ++ return c.newCTR(iv) ++} ++ ++func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { ++ return c.newGCMChecked(nonceSize, tagSize) ++} ++ ++func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) { ++ return c.newGCM(true) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go b/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go +new file mode 100644 +index 0000000000..a81cbdbef9 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go +@@ -0,0 +1,37 @@ ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++// This is a mirror of ++// https://github.com/golang/go/blob/36b87f273cc43e21685179dc1664ebb5493d26ae/src/crypto/internal/boring/bbig/big.go. ++ ++package bbig ++ ++import ( ++ "math/big" ++ "unsafe" ++ ++ "github.com/golang-fips/openssl/v2" ++) ++ ++func Enc(b *big.Int) openssl.BigInt { ++ if b == nil { ++ return nil ++ } ++ x := b.Bits() ++ if len(x) == 0 { ++ return openssl.BigInt{} ++ } ++ return unsafe.Slice((*uint)(&x[0]), len(x)) ++} ++ ++func Dec(b openssl.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/vendor/github.com/golang-fips/openssl/v2/big.go b/src/vendor/github.com/golang-fips/openssl/v2/big.go new file mode 100644 -index 0000000000..97e8515401 +index 0000000000..6461f241f8 --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl-fips/LICENSE -@@ -0,0 +1,20 @@ -+The MIT License (MIT) ++++ b/src/vendor/github.com/golang-fips/openssl/v2/big.go +@@ -0,0 +1,11 @@ ++package openssl + -+Copyright (c) 2022 The Golang FIPS Authors ++// This file does not have build constraints to ++// facilitate using BigInt in Go crypto. ++// Go crypto references BigInt unconditionally, ++// even if it is not finally used. + -+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: ++// 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 openssl/bbig. ++type BigInt []uint +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/cipher.go b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go +new file mode 100644 +index 0000000000..b56de6a74e +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go +@@ -0,0 +1,534 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto/cipher" ++ "encoding/binary" ++ "errors" ++ "runtime" ++ "strconv" ++ "sync" ++ "unsafe" ++) ++ ++type cipherKind int8 ++ ++const ( ++ cipherAES128 cipherKind = iota ++ cipherAES192 ++ cipherAES256 ++ cipherDES ++ cipherDES3 ++ cipherRC4 ++) ++ ++func (c cipherKind) String() string { ++ switch c { ++ case cipherAES128: ++ return "AES-128" ++ case cipherAES192: ++ return "AES-192" ++ case cipherAES256: ++ return "AES-256" ++ case cipherDES: ++ return "DES" ++ case cipherDES3: ++ return "DES3" ++ case cipherRC4: ++ return "RC4" ++ default: ++ panic("unknown cipher kind: " + strconv.Itoa(int(c))) ++ } ++} ++ ++type cipherMode int8 ++ ++const ( ++ cipherModeNone cipherMode = -1 ++ cipherModeECB cipherMode = iota ++ cipherModeCBC ++ cipherModeCTR ++ cipherModeGCM ++) ++ ++// cipherOp is the allowed operations for a cipher, ++// as documented in [EVP_CipherInit_ex]. ++// ++// [EVP_CipherInit_ex]: https://www.openssl.org/docs/man3.0/man3/EVP_CipherInit_ex.html ++type cipherOp int8 ++ ++const ( ++ cipherOpNone cipherOp = -1 // leaves the value of the previous call, if any. ++ cipherOpDecrypt cipherOp = 0 ++ cipherOpEncrypt cipherOp = 1 ++) ++ ++// cacheCipher is a cache of cipherKind to GO_EVP_CIPHER_PTR. ++var cacheCipher sync.Map ++ ++type cacheCipherKey struct { ++ kind cipherKind ++ mode cipherMode ++} ++ ++// loadCipher returns a cipher object for the given k. ++func loadCipher(k cipherKind, mode cipherMode) (cipher C.GO_EVP_CIPHER_PTR) { ++ if v, ok := cacheCipher.Load(cacheCipherKey{k, mode}); ok { ++ return v.(C.GO_EVP_CIPHER_PTR) ++ } ++ defer func() { ++ if cipher != nil && vMajor == 3 { ++ // On OpenSSL 3, directly operating on a EVP_CIPHER object ++ // not created by EVP_CIPHER has negative performance ++ // implications, as cipher operations will have ++ // to fetch it on every call. Better to just fetch it once here. ++ cipher = C.go_openssl_EVP_CIPHER_fetch(nil, C.go_openssl_EVP_CIPHER_get0_name(cipher), nil) ++ } ++ cacheCipher.Store(cacheCipherKey{k, mode}, cipher) ++ }() ++ switch k { ++ case cipherAES128: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_aes_128_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_aes_128_cbc() ++ case cipherModeCTR: ++ cipher = C.go_openssl_EVP_aes_128_ctr() ++ case cipherModeGCM: ++ cipher = C.go_openssl_EVP_aes_128_gcm() ++ } ++ case cipherAES192: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_aes_192_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_aes_192_cbc() ++ case cipherModeCTR: ++ cipher = C.go_openssl_EVP_aes_192_ctr() ++ case cipherModeGCM: ++ cipher = C.go_openssl_EVP_aes_192_gcm() ++ } ++ case cipherAES256: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_aes_256_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_aes_256_cbc() ++ case cipherModeCTR: ++ cipher = C.go_openssl_EVP_aes_256_ctr() ++ case cipherModeGCM: ++ cipher = C.go_openssl_EVP_aes_256_gcm() ++ } ++ case cipherDES: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_des_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_des_cbc() ++ } ++ case cipherDES3: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_des_ede3_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_des_ede3_cbc() ++ } ++ case cipherRC4: ++ cipher = C.go_openssl_EVP_rc4() ++ } ++ return cipher ++} ++ ++type evpCipher struct { ++ key []byte ++ enc_ctx C.GO_EVP_CIPHER_CTX_PTR ++ dec_ctx C.GO_EVP_CIPHER_CTX_PTR ++ kind cipherKind ++ blockSize int ++} ++ ++func newEVPCipher(key []byte, kind cipherKind) (*evpCipher, error) { ++ cipher := loadCipher(kind, cipherModeECB) ++ if cipher == nil { ++ return nil, errors.New("crypto/cipher: unsupported cipher: " + kind.String()) ++ } ++ c := &evpCipher{key: make([]byte, len(key)), kind: kind} ++ copy(c.key, key) ++ c.blockSize = int(C.go_openssl_EVP_CIPHER_get_block_size(cipher)) ++ runtime.SetFinalizer(c, (*evpCipher).finalize) ++ return c, nil ++} ++ ++func (c *evpCipher) finalize() { ++ if c.enc_ctx != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.enc_ctx) ++ } ++ if c.dec_ctx != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.dec_ctx) ++ } ++} ++ ++func (c *evpCipher) encrypt(dst, src []byte) error { ++ if len(src) < c.blockSize { ++ return errors.New("input not full block") ++ } ++ if len(dst) < c.blockSize { ++ return errors.New("output not full block") ++ } ++ // Only check for overlap between the parts of src and dst that will actually be used. ++ // This matches Go standard library behavior. ++ if inexactOverlap(dst[:c.blockSize], src[:c.blockSize]) { ++ return errors.New("invalid buffer overlap") ++ } ++ if c.enc_ctx == nil { ++ var err error ++ c.enc_ctx, err = newCipherCtx(c.kind, cipherModeECB, cipherOpEncrypt, c.key, nil) ++ if err != nil { ++ return err ++ } ++ } ++ ++ if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), C.int(c.blockSize)) != 1 { ++ return errors.New("EncryptUpdate failed") ++ } ++ runtime.KeepAlive(c) ++ return nil ++} ++ ++func (c *evpCipher) decrypt(dst, src []byte) error { ++ if len(src) < c.blockSize { ++ return errors.New("input not full block") ++ } ++ if len(dst) < c.blockSize { ++ return errors.New("output not full block") ++ } ++ // Only check for overlap between the parts of src and dst that will actually be used. ++ // This matches Go standard library behavior. ++ if inexactOverlap(dst[:c.blockSize], src[:c.blockSize]) { ++ return errors.New("invalid buffer overlap") ++ } ++ if c.dec_ctx == nil { ++ var err error ++ c.dec_ctx, err = newCipherCtx(c.kind, cipherModeECB, cipherOpDecrypt, c.key, nil) ++ if err != nil { ++ return err ++ } ++ if C.go_openssl_EVP_CIPHER_CTX_set_padding(c.dec_ctx, 0) != 1 { ++ return errors.New("could not disable cipher padding") ++ } ++ } ++ ++ C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), C.int(c.blockSize)) ++ runtime.KeepAlive(c) ++ return nil ++} ++ ++type cipherCBC struct { ++ ctx C.GO_EVP_CIPHER_CTX_PTR ++ blockSize int ++} ++ ++func (c *cipherCBC) finalize() { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) ++} ++ ++func (x *cipherCBC) BlockSize() int { return x.blockSize } ++ ++func (x *cipherCBC) CryptBlocks(dst, src []byte) { ++ if inexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src)%x.blockSize != 0 { ++ panic("crypto/cipher: input not full blocks") ++ } ++ if len(dst) < len(src) { ++ panic("crypto/cipher: output smaller than input") ++ } ++ if len(src) > 0 { ++ if C.go_openssl_EVP_CipherUpdate_wrapper(x.ctx, base(dst), base(src), C.int(len(src))) != 1 { ++ panic("crypto/cipher: CipherUpdate failed") ++ } ++ runtime.KeepAlive(x) ++ } ++} ++ ++func (x *cipherCBC) SetIV(iv []byte) { ++ if len(iv) != x.blockSize { ++ panic("cipher: incorrect length IV") ++ } ++ if C.go_openssl_EVP_CipherInit_ex(x.ctx, nil, nil, nil, base(iv), C.int(cipherOpNone)) != 1 { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++} ++ ++func (c *evpCipher) newCBC(iv []byte, op cipherOp) cipher.BlockMode { ++ ctx, err := newCipherCtx(c.kind, cipherModeCBC, op, c.key, iv) ++ if err != nil { ++ panic(err) ++ } ++ x := &cipherCBC{ctx: ctx, blockSize: c.blockSize} ++ runtime.SetFinalizer(x, (*cipherCBC).finalize) ++ if C.go_openssl_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { ++ panic("cipher: unable to set padding") ++ } ++ return x ++} ++ ++type cipherCTR struct { ++ ctx C.GO_EVP_CIPHER_CTX_PTR ++} ++ ++func (x *cipherCTR) 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 ++ } ++ if C.go_openssl_EVP_EncryptUpdate_wrapper(x.ctx, base(dst), base(src), C.int(len(src))) != 1 { ++ panic("crypto/cipher: EncryptUpdate failed") ++ } ++ runtime.KeepAlive(x) ++} ++ ++func (c *evpCipher) newCTR(iv []byte) cipher.Stream { ++ ctx, err := newCipherCtx(c.kind, cipherModeCTR, cipherOpEncrypt, c.key, iv) ++ if err != nil { ++ panic(err) ++ } ++ x := &cipherCTR{ctx: ctx} ++ runtime.SetFinalizer(x, (*cipherCTR).finalize) ++ return x ++} ++ ++func (c *cipherCTR) finalize() { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) ++} ++ ++type cipherGCM struct { ++ ctx C.GO_EVP_CIPHER_CTX_PTR ++ tls bool ++ minNextNonce uint64 ++ blockSize int ++} ++ ++const ( ++ gcmTagSize = 16 ++ gcmStandardNonceSize = 12 ++ gcmTlsAddSize = 13 ++ gcmTlsFixedNonceSize = 4 ++) ++ ++type noGCM struct { ++ *evpCipher ++} ++ ++func (g *noGCM) BlockSize() int { ++ return g.blockSize ++} ++ ++func (g *noGCM) Encrypt(dst, src []byte) { ++ g.encrypt(dst, src) ++} ++ ++func (g *noGCM) Decrypt(dst, src []byte) { ++ g.decrypt(dst, src) ++} ++ ++func (c *evpCipher) newGCMChecked(nonceSize, tagSize int) (cipher.AEAD, error) { ++ if nonceSize != gcmStandardNonceSize && tagSize != gcmTagSize { ++ return nil, errors.New("crypto/cipher: 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 (c *evpCipher) newGCM(tls bool) (cipher.AEAD, error) { ++ ctx, err := newCipherCtx(c.kind, cipherModeGCM, cipherOpNone, c.key, nil) ++ if err != nil { ++ return nil, err ++ } ++ g := &cipherGCM{ctx: ctx, tls: tls, blockSize: c.blockSize} ++ runtime.SetFinalizer(g, (*cipherGCM).finalize) ++ return g, nil ++} ++ ++func (g *cipherGCM) finalize() { ++ C.go_openssl_EVP_CIPHER_CTX_free(g.ctx) ++} ++ ++func (g *cipherGCM) NonceSize() int { ++ return gcmStandardNonceSize ++} ++ ++func (g *cipherGCM) Overhead() int { ++ return gcmTagSize ++} ++ ++func (g *cipherGCM) 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)*uint64(g.blockSize) || 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") ++ } ++ if g.tls { ++ if len(additionalData) != gcmTlsAddSize { ++ panic("cipher: incorrect additional data length given to GCM TLS") ++ } ++ // BoringCrypto enforces strictly monotonically increasing explicit nonces ++ // and to fail after 2^64 - 1 keys as per FIPS 140-2 IG A.5, ++ // but OpenSSL does not perform this check, so it is implemented here. ++ const maxUint64 = 1<<64 - 1 ++ counter := binary.BigEndian.Uint64(nonce[gcmTlsFixedNonceSize:]) ++ if counter == maxUint64 { ++ panic("cipher: nonce counter must be less than 2^64 - 1") ++ } ++ if counter < g.minNextNonce { ++ panic("cipher: nonce counter must be strictly monotonically increasing") ++ } ++ defer func() { ++ g.minNextNonce = counter + 1 ++ }() ++ } ++ ++ // Make room in dst to append plaintext+overhead. ++ ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize) ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if inexactOverlap(out, plaintext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ // Encrypt additional data. ++ // When sealing a TLS payload, OpenSSL app sets the additional data using ++ // 'EVP_CIPHER_CTX_ctrl(g.ctx, C.EVP_CTRL_AEAD_TLS1_AAD, C.EVP_AEAD_TLS1_AAD_LEN, base(additionalData))'. ++ // This makes the explicit nonce component to monotonically increase on every Seal operation without ++ // relying in the explicit nonce being securely set externally, ++ // and it also gives some interesting speed gains. ++ // Unfortunately we can't use it because Go expects AEAD.Seal to honor the provided nonce. ++ if C.go_openssl_EVP_CIPHER_CTX_seal_wrapper(g.ctx, base(out), base(nonce), ++ base(plaintext), C.int(len(plaintext)), ++ base(additionalData), C.int(len(additionalData))) != 1 { ++ ++ panic(fail("EVP_CIPHER_CTX_seal")) ++ } ++ runtime.KeepAlive(g) ++ return ret ++} ++ ++var errOpen = errors.New("cipher: message authentication failed") ++ ++func (g *cipherGCM) 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)*uint64(g.blockSize)+gcmTagSize { ++ return nil, errOpen ++ } ++ // BoringCrypto does not do any TLS check when decrypting, neither do we. ++ ++ tag := ciphertext[len(ciphertext)-gcmTagSize:] ++ ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] ++ ++ // Make room in dst to append ciphertext without tag. ++ ret, out := sliceForAppend(dst, len(ciphertext)) ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if inexactOverlap(out, ciphertext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ ok := C.go_openssl_EVP_CIPHER_CTX_open_wrapper( ++ g.ctx, base(out), base(nonce), ++ base(ciphertext), C.int(len(ciphertext)), ++ base(additionalData), C.int(len(additionalData)), base(tag)) ++ runtime.KeepAlive(g) ++ if ok == 0 { ++ // Zero output buffer on error. ++ for i := range out { ++ out[i] = 0 ++ } ++ return nil, errOpen ++ } ++ return ret, nil ++} ++ ++// sliceForAppend is a mirror of crypto/cipher.sliceForAppend. ++func sliceForAppend(in []byte, n int) (head, tail []byte) { ++ if total := len(in) + n; cap(in) >= total { ++ head = in[:total] ++ } else { ++ head = make([]byte, total) ++ copy(head, in) ++ } ++ tail = head[len(in):] ++ return ++} ++ ++func newCipherCtx(kind cipherKind, mode cipherMode, encrypt cipherOp, key, iv []byte) (ctx C.GO_EVP_CIPHER_CTX_PTR, err error) { ++ cipher := loadCipher(kind, mode) ++ if cipher == nil { ++ panic("crypto/cipher: unsupported cipher: " + kind.String()) ++ } ++ ctx = C.go_openssl_EVP_CIPHER_CTX_new() ++ if ctx == nil { ++ return nil, fail("unable to create EVP cipher ctx") ++ } ++ defer func() { ++ if err != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(ctx) ++ } ++ }() ++ if kind == cipherRC4 { ++ // RC4 cipher supports a variable key length. ++ // We need to set the key length before setting the key, ++ // and to do so we need to have an initialized cipher ctx. ++ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, nil, nil, C.int(encrypt)) != 1 { ++ return nil, newOpenSSLError("EVP_CipherInit_ex") ++ } ++ if C.go_openssl_EVP_CIPHER_CTX_set_key_length(ctx, C.int(len(key))) != 1 { ++ return nil, newOpenSSLError("EVP_CIPHER_CTX_set_key_length") ++ } ++ // Pass nil to the next call to EVP_CipherInit_ex to avoid resetting ctx's cipher. ++ cipher = nil ++ } ++ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), C.int(encrypt)) != 1 { ++ return nil, newOpenSSLError("unable to initialize EVP cipher ctx") ++ } ++ return ctx, nil ++} + -+The above copyright notice and this permission notice shall be included in all -+copies or substantial portions of the Software. ++// The following two functions are a mirror of golang.org/x/crypto/internal/subtle. + -+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 ++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/v2/des.go b/src/vendor/github.com/golang-fips/openssl/v2/des.go new file mode 100644 -index 0000000000..079fc3c4ad +index 0000000000..71b13333a2 --- /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 ++++ b/src/vendor/github.com/golang-fips/openssl/v2/des.go +@@ -0,0 +1,113 @@ ++//go:build !cmd_go_bootstrap + +package openssl + @@ -2416,543 +4571,734 @@ index 0000000000..079fc3c4ad +import ( + "crypto/cipher" + "errors" -+ "runtime" -+ "strconv" -+ "unsafe" +) + -+type aesKeySizeError int ++// SupportsDESCipher returns true if NewDESCipher is supported, ++// which uses ECB mode. ++// If CBC is also supported, then the returned cipher.Block ++// will also implement NewCBCEncrypter and NewCBCDecrypter. ++func SupportsDESCipher() bool { ++ // True for stock OpenSSL 1 w/o FIPS. ++ // False for stock OpenSSL 3 unless the legacy provider is available. ++ return (versionAtOrAbove(1, 1, 0) || !FIPS()) && loadCipher(cipherDES, cipherModeECB) != nil ++} + -+func (k aesKeySizeError) Error() string { -+ return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) ++// SupportsTripleDESCipher returns true if NewTripleDESCipher is supported, ++// which uses ECB mode. ++// If CBC is also supported, then the returned cipher.Block ++// will also implement NewCBCEncrypter and NewCBCDecrypter. ++func SupportsTripleDESCipher() bool { ++ // Should always be true for stock OpenSSL, ++ // even when using the FIPS provider. ++ return loadCipher(cipherDES3, cipherModeECB) != nil +} + -+const aesBlockSize = 16 ++func NewDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 8 { ++ return nil, errors.New("crypto/des: invalid key size") ++ } ++ c, err := newEVPCipher(key, cipherDES) ++ if err != nil { ++ return nil, err ++ } ++ // Should always be true for stock OpenSSL. ++ if loadCipher(cipherDES, cipherModeCBC) == nil { ++ return &desCipherWithoutCBC{c}, nil ++ } ++ return &desCipher{c}, nil ++} + -+type aesCipher struct { -+ key []byte -+ enc_ctx *C.EVP_CIPHER_CTX -+ dec_ctx *C.EVP_CIPHER_CTX -+ cipher *C.EVP_CIPHER ++func NewTripleDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 24 { ++ return nil, errors.New("crypto/des: invalid key size") ++ } ++ c, err := newEVPCipher(key, cipherDES3) ++ if err != nil { ++ return nil, err ++ } ++ // Should always be true for stock OpenSSL. ++ if loadCipher(cipherDES, cipherModeCBC) != nil { ++ return &desCipherWithoutCBC{c}, nil ++ } ++ return &desCipher{c}, nil +} + -+type extraModes interface { -+ // Copied out of crypto/aes/modes.go. ++type desExtraModes interface { + 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 _ desExtraModes = (*desCipher)(nil) ++ ++type desCipher struct { ++ *evpCipher +} + -+var _ extraModes = (*aesCipher)(nil) ++func (c *desCipher) BlockSize() int { ++ return c.blockSize ++} + -+func NewAESCipher(key []byte) (cipher.Block, error) { -+ c := &aesCipher{key: make([]byte, len(key))} -+ copy(c.key, key) ++func (c *desCipher) Encrypt(dst, src []byte) { ++ if err := c.encrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } ++} + -+ 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") ++func (c *desCipher) Decrypt(dst, src []byte) { ++ if err := c.decrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) + } ++} ++ ++func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpEncrypt) ++} + -+ runtime.SetFinalizer(c, (*aesCipher).finalize) ++func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpDecrypt) ++} + -+ return c, nil ++type desCipherWithoutCBC struct { ++ *evpCipher +} + -+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 *desCipherWithoutCBC) BlockSize() int { ++ return c.blockSize +} + -+func (c *aesCipher) BlockSize() int { return aesBlockSize } ++func (c *desCipherWithoutCBC) Encrypt(dst, src []byte) { ++ c.encrypt(dst, src) ++} + -+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") -+ } ++func (c *desCipherWithoutCBC) Decrypt(dst, src []byte) { ++ c.decrypt(dst, src) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ec.go b/src/vendor/github.com/golang-fips/openssl/v2/ec.go +new file mode 100644 +index 0000000000..eac2f8bbee +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/ec.go +@@ -0,0 +1,59 @@ ++//go:build !cmd_go_bootstrap + -+ 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") -+ } ++package openssl + -+ k := (*C.uchar)(unsafe.Pointer(&c.key[0])) ++// #include "goopenssl.h" ++import "C" + -+ 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") -+ } -+ } ++var ( ++ paramPubKey = C.CString("pub") ++ paramPrivKey = C.CString("priv") ++ paramGroup = C.CString("group") ++ paramECPubX = C.CString("qx") ++ paramECPubY = C.CString("qy") ++) + -+ 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 curveNID(curve string) (C.int, error) { ++ switch curve { ++ case "P-224": ++ return C.GO_NID_secp224r1, nil ++ case "P-256": ++ return C.GO_NID_X9_62_prime256v1, nil ++ case "P-384": ++ return C.GO_NID_secp384r1, nil ++ case "P-521": ++ return C.GO_NID_secp521r1, nil ++ } ++ return 0, errUnknownCurve +} + -+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") ++// encodeEcPoint encodes pt. ++func encodeEcPoint(group C.GO_EC_GROUP_PTR, pt C.GO_EC_POINT_PTR) ([]byte, error) { ++ // Get encoded point size. ++ n := C.go_openssl_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, nil, 0, nil) ++ if n == 0 { ++ return nil, newOpenSSLError("EC_POINT_point2oct") + } -+ if len(dst) < aesBlockSize { -+ panic("crypto/aes: output not full block") ++ // Encode point into bytes. ++ bytes := make([]byte, n) ++ n = C.go_openssl_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, base(bytes), n, nil) ++ if n == 0 { ++ return nil, newOpenSSLError("EC_POINT_point2oct") + } -+ 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])) ++ return bytes, nil ++} + -+ 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") -+ } ++// generateAndEncodeEcPublicKey calls newPubKeyPointFn to generate a public key point and then encodes it. ++func generateAndEncodeEcPublicKey(nid C.int, newPubKeyPointFn func(group C.GO_EC_GROUP_PTR) (C.GO_EC_POINT_PTR, error)) ([]byte, error) { ++ group := C.go_openssl_EC_GROUP_new_by_curve_name(nid) ++ if group == nil { ++ return nil, newOpenSSLError("EC_GROUP_new_by_curve_name") + } -+ // 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") ++ defer C.go_openssl_EC_GROUP_free(group) ++ pt, err := newPubKeyPointFn(group) ++ if err != nil { ++ return nil, err + } -+ 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) ++ defer C.go_openssl_EC_POINT_free(pt) ++ return encodeEcPoint(group, pt) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ecdh.go b/src/vendor/github.com/golang-fips/openssl/v2/ecdh.go +new file mode 100644 +index 0000000000..62e23333ce +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/ecdh.go +@@ -0,0 +1,323 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++ "runtime" ++ "unsafe" ++) + -+type aesCBC struct { -+ key []byte -+ mode C.int -+ iv [aesBlockSize]byte -+ ctx *C.EVP_CIPHER_CTX ++type PublicKeyECDH struct { ++ _pkey C.GO_EVP_PKEY_PTR ++ bytes []byte +} + -+func (x *aesCBC) BlockSize() int { return aesBlockSize } ++func (k *PublicKeyECDH) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} + -+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) -+ } ++type PrivateKeyECDH struct { ++ _pkey C.GO_EVP_PKEY_PTR ++ curve string ++ hasPublicKey bool +} + -+func (x *aesCBC) SetIV(iv []byte) { -+ if len(iv) != aesBlockSize { -+ panic("cipher: incorrect length IV") ++func (k *PrivateKeyECDH) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { ++ if len(bytes) < 1 { ++ return nil, errors.New("NewPublicKeyECDH: missing key") + } -+ 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") ++ pkey, err := newECDHPkey(curve, bytes, false) ++ if err != nil { ++ return nil, err + } ++ k := &PublicKeyECDH{pkey, append([]byte(nil), bytes...)} ++ runtime.SetFinalizer(k, (*PublicKeyECDH).finalize) ++ return k, nil +} + -+func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { -+ x := &aesCBC{key: c.key, mode: C.GO_AES_ENCRYPT} -+ copy(x.iv[:], iv) ++func (k *PublicKeyECDH) Bytes() []byte { return k.bytes } + -+ x.ctx = C._goboringcrypto_EVP_CIPHER_CTX_new() -+ if x.ctx == nil { -+ panic("cipher: unable to create EVP cipher ctx") ++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 ++} + -+ 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") ++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 pkey C.GO_EVP_PKEY_PTR ++ defer func() { ++ C.go_openssl_EVP_PKEY_free(pkey) ++ }() + -+ runtime.SetFinalizer(x, (*aesCBC).finalize) ++ var bytes []byte ++ switch vMajor { ++ case 1: ++ pkey = C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new") ++ } ++ key := getECKey(k._pkey) ++ if C.go_openssl_EVP_PKEY_set1_EC_KEY(pkey, key) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_set1_EC_KEY") ++ } ++ pt := C.go_openssl_EC_KEY_get0_public_key(key) ++ if pt == nil { ++ return nil, newOpenSSLError("EC_KEY_get0_public_key") ++ } ++ group := C.go_openssl_EC_KEY_get0_group(key) ++ var err error ++ bytes, err = encodeEcPoint(group, pt) ++ if err != nil { ++ return nil, err ++ } ++ case 3: ++ pkey = k._pkey ++ if C.go_openssl_EVP_PKEY_up_ref(pkey) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_up_ref") ++ } + -+ return x ++ var cbytes *C.uchar ++ n := C.go_openssl_EVP_PKEY_get1_encoded_public_key(k._pkey, &cbytes) ++ if n == 0 { ++ return nil, newOpenSSLError("EVP_PKEY_get_octet_string_param") ++ } ++ bytes = C.GoBytes(unsafe.Pointer(cbytes), C.int(n)) ++ cryptoFree(unsafe.Pointer(cbytes)) ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ pub := &PublicKeyECDH{pkey, bytes} ++ pkey = nil ++ runtime.SetFinalizer(pub, (*PublicKeyECDH).finalize) ++ return pub, nil +} + -+func (c *aesCBC) finalize() { -+ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++func newECDHPkey(curve string, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, error) { ++ nid, err := curveNID(curve) ++ if err != nil { ++ return nil, err ++ } ++ switch vMajor { ++ case 1: ++ return newECDHPkey1(nid, bytes, isPrivate) ++ case 3: ++ return newECDHPkey3(nid, bytes, isPrivate) ++ default: ++ panic(errUnsupportedVersion()) ++ } +} + -+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") ++func newECDHPkey1(nid C.int, bytes []byte, isPrivate bool) (pkey C.GO_EVP_PKEY_PTR, err error) { ++ if vMajor != 1 { ++ panic("incorrect vMajor version") + } ++ key := C.go_openssl_EC_KEY_new_by_curve_name(nid) ++ if key == nil { ++ return nil, newOpenSSLError("EC_KEY_new_by_curve_name") ++ } ++ defer func() { ++ if pkey == nil { ++ C.go_openssl_EC_KEY_free(key) ++ } ++ }() ++ if isPrivate { ++ priv := C.go_openssl_BN_bin2bn(base(bytes), C.int(len(bytes)), nil) ++ if priv == nil { ++ return nil, newOpenSSLError("BN_bin2bn") ++ } ++ defer C.go_openssl_BN_clear_free(priv) ++ if C.go_openssl_EC_KEY_set_private_key(key, priv) != 1 { ++ return nil, newOpenSSLError("EC_KEY_set_private_key") ++ } ++ } else { ++ group := C.go_openssl_EC_KEY_get0_group(key) ++ pub := C.go_openssl_EC_POINT_new(group) ++ if pub == nil { ++ return nil, newOpenSSLError("EC_POINT_new") ++ } ++ defer C.go_openssl_EC_POINT_free(pub) ++ if C.go_openssl_EC_POINT_oct2point(group, pub, base(bytes), C.size_t(len(bytes)), nil) != 1 { ++ return nil, errors.New("point not on curve") ++ } ++ if C.go_openssl_EC_KEY_set_public_key(key, pub) != 1 { ++ return nil, newOpenSSLError("EC_KEY_set_public_key") ++ } ++ } ++ return newEVPPKEY(key) ++} + -+ 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") ++func newECDHPkey3(nid C.int, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, error) { ++ if vMajor != 3 { ++ panic("incorrect vMajor version") + } -+ 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") ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") + } -+ if C.int(1) != C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) { -+ panic("cipher: unable to set padding") ++ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) ++ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramGroup, C.go_openssl_OBJ_nid2sn(nid), 0) ++ var selection C.int ++ if isPrivate { ++ priv := C.go_openssl_BN_bin2bn(base(bytes), C.int(len(bytes)), nil) ++ if priv == nil { ++ return nil, newOpenSSLError("BN_bin2bn") ++ } ++ defer C.go_openssl_BN_clear_free(priv) ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, paramPrivKey, priv) != 1 { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ } ++ selection = C.GO_EVP_PKEY_KEYPAIR ++ } else { ++ cbytes := C.CBytes(bytes) ++ defer C.free(cbytes) ++ C.go_openssl_OSSL_PARAM_BLD_push_octet_string(bld, paramPubKey, cbytes, C.size_t(len(bytes))) ++ selection = C.GO_EVP_PKEY_PUBLIC_KEY + } -+ -+ runtime.SetFinalizer(x, (*aesCBC).finalize) -+ return x ++ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ if params == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_to_param") ++ } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ return newEvpFromParams(C.GO_EVP_PKEY_EC, selection, params) +} + -+type aesCTR struct { -+ key []byte -+ iv [aesBlockSize]byte -+ ctx *C.EVP_CIPHER_CTX -+ num C.uint -+ ecount_buf [16]C.uint8_t ++// deriveEcdhPublicKey sets the raw public key of pkey by deriving it from ++// the raw private key. ++func deriveEcdhPublicKey(pkey C.GO_EVP_PKEY_PTR, curve string) error { ++ derive := func(group C.GO_EC_GROUP_PTR, priv C.GO_BIGNUM_PTR) (C.GO_EC_POINT_PTR, error) { ++ // 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 ++ pt := C.go_openssl_EC_POINT_new(group) ++ if pt == nil { ++ return nil, newOpenSSLError("EC_POINT_new") ++ } ++ if C.go_openssl_EC_POINT_mul(group, pt, priv, nil, nil, nil) == 0 { ++ C.go_openssl_EC_POINT_free(pt) ++ return nil, newOpenSSLError("EC_POINT_mul") ++ } ++ return pt, nil ++ } ++ switch vMajor { ++ case 1: ++ key := getECKey(pkey) ++ priv := C.go_openssl_EC_KEY_get0_private_key(key) ++ if priv == nil { ++ return newOpenSSLError("EC_KEY_get0_private_key") ++ } ++ group := C.go_openssl_EC_KEY_get0_group(key) ++ pub, err := derive(group, priv) ++ if err != nil { ++ return err ++ } ++ defer C.go_openssl_EC_POINT_free(pub) ++ if C.go_openssl_EC_KEY_set_public_key(key, pub) != 1 { ++ return newOpenSSLError("EC_KEY_set_public_key") ++ } ++ case 3: ++ var priv C.GO_BIGNUM_PTR ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramPrivKey, &priv) != 1 { ++ return newOpenSSLError("EVP_PKEY_get_bn_param") ++ } ++ defer C.go_openssl_BN_clear_free(priv) ++ nid, _ := curveNID(curve) ++ pubBytes, err := generateAndEncodeEcPublicKey(nid, func(group C.GO_EC_GROUP_PTR) (C.GO_EC_POINT_PTR, error) { ++ return derive(group, priv) ++ }) ++ if err != nil { ++ return err ++ } ++ if C.go_openssl_EVP_PKEY_set1_encoded_public_key(pkey, base(pubBytes), C.size_t(len(pubBytes))) != 1 { ++ return newOpenSSLError("EVP_PKEY_set1_encoded_public_key") ++ } ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ return nil +} + -+func (x *aesCTR) XORKeyStream(dst, src []byte) { -+ if inexactOverlap(dst, src) { -+ panic("crypto/cipher: invalid buffer overlap") ++func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { ++ defer runtime.KeepAlive(priv) ++ defer runtime.KeepAlive(pub) ++ ctx := C.go_openssl_EVP_PKEY_CTX_new(priv._pkey, nil) ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new") + } -+ if len(dst) < len(src) { -+ panic("crypto/cipher: output smaller than input") ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") + } -+ if len(src) == 0 { -+ return ++ if C.go_openssl_EVP_PKEY_derive_set_peer(ctx, pub._pkey) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_set_peer") + } -+ 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) ++ var outLen C.size_t ++ if C.go_openssl_EVP_PKEY_derive(ctx, nil, &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") ++ } ++ out := make([]byte, outLen) ++ if C.go_openssl_EVP_PKEY_derive(ctx, base(out), &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") ++ } ++ return out, nil +} + -+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") ++func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { ++ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve) ++ if err != nil { ++ return nil, nil, err + } -+ -+ 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") ++ var k *PrivateKeyECDH ++ defer func() { ++ if k == nil { ++ C.go_openssl_EVP_PKEY_free(pkey) + } -+ 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") ++ }() ++ var priv C.GO_BIGNUM_PTR ++ switch vMajor { ++ case 1: ++ key := getECKey(pkey) ++ priv = C.go_openssl_EC_KEY_get0_private_key(key) ++ if priv == nil { ++ return nil, nil, newOpenSSLError("EC_KEY_get0_private_key") + } -+ 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") ++ case 3: ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramPrivKey, &priv) != 1 { ++ return nil, nil, newOpenSSLError("EVP_PKEY_get_bn_param") + } ++ defer C.go_openssl_BN_clear_free(priv) ++ default: ++ panic(errUnsupportedVersion()) + } -+ -+ runtime.SetFinalizer(x, (*aesCTR).finalize) -+ -+ return x -+} -+ -+func (c *aesCTR) finalize() { -+ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++ // 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.go_openssl_EVP_PKEY_get_bits(pkey) ++ bytes := make([]byte, (bits+7)/8) ++ if err := bnToBinPad(priv, bytes); err != nil { ++ return nil, nil, err ++ } ++ k = &PrivateKeyECDH{pkey, curve, true} ++ runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) ++ return k, bytes, nil +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go b/src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go +new file mode 100644 +index 0000000000..46b16abf48 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go +@@ -0,0 +1,217 @@ ++//go:build !cmd_go_bootstrap + -+type aesGCM struct { -+ key []byte -+ tls bool -+} ++package openssl + -+const ( -+ gcmBlockSize = 16 -+ gcmTagSize = 16 -+ gcmStandardNonceSize = 12 ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "errors" ++ "runtime" +) + -+type aesNonceSizeError int ++type PrivateKeyECDSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} + -+func (n aesNonceSizeError) Error() string { -+ return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n)) ++func (k *PrivateKeyECDSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+type noGCM struct { -+ cipher.Block ++func (k *PrivateKeyECDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) +} + -+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) ++type PublicKeyECDSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR +} + -+// 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 (k *PublicKeyECDSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) { -+ return c.newGCM(true) ++func (k *PublicKeyECDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) +} + -+func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) { -+ keyLen := len(c.key) * 8 ++var errUnknownCurve = errors.New("openssl: unknown elliptic curve") + -+ 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") ++func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) { ++ pkey, err := newECDSAKey(curve, X, Y, nil) ++ if err != nil { ++ return nil, err + } ++ k := &PublicKeyECDSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PublicKeyECDSA).finalize) ++ return k, nil ++} + -+ g := &aesGCM{key: c.key, tls: tls} -+ if g.NonceSize() != gcmStandardNonceSize { -+ panic("boringcrypto: internal confusion about nonce size") ++func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error) { ++ pkey, err := newECDSAKey(curve, X, Y, D) ++ if err != nil { ++ return nil, err + } -+ if g.Overhead() != gcmTagSize { -+ panic("boringcrypto: internal confusion about tag size") ++ k := &PrivateKeyECDSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PrivateKeyECDSA).finalize) ++ return k, nil ++} ++ ++func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) { ++ // Generate the private key. ++ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve) ++ if err != nil { ++ return nil, nil, nil, err + } ++ defer C.go_openssl_EVP_PKEY_free(pkey) + -+ return g, nil -+} ++ var bx, by, bd C.GO_BIGNUM_PTR ++ defer func() { ++ C.go_openssl_BN_free(bx) ++ C.go_openssl_BN_free(by) ++ }() ++ switch vMajor { ++ case 1: ++ // Retrieve the internal EC_KEY, which holds the X, Y, and D coordinates. ++ key := getECKey(pkey) ++ group := C.go_openssl_EC_KEY_get0_group(key) ++ pt := C.go_openssl_EC_KEY_get0_public_key(key) ++ // Allocate two big numbers to store the X and Y coordinates. ++ bx, by = C.go_openssl_BN_new(), C.go_openssl_BN_new() ++ if bx == nil || by == nil { ++ return nil, nil, nil, newOpenSSLError("BN_new failed") ++ } ++ // Get X and Y. ++ if C.go_openssl_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 { ++ return nil, nil, nil, newOpenSSLError("EC_POINT_get_affine_coordinates_GFp failed") ++ } ++ // Get Z. We don't need to free it, get0 does not increase the reference count. ++ bd = C.go_openssl_EC_KEY_get0_private_key(key) ++ case 3: ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramECPubX, &bx) != 1 || ++ C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramECPubY, &by) != 1 || ++ C.go_openssl_EVP_PKEY_get_bn_param(pkey, paramPrivKey, &bd) != 1 { ++ return nil, nil, nil, newOpenSSLError("EVP_PKEY_get_bn_param") ++ } ++ defer C.go_openssl_BN_clear_free(bd) ++ default: ++ panic(errUnsupportedVersion()) ++ } + -+func (g *aesGCM) NonceSize() int { -+ return gcmStandardNonceSize ++ // Get D. ++ return bnToBig(bx), bnToBig(by), bnToBig(bd), nil +} + -+func (g *aesGCM) Overhead() int { -+ return gcmTagSize ++func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { ++ return evpSign(priv.withKey, 0, 0, 0, hash) +} + -+// 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 HashSignECDSA(priv *PrivateKeyECDSA, h crypto.Hash, msg []byte) ([]byte, error) { ++ return evpHashSign(priv.withKey, h, msg) +} + -+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") -+ } ++func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool { ++ return evpVerify(pub.withKey, 0, 0, 0, sig, hash) == nil ++} + -+ var ciphertextLen C.size_t ++func HashVerifyECDSA(pub *PublicKeyECDSA, h crypto.Hash, msg, sig []byte) bool { ++ return evpHashVerify(pub.withKey, h, msg, sig) == nil ++} + -+ 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") ++func newECDSAKey(curve string, X, Y, D BigInt) (C.GO_EVP_PKEY_PTR, error) { ++ nid, err := curveNID(curve) ++ if err != nil { ++ return nil, err + } -+ runtime.KeepAlive(g) -+ -+ if ciphertextLen != C.size_t(len(plaintext)+gcmTagSize) { -+ panic("boringcrypto: [seal] internal confusion about GCM tag size") ++ var bx, by, bd C.GO_BIGNUM_PTR ++ defer func() { ++ C.go_openssl_BN_free(bx) ++ C.go_openssl_BN_free(by) ++ C.go_openssl_BN_clear_free(bd) ++ }() ++ bx = bigToBN(X) ++ by = bigToBN(Y) ++ bd = bigToBN(D) ++ if bx == nil || by == nil || (D != nil && bd == nil) { ++ return nil, newOpenSSLError("BN_lebin2bn failed") ++ } ++ switch vMajor { ++ case 1: ++ return newECDSAKey1(nid, bx, by, bd) ++ case 3: ++ return newECDSAKey3(nid, bx, by, bd) ++ default: ++ panic(errUnsupportedVersion()) + } -+ 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") ++func newECDSAKey1(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (pkey C.GO_EVP_PKEY_PTR, err error) { ++ if vMajor != 1 { ++ panic("incorrect vMajor version") + } -+ if len(ciphertext) < gcmTagSize { -+ return nil, errOpen ++ key := C.go_openssl_EC_KEY_new_by_curve_name(nid) ++ if key == nil { ++ return nil, newOpenSSLError("EC_KEY_new_by_curve_name failed") + } -+ if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize { -+ return nil, errOpen ++ defer func() { ++ if pkey == nil { ++ defer C.go_openssl_EC_KEY_free(key) ++ } ++ }() ++ if C.go_openssl_EC_KEY_set_public_key_affine_coordinates(key, bx, by) != 1 { ++ return nil, newOpenSSLError("EC_KEY_set_public_key_affine_coordinates failed") + } -+ -+ // 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) ++ if bd != nil && C.go_openssl_EC_KEY_set_private_key(key, bd) != 1 { ++ return nil, newOpenSSLError("EC_KEY_set_private_key failed") + } -+ dst = dst[:n+len(ciphertext)-gcmTagSize] ++ return newEVPPKEY(key) ++} + -+ // Check delayed until now to make sure len(dst) is accurate. -+ if inexactOverlap(dst[n:], ciphertext) { -+ panic("cipher: invalid buffer overlap") ++func newECDSAKey3(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (C.GO_EVP_PKEY_PTR, error) { ++ if vMajor != 3 { ++ panic("incorrect vMajor version") + } -+ -+ 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 ++ // Create the encoded public key public key from bx and by. ++ pubBytes, err := generateAndEncodeEcPublicKey(nid, func(group C.GO_EC_GROUP_PTR) (C.GO_EC_POINT_PTR, error) { ++ pt := C.go_openssl_EC_POINT_new(group) ++ if pt == nil { ++ return nil, newOpenSSLError("EC_POINT_new") + } -+ return nil, errOpen ++ if C.go_openssl_EC_POINT_set_affine_coordinates(group, pt, bx, by, nil) != 1 { ++ C.go_openssl_EC_POINT_free(pt) ++ return nil, newOpenSSLError("EC_POINT_set_affine_coordinates") ++ } ++ return pt, nil ++ }) ++ if err != nil { ++ return nil, err + } -+ if outLen != C.size_t(len(ciphertext)-gcmTagSize) { -+ panic("boringcrypto: [open] internal confusion about GCM tag size") ++ // Construct the parameters. ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") ++ } ++ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) ++ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramGroup, C.go_openssl_OBJ_nid2sn(nid), 0) ++ cbytes := C.CBytes(pubBytes) ++ defer C.free(cbytes) ++ C.go_openssl_OSSL_PARAM_BLD_push_octet_string(bld, paramPubKey, cbytes, C.size_t(len(pubBytes))) ++ var selection C.int ++ if bd != nil { ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, paramPrivKey, bd) != 1 { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ } ++ selection = C.GO_EVP_PKEY_KEYPAIR ++ } else { ++ selection = C.GO_EVP_PKEY_PUBLIC_KEY + } -+ 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 ++ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ if params == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_to_param") + } -+ 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 ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ return newEvpFromParams(C.GO_EVP_PKEY_EC, selection, params) +} -+ -+// 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 +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go new file mode 100644 -index 0000000000..56adf47bf6 +index 0000000000..f66a2a1deb --- /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 ++++ b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go +@@ -0,0 +1,218 @@ ++//go:build !cmd_go_bootstrap + +package openssl + @@ -2961,418 +5307,347 @@ index 0000000000..56adf47bf6 +import ( + "errors" + "runtime" ++ "strconv" ++ "sync" + "unsafe" +) + ++const ( ++ // publicKeySizeEd25519 is the size, in bytes, of public keys as used in crypto/ed25519. ++ publicKeySizeEd25519 = 32 ++ // privateKeySizeEd25519 is the size, in bytes, of private keys as used in crypto/ed25519. ++ privateKeySizeEd25519 = 64 ++ // signatureSizeEd25519 is the size, in bytes, of signatures generated and verified by crypto/ed25519. ++ signatureSizeEd25519 = 64 ++ // seedSizeEd25519 is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. ++ seedSizeEd25519 = 32 ++) ++ ++// TODO: Add support for Ed25519ph and Ed25519ctx when OpenSSL supports them, ++// which will probably be in 3.2.0 (https://github.com/openssl/openssl/issues/20418). ++ +var ( -+ paramPrivKey = C.CString("priv") ++ onceSupportsEd25519 sync.Once ++ supportsEd25519 bool +) + -+type PublicKeyECDH struct { -+ _pkey *C.GO_EVP_PKEY -+ bytes []byte ++// SupportsEd25519 returns true if the current OpenSSL version supports ++// GenerateKeyEd25519, NewKeyFromSeedEd25519, SignEd25519 and VerifyEd25519. ++func SupportsEd25519() bool { ++ onceSupportsEd25519.Do(func() { ++ switch vMajor { ++ case 1: ++ supportsEd25519 = versionAtOrAbove(1, 1, 1) ++ case 3: ++ name := C.CString("ED25519") ++ defer C.free(unsafe.Pointer(name)) ++ sig := C.go_openssl_EVP_SIGNATURE_fetch(nil, name, nil) ++ if sig != nil { ++ C.go_openssl_EVP_SIGNATURE_free(sig) ++ supportsEd25519 = true ++ } ++ } ++ }) ++ return supportsEd25519 ++} + -+ // 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 ++type PublicKeyEd25519 struct { ++ _pkey C.GO_EVP_PKEY_PTR +} + -+func (k *PublicKeyECDH) finalize() { -+ if k.priv == nil { -+ C._goboringcrypto_EVP_PKEY_free(k._pkey) ++func (k *PublicKeyEd25519) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PublicKeyEd25519) Bytes() ([]byte, error) { ++ defer runtime.KeepAlive(k) ++ pub := make([]byte, publicKeySizeEd25519) ++ if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { ++ return nil, err + } ++ return pub, nil +} + -+type PrivateKeyECDH struct { -+ _pkey *C.GO_EVP_PKEY -+ curve string -+ hasPublicKey bool ++type PrivateKeyEd25519 struct { ++ _pkey C.GO_EVP_PKEY_PTR +} + -+func (k *PrivateKeyECDH) finalize() { -+ C._goboringcrypto_EVP_PKEY_free(k._pkey) ++func (k *PrivateKeyEd25519) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { -+ if len(bytes) < 1 { -+ return nil, errors.New("NewPublicKeyECDH: missing key") ++func (k *PrivateKeyEd25519) Bytes() ([]byte, error) { ++ defer runtime.KeepAlive(k) ++ priv := make([]byte, privateKeySizeEd25519) ++ if err := extractPKEYPrivEd25519(k._pkey, priv); err != nil { ++ return nil, err + } -+ pkey, err := newECDHPkey(curve, bytes, false) ++ return priv, nil ++} ++ ++func (k *PrivateKeyEd25519) Public() (*PublicKeyEd25519, error) { ++ pub := make([]byte, publicKeySizeEd25519) ++ if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { ++ return nil, err ++ } ++ pubk, err := NewPublicKeyEd25119(pub) + if err != nil { + return nil, err + } -+ k := &PublicKeyECDH{pkey, append([]byte(nil), bytes...), nil} -+ runtime.SetFinalizer(k, (*PublicKeyECDH).finalize) -+ return k, nil ++ return pubk, nil +} + -+func (k *PublicKeyECDH) Bytes() []byte { return k.bytes } -+ -+func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { -+ pkey, err := newECDHPkey(curve, bytes, true) ++// GenerateKeyEd25519 generates a private key. ++func GenerateKeyEd25519() (*PrivateKeyEd25519, error) { ++ pkeyPriv, err := generateEVPPKey(C.GO_EVP_PKEY_ED25519, 0, "") + if err != nil { + return nil, err + } -+ k := &PrivateKeyECDH{pkey, curve, false} -+ runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) -+ return k, nil ++ priv := &PrivateKeyEd25519{_pkey: pkeyPriv} ++ runtime.SetFinalizer(priv, (*PrivateKeyEd25519).finalize) ++ return priv, 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 ++func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { ++ if len(priv) != privateKeySizeEd25519 { ++ panic("ed25519: bad private key length: " + strconv.Itoa(len(priv))) + } -+ var bytes []byte -+ var cbytes *C.uchar ++ return NewPrivateKeyEd25519FromSeed(priv[:seedSizeEd25519]) ++} + -+ 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") ++func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { ++ if len(pub) != publicKeySizeEd25519 { ++ panic("ed25519: bad public key length: " + strconv.Itoa(len(pub))) + } -+ 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 ++ pkey := C.go_openssl_EVP_PKEY_new_raw_public_key(C.GO_EVP_PKEY_ED25519, nil, base(pub), C.size_t(len(pub))) ++ if pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new_raw_public_key") ++ } ++ pubk := &PublicKeyEd25519{_pkey: pkey} ++ runtime.SetFinalizer(pubk, (*PublicKeyEd25519).finalize) ++ return pubk, nil +} + -+func newECDHPkey(curve string, bytes []byte, isPrivate bool) (*C.GO_EVP_PKEY, error) { -+ nid, err := curveNID(curve) -+ if err != nil { -+ return nil, err ++// NewPrivateKeyEd25519FromSeed calculates a private key from a seed. It will panic if ++// len(seed) is not [SeedSize]. RFC 8032's private keys correspond to seeds in this ++// package. ++func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { ++ if len(seed) != seedSizeEd25519 { ++ panic("ed25519: bad seed length: " + strconv.Itoa(len(seed))) + } -+ -+ 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") -+ } ++ pkey := C.go_openssl_EVP_PKEY_new_raw_private_key(C.GO_EVP_PKEY_ED25519, nil, base(seed), C.size_t(len(seed))) ++ if pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new_raw_private_key") + } ++ priv := &PrivateKeyEd25519{_pkey: pkey} ++ runtime.SetFinalizer(priv, (*PrivateKeyEd25519).finalize) ++ return priv, nil ++} + -+ 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") ++func extractPKEYPubEd25519(pkey C.GO_EVP_PKEY_PTR, pub []byte) error { ++ pubSize := C.size_t(publicKeySizeEd25519) ++ if C.go_openssl_EVP_PKEY_get_raw_public_key(pkey, base(pub), &pubSize) != 1 { ++ return newOpenSSLError("EVP_PKEY_get_raw_public_key") ++ } ++ if pubSize != publicKeySizeEd25519 { ++ return errors.New("ed25519: bad public key length: " + strconv.Itoa(int(pubSize))) + } -+ return key, nil ++ return 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") ++func extractPKEYPrivEd25519(pkey C.GO_EVP_PKEY_PTR, priv []byte) error { ++ if err := extractPKEYPubEd25519(pkey, priv[seedSizeEd25519:]); err != nil { ++ return err ++ } ++ privSize := C.size_t(seedSizeEd25519) ++ if C.go_openssl_EVP_PKEY_get_raw_private_key(pkey, base(priv), &privSize) != 1 { ++ return newOpenSSLError("EVP_PKEY_get_raw_private_key") ++ } ++ if privSize != seedSizeEd25519 { ++ return errors.New("ed25519: bad private key length: " + strconv.Itoa(int(privSize))) + } + 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") ++// SignEd25519 signs the message with priv and returns a signature. ++func SignEd25519(priv *PrivateKeyEd25519, message []byte) (sig []byte, err error) { ++ // Outline the function body so that the returned key can be stack-allocated. ++ sig = make([]byte, signatureSizeEd25519) ++ err = signEd25519(priv, sig, message) ++ if err != nil { ++ return nil, err + } -+ return bytes, nil ++ return sig, err +} + -+func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { ++func signEd25519(priv *PrivateKeyEd25519, sig, message []byte) error { + defer runtime.KeepAlive(priv) -+ defer runtime.KeepAlive(pub) -+ ctx := C._goboringcrypto_EVP_PKEY_CTX_new(priv._pkey, nil) ++ ctx := C.go_openssl_EVP_MD_CTX_new() + if ctx == nil { -+ return nil, NewOpenSSLError("EVP_PKEY_CTX_new") ++ return newOpenSSLError("EVP_MD_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") ++ defer C.go_openssl_EVP_MD_CTX_free(ctx) ++ if C.go_openssl_EVP_DigestSignInit(ctx, nil, nil, nil, priv._pkey) != 1 { ++ return newOpenSSLError("EVP_DigestSignInit") + } -+ if C._goboringcrypto_EVP_PKEY_derive_set_peer_ex(ctx, pub._pkey, 1) != 1 { -+ return nil, NewOpenSSLError("EVP_PKEY_derive_set_peer_ex") ++ siglen := C.size_t(signatureSizeEd25519) ++ if C.go_openssl_EVP_DigestSign(ctx, base(sig), &siglen, base(message), C.size_t(len(message))) != 1 { ++ return newOpenSSLError("EVP_DigestSign") + } -+ 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") ++ if siglen != signatureSizeEd25519 { ++ return errors.New("ed25519: bad signature length: " + strconv.Itoa(int(siglen))) + } -+ return out, nil ++ return 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 ++// VerifyEd25519 reports whether sig is a valid signature of message by pub. ++func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error { ++ defer runtime.KeepAlive(pub) ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if ctx == nil { ++ return newOpenSSLError("EVP_MD_CTX_new") + } -+ 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) ++ defer C.go_openssl_EVP_MD_CTX_free(ctx) ++ if C.go_openssl_EVP_DigestVerifyInit(ctx, nil, nil, nil, pub._pkey) != 1 { ++ return newOpenSSLError("EVP_DigestVerifyInit") + } -+ // 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") ++ if C.go_openssl_EVP_DigestVerify(ctx, base(sig), C.size_t(len(sig)), base(message), C.size_t(len(message))) != 1 { ++ return errors.New("ed25519: invalid signature") + } -+ k = &PrivateKeyECDH{pkey, curve, true} -+ runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) -+ return k, bytes, nil ++ return 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 +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/evp.go b/src/vendor/github.com/golang-fips/openssl/v2/evp.go +new file mode 100644 +index 0000000000..b2886e6906 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/evp.go +@@ -0,0 +1,471 @@ ++//go:build !cmd_go_bootstrap ++ +package openssl - --// #include "goboringcrypto.h" ++ +// #include "goopenssl.h" - import "C" - import ( ++import "C" ++import ( + "crypto" -+ "encoding/asn1" - "errors" -+ "math/big" - "runtime" ++ "errors" ++ "hash" ++ "strconv" ++ "sync" + "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 ++// cacheMD is a cache of crypto.Hash to GO_EVP_MD_PTR. ++var cacheMD sync.Map ++ ++// hashToMD converts a hash.Hash implementation from this package to a GO_EVP_MD_PTR. ++func hashToMD(h hash.Hash) C.GO_EVP_MD_PTR { ++ var ch crypto.Hash ++ switch h.(type) { ++ case *sha1Hash: ++ ch = crypto.SHA1 ++ case *sha224Hash: ++ ch = crypto.SHA224 ++ case *sha256Hash: ++ ch = crypto.SHA256 ++ case *sha384Hash: ++ ch = crypto.SHA384 ++ case *sha512Hash: ++ ch = crypto.SHA512 ++ case *sha3_224Hash: ++ ch = crypto.SHA3_224 ++ case *sha3_256Hash: ++ ch = crypto.SHA3_256 ++ case *sha3_384Hash: ++ ch = crypto.SHA3_384 ++ case *sha3_512Hash: ++ ch = crypto.SHA3_512 ++ } ++ if ch != 0 { ++ return cryptoHashToMD(ch) ++ } ++ return nil +} + -+func HashVerifyECDSA(pub *PublicKeyECDSA, msg []byte, r, s *big.Int, h crypto.Hash) bool { -+ md := cryptoHashToMD(h) -+ if md == nil { -+ panic("boring: invalid hash") ++// cryptoHashToMD converts a crypto.Hash to a GO_EVP_MD_PTR. ++func cryptoHashToMD(ch crypto.Hash) (md C.GO_EVP_MD_PTR) { ++ if v, ok := cacheMD.Load(ch); ok { ++ return v.(C.GO_EVP_MD_PTR) + } -+ sig, err := asn1.Marshal(ecdsaSignature{r, s}) -+ if err != nil { -+ return false ++ defer func() { ++ if md != nil && vMajor == 3 { ++ // On OpenSSL 3, directly operating on a EVP_MD object ++ // not created by EVP_MD_fetch has negative performance ++ // implications, as digest operations will have ++ // to fetch it on every call. Better to just fetch it once here. ++ md = C.go_openssl_EVP_MD_fetch(nil, C.go_openssl_EVP_MD_get0_name(md), nil) ++ } ++ cacheMD.Store(ch, md) ++ }() ++ // SupportsHash returns false for MD5SHA1 because we don't ++ // provide a hash.Hash implementation for it. Yet, it can ++ // still be used when signing/verifying with an RSA key. ++ if ch == crypto.MD5SHA1 { ++ if vMajor == 1 && vMinor == 0 { ++ return C.go_openssl_EVP_md5_sha1_backport() ++ } else { ++ return C.go_openssl_EVP_md5_sha1() ++ } + } -+ 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" ++ switch ch { ++ case crypto.MD4: ++ if versionAtOrAbove(1, 1, 0) || !FIPS() { ++ return C.go_openssl_EVP_md4() ++ } ++ case crypto.MD5: ++ if versionAtOrAbove(1, 1, 0) || !FIPS() { ++ return C.go_openssl_EVP_md5() ++ } ++ case crypto.SHA1: ++ return C.go_openssl_EVP_sha1() ++ case crypto.SHA224: ++ return C.go_openssl_EVP_sha224() ++ case crypto.SHA256: ++ return C.go_openssl_EVP_sha256() ++ case crypto.SHA384: ++ return C.go_openssl_EVP_sha384() ++ case crypto.SHA512: ++ return C.go_openssl_EVP_sha512() ++ case crypto.SHA3_224: ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_224() ++ } ++ case crypto.SHA3_256: ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_256() ++ } ++ case crypto.SHA3_384: ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_384() ++ } ++ case crypto.SHA3_512: ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_512() ++ } ++ } ++ return nil ++} + -+func generateEVPPKey(id C.int, bits int, curve string) (*C.GO_EVP_PKEY, error) { -+ if (bits == 0 && curve == "") || (bits != 0 && curve != "") { ++func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error) { ++ if bits != 0 && curve != "" { + return nil, fail("incorrect generateEVPPKey parameters") + } -+ ctx := C._goboringcrypto_EVP_PKEY_CTX_new_id(id, nil) ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) + if ctx == nil { -+ return nil, NewOpenSSLError("EVP_PKEY_CTX_new_id failed") ++ 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") ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ if C.go_openssl_EVP_PKEY_keygen_init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_keygen_init 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 C.go_openssl_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 != "" { @@ -3380,1796 +5655,2314 @@ index 0000000000..46d2bdd068 + 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") ++ if C.go_openssl_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") ++ var pkey C.GO_EVP_PKEY_PTR ++ if C.go_openssl_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 ++type withKeyFunc func(func(C.GO_EVP_PKEY_PTR) C.int) C.int ++type initFunc func(C.GO_EVP_PKEY_CTX_PTR) error ++type cryptFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, *C.size_t, *C.uchar, C.size_t) error ++type verifyFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, C.size_t, *C.uchar, C.size_t) error + -+// This header file describes the OpenSSL ABI as built for use in Go. ++func setupEVP(withKey withKeyFunc, padding C.int, ++ h, mgfHash hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, ++ init initFunc) (ctx C.GO_EVP_PKEY_CTX_PTR, err error) { ++ defer func() { ++ if err != nil { ++ if ctx != nil { ++ C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ ctx = nil ++ } ++ } ++ }() + -+#include // size_t -+#include // uint8_t -+#include // memset ++ withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { ++ ctx = C.go_openssl_EVP_PKEY_CTX_new(pkey, nil) ++ return 1 ++ }) ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new failed") ++ } ++ if err := init(ctx); err != nil { ++ return nil, err ++ } ++ if padding == 0 { ++ return ctx, nil ++ } ++ // Each padding type has its own requirements in terms of when to apply the padding, ++ // so it can't be just set at this point. ++ setPadding := func() error { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_PADDING, padding, nil) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ return nil ++ } ++ switch padding { ++ case C.GO_RSA_PKCS1_OAEP_PADDING: ++ md := hashToMD(h) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ var mgfMD C.GO_EVP_MD_PTR ++ if mgfHash != nil { ++ // mgfHash is optional, but if it is set it must match a supported hash function. ++ mgfMD = hashToMD(mgfHash) ++ if mgfMD == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ } ++ // setPadding must happen before setting EVP_PKEY_CTRL_RSA_OAEP_MD. ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_MD, 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ if mgfHash != nil { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_MGF1_MD, 0, unsafe.Pointer(mgfMD)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ // ctx takes ownership of label, so malloc a copy for OpenSSL to free. ++ // OpenSSL does not take ownership of the label if the length is zero, ++ // so better avoid the allocation. ++ var clabel *C.uchar ++ if len(label) > 0 { ++ clabel = (*C.uchar)(cryptoMalloc(len(label))) ++ copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) ++ var err error ++ if vMajor == 3 { ++ ret := C.go_openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, unsafe.Pointer(clabel), C.int(len(label))) ++ if ret != 1 { ++ err = newOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") ++ } ++ } else { ++ ret := C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL, C.int(len(label)), unsafe.Pointer(clabel)) ++ if ret != 1 { ++ err = newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ if err != nil { ++ cryptoFree(unsafe.Pointer(clabel)) ++ return nil, err ++ } ++ } ++ case C.GO_RSA_PKCS1_PSS_PADDING: ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ // setPadding must happen after setting EVP_PKEY_CTRL_MD. ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ if saltLen != 0 { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_PSS_SALTLEN, saltLen, nil) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ ++ case C.GO_RSA_PKCS1_PADDING: ++ if ch != 0 { ++ // We support unhashed messages. ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ } ++ default: ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ } ++ return ctx, nil ++} + -+#include ++func cryptEVP(withKey withKeyFunc, padding C.int, ++ h, mgfHash hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, ++ init initFunc, crypt cryptFunc, in []byte) ([]byte, error) { + -+#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 ++ ctx, err := setupEVP(withKey, padding, h, mgfHash, label, saltLen, ch, init) ++ if err != nil { ++ return nil, err ++ } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ pkeySize := withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { ++ return C.go_openssl_EVP_PKEY_get_size(pkey) ++ }) ++ outLen := C.size_t(pkeySize) ++ out := make([]byte, pkeySize) ++ if err := crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))); err != nil { ++ return nil, err ++ } ++ // The size returned by EVP_PKEY_get_size() is only preliminary and not exact, ++ // so the final contents of the out buffer may be smaller. ++ return out[:outLen], nil ++} + -+#include ++func verifyEVP(withKey withKeyFunc, padding C.int, ++ h hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, ++ init initFunc, verify verifyFunc, ++ sig, in []byte) error { + -+#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; \ ++ ctx, err := setupEVP(withKey, padding, h, nil, label, saltLen, ch, init) ++ if err != nil { ++ return err + } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ return verify(ctx, base(sig), C.size_t(len(sig)), base(in), C.size_t(len(in))) ++} + -+#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; \ ++func evpEncrypt(withKey withKeyFunc, padding C.int, h, mgfHash hash.Hash, label, msg []byte) ([]byte, error) { ++ encryptInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { ++ if ret := C.go_openssl_EVP_PKEY_encrypt_init(ctx); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_encrypt_init failed") ++ } ++ return nil + } ++ encrypt := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) error { ++ if ret := C.go_openssl_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_encrypt failed") ++ } ++ return nil ++ } ++ return cryptEVP(withKey, padding, h, mgfHash, label, 0, 0, encryptInit, encrypt, msg) ++} + -+#define DEFINEMACRO(ret, func, args, argscall) \ -+ static inline ret _goboringcrypto_##func args \ -+ { \ -+ return func argscall; \ ++func evpDecrypt(withKey withKeyFunc, padding C.int, h, mgfHash hash.Hash, label, msg []byte) ([]byte, error) { ++ decryptInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { ++ if ret := C.go_openssl_EVP_PKEY_decrypt_init(ctx); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_decrypt_init failed") ++ } ++ return nil ++ } ++ decrypt := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) error { ++ if ret := C.go_openssl_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_decrypt failed") ++ } ++ return nil + } ++ return cryptEVP(withKey, padding, h, mgfHash, label, 0, 0, decryptInit, decrypt, msg) ++} + ++func evpSign(withKey withKeyFunc, padding C.int, saltLen C.int, h crypto.Hash, hashed []byte) ([]byte, error) { ++ signtInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { ++ if ret := C.go_openssl_EVP_PKEY_sign_init(ctx); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_sign_init failed") ++ } ++ return nil ++ } ++ sign := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) error { ++ if ret := C.go_openssl_EVP_PKEY_sign(ctx, out, outLen, in, inLen); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_sign failed") ++ } ++ return nil ++ } ++ return cryptEVP(withKey, padding, nil, nil, nil, saltLen, h, signtInit, sign, hashed) ++} + -+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; ++func evpVerify(withKey withKeyFunc, padding C.int, saltLen C.int, h crypto.Hash, sig, hashed []byte) error { ++ verifyInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { ++ if ret := C.go_openssl_EVP_PKEY_verify_init(ctx); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_verify_init failed") ++ } ++ return nil ++ } ++ verify := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen C.size_t, in *C.uchar, inLen C.size_t) error { ++ if ret := C.go_openssl_EVP_PKEY_verify(ctx, out, outLen, in, inLen); ret != 1 { ++ return newOpenSSLError("EVP_PKEY_verify failed") ++ } ++ return nil ++ } ++ return verifyEVP(withKey, padding, nil, nil, saltLen, h, verifyInit, verify, sig, hashed) +} + -+#include -+#include ++func evpHashSign(withKey withKeyFunc, h crypto.Hash, msg []byte) ([]byte, error) { ++ md := cryptoHashToMD(h) ++ if md == nil { ++ return nil, errors.New("unsupported hash function: " + strconv.Itoa(int(h))) ++ } ++ var out []byte ++ var outLen C.size_t ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_MD_CTX_new failed") ++ } ++ defer C.go_openssl_EVP_MD_CTX_free(ctx) ++ if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { ++ return C.go_openssl_EVP_DigestSignInit(ctx, nil, md, nil, key) ++ }) != 1 { ++ return nil, newOpenSSLError("EVP_DigestSignInit failed") ++ } ++ if C.go_openssl_EVP_DigestUpdate(ctx, unsafe.Pointer(base(msg)), C.size_t(len(msg))) != 1 { ++ return nil, newOpenSSLError("EVP_DigestUpdate failed") ++ } ++ // Obtain the signature length ++ if C.go_openssl_EVP_DigestSignFinal(ctx, nil, &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_DigestSignFinal failed") ++ } ++ out = make([]byte, outLen) ++ // Obtain the signature ++ if C.go_openssl_EVP_DigestSignFinal(ctx, base(out), &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_DigestSignFinal failed") ++ } ++ return out[:outLen], nil ++} + -+DEFINEFUNCINTERNAL(void, OPENSSL_init, (void), ()) ++func evpHashVerify(withKey withKeyFunc, h crypto.Hash, msg, sig []byte) error { ++ md := cryptoHashToMD(h) ++ if md == nil { ++ return errors.New("unsupported hash function: " + strconv.Itoa(int(h))) ++ } ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if ctx == nil { ++ return newOpenSSLError("EVP_MD_CTX_new failed") ++ } ++ defer C.go_openssl_EVP_MD_CTX_free(ctx) ++ if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { ++ return C.go_openssl_EVP_DigestVerifyInit(ctx, nil, md, nil, key) ++ }) != 1 { ++ return newOpenSSLError("EVP_DigestVerifyInit failed") ++ } ++ if C.go_openssl_EVP_DigestUpdate(ctx, unsafe.Pointer(base(msg)), C.size_t(len(msg))) != 1 { ++ return newOpenSSLError("EVP_DigestUpdate failed") ++ } ++ if C.go_openssl_EVP_DigestVerifyFinal(ctx, base(sig), C.size_t(len(sig))) != 1 { ++ return newOpenSSLError("EVP_DigestVerifyFinal failed") ++ } ++ return nil ++} + -+static unsigned long _goboringcrypto_internal_OPENSSL_VERSION_NUMBER(void) { -+ return OPENSSL_VERSION_NUMBER; ++func newEVPPKEY(key C.GO_EC_KEY_PTR) (C.GO_EVP_PKEY_PTR, error) { ++ pkey := C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_EC, unsafe.Pointer(key)) != 1 { ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ return pkey, nil +} + -+static void -+_goboringcrypto_OPENSSL_setup(void) { -+ _goboringcrypto_internal_OPENSSL_init(); ++// 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_PTR) (key C.GO_EC_KEY_PTR) { ++ if vMajor == 1 && vMinor == 0 { ++ if key0 := C.go_openssl_EVP_PKEY_get0(pkey); key0 != nil { ++ key = C.GO_EC_KEY_PTR(key0) ++ } ++ } else { ++ key = C.go_openssl_EVP_PKEY_get0_EC_KEY(pkey) ++ } ++ if key == nil { ++ panic("pkey does not contain an EC_KEY") ++ } ++ return key +} + -+#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"; ++func newEvpFromParams(id C.int, selection C.int, params C.GO_OSSL_PARAM_PTR) (C.GO_EVP_PKEY_PTR, error) { ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") + } -+ return e; ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ if C.go_openssl_EVP_PKEY_fromdata_init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_fromdata_init") ++ } ++ var pkey C.GO_EVP_PKEY_PTR ++ if C.go_openssl_EVP_PKEY_fromdata(ctx, &pkey, selection, params) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_fromdata") ++ } ++ return pkey, nil +} -+#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)) +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c +new file mode 100644 +index 0000000000..1e428d5269 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c +@@ -0,0 +1,218 @@ ++//go:build unix || windows + -+#include ++#include "goopenssl.h" + -+#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)) ++#ifdef _WIN32 ++# include ++# define dlsym (void*)GetProcAddress +#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 */ -+} ++# include // dlsym +#endif ++#include // fprintf ++ ++// Approach taken from .Net System.Security.Cryptography.Native ++// https://github.com/dotnet/runtime/blob/f64246ce08fb7a58221b2b7c8e68f69c02522b0d/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c ++ ++#define DEFINEFUNC(ret, func, args, argscall) ret (*_g_##func)args; ++#define DEFINEFUNC_LEGACY_1_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_1_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_1_1_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_3_0(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++ ++FOR_ALL_OPENSSL_FUNCTIONS ++ ++#undef DEFINEFUNC ++#undef DEFINEFUNC_LEGACY_1_1 ++#undef DEFINEFUNC_LEGACY_1_0 ++#undef DEFINEFUNC_LEGACY_1 ++#undef DEFINEFUNC_1_1 ++#undef DEFINEFUNC_1_1_1 ++#undef DEFINEFUNC_3_0 ++#undef DEFINEFUNC_RENAMED_1_1 ++#undef DEFINEFUNC_RENAMED_3_0 + -+int _goboringcrypto_OPENSSL_thread_setup(void); ++int ++go_openssl_fips_enabled(void* handle) ++{ ++ // For OpenSSL 1.x. ++ int (*FIPS_mode)(void); ++ FIPS_mode = (int (*)(void))dlsym(handle, "FIPS_mode"); ++ if (FIPS_mode != NULL) ++ return FIPS_mode(); ++ ++ // For OpenSSL 3.x. ++ int (*EVP_default_properties_is_fips_enabled)(void*); ++ int (*OSSL_PROVIDER_available)(void*, const char*); ++ EVP_default_properties_is_fips_enabled = (int (*)(void*))dlsym(handle, "EVP_default_properties_is_fips_enabled"); ++ OSSL_PROVIDER_available = (int (*)(void*, const char*))dlsym(handle, "OSSL_PROVIDER_available"); ++ if (EVP_default_properties_is_fips_enabled != NULL && OSSL_PROVIDER_available != NULL && ++ EVP_default_properties_is_fips_enabled(NULL) == 1 && OSSL_PROVIDER_available(NULL, "fips") == 1) ++ return 1; + -+#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); ++ return 0; +} -+#endif + -+#include ++// Load all the functions stored in FOR_ALL_OPENSSL_FUNCTIONS ++// and assign them to their corresponding function pointer ++// defined in goopenssl.h. ++void ++go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch) ++{ ++#define DEFINEFUNC_INTERNAL(name, func) \ ++ _g_##name = dlsym(handle, func); \ ++ if (_g_##name == NULL) { \ ++ fprintf(stderr, "Cannot get required symbol " #func " from libcrypto version %u.%u\n", major, minor); \ ++ abort(); \ ++ } ++#define DEFINEFUNC(ret, func, args, argscall) \ ++ DEFINEFUNC_INTERNAL(func, #func) ++#define DEFINEFUNC_LEGACY_1_1(ret, func, args, argscall) \ ++ if (major == 1 && minor == 1) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) \ ++ if (major == 1 && minor == 0) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) \ ++ if (major == 1) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++#define DEFINEFUNC_1_1(ret, func, args, argscall) \ ++ if (major == 3 || (major == 1 && minor == 1)) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++#define DEFINEFUNC_1_1_1(ret, func, args, argscall) \ ++ if (major == 3 || (major == 1 && minor == 1 && patch == 1)) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++#define DEFINEFUNC_3_0(ret, func, args, argscall) \ ++ if (major == 3) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) \ ++ if (major == 1 && minor == 0) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #oldfunc) \ ++ } \ ++ else \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) \ ++ if (major == 1) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #oldfunc) \ ++ } \ ++ else \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ ++ } ++ ++FOR_ALL_OPENSSL_FUNCTIONS + -+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)) ++#undef DEFINEFUNC ++#undef DEFINEFUNC_LEGACY_1_1 ++#undef DEFINEFUNC_LEGACY_1_0 ++#undef DEFINEFUNC_LEGACY_1 ++#undef DEFINEFUNC_1_1 ++#undef DEFINEFUNC_1_1_1 ++#undef DEFINEFUNC_3_0 ++#undef DEFINEFUNC_RENAMED_1_1 ++#undef DEFINEFUNC_RENAMED_3_0 ++} + -+int _goboringcrypto_stub_openssl_rand(void); -+int _goboringcrypto_restore_openssl_rand(void); -+int fbytes(unsigned char *buf, int num); ++static unsigned long ++version_num(void* handle) ++{ ++ unsigned long (*fn)(void); ++ // OPENSSL_version_num is defined in OpenSSL 1.1.0 and 1.1.1. ++ fn = (unsigned long (*)(void))dlsym(handle, "OpenSSL_version_num"); ++ if (fn != NULL) ++ return fn(); + ++ // SSLeay is defined in OpenSSL 1.0.2. ++ fn = (unsigned long (*)(void))dlsym(handle, "SSLeay"); ++ if (fn != NULL) ++ return fn(); + -+#include ++ return 0; ++} + -+enum ++int ++go_openssl_version_major(void* handle) +{ -+ GO_NID_md5_sha1 = NID_md5_sha1, ++ unsigned int (*fn)(void); ++ // OPENSSL_version_major is supported since OpenSSL 3. ++ fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_major"); ++ if (fn != NULL) ++ return (int)fn(); + -+ GO_NID_secp224r1 = NID_secp224r1, -+ GO_NID_X9_62_prime256v1 = NID_X9_62_prime256v1, -+ GO_NID_secp384r1 = NID_secp384r1, -+ GO_NID_secp521r1 = NID_secp521r1, ++ // If OPENSSL_version_major is not defined, try with OpenSSL 1 functions. ++ unsigned long num = version_num(handle); ++ if (num < 0x10000000L || num >= 0x20000000L) ++ return -1; + -+ GO_NID_sha224 = NID_sha224, -+ GO_NID_sha256 = NID_sha256, -+ GO_NID_sha384 = NID_sha384, -+ GO_NID_sha512 = NID_sha512, -+}; ++ return 1; ++} + -+#include ++int ++go_openssl_version_minor(void* handle) ++{ ++ unsigned int (*fn)(void); ++ // OPENSSL_version_minor is supported since OpenSSL 3. ++ fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_minor"); ++ if (fn != NULL) ++ return (int)fn(); ++ ++ // If OPENSSL_version_minor is not defined, try with OpenSSL 1 functions. ++ unsigned long num = version_num(handle); ++ // OpenSSL version number follows this schema: ++ // MNNFFPPS: major minor fix patch status. ++ if (num < 0x10000000L || num >= 0x10200000L) ++ { ++ // We only support minor version 0 and 1, ++ // so there is no need to implement an algorithm ++ // that decodes the version number into individual components. ++ return -1; ++ } + -+typedef SHA_CTX GO_SHA_CTX; ++ if (num >= 0x10100000L) ++ return 1; ++ ++ return 0; ++} + -+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)) ++int ++go_openssl_version_patch(void* handle) ++{ ++ unsigned int (*fn)(void); ++ // OPENSSL_version_patch is supported since OpenSSL 3. ++ fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_patch"); ++ if (fn != NULL) ++ return (int)fn(); ++ ++ // If OPENSSL_version_patch is not defined, try with OpenSSL 1 functions. ++ unsigned long num = version_num(handle); ++ // OpenSSL version number follows this schema: ++ // MNNFFPPS: major minor fix patch status. ++ if (num < 0x10000000L || num >= 0x10200000L) ++ { ++ // We only support minor version 0 and 1, ++ // so there is no need to implement an algorithm ++ // that decodes the version number into individual components. ++ return -1; ++ } + -+typedef SHA256_CTX GO_SHA256_CTX; ++ return (num >> 12) & 0xff; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h +new file mode 100644 +index 0000000000..a0e2b623a5 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h +@@ -0,0 +1,201 @@ ++// This header file describes the OpenSSL ABI as built for use in Go. + -+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)) ++#include // size_t + -+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)) ++#include "shims.h" + -+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)) ++static inline void ++go_openssl_do_leak_check(void) ++{ ++#ifndef __has_feature ++#define __has_feature(x) 0 ++#endif + -+#include ++#if (defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__) || \ ++ __has_feature(address_sanitizer) ++ extern void __lsan_do_leak_check(void); ++ __lsan_do_leak_check(); ++#endif ++} + -+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)) ++int go_openssl_fips_enabled(void* handle); ++int go_openssl_version_major(void* handle); ++int go_openssl_version_minor(void* handle); ++int go_openssl_version_patch(void* handle); ++int go_openssl_thread_setup(void); ++void go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch); ++const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void); ++ ++// Define pointers to all the used OpenSSL functions. ++// Calling C function pointers from Go is currently not supported. ++// It is possible to circumvent this by using a C function wrapper. ++// https://pkg.go.dev/cmd/cgo ++#define DEFINEFUNC(ret, func, args, argscall) \ ++ extern ret (*_g_##func)args; \ ++ static inline ret go_openssl_##func args \ ++ { \ ++ return _g_##func argscall; \ ++ } ++#define DEFINEFUNC_LEGACY_1_1(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_1_1(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_1_1_1(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_3_0(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++ ++FOR_ALL_OPENSSL_FUNCTIONS ++ ++#undef DEFINEFUNC ++#undef DEFINEFUNC_LEGACY_1_1 ++#undef DEFINEFUNC_LEGACY_1_0 ++#undef DEFINEFUNC_LEGACY_1 ++#undef DEFINEFUNC_1_1 ++#undef DEFINEFUNC_1_1_1 ++#undef DEFINEFUNC_3_0 ++#undef DEFINEFUNC_RENAMED_1_1 ++#undef DEFINEFUNC_RENAMED_3_0 ++ ++// go_hash_sum copies ctx into ctx2 and calls EVP_DigestFinal using ctx2. ++// This is necessary because Go hash.Hash mandates 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. ++// It is written in C because Sum() tend to be in the hot path, ++// and doing one cgo call instead of two is a significant performance win. +static inline int -+_goboringcrypto_EVP_MD_get_size(const GO_EVP_MD *arg0) ++go_hash_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out) +{ -+ return _goboringcrypto_internal_EVP_MD_size(arg0); ++ if (go_openssl_EVP_MD_CTX_copy(ctx2, ctx) != 1) ++ return 0; ++ // TODO: use EVP_DigestFinal_ex once we know why it leaks ++ // memory on OpenSSL 1.0.2. ++ return go_openssl_EVP_DigestFinal(ctx2, out, NULL); +} -+#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)) + ++// These wrappers allocate out_len on the C stack to avoid having to pass a pointer from Go, which would escape to the heap. ++// Use them only in situations where the output length can be safely discarded. +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 ++go_openssl_EVP_EncryptUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) ++{ ++ int len; ++ return go_openssl_EVP_EncryptUpdate(ctx, out, &len, in, in_len); +} + -+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 ++static inline int ++go_openssl_EVP_DecryptUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) ++{ ++ int len; ++ return go_openssl_EVP_DecryptUpdate(ctx, out, &len, in, in_len); +} + -+#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); -+ } ++static inline int ++go_openssl_EVP_CipherUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) ++{ ++ int len; ++ return go_openssl_EVP_CipherUpdate(ctx, out, &len, in, in_len); +} -+#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 ++// 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. + -+#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); ++go_openssl_EVP_CIPHER_CTX_seal_wrapper(const GO_EVP_CIPHER_CTX_PTR ctx, ++ unsigned char *out, ++ const unsigned char *nonce, ++ const unsigned char *in, int in_len, ++ const unsigned char *aad, int aad_len) ++{ ++ if (in_len == 0) in = (const unsigned char *)""; ++ if (aad_len == 0) aad = (const unsigned char *)""; + -+#include -+#include ++ if (go_openssl_EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) ++ return 0; + -+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)) ++ int discard_len, out_len; ++ if (go_openssl_EVP_EncryptUpdate(ctx, NULL, &discard_len, aad, aad_len) != 1 ++ || go_openssl_EVP_EncryptUpdate(ctx, out, &out_len, in, in_len) != 1 ++ || go_openssl_EVP_EncryptFinal_ex(ctx, out + out_len, &discard_len) != 1) ++ { ++ return 0; ++ } + -+void _goboringcrypto_EVP_AES_ctr128_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len); ++ if (in_len != out_len) ++ return 0; + -+int _goboringcrypto_EVP_AES_encrypt(EVP_CIPHER_CTX *ctx, const uint8_t *in, size_t in_len, uint8_t *out); ++ return go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_GET_TAG, 16, out + out_len); ++} + -+enum ++static inline int ++go_openssl_EVP_CIPHER_CTX_open_wrapper(const GO_EVP_CIPHER_CTX_PTR ctx, ++ unsigned char *out, ++ const unsigned char *nonce, ++ const unsigned char *in, int in_len, ++ const unsigned char *aad, int aad_len, ++ const unsigned char *tag) +{ -+ 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); ++ if (in_len == 0) { ++ in = (const unsigned char *)""; ++ // OpenSSL 1.0.2 in FIPS mode contains a bug: it will fail to verify ++ // unless EVP_DecryptUpdate is called at least once with a non-NULL ++ // output buffer. OpenSSL will not dereference the output buffer when ++ // the input length is zero, so set it to an arbitrary non-NULL pointer ++ // to satisfy OpenSSL when the caller only has authenticated additional ++ // data (AAD) to verify. While a stack-allocated buffer could be used, ++ // that would risk a stack-corrupting buffer overflow if OpenSSL ++ // unexpectedly dereferenced it. Instead pass a value which would ++ // segfault if dereferenced on any modern platform where a NULL-pointer ++ // dereference would also segfault. ++ if (out == NULL) out = (unsigned char *)1; ++ } ++ if (aad_len == 0) aad = (const unsigned char *)""; + -+void EVP_AES_cbc_dec(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len); ++ if (go_openssl_EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) ++ return 0; + -+typedef ENGINE GO_ENGINE; ++ // OpenSSL 1.0.x FIPS Object Module 2.0 versions below 2.0.5 require that ++ // the tag be set before the ciphertext, otherwise EVP_DecryptUpdate returns ++ // an error. At least one extant commercially-supported, FIPS validated ++ // build of OpenSSL 1.0.2 uses FIPS module version 2.0.1. Set the tag first ++ // to maximize compatibility with all OpenSSL version combinations. ++ if (go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)(tag)) != 1) ++ return 0; + -+#include ++ int discard_len, out_len; ++ if (go_openssl_EVP_DecryptUpdate(ctx, NULL, &discard_len, aad, aad_len) != 1 ++ || go_openssl_EVP_DecryptUpdate(ctx, out, &out_len, in, in_len) != 1) ++ { ++ return 0; ++ } + -+typedef BN_CTX GO_BN_CTX; -+typedef BIGNUM GO_BIGNUM; ++ if (go_openssl_EVP_DecryptFinal_ex(ctx, out + out_len, &discard_len) != 1) ++ return 0; + -+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)) ++ if (out_len != in_len) ++ return 0; + -+static inline int -+_goboringcrypto_BN_num_bytes(const GO_BIGNUM* a) { -+ return ((_goboringcrypto_BN_num_bits(a)+7)/8); ++ return 1; +} + -+#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; ++// Hand-roll custom wrappers for CRYPTO_malloc and CRYPTO_free which cast the ++// function pointers to the correct signatures for OpenSSL 1.0.2. + -+ copy = malloc(len); -+ if (!copy) -+ return NULL; -+ for (i = 0; i < len; i++) -+ copy[i] = s[len - i - 1]; ++static inline void * ++go_openssl_CRYPTO_malloc_legacy102(int num, const char *file, int line) { ++ return ((void *(*)(int, const char *, int))_g_CRYPTO_malloc)(num, file, line); ++} + -+ result = _goboringcrypto_BN_bin2bn(copy, len, ret); -+ free(copy); -+ return result; ++static inline void ++go_openssl_CRYPTO_free_legacy102(void *str) { ++ ((void (*)(void *))_g_CRYPTO_free)(str); +} +\ No newline at end of file +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hash.go b/src/vendor/github.com/golang-fips/openssl/v2/hash.go +new file mode 100644 +index 0000000000..646b4ce295 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hash.go +@@ -0,0 +1,793 @@ ++//go:build !cmd_go_bootstrap + -+static inline int -+_goboringcrypto_BN_bn2binpad(const GO_BIGNUM *a, unsigned char *to, int tolen) -+{ -+ int size = _goboringcrypto_BN_num_bytes(a); -+ int i; ++package openssl + -+ if (size > tolen) -+ return -1; ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "errors" ++ "hash" ++ "runtime" ++ "strconv" ++ "unsafe" ++) + -+ memset(to, 0, tolen - size); -+ if (_goboringcrypto_internal_BN_bn2bin(a, to + tolen - size) != size) -+ return -1; ++// NOTE: Implementation ported from https://go-review.googlesource.com/c/go/+/404295. ++// The cgo calls in this file are arranged to avoid marking the parameters as escaping. ++// To do that, we call noescape (including via addr). ++// We must also make sure that the data pointer arguments have the form unsafe.Pointer(&...) ++// so that cgo does not annotate them with cgoCheckPointer calls. If it did that, it might look ++// beyond the byte slice and find Go pointers in unprocessed parts of a larger allocation. ++// To do both of these simultaneously, the idiom is unsafe.Pointer(&*addr(p)), ++// where addr returns the base pointer of p, substituting a non-nil pointer for nil, ++// and applying a noescape along the way. ++// This is all to preserve compatibility with the allocation behavior of the non-openssl implementations. + -+ return tolen; ++func hashOneShot(ch crypto.Hash, p []byte, sum []byte) bool { ++ return C.go_openssl_EVP_Digest(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), (*C.uchar)(unsafe.Pointer(&*addr(sum))), nil, cryptoHashToMD(ch), nil) != 0 +} + -+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; ++func MD4(p []byte) (sum [16]byte) { ++ if !hashOneShot(crypto.MD4, p, sum[:]) { ++ panic("openssl: MD4 failed") ++ } ++ return ++} + -+ if (size != tolen) -+ return -1; ++func MD5(p []byte) (sum [16]byte) { ++ if !hashOneShot(crypto.MD5, p, sum[:]) { ++ panic("openssl: MD5 failed") ++ } ++ return ++} + -+ /* reverse bytes */ -+ for (i = 0; i < tolen / 2; i++) { -+ unsigned char tmp; ++func SHA1(p []byte) (sum [20]byte) { ++ if !hashOneShot(crypto.SHA1, p, sum[:]) { ++ panic("openssl: SHA1 failed") ++ } ++ return ++} + -+ tmp = to[i]; -+ to[i] = to[tolen - i - 1]; -+ to[tolen - i - 1] = tmp; ++func SHA224(p []byte) (sum [28]byte) { ++ if !hashOneShot(crypto.SHA224, p, sum[:]) { ++ panic("openssl: SHA224 failed") + } ++ return ++} + -+ return tolen; ++func SHA256(p []byte) (sum [32]byte) { ++ if !hashOneShot(crypto.SHA256, p, sum[:]) { ++ panic("openssl: SHA256 failed") ++ } ++ return +} -+#endif + -+#include ++func SHA384(p []byte) (sum [48]byte) { ++ if !hashOneShot(crypto.SHA384, p, sum[:]) { ++ panic("openssl: SHA384 failed") ++ } ++ return ++} + -+enum { -+ GO_EVP_PKEY_EC = EVP_PKEY_EC, -+}; ++func SHA512(p []byte) (sum [64]byte) { ++ if !hashOneShot(crypto.SHA512, p, sum[:]) { ++ panic("openssl: SHA512 failed") ++ } ++ return ++} + -+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; ++// SupportsHash returns true if a hash.Hash implementation is supported for h. ++func SupportsHash(h crypto.Hash) bool { ++ return cryptoHashToMD(h) != nil ++} + -+ pubkey = _goboringcrypto_EC_POINT_new(group); -+ if (!pubkey) -+ return 0; ++func SHA3_224(p []byte) (sum [28]byte) { ++ if !hashOneShot(crypto.SHA3_224, p, sum[:]) { ++ panic("openssl: SHA3_224 failed") ++ } ++ return ++} + -+ if (_goboringcrypto_EC_POINT_oct2point(group, pubkey, buf, len, ctx) != 1 || -+ _goboringcrypto_EC_KEY_set_public_key(eckey, pubkey) != 1) -+ ret = 0; ++func SHA3_256(p []byte) (sum [32]byte) { ++ if !hashOneShot(crypto.SHA3_256, p, sum[:]) { ++ panic("openssl: SHA3_256 failed") ++ } ++ return ++} + -+ _goboringcrypto_EC_POINT_free(pubkey); -+ return ret; ++func SHA3_384(p []byte) (sum [48]byte) { ++ if !hashOneShot(crypto.SHA3_384, p, sum[:]) { ++ panic("openssl: SHA3_384 failed") ++ } ++ return +} -+#endif + -+// TODO: EC_KEY_check_fips? ++func SHA3_512(p []byte) (sum [64]byte) { ++ if !hashOneShot(crypto.SHA3_512, p, sum[:]) { ++ panic("openssl: SHA3_512 failed") ++ } ++ return ++} + -+#include ++// evpHash implements generic hash methods. ++type evpHash struct { ++ ctx C.GO_EVP_MD_CTX_PTR ++ // ctx2 is used in evpHash.sum to avoid changing ++ // the state of ctx. Having it here allows reusing the ++ // same allocated object multiple times. ++ ctx2 C.GO_EVP_MD_CTX_PTR ++ size int ++ blockSize int ++} + -+typedef ECDSA_SIG GO_ECDSA_SIG; ++func newEvpHash(ch crypto.Hash, size, blockSize int) *evpHash { ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) ++ } ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if C.go_openssl_EVP_DigestInit_ex(ctx, md, nil) != 1 { ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ panic(newOpenSSLError("EVP_DigestInit_ex")) ++ } ++ ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ h := &evpHash{ ++ ctx: ctx, ++ ctx2: ctx2, ++ size: size, ++ blockSize: blockSize, ++ } ++ runtime.SetFinalizer(h, (*evpHash).finalize) ++ return h ++} + -+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)) ++func (h *evpHash) finalize() { ++ C.go_openssl_EVP_MD_CTX_free(h.ctx) ++ C.go_openssl_EVP_MD_CTX_free(h.ctx2) ++} + -+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)) ++func (h *evpHash) Reset() { ++ // There is no need to reset h.ctx2 because it is always reset after ++ // use in evpHash.sum. ++ if C.go_openssl_EVP_DigestInit_ex(h.ctx, nil, nil) != 1 { ++ panic(newOpenSSLError("EVP_DigestInit_ex")) ++ } ++ runtime.KeepAlive(h) ++} + -+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)) ++func (h *evpHash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&*addr(p)), C.size_t(len(p))) != 1 { ++ panic(newOpenSSLError("EVP_DigestUpdate")) ++ } ++ runtime.KeepAlive(h) ++ return len(p), nil ++} + -+#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(); ++func (h *evpHash) WriteString(s string) (int, error) { ++ if len(s) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(unsafe.StringData(s)), C.size_t(len(s))) == 0 { ++ panic("openssl: EVP_DigestUpdate failed") ++ } ++ runtime.KeepAlive(h) ++ return len(s), nil +} -+#endif + -+DEFINEFUNCINTERNAL(int, EVP_PKEY_assign, -+ (EVP_PKEY *pkey, int type, void *eckey), -+ (pkey, type, eckey)) ++func (h *evpHash) WriteByte(c byte) error { ++ if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&c), 1) == 0 { ++ panic("openssl: EVP_DigestUpdate failed") ++ } ++ runtime.KeepAlive(h) ++ return nil ++} + -+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)); ++func (h *evpHash) Size() int { ++ return h.size +} + -+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); ++func (h *evpHash) BlockSize() int { ++ return h.blockSize +} -+#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)) ++func (h *evpHash) sum(out []byte) { ++ if C.go_hash_sum(h.ctx, h.ctx2, base(out)) != 1 { ++ panic(newOpenSSLError("go_hash_sum")) ++ } ++ runtime.KeepAlive(h) ++} + -+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; ++// hashState returns a pointer to the internal hash structure. ++// ++// The EVP_MD_CTX memory layout has changed in OpenSSL 3 ++// and the property holding the internal structure is no longer md_data but algctx. ++func (h *evpHash) hashState() unsafe.Pointer { ++ switch vMajor { ++ case 1: ++ // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. ++ type mdCtx struct { ++ _ [2]unsafe.Pointer ++ _ C.ulong ++ md_data unsafe.Pointer ++ } ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).md_data ++ case 3: ++ // https://github.com/openssl/openssl/blob/5675a5aaf6a2e489022bcfc18330dae9263e598e/crypto/evp/evp_local.h#L16. ++ type mdCtx struct { ++ _ [3]unsafe.Pointer ++ _ C.ulong ++ _ [3]unsafe.Pointer ++ algctx unsafe.Pointer ++ } ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).algctx ++ default: ++ panic(errUnsupportedVersion()) ++ } ++} + -+ if (p != NULL) { -+ _goboringcrypto_BN_clear_free(r->p); -+ r->p = p; -+ } -+ if (q != NULL) { -+ _goboringcrypto_BN_clear_free(r->q); -+ r->q = q; -+ } ++// NewMD4 returns a new MD4 hash. ++// The returned hash doesn't implement encoding.BinaryMarshaler and ++// encoding.BinaryUnmarshaler. ++func NewMD4() hash.Hash { ++ return &md4Hash{ ++ evpHash: newEvpHash(crypto.MD4, 16, 64), ++ } ++} + -+ return 1; -+#else -+ return _goboringcrypto_internal_RSA_set0_factors(r, p, q); -+#endif ++type md4Hash struct { ++ *evpHash ++ out [16]byte +} + -+DEFINEFUNCINTERNAL(int, RSA_set0_crt_params, -+ (GO_RSA * rsa, GO_BIGNUM *dmp1, GO_BIGNUM *dmp2, GO_BIGNUM *iqmp), -+ (rsa, dmp1, dmp2, iqmp)) ++func (h *md4Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+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; ++// NewMD5 returns a new MD5 hash. ++func NewMD5() hash.Hash { ++ return &md5Hash{ ++ evpHash: newEvpHash(crypto.MD5, 16, 64), ++ } ++} + -+ 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; -+ } ++// md5State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/md5.h#L33. ++type md5State struct { ++ h [4]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 ++} + -+ return 1; -+#else -+ return _goboringcrypto_internal_RSA_set0_crt_params(r, dmp1, dmq1, iqmp); -+#endif ++type md5Hash struct { ++ *evpHash ++ out [16]byte +} + -+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 ++func (h *md5Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + ++const ( ++ md5Magic = "md5\x01" ++ md5MarshaledSize = len(md5Magic) + 4*4 + 64 + 8 ++) + -+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; ++func (h *md5Hash) MarshalBinary() ([]byte, error) { ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/md5: can't retrieve hash state") ++ } ++ b := make([]byte, 0, md5MarshaledSize) ++ b = append(b, md5Magic...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} ++ ++func (h *md5Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(md5Magic) || string(b[:len(md5Magic)]) != md5Magic { ++ return errors.New("crypto/md5: invalid hash state identifier") ++ } ++ if len(b) != md5MarshaledSize { ++ return errors.New("crypto/md5: invalid hash state size") ++ } ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/md5: can't retrieve hash state") ++ } ++ b = b[len(md5Magic):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil ++} + -+ 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; -+ } ++// NewSHA1 returns a new SHA1 hash. ++func NewSHA1() hash.Hash { ++ return &sha1Hash{ ++ evpHash: newEvpHash(crypto.SHA1, 20, 64), ++ } ++} + -+ return 1; -+#else -+ return _goboringcrypto_internal_RSA_set0_key(r, n, e, d); -+#endif ++type sha1Hash struct { ++ *evpHash ++ out [20]byte +} + -+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 ++func (h *sha1Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+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 ++// sha1State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34. ++type sha1State struct { ++ h [5]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 +} + -+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, -+}; ++const ( ++ sha1Magic = "sha\x01" ++ sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 ++) + -+enum { -+ GO_RSA_PSS_SALTLEN_AUTO = -2, -+ GO_RSA_PSS_SALTLEN_DIGEST = -1, -+}; ++func (h *sha1Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha1: can't retrieve hash state") ++ } ++ b := make([]byte, 0, sha1MarshaledSize) ++ b = append(b, sha1Magic...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} ++ ++func (h *sha1Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { ++ return errors.New("crypto/sha1: invalid hash state identifier") ++ } ++ if len(b) != sha1MarshaledSize { ++ return errors.New("crypto/sha1: invalid hash state size") ++ } ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha1: can't retrieve hash state") ++ } ++ b = b[len(sha1Magic):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil ++} + -+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)) ++// NewSHA224 returns a new SHA224 hash. ++func NewSHA224() hash.Hash { ++ return &sha224Hash{ ++ evpHash: newEvpHash(crypto.SHA224, 224/8, 64), ++ } ++} + -+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 ++type sha224Hash struct { ++ *evpHash ++ out [224 / 8]byte +} + -+#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); ++func (h *sha224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} -+#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); ++// NewSHA256 returns a new SHA256 hash. ++func NewSHA256() hash.Hash { ++ return &sha256Hash{ ++ evpHash: newEvpHash(crypto.SHA256, 256/8, 64), ++ } +} + -+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); ++type sha256Hash struct { ++ *evpHash ++ out [256 / 8]byte +} + -+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); ++func (h *sha256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+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)) ++const ( ++ magic224 = "sha\x02" ++ magic256 = "sha\x03" ++ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 ++) + -+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); ++// sha256State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L51. ++type sha256State struct { ++ h [8]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 ++} ++ ++func (h *sha224Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ b := make([]byte, 0, marshaledSize256) ++ b = append(b, magic224...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = appendUint32(b, d.h[5]) ++ b = appendUint32(b, d.h[6]) ++ b = appendUint32(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} ++ ++func (h *sha256Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ b := make([]byte, 0, marshaledSize256) ++ b = append(b, magic256...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = appendUint32(b, d.h[5]) ++ b = appendUint32(b, d.h[6]) ++ b = appendUint32(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} ++ ++func (h *sha224Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize256 { ++ return errors.New("crypto/sha256: invalid hash state size") ++ } ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ b = b[len(magic224):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b, d.h[5] = consumeUint32(b) ++ b, d.h[6] = consumeUint32(b) ++ b, d.h[7] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil +} -+# endif -+#endif + -+#if OPENSSL_VERSION_NUMBER >= 0x10101000L -+#include ++func (h *sha256Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize256 { ++ return errors.New("crypto/sha256: invalid hash state size") ++ } ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ b = b[len(magic256):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b, d.h[5] = consumeUint32(b) ++ b, d.h[6] = consumeUint32(b) ++ b, d.h[7] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil ++} + -+enum { -+ GO_EVP_PKEY_HKDF = EVP_PKEY_HKDF, -+}; ++// NewSHA384 returns a new SHA384 hash. ++func NewSHA384() hash.Hash { ++ return &sha384Hash{ ++ evpHash: newEvpHash(crypto.SHA384, 384/8, 128), ++ } ++} + -+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, -+}; ++type sha384Hash struct { ++ *evpHash ++ out [384 / 8]byte ++} + -+#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, -+}; ++func (h *sha384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+#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); ++// NewSHA512 returns a new SHA512 hash. ++func NewSHA512() hash.Hash { ++ return &sha512Hash{ ++ evpHash: newEvpHash(crypto.SHA512, 512/8, 128), ++ } +} + -+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)); ++type sha512Hash struct { ++ *evpHash ++ out [512 / 8]byte +} + -+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)); ++func (h *sha512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+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)); ++// sha512State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95. ++type sha512State struct { ++ h [8]uint64 ++ nl, nh uint64 ++ x [128]byte ++ nx uint32 +} + -+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)); ++const ( ++ magic384 = "sha\x04" ++ magic512_224 = "sha\x05" ++ magic512_256 = "sha\x06" ++ magic512 = "sha\x07" ++ marshaledSize512 = len(magic512) + 8*8 + 128 + 8 ++) ++ ++func (h *sha384Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ b := make([]byte, 0, marshaledSize512) ++ b = append(b, magic384...) ++ b = appendUint64(b, d.h[0]) ++ b = appendUint64(b, d.h[1]) ++ b = appendUint64(b, d.h[2]) ++ b = appendUint64(b, d.h[3]) ++ b = appendUint64(b, d.h[4]) ++ b = appendUint64(b, d.h[5]) ++ b = appendUint64(b, d.h[6]) ++ b = appendUint64(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, d.nl>>3|d.nh<<61) ++ return b, nil ++} ++ ++func (h *sha512Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ b := make([]byte, 0, marshaledSize512) ++ b = append(b, magic512...) ++ b = appendUint64(b, d.h[0]) ++ b = appendUint64(b, d.h[1]) ++ b = appendUint64(b, d.h[2]) ++ b = appendUint64(b, d.h[3]) ++ b = appendUint64(b, d.h[4]) ++ b = appendUint64(b, d.h[5]) ++ b = appendUint64(b, d.h[6]) ++ b = appendUint64(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, d.nl>>3|d.nh<<61) ++ return b, nil ++} ++ ++func (h *sha384Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if string(b[:len(magic384)]) != magic384 { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize512 { ++ return errors.New("crypto/sha512: invalid hash state size") ++ } ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ b = b[len(magic512):] ++ b, d.h[0] = consumeUint64(b) ++ b, d.h[1] = consumeUint64(b) ++ b, d.h[2] = consumeUint64(b) ++ b, d.h[3] = consumeUint64(b) ++ b, d.h[4] = consumeUint64(b) ++ b, d.h[5] = consumeUint64(b) ++ b, d.h[6] = consumeUint64(b) ++ b, d.h[7] = consumeUint64(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = n << 3 ++ d.nh = n >> 61 ++ d.nx = uint32(n) % 128 ++ return nil +} -+// 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 ++func (h *sha512Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if string(b[:len(magic512)]) != magic512 { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize512 { ++ return errors.New("crypto/sha512: invalid hash state size") ++ } ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ b = b[len(magic512):] ++ b, d.h[0] = consumeUint64(b) ++ b, d.h[1] = consumeUint64(b) ++ b, d.h[2] = consumeUint64(b) ++ b, d.h[3] = consumeUint64(b) ++ b, d.h[4] = consumeUint64(b) ++ b, d.h[5] = consumeUint64(b) ++ b, d.h[6] = consumeUint64(b) ++ b, d.h[7] = consumeUint64(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = n << 3 ++ d.nh = n >> 61 ++ d.nx = uint32(n) % 128 ++ return nil ++} + ++// NewSHA3_224 returns a new SHA3-224 hash. ++func NewSHA3_224() hash.Hash { ++ return &sha3_224Hash{ ++ evpHash: newEvpHash(crypto.SHA3_224, 224/8, 64), ++ } ++} + -+#else ++type sha3_224Hash struct { ++ *evpHash ++ out [224 / 8]byte ++} + -+/* 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. -+ */ ++func (h *sha3_224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+enum { -+ GO_EVP_PKEY_HKDF, -+}; ++// NewSHA3_256 returns a new SHA3-256 hash. ++func NewSHA3_256() hash.Hash { ++ return &sha3_256Hash{ ++ evpHash: newEvpHash(crypto.SHA3_256, 256/8, 64), ++ } ++} + -+enum { -+ GO_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY, -+ GO_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY, -+}; ++type sha3_256Hash struct { ++ *evpHash ++ out [256 / 8]byte ++} + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set_hkdf_mode(GO_EVP_PKEY_CTX *arg0, int arg1) -+{ -+ return -1; ++func (h *sha3_256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set_hkdf_md(GO_EVP_PKEY_CTX *arg0, const GO_EVP_MD *arg1) -+{ -+ return -1; ++// NewSHA3_384 returns a new SHA3-384 hash. ++func NewSHA3_384() hash.Hash { ++ return &sha3_384Hash{ ++ evpHash: newEvpHash(crypto.SHA3_384, 384/8, 128), ++ } +} + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set1_hkdf_salt(GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2) -+{ -+ return -1; ++type sha3_384Hash struct { ++ *evpHash ++ out [384 / 8]byte +} + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set1_hkdf_key(GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2) -+{ -+ return -1; ++func (h *sha3_384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_add1_hkdf_info(GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2) -+{ -+ return -1; ++// NewSHA3_512 returns a new SHA3-512 hash. ++func NewSHA3_512() hash.Hash { ++ return &sha3_512Hash{ ++ evpHash: newEvpHash(crypto.SHA3_512, 512/8, 128), ++ } +} -+#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, -+}; ++type sha3_512Hash struct { ++ *evpHash ++ out [512 / 8]byte ++} + -+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); ++func (h *sha3_512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} -+#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, -+}; ++// appendUint64 appends x into b as a big endian byte sequence. ++func appendUint64(b []byte, x uint64) []byte { ++ return append(b, ++ byte(x>>56), ++ byte(x>>48), ++ byte(x>>40), ++ byte(x>>32), ++ byte(x>>24), ++ byte(x>>16), ++ byte(x>>8), ++ byte(x), ++ ) ++} + -+#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)) ++// appendUint32 appends x into b as a big endian byte sequence. ++func appendUint32(b []byte, x uint32) []byte { ++ return append(b, byte(x>>24), byte(x>>16), byte(x>>8), byte(x)) ++} + -+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); ++// consumeUint64 reads a big endian uint64 number from b. ++func consumeUint64(b []byte) ([]byte, uint64) { ++ _ = b[7] ++ x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | ++ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 ++ return b[8:], x +} -+#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 ++// consumeUint32 reads a big endian uint32 number from b. ++func consumeUint32(b []byte) ([]byte, uint32) { ++ _ = b[3] ++ x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 ++ return b[4:], x ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go new file mode 100644 -index 0000000000..2e21224264 +index 0000000000..ac3fbba0c2 --- /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 ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go +@@ -0,0 +1,174 @@ ++//go:build !cmd_go_bootstrap + +package openssl + +// #include "goopenssl.h" +import "C" +import ( ++ "errors" + "hash" + "io" + "runtime" ++ "unsafe" +) + -+type hkdf struct { -+ ctx *C.GO_EVP_PKEY_CTX -+} -+ +func SupportsHKDF() bool { -+ return openSSLVersion() >= OPENSSL_VERSION_1_1_1 ++ return versionAtOrAbove(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") ++ if !SupportsHKDF() { ++ return nil, errUnsupportedVersion() + } + + ch := h() + md := hashToMD(ch) + if md == nil { -+ return nil, NewOpenSSLError("Unknown hash algorithm") ++ return nil, errors.New("unsupported hash function") + } + -+ ctx := C._goboringcrypto_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil) ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil) + if ctx == nil { -+ return nil, NewOpenSSLError("EVP_PKEY_CTX_new_id failed") ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") + } -+ c := &hkdf{ctx: ctx} -+ runtime.SetFinalizer(c, (*hkdf).finalize) -+ defer runtime.KeepAlive(c) ++ defer func() { ++ C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ }() + -+ if C._goboringcrypto_EVP_PKEY_derive_init(ctx) != 1 { -+ return nil, NewOpenSSLError("EVP_PKEY_derive_init failed") ++ if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") + } -+ 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") ++ switch vMajor { ++ case 3: ++ if C.go_openssl_EVP_PKEY_CTX_set_hkdf_mode(ctx, mode) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_set_hkdf_md(ctx, md) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") ++ } ++ case 1: ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_MODE, ++ C.int(mode), nil) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_MD, ++ 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") ++ } + } + ++ c := &hkdf{ctx: ctx, hashLen: ch.Size()} ++ ctx = nil ++ ++ runtime.SetFinalizer(c, (*hkdf).finalize) ++ + return c, nil +} + ++type hkdf struct { ++ ctx C.GO_EVP_PKEY_CTX_PTR ++ ++ hashLen int ++ buf []byte ++} ++ +func (c *hkdf) finalize() { + if c.ctx != nil { -+ C._goboringcrypto_EVP_PKEY_CTX_free(c.ctx) ++ C.go_openssl_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") ++ // EVP_PKEY_derive doesn't support incremental output, each call ++ // derives the key from scratch and returns the requested bytes. ++ // To implement io.Reader, we need to ask for len(c.buf) + len(p) ++ // bytes and copy the last derived len(p) bytes to p. ++ // We use c.buf to know how many bytes we've already derived and ++ // to avoid allocating the whole output buffer on each call. ++ prevLen := len(c.buf) ++ needLen := len(p) ++ remains := 255*c.hashLen - prevLen ++ // Check whether enough data can be generated. ++ if remains < needLen { ++ return 0, errors.New("hkdf: entropy limit reached") + } -+ return int(outLen), nil ++ c.buf = append(c.buf, make([]byte, needLen)...) ++ outLen := C.size_t(prevLen + needLen) ++ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(c.buf), &outLen) != 1 { ++ return 0, newOpenSSLError("EVP_PKEY_derive") ++ } ++ n := copy(p, c.buf[prevLen:outLen]) ++ return n, nil +} + +func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { -+ c, err := newHKDF(h, C.GO_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) ++ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_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") ++ switch vMajor { ++ case 3: ++ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, ++ base(secret), C.int(len(secret))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_salt(c.ctx, ++ base(salt), C.int(len(salt))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt") ++ } ++ case 1: ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_KEY, ++ C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_SALT, ++ C.int(len(salt)), unsafe.Pointer(base(salt))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt") ++ } + } + var outLen C.size_t -+ if C._goboringcrypto_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 { -+ return nil, NewOpenSSLError("EVP_PKEY_derive_init failed") ++ if C.go_openssl_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") + } + out := make([]byte, outLen) -+ if C._goboringcrypto_EVP_PKEY_derive(c.ctx, base(out), &outLen) != 1 { -+ return nil, NewOpenSSLError("EVP_PKEY_derive failed") ++ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(out), &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive") + } + 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) ++ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_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") ++ switch vMajor { ++ case 3: ++ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, ++ base(pseudorandomKey), C.int(len(pseudorandomKey))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_add1_hkdf_info(c.ctx, ++ base(info), C.int(len(info))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info") ++ } ++ case 1: ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_KEY, ++ C.int(len(pseudorandomKey)), unsafe.Pointer(base(pseudorandomKey))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_INFO, ++ C.int(len(info)), unsafe.Pointer(base(info))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info") ++ } + } + 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 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 VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool { -+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 +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hmac.go b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go new file mode 100644 -index 0000000000..e93b042e5e +index 0000000000..ef8116ce66 --- /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. ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go +@@ -0,0 +1,238 @@ ++//go:build !cmd_go_bootstrap + -+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl -+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl -+ -+package openssl -+ -+/* -+#cgo LDFLAGS: -ldl ++package openssl + -+#include "goopenssl.h" -+*/ ++// #include "goopenssl.h" +import "C" +import ( -+ "encoding/binary" -+ "errors" -+ "fmt" -+ "math/bits" -+ "os" ++ "hash" + "runtime" ++ "sync" + "unsafe" +) + -+const ( -+ fipsOn = C.int(1) -+ fipsOff = C.int(0) ++var paramDigest = C.CString("digest") ++ ++var ( ++ fetchHMACOnce sync.Once ++ evpHMAC C.GO_EVP_MAC_PTR +) + -+const GoStrictFipsEnv = "GOLANG_STRICT_FIPS" ++// NewHMAC returns a new HMAC using OpenSSL. ++// The function h must return a hash implemented by ++// OpenSSL (for example, h could be openssl.NewSHA256). ++// If h is not recognized, NewHMAC returns nil. ++func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { ++ ch := h() ++ md := hashToMD(ch) ++ if md == nil { ++ return nil ++ } + -+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)) -+) ++ if len(key) == 0 { ++ // This is supported in OpenSSL/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 behavior previously implemented, so as a workaround ++ // we pass an "empty" key. ++ key = make([]byte, C.GO_EVP_MAX_MD_SIZE) ++ } ++ ++ switch vMajor { ++ case 1: ++ return newHMAC1(key, ch, md) ++ case 3: ++ return newHMAC3(key, ch, md) ++ default: ++ panic(errUnsupportedVersion()) ++ } ++} + -+// Enabled controls whether FIPS crypto is enabled. -+var enabled = false ++// hmacCtx3 is used for OpenSSL 1. ++type hmacCtx1 struct { ++ ctx C.GO_HMAC_CTX_PTR ++} + -+// 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 ++// hmacCtx3 is used for OpenSSL 3. ++type hmacCtx3 struct { ++ ctx C.GO_EVP_MAC_CTX_PTR ++ key []byte // only set for OpenSSL 3.0.0, 3.0.1, and 3.0.2. ++} + -+var nativeEndian binary.ByteOrder ++type opensslHMAC struct { ++ ctx1 hmacCtx1 ++ ctx3 hmacCtx3 ++ size int ++ blockSize int ++ sum []byte ++} + -+func init() { -+ runtime.LockOSThread() -+ defer runtime.UnlockOSThread() ++func newHMAC1(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { ++ ctx := hmacCtxNew() ++ if ctx == nil { ++ panic("openssl: EVP_MAC_CTX_new failed") ++ } ++ if C.go_openssl_HMAC_Init_ex(ctx, unsafe.Pointer(&key[0]), C.int(len(key)), md, nil) == 0 { ++ panic(newOpenSSLError("HMAC_Init_ex failed")) ++ } ++ hmac := &opensslHMAC{ ++ size: h.Size(), ++ blockSize: h.BlockSize(), ++ ctx1: hmacCtx1{ctx}, ++ } ++ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) ++ return hmac ++} + -+ buf := [2]byte{} -+ *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD) ++func newHMAC3(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { ++ fetchHMACOnce.Do(func() { ++ name := C.CString("HMAC") ++ evpHMAC = C.go_openssl_EVP_MAC_fetch(nil, name, nil) ++ C.free(unsafe.Pointer(name)) ++ }) ++ if evpHMAC == nil { ++ panic("openssl: HMAC not supported") ++ } ++ ctx := C.go_openssl_EVP_MAC_CTX_new(evpHMAC) ++ if ctx == nil { ++ panic("openssl: EVP_MAC_CTX_new failed") ++ } ++ digest := C.go_openssl_EVP_MD_get0_name(md) ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ panic(newOpenSSLError("OSSL_PARAM_BLD_new")) ++ } ++ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) ++ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramDigest, digest, 0) ++ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ if params == nil { ++ panic(newOpenSSLError("OSSL_PARAM_BLD_to_param")) ++ } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ if C.go_openssl_EVP_MAC_init(ctx, base(key), C.size_t(len(key)), params) == 0 { ++ panic(newOpenSSLError("EVP_MAC_init failed")) ++ } ++ var hkey []byte ++ if vMinor == 0 && vPatch <= 2 { ++ // EVP_MAC_init only resets the ctx internal state if a key is passed ++ // when using OpenSSL 3.0.0, 3.0.1, and 3.0.2. Save a copy of the key ++ // in the context so Reset can use it later. New OpenSSL versions ++ // do not have this issue so it isn't necessary to save the key. ++ // See https://github.com/openssl/openssl/issues/17811. ++ hkey = make([]byte, len(key)) ++ copy(hkey, key) ++ } ++ hmac := &opensslHMAC{ ++ size: h.Size(), ++ blockSize: h.BlockSize(), ++ ctx3: hmacCtx3{ctx, hkey}, ++ } ++ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) ++ return hmac ++} + -+ switch buf { -+ case [2]byte{0xCD, 0xAB}: -+ nativeEndian = binary.LittleEndian -+ case [2]byte{0xAB, 0xCD}: -+ nativeEndian = binary.BigEndian ++func (h *opensslHMAC) Reset() { ++ switch vMajor { ++ case 1: ++ if C.go_openssl_HMAC_Init_ex(h.ctx1.ctx, nil, 0, nil, nil) == 0 { ++ panic(newOpenSSLError("HMAC_Init_ex failed")) ++ } ++ case 3: ++ if C.go_openssl_EVP_MAC_init(h.ctx3.ctx, base(h.ctx3.key), C.size_t(len(h.ctx3.key)), nil) == 0 { ++ panic(newOpenSSLError("EVP_MAC_init failed")) ++ } + default: -+ panic("Could not determine native endianness.") ++ panic(errUnsupportedVersion()) + } + -+ // Check if we can `dlopen` OpenSSL -+ if C._goboringcrypto_DLOPEN_OPENSSL() == C.NULL { -+ return -+ } ++ runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. ++ h.sum = nil ++} + -+ // Initialize the OpenSSL library. -+ C._goboringcrypto_OPENSSL_setup() ++func (h *opensslHMAC) finalize() { ++ switch vMajor { ++ case 1: ++ hmacCtxFree(h.ctx1.ctx) ++ case 3: ++ C.go_openssl_EVP_MAC_CTX_free(h.ctx3.ctx) ++ default: ++ panic(errUnsupportedVersion()) ++ } ++} + -+ // 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 (h *opensslHMAC) Write(p []byte) (int, error) { ++ if len(p) > 0 { ++ switch vMajor { ++ case 1: ++ C.go_openssl_HMAC_Update(h.ctx1.ctx, base(p), C.size_t(len(p))) ++ case 3: ++ C.go_openssl_EVP_MAC_update(h.ctx3.ctx, base(p), C.size_t(len(p))) ++ default: ++ panic(errUnsupportedVersion()) ++ } + } ++ runtime.KeepAlive(h) ++ return len(p), nil +} + -+func openSSLVersion() uint64 { -+ return uint64(C._goboringcrypto_internal_OPENSSL_VERSION_NUMBER()) ++func (h *opensslHMAC) Size() int { ++ return h.size +} + -+func enableBoringFIPSMode() { -+ enabled = true ++func (h *opensslHMAC) BlockSize() int { ++ return h.blockSize ++} + -+ if os.Getenv(GoStrictFipsEnv) == "1" { -+ strictFIPS = true ++func (h *opensslHMAC) Sum(in []byte) []byte { ++ if h.sum == nil { ++ size := h.Size() ++ h.sum = make([]byte, size) + } -+ -+ if C._goboringcrypto_OPENSSL_thread_setup() != 1 { -+ panic("boringcrypto: OpenSSL thread setup failed") ++ // Make copy of context because Go hash.Hash mandates ++ // 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. ++ switch vMajor { ++ case 1: ++ ctx2 := hmacCtxNew() ++ if ctx2 == nil { ++ panic("openssl: HMAC_CTX_new failed") ++ } ++ defer hmacCtxFree(ctx2) ++ if C.go_openssl_HMAC_CTX_copy(ctx2, h.ctx1.ctx) == 0 { ++ panic("openssl: HMAC_CTX_copy failed") ++ } ++ C.go_openssl_HMAC_Final(ctx2, base(h.sum), nil) ++ case 3: ++ ctx2 := C.go_openssl_EVP_MAC_CTX_dup(h.ctx3.ctx) ++ if ctx2 == nil { ++ panic("openssl: EVP_MAC_CTX_dup failed") ++ } ++ defer C.go_openssl_EVP_MAC_CTX_free(ctx2) ++ C.go_openssl_EVP_MAC_final(ctx2, base(h.sum), nil, C.size_t(len(h.sum))) ++ default: ++ panic(errUnsupportedVersion()) + } ++ return append(in, h.sum...) +} + -+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") ++func hmacCtxNew() C.GO_HMAC_CTX_PTR { ++ if vMajor == 1 && vMinor == 0 { ++ // 0x120 is the sizeof value when building against OpenSSL 1.0.2 on Ubuntu 16.04. ++ ctx := (C.GO_HMAC_CTX_PTR)(C.malloc(0x120)) ++ if ctx != nil { ++ C.go_openssl_HMAC_CTX_init(ctx) + } -+ return fipsConfigured ++ return ctx ++ } ++ return C.go_openssl_HMAC_CTX_new() ++} + -+ } else { -+ return os.Getenv("GOLANG_FIPS") == "1" || fipsConfigured ++func hmacCtxFree(ctx C.GO_HMAC_CTX_PTR) { ++ if vMajor == 1 && vMinor == 0 { ++ C.go_openssl_HMAC_CTX_cleanup(ctx) ++ C.free(unsafe.Pointer(ctx)) ++ return + } ++ C.go_openssl_HMAC_CTX_free(ctx) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init.go b/src/vendor/github.com/golang-fips/openssl/v2/init.go +new file mode 100644 +index 0000000000..a14663298b +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init.go +@@ -0,0 +1,64 @@ ++//go:build !cmd_go_bootstrap + -+var randstub bool ++package openssl + -+func RandStubbed() bool { -+ return randstub -+} ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++) + -+func StubOpenSSLRand() { -+ if !randstub { -+ randstub = true -+ C._goboringcrypto_stub_openssl_rand() ++// opensslInit loads and initialize OpenSSL. ++// If successful, it returns the major and minor OpenSSL version ++// as reported by the OpenSSL API. ++// ++// See Init() for details about file. ++func opensslInit(file string) (major, minor, patch uint, err error) { ++ // Load the OpenSSL shared library using dlopen. ++ handle, err := dlopen(file) ++ if err != nil { ++ return 0, 0, 0, err ++ } ++ ++ // Retrieve the loaded OpenSSL version and check if it is supported. ++ // Notice that major and minor could not match with the version parameter ++ // in case the name of the shared library file differs from the OpenSSL ++ // version it contains. ++ imajor := int(C.go_openssl_version_major(handle)) ++ iminor := int(C.go_openssl_version_minor(handle)) ++ ipatch := int(C.go_openssl_version_patch(handle)) ++ if imajor < 0 || iminor < 0 || ipatch < 0 { ++ return 0, 0, 0, errors.New("openssl: can't retrieve OpenSSL version") ++ } ++ major, minor, patch = uint(imajor), uint(iminor), uint(ipatch) ++ var supported bool ++ if major == 1 { ++ supported = minor == 0 || minor == 1 ++ } else if major == 3 { ++ // OpenSSL guarantees API and ABI compatibility within the same major version since OpenSSL 3. ++ supported = true ++ } ++ if !supported { ++ return 0, 0, 0, errUnsupportedVersion() ++ } ++ ++ // Load the OpenSSL functions. ++ // See shims.go for the complete list of supported functions. ++ C.go_openssl_load_functions(handle, C.uint(major), C.uint(minor), C.uint(patch)) ++ ++ // Initialize OpenSSL. ++ C.go_openssl_OPENSSL_init() ++ if major == 1 && minor == 0 { ++ if C.go_openssl_thread_setup() != 1 { ++ return 0, 0, 0, fail("openssl: thread setup") ++ } ++ C.go_openssl_OPENSSL_add_all_algorithms_conf() ++ C.go_openssl_ERR_load_crypto_strings() ++ } else { ++ flags := C.uint64_t(C.GO_OPENSSL_INIT_ADD_ALL_CIPHERS | C.GO_OPENSSL_INIT_ADD_ALL_DIGESTS | C.GO_OPENSSL_INIT_LOAD_CONFIG | C.GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS) ++ if C.go_openssl_OPENSSL_init_crypto(flags, nil) != 1 { ++ return 0, 0, 0, fail("openssl: init crypto") ++ } + } ++ return major, minor, patch, nil +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go b/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go +new file mode 100644 +index 0000000000..dbf5ac448f +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go +@@ -0,0 +1,31 @@ ++//go:build unix && !cmd_go_bootstrap + -+func RestoreOpenSSLRand() { -+ if randstub { -+ randstub = false -+ C._goboringcrypto_restore_openssl_rand() -+ } -+} ++package openssl + -+func hasSuffix(s, t string) bool { -+ return len(s) > len(t) && s[len(s)-len(t):] == t -+} ++// #cgo LDFLAGS: -ldl ++// #include ++// #include ++import "C" ++import ( ++ "errors" ++ "unsafe" ++) + -+func PanicIfStrictFIPS(msg string) { -+ if IsStrictFips() { -+ panic(msg) ++func dlopen(file string) (handle unsafe.Pointer, err error) { ++ cv := C.CString(file) ++ defer C.free(unsafe.Pointer(cv)) ++ handle = C.dlopen(cv, C.RTLD_LAZY|C.RTLD_LOCAL) ++ if handle == nil { ++ errstr := C.GoString(C.dlerror()) ++ return nil, errors.New("openssl: can't load " + file + ": " + errstr) + } ++ return handle, nil +} + -+func IsStrictFips() bool { -+ return os.Getenv(GoStrictFipsEnv) == "1" || strictFIPS ++func dlclose(handle unsafe.Pointer) error { ++ if C.dlclose(handle) != 0 { ++ errstr := C.GoString(C.dlerror()) ++ return errors.New("openssl: can't close libcrypto: " + errstr) ++ } ++ return nil +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go b/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go +new file mode 100644 +index 0000000000..3778e21227 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go +@@ -0,0 +1,36 @@ ++//go:build !cmd_go_bootstrap + -+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 -+ } ++package openssl + -+ 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]))) ++import ( ++ "syscall" ++ "unsafe" ++) + -+ } -+ return errors.New(message) ++type dlopenError struct { ++ file string ++ err error +} + -+// 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") -+ } ++func (e *dlopenError) Error() string { ++ return "openssl: can't load " + e.file + ": " + e.err.Error() +} + -+// 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") ++func (e *dlopenError) Unwrap() error { ++ return e.err ++} ++ ++func dlopen(file string) (handle unsafe.Pointer, err error) { ++ // As Windows generally does not ship with a system OpenSSL library, let ++ // alone a FIPS 140 certified one, use the default library search order so ++ // that we preferentially load the DLL bundled with the application. ++ h, err := syscall.LoadLibrary(file) ++ if err != nil { ++ return nil, &dlopenError{file: file, err: err} + } ++ return unsafe.Pointer(h), nil +} + -+// ExecutingTest returns a boolean indicating if we're -+// executing under a test binary or not. -+func ExecutingTest() bool { -+ name := os.Args[0] -+ return hasSuffix(name, "_test") || hasSuffix(name, ".test") ++func dlclose(handle unsafe.Pointer) error { ++ return syscall.FreeLibrary(syscall.Handle(handle)) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/openssl.go b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go +new file mode 100644 +index 0000000000..691bb16f72 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go +@@ -0,0 +1,419 @@ ++//go:build !cmd_go_bootstrap + -+type fail string ++// Package openssl provides access to OpenSSL cryptographic functions. ++package openssl + -+func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" } ++// #include "goopenssl.h" ++import "C" ++import ( ++ "encoding/binary" ++ "errors" ++ "math/bits" ++ "runtime" ++ "strconv" ++ "strings" ++ "sync" ++ "unsafe" ++) + -+const wordBytes = bits.UintSize / 8 ++var ( ++ // vMajor and vMinor hold the major/minor OpenSSL version. ++ // It is only populated if Init has been called. ++ vMajor, vMinor, vPatch uint ++) + -+// 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 ++var ( ++ initOnce sync.Once ++ initErr error ++) ++ ++var nativeEndian binary.ByteOrder ++ ++// CheckVersion checks if the OpenSSL version can be loaded ++// and if the FIPS mode is enabled. ++// This function can be called before Init. ++func CheckVersion(version string) (exists, fips bool) { ++ handle, _ := dlopen(version) ++ if handle == nil { ++ return false, false + } ++ defer dlclose(handle) ++ fips = C.go_openssl_fips_enabled(handle) == 1 ++ return true, fips +} + -+func wbase(b BigInt) *C.uint8_t { -+ if len(b) == 0 { -+ return nil -+ } -+ return (*C.uint8_t)(unsafe.Pointer(&b[0])) ++// Init loads and initializes OpenSSL from the shared library at path. ++// It must be called before any other OpenSSL call, except CheckVersion. ++// ++// Only the first call to Init is effective. ++// Subsequent calls will return the same error result as the one from the first call. ++// ++// The file is passed to dlopen() verbatim to load the OpenSSL shared library. ++// For example, `file=libcrypto.so.1.1.1k-fips` makes Init look for the shared ++// library libcrypto.so.1.1.1k-fips. ++func Init(file string) error { ++ initOnce.Do(func() { ++ 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.") ++ } ++ vMajor, vMinor, vPatch, initErr = opensslInit(file) ++ }) ++ return initErr +} + -+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 utoa(n uint) string { ++ return strconv.FormatUint(uint64(n), 10) +} + -+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 errUnsupportedVersion() error { ++ return errors.New("openssl: OpenSSL version: " + utoa(vMajor) + "." + utoa(vMinor) + "." + utoa(vPatch)) ++} ++ ++type fail string ++ ++func (e fail) Error() string { return "openssl: " + string(e) + " failed" } ++ ++// VersionText returns the version text of the OpenSSL currently loaded. ++func VersionText() string { ++ return C.GoString(C.go_openssl_OpenSSL_version(0)) +} + -+func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool { -+ if *bnp != nil { -+ C._goboringcrypto_BN_free(*bnp) -+ *bnp = nil ++var ( ++ providerNameFips = C.CString("fips") ++ providerNameDefault = C.CString("default") ++) ++ ++// FIPS returns true if OpenSSL is running in FIPS mode, else returns false. ++func FIPS() bool { ++ switch vMajor { ++ case 1: ++ return C.go_openssl_FIPS_mode() == 1 ++ case 3: ++ // If FIPS is not enabled via default properties, then we are sure FIPS is not used. ++ if C.go_openssl_EVP_default_properties_is_fips_enabled(nil) == 0 { ++ return false ++ } ++ // EVP_default_properties_is_fips_enabled can return true even if the FIPS provider isn't loaded, ++ // it is only based on the default properties. ++ // We can be sure that the FIPS provider is available if we can fetch an algorithm, e.g., SHA2-256, ++ // explicitly setting `fips=yes`. ++ return C.go_openssl_OSSL_PROVIDER_available(nil, providerNameFips) == 1 ++ default: ++ panic(errUnsupportedVersion()) + } -+ if b == nil { -+ return true ++} ++ ++// SetFIPS enables or disables FIPS mode. ++// ++// For OpenSSL 3, the `fips` provider is loaded if enabled is true, ++// else the `default` provider is loaded. ++func SetFIPS(enabled bool) error { ++ var mode C.int ++ if enabled { ++ mode = C.int(1) ++ } else { ++ mode = C.int(0) + } -+ bn := bigToBN(b) -+ if bn == nil { -+ return false ++ switch vMajor { ++ case 1: ++ if C.go_openssl_FIPS_mode_set(mode) != 1 { ++ return newOpenSSLError("FIPS_mode_set") ++ } ++ return nil ++ case 3: ++ var provName *C.char ++ if enabled { ++ provName = providerNameFips ++ } else { ++ provName = providerNameDefault ++ } ++ // Check if there is any provider that matches props. ++ if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { ++ // If not, fallback to provName provider. ++ if C.go_openssl_OSSL_PROVIDER_load(nil, provName) == nil { ++ return newOpenSSLError("OSSL_PROVIDER_try_load") ++ } ++ // Make sure we now have a provider available. ++ if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { ++ return fail("SetFIPS(" + strconv.FormatBool(enabled) + ") not supported") ++ } ++ } ++ if C.go_openssl_EVP_default_properties_enable_fips(nil, mode) != 1 { ++ return newOpenSSLError("openssl: EVP_default_properties_enable_fips") ++ } ++ return nil ++ default: ++ panic(errUnsupportedVersion()) + } -+ *bnp = bn -+ return true +} + -+// noescape hides a pointer from escape analysis. noescape is ++// 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 ++// output depends on the input. noescape is inlined and currently +// compiles down to zero instructions. +// USE CAREFULLY! +// @@ -5192,1985 +7985,1507 @@ index 0000000000..e93b042e5e + } + 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; ++// 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.uchar { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uchar)(unsafe.Pointer(&b[0])) +} -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; ++func sbase(b []byte) *C.char { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.char)(unsafe.Pointer(&b[0])) +} + -+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; ++func newOpenSSLError(msg string) error { ++ var b strings.Builder ++ b.WriteString(msg) ++ b.WriteString("\nopenssl error(s):") ++ for { ++ var ( ++ e C.ulong ++ file *C.char ++ line C.int ++ ) ++ switch vMajor { ++ case 1: ++ e = C.go_openssl_ERR_get_error_line(&file, &line) ++ case 3: ++ e = C.go_openssl_ERR_get_error_all(&file, &line, nil, nil, nil) ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ if e == 0 { ++ break ++ } ++ b.WriteByte('\n') ++ var buf [256]byte ++ C.go_openssl_ERR_error_string_n(e, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) ++ b.WriteString(string(buf[:]) + "\n\t" + C.GoString(file) + ":" + strconv.Itoa(int(line))) ++ } ++ return errors.New(b.String()) +} + -+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; ++var unknownFile = "\000" + -+err: -+ if (mdctx) -+ _goboringcrypto_EVP_MD_CTX_free(mdctx); -+ -+ return ret; ++// caller reports file and line number information about function invocations on ++// the calling goroutine's stack, in a form suitable for passing to C code. ++// The argument skip is the number of stack frames to ascend, with 0 identifying ++// the caller of caller. The return values report the file name and line number ++// within the file of the corresponding call. The returned file is a C string ++// with static storage duration. ++func caller(skip int) (file *C.char, line C.int) { ++ _, f, l, ok := runtime.Caller(skip + 1) ++ if !ok { ++ f = unknownFile ++ } ++ // The underlying bytes of the file string are null-terminated rodata with ++ // static lifetimes, so can be safely passed to C without worrying about ++ // leaking memory or use-after-free. ++ return (*C.char)(noescape(unsafe.Pointer(unsafe.StringData(f)))), C.int(l) +} + -+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; ++// cryptoMalloc allocates n bytes of memory on the OpenSSL heap, which may be ++// different from the heap which C.malloc allocates on. The allocated object ++// must be freed using cryptoFree. cryptoMalloc is equivalent to the ++// OPENSSL_malloc macro. ++// ++// Like C.malloc, this function is guaranteed to never return nil. If OpenSSL's ++// malloc indicates out of memory, it crashes the program. ++// ++// Only objects which the OpenSSL library will take ownership of (i.e. will be ++// freed by OPENSSL_free / CRYPTO_free) need to be allocated on the OpenSSL ++// heap. ++func cryptoMalloc(n int) unsafe.Pointer { ++ file, line := caller(1) ++ var p unsafe.Pointer ++ if vMajor == 1 && vMinor == 0 { ++ p = C.go_openssl_CRYPTO_malloc_legacy102(C.int(n), file, line) ++ } else { ++ p = C.go_openssl_CRYPTO_malloc(C.size_t(n), file, line) ++ } ++ if p == nil { ++ // Un-recover()-ably crash the program in the same manner as the ++ // C.malloc() wrapper function. ++ runtime_throw("openssl: CRYPTO_malloc failed") ++ } ++ return p ++} + -+ if (!(_goboringcrypto_EVP_PKEY_set1_RSA(pk, rsa_key))) -+ goto err; ++// cryptoFree frees an object allocated on the OpenSSL heap, which may be ++// different from the heap which C.malloc allocates on. cryptoFree is equivalent ++// to the OPENSSL_free macro. ++func cryptoFree(p unsafe.Pointer) { ++ if vMajor == 1 && vMinor == 0 { ++ C.go_openssl_CRYPTO_free_legacy102(p) ++ return ++ } ++ file, line := caller(1) ++ C.go_openssl_CRYPTO_free(p, file, line) ++} + -+ if (!(ctx = _goboringcrypto_EVP_PKEY_CTX_new(pk, NULL))) -+ goto err; ++const wordBytes = bits.UintSize / 8 + -+ if (1 != _goboringcrypto_EVP_PKEY_verify_init(ctx)) -+ goto err; ++// 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 ++ } ++} + -+ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) -+ goto err; ++func wbase(b BigInt) *C.uchar { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uchar)(unsafe.Pointer(&b[0])) ++} + -+ if (1 != _goboringcrypto_EVP_PKEY_verify(ctx, sig, slen, msg, msgLen)) -+ goto err; ++// bignum_st_1_0_2 is bignum_st (BIGNUM) memory layout in OpenSSL 1.0.2. ++type bignum_st_1_0_2 struct { ++ d unsafe.Pointer // Pointer to an array of BN_ULONG bit chunks ++ top C.int // Index of last used d +1 ++ dmax C.int ++ neg C.int ++ flags C.int ++} + -+ /* Success */ -+ ret = 1; ++func bigToBN(x BigInt) C.GO_BIGNUM_PTR { ++ if len(x) == 0 { ++ return nil ++ } + -+err: -+ if (ctx) -+ _goboringcrypto_EVP_PKEY_CTX_free(ctx); -+ if (pk) -+ _goboringcrypto_EVP_PKEY_free(pk); ++ if vMajor == 1 && vMinor == 0 { ++ // OpenSSL 1.0.x does not export bn_lebin2bn on all platforms, ++ // so we have to emulate it. ++ bn := C.go_openssl_BN_new() ++ if bn == nil { ++ return nil ++ } ++ if C.go_openssl_bn_expand2(bn, C.int(len(x))) == nil { ++ C.go_openssl_BN_free(bn) ++ panic(newOpenSSLError("BN_expand2")) ++ } ++ // The bytes of a BigInt are laid out in memory in the same order as a ++ // BIGNUM, regardless of host endianness. ++ bns := (*bignum_st_1_0_2)(unsafe.Pointer(bn)) ++ d := unsafe.Slice((*uint)(bns.d), len(x)) ++ bns.top = C.int(copy(d, x)) ++ return bn ++ } + -+ return ret; ++ 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.go_openssl_BN_lebin2bn(wbase(x), C.int(len(x)*wordBytes), nil) +} -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() ++func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { ++ if bn == nil { ++ return nil ++ } + -+/* This array will store all of the mutexes available to OpenSSL. */ -+static MUTEX_TYPE *mutex_buf = NULL; ++ if vMajor == 1 && vMinor == 0 { ++ // OpenSSL 1.0.x does not export bn_bn2lebinpad on all platforms, ++ // so we have to emulate it. ++ bns := (*bignum_st_1_0_2)(unsafe.Pointer(bn)) ++ d := unsafe.Slice((*uint)(bns.d), bns.top) ++ x := make(BigInt, len(d)) ++ copy(x, d) ++ return x ++ } + -+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]); ++ // Limbs are always ordered in LSB first, so we can safely apply ++ // BN_bn2lebinpad regardless of host endianness. ++ x := make(BigInt, C.go_openssl_BN_num_bits(bn)) ++ if C.go_openssl_BN_bn2lebinpad(bn, wbase(x), C.int(len(x)*wordBytes)) == 0 { ++ panic("openssl: bignum conversion failed") ++ } ++ if nativeEndian == binary.BigEndian { ++ x.byteSwap() ++ } ++ return x +} + -+static unsigned long id_function(void) { -+ return ((unsigned long)syscall(__NR_gettid)); ++func bnNumBytes(bn C.GO_BIGNUM_PTR) int { ++ return (int(C.go_openssl_BN_num_bits(bn)) + 7) / 8 +} + -+int _goboringcrypto_OPENSSL_thread_setup(void) { -+ int i; ++// bnToBinPad converts the absolute value of bn into big-endian form and stores ++// it at to, padding with zeroes if necessary. If len(to) is not large enough to ++// hold the result, an error is returned. ++func bnToBinPad(bn C.GO_BIGNUM_PTR, to []byte) error { ++ if vMajor == 1 && vMinor == 0 { ++ // OpenSSL 1.0.x does not export bn_bn2binpad on all platforms, ++ // so we have to emulate it. ++ n := bnNumBytes(bn) ++ pad := len(to) - n ++ if pad < 0 { ++ return errors.New("openssl: destination buffer too small") ++ } ++ for i := 0; i < pad; i++ { ++ to[i] = 0 ++ } ++ if int(C.go_openssl_BN_bn2bin(bn, base(to[pad:]))) != n { ++ return errors.New("openssl: BN_bn2bin short write") ++ } ++ return nil ++ } + -+ 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; ++ if C.go_openssl_BN_bn2binpad(bn, base(to), C.int(len(to))) < 0 { ++ return newOpenSSLError("BN_bn2binpad") ++ } ++ return nil +} -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; -+ } ++func CheckLeaks() { ++ C.go_openssl_do_leak_check() +} + -+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; -+ } ++// versionAtOrAbove returns true when ++// (vMajor, vMinor, vPatch) >= (major, minor, patch), ++// compared lexicographically. ++func versionAtOrAbove(major, minor, patch uint) bool { ++ return vMajor > major || (vMajor == major && vMinor > minor) || (vMajor == major && vMinor == minor && vPatch >= patch) +} -diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go new file mode 100644 -index 0000000000..df4ebe3297 +index 0000000000..a895eab2d5 --- /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 ++++ b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go +@@ -0,0 +1,28 @@ ++//go:build !cmd_go_bootstrap + -+#include "goopenssl.h" ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++ "hash" ++) + -+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); ++func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) ([]byte, error) { ++ md := hashToMD(h()) ++ if md == nil { ++ return nil, errors.New("unsupported hash function") ++ } ++ if len(password) == 0 && vMajor == 1 && vMinor == 0 { ++ // x/crypto/pbkdf2 supports empty passwords, but OpenSSL 1.0.2 ++ // does not. As a workaround, we pass an "empty" password. ++ password = make([]byte, C.GO_EVP_MAX_MD_SIZE) ++ } ++ out := make([]byte, keyLen) ++ ok := C.go_openssl_PKCS5_PBKDF2_HMAC(sbase(password), C.int(len(password)), base(salt), C.int(len(salt)), C.int(iter), md, C.int(keyLen), base(out)) ++ if ok != 1 { ++ return nil, newOpenSSLError("PKCS5_PBKDF2_HMAC") ++ } ++ return out, nil +} -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 +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c new file mode 100644 -index 0000000000..8205b040c5 +index 0000000000..50d49b1f10 --- /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 ++++ b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c +@@ -0,0 +1,126 @@ ++// 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" ++/* ++ * 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 ++ */ + -+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; ++#include "goopenssl.h" + -+ point = _goboringcrypto_EC_POINT_new(group); -+ if (!point) -+ return NULL; ++#define NID_md5_sha1 114 ++ ++#define MD5_CBLOCK 64 ++#define MD5_LBLOCK (MD5_CBLOCK/4) ++#define MD5_DIGEST_LENGTH 16 ++#define SHA_LBLOCK 16 ++#define SHA_DIGEST_LENGTH 20 ++ ++#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} ++ ++// Change: MD5_LONG and SHA_LONG have been expanded to unsigned int, ++// which is always 32 bits. This avoids adding some obscure logic ++// to support 16-bit platforms. ++ ++# define MD5_LONG unsigned int ++# define SHA_LONG unsigned int ++ ++typedef struct env_md_st EVP_MD; ++typedef struct env_md_ctx_st EVP_MD_CTX; ++ ++struct env_md_ctx_st { ++ void *digest; ++ void *engine; ++ unsigned long flags; ++ void *md_data; ++ void *pctx; ++ void *update; ++} /* EVP_MD_CTX */ ; ++ ++struct env_md_st { ++ int type; ++ int pkey_type; ++ int md_size; ++ unsigned long flags; ++ int (*init) (EVP_MD_CTX *ctx); ++ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); ++ int (*final) (EVP_MD_CTX *ctx, unsigned char *md); ++ void *copy; ++ void *cleanup; ++ void *sign; ++ void *verify; ++ int required_pkey_type[5]; ++ int block_size; ++ int ctx_size; ++ void *md_ctrl; ++} /* EVP_MD */ ; ++ ++typedef struct MD5state_st { ++ MD5_LONG A, B, C, D; ++ MD5_LONG Nl, Nh; ++ MD5_LONG data[MD5_LBLOCK]; ++ MD5_LONG num; ++} MD5_CTX; ++ ++typedef struct SHAstate_st { ++ SHA_LONG h0, h1, h2, h3, h4; ++ SHA_LONG Nl, Nh; ++ SHA_LONG data[SHA_LBLOCK]; ++ SHA_LONG num; ++} SHA_CTX; + -+ if (_goboringcrypto_EC_POINT_mul(group, point, priv, NULL, NULL, NULL) != 1) { -+ _goboringcrypto_EC_POINT_free(point); -+ return NULL; -+ } ++struct md5_sha1_ctx { ++ MD5_CTX md5; ++ SHA_CTX sha1; ++}; + -+ return point; ++static int md5_sha1_init(EVP_MD_CTX *ctx) { ++ struct md5_sha1_ctx *mctx = ctx->md_data; ++ if (!go_openssl_MD5_Init(&mctx->md5)) ++ return 0; ++ return go_openssl_SHA1_Init(&mctx->sha1); +} + -+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; ++static int md5_sha1_update(EVP_MD_CTX *ctx, const void *data, ++ size_t count) { ++ struct md5_sha1_ctx *mctx = ctx->md_data; ++ if (!go_openssl_MD5_Update(&mctx->md5, data, count)) ++ return 0; ++ return go_openssl_SHA1_Update(&mctx->sha1, data, count); ++} + -+ 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; ++static int md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) { ++ struct md5_sha1_ctx *mctx = ctx->md_data; ++ if (!go_openssl_MD5_Final(md, &mctx->md5)) ++ return 0; ++ return go_openssl_SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); ++} + -+ if (is_private) { -+ BIGNUM *priv; ++// Change: Removed: ++// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) + -+ priv = _goboringcrypto_BN_bin2bn(bytes, len, NULL); -+ if (!priv) -+ goto err; ++static const EVP_MD md5_sha1_md = { ++ NID_md5_sha1, ++ NID_md5_sha1, ++ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, ++ 0, ++ md5_sha1_init, ++ md5_sha1_update, ++ md5_sha1_final, ++ NULL, ++ NULL, ++ EVP_PKEY_NULL_method, // Change: inserted ++ MD5_CBLOCK, ++ sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), ++ NULL, // Change: was ctrl ++}; + -+ if (!_goboringcrypto_internal_OSSL_PARAM_BLD_push_BN(bld, "priv", priv)) { -+ _goboringcrypto_BN_clear_free(priv); -+ goto err; -+ } ++// Change: Apply name mangling. ++const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void) { ++ return (const GO_EVP_MD_PTR)&md5_sha1_md; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rand.go b/src/vendor/github.com/golang-fips/openssl/v2/rand.go +new file mode 100644 +index 0000000000..9fd709635c +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rand.go +@@ -0,0 +1,20 @@ ++//go:build !cmd_go_bootstrap + -+ params = _goboringcrypto_internal_OSSL_PARAM_BLD_to_param(bld); -+ if (!params) { -+ _goboringcrypto_BN_clear_free(priv); -+ goto err; -+ } ++package openssl + -+ _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; ++// #include "goopenssl.h" ++import "C" ++import "unsafe" + -+ params = _goboringcrypto_internal_OSSL_PARAM_BLD_to_param(bld); -+ if (!params) -+ goto err; ++type randReader int + -+ selection = GO_EVP_PKEY_PUBLIC_KEY; ++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.go_openssl_RAND_bytes((*C.uchar)(unsafe.Pointer(&b[0])), C.int(len(b))) == 0 { ++ return 0, newOpenSSLError("RAND_bytes") + } ++ return len(b), nil ++} + -+ ctx = _goboringcrypto_EVP_PKEY_CTX_new_id(GO_EVP_PKEY_EC, NULL); -+ if (!ctx) -+ goto err; ++const RandReader = randReader(0) +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rc4.go b/src/vendor/github.com/golang-fips/openssl/v2/rc4.go +new file mode 100644 +index 0000000000..f88150591e +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rc4.go +@@ -0,0 +1,66 @@ ++//go:build !cmd_go_bootstrap + -+ if (_goboringcrypto_internal_EVP_PKEY_fromdata_init(ctx) != 1) -+ goto err; ++package openssl + -+ if (_goboringcrypto_internal_EVP_PKEY_fromdata(ctx, &result, selection, ¶ms[0]) != 1) -+ goto err; ++// #include "goopenssl.h" ++import "C" ++import "runtime" + -+err: -+ _goboringcrypto_internal_OSSL_PARAM_BLD_free(bld); -+ _goboringcrypto_internal_OSSL_PARAM_free(params); -+ _goboringcrypto_EVP_PKEY_CTX_free(ctx); -+ return result; ++// SupportsRC4 returns true if NewRC4Cipher is supported. ++func SupportsRC4() bool { ++ // True for stock OpenSSL 1 w/o FIPS. ++ // False for stock OpenSSL 3 unless the legacy provider is available. ++ return (versionAtOrAbove(1, 1, 0) || !FIPS()) && loadCipher(cipherRC4, cipherModeNone) != nil +} + -+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; ++// A RC4Cipher is an instance of RC4 using a particular key. ++type RC4Cipher struct { ++ ctx C.GO_EVP_CIPHER_CTX_PTR ++} + -+ *result = malloc(len); -+ if (!*result) { -+ _goboringcrypto_internal_CRYPTO_free(res, __FILE__, __LINE__); -+ return 0; ++// NewRC4Cipher creates and returns a new Cipher. ++func NewRC4Cipher(key []byte) (*RC4Cipher, error) { ++ ctx, err := newCipherCtx(cipherRC4, cipherModeNone, cipherOpEncrypt, key, nil) ++ if err != nil { ++ return nil, err + } -+ memcpy(*result, res, len); -+ _goboringcrypto_internal_CRYPTO_free(res, __FILE__, __LINE__); -+ return len; ++ c := &RC4Cipher{ctx} ++ runtime.SetFinalizer(c, (*RC4Cipher).finalize) ++ return c, nil +} + -+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; ++func (c *RC4Cipher) finalize() { ++ if c.ctx != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) ++ } ++} + -+err: -+ _goboringcrypto_EC_GROUP_free(group); -+ _goboringcrypto_EC_POINT_free(point); -+ _goboringcrypto_BN_free(priv); -+ free(pub); -+ return result; ++// Reset zeros the key data and makes the Cipher unusable. ++func (c *RC4Cipher) Reset() { ++ if c.ctx != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) ++ c.ctx = nil ++ } +} + -+#else ++// XORKeyStream sets dst to the result of XORing src with the key stream. ++// Dst and src must overlap entirely or not at all. ++func (c *RC4Cipher) XORKeyStream(dst, src []byte) { ++ if c.ctx == nil || len(src) == 0 { ++ return ++ } ++ if inexactOverlap(dst[:len(src)], src) { ++ panic("crypto/rc4: invalid buffer overlap") ++ } ++ // panic if len(dst) < len(src) with a runtime out of bound error, ++ // which is what crypto/rc4 does. ++ _ = dst[len(src)-1] ++ var outLen C.int ++ if C.go_openssl_EVP_EncryptUpdate(c.ctx, base(dst), &outLen, base(src), C.int(len(src))) != 1 { ++ panic("crypto/cipher: EncryptUpdate failed") ++ } ++ if int(outLen) != len(src) { ++ panic("crypto/rc4: src not fully XORed") ++ } ++ runtime.KeepAlive(c) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rsa.go b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go +new file mode 100644 +index 0000000000..5aef65b84f +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go +@@ -0,0 +1,419 @@ ++//go:build !cmd_go_bootstrap + -+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; ++package openssl + -+ key = _goboringcrypto_EC_KEY_new_by_curve_name(nid); -+ if (!key) -+ goto err; ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "crypto/subtle" ++ "errors" ++ "hash" ++ "runtime" ++ "unsafe" ++) + -+ if (is_private) { -+ BIGNUM *priv; ++var ( ++ paramRSA_N = C.CString("n") ++ paramRSA_E = C.CString("e") ++ paramRSA_D = C.CString("d") ++ paramRSA_P = C.CString("rsa-factor1") ++ paramRSA_Q = C.CString("rsa-factor2") ++ paramRSA_Dp = C.CString("rsa-exponent1") ++ paramRSA_Dq = C.CString("rsa-exponent2") ++ paramRSA_Qinv = C.CString("rsa-coefficient1") ++) + -+ 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; ++func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { ++ bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { ++ return nil, nil, nil, nil, nil, nil, nil, nil, e ++ } ++ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_RSA, bits, "") ++ if err != nil { ++ return bad(err) ++ } ++ defer C.go_openssl_EVP_PKEY_free(pkey) ++ switch vMajor { ++ case 1: ++ key := C.go_openssl_EVP_PKEY_get1_RSA(pkey) ++ if key == nil { ++ return bad(newOpenSSLError("EVP_PKEY_get1_RSA failed")) + } -+ _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; ++ defer C.go_openssl_RSA_free(key) ++ var n, e, d, p, q, dmp1, dmq1, iqmp C.GO_BIGNUM_PTR ++ if vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ n, e, d, p, q, dmp1, dmq1, iqmp = r.n, r.e, r.d, r.p, r.q, r.dmp1, r.dmq1, r.iqmp ++ } else { ++ C.go_openssl_RSA_get0_key(key, &n, &e, &d) ++ C.go_openssl_RSA_get0_factors(key, &p, &q) ++ C.go_openssl_RSA_get0_crt_params(key, &dmp1, &dmq1, &iqmp) + } -+ if (_goboringcrypto_EC_POINT_oct2point(group, pub, bytes, len, NULL) != 1) { -+ _goboringcrypto_EC_POINT_free(pub); -+ goto err; ++ N, E, D = bnToBig(n), bnToBig(e), bnToBig(d) ++ P, Q = bnToBig(p), bnToBig(q) ++ Dp, Dq, Qinv = bnToBig(dmp1), bnToBig(dmq1), bnToBig(iqmp) ++ case 3: ++ tmp := C.go_openssl_BN_new() ++ if tmp == nil { ++ return bad(newOpenSSLError("BN_new failed")) ++ } ++ defer func() { ++ C.go_openssl_BN_clear_free(tmp) ++ }() ++ var err error ++ setBigInt := func(bi *BigInt, param *C.char) bool { ++ if err != nil { ++ return false ++ } ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, param, &tmp) != 1 { ++ err = newOpenSSLError("EVP_PKEY_get_bn_param failed") ++ return false ++ } ++ *bi = bnToBig(tmp) ++ C.go_openssl_BN_clear(tmp) ++ return true + } -+ if (_goboringcrypto_EC_KEY_set_public_key(key, pub) != 1) { -+ _goboringcrypto_EC_POINT_free(pub); -+ goto err; ++ if !(setBigInt(&N, paramRSA_N) && ++ setBigInt(&E, paramRSA_E) && ++ setBigInt(&D, paramRSA_D) && ++ setBigInt(&P, paramRSA_P) && ++ setBigInt(&Q, paramRSA_Q) && ++ setBigInt(&Dp, paramRSA_Dp) && ++ setBigInt(&Dq, paramRSA_Dq) && ++ setBigInt(&Qinv, paramRSA_Qinv)) { ++ return bad(err) + } -+ _goboringcrypto_EC_POINT_free(pub); ++ default: ++ panic(errUnsupportedVersion()) + } ++ return ++} + -+ result = _goboringcrypto_EVP_PKEY_new(); -+ if (!result) -+ goto err; ++type PublicKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} + -+ if (_goboringcrypto_EVP_PKEY_assign_EC_KEY(result, key) != 1) { -+ _goboringcrypto_EVP_PKEY_free(result); -+ result = NULL; -+ goto err; ++func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { ++ var pkey C.GO_EVP_PKEY_PTR ++ switch vMajor { ++ case 1: ++ key := C.go_openssl_RSA_new() ++ if key == nil { ++ return nil, newOpenSSLError("RSA_new failed") ++ } ++ if !rsaSetKey(key, N, E, nil) { ++ return nil, fail("RSA_set0_key") ++ } ++ pkey = C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ C.go_openssl_RSA_free(key) ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { ++ C.go_openssl_RSA_free(key) ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ case 3: ++ var err error ++ if pkey, err = newRSAKey3(false, N, E, nil, nil, nil, nil, nil, nil); err != nil { ++ return nil, err ++ } ++ default: ++ panic(errUnsupportedVersion()) + } -+ key = NULL; -+ -+err: -+ _goboringcrypto_EC_KEY_free(key); -+ return result; ++ k := &PublicKeyRSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) ++ return k, nil +} + -+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); ++func (k *PublicKeyRSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+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; ++func (k *PublicKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ // Because of the finalizer, any time _pkey is passed to cgo, that call must ++ // be followed by a call to runtime.KeepAlive, to make sure k is not ++ // collected (and finalized) before the cgo call returns. ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} + -+ group = _goboringcrypto_EC_KEY_get0_group(key); -+ point = public_key_from_private(group, priv); -+ if (!point) -+ return 0; ++type PrivateKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} + -+ if (_goboringcrypto_EC_KEY_set_public_key(key, point) != 1) { -+ _goboringcrypto_EC_POINT_free(point); -+ return 0; ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) { ++ var pkey C.GO_EVP_PKEY_PTR ++ switch vMajor { ++ case 1: ++ key := C.go_openssl_RSA_new() ++ if key == nil { ++ return nil, newOpenSSLError("RSA_new failed") ++ } ++ if !rsaSetKey(key, N, E, D) { ++ return nil, fail("RSA_set0_key") ++ } ++ if P != nil && Q != nil { ++ if !rsaSetFactors(key, P, Q) { ++ return nil, fail("RSA_set0_factors") ++ } ++ } ++ if Dp != nil && Dq != nil && Qinv != nil { ++ if !rsaSetCRTParams(key, Dp, Dq, Qinv) { ++ return nil, fail("RSA_set0_crt_params") ++ } ++ } ++ pkey = C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ C.go_openssl_RSA_free(key) ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { ++ C.go_openssl_RSA_free(key) ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ case 3: ++ var err error ++ if pkey, err = newRSAKey3(true, N, E, D, P, Q, Dp, Dq, Qinv); err != nil { ++ return nil, err ++ } ++ default: ++ panic(errUnsupportedVersion()) + } -+ -+ _goboringcrypto_EC_POINT_free(point); -+ return 1; ++ k := &PrivateKeyRSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) ++ return k, nil +} + -+#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; ++func (k *PrivateKeyRSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+/* -+ * 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) ++func (k *PrivateKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ // Because of the finalizer, any time _pkey is passed to cgo, that call must ++ // be followed by a call to runtime.KeepAlive, to make sure k is not ++ // collected (and finalized) before the cgo call returns. ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} + -+#include -+#include -+#include -+#include -+#include -+#include ++func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, ciphertext) ++} + -+struct md5_sha1_ctx { -+ MD5_CTX md5; -+ SHA_CTX sha1; -+}; ++func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, msg) ++} + -+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); ++func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, ciphertext) +} + -+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); ++func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, msg) +} + -+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); ++func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ ret, err := evpDecrypt(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, ciphertext) ++ if err != nil { ++ return nil, err ++ } ++ // We could return here, but the Go standard library test expects DecryptRSANoPadding to verify the result ++ // in order to defend against errors in the CRT computation. ++ // ++ // The following code tries to replicate the verification implemented in the upstream function decryptAndCheck, found at ++ // https://github.com/golang/go/blob/9de1ac6ac2cad3871760d0aa288f5ca713afd0a6/src/crypto/rsa/rsa.go#L569-L582. ++ pub := &PublicKeyRSA{_pkey: priv._pkey} ++ // A private EVP_PKEY can be used as a public key as it contains the public information. ++ enc, err := EncryptRSANoPadding(pub, ret) ++ if err != nil { ++ return nil, err ++ } ++ // Upstream does not do a constant time comparison because it works with math/big instead of byte slices, ++ // and math/big does not support constant-time arithmetic yet. See #20654 for more info. ++ if subtle.ConstantTimeCompare(ciphertext, enc) != 1 { ++ return nil, errors.New("rsa: internal error") ++ } ++ return ret, nil +} + -+// Change: Removed: -+// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) ++func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, msg) ++} + -+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 -+}; ++func saltLength(saltLen int, sign bool) (C.int, error) { ++ // A salt length of -2 is valid in OpenSSL, but not in crypto/rsa, so reject ++ // it, and lengths < -2, before we convert to the OpenSSL sentinel values. ++ if saltLen <= -2 { ++ return 0, errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative") ++ } ++ // OpenSSL uses sentinel salt length values like Go crypto does, ++ // but the values don't fully match for rsa.PSSSaltLengthAuto (0). ++ if saltLen == 0 { ++ if sign { ++ if vMajor == 1 { ++ // OpenSSL 1.x uses -2 to mean maximal size when signing where Go crypto uses 0. ++ return C.GO_RSA_PSS_SALTLEN_MAX_SIGN, nil ++ } ++ // OpenSSL 3.x deprecated RSA_PSS_SALTLEN_MAX_SIGN ++ // and uses -3 to mean maximal size when signing where Go crypto uses 0. ++ return C.GO_RSA_PSS_SALTLEN_MAX, nil ++ } ++ // OpenSSL uses -2 to mean auto-detect size when verifying where Go crypto uses 0. ++ return C.GO_RSA_PSS_SALTLEN_AUTO, nil ++ } ++ return C.int(saltLen), nil ++} + -+// Change: Apply name mangling. -+const GO_EVP_MD *_goboringcrypto_backport_EVP_md5_sha1(void) { -+ return &md5_sha1_md; ++func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { ++ cSaltLen, err := saltLength(saltLen, true) ++ if err != nil { ++ return nil, err ++ } ++ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, hashed) +} -+#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" ++func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { ++ cSaltLen, err := saltLength(saltLen, false) ++ if err != nil { ++ return err ++ } ++ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, sig, hashed) ++} + -+// 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); ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, hashed) +} -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" ++func HashSignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte) ([]byte, error) { ++ return evpHashSign(priv.withKey, h, msg) ++} + -+// 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 ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { ++ if pub.withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { ++ size := C.go_openssl_EVP_PKEY_get_size(pkey) ++ if len(sig) < int(size) { ++ return 0 ++ } ++ return 1 ++ }) == 0 { ++ return errors.New("crypto/rsa: verification error") ++ } ++ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, sig, hashed) ++} + -+#include "goopenssl.h" -+#include ++func HashVerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte) error { ++ return evpHashVerify(pub.withKey, h, msg, sig) ++} + -+static RAND_METHOD fake_rand; -+static const RAND_METHOD *old_rand; ++// rsa_st_1_0_2 is rsa_st memory layout in OpenSSL 1.0.2. ++type rsa_st_1_0_2 struct { ++ _ C.int ++ _ C.long ++ _ [2]unsafe.Pointer ++ n, e, d C.GO_BIGNUM_PTR ++ p, q C.GO_BIGNUM_PTR ++ dmp1, dmq1, iqmp C.GO_BIGNUM_PTR ++ // It contains more fields, but we are not interesed on them. ++} + -+int _goboringcrypto_stub_openssl_rand(void) { -+ /* save old rand method */ -+ if ((old_rand = _goboringcrypto_RAND_get_rand_method()) == NULL) -+ return 0; ++func bnSet(b1 *C.GO_BIGNUM_PTR, b2 BigInt) { ++ if b2 == nil { ++ return ++ } ++ if *b1 != nil { ++ C.go_openssl_BN_clear_free(*b1) ++ } ++ *b1 = bigToBN(b2) ++} + -+ 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; ++func rsaSetKey(key C.GO_RSA_PTR, n, e, d BigInt) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ //r.d and d will be nil for public keys. ++ if (r.n == nil && n == nil) || ++ (r.e == nil && e == nil) { ++ return false ++ } ++ bnSet(&r.n, n) ++ bnSet(&r.e, e) ++ bnSet(&r.d, d) ++ return true ++ } ++ return C.go_openssl_RSA_set0_key(key, bigToBN(n), bigToBN(e), bigToBN(d)) == 1 +} + -+int _goboringcrypto_restore_openssl_rand(void) { -+ if (!_goboringcrypto_RAND_set_rand_method(old_rand)) -+ return 0; -+ else -+ return 1; ++func rsaSetFactors(key C.GO_RSA_PTR, p, q BigInt) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ if (r.p == nil && p == nil) || ++ (r.q == nil && q == nil) { ++ return false ++ } ++ bnSet(&r.p, p) ++ bnSet(&r.q, q) ++ return true ++ } ++ return C.go_openssl_RSA_set0_factors(key, bigToBN(p), bigToBN(q)) == 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; ++func rsaSetCRTParams(key C.GO_RSA_PTR, dmp1, dmq1, iqmp BigInt) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ if (r.dmp1 == nil && dmp1 == nil) || ++ (r.dmq1 == nil && dmq1 == nil) || ++ (r.iqmp == nil && iqmp == nil) { ++ return false ++ } ++ bnSet(&r.dmp1, dmp1) ++ bnSet(&r.dmq1, dmq1) ++ bnSet(&r.iqmp, iqmp) ++ return true ++ } ++ return C.go_openssl_RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == 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") -- } -- 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") -+ return nil, NewOpenSSLError("RSA_new failed") -+ } -+ 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 -- } -- -- // 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 -+ 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 ++ ++func newRSAKey3(isPriv bool, N, E, D, P, Q, Dp, Dq, Qinv BigInt) (C.GO_EVP_PKEY_PTR, error) { ++ // Construct the parameters. ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") ++ } ++ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) ++ var comps = [...]struct { ++ name *C.char ++ num BigInt ++ }{ ++ {paramRSA_N, N}, {paramRSA_E, E}, {paramRSA_D, D}, ++ {paramRSA_P, P}, {paramRSA_Q, Q}, ++ {paramRSA_Dp, Dp}, {paramRSA_Dq, Dq}, {paramRSA_Qinv, Qinv}, ++ } ++ for _, comp := range comps { ++ if comp.num == nil { ++ continue + } - } -- - 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 -- } -- -- // 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 -+ 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 ++ b := bigToBN(comp.num) ++ if b == nil { ++ return nil, newOpenSSLError("BN_lebin2bn failed") + } - } -- - 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()) ++ // b must remain valid until OSSL_PARAM_BLD_to_param has been called. ++ defer C.go_openssl_BN_clear_free(b) ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, comp.name, b) != 1 { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ } ++ } ++ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ if params == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_to_param") + } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ selection := C.GO_EVP_PKEY_PUBLIC_KEY ++ if isPriv { ++ selection = C.GO_EVP_PKEY_KEYPAIR ++ } ++ return newEvpFromParams(C.GO_EVP_PKEY_RSA, C.int(selection), params) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/shims.h b/src/vendor/github.com/golang-fips/openssl/v2/shims.h +new file mode 100644 +index 0000000000..4457a3e491 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/shims.h +@@ -0,0 +1,370 @@ ++#include // size_t ++#include // uint64_t ++ ++// #include ++enum { ++ GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS = 0x00000002L, ++ GO_OPENSSL_INIT_ADD_ALL_CIPHERS = 0x00000004L, ++ GO_OPENSSL_INIT_ADD_ALL_DIGESTS = 0x00000008L, ++ GO_OPENSSL_INIT_LOAD_CONFIG = 0x00000040L ++}; ++ ++// #include ++enum { ++ GO_EVP_CTRL_GCM_GET_TAG = 0x10, ++ GO_EVP_CTRL_GCM_SET_TAG = 0x11, ++ GO_EVP_PKEY_CTRL_MD = 1, ++ GO_EVP_PKEY_RSA = 6, ++ GO_EVP_PKEY_EC = 408, ++ GO_EVP_PKEY_TLS1_PRF = 1021, ++ GO_EVP_PKEY_HKDF = 1036, ++ GO_EVP_PKEY_ED25519 = 1087, ++ /* This is defined differently in OpenSSL 3 (1 << 11), but in our ++ * code it is only used in OpenSSL 1. ++ */ ++ GO1_EVP_PKEY_OP_DERIVE = (1 << 10), ++ GO_EVP_MAX_MD_SIZE = 64, ++ ++ GO_EVP_PKEY_PUBLIC_KEY = 0x86, ++ GO_EVP_PKEY_KEYPAIR = 0x87 ++}; ++ ++// #include ++enum { ++ GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = 0x1001 ++}; + -+ md := cryptoHashToMD(h) -+ if md == nil { -+ return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h))) -+ } ++// #include ++enum { ++ GO_EVP_KDF_HKDF_MODE_EXTRACT_ONLY = 1, ++ GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY = 2, ++ ++ GO_EVP_PKEY_CTRL_TLS_MD = 0x1000, ++ GO_EVP_PKEY_CTRL_TLS_SECRET = 0x1001, ++ GO_EVP_PKEY_CTRL_TLS_SEED = 0x1002, ++ GO_EVP_PKEY_CTRL_HKDF_MD = 0x1003, ++ GO_EVP_PKEY_CTRL_HKDF_SALT = 0x1004, ++ GO_EVP_PKEY_CTRL_HKDF_KEY = 0x1005, ++ GO_EVP_PKEY_CTRL_HKDF_INFO = 0x1006, ++ GO_EVP_PKEY_CTRL_HKDF_MODE = 0x1007 ++}; + -+ 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 - } - -- md := cryptoHashToMD(h) -- if md == nil { -- return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h))) -+ var out []byte -+ var outLen C.size_t ++typedef enum { ++ GO_POINT_CONVERSION_UNCOMPRESSED = 4, ++} point_conversion_form_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") - } -- nid := C._goboringcrypto_EVP_MD_type(md) -+ return out[:outLen], nil ++// #include ++enum { ++ GO_NID_X9_62_prime256v1 = 415, ++ GO_NID_secp224r1 = 713, ++ GO_NID_secp384r1 = 715, ++ GO_NID_secp521r1 = 716 ++}; ++ ++// #include ++enum { ++ GO_RSA_PKCS1_PADDING = 1, ++ GO_RSA_NO_PADDING = 3, ++ GO_RSA_PKCS1_OAEP_PADDING = 4, ++ GO_RSA_PKCS1_PSS_PADDING = 6, ++ GO_RSA_PSS_SALTLEN_DIGEST = -1, ++ GO_RSA_PSS_SALTLEN_AUTO = -2, ++ GO_RSA_PSS_SALTLEN_MAX_SIGN = -2, ++ GO_RSA_PSS_SALTLEN_MAX = -3, ++ GO_EVP_PKEY_CTRL_RSA_PADDING = 0x1001, ++ GO_EVP_PKEY_CTRL_RSA_PSS_SALTLEN = 0x1002, ++ GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS = 0x1003, ++ GO_EVP_PKEY_CTRL_RSA_MGF1_MD = 0x1005, ++ GO_EVP_PKEY_CTRL_RSA_OAEP_MD = 0x1009, ++ GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL = 0x100A ++}; ++ ++typedef void* GO_OPENSSL_INIT_SETTINGS_PTR; ++typedef void* GO_OSSL_LIB_CTX_PTR; ++typedef void* GO_OSSL_PROVIDER_PTR; ++typedef void* GO_ENGINE_PTR; ++typedef void* GO_EVP_PKEY_PTR; ++typedef void* GO_EVP_PKEY_CTX_PTR; ++typedef void* GO_EVP_MD_PTR; ++typedef void* GO_EVP_MD_CTX_PTR; ++typedef void* GO_HMAC_CTX_PTR; ++typedef void* GO_EVP_CIPHER_PTR; ++typedef void* GO_EVP_CIPHER_CTX_PTR; ++typedef void* GO_EC_KEY_PTR; ++typedef void* GO_EC_POINT_PTR; ++typedef void* GO_EC_GROUP_PTR; ++typedef void* GO_RSA_PTR; ++typedef void* GO_BIGNUM_PTR; ++typedef void* GO_BN_CTX_PTR; ++typedef void* GO_EVP_MAC_PTR; ++typedef void* GO_EVP_MAC_CTX_PTR; ++typedef void* GO_OSSL_PARAM_BLD_PTR; ++typedef void* GO_OSSL_PARAM_PTR; ++typedef void* GO_CRYPTO_THREADID_PTR; ++typedef void* GO_EVP_SIGNATURE_PTR; ++ ++// #include ++typedef void* GO_MD5_CTX_PTR; ++ ++// #include ++typedef void* GO_SHA_CTX_PTR; ++ ++// FOR_ALL_OPENSSL_FUNCTIONS is the list of all functions from libcrypto that are used in this package. ++// Forgetting to add a function here results in build failure with message reporting the function ++// that needs to be added. ++// ++// The purpose of FOR_ALL_OPENSSL_FUNCTIONS is to define all libcrypto functions ++// without depending on the openssl headers so it is easier to use this package ++// with an openssl version different that the one used at build time. ++// ++// The following macros may not be defined at this point, ++// they are not resolved here but just accumulated in FOR_ALL_OPENSSL_FUNCTIONS. ++// ++// DEFINEFUNC defines and loads openssl functions that can be directly called from Go as their signatures match ++// the OpenSSL API and do not require special logic. ++// The process will be aborted if the function can't be loaded. ++// ++// DEFINEFUNC_LEGACY_1_1 acts like DEFINEFUNC but only aborts the process if the function can't be loaded ++// when using 1.1.x. This indicates the function is required when using 1.1.x, but is unused when using later versions. ++// It also might not exist in later versions. ++// ++// DEFINEFUNC_LEGACY_1_0 acts like DEFINEFUNC but only aborts the process if the function can't be loaded ++// when using 1.0.x. This indicates the function is required when using 1.0.x, but is unused when using later versions. ++// It also might not exist in later versions. ++// ++// DEFINEFUNC_LEGACY_1 acts like DEFINEFUNC but only aborts the process if the function can't be loaded ++// when using 1.x. This indicates the function is required when using 1.x, but is unused when using later versions. ++// It also might not exist in later versions. ++// ++// DEFINEFUNC_1_1 acts like DEFINEFUNC but only aborts the process if function can't be loaded ++// when using 1.1.0 or higher. ++// ++// DEFINEFUNC_1_1_1 acts like DEFINEFUNC but only aborts the process if function can't be loaded ++// when using 1.1.1 or higher. ++// ++// DEFINEFUNC_3_0 acts like DEFINEFUNC but only aborts the process if function can't be loaded ++// when using 3.0.0 or higher. ++// ++// DEFINEFUNC_RENAMED_1_1 acts like DEFINEFUNC but tries to load the function using the new name when using >= 1.1.x ++// and the old name when using 1.0.2. In both cases the function will have the new name. ++// ++// DEFINEFUNC_RENAMED_3_0 acts like DEFINEFUNC but tries to load the function using the new name when using >= 3.x ++// and the old name when using 1.x. In both cases the function will have the new name. ++// ++// #include ++// #include ++// #include ++// #include ++// #include ++// #include ++// #include ++// #if OPENSSL_VERSION_NUMBER >= 0x30000000L ++// #include ++// #include ++// #endif ++// #if OPENSSL_VERSION_NUMBER < 0x10100000L ++// #include ++// #endif ++#define FOR_ALL_OPENSSL_FUNCTIONS \ ++DEFINEFUNC(void, ERR_error_string_n, (unsigned long e, char *buf, size_t len), (e, buf, len)) \ ++DEFINEFUNC_LEGACY_1(unsigned long, ERR_get_error_line, (const char **file, int *line), (file, line)) \ ++DEFINEFUNC_3_0(unsigned long, ERR_get_error_all, (const char **file, int *line, const char **func, const char **data, int *flags), (file, line, func, data, flags)) \ ++DEFINEFUNC_RENAMED_1_1(const char *, OpenSSL_version, SSLeay_version, (int type), (type)) \ ++DEFINEFUNC(void, OPENSSL_init, (void), ()) \ ++DEFINEFUNC_LEGACY_1_0(void, ERR_load_crypto_strings, (void), ()) \ ++DEFINEFUNC_LEGACY_1_0(int, CRYPTO_num_locks, (void), ()) \ ++DEFINEFUNC_LEGACY_1_0(int, CRYPTO_THREADID_set_callback, (void (*threadid_func) (GO_CRYPTO_THREADID_PTR)), (threadid_func)) \ ++DEFINEFUNC_LEGACY_1_0(void, CRYPTO_THREADID_set_numeric, (GO_CRYPTO_THREADID_PTR id, unsigned long val), (id, val)) \ ++DEFINEFUNC_LEGACY_1_0(void, CRYPTO_set_locking_callback, (void (*locking_function)(int mode, int n, const char *file, int line)), (locking_function)) \ ++/* CRYPTO_malloc argument num changes from int to size_t in OpenSSL 1.1.0, */ \ ++/* and CRYPTO_free has file and line arguments added. */ \ ++/* Exclude them from headercheck tool when using previous OpenSSL versions. */ \ ++/*check:from=1.1.0*/ DEFINEFUNC(void *, CRYPTO_malloc, (size_t num, const char *file, int line), (num, file, line)) \ ++/*check:from=1.1.0*/ DEFINEFUNC(void, CRYPTO_free, (void *str, const char *file, int line), (str, file, line)) \ ++DEFINEFUNC_LEGACY_1_0(void, OPENSSL_add_all_algorithms_conf, (void), ()) \ ++DEFINEFUNC_1_1(int, OPENSSL_init_crypto, (uint64_t ops, const GO_OPENSSL_INIT_SETTINGS_PTR settings), (ops, settings)) \ ++DEFINEFUNC_LEGACY_1(int, FIPS_mode, (void), ()) \ ++DEFINEFUNC_LEGACY_1(int, FIPS_mode_set, (int r), (r)) \ ++DEFINEFUNC_3_0(int, EVP_default_properties_is_fips_enabled, (GO_OSSL_LIB_CTX_PTR libctx), (libctx)) \ ++DEFINEFUNC_3_0(int, EVP_default_properties_enable_fips, (GO_OSSL_LIB_CTX_PTR libctx, int enable), (libctx, enable)) \ ++DEFINEFUNC_3_0(int, OSSL_PROVIDER_available, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ ++DEFINEFUNC_3_0(GO_OSSL_PROVIDER_PTR, OSSL_PROVIDER_load, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ ++DEFINEFUNC_3_0(GO_EVP_MD_PTR, EVP_MD_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ ++DEFINEFUNC_3_0(void, EVP_MD_free, (GO_EVP_MD_PTR md), (md)) \ ++DEFINEFUNC_3_0(const char *, EVP_MD_get0_name, (const GO_EVP_MD_PTR md), (md)) \ ++DEFINEFUNC(int, RAND_bytes, (unsigned char *arg0, int arg1), (arg0, arg1)) \ ++DEFINEFUNC_RENAMED_1_1(GO_EVP_MD_CTX_PTR, EVP_MD_CTX_new, EVP_MD_CTX_create, (void), ()) \ ++DEFINEFUNC_RENAMED_1_1(void, EVP_MD_CTX_free, EVP_MD_CTX_destroy, (GO_EVP_MD_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC(int, EVP_MD_CTX_copy, (GO_EVP_MD_CTX_PTR out, const GO_EVP_MD_CTX_PTR in), (out, in)) \ ++DEFINEFUNC(int, EVP_Digest, (const void *data, size_t count, unsigned char *md, unsigned int *size, const GO_EVP_MD_PTR type, GO_ENGINE_PTR impl), (data, count, md, size, type, impl)) \ ++DEFINEFUNC(int, EVP_DigestInit_ex, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR impl), (ctx, type, impl)) \ ++DEFINEFUNC(int, EVP_DigestInit, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type), (ctx, type)) \ ++DEFINEFUNC(int, EVP_DigestUpdate, (GO_EVP_MD_CTX_PTR ctx, const void *d, size_t cnt), (ctx, d, cnt)) \ ++DEFINEFUNC(int, EVP_DigestFinal, (GO_EVP_MD_CTX_PTR ctx, unsigned char *md, unsigned int *s), (ctx, md, s)) \ ++DEFINEFUNC_1_1_1(int, EVP_DigestSign, (GO_EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ ++DEFINEFUNC(int, EVP_DigestSignInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ ++DEFINEFUNC(int, EVP_DigestSignFinal, (GO_EVP_MD_CTX_PTR ctx, unsigned char *sig, size_t *siglen), (ctx, sig, siglen)) \ ++DEFINEFUNC(int, EVP_DigestVerifyInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ ++DEFINEFUNC(int, EVP_DigestVerifyFinal, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen), (ctx, sig, siglen)) \ ++DEFINEFUNC_1_1_1(int, EVP_DigestVerify, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ ++DEFINEFUNC_LEGACY_1_0(int, MD5_Init, (GO_MD5_CTX_PTR c), (c)) \ ++DEFINEFUNC_LEGACY_1_0(int, MD5_Update, (GO_MD5_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ ++DEFINEFUNC_LEGACY_1_0(int, MD5_Final, (unsigned char *md, GO_MD5_CTX_PTR c), (md, c)) \ ++DEFINEFUNC_LEGACY_1_0(int, SHA1_Init, (GO_SHA_CTX_PTR c), (c)) \ ++DEFINEFUNC_LEGACY_1_0(int, SHA1_Update, (GO_SHA_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ ++DEFINEFUNC_LEGACY_1_0(int, SHA1_Final, (unsigned char *md, GO_SHA_CTX_PTR c), (md, c)) \ ++DEFINEFUNC_1_1(const GO_EVP_MD_PTR, EVP_md5_sha1, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_md4, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_md5, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha1, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha224, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha256, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha384, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha512, (void), ()) \ ++DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_224, (void), ()) \ ++DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_256, (void), ()) \ ++DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_384, (void), ()) \ ++DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_512, (void), ()) \ ++DEFINEFUNC_LEGACY_1_0(void, HMAC_CTX_init, (GO_HMAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1_0(void, HMAC_CTX_cleanup, (GO_HMAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1(int, HMAC_Init_ex, (GO_HMAC_CTX_PTR arg0, const void *arg1, int arg2, const GO_EVP_MD_PTR arg3, GO_ENGINE_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC_LEGACY_1(int, HMAC_Update, (GO_HMAC_CTX_PTR arg0, const unsigned char *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_LEGACY_1(int, HMAC_Final, (GO_HMAC_CTX_PTR arg0, unsigned char *arg1, unsigned int *arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_LEGACY_1(int, HMAC_CTX_copy, (GO_HMAC_CTX_PTR dest, GO_HMAC_CTX_PTR src), (dest, src)) \ ++DEFINEFUNC_LEGACY_1_1(void, HMAC_CTX_free, (GO_HMAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1_1(GO_HMAC_CTX_PTR, HMAC_CTX_new, (void), ()) \ ++DEFINEFUNC(GO_EVP_CIPHER_CTX_PTR, EVP_CIPHER_CTX_new, (void), ()) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_set_padding, (GO_EVP_CIPHER_CTX_PTR x, int padding), (x, padding)) \ ++DEFINEFUNC(int, EVP_CipherInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv, int enc), (ctx, type, impl, key, iv, enc)) \ ++DEFINEFUNC(int, EVP_CipherUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(int, EVP_EncryptInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv), (ctx, type, impl, key, iv)) \ ++DEFINEFUNC(int, EVP_EncryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(int, EVP_EncryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl), (ctx, out, outl)) \ ++DEFINEFUNC(int, EVP_DecryptInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv), (ctx, type, impl, key, iv)) \ ++DEFINEFUNC(int, EVP_DecryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(int, EVP_DecryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *outm, int *outl), (ctx, outm, outl)) \ ++DEFINEFUNC_3_0(GO_EVP_CIPHER_PTR, EVP_CIPHER_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ ++DEFINEFUNC_3_0(const char *, EVP_CIPHER_get0_name, (const GO_EVP_CIPHER_PTR cipher), (cipher)) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_gcm, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_ctr, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_gcm, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_ctr, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ctr, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_gcm, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_rc4, (void), ()) \ ++DEFINEFUNC_RENAMED_3_0(int, EVP_CIPHER_get_block_size, EVP_CIPHER_block_size, (const GO_EVP_CIPHER_PTR cipher), (cipher)) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_set_key_length, (GO_EVP_CIPHER_CTX_PTR x, int keylen), (x, keylen)) \ ++DEFINEFUNC(void, EVP_CIPHER_CTX_free, (GO_EVP_CIPHER_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (GO_EVP_CIPHER_CTX_PTR ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) \ ++DEFINEFUNC(GO_EVP_PKEY_PTR, EVP_PKEY_new, (void), ()) \ ++DEFINEFUNC_1_1_1(GO_EVP_PKEY_PTR, EVP_PKEY_new_raw_private_key, (int type, GO_ENGINE_PTR e, const unsigned char *key, size_t keylen), (type, e, key, keylen)) \ ++DEFINEFUNC_1_1_1(GO_EVP_PKEY_PTR, EVP_PKEY_new_raw_public_key, (int type, GO_ENGINE_PTR e, const unsigned char *key, size_t keylen), (type, e, key, keylen)) \ ++/* EVP_PKEY_size and EVP_PKEY_get_bits pkey parameter is const since OpenSSL 1.1.1. */ \ ++/* Exclude it from headercheck tool when using previous OpenSSL versions. */ \ ++/*check:from=1.1.1*/ DEFINEFUNC_RENAMED_3_0(int, EVP_PKEY_get_size, EVP_PKEY_size, (const GO_EVP_PKEY_PTR pkey), (pkey)) \ ++/*check:from=1.1.1*/ DEFINEFUNC_RENAMED_3_0(int, EVP_PKEY_get_bits, EVP_PKEY_bits, (const GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1(GO_RSA_PTR, EVP_PKEY_get1_RSA, (GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC_LEGACY_1(int, EVP_PKEY_assign, (GO_EVP_PKEY_PTR pkey, int type, void *key), (pkey, type, key)) \ ++DEFINEFUNC(int, EVP_PKEY_verify, (GO_EVP_PKEY_CTX_PTR ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sig, siglen, tbs, tbslen)) \ ++DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new, (GO_EVP_PKEY_PTR arg0, GO_ENGINE_PTR arg1), (arg0, arg1)) \ ++DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new_id, (int id, GO_ENGINE_PTR e), (id, e)) \ ++DEFINEFUNC(int, EVP_PKEY_keygen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC(int, EVP_PKEY_keygen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ ++DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_CTX_ctrl, (GO_EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2), (ctx, keytype, optype, cmd, p1, p2)) \ ++DEFINEFUNC(int, EVP_PKEY_decrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EVP_PKEY_encrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EVP_PKEY_decrypt_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_encrypt_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_sign_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_verify_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_sign, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EVP_PKEY_derive_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC(int, EVP_PKEY_derive_set_peer, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR peer), (ctx, peer)) \ ++DEFINEFUNC(int, EVP_PKEY_derive, (GO_EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t *keylen), (ctx, key, keylen)) \ ++DEFINEFUNC_LEGACY_1_0(void*, EVP_PKEY_get0, (GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC_LEGACY_1_1(GO_EC_KEY_PTR, EVP_PKEY_get0_EC_KEY, (GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_fromdata_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_fromdata, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *pkey, int selection, GO_OSSL_PARAM_PTR params), (ctx, pkey, selection, params)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_set1_encoded_public_key, (GO_EVP_PKEY_PTR pkey, const unsigned char *pub, size_t publen), (pkey, pub, publen)) \ ++DEFINEFUNC_3_0(size_t, EVP_PKEY_get1_encoded_public_key, (GO_EVP_PKEY_PTR pkey, unsigned char **ppub), (pkey, ppub)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_get_bn_param, (const GO_EVP_PKEY_PTR pkey, const char *key_name, GO_BIGNUM_PTR *bn), (pkey, key_name, bn)) \ ++DEFINEFUNC_LEGACY_1(GO_RSA_PTR, RSA_new, (void), ()) \ ++DEFINEFUNC_LEGACY_1(void, RSA_free, (GO_RSA_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1_1(int, RSA_set0_factors, (GO_RSA_PTR rsa, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q), (rsa, p, q)) \ ++DEFINEFUNC_LEGACY_1_1(int, RSA_set0_crt_params, (GO_RSA_PTR rsa, GO_BIGNUM_PTR dmp1, GO_BIGNUM_PTR dmp2, GO_BIGNUM_PTR iqmp), (rsa, dmp1, dmp2, iqmp)) \ ++DEFINEFUNC_LEGACY_1_1(void, RSA_get0_crt_params, (const GO_RSA_PTR r, const GO_BIGNUM_PTR *dmp1, const GO_BIGNUM_PTR *dmq1, const GO_BIGNUM_PTR *iqmp), (r, dmp1, dmq1, iqmp)) \ ++DEFINEFUNC_LEGACY_1_1(int, RSA_set0_key, (GO_RSA_PTR r, GO_BIGNUM_PTR n, GO_BIGNUM_PTR e, GO_BIGNUM_PTR d), (r, n, e, d)) \ ++DEFINEFUNC_LEGACY_1_1(void, RSA_get0_factors, (const GO_RSA_PTR rsa, const GO_BIGNUM_PTR *p, const GO_BIGNUM_PTR *q), (rsa, p, q)) \ ++DEFINEFUNC_LEGACY_1_1(void, RSA_get0_key, (const GO_RSA_PTR rsa, const GO_BIGNUM_PTR *n, const GO_BIGNUM_PTR *e, const GO_BIGNUM_PTR *d), (rsa, n, e, d)) \ ++DEFINEFUNC(GO_BIGNUM_PTR, BN_new, (void), ()) \ ++DEFINEFUNC(void, BN_free, (GO_BIGNUM_PTR arg0), (arg0)) \ ++DEFINEFUNC(void, BN_clear, (GO_BIGNUM_PTR arg0), (arg0)) \ ++DEFINEFUNC(void, BN_clear_free, (GO_BIGNUM_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, BN_num_bits, (const GO_BIGNUM_PTR arg0), (arg0)) \ ++DEFINEFUNC(GO_BIGNUM_PTR, BN_bin2bn, (const unsigned char *arg0, int arg1, GO_BIGNUM_PTR arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_LEGACY_1_0(int, BN_bn2bin, (const GO_BIGNUM_PTR a, unsigned char *to), (a, to)) \ ++DEFINEFUNC_LEGACY_1_0(GO_BIGNUM_PTR, bn_expand2, (GO_BIGNUM_PTR a, int n), (a, n)) \ ++DEFINEFUNC_1_1(GO_BIGNUM_PTR, BN_lebin2bn, (const unsigned char *s, int len, GO_BIGNUM_PTR ret), (s, len, ret)) \ ++DEFINEFUNC_1_1(int, BN_bn2lebinpad, (const GO_BIGNUM_PTR a, unsigned char *to, int tolen), (a, to, tolen)) \ ++DEFINEFUNC_1_1(int, BN_bn2binpad, (const GO_BIGNUM_PTR a, unsigned char *to, int tolen), (a, to, tolen)) \ ++DEFINEFUNC_LEGACY_1(int, EC_KEY_set_public_key_affine_coordinates, (GO_EC_KEY_PTR key, GO_BIGNUM_PTR x, GO_BIGNUM_PTR y), (key, x, y)) \ ++DEFINEFUNC_LEGACY_1(int, EC_KEY_set_public_key, (GO_EC_KEY_PTR key, const GO_EC_POINT_PTR pub), (key, pub)) \ ++DEFINEFUNC_LEGACY_1(void, EC_KEY_free, (GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1(const GO_EC_GROUP_PTR, EC_KEY_get0_group, (const GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1(const GO_BIGNUM_PTR, EC_KEY_get0_private_key, (const GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1(const GO_EC_POINT_PTR, EC_KEY_get0_public_key, (const GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1(GO_EC_KEY_PTR, EC_KEY_new_by_curve_name, (int arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1(int, EC_KEY_set_private_key, (GO_EC_KEY_PTR arg0, const GO_BIGNUM_PTR arg1), (arg0, arg1)) \ ++DEFINEFUNC(GO_EC_POINT_PTR, EC_POINT_new, (const GO_EC_GROUP_PTR arg0), (arg0)) \ ++DEFINEFUNC(void, EC_POINT_free, (GO_EC_POINT_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EC_POINT_mul, (const GO_EC_GROUP_PTR group, GO_EC_POINT_PTR r, const GO_BIGNUM_PTR n, const GO_EC_POINT_PTR q, const GO_BIGNUM_PTR m, GO_BN_CTX_PTR ctx), (group, r, n, q, m, ctx)) \ ++DEFINEFUNC_LEGACY_1(int, EC_POINT_get_affine_coordinates_GFp, (const GO_EC_GROUP_PTR arg0, const GO_EC_POINT_PTR arg1, GO_BIGNUM_PTR arg2, GO_BIGNUM_PTR arg3, GO_BN_CTX_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC_3_0(int, EC_POINT_set_affine_coordinates, (const GO_EC_GROUP_PTR arg0, GO_EC_POINT_PTR arg1, const GO_BIGNUM_PTR arg2, const GO_BIGNUM_PTR arg3, GO_BN_CTX_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(size_t, EC_POINT_point2oct, (const GO_EC_GROUP_PTR group, const GO_EC_POINT_PTR p, point_conversion_form_t form, unsigned char *buf, size_t len, GO_BN_CTX_PTR ctx), (group, p, form, buf, len, ctx)) \ ++DEFINEFUNC(int, EC_POINT_oct2point, (const GO_EC_GROUP_PTR group, GO_EC_POINT_PTR p, const unsigned char *buf, size_t len, GO_BN_CTX_PTR ctx), (group, p, buf, len, ctx)) \ ++DEFINEFUNC(const char *, OBJ_nid2sn, (int n), (n)) \ ++DEFINEFUNC(GO_EC_GROUP_PTR, EC_GROUP_new_by_curve_name, (int nid), (nid)) \ ++DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP_PTR group), (group)) \ ++DEFINEFUNC_3_0(GO_EVP_MAC_PTR, EVP_MAC_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ ++DEFINEFUNC_3_0(GO_EVP_MAC_CTX_PTR, EVP_MAC_CTX_new, (GO_EVP_MAC_PTR arg0), (arg0)) \ ++DEFINEFUNC_3_0(void, EVP_MAC_CTX_free, (GO_EVP_MAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC_3_0(GO_EVP_MAC_CTX_PTR, EVP_MAC_CTX_dup, (const GO_EVP_MAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC_3_0(int, EVP_MAC_init, (GO_EVP_MAC_CTX_PTR ctx, const unsigned char *key, size_t keylen, const GO_OSSL_PARAM_PTR params), (ctx, key, keylen, params)) \ ++DEFINEFUNC_3_0(int, EVP_MAC_update, (GO_EVP_MAC_CTX_PTR ctx, const unsigned char *data, size_t datalen), (ctx, data, datalen)) \ ++DEFINEFUNC_3_0(int, EVP_MAC_final, (GO_EVP_MAC_CTX_PTR ctx, unsigned char *out, size_t *outl, size_t outsize), (ctx, out, outl, outsize)) \ ++DEFINEFUNC_3_0(void, OSSL_PARAM_free, (GO_OSSL_PARAM_PTR p), (p)) \ ++DEFINEFUNC_3_0(GO_OSSL_PARAM_BLD_PTR, OSSL_PARAM_BLD_new, (void), ()) \ ++DEFINEFUNC_3_0(void, OSSL_PARAM_BLD_free, (GO_OSSL_PARAM_BLD_PTR bld), (bld)) \ ++DEFINEFUNC_3_0(GO_OSSL_PARAM_PTR, OSSL_PARAM_BLD_to_param, (GO_OSSL_PARAM_BLD_PTR bld), (bld)) \ ++DEFINEFUNC_3_0(int, OSSL_PARAM_BLD_push_utf8_string, (GO_OSSL_PARAM_BLD_PTR bld, const char *key, const char *buf, size_t bsize), (bld, key, buf, bsize)) \ ++DEFINEFUNC_3_0(int, OSSL_PARAM_BLD_push_octet_string, (GO_OSSL_PARAM_BLD_PTR bld, const char *key, const void *buf, size_t bsize), (bld, key, buf, bsize)) \ ++DEFINEFUNC_3_0(int, OSSL_PARAM_BLD_push_BN, (GO_OSSL_PARAM_BLD_PTR bld, const char *key, const GO_BIGNUM_PTR bn), (bld, key, bn)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set_hkdf_mode, (GO_EVP_PKEY_CTX_PTR arg0, int arg1), (arg0, arg1)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set_hkdf_md, (GO_EVP_PKEY_CTX_PTR arg0, const GO_EVP_MD_PTR arg1), (arg0, arg1)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set1_hkdf_salt, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set1_hkdf_key, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_add1_hkdf_info, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_up_ref, (GO_EVP_PKEY_PTR key), (key)) \ ++DEFINEFUNC_LEGACY_1(int, EVP_PKEY_set1_EC_KEY, (GO_EVP_PKEY_PTR pkey, GO_EC_KEY_PTR key), (pkey, key)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set0_rsa_oaep_label, (GO_EVP_PKEY_CTX_PTR ctx, void *label, int len), (ctx, label, len)) \ ++DEFINEFUNC(int, PKCS5_PBKDF2_HMAC, (const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const GO_EVP_MD_PTR digest, int keylen, unsigned char *out), (pass, passlen, salt, saltlen, iter, digest, keylen, out)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set_tls1_prf_md, (GO_EVP_PKEY_CTX_PTR arg0, const GO_EVP_MD_PTR arg1), (arg0, arg1)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set1_tls1_prf_secret, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_3_0(int, EVP_PKEY_CTX_add1_tls1_prf_seed, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_public_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len), (pkey, pub, len)) \ ++DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_private_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t *len), (pkey, priv, len)) \ ++DEFINEFUNC_3_0(GO_EVP_SIGNATURE_PTR, EVP_SIGNATURE_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ ++DEFINEFUNC_3_0(void, EVP_SIGNATURE_free, (GO_EVP_SIGNATURE_PTR signature), (signature)) \ ++ +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c +new file mode 100644 +index 0000000000..dc2df609b0 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c +@@ -0,0 +1,35 @@ ++//go:build unix ++ ++#include "goopenssl.h" ++#include ++ ++#define CRYPTO_LOCK 0x01 ++ ++/* This array will store all of the mutexes available to OpenSSL. */ ++static pthread_mutex_t *mutex_buf = NULL; ++ ++static void locking_function(int mode, int n, const char *file, int line) ++{ ++ if (mode & CRYPTO_LOCK) ++ pthread_mutex_lock(&mutex_buf[n]); ++ else ++ pthread_mutex_unlock(&mutex_buf[n]); +} + -+func signRSAPKCS1v15Raw(priv *PrivateKeyRSA, msg []byte, md *C.GO_EVP_MD) ([]byte, error) { - var out []byte -- var outLen C.uint -+ var outLen C.size_t -+ PanicIfStrictFIPS("You must provide a raw unhashed message for PKCS1v15 signing and use HashSignPKCS1v15 instead of SignPKCS1v15") ++static void thread_id(GO_CRYPTO_THREADID_PTR tid) ++{ ++ go_openssl_CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); ++} + - 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) -+ 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, fail("RSA_sign") -+ return nil, NewOpenSSLError("RSA_sign") - } -+ runtime.KeepAlive(priv) - 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 -+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte, msgIsHashed bool) error { -+ if h == 0 && ExecutingTest() { -+ return verifyRSAPKCS1v15Raw(pub, msg, sig) -+ } ++int go_openssl_thread_setup(void) ++{ ++ mutex_buf = malloc(go_openssl_CRYPTO_num_locks()*sizeof(pthread_mutex_t)); ++ if (!mutex_buf) ++ return 0; ++ int i; ++ for (i = 0; i < go_openssl_CRYPTO_num_locks(); i++) ++ pthread_mutex_init(&mutex_buf[i], NULL); ++ go_openssl_CRYPTO_THREADID_set_callback(thread_id); ++ go_openssl_CRYPTO_set_locking_callback(locking_function); ++ return 1; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_windows.c b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_windows.c +new file mode 100644 +index 0000000000..7bc66d8014 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_windows.c +@@ -0,0 +1,33 @@ ++//go:build windows + -+ md := cryptoHashToMD(h) ++#include "goopenssl.h" ++ ++#include ++#include ++ ++#define CRYPTO_LOCK 0x01 ++ ++/* This array will store all of the mutexes available to OpenSSL. */ ++static HANDLE *mutex_buf = NULL; ++ ++static void locking_function(int mode, int n, const char *file, int line) ++{ ++ if (mode & CRYPTO_LOCK) ++ WaitForSingleObject(mutex_buf[n], INFINITE); ++ else ++ ReleaseMutex(mutex_buf[n]); ++} ++ ++int go_openssl_thread_setup(void) ++{ ++ mutex_buf = malloc(go_openssl_CRYPTO_num_locks()*sizeof(HANDLE)); ++ if (!mutex_buf) ++ return 0; ++ int i; ++ for (i = 0; i < go_openssl_CRYPTO_num_locks(); i++) ++ mutex_buf[i] = CreateMutex(NULL, FALSE, NULL); ++ go_openssl_CRYPTO_set_locking_callback(locking_function); ++ // go_openssl_CRYPTO_set_id_callback is not needed on Windows ++ // as OpenSSL uses GetCurrentThreadId() by default. ++ return 1; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go +new file mode 100644 +index 0000000000..3153fc81ec +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go +@@ -0,0 +1,104 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "errors" ++ "hash" ++ "unsafe" ++) ++ ++func SupportsTLS1PRF() bool { ++ return vMajor > 1 || ++ (vMajor >= 1 && vMinor >= 1) ++} ++ ++// TLS1PRF implements the TLS 1.0/1.1 pseudo-random function if h is nil, ++// else it implements the TLS 1.2 pseudo-random function. ++// The pseudo-random number will be written to result and will be of length len(result). ++func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { ++ var md C.GO_EVP_MD_PTR ++ if h == nil { ++ // TLS 1.0/1.1 PRF doesn't allow to specify the hash function, ++ // it always uses MD5SHA1. If h is nil, then assume ++ // that the caller wants to use TLS 1.0/1.1 PRF. ++ // OpenSSL detects this case by checking if the hash ++ // function is MD5SHA1. ++ md = cryptoHashToMD(crypto.MD5SHA1) ++ } else { ++ md = hashToMD(h()) ++ } + if md == nil { -+ return errors.New("crypto/rsa: unsupported hash function") ++ return errors.New("unsupported hash function") + } + -+ 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") ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_TLS1_PRF, nil) ++ if ctx == nil { ++ return newOpenSSLError("EVP_PKEY_CTX_new_id") + } ++ defer func() { ++ C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ }() + -+ 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") ++ if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { ++ return newOpenSSLError("EVP_PKEY_derive_init") ++ } ++ switch vMajor { ++ case 3: ++ if C.go_openssl_EVP_PKEY_CTX_set_tls1_prf_md(ctx, md) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_set1_tls1_prf_secret(ctx, ++ base(secret), C.int(len(secret))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, ++ base(label), C.int(len(label))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, ++ base(seed), C.int(len(seed))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ } ++ case 1: ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_MD, ++ 0, unsafe.Pointer(md)) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_SECRET, ++ C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_SEED, ++ C.int(len(label)), unsafe.Pointer(base(label))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, ++ C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_TLS_SEED, ++ C.int(len(seed)), unsafe.Pointer(base(seed))) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ } ++ } ++ outLen := C.size_t(len(result)) ++ if C.go_openssl_EVP_PKEY_derive(ctx, base(result), &outLen) != 1 { ++ return newOpenSSLError("EVP_PKEY_derive") ++ } ++ // The Go standard library expects TLS1PRF to return the requested number of bytes, ++ // fail if it doesn't. While there is no known situation where this will happen, ++ // EVP_PKEY_derive handles multiple algorithms and there could be a subtle mismatch ++ // after more code changes in the future. ++ if outLen != C.size_t(len(result)) { ++ return errors.New("tls1-prf: derived less bytes than requested") + } + 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 4de656b0e8..273a9d49d6 100644 +index 4de656b0e8..8fdf76a925 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 +@@ -1,3 +1,7 @@ ++# github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28 ++## explicit; go 1.20 ++github.com/golang-fips/openssl/v2 ++github.com/golang-fips/openssl/v2/bbig # golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d ## explicit; go 1.17 golang.org/x/crypto/chacha20 diff --git a/patches/002-strict-fips-runtime-detection.patch b/patches/002-strict-fips-runtime-detection.patch index ad4c22fe4c..053c8fbe6d 100644 --- a/patches/002-strict-fips-runtime-detection.patch +++ b/patches/002-strict-fips-runtime-detection.patch @@ -26,29 +26,51 @@ index 0000000000..6fcd7139c6 + 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 +index a27da89d4d..e1a78a0db3 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" +@@ -17,6 +17,10 @@ import ( "io" -+ "math/big" -+ -+ "github.com/golang-fips/openssl-fips/openssl" ) +func init() { -+ strictFIPSNonCompliantBinaryCheck() ++ strictFIPSNonCompliantBinaryCheck() +} + var enabled = false // Unreachable marks code that should be unreachable +@@ -43,13 +47,13 @@ func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not availab + + const RandReader = randReader(0) + +-func Enabled() bool { return false } +-func NewSHA1() hash.Hash { panic("boringcrypto: not available") } +-func NewSHA224() hash.Hash { panic("boringcrypto: not available") } +-func NewSHA256() hash.Hash { panic("boringcrypto: not available") } +-func NewSHA384() hash.Hash { panic("boringcrypto: not available") } +-func NewSHA512() hash.Hash { panic("boringcrypto: not available") } +-func SHA1(_ []byte) [20]byte { panic("boringcrypto: not available") } ++func Enabled() bool { return false } ++func NewSHA1() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA224() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA256() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA384() hash.Hash { panic("boringcrypto: not available") } ++func NewSHA512() hash.Hash { panic("boringcrypto: not available") } ++func SHA1(_ []byte) [20]byte { panic("boringcrypto: not available") } + func SHA224(_ []byte) [28]byte { panic("boringcrypto: not available") } + func SHA256(_ []byte) [32]byte { panic("boringcrypto: not available") } + func SHA384(_ []byte) [48]byte { panic("boringcrypto: not available") } +@@ -86,7 +90,8 @@ func VerifyECDSA(pub *PublicKeyECDSA, hash, sig []byte) bool { + + type PublicKeyECDH struct{ _ int } + type PrivateKeyECDH struct{ _ int } +-func (pc *PublicKeyECDH) Bytes() []byte { panic("boringcrypto: not available") } ++ ++func (pc *PublicKeyECDH) Bytes() []byte { panic("boringcrypto: not available") } + func (pc *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { panic("boringcrypto: not available") } + + func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { diff --git a/src/crypto/internal/backend/not_strict_fips.go b/src/crypto/internal/backend/not_strict_fips.go new file mode 100644 index 0000000000..f8e8fd6869 @@ -66,19 +88,16 @@ index 0000000000..f8e8fd6869 +func strictFIPSNonCompliantBinaryCheck() { +} diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go -index 2087c555a4..3e5ee01efc 100644 +index 45862eda3d..f431a7cdf4 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" - ) +@@ -19,6 +19,7 @@ import ( + var enabled bool -+func init() { + func init() { + strictFIPSOpenSSLRuntimeCheck() -+} -+ - // Enabled controls whether FIPS crypto is enabled. - var Enabled = openssl.Enabled + enabled = openssl.FIPS() + } diff --git a/src/crypto/internal/backend/strict_fips.go b/src/crypto/internal/backend/strict_fips.go new file mode 100644 diff --git a/patches/003-init-openssl-v2-backend.patch b/patches/003-init-openssl-v2-backend.patch new file mode 100644 index 0000000000..62a3de8021 --- /dev/null +++ b/patches/003-init-openssl-v2-backend.patch @@ -0,0 +1,81 @@ +diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go +index 49bb6da477..69e29d3528 100644 +--- a/src/crypto/internal/backend/openssl.go ++++ b/src/crypto/internal/backend/openssl.go +@@ -11,16 +11,64 @@ + package backend + + import ( +- "os" ++ "crypto/internal/boring/sig" + "github.com/golang-fips/openssl/v2" ++ "os" ++ "syscall" + ) + + // Enabled controls whether FIPS crypto is enabled. + var enabled bool + ++var knownVersions = [...]string{"3", "1.1", "11", "111", "1.0.2", "1.0.0", "10"} ++ + func init() { +- strictFIPSOpenSSLRuntimeCheck() +- enabled = openssl.FIPS() ++ version, _ := syscall.Getenv("GO_OPENSSL_VERSION_OVERRIDE") ++ if version == "" { ++ var fallbackVersion string ++ for _, v := range knownVersions { ++ exists, fips := openssl.CheckVersion(v) ++ if exists && fips { ++ version = v ++ break ++ } ++ if exists && fallbackVersion == "" { ++ fallbackVersion = v ++ } ++ } ++ if version == "" && fallbackVersion != "" { ++ version = fallbackVersion ++ } ++ } ++ if err := openssl.Init(version); err != nil { ++ panic("opensslcrypto: can't initialize OpenSSL " + version + ": " + err.Error()) ++ } ++ // 0: FIPS opt-out: abort the process if it is enabled and can't be disabled. ++ // 1: FIPS required: abort the process if it is not enabled and can't be enabled. ++ // other values: do not override OpenSSL configured FIPS mode. ++ var fips string ++ if v, ok := syscall.Getenv("GOLANG_FIPS"); ok { ++ fips = v ++ } else if hostFIPSModeEnabled() { ++ // System configuration can only force FIPS mode. ++ fips = "1" ++ } ++ switch fips { ++ case "0": ++ if openssl.FIPS() { ++ if err := openssl.SetFIPS(false); err != nil { ++ panic("opensslcrypto: can't disable FIPS mode for " + openssl.VersionText() + ": " + err.Error()) ++ } ++ } ++ case "1": ++ if !openssl.FIPS() { ++ if err := openssl.SetFIPS(true); err != nil { ++ panic("opensslcrypto: can't enable FIPS mode for " + openssl.VersionText() + ": " + err.Error()) ++ } ++ } ++ enabled = true ++ } ++ sig.BoringCrypto() + } + + func Enabled() bool { +@@ -61,8 +109,6 @@ func UnreachableExceptTests() { + } + } + +- +- + const RandReader = openssl.RandReader + + var NewGCMTLS = openssl.NewGCMTLS diff --git a/patches/004-fixes.patch b/patches/004-fixes.patch new file mode 100644 index 0000000000..059be518c6 --- /dev/null +++ b/patches/004-fixes.patch @@ -0,0 +1,269 @@ +diff --git a/api/go1.16.txt b/api/go1.16.txt +index e12a050939..e555bfdf5c 100644 +--- a/api/go1.16.txt ++++ b/api/go1.16.txt +@@ -8525,3 +8525,5 @@ pkg syscall (darwin-arm64-cgo), type WaitStatus uint32 + pkg syscall (darwin-arm64-cgo), var Stderr int + pkg syscall (darwin-arm64-cgo), var Stdin int + pkg syscall (darwin-arm64-cgo), var Stdout int ++pkg crypto/rsa, func GenerateKeyNotBoring(io.Reader, int) (*PrivateKey, error) ++pkg crypto/rsa, func GenerateMultiPrimeKeyNotBoring(io.Reader, int, int) (*PrivateKey, error) +diff --git a/src/crypto/rsa/boring_test.go b/src/crypto/rsa/boring_test.go +index 4e7fd9de4a..bd060c6a9d 100644 +--- a/src/crypto/rsa/boring_test.go ++++ b/src/crypto/rsa/boring_test.go +@@ -22,7 +22,7 @@ import ( + ) + + func TestBoringASN1Marshal(t *testing.T) { +- k, err := GenerateKey(rand.Reader, 128) ++ k, err := GenerateKey(rand.Reader, 3072) + if err != nil { + t.Fatal(err) + } +diff --git a/src/crypto/rsa/equal_test.go b/src/crypto/rsa/equal_test.go +index 90f4bf9475..688df68545 100644 +--- a/src/crypto/rsa/equal_test.go ++++ b/src/crypto/rsa/equal_test.go +@@ -13,7 +13,7 @@ import ( + ) + + func TestEqual(t *testing.T) { +- private, _ := rsa.GenerateKey(rand.Reader, 512) ++ private, _ := rsa.GenerateKey(rand.Reader, 2048) + public := &private.PublicKey + + if !public.Equal(public) { +@@ -41,7 +41,7 @@ func TestEqual(t *testing.T) { + t.Errorf("private key is not equal to itself after decoding: %v", private) + } + +- other, _ := rsa.GenerateKey(rand.Reader, 512) ++ other, _ := rsa.GenerateKey(rand.Reader, 2048) + if public.Equal(other.Public()) { + t.Errorf("different public keys are Equal") + } +diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go +index befd1612b5..afa25a737c 100644 +--- a/src/crypto/rsa/pss_test.go ++++ b/src/crypto/rsa/pss_test.go +@@ -301,7 +301,7 @@ func fromHex(hexStr string) []byte { + } + + func TestInvalidPSSSaltLength(t *testing.T) { +- key, err := GenerateKey(rand.Reader, 245) ++ key, err := GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatal(err) + } +diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go +index dd79dc5439..52f2ac347c 100644 +--- a/src/crypto/rsa/rsa.go ++++ b/src/crypto/rsa/rsa.go +@@ -264,6 +264,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { + return GenerateMultiPrimeKey(random, 2, bits) + } + ++ + // GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit + // size and the given random source. + // +@@ -284,6 +285,24 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { + // + // [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf + func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { ++ if boring.Enabled() && boring.IsStrictFIPSMode() && !(random == boring.RandReader && nprimes == 2 && ++ (bits == 2048 || bits == 3072 || bits == 4096)) { ++ return nil, errors.New("crypto/rsa: invalid primes or bits for boring") ++ } ++ return generateMultiPrimeKeyInternal(random, nprimes, bits) ++} ++ ++func GenerateKeyNotBoring(random io.Reader, bits int) (*PrivateKey, error) { ++ boring.UnreachableExceptTests() ++ return generateMultiPrimeKeyInternal(random, 2, bits) ++} ++ ++func GenerateMultiPrimeKeyNotBoring(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { ++ boring.UnreachableExceptTests() ++ return generateMultiPrimeKeyInternal(random, nprimes, bits) ++} ++ ++func generateMultiPrimeKeyInternal(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { + randutil.MaybeReadByte(random) + + if boring.Enabled() && random == boring.RandReader && nprimes == 2 && +@@ -324,6 +343,7 @@ func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey + return key, nil + } + ++ + priv := new(PrivateKey) + priv.E = 65537 + +diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go +index 4b7427e1ae..da8c104044 100644 +--- a/src/crypto/rsa/rsa_test.go ++++ b/src/crypto/rsa/rsa_test.go +@@ -26,7 +26,17 @@ import ( + import "crypto/internal/backend/boringtest" + + func TestKeyGeneration(t *testing.T) { +- for _, size := range []int{128, 1024, 2048, 3072} { ++ testKeys := []int{128, 1024} ++ if boring.Enabled() { ++ for _, size := range testKeys { ++ _, err := GenerateKey(rand.Reader, size) ++ if err == nil && boring.IsStrictFIPSMode() { ++ t.Errorf("Gener(%d): boring: bad accept", size) ++ } ++ } ++ testKeys = []int{2048, 3072} ++ } ++ for _, size := range testKeys { + priv, err := GenerateKey(rand.Reader, size) + if err != nil { + t.Errorf("GenerateKey(%d): %v", size, err) +@@ -53,7 +63,12 @@ func Test3PrimeKeyGeneration(t *testing.T) { + + priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size) + if err != nil { ++ if boring.IsStrictFIPSMode() { ++ return ++ } + t.Errorf("failed to generate key") ++ } else if boring.IsStrictFIPSMode() { ++ t.Errorf("bad accept in strictfipsmode") + } + testKeyBasics(t, priv) + } +@@ -66,12 +81,20 @@ func Test4PrimeKeyGeneration(t *testing.T) { + + priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size) + if err != nil { ++ if boring.IsStrictFIPSMode() { ++ return ++ } + t.Errorf("failed to generate key") ++ } else if boring.IsStrictFIPSMode() { ++ t.Errorf("bad accept in strictfipsmode") + } + testKeyBasics(t, priv) + } + + func TestNPrimeKeyGeneration(t *testing.T) { ++ if boring.Enabled() { ++ t.Skip("Not supported in boring mode") ++ } + primeSize := 64 + maxN := 24 + if testing.Short() { +@@ -206,7 +229,7 @@ func TestEverything(t *testing.T) { + size := size + t.Run(fmt.Sprintf("%d", size), func(t *testing.T) { + t.Parallel() +- priv, err := GenerateKey(rand.Reader, size) ++ priv, err := GenerateKeyNotBoring(rand.Reader, size) + if err != nil { + t.Errorf("GenerateKey(%d): %v", size, err) + } +diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go +index 49702f59ba..e7ae7fc5ca 100644 +--- a/src/crypto/tls/boring_test.go ++++ b/src/crypto/tls/boring_test.go +@@ -329,7 +329,7 @@ func TestBoringCertAlgs(t *testing.T) { + // Set up some roots, intermediate CAs, and leaf certs with various algorithms. + // X_Y is X signed by Y. + R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) +- R2 := boringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA) ++ R2 := boringCert(t, "R2", NotBoringRSAKey(t, 512), nil, boringCertCA) + + M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) + +@@ -353,9 +353,9 @@ func TestBoringCertAlgs(t *testing.T) { + // Older versions of OpenSSL allow 1024 bit leaf certs + var L2_I *boringCertificate + if boringtest.Supports(t, "RSA1024LeafCert") { +- L2_I = boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf) ++ L2_I = boringCert(t, "L2_I", NotBoringRSAKey(t, 1024), I_R1, boringCertLeaf) + } else { +- L2_I = boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf|boringCertNotBoring) ++ L2_I = boringCert(t, "L2_I", NotBoringRSAKey(t, 1024), I_R1, boringCertLeaf|boringCertNotBoring) + } + + // client verifying server cert +@@ -515,6 +515,15 @@ const ( + boringCertNotBoring = 0x100 + ) + ++func NotBoringRSAKey(t *testing.T, size int) *rsa.PrivateKey { ++ k, err := rsa.GenerateKeyNotBoring(rand.Reader, size) ++ if err != nil { ++ t.Fatal(err) ++ } ++ return k ++} ++ ++ + func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey { + k, err := rsa.GenerateKey(rand.Reader, size) + if err != nil { +diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go +index 07b3c7095e..88b69937be 100644 +--- a/src/crypto/x509/boring_test.go ++++ b/src/crypto/x509/boring_test.go +@@ -27,6 +27,14 @@ const ( + boringCertFIPSOK = 0x80 + ) + ++func notBoringRSAKey(t *testing.T, size int) *rsa.PrivateKey { ++ k, err := rsa.GenerateKeyNotBoring(rand.Reader, size) ++ if err != nil { ++ t.Fatal(err) ++ } ++ return k ++} ++ + func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey { + k, err := rsa.GenerateKey(rand.Reader, size) + if err != nil { +@@ -55,7 +63,7 @@ type boringCertificate struct { + + func TestBoringAllowCert(t *testing.T) { + R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) +- R2 := testBoringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA) ++ R2 := testBoringCert(t, "R2", notBoringRSAKey(t, 512), nil, boringCertCA) + R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK) + + M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) +@@ -78,7 +86,7 @@ func TestBoringAllowCert(t *testing.T) { + testBoringCert(t, "I_R3", I_R3.key, R3, boringCertCA|boringCertFIPSOK) + + testBoringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK) +- testBoringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf) ++ testBoringCert(t, "L2_I", notBoringRSAKey(t, 1024), I_R1, boringCertLeaf) + } + + func testBoringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate { +diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go +index 22a104f338..8f77ffda62 100644 +--- a/src/crypto/x509/x509_test.go ++++ b/src/crypto/x509/x509_test.go +@@ -2927,7 +2927,7 @@ func TestUnknownExtKey(t *testing.T) { + DNSNames: []string{"foo"}, + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsage(-1)}, + } +- signer, err := rsa.GenerateKey(rand.Reader, 1024) ++ signer, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Errorf("failed to generate key for TestUnknownExtKey") + } +@@ -3090,7 +3090,7 @@ func TestCreateCertificateBrokenSigner(t *testing.T) { + SerialNumber: big.NewInt(10), + DNSNames: []string{"example.com"}, + } +- k, err := rsa.GenerateKey(rand.Reader, 1024) ++ k, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("failed to generate test key: %s", err) + } diff --git a/patches/005-fixes-2.patch b/patches/005-fixes-2.patch new file mode 100644 index 0000000000..76b1cbdecf --- /dev/null +++ b/patches/005-fixes-2.patch @@ -0,0 +1,75 @@ +diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go +index ac90ba299f..88be5de522 100644 +--- a/src/crypto/internal/backend/nobackend.go ++++ b/src/crypto/internal/backend/nobackend.go +@@ -10,15 +10,15 @@ package backend + import ( + "crypto" + "crypto/cipher" +- "crypto/internal/boring/sig" +- "math/big" + bbig "crypto/internal/boring" ++ "crypto/internal/boring/sig" + "hash" + "io" ++ "math/big" + ) + + func init() { +- strictFIPSNonCompliantBinaryCheck() ++ strictFIPSNonCompliantBinaryCheck() + } + + var enabled = false +@@ -32,6 +32,10 @@ func Unreachable() { + sig.StandardCrypto() + } + ++func IsStrictFIPSMode() bool { ++ return false ++} ++ + // UnreachableExceptTests marks code that should be unreachable + // when BoringCrypto is in use. It is a no-op without BoringCrypto. + func UnreachableExceptTests() {} +diff --git a/src/crypto/internal/backend/not_strict_fips.go b/src/crypto/internal/backend/not_strict_fips.go +index f8e8fd6869..806b035aa8 100644 +--- a/src/crypto/internal/backend/not_strict_fips.go ++++ b/src/crypto/internal/backend/not_strict_fips.go +@@ -3,6 +3,8 @@ + + package backend + ++var isStrictFIPS bool = false ++ + func strictFIPSOpenSSLRuntimeCheck() { + } + +diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go +index 69a1c2bd0c..0e9fec07b7 100644 +--- a/src/crypto/internal/backend/openssl.go ++++ b/src/crypto/internal/backend/openssl.go +@@ -71,6 +71,10 @@ func init() { + sig.BoringCrypto() + } + ++func IsStrictFIPSMode() bool { ++ return isStrictFIPS ++} ++ + func Enabled() bool { + return enabled + } +diff --git a/src/crypto/internal/backend/strict_fips.go b/src/crypto/internal/backend/strict_fips.go +index 894eeca942..c1bda67f12 100644 +--- a/src/crypto/internal/backend/strict_fips.go ++++ b/src/crypto/internal/backend/strict_fips.go +@@ -8,6 +8,8 @@ import ( + "os" + ) + ++var isStrictFIPS bool = true ++ + func strictFIPSOpenSSLRuntimeCheck() { + if hostFIPSModeEnabled() && !Enabled() { + fmt.Fprintln(os.Stderr, "FIPS mode is enabled, but the required OpenSSL backend is unavailable") diff --git a/patches/006-fixes-3.patch b/patches/006-fixes-3.patch new file mode 100644 index 0000000000..b2702ffcad --- /dev/null +++ b/patches/006-fixes-3.patch @@ -0,0 +1,81 @@ +diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go +index 0e9fec07b7..07d7692277 100644 +--- a/src/crypto/internal/backend/openssl.go ++++ b/src/crypto/internal/backend/openssl.go +@@ -12,9 +12,11 @@ package backend + + import ( + "crypto/internal/boring/sig" +- "github.com/golang-fips/openssl/v2" ++ "fmt" + "os" + "syscall" ++ ++ "github.com/golang-fips/openssl/v2" + ) + + // Enabled controls whether FIPS crypto is enabled. +@@ -27,13 +29,14 @@ func init() { + if version == "" { + var fallbackVersion string + for _, v := range knownVersions { +- exists, fips := openssl.CheckVersion(v) ++ vv := fmt.Sprintf("libcrypto.so.%s", v) ++ exists, fips := openssl.CheckVersion(vv) + if exists && fips { +- version = v ++ version = vv + break + } + if exists && fallbackVersion == "" { +- fallbackVersion = v ++ fallbackVersion = vv + } + } + if version == "" && fallbackVersion != "" { +diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go +index e7ae7fc5ca..01d3c35f35 100644 +--- a/src/crypto/tls/boring_test.go ++++ b/src/crypto/tls/boring_test.go +@@ -7,6 +7,7 @@ + package tls + + import ( ++ "crypto" + "crypto/ecdsa" + "crypto/elliptic" + boring "crypto/internal/backend" +@@ -216,7 +217,10 @@ func TestBoringServerSignatureAndHash(t *testing.T) { + + testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash} + +- sigType, _, _ := typeAndHashFromSignatureScheme(sigHash) ++ sigType, hashFunc, _ := typeAndHashFromSignatureScheme(sigHash) ++ if hashFunc == crypto.SHA1 && !boringtest.Supports(t, "SHA1") { ++ t.Skip("unsupported in FIPS mode") ++ } + switch sigType { + case signaturePKCS1v15, signatureRSAPSS: + serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256} +@@ -329,7 +333,7 @@ func TestBoringCertAlgs(t *testing.T) { + // Set up some roots, intermediate CAs, and leaf certs with various algorithms. + // X_Y is X signed by Y. + R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) +- R2 := boringCert(t, "R2", NotBoringRSAKey(t, 512), nil, boringCertCA) ++ R2 := boringCert(t, "R2", NotBoringRSAKey(t, 2560), nil, boringCertCA) + + M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) + +diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go +index 88b69937be..38790b33af 100644 +--- a/src/crypto/x509/boring_test.go ++++ b/src/crypto/x509/boring_test.go +@@ -63,7 +63,7 @@ type boringCertificate struct { + + func TestBoringAllowCert(t *testing.T) { + R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK) +- R2 := testBoringCert(t, "R2", notBoringRSAKey(t, 512), nil, boringCertCA) ++ R2 := testBoringCert(t, "R2", notBoringRSAKey(t, 2560), nil, boringCertCA) + R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK) + + M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK) diff --git a/patches/007-fixes-4.patch b/patches/007-fixes-4.patch new file mode 100644 index 0000000000..64935d1a43 --- /dev/null +++ b/patches/007-fixes-4.patch @@ -0,0 +1,14 @@ +diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go +index 07d7692277..8812475b92 100644 +--- a/src/crypto/internal/backend/openssl.go ++++ b/src/crypto/internal/backend/openssl.go +@@ -43,6 +43,9 @@ func init() { + version = fallbackVersion + } + } ++ if version == "" { ++ strictFIPSOpenSSLRuntimeCheck() ++ } + if err := openssl.Init(version); err != nil { + panic("opensslcrypto: can't initialize OpenSSL " + version + ": " + err.Error()) + } diff --git a/patches/008-fixes-5.patch b/patches/008-fixes-5.patch new file mode 100644 index 0000000000..d87ef9d8e5 --- /dev/null +++ b/patches/008-fixes-5.patch @@ -0,0 +1,61 @@ +From 6640803d938b82efd32da6459b8f1ee53df5a180 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Mon, 16 Oct 2023 12:22:50 +0900 +Subject: [PATCH] crypto/rsa: use SHA256 instead of SHA1 in PKCS#1 v1.5 tests + +This switches to unconditionally using SHA256 for PKCS#1 v1.5 signing +and verification in tests, to pacify errors in FIPS mode. + +Signed-off-by: Daiki Ueno +--- + src/crypto/rsa/pkcs1v15_test.go | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go +index 0853178e3ab7b..3db1e94ffff2b 100644 +--- a/src/crypto/rsa/pkcs1v15_test.go ++++ b/src/crypto/rsa/pkcs1v15_test.go +@@ -11,7 +11,6 @@ import ( + "crypto/internal/backend/boringtest" + "crypto/rand" + . "crypto/rsa" +- "crypto/sha1" + "crypto/sha256" + "crypto/x509" + "encoding/base64" +@@ -210,16 +209,16 @@ type signPKCS1v15Test struct { + // + // `openssl rsautl -verify -inkey pk -in signature | hexdump -C` + var signPKCS1v15Tests = []signPKCS1v15Test{ +- {"Test.\n", "0c7c85d938862248846cba06b06ac9bfe752aafed3092c224f257855006aa35b43d101e6c8e59cbc4c20b07c81552963f189dea700e042d4b70c236a031a29a9273cc138e69dc1a5834491de4822d8cb6acf218789d2586cb0f3892236b0948ffaf8691f6fa04597caa45068f9be39b8ea8b5336a8c94e2696f872120778abcfea711e5fbf75f835f0f5204ccdd020013c2ceae25e9d1378a1d10cf86ca269eef48fee8ebb5e8dfb08f0c48d22d1a7162e080ec1f6e48541288aaaa1f2370f0688cf1786a32abed41df1d3b96b665794bf7a772743fc8b62d73901cea4569494c794a01ccc7dda0d42199f5b58739c0c0e280774b56ccf51993f5ea3d4954319"}, ++ {"Test.\n", "0c7da2fe34372c9e433ca668b6edf4cd7f7eb29f11c11c44d99cb6dc6fe4344cc656075015de6d0249d25b6e01bf22276e9f97f6e64f5905ce96cfc69e3c30e3813eb80553b1e53993482b97c920d030e1daf6c5f11f532a166a4b4aea34c6f8ed5579ccf6bfd5e20250d1979e97c358363da8ae15a095f07e9c54bfb948a94a75a6c8a0cbe4b9970d780ddf49369b2f134915e9a8ccf20e7b07981d0b95978630ee754f20bad163cdcff8c56c9bc66fd1060961779f1554894597086477d15346955d1a1c67d9718c4d25d840cf83fe203fd4e5681fc388a0395b79b94b1ade281f3682fb08a02ed6fa209caf489e9ccf501a86e99a36737b241c1e8ab2c2a4"}, + } + + func TestSignPKCS1v15(t *testing.T) { + for i, test := range signPKCS1v15Tests { +- h := sha1.New() ++ h := sha256.New() + h.Write([]byte(test.in)) + digest := h.Sum(nil) + +- s, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.SHA1, digest) ++ s, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.SHA256, digest) + if err != nil { + t.Errorf("#%d %s", i, err) + } +@@ -233,13 +232,13 @@ func TestSignPKCS1v15(t *testing.T) { + + func TestVerifyPKCS1v15(t *testing.T) { + for i, test := range signPKCS1v15Tests { +- h := sha1.New() ++ h := sha256.New() + h.Write([]byte(test.in)) + digest := h.Sum(nil) + + sig, _ := hex.DecodeString(test.out) + +- err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.SHA1, digest, sig) ++ err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.SHA256, digest, sig) + if err != nil { + t.Errorf("#%d %s", i, err) + } diff --git a/patches/009-fixes-6.patch b/patches/009-fixes-6.patch new file mode 100644 index 0000000000..c28216cce5 --- /dev/null +++ b/patches/009-fixes-6.patch @@ -0,0 +1,96 @@ +From 662ae4c37854734b17b095a36e42a8bbbcd85338 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Mon, 16 Oct 2023 12:25:26 +0900 +Subject: [PATCH] crypto/x509: adjust tests to pass under FIPS + +This fixes the following issues: + + --- FAIL: TestImports (0.93s) + x509_test.go:1411: failed to run x509_test_import.go: exit status 1 + panic: failed to create certificate with basic imports: EVP_PKEY_sign_init failed + openssl error(s): + error:1C800069:Provider routines::invalid key length + providers/common/securitycheck.c:67 + + goroutine 1 [running]: + main.main() + /__w/go/go/go/src/crypto/x509/x509_test_import.go:41 +0x205 + exit status 2 + --- FAIL: TestDisableSHA1ForCertOnly (0.00s) + x509_test.go:3653: failed to generate test cert: EVP_PKEY_fromdata + openssl error(s): + +The former was using too short RSA key (512 bits), while the latter +should be skipped when SHA1 signatures are not supported. + +Signed-off-by: Daiki Ueno +--- + src/crypto/x509/x509_test.go | 3 +++ + src/crypto/x509/x509_test_import.go | 40 +++++++++++++++++++++++------ + 2 files changed, 35 insertions(+), 8 deletions(-) + +diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go +index 6621f1b8cc304..356528e69cc36 100644 +--- a/src/crypto/x509/x509_test.go ++++ b/src/crypto/x509/x509_test.go +@@ -3637,6 +3637,9 @@ func TestParseUniqueID(t *testing.T) { + } + + func TestDisableSHA1ForCertOnly(t *testing.T) { ++ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { ++ t.Skip("unsupported in FIPS mode") ++ } + t.Setenv("GODEBUG", "") + + tmpl := &Certificate{ +diff --git a/src/crypto/x509/x509_test_import.go b/src/crypto/x509/x509_test_import.go +index 2474e3d810edf..492cb0a87554c 100644 +--- a/src/crypto/x509/x509_test_import.go ++++ b/src/crypto/x509/x509_test_import.go +@@ -42,14 +42,38 @@ func main() { + } + } + +-var pemPrivateKey = testingKey(`-----BEGIN RSA TESTING KEY----- +-MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 +-fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu +-/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu +-RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/ +-EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A +-IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS +-tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V ++// This key is generated with the following command: ++// ++// openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem ++// openssl pkey -traditional -in key.pem > key-traditional.pem ++// ++var pemPrivateKey = testingKey(` ++-----BEGIN RSA TESTING KEY----- ++MIIEogIBAAKCAQEAp5qgUIj096pw8U+AjcJucLWenR3oe+tEthXiAuqcYgslW5UU ++lMim34U/h7NbLvbG2KJ2chUsmLtuCFaoIe/YKW5DKm3SPytK/KCBsVa+MQ7zuF/1 ++ks5p7yBqFBl6QTekMzwskt/zyDIG9f3A+38akruHNBvUgYqwbWPx4ycclQ52GSev ++/Cfx0I68TGT5SwN/eCJ/ghq3iGAf0mX1bkVaW1seKbL49aAA94KnDCRdl813+S2R ++EPDf2tZwlT0JpZm5QtAqthonZjkjHocZNxhkKF3XWUntE/+l6R4A+CWZlC2vmUc1 ++hJTEraksy2JUIjxAaq//FnDpIEVG/N2ofmNpaQIDAQABAoIBAAYH7h9fwkLcNvqz ++8+oF9k/ndSjtr9UvstYDhRG6S/zKLmK0g1xUOQ7/fjj9lvkiZ6bZd74krWlkizHR ++HnU0KnjZLyEKeR+NSQI8q1YMi0T8JwB6MX3CIDU62x5UiV3p6OZwEqGJXf4U8MOu ++ySAzo2rmxRd2reeobC9Pgp98I47oeqaSRwFVZRPfKk5RvfI7KRmL58BAB0XS56PA ++PJ+3l0fB/oIV11iaBEKildxLDtrvlepQ2KPNf7Dpk0/CPRtS/jxyxIyML8tjR3F0 ++KuHplsRjTANyzW/aHddO1fnfnXsVo+0PzSPTHCbxKSu5XmChqsKoB1jM+/tJci4y ++ST5hUXUCgYEAzfA5XEMkR/NNJMfR+FBbdfpQ1b0wqH3qtWZx/tBjKC2Y0XnDQ8ZR ++SEWONLVZMRtTlJaHIPZ9i6anQRR5harrff0OpsKiJUGDout8ehE6eiN8ABWGNlCI ++AiLCerVJZMDcSuDU7xsdHVIdSxYh88Z9g54vUQ4214BG/G0Qm1emV3UCgYEA0FjP ++wq5cEGt9xDCg+oXk0bLm4Wn4FkabJH7M+oCosHHY9W1vgvv50bpNoAbaB5r1mlan ++T6gEtkQPB2juMTnuIwRL+kvOmSKqZGlAsyrq8smTuBUv7brbybkYN3Rg51KV6u1J ++vCdGpMYWHUNRkkQ88cr6iFPodYU+CzRR4ABif6UCgYBc0jDYb/7TW0tjD5mJJZcD ++xw5WOE7NMuvuVT1+T6jRvDOL/yjOzH1oaMle4npQEvQKHgrMBa2ymyv5vmPDprU7 ++9Sp8aW+yASR281MIpelIkePbGdiDdKrI46fqrPlmqzLfoRT4rKzjwVYouNIW0VlT ++UKIdE54OZegY8IOysL/t3QKBgDZnSnECiIW9G80UCaUBO3vKZGFuA1sFutMvzSSI ++XgQc5lNH7TtdwqESLdzgjSQ5QXK4t92j+P8DDI2Zx8DQ6K76G0DTdLImDCpGFZ/z ++UABvxIPn/GjuRyAIlhs852Tf+seqiHt6Igc6tmGTx4QTD3rvzrW0e1ncnhPc6Jg+ ++YXoFAoGARD9OPrd4J2N+nkSWif9VOuPHvOXEczwBDJbsAGrOW1kTbDStF0OIVOt0 ++Ukj+mnnL8ZNyVLgTrZDRfXvlA94EbPK5/rMAYwjMlXHP8R22ts3eDMNUdw0/Zl1g ++QOhL8wXZcdwHKsONy55kZHo8pmneqi9EnqqLGguLwx5WIMzWvZ8= + -----END RSA TESTING KEY----- + `) + diff --git a/patches/010-fixes-7.patch b/patches/010-fixes-7.patch new file mode 100644 index 0000000000..bb9a9645e0 --- /dev/null +++ b/patches/010-fixes-7.patch @@ -0,0 +1,63 @@ +diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go +index 3551b470ce..6f9573d066 100644 +--- a/src/crypto/x509/verify_test.go ++++ b/src/crypto/x509/verify_test.go +@@ -8,6 +8,7 @@ import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" ++ boring "crypto/internal/backend" + "crypto/rand" + "crypto/x509/pkix" + "encoding/asn1" +@@ -37,6 +38,8 @@ type verifyTest struct { + + errorCallback func(*testing.T, error) + expectedChains [][]string ++ ++ boringSkip bool + } + + var verifyTests = []verifyTest{ +@@ -143,6 +146,7 @@ var verifyTests = []verifyTest{ + // The StartCom root is not trusted by Windows when the default + // ServerAuth EKU is requested. + systemSkip: true, ++ boringSkip: true, + + expectedChains: [][]string{ + {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, +@@ -155,6 +159,7 @@ var verifyTests = []verifyTest{ + roots: []string{startComRoot}, + currentTime: 1302726541, + keyUsages: []ExtKeyUsage{ExtKeyUsageAny}, ++ boringSkip: true, + + expectedChains: [][]string{ + {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, +@@ -167,6 +172,7 @@ var verifyTests = []verifyTest{ + roots: []string{startComRoot}, + currentTime: 1302726541, + systemSkip: true, // see dnssec-exp test ++ boringSkip: true, + + expectedChains: [][]string{ + {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, +@@ -228,6 +234,7 @@ var verifyTests = []verifyTest{ + roots: []string{globalSignRoot}, + currentTime: 1382387896, + dnsName: "secure.iddl.vt.edu", ++ boringSkip: true, + + expectedChains: [][]string{ + { +@@ -557,6 +564,9 @@ func TestGoVerify(t *testing.T) { + + for _, test := range verifyTests { + t.Run(test.name, func(t *testing.T) { ++ if test.boringSkip && boring.Enabled() { ++ t.Skip("skipping test with BoringCrypto") ++ } + testVerify(t, test, false) + }) + } diff --git a/scripts/create-secondary-patch.sh b/scripts/create-secondary-patch.sh index 148c2d0ee8..581c752600 100755 --- a/scripts/create-secondary-patch.sh +++ b/scripts/create-secondary-patch.sh @@ -6,8 +6,6 @@ set -ex # merge conflicts if this was a patch, so we do them here instead and generate a patch # after. GO_SOURCES=src/crypto/**/*.go -sed -i -e "s/boring.SignRSAPKCS1v15(bkey, hash, hashed)/boring.SignRSAPKCS1v15(bkey, hash, hashed, true)/g" src/crypto/rsa/pkcs1v15.go -sed -i -e "s/boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig)/boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig, hash != crypto.Hash(0))/g" src/crypto/rsa/pkcs1v15.go sed -i -e "s/boring\.Enabled/boring\.Enabled()/g" ${GO_SOURCES} sed -i -e "s/\"crypto\/internal\/boring\"/boring \"crypto\/internal\/backend\"/g" ${GO_SOURCES} sed -i -e "s/\"crypto\/internal\/boring\/bbig\"/\"crypto\/internal\/backend\/bbig\"/g" ${GO_SOURCES} @@ -21,21 +19,37 @@ sed -i -e "s/\!no_openssl/boringcrypto/g" src/crypto/boring/boring.go # Remove the crypto/internal/boring code as we're replacing it with the openssl backend code. rm -rf src/crypto/internal/boring/*.go -rm -rf src/crypto/internal/boring/bbig +#rm -rf src/crypto/internal/boring/bbig rm src/crypto/boring/notboring_test.go rm src/crypto/boring/boring_test.go +echo """// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package boring provides access to BoringCrypto implementation functions. +// Check the constant Enabled to find out whether BoringCrypto is available. +// If BoringCrypto is not available, the functions in this package all panic. +package boring + +import \"github.com/golang-fips/openssl/v2\" + +// A BigInt is the raw words from a BigInt. +// This definition allows us to avoid importing math/big. +// Conversion between BigInt and *big.Int is in crypto/internal/boring/bbig. +type BigInt = openssl.BigInt +""" > src/crypto/internal/boring/doc.go # Add new openssl backend to module and vendor it. cd src SCRIPT_DIR=$(readlink -f $(dirname $0)) CONFIG_DIR=$(readlink -f $(dirname $0)/../config) OPENSSL_FIPS_REF=$(go run ${SCRIPT_DIR}/versions.go ${CONFIG_DIR}/versions.json \ - github.com/golang-fips/openssl-fips) -go get github.com/golang-fips/openssl-fips@${OPENSSL_FIPS_REF} + github.com/golang-fips/openssl) +go get github.com/golang-fips/openssl/v2@${OPENSSL_FIPS_REF} replace="${1}" if [ -n "${replace}" ]; then - echo "replace github.com/golang-fips/openssl-fips => ${replace}" >> go.mod + go mod edit -replace github.com/golang-fips/openssl/v2="${replace}" fi ../bin/go mod tidy ../bin/go mod vendor diff --git a/scripts/setup-initial-patch.sh b/scripts/setup-initial-patch.sh index b1dab7ecaa..3478a9810e 100755 --- a/scripts/setup-initial-patch.sh +++ b/scripts/setup-initial-patch.sh @@ -9,6 +9,7 @@ function cleanup() { # shellcheck disable=SC2181 if [ "0" != "${?}" ]; then cd "${ROOT}" + git reset go rm -rf go fi } @@ -37,6 +38,7 @@ shift $((OPTIND-1)) # Enter the submodule directory. cd ./go ORIGINAL_GIT_SHA=$(git rev-parse HEAD) +echo $replacement # Build the Go toolchain before applying patches. This allows us to use this toolchain in later steps # when running `go mod` commands.