From e9507062deb9f4123aac06b04f7ce81298cedb23 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 21 Sep 2023 12:50:18 +0200 Subject: [PATCH 1/3] rebase with main --- .../0002-Add-crypto-backend-foundation.patch | 125 +- .../0003-Add-BoringSSL-crypto-backend.patch | 23 +- patches/0004-Add-OpenSSL-crypto-backend.patch | 74 +- patches/0005-Add-CNG-crypto-backend.patch | 38 +- patches/0006-Vendor-crypto-backends.patch | 5266 ++++++++++------- 5 files changed, 3350 insertions(+), 2176 deletions(-) diff --git a/patches/0002-Add-crypto-backend-foundation.patch b/patches/0002-Add-crypto-backend-foundation.patch index 231c662a45e..6704ced8341 100644 --- a/patches/0002-Add-crypto-backend-foundation.patch +++ b/patches/0002-Add-crypto-backend-foundation.patch @@ -17,9 +17,9 @@ Subject: [PATCH] Add crypto backend foundation src/crypto/hmac/hmac_test.go | 2 +- src/crypto/internal/backend/backend_test.go | 30 +++++ src/crypto/internal/backend/bbig/big.go | 17 +++ - src/crypto/internal/backend/common.go | 78 ++++++++++++ + src/crypto/internal/backend/common.go | 78 +++++++++++ src/crypto/internal/backend/isrequirefips.go | 9 ++ - src/crypto/internal/backend/nobackend.go | 127 +++++++++++++++++++ + src/crypto/internal/backend/nobackend.go | 135 +++++++++++++++++++ src/crypto/internal/backend/norequirefips.go | 9 ++ src/crypto/internal/backend/stub.s | 10 ++ src/crypto/rand/rand_unix.go | 2 +- @@ -37,9 +37,10 @@ Subject: [PATCH] Add crypto backend foundation src/crypto/sha512/sha512_test.go | 2 +- src/crypto/tls/cipher_suites.go | 2 +- src/crypto/tls/key_schedule.go | 18 ++- + src/crypto/tls/prf.go | 39 ++++-- src/go/build/deps_test.go | 2 + src/runtime/runtime_boring.go | 5 + - 35 files changed, 333 insertions(+), 30 deletions(-) + 36 files changed, 371 insertions(+), 39 deletions(-) create mode 100644 src/crypto/internal/backend/backend_test.go create mode 100644 src/crypto/internal/backend/bbig/big.go create mode 100644 src/crypto/internal/backend/common.go @@ -356,10 +357,10 @@ index 00000000000000..e5d7570d6d4363 +const isRequireFIPS = true diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go new file mode 100644 -index 00000000000000..2be7b5a47926bb +index 00000000000000..e3e9817a7c5c40 --- /dev/null +++ b/src/crypto/internal/backend/nobackend.go -@@ -0,0 +1,127 @@ +@@ -0,0 +1,135 @@ +// 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. @@ -387,6 +388,8 @@ index 00000000000000..2be7b5a47926bb + +const RandReader = randReader(0) + ++func SupportsHash(h crypto.Hash) bool { panic("cryptobackend: not available") } ++ +func NewSHA1() hash.Hash { panic("cryptobackend: not available") } +func NewSHA224() hash.Hash { panic("cryptobackend: not available") } +func NewSHA256() hash.Hash { panic("cryptobackend: not available") } @@ -487,6 +490,12 @@ index 00000000000000..2be7b5a47926bb +func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { + panic("cryptobackend: not available") +} ++ ++func SupportsTLS1PRF() bool { panic("cryptobackend: not available") } ++ ++func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { ++ panic("cryptobackend: not available") ++} diff --git a/src/crypto/internal/backend/norequirefips.go b/src/crypto/internal/backend/norequirefips.go new file mode 100644 index 00000000000000..26bfb5f6a643f3 @@ -741,8 +750,112 @@ index d7f082c9ee1e04..14a85fbf1bd465 100644 return hkdf.Extract(c.hash.New, newSecret, currentSecret) } +diff --git a/src/crypto/tls/prf.go b/src/crypto/tls/prf.go +index 20bac96e86703b..de4d681151878f 100644 +--- a/src/crypto/tls/prf.go ++++ b/src/crypto/tls/prf.go +@@ -7,6 +7,7 @@ package tls + import ( + "crypto" + "crypto/hmac" ++ boring "crypto/internal/backend" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" +@@ -45,7 +46,13 @@ func pHash(result, secret, seed []byte, hash func() hash.Hash) { + } + + // prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5. +-func prf10(result, secret, label, seed []byte) { ++func prf10(result, secret, label, seed []byte) error { ++ if boring.Enabled && boring.SupportsTLS1PRF() && boring.SupportsHash(crypto.MD5SHA1) { ++ if err := boring.TLS1PRF(result, secret, label, seed, nil); err != nil { ++ return fmt.Errorf("crypto/tls: prf10: %v", err) ++ } ++ return nil ++ } + hashSHA1 := sha1.New + hashMD5 := md5.New + +@@ -61,16 +68,24 @@ func prf10(result, secret, label, seed []byte) { + for i, b := range result2 { + result[i] ^= b + } ++ return nil + } + + // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5. +-func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { +- return func(result, secret, label, seed []byte) { ++func prf12(h crypto.Hash, hashFunc func() hash.Hash) func(result, secret, label, seed []byte) error { ++ return func(result, secret, label, seed []byte) error { ++ if boring.Enabled && boring.SupportsTLS1PRF() && boring.SupportsHash(h) { ++ if err := boring.TLS1PRF(result, secret, label, seed, hashFunc); err != nil { ++ return fmt.Errorf("crypto/tls: prf12: %v", err) ++ } ++ return nil ++ } + labelAndSeed := make([]byte, len(label)+len(seed)) + copy(labelAndSeed, label) + copy(labelAndSeed[len(label):], seed) + + pHash(result, secret, labelAndSeed, hashFunc) ++ return nil + } + } + +@@ -85,21 +100,23 @@ var keyExpansionLabel = []byte("key expansion") + var clientFinishedLabel = []byte("client finished") + var serverFinishedLabel = []byte("server finished") + +-func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { ++func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte) error, crypto.Hash) { + switch version { + case VersionTLS10, VersionTLS11: + return prf10, crypto.Hash(0) + case VersionTLS12: + if suite.flags&suiteSHA384 != 0 { +- return prf12(sha512.New384), crypto.SHA384 ++ h := crypto.SHA384 ++ return prf12(h, sha512.New384), h + } +- return prf12(sha256.New), crypto.SHA256 ++ h := crypto.SHA256 ++ return prf12(h, sha256.New), h + default: + panic("unknown version") + } + } + +-func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { ++func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) error { + prf, _ := prfAndHashForVersion(version, suite) + return prf + } +@@ -177,7 +194,7 @@ type finishedHash struct { + buffer []byte + + version uint16 +- prf func(result, secret, label, seed []byte) ++ prf func(result, secret, label, seed []byte) error + } + + func (h *finishedHash) Write(msg []byte) (n int, err error) { +@@ -286,7 +303,11 @@ func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clien + } + + keyMaterial := make([]byte, length) +- prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) ++ if err := prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed); err != nil { ++ // Could happen if the seed is too large. The Go implementation doesn't limit the seed size, ++ // as RFC 5705 doesn't specify a limit, but stock OpenSSL restrict it to 1024 and CNG to 256. ++ return nil, err ++ } + return keyMaterial, nil + } + } diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go -index ff03691eb90397..1a8530d999b0c9 100644 +index ca0c4089a2e505..4a6d42b18c46bc 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -428,6 +428,7 @@ var depsRules = ` diff --git a/patches/0003-Add-BoringSSL-crypto-backend.patch b/patches/0003-Add-BoringSSL-crypto-backend.patch index 732a3b01b9f..16ef4dc7500 100644 --- a/patches/0003-Add-BoringSSL-crypto-backend.patch +++ b/patches/0003-Add-BoringSSL-crypto-backend.patch @@ -5,8 +5,8 @@ Subject: [PATCH] Add BoringSSL crypto backend --- .../internal/backend/bbig/big_boring.go | 12 ++ - src/crypto/internal/backend/boring_linux.go | 146 ++++++++++++++++++ - 2 files changed, 158 insertions(+) + src/crypto/internal/backend/boring_linux.go | 161 ++++++++++++++++++ + 2 files changed, 173 insertions(+) create mode 100644 src/crypto/internal/backend/bbig/big_boring.go create mode 100644 src/crypto/internal/backend/boring_linux.go @@ -30,10 +30,10 @@ index 00000000000000..0b62cef68546d0 +var Dec = bbig.Dec diff --git a/src/crypto/internal/backend/boring_linux.go b/src/crypto/internal/backend/boring_linux.go new file mode 100644 -index 00000000000000..4f3057b92627c3 +index 00000000000000..35e1d00d29980d --- /dev/null +++ b/src/crypto/internal/backend/boring_linux.go -@@ -0,0 +1,146 @@ +@@ -0,0 +1,161 @@ +// 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. @@ -57,6 +57,15 @@ index 00000000000000..4f3057b92627c3 + +const RandReader = boring.RandReader + ++func SupportsHash(h crypto.Hash) bool { ++ switch h { ++ case crypto.SHA1, crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512: ++ return true ++ default: ++ return false ++ } ++} ++ +func NewSHA1() hash.Hash { return boring.NewSHA1() } +func NewSHA224() hash.Hash { return boring.NewSHA224() } +func NewSHA256() hash.Hash { return boring.NewSHA256() } @@ -180,3 +189,9 @@ index 00000000000000..4f3057b92627c3 +func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { + panic("cryptobackend: not available") +} ++ ++func SupportsTLS1PRF() bool { return false } ++ ++func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { ++ panic("cryptobackend: not available") ++} diff --git a/patches/0004-Add-OpenSSL-crypto-backend.patch b/patches/0004-Add-OpenSSL-crypto-backend.patch index 08bee263d54..72a885884fa 100644 --- a/patches/0004-Add-OpenSSL-crypto-backend.patch +++ b/patches/0004-Add-OpenSSL-crypto-backend.patch @@ -14,7 +14,7 @@ Subject: [PATCH] Add OpenSSL crypto backend src/crypto/ecdsa/notboring.go | 2 +- src/crypto/internal/backend/bbig/big.go | 2 +- .../internal/backend/bbig/big_openssl.go | 12 + - src/crypto/internal/backend/openssl_linux.go | 239 ++++++++++++++++++ + src/crypto/internal/backend/openssl_linux.go | 261 ++++++++++++++++++ src/crypto/internal/boring/fipstls/stub.s | 2 +- src/crypto/internal/boring/fipstls/tls.go | 2 +- src/crypto/rsa/boring.go | 2 +- @@ -37,7 +37,7 @@ Subject: [PATCH] Add OpenSSL crypto backend .../goexperiment/exp_opensslcrypto_on.go | 9 + src/internal/goexperiment/flags.go | 1 + src/os/exec/exec_test.go | 9 + - 33 files changed, 321 insertions(+), 23 deletions(-) + 33 files changed, 343 insertions(+), 23 deletions(-) create mode 100644 src/crypto/internal/backend/bbig/big_openssl.go create mode 100644 src/crypto/internal/backend/openssl_linux.go create mode 100644 src/internal/goexperiment/exp_opensslcrypto_off.go @@ -190,10 +190,10 @@ index 00000000000000..e6695dd66b1d02 +var Dec = bbig.Dec diff --git a/src/crypto/internal/backend/openssl_linux.go b/src/crypto/internal/backend/openssl_linux.go new file mode 100644 -index 00000000000000..401ac5ce6101d9 +index 00000000000000..1da89e6645069f --- /dev/null +++ b/src/crypto/internal/backend/openssl_linux.go -@@ -0,0 +1,239 @@ +@@ -0,0 +1,261 @@ +// 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. @@ -226,26 +226,36 @@ index 00000000000000..401ac5ce6101d9 +// Fedora derived distros use different naming for the version 1.0.x. +var knownVersions = [...]string{"3", "1.1", "11", "111", "1.0.2", "1.0.0", "10"} + ++const lcryptoPrefix = "libcrypto.so." ++ +func init() { -+ version, _ := syscall.Getenv("GO_OPENSSL_VERSION_OVERRIDE") -+ if version == "" { -+ var fallbackVersion string ++ var lcrypto string ++ if version, _ := syscall.Getenv("GO_OPENSSL_VERSION_OVERRIDE"); version != "" { ++ lcrypto = lcryptoPrefix + version ++ } else { ++ // Try to find the highest available FIPS-enabled version of OpenSSL ++ // using the known library suffixes. ++ var lcryptoFallback string + for _, v := range knownVersions { -+ exists, fips := openssl.CheckVersion(v) -+ if exists && fips { -+ version = v -+ break -+ } -+ if exists && fallbackVersion == "" { -+ fallbackVersion = v ++ lcryptoCandidate := lcryptoPrefix + v ++ if exists, fips := openssl.CheckVersion(lcryptoCandidate); exists { ++ if fips { ++ lcrypto = lcryptoCandidate ++ break ++ } ++ if lcryptoFallback == "" { ++ lcryptoFallback = lcryptoCandidate ++ } + } + } -+ if version == "" && fallbackVersion != "" { -+ version = fallbackVersion ++ if lcrypto == "" && lcryptoFallback != "" { ++ // There is no FIPS-enabled version of OpenSSL, ++ // use the highest available version. ++ lcrypto = lcryptoFallback + } + } -+ if err := openssl.Init(version); err != nil { -+ panic("opensslcrypto: can't initialize OpenSSL " + version + ": " + err.Error()) ++ if err := openssl.Init(lcrypto); err != nil { ++ panic("opensslcrypto: can't initialize OpenSSL " + lcrypto + ": " + 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. @@ -308,6 +318,10 @@ index 00000000000000..401ac5ce6101d9 + +const RandReader = openssl.RandReader + ++func SupportsHash(h crypto.Hash) bool { ++ return openssl.SupportsHash(h) ++} ++ +func NewSHA1() hash.Hash { return openssl.NewSHA1() } +func NewSHA224() hash.Hash { return openssl.NewSHA224() } +func NewSHA256() hash.Hash { return openssl.NewSHA256() } @@ -433,6 +447,14 @@ index 00000000000000..401ac5ce6101d9 +func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { + return openssl.ExtractHKDF(h, secret, salt) +} ++ ++func SupportsTLS1PRF() bool { ++ return openssl.SupportsTLS1PRF() ++} ++ ++func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { ++ return openssl.TLS1PRF(result, secret, label, seed, h) ++} diff --git a/src/crypto/internal/boring/fipstls/stub.s b/src/crypto/internal/boring/fipstls/stub.s index f2e5a503eaacb6..1dc7116efdff2e 100644 --- a/src/crypto/internal/boring/fipstls/stub.s @@ -629,29 +651,29 @@ index c83a7272c9f01f..a0548a7f9179c5 100644 package x509 diff --git a/src/go.mod b/src/go.mod -index beb4d13d8bdc6f..3de2b296d0fecb 100644 +index beb4d13d8bdc6f..e7fb80cab94b01 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,6 +3,7 @@ module std go 1.22 require ( -+ github.com/golang-fips/openssl/v2 v2.0.0-rc.2 ++ github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 golang.org/x/crypto v0.12.0 golang.org/x/net v0.14.1-0.20230809150940-1e23797619c9 ) diff --git a/src/go.sum b/src/go.sum -index 81b83159f77a36..ff87d3883113cd 100644 +index 81b83159f77a36..91eca9cd0b05e6 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,3 +1,5 @@ -+github.com/golang-fips/openssl/v2 v2.0.0-rc.2 h1:0RFGh/pnzSAe5LlriE416hQUYxYNFZD9y/53d0ld7K0= -+github.com/golang-fips/openssl/v2 v2.0.0-rc.2/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 h1:rTL9t7VhLvvOt4e/EZvXfJISo2igRm7GqK0pX1OQnx8= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/net v0.14.1-0.20230809150940-1e23797619c9 h1:eQR0jFW5dN2q8lFzSF7rjkRCOOnBf0llczNvITm6ICs= diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go -index 1a8530d999b0c9..a31878487bc285 100644 +index 4a6d42b18c46bc..0a6be3cc0231fc 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -427,6 +427,8 @@ var depsRules = ` @@ -732,7 +754,7 @@ index 5d0f5b678b4f9d..416b5002944529 100644 // SystemCrypto enables the OpenSSL or CNG crypto experiment depending on // which one is appropriate on the target GOOS. diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go -index 473f92ba8e43a1..b4df61a7b95c7a 100644 +index 71a00494ad3bbe..3255ed72385a4a 100644 --- a/src/os/exec/exec_test.go +++ b/src/os/exec/exec_test.go @@ -14,6 +14,7 @@ import ( @@ -743,7 +765,7 @@ index 473f92ba8e43a1..b4df61a7b95c7a 100644 "internal/poll" "internal/testenv" "io" -@@ -700,6 +701,14 @@ func TestExtraFiles(t *testing.T) { +@@ -737,6 +738,14 @@ func TestExtraFiles(t *testing.T) { t.Skipf("skipping test on %q", runtime.GOOS) } diff --git a/patches/0005-Add-CNG-crypto-backend.patch b/patches/0005-Add-CNG-crypto-backend.patch index 20a5b723cf2..83059d46ba9 100644 --- a/patches/0005-Add-CNG-crypto-backend.patch +++ b/patches/0005-Add-CNG-crypto-backend.patch @@ -12,7 +12,7 @@ Subject: [PATCH] Add CNG crypto backend src/crypto/internal/backend/backend_test.go | 4 +- src/crypto/internal/backend/bbig/big.go | 2 +- src/crypto/internal/backend/bbig/big_cng.go | 12 + - src/crypto/internal/backend/cng_windows.go | 220 ++++++++++++++++++ + src/crypto/internal/backend/cng_windows.go | 232 ++++++++++++++++++ src/crypto/internal/backend/common.go | 33 ++- src/crypto/internal/boring/fipstls/stub.s | 2 +- src/crypto/internal/boring/fipstls/tls.go | 2 +- @@ -46,7 +46,7 @@ Subject: [PATCH] Add CNG crypto backend .../goexperiment/exp_cngcrypto_off.go | 9 + src/internal/goexperiment/exp_cngcrypto_on.go | 9 + src/internal/goexperiment/flags.go | 1 + - 42 files changed, 410 insertions(+), 40 deletions(-) + 42 files changed, 422 insertions(+), 40 deletions(-) create mode 100644 src/crypto/internal/backend/bbig/big_cng.go create mode 100644 src/crypto/internal/backend/cng_windows.go create mode 100644 src/internal/goexperiment/exp_cngcrypto_off.go @@ -165,10 +165,10 @@ index 00000000000000..92623031fd87d0 +var Dec = bbig.Dec diff --git a/src/crypto/internal/backend/cng_windows.go b/src/crypto/internal/backend/cng_windows.go new file mode 100644 -index 00000000000000..a6127c1fa36403 +index 00000000000000..27a0480c8ceb75 --- /dev/null +++ b/src/crypto/internal/backend/cng_windows.go -@@ -0,0 +1,220 @@ +@@ -0,0 +1,232 @@ +// 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. @@ -211,6 +211,10 @@ index 00000000000000..a6127c1fa36403 + +const RandReader = cng.RandReader + ++func SupportsHash(h crypto.Hash) bool { ++ return cng.SupportsHash(h) ++} ++ +func NewSHA1() hash.Hash { + return cng.NewSHA1() +} @@ -389,6 +393,14 @@ index 00000000000000..a6127c1fa36403 +func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { + return cng.ExtractHKDF(h, secret, salt) +} ++ ++func SupportsTLS1PRF() bool { ++ return true ++} ++ ++func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { ++ return cng.TLS1PRF(result, secret, label, seed, h) ++} diff --git a/src/crypto/internal/backend/common.go b/src/crypto/internal/backend/common.go index efdd080a1b7708..9d7f7b849d6485 100644 --- a/src/crypto/internal/backend/common.go @@ -1004,31 +1016,31 @@ index a0548a7f9179c5..ae6117a1554b7f 100644 package x509 diff --git a/src/go.mod b/src/go.mod -index 3de2b296d0fecb..e441e40d1227b0 100644 +index e7fb80cab94b01..9e86277d8e3bbe 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,6 +4,7 @@ go 1.22 require ( - github.com/golang-fips/openssl/v2 v2.0.0-rc.2 -+ github.com/microsoft/go-crypto-winnative v0.0.0-20230822062938-306d53ca6072 + github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 ++ github.com/microsoft/go-crypto-winnative v0.0.0-20230919193409-4899d534a7ff golang.org/x/crypto v0.12.0 golang.org/x/net v0.14.1-0.20230809150940-1e23797619c9 ) diff --git a/src/go.sum b/src/go.sum -index ff87d3883113cd..497d219d18acd9 100644 +index 91eca9cd0b05e6..d40c2bc8984d29 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,5 +1,7 @@ - github.com/golang-fips/openssl/v2 v2.0.0-rc.2 h1:0RFGh/pnzSAe5LlriE416hQUYxYNFZD9y/53d0ld7K0= - github.com/golang-fips/openssl/v2 v2.0.0-rc.2/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= -+github.com/microsoft/go-crypto-winnative v0.0.0-20230822062938-306d53ca6072 h1:FyW57WKhBHQm/ebpbvQ7+eMiKBRQuLEA6iq228Py1fI= -+github.com/microsoft/go-crypto-winnative v0.0.0-20230822062938-306d53ca6072/go.mod h1:fveERXKbeK+XLmOyU24caKnIT/S5nniAX9XCRHfnrM4= + github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 h1:rTL9t7VhLvvOt4e/EZvXfJISo2igRm7GqK0pX1OQnx8= + github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= ++github.com/microsoft/go-crypto-winnative v0.0.0-20230919193409-4899d534a7ff h1:m0Cr4tuDOCmNoHtQV7RRTTH54d5Q9yV2g0AC2SO/7uI= ++github.com/microsoft/go-crypto-winnative v0.0.0-20230919193409-4899d534a7ff/go.mod h1:fveERXKbeK+XLmOyU24caKnIT/S5nniAX9XCRHfnrM4= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/net v0.14.1-0.20230809150940-1e23797619c9 h1:eQR0jFW5dN2q8lFzSF7rjkRCOOnBf0llczNvITm6ICs= diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go -index a31878487bc285..0a7ef1f77b040a 100644 +index 0a6be3cc0231fc..d9cf7f503b107b 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -427,6 +427,10 @@ var depsRules = ` diff --git a/patches/0006-Vendor-crypto-backends.patch b/patches/0006-Vendor-crypto-backends.patch index 3b53f1238ee..04363083894 100644 --- a/patches/0006-Vendor-crypto-backends.patch +++ b/patches/0006-Vendor-crypto-backends.patch @@ -7,73 +7,94 @@ To reproduce, run 'go mod vendor' in 'go/src'. --- .../golang-fips/openssl/v2/.gitleaks.toml | 9 + .../github.com/golang-fips/openssl/v2/LICENSE | 20 + - .../golang-fips/openssl/v2/README.md | 64 ++ - .../github.com/golang-fips/openssl/v2/aes.go | 549 ++++++++++++++ + .../golang-fips/openssl/v2/README.md | 62 ++ + .../github.com/golang-fips/openssl/v2/aes.go | 84 ++ .../golang-fips/openssl/v2/bbig/big.go | 37 + .../github.com/golang-fips/openssl/v2/big.go | 11 + + .../golang-fips/openssl/v2/cgo_go122.go | 13 + + .../golang-fips/openssl/v2/cipher.go | 509 +++++++++++ + .../github.com/golang-fips/openssl/v2/des.go | 107 +++ .../github.com/golang-fips/openssl/v2/ec.go | 59 ++ - .../github.com/golang-fips/openssl/v2/ecdh.go | 323 ++++++++ - .../golang-fips/openssl/v2/ecdsa.go | 217 ++++++ - .../github.com/golang-fips/openssl/v2/evp.go | 460 ++++++++++++ - .../golang-fips/openssl/v2/goopenssl.c | 213 ++++++ - .../golang-fips/openssl/v2/goopenssl.h | 170 +++++ - .../github.com/golang-fips/openssl/v2/hkdf.go | 158 ++++ + .../github.com/golang-fips/openssl/v2/ecdh.go | 323 +++++++ + .../golang-fips/openssl/v2/ecdsa.go | 217 +++++ + .../github.com/golang-fips/openssl/v2/evp.go | 473 +++++++++++ + .../golang-fips/openssl/v2/goopenssl.c | 218 +++++ + .../golang-fips/openssl/v2/goopenssl.h | 183 ++++ + .../github.com/golang-fips/openssl/v2/hash.go | 793 ++++++++++++++++++ + .../github.com/golang-fips/openssl/v2/hkdf.go | 174 ++++ .../github.com/golang-fips/openssl/v2/hmac.go | 238 ++++++ - .../github.com/golang-fips/openssl/v2/init.go | 72 ++ - .../golang-fips/openssl/v2/openssl.go | 273 +++++++ - .../openssl/v2/port_evp_md5_sha1.c | 128 ++++ + .../github.com/golang-fips/openssl/v2/init.go | 63 ++ + .../golang-fips/openssl/v2/init_unix.go | 31 + + .../golang-fips/openssl/v2/init_windows.go | 36 + + .../golang-fips/openssl/v2/openssl.go | 412 +++++++++ + .../golang-fips/openssl/v2/pbkdf2.go | 28 + + .../openssl/v2/port_evp_md5_sha1.c | 126 +++ .../github.com/golang-fips/openssl/v2/rand.go | 20 + - .../github.com/golang-fips/openssl/v2/rsa.go | 419 +++++++++++ - .../github.com/golang-fips/openssl/v2/sha.go | 690 ++++++++++++++++++ - .../github.com/golang-fips/openssl/v2/shims.h | 343 +++++++++ - .../golang-fips/openssl/v2/thread_setup.c | 35 + + .../github.com/golang-fips/openssl/v2/rsa.go | 419 +++++++++ + .../github.com/golang-fips/openssl/v2/shims.h | 358 ++++++++ + .../openssl/v2/thread_setup_unix.c | 35 + + .../openssl/v2/thread_setup_windows.c | 33 + + .../golang-fips/openssl/v2/tls1prf.go | 104 +++ .../microsoft/go-crypto-winnative/LICENSE | 21 + - .../microsoft/go-crypto-winnative/cng/aes.go | 359 +++++++++ + .../microsoft/go-crypto-winnative/cng/aes.go | 331 ++++++++ .../go-crypto-winnative/cng/bbig/big.go | 31 + .../microsoft/go-crypto-winnative/cng/big.go | 30 + - .../microsoft/go-crypto-winnative/cng/cng.go | 130 ++++ - .../microsoft/go-crypto-winnative/cng/ecdh.go | 260 +++++++ - .../go-crypto-winnative/cng/ecdsa.go | 175 +++++ - .../microsoft/go-crypto-winnative/cng/hash.go | 298 ++++++++ + .../go-crypto-winnative/cng/cipher.go | 56 ++ + .../microsoft/go-crypto-winnative/cng/cng.go | 130 +++ + .../microsoft/go-crypto-winnative/cng/des.go | 106 +++ + .../microsoft/go-crypto-winnative/cng/ecdh.go | 260 ++++++ + .../go-crypto-winnative/cng/ecdsa.go | 175 ++++ + .../microsoft/go-crypto-winnative/cng/hash.go | 298 +++++++ .../microsoft/go-crypto-winnative/cng/hkdf.go | 150 ++++ .../microsoft/go-crypto-winnative/cng/hmac.go | 55 ++ - .../microsoft/go-crypto-winnative/cng/keys.go | 178 +++++ - .../go-crypto-winnative/cng/pbkdf2.go | 71 ++ + .../microsoft/go-crypto-winnative/cng/keys.go | 178 ++++ + .../go-crypto-winnative/cng/pbkdf2.go | 74 ++ .../microsoft/go-crypto-winnative/cng/rand.go | 28 + - .../microsoft/go-crypto-winnative/cng/rsa.go | 374 ++++++++++ - .../internal/bcrypt/bcrypt_windows.go | 276 +++++++ - .../internal/bcrypt/zsyscall_windows.go | 389 ++++++++++ + .../microsoft/go-crypto-winnative/cng/rsa.go | 374 +++++++++ + .../go-crypto-winnative/cng/tls1prf.go | 92 ++ + .../internal/bcrypt/bcrypt_windows.go | 283 +++++++ + .../internal/bcrypt/zsyscall_windows.go | 389 +++++++++ .../internal/subtle/aliasing.go | 32 + .../internal/sysdll/sys_windows.go | 55 ++ src/vendor/modules.txt | 11 + - 41 files changed, 7431 insertions(+) + 52 files changed, 8354 insertions(+) create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/LICENSE create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/README.md create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/aes.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/big.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/cgo_go122.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/cipher.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/des.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/ec.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/ecdh.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/evp.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/hash.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/hkdf.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/hmac.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/init.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/init_unix.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/init_windows.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/openssl.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/rand.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/rsa.go - create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/sha.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/shims.h - create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/thread_setup.c + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/thread_setup_windows.c + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/LICENSE create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/bbig/big.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/big.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/cipher.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/cng.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/des.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/ecdh.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/ecdsa.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go @@ -83,6 +104,7 @@ To reproduce, run 'go mod vendor' in 'go/src'. create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/pbkdf2.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/rand.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/rsa.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/cng/tls1prf.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/bcrypt_windows.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/zsyscall_windows.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/internal/subtle/aliasing.go @@ -132,10 +154,10 @@ index 00000000000000..97e85154015761 \ 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 00000000000000..0b6fb805c113bb +index 00000000000000..e12474e6b54e43 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/README.md -@@ -0,0 +1,64 @@ +@@ -0,0 +1,62 @@ +# 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) @@ -188,9 +210,7 @@ index 00000000000000..0b6fb805c113bb + +## Limitations + -+OpenSSL is used for a given build only in limited circumstances: -+ -+- The platform must be `GOOS=linux`. ++- Only Unix, Unix-like and Windows platforms are supported. +- The build must set `CGO_ENABLED=1`. + +## Acknowledgements @@ -202,11 +222,180 @@ index 00000000000000..0b6fb805c113bb +- The portable OpenSSL implementation is ported from Microsoft's [.NET runtime](https://github.com/dotnet/runtime) cryptography module. 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 00000000000000..a17f473ce30c87 +index 00000000000000..ecda35a992410f --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/aes.go -@@ -0,0 +1,549 @@ -+//go:build linux +@@ -0,0 +1,84 @@ ++//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) { ++ c.encrypt(dst, src) ++} ++ ++func (c *aesCipher) Decrypt(dst, src []byte) { ++ c.decrypt(dst, src) ++} ++ ++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 00000000000000..a81cbdbef93148 +--- /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 00000000000000..6461f241f863fc +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/big.go +@@ -0,0 +1,11 @@ ++package openssl ++ ++// 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. ++ ++// 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/cgo_go122.go b/src/vendor/github.com/golang-fips/openssl/v2/cgo_go122.go +new file mode 100644 +index 00000000000000..555f58c59979a8 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/cgo_go122.go +@@ -0,0 +1,13 @@ ++//go:build go1.22 && !cmd_go_bootstrap ++ ++package openssl ++ ++/* ++// The following noescape and nocallback directives are used to ++// prevent the Go compiler from allocating function parameters on the ++// heap. This is just a performance optimization. Only add those ++// functions that are known to allocate. ++#cgo noescape go_openssl_EVP_PKEY_derive ++#cgo nocallback go_openssl_EVP_PKEY_derive ++*/ ++import "C" +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 00000000000000..df6c40f1d9b95b +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go +@@ -0,0 +1,509 @@ ++//go:build !cmd_go_bootstrap + +package openssl + @@ -225,26 +414,62 @@ index 00000000000000..a17f473ce30c87 +type cipherKind int8 + +const ( -+ cipherAES128_ECB cipherKind = iota -+ cipherAES192_ECB -+ cipherAES256_ECB -+ cipherAES128_CBC -+ cipherAES192_CBC -+ cipherAES256_CBC -+ cipherAES128_CTR -+ cipherAES192_CTR -+ cipherAES256_CTR -+ cipherAES128_GCM -+ cipherAES192_GCM -+ cipherAES256_GCM ++ cipherAES128 cipherKind = iota ++ cipherAES192 ++ cipherAES256 ++ cipherDES ++ cipherDES3 ++) ++ ++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" ++ default: ++ panic("unknown cipher kind: " + strconv.Itoa(int(c))) ++ } ++} ++ ++type cipherMode int8 ++ ++const ( ++ 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 + -+// newCipher returns a cipher object for the given k. -+func newCipher(k cipherKind) (cipher C.GO_EVP_CIPHER_PTR) { -+ if v, ok := cacheCipher.Load(k); ok { ++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() { @@ -255,86 +480,81 @@ index 00000000000000..a17f473ce30c87 + // 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(k, cipher) ++ cacheCipher.Store(cacheCipherKey{k, mode}, cipher) + }() + switch k { -+ case cipherAES128_CBC: -+ cipher = C.go_openssl_EVP_aes_128_cbc() -+ case cipherAES192_CBC: -+ cipher = C.go_openssl_EVP_aes_192_cbc() -+ case cipherAES256_CBC: -+ cipher = C.go_openssl_EVP_aes_256_cbc() -+ case cipherAES128_ECB: -+ cipher = C.go_openssl_EVP_aes_128_ecb() -+ case cipherAES192_ECB: -+ cipher = C.go_openssl_EVP_aes_192_ecb() -+ case cipherAES256_ECB: -+ cipher = C.go_openssl_EVP_aes_256_ecb() -+ case cipherAES128_CTR: -+ cipher = C.go_openssl_EVP_aes_128_ctr() -+ case cipherAES192_CTR: -+ cipher = C.go_openssl_EVP_aes_192_ctr() -+ case cipherAES256_CTR: -+ cipher = C.go_openssl_EVP_aes_256_ctr() -+ case cipherAES128_GCM: -+ cipher = C.go_openssl_EVP_aes_128_gcm() -+ case cipherAES192_GCM: -+ cipher = C.go_openssl_EVP_aes_192_gcm() -+ case cipherAES256_GCM: -+ cipher = C.go_openssl_EVP_aes_256_gcm() ++ 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() ++ } + } + return cipher +} + -+type aesKeySizeError int -+ -+func (k aesKeySizeError) Error() string { -+ return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) -+} -+ -+const aesBlockSize = 16 -+ -+type aesCipher struct { -+ key []byte -+ enc_ctx C.GO_EVP_CIPHER_CTX_PTR -+ dec_ctx C.GO_EVP_CIPHER_CTX_PTR -+ kind cipherKind -+} -+ -+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) ++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 +} + -+var _ extraModes = (*aesCipher)(nil) -+ -+func NewAESCipher(key []byte) (cipher.Block, error) { -+ c := &aesCipher{key: make([]byte, len(key))} -+ copy(c.key, key) -+ -+ switch len(c.key) * 8 { -+ case 128: -+ c.kind = cipherAES128_ECB -+ case 192: -+ c.kind = cipherAES192_ECB -+ case 256: -+ c.kind = cipherAES256_ECB -+ default: -+ return nil, errors.New("crypto/cipher: Invalid key size") ++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()) + } -+ -+ runtime.SetFinalizer(c, (*aesCipher).finalize) -+ ++ 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 *aesCipher) finalize() { ++func (c *evpCipher) finalize() { + if c.enc_ctx != nil { + C.go_openssl_EVP_CIPHER_CTX_free(c.enc_ctx) + } @@ -343,46 +563,47 @@ index 00000000000000..a17f473ce30c87 + } +} + -+func (c *aesCipher) BlockSize() int { return aesBlockSize } -+ -+func (c *aesCipher) Encrypt(dst, src []byte) { -+ if inexactOverlap(dst, src) { -+ panic("crypto/cipher: invalid buffer overlap") ++func (c *evpCipher) encrypt(dst, src []byte) { ++ if len(src) < c.blockSize { ++ panic("crypto/cipher: input not full block") + } -+ if len(src) < aesBlockSize { -+ panic("crypto/aes: input not full block") ++ if len(dst) < c.blockSize { ++ panic("crypto/cipher: output not full block") + } -+ if len(dst) < aesBlockSize { -+ panic("crypto/aes: 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]) { ++ panic("crypto/cipher: invalid buffer overlap") + } -+ + if c.enc_ctx == nil { + var err error -+ c.enc_ctx, err = newCipherCtx(c.kind, C.GO_AES_ENCRYPT, c.key, nil) ++ c.enc_ctx, err = newCipherCtx(c.kind, cipherModeECB, cipherOpEncrypt, c.key, nil) + if err != nil { + panic(err) + } + } + -+ if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), aesBlockSize) != 1 { ++ if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), C.int(c.blockSize)) != 1 { + panic("crypto/cipher: EncryptUpdate failed") + } + runtime.KeepAlive(c) +} + -+func (c *aesCipher) Decrypt(dst, src []byte) { -+ if inexactOverlap(dst, src) { -+ panic("crypto/cipher: invalid buffer overlap") ++func (c *evpCipher) decrypt(dst, src []byte) { ++ if len(src) < c.blockSize { ++ panic("crypto/cipher: input not full block") + } -+ if len(src) < aesBlockSize { -+ panic("crypto/aes: input not full block") ++ if len(dst) < c.blockSize { ++ panic("crypto/cipher: output not full block") + } -+ if len(dst) < aesBlockSize { -+ panic("crypto/aes: 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]) { ++ panic("crypto/cipher: invalid buffer overlap") + } + if c.dec_ctx == nil { + var err error -+ c.dec_ctx, err = newCipherCtx(c.kind, C.GO_AES_DECRYPT, c.key, nil) ++ c.dec_ctx, err = newCipherCtx(c.kind, cipherModeECB, cipherOpDecrypt, c.key, nil) + if err != nil { + panic(err) + } @@ -391,21 +612,26 @@ index 00000000000000..a17f473ce30c87 + } + } + -+ C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), aesBlockSize) ++ C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), C.int(c.blockSize)) + runtime.KeepAlive(c) +} + -+type aesCBC struct { -+ ctx C.GO_EVP_CIPHER_CTX_PTR ++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 *aesCBC) BlockSize() int { return aesBlockSize } ++func (x *cipherCBC) BlockSize() int { return x.blockSize } + -+func (x *aesCBC) CryptBlocks(dst, src []byte) { ++func (x *cipherCBC) CryptBlocks(dst, src []byte) { + if inexactOverlap(dst, src) { + panic("crypto/cipher: invalid buffer overlap") + } -+ if len(src)%aesBlockSize != 0 { ++ if len(src)%x.blockSize != 0 { + panic("crypto/cipher: input not full blocks") + } + if len(dst) < len(src) { @@ -419,81 +645,33 @@ index 00000000000000..a17f473ce30c87 + } +} + -+func (x *aesCBC) SetIV(iv []byte) { -+ if len(iv) != aesBlockSize { ++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), -1) != 1 { ++ 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 *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { -+ x := new(aesCBC) -+ -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_CBC -+ case 192: -+ cipher = cipherAES192_CBC -+ case 256: -+ cipher = cipherAES256_CBC -+ default: -+ panic("openssl: unsupported key length") -+ } -+ var err error -+ x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) -+ if err != nil { -+ panic(err) -+ } -+ -+ runtime.SetFinalizer(x, (*aesCBC).finalize) -+ -+ if C.go_openssl_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { -+ panic("cipher: unable to set padding") -+ } -+ return x -+} -+ -+func (c *aesCBC) finalize() { -+ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) -+} -+ -+func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { -+ x := new(aesCBC) -+ -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_CBC -+ case 192: -+ cipher = cipherAES192_CBC -+ case 256: -+ cipher = cipherAES256_CBC -+ default: -+ panic("openssl: unsupported key length") -+ } -+ -+ var err error -+ x.ctx, err = newCipherCtx(cipher, C.GO_AES_DECRYPT, c.key, iv) ++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) + } -+ -+ runtime.SetFinalizer(x, (*aesCBC).finalize) -+ ++ 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 aesCTR struct { ++type cipherCTR struct { + ctx C.GO_EVP_CIPHER_CTX_PTR +} + -+func (x *aesCTR) XORKeyStream(dst, src []byte) { ++func (x *cipherCTR) XORKeyStream(dst, src []byte) { + if inexactOverlap(dst, src) { + panic("crypto/cipher: invalid buffer overlap") + } @@ -509,39 +687,25 @@ index 00000000000000..a17f473ce30c87 + runtime.KeepAlive(x) +} + -+func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { -+ x := new(aesCTR) -+ -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_CTR -+ case 192: -+ cipher = cipherAES192_CTR -+ case 256: -+ cipher = cipherAES256_CTR -+ default: -+ panic("openssl: unsupported key length") -+ } -+ var err error -+ x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) ++func (c *evpCipher) newCTR(iv []byte) cipher.Stream { ++ ctx, err := newCipherCtx(c.kind, cipherModeCTR, cipherOpEncrypt, c.key, iv) + if err != nil { + panic(err) + } -+ -+ runtime.SetFinalizer(x, (*aesCTR).finalize) -+ ++ x := &cipherCTR{ctx: ctx} ++ runtime.SetFinalizer(x, (*cipherCTR).finalize) + return x +} + -+func (c *aesCTR) finalize() { ++func (c *cipherCTR) finalize() { + C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) +} + -+type aesGCM struct { ++type cipherGCM struct { + ctx C.GO_EVP_CIPHER_CTX_PTR + tls bool + minNextNonce uint64 ++ blockSize int +} + +const ( @@ -551,19 +715,25 @@ index 00000000000000..a17f473ce30c87 + gcmTlsFixedNonceSize = 4 +) + -+type aesNonceSizeError int ++type noGCM struct { ++ *evpCipher ++} + -+func (n aesNonceSizeError) Error() string { -+ return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n)) ++func (g *noGCM) BlockSize() int { ++ return g.blockSize +} + -+type noGCM struct { -+ cipher.Block ++func (g *noGCM) Encrypt(dst, src []byte) { ++ g.encrypt(dst, src) +} + -+func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { ++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/aes: GCM tag and nonce sizes can't be non-standard at the same time") ++ 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 { @@ -575,54 +745,33 @@ index 00000000000000..a17f473ce30c87 + return c.newGCM(false) +} + -+// NewGCMTLS returns a GCM cipher specific to TLS -+// and should not be used for non-TLS purposes. -+func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { -+ return c.(*aesCipher).NewGCMTLS() -+} -+ -+func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) { -+ return c.newGCM(true) -+} -+ -+func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) { -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_GCM -+ case 192: -+ cipher = cipherAES192_GCM -+ case 256: -+ cipher = cipherAES256_GCM -+ default: -+ panic("openssl: unsupported key length") -+ } -+ ctx, err := newCipherCtx(cipher, -1, c.key, nil) ++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 := &aesGCM{ctx: ctx, tls: tls} -+ runtime.SetFinalizer(g, (*aesGCM).finalize) ++ g := &cipherGCM{ctx: ctx, tls: tls, blockSize: c.blockSize} ++ runtime.SetFinalizer(g, (*cipherGCM).finalize) + return g, nil +} + -+func (g *aesGCM) finalize() { ++func (g *cipherGCM) finalize() { + C.go_openssl_EVP_CIPHER_CTX_free(g.ctx) +} + -+func (g *aesGCM) NonceSize() int { ++func (g *cipherGCM) NonceSize() int { + return gcmStandardNonceSize +} + -+func (g *aesGCM) Overhead() int { ++func (g *cipherGCM) Overhead() int { + return gcmTagSize +} + -+func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { ++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)*aesBlockSize || len(plaintext)+gcmTagSize < len(plaintext) { ++ 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) { @@ -675,14 +824,14 @@ index 00000000000000..a17f473ce30c87 + +var errOpen = errors.New("cipher: message authentication failed") + -+func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { ++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)*aesBlockSize+gcmTagSize { ++ 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. @@ -725,16 +874,16 @@ index 00000000000000..a17f473ce30c87 + return +} + -+func newCipherCtx(kind cipherKind, mode C.int, key, iv []byte) (C.GO_EVP_CIPHER_CTX_PTR, error) { -+ cipher := newCipher(kind) ++func newCipherCtx(kind cipherKind, mode cipherMode, encrypt cipherOp, key, iv []byte) (C.GO_EVP_CIPHER_CTX_PTR, error) { ++ cipher := loadCipher(kind, mode) + if cipher == nil { -+ panic("openssl: unsupported cipher: " + strconv.Itoa(int(kind))) ++ 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") + } -+ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), mode) != 1 { ++ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), C.int(encrypt)) != 1 { + C.go_openssl_EVP_CIPHER_CTX_free(ctx) + return nil, fail("unable to initialize EVP cipher ctx") + } @@ -755,73 +904,126 @@ index 00000000000000..a17f473ce30c87 + } + return anyOverlap(x, y) +} -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 +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 00000000000000..a81cbdbef93148 +index 00000000000000..5f5e3748899a78 --- /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. ++++ b/src/vendor/github.com/golang-fips/openssl/v2/des.go +@@ -0,0 +1,107 @@ ++//go:build !cmd_go_bootstrap + -+// This is a mirror of -+// https://github.com/golang/go/blob/36b87f273cc43e21685179dc1664ebb5493d26ae/src/crypto/internal/boring/bbig/big.go. -+ -+package bbig ++package openssl + ++// #include "goopenssl.h" ++import "C" +import ( -+ "math/big" -+ "unsafe" -+ -+ "github.com/golang-fips/openssl/v2" ++ "crypto/cipher" ++ "errors" +) + -+func Enc(b *big.Int) openssl.BigInt { -+ if b == nil { -+ return nil ++// 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. ++ // False for stock OpenSSL 3 unless the legacy provider is available. ++ return loadCipher(cipherDES, cipherModeECB) != nil ++} ++ ++// 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 ++} ++ ++func NewDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 8 { ++ return nil, errors.New("crypto/des: invalid key size") + } -+ x := b.Bits() -+ if len(x) == 0 { -+ return openssl.BigInt{} ++ c, err := newEVPCipher(key, cipherDES) ++ if err != nil { ++ return nil, err + } -+ return unsafe.Slice((*uint)(&x[0]), len(x)) ++ // Should always be true for stock OpenSSL. ++ if loadCipher(cipherDES, cipherModeCBC) == nil { ++ return &desCipherWithoutCBC{c}, nil ++ } ++ return &desCipher{c}, nil +} + -+func Dec(b openssl.BigInt) *big.Int { -+ if b == nil { -+ return nil ++func NewTripleDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 24 { ++ return nil, errors.New("crypto/des: invalid key size") + } -+ if len(b) == 0 { -+ return new(big.Int) ++ c, err := newEVPCipher(key, cipherDES3) ++ if err != nil { ++ return nil, err + } -+ x := unsafe.Slice((*big.Word)(&b[0]), len(b)) -+ return new(big.Int).SetBits(x) ++ // Should always be true for stock OpenSSL. ++ if loadCipher(cipherDES, cipherModeCBC) != nil { ++ return &desCipherWithoutCBC{c}, nil ++ } ++ return &desCipher{c}, nil +} -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 00000000000000..6461f241f863fc ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/big.go -@@ -0,0 +1,11 @@ -+package openssl + -+// 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. ++type desExtraModes interface { ++ NewCBCEncrypter(iv []byte) cipher.BlockMode ++ NewCBCDecrypter(iv []byte) cipher.BlockMode ++} + -+// 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 ++var _ desExtraModes = (*desCipher)(nil) ++ ++type desCipher struct { ++ *evpCipher ++} ++ ++func (c *desCipher) BlockSize() int { ++ return c.blockSize ++} ++ ++func (c *desCipher) Encrypt(dst, src []byte) { ++ c.encrypt(dst, src) ++} ++ ++func (c *desCipher) Decrypt(dst, src []byte) { ++ c.decrypt(dst, src) ++} ++ ++func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpEncrypt) ++} ++ ++func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpDecrypt) ++} ++ ++type desCipherWithoutCBC struct { ++ *evpCipher ++} ++ ++func (c *desCipherWithoutCBC) BlockSize() int { ++ return c.blockSize ++} ++ ++func (c *desCipherWithoutCBC) Encrypt(dst, src []byte) { ++ c.encrypt(dst, src) ++} ++ ++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 00000000000000..1c477112a783f8 +index 00000000000000..eac2f8bbee303c --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ec.go @@ -0,0 +1,59 @@ -+//go:build linux ++//go:build !cmd_go_bootstrap + +package openssl + @@ -882,11 +1084,11 @@ index 00000000000000..1c477112a783f8 +} 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 00000000000000..7e81ba63deab39 +index 00000000000000..62e23333cedae2 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ecdh.go @@ -0,0 +1,323 @@ -+//go:build linux ++//go:build !cmd_go_bootstrap + +package openssl + @@ -989,7 +1191,7 @@ index 00000000000000..7e81ba63deab39 + return nil, newOpenSSLError("EVP_PKEY_get_octet_string_param") + } + bytes = C.GoBytes(unsafe.Pointer(cbytes), C.int(n)) -+ C.free(unsafe.Pointer(cbytes)) ++ cryptoFree(unsafe.Pointer(cbytes)) + default: + panic(errUnsupportedVersion()) + } @@ -1202,8 +1404,8 @@ index 00000000000000..7e81ba63deab39 + // generating a private ECDH key. + bits := C.go_openssl_EVP_PKEY_get_bits(pkey) + bytes := make([]byte, (bits+7)/8) -+ if C.go_openssl_BN_bn2binpad(priv, base(bytes), C.int(len(bytes))) == 0 { -+ return nil, nil, newOpenSSLError("BN_bn2binpad") ++ if err := bnToBinPad(priv, bytes); err != nil { ++ return nil, nil, err + } + k = &PrivateKeyECDH{pkey, curve, true} + runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) @@ -1211,11 +1413,11 @@ index 00000000000000..7e81ba63deab39 +} 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 00000000000000..5ff2cbafc7aed6 +index 00000000000000..46b16abf483e65 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ecdsa.go @@ -0,0 +1,217 @@ -+//go:build linux ++//go:build !cmd_go_bootstrap + +package openssl + @@ -1434,11 +1636,11 @@ index 00000000000000..5ff2cbafc7aed6 +} 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 00000000000000..cdb7b2e1fd5030 +index 00000000000000..c7f53e3e553a3d --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/evp.go -@@ -0,0 +1,460 @@ -+//go:build linux +@@ -0,0 +1,473 @@ ++//go:build !cmd_go_bootstrap + +package openssl + @@ -1500,15 +1702,21 @@ index 00000000000000..cdb7b2e1fd5030 + } + cacheMD.Store(ch, md) + }() -+ switch ch { -+ case crypto.MD5: -+ return C.go_openssl_EVP_md5() -+ case crypto.MD5SHA1: ++ // 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() + } ++ } ++ switch ch { ++ case crypto.MD4: ++ return C.go_openssl_EVP_md4() ++ case crypto.MD5: ++ return C.go_openssl_EVP_md5() + case crypto.SHA1: + return C.go_openssl_EVP_sha1() + case crypto.SHA224: @@ -1520,25 +1728,21 @@ index 00000000000000..cdb7b2e1fd5030 + case crypto.SHA512: + return C.go_openssl_EVP_sha512() + case crypto.SHA3_224: -+ if !SupportsSHA3() { -+ return nil ++ if version1_1_1_or_above() { ++ return C.go_openssl_EVP_sha3_224() + } -+ return C.go_openssl_EVP_sha3_224() + case crypto.SHA3_256: -+ if !SupportsSHA3() { -+ return nil ++ if version1_1_1_or_above() { ++ return C.go_openssl_EVP_sha3_256() + } -+ return C.go_openssl_EVP_sha3_256() + case crypto.SHA3_384: -+ if !SupportsSHA3() { -+ return nil ++ if version1_1_1_or_above() { ++ return C.go_openssl_EVP_sha3_384() + } -+ return C.go_openssl_EVP_sha3_384() + case crypto.SHA3_512: -+ if !SupportsSHA3() { -+ return nil ++ if version1_1_1_or_above() { ++ return C.go_openssl_EVP_sha3_512() + } -+ return C.go_openssl_EVP_sha3_512() + } + return nil +} @@ -1641,23 +1845,34 @@ index 00000000000000..cdb7b2e1fd5030 + } + } + // ctx takes ownership of label, so malloc a copy for OpenSSL to free. -+ // OpenSSL 1.1.1 and higher does not take ownership of the label if the length is zero, ++ // 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 { -+ // Go guarantees C.malloc never returns nil. -+ clabel = (*C.uchar)(C.malloc(C.size_t(len(label)))) ++ clabel = (*C.uchar)(cryptoMalloc(len(label))) + copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) + } -+ var ret C.int ++ 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))) ++ // Docs say EVP_PKEY_CTX_set0_rsa_oaep_label accepts a null label, ++ // but it does not: https://github.com/openssl/openssl/issues/21288 ++ if len(label) == 0 { ++ // cryptoMalloc can't create a zero-length array: use size 1. ++ clabel = (*C.uchar)(cryptoMalloc(1)) ++ } ++ 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)) ++ 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 ret != 1 { -+ C.free(unsafe.Pointer(clabel)) -+ return nil, 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) @@ -1900,15 +2115,20 @@ index 00000000000000..cdb7b2e1fd5030 +} 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 00000000000000..b72b5952498803 +index 00000000000000..ec4adc153998f5 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c -@@ -0,0 +1,213 @@ -+//go:build linux +@@ -0,0 +1,218 @@ ++//go:build unix || windows + +#include "goopenssl.h" + -+#include // dlsym ++#ifdef _WIN32 ++# include ++# define dlsym (void*)GetProcAddress ++#else ++# include // dlsym ++#endif +#include // fprintf + +// Approach taken from .Net System.Security.Cryptography.Native @@ -2119,10 +2339,10 @@ index 00000000000000..b72b5952498803 +} 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 00000000000000..c9f4c2a40a7a2f +index 00000000000000..d0ffe6cbe51626 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h -@@ -0,0 +1,170 @@ +@@ -0,0 +1,183 @@ +// This header file describes the OpenSSL ABI as built for use in Go. + +#include // size_t @@ -2191,14 +2411,14 @@ index 00000000000000..c9f4c2a40a7a2f +#undef DEFINEFUNC_RENAMED_1_1 +#undef DEFINEFUNC_RENAMED_3_0 + -+// go_sha_sum copies ctx into ctx2 and calls EVP_DigestFinal using ctx2. ++// 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 -+go_sha_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out) ++go_hash_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out) +{ + if (go_openssl_EVP_MD_CTX_copy(ctx2, ctx) != 1) + return 0; @@ -2241,10 +2461,10 @@ index 00000000000000..c9f4c2a40a7a2f + const unsigned char *in, int in_len, + const unsigned char *aad, int aad_len) +{ -+ if (in_len == 0) in = ""; -+ if (aad_len == 0) aad = ""; ++ if (in_len == 0) in = (const unsigned char *)""; ++ if (aad_len == 0) aad = (const unsigned char *)""; + -+ if (go_openssl_EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, GO_AES_ENCRYPT) != 1) ++ if (go_openssl_EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) + return 0; + + int discard_len, out_len; @@ -2269,10 +2489,10 @@ index 00000000000000..c9f4c2a40a7a2f + const unsigned char *aad, int aad_len, + const unsigned char *tag) +{ -+ if (in_len == 0) in = ""; -+ if (aad_len == 0) aad = ""; ++ if (in_len == 0) in = (const unsigned char *)""; ++ if (aad_len == 0) aad = (const unsigned char *)""; + -+ if (go_openssl_EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, GO_AES_DECRYPT) != 1) ++ if (go_openssl_EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) + return 0; + + int discard_len, out_len; @@ -2293,2058 +2513,2432 @@ index 00000000000000..c9f4c2a40a7a2f + + return 1; +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go ++ ++// Hand-roll custom wrappers for CRYPTO_malloc and CRYPTO_free which cast the ++// function pointers to the correct signatures for OpenSSL 1.0.2. ++ ++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); ++} ++ ++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 00000000000000..3d5e84573db754 +index 00000000000000..646b4ce295896c --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go -@@ -0,0 +1,158 @@ -+//go:build linux ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hash.go +@@ -0,0 +1,793 @@ ++//go:build !cmd_go_bootstrap + +package openssl + +// #include "goopenssl.h" +import "C" +import ( ++ "crypto" + "errors" + "hash" -+ "io" + "runtime" ++ "strconv" + "unsafe" +) + -+func SupportsHKDF() bool { -+ return vMajor > 1 || -+ (vMajor >= 1 && vMinor > 1) || -+ (vMajor >= 1 && vMinor >= 1 && vPatch >= 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. ++ ++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 +} + -+func newHKDF(h func() hash.Hash, mode C.int) (*hkdf, error) { -+ if !SupportsHKDF() { -+ return nil, errUnsupportedVersion() ++func MD4(p []byte) (sum [16]byte) { ++ if !hashOneShot(crypto.MD4, p, sum[:]) { ++ panic("openssl: MD4 failed") + } ++ return ++} + -+ ch := h() -+ md := hashToMD(ch) -+ if md == nil { -+ return nil, errors.New("unsupported hash function") ++func MD5(p []byte) (sum [16]byte) { ++ if !hashOneShot(crypto.MD5, p, sum[:]) { ++ panic("openssl: MD5 failed") + } ++ return ++} + -+ 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") ++func SHA1(p []byte) (sum [20]byte) { ++ if !hashOneShot(crypto.SHA1, p, sum[:]) { ++ panic("openssl: SHA1 failed") + } -+ defer func() { -+ C.go_openssl_EVP_PKEY_CTX_free(ctx) -+ }() ++ return ++} + -+ if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive_init") -+ } -+ 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") -+ } ++func SHA224(p []byte) (sum [28]byte) { ++ if !hashOneShot(crypto.SHA224, p, sum[:]) { ++ panic("openssl: SHA224 failed") + } ++ return ++} + -+ c := &hkdf{ctx: ctx} -+ ctx = nil ++func SHA256(p []byte) (sum [32]byte) { ++ if !hashOneShot(crypto.SHA256, p, sum[:]) { ++ panic("openssl: SHA256 failed") ++ } ++ return ++} + -+ runtime.SetFinalizer(c, (*hkdf).finalize) ++func SHA384(p []byte) (sum [48]byte) { ++ if !hashOneShot(crypto.SHA384, p, sum[:]) { ++ panic("openssl: SHA384 failed") ++ } ++ return ++} + -+ return c, nil ++func SHA512(p []byte) (sum [64]byte) { ++ if !hashOneShot(crypto.SHA512, p, sum[:]) { ++ panic("openssl: SHA512 failed") ++ } ++ return +} + -+type hkdf struct { -+ ctx C.GO_EVP_PKEY_CTX_PTR ++// SupportsHash returns true if a hash.Hash implementation is supported for h. ++func SupportsHash(h crypto.Hash) bool { ++ return cryptoHashToMD(h) != nil +} + -+func (c *hkdf) finalize() { -+ if c.ctx != nil { -+ C.go_openssl_EVP_PKEY_CTX_free(c.ctx) ++func SHA3_224(p []byte) (sum [28]byte) { ++ if !hashOneShot(crypto.SHA3_224, p, sum[:]) { ++ panic("openssl: SHA3_224 failed") + } ++ return +} + -+func (c *hkdf) Read(p []byte) (int, error) { -+ defer runtime.KeepAlive(c) ++func SHA3_256(p []byte) (sum [32]byte) { ++ if !hashOneShot(crypto.SHA3_256, p, sum[:]) { ++ panic("openssl: SHA3_256 failed") ++ } ++ return ++} + -+ outLen := C.size_t(len(p)) -+ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(p), &outLen) != 1 { -+ return 0, newOpenSSLError("EVP_PKEY_derive") ++func SHA3_384(p []byte) (sum [48]byte) { ++ if !hashOneShot(crypto.SHA3_384, p, sum[:]) { ++ panic("openssl: SHA3_384 failed") + } -+ return int(outLen), nil ++ return +} + -+func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { -+ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_MODE_EXTRACT_ONLY) -+ if err != nil { -+ return nil, err ++func SHA3_512(p []byte) (sum [64]byte) { ++ if !hashOneShot(crypto.SHA3_512, p, sum[:]) { ++ panic("openssl: SHA3_512 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") -+ } ++ return ++} ++ ++// 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 ++} ++ ++func newEvpHash(ch crypto.Hash, size, blockSize int) *evpHash { ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) + } -+ var outLen C.size_t -+ if C.go_openssl_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive_init") ++ 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")) + } -+ out := make([]byte, outLen) -+ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(out), &outLen) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive") ++ ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ h := &evpHash{ ++ ctx: ctx, ++ ctx2: ctx2, ++ size: size, ++ blockSize: blockSize, + } -+ return out[:outLen], nil ++ runtime.SetFinalizer(h, (*evpHash).finalize) ++ return h +} + -+func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) { -+ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY) -+ if err != nil { -+ return nil, err -+ } -+ 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") -+ } ++func (h *evpHash) finalize() { ++ C.go_openssl_EVP_MD_CTX_free(h.ctx) ++ C.go_openssl_EVP_MD_CTX_free(h.ctx2) ++} ++ ++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")) + } -+ return c, nil ++ runtime.KeepAlive(h) +} -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 00000000000000..8b728a704418ee ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go -@@ -0,0 +1,238 @@ -+//go:build linux + -+package openssl ++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 ++} + -+// #include "goopenssl.h" -+import "C" -+import ( -+ "hash" -+ "runtime" -+ "sync" -+ "unsafe" -+) ++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 ++} + -+var paramDigest = C.CString("digest") ++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 ++} + -+var ( -+ fetchHMACOnce sync.Once -+ evpHMAC C.GO_EVP_MAC_PTR -+) ++func (h *evpHash) Size() int { ++ return h.size ++} + -+// 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 -+ } ++func (h *evpHash) BlockSize() int { ++ return h.blockSize ++} + -+ 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) ++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) ++} + ++// 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: -+ return newHMAC1(key, ch, md) ++ // 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: -+ return newHMAC3(key, ch, md) ++ // 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()) + } +} + -+// hmacCtx3 is used for OpenSSL 1. -+type hmacCtx1 struct { -+ ctx C.GO_HMAC_CTX_PTR ++// 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), ++ } +} + -+// 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. ++type md4Hash struct { ++ *evpHash ++ out [16]byte +} + -+type opensslHMAC struct { -+ ctx1 hmacCtx1 -+ ctx3 hmacCtx3 -+ size int -+ blockSize int -+ sum []byte ++func (h *md4Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+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")) ++// NewMD5 returns a new MD5 hash. ++func NewMD5() hash.Hash { ++ return &md5Hash{ ++ evpHash: newEvpHash(crypto.MD5, 16, 64), + } -+ hmac := &opensslHMAC{ -+ size: h.Size(), -+ blockSize: h.BlockSize(), -+ ctx1: hmacCtx1{ctx}, ++} ++ ++// 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 ++} ++ ++type md5Hash struct { ++ *evpHash ++ out [16]byte ++} ++ ++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 ++) ++ ++func (h *md5Hash) MarshalBinary() ([]byte, error) { ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/md5: can't retrieve hash state") + } -+ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) -+ return hmac ++ 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 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") ++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") + } -+ ctx := C.go_openssl_EVP_MAC_CTX_new(evpHMAC) -+ if ctx == nil { -+ panic("openssl: EVP_MAC_CTX_new failed") ++ if len(b) != md5MarshaledSize { ++ return errors.New("crypto/md5: invalid hash state size") + } -+ 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")) ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/md5: can't retrieve hash state") + } -+ 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 ++ 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 +} + -+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(errUnsupportedVersion()) ++// NewSHA1 returns a new SHA1 hash. ++func NewSHA1() hash.Hash { ++ return &sha1Hash{ ++ evpHash: newEvpHash(crypto.SHA1, 20, 64), + } -+ -+ runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. -+ h.sum = nil +} + -+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()) -+ } ++type sha1Hash struct { ++ *evpHash ++ out [20]byte +} + -+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 (h *sha1Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+func (h *opensslHMAC) Size() int { -+ return h.size ++// 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 +} + -+func (h *opensslHMAC) BlockSize() int { -+ return h.blockSize ++const ( ++ sha1Magic = "sha\x01" ++ sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 ++) ++ ++func (h *sha1Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha1: can't retrieve hash state") ++ } ++ b := make([]byte, 0, sha1MarshaledSize) ++ b = append(b, sha1Magic...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil +} + -+func (h *opensslHMAC) Sum(in []byte) []byte { -+ if h.sum == nil { -+ size := h.Size() -+ h.sum = make([]byte, size) ++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") + } -+ // 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()) ++ if len(b) != sha1MarshaledSize { ++ return errors.New("crypto/sha1: invalid hash state size") + } -+ return append(in, h.sum...) ++ 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 +} + -+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 ctx ++// NewSHA224 returns a new SHA224 hash. ++func NewSHA224() hash.Hash { ++ return &sha224Hash{ ++ evpHash: newEvpHash(crypto.SHA224, 224/8, 64), + } -+ return C.go_openssl_HMAC_CTX_new() +} + -+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 ++type sha224Hash struct { ++ *evpHash ++ out [224 / 8]byte ++} ++ ++func (h *sha224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// NewSHA256 returns a new SHA256 hash. ++func NewSHA256() hash.Hash { ++ return &sha256Hash{ ++ evpHash: newEvpHash(crypto.SHA256, 256/8, 64), + } -+ 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 00000000000000..c6c323b6f9c826 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/init.go -@@ -0,0 +1,72 @@ -+//go:build linux + -+package openssl ++type sha256Hash struct { ++ *evpHash ++ out [256 / 8]byte ++} + -+// #include "goopenssl.h" -+// #include -+import "C" -+import ( -+ "errors" -+ "unsafe" ++func (h *sha256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++const ( ++ magic224 = "sha\x02" ++ magic256 = "sha\x03" ++ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 +) + -+// 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 version. -+func opensslInit(version string) (major, minor, patch int, err error) { -+ // Load the OpenSSL shared library using dlopen. -+ handle := dlopen(version) -+ if handle == nil { -+ errstr := C.GoString(C.dlerror()) -+ return 0, 0, 0, errors.New("openssl: can't load libcrypto.so." + version + ": " + errstr) -+ } ++// 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 ++} + -+ // 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. -+ major = int(C.go_openssl_version_major(handle)) -+ minor = int(C.go_openssl_version_minor(handle)) -+ patch = int(C.go_openssl_version_patch(handle)) -+ if major == -1 || minor == -1 || patch == -1 { -+ return 0, 0, 0, errors.New("openssl: can't retrieve OpenSSL version") -+ } -+ 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() ++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 ++} + -+ // Load the OpenSSL functions. -+ // See shims.go for the complete list of supported functions. -+ C.go_openssl_load_functions(handle, C.int(major), C.int(minor), C.int(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") -+ } ++func (h *sha256Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") + } -+ return major, minor, patch, nil ++ 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 dlopen(version string) unsafe.Pointer { -+ cv := C.CString("libcrypto.so." + version) -+ defer C.free(unsafe.Pointer(cv)) -+ return C.dlopen(cv, C.RTLD_LAZY|C.RTLD_LOCAL) ++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 +} -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 00000000000000..7c964f6e05e096 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go -@@ -0,0 +1,273 @@ -+//go:build linux -+ -+// Package openssl provides access to OpenSSL cryptographic functions. -+package openssl -+ -+// #include "goopenssl.h" -+// #include -+// #cgo LDFLAGS: -ldl -+import "C" -+import ( -+ "encoding/binary" -+ "errors" -+ "math/bits" -+ "strconv" -+ "strings" -+ "sync" -+ "unsafe" -+) + -+var ( -+ // vMajor and vMinor hold the major/minor OpenSSL version. -+ // It is only populated if Init has been called. -+ vMajor, vMinor, vPatch int -+) -+ -+var ( -+ initOnce sync.Once -+ initErr error -+) -+ -+var nativeEndian binary.ByteOrder ++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 ++} + -+// 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 ++// NewSHA384 returns a new SHA384 hash. ++func NewSHA384() hash.Hash { ++ return &sha384Hash{ ++ evpHash: newEvpHash(crypto.SHA384, 384/8, 128), + } -+ defer C.dlclose(handle) -+ fips = C.go_openssl_fips_enabled(handle) == 1 -+ return true, fips +} + -+// Init loads and initializes OpenSSL. -+// 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. -+// -+// version will be appended to the OpenSSL shared library name as a version suffix -+// when calling dlopen. For example, `version=1.1.1k-fips` makes Init look for -+// the shared library libcrypto.so.1.1.1k-fips. -+func Init(version string) error { -+ initOnce.Do(func() { -+ buf := [2]byte{} -+ *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD) ++type sha384Hash struct { ++ *evpHash ++ out [384 / 8]byte ++} + -+ 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(version) -+ }) -+ return initErr ++func (h *sha384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+func errUnsupportedVersion() error { -+ return errors.New("openssl: OpenSSL version: " + strconv.Itoa(vMajor) + "." + strconv.Itoa(vMinor) + "." + strconv.Itoa(vPatch)) ++// NewSHA512 returns a new SHA512 hash. ++func NewSHA512() hash.Hash { ++ return &sha512Hash{ ++ evpHash: newEvpHash(crypto.SHA512, 512/8, 128), ++ } +} + -+type fail string ++type sha512Hash struct { ++ *evpHash ++ out [512 / 8]byte ++} + -+func (e fail) Error() string { return "openssl: " + string(e) + " failed" } ++func (h *sha512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+// VersionText returns the version text of the OpenSSL currently loaded. -+func VersionText() string { -+ return C.GoString(C.go_openssl_OpenSSL_version(0)) ++// 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 +} + -+var ( -+ providerNameFips = C.CString("fips") -+ providerNameDefault = C.CString("default") ++const ( ++ magic384 = "sha\x04" ++ magic512_224 = "sha\x05" ++ magic512_256 = "sha\x06" ++ magic512 = "sha\x07" ++ marshaledSize512 = len(magic512) + 8*8 + 128 + 8 +) + -+// 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()) ++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 +} + -+// 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) -+ } -+ 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()) ++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 +} + -+// noescape hides a pointer from escape analysis. noescape is -+// the identity function but escape analysis doesn't think the -+// output depends on the input. noescape is inlined and currently -+// compiles down to zero instructions. -+// USE CAREFULLY! -+// -+//go:nosplit -+func noescape(p unsafe.Pointer) unsafe.Pointer { -+ x := uintptr(p) -+ return unsafe.Pointer(x ^ 0) ++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 +} + -+var zero byte -+ -+// addr converts p to its base addr, including a noescape along the way. -+// If p is nil, addr returns a non-nil pointer, so that the result can always -+// be dereferenced. -+// -+//go:nosplit -+func addr(p []byte) *byte { -+ if len(p) == 0 { -+ return &zero ++func (h *sha512Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") + } -+ return (*byte)(noescape(unsafe.Pointer(&p[0]))) ++ 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 +} + -+// 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 ++// NewSHA3_224 returns a new SHA3-224 hash. ++func NewSHA3_224() hash.Hash { ++ return &sha3_224Hash{ ++ evpHash: newEvpHash(crypto.SHA3_224, 224/8, 64), + } -+ return (*C.uchar)(unsafe.Pointer(&b[0])) +} + -+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()) ++type sha3_224Hash struct { ++ *evpHash ++ out [224 / 8]byte +} + -+const wordBytes = bits.UintSize / 8 ++func (h *sha3_224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+// 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 ++// NewSHA3_256 returns a new SHA3-256 hash. ++func NewSHA3_256() hash.Hash { ++ return &sha3_256Hash{ ++ evpHash: newEvpHash(crypto.SHA3_256, 256/8, 64), + } +} + -+func wbase(b BigInt) *C.uchar { -+ if len(b) == 0 { -+ return nil -+ } -+ return (*C.uchar)(unsafe.Pointer(&b[0])) ++type sha3_256Hash struct { ++ *evpHash ++ out [256 / 8]byte +} + -+func bigToBN(x BigInt) C.GO_BIGNUM_PTR { -+ if len(x) == 0 { -+ return nil -+ } -+ 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) ++func (h *sha3_256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { -+ if bn == nil { -+ return nil -+ } -+ // 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() ++// NewSHA3_384 returns a new SHA3-384 hash. ++func NewSHA3_384() hash.Hash { ++ return &sha3_384Hash{ ++ evpHash: newEvpHash(crypto.SHA3_384, 384/8, 128), + } -+ return x +} + -+func CheckLeaks() { -+ C.go_openssl_do_leak_check() ++type sha3_384Hash struct { ++ *evpHash ++ out [384 / 8]byte +} -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 00000000000000..6d055cd10a38c9 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c -@@ -0,0 +1,128 @@ -+//go:build linux + -+// 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. ++func (h *sha3_384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+/* -+ * 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 -+ */ ++// NewSHA3_512 returns a new SHA3-512 hash. ++func NewSHA3_512() hash.Hash { ++ return &sha3_512Hash{ ++ evpHash: newEvpHash(crypto.SHA3_512, 512/8, 128), ++ } ++} + -+#include "goopenssl.h" ++type sha3_512Hash struct { ++ *evpHash ++ out [512 / 8]byte ++} + -+#define NID_md5_sha1 114 ++func (h *sha3_512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+#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; -+ -+struct md5_sha1_ctx { -+ MD5_CTX md5; -+ SHA_CTX sha1; -+}; -+ -+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 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); ++// 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), ++ ) +} + -+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); ++// 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)) +} + -+// Change: Removed: -+// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) -+ -+static const EVP_MD md5_sha1_md = { -+ NID_md5_sha1, -+ NID_md5_sha1, -+ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, -+ 0, -+ 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 -+}; -+ -+// 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; ++// 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 +} -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 00000000000000..3c8ac7ba1fa172 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/rand.go -@@ -0,0 +1,20 @@ -+//go:build linux -+ -+package openssl -+ -+// #include "goopenssl.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.go_openssl_RAND_bytes((*C.uchar)(unsafe.Pointer(&b[0])), C.int(len(b))) == 0 { -+ return 0, newOpenSSLError("RAND_bytes") -+ } -+ return len(b), nil ++// 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 +} -+ -+const RandReader = randReader(0) -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rsa.go b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go +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 00000000000000..4df9e4047e82a0 +index 00000000000000..0d33e34a671b08 --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go -@@ -0,0 +1,419 @@ -+//go:build linux ++++ 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 ( -+ "crypto" -+ "crypto/subtle" + "errors" + "hash" ++ "io" + "runtime" + "unsafe" +) + -+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") -+) ++func SupportsHKDF() bool { ++ return version1_1_1_or_above() ++} + -+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 ++func newHKDF(h func() hash.Hash, mode C.int) (*hkdf, error) { ++ if !SupportsHKDF() { ++ return nil, errUnsupportedVersion() + } -+ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_RSA, bits, "") -+ if err != nil { -+ return bad(err) ++ ++ ch := h() ++ md := hashToMD(ch) ++ if md == nil { ++ return nil, errors.New("unsupported hash function") ++ } ++ ++ 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") ++ } ++ defer func() { ++ 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") + } -+ 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")) -+ } -+ 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) -+ } -+ 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")) ++ if C.go_openssl_EVP_PKEY_CTX_set_hkdf_mode(ctx, mode) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") + } -+ 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 C.go_openssl_EVP_PKEY_CTX_set_hkdf_md(ctx, md) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") + } -+ 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) ++ 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") + } -+ default: -+ panic(errUnsupportedVersion()) -+ } -+ return ++ 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 PublicKeyRSA struct { -+ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. -+ _pkey C.GO_EVP_PKEY_PTR ++type hkdf struct { ++ ctx C.GO_EVP_PKEY_CTX_PTR ++ ++ hashLen int ++ buf []byte +} + -+func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { -+ var pkey C.GO_EVP_PKEY_PTR ++func (c *hkdf) finalize() { ++ if c.ctx != nil { ++ C.go_openssl_EVP_PKEY_CTX_free(c.ctx) ++ } ++} ++ ++func (c *hkdf) Read(p []byte) (int, error) { ++ defer runtime.KeepAlive(c) ++ ++ // 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") ++ } ++ 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_KDF_HKDF_MODE_EXTRACT_ONLY) ++ if err != nil { ++ return nil, err ++ } + switch vMajor { -+ case 1: -+ key := C.go_openssl_RSA_new() -+ if key == nil { -+ return nil, newOpenSSLError("RSA_new failed") ++ 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 !rsaSetKey(key, N, E, nil) { -+ return nil, fail("RSA_set0_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") + } -+ pkey = C.go_openssl_EVP_PKEY_new() -+ if pkey == nil { -+ C.go_openssl_RSA_free(key) -+ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ 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_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") ++ 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.go_openssl_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") ++ } ++ out := make([]byte, outLen) ++ 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_KDF_HKDF_MODE_EXPAND_ONLY) ++ if err != nil { ++ return nil, err ++ } ++ switch vMajor { + case 3: -+ var err error -+ if pkey, err = newRSAKey3(false, N, E, nil, nil, nil, nil, nil, nil); err != nil { -+ return nil, err ++ 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") + } -+ default: -+ panic(errUnsupportedVersion()) + } -+ k := &PublicKeyRSA{_pkey: pkey} -+ runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) -+ return k, nil ++ return c, nil +} +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 00000000000000..ef8116ce666bd6 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go +@@ -0,0 +1,238 @@ ++//go:build !cmd_go_bootstrap + -+func (k *PublicKeyRSA) finalize() { -+ C.go_openssl_EVP_PKEY_free(k._pkey) -+} ++package openssl + -+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) -+} ++// #include "goopenssl.h" ++import "C" ++import ( ++ "hash" ++ "runtime" ++ "sync" ++ "unsafe" ++) + -+type PrivateKeyRSA struct { -+ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. -+ _pkey C.GO_EVP_PKEY_PTR -+} ++var paramDigest = C.CString("digest") ++ ++var ( ++ fetchHMACOnce sync.Once ++ evpHMAC C.GO_EVP_MAC_PTR ++) ++ ++// 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 ++ } ++ ++ 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) ++ } + -+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") -+ } ++ return newHMAC1(key, ch, md) + case 3: -+ var err error -+ if pkey, err = newRSAKey3(true, N, E, D, P, Q, Dp, Dq, Qinv); err != nil { -+ return nil, err -+ } ++ return newHMAC3(key, ch, md) + default: + panic(errUnsupportedVersion()) + } -+ k := &PrivateKeyRSA{_pkey: pkey} -+ runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) -+ return k, nil -+} -+ -+func (k *PrivateKeyRSA) finalize() { -+ C.go_openssl_EVP_PKEY_free(k._pkey) -+} -+ -+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) +} + -+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) ++// hmacCtx3 is used for OpenSSL 1. ++type hmacCtx1 struct { ++ ctx C.GO_HMAC_CTX_PTR +} + -+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) ++// 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. +} + -+func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { -+ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, ciphertext) ++type opensslHMAC struct { ++ ctx1 hmacCtx1 ++ ctx3 hmacCtx3 ++ size int ++ blockSize int ++ sum []byte +} + -+func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, msg) -+} -+ -+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 ++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") + } -+ // 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 ++ 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")) + } -+ // 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") ++ hmac := &opensslHMAC{ ++ size: h.Size(), ++ blockSize: h.BlockSize(), ++ ctx1: hmacCtx1{ctx}, + } -+ return ret, nil -+} -+ -+func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ return evpEncrypt(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, msg) ++ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) ++ return hmac +} + -+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") ++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") + } -+ // 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 ++ ctx := C.go_openssl_EVP_MAC_CTX_new(evpHMAC) ++ if ctx == nil { ++ panic("openssl: EVP_MAC_CTX_new failed") + } -+ return C.int(saltLen), nil -+} -+ -+func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { -+ cSaltLen, err := saltLength(saltLen, true) -+ if err != nil { -+ return nil, err ++ 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")) + } -+ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, hashed) ++ 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 +} + -+func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { -+ cSaltLen, err := saltLength(saltLen, false) -+ if err != nil { -+ return err ++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(errUnsupportedVersion()) + } -+ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, sig, hashed) -+} + -+func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { -+ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, hashed) ++ runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. ++ h.sum = nil +} + -+func HashSignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte) ([]byte, error) { -+ return evpHashSign(priv.withKey, h, msg) ++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()) ++ } +} + -+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 ++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()) + } -+ return 1 -+ }) == 0 { -+ return errors.New("crypto/rsa: verification error") + } -+ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, sig, hashed) ++ runtime.KeepAlive(h) ++ return len(p), nil +} + -+func HashVerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte) error { -+ return evpHashVerify(pub.withKey, h, msg, sig) ++func (h *opensslHMAC) Size() int { ++ return h.size +} + -+// 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. ++func (h *opensslHMAC) BlockSize() int { ++ return h.blockSize +} + -+func bnSet(b1 *C.GO_BIGNUM_PTR, b2 BigInt) { -+ if b2 == nil { -+ return -+ } -+ if *b1 != nil { -+ C.go_openssl_BN_clear_free(*b1) ++func (h *opensslHMAC) Sum(in []byte) []byte { ++ if h.sum == nil { ++ size := h.Size() ++ h.sum = make([]byte, size) + } -+ *b1 = bigToBN(b2) -+} -+ -+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 ++ // 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") + } -+ bnSet(&r.n, n) -+ bnSet(&r.e, e) -+ bnSet(&r.d, d) -+ return true ++ 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 C.go_openssl_RSA_set0_key(key, bigToBN(n), bigToBN(e), bigToBN(d)) == 1 ++ return append(in, h.sum...) +} + -+func rsaSetFactors(key C.GO_RSA_PTR, p, q BigInt) bool { ++func hmacCtxNew() C.GO_HMAC_CTX_PTR { + 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 ++ // 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) + } -+ bnSet(&r.p, p) -+ bnSet(&r.q, q) -+ return true ++ return ctx + } -+ return C.go_openssl_RSA_set0_factors(key, bigToBN(p), bigToBN(q)) == 1 ++ return C.go_openssl_HMAC_CTX_new() +} + -+func rsaSetCRTParams(key C.GO_RSA_PTR, dmp1, dmq1, iqmp BigInt) bool { ++func hmacCtxFree(ctx C.GO_HMAC_CTX_PTR) { + 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 ++ C.go_openssl_HMAC_CTX_cleanup(ctx) ++ C.free(unsafe.Pointer(ctx)) ++ return + } -+ return C.go_openssl_RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == 1 ++ C.go_openssl_HMAC_CTX_free(ctx) +} -+ -+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 -+ } -+ b := bigToBN(comp.num) -+ if b == nil { -+ return nil, newOpenSSLError("BN_lebin2bn failed") -+ } -+ // 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/sha.go b/src/vendor/github.com/golang-fips/openssl/v2/sha.go +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 00000000000000..45b8390767a13f +index 00000000000000..21126ff55054cf --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/sha.go -@@ -0,0 +1,690 @@ -+//go:build linux ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init.go +@@ -0,0 +1,63 @@ ++//go:build !cmd_go_bootstrap + +package openssl + +// #include "goopenssl.h" +import "C" +import ( -+ "crypto" + "errors" -+ "hash" -+ "runtime" -+ "strconv" -+ "unsafe" +) + -+// 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. -+ -+func shaX(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 -+} -+ -+func SHA1(p []byte) (sum [20]byte) { -+ if !shaX(crypto.SHA1, p, sum[:]) { -+ panic("openssl: SHA1 failed") -+ } -+ return -+} -+ -+func SHA224(p []byte) (sum [28]byte) { -+ if !shaX(crypto.SHA224, p, sum[:]) { -+ panic("openssl: SHA224 failed") ++// 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 int, err error) { ++ // Load the OpenSSL shared library using dlopen. ++ handle, err := dlopen(file) ++ if err != nil { ++ return 0, 0, 0, err + } -+ return -+} + -+func SHA256(p []byte) (sum [32]byte) { -+ if !shaX(crypto.SHA256, p, sum[:]) { -+ panic("openssl: SHA256 failed") ++ // 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. ++ major = int(C.go_openssl_version_major(handle)) ++ minor = int(C.go_openssl_version_minor(handle)) ++ patch = int(C.go_openssl_version_patch(handle)) ++ if major == -1 || minor == -1 || patch == -1 { ++ return 0, 0, 0, errors.New("openssl: can't retrieve OpenSSL version") + } -+ return -+} -+ -+func SHA384(p []byte) (sum [48]byte) { -+ if !shaX(crypto.SHA384, p, sum[:]) { -+ panic("openssl: SHA384 failed") ++ 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 + } -+ return -+} -+ -+func SHA512(p []byte) (sum [64]byte) { -+ if !shaX(crypto.SHA512, p, sum[:]) { -+ panic("openssl: SHA512 failed") ++ if !supported { ++ return 0, 0, 0, errUnsupportedVersion() + } -+ return -+} + -+// Same as SupportsHKDF, as in v1.1.1+ -+func SupportsSHA3() bool { -+ return vMajor > 1 || -+ (vMajor >= 1 && vMinor > 1) || -+ (vMajor >= 1 && vMinor >= 1 && vPatch >= 1) -+} ++ // Load the OpenSSL functions. ++ // See shims.go for the complete list of supported functions. ++ C.go_openssl_load_functions(handle, C.int(major), C.int(minor), C.int(patch)) + -+func SHA3_224(p []byte) (sum [28]byte) { -+ if !shaX(crypto.SHA3_224, p, sum[:]) { -+ panic("openssl: SHA3_224 failed") ++ // 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 ++ 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 00000000000000..dbf5ac448fdf80 +--- /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 SHA3_256(p []byte) (sum [32]byte) { -+ if !shaX(crypto.SHA3_256, p, sum[:]) { -+ panic("openssl: SHA3_256 failed") -+ } -+ return -+} ++package openssl + -+func SHA3_384(p []byte) (sum [48]byte) { -+ if !shaX(crypto.SHA3_384, p, sum[:]) { -+ panic("openssl: SHA3_384 failed") ++// #cgo LDFLAGS: -ldl ++// #include ++// #include ++import "C" ++import ( ++ "errors" ++ "unsafe" ++) ++ ++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 ++ return handle, nil +} + -+func SHA3_512(p []byte) (sum [64]byte) { -+ if !shaX(crypto.SHA3_512, p, sum[:]) { -+ panic("openssl: SHA3_512 failed") ++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 ++ 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 00000000000000..3778e21227abb9 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go +@@ -0,0 +1,36 @@ ++//go:build !cmd_go_bootstrap + -+// 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 -+} ++package openssl + -+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 -+} ++import ( ++ "syscall" ++ "unsafe" ++) + -+func (h *evpHash) finalize() { -+ C.go_openssl_EVP_MD_CTX_free(h.ctx) -+ C.go_openssl_EVP_MD_CTX_free(h.ctx2) ++type dlopenError struct { ++ file string ++ err error +} + -+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) ++func (e *dlopenError) Error() string { ++ return "openssl: can't load " + e.file + ": " + e.err.Error() +} + -+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 ++func (e *dlopenError) Unwrap() error { ++ return e.err +} + -+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") ++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} + } -+ runtime.KeepAlive(h) -+ return len(s), nil ++ return unsafe.Pointer(h), nil +} + -+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 ++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 00000000000000..14b1a81e5ac8a5 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go +@@ -0,0 +1,412 @@ ++//go:build !cmd_go_bootstrap + -+func (h *evpHash) Size() int { -+ return h.size -+} ++// Package openssl provides access to OpenSSL cryptographic functions. ++package openssl + -+func (h *evpHash) BlockSize() int { -+ return h.blockSize -+} ++// #include "goopenssl.h" ++import "C" ++import ( ++ "encoding/binary" ++ "errors" ++ "math/bits" ++ "runtime" ++ "strconv" ++ "strings" ++ "sync" ++ "unsafe" ++) + -+func (h *evpHash) sum(out []byte) { -+ if C.go_sha_sum(h.ctx, h.ctx2, base(out)) != 1 { -+ panic(newOpenSSLError("go_sha_sum")) -+ } -+ runtime.KeepAlive(h) -+} ++var ( ++ // vMajor and vMinor hold the major/minor OpenSSL version. ++ // It is only populated if Init has been called. ++ vMajor, vMinor, vPatch int ++) + -+// shaState returns a pointer to the internal sha structure. ++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 ++} ++ ++// Init loads and initializes OpenSSL from the shared library at path. ++// It must be called before any other OpenSSL call, except CheckVersion. +// -+// 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) shaState() unsafe.Pointer { ++// 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 errUnsupportedVersion() error { ++ return errors.New("openssl: OpenSSL version: " + strconv.Itoa(vMajor) + "." + strconv.Itoa(vMinor) + "." + strconv.Itoa(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)) ++} ++ ++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: -+ // 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 ++ return C.go_openssl_FIPS_mode() == 1 + 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 ++ // 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 + } -+ return (*mdCtx)(unsafe.Pointer(h.ctx)).algctx ++ // 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()) + } +} + -+// NewSHA1 returns a new SHA1 hash. -+func NewSHA1() hash.Hash { -+ return &sha1Hash{ -+ evpHash: newEvpHash(crypto.SHA1, 20, 64), ++// 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) ++ } ++ 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()) + } +} + -+type sha1Hash struct { -+ *evpHash -+ out [20]byte ++// noescape hides a pointer from escape analysis. noescape is ++// the identity function but escape analysis doesn't think the ++// output depends on the input. noescape is inlined and currently ++// compiles down to zero instructions. ++// USE CAREFULLY! ++// ++//go:nosplit ++func noescape(p unsafe.Pointer) unsafe.Pointer { ++ x := uintptr(p) ++ return unsafe.Pointer(x ^ 0) +} + -+func (h *sha1Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} ++var zero byte + -+// 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 ++// addr converts p to its base addr, including a noescape along the way. ++// If p is nil, addr returns a non-nil pointer, so that the result can always ++// be dereferenced. ++// ++//go:nosplit ++func addr(p []byte) *byte { ++ if len(p) == 0 { ++ return &zero ++ } ++ return (*byte)(noescape(unsafe.Pointer(&p[0]))) +} + -+const ( -+ sha1Magic = "sha\x01" -+ sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 -+) -+ -+func (h *sha1Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha1State)(h.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha1: can't retrieve hash state") ++// 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 + } -+ 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 ++ return (*C.uchar)(unsafe.Pointer(&b[0])) +} + -+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.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha1: can't retrieve hash state") ++func sbase(b []byte) *C.char { ++ if len(b) == 0 { ++ return nil + } -+ 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 ++ return (*C.char)(unsafe.Pointer(&b[0])) +} + -+// NewSHA224 returns a new SHA224 hash. -+func NewSHA224() hash.Hash { -+ return &sha224Hash{ -+ evpHash: newEvpHash(crypto.SHA224, 224/8, 64), ++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()) +} + -+type sha224Hash struct { -+ *evpHash -+ out [224 / 8]byte -+} ++var unknownFile = "\000" + -+func (h *sha224Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++// 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) +} + -+// NewSHA256 returns a new SHA256 hash. -+func NewSHA256() hash.Hash { -+ return &sha256Hash{ -+ evpHash: newEvpHash(crypto.SHA256, 256/8, 64), ++// 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 +} + -+type sha256Hash struct { -+ *evpHash -+ out [256 / 8]byte ++// 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) +} + -+func (h *sha256Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++const wordBytes = bits.UintSize / 8 ++ ++// Reverse each limb of z. ++func (z BigInt) byteSwap() { ++ for i, d := range z { ++ var n uint = 0 ++ for j := 0; j < wordBytes; j++ { ++ n |= uint(byte(d)) << (8 * (wordBytes - j - 1)) ++ d >>= 8 ++ } ++ z[i] = n ++ } +} + -+const ( -+ magic224 = "sha\x02" -+ magic256 = "sha\x03" -+ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 -+) ++func wbase(b BigInt) *C.uchar { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uchar)(unsafe.Pointer(&b[0])) ++} + -+// 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 ++// 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 +} + -+func (h *sha224Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha256State)(h.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++func bigToBN(x BigInt) C.GO_BIGNUM_PTR { ++ if len(x) == 0 { ++ return nil + } -+ 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.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ 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 + } -+ 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 ++ ++ 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) +} + -+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") ++func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { ++ if bn == nil { ++ return nil + } -+ if len(b) != marshaledSize256 { -+ return errors.New("crypto/sha256: invalid hash state size") ++ ++ 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 + } -+ d := (*sha256State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha256: can't retrieve hash state") ++ ++ // 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 ++} ++ ++func bnNumBytes(bn C.GO_BIGNUM_PTR) int { ++ return (int(C.go_openssl_BN_num_bits(bn)) + 7) / 8 ++} ++ ++// 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 ++ } ++ ++ if C.go_openssl_BN_bn2binpad(bn, base(to), C.int(len(to))) < 0 { ++ return newOpenSSLError("BN_bn2binpad") + } -+ 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 +} + -+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") ++func CheckLeaks() { ++ C.go_openssl_do_leak_check() ++} ++ ++func version1_1_1_or_above() bool { ++ return vMajor > 1 || (vMajor >= 1 && vMinor > 1) || (vMajor >= 1 && vMinor >= 1 && vPatch >= 1) ++} +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 00000000000000..a895eab2d54767 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go +@@ -0,0 +1,28 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++ "hash" ++) ++ ++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(b) != marshaledSize256 { -+ return errors.New("crypto/sha256: invalid hash state size") ++ 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) + } -+ d := (*sha256State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha256: can't retrieve hash state") ++ 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/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 00000000000000..50d49b1f103351 +--- /dev/null ++++ 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. ++ ++/* ++ * 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 ++ */ ++ ++#include "goopenssl.h" ++ ++#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; ++ ++struct md5_sha1_ctx { ++ MD5_CTX md5; ++ SHA_CTX sha1; ++}; ++ ++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 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); ++} ++ ++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); ++} ++ ++// Change: Removed: ++// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) ++ ++static const EVP_MD md5_sha1_md = { ++ NID_md5_sha1, ++ NID_md5_sha1, ++ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, ++ 0, ++ 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 ++}; ++ ++// 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 00000000000000..9fd709635c3b40 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rand.go +@@ -0,0 +1,20 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.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.go_openssl_RAND_bytes((*C.uchar)(unsafe.Pointer(&b[0])), C.int(len(b))) == 0 { ++ return 0, newOpenSSLError("RAND_bytes") ++ } ++ return len(b), nil ++} ++ ++const RandReader = randReader(0) +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 00000000000000..5aef65b84f6781 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go +@@ -0,0 +1,419 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "crypto/subtle" ++ "errors" ++ "hash" ++ "runtime" ++ "unsafe" ++) ++ ++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") ++) ++ ++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")) ++ } ++ 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) ++ } ++ 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 !(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) ++ } ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ return ++} ++ ++type PublicKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} ++ ++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()) + } -+ 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 ++ k := &PublicKeyRSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) ++ return k, nil +} + -+// NewSHA384 returns a new SHA384 hash. -+func NewSHA384() hash.Hash { -+ return &sha384Hash{ -+ evpHash: newEvpHash(crypto.SHA384, 384/8, 128), -+ } ++func (k *PublicKeyRSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+type sha384Hash struct { -+ *evpHash -+ out [384 / 8]byte ++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) +} + -+func (h *sha384Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++type PrivateKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR +} + -+// NewSHA512 returns a new SHA512 hash. -+func NewSHA512() hash.Hash { -+ return &sha512Hash{ -+ evpHash: newEvpHash(crypto.SHA512, 512/8, 128), ++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()) + } ++ k := &PrivateKeyRSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) ++ return k, nil +} + -+type sha512Hash struct { -+ *evpHash -+ out [512 / 8]byte ++func (k *PrivateKeyRSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+func (h *sha512Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++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) +} + -+// 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 ++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) +} + -+const ( -+ magic384 = "sha\x04" -+ magic512_224 = "sha\x05" -+ magic512_256 = "sha\x06" -+ magic512 = "sha\x07" -+ marshaledSize512 = len(magic512) + 8*8 + 128 + 8 -+) ++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) ++} + -+func (h *sha384Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512State)(h.shaState()) -+ 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 DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, ciphertext) +} + -+func (h *sha512Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512State)(h.shaState()) -+ 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 EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, msg) +} + -+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") ++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 + } -+ if len(b) != marshaledSize512 { -+ return errors.New("crypto/sha512: invalid hash state size") ++ // 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 + } -+ d := (*sha512State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha512: can't retrieve hash state") ++ // 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") + } -+ 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 ++ return ret, 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 := (*sha512State)(h.shaState()) -+ 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 ++func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, msg) +} + -+// NewSHA3_224 returns a new SHA3-224 hash. -+func NewSHA3_224() hash.Hash { -+ return &sha3_224Hash{ -+ evpHash: newEvpHash(crypto.SHA3_224, 224/8, 64), ++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 +} + -+type sha3_224Hash struct { -+ *evpHash -+ out [224 / 8]byte -+} -+ -+func (h *sha3_224Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++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) +} + -+// NewSHA3_256 returns a new SHA3-256 hash. -+func NewSHA3_256() hash.Hash { -+ return &sha3_256Hash{ -+ evpHash: newEvpHash(crypto.SHA3_256, 256/8, 64), ++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) +} + -+type sha3_256Hash struct { -+ *evpHash -+ out [256 / 8]byte ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, hashed) +} + -+func (h *sha3_256Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++func HashSignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte) ([]byte, error) { ++ return evpHashSign(priv.withKey, h, msg) +} + -+// NewSHA3_384 returns a new SHA3-384 hash. -+func NewSHA3_384() hash.Hash { -+ return &sha3_384Hash{ -+ evpHash: newEvpHash(crypto.SHA3_384, 384/8, 128), ++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) +} + -+type sha3_384Hash struct { -+ *evpHash -+ out [384 / 8]byte ++func HashVerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte) error { ++ return evpHashVerify(pub.withKey, h, msg, sig) +} + -+func (h *sha3_384Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++// 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. +} + -+// NewSHA3_512 returns a new SHA3-512 hash. -+func NewSHA3_512() hash.Hash { -+ return &sha3_512Hash{ -+ evpHash: newEvpHash(crypto.SHA3_512, 512/8, 128), ++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) +} + -+type sha3_512Hash struct { -+ *evpHash -+ out [512 / 8]byte -+} -+ -+func (h *sha3_512Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// 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), -+ ) ++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 +} + -+// 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)) ++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 +} + -+// 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 ++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 +} + -+// 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 ++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 ++ } ++ b := bigToBN(comp.num) ++ if b == nil { ++ return nil, newOpenSSLError("BN_lebin2bn failed") ++ } ++ // 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 00000000000000..56a29113160a9d +index 00000000000000..858c47e747026c --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/shims.h -@@ -0,0 +1,343 @@ +@@ -0,0 +1,358 @@ +#include // size_t +#include // uint64_t + @@ -4356,12 +4950,6 @@ index 00000000000000..56a29113160a9d + GO_OPENSSL_INIT_LOAD_CONFIG = 0x00000040L +}; + -+// #include -+enum { -+ GO_AES_ENCRYPT = 1, -+ GO_AES_DECRYPT = 0 -+}; -+ +// #include +enum { + GO_EVP_CTRL_GCM_GET_TAG = 0x10, @@ -4369,6 +4957,7 @@ index 00000000000000..56a29113160a9d + 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, + /* This is defined differently in OpenSSL 3 (1 << 11), but in our + * code it is only used in OpenSSL 1. @@ -4390,6 +4979,9 @@ index 00000000000000..56a29113160a9d + 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, @@ -4523,6 +5115,11 @@ index 00000000000000..56a29113160a9d +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), ()) \ @@ -4554,6 +5151,7 @@ index 00000000000000..56a29113160a9d +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), ()) \ @@ -4579,6 +5177,7 @@ index 00000000000000..56a29113160a9d +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)) \ @@ -4595,6 +5194,11 @@ index 00000000000000..56a29113160a9d +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_RENAMED_3_0(int, EVP_CIPHER_get_block_size, EVP_CIPHER_block_size, (const GO_EVP_CIPHER_PTR cipher), (cipher)) \ +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), ()) \ @@ -4643,10 +5247,11 @@ index 00000000000000..56a29113160a9d +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)) \ -+/* bn_lebin2bn, bn_bn2lebinpad and BN_bn2binpad are not exported in any OpenSSL 1.0.2, but they exist. */ \ -+/*check:from=1.1.0*/ DEFINEFUNC_RENAMED_1_1(GO_BIGNUM_PTR, BN_lebin2bn, bn_lebin2bn, (const unsigned char *s, int len, GO_BIGNUM_PTR ret), (s, len, ret)) \ -+/*check:from=1.1.0*/ DEFINEFUNC_RENAMED_1_1(int, BN_bn2lebinpad, bn_bn2lebinpad, (const GO_BIGNUM_PTR a, unsigned char *to, int tolen), (a, to, tolen)) \ -+/*check:from=1.1.0*/ DEFINEFUNC_RENAMED_1_1(int, BN_bn2binpad, bn_bn2binpad, (const GO_BIGNUM_PTR a, unsigned char *to, int tolen), (a, to, tolen)) \ ++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)) \ @@ -4687,14 +5292,18 @@ index 00000000000000..56a29113160a9d +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)) \ + -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/thread_setup.c b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup.c +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 00000000000000..aa497baf13744b +index 00000000000000..dc2df609b01b59 --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup.c ++++ b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c @@ -0,0 +1,35 @@ -+//go:build linux ++//go:build unix + +#include "goopenssl.h" +#include @@ -4712,22 +5321,171 @@ index 00000000000000..aa497baf13744b + pthread_mutex_unlock(&mutex_buf[n]); +} + -+static void thread_id(GO_CRYPTO_THREADID_PTR tid) -+{ -+ go_openssl_CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); -+} ++static void thread_id(GO_CRYPTO_THREADID_PTR tid) ++{ ++ go_openssl_CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); ++} ++ ++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 00000000000000..7bc66d80145794 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_windows.c +@@ -0,0 +1,33 @@ ++//go:build windows ++ ++#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 00000000000000..3153fc81ec0279 +--- /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("unsupported hash function") ++ } ++ ++ 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) ++ }() + -+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; ++ 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 +} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/LICENSE b/src/vendor/github.com/microsoft/go-crypto-winnative/LICENSE new file mode 100644 @@ -4758,10 +5516,10 @@ index 00000000000000..9e841e7a26e4eb + SOFTWARE diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go new file mode 100644 -index 00000000000000..e3b865ab7823d1 +index 00000000000000..1722fa341daff9 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go -@@ -0,0 +1,359 @@ +@@ -0,0 +1,331 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -4782,50 +5540,18 @@ index 00000000000000..e3b865ab7823d1 + +const aesBlockSize = 16 + -+type aesAlgorithm struct { -+ handle bcrypt.ALG_HANDLE -+ allowedKeyLengths bcrypt.KEY_LENGTHS_STRUCT -+} -+ -+func loadAes(mode string) (aesAlgorithm, error) { -+ v, err := loadOrStoreAlg(bcrypt.AES_ALGORITHM, bcrypt.ALG_NONE_FLAG, mode, func(h bcrypt.ALG_HANDLE) (interface{}, error) { -+ // Windows 8 added support to set the CipherMode value on a key, -+ // but Windows 7 requires that it be set on the algorithm before key creation. -+ err := setString(bcrypt.HANDLE(h), bcrypt.CHAINING_MODE, mode) -+ if err != nil { -+ return nil, err -+ } -+ lengths, err := getKeyLengths(bcrypt.HANDLE(h)) -+ if err != nil { -+ return nil, err -+ } -+ return aesAlgorithm{h, lengths}, nil -+ }) -+ if err != nil { -+ return aesAlgorithm{}, nil -+ } -+ return v.(aesAlgorithm), nil -+} -+ +type aesCipher struct { + kh bcrypt.KEY_HANDLE + key []byte +} + +func NewAESCipher(key []byte) (cipher.Block, error) { -+ h, err := loadAes(bcrypt.CHAIN_MODE_ECB) ++ kh, err := newCipherHandle(bcrypt.AES_ALGORITHM, bcrypt.CHAIN_MODE_ECB, key) + if err != nil { + return nil, err + } -+ if !keyIsAllowed(h.allowedKeyLengths, uint32(len(key)*8)) { -+ return nil, errors.New("crypto/cipher: invalid key size") -+ } -+ c := &aesCipher{key: make([]byte, len(key))} ++ c := &aesCipher{kh: kh, key: make([]byte, len(key))} + copy(c.key, key) -+ err = bcrypt.GenerateSymmetricKey(h.handle, &c.kh, nil, c.key, 0) -+ if err != nil { -+ return nil, err -+ } + runtime.SetFinalizer(c, (*aesCipher).finalize) + return c, nil +} @@ -4880,11 +5606,11 @@ index 00000000000000..e3b865ab7823d1 +} + +func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { -+ return newCBC(true, c.key, iv) ++ return newCBC(true, bcrypt.AES_ALGORITHM, c.key, iv) +} + +func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { -+ return newCBC(false, c.key, iv) ++ return newCBC(false, bcrypt.AES_ALGORITHM, c.key, iv) +} + +type noGCM struct { @@ -4915,38 +5641,46 @@ index 00000000000000..e3b865ab7823d1 + return newGCM(c.key, true) +} + -+type aesCBC struct { -+ kh bcrypt.KEY_HANDLE -+ iv [aesBlockSize]byte -+ encrypt bool ++type cbcCipher struct { ++ kh bcrypt.KEY_HANDLE ++ // Use aesBlockSize, the max of all supported cipher block sizes. ++ // The array avoids allocations (vs. a slice). ++ iv [aesBlockSize]byte ++ blockSize int ++ encrypt bool +} + -+func newCBC(encrypt bool, key, iv []byte) *aesCBC { -+ h, err := loadAes(bcrypt.CHAIN_MODE_CBC) -+ if err != nil { -+ panic(err) ++func newCBC(encrypt bool, alg string, key, iv []byte) *cbcCipher { ++ var blockSize int ++ switch alg { ++ case bcrypt.AES_ALGORITHM: ++ blockSize = aesBlockSize ++ case bcrypt.DES_ALGORITHM: ++ blockSize = desBlockSize ++ default: ++ panic("invalid algorithm: " + alg) + } -+ x := &aesCBC{encrypt: encrypt} -+ x.SetIV(iv) -+ err = bcrypt.GenerateSymmetricKey(h.handle, &x.kh, nil, key, 0) ++ kh, err := newCipherHandle(alg, bcrypt.CHAIN_MODE_CBC, key) + if err != nil { + panic(err) + } -+ runtime.SetFinalizer(x, (*aesCBC).finalize) ++ x := &cbcCipher{kh: kh, encrypt: encrypt, blockSize: blockSize} ++ runtime.SetFinalizer(x, (*cbcCipher).finalize) ++ x.SetIV(iv) + return x +} + -+func (x *aesCBC) finalize() { ++func (x *cbcCipher) finalize() { + bcrypt.DestroyKey(x.kh) +} + -+func (x *aesCBC) BlockSize() int { return aesBlockSize } ++func (x *cbcCipher) BlockSize() int { return x.blockSize } + -+func (x *aesCBC) CryptBlocks(dst, src []byte) { ++func (x *cbcCipher) CryptBlocks(dst, src []byte) { + if subtle.InexactOverlap(dst, src) { + panic("crypto/cipher: invalid buffer overlap") + } -+ if len(src)%aesBlockSize != 0 { ++ if len(src)%x.blockSize != 0 { + panic("crypto/cipher: input not full blocks") + } + if len(dst) < len(src) { @@ -4958,9 +5692,9 @@ index 00000000000000..e3b865ab7823d1 + var ret uint32 + var err error + if x.encrypt { -+ err = bcrypt.Encrypt(x.kh, src, nil, x.iv[:], dst, &ret, 0) ++ err = bcrypt.Encrypt(x.kh, src, nil, x.iv[:x.blockSize], dst, &ret, 0) + } else { -+ err = bcrypt.Decrypt(x.kh, src, nil, x.iv[:], dst, &ret, 0) ++ err = bcrypt.Decrypt(x.kh, src, nil, x.iv[:x.blockSize], dst, &ret, 0) + } + if err != nil { + panic(err) @@ -4971,8 +5705,8 @@ index 00000000000000..e3b865ab7823d1 + runtime.KeepAlive(x) +} + -+func (x *aesCBC) SetIV(iv []byte) { -+ if len(iv) != aesBlockSize { ++func (x *cbcCipher) SetIV(iv []byte) { ++ if len(iv) != x.blockSize { + panic("cipher: incorrect length IV") + } + copy(x.iv[:], iv) @@ -4996,15 +5730,11 @@ index 00000000000000..e3b865ab7823d1 +} + +func newGCM(key []byte, tls bool) (*aesGCM, error) { -+ h, err := loadAes(bcrypt.CHAIN_MODE_GCM) -+ if err != nil { -+ return nil, err -+ } -+ g := &aesGCM{tls: tls} -+ err = bcrypt.GenerateSymmetricKey(h.handle, &g.kh, nil, key, 0) ++ kh, err := newCipherHandle(bcrypt.AES_ALGORITHM, bcrypt.CHAIN_MODE_GCM, key) + if err != nil { + return nil, err + } ++ g := &aesGCM{kh: kh, tls: tls} + runtime.SetFinalizer(g, (*aesGCM).finalize) + return g, nil +} @@ -5194,6 +5924,68 @@ index 00000000000000..36f0e0c6e278bc + // plus the minimum number of bits to represent the first byte. + return (len(x)-1)*_S + bits.Len(uint(x[0])) +} +diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/cipher.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/cipher.go +new file mode 100644 +index 00000000000000..61f5dc878d6c56 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/cipher.go +@@ -0,0 +1,56 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build windows ++// +build windows ++ ++package cng ++ ++import ( ++ "errors" ++ ++ "github.com/microsoft/go-crypto-winnative/internal/bcrypt" ++) ++ ++type cipherAlgorithm struct { ++ handle bcrypt.ALG_HANDLE ++ allowedKeyLengths bcrypt.KEY_LENGTHS_STRUCT ++} ++ ++func loadCipher(id, mode string) (cipherAlgorithm, error) { ++ v, err := loadOrStoreAlg(id, bcrypt.ALG_NONE_FLAG, mode, func(h bcrypt.ALG_HANDLE) (interface{}, error) { ++ if mode != "" { ++ // Windows 8 added support to set the CipherMode value on a key, ++ // but Windows 7 requires that it be set on the algorithm before key creation. ++ err := setString(bcrypt.HANDLE(h), bcrypt.CHAINING_MODE, mode) ++ if err != nil { ++ return nil, err ++ } ++ } ++ lengths, err := getKeyLengths(bcrypt.HANDLE(h)) ++ if err != nil { ++ return nil, err ++ } ++ return cipherAlgorithm{h, lengths}, nil ++ }) ++ if err != nil { ++ return cipherAlgorithm{}, nil ++ } ++ return v.(cipherAlgorithm), nil ++} ++ ++func newCipherHandle(id, mode string, key []byte) (bcrypt.KEY_HANDLE, error) { ++ h, err := loadCipher(id, mode) ++ if err != nil { ++ return 0, err ++ } ++ if !keyIsAllowed(h.allowedKeyLengths, uint32(len(key)*8)) { ++ return 0, errors.New("crypto/cipher: invalid key size") ++ } ++ var kh bcrypt.KEY_HANDLE ++ err = bcrypt.GenerateSymmetricKey(h.handle, &kh, nil, key, 0) ++ if err != nil { ++ return 0, err ++ } ++ return kh, nil ++} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/cng.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/cng.go new file mode 100644 index 00000000000000..844c087287cabe @@ -5330,6 +6122,118 @@ index 00000000000000..844c087287cabe + } + return (bits-lengths.MinLength)%lengths.Increment == 0 +} +diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/des.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/des.go +new file mode 100644 +index 00000000000000..78b4d0a54a3689 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/des.go +@@ -0,0 +1,106 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build windows ++// +build windows ++ ++package cng ++ ++import ( ++ "crypto/cipher" ++ "runtime" ++ ++ "github.com/microsoft/go-crypto-winnative/internal/bcrypt" ++ "github.com/microsoft/go-crypto-winnative/internal/subtle" ++) ++ ++const desBlockSize = 8 ++ ++type desCipher struct { ++ kh bcrypt.KEY_HANDLE ++ key []byte ++} ++ ++func NewDESCipher(key []byte) (cipher.Block, error) { ++ kh, err := newCipherHandle(bcrypt.DES_ALGORITHM, "", key) ++ if err != nil { ++ return nil, err ++ } ++ c := &desCipher{kh: kh, key: make([]byte, len(key))} ++ copy(c.key, key) ++ runtime.SetFinalizer(c, (*desCipher).finalize) ++ return c, nil ++} ++ ++func NewTripleDESCipher(key []byte) (cipher.Block, error) { ++ kh, err := newCipherHandle(bcrypt.DES3_ALGORITHM, "", key) ++ if err != nil { ++ return nil, err ++ } ++ c := &desCipher{kh: kh, key: make([]byte, len(key))} ++ copy(c.key, key) ++ runtime.SetFinalizer(c, (*desCipher).finalize) ++ return c, nil ++} ++ ++func (c *desCipher) finalize() { ++ bcrypt.DestroyKey(c.kh) ++} ++ ++func (c *desCipher) BlockSize() int { return desBlockSize } ++ ++func (c *desCipher) Encrypt(dst, src []byte) { ++ if len(src) < desBlockSize { ++ panic("crypto/des: input not full block") ++ } ++ if len(dst) < desBlockSize { ++ panic("crypto/des: output not full block") ++ } ++ // cypher.Block.Encrypt() is documented to encrypt one full block ++ // at a time, so we truncate the input and output to the block size. ++ dst, src = dst[:desBlockSize], src[:desBlockSize] ++ if subtle.InexactOverlap(dst, src) { ++ panic("crypto/des: invalid buffer overlap") ++ } ++ var ret uint32 ++ err := bcrypt.Encrypt(c.kh, src, nil, nil, dst, &ret, 0) ++ if err != nil { ++ panic(err) ++ } ++ if int(ret) != len(src) { ++ panic("crypto/des: plaintext not fully encrypted") ++ } ++ runtime.KeepAlive(c) ++} ++ ++func (c *desCipher) Decrypt(dst, src []byte) { ++ if len(src) < desBlockSize { ++ panic("crypto/des: input not full block") ++ } ++ if len(dst) < desBlockSize { ++ panic("crypto/des: output not full block") ++ } ++ // cypher.Block.Decrypt() is documented to decrypt one full block ++ // at a time, so we truncate the input and output to the block size. ++ dst, src = dst[:desBlockSize], src[:desBlockSize] ++ if subtle.InexactOverlap(dst, src) { ++ panic("crypto/des: invalid buffer overlap") ++ } ++ var ret uint32 ++ err := bcrypt.Decrypt(c.kh, src, nil, nil, dst, &ret, 0) ++ if err != nil { ++ panic(err) ++ } ++ if int(ret) != len(src) { ++ panic("crypto/des: plaintext not fully decrypted") ++ } ++ runtime.KeepAlive(c) ++} ++ ++func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return newCBC(true, bcrypt.DES_ALGORITHM, c.key, iv) ++} ++ ++func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return newCBC(false, bcrypt.DES_ALGORITHM, c.key, iv) ++} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/ecdh.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/ecdh.go new file mode 100644 index 00000000000000..cd6e9a98f6f967 @@ -6484,10 +7388,10 @@ index 00000000000000..95c3bcdc5e788d +} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/pbkdf2.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/pbkdf2.go new file mode 100644 -index 00000000000000..078a358887f620 +index 00000000000000..42614c9c748f80 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/pbkdf2.go -@@ -0,0 +1,71 @@ +@@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -6530,22 +7434,25 @@ index 00000000000000..078a358887f620 + } + defer bcrypt.DestroyKey(kh) + u16HashID := utf16FromString(hashID) -+ buffers := [...]bcrypt.Buffer{ -+ { ++ buffers := make([]bcrypt.Buffer, 0, 3) ++ buffers = append(buffers, ++ bcrypt.Buffer{ + Type: bcrypt.KDF_ITERATION_COUNT, + Data: uintptr(unsafe.Pointer(&iter)), + Length: 8, + }, -+ { -+ Type: bcrypt.KDF_SALT, -+ Data: uintptr(unsafe.Pointer(&salt[0])), -+ Length: uint32(len(salt)), -+ }, -+ { ++ bcrypt.Buffer{ + Type: bcrypt.KDF_HASH_ALGORITHM, + Data: uintptr(unsafe.Pointer(&u16HashID[0])), + Length: uint32(len(u16HashID) * 2), -+ }, ++ }) ++ if len(salt) > 0 { ++ // The salt is optional. ++ buffers = append(buffers, bcrypt.Buffer{ ++ Type: bcrypt.KDF_SALT, ++ Data: uintptr(unsafe.Pointer(&salt[0])), ++ Length: uint32(len(salt)), ++ }) + } + params := &bcrypt.BufferDesc{ + Count: uint32(len(buffers)), @@ -6973,12 +7880,110 @@ index 00000000000000..7e3f7abe3487cb + } + return "" +} +diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/tls1prf.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/tls1prf.go +new file mode 100644 +index 00000000000000..30ef2242bc3cf3 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/tls1prf.go +@@ -0,0 +1,92 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build windows ++// +build windows ++ ++package cng ++ ++import ( ++ "errors" ++ "hash" ++ "unsafe" ++ ++ "github.com/microsoft/go-crypto-winnative/internal/bcrypt" ++) ++ ++func loadTLS1PRF(id string) (bcrypt.ALG_HANDLE, error) { ++ h, err := loadOrStoreAlg(id, 0, "", func(h bcrypt.ALG_HANDLE) (interface{}, error) { ++ return h, nil ++ }) ++ if err != nil { ++ return 0, err ++ } ++ return h.(bcrypt.ALG_HANDLE), nil ++} ++ ++// 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 { ++ // TLS 1.0/1.1 PRF uses MD5SHA1. ++ algID := bcrypt.TLS1_1_KDF_ALGORITHM ++ var hashID string ++ if h != nil { ++ // If h is specified, assume the caller wants to use TLS 1.2 PRF. ++ // TLS 1.0/1.1 PRF doesn't allow specifying the hash function. ++ if hashID = hashToID(h()); hashID == "" { ++ return errors.New("cng: unsupported hash function") ++ } ++ algID = bcrypt.TLS1_2_KDF_ALGORITHM ++ } ++ ++ alg, err := loadTLS1PRF(algID) ++ if err != nil { ++ return err ++ } ++ var kh bcrypt.KEY_HANDLE ++ if err := bcrypt.GenerateSymmetricKey(alg, &kh, nil, secret, 0); err != nil { ++ return err ++ } ++ ++ buffers := make([]bcrypt.Buffer, 0, 3) ++ if len(label) > 0 { ++ buffers = append(buffers, bcrypt.Buffer{ ++ Type: bcrypt.KDF_TLS_PRF_LABEL, ++ Data: uintptr(unsafe.Pointer(&label[0])), ++ Length: uint32(len(label)), ++ }) ++ } ++ if len(seed) > 0 { ++ buffers = append(buffers, bcrypt.Buffer{ ++ Type: bcrypt.KDF_TLS_PRF_SEED, ++ Data: uintptr(unsafe.Pointer(&seed[0])), ++ Length: uint32(len(seed)), ++ }) ++ } ++ if algID == bcrypt.TLS1_2_KDF_ALGORITHM { ++ u16HashID := utf16FromString(hashID) ++ buffers = append(buffers, bcrypt.Buffer{ ++ Type: bcrypt.KDF_HASH_ALGORITHM, ++ Data: uintptr(unsafe.Pointer(&u16HashID[0])), ++ Length: uint32(len(u16HashID) * 2), ++ }) ++ } ++ params := &bcrypt.BufferDesc{ ++ Count: uint32(len(buffers)), ++ Buffers: &buffers[0], ++ } ++ var size uint32 ++ err = bcrypt.KeyDerivation(kh, params, result, &size, 0) ++ if err != nil { ++ return err ++ } ++ // 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, ++ // BCryptKeyDerivation handles multiple algorithms and there could be a subtle mismatch ++ // after more code changes in the future. ++ if size != uint32(len(result)) { ++ return errors.New("tls1-prf: derived less bytes than requested") ++ } ++ return nil ++} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/bcrypt_windows.go b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/bcrypt_windows.go new file mode 100644 -index 00000000000000..69ce980e93d0df +index 00000000000000..829ec6611c1d86 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/bcrypt_windows.go -@@ -0,0 +1,276 @@ +@@ -0,0 +1,283 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -6992,21 +7997,25 @@ index 00000000000000..69ce980e93d0df +) + +const ( -+ SHA1_ALGORITHM = "SHA1" -+ SHA256_ALGORITHM = "SHA256" -+ SHA384_ALGORITHM = "SHA384" -+ SHA512_ALGORITHM = "SHA512" -+ SHA3_256_ALGORITHM = "SHA3-256" -+ SHA3_384_ALGORITHM = "SHA3-384" -+ SHA3_512_ALGORITHM = "SHA3-512" -+ AES_ALGORITHM = "AES" -+ RSA_ALGORITHM = "RSA" -+ MD4_ALGORITHM = "MD4" -+ MD5_ALGORITHM = "MD5" -+ ECDSA_ALGORITHM = "ECDSA" -+ ECDH_ALGORITHM = "ECDH" -+ HKDF_ALGORITHM = "HKDF" -+ PBKDF2_ALGORITHM = "PBKDF2" ++ SHA1_ALGORITHM = "SHA1" ++ SHA256_ALGORITHM = "SHA256" ++ SHA384_ALGORITHM = "SHA384" ++ SHA512_ALGORITHM = "SHA512" ++ SHA3_256_ALGORITHM = "SHA3-256" ++ SHA3_384_ALGORITHM = "SHA3-384" ++ SHA3_512_ALGORITHM = "SHA3-512" ++ AES_ALGORITHM = "AES" ++ RSA_ALGORITHM = "RSA" ++ MD4_ALGORITHM = "MD4" ++ MD5_ALGORITHM = "MD5" ++ ECDSA_ALGORITHM = "ECDSA" ++ ECDH_ALGORITHM = "ECDH" ++ HKDF_ALGORITHM = "HKDF" ++ PBKDF2_ALGORITHM = "PBKDF2" ++ DES_ALGORITHM = "DES" ++ DES3_ALGORITHM = "3DES" // 3DES_ALGORITHM ++ TLS1_1_KDF_ALGORITHM = "TLS1_1_KDF" ++ TLS1_2_KDF_ALGORITHM = "TLS1_2_KDF" +) + +const ( @@ -7045,9 +8054,12 @@ index 00000000000000..69ce980e93d0df +) + +const ( -+ KDF_HASH_ALGORITHM = 0x0 -+ KDF_ITERATION_COUNT = 0x10 -+ KDF_SALT = 0xF ++ KDF_HASH_ALGORITHM = 0x0 ++ KDF_TLS_PRF_LABEL = 0x4 ++ KDF_TLS_PRF_SEED = 0x5 ++ KDF_TLS_PRF_PROTOCOL = 0x6 ++ KDF_ITERATION_COUNT = 0x10 ++ KDF_SALT = 0xF +) + +const ( @@ -7750,15 +8762,15 @@ index 00000000000000..1722410e5af193 + return getSystemDirectory() + "\\" + dll +} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index abd3f0b5193381..0e35ad96e33c2c 100644 +index abd3f0b5193381..e62e6149066c22 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,14 @@ -+# github.com/golang-fips/openssl/v2 v2.0.0-rc.2 ++# github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 +## explicit; go 1.20 +github.com/golang-fips/openssl/v2 +github.com/golang-fips/openssl/v2/bbig -+# github.com/microsoft/go-crypto-winnative v0.0.0-20230822062938-306d53ca6072 ++# github.com/microsoft/go-crypto-winnative v0.0.0-20230919193409-4899d534a7ff +## explicit; go 1.17 +github.com/microsoft/go-crypto-winnative/cng +github.com/microsoft/go-crypto-winnative/cng/bbig From ec9197669f6cb0891409e4ff33daf9b6b3c2167c Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 21 Sep 2023 14:51:48 +0200 Subject: [PATCH 2/3] properly handle prf errors --- .../0002-Add-crypto-backend-foundation.patch | 245 +++++++++++++++++- 1 file changed, 239 insertions(+), 6 deletions(-) diff --git a/patches/0002-Add-crypto-backend-foundation.patch b/patches/0002-Add-crypto-backend-foundation.patch index 6704ced8341..f404797f2c0 100644 --- a/patches/0002-Add-crypto-backend-foundation.patch +++ b/patches/0002-Add-crypto-backend-foundation.patch @@ -36,11 +36,14 @@ Subject: [PATCH] Add crypto backend foundation src/crypto/sha512/sha512.go | 2 +- src/crypto/sha512/sha512_test.go | 2 +- src/crypto/tls/cipher_suites.go | 2 +- + src/crypto/tls/handshake_client.go | 25 +++- + src/crypto/tls/handshake_server.go | 25 +++- src/crypto/tls/key_schedule.go | 18 ++- - src/crypto/tls/prf.go | 39 ++++-- + src/crypto/tls/prf.go | 77 +++++++---- + src/crypto/tls/prf_test.go | 12 +- src/go/build/deps_test.go | 2 + src/runtime/runtime_boring.go | 5 + - 36 files changed, 371 insertions(+), 39 deletions(-) + 39 files changed, 445 insertions(+), 65 deletions(-) create mode 100644 src/crypto/internal/backend/backend_test.go create mode 100644 src/crypto/internal/backend/bbig/big.go create mode 100644 src/crypto/internal/backend/common.go @@ -714,6 +717,130 @@ index 589e8b6fafbba3..0a6d665ee3096d 100644 "crypto/rc4" "crypto/sha1" "crypto/sha256" +diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go +index 4649f36dea6773..f96b2b28862234 100644 +--- a/src/crypto/tls/handshake_client.go ++++ b/src/crypto/tls/handshake_client.go +@@ -653,12 +653,16 @@ func (hs *clientHandshakeState) doFullHandshake() error { + + if hs.serverHello.extendedMasterSecret { + c.extMasterSecret = true +- hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, ++ hs.masterSecret, err = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, + hs.finishedHash.Sum()) + } else { +- hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, ++ hs.masterSecret, err = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, + hs.hello.random, hs.serverHello.random) + } ++ if err != nil { ++ c.sendAlert(alertInternalError) ++ return err ++ } + if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil { + c.sendAlert(alertInternalError) + return errors.New("tls: failed to write to key log: " + err.Error()) +@@ -719,8 +723,12 @@ func (hs *clientHandshakeState) doFullHandshake() error { + func (hs *clientHandshakeState) establishKeys() error { + c := hs.c + +- clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := ++ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV, err := + keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) ++ if err != nil { ++ c.sendAlert(alertInternalError) ++ return err ++ } + var clientCipher, serverCipher any + var clientHash, serverHash hash.Hash + if hs.suite.cipher != nil { +@@ -860,7 +868,11 @@ func (hs *clientHandshakeState) readFinished(out []byte) error { + return unexpectedMessageError(serverFinished, msg) + } + +- verify := hs.finishedHash.serverSum(hs.masterSecret) ++ verify, err := hs.finishedHash.serverSum(hs.masterSecret) ++ if err != nil { ++ c.sendAlert(alertHandshakeFailure) ++ return err ++ } + if len(verify) != len(serverFinished.verifyData) || + subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { + c.sendAlert(alertHandshakeFailure) +@@ -930,7 +942,10 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error { + } + + finished := new(finishedMsg) +- finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) ++ var err error ++ if finished.verifyData, err = hs.finishedHash.clientSum(hs.masterSecret); err != nil { ++ return err ++ } + if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil { + return err + } +diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go +index 996b23b1f52341..0c645ead0adba3 100644 +--- a/src/crypto/tls/handshake_server.go ++++ b/src/crypto/tls/handshake_server.go +@@ -668,12 +668,16 @@ func (hs *serverHandshakeState) doFullHandshake() error { + } + if hs.hello.extendedMasterSecret { + c.extMasterSecret = true +- hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, ++ hs.masterSecret, err = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, + hs.finishedHash.Sum()) + } else { +- hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, ++ hs.masterSecret, err = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, + hs.clientHello.random, hs.hello.random) + } ++ if err != nil { ++ c.sendAlert(alertInternalError) ++ return err ++ } + if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil { + c.sendAlert(alertInternalError) + return err +@@ -737,8 +741,12 @@ func (hs *serverHandshakeState) doFullHandshake() error { + func (hs *serverHandshakeState) establishKeys() error { + c := hs.c + +- clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := ++ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV, err := + keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) ++ if err != nil { ++ c.sendAlert(alertInternalError) ++ return err ++ } + + var clientCipher, serverCipher any + var clientHash, serverHash hash.Hash +@@ -779,7 +787,11 @@ func (hs *serverHandshakeState) readFinished(out []byte) error { + return unexpectedMessageError(clientFinished, msg) + } + +- verify := hs.finishedHash.clientSum(hs.masterSecret) ++ verify, err := hs.finishedHash.clientSum(hs.masterSecret) ++ if err != nil { ++ c.sendAlert(alertHandshakeFailure) ++ return err ++ } + if len(verify) != len(clientFinished.verifyData) || + subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { + c.sendAlert(alertHandshakeFailure) +@@ -843,7 +855,10 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error { + } + + finished := new(finishedMsg) +- finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) ++ var err error ++ if finished.verifyData, err = hs.finishedHash.serverSum(hs.masterSecret); err != nil { ++ return err ++ } + if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil { + return err + } diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go index d7f082c9ee1e04..14a85fbf1bd465 100644 --- a/src/crypto/tls/key_schedule.go @@ -751,7 +878,7 @@ index d7f082c9ee1e04..14a85fbf1bd465 100644 } diff --git a/src/crypto/tls/prf.go b/src/crypto/tls/prf.go -index 20bac96e86703b..de4d681151878f 100644 +index 20bac96e86703b..c47391f684dc6f 100644 --- a/src/crypto/tls/prf.go +++ b/src/crypto/tls/prf.go @@ -7,6 +7,7 @@ package tls @@ -804,7 +931,7 @@ index 20bac96e86703b..de4d681151878f 100644 } } -@@ -85,21 +100,23 @@ var keyExpansionLabel = []byte("key expansion") +@@ -85,56 +100,64 @@ var keyExpansionLabel = []byte("key expansion") var clientFinishedLabel = []byte("client finished") var serverFinishedLabel = []byte("server finished") @@ -832,7 +959,56 @@ index 20bac96e86703b..de4d681151878f 100644 prf, _ := prfAndHashForVersion(version, suite) return prf } -@@ -177,7 +194,7 @@ type finishedHash struct { + + // masterFromPreMasterSecret generates the master secret from the pre-master + // secret. See RFC 5246, Section 8.1. +-func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { ++func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) ([]byte, error) { + seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) + seed = append(seed, clientRandom...) + seed = append(seed, serverRandom...) + + masterSecret := make([]byte, masterSecretLength) +- prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed) +- return masterSecret ++ if err := prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed); err != nil { ++ return nil, err ++ } ++ return masterSecret, nil + } + + // extMasterFromPreMasterSecret generates the extended master secret from the + // pre-master secret. See RFC 7627. +-func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) []byte { ++func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) ([]byte, error) { + masterSecret := make([]byte, masterSecretLength) +- prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript) +- return masterSecret ++ if err := prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript); err != nil { ++ return nil, err ++ } ++ return masterSecret, nil + } + + // keysFromMasterSecret generates the connection keys from the master + // secret, given the lengths of the MAC key, cipher key and IV, as defined in + // RFC 2246, Section 6.3. +-func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { ++func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte, err error) { + seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) + seed = append(seed, serverRandom...) + seed = append(seed, clientRandom...) + + n := 2*macLen + 2*keyLen + 2*ivLen + keyMaterial := make([]byte, n) +- prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed) ++ if err = prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed); err != nil { ++ return ++ } + clientMAC = keyMaterial[:macLen] + keyMaterial = keyMaterial[macLen:] + serverMAC = keyMaterial[:macLen] +@@ -177,7 +200,7 @@ type finishedHash struct { buffer []byte version uint16 @@ -841,7 +1017,36 @@ index 20bac96e86703b..de4d681151878f 100644 } func (h *finishedHash) Write(msg []byte) (n int, err error) { -@@ -286,7 +303,11 @@ func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clien +@@ -208,18 +231,22 @@ func (h finishedHash) Sum() []byte { + + // clientSum returns the contents of the verify_data member of a client's + // Finished message. +-func (h finishedHash) clientSum(masterSecret []byte) []byte { ++func (h finishedHash) clientSum(masterSecret []byte) ([]byte, error) { + out := make([]byte, finishedVerifyLength) +- h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) +- return out ++ if err := h.prf(out, masterSecret, clientFinishedLabel, h.Sum()); err != nil { ++ return nil, err ++ } ++ return out, nil + } + + // serverSum returns the contents of the verify_data member of a server's + // Finished message. +-func (h finishedHash) serverSum(masterSecret []byte) []byte { ++func (h finishedHash) serverSum(masterSecret []byte) ([]byte, error) { + out := make([]byte, finishedVerifyLength) +- h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) +- return out ++ if err := h.prf(out, masterSecret, serverFinishedLabel, h.Sum()); err != nil { ++ return nil, err ++ } ++ return out, nil + } + + // hashForClientCertificate returns the handshake messages so far, pre-hashed if +@@ -286,7 +313,11 @@ func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clien } keyMaterial := make([]byte, length) @@ -854,6 +1059,34 @@ index 20bac96e86703b..de4d681151878f 100644 return keyMaterial, nil } } +diff --git a/src/crypto/tls/prf_test.go b/src/crypto/tls/prf_test.go +index 8233985a62bd22..f46d4636557714 100644 +--- a/src/crypto/tls/prf_test.go ++++ b/src/crypto/tls/prf_test.go +@@ -51,13 +51,21 @@ func TestKeysFromPreMasterSecret(t *testing.T) { + clientRandom, _ := hex.DecodeString(test.clientRandom) + serverRandom, _ := hex.DecodeString(test.serverRandom) + +- masterSecret := masterFromPreMasterSecret(test.version, test.suite, in, clientRandom, serverRandom) ++ masterSecret, err := masterFromPreMasterSecret(test.version, test.suite, in, clientRandom, serverRandom) ++ if err != nil { ++ t.Errorf("#%d: masterFromPreMasterSecret failed: %s", i, err) ++ continue ++ } + if s := hex.EncodeToString(masterSecret); s != test.masterSecret { + t.Errorf("#%d: bad master secret %s, want %s", i, s, test.masterSecret) + continue + } + +- clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0) ++ clientMAC, serverMAC, clientKey, serverKey, _, _, err := keysFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0) ++ if err != nil { ++ t.Errorf("#%d: keysFromMasterSecret failed: %s", i, err) ++ continue ++ } + clientMACString := hex.EncodeToString(clientMAC) + serverMACString := hex.EncodeToString(serverMAC) + clientKeyString := hex.EncodeToString(clientKey) diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go index ca0c4089a2e505..4a6d42b18c46bc 100644 --- a/src/go/build/deps_test.go From 0ed41ca57469cc4925ec2a50ead2d9886c413739 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Tue, 26 Sep 2023 15:34:38 +0200 Subject: [PATCH 3/3] upgrade openssl backend --- patches/0004-Add-OpenSSL-crypto-backend.patch | 10 +-- patches/0005-Add-CNG-crypto-backend.patch | 10 +-- patches/0006-Vendor-crypto-backends.patch | 70 +++++++++++-------- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/patches/0004-Add-OpenSSL-crypto-backend.patch b/patches/0004-Add-OpenSSL-crypto-backend.patch index 72a885884fa..bd2f300c30b 100644 --- a/patches/0004-Add-OpenSSL-crypto-backend.patch +++ b/patches/0004-Add-OpenSSL-crypto-backend.patch @@ -651,24 +651,24 @@ index c83a7272c9f01f..a0548a7f9179c5 100644 package x509 diff --git a/src/go.mod b/src/go.mod -index beb4d13d8bdc6f..e7fb80cab94b01 100644 +index beb4d13d8bdc6f..8bc13536fc98c0 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,6 +3,7 @@ module std go 1.22 require ( -+ github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 ++ github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230926133027-251d5fd9efa6 golang.org/x/crypto v0.12.0 golang.org/x/net v0.14.1-0.20230809150940-1e23797619c9 ) diff --git a/src/go.sum b/src/go.sum -index 81b83159f77a36..91eca9cd0b05e6 100644 +index 81b83159f77a36..fca63cfe4a8d1d 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,3 +1,5 @@ -+github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 h1:rTL9t7VhLvvOt4e/EZvXfJISo2igRm7GqK0pX1OQnx8= -+github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230926133027-251d5fd9efa6 h1:htngJbDceHA29WbezaO55msU/iITDkdto1p1iHHmjC0= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230926133027-251d5fd9efa6/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/net v0.14.1-0.20230809150940-1e23797619c9 h1:eQR0jFW5dN2q8lFzSF7rjkRCOOnBf0llczNvITm6ICs= diff --git a/patches/0005-Add-CNG-crypto-backend.patch b/patches/0005-Add-CNG-crypto-backend.patch index 83059d46ba9..5830aab6291 100644 --- a/patches/0005-Add-CNG-crypto-backend.patch +++ b/patches/0005-Add-CNG-crypto-backend.patch @@ -1016,24 +1016,24 @@ index a0548a7f9179c5..ae6117a1554b7f 100644 package x509 diff --git a/src/go.mod b/src/go.mod -index e7fb80cab94b01..9e86277d8e3bbe 100644 +index 8bc13536fc98c0..da1926b3982c3a 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,6 +4,7 @@ go 1.22 require ( - github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 + github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230926133027-251d5fd9efa6 + github.com/microsoft/go-crypto-winnative v0.0.0-20230919193409-4899d534a7ff golang.org/x/crypto v0.12.0 golang.org/x/net v0.14.1-0.20230809150940-1e23797619c9 ) diff --git a/src/go.sum b/src/go.sum -index 91eca9cd0b05e6..d40c2bc8984d29 100644 +index fca63cfe4a8d1d..0c5126e6ced297 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,5 +1,7 @@ - github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 h1:rTL9t7VhLvvOt4e/EZvXfJISo2igRm7GqK0pX1OQnx8= - github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= + github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230926133027-251d5fd9efa6 h1:htngJbDceHA29WbezaO55msU/iITDkdto1p1iHHmjC0= + github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230926133027-251d5fd9efa6/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= +github.com/microsoft/go-crypto-winnative v0.0.0-20230919193409-4899d534a7ff h1:m0Cr4tuDOCmNoHtQV7RRTTH54d5Q9yV2g0AC2SO/7uI= +github.com/microsoft/go-crypto-winnative v0.0.0-20230919193409-4899d534a7ff/go.mod h1:fveERXKbeK+XLmOyU24caKnIT/S5nniAX9XCRHfnrM4= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= diff --git a/patches/0006-Vendor-crypto-backends.patch b/patches/0006-Vendor-crypto-backends.patch index 04363083894..314b1df23f2 100644 --- a/patches/0006-Vendor-crypto-backends.patch +++ b/patches/0006-Vendor-crypto-backends.patch @@ -8,12 +8,12 @@ To reproduce, run 'go mod vendor' in 'go/src'. .../golang-fips/openssl/v2/.gitleaks.toml | 9 + .../github.com/golang-fips/openssl/v2/LICENSE | 20 + .../golang-fips/openssl/v2/README.md | 62 ++ - .../github.com/golang-fips/openssl/v2/aes.go | 84 ++ + .../github.com/golang-fips/openssl/v2/aes.go | 90 ++ .../golang-fips/openssl/v2/bbig/big.go | 37 + .../github.com/golang-fips/openssl/v2/big.go | 11 + .../golang-fips/openssl/v2/cgo_go122.go | 13 + - .../golang-fips/openssl/v2/cipher.go | 509 +++++++++++ - .../github.com/golang-fips/openssl/v2/des.go | 107 +++ + .../golang-fips/openssl/v2/cipher.go | 511 +++++++++++ + .../github.com/golang-fips/openssl/v2/des.go | 113 +++ .../github.com/golang-fips/openssl/v2/ec.go | 59 ++ .../github.com/golang-fips/openssl/v2/ecdh.go | 323 +++++++ .../golang-fips/openssl/v2/ecdsa.go | 217 +++++ @@ -57,7 +57,7 @@ To reproduce, run 'go mod vendor' in 'go/src'. .../internal/subtle/aliasing.go | 32 + .../internal/sysdll/sys_windows.go | 55 ++ src/vendor/modules.txt | 11 + - 52 files changed, 8354 insertions(+) + 52 files changed, 8368 insertions(+) create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/LICENSE create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/README.md @@ -222,10 +222,10 @@ index 00000000000000..e12474e6b54e43 +- The portable OpenSSL implementation is ported from Microsoft's [.NET runtime](https://github.com/dotnet/runtime) cryptography module. 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 00000000000000..ecda35a992410f +index 00000000000000..1fc11f00cdd704 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/aes.go -@@ -0,0 +1,84 @@ +@@ -0,0 +1,90 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -284,11 +284,17 @@ index 00000000000000..ecda35a992410f +} + +func (c *aesCipher) Encrypt(dst, src []byte) { -+ c.encrypt(dst, src) ++ 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) { -+ c.decrypt(dst, src) ++ 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 { @@ -391,10 +397,10 @@ index 00000000000000..555f58c59979a8 +import "C" 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 00000000000000..df6c40f1d9b95b +index 00000000000000..c88286905ee4d8 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go -@@ -0,0 +1,509 @@ +@@ -0,0 +1,511 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -563,57 +569,59 @@ index 00000000000000..df6c40f1d9b95b + } +} + -+func (c *evpCipher) encrypt(dst, src []byte) { ++func (c *evpCipher) encrypt(dst, src []byte) error { + if len(src) < c.blockSize { -+ panic("crypto/cipher: input not full block") ++ return errors.New("input not full block") + } + if len(dst) < c.blockSize { -+ panic("crypto/cipher: output not full block") ++ 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]) { -+ panic("crypto/cipher: invalid buffer overlap") ++ 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 { -+ panic(err) ++ return err + } + } + + if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), C.int(c.blockSize)) != 1 { -+ panic("crypto/cipher: EncryptUpdate failed") ++ return errors.New("EncryptUpdate failed") + } + runtime.KeepAlive(c) ++ return nil +} + -+func (c *evpCipher) decrypt(dst, src []byte) { ++func (c *evpCipher) decrypt(dst, src []byte) error { + if len(src) < c.blockSize { -+ panic("crypto/cipher: input not full block") ++ return errors.New("input not full block") + } + if len(dst) < c.blockSize { -+ panic("crypto/cipher: output not full block") ++ 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]) { -+ panic("crypto/cipher: invalid buffer overlap") ++ 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 { -+ panic(err) ++ return err + } + if C.go_openssl_EVP_CIPHER_CTX_set_padding(c.dec_ctx, 0) != 1 { -+ panic("crypto/cipher: could not disable cipher padding") ++ 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 { @@ -906,10 +914,10 @@ index 00000000000000..df6c40f1d9b95b +} 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 00000000000000..5f5e3748899a78 +index 00000000000000..98b15d2d208a22 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/des.go -@@ -0,0 +1,107 @@ +@@ -0,0 +1,113 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -987,11 +995,17 @@ index 00000000000000..5f5e3748899a78 +} + +func (c *desCipher) Encrypt(dst, src []byte) { -+ c.encrypt(dst, src) ++ if err := c.encrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } +} + +func (c *desCipher) Decrypt(dst, src []byte) { -+ c.decrypt(dst, src) ++ 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 { @@ -8762,11 +8776,11 @@ index 00000000000000..1722410e5af193 + return getSystemDirectory() + "\\" + dll +} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index abd3f0b5193381..e62e6149066c22 100644 +index abd3f0b5193381..929469ecc4d448 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,14 @@ -+# github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230919070839-9783f40bfa74 ++# github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20230926133027-251d5fd9efa6 +## explicit; go 1.20 +github.com/golang-fips/openssl/v2 +github.com/golang-fips/openssl/v2/bbig