From 857f3abbed51d851177a04a3071e0900f5dddb88 Mon Sep 17 00:00:00 2001 From: George Adams Date: Wed, 18 Dec 2024 16:19:59 +0000 Subject: [PATCH 1/8] initial implementation of macOS crypto backend --- eng/_util/buildutil/buildutil.go | 1 + .../stages/go-builder-matrix-stages.yml | 3 + .../0001-Add-systemcrypto-GOEXPERIMENT.patch | 64 +- .../0002-Add-crypto-backend-foundation.patch | 42 +- .../0003-Add-BoringSSL-crypto-backend.patch | 16 +- patches/0004-Add-OpenSSL-crypto-backend.patch | 20 +- patches/0005-Add-CNG-crypto-backend.patch | 22 +- patches/0006-Add-Darwin-crypto-backend.patch | 797 ++++++++++++++++++ ...atch => 0007-Vendor-crypto-backends.patch} | 35 +- ....patch => 0008-Add-backend-code-gen.patch} | 121 ++- ...patch => 0009-Update-default-go.env.patch} | 0 ... 0010-Skip-failing-tests-on-Windows.patch} | 0 ...OFIPS-when-running-the-Go-toolchain.patch} | 0 ...pport-for-logging-used-Windows-APIs.patch} | 0 ... 0013-remove-long-path-support-hack.patch} | 0 ...ernal-go.mod-files-used-for-codegen.patch} | 0 ...21-when-TLS-fipsonly-mode-is-enable.patch} | 0 17 files changed, 1043 insertions(+), 78 deletions(-) create mode 100644 patches/0006-Add-Darwin-crypto-backend.patch rename patches/{0006-Vendor-crypto-backends.patch => 0007-Vendor-crypto-backends.patch} (99%) rename patches/{0007-Add-backend-code-gen.patch => 0008-Add-backend-code-gen.patch} (83%) rename patches/{0008-Update-default-go.env.patch => 0009-Update-default-go.env.patch} (100%) rename patches/{0009-Skip-failing-tests-on-Windows.patch => 0010-Skip-failing-tests-on-Windows.patch} (100%) rename patches/{0010-unset-GOFIPS-when-running-the-Go-toolchain.patch => 0011-unset-GOFIPS-when-running-the-Go-toolchain.patch} (100%) rename patches/{0011-add-support-for-logging-used-Windows-APIs.patch => 0012-add-support-for-logging-used-Windows-APIs.patch} (100%) rename patches/{0012-remove-long-path-support-hack.patch => 0013-remove-long-path-support-hack.patch} (100%) rename patches/{0013-Omit-internal-go.mod-files-used-for-codegen.patch => 0014-Omit-internal-go.mod-files-used-for-codegen.patch} (100%) rename patches/{0014-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch => 0015-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch} (100%) diff --git a/eng/_util/buildutil/buildutil.go b/eng/_util/buildutil/buildutil.go index 4de7511bf5c..d8e705415af 100644 --- a/eng/_util/buildutil/buildutil.go +++ b/eng/_util/buildutil/buildutil.go @@ -91,6 +91,7 @@ func AppendExperimentEnv(experiment string) { if strings.Contains(experiment, "opensslcrypto") || strings.Contains(experiment, "cngcrypto") || strings.Contains(experiment, "boringcrypto") || + strings.Contains(experiment, "darwincrypto") || strings.Contains(experiment, "systemcrypto") { experiment += ",allowcryptofallback" diff --git a/eng/pipeline/stages/go-builder-matrix-stages.yml b/eng/pipeline/stages/go-builder-matrix-stages.yml index 3d0827fa482..e200cf15311 100644 --- a/eng/pipeline/stages/go-builder-matrix-stages.yml +++ b/eng/pipeline/stages/go-builder-matrix-stages.yml @@ -81,6 +81,9 @@ stages: - { os: linux, arch: arm64, config: buildandpack } - ${{ if parameters.innerloop }}: - { os: darwin, arch: amd64, config: devscript } + - { os: darwin, arch: amd64, config: test } + - { experiment: darwincrypto, os: darwin, arch: amd64, config: test } + - { experiment: darwincrypto, os: darwin, arch: amd64, config: test, fips: true } - { os: linux, arch: amd64, config: devscript } - { os: linux, arch: amd64, config: test } - { os: linux, arch: amd64, config: test, distro: ubuntu } diff --git a/patches/0001-Add-systemcrypto-GOEXPERIMENT.patch b/patches/0001-Add-systemcrypto-GOEXPERIMENT.patch index 1c2e50368f3..594dd0236d2 100644 --- a/patches/0001-Add-systemcrypto-GOEXPERIMENT.patch +++ b/patches/0001-Add-systemcrypto-GOEXPERIMENT.patch @@ -11,18 +11,18 @@ information about the behavior. Includes new tests in "build_test.go" and "buildbackend_test.go" to help maintain this feature. For more information, see the test files. --- - src/cmd/go/internal/modindex/build.go | 54 ++++++++++++++ - src/cmd/go/internal/modindex/build_test.go | 73 +++++++++++++++++++ - src/go/build/build.go | 54 ++++++++++++++ - src/go/build/buildbackend_test.go | 66 +++++++++++++++++ + src/cmd/go/internal/modindex/build.go | 57 +++++++++++++ + src/cmd/go/internal/modindex/build_test.go | 73 ++++++++++++++++ + src/go/build/build.go | 57 +++++++++++++ + src/go/build/buildbackend_test.go | 84 +++++++++++++++++++ .../testdata/backendtags_openssl/main.go | 3 + .../testdata/backendtags_openssl/openssl.go | 3 + .../build/testdata/backendtags_system/main.go | 3 + .../backendtags_system/systemcrypto.go | 3 + - .../goexperiment/exp_systemcrypto_off.go | 9 +++ - .../goexperiment/exp_systemcrypto_on.go | 9 +++ + .../goexperiment/exp_systemcrypto_off.go | 9 ++ + .../goexperiment/exp_systemcrypto_on.go | 9 ++ src/internal/goexperiment/flags.go | 15 ++++ - 11 files changed, 292 insertions(+) + 11 files changed, 316 insertions(+) create mode 100644 src/cmd/go/internal/modindex/build_test.go create mode 100644 src/go/build/buildbackend_test.go create mode 100644 src/go/build/testdata/backendtags_openssl/main.go @@ -33,16 +33,17 @@ maintain this feature. For more information, see the test files. create mode 100644 src/internal/goexperiment/exp_systemcrypto_on.go diff --git a/src/cmd/go/internal/modindex/build.go b/src/cmd/go/internal/modindex/build.go -index b57f2f6368f0fe..9ddde1ce9a2286 100644 +index b4dacb0f523a8d..4315c288d10cb3 100644 --- a/src/cmd/go/internal/modindex/build.go +++ b/src/cmd/go/internal/modindex/build.go -@@ -880,13 +880,67 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool { +@@ -886,13 +886,70 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool { name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto } + const system = "goexperiment.systemcrypto" + const openssl = "goexperiment.opensslcrypto" + const cng = "goexperiment.cngcrypto" ++ const darwin = "goexperiment.darwincrypto" + const boring = "goexperiment.boringcrypto" + // Implement the SystemCrypto GOEXPERIMENT logic. This is done here rather + // than during GOEXPERIMENT parsing so "-tags goexperiment.systemcrypto" @@ -63,11 +64,12 @@ index b57f2f6368f0fe..9ddde1ce9a2286 100644 + satisfiedByAnyBackend := name == system + satisfiedBySystemCrypto := + (ctxt.GOOS == "linux" && name == openssl) || -+ (ctxt.GOOS == "windows" && name == cng) ++ (ctxt.GOOS == "windows" && name == cng) || ++ (ctxt.GOOS == "darwin" && name == darwin) + satisfiedBy := func(tag string) bool { + if satisfiedByAnyBackend { + switch tag { -+ case openssl, cng, boring: ++ case openssl, cng, darwin, boring: + return true + } + } @@ -81,6 +83,7 @@ index b57f2f6368f0fe..9ddde1ce9a2286 100644 + if satisfiedByAnyBackend { + allTags[openssl] = true + allTags[cng] = true ++ allTags[darwin] = true + allTags[boring] = true + } + if satisfiedBySystemCrypto { @@ -184,16 +187,17 @@ index 00000000000000..1756c5d027fee0 + } +} diff --git a/src/go/build/build.go b/src/go/build/build.go -index dd6cdc903a21a8..48adcfed5cf3cb 100644 +index 9ffffda08a99b1..78fd536fa6a6d1 100644 --- a/src/go/build/build.go +++ b/src/go/build/build.go -@@ -1947,13 +1947,67 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool { +@@ -1984,13 +1984,70 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool { name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto } + const system = "goexperiment.systemcrypto" + const openssl = "goexperiment.opensslcrypto" + const cng = "goexperiment.cngcrypto" ++ const darwin = "goexperiment.darwincrypto" + const boring = "goexperiment.boringcrypto" + // Implement the SystemCrypto GOEXPERIMENT logic. This is done here rather + // than during GOEXPERIMENT parsing so "-tags goexperiment.systemcrypto" @@ -214,11 +218,12 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644 + satisfiedByAnyBackend := name == system + satisfiedBySystemCrypto := + (ctxt.GOOS == "linux" && name == openssl) || -+ (ctxt.GOOS == "windows" && name == cng) ++ (ctxt.GOOS == "windows" && name == cng) || ++ (ctxt.GOOS == "darwin" && name == darwin) + satisfiedBy := func(tag string) bool { + if satisfiedByAnyBackend { + switch tag { -+ case openssl, cng, boring: ++ case openssl, cng, darwin, boring: + return true + } + } @@ -232,6 +237,7 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644 + if satisfiedByAnyBackend { + allTags[openssl] = true + allTags[cng] = true ++ allTags[darwin] = true + allTags[boring] = true + } + if satisfiedBySystemCrypto { @@ -257,10 +263,10 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644 } diff --git a/src/go/build/buildbackend_test.go b/src/go/build/buildbackend_test.go new file mode 100644 -index 00000000000000..a22abbb42e37c0 +index 00000000000000..aa3c5f1007ed79 --- /dev/null +++ b/src/go/build/buildbackend_test.go -@@ -0,0 +1,66 @@ +@@ -0,0 +1,84 @@ +// Copyright 2023 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. @@ -318,7 +324,7 @@ index 00000000000000..a22abbb42e37c0 + if err != nil { + t.Fatal(err) + } -+ want = []string{"goexperiment.boringcrypto", "goexperiment.cngcrypto", "goexperiment.opensslcrypto", "goexperiment.systemcrypto"} ++ want = []string{"goexperiment.boringcrypto", "goexperiment.cngcrypto", "goexperiment.darwincrypto", "goexperiment.opensslcrypto", "goexperiment.systemcrypto"} + if !reflect.DeepEqual(p.AllTags, want) { + t.Errorf("AllTags = %v, want %v", p.AllTags, want) + } @@ -326,6 +332,24 @@ index 00000000000000..a22abbb42e37c0 + if !reflect.DeepEqual(p.GoFiles, wantFiles) { + t.Errorf("GoFiles = %v, want %v", p.GoFiles, wantFiles) + } ++ ++ ctxt.GOARCH = "amd64" ++ ctxt.GOOS = "darwin" ++ ctxt.BuildTags = []string{"goexperiment.darwincrypto"} ++ p, err = ctxt.ImportDir("testdata/backendtags_openssl", 0) ++ if err != nil { ++ t.Fatal(err) ++ } ++ // Given the current GOOS (darwin), systemcrypto would not affect the ++ // decision, so we don't want it to be included in AllTags. ++ want = []string{"goexperiment.opensslcrypto"} ++ if !reflect.DeepEqual(p.AllTags, want) { ++ t.Errorf("AllTags = %v, want %v", p.AllTags, want) ++ } ++ wantFiles = []string{"main.go"} ++ if !reflect.DeepEqual(p.GoFiles, wantFiles) { ++ t.Errorf("GoFiles = %v, want %v", p.GoFiles, wantFiles) ++ } +} diff --git a/src/go/build/testdata/backendtags_openssl/main.go b/src/go/build/testdata/backendtags_openssl/main.go new file mode 100644 @@ -394,14 +418,14 @@ index 00000000000000..9c5b0bbc7b99dc +const SystemCrypto = true +const SystemCryptoInt = 1 diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go -index ae3cbaf89fa5dd..de79140b2d4780 100644 +index 31b3d0315b64f8..de1dfa6e567a71 100644 --- a/src/internal/goexperiment/flags.go +++ b/src/internal/goexperiment/flags.go @@ -60,6 +60,21 @@ type Flags struct { StaticLockRanking bool BoringCrypto bool -+ // SystemCrypto enables the OpenSSL or CNG crypto experiment depending on ++ // SystemCrypto enables the OpenSSL, CNG or Darwin crypto experiment depending on + // which one is appropriate on the target GOOS. + // + // If SystemCrypto is enabled but no crypto experiment is appropriate on the diff --git a/patches/0002-Add-crypto-backend-foundation.patch b/patches/0002-Add-crypto-backend-foundation.patch index a9ae91f13d4..01618d7be7b 100644 --- a/patches/0002-Add-crypto-backend-foundation.patch +++ b/patches/0002-Add-crypto-backend-foundation.patch @@ -590,7 +590,7 @@ index 039bd82ed21f9f..69a97d9bf250be 100644 panic("boringcrypto: not available") diff --git a/src/crypto/ed25519/boring.go b/src/crypto/ed25519/boring.go new file mode 100644 -index 00000000000000..3a7d7b76c8d8d7 +index 00000000000000..ff5c426b4fdaea --- /dev/null +++ b/src/crypto/ed25519/boring.go @@ -0,0 +1,71 @@ @@ -619,11 +619,11 @@ index 00000000000000..3a7d7b76c8d8d7 +} + +type boringPub struct { -+ key *boring.PublicKeyEd25519 ++ key boring.PublicKeyEd25519 + orig [PublicKeySize]byte +} + -+func boringPublicKey(pub PublicKey) (*boring.PublicKeyEd25519, error) { ++func boringPublicKey(pub PublicKey) (boring.PublicKeyEd25519, error) { + // Use the pointer to the underlying pub array as key. + p := unsafe.SliceData(pub) + b := pubCache.Get(p) @@ -635,7 +635,7 @@ index 00000000000000..3a7d7b76c8d8d7 + copy(b.orig[:], pub) + key, err := boring.NewPublicKeyEd25119(b.orig[:]) + if err != nil { -+ return nil, err ++ return key, err + } + b.key = key + pubCache.Put(p, b) @@ -643,11 +643,11 @@ index 00000000000000..3a7d7b76c8d8d7 +} + +type boringPriv struct { -+ key *boring.PrivateKeyEd25519 ++ key boring.PrivateKeyEd25519 + orig [PrivateKeySize]byte +} + -+func boringPrivateKey(priv PrivateKey) (*boring.PrivateKeyEd25519, error) { ++func boringPrivateKey(priv PrivateKey) (boring.PrivateKeyEd25519, error) { + // Use the pointer to the underlying priv array as key. + p := unsafe.SliceData(priv) + b := privCache.Get(p) @@ -659,7 +659,7 @@ index 00000000000000..3a7d7b76c8d8d7 + copy(b.orig[:], priv) + key, err := boring.NewPrivateKeyEd25119(b.orig[:]) + if err != nil { -+ return nil, err ++ return key, err + } + b.key = key + privCache.Put(p, b) @@ -793,7 +793,7 @@ index c1f8ff784e4a5c..308d814ff6302b 100644 return errors.New("ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)") diff --git a/src/crypto/ed25519/notboring.go b/src/crypto/ed25519/notboring.go new file mode 100644 -index 00000000000000..b0cdd44d81c753 +index 00000000000000..77b69a3be88183 --- /dev/null +++ b/src/crypto/ed25519/notboring.go @@ -0,0 +1,16 @@ @@ -807,10 +807,10 @@ index 00000000000000..b0cdd44d81c753 + +import boring "crypto/internal/backend" + -+func boringPublicKey(PublicKey) (*boring.PublicKeyEd25519, error) { ++func boringPublicKey(PublicKey) (boring.PublicKeyEd25519, error) { + panic("boringcrypto: not available") +} -+func boringPrivateKey(PrivateKey) (*boring.PrivateKeyEd25519, error) { ++func boringPrivateKey(PrivateKey) (boring.PrivateKeyEd25519, error) { + panic("boringcrypto: not available") +} diff --git a/src/crypto/hkdf/hkdf.go b/src/crypto/hkdf/hkdf.go @@ -936,7 +936,7 @@ index 00000000000000..c2c06d3bff8c74 +} diff --git a/src/crypto/internal/backend/bbig/big.go b/src/crypto/internal/backend/bbig/big.go new file mode 100644 -index 00000000000000..20251a290dc2e0 +index 00000000000000..ab3f30825dcfa1 --- /dev/null +++ b/src/crypto/internal/backend/bbig/big.go @@ -0,0 +1,17 @@ @@ -944,7 +944,7 @@ index 00000000000000..20251a290dc2e0 +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + -+//go:build !goexperiment.systemcrypto ++//go:build !goexperiment.systemcrypto || (goexperiment.darwincrypto && !cgo) + +package bbig + @@ -1148,7 +1148,7 @@ index 00000000000000..83691d7dd42d51 +} diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go new file mode 100644 -index 00000000000000..71e0ec9dc25a02 +index 00000000000000..06e19c55345187 --- /dev/null +++ b/src/crypto/internal/backend/nobackend.go @@ -0,0 +1,229 @@ @@ -1317,37 +1317,37 @@ index 00000000000000..71e0ec9dc25a02 + +type PublicKeyEd25519 struct{} + -+func (k *PublicKeyEd25519) Bytes() ([]byte, error) { ++func (k PublicKeyEd25519) Bytes() ([]byte, error) { + panic("cryptobackend: not available") +} + +type PrivateKeyEd25519 struct{} + -+func (k *PrivateKeyEd25519) Bytes() ([]byte, error) { ++func (k PrivateKeyEd25519) Bytes() ([]byte, error) { + panic("cryptobackend: not available") +} + -+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) { ++func GenerateKeyEd25519() (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { ++func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) { ++func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) { + panic("cryptobackend: not available") +} + -+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error { ++func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error { + panic("cryptobackend: not available") +} + diff --git a/patches/0003-Add-BoringSSL-crypto-backend.patch b/patches/0003-Add-BoringSSL-crypto-backend.patch index d60a06344d5..60576d523a2 100644 --- a/patches/0003-Add-BoringSSL-crypto-backend.patch +++ b/patches/0003-Add-BoringSSL-crypto-backend.patch @@ -235,37 +235,37 @@ index 00000000000000..b1bd6d5ba756d7 + +type PublicKeyEd25519 struct{} + -+func (k *PublicKeyEd25519) Bytes() ([]byte, error) { ++func (k PublicKeyEd25519) Bytes() ([]byte, error) { + panic("cryptobackend: not available") +} + +type PrivateKeyEd25519 struct{} + -+func (k *PrivateKeyEd25519) Bytes() ([]byte, error) { ++func (k PrivateKeyEd25519) Bytes() ([]byte, error) { + panic("cryptobackend: not available") +} + -+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) { ++func GenerateKeyEd25519() (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { ++func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) { ++func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) { + panic("cryptobackend: not available") +} + -+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error { ++func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error { + panic("cryptobackend: not available") +} + diff --git a/patches/0004-Add-OpenSSL-crypto-backend.patch b/patches/0004-Add-OpenSSL-crypto-backend.patch index 2653fef1da7..4b81b1b0e92 100644 --- a/patches/0004-Add-OpenSSL-crypto-backend.patch +++ b/patches/0004-Add-OpenSSL-crypto-backend.patch @@ -404,30 +404,30 @@ index 00000000000000..d3a663737a1ce3 + +func SupportsEd25519() bool { return openssl.SupportsEd25519() } + -+type PublicKeyEd25519 = openssl.PublicKeyEd25519 -+type PrivateKeyEd25519 = openssl.PrivateKeyEd25519 ++type PublicKeyEd25519 = *openssl.PublicKeyEd25519 ++type PrivateKeyEd25519 = *openssl.PrivateKeyEd25519 + -+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) { ++func GenerateKeyEd25519() (PrivateKeyEd25519, error) { + return openssl.GenerateKeyEd25519() +} + -+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) { + return openssl.NewPrivateKeyEd25119(priv) +} + -+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { ++func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) { + return openssl.NewPublicKeyEd25119(pub) +} + -+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) { + return openssl.NewPrivateKeyEd25519FromSeed(seed) +} + -+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) { ++func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) { + return openssl.SignEd25519(priv, message) +} + -+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error { ++func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error { + return openssl.VerifyEd25519(pub, message, sig) +} + @@ -602,7 +602,7 @@ index 00000000000000..a7f2712e9e1464 +const OpenSSLCrypto = true +const OpenSSLCryptoInt = 1 diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go -index e126e388e84025..233a12ee542328 100644 +index de1dfa6e567a71..d56306bf10a356 100644 --- a/src/internal/goexperiment/flags.go +++ b/src/internal/goexperiment/flags.go @@ -59,6 +59,7 @@ type Flags struct { @@ -611,7 +611,7 @@ index e126e388e84025..233a12ee542328 100644 BoringCrypto bool + OpenSSLCrypto bool - // SystemCrypto enables the OpenSSL or CNG crypto experiment depending on + // SystemCrypto enables the OpenSSL, CNG or Darwin 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 8c623871932f7d..2fa55073f5c19c 100644 diff --git a/patches/0005-Add-CNG-crypto-backend.patch b/patches/0005-Add-CNG-crypto-backend.patch index 8019bd12e7a..06b384201b5 100644 --- a/patches/0005-Add-CNG-crypto-backend.patch +++ b/patches/0005-Add-CNG-crypto-backend.patch @@ -84,7 +84,7 @@ 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..c37247c8a2c7c6 +index 00000000000000..8b5416f5be0955 --- /dev/null +++ b/src/crypto/internal/backend/cng_windows.go @@ -0,0 +1,316 @@ @@ -335,37 +335,37 @@ index 00000000000000..c37247c8a2c7c6 + +type PublicKeyEd25519 struct{} + -+func (k *PublicKeyEd25519) Bytes() ([]byte, error) { ++func (k PublicKeyEd25519) Bytes() ([]byte, error) { + panic("cryptobackend: not available") +} + +type PrivateKeyEd25519 struct{} + -+func (k *PrivateKeyEd25519) Bytes() ([]byte, error) { ++func (k PrivateKeyEd25519) Bytes() ([]byte, error) { + panic("cryptobackend: not available") +} + -+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) { ++func GenerateKeyEd25519() (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { ++func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { ++func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) { + panic("cryptobackend: not available") +} + -+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) { ++func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) { + panic("cryptobackend: not available") +} + -+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error { ++func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error { + panic("cryptobackend: not available") +} + @@ -572,7 +572,7 @@ index 00000000000000..99ee2542ca38a9 +const CNGCrypto = true +const CNGCryptoInt = 1 diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go -index 233a12ee542328..8c140f0dbed134 100644 +index d56306bf10a356..c6f64c18bdd13f 100644 --- a/src/internal/goexperiment/flags.go +++ b/src/internal/goexperiment/flags.go @@ -60,6 +60,7 @@ type Flags struct { @@ -581,5 +581,5 @@ index 233a12ee542328..8c140f0dbed134 100644 OpenSSLCrypto bool + CNGCrypto bool - // SystemCrypto enables the OpenSSL or CNG crypto experiment depending on + // SystemCrypto enables the OpenSSL, CNG or Darwin crypto experiment depending on // which one is appropriate on the target GOOS. diff --git a/patches/0006-Add-Darwin-crypto-backend.patch b/patches/0006-Add-Darwin-crypto-backend.patch new file mode 100644 index 00000000000..19186e0c65e --- /dev/null +++ b/patches/0006-Add-Darwin-crypto-backend.patch @@ -0,0 +1,797 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: George Adams +Date: Tue, 17 Dec 2024 13:17:39 +0000 +Subject: [PATCH] Add Darwin crypto backend + +--- + src/crypto/ecdsa/ecdsa.go | 6 +- + src/crypto/ed25519/ed25519_test.go | 3 +- + .../internal/backend/bbig/big_darwin.go | 12 + + src/crypto/internal/backend/common.go | 36 +- + src/crypto/internal/backend/darwin_darwin.go | 326 ++++++++++++++++++ + src/crypto/internal/backend/fips140/darwin.go | 11 + + src/crypto/rsa/boring.go | 7 +- + src/crypto/rsa/darwin.go | 71 ++++ + src/crypto/rsa/fips.go | 10 +- + src/crypto/rsa/pss_test.go | 5 +- + src/go.mod | 1 + + src/go.sum | 2 + + src/go/build/deps_test.go | 5 +- + src/go/build/vendor_test.go | 1 + + .../goexperiment/exp_darwincrypto_off.go | 9 + + .../goexperiment/exp_darwincrypto_on.go | 9 + + src/internal/goexperiment/flags.go | 1 + + 17 files changed, 502 insertions(+), 13 deletions(-) + create mode 100644 src/crypto/internal/backend/bbig/big_darwin.go + create mode 100644 src/crypto/internal/backend/darwin_darwin.go + create mode 100644 src/crypto/internal/backend/fips140/darwin.go + create mode 100644 src/crypto/rsa/darwin.go + create mode 100644 src/internal/goexperiment/exp_darwincrypto_off.go + create mode 100644 src/internal/goexperiment/exp_darwincrypto_on.go + +diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go +index 41ac17df22d7d7..84a7ba02c88620 100644 +--- a/src/crypto/ecdsa/ecdsa.go ++++ b/src/crypto/ecdsa/ecdsa.go +@@ -159,7 +159,7 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp + func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) { + randutil.MaybeReadByte(rand) + +- if boring.Enabled && rand == boring.RandReader { ++ if boring.Enabled && rand == boring.RandReader && boring.IsCurveSupported(c.Params().Name) { + x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name) + if err != nil { + return nil, err +@@ -208,7 +208,7 @@ var errNoAsm = errors.New("no assembly implementation available") + func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { + randutil.MaybeReadByte(rand) + +- if boring.Enabled && rand == boring.RandReader { ++ if boring.Enabled && rand == boring.RandReader && boring.IsCurveSupported(priv.Curve.Params().Name) { + b, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -319,7 +319,7 @@ func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) { + // The inputs are not considered confidential, and may leak through timing side + // channels, or if an attacker has control of part of the inputs. + func VerifyASN1(pub *PublicKey, hash, sig []byte) bool { +- if boring.Enabled { ++ if boring.Enabled && boring.IsCurveSupported(pub.Curve.Params().Name) { + key, err := boringPublicKey(pub) + if err != nil { + return false +diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go +index 87d0132df11d8b..00dd5224a70418 100644 +--- a/src/crypto/ed25519/ed25519_test.go ++++ b/src/crypto/ed25519/ed25519_test.go +@@ -13,6 +13,7 @@ import ( + "crypto/rand" + "crypto/sha512" + "encoding/hex" ++ "internal/goexperiment" + "log" + "os" + "strings" +@@ -316,7 +317,7 @@ func TestGolden(t *testing.T) { + copy(priv[32:], pubKey) + + sig2 := Sign(priv[:], msg) +- if !bytes.Equal(sig, sig2[:]) { ++ if !bytes.Equal(sig, sig2[:]) && !goexperiment.DarwinCrypto { + t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) + } + +diff --git a/src/crypto/internal/backend/bbig/big_darwin.go b/src/crypto/internal/backend/bbig/big_darwin.go +new file mode 100644 +index 00000000000000..77f3ca5d262769 +--- /dev/null ++++ b/src/crypto/internal/backend/bbig/big_darwin.go +@@ -0,0 +1,12 @@ ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build goexperiment.darwincrypto && cgo ++ ++package bbig ++ ++import "github.com/microsoft/go-crypto-darwin/bbig" ++ ++var Enc = bbig.Enc ++var Dec = bbig.Dec +diff --git a/src/crypto/internal/backend/common.go b/src/crypto/internal/backend/common.go +index 91223c0ef0f810..d27bfee89e2534 100644 +--- a/src/crypto/internal/backend/common.go ++++ b/src/crypto/internal/backend/common.go +@@ -5,6 +5,7 @@ + package backend + + import ( ++ "crypto" + "crypto/internal/backend/fips140" + "crypto/internal/boring/sig" + "internal/goexperiment" +@@ -14,7 +15,7 @@ import ( + func init() { + if fips140.Enabled() { + if !Enabled { +- if runtime.GOOS != "linux" && runtime.GOOS != "windows" { ++ if runtime.GOOS != "linux" && runtime.GOOS != "windows" && runtime.GOOS != "darwin" { + panic("FIPS mode requested (" + fips140.Message + ") but no crypto backend is supported on " + runtime.GOOS) + } + panic("FIPS mode requested (" + fips140.Message + ") but no supported crypto backend is enabled") +@@ -75,5 +76,38 @@ func IsSaltSupported(salt int) bool { + if goexperiment.CNGCrypto { + return salt != 0 // rsa.PSSSaltLengthAuto + } ++ if goexperiment.DarwinCrypto { ++ return salt == -1 // CommonCrypto doesn't support custom salt length ++ } ++ return true ++} ++ ++func IsCurveSupported(curve string) bool { ++ switch curve { ++ case "P-256", "P-384", "P-521": ++ return true ++ case "P-224": ++ return !goexperiment.DarwinCrypto ++ } ++ return false ++} ++ ++func IsRSAOAEPLabelSupported(label []byte) bool { ++ if goexperiment.DarwinCrypto { ++ // CommonCrypto doesn't support labels ++ // https://github.com/microsoft/go-crypto-darwin/issues/22 ++ return len(label) == 0 ++ } ++ return true ++} ++ ++func IsPKCS1v15HashSupported(hash crypto.Hash) bool { ++ if goexperiment.DarwinCrypto { ++ switch hash { ++ case crypto.SHA1, crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512, 0: ++ return true ++ } ++ return false ++ } + return true + } +diff --git a/src/crypto/internal/backend/darwin_darwin.go b/src/crypto/internal/backend/darwin_darwin.go +new file mode 100644 +index 00000000000000..45ec6c83d669c7 +--- /dev/null ++++ b/src/crypto/internal/backend/darwin_darwin.go +@@ -0,0 +1,326 @@ ++// Copyright 2017 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build goexperiment.darwincrypto && darwin && cgo ++ ++// Package darwin provides access to DarwinCrypto implementation functions. ++// Check the variable Enabled to find out whether DarwinCrypto is available. ++// If DarwinCrypto is not available, the functions in this package all panic. ++package backend ++ ++import ( ++ "crypto" ++ "crypto/cipher" ++ "crypto/internal/boring/sig" ++ "crypto/internal/fips140/nistec" ++ "errors" ++ "hash" ++ _ "unsafe" ++ ++ "github.com/microsoft/go-crypto-darwin/xcrypto" ++) ++ ++// Enabled controls whether FIPS crypto is enabled. ++const Enabled = true ++ ++type BigInt = xcrypto.BigInt ++ ++func init() { ++ sig.BoringCrypto() ++} ++ ++const RandReader = xcrypto.RandReader ++ ++func SupportsHash(h crypto.Hash) bool { ++ return xcrypto.SupportsHash(h) ++} ++ ++func NewMD5() hash.Hash { return xcrypto.NewMD5() } ++func NewSHA1() hash.Hash { return xcrypto.NewSHA1() } ++func NewSHA224() hash.Hash { return xcrypto.NewSHA224() } ++func NewSHA256() hash.Hash { return xcrypto.NewSHA256() } ++func NewSHA384() hash.Hash { return xcrypto.NewSHA384() } ++func NewSHA512() hash.Hash { return xcrypto.NewSHA512() } ++ ++func MD5(p []byte) (sum [16]byte) { return xcrypto.MD5(p) } ++func SHA1(p []byte) (sum [20]byte) { return xcrypto.SHA1(p) } ++func SHA224(p []byte) (sum [28]byte) { return xcrypto.SHA224(p) } ++func SHA256(p []byte) (sum [32]byte) { return xcrypto.SHA256(p) } ++func SHA384(p []byte) (sum [48]byte) { return xcrypto.SHA384(p) } ++func SHA512(p []byte) (sum [64]byte) { return xcrypto.SHA512(p) } ++ ++func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { ++ return xcrypto.NewHMAC(h, key) ++} ++ ++func NewAESCipher(key []byte) (cipher.Block, error) { ++ return xcrypto.NewAESCipher(key) ++} ++ ++func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { ++ return xcrypto.NewGCMTLS(c) ++} ++ ++func NewGCMTLS13(c cipher.Block) (cipher.AEAD, error) { ++ return xcrypto.NewGCMTLS13(c) ++} ++ ++type PublicKeyECDSA = xcrypto.PublicKeyECDSA ++type PrivateKeyECDSA = xcrypto.PrivateKeyECDSA ++ ++func GenerateKeyECDSA(curve string) (X, Y, D xcrypto.BigInt, err error) { ++ return xcrypto.GenerateKeyECDSA(curve) ++} ++ ++func NewPrivateKeyECDSA(curve string, X, Y, D xcrypto.BigInt) (*xcrypto.PrivateKeyECDSA, error) { ++ return xcrypto.NewPrivateKeyECDSA(curve, X, Y, D) ++} ++ ++func NewPublicKeyECDSA(curve string, X, Y xcrypto.BigInt) (*xcrypto.PublicKeyECDSA, error) { ++ return xcrypto.NewPublicKeyECDSA(curve, X, Y) ++} ++ ++//go:linkname encodeSignature crypto/ecdsa.encodeSignature ++func encodeSignature(r, s []byte) ([]byte, error) ++ ++//go:linkname parseSignature crypto/ecdsa.parseSignature ++func parseSignature(sig []byte) (r, s []byte, err error) ++ ++func SignMarshalECDSA(priv *xcrypto.PrivateKeyECDSA, hash []byte) ([]byte, error) { ++ return xcrypto.SignMarshalECDSA(priv, hash) ++} ++ ++func VerifyECDSA(pub *xcrypto.PublicKeyECDSA, hash []byte, sig []byte) bool { ++ return xcrypto.VerifyECDSA(pub, hash, sig) ++} ++ ++type PublicKeyRSA = xcrypto.PublicKeyRSA ++type PrivateKeyRSA = xcrypto.PrivateKeyRSA ++ ++func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *xcrypto.PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ return xcrypto.DecryptRSAOAEP(h, priv, ciphertext, label) ++} ++ ++func DecryptRSAPKCS1(priv *xcrypto.PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return xcrypto.DecryptRSAPKCS1(priv, ciphertext) ++} ++ ++func DecryptRSANoPadding(priv *xcrypto.PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return xcrypto.DecryptRSANoPadding(priv, ciphertext) ++} ++ ++func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *xcrypto.PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ return xcrypto.EncryptRSAOAEP(h, pub, msg, label) ++} ++ ++func EncryptRSAPKCS1(pub *xcrypto.PublicKeyRSA, msg []byte) ([]byte, error) { ++ return xcrypto.EncryptRSAPKCS1(pub, msg) ++} ++ ++func EncryptRSANoPadding(pub *xcrypto.PublicKeyRSA, msg []byte) ([]byte, error) { ++ return xcrypto.EncryptRSANoPadding(pub, msg) ++} ++ ++//go:linkname decodeKeyRSA crypto/rsa.decodeKey ++func decodeKeyRSA(data []byte) (N, E, D, P, Q, Dp, Dq, Qinv xcrypto.BigInt, err error) ++ ++//go:linkname encodeKeyRSA crypto/rsa.encodeKey ++func encodeKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv xcrypto.BigInt) ([]byte, error) ++ ++//go:linkname encodePublicKeyRSA crypto/rsa.encodePublicKey ++func encodePublicKeyRSA(N, E xcrypto.BigInt) ([]byte, error) ++ ++func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv xcrypto.BigInt, err error) { ++ data, err := xcrypto.GenerateKeyRSA(bits) ++ if err != nil { ++ return ++ } ++ return decodeKeyRSA(data) ++} ++ ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv xcrypto.BigInt) (*xcrypto.PrivateKeyRSA, error) { ++ encoded, err := encodeKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv) ++ if err != nil { ++ return nil, err ++ } ++ return xcrypto.NewPrivateKeyRSA(encoded) ++} ++ ++func NewPublicKeyRSA(N, E xcrypto.BigInt) (*xcrypto.PublicKeyRSA, error) { ++ encoded, err := encodePublicKeyRSA(N, E) ++ if err != nil { ++ return nil, err ++ } ++ return xcrypto.NewPublicKeyRSA(encoded) ++} ++ ++func SignRSAPKCS1v15(priv *xcrypto.PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ return xcrypto.SignRSAPKCS1v15(priv, h, hashed) ++} ++ ++func SignRSAPSS(priv *xcrypto.PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { ++ return xcrypto.SignRSAPSS(priv, h, hashed, saltLen) ++} ++ ++func VerifyRSAPKCS1v15(pub *xcrypto.PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { ++ return xcrypto.VerifyRSAPKCS1v15(pub, h, hashed, sig) ++} ++ ++func VerifyRSAPSS(pub *xcrypto.PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { ++ return xcrypto.VerifyRSAPSS(pub, h, hashed, sig, saltLen) ++} ++ ++type PrivateKeyECDH = xcrypto.PrivateKeyECDH ++type PublicKeyECDH = xcrypto.PublicKeyECDH ++ ++func ECDH(priv *xcrypto.PrivateKeyECDH, pub *xcrypto.PublicKeyECDH) ([]byte, error) { ++ return xcrypto.ECDH(priv, pub) ++} ++ ++func GenerateKeyECDH(curve string) (*xcrypto.PrivateKeyECDH, []byte, error) { ++ return xcrypto.GenerateKeyECDH(curve) ++} ++ ++func NewPrivateKeyECDH(curve string, bytes []byte) (*xcrypto.PrivateKeyECDH, error) { ++ var key []byte ++ switch curve { ++ case "P-256": ++ p, err := nistec.NewP256Point().ScalarBaseMult(bytes) ++ if err != nil { ++ return nil, err ++ } ++ key = p.Bytes() ++ case "P-384": ++ p, err := nistec.NewP384Point().ScalarBaseMult(bytes) ++ if err != nil { ++ return nil, err ++ } ++ key = p.Bytes() ++ case "P-521": ++ p, err := nistec.NewP521Point().ScalarBaseMult(bytes) ++ if err != nil { ++ return nil, err ++ } ++ key = p.Bytes() ++ default: ++ return nil, errors.New("NewPrivateKeyECDH: unsupported curve: " + curve) ++ } ++ return xcrypto.NewPrivateKeyECDH(curve, key, bytes) ++} ++ ++func NewPublicKeyECDH(curve string, bytes []byte) (*xcrypto.PublicKeyECDH, error) { ++ return xcrypto.NewPublicKeyECDH(curve, bytes) ++} ++ ++func SupportsHKDF() bool { ++ return true ++} ++ ++func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte, keyLength int) ([]byte, error) { ++ return xcrypto.ExpandHKDF(h, pseudorandomKey, info, keyLength) ++} ++ ++func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { ++ return xcrypto.ExtractHKDF(h, secret, salt) ++} ++ ++func SupportsPBKDF2() bool { ++ return true ++} ++ ++func PBKDF2(pass, salt []byte, iter, keyLen int, h func() hash.Hash) ([]byte, error) { ++ return xcrypto.PBKDF2(pass, salt, iter, keyLen, h) ++} ++ ++func SupportsTLS1PRF() bool { ++ return false ++} ++ ++func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { ++ panic("cryptobackend: not available") ++} ++ ++func SupportsDESCipher() bool { ++ return true ++} ++ ++func SupportsTripleDESCipher() bool { ++ return true ++} ++ ++func NewDESCipher(key []byte) (cipher.Block, error) { ++ return xcrypto.NewDESCipher(key) ++} ++ ++func NewTripleDESCipher(key []byte) (cipher.Block, error) { ++ return xcrypto.NewTripleDESCipher(key) ++} ++ ++func SupportsRC4() bool { return true } ++ ++type RC4Cipher = xcrypto.RC4Cipher ++ ++func NewRC4Cipher(key []byte) (*RC4Cipher, error) { return xcrypto.NewRC4Cipher(key) } ++ ++func SupportsEd25519() bool { ++ return true ++} ++ ++type PublicKeyEd25519 = xcrypto.PublicKeyEd25519 ++type PrivateKeyEd25519 = xcrypto.PrivateKeyEd25519 ++ ++func GenerateKeyEd25519() (PrivateKeyEd25519, error) { ++ return xcrypto.GenerateKeyEd25519(), nil ++} ++ ++func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) { ++ return xcrypto.NewPrivateKeyEd25519(priv) ++} ++ ++func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) { ++ return xcrypto.NewPublicKeyEd25519(pub) ++} ++ ++func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) { ++ return xcrypto.NewPrivateKeyEd25519FromSeed(seed) ++} ++ ++func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) { ++ return xcrypto.SignEd25519(priv, message) ++} ++ ++func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error { ++ return xcrypto.VerifyEd25519(pub, message, sig) ++} ++ ++func SupportsDSA(l, n int) bool { ++ return false ++} ++ ++func GenerateParametersDSA(l, n int) (p, q, g xcrypto.BigInt, err error) { ++ panic("cryptobackend: not available") ++} ++ ++type PrivateKeyDSA struct{} ++type PublicKeyDSA struct{} ++ ++func GenerateKeyDSA(p, q, g xcrypto.BigInt) (x, y xcrypto.BigInt, err error) { ++ panic("cryptobackend: not available") ++} ++ ++func NewPrivateKeyDSA(p, q, g, x, y xcrypto.BigInt) (*PrivateKeyDSA, error) { ++ panic("cryptobackend: not available") ++} ++ ++func NewPublicKeyDSA(p, q, g, y xcrypto.BigInt) (*PublicKeyDSA, error) { ++ panic("cryptobackend: not available") ++} ++ ++func SignDSA(priv *PrivateKeyDSA, hash []byte, parseSignature func([]byte) (xcrypto.BigInt, xcrypto.BigInt, error)) (r, s xcrypto.BigInt, err error) { ++ panic("cryptobackend: not available") ++} ++ ++func VerifyDSA(pub *PublicKeyDSA, hashed []byte, r, s xcrypto.BigInt, encodeSignature func(r, s xcrypto.BigInt) ([]byte, error)) bool { ++ panic("cryptobackend: not available") ++} +diff --git a/src/crypto/internal/backend/fips140/darwin.go b/src/crypto/internal/backend/fips140/darwin.go +new file mode 100644 +index 00000000000000..ef5af5d956163e +--- /dev/null ++++ b/src/crypto/internal/backend/fips140/darwin.go +@@ -0,0 +1,11 @@ ++// Copyright 2024 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build goexperiment.darwincrypto ++ ++package fips140 ++ ++func systemFIPSMode() bool { ++ return false ++} +diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go +index d52faddef45549..b276571ddf9fc8 100644 +--- a/src/crypto/rsa/boring.go ++++ b/src/crypto/rsa/boring.go +@@ -10,6 +10,7 @@ import ( + boring "crypto/internal/backend" + "crypto/internal/backend/bbig" + "crypto/internal/boring/bcache" ++ "internal/goexperiment" + "math/big" + ) + +@@ -62,11 +63,15 @@ type boringPriv struct { + } + + func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyRSA, error) { ++ // CommonCrypto requires the CRT values to be precomputed if nil ++ if goexperiment.DarwinCrypto && (priv.Precomputed.Dp == nil || priv.Precomputed.Dq == nil || priv.Precomputed.Qinv == nil) { ++ priv.Precompute() ++ priv.Precomputed.fips = nil ++ } + b := privCache.Get(priv) + if b != nil && privateKeyEqual(&b.orig, priv) { + return b.key, nil + } +- + b = new(boringPriv) + b.orig = copyPrivateKey(priv) + +diff --git a/src/crypto/rsa/darwin.go b/src/crypto/rsa/darwin.go +new file mode 100644 +index 00000000000000..1b9c63523ee90e +--- /dev/null ++++ b/src/crypto/rsa/darwin.go +@@ -0,0 +1,71 @@ ++// Copyright 2017 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build goexperiment.darwincrypto ++ ++package rsa ++ ++import ( ++ "crypto/internal/backend" ++ "crypto/internal/backend/bbig" ++ "errors" ++ "math/big" ++ _ "unsafe" ++ ++ "golang.org/x/crypto/cryptobyte" ++ "golang.org/x/crypto/cryptobyte/asn1" ++) ++ ++//go:linkname decodeKey ++func decodeKey(data []byte) (N, E, D, P, Q, Dp, Dq, Qinv backend.BigInt, err error) { ++ bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv backend.BigInt, err error) { ++ return nil, nil, nil, nil, nil, nil, nil, nil, e ++ } ++ input := cryptobyte.String(data) ++ var version int ++ n, e, d, p, q, dp, dq, qinv := new(big.Int), new(big.Int), new(big.Int), new(big.Int), ++ new(big.Int), new(big.Int), new(big.Int), new(big.Int) ++ // Parse the ASN.1 sequence ++ if !input.ReadASN1(&input, asn1.SEQUENCE) { ++ return bad(errors.New("invalid ASN.1 structure: not a sequence")) ++ } ++ if !input.ReadASN1Integer(&version) || version != 0 { ++ return bad(errors.New("invalid ASN.1 structure: unsupported version")) ++ } ++ if !input.ReadASN1Integer(n) || !input.ReadASN1Integer(e) || ++ !input.ReadASN1Integer(d) || !input.ReadASN1Integer(p) || ++ !input.ReadASN1Integer(q) || !input.ReadASN1Integer(dp) || ++ !input.ReadASN1Integer(dq) || !input.ReadASN1Integer(qinv) { ++ return bad(errors.New("invalid ASN.1 structure")) ++ } ++ return bbig.Enc(n), bbig.Enc(e), bbig.Enc(d), bbig.Enc(p), bbig.Enc(q), ++ bbig.Enc(dp), bbig.Enc(dq), bbig.Enc(qinv), nil ++} ++ ++//go:linkname encodeKey ++func encodeKey(N, E, D, P, Q, Dp, Dq, Qinv backend.BigInt) ([]byte, error) { ++ builder := cryptobyte.NewBuilder(nil) ++ builder.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) { ++ b.AddASN1Int64(0) // Add version as int64 ++ b.AddASN1BigInt(bbig.Dec(N)) // Add modulus ++ b.AddASN1BigInt(bbig.Dec(E)) // Add public exponent ++ b.AddASN1BigInt(bbig.Dec(D)) // Add private exponent ++ b.AddASN1BigInt(bbig.Dec(P)) // Add prime1 ++ b.AddASN1BigInt(bbig.Dec(Q)) // Add prime2 ++ b.AddASN1BigInt(bbig.Dec(Dp)) // Add exponent1 ++ b.AddASN1BigInt(bbig.Dec(Dq)) // Add exponent2 ++ b.AddASN1BigInt(bbig.Dec(Qinv)) // Add coefficient ++ }) ++ return builder.Bytes() ++} ++ ++//go:linkname encodePublicKey ++func encodePublicKey(N, E backend.BigInt) ([]byte, error) { ++ builder := cryptobyte.NewBuilder(nil) ++ builder.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) { ++ b.AddASN1BigInt(bbig.Dec(N)) // Add modulus ++ b.AddASN1BigInt(bbig.Dec(E)) // Add public exponent ++ }) ++ return builder.Bytes() ++} +diff --git a/src/crypto/rsa/fips.go b/src/crypto/rsa/fips.go +index ccb027810a7e07..149b109e0faa35 100644 +--- a/src/crypto/rsa/fips.go ++++ b/src/crypto/rsa/fips.go +@@ -78,7 +78,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, + hash = opts.Hash + } + +- if boring.Enabled && rand == boring.RandReader && boring.IsRSAKeySupported(len(priv.Primes)) && boring.SupportsHash(hash) { ++ if boring.Enabled && rand == boring.RandReader && boring.IsSaltSupported(opts.saltLength()) && boring.IsRSAKeySupported(len(priv.Primes)) && boring.SupportsHash(hash) { + bkey, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -200,7 +200,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l + + defer hash.Reset() + +- if boring.Enabled && random == boring.RandReader { ++ if boring.Enabled && random == boring.RandReader && boring.IsRSAOAEPLabelSupported(label) { + hash.Reset() + k := pub.Size() + if len(msg) > k-2*hash.Size()-2 { +@@ -249,7 +249,7 @@ func decryptOAEP(hash, mgfHash hash.Hash, priv *PrivateKey, ciphertext []byte, l + } + } + +- if boring.Enabled && boring.IsRSAKeySupported(len(priv.Primes)) { ++ if boring.Enabled && boring.IsRSAKeySupported(len(priv.Primes)) && boring.IsRSAOAEPLabelSupported(label) { + k := priv.Size() + if len(ciphertext) > k || + k < hash.Size()*2+2 { +@@ -305,7 +305,7 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ + return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode") + } + +- if boring.Enabled && boring.IsRSAKeySupported(len(priv.Primes)) { ++ if boring.Enabled && boring.IsRSAKeySupported(len(priv.Primes)) && boring.IsPKCS1v15HashSupported(hash) { + bkey, err := boringPrivateKey(priv) + if err != nil { + return nil, err +@@ -339,7 +339,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) + return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode") + } + +- if boring.Enabled { ++ if boring.Enabled && boring.IsPKCS1v15HashSupported(hash) { + bkey, err := boringPublicKey(pub) + if err != nil { + return err +diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go +index 7d7115cff81cea..d3ba67fe4d0611 100644 +--- a/src/crypto/rsa/pss_test.go ++++ b/src/crypto/rsa/pss_test.go +@@ -15,6 +15,7 @@ import ( + "crypto/sha256" + "crypto/sha512" + "encoding/hex" ++ "internal/goexperiment" + "math/big" + "os" + "strconv" +@@ -103,8 +104,10 @@ func TestPSSGolden(t *testing.T) { + h.Reset() + h.Write(msg) + hashed = h.Sum(hashed[:0]) +- + if err := VerifyPSS(key, hash, hashed, sig, opts); err != nil { ++ if goexperiment.DarwinCrypto && key.N.BitLen() == 1025 { ++ t.Skip("CommonCrypto doesn't support golden test entries with this key size") ++ } + t.Error(err) + } + default: +diff --git a/src/go.mod b/src/go.mod +index e9da0eb1301b93..f03fcd766104e9 100644 +--- a/src/go.mod ++++ b/src/go.mod +@@ -4,6 +4,7 @@ go 1.24 + + require ( + github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf ++ github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 + github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 + golang.org/x/crypto v0.30.0 + golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 +diff --git a/src/go.sum b/src/go.sum +index b464f023942b74..90bd105cd407fb 100644 +--- a/src/go.sum ++++ b/src/go.sum +@@ -1,5 +1,7 @@ + github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf h1:gkjE7LMxjlaSn8fdvbT/HJrpGcW/ZnwYpps7sSBhLD4= + github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= ++github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 h1:T8v8j/vr3sqmsP3BuriGfTYWu2JpEF3QoisX6hOjerU= ++github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1/go.mod h1:LyP4oZ0QcysEJdqUTOk9ngNFArRFK94YRImkoJ8julQ= + github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 h1:fMAxrMWT19/kkIZIuB9cjqW8SqRxCH2+2ZiZr5qrpuI= + github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= + golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go +index 1fcadbf6c19d79..b0da426bf18177 100644 +--- a/src/go/build/deps_test.go ++++ b/src/go/build/deps_test.go +@@ -519,6 +519,8 @@ var depsRules = ` + < github.com/microsoft/go-crypto-winnative/internal/sysdll + < github.com/microsoft/go-crypto-winnative/internal/bcrypt + < github.com/microsoft/go-crypto-winnative/cng ++ < github.com/microsoft/go-crypto-darwin/internal/cryptokit ++ < github.com/microsoft/go-crypto-darwin/xcrypto + < github.com/golang-fips/openssl/v2/internal/subtle + < github.com/golang-fips/openssl/v2 + < crypto/internal/boring +@@ -546,6 +548,7 @@ var depsRules = ` + CRYPTO, FMT, math/big + < github.com/microsoft/go-crypto-winnative/cng/bbig + < github.com/golang-fips/openssl/v2/bbig ++ < github.com/microsoft/go-crypto-darwin/bbig + < crypto/internal/boring/bbig + < crypto/internal/backend/bbig + < crypto/rand +@@ -860,7 +863,7 @@ func findImports(pkg string) ([]string, error) { + } + var imports []string + var haveImport = map[string]bool{} +- if pkg == "crypto/internal/boring" || pkg == "github.com/golang-fips/openssl/v2" { ++ if pkg == "crypto/internal/boring" || pkg == "github.com/golang-fips/openssl/v2" || strings.HasPrefix(pkg, "github.com/microsoft/go-crypto-darwin") { + haveImport["C"] = true // kludge: prevent C from appearing in crypto/internal/boring imports + } + fset := token.NewFileSet() +diff --git a/src/go/build/vendor_test.go b/src/go/build/vendor_test.go +index 1d0b9b20e9b1d4..6092c93d4c5b26 100644 +--- a/src/go/build/vendor_test.go ++++ b/src/go/build/vendor_test.go +@@ -24,6 +24,7 @@ var allowedPackagePrefixes = []string{ + "rsc.io/markdown", + "github.com/golang-fips/openssl", + "github.com/microsoft/go-crypto-winnative", ++ "github.com/microsoft/go-crypto-darwin", + } + + // Verify that the vendor directories contain only packages matching the list above. +diff --git a/src/internal/goexperiment/exp_darwincrypto_off.go b/src/internal/goexperiment/exp_darwincrypto_off.go +new file mode 100644 +index 00000000000000..bc4440e01419fb +--- /dev/null ++++ b/src/internal/goexperiment/exp_darwincrypto_off.go +@@ -0,0 +1,9 @@ ++// Code generated by mkconsts.go. DO NOT EDIT. ++ ++//go:build !goexperiment.darwincrypto ++// +build !goexperiment.darwincrypto ++ ++package goexperiment ++ ++const DarwinCrypto = false ++const DarwinCryptoInt = 0 +diff --git a/src/internal/goexperiment/exp_darwincrypto_on.go b/src/internal/goexperiment/exp_darwincrypto_on.go +new file mode 100644 +index 00000000000000..3215ce2784e94d +--- /dev/null ++++ b/src/internal/goexperiment/exp_darwincrypto_on.go +@@ -0,0 +1,9 @@ ++// Code generated by mkconsts.go. DO NOT EDIT. ++ ++//go:build goexperiment.darwincrypto ++// +build goexperiment.darwincrypto ++ ++package goexperiment ++ ++const DarwinCrypto = true ++const DarwinCryptoInt = 1 +diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go +index c6f64c18bdd13f..e6c9b7d5e62dc0 100644 +--- a/src/internal/goexperiment/flags.go ++++ b/src/internal/goexperiment/flags.go +@@ -61,6 +61,7 @@ type Flags struct { + BoringCrypto bool + OpenSSLCrypto bool + CNGCrypto bool ++ DarwinCrypto bool + + // SystemCrypto enables the OpenSSL, CNG or Darwin crypto experiment depending on + // which one is appropriate on the target GOOS. diff --git a/patches/0006-Vendor-crypto-backends.patch b/patches/0007-Vendor-crypto-backends.patch similarity index 99% rename from patches/0006-Vendor-crypto-backends.patch rename to patches/0007-Vendor-crypto-backends.patch index 24e3632a13f..5a08acdfbfc 100644 --- a/patches/0006-Vendor-crypto-backends.patch +++ b/patches/0007-Vendor-crypto-backends.patch @@ -5,6 +5,8 @@ Subject: [PATCH] Vendor crypto backends To reproduce, run 'go mod vendor' in 'go/src'. --- + src/go.mod | 4 +- + src/go.sum | 8 +- .../golang-fips/openssl/v2/.gitignore | 1 + .../golang-fips/openssl/v2/.gitleaks.toml | 9 + .../github.com/golang-fips/openssl/v2/LICENSE | 20 + @@ -69,7 +71,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 + - 64 files changed, 10969 insertions(+), 6 deletions(-) + 66 files changed, 10981 insertions(+), 6 deletions(-) create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitignore 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 @@ -134,6 +136,37 @@ To reproduce, run 'go mod vendor' in 'go/src'. create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/internal/subtle/aliasing.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/internal/sysdll/sys_windows.go +diff --git a/src/go.mod b/src/go.mod +index e9da0eb1301b93..96bdcd421e1129 100644 +--- a/src/go.mod ++++ b/src/go.mod +@@ -3,8 +3,8 @@ module std + go 1.24 + + require ( +- github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf +- github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 ++ github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 ++ github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 + golang.org/x/crypto v0.30.0 + golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 + ) +diff --git a/src/go.sum b/src/go.sum +index b464f023942b74..abebb59dcd7739 100644 +--- a/src/go.sum ++++ b/src/go.sum +@@ -1,7 +1,7 @@ +-github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf h1:gkjE7LMxjlaSn8fdvbT/HJrpGcW/ZnwYpps7sSBhLD4= +-github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= +-github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 h1:fMAxrMWT19/kkIZIuB9cjqW8SqRxCH2+2ZiZr5qrpuI= +-github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= ++github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 h1:OhuURhDVbg+f/BvlG+qT5sQVkutwhI0Kmsy7koQ4l9A= ++github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= ++github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 h1:KB8xmJcFSPlZFMg2mxz5b6DCE8k1qpHy2HFevAJLELI= ++github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= + golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= + golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= + golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 h1:+Yk1FZ5E+/ewA0nOO/HRYs9E4yeqpGOShuSAdzCNNoQ= diff --git a/src/vendor/github.com/golang-fips/openssl/v2/.gitignore b/src/vendor/github.com/golang-fips/openssl/v2/.gitignore new file mode 100644 index 00000000000000..79b5594df7fa29 diff --git a/patches/0007-Add-backend-code-gen.patch b/patches/0008-Add-backend-code-gen.patch similarity index 83% rename from patches/0007-Add-backend-code-gen.patch rename to patches/0008-Add-backend-code-gen.patch index 6ef13b7efdd..56fac13f1eb 100644 --- a/patches/0007-Add-backend-code-gen.patch +++ b/patches/0008-Add-backend-code-gen.patch @@ -32,23 +32,31 @@ the repository to run the generators. .../exp_allowcryptofallback_on.go | 9 + src/internal/goexperiment/flags.go | 8 + .../backenderr_gen_conflict_boring_cng.go | 17 ++ + .../backenderr_gen_conflict_boring_darwin.go | 17 ++ .../backenderr_gen_conflict_boring_openssl.go | 17 ++ + .../backenderr_gen_conflict_cng_darwin.go | 17 ++ .../backenderr_gen_conflict_cng_openssl.go | 17 ++ + .../backenderr_gen_conflict_darwin_openssl.go | 17 ++ .../backenderr_gen_nofallback_boring.go | 24 ++ src/runtime/backenderr_gen_nofallback_cng.go | 24 ++ + .../backenderr_gen_nofallback_darwin.go | 24 ++ .../backenderr_gen_nofallback_openssl.go | 24 ++ ...ckenderr_gen_requirefips_nosystemcrypto.go | 17 ++ .../backenderr_gen_systemcrypto_nobackend.go | 16 + - 14 files changed, 487 insertions(+), 1 deletion(-) + 18 files changed, 562 insertions(+), 1 deletion(-) create mode 100644 src/crypto/internal/backend/backendgen.go create mode 100644 src/crypto/internal/backend/backendgen_test.go create mode 100644 src/internal/goexperiment/exp_allowcryptofallback_off.go create mode 100644 src/internal/goexperiment/exp_allowcryptofallback_on.go create mode 100644 src/runtime/backenderr_gen_conflict_boring_cng.go + create mode 100644 src/runtime/backenderr_gen_conflict_boring_darwin.go create mode 100644 src/runtime/backenderr_gen_conflict_boring_openssl.go + create mode 100644 src/runtime/backenderr_gen_conflict_cng_darwin.go create mode 100644 src/runtime/backenderr_gen_conflict_cng_openssl.go + create mode 100644 src/runtime/backenderr_gen_conflict_darwin_openssl.go create mode 100644 src/runtime/backenderr_gen_nofallback_boring.go create mode 100644 src/runtime/backenderr_gen_nofallback_cng.go + create mode 100644 src/runtime/backenderr_gen_nofallback_darwin.go create mode 100644 src/runtime/backenderr_gen_nofallback_openssl.go create mode 100644 src/runtime/backenderr_gen_requirefips_nosystemcrypto.go create mode 100644 src/runtime/backenderr_gen_systemcrypto_nobackend.go @@ -370,7 +378,7 @@ index 00000000000000..1ba948c8f207e5 + return bs +} diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go -index ad6081552af15d..d5948dbc5f8a2a 100644 +index 06e19c55345187..cf748c3ef8e0cf 100644 --- a/src/crypto/internal/backend/nobackend.go +++ b/src/crypto/internal/backend/nobackend.go @@ -4,7 +4,7 @@ @@ -378,7 +386,7 @@ index ad6081552af15d..d5948dbc5f8a2a 100644 // Do not edit the build constraint by hand. It is generated by "backendgen.go". -//go:build ignore -+//go:build !(goexperiment.boringcrypto && linux && cgo && (amd64 || arm64) && !android && !msan) && !(goexperiment.cngcrypto && windows) && !(goexperiment.opensslcrypto && linux && cgo) ++//go:build !(goexperiment.boringcrypto && linux && cgo && (amd64 || arm64) && !android && !msan) && !(goexperiment.cngcrypto && windows) && !(goexperiment.darwincrypto && darwin && cgo) && !(goexperiment.opensslcrypto && linux && cgo) package backend @@ -413,7 +421,7 @@ index 00000000000000..8d0c3fde9ab5e8 +const AllowCryptoFallback = true +const AllowCryptoFallbackInt = 1 diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go -index c2f69930e2240e..c8e10ebc1696c4 100644 +index c6f64c18bdd13f..eb21eb48f2524b 100644 --- a/src/internal/goexperiment/flags.go +++ b/src/internal/goexperiment/flags.go @@ -77,6 +77,14 @@ type Flags struct { @@ -454,6 +462,29 @@ index 00000000000000..361db2a962d60f + For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips + ` +} +diff --git a/src/runtime/backenderr_gen_conflict_boring_darwin.go b/src/runtime/backenderr_gen_conflict_boring_darwin.go +new file mode 100644 +index 00000000000000..6c48a4e50fa72e +--- /dev/null ++++ b/src/runtime/backenderr_gen_conflict_boring_darwin.go +@@ -0,0 +1,17 @@ ++// Copyright 2023 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 file is generated by crypto/internal/backend. DO NOT EDIT. DO NOT manually create files with the prefix "backenderr_gen_". ++ ++//go:build goexperiment.boringcrypto && goexperiment.darwincrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The boring and darwin backends are both enabled, but they are mutually exclusive. ++ Please make sure only one crypto backend experiment is enabled by GOEXPERIMENT or '-tags'. ++ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips ++ ` ++} diff --git a/src/runtime/backenderr_gen_conflict_boring_openssl.go b/src/runtime/backenderr_gen_conflict_boring_openssl.go new file mode 100644 index 00000000000000..91fac35011b24c @@ -477,6 +508,29 @@ index 00000000000000..91fac35011b24c + For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips + ` +} +diff --git a/src/runtime/backenderr_gen_conflict_cng_darwin.go b/src/runtime/backenderr_gen_conflict_cng_darwin.go +new file mode 100644 +index 00000000000000..2e82a5cff034b7 +--- /dev/null ++++ b/src/runtime/backenderr_gen_conflict_cng_darwin.go +@@ -0,0 +1,17 @@ ++// Copyright 2023 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 file is generated by crypto/internal/backend. DO NOT EDIT. DO NOT manually create files with the prefix "backenderr_gen_". ++ ++//go:build goexperiment.cngcrypto && goexperiment.darwincrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The cng and darwin backends are both enabled, but they are mutually exclusive. ++ Please make sure only one crypto backend experiment is enabled by GOEXPERIMENT or '-tags'. ++ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips ++ ` ++} diff --git a/src/runtime/backenderr_gen_conflict_cng_openssl.go b/src/runtime/backenderr_gen_conflict_cng_openssl.go new file mode 100644 index 00000000000000..bf44084570bbbc @@ -500,6 +554,29 @@ index 00000000000000..bf44084570bbbc + For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips + ` +} +diff --git a/src/runtime/backenderr_gen_conflict_darwin_openssl.go b/src/runtime/backenderr_gen_conflict_darwin_openssl.go +new file mode 100644 +index 00000000000000..90f4361e28cd94 +--- /dev/null ++++ b/src/runtime/backenderr_gen_conflict_darwin_openssl.go +@@ -0,0 +1,17 @@ ++// Copyright 2023 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 file is generated by crypto/internal/backend. DO NOT EDIT. DO NOT manually create files with the prefix "backenderr_gen_". ++ ++//go:build goexperiment.darwincrypto && goexperiment.opensslcrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The darwin and openssl backends are both enabled, but they are mutually exclusive. ++ Please make sure only one crypto backend experiment is enabled by GOEXPERIMENT or '-tags'. ++ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips ++ ` ++} diff --git a/src/runtime/backenderr_gen_nofallback_boring.go b/src/runtime/backenderr_gen_nofallback_boring.go new file mode 100644 index 00000000000000..6db0ed6dc09639 @@ -560,9 +637,39 @@ index 00000000000000..ae7f798ea41225 + For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips + ` +} +diff --git a/src/runtime/backenderr_gen_nofallback_darwin.go b/src/runtime/backenderr_gen_nofallback_darwin.go +new file mode 100644 +index 00000000000000..8a32f2cb25bda2 +--- /dev/null ++++ b/src/runtime/backenderr_gen_nofallback_darwin.go +@@ -0,0 +1,24 @@ ++// Copyright 2023 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 file is generated by crypto/internal/backend. DO NOT EDIT. DO NOT manually create files with the prefix "backenderr_gen_". ++ ++//go:build goexperiment.darwincrypto && !(goexperiment.darwincrypto && darwin && cgo) && !goexperiment.allowcryptofallback ++ ++package runtime ++ ++func init() { ++ ` ++ The goexperiment.darwincrypto tag is specified, but other tags required to enable that backend were not met. ++ Required build tags: ++ goexperiment.darwincrypto && darwin && cgo ++ Please check your build environment and build command for a reason one or more of these tags weren't specified. ++ ++ If you only performed a Go toolset upgrade and didn't expect this error, your code was likely depending on fallback to Go standard library crypto. ++ As of Go 1.21, Go crypto fallback is a build error. This helps prevent accidental fallback. ++ Removing darwincrypto will restore pre-1.21 behavior by intentionally using Go standard library crypto. ++ ++ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips ++ ` ++} diff --git a/src/runtime/backenderr_gen_nofallback_openssl.go b/src/runtime/backenderr_gen_nofallback_openssl.go new file mode 100644 -index 00000000000000..351be70262084b +index 00000000000000..7e1679dfc37a23 --- /dev/null +++ b/src/runtime/backenderr_gen_nofallback_openssl.go @@ -0,0 +1,24 @@ @@ -615,7 +722,7 @@ index 00000000000000..1c015dd2b08972 +} diff --git a/src/runtime/backenderr_gen_systemcrypto_nobackend.go b/src/runtime/backenderr_gen_systemcrypto_nobackend.go new file mode 100644 -index 00000000000000..97ba7da6260b50 +index 00000000000000..95be7ad8d38cae --- /dev/null +++ b/src/runtime/backenderr_gen_systemcrypto_nobackend.go @@ -0,0 +1,16 @@ @@ -625,7 +732,7 @@ index 00000000000000..97ba7da6260b50 + +// This file is generated by crypto/internal/backend. DO NOT EDIT. DO NOT manually create files with the prefix "backenderr_gen_". + -+//go:build goexperiment.systemcrypto && !goexperiment.boringcrypto && !goexperiment.cngcrypto && !goexperiment.opensslcrypto ++//go:build goexperiment.systemcrypto && !goexperiment.boringcrypto && !goexperiment.cngcrypto && !goexperiment.darwincrypto && !goexperiment.opensslcrypto + +package runtime + diff --git a/patches/0008-Update-default-go.env.patch b/patches/0009-Update-default-go.env.patch similarity index 100% rename from patches/0008-Update-default-go.env.patch rename to patches/0009-Update-default-go.env.patch diff --git a/patches/0009-Skip-failing-tests-on-Windows.patch b/patches/0010-Skip-failing-tests-on-Windows.patch similarity index 100% rename from patches/0009-Skip-failing-tests-on-Windows.patch rename to patches/0010-Skip-failing-tests-on-Windows.patch diff --git a/patches/0010-unset-GOFIPS-when-running-the-Go-toolchain.patch b/patches/0011-unset-GOFIPS-when-running-the-Go-toolchain.patch similarity index 100% rename from patches/0010-unset-GOFIPS-when-running-the-Go-toolchain.patch rename to patches/0011-unset-GOFIPS-when-running-the-Go-toolchain.patch diff --git a/patches/0011-add-support-for-logging-used-Windows-APIs.patch b/patches/0012-add-support-for-logging-used-Windows-APIs.patch similarity index 100% rename from patches/0011-add-support-for-logging-used-Windows-APIs.patch rename to patches/0012-add-support-for-logging-used-Windows-APIs.patch diff --git a/patches/0012-remove-long-path-support-hack.patch b/patches/0013-remove-long-path-support-hack.patch similarity index 100% rename from patches/0012-remove-long-path-support-hack.patch rename to patches/0013-remove-long-path-support-hack.patch diff --git a/patches/0013-Omit-internal-go.mod-files-used-for-codegen.patch b/patches/0014-Omit-internal-go.mod-files-used-for-codegen.patch similarity index 100% rename from patches/0013-Omit-internal-go.mod-files-used-for-codegen.patch rename to patches/0014-Omit-internal-go.mod-files-used-for-codegen.patch diff --git a/patches/0014-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch b/patches/0015-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch similarity index 100% rename from patches/0014-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch rename to patches/0015-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch From d69b1a15ede0cdb686a7a7f4a3c85532c64b7686 Mon Sep 17 00:00:00 2001 From: George Adams Date: Wed, 8 Jan 2025 19:27:47 +0000 Subject: [PATCH 2/8] fixup patches --- patches/0005-Add-CNG-crypto-backend.patch | 6 +- patches/0006-Add-Darwin-crypto-backend.patch | 16 +- patches/0007-Vendor-crypto-backends.patch | 5290 ++++++++++++++---- 3 files changed, 4112 insertions(+), 1200 deletions(-) diff --git a/patches/0005-Add-CNG-crypto-backend.patch b/patches/0005-Add-CNG-crypto-backend.patch index 06b384201b5..afc775167ff 100644 --- a/patches/0005-Add-CNG-crypto-backend.patch +++ b/patches/0005-Add-CNG-crypto-backend.patch @@ -84,7 +84,7 @@ 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..8b5416f5be0955 +index 00000000000000..86aac21a28cbee --- /dev/null +++ b/src/crypto/internal/backend/cng_windows.go @@ -0,0 +1,316 @@ @@ -483,7 +483,7 @@ index a4af0a2144870a..7d7115cff81cea 100644 t.Fatal(err) } diff --git a/src/go.mod b/src/go.mod -index 186ced4a1123a8..e9da0eb1301b93 100644 +index 186ced4a1123a8..897c3802237b4e 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,6 +4,7 @@ go 1.24 @@ -495,7 +495,7 @@ index 186ced4a1123a8..e9da0eb1301b93 100644 golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 ) diff --git a/src/go.sum b/src/go.sum -index 0a58eccb57a869..b464f023942b74 100644 +index 0a58eccb57a869..7cece574a42291 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,5 +1,7 @@ diff --git a/patches/0006-Add-Darwin-crypto-backend.patch b/patches/0006-Add-Darwin-crypto-backend.patch index 19186e0c65e..49bc4c58e6e 100644 --- a/patches/0006-Add-Darwin-crypto-backend.patch +++ b/patches/0006-Add-Darwin-crypto-backend.patch @@ -688,28 +688,28 @@ index 7d7115cff81cea..d3ba67fe4d0611 100644 } default: diff --git a/src/go.mod b/src/go.mod -index e9da0eb1301b93..f03fcd766104e9 100644 +index 897c3802237b4e..0119f5ce8fe623 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,6 +4,7 @@ go 1.24 require ( - github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf + github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 + github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 - github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 + github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 golang.org/x/crypto v0.30.0 golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 diff --git a/src/go.sum b/src/go.sum -index b464f023942b74..90bd105cd407fb 100644 +index 7cece574a42291..6050c2fe0c5081 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,5 +1,7 @@ - github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf h1:gkjE7LMxjlaSn8fdvbT/HJrpGcW/ZnwYpps7sSBhLD4= - github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= + github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 h1:OhuURhDVbg+f/BvlG+qT5sQVkutwhI0Kmsy7koQ4l9A= + github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= +github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 h1:T8v8j/vr3sqmsP3BuriGfTYWu2JpEF3QoisX6hOjerU= +github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1/go.mod h1:LyP4oZ0QcysEJdqUTOk9ngNFArRFK94YRImkoJ8julQ= - github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 h1:fMAxrMWT19/kkIZIuB9cjqW8SqRxCH2+2ZiZr5qrpuI= - github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= + github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 h1:KB8xmJcFSPlZFMg2mxz5b6DCE8k1qpHy2HFevAJLELI= + github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go index 1fcadbf6c19d79..b0da426bf18177 100644 diff --git a/patches/0007-Vendor-crypto-backends.patch b/patches/0007-Vendor-crypto-backends.patch index 5a08acdfbfc..7cc65ab1998 100644 --- a/patches/0007-Vendor-crypto-backends.patch +++ b/patches/0007-Vendor-crypto-backends.patch @@ -5,73 +5,95 @@ Subject: [PATCH] Vendor crypto backends To reproduce, run 'go mod vendor' in 'go/src'. --- - src/go.mod | 4 +- - src/go.sum | 8 +- - .../golang-fips/openssl/v2/.gitignore | 1 + - .../golang-fips/openssl/v2/.gitleaks.toml | 9 + - .../github.com/golang-fips/openssl/v2/LICENSE | 20 + - .../golang-fips/openssl/v2/README.md | 66 ++ - .../github.com/golang-fips/openssl/v2/aes.go | 147 ++++ - .../golang-fips/openssl/v2/bbig/big.go | 37 + - .../github.com/golang-fips/openssl/v2/big.go | 11 + - .../golang-fips/openssl/v2/cgo_go124.go | 18 + - .../golang-fips/openssl/v2/cipher.go | 569 ++++++++++++++ - .../github.com/golang-fips/openssl/v2/des.go | 114 +++ - .../github.com/golang-fips/openssl/v2/dsa.go | 323 ++++++++ - .../github.com/golang-fips/openssl/v2/ec.go | 68 ++ - .../github.com/golang-fips/openssl/v2/ecdh.go | 303 ++++++++ - .../golang-fips/openssl/v2/ecdsa.go | 208 +++++ - .../golang-fips/openssl/v2/ed25519.go | 228 ++++++ - .../github.com/golang-fips/openssl/v2/evp.go | 580 ++++++++++++++ - .../golang-fips/openssl/v2/goopenssl.c | 248 ++++++ - .../golang-fips/openssl/v2/goopenssl.h | 261 +++++++ - .../github.com/golang-fips/openssl/v2/hash.go | 714 ++++++++++++++++++ - .../github.com/golang-fips/openssl/v2/hkdf.go | 322 ++++++++ - .../github.com/golang-fips/openssl/v2/hmac.go | 274 +++++++ - .../github.com/golang-fips/openssl/v2/init.go | 64 ++ - .../golang-fips/openssl/v2/init_unix.go | 31 + - .../golang-fips/openssl/v2/init_windows.go | 36 + - .../golang-fips/openssl/v2/openssl.go | 469 ++++++++++++ - .../golang-fips/openssl/v2/params.go | 210 ++++++ - .../golang-fips/openssl/v2/pbkdf2.go | 62 ++ - .../golang-fips/openssl/v2/port_dsa.c | 85 +++ - .../github.com/golang-fips/openssl/v2/rand.go | 20 + - .../github.com/golang-fips/openssl/v2/rc4.go | 66 ++ - .../github.com/golang-fips/openssl/v2/rsa.go | 408 ++++++++++ - .../github.com/golang-fips/openssl/v2/shims.h | 413 ++++++++++ - .../golang-fips/openssl/v2/thread_setup.go | 14 + - .../golang-fips/openssl/v2/thread_setup.h | 4 + - .../openssl/v2/thread_setup_unix.c | 64 ++ - .../openssl/v2/thread_setup_windows.c | 64 ++ - .../golang-fips/openssl/v2/tls1prf.go | 160 ++++ - .../github.com/golang-fips/openssl/v2/zaes.go | 86 +++ - .../microsoft/go-crypto-winnative/LICENSE | 21 + - .../microsoft/go-crypto-winnative/cng/aes.go | 393 ++++++++++ - .../go-crypto-winnative/cng/bbig/big.go | 31 + - .../microsoft/go-crypto-winnative/cng/big.go | 30 + - .../go-crypto-winnative/cng/cipher.go | 52 ++ - .../microsoft/go-crypto-winnative/cng/cng.go | 131 ++++ - .../microsoft/go-crypto-winnative/cng/des.go | 106 +++ - .../microsoft/go-crypto-winnative/cng/dsa.go | 465 ++++++++++++ - .../microsoft/go-crypto-winnative/cng/ecdh.go | 255 +++++++ - .../go-crypto-winnative/cng/ecdsa.go | 169 +++++ - .../microsoft/go-crypto-winnative/cng/hash.go | 312 ++++++++ - .../microsoft/go-crypto-winnative/cng/hkdf.go | 124 +++ - .../microsoft/go-crypto-winnative/cng/hmac.go | 35 + - .../microsoft/go-crypto-winnative/cng/keys.go | 220 ++++++ - .../go-crypto-winnative/cng/pbkdf2.go | 70 ++ - .../microsoft/go-crypto-winnative/cng/rand.go | 28 + - .../microsoft/go-crypto-winnative/cng/rc4.go | 65 ++ - .../microsoft/go-crypto-winnative/cng/rsa.go | 396 ++++++++++ - .../microsoft/go-crypto-winnative/cng/sha3.go | 284 +++++++ - .../go-crypto-winnative/cng/tls1prf.go | 88 +++ - .../internal/bcrypt/bcrypt_windows.go | 368 +++++++++ - .../internal/bcrypt/ntstatus_windows.go | 45 ++ - .../internal/bcrypt/zsyscall_windows.go | 412 ++++++++++ - .../internal/subtle/aliasing.go | 32 + - .../internal/sysdll/sys_windows.go | 55 ++ - src/vendor/modules.txt | 11 + - 66 files changed, 10981 insertions(+), 6 deletions(-) + .../golang-fips/openssl/v2/.gitignore | 1 + + .../golang-fips/openssl/v2/.gitleaks.toml | 9 + + .../github.com/golang-fips/openssl/v2/LICENSE | 20 + + .../golang-fips/openssl/v2/README.md | 66 ++ + .../github.com/golang-fips/openssl/v2/aes.go | 147 +++ + .../golang-fips/openssl/v2/bbig/big.go | 37 + + .../github.com/golang-fips/openssl/v2/big.go | 11 + + .../golang-fips/openssl/v2/cgo_go124.go | 18 + + .../golang-fips/openssl/v2/cipher.go | 569 +++++++++ + .../github.com/golang-fips/openssl/v2/des.go | 114 ++ + .../github.com/golang-fips/openssl/v2/dsa.go | 323 +++++ + .../github.com/golang-fips/openssl/v2/ec.go | 68 ++ + .../github.com/golang-fips/openssl/v2/ecdh.go | 303 +++++ + .../golang-fips/openssl/v2/ecdsa.go | 208 ++++ + .../golang-fips/openssl/v2/ed25519.go | 218 ++++ + .../github.com/golang-fips/openssl/v2/evp.go | 569 +++++++++ + .../golang-fips/openssl/v2/goopenssl.c | 248 ++++ + .../golang-fips/openssl/v2/goopenssl.h | 262 +++++ + .../github.com/golang-fips/openssl/v2/hash.go | 1041 +++++++++++++++++ + .../github.com/golang-fips/openssl/v2/hkdf.go | 322 +++++ + .../github.com/golang-fips/openssl/v2/hmac.go | 274 +++++ + .../github.com/golang-fips/openssl/v2/init.go | 64 + + .../golang-fips/openssl/v2/init_unix.go | 31 + + .../golang-fips/openssl/v2/init_windows.go | 36 + + .../golang-fips/openssl/v2/openssl.go | 469 ++++++++ + .../golang-fips/openssl/v2/params.go | 210 ++++ + .../golang-fips/openssl/v2/pbkdf2.go | 62 + + .../golang-fips/openssl/v2/port_dsa.c | 85 ++ + .../openssl/v2/port_evp_md5_sha1.c | 126 ++ + .../github.com/golang-fips/openssl/v2/rand.go | 20 + + .../github.com/golang-fips/openssl/v2/rc4.go | 66 ++ + .../github.com/golang-fips/openssl/v2/rsa.go | 408 +++++++ + .../github.com/golang-fips/openssl/v2/shims.h | 416 +++++++ + .../golang-fips/openssl/v2/thread_setup.go | 14 + + .../golang-fips/openssl/v2/thread_setup.h | 4 + + .../openssl/v2/thread_setup_unix.c | 64 + + .../openssl/v2/thread_setup_windows.c | 64 + + .../golang-fips/openssl/v2/tls1prf.go | 160 +++ + .../github.com/golang-fips/openssl/v2/zaes.go | 86 ++ + .../microsoft/go-crypto-darwin/LICENSE | 21 + + .../microsoft/go-crypto-darwin/bbig/big.go | 31 + + .../internal/cryptokit/cryptokit.go | 34 + + .../internal/cryptokit/cryptokit.h | 43 + + .../internal/cryptokit/ed25519.go | 72 ++ + .../internal/cryptokit/gcm.go | 36 + + .../internal/cryptokit/hkdf.go | 77 ++ + .../microsoft/go-crypto-darwin/xcrypto/aes.go | 306 +++++ + .../microsoft/go-crypto-darwin/xcrypto/big.go | 16 + + .../go-crypto-darwin/xcrypto/cgo_go124.go | 21 + + .../go-crypto-darwin/xcrypto/cipher.go | 122 ++ + .../microsoft/go-crypto-darwin/xcrypto/des.go | 117 ++ + .../microsoft/go-crypto-darwin/xcrypto/ec.go | 32 + + .../go-crypto-darwin/xcrypto/ecdh.go | 135 +++ + .../go-crypto-darwin/xcrypto/ecdsa.go | 181 +++ + .../go-crypto-darwin/xcrypto/ed25519.go | 100 ++ + .../microsoft/go-crypto-darwin/xcrypto/evp.go | 338 ++++++ + .../go-crypto-darwin/xcrypto/hash.go | 391 +++++++ + .../go-crypto-darwin/xcrypto/hkdf.go | 66 ++ + .../go-crypto-darwin/xcrypto/hmac.go | 113 ++ + .../go-crypto-darwin/xcrypto/pbkdf2.go | 65 + + .../go-crypto-darwin/xcrypto/rand.go | 26 + + .../microsoft/go-crypto-darwin/xcrypto/rc4.go | 83 ++ + .../microsoft/go-crypto-darwin/xcrypto/rsa.go | 194 +++ + .../go-crypto-darwin/xcrypto/xcrypto.go | 59 + + .../microsoft/go-crypto-winnative/LICENSE | 21 + + .../microsoft/go-crypto-winnative/cng/aes.go | 393 +++++++ + .../go-crypto-winnative/cng/bbig/big.go | 31 + + .../microsoft/go-crypto-winnative/cng/big.go | 30 + + .../go-crypto-winnative/cng/cipher.go | 52 + + .../microsoft/go-crypto-winnative/cng/cng.go | 131 +++ + .../microsoft/go-crypto-winnative/cng/des.go | 106 ++ + .../microsoft/go-crypto-winnative/cng/dsa.go | 465 ++++++++ + .../microsoft/go-crypto-winnative/cng/ecdh.go | 255 ++++ + .../go-crypto-winnative/cng/ecdsa.go | 169 +++ + .../microsoft/go-crypto-winnative/cng/hash.go | 306 +++++ + .../microsoft/go-crypto-winnative/cng/hkdf.go | 124 ++ + .../microsoft/go-crypto-winnative/cng/hmac.go | 35 + + .../microsoft/go-crypto-winnative/cng/keys.go | 220 ++++ + .../go-crypto-winnative/cng/pbkdf2.go | 70 ++ + .../microsoft/go-crypto-winnative/cng/rand.go | 28 + + .../microsoft/go-crypto-winnative/cng/rc4.go | 65 + + .../microsoft/go-crypto-winnative/cng/rsa.go | 396 +++++++ + .../go-crypto-winnative/cng/tls1prf.go | 88 ++ + .../internal/bcrypt/bcrypt_windows.go | 359 ++++++ + .../internal/bcrypt/zsyscall_windows.go | 389 ++++++ + .../internal/subtle/aliasing.go | 32 + + .../internal/sysdll/sys_windows.go | 55 + + src/vendor/modules.txt | 16 + + 88 files changed, 13728 insertions(+) create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitignore 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 @@ -100,6 +122,7 @@ To reproduce, run 'go mod vendor' in 'go/src'. create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/params.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_dsa.c + 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/rc4.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/rsa.go @@ -110,6 +133,31 @@ To reproduce, run 'go mod vendor' in 'go/src'. 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/golang-fips/openssl/v2/zaes.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/LICENSE + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/bbig/big.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.h + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/ed25519.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/gcm.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/hkdf.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/big.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cgo_go124.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cipher.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/des.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ec.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdh.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdsa.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ed25519.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/evp.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hash.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hkdf.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hmac.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/pbkdf2.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rand.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rc4.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rsa.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/xcrypto.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 @@ -128,45 +176,12 @@ To reproduce, run 'go mod vendor' in 'go/src'. 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/rc4.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/sha3.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/ntstatus_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 create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/internal/sysdll/sys_windows.go -diff --git a/src/go.mod b/src/go.mod -index e9da0eb1301b93..96bdcd421e1129 100644 ---- a/src/go.mod -+++ b/src/go.mod -@@ -3,8 +3,8 @@ module std - go 1.24 - - require ( -- github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf -- github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 -+ github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 -+ github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 - golang.org/x/crypto v0.30.0 - golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 - ) -diff --git a/src/go.sum b/src/go.sum -index b464f023942b74..abebb59dcd7739 100644 ---- a/src/go.sum -+++ b/src/go.sum -@@ -1,7 +1,7 @@ --github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf h1:gkjE7LMxjlaSn8fdvbT/HJrpGcW/ZnwYpps7sSBhLD4= --github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= --github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 h1:fMAxrMWT19/kkIZIuB9cjqW8SqRxCH2+2ZiZr5qrpuI= --github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= -+github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 h1:OhuURhDVbg+f/BvlG+qT5sQVkutwhI0Kmsy7koQ4l9A= -+github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= -+github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 h1:KB8xmJcFSPlZFMg2mxz5b6DCE8k1qpHy2HFevAJLELI= -+github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= - golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= - golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= - golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 h1:+Yk1FZ5E+/ewA0nOO/HRYs9E4yeqpGOShuSAdzCNNoQ= diff --git a/src/vendor/github.com/golang-fips/openssl/v2/.gitignore b/src/vendor/github.com/golang-fips/openssl/v2/.gitignore new file mode 100644 index 00000000000000..79b5594df7fa29 @@ -2148,10 +2163,10 @@ index 00000000000000..bc5f1117fd4355 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go new file mode 100644 -index 00000000000000..f96db2cd5efcad +index 00000000000000..cd237025109997 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go -@@ -0,0 +1,228 @@ +@@ -0,0 +1,218 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -2244,7 +2259,7 @@ index 00000000000000..f96db2cd5efcad + if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { + return nil, err + } -+ pubk, err := NewPublicKeyEd25519(pub) ++ pubk, err := NewPublicKeyEd25119(pub) + if err != nil { + return nil, err + } @@ -2262,24 +2277,14 @@ index 00000000000000..f96db2cd5efcad + return priv, nil +} + -+// Deprecated: use NewPrivateKeyEd25519 instead. +func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { -+ return NewPrivateKeyEd25519(priv) -+} -+ -+func NewPrivateKeyEd25519(priv []byte) (*PrivateKeyEd25519, error) { + if len(priv) != privateKeySizeEd25519 { + panic("ed25519: bad private key length: " + strconv.Itoa(len(priv))) + } + return NewPrivateKeyEd25519FromSeed(priv[:seedSizeEd25519]) +} + -+// Deprecated: use NewPublicKeyEd25519 instead. +func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { -+ return NewPublicKeyEd25519(pub) -+} -+ -+func NewPublicKeyEd25519(pub []byte) (*PublicKeyEd25519, error) { + if len(pub) != publicKeySizeEd25519 { + panic("ed25519: bad public key length: " + strconv.Itoa(len(pub))) + } @@ -2382,10 +2387,10 @@ index 00000000000000..f96db2cd5efcad +} 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..8b5b367f9f8092 +index 00000000000000..ef68bbfb8fb065 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/evp.go -@@ -0,0 +1,580 @@ +@@ -0,0 +1,569 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -2436,8 +2441,29 @@ index 00000000000000..8b5b367f9f8092 + +// hashToMD converts a hash.Hash implementation from this package to a GO_EVP_MD_PTR. +func hashToMD(h hash.Hash) C.GO_EVP_MD_PTR { -+ if h, ok := h.(*evpHash); ok { -+ return h.alg.md ++ var ch crypto.Hash ++ switch h.(type) { ++ case *sha1Hash, *sha1Marshal: ++ ch = crypto.SHA1 ++ case *sha224Hash, *sha224Marshal: ++ ch = crypto.SHA224 ++ case *sha256Hash, *sha256Marshal: ++ ch = crypto.SHA256 ++ case *sha384Hash, *sha384Marshal: ++ ch = crypto.SHA384 ++ case *sha512Hash, *sha512Marshal: ++ ch = crypto.SHA512 ++ case *sha3_224Hash: ++ ch = crypto.SHA3_224 ++ case *sha3_256Hash: ++ ch = crypto.SHA3_256 ++ case *sha3_384Hash: ++ ch = crypto.SHA3_384 ++ case *sha3_512Hash: ++ ch = crypto.SHA3_512 ++ } ++ if ch != 0 { ++ return cryptoHashToMD(ch) + } + return nil +} @@ -2456,110 +2482,78 @@ index 00000000000000..8b5b367f9f8092 + return md, nil +} + -+type hashAlgorithm struct { -+ md C.GO_EVP_MD_PTR -+ ch crypto.Hash -+ size int -+ blockSize int -+ marshallable bool -+ magic string -+ marshalledSize int -+} -+ -+// loadHash converts a crypto.Hash to a EVP_MD. -+func loadHash(ch crypto.Hash) *hashAlgorithm { ++// cryptoHashToMD converts a crypto.Hash to a GO_EVP_MD_PTR. ++func cryptoHashToMD(ch crypto.Hash) (md C.GO_EVP_MD_PTR) { + if v, ok := cacheMD.Load(ch); ok { -+ return v.(*hashAlgorithm) ++ return v.(C.GO_EVP_MD_PTR) + } -+ -+ var hash hashAlgorithm -+ switch ch { -+ case crypto.RIPEMD160: -+ hash.md = C.go_openssl_EVP_ripemd160() -+ case crypto.MD4: -+ hash.md = C.go_openssl_EVP_md4() -+ case crypto.MD5: -+ hash.md = C.go_openssl_EVP_md5() -+ hash.magic = md5Magic -+ hash.marshalledSize = md5MarshaledSize -+ case crypto.MD5SHA1: ++ defer func() { ++ if md != nil { ++ switch vMajor { ++ case 1: ++ // On OpenSSL 1 EVP_MD objects can be not-nil even ++ // when they are not supported. We need to pass the md ++ // to a EVP_MD_CTX to really know if they can be used. ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if C.go_openssl_EVP_DigestInit_ex(ctx, md, nil) != 1 { ++ md = nil ++ } ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ case 3: ++ // On OpenSSL 3, directly operating on a EVP_MD object ++ // not created by EVP_MD_fetch has negative performance ++ // implications, as digest operations will have ++ // to fetch it on every call. Better to just fetch it once here. ++ md = C.go_openssl_EVP_MD_fetch(nil, C.go_openssl_EVP_MD_get0_name(md), nil) ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ } ++ cacheMD.Store(ch, md) ++ }() ++ // SupportsHash returns false for MD5SHA1 because we don't ++ // provide a hash.Hash implementation for it. Yet, it can ++ // still be used when signing/verifying with an RSA key. ++ if ch == crypto.MD5SHA1 { + if vMajor == 1 && vMinor == 0 { -+ // OpenSSL 1.0.2 does not support MD5SHA1. -+ hash.md = nil ++ return C.go_openssl_EVP_md5_sha1_backport() + } else { -+ hash.md = C.go_openssl_EVP_md5_sha1() ++ 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: -+ hash.md = C.go_openssl_EVP_sha1() -+ hash.magic = sha1Magic -+ hash.marshalledSize = sha1MarshaledSize ++ return C.go_openssl_EVP_sha1() + case crypto.SHA224: -+ hash.md = C.go_openssl_EVP_sha224() -+ hash.magic = magic224 -+ hash.marshalledSize = marshaledSize256 ++ return C.go_openssl_EVP_sha224() + case crypto.SHA256: -+ hash.md = C.go_openssl_EVP_sha256() -+ hash.magic = magic256 -+ hash.marshalledSize = marshaledSize256 ++ return C.go_openssl_EVP_sha256() + case crypto.SHA384: -+ hash.md = C.go_openssl_EVP_sha384() -+ hash.magic = magic384 -+ hash.marshalledSize = marshaledSize512 ++ return C.go_openssl_EVP_sha384() + case crypto.SHA512: -+ hash.md = C.go_openssl_EVP_sha512() -+ hash.magic = magic512 -+ hash.marshalledSize = marshaledSize512 -+ case crypto.SHA512_224: -+ if versionAtOrAbove(1, 1, 1) { -+ hash.md = C.go_openssl_EVP_sha512_224() -+ hash.magic = magic512_224 -+ hash.marshalledSize = marshaledSize512 -+ } -+ case crypto.SHA512_256: -+ if versionAtOrAbove(1, 1, 1) { -+ hash.md = C.go_openssl_EVP_sha512_256() -+ hash.magic = magic512_256 -+ hash.marshalledSize = marshaledSize512 -+ } ++ return C.go_openssl_EVP_sha512() + case crypto.SHA3_224: + if versionAtOrAbove(1, 1, 1) { -+ hash.md = C.go_openssl_EVP_sha3_224() ++ return C.go_openssl_EVP_sha3_224() + } + case crypto.SHA3_256: + if versionAtOrAbove(1, 1, 1) { -+ hash.md = C.go_openssl_EVP_sha3_256() ++ return C.go_openssl_EVP_sha3_256() + } + case crypto.SHA3_384: + if versionAtOrAbove(1, 1, 1) { -+ hash.md = C.go_openssl_EVP_sha3_384() ++ return C.go_openssl_EVP_sha3_384() + } + case crypto.SHA3_512: + if versionAtOrAbove(1, 1, 1) { -+ hash.md = C.go_openssl_EVP_sha3_512() -+ } -+ } -+ if hash.md == nil { -+ cacheMD.Store(ch, (*hashAlgorithm)(nil)) -+ return nil -+ } -+ hash.ch = ch -+ hash.size = int(C.go_openssl_EVP_MD_get_size(hash.md)) -+ hash.blockSize = int(C.go_openssl_EVP_MD_get_block_size(hash.md)) -+ if vMajor == 3 { -+ // On OpenSSL 3, directly operating on a EVP_MD object -+ // not created by EVP_MD_fetch has negative performance -+ // implications, as digest operations will have -+ // to fetch it on every call. Better to just fetch it once here. -+ md := C.go_openssl_EVP_MD_fetch(nil, C.go_openssl_EVP_MD_get0_name(hash.md), nil) -+ // Don't overwrite md in case it can't be fetched, as the md may still be used -+ // outside of EVP_MD_CTX, for example to sign and verify RSA signatures. -+ if md != nil { -+ hash.md = md ++ return C.go_openssl_EVP_sha3_512() + } + } -+ hash.marshallable = hash.magic != "" && isHashMarshallable(hash.md) -+ cacheMD.Store(ch, &hash) -+ return &hash ++ return nil +} + +// generateEVPPKey generates a new EVP_PKEY with the given id and properties. @@ -2701,11 +2695,11 @@ index 00000000000000..8b5b367f9f8092 + } + } + case C.GO_RSA_PKCS1_PSS_PADDING: -+ alg := loadHash(ch) -+ if alg == nil { ++ md := cryptoHashToMD(ch) ++ if md == nil { + return nil, errors.New("crypto/rsa: unsupported hash function") + } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(alg.md)) != 1 { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { + return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + } + // setPadding must happen after setting EVP_PKEY_CTRL_MD. @@ -2721,11 +2715,11 @@ index 00000000000000..8b5b367f9f8092 + case C.GO_RSA_PKCS1_PADDING: + if ch != 0 { + // We support unhashed messages. -+ alg := loadHash(ch) -+ if alg == nil { ++ md := cryptoHashToMD(ch) ++ if md == nil { + return nil, errors.New("crypto/rsa: unsupported hash function") + } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(alg.md)) != 1 { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { + return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + } + if err := setPadding(); err != nil { @@ -2840,8 +2834,8 @@ index 00000000000000..8b5b367f9f8092 +} + +func evpHashSign(withKey withKeyFunc, h crypto.Hash, msg []byte) ([]byte, error) { -+ alg := loadHash(h) -+ if alg == nil { ++ md := cryptoHashToMD(h) ++ if md == nil { + return nil, errors.New("unsupported hash function: " + strconv.Itoa(int(h))) + } + var out []byte @@ -2852,7 +2846,7 @@ index 00000000000000..8b5b367f9f8092 + } + defer C.go_openssl_EVP_MD_CTX_free(ctx) + if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { -+ return C.go_openssl_EVP_DigestSignInit(ctx, nil, alg.md, nil, key) ++ return C.go_openssl_EVP_DigestSignInit(ctx, nil, md, nil, key) + }) != 1 { + return nil, newOpenSSLError("EVP_DigestSignInit failed") + } @@ -2872,8 +2866,8 @@ index 00000000000000..8b5b367f9f8092 +} + +func evpHashVerify(withKey withKeyFunc, h crypto.Hash, msg, sig []byte) error { -+ alg := loadHash(h) -+ if alg == nil { ++ md := cryptoHashToMD(h) ++ if md == nil { + return errors.New("unsupported hash function: " + strconv.Itoa(int(h))) + } + ctx := C.go_openssl_EVP_MD_CTX_new() @@ -2882,7 +2876,7 @@ index 00000000000000..8b5b367f9f8092 + } + defer C.go_openssl_EVP_MD_CTX_free(ctx) + if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { -+ return C.go_openssl_EVP_DigestVerifyInit(ctx, nil, alg.md, nil, key) ++ return C.go_openssl_EVP_DigestVerifyInit(ctx, nil, md, nil, key) + }) != 1 { + return newOpenSSLError("EVP_DigestVerifyInit failed") + } @@ -3222,10 +3216,10 @@ index 00000000000000..626f184badc53d +} 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..f5cdced630679f +index 00000000000000..1165f99157c663 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h -@@ -0,0 +1,261 @@ +@@ -0,0 +1,262 @@ +// This header file describes the OpenSSL ABI as built for use in Go. + +#include // size_t @@ -3255,6 +3249,7 @@ index 00000000000000..f5cdced630679f +int go_openssl_version_patch(void* handle); +int go_openssl_thread_setup(void); +void go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch); ++const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void); +void go_openssl_DSA_get0_pqg_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *p, GO_BIGNUM_PTR *q, GO_BIGNUM_PTR *g); +int go_openssl_DSA_set0_pqg_backport(GO_DSA_PTR d, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g); +void go_openssl_DSA_get0_key_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *pub_key, GO_BIGNUM_PTR *priv_key); @@ -3490,10 +3485,10 @@ index 00000000000000..f5cdced630679f \ 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..b2109857b49bdf +index 00000000000000..6fd3a518906004 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/hash.go -@@ -0,0 +1,714 @@ +@@ -0,0 +1,1041 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -3510,9 +3505,6 @@ index 00000000000000..b2109857b49bdf + "unsafe" +) + -+// maxHashSize is the size of SHA52 and SHA3_512, the largest hashes we support. -+const maxHashSize = 64 -+ +// 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). @@ -3525,7 +3517,7 @@ index 00000000000000..b2109857b49bdf +// 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, loadHash(ch).md, nil) != 0 ++ 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 MD4(p []byte) (sum [16]byte) { @@ -3577,43 +3569,9 @@ index 00000000000000..b2109857b49bdf + return +} + -+func SHA512_224(p []byte) (sum [28]byte) { -+ if !hashOneShot(crypto.SHA512_224, p, sum[:]) { -+ panic("openssl: SHA512 failed") -+ } -+ return -+} -+ -+func SHA512_256(p []byte) (sum [32]byte) { -+ if !hashOneShot(crypto.SHA512_256, p, sum[:]) { -+ panic("openssl: SHA512_256 failed") -+ } -+ return -+} -+ -+// cacheHashSupported is a cache of crypto.Hash support. -+var cacheHashSupported sync.Map -+ -+// SupportsHash reports whether the current OpenSSL version supports the given hash. ++// SupportsHash returns true if a hash.Hash implementation is supported for h. +func SupportsHash(h crypto.Hash) bool { -+ if v, ok := cacheHashSupported.Load(h); ok { -+ return v.(bool) -+ } -+ alg := loadHash(h) -+ if alg == nil { -+ cacheHashSupported.Store(h, false) -+ return false -+ } -+ // EVP_MD objects can be non-nil even when they can't be used -+ // in a EVP_MD_CTX, e.g. MD5 in FIPS mode. We need to prove -+ // if they can be used by passing them to a EVP_MD_CTX. -+ var supported bool -+ if ctx := C.go_openssl_EVP_MD_CTX_new(); ctx != nil { -+ supported = C.go_openssl_EVP_DigestInit_ex(ctx, alg.md, nil) == 1 -+ C.go_openssl_EVP_MD_CTX_free(ctx) -+ } -+ cacheHashSupported.Store(h, supported) -+ return supported ++ return cryptoHashToMD(h) != nil +} + +func SHA3_224(p []byte) (sum [28]byte) { @@ -3644,79 +3602,21 @@ index 00000000000000..b2109857b49bdf + return +} + -+// NewMD4 returns a new MD4 hash. -+// The returned hash doesn't implement encoding.BinaryMarshaler and -+// encoding.BinaryUnmarshaler. -+func NewMD4() hash.Hash { -+ return newEvpHash(crypto.MD4) -+} -+ -+// NewMD5 returns a new MD5 hash. -+func NewMD5() hash.Hash { -+ return newEvpHash(crypto.MD5) -+} -+ -+// NewSHA1 returns a new SHA1 hash. -+func NewSHA1() hash.Hash { -+ return newEvpHash(crypto.SHA1) -+} -+ -+// NewSHA224 returns a new SHA224 hash. -+func NewSHA224() hash.Hash { -+ return newEvpHash(crypto.SHA224) -+} -+ -+// NewSHA256 returns a new SHA256 hash. -+func NewSHA256() hash.Hash { -+ return newEvpHash(crypto.SHA256) -+} -+ -+// NewSHA384 returns a new SHA384 hash. -+func NewSHA384() hash.Hash { -+ return newEvpHash(crypto.SHA384) -+} -+ -+// NewSHA512 returns a new SHA512 hash. -+func NewSHA512() hash.Hash { -+ return newEvpHash(crypto.SHA512) -+} -+ -+// NewSHA512_224 returns a new SHA512_224 hash. -+func NewSHA512_224() hash.Hash { -+ return newEvpHash(crypto.SHA512_224) -+} -+ -+// NewSHA512_256 returns a new SHA512_256 hash. -+func NewSHA512_256() hash.Hash { -+ return newEvpHash(crypto.SHA512_256) -+} -+ -+// NewSHA3_224 returns a new SHA3-224 hash. -+func NewSHA3_224() hash.Hash { -+ return newEvpHash(crypto.SHA3_224) -+} -+ -+// NewSHA3_256 returns a new SHA3-256 hash. -+func NewSHA3_256() hash.Hash { -+ return newEvpHash(crypto.SHA3_256) -+} -+ -+// NewSHA3_384 returns a new SHA3-384 hash. -+func NewSHA3_384() hash.Hash { -+ return newEvpHash(crypto.SHA3_384) -+} -+ -+// NewSHA3_512 returns a new SHA3-512 hash. -+func NewSHA3_512() hash.Hash { -+ return newEvpHash(crypto.SHA3_512) -+} ++var isMarshallableCache sync.Map + -+// isHashMarshallable returns true if the memory layout of md ++// isHashMarshallable returns true if the memory layout of cb +// is known by this library and can therefore be marshalled. -+func isHashMarshallable(md C.GO_EVP_MD_PTR) bool { ++func isHashMarshallable(ch crypto.Hash) bool { + if vMajor == 1 { + return true + } ++ if v, ok := isMarshallableCache.Load(ch); ok { ++ return v.(bool) ++ } ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ return false ++ } + prov := C.go_openssl_EVP_MD_get0_provider(md) + if prov == nil { + return false @@ -3729,73 +3629,51 @@ index 00000000000000..b2109857b49bdf + // We only know the memory layout of the built-in providers. + // See evpHash.hashState for more details. + marshallable := name == "default" || name == "fips" ++ isMarshallableCache.Store(ch, marshallable) + return marshallable +} + -+// cloneHash is an interface that defines a Clone method. -+// -+// hahs.CloneHash will probably be added in Go 1.25, see https://golang.org/issue/69521, -+// but we need it now. -+type cloneHash interface { -+ hash.Hash -+ // Clone returns a separate Hash instance with the same state as h. -+ Clone() hash.Hash -+} -+ -+var _ hash.Hash = (*evpHash)(nil) -+var _ cloneHash = (*evpHash)(nil) -+ +// evpHash implements generic hash methods. +type evpHash struct { -+ alg *hashAlgorithm + 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 ++ ctx2 C.GO_EVP_MD_CTX_PTR ++ size int ++ blockSize int ++ marshallable bool +} + +func newEvpHash(ch crypto.Hash) *evpHash { -+ alg := loadHash(ch) -+ if alg == nil { ++ md := cryptoHashToMD(ch) ++ if md == nil { + panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) + } -+ h := &evpHash{alg: alg} -+ // Don't call init() yet, it would be wasteful -+ // if the caller only wants to know the hash type. This -+ // is a common pattern in this package, as some functions -+ // accept a `func() hash.Hash` parameter and call it just -+ // to know the hash type. -+ return h -+} -+ -+func (h *evpHash) finalize() { -+ if h.ctx != nil { -+ C.go_openssl_EVP_MD_CTX_free(h.ctx) ++ 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")) + } -+ if h.ctx2 != nil { -+ C.go_openssl_EVP_MD_CTX_free(h.ctx2) ++ ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ blockSize := int(C.go_openssl_EVP_MD_get_block_size(md)) ++ h := &evpHash{ ++ ctx: ctx, ++ ctx2: ctx2, ++ size: ch.Size(), ++ blockSize: blockSize, ++ marshallable: isHashMarshallable(ch), + } ++ runtime.SetFinalizer(h, (*evpHash).finalize) ++ return h +} + -+func (h *evpHash) init() { -+ if h.ctx != nil { -+ return -+ } -+ h.ctx = C.go_openssl_EVP_MD_CTX_new() -+ if C.go_openssl_EVP_DigestInit_ex(h.ctx, h.alg.md, nil) != 1 { -+ C.go_openssl_EVP_MD_CTX_free(h.ctx) -+ panic(newOpenSSLError("EVP_DigestInit_ex")) -+ } -+ h.ctx2 = C.go_openssl_EVP_MD_CTX_new() -+ runtime.SetFinalizer(h, (*evpHash).finalize) ++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() { -+ if h.ctx == nil { -+ // The hash is not initialized yet, no need to reset. -+ return -+ } + // 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 { @@ -3805,11 +3683,7 @@ index 00000000000000..b2109857b49bdf +} + +func (h *evpHash) Write(p []byte) (int, error) { -+ if len(p) == 0 { -+ return 0, nil -+ } -+ h.init() -+ if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&*addr(p)), C.size_t(len(p))) != 1 { ++ 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) @@ -3817,11 +3691,7 @@ index 00000000000000..b2109857b49bdf +} + +func (h *evpHash) WriteString(s string) (int, error) { -+ if len(s) == 0 { -+ return 0, nil -+ } -+ h.init() -+ if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(unsafe.StringData(s)), C.size_t(len(s))) == 0 { ++ 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) @@ -3829,7 +3699,6 @@ index 00000000000000..b2109857b49bdf +} + +func (h *evpHash) WriteByte(c byte) error { -+ h.init() + if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&c), 1) == 0 { + panic("openssl: EVP_DigestUpdate failed") + } @@ -3838,53 +3707,56 @@ index 00000000000000..b2109857b49bdf +} + +func (h *evpHash) Size() int { -+ return h.alg.size ++ return h.size +} + +func (h *evpHash) BlockSize() int { -+ return h.alg.blockSize ++ return h.blockSize +} + -+func (h *evpHash) Sum(in []byte) []byte { -+ h.init() -+ out := make([]byte, h.Size(), maxHashSize) // explicit cap to allow stack allocation ++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) -+ return append(in, out...) +} + -+// Clone returns a new evpHash object that is a deep clone of itself. ++// clone returns a new evpHash object that is a deep clone of itself. +// The duplicate object contains all state and data contained in the +// original object at the point of duplication. -+func (h *evpHash) Clone() hash.Hash { -+ h2 := &evpHash{alg: h.alg} -+ if h.ctx != nil { -+ h2.ctx = C.go_openssl_EVP_MD_CTX_new() -+ if h2.ctx == nil { -+ panic(newOpenSSLError("EVP_MD_CTX_new")) -+ } -+ if C.go_openssl_EVP_MD_CTX_copy_ex(h2.ctx, h.ctx) != 1 { -+ C.go_openssl_EVP_MD_CTX_free(h2.ctx) -+ panic(newOpenSSLError("EVP_MD_CTX_copy")) -+ } -+ h2.ctx2 = C.go_openssl_EVP_MD_CTX_new() -+ if h2.ctx2 == nil { -+ C.go_openssl_EVP_MD_CTX_free(h2.ctx) -+ panic(newOpenSSLError("EVP_MD_CTX_new")) -+ } -+ runtime.SetFinalizer(h2, (*evpHash).finalize) ++func (h *evpHash) clone() (*evpHash, error) { ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_MD_CTX_new") + } -+ runtime.KeepAlive(h) -+ return h2 ++ if C.go_openssl_EVP_MD_CTX_copy_ex(ctx, h.ctx) != 1 { ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ return nil, newOpenSSLError("EVP_MD_CTX_copy") ++ } ++ ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ if ctx2 == nil { ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ return nil, newOpenSSLError("EVP_MD_CTX_new") ++ } ++ cloned := &evpHash{ ++ ctx: ctx, ++ ctx2: ctx2, ++ size: h.size, ++ blockSize: h.blockSize, ++ marshallable: h.marshallable, ++ } ++ runtime.SetFinalizer(cloned, (*evpHash).finalize) ++ return cloned, nil +} + +// hashState returns a pointer to the internal hash structure. +// +// The EVP_MD_CTX memory layout has changed in OpenSSL 3 +// and the property holding the internal structure is no longer md_data but algctx. -+func hashState(ctx C.GO_EVP_MD_CTX_PTR) unsafe.Pointer { ++func (h *evpHash) hashState() unsafe.Pointer { ++ if !h.marshallable { ++ panic("openssl: hash state is not marshallable") ++ } + switch vMajor { + case 1: + // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. @@ -3893,7 +3765,7 @@ index 00000000000000..b2109857b49bdf + _ C.ulong + md_data unsafe.Pointer + } -+ return (*mdCtx)(unsafe.Pointer(ctx)).md_data ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).md_data + case 3: + // https://github.com/openssl/openssl/blob/5675a5aaf6a2e489022bcfc18330dae9263e598e/crypto/evp/evp_local.h#L16. + type mdCtx struct { @@ -3902,98 +3774,49 @@ index 00000000000000..b2109857b49bdf + _ [3]unsafe.Pointer + algctx unsafe.Pointer + } -+ return (*mdCtx)(unsafe.Pointer(ctx)).algctx ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).algctx + default: + panic(errUnsupportedVersion()) + } +} + -+func (d *evpHash) MarshalBinary() ([]byte, error) { -+ if !d.alg.marshallable { -+ return nil, errors.New("openssl: hash state is not marshallable") ++// 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), + } -+ buf := make([]byte, 0, d.alg.marshalledSize) -+ return d.AppendBinary(buf) +} + -+func (d *evpHash) AppendBinary(buf []byte) ([]byte, error) { -+ defer runtime.KeepAlive(d) -+ d.init() -+ if !d.alg.marshallable { -+ return nil, errors.New("openssl: hash state is not marshallable") -+ } -+ state := hashState(d.ctx) -+ if state == nil { -+ return nil, errors.New("openssl: can't retrieve hash state") -+ } -+ var appender interface { -+ AppendBinary([]byte) ([]byte, error) -+ } -+ switch d.alg.ch { -+ case crypto.MD5: -+ appender = (*md5State)(state) -+ case crypto.SHA1: -+ appender = (*sha1State)(state) -+ case crypto.SHA224: -+ appender = (*sha256State)(state) -+ case crypto.SHA256: -+ appender = (*sha256State)(state) -+ case crypto.SHA384: -+ appender = (*sha512State)(state) -+ case crypto.SHA512: -+ appender = (*sha512State)(state) -+ case crypto.SHA512_224: -+ appender = (*sha512State)(state) -+ case crypto.SHA512_256: -+ appender = (*sha512State)(state) -+ default: -+ panic("openssl: unsupported hash function: " + strconv.Itoa(int(d.alg.ch))) -+ } -+ buf = append(buf, d.alg.magic[:]...) -+ return appender.AppendBinary(buf) ++type md4Hash struct { ++ *evpHash ++ out [16]byte +} + -+func (d *evpHash) UnmarshalBinary(b []byte) error { -+ defer runtime.KeepAlive(d) -+ d.init() -+ if !d.alg.marshallable { -+ return errors.New("openssl: hash state is not marshallable") -+ } -+ if len(b) < len(d.alg.magic) || string(b[:len(d.alg.magic)]) != string(d.alg.magic[:]) { -+ return errors.New("openssl: invalid hash state identifier") -+ } -+ if len(b) != d.alg.marshalledSize { -+ return errors.New("openssl: invalid hash state size") -+ } -+ state := hashState(d.ctx) -+ if state == nil { -+ return errors.New("openssl: can't retrieve hash state") -+ } -+ b = b[len(d.alg.magic):] -+ var unmarshaler interface { -+ UnmarshalBinary([]byte) error ++func (h *md4Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *md4Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err + } -+ switch d.alg.ch { -+ case crypto.MD5: -+ unmarshaler = (*md5State)(state) -+ case crypto.SHA1: -+ unmarshaler = (*sha1State)(state) -+ case crypto.SHA224: -+ unmarshaler = (*sha256State)(state) -+ case crypto.SHA256: -+ unmarshaler = (*sha256State)(state) -+ case crypto.SHA384: -+ unmarshaler = (*sha512State)(state) -+ case crypto.SHA512: -+ unmarshaler = (*sha512State)(state) -+ case crypto.SHA512_224: -+ unmarshaler = (*sha512State)(state) -+ case crypto.SHA512_256: -+ unmarshaler = (*sha512State)(state) -+ default: -+ panic("openssl: unsupported hash function: " + strconv.Itoa(int(d.alg.ch))) ++ return &md4Hash{evpHash: c}, nil ++} ++ ++// NewMD5 returns a new MD5 hash. ++func NewMD5() hash.Hash { ++ h := md5Hash{evpHash: newEvpHash(crypto.MD5)} ++ if h.marshallable { ++ return &md5Marshal{h} + } -+ return unmarshaler.UnmarshalBinary(b) ++ return &h +} + +// md5State layout is taken from @@ -4005,12 +3828,53 @@ index 00000000000000..b2109857b49bdf + 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[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *md5Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &md5Hash{evpHash: c}, nil ++} ++ +const ( + md5Magic = "md5\x01" + md5MarshaledSize = len(md5Magic) + 4*4 + 64 + 8 +) + -+func (d *md5State) UnmarshalBinary(b []byte) error { ++type md5Marshal struct { ++ md5Hash ++} ++ ++func (h *md5Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, md5MarshaledSize) ++ return h.AppendBinary(buf) ++} ++ ++func (h *md5Marshal) UnmarshalBinary(b []byte) error { ++ if len(b) < len(md5Magic) || string(b[:len(md5Magic)]) != md5Magic { ++ return errors.New("crypto/md5: invalid hash state identifier") ++ } ++ if len(b) != md5MarshaledSize { ++ return errors.New("crypto/md5: invalid hash state size") ++ } ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/md5: can't retrieve hash state") ++ } ++ b = b[len(md5Magic):] + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) + b, d.h[2] = consumeUint32(b) @@ -4023,7 +3887,13 @@ index 00000000000000..b2109857b49bdf + return nil +} + -+func (d *md5State) AppendBinary(buf []byte) ([]byte, error) { ++func (h *md5Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/md5: can't retrieve hash state") ++ } ++ ++ buf = append(buf, md5Magic...) + buf = appendUint32(buf, d.h[0]) + buf = appendUint32(buf, d.h[1]) + buf = appendUint32(buf, d.h[2]) @@ -4034,6 +3904,36 @@ index 00000000000000..b2109857b49bdf + return buf, nil +} + ++// NewSHA1 returns a new SHA1 hash. ++func NewSHA1() hash.Hash { ++ h := sha1Hash{evpHash: newEvpHash(crypto.SHA1)} ++ if h.marshallable { ++ return &sha1Marshal{h} ++ } ++ return &h ++} ++ ++type sha1Hash struct { ++ *evpHash ++ out [20]byte ++} ++ ++func (h *sha1Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha1Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha1Hash{evpHash: c}, nil ++} ++ +// sha1State layout is taken from +// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34. +type sha1State struct { @@ -4048,7 +3948,27 @@ index 00000000000000..b2109857b49bdf + sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 +) + -+func (d *sha1State) UnmarshalBinary(b []byte) error { ++type sha1Marshal struct { ++ sha1Hash ++} ++ ++func (h *sha1Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, sha1MarshaledSize) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha1Marshal) UnmarshalBinary(b []byte) error { ++ if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { ++ return errors.New("crypto/sha1: invalid hash state identifier") ++ } ++ if len(b) != sha1MarshaledSize { ++ return errors.New("crypto/sha1: invalid hash state size") ++ } ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha1: can't retrieve hash state") ++ } ++ b = b[len(sha1Magic):] + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) + b, d.h[2] = consumeUint32(b) @@ -4062,7 +3982,12 @@ index 00000000000000..b2109857b49bdf + return nil +} + -+func (d *sha1State) AppendBinary(buf []byte) ([]byte, error) { ++func (h *sha1Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha1: can't retrieve hash state") ++ } ++ buf = append(buf, sha1Magic...) + buf = appendUint32(buf, d.h[0]) + buf = appendUint32(buf, d.h[1]) + buf = appendUint32(buf, d.h[2]) @@ -4074,11 +3999,71 @@ index 00000000000000..b2109857b49bdf + return buf, nil +} + -+const ( -+ magic224 = "sha\x02" -+ magic256 = "sha\x03" -+ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 -+) ++// NewSHA224 returns a new SHA224 hash. ++func NewSHA224() hash.Hash { ++ h := sha224Hash{evpHash: newEvpHash(crypto.SHA224)} ++ if h.marshallable { ++ return &sha224Marshal{h} ++ } ++ return &h ++} ++ ++type sha224Hash struct { ++ *evpHash ++ out [224 / 8]byte ++} ++ ++func (h *sha224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha224Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha224Hash{evpHash: c}, nil ++} ++ ++// NewSHA256 returns a new SHA256 hash. ++func NewSHA256() hash.Hash { ++ h := sha256Hash{evpHash: newEvpHash(crypto.SHA256)} ++ if h.marshallable { ++ return &sha256Marshal{h} ++ } ++ return &h ++} ++ ++type sha256Hash struct { ++ *evpHash ++ out [256 / 8]byte ++} ++ ++func (h *sha256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha256Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha256Hash{evpHash: c}, nil ++} ++ ++const ( ++ magic224 = "sha\x02" ++ magic256 = "sha\x03" ++ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 ++) + +// sha256State layout is taken from +// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L51. @@ -4089,7 +4074,64 @@ index 00000000000000..b2109857b49bdf + nx uint32 +} + -+func (d *sha256State) UnmarshalBinary(b []byte) error { ++type sha224Marshal struct { ++ sha224Hash ++} ++ ++type sha256Marshal struct { ++ sha256Hash ++} ++ ++func (h *sha224Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, marshaledSize256) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha256Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, marshaledSize256) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha224Marshal) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ 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 ++} ++ ++func (h *sha256Marshal) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ 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) @@ -4106,7 +4148,32 @@ index 00000000000000..b2109857b49bdf + return nil +} + -+func (d *sha256State) AppendBinary(buf []byte) ([]byte, error) { ++func (h *sha224Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ buf = append(buf, magic224...) ++ buf = appendUint32(buf, d.h[0]) ++ buf = appendUint32(buf, d.h[1]) ++ buf = appendUint32(buf, d.h[2]) ++ buf = appendUint32(buf, d.h[3]) ++ buf = appendUint32(buf, d.h[4]) ++ buf = appendUint32(buf, d.h[5]) ++ buf = appendUint32(buf, d.h[6]) ++ buf = appendUint32(buf, d.h[7]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return buf, nil ++} ++ ++func (h *sha256Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ buf = append(buf, magic256...) + buf = appendUint32(buf, d.h[0]) + buf = appendUint32(buf, d.h[1]) + buf = appendUint32(buf, d.h[2]) @@ -4121,6 +4188,66 @@ index 00000000000000..b2109857b49bdf + return buf, nil +} + ++// NewSHA384 returns a new SHA384 hash. ++func NewSHA384() hash.Hash { ++ h := sha384Hash{evpHash: newEvpHash(crypto.SHA384)} ++ if h.marshallable { ++ return &sha384Marshal{h} ++ } ++ return &h ++} ++ ++type sha384Hash struct { ++ *evpHash ++ out [384 / 8]byte ++} ++ ++func (h *sha384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha384Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha384Hash{evpHash: c}, nil ++} ++ ++// NewSHA512 returns a new SHA512 hash. ++func NewSHA512() hash.Hash { ++ h := sha512Hash{evpHash: newEvpHash(crypto.SHA512)} ++ if h.marshallable { ++ return &sha512Marshal{h} ++ } ++ return &h ++} ++ ++type sha512Hash struct { ++ *evpHash ++ out [512 / 8]byte ++} ++ ++func (h *sha512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha512Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha512Hash{evpHash: c}, nil ++} ++ +// sha512State layout is taken from +// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95. +type sha512State struct { @@ -4138,12 +4265,70 @@ index 00000000000000..b2109857b49bdf + marshaledSize512 = len(magic512) + 8*8 + 128 + 8 +) + -+func (d *sha512State) MarshalBinary() ([]byte, error) { ++type sha384Marshal struct { ++ sha384Hash ++} ++ ++type sha512Marshal struct { ++ sha512Hash ++} ++ ++func (h *sha384Marshal) MarshalBinary() ([]byte, error) { ++ buf := make([]byte, 0, marshaledSize512) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha512Marshal) MarshalBinary() ([]byte, error) { + buf := make([]byte, 0, marshaledSize512) -+ return d.AppendBinary(buf) ++ return h.AppendBinary(buf) ++} ++ ++func (h *sha384Marshal) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ 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 +} + -+func (d *sha512State) UnmarshalBinary(b []byte) error { ++func (h *sha512Marshal) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ 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) @@ -4160,7 +4345,32 @@ index 00000000000000..b2109857b49bdf + return nil +} + -+func (d *sha512State) AppendBinary(buf []byte) ([]byte, error) { ++func (h *sha384Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ buf = append(buf, magic384...) ++ buf = appendUint64(buf, d.h[0]) ++ buf = appendUint64(buf, d.h[1]) ++ buf = appendUint64(buf, d.h[2]) ++ buf = appendUint64(buf, d.h[3]) ++ buf = appendUint64(buf, d.h[4]) ++ buf = appendUint64(buf, d.h[5]) ++ buf = appendUint64(buf, d.h[6]) ++ buf = appendUint64(buf, d.h[7]) ++ buf = append(buf, d.x[:d.nx]...) ++ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) ++ buf = appendUint64(buf, d.nl>>3|d.nh<<61) ++ return buf, nil ++} ++ ++func (h *sha512Marshal) AppendBinary(buf []byte) ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ buf = append(buf, magic512...) + buf = appendUint64(buf, d.h[0]) + buf = appendUint64(buf, d.h[1]) + buf = appendUint64(buf, d.h[2]) @@ -4175,6 +4385,118 @@ index 00000000000000..b2109857b49bdf + return buf, nil +} + ++// NewSHA3_224 returns a new SHA3-224 hash. ++func NewSHA3_224() hash.Hash { ++ return &sha3_224Hash{ ++ evpHash: newEvpHash(crypto.SHA3_224), ++ } ++} ++ ++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[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_224Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_224Hash{evpHash: c}, nil ++} ++ ++// NewSHA3_256 returns a new SHA3-256 hash. ++func NewSHA3_256() hash.Hash { ++ return &sha3_256Hash{ ++ evpHash: newEvpHash(crypto.SHA3_256), ++ } ++} ++ ++type sha3_256Hash struct { ++ *evpHash ++ out [256 / 8]byte ++} ++ ++func (h *sha3_256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_256Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_256Hash{evpHash: c}, nil ++} ++ ++// NewSHA3_384 returns a new SHA3-384 hash. ++func NewSHA3_384() hash.Hash { ++ return &sha3_384Hash{ ++ evpHash: newEvpHash(crypto.SHA3_384), ++ } ++} ++ ++type sha3_384Hash struct { ++ *evpHash ++ out [384 / 8]byte ++} ++ ++func (h *sha3_384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_384Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_384Hash{evpHash: c}, nil ++} ++ ++// NewSHA3_512 returns a new SHA3-512 hash. ++func NewSHA3_512() hash.Hash { ++ return &sha3_512Hash{ ++ evpHash: newEvpHash(crypto.SHA3_512), ++ } ++} ++ ++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[:]...) ++} ++ ++// Clone returns a new [hash.Hash] object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *sha3_512Hash) Clone() (hash.Hash, error) { ++ c, err := h.clone() ++ if err != nil { ++ return nil, err ++ } ++ return &sha3_512Hash{evpHash: c}, nil ++} ++ +// appendUint64 appends x into b as a big endian byte sequence. +func appendUint64(b []byte, x uint64) []byte { + return append(b, @@ -5816,6 +6138,138 @@ index 00000000000000..5a948eafdbc6a7 + return 1; +} \ No newline at end of file +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c +new file mode 100644 +index 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 @@ -6330,10 +6784,10 @@ index 00000000000000..da5c7636173775 +} 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..437312ad795fc3 +index 00000000000000..c8f599f71c0b20 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/shims.h -@@ -0,0 +1,413 @@ +@@ -0,0 +1,416 @@ +#include // size_t +#include // uint64_t + @@ -6566,8 +7020,13 @@ index 00000000000000..437312ad795fc3 +DEFINEFUNC(int, EVP_DigestVerifyInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ +DEFINEFUNC(int, EVP_DigestVerifyFinal, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen), (ctx, sig, siglen)) \ +DEFINEFUNC_1_1_1(int, EVP_DigestVerify, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ ++DEFINEFUNC_LEGACY_1_0(int, MD5_Init, (GO_MD5_CTX_PTR c), (c)) \ ++DEFINEFUNC_LEGACY_1_0(int, MD5_Update, (GO_MD5_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ ++DEFINEFUNC_LEGACY_1_0(int, MD5_Final, (unsigned char *md, GO_MD5_CTX_PTR c), (md, c)) \ ++DEFINEFUNC_LEGACY_1_0(int, SHA1_Init, (GO_SHA_CTX_PTR c), (c)) \ ++DEFINEFUNC_LEGACY_1_0(int, SHA1_Update, (GO_SHA_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ ++DEFINEFUNC_LEGACY_1_0(int, SHA1_Final, (unsigned char *md, GO_SHA_CTX_PTR c), (md, c)) \ +DEFINEFUNC_1_1(const GO_EVP_MD_PTR, EVP_md5_sha1, (void), ()) \ -+DEFINEFUNC(const GO_EVP_MD_PTR, EVP_ripemd160, (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), ()) \ @@ -6575,8 +7034,6 @@ index 00000000000000..437312ad795fc3 +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha256, (void), ()) \ +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha384, (void), ()) \ +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha512, (void), ()) \ -+DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha512_224, (void), ()) \ -+DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha512_256, (void), ()) \ +DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_224, (void), ()) \ +DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_256, (void), ()) \ +DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_384, (void), ()) \ @@ -6919,7 +7376,7 @@ index 00000000000000..93281d6cffc352 +} 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..33134548830d3e +index 00000000000000..f342f221ea0c92 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go @@ -0,0 +1,160 @@ @@ -6960,7 +7417,7 @@ index 00000000000000..33134548830d3e + // 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 = loadHash(crypto.MD5SHA1).md ++ md = cryptoHashToMD(crypto.MD5SHA1) + } else { + h, err := hashFuncHash(fh) + if err != nil { @@ -7054,126 +7511,2955 @@ index 00000000000000..33134548830d3e +func tls1PRF3(result, secret, label, seed []byte, md C.GO_EVP_MD_PTR) error { + checkMajorVersion(3) + -+ kdf, err := fetchTLS1PRF3() ++ kdf, err := fetchTLS1PRF3() ++ if err != nil { ++ return err ++ } ++ ctx := C.go_openssl_EVP_KDF_CTX_new(kdf) ++ if ctx == nil { ++ return newOpenSSLError("EVP_KDF_CTX_new") ++ } ++ defer C.go_openssl_EVP_KDF_CTX_free(ctx) ++ ++ bld, err := newParamBuilder() ++ if err != nil { ++ return err ++ } ++ bld.addUTF8String(_OSSL_KDF_PARAM_DIGEST, C.go_openssl_EVP_MD_get0_name(md), 0) ++ bld.addOctetString(_OSSL_KDF_PARAM_SECRET, secret) ++ bld.addOctetString(_OSSL_KDF_PARAM_SEED, label) ++ bld.addOctetString(_OSSL_KDF_PARAM_SEED, seed) ++ params, err := bld.build() ++ if err != nil { ++ return err ++ } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ ++ if C.go_openssl_EVP_KDF_derive(ctx, base(result), C.size_t(len(result)), params) != 1 { ++ return newOpenSSLError("EVP_KDF_derive") ++ } ++ return nil ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/zaes.go b/src/vendor/github.com/golang-fips/openssl/v2/zaes.go +new file mode 100644 +index 00000000000000..e60a5dde390be6 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/zaes.go +@@ -0,0 +1,86 @@ ++// Code generated by cmd/genaesmodes. DO NOT EDIT. ++ ++//go:build cgo && !cmd_go_bootstrap ++ ++package openssl ++ ++import "crypto/cipher" ++ ++type cipherWithCBC struct { ++ aesCipher ++} ++ ++type cipherWithCTR struct { ++ aesCipher ++} ++ ++type cipherWithCBC_CTR struct { ++ aesCipher ++ cipherWithCBC ++ cipherWithCTR ++} ++ ++type cipherWithGCM struct { ++ aesCipher ++} ++ ++type cipherWithCBC_GCM struct { ++ aesCipher ++ cipherWithCBC ++ cipherWithGCM ++} ++ ++type cipherWithCTR_GCM struct { ++ aesCipher ++ cipherWithCTR ++ cipherWithGCM ++} ++ ++type cipherWithCBC_CTR_GCM struct { ++ aesCipher ++ cipherWithCBC ++ cipherWithCTR ++ cipherWithGCM ++} ++ ++func newAESBlock(c *evpCipher, kind cipherKind) cipher.Block { ++ aes := aesCipher{c} ++ var block cipher.Block ++ supportsCBC := loadCipher(kind, cipherModeCBC) != nil ++ supportsCTR := loadCipher(kind, cipherModeCTR) != nil ++ supportsGCM := loadCipher(kind, cipherModeGCM) != nil ++ switch { ++ case !supportsCBC && !supportsCTR && !supportsGCM: ++ block = aes ++ case supportsCBC && !supportsCTR && !supportsGCM: ++ block = cipherWithCBC{aes} ++ case !supportsCBC && supportsCTR && !supportsGCM: ++ block = cipherWithCTR{aes} ++ case supportsCBC && supportsCTR && !supportsGCM: ++ block = cipherWithCBC_CTR{aes, ++ cipherWithCBC{aes}, ++ cipherWithCTR{aes}, ++ } ++ case !supportsCBC && !supportsCTR && supportsGCM: ++ block = cipherWithGCM{aes} ++ case supportsCBC && !supportsCTR && supportsGCM: ++ block = cipherWithCBC_GCM{aes, ++ cipherWithCBC{aes}, ++ cipherWithGCM{aes}, ++ } ++ case !supportsCBC && supportsCTR && supportsGCM: ++ block = cipherWithCTR_GCM{aes, ++ cipherWithCTR{aes}, ++ cipherWithGCM{aes}, ++ } ++ case supportsCBC && supportsCTR && supportsGCM: ++ block = cipherWithCBC_CTR_GCM{aes, ++ cipherWithCBC{aes}, ++ cipherWithCTR{aes}, ++ cipherWithGCM{aes}, ++ } ++ default: ++ panic("unreachable") ++ } ++ return block ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/LICENSE b/src/vendor/github.com/microsoft/go-crypto-darwin/LICENSE +new file mode 100644 +index 00000000000000..9e841e7a26e4eb +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/LICENSE +@@ -0,0 +1,21 @@ ++ MIT License ++ ++ Copyright (c) Microsoft Corporation. ++ ++ Permission is hereby granted, free of charge, to any person obtaining a copy ++ of this software and associated documentation files (the "Software"), to deal ++ in the Software without restriction, including without limitation the rights ++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ copies of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ ++ The above copyright notice and this permission notice shall be included in all ++ copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ SOFTWARE +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/bbig/big.go b/src/vendor/github.com/microsoft/go-crypto-darwin/bbig/big.go +new file mode 100644 +index 00000000000000..73891afeab93d7 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/bbig/big.go +@@ -0,0 +1,31 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++package bbig ++ ++import ( ++ "math/big" ++ ++ "github.com/microsoft/go-crypto-darwin/xcrypto" ++) ++ ++func Enc(b *big.Int) xcrypto.BigInt { ++ if b == nil { ++ return nil ++ } ++ x := b.Bytes() ++ if len(x) == 0 { ++ return xcrypto.BigInt{} ++ } ++ return x ++} ++ ++func Dec(b xcrypto.BigInt) *big.Int { ++ if b == nil { ++ return nil ++ } ++ if len(b) == 0 { ++ return new(big.Int) ++ } ++ return new(big.Int).SetBytes(b) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.go b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.go +new file mode 100644 +index 00000000000000..5d331b8ed22252 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.go +@@ -0,0 +1,34 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package cryptokit ++ ++// #cgo CFLAGS: -Wno-deprecated-declarations ++// #cgo LDFLAGS: -L /Library/Developer/CommandLineTools/usr/lib/swift/macosx ${SRCDIR}/CryptoKit.o ++import "C" ++import "unsafe" ++ ++// base returns the address of the underlying array in b, ++// being careful not to panic when b has zero length. ++func base(b []byte) *C.uchar { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uchar)(unsafe.Pointer(&b[0])) ++} ++ ++func sbase(b []byte) *C.char { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.char)(unsafe.Pointer(&b[0])) ++} ++ ++func pbase(b []byte) unsafe.Pointer { ++ if len(b) == 0 { ++ return nil ++ } ++ return unsafe.Pointer(&b[0]) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.h b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.h +new file mode 100644 +index 00000000000000..dfc73697c392f8 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.h +@@ -0,0 +1,43 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++#ifndef CRYPTOKIT_H ++#define CRYPTOKIT_H ++ ++#include ++#include ++ ++// AES GCM encryption and decryption ++int encryptAESGCM(const uint8_t* key, size_t keyLength, ++ const uint8_t* data, size_t dataLength, ++ const uint8_t* nonce, size_t nonceLength, ++ const uint8_t* aad, size_t aadLength, ++ uint8_t* cipherText, size_t cipherTextLength, ++ uint8_t* tag); ++int decryptAESGCM(const uint8_t* key, size_t keyLength, ++ const uint8_t* data, size_t dataLength, ++ const uint8_t* nonce, size_t nonceLength, ++ const uint8_t* aad, size_t aadLength, ++ const uint8_t* tag, size_t tagLength, ++ uint8_t* out, size_t* outLength); ++ ++// Generates an Ed25519 keypair. ++// The private key is 64 bytes (first 32 bytes are the seed, next 32 bytes are the public key). ++// The public key is 32 bytes. ++void generateKeyEd25519(uint8_t* key); ++int newPrivateKeyEd25519FromSeed(uint8_t* key, const uint8_t* seed); ++int newPublicKeyEd25519(uint8_t* key, const uint8_t* pub); ++int signEd25519(const uint8_t* privateKey, const uint8_t* message, size_t messageLength, uint8_t* sigBuffer); ++int verifyEd25519(const uint8_t* publicKey, const uint8_t* message, size_t messageLength, const uint8_t* sig); ++ ++// HKDF key derivation ++int extractHKDF(int32_t hashFunction, ++ const uint8_t* secret, size_t secretLength, ++ const uint8_t* salt, size_t saltLength, ++ uint8_t* prk, size_t prkLength); ++int expandHKDF(int32_t hashFunction, ++ const uint8_t* prk, size_t prkLength, ++ const uint8_t* info, size_t infoLength, ++ uint8_t* okm, size_t okmLength); ++ ++#endif /* CRYPTOKIT_H */ +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/ed25519.go b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/ed25519.go +new file mode 100644 +index 00000000000000..2fa15c8fa5529a +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/ed25519.go +@@ -0,0 +1,72 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package cryptokit ++ ++// #include "cryptokit.h" ++import "C" ++import ( ++ "errors" ++) ++ ++// GenerateKeyEd25519 generates an Ed25519 private key using the Swift implementation. ++func GenerateKeyEd25519(key []byte) { ++ C.generateKeyEd25519(base(key)) ++} ++ ++// NewPrivateKeyEd25519FromSeed generates an Ed25519 private key from a seed. ++func NewPrivateKeyEd25519FromSeed(key, seed []byte) error { ++ result := C.newPrivateKeyEd25519FromSeed(base(key), base(seed)) ++ if result != 0 { ++ return errors.New("failed to generate Ed25519 key from seed") ++ } ++ return nil ++} ++ ++// NewPublicKeyEd25519 creates a new Ed25519 public key from raw bytes. ++func NewPublicKeyEd25519(key, pub []byte) error { ++ result := C.newPublicKeyEd25519(base(key), base(pub)) ++ if result != 0 { ++ return errors.New("failed to create Ed25519 public key") ++ } ++ return nil ++} ++ ++// SignEd25519 signs a message using the provided private key. ++func SignEd25519(sig, privateKey, message []byte) error { ++ result := C.signEd25519(base(privateKey), base(message), C.size_t(len(message)), base(sig)) ++ if result < 0 { ++ switch result { ++ case -1: ++ return errors.New("invalid inputs to SignEd25519") ++ case -2: ++ return errors.New("failed to reconstruct private key") ++ case -3: ++ return errors.New("failed to sign the message") ++ case -4: ++ return errors.New("signature buffer too small") ++ default: ++ return errors.New("unknown error in SignEd25519") ++ } ++ } ++ return nil ++} ++ ++// VerifyEd25519 verifies a signature using the provided public key and message. ++func VerifyEd25519(publicKey, message, sig []byte) error { ++ result := C.verifyEd25519(base(publicKey), base(message), C.size_t(len(message)), base(sig)) ++ switch result { ++ case 1: ++ return nil // Valid signature ++ case 0: ++ return errors.New("ed25519: invalid signature") ++ case -1: ++ return errors.New("invalid inputs to VerifyEd25519") ++ case -2: ++ return errors.New("failed to reconstruct public key") ++ default: ++ return errors.New("unknown error in VerifyEd25519") ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/gcm.go b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/gcm.go +new file mode 100644 +index 00000000000000..458e9eb57416b1 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/gcm.go +@@ -0,0 +1,36 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package cryptokit ++ ++// #include "cryptokit.h" ++import "C" ++ ++// EncryptAESGCM performs AES-GCM encryption using Swift. ++func EncryptAESGCM(key, plaintext, nonce, additionalData, ciphertext, tag []byte) int { ++ err := C.encryptAESGCM( ++ base(key), C.size_t(len(key)), ++ base(plaintext), C.size_t(len(plaintext)), ++ base(nonce), C.size_t(len(nonce)), ++ base(additionalData), C.size_t(len(additionalData)), ++ base(ciphertext), C.size_t(len(ciphertext)), ++ base(tag), ++ ) ++ return int(err) ++} ++ ++// DecryptAESGCM performs AES-GCM decryption using Swift. ++func DecryptAESGCM(key, ciphertext, nonce, additionalData, tag, plaintext []byte) (int, int) { ++ var decSize C.size_t ++ err := C.decryptAESGCM( ++ base(key), C.size_t(len(key)), ++ base(ciphertext), C.size_t(len(ciphertext)), ++ base(nonce), C.size_t(len(nonce)), ++ base(additionalData), C.size_t(len(additionalData)), ++ base(tag), C.size_t(len(tag)), ++ base(plaintext), &decSize, ++ ) ++ return int(decSize), int(err) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/hkdf.go b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/hkdf.go +new file mode 100644 +index 00000000000000..da161adcd88ea6 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/hkdf.go +@@ -0,0 +1,77 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package cryptokit ++ ++// #include "cryptokit.h" ++import "C" ++import ( ++ "crypto" ++ "errors" ++) ++ ++// ExtractHKDF performs the extract step of HKDF using the specified hash function. ++func ExtractHKDF(hash crypto.Hash, secret, salt []byte) ([]byte, error) { ++ h, err := cryptoHashToSwift(hash) ++ if err != nil { ++ return nil, err ++ } ++ ++ // Allocate buffer for derived key ++ prk := make([]byte, hash.Size()) ++ ++ // Call Swift function ++ result := C.extractHKDF( ++ h, ++ base(secret), C.size_t(len(secret)), ++ base(salt), C.size_t(len(salt)), ++ base(prk), C.size_t(len(prk)), ++ ) ++ ++ if result != 0 { ++ return nil, errors.New("HKDF derivation failed") ++ } ++ ++ return prk, nil ++} ++ ++func ExpandHKDF(hash crypto.Hash, pseudorandomKey, info []byte, keyLength int) ([]byte, error) { ++ h, err := cryptoHashToSwift(hash) ++ if err != nil { ++ return nil, err ++ } ++ ++ // Allocate buffer for derived key ++ expandedKey := make([]byte, keyLength) ++ ++ // Call Swift function ++ result := C.expandHKDF( ++ h, ++ base(pseudorandomKey), C.size_t(len(pseudorandomKey)), ++ base(info), C.size_t(len(info)), ++ base(expandedKey), C.size_t(len(expandedKey)), ++ ) ++ ++ if result != 0 { ++ return nil, errors.New("HKDF derivation failed") ++ } ++ ++ return expandedKey, nil ++} ++ ++func cryptoHashToSwift(hash crypto.Hash) (C.int32_t, error) { ++ switch hash { ++ case crypto.SHA1: ++ return 1, nil ++ case crypto.SHA256: ++ return 2, nil ++ case crypto.SHA384: ++ return 3, nil ++ case crypto.SHA512: ++ return 4, nil ++ default: ++ return 0, errors.New("unsupported hash function") ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go +new file mode 100644 +index 00000000000000..27a42bfc89ca06 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go +@@ -0,0 +1,306 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "crypto/cipher" ++ "errors" ++ "slices" ++ ++ "github.com/microsoft/go-crypto-darwin/internal/cryptokit" ++) ++ ++//go:generate go run github.com/microsoft/go-crypto-darwin/cmd/gentestvectors -out vectors_test.go ++ ++type cipherGCMTLS uint8 ++ ++const ( ++ cipherGCMTLSNone cipherGCMTLS = iota ++ cipherGCMTLS12 ++ cipherGCMTLS13 ++) ++ ++const ( ++ // AES block size is the same for all key sizes ++ aesBlockSize = C.kCCBlockSizeAES128 ++ gcmTagSize = 16 ++ gcmStandardNonceSize = 12 ++ // TLS 1.2 additional data is constructed as: ++ // ++ // additional_data = seq_num(8) + TLSCompressed.type(1) + TLSCompressed.version(2) + TLSCompressed.length(2); ++ gcmTls12AddSize = 13 ++ // TLS 1.3 additional data is constructed as: ++ // ++ // additional_data = TLSCiphertext.opaque_type(1) || TLSCiphertext.legacy_record_version(2) || TLSCiphertext.length(2) ++ gcmTls13AddSize = 5 ++ gcmTlsFixedNonceSize = 4 ++) ++ ++type aesCipher struct { ++ key []byte ++ kind C.CCAlgorithm ++} ++ ++func NewAESCipher(key []byte) (cipher.Block, error) { ++ var alg C.CCAlgorithm ++ switch len(key) { ++ case 16, 24, 32: ++ alg = C.kCCAlgorithmAES ++ default: ++ return nil, errors.New("crypto/aes: invalid key size") ++ } ++ c := &aesCipher{ ++ key: slices.Clone(key), ++ kind: alg, ++ } ++ return c, nil ++} ++ ++func (c *aesCipher) BlockSize() int { return aesBlockSize } ++ ++func (c *aesCipher) Encrypt(dst, src []byte) { ++ blockSize := c.BlockSize() ++ if len(src) < blockSize || len(dst) < blockSize { ++ panic("crypto/aes: input or output block is too small") ++ } ++ ++ src, dst = src[:blockSize], dst[:blockSize] ++ ++ if inexactOverlap(dst, src) { ++ panic("crypto/aes: invalid buffer overlap") ++ } ++ ++ status := C.CCCrypt( ++ C.kCCEncrypt, // Operation ++ C.CCAlgorithm(c.kind), // Algorithm ++ 0, // Options ++ pbase(c.key), // Key ++ C.size_t(len(c.key)), // Key length ++ nil, // IV ++ pbase(src), // Input ++ C.size_t(blockSize), // Input length ++ pbase(dst), // Output ++ C.size_t(blockSize), // Output length ++ nil, // Output length ++ ) ++ if status != C.kCCSuccess { ++ panic("crypto/aes: encryption failed") ++ } ++} ++ ++func (c *aesCipher) Decrypt(dst, src []byte) { ++ blockSize := c.BlockSize() ++ if len(src) < blockSize || len(dst) < blockSize { ++ panic("crypto/aes: input or output block is too small") ++ } ++ ++ src, dst = src[:blockSize], dst[:blockSize] ++ ++ if inexactOverlap(dst, src) { ++ panic("crypto/aes: invalid buffer overlap") ++ } ++ ++ status := C.CCCrypt( ++ C.kCCDecrypt, // Operation ++ C.CCAlgorithm(c.kind), // Algorithm ++ 0, // Options ++ pbase(c.key), // Key ++ C.size_t(len(c.key)), // Key length ++ nil, // IV ++ pbase(src), // Input ++ C.size_t(blockSize), // Input length ++ pbase(dst), // Output ++ C.size_t(blockSize), // Output length ++ nil, // Output length ++ ) ++ if status != C.kCCSuccess { ++ panic("crypto/aes: decryption failed") ++ } ++} ++ ++type aesGCM struct { ++ key []byte ++ tls cipherGCMTLS ++ // minNextNonce is the minimum value that the next nonce can be, enforced by ++ // all TLS modes. ++ minNextNonce uint64 ++ // mask is the nonce mask used in TLS 1.3 mode. ++ mask uint64 ++ // maskInitialized is true if mask has been initialized. This happens during ++ // the first Seal. The initialized mask may be 0. Used by TLS 1.3 mode. ++ maskInitialized bool ++} ++ ++type noGCM struct { ++ cipher.Block ++} ++ ++// NewGCM constructs a GCM block mode for AES using the cryptokit package ++func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { ++ if nonceSize != gcmStandardNonceSize && tagSize != gcmTagSize { ++ return nil, errors.New("crypto/aes: GCM tag and nonce sizes can't be non-standard at the same time") ++ } ++ // Fall back to standard library for GCM with non-standard nonce or tag size. ++ if nonceSize != gcmStandardNonceSize { ++ return cipher.NewGCMWithNonceSize(&noGCM{c}, nonceSize) ++ } ++ if tagSize != gcmTagSize { ++ return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize) ++ } ++ return &aesGCM{key: c.key, tls: cipherGCMTLSNone}, nil ++} ++ ++func (g *aesGCM) NonceSize() int { return gcmStandardNonceSize } ++ ++func (g *aesGCM) Overhead() int { return gcmTagSize } ++ ++func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { ++ if len(nonce) != gcmStandardNonceSize { ++ panic("cipher: incorrect nonce length given to GCM") ++ } ++ if uint64(len(plaintext)) > ((1<<32)-2)*aesBlockSize || len(plaintext)+gcmTagSize < len(plaintext) { ++ panic("cipher: message too large for GCM") ++ } ++ if len(dst)+len(plaintext)+gcmTagSize < len(dst) { ++ panic("cipher: message too large for buffer") ++ } ++ ++ if g.tls != cipherGCMTLSNone { ++ if g.tls == cipherGCMTLS12 && len(additionalData) != gcmTls12AddSize { ++ panic("cipher: incorrect additional data length given to GCM TLS 1.2") ++ } else if g.tls == cipherGCMTLS13 && len(additionalData) != gcmTls13AddSize { ++ panic("cipher: incorrect additional data length given to GCM TLS 1.3") ++ } ++ counter := bigUint64(nonce[gcmTlsFixedNonceSize:]) ++ ++ // TLS 1.3 Masking ++ if g.tls == cipherGCMTLS13 { ++ if !g.maskInitialized { ++ g.mask = counter ++ g.maskInitialized = true ++ } ++ // Apply mask to the counter ++ counter ^= g.mask ++ } ++ ++ // Enforce monotonicity and max limit ++ const maxUint64 = 1<<64 - 1 ++ if counter == maxUint64 { ++ panic("cipher: nonce counter must be less than 2^64 - 1") ++ } ++ if counter < g.minNextNonce { ++ panic("cipher: nonce counter must be strictly monotonically increasing") ++ } ++ ++ defer func() { ++ g.minNextNonce = counter + 1 ++ }() ++ } ++ ++ // Make room in dst to append plaintext+overhead. ++ ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize) ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if inexactOverlap(out, plaintext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ tag := out[len(out)-gcmTagSize:] ++ err := cryptokit.EncryptAESGCM(g.key, plaintext, nonce, additionalData, out[:len(out)-gcmTagSize], tag) ++ if err != 0 { ++ panic("cipher: encryption failed") ++ } ++ return ret ++} ++ ++var errOpen = errors.New("cipher: message authentication failed") ++ ++func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { ++ if len(nonce) != gcmStandardNonceSize { ++ panic("cipher: incorrect nonce length given to GCM") ++ } ++ if len(ciphertext) < gcmTagSize { ++ return nil, errOpen ++ } ++ if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize { ++ return nil, errOpen ++ } ++ // BoringCrypto does not do any TLS check when decrypting, neither do we. ++ ++ // Ensure we don't process if ciphertext lacks both ciphertext and tag ++ if len(ciphertext) < gcmTagSize { ++ return nil, errors.New("decryption failed: ciphertext too short for tag") ++ } ++ ++ tag := ciphertext[len(ciphertext)-gcmTagSize:] ++ ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] ++ ++ // Make room in dst to append ciphertext without tag. ++ ret, out := sliceForAppend(dst, len(ciphertext)) ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if inexactOverlap(out, ciphertext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ decSize, err := cryptokit.DecryptAESGCM(g.key, ciphertext, nonce, additionalData, tag, out) ++ if err != 0 || int(decSize) != len(ciphertext) { ++ // If the decrypted data size does not match, zero out `out` and return `errOpen` ++ for i := range out { ++ out[i] = 0 ++ } ++ return nil, errOpen ++ } ++ return ret, nil ++} ++ ++// NewGCMTLS returns a GCM cipher specific to TLS ++// and should not be used for non-TLS purposes. ++func NewGCMTLS(block cipher.Block) (cipher.AEAD, error) { ++ cipher, ok := block.(*aesCipher) ++ if !ok { ++ return nil, errors.New("crypto/aes: invalid block cipher") ++ } ++ return &aesGCM{key: cipher.key, tls: cipherGCMTLS12}, nil ++} ++ ++// NewGCMTLS13 returns a GCM cipher specific to TLS 1.3 and should not be used ++// for non-TLS purposes. ++func NewGCMTLS13(block cipher.Block) (cipher.AEAD, error) { ++ cipher, ok := block.(*aesCipher) ++ if !ok { ++ return nil, errors.New("crypto/aes: invalid block cipher") ++ } ++ return &aesGCM{key: cipher.key, tls: cipherGCMTLS13}, nil ++} ++ ++func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return newCBC(C.kCCEncrypt, c.kind, c.key, iv) ++} ++ ++func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return newCBC(C.kCCDecrypt, c.kind, c.key, iv) ++} ++ ++// sliceForAppend is a mirror of crypto/cipher.sliceForAppend. ++func sliceForAppend(in []byte, n int) (head, tail []byte) { ++ if total := len(in) + n; cap(in) >= total { ++ head = in[:total] ++ } else { ++ head = make([]byte, total) ++ copy(head, in) ++ } ++ tail = head[len(in):] ++ return ++} ++ ++func bigUint64(b []byte) uint64 { ++ _ = b[7] // bounds check hint to compiler; see go.dev/issue/14808 ++ return 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 ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/big.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/big.go +new file mode 100644 +index 00000000000000..865e22ab6a3dda +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/big.go +@@ -0,0 +1,16 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++package xcrypto ++ ++// 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 big-endian bytes from a math/big BigInt, ++// which are normalized to remove any leading 0 byte. ++// Windows BCrypt accepts this specific data format. ++// This definition allows us to avoid importing math/big. ++// Conversion between BigInt and *big.Int is in xcrypto/bbig. ++type BigInt []byte +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cgo_go124.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cgo_go124.go +new file mode 100644 +index 00000000000000..375bc368162acb +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cgo_go124.go +@@ -0,0 +1,21 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build go1.24 && darwin ++ ++package xcrypto ++ ++// The following noescape and nocallback directives are used to prevent the Go ++// compiler from allocating function parameters on the heap. See ++// https://github.com/golang/go/blob/0733682e5ff4cd294f5eccb31cbe87a543147bc6/src/cmd/cgo/doc.go#L439-L461 ++// ++// If possible, write a C wrapper function to optimize a call rather than using ++// this feature so the optimization will work for all supported Go versions. ++// ++// This is just a performance optimization. Only add functions that have been ++// observed to benefit from these directives, not every function that is merely ++// expected to meet the noescape/nocallback criteria. ++ ++// #cgo noescape SecRandomCopyBytes ++// #cgo nocallback SecRandomCopyBytes ++import "C" +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cipher.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cipher.go +new file mode 100644 +index 00000000000000..9f3a8f92bd43fc +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/cipher.go +@@ -0,0 +1,122 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++ ++import ( ++ "runtime" ++ "unsafe" ++) ++ ++type cbcCipher struct { ++ blockSize int ++ cryptor C.CCCryptorRef ++} ++ ++func newCBC(operation C.CCOperation, kind C.CCAlgorithm, key, iv []byte) *cbcCipher { ++ var blockSize int ++ switch kind { ++ case C.kCCAlgorithmAES: ++ blockSize = aesBlockSize ++ case C.kCCAlgorithmDES, C.kCCAlgorithm3DES: ++ blockSize = desBlockSize ++ default: ++ panic("invalid algorithm") ++ } ++ ++ // Create and initialize the cbcMode struct with CCCryptorCreate here ++ x := &cbcCipher{blockSize: blockSize} ++ status := C.CCCryptorCreateWithMode( ++ operation, // Specifies whether encryption or decryption is performed (kCCEncrypt or kCCDecrypt). ++ C.kCCModeCBC, // Mode of operation, here explicitly set to CBC (Cipher Block Chaining). ++ C.CCAlgorithm(kind), // The encryption algorithm (e.g., kCCAlgorithmAES128, kCCAlgorithmDES). ++ C.ccNoPadding, // Padding option, set to no padding; padding can be handled at a higher level if necessary. ++ pbase(iv), // Initialization Vector (IV) for the cipher, required for CBC mode. Should be nil for ECB mode. ++ pbase(key), // Pointer to the encryption key. ++ C.size_t(len(key)), // Length of the encryption key in bytes. ++ nil, // Tweak key, used only for XTS mode; here set to nil as it’s not required for CBC. ++ 0, // Length of the tweak key, set to 0 as tweak is nil. ++ 0, // Number of rounds, mainly for RC2 and Blowfish; not used here, so set to 0. ++ 0, // Mode options for CTR and F8 modes; not used for CBC, so set to 0. ++ &x.cryptor, // Pointer to the CCCryptorRef output, which will hold the state for encryption or decryption. ++ ) ++ ++ if status != C.kCCSuccess { ++ panic("crypto/des: CCCryptorCreate failed") ++ } ++ ++ runtime.SetFinalizer(x, (*cbcCipher).finalize) ++ return x ++ ++} ++ ++func (x *cbcCipher) finalize() { ++ if x.cryptor != nil { ++ C.CCCryptorRelease(x.cryptor) ++ x.cryptor = nil ++ } ++} ++ ++func (x *cbcCipher) BlockSize() int { return x.blockSize } ++ ++func (x *cbcCipher) CryptBlocks(dst, src []byte) { ++ if inexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src)%x.blockSize != 0 { ++ panic("crypto/cipher: input not full blocks") ++ } ++ if len(dst) < len(src) { ++ panic("crypto/cipher: output smaller than input") ++ } ++ if len(src) == 0 { ++ return ++ } ++ var outLength C.size_t ++ status := C.CCCryptorUpdate( ++ x.cryptor, // CCCryptorRef created by CCCryptorCreateWithMode; holds the encryption/decryption state. ++ pbase(src), // Pointer to the input data (source buffer) to be encrypted or decrypted. ++ C.size_t(len(src)), // Length of the input data in bytes. ++ pbase(dst), // Pointer to the output buffer (destination buffer) where the result will be stored. ++ C.size_t(len(dst)), // Size of the output buffer in bytes; must be large enough to hold the processed data. ++ &outLength, // Pointer to a variable that will contain the number of bytes written to the output buffer. ++ ) ++ if status != C.kCCSuccess { ++ panic("crypto/cipher: CCCryptorUpdate failed") ++ } ++ runtime.KeepAlive(x) ++} ++ ++func (x *cbcCipher) SetIV(iv []byte) { ++ if len(iv) != x.blockSize { ++ panic("crypto/cipher: incorrect IV length") ++ } ++ status := C.CCCryptorReset( ++ x.cryptor, // CCCryptorRef created by CCCryptorCreateWithMode; holds the encryption/decryption state. ++ pbase(iv), // Pointer to the new IV to be set. ++ ) ++ if status != C.kCCSuccess { ++ panic("crypto/cipher: CCCryptorReset failed") ++ } ++ runtime.KeepAlive(x) ++} ++ ++// The following two functions are a mirror of golang.org/x/crypto/internal/subtle. ++ ++func anyOverlap(x, y []byte) bool { ++ return len(x) > 0 && len(y) > 0 && ++ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && ++ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) ++} ++ ++func inexactOverlap(x, y []byte) bool { ++ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { ++ return false ++ } ++ return anyOverlap(x, y) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/des.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/des.go +new file mode 100644 +index 00000000000000..ce490c1167c536 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/des.go +@@ -0,0 +1,117 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "crypto/cipher" ++ "errors" ++ "slices" ++) ++ ++const desBlockSize = C.kCCBlockSizeDES ++ ++type desCipher struct { ++ key []byte ++ kind C.CCAlgorithm ++} ++ ++// NewDESCipher creates a new DES cipher block using the specified key (8 bytes). ++func NewDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 8 { ++ return nil, errors.New("crypto/des: invalid key size for DES") ++ } ++ ++ c := &desCipher{ ++ key: slices.Clone(key), ++ kind: C.kCCAlgorithmDES, ++ } ++ return c, nil ++} ++ ++// NewTripleDESCipher creates a new 3DES cipher block using the specified key (24 bytes). ++func NewTripleDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 24 { ++ return nil, errors.New("crypto/des: invalid key size for 3DES") ++ } ++ ++ c := &desCipher{ ++ key: slices.Clone(key), ++ kind: C.kCCAlgorithm3DES, ++ } ++ return c, nil ++} ++ ++func (c *desCipher) BlockSize() int { return desBlockSize } ++ ++func (c *desCipher) Encrypt(dst, src []byte) { ++ blockSize := c.BlockSize() ++ if len(src) < blockSize || len(dst) < blockSize { ++ panic("crypto/des: input or output block is too small") ++ } ++ ++ if inexactOverlap(dst[:blockSize], src[:blockSize]) { ++ panic("crypto/des: invalid buffer overlap") ++ } ++ ++ var outLength C.size_t ++ status := C.CCCrypt( ++ C.kCCEncrypt, ++ C.CCAlgorithm(c.kind), ++ C.kCCOptionECBMode, ++ pbase(c.key), ++ C.size_t(len(c.key)), ++ nil, ++ pbase(src[:blockSize]), ++ C.size_t(blockSize), ++ pbase(dst[:blockSize]), ++ C.size_t(blockSize), ++ &outLength, ++ ) ++ if status != C.kCCSuccess { ++ panic("crypto/des: encryption failed") ++ } ++} ++ ++func (c *desCipher) Decrypt(dst, src []byte) { ++ blockSize := c.BlockSize() ++ if len(src) < blockSize || len(dst) < blockSize { ++ panic("crypto/des: input or output block is too small") ++ } ++ ++ if inexactOverlap(dst[:blockSize], src[:blockSize]) { ++ panic("crypto/des: invalid buffer overlap") ++ } ++ ++ var outLength C.size_t ++ status := C.CCCrypt( ++ C.kCCDecrypt, ++ C.CCAlgorithm(c.kind), ++ C.kCCOptionECBMode, ++ pbase(c.key), ++ C.size_t(len(c.key)), ++ nil, ++ pbase(src[:blockSize]), ++ C.size_t(blockSize), ++ pbase(dst[:blockSize]), ++ C.size_t(blockSize), ++ &outLength, ++ ) ++ if status != C.kCCSuccess { ++ panic("crypto/des: decryption failed") ++ } ++} ++ ++// CBC mode encrypter ++func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return newCBC(C.kCCEncrypt, c.kind, c.key, iv) ++} ++ ++// CBC mode decrypter ++func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return newCBC(C.kCCDecrypt, c.kind, c.key, iv) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ec.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ec.go +new file mode 100644 +index 00000000000000..e57bde33af4c98 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ec.go +@@ -0,0 +1,32 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++func curveToKeySizeInBits(curve string) int { ++ switch curve { ++ case "P-256": ++ return 256 ++ case "P-384": ++ return 384 ++ case "P-521": ++ return 521 ++ default: ++ return 0 ++ } ++} ++ ++func curveToKeySizeInBytes(curve string) int { ++ switch curve { ++ case "P-256": ++ return (256 + 7) / 8 ++ case "P-384": ++ return (384 + 7) / 8 ++ case "P-521": ++ return (521 + 7) / 8 ++ default: ++ return 0 ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdh.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdh.go +new file mode 100644 +index 00000000000000..3bdd3937670285 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdh.go +@@ -0,0 +1,135 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "errors" ++ "runtime" ++ "slices" ++) ++ ++type PublicKeyECDH struct { ++ _pkey C.SecKeyRef ++ bytes []byte ++} ++ ++func (k *PublicKeyECDH) finalize() { ++ if k._pkey != 0 { ++ C.CFRelease(C.CFTypeRef(k._pkey)) ++ } ++} ++ ++type PrivateKeyECDH struct { ++ _pkey C.SecKeyRef ++ pub []byte ++} ++ ++func (k *PrivateKeyECDH) finalize() { ++ if k._pkey != 0 { ++ C.CFRelease(C.CFTypeRef(k._pkey)) ++ } ++} ++ ++func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { ++ if len(bytes) < 1 { ++ return nil, errors.New("NewPublicKeyECDH: missing key") ++ } ++ pubKeyRef, err := createSecKeyWithData(bytes, C.kSecAttrKeyTypeECSECPrimeRandom, C.kSecAttrKeyClassPublic) ++ if err != nil { ++ return nil, err ++ } ++ pubKey := &PublicKeyECDH{pubKeyRef, slices.Clone(bytes)} ++ runtime.SetFinalizer(pubKey, (*PublicKeyECDH).finalize) ++ return pubKey, nil ++} ++ ++func (k *PublicKeyECDH) Bytes() []byte { return k.bytes } ++ ++// bytes expects the public key to be in uncompressed ANSI X9.63 format ++func NewPrivateKeyECDH(curve string, pub, priv []byte) (*PrivateKeyECDH, error) { ++ key := append(slices.Clone(pub), priv...) ++ privKeyRef, err := createSecKeyWithData(key, C.kSecAttrKeyTypeECSECPrimeRandom, C.kSecAttrKeyClassPrivate) ++ if err != nil { ++ return nil, err ++ } ++ privKey := &PrivateKeyECDH{privKeyRef, pub} ++ runtime.SetFinalizer(privKey, (*PrivateKeyECDH).finalize) ++ return privKey, nil ++} ++ ++func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { ++ defer runtime.KeepAlive(k) ++ pubKeyRef := C.SecKeyCopyPublicKey(k._pkey) ++ if pubKeyRef == 0 { ++ return nil, errors.New("failed to extract public key") ++ } ++ pubKey := &PublicKeyECDH{pubKeyRef, k.pub} ++ runtime.SetFinalizer(pubKey, (*PublicKeyECDH).finalize) ++ return pubKey, nil ++} ++ ++func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { ++ defer runtime.KeepAlive(priv) ++ defer runtime.KeepAlive(pub) ++ ++ var algorithm C.CFStringRef = C.kSecKeyAlgorithmECDHKeyExchangeStandard ++ ++ supported := C.SecKeyIsAlgorithmSupported(priv._pkey, C.kSecKeyOperationTypeKeyExchange, algorithm) ++ if supported == 0 { ++ return nil, errors.New("ECDH algorithm not supported for the given private key") ++ } ++ ++ var cfErr C.CFErrorRef ++ // Perform the key exchange ++ sharedSecretRef := C.SecKeyCopyKeyExchangeResult( ++ priv._pkey, ++ algorithm, ++ pub._pkey, ++ C.CFDictionaryRef(0), ++ &cfErr, ++ ) ++ if err := goCFErrorRef(cfErr); err != nil { ++ return nil, err ++ } ++ defer C.CFRelease(C.CFTypeRef(sharedSecretRef)) ++ ++ sharedSecret := cfDataToBytes(sharedSecretRef) ++ return sharedSecret, nil ++} ++ ++func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { ++ keySize := curveToKeySizeInBytes(curve) ++ if keySize == 0 { ++ return nil, nil, errors.New("unsupported curve") ++ } ++ keySizeInBits := curveToKeySizeInBits(curve) ++ // Generate the private key and get its DER representation ++ privKeyDER, privKeyRef, err := createSecKeyRandom(C.kSecAttrKeyTypeECSECPrimeRandom, keySizeInBits) ++ if err != nil { ++ return nil, nil, err ++ } ++ pub, priv, err := extractECDHComponents(privKeyDER, keySize) ++ if err != nil { ++ C.CFRelease(C.CFTypeRef(privKeyRef)) ++ return nil, nil, err ++ } ++ k := &PrivateKeyECDH{privKeyRef, pub} ++ runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) ++ return k, priv, nil ++} ++ ++func extractECDHComponents(der []byte, keySize int) (pub, priv []byte, err error) { ++ // The private component is the last of the three equally-sized chunks ++ // for the elliptic curve private key. ++ if len(der) != 1+keySize*3 { ++ return nil, nil, errors.New("invalid key length: insufficient data for private component") ++ } ++ pub = der[:1+keySize*2] ++ priv = der[1+keySize*2:] ++ return ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdsa.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdsa.go +new file mode 100644 +index 00000000000000..fb0e207a89ff67 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ecdsa.go +@@ -0,0 +1,181 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "errors" ++ "runtime" ++) ++ ++type PrivateKeyECDSA struct { ++ _pkey C.SecKeyRef ++} ++ ++func (k *PrivateKeyECDSA) finalize() { ++ if k._pkey != 0 { ++ C.CFRelease(C.CFTypeRef(k._pkey)) ++ } ++} ++ ++func (k *PrivateKeyECDSA) withKey(f func(C.SecKeyRef) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} ++ ++type PublicKeyECDSA struct { ++ _pkey C.SecKeyRef ++} ++ ++func (k *PublicKeyECDSA) finalize() { ++ if k._pkey != 0 { ++ C.CFRelease(C.CFTypeRef(k._pkey)) ++ } ++} ++ ++func (k *PublicKeyECDSA) withKey(f func(C.SecKeyRef) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} ++ ++func NewPublicKeyECDSA(curve string, x, y BigInt) (*PublicKeyECDSA, error) { ++ keySize := curveToKeySizeInBytes(curve) ++ if keySize == 0 { ++ return nil, errors.New("unsupported curve") ++ } ++ encodedKey, err := encodeToUncompressedAnsiX963Key(x, y, nil, keySize) ++ if err != nil { ++ return nil, errors.New("failed to encode public key to uncompressed ANSI X9.63 format") ++ } ++ ++ pubKeyRef, err := createSecKeyWithData(encodedKey, C.kSecAttrKeyTypeECSECPrimeRandom, C.kSecAttrKeyClassPublic) ++ if err != nil { ++ return nil, err ++ } ++ ++ pubKey := &PublicKeyECDSA{_pkey: pubKeyRef} ++ runtime.SetFinalizer(pubKey, (*PublicKeyECDSA).finalize) ++ return pubKey, nil ++} ++ ++// NewPrivateKeyECDSA creates a new ECDSA private key using the provided curve name and parameters (x, y, d). ++func NewPrivateKeyECDSA(curve string, x, y, d BigInt) (*PrivateKeyECDSA, error) { ++ keySize := curveToKeySizeInBytes(curve) ++ if keySize == 0 { ++ return nil, errors.New("unsupported curve") ++ } ++ encodedKey, err := encodeToUncompressedAnsiX963Key(x, y, d, keySize) ++ if err != nil { ++ return nil, errors.New("crypto/ecdsa: failed to encode private key: " + err.Error()) ++ } ++ ++ privKeyRef, err := createSecKeyWithData(encodedKey, C.kSecAttrKeyTypeECSECPrimeRandom, C.kSecAttrKeyClassPrivate) ++ if err != nil { ++ return nil, err ++ } ++ ++ // Wrap and finalize ++ k := &PrivateKeyECDSA{_pkey: privKeyRef} ++ runtime.SetFinalizer(k, (*PrivateKeyECDSA).finalize) ++ return k, nil ++} ++ ++func GenerateKeyECDSA(curve string) (x, y, d BigInt, err error) { ++ keySize := curveToKeySizeInBytes(curve) ++ if keySize == 0 { ++ return nil, nil, nil, errors.New("unsupported curve") ++ } ++ ++ keySizeInBits := curveToKeySizeInBits(curve) ++ privKeyDER, privKeyRef, err := createSecKeyRandom(C.kSecAttrKeyTypeECSECPrimeRandom, keySizeInBits) ++ if err != nil { ++ return nil, nil, nil, err ++ } ++ defer C.CFRelease(C.CFTypeRef(privKeyRef)) ++ return decodeFromUncompressedAnsiX963Key(privKeyDER, keySize) ++} ++ ++func SignMarshalECDSA(priv *PrivateKeyECDSA, hashed []byte) ([]byte, error) { ++ return evpSign(priv.withKey, algorithmTypeECDSA, 0, hashed) ++} ++ ++func VerifyECDSA(pub *PublicKeyECDSA, hashed []byte, sig []byte) bool { ++ return evpVerify(pub.withKey, algorithmTypeECDSA, 0, hashed, sig) == nil ++} ++ ++// encodeToUncompressedAnsiX963Key encodes the given elliptic curve point (x, y) and optional private key (d) ++// into an uncompressed ANSI X9.63 format byte slice. ++func encodeToUncompressedAnsiX963Key(x, y, d BigInt, keySize int) ([]byte, error) { ++ // Build the uncompressed key point (0x04 || x || y { || d }) ++ size := 1 + keySize*2 ++ if d != nil { ++ size += keySize ++ } ++ out := make([]byte, size) ++ out[0] = 0x04 ++ err := encodeBigInt(out[1:], []sizedBigInt{ ++ {x, keySize}, {y, keySize}, ++ {d, keySize}, ++ }) ++ if err != nil { ++ return nil, err ++ } ++ return out, nil ++} ++ ++// decodeFromUncompressedAnsiX963Key decodes the given uncompressed ANSI X9.63 format byte slice into ++// the elliptic curve point (x, y) and optional private key (d). ++func decodeFromUncompressedAnsiX963Key(key []byte, keySize int) (x, y, d BigInt, err error) { ++ if len(key) < 1 || key[0] != 0x04 { ++ return nil, nil, nil, errors.New("invalid uncompressed key format") ++ } ++ if len(key) < 1+keySize*2 { ++ return nil, nil, nil, errors.New("invalid key length") ++ } ++ x = normalizeBigInt(key[1 : 1+keySize]) ++ y = normalizeBigInt(key[1+keySize : 1+keySize*2]) ++ if len(key) > 1+keySize*2 { ++ d = normalizeBigInt(key[1+keySize*2:]) ++ return x, y, d, nil ++ } ++ return x, y, nil, nil ++} ++ ++func normalizeBigInt(b []byte) BigInt { ++ // Remove leading zero bytes ++ for len(b) > 0 && b[0] == 0 { ++ b = b[1:] ++ } ++ return b ++} ++ ++// sizedBigInt defines a big integer with ++// a size that can be different from the ++// one provided by len(b). ++type sizedBigInt struct { ++ b BigInt ++ size int ++} ++ ++// encodeBigInt encodes ints into data. ++// It stops iterating over ints when it finds one nil element. ++func encodeBigInt(data []byte, ints []sizedBigInt) error { ++ for _, v := range ints { ++ if v.b == nil { ++ return nil ++ } ++ normalized := normalizeBigInt(v.b) ++ // b might be shorter than size if the original big number contained leading zeros. ++ leadingZeros := int(v.size) - len(normalized) ++ if leadingZeros < 0 { ++ return errors.New("commoncrypto: invalid parameters") ++ } ++ copy(data[leadingZeros:], normalized) ++ data = data[v.size:] ++ } ++ return nil ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ed25519.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ed25519.go +new file mode 100644 +index 00000000000000..f59e6f9af58cd4 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/ed25519.go +@@ -0,0 +1,100 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin && cgo ++ ++package xcrypto ++ ++import ( ++ "strconv" ++ ++ "github.com/microsoft/go-crypto-darwin/internal/cryptokit" ++) ++ ++const ( ++ // publicKeySizeEd25519 is the size, in bytes, of public keys as used in crypto/ed25519. ++ publicKeySizeEd25519 = 32 ++ // privateKeySizeEd25519 is the size, in bytes, of private keys as used in crypto/ed25519. ++ privateKeySizeEd25519 = 64 ++ // signatureSizeEd25519 is the size, in bytes, of signatures generated and verified by crypto/ed25519. ++ signatureSizeEd25519 = 64 ++ // seedSizeEd25519 is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. ++ seedSizeEd25519 = 32 ++) ++ ++// PublicKeyEd25519 represents an Ed25519 public key. ++type PublicKeyEd25519 []byte ++ ++// PrivateKeyEd25519 represents an Ed25519 private key. ++type PrivateKeyEd25519 []byte ++ ++func (k PrivateKeyEd25519) Public() PublicKeyEd25519 { ++ publicKey := make([]byte, publicKeySizeEd25519) ++ copy(publicKey, k[seedSizeEd25519:]) ++ return PublicKeyEd25519(publicKey) ++} ++ ++// GenerateKeyEd25519 generates a new Ed25519 private key. ++func GenerateKeyEd25519() PrivateKeyEd25519 { ++ pkeyPriv := make([]byte, privateKeySizeEd25519) ++ cryptokit.GenerateKeyEd25519(pkeyPriv) ++ return pkeyPriv ++} ++ ++func NewPrivateKeyEd25519(priv []byte) (PrivateKeyEd25519, error) { ++ if len(priv) != privateKeySizeEd25519 { ++ panic("ed25519: bad private key length: " + strconv.Itoa(len(priv))) ++ } ++ return NewPrivateKeyEd25519FromSeed(priv[:seedSizeEd25519]) ++} ++ ++func (k PrivateKeyEd25519) Bytes() ([]byte, error) { ++ return k, nil ++} ++ ++func NewPublicKeyEd25519(pub []byte) (PublicKeyEd25519, error) { ++ if len(pub) != publicKeySizeEd25519 { ++ panic("ed25519: bad public key length: " + strconv.Itoa(len(pub))) ++ } ++ pkey := make([]byte, publicKeySizeEd25519) ++ err := cryptokit.NewPublicKeyEd25519(pkey, pub) ++ if err != nil { ++ return nil, err ++ } ++ return pkey, nil ++} ++ ++func (k PublicKeyEd25519) Bytes() ([]byte, error) { ++ return k, nil ++} ++ ++// NewPrivateKeyEd25519FromSeed calculates a private key from a seed. It will panic if ++// len(seed) is not [SeedSize]. RFC 8032's private keys correspond to seeds in this ++// package. ++// NewPrivateKeyEd25519FromSeed creates an Ed25519 private key from a seed. ++func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) { ++ if len(seed) != seedSizeEd25519 { ++ panic("ed25519: bad seed length: " + strconv.Itoa(len(seed))) ++ } ++ pkey := make([]byte, privateKeySizeEd25519) ++ err := cryptokit.NewPrivateKeyEd25519FromSeed(pkey, seed) ++ if err != nil { ++ return nil, err ++ } ++ return pkey, nil ++} ++ ++// SignEd25519 signs the message with priv and returns a signature. ++func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) { ++ sig := make([]byte, signatureSizeEd25519) ++ err := cryptokit.SignEd25519(sig, priv, message) ++ if err != nil { ++ return nil, err ++ } ++ return sig, nil ++} ++ ++// VerifyEd25519 reports whether sig is a valid signature of message by pub. ++func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error { ++ return cryptokit.VerifyEd25519(pub, message, sig) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/evp.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/evp.go +new file mode 100644 +index 00000000000000..f253eeac15bcc0 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/evp.go +@@ -0,0 +1,338 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "crypto" ++ "errors" ++ "hash" ++ "unsafe" ++) ++ ++type algorithmType int ++ ++const ( ++ algorithmTypePSS algorithmType = iota ++ algorithmTypeRAW ++ algorithmTypePKCS1v15Enc ++ algorithmTypePKCS1v15Sig ++ algorithmTypeOAEP ++ algorithmTypeECDSA ++) ++ ++// Algorithm maps for translating crypto.Hash to SecKeyAlgorithm. ++var ( ++ rsaRaw = map[crypto.Hash]C.CFStringRef{ ++ 0: C.kSecKeyAlgorithmRSAEncryptionRaw, ++ } ++ rsaPKCS1v15Algorithms = map[crypto.Hash]C.CFStringRef{ ++ crypto.SHA1: C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1, ++ crypto.SHA224: C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224, ++ crypto.SHA256: C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256, ++ crypto.SHA384: C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384, ++ crypto.SHA512: C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512, ++ 0: C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw, ++ } ++ rsaPSSAlgorithms = map[crypto.Hash]C.CFStringRef{ ++ crypto.SHA1: C.kSecKeyAlgorithmRSASignatureDigestPSSSHA1, ++ crypto.SHA224: C.kSecKeyAlgorithmRSASignatureDigestPSSSHA224, ++ crypto.SHA256: C.kSecKeyAlgorithmRSASignatureDigestPSSSHA256, ++ crypto.SHA384: C.kSecKeyAlgorithmRSASignatureDigestPSSSHA384, ++ crypto.SHA512: C.kSecKeyAlgorithmRSASignatureDigestPSSSHA512, ++ } ++ rsaOAEPAlgorithms = map[crypto.Hash]C.CFStringRef{ ++ crypto.SHA1: C.kSecKeyAlgorithmRSAEncryptionOAEPSHA1, ++ crypto.SHA224: C.kSecKeyAlgorithmRSAEncryptionOAEPSHA224, ++ crypto.SHA256: C.kSecKeyAlgorithmRSAEncryptionOAEPSHA256, ++ crypto.SHA384: C.kSecKeyAlgorithmRSAEncryptionOAEPSHA384, ++ crypto.SHA512: C.kSecKeyAlgorithmRSAEncryptionOAEPSHA512, ++ } ++) ++ ++type withKeyFunc func(func(C.SecKeyRef) C.int) C.int ++ ++// Encrypt encrypts a plaintext message using a given key and algorithm. ++func evpEncrypt(withKey withKeyFunc, algorithmType algorithmType, plaintext []byte, hash hash.Hash) ([]byte, error) { ++ var cryptoHash crypto.Hash ++ if hash != nil { ++ var err error ++ cryptoHash, err = hashToCryptoHash(hash) ++ if err != nil { ++ return nil, err ++ } ++ } ++ algorithm, err := selectAlgorithm(cryptoHash, algorithmType) ++ if err != nil { ++ return nil, err ++ } ++ ++ dataRef := bytesToCFData(plaintext) ++ defer cfRelease(unsafe.Pointer(dataRef)) ++ ++ var encryptedDataRef C.CFDataRef ++ result := withKey(func(key C.SecKeyRef) C.int { ++ if C.SecKeyIsAlgorithmSupported(key, C.kSecKeyOperationTypeEncrypt, algorithm) != 1 { ++ return -1 // Algorithm not supported by the key ++ } ++ encryptedDataRef = C.SecKeyCreateEncryptedData(key, algorithm, dataRef, nil) ++ if encryptedDataRef == 0 { ++ return -1 // Encryption failed ++ } ++ return 0 ++ }) ++ if result != 0 { ++ return nil, errors.New("encryption failed") ++ } ++ defer cfRelease(unsafe.Pointer(encryptedDataRef)) ++ ++ return cfDataToBytes(encryptedDataRef), nil ++} ++ ++// Decrypt decrypts a ciphertext using a given key and algorithm. ++func evpDecrypt(withKey withKeyFunc, algorithmType algorithmType, ciphertext []byte, hash hash.Hash) ([]byte, error) { ++ var cryptoHash crypto.Hash ++ if hash != nil { ++ var err error ++ cryptoHash, err = hashToCryptoHash(hash) ++ if err != nil { ++ return nil, err ++ } ++ } ++ algorithm, err := selectAlgorithm(cryptoHash, algorithmType) ++ if err != nil { ++ return nil, err ++ } ++ ++ msg := bytesToCFData(ciphertext) ++ ++ var decryptedDataRef C.CFDataRef ++ var cfErr C.CFErrorRef ++ result := withKey(func(key C.SecKeyRef) C.int { ++ if C.SecKeyIsAlgorithmSupported(key, C.kSecKeyOperationTypeDecrypt, algorithm) != 1 { ++ return -1 // Algorithm not supported by the key ++ } ++ decryptedDataRef = C.SecKeyCreateDecryptedData(key, algorithm, msg, &cfErr) ++ if decryptedDataRef == 0 { ++ return -1 // Decryption failed ++ } ++ return 0 // Success ++ }) ++ ++ if err := goCFErrorRef(cfErr); err != nil { ++ return nil, err ++ } ++ ++ if result != 0 || decryptedDataRef == 0 { ++ return nil, errors.New("decryption failed") ++ } ++ defer cfRelease(unsafe.Pointer(decryptedDataRef)) ++ ++ return cfDataToBytes(decryptedDataRef), nil ++} ++ ++func evpSign(withKey withKeyFunc, algorithmType algorithmType, hash crypto.Hash, hashed []byte) ([]byte, error) { ++ algorithm, err := selectAlgorithm(hash, algorithmType) ++ if err != nil { ++ return nil, err ++ } ++ ++ var signedDataRef C.CFDataRef ++ var cfErr C.CFErrorRef ++ result := withKey(func(key C.SecKeyRef) C.int { ++ if C.SecKeyIsAlgorithmSupported(key, C.kSecKeyOperationTypeSign, algorithm) != 1 { ++ return -1 // Algorithm not supported by the key ++ } ++ signedDataRef = C.SecKeyCreateSignature(key, algorithm, bytesToCFData(hashed), &cfErr) ++ if signedDataRef == 0 { ++ return -1 // Signing failed ++ } ++ return 0 // Success ++ }) ++ ++ if err := goCFErrorRef(cfErr); err != nil { ++ return nil, err ++ } ++ ++ if result != 0 || signedDataRef == 0 { ++ return nil, errors.New("signing failed") ++ } ++ defer cfRelease(unsafe.Pointer(signedDataRef)) ++ ++ return cfDataToBytes(signedDataRef), nil ++} ++ ++func evpVerify(withKey withKeyFunc, algorithmType algorithmType, hash crypto.Hash, hashed, signature []byte) error { ++ algorithm, err := selectAlgorithm(hash, algorithmType) ++ if err != nil { ++ return err ++ } ++ ++ var cfErr C.CFErrorRef ++ result := withKey(func(key C.SecKeyRef) C.int { ++ if C.SecKeyIsAlgorithmSupported(key, C.kSecKeyOperationTypeVerify, algorithm) != 1 { ++ return -1 // Algorithm not supported by the key ++ } ++ if C.SecKeyVerifySignature(key, algorithm, bytesToCFData(hashed), bytesToCFData(signature), &cfErr) != 1 { ++ return -1 // Verification failed ++ } ++ return 0 // Success ++ }) ++ ++ if err := goCFErrorRef(cfErr); err != nil { ++ return err ++ } ++ ++ if result != 0 { ++ return errors.New("verification failed") ++ } ++ return nil ++} ++ ++// hashToCryptoHash converts a hash.Hash to a crypto.Hash. ++func hashToCryptoHash(hash hash.Hash) (crypto.Hash, error) { ++ switch hash.(type) { ++ case *sha1Hash: ++ return crypto.SHA1, nil ++ case *sha224Hash: ++ return crypto.SHA224, nil ++ case *sha256Hash: ++ return crypto.SHA256, nil ++ case *sha384Hash: ++ return crypto.SHA384, nil ++ case *sha512Hash: ++ return crypto.SHA512, nil ++ default: ++ return 0, errors.New("unsupported hash function") ++ } ++} ++ ++// selectAlgorithm selects the appropriate SecKeyAlgorithm based on hash and algorithm type. ++func selectAlgorithm(hash crypto.Hash, algorithmType algorithmType) (C.CFStringRef, error) { ++ var algorithmMap map[crypto.Hash]C.CFStringRef ++ switch algorithmType { ++ case algorithmTypePSS: ++ algorithmMap = rsaPSSAlgorithms ++ case algorithmTypeRAW: ++ algorithmMap = rsaRaw ++ case algorithmTypePKCS1v15Enc: ++ return C.kSecKeyAlgorithmRSAEncryptionPKCS1, nil ++ case algorithmTypePKCS1v15Sig: ++ algorithmMap = rsaPKCS1v15Algorithms ++ case algorithmTypeOAEP: ++ algorithmMap = rsaOAEPAlgorithms ++ case algorithmTypeECDSA: ++ return C.kSecKeyAlgorithmECDSASignatureDigestX962, nil ++ default: ++ return 0, errors.New("unsupported algorithm type") ++ } ++ ++ algorithm, ok := algorithmMap[hash] ++ if !ok { ++ return 0, errors.New("unsupported combination of algorithm type and hash") ++ } ++ ++ return algorithm, nil ++} ++ ++// bytesToCFData turns a byte slice into a CFDataRef. Caller then "owns" the ++// CFDataRef and must CFRelease the CFDataRef when done. ++func bytesToCFData(buf []byte) C.CFDataRef { ++ return C.CFDataCreate(C.kCFAllocatorDefault, (*C.UInt8)(unsafe.Pointer(&buf[0])), C.CFIndex(len(buf))) ++} ++ ++// cfDataToBytes turns a CFDataRef into a byte slice. ++func cfDataToBytes(cfData C.CFDataRef) []byte { ++ return C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(cfData)), C.int(C.CFDataGetLength(cfData))) ++} ++ ++// cfRelease releases a CoreFoundation object. ++func cfRelease(ref unsafe.Pointer) { ++ C.CFRelease(C.CFTypeRef(ref)) ++} ++ ++// createSecKeyWithData creates a SecKey from the provided encoded key and attributes dictionary. ++func createSecKeyWithData(encodedKey []byte, keyType, keyClass C.CFStringRef) (C.SecKeyRef, error) { ++ encodedKeyCF := C.CFDataCreate(C.kCFAllocatorDefault, base(encodedKey), C.CFIndex(len(encodedKey))) ++ if encodedKeyCF == 0 { ++ return 0, errors.New("xcrypto: failed to create CFData for private key") ++ } ++ defer C.CFRelease(C.CFTypeRef(encodedKeyCF)) ++ ++ attrKeys := []C.CFTypeRef{ ++ C.CFTypeRef(C.kSecAttrKeyType), ++ C.CFTypeRef(C.kSecAttrKeyClass), ++ } ++ ++ attrValues := []C.CFTypeRef{ ++ C.CFTypeRef(keyType), ++ C.CFTypeRef(keyClass), ++ } ++ ++ // Create attributes dictionary for the key ++ attrDict := C.CFDictionaryCreate( ++ C.kCFAllocatorDefault, ++ (*unsafe.Pointer)(unsafe.Pointer(&attrKeys[0])), ++ (*unsafe.Pointer)(unsafe.Pointer(&attrValues[0])), ++ C.CFIndex(len(attrKeys)), ++ nil, ++ nil, ++ ) ++ if attrDict == 0 { ++ return 0, errors.New("xcrypto: failed to create attributes dictionary") ++ } ++ defer C.CFRelease(C.CFTypeRef(attrDict)) ++ ++ // Generate the SecKey ++ var errorRef C.CFErrorRef ++ key := C.SecKeyCreateWithData(encodedKeyCF, attrDict, &errorRef) ++ if err := goCFErrorRef(errorRef); err != nil { ++ return 0, err ++ } ++ return key, nil ++} ++ ++// createSecKeyRandom creates a new SecKey with the provided attributes dictionary. ++func createSecKeyRandom(keyType C.CFStringRef, keySize int) ([]byte, C.SecKeyRef, error) { ++ keyAttrs := C.CFDictionaryCreateMutable(C.kCFAllocatorDefault, 0, nil, nil) ++ if keyAttrs == 0 { ++ return nil, 0, errors.New("failed to create key attributes dictionary") ++ } ++ defer C.CFRelease(C.CFTypeRef(keyAttrs)) ++ ++ C.CFDictionarySetValue( ++ keyAttrs, ++ unsafe.Pointer(C.kSecAttrKeyType), ++ unsafe.Pointer(keyType), ++ ) ++ ++ C.CFDictionarySetValue( ++ keyAttrs, ++ unsafe.Pointer(C.kSecAttrKeySizeInBits), ++ unsafe.Pointer(C.CFNumberCreate(C.kCFAllocatorDefault, C.kCFNumberIntType, unsafe.Pointer(&keySize))), ++ ) ++ ++ // Generate the private key ++ var errorRef C.CFErrorRef ++ var privKeyRef C.SecKeyRef = C.SecKeyCreateRandomKey(C.CFDictionaryRef(keyAttrs), &errorRef) ++ if err := goCFErrorRef(errorRef); err != nil { ++ return nil, 0, err ++ } ++ ++ // Export the private key as DER ++ privData := C.SecKeyCopyExternalRepresentation(privKeyRef, &errorRef) ++ if err := goCFErrorRef(errorRef); err != nil { ++ return nil, 0, err ++ } ++ defer C.CFRelease(C.CFTypeRef(privData)) ++ ++ privKeyDER := cfDataToBytes(privData) ++ if privKeyDER == nil { ++ return nil, 0, errors.New("failed to convert CFData to bytes") ++ } ++ return privKeyDER, privKeyRef, nil ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hash.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hash.go +new file mode 100644 +index 00000000000000..2618e53134e915 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hash.go +@@ -0,0 +1,391 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "crypto" ++ "errors" ++ "hash" ++ "runtime" ++ "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-commoncrypto implementations. ++ ++// SupportsHash returns true if a hash.Hash implementation is supported for h. ++func SupportsHash(h crypto.Hash) bool { ++ switch h { ++ case crypto.MD4, crypto.MD5, crypto.SHA1, crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512: ++ return true ++ default: ++ return false ++ } ++} ++ ++func MD4(p []byte) (sum [16]byte) { ++ result := C.CC_MD4(unsafe.Pointer(&*addr(p)), C.CC_LONG(len(p)), (*C.uchar)(&*addr(sum[:]))) ++ if result == nil { ++ panic("commoncrypto: MD4 failed") ++ } ++ return ++} ++ ++func MD5(p []byte) (sum [16]byte) { ++ result := C.CC_MD5(unsafe.Pointer(&*addr(p)), C.CC_LONG(len(p)), (*C.uchar)(&*addr(sum[:]))) ++ if result == nil { ++ panic("commoncrypto: MD5 failed") ++ } ++ return ++} ++ ++func SHA1(p []byte) (sum [20]byte) { ++ result := C.CC_SHA1(unsafe.Pointer(&*addr(p)), C.CC_LONG(len(p)), (*C.uchar)(&*addr(sum[:]))) ++ if result == nil { ++ panic("commoncrypto: SHA1 failed") ++ } ++ return ++} ++ ++func SHA224(p []byte) (sum [28]byte) { ++ result := C.CC_SHA224(unsafe.Pointer(&*addr(p)), C.CC_LONG(len(p)), (*C.uchar)(&*addr(sum[:]))) ++ if result == nil { ++ panic("commoncrypto: SHA224 failed") ++ } ++ return ++} ++ ++func SHA256(p []byte) (sum [32]byte) { ++ result := C.CC_SHA256(unsafe.Pointer(&*addr(p)), C.CC_LONG(len(p)), (*C.uchar)(&*addr(sum[:]))) ++ if result == nil { ++ panic("commoncrypto: SHA256 failed") ++ } ++ return ++} ++ ++func SHA384(p []byte) (sum [48]byte) { ++ result := C.CC_SHA384(unsafe.Pointer(&*addr(p)), C.CC_LONG(len(p)), (*C.uchar)(&*addr(sum[:]))) ++ if result == nil { ++ panic("commoncrypto: SHA384 failed") ++ } ++ return ++} ++ ++func SHA512(p []byte) (sum [64]byte) { ++ result := C.CC_SHA512(unsafe.Pointer(&*addr(p)), C.CC_LONG(len(p)), (*C.uchar)(&*addr(sum[:]))) ++ if result == nil { ++ panic("commoncrypto: SHA512 failed") ++ } ++ return ++} ++ ++// cloneHash is an interface that defines a Clone method. ++// ++// hash.CloneHash will probably be added in Go 1.25, see https://golang.org/issue/69521, ++// but we need it now. ++type cloneHash interface { ++ hash.Hash ++ // Clone returns a separate Hash instance with the same state as h. ++ Clone() hash.Hash ++} ++ ++var _ hash.Hash = (*evpHash)(nil) ++var _ cloneHash = (*evpHash)(nil) ++ ++// evpHash implements generic hash methods. ++type evpHash struct { ++ ctx unsafe.Pointer ++ // 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 unsafe.Pointer ++ init func(ctx unsafe.Pointer) C.int ++ update func(ctx unsafe.Pointer, data []byte) C.int ++ final func(ctx unsafe.Pointer, digest []byte) C.int ++ blockSize int ++ size int ++ ctxSize int ++} ++ ++func newEvpHash(init func(ctx unsafe.Pointer) C.int, update func(ctx unsafe.Pointer, data []byte) C.int, final func(ctx unsafe.Pointer, digest []byte) C.int, ctxSize, blockSize, size int) *evpHash { ++ h := &evpHash{ ++ init: init, ++ update: update, ++ final: final, ++ blockSize: blockSize, ++ size: size, ++ ctxSize: ctxSize, ++ } ++ runtime.SetFinalizer(h, (*evpHash).finalize) ++ return h ++} ++ ++func (h *evpHash) finalize() { ++ if h.ctx != nil { ++ C.free(h.ctx) ++ } ++ if h.ctx2 != nil { ++ C.free(h.ctx2) ++ } ++} ++ ++func (h *evpHash) initialize() { ++ if h.ctx == nil { ++ h.ctx = C.malloc(C.size_t(h.ctxSize)) ++ h.ctx2 = C.malloc(C.size_t(h.ctxSize)) ++ if h.init(h.ctx) != 1 { ++ C.free(h.ctx) ++ C.free(h.ctx2) ++ panic("commoncrypto: initialization failed") ++ } ++ } ++} ++ ++func (h *evpHash) Reset() { ++ if h.ctx == nil { ++ // The hash is not initialized yet, no need to reset. ++ return ++ } ++ // There is no need to reset h.ctx2 because it is always reset after ++ // use in evpHash.sum. ++ h.init(h.ctx) ++ runtime.KeepAlive(h) ++} ++ ++func (h *evpHash) Write(p []byte) (int, error) { ++ h.initialize() ++ if len(p) > 0 { ++ // Use a local variable to prevent the compiler from misinterpreting the pointer ++ data := p ++ if h.update(h.ctx, data) != 1 { ++ return 0, errors.New("commoncrypto: Update function failed") ++ } ++ } ++ runtime.KeepAlive(h) // Ensure the hash object is not garbage-collected ++ return len(p), nil ++} ++ ++func (h *evpHash) WriteString(s string) (int, error) { ++ h.initialize() ++ if len(s) > 0 { ++ data := []byte(s) ++ if h.update(h.ctx, data) != 1 { ++ return 0, errors.New("commoncrypto: Update function failed") ++ } ++ } ++ runtime.KeepAlive(h) ++ return len(s), nil ++} ++ ++func (h *evpHash) WriteByte(c byte) error { ++ h.initialize() ++ if h.update(h.ctx, []byte{c}) != 1 { ++ return errors.New("commoncrypto: Update function failed") ++ } ++ runtime.KeepAlive(h) ++ return nil ++} ++func (h *evpHash) Size() int { ++ return h.size ++} ++ ++func (h *evpHash) BlockSize() int { ++ return h.blockSize ++} ++ ++func (h *evpHash) Sum(b []byte) []byte { ++ h.initialize() ++ digest := make([]byte, h.size) ++ C.memcpy(h.ctx2, h.ctx, C.size_t(h.ctxSize)) ++ h.final(h.ctx2, digest) ++ return append(b, digest...) ++} ++ ++// Clone returns a new evpHash object that is a deep clone of itself. ++// The duplicate object contains all state and data contained in the ++// original object at the point of duplication. ++func (h *evpHash) Clone() hash.Hash { ++ h.initialize() ++ cloned := &evpHash{ ++ init: h.init, ++ update: h.update, ++ final: h.final, ++ blockSize: h.blockSize, ++ size: h.size, ++ ctxSize: h.ctxSize, ++ } ++ cloned.ctx = C.malloc(C.size_t(h.ctxSize)) ++ cloned.ctx2 = C.malloc(C.size_t(h.ctxSize)) ++ C.memcpy(cloned.ctx, h.ctx, C.size_t(h.ctxSize)) ++ C.memcpy(cloned.ctx2, h.ctx2, C.size_t(h.ctxSize)) ++ runtime.SetFinalizer(cloned, (*evpHash).finalize) ++ runtime.KeepAlive(h) ++ return cloned ++} ++ ++type md4Hash struct { ++ *evpHash ++} ++ ++// NewMD4 initializes a new MD4 hasher. ++func NewMD4() hash.Hash { ++ return &md4Hash{ ++ evpHash: newEvpHash( ++ func(ctx unsafe.Pointer) C.int { return C.CC_MD4_Init((*C.CC_MD4_CTX)(ctx)) }, ++ func(ctx unsafe.Pointer, data []byte) C.int { ++ return C.CC_MD4_Update((*C.CC_MD4_CTX)(ctx), unsafe.Pointer(&*addr(data)), C.CC_LONG(len(data))) ++ }, ++ func(ctx unsafe.Pointer, digest []byte) C.int { ++ return C.CC_MD4_Final(base(digest), (*C.CC_MD4_CTX)(ctx)) ++ }, ++ C.sizeof_CC_MD4_CTX, ++ C.CC_MD4_BLOCK_BYTES, ++ C.CC_MD4_DIGEST_LENGTH, ++ ), ++ } ++} ++ ++type md5Hash struct { ++ *evpHash ++} ++ ++// NewMD5 initializes a new MD5 hasher. ++func NewMD5() hash.Hash { ++ return &md5Hash{ ++ evpHash: newEvpHash( ++ func(ctx unsafe.Pointer) C.int { return C.CC_MD5_Init((*C.CC_MD5_CTX)(ctx)) }, ++ func(ctx unsafe.Pointer, data []byte) C.int { ++ return C.CC_MD5_Update((*C.CC_MD5_CTX)(ctx), unsafe.Pointer(&*addr(data)), C.CC_LONG(len(data))) ++ }, ++ func(ctx unsafe.Pointer, digest []byte) C.int { ++ return C.CC_MD5_Final(base(digest), (*C.CC_MD5_CTX)(ctx)) ++ }, ++ C.sizeof_CC_MD5_CTX, ++ C.CC_MD5_BLOCK_BYTES, ++ C.CC_MD5_DIGEST_LENGTH, ++ ), ++ } ++} ++ ++type sha1Hash struct { ++ *evpHash ++} ++ ++// NewSHA1 initializes a new SHA1 hasher. ++func NewSHA1() hash.Hash { ++ return &sha1Hash{ ++ evpHash: newEvpHash( ++ func(ctx unsafe.Pointer) C.int { return C.CC_SHA1_Init((*C.CC_SHA1_CTX)(ctx)) }, ++ func(ctx unsafe.Pointer, data []byte) C.int { ++ return C.CC_SHA1_Update((*C.CC_SHA1_CTX)(ctx), unsafe.Pointer(&*addr(data)), C.CC_LONG(len(data))) ++ }, ++ func(ctx unsafe.Pointer, digest []byte) C.int { ++ return C.CC_SHA1_Final(base(digest), (*C.CC_SHA1_CTX)(ctx)) ++ }, ++ C.sizeof_CC_SHA1_CTX, ++ C.CC_SHA1_BLOCK_BYTES, ++ C.CC_SHA1_DIGEST_LENGTH, ++ ), ++ } ++} ++ ++type sha224Hash struct { ++ *evpHash ++} ++ ++// NewSHA224 initializes a new SHA224 hasher. ++func NewSHA224() hash.Hash { ++ return &sha224Hash{ ++ evpHash: newEvpHash( ++ func(ctx unsafe.Pointer) C.int { return C.CC_SHA224_Init((*C.CC_SHA256_CTX)(ctx)) }, ++ func(ctx unsafe.Pointer, data []byte) C.int { ++ return C.CC_SHA224_Update((*C.CC_SHA256_CTX)(ctx), unsafe.Pointer(&*addr(data)), C.CC_LONG(len(data))) ++ }, ++ func(ctx unsafe.Pointer, digest []byte) C.int { ++ return C.CC_SHA224_Final(base(digest), (*C.CC_SHA256_CTX)(ctx)) ++ }, ++ C.sizeof_CC_SHA256_CTX, ++ C.CC_SHA224_BLOCK_BYTES, ++ C.CC_SHA224_DIGEST_LENGTH, ++ ), ++ } ++} ++ ++type sha256Hash struct { ++ *evpHash ++} ++ ++// NewSHA256 initializes a new SHA256 hasher. ++func NewSHA256() hash.Hash { ++ return &sha256Hash{ ++ evpHash: newEvpHash( ++ func(ctx unsafe.Pointer) C.int { return C.CC_SHA256_Init((*C.CC_SHA256_CTX)(ctx)) }, ++ func(ctx unsafe.Pointer, data []byte) C.int { ++ return C.CC_SHA256_Update((*C.CC_SHA256_CTX)(ctx), unsafe.Pointer(&*addr(data)), C.CC_LONG(len(data))) ++ }, ++ func(ctx unsafe.Pointer, digest []byte) C.int { ++ return C.CC_SHA256_Final(base(digest), (*C.CC_SHA256_CTX)(ctx)) ++ }, ++ C.sizeof_CC_SHA256_CTX, ++ C.CC_SHA256_BLOCK_BYTES, ++ C.CC_SHA256_DIGEST_LENGTH, ++ ), ++ } ++} ++ ++type sha384Hash struct { ++ *evpHash ++} ++ ++// NewSHA384 initializes a new SHA384 hasher. ++func NewSHA384() hash.Hash { ++ return &sha384Hash{ ++ evpHash: newEvpHash( ++ func(ctx unsafe.Pointer) C.int { return C.CC_SHA384_Init((*C.CC_SHA512_CTX)(ctx)) }, ++ func(ctx unsafe.Pointer, data []byte) C.int { ++ return C.CC_SHA384_Update((*C.CC_SHA512_CTX)(ctx), unsafe.Pointer(&*addr(data)), C.CC_LONG(len(data))) ++ }, ++ func(ctx unsafe.Pointer, digest []byte) C.int { ++ return C.CC_SHA384_Final(base(digest), (*C.CC_SHA512_CTX)(ctx)) ++ }, ++ C.sizeof_CC_SHA512_CTX, ++ C.CC_SHA384_BLOCK_BYTES, ++ C.CC_SHA384_DIGEST_LENGTH, ++ ), ++ } ++} ++ ++type sha512Hash struct { ++ *evpHash ++} ++ ++// NewSHA512 initializes a new SHA512 hasher. ++func NewSHA512() hash.Hash { ++ return &sha512Hash{ ++ evpHash: newEvpHash( ++ func(ctx unsafe.Pointer) C.int { return C.CC_SHA512_Init((*C.CC_SHA512_CTX)(ctx)) }, ++ func(ctx unsafe.Pointer, data []byte) C.int { ++ return C.CC_SHA512_Update((*C.CC_SHA512_CTX)(ctx), unsafe.Pointer(&*addr(data)), C.CC_LONG(len(data))) ++ }, ++ func(ctx unsafe.Pointer, digest []byte) C.int { ++ return C.CC_SHA512_Final(base(digest), (*C.CC_SHA512_CTX)(ctx)) ++ }, ++ C.sizeof_CC_SHA512_CTX, ++ C.CC_SHA512_BLOCK_BYTES, ++ C.CC_SHA512_DIGEST_LENGTH, ++ ), ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hkdf.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hkdf.go +new file mode 100644 +index 00000000000000..3cc2d5d31927e0 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hkdf.go +@@ -0,0 +1,66 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin && cgo ++ ++package xcrypto ++ ++import ( ++ "errors" ++ "hash" ++ ++ "github.com/microsoft/go-crypto-darwin/internal/cryptokit" ++) ++ ++// ExtractHKDF performs the extract step of HKDF using the specified hash function. ++func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { ++ // Handle empty secret ++ if len(secret) == 0 { ++ return nil, errors.New("secret cannot be empty") ++ } ++ ++ hash, err := hashToCryptoHash(h()) ++ if err != nil { ++ return nil, err ++ } ++ ++ // Default salt to a zero-filled array if not provided ++ if len(salt) == 0 { ++ salt = make([]byte, hash.Size()) ++ } ++ ++ prk, err := cryptokit.ExtractHKDF(hash, secret, salt) ++ if err != nil { ++ return nil, err ++ } ++ ++ return prk, nil ++} ++ ++// ExpandHKDF performs the expand step of HKDF using the specified hash function. ++func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte, keyLength int) ([]byte, error) { ++ // Handle empty secret ++ if len(pseudorandomKey) == 0 { ++ return nil, errors.New("pseudorandom key cannot be empty") ++ } ++ ++ hash, err := hashToCryptoHash(h()) ++ if err != nil { ++ return nil, err ++ } ++ ++ // Determine the maximum expandable key length based on the hash function ++ maxAllowedLength := hash.Size() * 255 ++ ++ // Validate requested key length ++ if keyLength > maxAllowedLength { ++ return nil, errors.New("requested key length exceeds maximum allowable size") ++ } ++ ++ expandedKey, err := cryptokit.ExpandHKDF(hash, pseudorandomKey, info, keyLength) ++ if err != nil { ++ return nil, err ++ } ++ ++ return expandedKey, nil ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hmac.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hmac.go +new file mode 100644 +index 00000000000000..1b22b0a331f825 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hmac.go +@@ -0,0 +1,113 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "errors" ++ "hash" ++ "runtime" ++ "slices" ++ "unsafe" ++) ++ ++// commonCryptoHMAC encapsulates an HMAC using xcrypto. ++type commonCryptoHMAC struct { ++ ctx C.CCHmacContext ++ alg C.CCAlgorithm ++ key []byte ++ output []byte ++ size int ++ blockSize int ++} ++ ++// NewHMAC returns a new HMAC using xcrypto. ++// The function h must return a hash implemented by ++// CommonCrypto (for example, h could be xcrypto.NewSHA256). ++// If h is not recognized, NewHMAC returns nil. ++func NewHMAC(fh func() hash.Hash, key []byte) hash.Hash { ++ h := fh() ++ ccDigest, err := hashToCCDigestHMAC(h) ++ if err != nil { ++ return nil // Unsupported hash function. ++ } ++ ++ // Handle empty key case to match CommonCrypto's behavior. ++ if len(key) == 0 { ++ key = make([]byte, C.CC_SHA512_DIGEST_LENGTH) ++ } else { ++ key = slices.Clone(key) ++ } ++ ++ hmac := &commonCryptoHMAC{ ++ alg: ccDigest, ++ key: key, ++ size: h.Size(), ++ blockSize: h.BlockSize(), ++ } ++ ++ // Initialize the HMAC context with xcrypto. ++ C.CCHmacInit(&hmac.ctx, hmac.alg, pbase(hmac.key), C.size_t(len(hmac.key))) ++ return hmac ++} ++ ++// Write adds more data to the running HMAC hash. ++func (h *commonCryptoHMAC) Write(p []byte) (int, error) { ++ if len(p) > 0 { ++ C.CCHmacUpdate(&h.ctx, unsafe.Pointer(&*addr(p)), C.size_t(len(p))) ++ } ++ runtime.KeepAlive(h) ++ return len(p), nil ++} ++ ++// Sum appends the current HMAC of the data to `in`. ++func (h *commonCryptoHMAC) Sum(in []byte) []byte { ++ if h.output == nil { ++ h.output = make([]byte, h.size) ++ } ++ // Copy the context to preserve it for further operations after Sum is called. ++ hmacCtxCopy := h.ctx ++ C.CCHmacFinal(&hmacCtxCopy, pbase(h.output)) ++ return append(in, h.output...) ++} ++ ++// Reset resets the HMAC state to initial values. ++func (h *commonCryptoHMAC) Reset() { ++ // Re-initialize the HMAC context with the stored key and algorithm. ++ C.CCHmacInit(&h.ctx, h.alg, pbase(h.key), C.size_t(len(h.key))) ++ runtime.KeepAlive(h) ++} ++ ++// Size returns the size of the HMAC output. ++func (h commonCryptoHMAC) Size() int { ++ return h.size ++} ++ ++// BlockSize returns the block size of the underlying hash function. ++func (h commonCryptoHMAC) BlockSize() int { ++ return h.blockSize ++} ++ ++// Mapping Go hash functions to CommonCrypto hash constants ++func hashToCCDigestHMAC(hash hash.Hash) (C.CCAlgorithm, error) { ++ switch hash.(type) { ++ case *md5Hash: ++ return C.kCCHmacAlgMD5, nil ++ case *sha1Hash: ++ return C.kCCHmacAlgSHA1, nil ++ case *sha224Hash: ++ return C.kCCHmacAlgSHA224, nil ++ case *sha256Hash: ++ return C.kCCHmacAlgSHA256, nil ++ case *sha384Hash: ++ return C.kCCHmacAlgSHA384, nil ++ case *sha512Hash: ++ return C.kCCHmacAlgSHA512, nil ++ default: ++ return 0, errors.New("unsupported hash function") ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/pbkdf2.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/pbkdf2.go +new file mode 100644 +index 00000000000000..e49dc1c0de3cef +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/pbkdf2.go +@@ -0,0 +1,65 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "errors" ++ "hash" ++ "unsafe" ++) ++ ++func PBKDF2(password, salt []byte, iter, keyLen int, fh func() hash.Hash) ([]byte, error) { ++ // Map Go hash function to CommonCrypto hash constant ++ ccDigest, err := hashToCCDigestPBKDF2(fh()) ++ if err != nil { ++ return nil, err ++ } ++ ++ if len(password) == 0 { ++ // CommonCrypto requires a non-empty password ++ // Substitute empty password with placeholder ++ password = make([]byte, 1) ++ } ++ ++ // Allocate output buffer for the derived key ++ derivedKey := make([]byte, keyLen) ++ ++ // Call CommonCrypto's PBKDF2 implementation ++ status := C.CCKeyDerivationPBKDF( ++ C.kCCPBKDF2, // PBKDF2 algorithm ++ sbase(password), C.size_t(len(password)), // Password and its length ++ base(salt), C.size_t(len(salt)), // Salt and its length ++ ccDigest, // Digest algorithm ++ C.uint(iter), // Iteration count ++ (*C.uchar)(unsafe.Pointer(&derivedKey[0])), C.size_t(keyLen), // Output buffer for derived key and its length ++ ) ++ ++ if status != C.kCCSuccess { ++ return nil, errors.New("PBKDF2 key derivation failed") ++ } ++ ++ return derivedKey, nil ++} ++ ++// Mapping Go hash functions to CommonCrypto hash constants ++func hashToCCDigestPBKDF2(hash hash.Hash) (C.CCAlgorithm, error) { ++ switch hash.(type) { ++ case *sha1Hash: ++ return C.kCCPRFHmacAlgSHA1, nil ++ case *sha224Hash: ++ return C.kCCPRFHmacAlgSHA224, nil ++ case *sha256Hash: ++ return C.kCCPRFHmacAlgSHA256, nil ++ case *sha384Hash: ++ return C.kCCPRFHmacAlgSHA384, nil ++ case *sha512Hash: ++ return C.kCCPRFHmacAlgSHA512, nil ++ default: ++ return 0, errors.New("unsupported hash function") ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rand.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rand.go +new file mode 100644 +index 00000000000000..e58c0b3b19a68b +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rand.go +@@ -0,0 +1,26 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "errors" ++ "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.SecRandomCopyBytes(C.kSecRandomDefault, C.size_t(len(b)), unsafe.Pointer(&b[0])) != 0 { ++ return 0, errors.New("crypto/rand: unable to read from source") ++ } ++ return len(b), nil ++} ++ ++const RandReader = randReader(0) +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rc4.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rc4.go +new file mode 100644 +index 00000000000000..415889c4f1bdd2 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rc4.go +@@ -0,0 +1,83 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "errors" ++ "runtime" ++ "slices" ++ "unsafe" ++) ++ ++// RC4Cipher is an instance of RC4 using a particular key. ++type RC4Cipher struct { ++ ctx C.CCCryptorRef ++} ++ ++// NewRC4Cipher creates and returns a new RC4 cipher with the given key. ++func NewRC4Cipher(key []byte) (*RC4Cipher, error) { ++ // Clone the key to prevent modification. ++ key = slices.Clone(key) ++ var ctx C.CCCryptorRef ++ status := C.CCCryptorCreate( ++ C.kCCEncrypt, // Operation (RC4 stream) ++ C.kCCAlgorithmRC4, // Algorithm ++ 0, // No padding or other options ++ pbase(key), // Key ++ C.size_t(len(key)), // Key length ++ nil, // No IV needed for RC4 ++ &ctx, // Output: CCCryptorRef ++ ) ++ if status != C.kCCSuccess { ++ return nil, errors.New("failed to create RC4 cipher") ++ } ++ c := &RC4Cipher{ctx: ctx} ++ runtime.SetFinalizer(c, (*RC4Cipher).finalize) ++ return c, nil ++} ++ ++// finalize releases the RC4 cipher context when no longer needed. ++func (c *RC4Cipher) finalize() { ++ if c.ctx != nil { ++ C.CCCryptorRelease(c.ctx) ++ } ++} ++ ++// Reset zeros the key data and makes the cipher unusable. ++func (c *RC4Cipher) Reset() { ++ if c.ctx != nil { ++ C.CCCryptorRelease(c.ctx) ++ c.ctx = nil ++ } ++} ++ ++// XORKeyStream sets dst to the result of XORing src with the key stream. ++func (c *RC4Cipher) XORKeyStream(dst, src []byte) { ++ if c.ctx == nil || len(src) == 0 { ++ return ++ } ++ if inexactOverlap(dst[:len(src)], src) { ++ panic("crypto/rc4: invalid buffer overlap") ++ } ++ // Ensures `dst` has sufficient space. ++ _ = dst[len(src)-1] ++ var outLen C.size_t ++ status := C.CCCryptorUpdate( ++ c.ctx, ++ unsafe.Pointer(&*addr(src)), C.size_t(len(src)), // Input ++ unsafe.Pointer(&*addr(dst)), C.size_t(len(dst)), // Output ++ &outLen, ++ ) ++ if status != C.kCCSuccess { ++ panic("crypto/cipher: CCCryptorUpdate failed") ++ } ++ if int(outLen) != len(src) { ++ panic("crypto/rc4: src not fully XORed") ++ } ++ runtime.KeepAlive(c) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rsa.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rsa.go +new file mode 100644 +index 00000000000000..63df684569e671 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/rsa.go +@@ -0,0 +1,194 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #include ++import "C" ++import ( ++ "crypto" ++ "errors" ++ "hash" ++ "runtime" ++ "strconv" ++) ++ ++// GenerateKeyRSA generates an RSA key pair on macOS. ++// asn1Data is encoded as PKCS#1 ASN1 DER. ++func GenerateKeyRSA(bits int) (asn1Data []byte, err error) { ++ privKeyDER, privKeyRef, err := createSecKeyRandom(C.kSecAttrKeyTypeRSA, bits) ++ if err != nil { ++ return nil, err ++ } ++ C.CFRelease(C.CFTypeRef(privKeyRef)) ++ return privKeyDER, nil ++} ++ ++type PublicKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.SecKeyRef ++} ++ ++func (k *PublicKeyRSA) finalize() { ++ if k._pkey != 0 { ++ C.CFRelease(C.CFTypeRef(k._pkey)) ++ } ++} ++ ++// NewPublicKeyRSA creates a new RSA public key from ASN1 DER encoded data. ++func NewPublicKeyRSA(asn1Data []byte) (*PublicKeyRSA, error) { ++ pubKeyRef, err := createSecKeyWithData(asn1Data, C.kSecAttrKeyTypeRSA, C.kSecAttrKeyClassPublic) + if err != nil { -+ return err ++ return nil, err + } -+ ctx := C.go_openssl_EVP_KDF_CTX_new(kdf) -+ if ctx == nil { -+ return newOpenSSLError("EVP_KDF_CTX_new") ++ ++ key := &PublicKeyRSA{_pkey: pubKeyRef} ++ runtime.SetFinalizer(key, (*PublicKeyRSA).finalize) ++ return key, nil ++} ++ ++func (k *PublicKeyRSA) withKey(f func(C.SecKeyRef) C.int) C.int { ++ // Because of the finalizer, any time key is passed to cgo, that call must ++ // be followed by a call to runtime.KeepAlive, to make sure k is not ++ // collected (and finalized) before the cgo call returns. ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} ++ ++type PrivateKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.SecKeyRef ++} ++ ++func (k *PrivateKeyRSA) finalize() { ++ if k._pkey != 0 { ++ C.CFRelease(C.CFTypeRef(k._pkey)) + } -+ defer C.go_openssl_EVP_KDF_CTX_free(ctx) ++} + -+ bld, err := newParamBuilder() ++// NewPrivateKeyRSA creates a new RSA private key from ASN1 DER encoded data. ++func NewPrivateKeyRSA(asn1Data []byte) (*PrivateKeyRSA, error) { ++ privKeyRef, err := createSecKeyWithData(asn1Data, C.kSecAttrKeyTypeRSA, C.kSecAttrKeyClassPrivate) + if err != nil { -+ return err ++ return nil, err + } -+ bld.addUTF8String(_OSSL_KDF_PARAM_DIGEST, C.go_openssl_EVP_MD_get0_name(md), 0) -+ bld.addOctetString(_OSSL_KDF_PARAM_SECRET, secret) -+ bld.addOctetString(_OSSL_KDF_PARAM_SEED, label) -+ bld.addOctetString(_OSSL_KDF_PARAM_SEED, seed) -+ params, err := bld.build() -+ if err != nil { -+ return err ++ ++ key := &PrivateKeyRSA{_pkey: privKeyRef} ++ runtime.SetFinalizer(key, (*PrivateKeyRSA).finalize) ++ return key, nil ++} ++ ++func (k *PrivateKeyRSA) PublicKey() *PublicKeyRSA { ++ var pubKeyRef C.SecKeyRef ++ k.withKey(func(key C.SecKeyRef) C.int { ++ pubKeyRef = C.SecKeyCopyPublicKey(k._pkey) ++ return 0 ++ }) ++ pubKey := &PublicKeyRSA{_pkey: pubKeyRef} ++ runtime.SetFinalizer(pubKey, (*PublicKeyRSA).finalize) ++ return pubKey ++} ++ ++func (k *PrivateKeyRSA) withKey(f func(C.SecKeyRef) 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) ++} ++ ++// DecryptRSAOAEP decrypts data using RSA-OAEP. ++func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ if len(label) > 0 { ++ // https://github.com/microsoft/go-crypto-darwin/issues/22 ++ panic("crypto/rsa: label is not supported on macOS") + } -+ defer C.go_openssl_OSSL_PARAM_free(params) ++ return evpDecrypt(priv.withKey, algorithmTypeOAEP, ciphertext, h) ++} + -+ if C.go_openssl_EVP_KDF_derive(ctx, base(result), C.size_t(len(result)), params) != 1 { -+ return newOpenSSLError("EVP_KDF_derive") ++// EncryptRSAOAEP encrypts data using RSA-OAEP. ++func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ if len(label) > 0 { ++ // https://github.com/microsoft/go-crypto-darwin/issues/22 ++ panic("crypto/rsa: label is not supported on macOS") + } -+ return nil ++ return evpEncrypt(pub.withKey, algorithmTypeOAEP, msg, h) +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/zaes.go b/src/vendor/github.com/golang-fips/openssl/v2/zaes.go -new file mode 100644 -index 00000000000000..e60a5dde390be6 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/zaes.go -@@ -0,0 +1,86 @@ -+// Code generated by cmd/genaesmodes. DO NOT EDIT. + -+//go:build cgo && !cmd_go_bootstrap ++// SignRSAPSS signs data with RSA-PSS. ++func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { ++ return evpSign(priv.withKey, algorithmTypePSS, h, hashed) ++} + -+package openssl ++// VerifyRSAPSS verifies data with RSA-PSS. ++func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { ++ return evpVerify(pub.withKey, algorithmTypePSS, h, hashed, sig) ++} + -+import "crypto/cipher" ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ return evpSign(priv.withKey, algorithmTypePKCS1v15Sig, h, hashed) ++} + -+type cipherWithCBC struct { -+ aesCipher ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { ++ if pub.withKey(func(key C.SecKeyRef) C.int { ++ size := C.SecKeyGetBlockSize(key) ++ if len(sig) < int(size) { ++ return 0 ++ } ++ return 1 ++ }) == 0 { ++ return errors.New("crypto/rsa: verification error") ++ } ++ return evpVerify(pub.withKey, algorithmTypePKCS1v15Sig, h, hashed, sig) +} + -+type cipherWithCTR struct { -+ aesCipher ++// DecryptRSAPKCS1 decrypts data using RSA PKCS#1 v1.5 padding. ++func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return evpDecrypt(priv.withKey, algorithmTypePKCS1v15Enc, ciphertext, nil) +} + -+type cipherWithCBC_CTR struct { -+ aesCipher -+ cipherWithCBC -+ cipherWithCTR ++// EncryptRSAPKCS1 encrypts data using RSA PKCS#1 v1.5 padding. ++func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, algorithmTypePKCS1v15Enc, msg, nil) +} + -+type cipherWithGCM struct { -+ aesCipher ++func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return evpDecrypt(priv.withKey, algorithmTypeRAW, ciphertext, nil) +} + -+type cipherWithCBC_GCM struct { -+ aesCipher -+ cipherWithCBC -+ cipherWithGCM ++func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, algorithmTypeRAW, msg, nil) +} + -+type cipherWithCTR_GCM struct { -+ aesCipher -+ cipherWithCTR -+ cipherWithGCM ++// Helper functions ++ ++type cfError struct { ++ code int ++ message string +} + -+type cipherWithCBC_CTR_GCM struct { -+ aesCipher -+ cipherWithCBC -+ cipherWithCTR -+ cipherWithGCM ++func (e *cfError) Error() string { ++ if e.message == "" { ++ return "CFError(" + strconv.Itoa(e.code) + "): unknown error" ++ } ++ return "CFError(" + strconv.Itoa(e.code) + "): " + e.message +} + -+func newAESBlock(c *evpCipher, kind cipherKind) cipher.Block { -+ aes := aesCipher{c} -+ var block cipher.Block -+ supportsCBC := loadCipher(kind, cipherModeCBC) != nil -+ supportsCTR := loadCipher(kind, cipherModeCTR) != nil -+ supportsGCM := loadCipher(kind, cipherModeGCM) != nil -+ switch { -+ case !supportsCBC && !supportsCTR && !supportsGCM: -+ block = aes -+ case supportsCBC && !supportsCTR && !supportsGCM: -+ block = cipherWithCBC{aes} -+ case !supportsCBC && supportsCTR && !supportsGCM: -+ block = cipherWithCTR{aes} -+ case supportsCBC && supportsCTR && !supportsGCM: -+ block = cipherWithCBC_CTR{aes, -+ cipherWithCBC{aes}, -+ cipherWithCTR{aes}, -+ } -+ case !supportsCBC && !supportsCTR && supportsGCM: -+ block = cipherWithGCM{aes} -+ case supportsCBC && !supportsCTR && supportsGCM: -+ block = cipherWithCBC_GCM{aes, -+ cipherWithCBC{aes}, -+ cipherWithGCM{aes}, -+ } -+ case !supportsCBC && supportsCTR && supportsGCM: -+ block = cipherWithCTR_GCM{aes, -+ cipherWithCTR{aes}, -+ cipherWithGCM{aes}, -+ } -+ case supportsCBC && supportsCTR && supportsGCM: -+ block = cipherWithCBC_CTR_GCM{aes, -+ cipherWithCBC{aes}, -+ cipherWithCTR{aes}, -+ cipherWithGCM{aes}, ++func goCFErrorRef(ref C.CFErrorRef) error { ++ if ref == 0 { ++ return nil ++ } ++ var message string ++ if desc := C.CFErrorCopyDescription(ref); desc != C.CFStringRef(0) { ++ defer C.CFRelease(C.CFTypeRef(desc)) ++ if cstr := C.CFStringGetCStringPtr(desc, C.kCFStringEncodingUTF8); cstr != nil { ++ message = C.GoString(cstr) + } -+ default: -+ panic("unreachable") + } -+ return block ++ return &cfError{ ++ code: int(C.CFErrorGetCode(ref)), ++ message: message, ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/xcrypto.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/xcrypto.go +new file mode 100644 +index 00000000000000..9451d05599f3a8 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/xcrypto.go +@@ -0,0 +1,59 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build darwin ++ ++package xcrypto ++ ++// #cgo CFLAGS: -Wno-deprecated-declarations ++import "C" ++import "unsafe" ++ ++// noescape hides a pointer from escape analysis. noescape is ++// the identity function but escape analysis doesn't think the ++// output depends on the input. noescape is inlined and currently ++// compiles down to zero instructions. ++// USE CAREFULLY! ++// ++//go:nosplit ++func noescape(p unsafe.Pointer) unsafe.Pointer { ++ x := uintptr(p) ++ return unsafe.Pointer(x ^ 0) ++} ++ ++var zero byte ++ ++// addr converts p to its base addr, including a noescape along the way. ++// If p is nil, addr returns a non-nil pointer, so that the result can always ++// be dereferenced. ++// ++//go:nosplit ++func addr(p []byte) *byte { ++ if len(p) == 0 { ++ return &zero ++ } ++ return (*byte)(noescape(unsafe.Pointer(&p[0]))) ++} ++ ++// base returns the address of the underlying array in b, ++// being careful not to panic when b has zero length. ++func base(b []byte) *C.uchar { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uchar)(unsafe.Pointer(&b[0])) ++} ++ ++func sbase(b []byte) *C.char { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.char)(unsafe.Pointer(&b[0])) ++} ++ ++func pbase(b []byte) unsafe.Pointer { ++ if len(b) == 0 { ++ return nil ++ } ++ return unsafe.Pointer(&b[0]) +} 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 @@ -8890,10 +12176,10 @@ index 00000000000000..586e9ae2ebb0c9 +} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go new file mode 100644 -index 00000000000000..a674496f18a3af +index 00000000000000..87b1c95dc7f911 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go -@@ -0,0 +1,312 @@ +@@ -0,0 +1,306 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -8912,9 +12198,6 @@ index 00000000000000..a674496f18a3af + "github.com/microsoft/go-crypto-winnative/internal/bcrypt" +) + -+// maxHashSize is the size of SHA512 and SHA3_512, the largest hashes we support. -+const maxHashSize = 64 -+ +// SupportsHash returns true if a hash.Hash implementation is supported for h. +func SupportsHash(h crypto.Hash) bool { + switch h { @@ -8983,6 +12266,27 @@ index 00000000000000..a674496f18a3af + return +} + ++func SHA3_256(p []byte) (sum [32]byte) { ++ if err := hashOneShot(bcrypt.SHA3_256_ALGORITHM, p, sum[:]); err != nil { ++ panic("bcrypt: SHA3_256 failed") ++ } ++ return ++} ++ ++func SHA3_384(p []byte) (sum [48]byte) { ++ if err := hashOneShot(bcrypt.SHA3_384_ALGORITHM, p, sum[:]); err != nil { ++ panic("bcrypt: SHA3_384 failed") ++ } ++ return ++} ++ ++func SHA3_512(p []byte) (sum [64]byte) { ++ if err := hashOneShot(bcrypt.SHA3_512_ALGORITHM, p, sum[:]); err != nil { ++ panic("bcrypt: SHA3_512 failed") ++ } ++ return ++} ++ +// NewMD4 returns a new MD4 hash. +func NewMD4() hash.Hash { + return newHashX(bcrypt.MD4_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) @@ -9013,6 +12317,21 @@ index 00000000000000..a674496f18a3af + return newHashX(bcrypt.SHA512_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) +} + ++// NewSHA3_256 returns a new SHA256 hash. ++func NewSHA3_256() hash.Hash { ++ return newHashX(bcrypt.SHA3_256_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) ++} ++ ++// NewSHA3_384 returns a new SHA384 hash. ++func NewSHA3_384() hash.Hash { ++ return newHashX(bcrypt.SHA3_384_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) ++} ++ ++// NewSHA3_512 returns a new SHA512 hash. ++func NewSHA3_512() hash.Hash { ++ return newHashX(bcrypt.SHA3_512_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) ++} ++ +type hashAlgorithm struct { + handle bcrypt.ALG_HANDLE + id string @@ -9035,33 +12354,20 @@ index 00000000000000..a674496f18a3af +} + +// hashToID converts a hash.Hash implementation from this package -+// to a CNG hash ID -+func hashToID(h hash.Hash) string { -+ hx, ok := h.(*hashX) -+ if !ok { -+ return "" -+ } -+ return hx.alg.id -+} -+ -+// cloneHash is an interface that defines a Clone method. -+// -+// hash.CloneHash will probably be added in Go 1.25, see https://golang.org/issue/69521, -+// but we need it now. -+type cloneHash interface { -+ hash.Hash -+ // Clone returns a separate Hash instance with the same state as h. -+ Clone() hash.Hash ++// to a CNG hash ID ++func hashToID(h hash.Hash) string { ++ hx, ok := h.(*hashX) ++ if !ok { ++ return "" ++ } ++ return hx.alg.id +} + -+var _ hash.Hash = (*hashX)(nil) -+var _ cloneHash = (*hashX)(nil) -+ -+// hashX implements [hash.Hash]. +type hashX struct { -+ alg *hashAlgorithm -+ ctx bcrypt.HASH_HANDLE ++ alg *hashAlgorithm ++ _ctx bcrypt.HASH_HANDLE // access it using withCtx + ++ buf []byte + key []byte +} + @@ -9072,72 +12378,88 @@ index 00000000000000..a674496f18a3af + panic(err) + } + h := &hashX{alg: alg, key: bytes.Clone(key)} -+ // Don't call bcrypt.CreateHash yet, it would be wasteful -+ // if the caller only wants to know the hash type. This -+ // is a common pattern in this package, as some functions -+ // accept a `func() hash.Hash` parameter and call it just -+ // to know the hash type. ++ // Don't allocate hx.buf nor call bcrypt.CreateHash yet, ++ // which would be wasteful if the caller only wants to know ++ // the hash type. This is a common pattern in this package, ++ // as some functions accept a `func() hash.Hash` parameter ++ // and call it just to know the hash type. ++ runtime.SetFinalizer(h, (*hashX).finalize) + return h +} + +func (h *hashX) finalize() { -+ bcrypt.DestroyHash(h.ctx) ++ if h._ctx != 0 { ++ bcrypt.DestroyHash(h._ctx) ++ } +} + -+func (h *hashX) init() { ++func (h *hashX) withCtx(fn func(ctx bcrypt.HASH_HANDLE) error) error { + defer runtime.KeepAlive(h) -+ if h.ctx != 0 { -+ return -+ } -+ err := bcrypt.CreateHash(h.alg.handle, &h.ctx, nil, h.key, bcrypt.HASH_REUSABLE_FLAG) -+ if err != nil { -+ panic(err) ++ if h._ctx == 0 { ++ err := bcrypt.CreateHash(h.alg.handle, &h._ctx, nil, h.key, 0) ++ if err != nil { ++ panic(err) ++ } + } -+ runtime.SetFinalizer(h, (*hashX).finalize) ++ return fn(h._ctx) +} + -+func (h *hashX) Clone() hash.Hash { -+ defer runtime.KeepAlive(h) ++func (h *hashX) Clone() (hash.Hash, error) { + h2 := &hashX{alg: h.alg, key: bytes.Clone(h.key)} -+ if h.ctx != 0 { -+ hashClone(h.ctx, &h2.ctx) -+ runtime.SetFinalizer(h2, (*hashX).finalize) ++ err := h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { ++ return bcrypt.DuplicateHash(ctx, &h2._ctx, nil, 0) ++ }) ++ if err != nil { ++ return nil, err + } -+ return h2 ++ runtime.SetFinalizer(h2, (*hashX).finalize) ++ return h2, nil +} + +func (h *hashX) Reset() { -+ defer runtime.KeepAlive(h) -+ if h.ctx != 0 { -+ hashReset(h.ctx, h.Size()) ++ if h._ctx != 0 { ++ bcrypt.DestroyHash(h._ctx) ++ h._ctx = 0 + } +} + +func (h *hashX) Write(p []byte) (n int, err error) { -+ defer runtime.KeepAlive(h) -+ h.init() -+ hashData(h.ctx, p) ++ err = h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { ++ for n < len(p) && err == nil { ++ nn := len32(p[n:]) ++ err = bcrypt.HashData(h._ctx, p[n:n+nn], 0) ++ n += nn ++ } ++ return err ++ }) ++ if err != nil { ++ // hash.Hash interface mandates Write should never return an error. ++ panic(err) ++ } + return len(p), nil +} + +func (h *hashX) WriteString(s string) (int, error) { -+ defer runtime.KeepAlive(h) -+ return h.Write(unsafe.Slice(unsafe.StringData(s), len(s))) ++ // TODO: use unsafe.StringData once we drop support ++ // for go1.19 and earlier. ++ hdr := (*struct { ++ Data *byte ++ Len int ++ })(unsafe.Pointer(&s)) ++ return h.Write(unsafe.Slice(hdr.Data, len(s))) +} + +func (h *hashX) WriteByte(c byte) error { -+ defer runtime.KeepAlive(h) -+ h.init() -+ hashByte(h.ctx, c) ++ err := h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { ++ return bcrypt.HashDataRaw(h._ctx, &c, 1, 0) ++ }) ++ if err != nil { ++ // hash.Hash interface mandates Write should never return an error. ++ panic(err) ++ } + return nil +} + -+func (h *hashX) Sum(in []byte) []byte { -+ defer runtime.KeepAlive(h) -+ h.init() -+ return hashSum(h.ctx, h.Size(), in) -+} -+ +func (h *hashX) Size() int { + return int(h.alg.size) +} @@ -9146,65 +12468,23 @@ index 00000000000000..a674496f18a3af + return int(h.alg.blockSize) +} + -+// hashData writes p to ctx. It panics on error. -+func hashData(ctx bcrypt.HASH_HANDLE, p []byte) { -+ var n int -+ var err error -+ for n < len(p) && err == nil { -+ nn := len32(p[n:]) -+ err = bcrypt.HashData(ctx, p[n:n+nn], 0) -+ n += nn -+ } -+ if err != nil { -+ panic(err) -+ } -+} -+ -+// hashByte writes c to ctx. It panics on error. -+func hashByte(ctx bcrypt.HASH_HANDLE, c byte) { -+ err := bcrypt.HashDataRaw(ctx, &c, 1, 0) -+ if err != nil { -+ panic(err) -+ } -+} -+ -+// hashSum writes the hash of ctx to in and returns the result. -+// size is the size of the hash output. -+// It panics on error. -+func hashSum(ctx bcrypt.HASH_HANDLE, size int, in []byte) []byte { ++func (h *hashX) Sum(in []byte) []byte { + var ctx2 bcrypt.HASH_HANDLE -+ err := bcrypt.DuplicateHash(ctx, &ctx2, nil, 0) ++ err := h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { ++ return bcrypt.DuplicateHash(ctx, &ctx2, nil, 0) ++ }) + if err != nil { + panic(err) + } + defer bcrypt.DestroyHash(ctx2) -+ buf := make([]byte, size, maxHashSize) // explicit cap to allow stack allocation -+ err = bcrypt.FinishHash(ctx2, buf, 0) -+ if err != nil { -+ panic(err) ++ if h.buf == nil { ++ h.buf = make([]byte, h.alg.size) + } -+ return append(in, buf...) -+} -+ -+// hashReset resets the hash state of ctx. -+// size is the size of the hash output. -+// It panics on error. -+func hashReset(ctx bcrypt.HASH_HANDLE, size int) { -+ // bcrypt.FinishHash expects the output buffer to match the hash size. -+ // We don't care about the output, so we just pass a stack-allocated buffer -+ // that is large enough to hold the largest hash size we support. -+ var discard [maxHashSize]byte -+ if err := bcrypt.FinishHash(ctx, discard[:size], 0); err != nil { -+ panic(err) -+ } -+} -+ -+// hashClone clones ctx into ctx2. It panics on error. -+func hashClone(ctx bcrypt.HASH_HANDLE, ctx2 *bcrypt.HASH_HANDLE) { -+ err := bcrypt.DuplicateHash(ctx, ctx2, nil, 0) ++ err = bcrypt.FinishHash(ctx2, h.buf, 0) + if err != nil { + panic(err) + } ++ return append(in, h.buf...) +} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hkdf.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hkdf.go new file mode 100644 @@ -10186,296 +13466,6 @@ index 00000000000000..0269f9cf86539e + } + return "" +} -diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/sha3.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/sha3.go -new file mode 100644 -index 00000000000000..d7aa193e00e653 ---- /dev/null -+++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/sha3.go -@@ -0,0 +1,284 @@ -+// Copyright (c) Microsoft Corporation. -+// Licensed under the MIT License. -+ -+//go:build windows -+// +build windows -+ -+package cng -+ -+import ( -+ "hash" -+ "runtime" -+ "unsafe" -+ -+ "github.com/microsoft/go-crypto-winnative/internal/bcrypt" -+) -+ -+// SumSHA3_256 returns the SHA3-256 checksum of the data. -+func SumSHA3_256(p []byte) (sum [32]byte) { -+ if err := hashOneShot(bcrypt.SHA3_256_ALGORITHM, p, sum[:]); err != nil { -+ panic("bcrypt: SHA3_256 failed") -+ } -+ return -+} -+ -+// SumSHA3_384 returns the SHA3-384 checksum of the data. -+func SumSHA3_384(p []byte) (sum [48]byte) { -+ if err := hashOneShot(bcrypt.SHA3_384_ALGORITHM, p, sum[:]); err != nil { -+ panic("bcrypt: SHA3_384 failed") -+ } -+ return -+} -+ -+// SumSHA3_512 returns the SHA3-512 checksum of the data. -+func SumSHA3_512(p []byte) (sum [64]byte) { -+ if err := hashOneShot(bcrypt.SHA3_512_ALGORITHM, p, sum[:]); err != nil { -+ panic("bcrypt: SHA3_512 failed") -+ } -+ return -+} -+ -+// SumSHAKE128 applies the SHAKE128 extendable output function to data and -+// returns an output of the given length in bytes. -+func SumSHAKE128(data []byte, length int) []byte { -+ out := make([]byte, length) -+ if err := hashOneShot(bcrypt.CSHAKE128_ALGORITHM, data, out); err != nil { -+ panic("bcrypt: CSHAKE128_ALGORITHM failed") -+ } -+ return out -+} -+ -+// SumSHAKE256 applies the SHAKE256 extendable output function to data and -+// returns an output of the given length in bytes. -+func SumSHAKE256(data []byte, length int) []byte { -+ out := make([]byte, length) -+ if err := hashOneShot(bcrypt.CSHAKE256_ALGORITHM, data, out); err != nil { -+ panic("bcrypt: CSHAKE256_ALGORITHM failed") -+ } -+ return out -+} -+ -+// SupportsSHAKE128 returns true if the SHAKE128 extendable output function is -+// supported. -+func SupportsSHAKE128() bool { -+ _, err := loadHash(bcrypt.CSHAKE128_ALGORITHM, bcrypt.ALG_NONE_FLAG) -+ return err == nil -+} -+ -+// SupportsSHAKE256 returns true if the SHAKE256 extendable output function is -+// supported. -+func SupportsSHAKE256() bool { -+ _, err := loadHash(bcrypt.CSHAKE256_ALGORITHM, bcrypt.ALG_NONE_FLAG) -+ return err == nil -+} -+ -+var _ hash.Hash = (*DigestSHA3)(nil) -+var _ cloneHash = (*DigestSHA3)(nil) -+ -+// DigestSHA3 is the [sha3.SHA3] implementation using the CNG API. -+type DigestSHA3 struct { -+ alg *hashAlgorithm -+ ctx bcrypt.HASH_HANDLE -+} -+ -+// newDigestSHA3 returns a new hash.Hash using the specified algorithm. -+func newDigestSHA3(id string) *DigestSHA3 { -+ alg, err := loadHash(id, bcrypt.ALG_NONE_FLAG) -+ if err != nil { -+ panic(err) -+ } -+ h := &DigestSHA3{alg: alg} -+ // Don't call bcrypt.CreateHash yet, it would be wasteful -+ // if the caller only wants to know the hash type. This -+ // is a common pattern in this package, as some functions -+ // accept a `func() hash.Hash` parameter and call it just -+ // to know the hash type. -+ return h -+} -+ -+func (h *DigestSHA3) finalize() { -+ bcrypt.DestroyHash(h.ctx) -+} -+ -+func (h *DigestSHA3) init() { -+ defer runtime.KeepAlive(h) -+ if h.ctx != 0 { -+ return -+ } -+ err := bcrypt.CreateHash(h.alg.handle, &h.ctx, nil, nil, bcrypt.HASH_REUSABLE_FLAG) -+ if err != nil { -+ panic(err) -+ } -+ runtime.SetFinalizer(h, (*DigestSHA3).finalize) -+} -+ -+func (h *DigestSHA3) Clone() hash.Hash { -+ defer runtime.KeepAlive(h) -+ h2 := &DigestSHA3{alg: h.alg} -+ if h.ctx != 0 { -+ hashClone(h.ctx, &h2.ctx) -+ runtime.SetFinalizer(h2, (*DigestSHA3).finalize) -+ } -+ return h2 -+} -+ -+func (h *DigestSHA3) Reset() { -+ defer runtime.KeepAlive(h) -+ if h.ctx != 0 { -+ hashReset(h.ctx, h.Size()) -+ } -+} -+ -+func (h *DigestSHA3) Write(p []byte) (n int, err error) { -+ defer runtime.KeepAlive(h) -+ h.init() -+ hashData(h.ctx, p) -+ return len(p), nil -+} -+ -+func (h *DigestSHA3) WriteString(s string) (int, error) { -+ defer runtime.KeepAlive(h) -+ return h.Write(unsafe.Slice(unsafe.StringData(s), len(s))) -+} -+ -+func (h *DigestSHA3) WriteByte(c byte) error { -+ defer runtime.KeepAlive(h) -+ h.init() -+ hashByte(h.ctx, c) -+ return nil -+} -+ -+func (h *DigestSHA3) Sum(in []byte) []byte { -+ defer runtime.KeepAlive(h) -+ h.init() -+ return hashSum(h.ctx, h.Size(), in) -+} -+ -+func (h *DigestSHA3) Size() int { -+ return int(h.alg.size) -+} -+ -+func (h *DigestSHA3) BlockSize() int { -+ return int(h.alg.blockSize) -+} -+ -+// NewSHA3_256 returns a new SHA256 hash. -+func NewSHA3_256() *DigestSHA3 { -+ return newDigestSHA3(bcrypt.SHA3_256_ALGORITHM) -+} -+ -+// NewSHA3_384 returns a new SHA384 hash. -+func NewSHA3_384() *DigestSHA3 { -+ return newDigestSHA3(bcrypt.SHA3_384_ALGORITHM) -+} -+ -+// NewSHA3_512 returns a new SHA512 hash. -+func NewSHA3_512() *DigestSHA3 { -+ return newDigestSHA3(bcrypt.SHA3_512_ALGORITHM) -+} -+ -+// SHAKE is an instance of a SHAKE extendable output function. -+type SHAKE struct { -+ ctx bcrypt.HASH_HANDLE -+ blockSize uint32 -+} -+ -+func newShake(id string, N, S []byte) *SHAKE { -+ alg, err := loadHash(id, bcrypt.ALG_NONE_FLAG) -+ if err != nil { -+ panic(err) -+ } -+ h := &SHAKE{blockSize: alg.blockSize} -+ err = bcrypt.CreateHash(alg.handle, &h.ctx, nil, nil, bcrypt.HASH_REUSABLE_FLAG) -+ if err != nil { -+ panic(err) -+ } -+ if len(N) != 0 { -+ if err := bcrypt.SetProperty(bcrypt.HANDLE(h.ctx), utf16PtrFromString(bcrypt.FUNCTION_NAME_STRING), N, 0); err != nil { -+ panic(err) -+ } -+ } -+ if len(S) != 0 { -+ if err := bcrypt.SetProperty(bcrypt.HANDLE(h.ctx), utf16PtrFromString(bcrypt.CUSTOMIZATION_STRING), S, 0); err != nil { -+ panic(err) -+ } -+ } -+ runtime.SetFinalizer(h, (*SHAKE).finalize) -+ return h -+} -+ -+// NewSHAKE128 creates a new SHAKE128 XOF. -+func NewSHAKE128() *SHAKE { -+ return newShake(bcrypt.CSHAKE128_ALGORITHM, nil, nil) -+} -+ -+// NewSHAKE256 creates a new SHAKE256 XOF. -+func NewSHAKE256() *SHAKE { -+ return newShake(bcrypt.CSHAKE256_ALGORITHM, nil, nil) -+} -+ -+// NewCSHAKE128 creates a new cSHAKE128 XOF. -+// -+// N is used to define functions based on cSHAKE, it can be empty when plain -+// cSHAKE is desired. S is a customization byte string used for domain -+// separation. When N and S are both empty, this is equivalent to NewSHAKE128. -+func NewCSHAKE128(N, S []byte) *SHAKE { -+ return newShake(bcrypt.CSHAKE128_ALGORITHM, N, S) -+} -+ -+// NewCSHAKE256 creates a new cSHAKE256 XOF. -+// -+// N is used to define functions based on cSHAKE, it can be empty when plain -+// cSHAKE is desired. S is a customization byte string used for domain -+// separation. When N and S are both empty, this is equivalent to NewSHAKE256. -+func NewCSHAKE256(N, S []byte) *SHAKE { -+ return newShake(bcrypt.CSHAKE256_ALGORITHM, N, S) -+} -+ -+func (h *SHAKE) finalize() { -+ bcrypt.DestroyHash(h.ctx) -+} -+ -+// Write absorbs more data into the XOF's state. -+// -+// It panics if any output has already been read. -+func (s *SHAKE) Write(p []byte) (n int, err error) { -+ if len(p) == 0 { -+ return 0, nil -+ } -+ defer runtime.KeepAlive(s) -+ hashData(s.ctx, p) -+ return len(p), nil -+} -+ -+// Read squeezes more output from the XOF. -+// -+// Any call to Write after a call to Read will panic. -+func (s *SHAKE) Read(p []byte) (n int, err error) { -+ if len(p) == 0 { -+ return 0, nil -+ } -+ defer runtime.KeepAlive(s) -+ for n < len(p) && err == nil { -+ nn := len32(p[n:]) -+ err = bcrypt.FinishHash(s.ctx, p[n:n+nn], bcrypt.HASH_DONT_RESET_FLAG) -+ n += nn -+ } -+ if err != nil { -+ panic(err) -+ } -+ return len(p), nil -+} -+ -+// Reset resets the XOF to its initial state. -+func (s *SHAKE) Reset() { -+ defer runtime.KeepAlive(s) -+ // SHAKE has a variable size, CNG doesn't change the size of the hash -+ // when resetting, so we can pass a small value here. -+ hashReset(s.ctx, 1) -+} -+ -+// BlockSize returns the rate of the XOF. -+func (s *SHAKE) BlockSize() int { -+ return int(s.blockSize) -+} 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..5a3fb01606ef95 @@ -10572,10 +13562,10 @@ index 00000000000000..5a3fb01606ef95 +} 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..7d34e6661d3086 +index 00000000000000..090c74a894e170 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/bcrypt_windows.go -@@ -0,0 +1,368 @@ +@@ -0,0 +1,359 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -10600,8 +13590,6 @@ index 00000000000000..7d34e6661d3086 + SHA3_256_ALGORITHM = "SHA3-256" + SHA3_384_ALGORITHM = "SHA3-384" + SHA3_512_ALGORITHM = "SHA3-512" -+ CSHAKE128_ALGORITHM = "CSHAKE128" -+ CSHAKE256_ALGORITHM = "CSHAKE256" + AES_ALGORITHM = "AES" + RC4_ALGORITHM = "RC4" + RSA_ALGORITHM = "RSA" @@ -10627,19 +13615,17 @@ index 00000000000000..7d34e6661d3086 +) + +const ( -+ HASH_LENGTH = "HashDigestLength" -+ HASH_BLOCK_LENGTH = "HashBlockLength" -+ CHAINING_MODE = "ChainingMode" -+ CHAIN_MODE_ECB = "ChainingModeECB" -+ CHAIN_MODE_CBC = "ChainingModeCBC" -+ CHAIN_MODE_GCM = "ChainingModeGCM" -+ KEY_LENGTH = "KeyLength" -+ KEY_LENGTHS = "KeyLengths" -+ SIGNATURE_LENGTH = "SignatureLength" -+ BLOCK_LENGTH = "BlockLength" -+ ECC_CURVE_NAME = "ECCCurveName" -+ FUNCTION_NAME_STRING = "FunctionNameString" -+ CUSTOMIZATION_STRING = "CustomizationString" ++ HASH_LENGTH = "HashDigestLength" ++ HASH_BLOCK_LENGTH = "HashBlockLength" ++ CHAINING_MODE = "ChainingMode" ++ CHAIN_MODE_ECB = "ChainingModeECB" ++ CHAIN_MODE_CBC = "ChainingModeCBC" ++ CHAIN_MODE_GCM = "ChainingModeGCM" ++ KEY_LENGTH = "KeyLength" ++ KEY_LENGTHS = "KeyLengths" ++ SIGNATURE_LENGTH = "SignatureLength" ++ BLOCK_LENGTH = "BlockLength" ++ ECC_CURVE_NAME = "ECCCurveName" +) + +const ( @@ -10696,11 +13682,6 @@ index 00000000000000..7d34e6661d3086 +) + +const ( -+ HASH_DONT_RESET_FLAG = 0x00000001 -+ HASH_REUSABLE_FLAG = 0x00000020 -+) -+ -+const ( + KDF_RAW_SECRET = "TRUNCATE" +) + @@ -10885,7 +13866,7 @@ index 00000000000000..7d34e6661d3086 + Count [4]uint8 +} + -+func Encrypt(hKey KEY_HANDLE, plaintext []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { ++func Encrypt(hKey KEY_HANDLE, plaintext []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { + var pInput *byte + if len(plaintext) > 0 { + pInput = &plaintext[0] @@ -10898,42 +13879,42 @@ index 00000000000000..7d34e6661d3086 + return _Encrypt(hKey, pInput, uint32(len(plaintext)), pPaddingInfo, pbIV, pbOutput, pcbResult, dwFlags) +} + -+//sys GetFipsAlgorithmMode(enabled *bool) (ntstatus error) = bcrypt.BCryptGetFipsAlgorithmMode -+//sys SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptSetProperty -+//sys GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGetProperty -+//sys OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (ntstatus error) = bcrypt.BCryptOpenAlgorithmProvider -+//sys CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (ntstatus error) = bcrypt.BCryptCloseAlgorithmProvider ++//sys GetFipsAlgorithmMode(enabled *bool) (s error) = bcrypt.BCryptGetFipsAlgorithmMode ++//sys SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (s error) = bcrypt.BCryptSetProperty ++//sys GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptGetProperty ++//sys OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (s error) = bcrypt.BCryptOpenAlgorithmProvider ++//sys CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (s error) = bcrypt.BCryptCloseAlgorithmProvider + +// SHA and HMAC + -+//sys Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (ntstatus error) = bcrypt.BCryptHash -+//sys CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptCreateHash -+//sys DestroyHash(hHash HASH_HANDLE) (ntstatus error) = bcrypt.BCryptDestroyHash -+//sys HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptHashData -+//sys HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptHashData -+//sys DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptDuplicateHash -+//sys FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptFinishHash ++//sys Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (s error) = bcrypt.BCryptHash ++//sys CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (s error) = bcrypt.BCryptCreateHash ++//sys DestroyHash(hHash HASH_HANDLE) (s error) = bcrypt.BCryptDestroyHash ++//sys HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (s error) = bcrypt.BCryptHashData ++//sys HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (s error) = bcrypt.BCryptHashData ++//sys DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (s error) = bcrypt.BCryptDuplicateHash ++//sys FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (s error) = bcrypt.BCryptFinishHash + +// Rand + -+//sys GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGenRandom ++//sys GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (s error) = bcrypt.BCryptGenRandom + +// Keys + -+//sys generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGenerateSymmetricKey -+//sys GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGenerateKeyPair -+//sys FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (ntstatus error) = bcrypt.BCryptFinalizeKeyPair -+//sys ImportKeyPair (hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptImportKeyPair -+//sys ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptExportKey -+//sys DestroyKey(hKey KEY_HANDLE) (ntstatus error) = bcrypt.BCryptDestroyKey -+//sys _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptEncrypt -+//sys Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptDecrypt -+//sys SignHash (hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptSignHash -+//sys VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptVerifySignature -+//sys SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (ntstatus error) = bcrypt.BCryptSecretAgreement -+//sys DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptDeriveKey -+//sys KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptKeyDerivation -+//sys DestroySecret(hSecret SECRET_HANDLE) (ntstatus error) = bcrypt.BCryptDestroySecret ++//sys generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (s error) = bcrypt.BCryptGenerateSymmetricKey ++//sys GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (s error) = bcrypt.BCryptGenerateKeyPair ++//sys FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (s error) = bcrypt.BCryptFinalizeKeyPair ++//sys ImportKeyPair (hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (s error) = bcrypt.BCryptImportKeyPair ++//sys ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptExportKey ++//sys DestroyKey(hKey KEY_HANDLE) (s error) = bcrypt.BCryptDestroyKey ++//sys _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) = bcrypt.BCryptEncrypt ++//sys Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) = bcrypt.BCryptDecrypt ++//sys SignHash (hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) = bcrypt.BCryptSignHash ++//sys VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (s error) = bcrypt.BCryptVerifySignature ++//sys SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (s error) = bcrypt.BCryptSecretAgreement ++//sys DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptDeriveKey ++//sys KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptKeyDerivation ++//sys DestroySecret(hSecret SECRET_HANDLE) (s error) = bcrypt.BCryptDestroySecret + +func GenerateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret []byte, dwFlags uint32) error { + cbLen := uint32(len(pbSecret)) @@ -10944,63 +13925,12 @@ index 00000000000000..7d34e6661d3086 + } + return generateSymmetricKey(hAlgorithm, phKey, pbKeyObject, &pbSecret[0], cbLen, dwFlags) +} -diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/ntstatus_windows.go b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/ntstatus_windows.go -new file mode 100644 -index 00000000000000..ec2eb01aa3cd8a ---- /dev/null -+++ b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/ntstatus_windows.go -@@ -0,0 +1,45 @@ -+// Copyright (c) Microsoft Corporation. -+// Licensed under the MIT License. -+ -+package bcrypt -+ -+import ( -+ "strconv" -+ "syscall" -+ "unicode/utf16" -+) -+ -+const ( -+ FORMAT_MESSAGE_FROM_HMODULE = 2048 -+ FORMAT_MESSAGE_FROM_SYSTEM = 4096 -+ FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192 -+ -+ LANG_ENGLISH = 0x09 -+ SUBLANG_ENGLISH_US = 0x01 -+) -+ -+type NTStatus uint32 -+ -+func (s NTStatus) Errno() syscall.Errno { -+ return rtlNtStatusToDosErrorNoTeb(s) -+} -+ -+func langID(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) } -+ -+func (s NTStatus) Error() string { -+ b := make([]uint16, 300) -+ n, err := formatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ARGUMENT_ARRAY, modntdll.Handle(), uint32(s), langID(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil) -+ if err != nil { -+ return "NTSTATUS 0x" + strconv.FormatUint(uint64(s), 16) -+ } -+ // trim terminating \r and \n -+ for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { -+ } -+ return string(utf16.Decode(b[:n])) -+} -+ -+// NT Native APIs -+//sys rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb -+ -+// windows api calls -+//sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/zsyscall_windows.go b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/zsyscall_windows.go new file mode 100644 -index 00000000000000..5d049f025b0301 +index 00000000000000..3c6a5764eb92ec --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/zsyscall_windows.go -@@ -0,0 +1,412 @@ +@@ -0,0 +1,389 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package bcrypt @@ -11040,9 +13970,7 @@ index 00000000000000..5d049f025b0301 +} + +var ( -+ modbcrypt = syscall.NewLazyDLL(sysdll.Add("bcrypt.dll")) -+ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) -+ modntdll = syscall.NewLazyDLL(sysdll.Add("ntdll.dll")) ++ modbcrypt = syscall.NewLazyDLL(sysdll.Add("bcrypt.dll")) + + procBCryptCloseAlgorithmProvider = modbcrypt.NewProc("BCryptCloseAlgorithmProvider") + procBCryptCreateHash = modbcrypt.NewProc("BCryptCreateHash") @@ -11070,19 +13998,17 @@ index 00000000000000..5d049f025b0301 + procBCryptSetProperty = modbcrypt.NewProc("BCryptSetProperty") + procBCryptSignHash = modbcrypt.NewProc("BCryptSignHash") + procBCryptVerifySignature = modbcrypt.NewProc("BCryptVerifySignature") -+ procFormatMessageW = modkernel32.NewProc("FormatMessageW") -+ procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") +) + -+func CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (ntstatus error) { ++func CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (s error) { + r0, _, _ := syscall.Syscall(procBCryptCloseAlgorithmProvider.Addr(), 2, uintptr(hAlgorithm), uintptr(dwFlags), 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (ntstatus error) { ++func CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbHashObject) > 0 { + _p0 = &pbHashObject[0] @@ -11093,12 +14019,12 @@ index 00000000000000..5d049f025b0301 + } + r0, _, _ := syscall.Syscall9(procBCryptCreateHash.Addr(), 7, uintptr(hAlgorithm), uintptr(unsafe.Pointer(phHash)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbHashObject)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbSecret)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { ++func Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] @@ -11113,60 +14039,60 @@ index 00000000000000..5d049f025b0301 + } + r0, _, _ := syscall.Syscall12(procBCryptDecrypt.Addr(), 10, uintptr(hKey), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbIV)), uintptr(unsafe.Pointer(_p2)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { ++func DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbDerivedKey) > 0 { + _p0 = &pbDerivedKey[0] + } + r0, _, _ := syscall.Syscall9(procBCryptDeriveKey.Addr(), 7, uintptr(hSharedSecret), uintptr(unsafe.Pointer(pwszKDF)), uintptr(unsafe.Pointer(pParameterList)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbDerivedKey)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func DestroyHash(hHash HASH_HANDLE) (ntstatus error) { ++func DestroyHash(hHash HASH_HANDLE) (s error) { + r0, _, _ := syscall.Syscall(procBCryptDestroyHash.Addr(), 1, uintptr(hHash), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func DestroyKey(hKey KEY_HANDLE) (ntstatus error) { ++func DestroyKey(hKey KEY_HANDLE) (s error) { + r0, _, _ := syscall.Syscall(procBCryptDestroyKey.Addr(), 1, uintptr(hKey), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func DestroySecret(hSecret SECRET_HANDLE) (ntstatus error) { ++func DestroySecret(hSecret SECRET_HANDLE) (s error) { + r0, _, _ := syscall.Syscall(procBCryptDestroySecret.Addr(), 1, uintptr(hSecret), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (ntstatus error) { ++func DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbHashObject) > 0 { + _p0 = &pbHashObject[0] + } + r0, _, _ := syscall.Syscall6(procBCryptDuplicateHash.Addr(), 5, uintptr(hHash), uintptr(unsafe.Pointer(phNewHash)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbHashObject)), uintptr(dwFlags), 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { ++func _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { + var _p0 *byte + if len(pbIV) > 0 { + _p0 = &pbIV[0] @@ -11177,76 +14103,76 @@ index 00000000000000..5d049f025b0301 + } + r0, _, _ := syscall.Syscall12(procBCryptEncrypt.Addr(), 10, uintptr(hKey), uintptr(unsafe.Pointer(pbInput)), uintptr(cbInput), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbIV)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { ++func ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbOutput) > 0 { + _p0 = &pbOutput[0] + } + r0, _, _ := syscall.Syscall9(procBCryptExportKey.Addr(), 7, uintptr(hKey), uintptr(hExportKey), uintptr(unsafe.Pointer(pszBlobType)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (ntstatus error) { ++func FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (s error) { + r0, _, _ := syscall.Syscall(procBCryptFinalizeKeyPair.Addr(), 2, uintptr(hKey), uintptr(dwFlags), 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (ntstatus error) { ++func FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbOutput) > 0 { + _p0 = &pbOutput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptFinishHash.Addr(), 4, uintptr(hHash), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbOutput)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (ntstatus error) { ++func GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbBuffer) > 0 { + _p0 = &pbBuffer[0] + } + r0, _, _ := syscall.Syscall6(procBCryptGenRandom.Addr(), 4, uintptr(hAlgorithm), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbBuffer)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (ntstatus error) { ++func GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (s error) { + r0, _, _ := syscall.Syscall6(procBCryptGenerateKeyPair.Addr(), 4, uintptr(hAlgorithm), uintptr(unsafe.Pointer(phKey)), uintptr(dwLength), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (ntstatus error) { ++func generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbKeyObject) > 0 { + _p0 = &pbKeyObject[0] + } + r0, _, _ := syscall.Syscall9(procBCryptGenerateSymmetricKey.Addr(), 7, uintptr(hAlgorithm), uintptr(unsafe.Pointer(phKey)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbKeyObject)), uintptr(unsafe.Pointer(pbSecret)), uintptr(cbSecret), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func GetFipsAlgorithmMode(enabled *bool) (ntstatus error) { ++func GetFipsAlgorithmMode(enabled *bool) (s error) { + var _p0 uint32 + if *enabled { + _p0 = 1 @@ -11254,24 +14180,24 @@ index 00000000000000..5d049f025b0301 + r0, _, _ := syscall.Syscall(procBCryptGetFipsAlgorithmMode.Addr(), 1, uintptr(unsafe.Pointer(&_p0)), 0, 0) + *enabled = _p0 != 0 + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { ++func GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbOutput) > 0 { + _p0 = &pbOutput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptGetProperty.Addr(), 6, uintptr(hObject), uintptr(unsafe.Pointer(pszProperty)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags)) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (ntstatus error) { ++func Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (s error) { + var _p0 *byte + if len(pbSecret) > 0 { + _p0 = &pbSecret[0] @@ -11286,84 +14212,84 @@ index 00000000000000..5d049f025b0301 + } + r0, _, _ := syscall.Syscall9(procBCryptHash.Addr(), 7, uintptr(hAlgorithm), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbSecret)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbInput)), uintptr(unsafe.Pointer(_p2)), uintptr(len(pbOutput)), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (ntstatus error) { ++func HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (s error) { + r0, _, _ := syscall.Syscall6(procBCryptHashData.Addr(), 4, uintptr(hHash), uintptr(unsafe.Pointer(pbInput)), uintptr(cbInput), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) { ++func HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptHashData.Addr(), 4, uintptr(hHash), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func ImportKeyPair(hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) { ++func ImportKeyPair(hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] + } + r0, _, _ := syscall.Syscall9(procBCryptImportKeyPair.Addr(), 7, uintptr(hAlgorithm), uintptr(hImportKey), uintptr(unsafe.Pointer(pszBlobType)), uintptr(unsafe.Pointer(phKey)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { ++func KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbDerivedKey) > 0 { + _p0 = &pbDerivedKey[0] + } + r0, _, _ := syscall.Syscall6(procBCryptKeyDerivation.Addr(), 6, uintptr(hKey), uintptr(unsafe.Pointer(pParameterList)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbDerivedKey)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags)) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (ntstatus error) { ++func OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (s error) { + r0, _, _ := syscall.Syscall6(procBCryptOpenAlgorithmProvider.Addr(), 4, uintptr(unsafe.Pointer(phAlgorithm)), uintptr(unsafe.Pointer(pszAlgId)), uintptr(unsafe.Pointer(pszImplementation)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (ntstatus error) { ++func SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (s error) { + r0, _, _ := syscall.Syscall6(procBCryptSecretAgreement.Addr(), 4, uintptr(hPrivKey), uintptr(hPubKey), uintptr(unsafe.Pointer(phAgreedSecret)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (ntstatus error) { ++func SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (s error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptSetProperty.Addr(), 5, uintptr(hObject), uintptr(unsafe.Pointer(pszProperty)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(dwFlags), 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func SignHash(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { ++func SignHash(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] @@ -11374,12 +14300,12 @@ index 00000000000000..5d049f025b0301 + } + r0, _, _ := syscall.Syscall9(procBCryptSignHash.Addr(), 8, uintptr(hKey), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) ++ s = syscall.Errno(r0) + } + return +} + -+func VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (ntstatus error) { ++func VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (s error) { + var _p0 *byte + if len(pbHash) > 0 { + _p0 = &pbHash[0] @@ -11390,29 +14316,10 @@ index 00000000000000..5d049f025b0301 + } + r0, _, _ := syscall.Syscall9(procBCryptVerifySignature.Addr(), 7, uintptr(hKey), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbHash)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbSignature)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ ntstatus = NTStatus(r0) -+ } -+ return -+} -+ -+func formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { -+ var _p0 *uint16 -+ if len(buf) > 0 { -+ _p0 = &buf[0] -+ } -+ r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) -+ n = uint32(r0) -+ if n == 0 { -+ err = errnoErr(e1) ++ s = syscall.Errno(r0) + } + return +} -+ -+func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) { -+ r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(ntstatus), 0, 0) -+ ret = syscall.Errno(r0) -+ return -+} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/internal/subtle/aliasing.go b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/subtle/aliasing.go new file mode 100644 index 00000000000000..db09e4aae64f8c @@ -11513,15 +14420,20 @@ index 00000000000000..1722410e5af193 + return getSystemDirectory() + "\\" + dll +} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index 1c8de570cc2f1f..5b05c5eed355ca 100644 +index 1c8de570cc2f1f..f9257989b097b5 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt -@@ -1,3 +1,14 @@ -+# github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 +@@ -1,3 +1,19 @@ ++# github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf +## explicit; go 1.22 +github.com/golang-fips/openssl/v2 +github.com/golang-fips/openssl/v2/bbig -+# github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 ++# github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 ++## explicit; go 1.22 ++github.com/microsoft/go-crypto-darwin/bbig ++github.com/microsoft/go-crypto-darwin/internal/cryptokit ++github.com/microsoft/go-crypto-darwin/xcrypto ++# github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 +## explicit; go 1.22 +github.com/microsoft/go-crypto-winnative/cng +github.com/microsoft/go-crypto-winnative/cng/bbig From 2e0d3da86c90086eb77ddb2390ee7c448a62e607 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Wed, 8 Jan 2025 09:49:39 -0800 Subject: [PATCH 3/8] Also unassign GOROOT in run-builder --- eng/_util/buildutil/buildutil.go | 16 ++++++++++++++++ eng/_util/cmd/build/build.go | 11 ++--------- eng/_util/cmd/run-builder/run-builder.go | 4 ++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/eng/_util/buildutil/buildutil.go b/eng/_util/buildutil/buildutil.go index d8e705415af..6177f2f601d 100644 --- a/eng/_util/buildutil/buildutil.go +++ b/eng/_util/buildutil/buildutil.go @@ -104,3 +104,19 @@ func AppendExperimentEnv(experiment string) { panic(err) } } + +// UnassignGOROOT unsets the GOROOT env var if it is set. +// +// Setting GOROOT explicitly in the environment has not been necessary since Go +// 1.9 (https://go.dev/doc/go1.9#goroot), but a dev or build machine may still +// have it set. It interferes with attempts to run the built Go (such as when +// building the race runtime), so remove the explicit GOROOT if set. +func UnassignGOROOT() error { + if explicitRoot, ok := os.LookupEnv("GOROOT"); ok { + fmt.Printf("---- Removing explicit GOROOT from environment: %v\n", explicitRoot) + if err := os.Unsetenv("GOROOT"); err != nil { + return err + } + } + return nil +} diff --git a/eng/_util/cmd/build/build.go b/eng/_util/cmd/build/build.go index e87ab876093..e0d0ec0e626 100644 --- a/eng/_util/cmd/build/build.go +++ b/eng/_util/cmd/build/build.go @@ -138,15 +138,8 @@ func build(o *options) error { } fmt.Printf("---- Target platform: %v_%v\n", targetOS, targetArch) - // Setting GOROOT explicitly in the environment has not been necessary since Go 1.9 - // (https://go.dev/doc/go1.9#goroot), but a dev or build machine may still have it set. It - // interferes with attempts to run the built Go (such as when building the race runtime), so - // remove the explicit GOROOT if set. - if explicitRoot, ok := os.LookupEnv("GOROOT"); ok { - fmt.Printf("---- Removing explicit GOROOT from environment: %v\n", explicitRoot) - if err := os.Unsetenv("GOROOT"); err != nil { - return err - } + if err := buildutil.UnassignGOROOT(); err != nil { + return err } // The upstream build scripts in {repo-root}/src require your working directory to be src, or diff --git a/eng/_util/cmd/run-builder/run-builder.go b/eng/_util/cmd/run-builder/run-builder.go index a256693ae5d..6e5c542bc0d 100644 --- a/eng/_util/cmd/run-builder/run-builder.go +++ b/eng/_util/cmd/run-builder/run-builder.go @@ -105,6 +105,10 @@ func main() { env("GO_TEST_TIMEOUT_SCALE", strconv.Itoa(timeoutScale)) } + if err := buildutil.UnassignGOROOT(); err != nil { + log.Fatal(err) + } + buildCmdline := []string{"pwsh", "eng/run.ps1", "build"} // run.ps1 compiles Go code, so we can't use the experiment yet. We must pass the experiment From 3fd8fb20c0ba000d74cbf296a8359f299ccac34b Mon Sep 17 00:00:00 2001 From: George Adams Date: Wed, 8 Jan 2025 19:43:02 +0000 Subject: [PATCH 4/8] fix patches --- patches/0006-Add-Darwin-crypto-backend.patch | 92 ++- patches/0007-Vendor-crypto-backends.patch | 795 ++++++++++++++----- 2 files changed, 673 insertions(+), 214 deletions(-) diff --git a/patches/0006-Add-Darwin-crypto-backend.patch b/patches/0006-Add-Darwin-crypto-backend.patch index 49bc4c58e6e..ff0e7f3ff47 100644 --- a/patches/0006-Add-Darwin-crypto-backend.patch +++ b/patches/0006-Add-Darwin-crypto-backend.patch @@ -4,6 +4,9 @@ Date: Tue, 17 Dec 2024 13:17:39 +0000 Subject: [PATCH] Add Darwin crypto backend --- + .gitignore | 2 + + src/cmd/go/go_boring_test.go | 9 +- + src/cmd/go/testdata/script/darwin_no_cgo.txt | 2 + src/crypto/ecdsa/ecdsa.go | 6 +- src/crypto/ed25519/ed25519_test.go | 3 +- .../internal/backend/bbig/big_darwin.go | 12 + @@ -21,7 +24,8 @@ Subject: [PATCH] Add Darwin crypto backend .../goexperiment/exp_darwincrypto_off.go | 9 + .../goexperiment/exp_darwincrypto_on.go | 9 + src/internal/goexperiment/flags.go | 1 + - 17 files changed, 502 insertions(+), 13 deletions(-) + src/runtime/pprof/vminfo_darwin_test.go | 6 + + 21 files changed, 520 insertions(+), 14 deletions(-) create mode 100644 src/crypto/internal/backend/bbig/big_darwin.go create mode 100644 src/crypto/internal/backend/darwin_darwin.go create mode 100644 src/crypto/internal/backend/fips140/darwin.go @@ -29,11 +33,59 @@ Subject: [PATCH] Add Darwin crypto backend create mode 100644 src/internal/goexperiment/exp_darwincrypto_off.go create mode 100644 src/internal/goexperiment/exp_darwincrypto_on.go +diff --git a/.gitignore b/.gitignore +index c6512e64a4ef39..b3b01db73b009d 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -46,6 +46,8 @@ _testmain.go + /test/run.out + /test/times.out + ++!/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/CryptoKit.o ++ + # This file includes artifacts of Go build that should not be checked in. + # For files created by specific development environment (e.g. editor), + # use alternative ways to exclude files from git. +diff --git a/src/cmd/go/go_boring_test.go b/src/cmd/go/go_boring_test.go +index 06478963f4be44..8111b143a1295b 100644 +--- a/src/cmd/go/go_boring_test.go ++++ b/src/cmd/go/go_boring_test.go +@@ -6,9 +6,16 @@ + + package main_test + +-import "testing" ++import ( ++ "internal/goexperiment" ++ "testing" ++) + + func TestBoringInternalLink(t *testing.T) { ++ if goexperiment.DarwinCrypto { ++ // https://github.com/microsoft/go-crypto-darwin/issues/33 ++ t.Skip("skipping on Darwin") ++ } + tg := testgo(t) + defer tg.cleanup() + tg.parallel() +diff --git a/src/cmd/go/testdata/script/darwin_no_cgo.txt b/src/cmd/go/testdata/script/darwin_no_cgo.txt +index fa445925b7c374..e36ac86fcaa58d 100644 +--- a/src/cmd/go/testdata/script/darwin_no_cgo.txt ++++ b/src/cmd/go/testdata/script/darwin_no_cgo.txt +@@ -4,6 +4,8 @@ + # of cmd/go, which imports approximately everything + # in std (certainly everything relevant). + [!GOOS:darwin] skip ++[GOEXPERIMENT:darwincrypto] skip ++[GOEXPERIMENT:systemcrypto] skip + go list -deps cmd/go + ! stdout runtime/cgo + diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go -index 41ac17df22d7d7..84a7ba02c88620 100644 +index 049da55bd70f2c..cd075f0efbc744 100644 --- a/src/crypto/ecdsa/ecdsa.go +++ b/src/crypto/ecdsa/ecdsa.go -@@ -159,7 +159,7 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp +@@ -161,7 +161,7 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) { randutil.MaybeReadByte(rand) @@ -42,7 +94,7 @@ index 41ac17df22d7d7..84a7ba02c88620 100644 x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name) if err != nil { return nil, err -@@ -208,7 +208,7 @@ var errNoAsm = errors.New("no assembly implementation available") +@@ -210,7 +210,7 @@ var errNoAsm = errors.New("no assembly implementation available") func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { randutil.MaybeReadByte(rand) @@ -51,7 +103,7 @@ index 41ac17df22d7d7..84a7ba02c88620 100644 b, err := boringPrivateKey(priv) if err != nil { return nil, err -@@ -319,7 +319,7 @@ func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) { +@@ -321,7 +321,7 @@ func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) { // The inputs are not considered confidential, and may leak through timing side // channels, or if an attacker has control of part of the inputs. func VerifyASN1(pub *PublicKey, hash, sig []byte) bool { @@ -688,7 +740,7 @@ index 7d7115cff81cea..d3ba67fe4d0611 100644 } default: diff --git a/src/go.mod b/src/go.mod -index 897c3802237b4e..0119f5ce8fe623 100644 +index 96bdcd421e1129..f6d6bee65d0cd5 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,6 +4,7 @@ go 1.24 @@ -700,7 +752,7 @@ index 897c3802237b4e..0119f5ce8fe623 100644 golang.org/x/crypto v0.30.0 golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 diff --git a/src/go.sum b/src/go.sum -index 7cece574a42291..6050c2fe0c5081 100644 +index abebb59dcd7739..61b84a86e0e66c 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,5 +1,7 @@ @@ -712,7 +764,7 @@ index 7cece574a42291..6050c2fe0c5081 100644 github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go -index 1fcadbf6c19d79..b0da426bf18177 100644 +index 997244c84e57c5..4b0585fe1bea25 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -519,6 +519,8 @@ var depsRules = ` @@ -795,3 +847,27 @@ index c6f64c18bdd13f..e6c9b7d5e62dc0 100644 // SystemCrypto enables the OpenSSL, CNG or Darwin crypto experiment depending on // which one is appropriate on the target GOOS. +diff --git a/src/runtime/pprof/vminfo_darwin_test.go b/src/runtime/pprof/vminfo_darwin_test.go +index 6d375c5d53368a..39154b000ddc67 100644 +--- a/src/runtime/pprof/vminfo_darwin_test.go ++++ b/src/runtime/pprof/vminfo_darwin_test.go +@@ -11,6 +11,7 @@ import ( + "bytes" + "fmt" + "internal/abi" ++ "internal/goexperiment" + "internal/testenv" + "os" + "os/exec" +@@ -21,6 +22,11 @@ import ( + ) + + func TestVMInfo(t *testing.T) { ++ if goexperiment.DarwinCrypto { ++ // Fails on macOS when using system crypto. ++ // https://github.com/microsoft/go/issues/1466 ++ t.Skip("skipping on Darwin") ++ } + var begin, end, offset uint64 + var filename string + first := true diff --git a/patches/0007-Vendor-crypto-backends.patch b/patches/0007-Vendor-crypto-backends.patch index 7cc65ab1998..e922fabef15 100644 --- a/patches/0007-Vendor-crypto-backends.patch +++ b/patches/0007-Vendor-crypto-backends.patch @@ -79,7 +79,7 @@ To reproduce, run 'go mod vendor' in 'go/src'. .../microsoft/go-crypto-winnative/cng/dsa.go | 465 ++++++++ .../microsoft/go-crypto-winnative/cng/ecdh.go | 255 ++++ .../go-crypto-winnative/cng/ecdsa.go | 169 +++ - .../microsoft/go-crypto-winnative/cng/hash.go | 306 +++++ + .../microsoft/go-crypto-winnative/cng/hash.go | 312 +++++ .../microsoft/go-crypto-winnative/cng/hkdf.go | 124 ++ .../microsoft/go-crypto-winnative/cng/hmac.go | 35 + .../microsoft/go-crypto-winnative/cng/keys.go | 220 ++++ @@ -87,13 +87,15 @@ To reproduce, run 'go mod vendor' in 'go/src'. .../microsoft/go-crypto-winnative/cng/rand.go | 28 + .../microsoft/go-crypto-winnative/cng/rc4.go | 65 + .../microsoft/go-crypto-winnative/cng/rsa.go | 396 +++++++ + .../microsoft/go-crypto-winnative/cng/sha3.go | 284 +++++ .../go-crypto-winnative/cng/tls1prf.go | 88 ++ - .../internal/bcrypt/bcrypt_windows.go | 359 ++++++ - .../internal/bcrypt/zsyscall_windows.go | 389 ++++++ + .../internal/bcrypt/bcrypt_windows.go | 368 ++++++ + .../internal/bcrypt/ntstatus_windows.go | 45 + + .../internal/bcrypt/zsyscall_windows.go | 412 +++++++ .../internal/subtle/aliasing.go | 32 + .../internal/sysdll/sys_windows.go | 55 + src/vendor/modules.txt | 16 + - 88 files changed, 13728 insertions(+) + 90 files changed, 14095 insertions(+) create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitignore 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 @@ -176,8 +178,10 @@ To reproduce, run 'go mod vendor' in 'go/src'. 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/rc4.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/sha3.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/ntstatus_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 create mode 100644 src/vendor/github.com/microsoft/go-crypto-winnative/internal/sysdll/sys_windows.go @@ -12176,10 +12180,10 @@ index 00000000000000..586e9ae2ebb0c9 +} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go new file mode 100644 -index 00000000000000..87b1c95dc7f911 +index 00000000000000..a674496f18a3af --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go -@@ -0,0 +1,306 @@ +@@ -0,0 +1,312 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -12198,6 +12202,9 @@ index 00000000000000..87b1c95dc7f911 + "github.com/microsoft/go-crypto-winnative/internal/bcrypt" +) + ++// maxHashSize is the size of SHA512 and SHA3_512, the largest hashes we support. ++const maxHashSize = 64 ++ +// SupportsHash returns true if a hash.Hash implementation is supported for h. +func SupportsHash(h crypto.Hash) bool { + switch h { @@ -12266,27 +12273,6 @@ index 00000000000000..87b1c95dc7f911 + return +} + -+func SHA3_256(p []byte) (sum [32]byte) { -+ if err := hashOneShot(bcrypt.SHA3_256_ALGORITHM, p, sum[:]); err != nil { -+ panic("bcrypt: SHA3_256 failed") -+ } -+ return -+} -+ -+func SHA3_384(p []byte) (sum [48]byte) { -+ if err := hashOneShot(bcrypt.SHA3_384_ALGORITHM, p, sum[:]); err != nil { -+ panic("bcrypt: SHA3_384 failed") -+ } -+ return -+} -+ -+func SHA3_512(p []byte) (sum [64]byte) { -+ if err := hashOneShot(bcrypt.SHA3_512_ALGORITHM, p, sum[:]); err != nil { -+ panic("bcrypt: SHA3_512 failed") -+ } -+ return -+} -+ +// NewMD4 returns a new MD4 hash. +func NewMD4() hash.Hash { + return newHashX(bcrypt.MD4_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) @@ -12317,21 +12303,6 @@ index 00000000000000..87b1c95dc7f911 + return newHashX(bcrypt.SHA512_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) +} + -+// NewSHA3_256 returns a new SHA256 hash. -+func NewSHA3_256() hash.Hash { -+ return newHashX(bcrypt.SHA3_256_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) -+} -+ -+// NewSHA3_384 returns a new SHA384 hash. -+func NewSHA3_384() hash.Hash { -+ return newHashX(bcrypt.SHA3_384_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) -+} -+ -+// NewSHA3_512 returns a new SHA512 hash. -+func NewSHA3_512() hash.Hash { -+ return newHashX(bcrypt.SHA3_512_ALGORITHM, bcrypt.ALG_NONE_FLAG, nil) -+} -+ +type hashAlgorithm struct { + handle bcrypt.ALG_HANDLE + id string @@ -12363,11 +12334,24 @@ index 00000000000000..87b1c95dc7f911 + return hx.alg.id +} + ++// cloneHash is an interface that defines a Clone method. ++// ++// hash.CloneHash will probably be added in Go 1.25, see https://golang.org/issue/69521, ++// but we need it now. ++type cloneHash interface { ++ hash.Hash ++ // Clone returns a separate Hash instance with the same state as h. ++ Clone() hash.Hash ++} ++ ++var _ hash.Hash = (*hashX)(nil) ++var _ cloneHash = (*hashX)(nil) ++ ++// hashX implements [hash.Hash]. +type hashX struct { -+ alg *hashAlgorithm -+ _ctx bcrypt.HASH_HANDLE // access it using withCtx ++ alg *hashAlgorithm ++ ctx bcrypt.HASH_HANDLE + -+ buf []byte + key []byte +} + @@ -12378,88 +12362,72 @@ index 00000000000000..87b1c95dc7f911 + panic(err) + } + h := &hashX{alg: alg, key: bytes.Clone(key)} -+ // Don't allocate hx.buf nor call bcrypt.CreateHash yet, -+ // which would be wasteful if the caller only wants to know -+ // the hash type. This is a common pattern in this package, -+ // as some functions accept a `func() hash.Hash` parameter -+ // and call it just to know the hash type. -+ runtime.SetFinalizer(h, (*hashX).finalize) ++ // Don't call bcrypt.CreateHash yet, it would be wasteful ++ // if the caller only wants to know the hash type. This ++ // is a common pattern in this package, as some functions ++ // accept a `func() hash.Hash` parameter and call it just ++ // to know the hash type. + return h +} + +func (h *hashX) finalize() { -+ if h._ctx != 0 { -+ bcrypt.DestroyHash(h._ctx) -+ } ++ bcrypt.DestroyHash(h.ctx) +} + -+func (h *hashX) withCtx(fn func(ctx bcrypt.HASH_HANDLE) error) error { ++func (h *hashX) init() { + defer runtime.KeepAlive(h) -+ if h._ctx == 0 { -+ err := bcrypt.CreateHash(h.alg.handle, &h._ctx, nil, h.key, 0) -+ if err != nil { -+ panic(err) -+ } ++ if h.ctx != 0 { ++ return + } -+ return fn(h._ctx) ++ err := bcrypt.CreateHash(h.alg.handle, &h.ctx, nil, h.key, bcrypt.HASH_REUSABLE_FLAG) ++ if err != nil { ++ panic(err) ++ } ++ runtime.SetFinalizer(h, (*hashX).finalize) +} + -+func (h *hashX) Clone() (hash.Hash, error) { ++func (h *hashX) Clone() hash.Hash { ++ defer runtime.KeepAlive(h) + h2 := &hashX{alg: h.alg, key: bytes.Clone(h.key)} -+ err := h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { -+ return bcrypt.DuplicateHash(ctx, &h2._ctx, nil, 0) -+ }) -+ if err != nil { -+ return nil, err ++ if h.ctx != 0 { ++ hashClone(h.ctx, &h2.ctx) ++ runtime.SetFinalizer(h2, (*hashX).finalize) + } -+ runtime.SetFinalizer(h2, (*hashX).finalize) -+ return h2, nil ++ return h2 +} + +func (h *hashX) Reset() { -+ if h._ctx != 0 { -+ bcrypt.DestroyHash(h._ctx) -+ h._ctx = 0 ++ defer runtime.KeepAlive(h) ++ if h.ctx != 0 { ++ hashReset(h.ctx, h.Size()) + } +} + +func (h *hashX) Write(p []byte) (n int, err error) { -+ err = h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { -+ for n < len(p) && err == nil { -+ nn := len32(p[n:]) -+ err = bcrypt.HashData(h._ctx, p[n:n+nn], 0) -+ n += nn -+ } -+ return err -+ }) -+ if err != nil { -+ // hash.Hash interface mandates Write should never return an error. -+ panic(err) -+ } ++ defer runtime.KeepAlive(h) ++ h.init() ++ hashData(h.ctx, p) + return len(p), nil +} + +func (h *hashX) WriteString(s string) (int, error) { -+ // TODO: use unsafe.StringData once we drop support -+ // for go1.19 and earlier. -+ hdr := (*struct { -+ Data *byte -+ Len int -+ })(unsafe.Pointer(&s)) -+ return h.Write(unsafe.Slice(hdr.Data, len(s))) ++ defer runtime.KeepAlive(h) ++ return h.Write(unsafe.Slice(unsafe.StringData(s), len(s))) +} + +func (h *hashX) WriteByte(c byte) error { -+ err := h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { -+ return bcrypt.HashDataRaw(h._ctx, &c, 1, 0) -+ }) -+ if err != nil { -+ // hash.Hash interface mandates Write should never return an error. -+ panic(err) -+ } ++ defer runtime.KeepAlive(h) ++ h.init() ++ hashByte(h.ctx, c) + return nil +} + ++func (h *hashX) Sum(in []byte) []byte { ++ defer runtime.KeepAlive(h) ++ h.init() ++ return hashSum(h.ctx, h.Size(), in) ++} ++ +func (h *hashX) Size() int { + return int(h.alg.size) +} @@ -12468,23 +12436,65 @@ index 00000000000000..87b1c95dc7f911 + return int(h.alg.blockSize) +} + -+func (h *hashX) Sum(in []byte) []byte { ++// hashData writes p to ctx. It panics on error. ++func hashData(ctx bcrypt.HASH_HANDLE, p []byte) { ++ var n int ++ var err error ++ for n < len(p) && err == nil { ++ nn := len32(p[n:]) ++ err = bcrypt.HashData(ctx, p[n:n+nn], 0) ++ n += nn ++ } ++ if err != nil { ++ panic(err) ++ } ++} ++ ++// hashByte writes c to ctx. It panics on error. ++func hashByte(ctx bcrypt.HASH_HANDLE, c byte) { ++ err := bcrypt.HashDataRaw(ctx, &c, 1, 0) ++ if err != nil { ++ panic(err) ++ } ++} ++ ++// hashSum writes the hash of ctx to in and returns the result. ++// size is the size of the hash output. ++// It panics on error. ++func hashSum(ctx bcrypt.HASH_HANDLE, size int, in []byte) []byte { + var ctx2 bcrypt.HASH_HANDLE -+ err := h.withCtx(func(ctx bcrypt.HASH_HANDLE) error { -+ return bcrypt.DuplicateHash(ctx, &ctx2, nil, 0) -+ }) ++ err := bcrypt.DuplicateHash(ctx, &ctx2, nil, 0) + if err != nil { + panic(err) + } + defer bcrypt.DestroyHash(ctx2) -+ if h.buf == nil { -+ h.buf = make([]byte, h.alg.size) ++ buf := make([]byte, size, maxHashSize) // explicit cap to allow stack allocation ++ err = bcrypt.FinishHash(ctx2, buf, 0) ++ if err != nil { ++ panic(err) ++ } ++ return append(in, buf...) ++} ++ ++// hashReset resets the hash state of ctx. ++// size is the size of the hash output. ++// It panics on error. ++func hashReset(ctx bcrypt.HASH_HANDLE, size int) { ++ // bcrypt.FinishHash expects the output buffer to match the hash size. ++ // We don't care about the output, so we just pass a stack-allocated buffer ++ // that is large enough to hold the largest hash size we support. ++ var discard [maxHashSize]byte ++ if err := bcrypt.FinishHash(ctx, discard[:size], 0); err != nil { ++ panic(err) + } -+ err = bcrypt.FinishHash(ctx2, h.buf, 0) ++} ++ ++// hashClone clones ctx into ctx2. It panics on error. ++func hashClone(ctx bcrypt.HASH_HANDLE, ctx2 *bcrypt.HASH_HANDLE) { ++ err := bcrypt.DuplicateHash(ctx, ctx2, nil, 0) + if err != nil { + panic(err) + } -+ return append(in, h.buf...) +} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hkdf.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hkdf.go new file mode 100644 @@ -13466,6 +13476,296 @@ index 00000000000000..0269f9cf86539e + } + return "" +} +diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/sha3.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/sha3.go +new file mode 100644 +index 00000000000000..d7aa193e00e653 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/sha3.go +@@ -0,0 +1,284 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build windows ++// +build windows ++ ++package cng ++ ++import ( ++ "hash" ++ "runtime" ++ "unsafe" ++ ++ "github.com/microsoft/go-crypto-winnative/internal/bcrypt" ++) ++ ++// SumSHA3_256 returns the SHA3-256 checksum of the data. ++func SumSHA3_256(p []byte) (sum [32]byte) { ++ if err := hashOneShot(bcrypt.SHA3_256_ALGORITHM, p, sum[:]); err != nil { ++ panic("bcrypt: SHA3_256 failed") ++ } ++ return ++} ++ ++// SumSHA3_384 returns the SHA3-384 checksum of the data. ++func SumSHA3_384(p []byte) (sum [48]byte) { ++ if err := hashOneShot(bcrypt.SHA3_384_ALGORITHM, p, sum[:]); err != nil { ++ panic("bcrypt: SHA3_384 failed") ++ } ++ return ++} ++ ++// SumSHA3_512 returns the SHA3-512 checksum of the data. ++func SumSHA3_512(p []byte) (sum [64]byte) { ++ if err := hashOneShot(bcrypt.SHA3_512_ALGORITHM, p, sum[:]); err != nil { ++ panic("bcrypt: SHA3_512 failed") ++ } ++ return ++} ++ ++// SumSHAKE128 applies the SHAKE128 extendable output function to data and ++// returns an output of the given length in bytes. ++func SumSHAKE128(data []byte, length int) []byte { ++ out := make([]byte, length) ++ if err := hashOneShot(bcrypt.CSHAKE128_ALGORITHM, data, out); err != nil { ++ panic("bcrypt: CSHAKE128_ALGORITHM failed") ++ } ++ return out ++} ++ ++// SumSHAKE256 applies the SHAKE256 extendable output function to data and ++// returns an output of the given length in bytes. ++func SumSHAKE256(data []byte, length int) []byte { ++ out := make([]byte, length) ++ if err := hashOneShot(bcrypt.CSHAKE256_ALGORITHM, data, out); err != nil { ++ panic("bcrypt: CSHAKE256_ALGORITHM failed") ++ } ++ return out ++} ++ ++// SupportsSHAKE128 returns true if the SHAKE128 extendable output function is ++// supported. ++func SupportsSHAKE128() bool { ++ _, err := loadHash(bcrypt.CSHAKE128_ALGORITHM, bcrypt.ALG_NONE_FLAG) ++ return err == nil ++} ++ ++// SupportsSHAKE256 returns true if the SHAKE256 extendable output function is ++// supported. ++func SupportsSHAKE256() bool { ++ _, err := loadHash(bcrypt.CSHAKE256_ALGORITHM, bcrypt.ALG_NONE_FLAG) ++ return err == nil ++} ++ ++var _ hash.Hash = (*DigestSHA3)(nil) ++var _ cloneHash = (*DigestSHA3)(nil) ++ ++// DigestSHA3 is the [sha3.SHA3] implementation using the CNG API. ++type DigestSHA3 struct { ++ alg *hashAlgorithm ++ ctx bcrypt.HASH_HANDLE ++} ++ ++// newDigestSHA3 returns a new hash.Hash using the specified algorithm. ++func newDigestSHA3(id string) *DigestSHA3 { ++ alg, err := loadHash(id, bcrypt.ALG_NONE_FLAG) ++ if err != nil { ++ panic(err) ++ } ++ h := &DigestSHA3{alg: alg} ++ // Don't call bcrypt.CreateHash yet, it would be wasteful ++ // if the caller only wants to know the hash type. This ++ // is a common pattern in this package, as some functions ++ // accept a `func() hash.Hash` parameter and call it just ++ // to know the hash type. ++ return h ++} ++ ++func (h *DigestSHA3) finalize() { ++ bcrypt.DestroyHash(h.ctx) ++} ++ ++func (h *DigestSHA3) init() { ++ defer runtime.KeepAlive(h) ++ if h.ctx != 0 { ++ return ++ } ++ err := bcrypt.CreateHash(h.alg.handle, &h.ctx, nil, nil, bcrypt.HASH_REUSABLE_FLAG) ++ if err != nil { ++ panic(err) ++ } ++ runtime.SetFinalizer(h, (*DigestSHA3).finalize) ++} ++ ++func (h *DigestSHA3) Clone() hash.Hash { ++ defer runtime.KeepAlive(h) ++ h2 := &DigestSHA3{alg: h.alg} ++ if h.ctx != 0 { ++ hashClone(h.ctx, &h2.ctx) ++ runtime.SetFinalizer(h2, (*DigestSHA3).finalize) ++ } ++ return h2 ++} ++ ++func (h *DigestSHA3) Reset() { ++ defer runtime.KeepAlive(h) ++ if h.ctx != 0 { ++ hashReset(h.ctx, h.Size()) ++ } ++} ++ ++func (h *DigestSHA3) Write(p []byte) (n int, err error) { ++ defer runtime.KeepAlive(h) ++ h.init() ++ hashData(h.ctx, p) ++ return len(p), nil ++} ++ ++func (h *DigestSHA3) WriteString(s string) (int, error) { ++ defer runtime.KeepAlive(h) ++ return h.Write(unsafe.Slice(unsafe.StringData(s), len(s))) ++} ++ ++func (h *DigestSHA3) WriteByte(c byte) error { ++ defer runtime.KeepAlive(h) ++ h.init() ++ hashByte(h.ctx, c) ++ return nil ++} ++ ++func (h *DigestSHA3) Sum(in []byte) []byte { ++ defer runtime.KeepAlive(h) ++ h.init() ++ return hashSum(h.ctx, h.Size(), in) ++} ++ ++func (h *DigestSHA3) Size() int { ++ return int(h.alg.size) ++} ++ ++func (h *DigestSHA3) BlockSize() int { ++ return int(h.alg.blockSize) ++} ++ ++// NewSHA3_256 returns a new SHA256 hash. ++func NewSHA3_256() *DigestSHA3 { ++ return newDigestSHA3(bcrypt.SHA3_256_ALGORITHM) ++} ++ ++// NewSHA3_384 returns a new SHA384 hash. ++func NewSHA3_384() *DigestSHA3 { ++ return newDigestSHA3(bcrypt.SHA3_384_ALGORITHM) ++} ++ ++// NewSHA3_512 returns a new SHA512 hash. ++func NewSHA3_512() *DigestSHA3 { ++ return newDigestSHA3(bcrypt.SHA3_512_ALGORITHM) ++} ++ ++// SHAKE is an instance of a SHAKE extendable output function. ++type SHAKE struct { ++ ctx bcrypt.HASH_HANDLE ++ blockSize uint32 ++} ++ ++func newShake(id string, N, S []byte) *SHAKE { ++ alg, err := loadHash(id, bcrypt.ALG_NONE_FLAG) ++ if err != nil { ++ panic(err) ++ } ++ h := &SHAKE{blockSize: alg.blockSize} ++ err = bcrypt.CreateHash(alg.handle, &h.ctx, nil, nil, bcrypt.HASH_REUSABLE_FLAG) ++ if err != nil { ++ panic(err) ++ } ++ if len(N) != 0 { ++ if err := bcrypt.SetProperty(bcrypt.HANDLE(h.ctx), utf16PtrFromString(bcrypt.FUNCTION_NAME_STRING), N, 0); err != nil { ++ panic(err) ++ } ++ } ++ if len(S) != 0 { ++ if err := bcrypt.SetProperty(bcrypt.HANDLE(h.ctx), utf16PtrFromString(bcrypt.CUSTOMIZATION_STRING), S, 0); err != nil { ++ panic(err) ++ } ++ } ++ runtime.SetFinalizer(h, (*SHAKE).finalize) ++ return h ++} ++ ++// NewSHAKE128 creates a new SHAKE128 XOF. ++func NewSHAKE128() *SHAKE { ++ return newShake(bcrypt.CSHAKE128_ALGORITHM, nil, nil) ++} ++ ++// NewSHAKE256 creates a new SHAKE256 XOF. ++func NewSHAKE256() *SHAKE { ++ return newShake(bcrypt.CSHAKE256_ALGORITHM, nil, nil) ++} ++ ++// NewCSHAKE128 creates a new cSHAKE128 XOF. ++// ++// N is used to define functions based on cSHAKE, it can be empty when plain ++// cSHAKE is desired. S is a customization byte string used for domain ++// separation. When N and S are both empty, this is equivalent to NewSHAKE128. ++func NewCSHAKE128(N, S []byte) *SHAKE { ++ return newShake(bcrypt.CSHAKE128_ALGORITHM, N, S) ++} ++ ++// NewCSHAKE256 creates a new cSHAKE256 XOF. ++// ++// N is used to define functions based on cSHAKE, it can be empty when plain ++// cSHAKE is desired. S is a customization byte string used for domain ++// separation. When N and S are both empty, this is equivalent to NewSHAKE256. ++func NewCSHAKE256(N, S []byte) *SHAKE { ++ return newShake(bcrypt.CSHAKE256_ALGORITHM, N, S) ++} ++ ++func (h *SHAKE) finalize() { ++ bcrypt.DestroyHash(h.ctx) ++} ++ ++// Write absorbs more data into the XOF's state. ++// ++// It panics if any output has already been read. ++func (s *SHAKE) Write(p []byte) (n int, err error) { ++ if len(p) == 0 { ++ return 0, nil ++ } ++ defer runtime.KeepAlive(s) ++ hashData(s.ctx, p) ++ return len(p), nil ++} ++ ++// Read squeezes more output from the XOF. ++// ++// Any call to Write after a call to Read will panic. ++func (s *SHAKE) Read(p []byte) (n int, err error) { ++ if len(p) == 0 { ++ return 0, nil ++ } ++ defer runtime.KeepAlive(s) ++ for n < len(p) && err == nil { ++ nn := len32(p[n:]) ++ err = bcrypt.FinishHash(s.ctx, p[n:n+nn], bcrypt.HASH_DONT_RESET_FLAG) ++ n += nn ++ } ++ if err != nil { ++ panic(err) ++ } ++ return len(p), nil ++} ++ ++// Reset resets the XOF to its initial state. ++func (s *SHAKE) Reset() { ++ defer runtime.KeepAlive(s) ++ // SHAKE has a variable size, CNG doesn't change the size of the hash ++ // when resetting, so we can pass a small value here. ++ hashReset(s.ctx, 1) ++} ++ ++// BlockSize returns the rate of the XOF. ++func (s *SHAKE) BlockSize() int { ++ return int(s.blockSize) ++} 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..5a3fb01606ef95 @@ -13562,10 +13862,10 @@ index 00000000000000..5a3fb01606ef95 +} 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..090c74a894e170 +index 00000000000000..7d34e6661d3086 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/bcrypt_windows.go -@@ -0,0 +1,359 @@ +@@ -0,0 +1,368 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -13590,6 +13890,8 @@ index 00000000000000..090c74a894e170 + SHA3_256_ALGORITHM = "SHA3-256" + SHA3_384_ALGORITHM = "SHA3-384" + SHA3_512_ALGORITHM = "SHA3-512" ++ CSHAKE128_ALGORITHM = "CSHAKE128" ++ CSHAKE256_ALGORITHM = "CSHAKE256" + AES_ALGORITHM = "AES" + RC4_ALGORITHM = "RC4" + RSA_ALGORITHM = "RSA" @@ -13615,17 +13917,19 @@ index 00000000000000..090c74a894e170 +) + +const ( -+ HASH_LENGTH = "HashDigestLength" -+ HASH_BLOCK_LENGTH = "HashBlockLength" -+ CHAINING_MODE = "ChainingMode" -+ CHAIN_MODE_ECB = "ChainingModeECB" -+ CHAIN_MODE_CBC = "ChainingModeCBC" -+ CHAIN_MODE_GCM = "ChainingModeGCM" -+ KEY_LENGTH = "KeyLength" -+ KEY_LENGTHS = "KeyLengths" -+ SIGNATURE_LENGTH = "SignatureLength" -+ BLOCK_LENGTH = "BlockLength" -+ ECC_CURVE_NAME = "ECCCurveName" ++ HASH_LENGTH = "HashDigestLength" ++ HASH_BLOCK_LENGTH = "HashBlockLength" ++ CHAINING_MODE = "ChainingMode" ++ CHAIN_MODE_ECB = "ChainingModeECB" ++ CHAIN_MODE_CBC = "ChainingModeCBC" ++ CHAIN_MODE_GCM = "ChainingModeGCM" ++ KEY_LENGTH = "KeyLength" ++ KEY_LENGTHS = "KeyLengths" ++ SIGNATURE_LENGTH = "SignatureLength" ++ BLOCK_LENGTH = "BlockLength" ++ ECC_CURVE_NAME = "ECCCurveName" ++ FUNCTION_NAME_STRING = "FunctionNameString" ++ CUSTOMIZATION_STRING = "CustomizationString" +) + +const ( @@ -13682,6 +13986,11 @@ index 00000000000000..090c74a894e170 +) + +const ( ++ HASH_DONT_RESET_FLAG = 0x00000001 ++ HASH_REUSABLE_FLAG = 0x00000020 ++) ++ ++const ( + KDF_RAW_SECRET = "TRUNCATE" +) + @@ -13866,7 +14175,7 @@ index 00000000000000..090c74a894e170 + Count [4]uint8 +} + -+func Encrypt(hKey KEY_HANDLE, plaintext []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { ++func Encrypt(hKey KEY_HANDLE, plaintext []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { + var pInput *byte + if len(plaintext) > 0 { + pInput = &plaintext[0] @@ -13879,42 +14188,42 @@ index 00000000000000..090c74a894e170 + return _Encrypt(hKey, pInput, uint32(len(plaintext)), pPaddingInfo, pbIV, pbOutput, pcbResult, dwFlags) +} + -+//sys GetFipsAlgorithmMode(enabled *bool) (s error) = bcrypt.BCryptGetFipsAlgorithmMode -+//sys SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (s error) = bcrypt.BCryptSetProperty -+//sys GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptGetProperty -+//sys OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (s error) = bcrypt.BCryptOpenAlgorithmProvider -+//sys CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (s error) = bcrypt.BCryptCloseAlgorithmProvider ++//sys GetFipsAlgorithmMode(enabled *bool) (ntstatus error) = bcrypt.BCryptGetFipsAlgorithmMode ++//sys SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptSetProperty ++//sys GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGetProperty ++//sys OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (ntstatus error) = bcrypt.BCryptOpenAlgorithmProvider ++//sys CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (ntstatus error) = bcrypt.BCryptCloseAlgorithmProvider + +// SHA and HMAC + -+//sys Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (s error) = bcrypt.BCryptHash -+//sys CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (s error) = bcrypt.BCryptCreateHash -+//sys DestroyHash(hHash HASH_HANDLE) (s error) = bcrypt.BCryptDestroyHash -+//sys HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (s error) = bcrypt.BCryptHashData -+//sys HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (s error) = bcrypt.BCryptHashData -+//sys DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (s error) = bcrypt.BCryptDuplicateHash -+//sys FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (s error) = bcrypt.BCryptFinishHash ++//sys Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (ntstatus error) = bcrypt.BCryptHash ++//sys CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptCreateHash ++//sys DestroyHash(hHash HASH_HANDLE) (ntstatus error) = bcrypt.BCryptDestroyHash ++//sys HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptHashData ++//sys HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptHashData ++//sys DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptDuplicateHash ++//sys FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptFinishHash + +// Rand + -+//sys GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (s error) = bcrypt.BCryptGenRandom ++//sys GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGenRandom + +// Keys + -+//sys generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (s error) = bcrypt.BCryptGenerateSymmetricKey -+//sys GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (s error) = bcrypt.BCryptGenerateKeyPair -+//sys FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (s error) = bcrypt.BCryptFinalizeKeyPair -+//sys ImportKeyPair (hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (s error) = bcrypt.BCryptImportKeyPair -+//sys ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptExportKey -+//sys DestroyKey(hKey KEY_HANDLE) (s error) = bcrypt.BCryptDestroyKey -+//sys _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) = bcrypt.BCryptEncrypt -+//sys Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) = bcrypt.BCryptDecrypt -+//sys SignHash (hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) = bcrypt.BCryptSignHash -+//sys VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (s error) = bcrypt.BCryptVerifySignature -+//sys SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (s error) = bcrypt.BCryptSecretAgreement -+//sys DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptDeriveKey -+//sys KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) = bcrypt.BCryptKeyDerivation -+//sys DestroySecret(hSecret SECRET_HANDLE) (s error) = bcrypt.BCryptDestroySecret ++//sys generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGenerateSymmetricKey ++//sys GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptGenerateKeyPair ++//sys FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (ntstatus error) = bcrypt.BCryptFinalizeKeyPair ++//sys ImportKeyPair (hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) = bcrypt.BCryptImportKeyPair ++//sys ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptExportKey ++//sys DestroyKey(hKey KEY_HANDLE) (ntstatus error) = bcrypt.BCryptDestroyKey ++//sys _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptEncrypt ++//sys Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptDecrypt ++//sys SignHash (hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptSignHash ++//sys VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (ntstatus error) = bcrypt.BCryptVerifySignature ++//sys SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (ntstatus error) = bcrypt.BCryptSecretAgreement ++//sys DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptDeriveKey ++//sys KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) = bcrypt.BCryptKeyDerivation ++//sys DestroySecret(hSecret SECRET_HANDLE) (ntstatus error) = bcrypt.BCryptDestroySecret + +func GenerateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret []byte, dwFlags uint32) error { + cbLen := uint32(len(pbSecret)) @@ -13925,12 +14234,63 @@ index 00000000000000..090c74a894e170 + } + return generateSymmetricKey(hAlgorithm, phKey, pbKeyObject, &pbSecret[0], cbLen, dwFlags) +} +diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/ntstatus_windows.go b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/ntstatus_windows.go +new file mode 100644 +index 00000000000000..ec2eb01aa3cd8a +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/ntstatus_windows.go +@@ -0,0 +1,45 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++package bcrypt ++ ++import ( ++ "strconv" ++ "syscall" ++ "unicode/utf16" ++) ++ ++const ( ++ FORMAT_MESSAGE_FROM_HMODULE = 2048 ++ FORMAT_MESSAGE_FROM_SYSTEM = 4096 ++ FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192 ++ ++ LANG_ENGLISH = 0x09 ++ SUBLANG_ENGLISH_US = 0x01 ++) ++ ++type NTStatus uint32 ++ ++func (s NTStatus) Errno() syscall.Errno { ++ return rtlNtStatusToDosErrorNoTeb(s) ++} ++ ++func langID(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) } ++ ++func (s NTStatus) Error() string { ++ b := make([]uint16, 300) ++ n, err := formatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ARGUMENT_ARRAY, modntdll.Handle(), uint32(s), langID(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil) ++ if err != nil { ++ return "NTSTATUS 0x" + strconv.FormatUint(uint64(s), 16) ++ } ++ // trim terminating \r and \n ++ for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { ++ } ++ return string(utf16.Decode(b[:n])) ++} ++ ++// NT Native APIs ++//sys rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb ++ ++// windows api calls ++//sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/zsyscall_windows.go b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/zsyscall_windows.go new file mode 100644 -index 00000000000000..3c6a5764eb92ec +index 00000000000000..5d049f025b0301 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/bcrypt/zsyscall_windows.go -@@ -0,0 +1,389 @@ +@@ -0,0 +1,412 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package bcrypt @@ -13970,7 +14330,9 @@ index 00000000000000..3c6a5764eb92ec +} + +var ( -+ modbcrypt = syscall.NewLazyDLL(sysdll.Add("bcrypt.dll")) ++ modbcrypt = syscall.NewLazyDLL(sysdll.Add("bcrypt.dll")) ++ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) ++ modntdll = syscall.NewLazyDLL(sysdll.Add("ntdll.dll")) + + procBCryptCloseAlgorithmProvider = modbcrypt.NewProc("BCryptCloseAlgorithmProvider") + procBCryptCreateHash = modbcrypt.NewProc("BCryptCreateHash") @@ -13998,17 +14360,19 @@ index 00000000000000..3c6a5764eb92ec + procBCryptSetProperty = modbcrypt.NewProc("BCryptSetProperty") + procBCryptSignHash = modbcrypt.NewProc("BCryptSignHash") + procBCryptVerifySignature = modbcrypt.NewProc("BCryptVerifySignature") ++ procFormatMessageW = modkernel32.NewProc("FormatMessageW") ++ procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") +) + -+func CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (s error) { ++func CloseAlgorithmProvider(hAlgorithm ALG_HANDLE, dwFlags uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall(procBCryptCloseAlgorithmProvider.Addr(), 2, uintptr(hAlgorithm), uintptr(dwFlags), 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (s error) { ++func CreateHash(hAlgorithm ALG_HANDLE, phHash *HASH_HANDLE, pbHashObject []byte, pbSecret []byte, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbHashObject) > 0 { + _p0 = &pbHashObject[0] @@ -14019,12 +14383,12 @@ index 00000000000000..3c6a5764eb92ec + } + r0, _, _ := syscall.Syscall9(procBCryptCreateHash.Addr(), 7, uintptr(hAlgorithm), uintptr(unsafe.Pointer(phHash)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbHashObject)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbSecret)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { ++func Decrypt(hKey KEY_HANDLE, pbInput []byte, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] @@ -14039,60 +14403,60 @@ index 00000000000000..3c6a5764eb92ec + } + r0, _, _ := syscall.Syscall12(procBCryptDecrypt.Addr(), 10, uintptr(hKey), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbIV)), uintptr(unsafe.Pointer(_p2)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) { ++func DeriveKey(hSharedSecret SECRET_HANDLE, pwszKDF *uint16, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbDerivedKey) > 0 { + _p0 = &pbDerivedKey[0] + } + r0, _, _ := syscall.Syscall9(procBCryptDeriveKey.Addr(), 7, uintptr(hSharedSecret), uintptr(unsafe.Pointer(pwszKDF)), uintptr(unsafe.Pointer(pParameterList)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbDerivedKey)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func DestroyHash(hHash HASH_HANDLE) (s error) { ++func DestroyHash(hHash HASH_HANDLE) (ntstatus error) { + r0, _, _ := syscall.Syscall(procBCryptDestroyHash.Addr(), 1, uintptr(hHash), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func DestroyKey(hKey KEY_HANDLE) (s error) { ++func DestroyKey(hKey KEY_HANDLE) (ntstatus error) { + r0, _, _ := syscall.Syscall(procBCryptDestroyKey.Addr(), 1, uintptr(hKey), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func DestroySecret(hSecret SECRET_HANDLE) (s error) { ++func DestroySecret(hSecret SECRET_HANDLE) (ntstatus error) { + r0, _, _ := syscall.Syscall(procBCryptDestroySecret.Addr(), 1, uintptr(hSecret), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (s error) { ++func DuplicateHash(hHash HASH_HANDLE, phNewHash *HASH_HANDLE, pbHashObject []byte, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbHashObject) > 0 { + _p0 = &pbHashObject[0] + } + r0, _, _ := syscall.Syscall6(procBCryptDuplicateHash.Addr(), 5, uintptr(hHash), uintptr(unsafe.Pointer(phNewHash)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbHashObject)), uintptr(dwFlags), 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { ++func _Encrypt(hKey KEY_HANDLE, pbInput *byte, cbInput uint32, pPaddingInfo unsafe.Pointer, pbIV []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { + var _p0 *byte + if len(pbIV) > 0 { + _p0 = &pbIV[0] @@ -14103,76 +14467,76 @@ index 00000000000000..3c6a5764eb92ec + } + r0, _, _ := syscall.Syscall12(procBCryptEncrypt.Addr(), 10, uintptr(hKey), uintptr(unsafe.Pointer(pbInput)), uintptr(cbInput), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbIV)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) { ++func ExportKey(hKey KEY_HANDLE, hExportKey KEY_HANDLE, pszBlobType *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbOutput) > 0 { + _p0 = &pbOutput[0] + } + r0, _, _ := syscall.Syscall9(procBCryptExportKey.Addr(), 7, uintptr(hKey), uintptr(hExportKey), uintptr(unsafe.Pointer(pszBlobType)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (s error) { ++func FinalizeKeyPair(hKey KEY_HANDLE, dwFlags uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall(procBCryptFinalizeKeyPair.Addr(), 2, uintptr(hKey), uintptr(dwFlags), 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (s error) { ++func FinishHash(hHash HASH_HANDLE, pbOutput []byte, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbOutput) > 0 { + _p0 = &pbOutput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptFinishHash.Addr(), 4, uintptr(hHash), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbOutput)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (s error) { ++func GenRandom(hAlgorithm ALG_HANDLE, pbBuffer []byte, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbBuffer) > 0 { + _p0 = &pbBuffer[0] + } + r0, _, _ := syscall.Syscall6(procBCryptGenRandom.Addr(), 4, uintptr(hAlgorithm), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbBuffer)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (s error) { ++func GenerateKeyPair(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, dwLength uint32, dwFlags uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall6(procBCryptGenerateKeyPair.Addr(), 4, uintptr(hAlgorithm), uintptr(unsafe.Pointer(phKey)), uintptr(dwLength), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (s error) { ++func generateSymmetricKey(hAlgorithm ALG_HANDLE, phKey *KEY_HANDLE, pbKeyObject []byte, pbSecret *byte, cbSecret uint32, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbKeyObject) > 0 { + _p0 = &pbKeyObject[0] + } + r0, _, _ := syscall.Syscall9(procBCryptGenerateSymmetricKey.Addr(), 7, uintptr(hAlgorithm), uintptr(unsafe.Pointer(phKey)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbKeyObject)), uintptr(unsafe.Pointer(pbSecret)), uintptr(cbSecret), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func GetFipsAlgorithmMode(enabled *bool) (s error) { ++func GetFipsAlgorithmMode(enabled *bool) (ntstatus error) { + var _p0 uint32 + if *enabled { + _p0 = 1 @@ -14180,24 +14544,24 @@ index 00000000000000..3c6a5764eb92ec + r0, _, _ := syscall.Syscall(procBCryptGetFipsAlgorithmMode.Addr(), 1, uintptr(unsafe.Pointer(&_p0)), 0, 0) + *enabled = _p0 != 0 + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (s error) { ++func GetProperty(hObject HANDLE, pszProperty *uint16, pbOutput []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbOutput) > 0 { + _p0 = &pbOutput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptGetProperty.Addr(), 6, uintptr(hObject), uintptr(unsafe.Pointer(pszProperty)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags)) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (s error) { ++func Hash(hAlgorithm ALG_HANDLE, pbSecret []byte, pbInput []byte, pbOutput []byte) (ntstatus error) { + var _p0 *byte + if len(pbSecret) > 0 { + _p0 = &pbSecret[0] @@ -14212,84 +14576,84 @@ index 00000000000000..3c6a5764eb92ec + } + r0, _, _ := syscall.Syscall9(procBCryptHash.Addr(), 7, uintptr(hAlgorithm), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbSecret)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbInput)), uintptr(unsafe.Pointer(_p2)), uintptr(len(pbOutput)), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (s error) { ++func HashDataRaw(hHash HASH_HANDLE, pbInput *byte, cbInput uint32, dwFlags uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall6(procBCryptHashData.Addr(), 4, uintptr(hHash), uintptr(unsafe.Pointer(pbInput)), uintptr(cbInput), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (s error) { ++func HashData(hHash HASH_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptHashData.Addr(), 4, uintptr(hHash), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func ImportKeyPair(hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (s error) { ++func ImportKeyPair(hAlgorithm ALG_HANDLE, hImportKey KEY_HANDLE, pszBlobType *uint16, phKey *KEY_HANDLE, pbInput []byte, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] + } + r0, _, _ := syscall.Syscall9(procBCryptImportKeyPair.Addr(), 7, uintptr(hAlgorithm), uintptr(hImportKey), uintptr(unsafe.Pointer(pszBlobType)), uintptr(unsafe.Pointer(phKey)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (s error) { ++func KeyDerivation(hKey KEY_HANDLE, pParameterList *BufferDesc, pbDerivedKey []byte, pcbResult *uint32, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbDerivedKey) > 0 { + _p0 = &pbDerivedKey[0] + } + r0, _, _ := syscall.Syscall6(procBCryptKeyDerivation.Addr(), 6, uintptr(hKey), uintptr(unsafe.Pointer(pParameterList)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbDerivedKey)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags)) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (s error) { ++func OpenAlgorithmProvider(phAlgorithm *ALG_HANDLE, pszAlgId *uint16, pszImplementation *uint16, dwFlags AlgorithmProviderFlags) (ntstatus error) { + r0, _, _ := syscall.Syscall6(procBCryptOpenAlgorithmProvider.Addr(), 4, uintptr(unsafe.Pointer(phAlgorithm)), uintptr(unsafe.Pointer(pszAlgId)), uintptr(unsafe.Pointer(pszImplementation)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (s error) { ++func SecretAgreement(hPrivKey KEY_HANDLE, hPubKey KEY_HANDLE, phAgreedSecret *SECRET_HANDLE, dwFlags uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall6(procBCryptSecretAgreement.Addr(), 4, uintptr(hPrivKey), uintptr(hPubKey), uintptr(unsafe.Pointer(phAgreedSecret)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (s error) { ++func SetProperty(hObject HANDLE, pszProperty *uint16, pbInput []byte, dwFlags uint32) (ntstatus error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] + } + r0, _, _ := syscall.Syscall6(procBCryptSetProperty.Addr(), 5, uintptr(hObject), uintptr(unsafe.Pointer(pszProperty)), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(dwFlags), 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func SignHash(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (s error) { ++func SignHash(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbInput []byte, pbOutput []byte, pcbResult *uint32, dwFlags PadMode) (ntstatus error) { + var _p0 *byte + if len(pbInput) > 0 { + _p0 = &pbInput[0] @@ -14300,12 +14664,12 @@ index 00000000000000..3c6a5764eb92ec + } + r0, _, _ := syscall.Syscall9(procBCryptSignHash.Addr(), 8, uintptr(hKey), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbInput)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbOutput)), uintptr(unsafe.Pointer(pcbResult)), uintptr(dwFlags), 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} + -+func VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (s error) { ++func VerifySignature(hKey KEY_HANDLE, pPaddingInfo unsafe.Pointer, pbHash []byte, pbSignature []byte, dwFlags PadMode) (ntstatus error) { + var _p0 *byte + if len(pbHash) > 0 { + _p0 = &pbHash[0] @@ -14316,10 +14680,29 @@ index 00000000000000..3c6a5764eb92ec + } + r0, _, _ := syscall.Syscall9(procBCryptVerifySignature.Addr(), 7, uintptr(hKey), uintptr(pPaddingInfo), uintptr(unsafe.Pointer(_p0)), uintptr(len(pbHash)), uintptr(unsafe.Pointer(_p1)), uintptr(len(pbSignature)), uintptr(dwFlags), 0, 0) + if r0 != 0 { -+ s = syscall.Errno(r0) ++ ntstatus = NTStatus(r0) + } + return +} ++ ++func formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { ++ var _p0 *uint16 ++ if len(buf) > 0 { ++ _p0 = &buf[0] ++ } ++ r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) ++ n = uint32(r0) ++ if n == 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) { ++ r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(ntstatus), 0, 0) ++ ret = syscall.Errno(r0) ++ return ++} diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/internal/subtle/aliasing.go b/src/vendor/github.com/microsoft/go-crypto-winnative/internal/subtle/aliasing.go new file mode 100644 index 00000000000000..db09e4aae64f8c @@ -14420,7 +14803,7 @@ index 00000000000000..1722410e5af193 + return getSystemDirectory() + "\\" + dll +} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index 1c8de570cc2f1f..f9257989b097b5 100644 +index 1c8de570cc2f1f..eff1538ca84b8a 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,19 @@ @@ -14433,7 +14816,7 @@ index 1c8de570cc2f1f..f9257989b097b5 100644 +github.com/microsoft/go-crypto-darwin/bbig +github.com/microsoft/go-crypto-darwin/internal/cryptokit +github.com/microsoft/go-crypto-darwin/xcrypto -+# github.com/microsoft/go-crypto-winnative v0.0.0-20241212090637-6d419040e383 ++# github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 +## explicit; go 1.22 +github.com/microsoft/go-crypto-winnative/cng +github.com/microsoft/go-crypto-winnative/cng/bbig From 91d507b89eb659369dce3a7a4f7d93334b8e9f15 Mon Sep 17 00:00:00 2001 From: George Adams Date: Thu, 9 Jan 2025 10:20:44 +0000 Subject: [PATCH 5/8] try to fix test --- patches/0006-Add-Darwin-crypto-backend.patch | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/patches/0006-Add-Darwin-crypto-backend.patch b/patches/0006-Add-Darwin-crypto-backend.patch index ff0e7f3ff47..c3f556aa985 100644 --- a/patches/0006-Add-Darwin-crypto-backend.patch +++ b/patches/0006-Add-Darwin-crypto-backend.patch @@ -24,8 +24,9 @@ Subject: [PATCH] Add Darwin crypto backend .../goexperiment/exp_darwincrypto_off.go | 9 + .../goexperiment/exp_darwincrypto_on.go | 9 + src/internal/goexperiment/flags.go | 1 + + src/net/lookup_test.go | 3 + src/runtime/pprof/vminfo_darwin_test.go | 6 + - 21 files changed, 520 insertions(+), 14 deletions(-) + 22 files changed, 523 insertions(+), 14 deletions(-) create mode 100644 src/crypto/internal/backend/bbig/big_darwin.go create mode 100644 src/crypto/internal/backend/darwin_darwin.go create mode 100644 src/crypto/internal/backend/fips140/darwin.go @@ -847,6 +848,20 @@ index c6f64c18bdd13f..e6c9b7d5e62dc0 100644 // SystemCrypto enables the OpenSSL, CNG or Darwin crypto experiment depending on // which one is appropriate on the target GOOS. +diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go +index 514cbd098ae772..8ec689416dde1d 100644 +--- a/src/net/lookup_test.go ++++ b/src/net/lookup_test.go +@@ -1501,6 +1501,9 @@ func TestLookupPortIPNetworkString(t *testing.T) { + } + + func TestLookupNoSuchHost(t *testing.T) { ++ if runtime.GOOS == "darwin" { ++ t.Skip("skipping on darwin; see https://github.com/microsoft/go/issues/1394") ++ } + mustHaveExternalNetwork(t) + + const testNXDOMAIN = "invalid.invalid." diff --git a/src/runtime/pprof/vminfo_darwin_test.go b/src/runtime/pprof/vminfo_darwin_test.go index 6d375c5d53368a..39154b000ddc67 100644 --- a/src/runtime/pprof/vminfo_darwin_test.go From 8bd9fd4b6c2875dfaa8fa20afb4b60c59e8e7792 Mon Sep 17 00:00:00 2001 From: George Adams Date: Thu, 9 Jan 2025 10:51:25 +0000 Subject: [PATCH 6/8] rebase --- patches/0006-Add-Darwin-crypto-backend.patch | 10 +- patches/0007-Vendor-crypto-backends.patch | 2014 ++++++++++-------- 2 files changed, 1074 insertions(+), 950 deletions(-) diff --git a/patches/0006-Add-Darwin-crypto-backend.patch b/patches/0006-Add-Darwin-crypto-backend.patch index c3f556aa985..9e5dbaec7d0 100644 --- a/patches/0006-Add-Darwin-crypto-backend.patch +++ b/patches/0006-Add-Darwin-crypto-backend.patch @@ -741,26 +741,26 @@ index 7d7115cff81cea..d3ba67fe4d0611 100644 } default: diff --git a/src/go.mod b/src/go.mod -index 96bdcd421e1129..f6d6bee65d0cd5 100644 +index 96bdcd421e1129..04eb0c1c82ebb8 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,6 +4,7 @@ go 1.24 require ( github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 -+ github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 ++ github.com/microsoft/go-crypto-darwin v0.0.2-0.20250109125424-5d0e67f47146 github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 golang.org/x/crypto v0.30.0 golang.org/x/net v0.32.1-0.20241206180132-552d8ac903a1 diff --git a/src/go.sum b/src/go.sum -index abebb59dcd7739..61b84a86e0e66c 100644 +index abebb59dcd7739..5683f4da5e4f04 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,5 +1,7 @@ github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 h1:OhuURhDVbg+f/BvlG+qT5sQVkutwhI0Kmsy7koQ4l9A= github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337/go.mod h1:OYUBsoxLpFu8OFyhZHxfpN8lgcsw8JhTC3BQK7+XUc0= -+github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 h1:T8v8j/vr3sqmsP3BuriGfTYWu2JpEF3QoisX6hOjerU= -+github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1/go.mod h1:LyP4oZ0QcysEJdqUTOk9ngNFArRFK94YRImkoJ8julQ= ++github.com/microsoft/go-crypto-darwin v0.0.2-0.20250109125424-5d0e67f47146 h1:xg58D1m8jeq0lkMf7TmcLZXCAK/PRlT0aG02PYlA6C0= ++github.com/microsoft/go-crypto-darwin v0.0.2-0.20250109125424-5d0e67f47146/go.mod h1:LyP4oZ0QcysEJdqUTOk9ngNFArRFK94YRImkoJ8julQ= github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37 h1:KB8xmJcFSPlZFMg2mxz5b6DCE8k1qpHy2HFevAJLELI= github.com/microsoft/go-crypto-winnative v0.0.0-20250108090702-b49854c00e37/go.mod h1:JkxQeL8dGcyCuKjn1Etz4NmQrOMImMy4BA9hptEfVFA= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= diff --git a/patches/0007-Vendor-crypto-backends.patch b/patches/0007-Vendor-crypto-backends.patch index e922fabef15..b416f62f939 100644 --- a/patches/0007-Vendor-crypto-backends.patch +++ b/patches/0007-Vendor-crypto-backends.patch @@ -5,97 +5,97 @@ Subject: [PATCH] Vendor crypto backends To reproduce, run 'go mod vendor' in 'go/src'. --- - .../golang-fips/openssl/v2/.gitignore | 1 + - .../golang-fips/openssl/v2/.gitleaks.toml | 9 + - .../github.com/golang-fips/openssl/v2/LICENSE | 20 + - .../golang-fips/openssl/v2/README.md | 66 ++ - .../github.com/golang-fips/openssl/v2/aes.go | 147 +++ - .../golang-fips/openssl/v2/bbig/big.go | 37 + - .../github.com/golang-fips/openssl/v2/big.go | 11 + - .../golang-fips/openssl/v2/cgo_go124.go | 18 + - .../golang-fips/openssl/v2/cipher.go | 569 +++++++++ - .../github.com/golang-fips/openssl/v2/des.go | 114 ++ - .../github.com/golang-fips/openssl/v2/dsa.go | 323 +++++ - .../github.com/golang-fips/openssl/v2/ec.go | 68 ++ - .../github.com/golang-fips/openssl/v2/ecdh.go | 303 +++++ - .../golang-fips/openssl/v2/ecdsa.go | 208 ++++ - .../golang-fips/openssl/v2/ed25519.go | 218 ++++ - .../github.com/golang-fips/openssl/v2/evp.go | 569 +++++++++ - .../golang-fips/openssl/v2/goopenssl.c | 248 ++++ - .../golang-fips/openssl/v2/goopenssl.h | 262 +++++ - .../github.com/golang-fips/openssl/v2/hash.go | 1041 +++++++++++++++++ - .../github.com/golang-fips/openssl/v2/hkdf.go | 322 +++++ - .../github.com/golang-fips/openssl/v2/hmac.go | 274 +++++ - .../github.com/golang-fips/openssl/v2/init.go | 64 + - .../golang-fips/openssl/v2/init_unix.go | 31 + - .../golang-fips/openssl/v2/init_windows.go | 36 + - .../golang-fips/openssl/v2/openssl.go | 469 ++++++++ - .../golang-fips/openssl/v2/params.go | 210 ++++ - .../golang-fips/openssl/v2/pbkdf2.go | 62 + - .../golang-fips/openssl/v2/port_dsa.c | 85 ++ - .../openssl/v2/port_evp_md5_sha1.c | 126 ++ - .../github.com/golang-fips/openssl/v2/rand.go | 20 + - .../github.com/golang-fips/openssl/v2/rc4.go | 66 ++ - .../github.com/golang-fips/openssl/v2/rsa.go | 408 +++++++ - .../github.com/golang-fips/openssl/v2/shims.h | 416 +++++++ - .../golang-fips/openssl/v2/thread_setup.go | 14 + - .../golang-fips/openssl/v2/thread_setup.h | 4 + - .../openssl/v2/thread_setup_unix.c | 64 + - .../openssl/v2/thread_setup_windows.c | 64 + - .../golang-fips/openssl/v2/tls1prf.go | 160 +++ - .../github.com/golang-fips/openssl/v2/zaes.go | 86 ++ - .../microsoft/go-crypto-darwin/LICENSE | 21 + - .../microsoft/go-crypto-darwin/bbig/big.go | 31 + - .../internal/cryptokit/cryptokit.go | 34 + - .../internal/cryptokit/cryptokit.h | 43 + - .../internal/cryptokit/ed25519.go | 72 ++ - .../internal/cryptokit/gcm.go | 36 + - .../internal/cryptokit/hkdf.go | 77 ++ - .../microsoft/go-crypto-darwin/xcrypto/aes.go | 306 +++++ - .../microsoft/go-crypto-darwin/xcrypto/big.go | 16 + - .../go-crypto-darwin/xcrypto/cgo_go124.go | 21 + - .../go-crypto-darwin/xcrypto/cipher.go | 122 ++ - .../microsoft/go-crypto-darwin/xcrypto/des.go | 117 ++ - .../microsoft/go-crypto-darwin/xcrypto/ec.go | 32 + - .../go-crypto-darwin/xcrypto/ecdh.go | 135 +++ - .../go-crypto-darwin/xcrypto/ecdsa.go | 181 +++ - .../go-crypto-darwin/xcrypto/ed25519.go | 100 ++ - .../microsoft/go-crypto-darwin/xcrypto/evp.go | 338 ++++++ - .../go-crypto-darwin/xcrypto/hash.go | 391 +++++++ - .../go-crypto-darwin/xcrypto/hkdf.go | 66 ++ - .../go-crypto-darwin/xcrypto/hmac.go | 113 ++ - .../go-crypto-darwin/xcrypto/pbkdf2.go | 65 + - .../go-crypto-darwin/xcrypto/rand.go | 26 + - .../microsoft/go-crypto-darwin/xcrypto/rc4.go | 83 ++ - .../microsoft/go-crypto-darwin/xcrypto/rsa.go | 194 +++ - .../go-crypto-darwin/xcrypto/xcrypto.go | 59 + - .../microsoft/go-crypto-winnative/LICENSE | 21 + - .../microsoft/go-crypto-winnative/cng/aes.go | 393 +++++++ - .../go-crypto-winnative/cng/bbig/big.go | 31 + - .../microsoft/go-crypto-winnative/cng/big.go | 30 + - .../go-crypto-winnative/cng/cipher.go | 52 + - .../microsoft/go-crypto-winnative/cng/cng.go | 131 +++ - .../microsoft/go-crypto-winnative/cng/des.go | 106 ++ - .../microsoft/go-crypto-winnative/cng/dsa.go | 465 ++++++++ - .../microsoft/go-crypto-winnative/cng/ecdh.go | 255 ++++ - .../go-crypto-winnative/cng/ecdsa.go | 169 +++ - .../microsoft/go-crypto-winnative/cng/hash.go | 312 +++++ - .../microsoft/go-crypto-winnative/cng/hkdf.go | 124 ++ - .../microsoft/go-crypto-winnative/cng/hmac.go | 35 + - .../microsoft/go-crypto-winnative/cng/keys.go | 220 ++++ - .../go-crypto-winnative/cng/pbkdf2.go | 70 ++ - .../microsoft/go-crypto-winnative/cng/rand.go | 28 + - .../microsoft/go-crypto-winnative/cng/rc4.go | 65 + - .../microsoft/go-crypto-winnative/cng/rsa.go | 396 +++++++ - .../microsoft/go-crypto-winnative/cng/sha3.go | 284 +++++ - .../go-crypto-winnative/cng/tls1prf.go | 88 ++ - .../internal/bcrypt/bcrypt_windows.go | 368 ++++++ - .../internal/bcrypt/ntstatus_windows.go | 45 + - .../internal/bcrypt/zsyscall_windows.go | 412 +++++++ - .../internal/subtle/aliasing.go | 32 + - .../internal/sysdll/sys_windows.go | 55 + - src/vendor/modules.txt | 16 + - 90 files changed, 14095 insertions(+) + .../golang-fips/openssl/v2/.gitignore | 1 + + .../golang-fips/openssl/v2/.gitleaks.toml | 9 + + .../github.com/golang-fips/openssl/v2/LICENSE | 20 + + .../golang-fips/openssl/v2/README.md | 66 ++ + .../github.com/golang-fips/openssl/v2/aes.go | 147 ++++ + .../golang-fips/openssl/v2/bbig/big.go | 37 + + .../github.com/golang-fips/openssl/v2/big.go | 11 + + .../golang-fips/openssl/v2/cgo_go124.go | 18 + + .../golang-fips/openssl/v2/cipher.go | 569 ++++++++++++++ + .../github.com/golang-fips/openssl/v2/des.go | 114 +++ + .../github.com/golang-fips/openssl/v2/dsa.go | 323 ++++++++ + .../github.com/golang-fips/openssl/v2/ec.go | 68 ++ + .../github.com/golang-fips/openssl/v2/ecdh.go | 303 ++++++++ + .../golang-fips/openssl/v2/ecdsa.go | 208 +++++ + .../golang-fips/openssl/v2/ed25519.go | 228 ++++++ + .../github.com/golang-fips/openssl/v2/evp.go | 580 ++++++++++++++ + .../golang-fips/openssl/v2/goopenssl.c | 248 ++++++ + .../golang-fips/openssl/v2/goopenssl.h | 261 +++++++ + .../github.com/golang-fips/openssl/v2/hash.go | 714 ++++++++++++++++++ + .../github.com/golang-fips/openssl/v2/hkdf.go | 322 ++++++++ + .../github.com/golang-fips/openssl/v2/hmac.go | 274 +++++++ + .../github.com/golang-fips/openssl/v2/init.go | 64 ++ + .../golang-fips/openssl/v2/init_unix.go | 31 + + .../golang-fips/openssl/v2/init_windows.go | 36 + + .../golang-fips/openssl/v2/openssl.go | 469 ++++++++++++ + .../golang-fips/openssl/v2/params.go | 210 ++++++ + .../golang-fips/openssl/v2/pbkdf2.go | 62 ++ + .../golang-fips/openssl/v2/port_dsa.c | 85 +++ + .../github.com/golang-fips/openssl/v2/rand.go | 20 + + .../github.com/golang-fips/openssl/v2/rc4.go | 66 ++ + .../github.com/golang-fips/openssl/v2/rsa.go | 408 ++++++++++ + .../github.com/golang-fips/openssl/v2/shims.h | 413 ++++++++++ + .../golang-fips/openssl/v2/thread_setup.go | 14 + + .../golang-fips/openssl/v2/thread_setup.h | 4 + + .../openssl/v2/thread_setup_unix.c | 64 ++ + .../openssl/v2/thread_setup_windows.c | 64 ++ + .../golang-fips/openssl/v2/tls1prf.go | 160 ++++ + .../github.com/golang-fips/openssl/v2/zaes.go | 86 +++ + .../microsoft/go-crypto-darwin/LICENSE | 21 + + .../microsoft/go-crypto-darwin/bbig/big.go | 31 + + .../internal/cryptokit/CryptoKit.o | Bin 0 -> 100952 bytes + .../internal/cryptokit/cryptokit.go | 34 + + .../internal/cryptokit/cryptokit.h | 43 ++ + .../internal/cryptokit/ed25519.go | 72 ++ + .../internal/cryptokit/gcm.go | 36 + + .../internal/cryptokit/hkdf.go | 77 ++ + .../microsoft/go-crypto-darwin/xcrypto/aes.go | 306 ++++++++ + .../microsoft/go-crypto-darwin/xcrypto/big.go | 16 + + .../go-crypto-darwin/xcrypto/cgo_go124.go | 21 + + .../go-crypto-darwin/xcrypto/cipher.go | 122 +++ + .../microsoft/go-crypto-darwin/xcrypto/des.go | 117 +++ + .../microsoft/go-crypto-darwin/xcrypto/ec.go | 32 + + .../go-crypto-darwin/xcrypto/ecdh.go | 135 ++++ + .../go-crypto-darwin/xcrypto/ecdsa.go | 181 +++++ + .../go-crypto-darwin/xcrypto/ed25519.go | 100 +++ + .../microsoft/go-crypto-darwin/xcrypto/evp.go | 338 +++++++++ + .../go-crypto-darwin/xcrypto/hash.go | 391 ++++++++++ + .../go-crypto-darwin/xcrypto/hkdf.go | 66 ++ + .../go-crypto-darwin/xcrypto/hmac.go | 113 +++ + .../go-crypto-darwin/xcrypto/pbkdf2.go | 65 ++ + .../go-crypto-darwin/xcrypto/rand.go | 26 + + .../microsoft/go-crypto-darwin/xcrypto/rc4.go | 83 ++ + .../microsoft/go-crypto-darwin/xcrypto/rsa.go | 194 +++++ + .../go-crypto-darwin/xcrypto/xcrypto.go | 59 ++ + .../microsoft/go-crypto-winnative/LICENSE | 21 + + .../microsoft/go-crypto-winnative/cng/aes.go | 393 ++++++++++ + .../go-crypto-winnative/cng/bbig/big.go | 31 + + .../microsoft/go-crypto-winnative/cng/big.go | 30 + + .../go-crypto-winnative/cng/cipher.go | 52 ++ + .../microsoft/go-crypto-winnative/cng/cng.go | 131 ++++ + .../microsoft/go-crypto-winnative/cng/des.go | 106 +++ + .../microsoft/go-crypto-winnative/cng/dsa.go | 465 ++++++++++++ + .../microsoft/go-crypto-winnative/cng/ecdh.go | 255 +++++++ + .../go-crypto-winnative/cng/ecdsa.go | 169 +++++ + .../microsoft/go-crypto-winnative/cng/hash.go | 312 ++++++++ + .../microsoft/go-crypto-winnative/cng/hkdf.go | 124 +++ + .../microsoft/go-crypto-winnative/cng/hmac.go | 35 + + .../microsoft/go-crypto-winnative/cng/keys.go | 220 ++++++ + .../go-crypto-winnative/cng/pbkdf2.go | 70 ++ + .../microsoft/go-crypto-winnative/cng/rand.go | 28 + + .../microsoft/go-crypto-winnative/cng/rc4.go | 65 ++ + .../microsoft/go-crypto-winnative/cng/rsa.go | 396 ++++++++++ + .../microsoft/go-crypto-winnative/cng/sha3.go | 284 +++++++ + .../go-crypto-winnative/cng/tls1prf.go | 88 +++ + .../internal/bcrypt/bcrypt_windows.go | 368 +++++++++ + .../internal/bcrypt/ntstatus_windows.go | 45 ++ + .../internal/bcrypt/zsyscall_windows.go | 412 ++++++++++ + .../internal/subtle/aliasing.go | 32 + + .../internal/sysdll/sys_windows.go | 55 ++ + src/vendor/modules.txt | 16 + + 90 files changed, 13659 insertions(+) create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitignore 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 @@ -124,7 +124,6 @@ To reproduce, run 'go mod vendor' in 'go/src'. create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/params.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_dsa.c - 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/rc4.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/rsa.go @@ -137,6 +136,7 @@ To reproduce, run 'go mod vendor' in 'go/src'. create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/zaes.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/LICENSE create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/bbig/big.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/CryptoKit.o create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.h create mode 100644 src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/ed25519.go @@ -2167,10 +2167,10 @@ index 00000000000000..bc5f1117fd4355 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go new file mode 100644 -index 00000000000000..cd237025109997 +index 00000000000000..f96db2cd5efcad --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go -@@ -0,0 +1,218 @@ +@@ -0,0 +1,228 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -2263,7 +2263,7 @@ index 00000000000000..cd237025109997 + if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { + return nil, err + } -+ pubk, err := NewPublicKeyEd25119(pub) ++ pubk, err := NewPublicKeyEd25519(pub) + if err != nil { + return nil, err + } @@ -2281,14 +2281,24 @@ index 00000000000000..cd237025109997 + return priv, nil +} + ++// Deprecated: use NewPrivateKeyEd25519 instead. +func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { ++ return NewPrivateKeyEd25519(priv) ++} ++ ++func NewPrivateKeyEd25519(priv []byte) (*PrivateKeyEd25519, error) { + if len(priv) != privateKeySizeEd25519 { + panic("ed25519: bad private key length: " + strconv.Itoa(len(priv))) + } + return NewPrivateKeyEd25519FromSeed(priv[:seedSizeEd25519]) +} + ++// Deprecated: use NewPublicKeyEd25519 instead. +func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { ++ return NewPublicKeyEd25519(pub) ++} ++ ++func NewPublicKeyEd25519(pub []byte) (*PublicKeyEd25519, error) { + if len(pub) != publicKeySizeEd25519 { + panic("ed25519: bad public key length: " + strconv.Itoa(len(pub))) + } @@ -2391,10 +2401,10 @@ index 00000000000000..cd237025109997 +} 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..ef68bbfb8fb065 +index 00000000000000..8b5b367f9f8092 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/evp.go -@@ -0,0 +1,569 @@ +@@ -0,0 +1,580 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -2445,29 +2455,8 @@ index 00000000000000..ef68bbfb8fb065 + +// hashToMD converts a hash.Hash implementation from this package to a GO_EVP_MD_PTR. +func hashToMD(h hash.Hash) C.GO_EVP_MD_PTR { -+ var ch crypto.Hash -+ switch h.(type) { -+ case *sha1Hash, *sha1Marshal: -+ ch = crypto.SHA1 -+ case *sha224Hash, *sha224Marshal: -+ ch = crypto.SHA224 -+ case *sha256Hash, *sha256Marshal: -+ ch = crypto.SHA256 -+ case *sha384Hash, *sha384Marshal: -+ ch = crypto.SHA384 -+ case *sha512Hash, *sha512Marshal: -+ ch = crypto.SHA512 -+ case *sha3_224Hash: -+ ch = crypto.SHA3_224 -+ case *sha3_256Hash: -+ ch = crypto.SHA3_256 -+ case *sha3_384Hash: -+ ch = crypto.SHA3_384 -+ case *sha3_512Hash: -+ ch = crypto.SHA3_512 -+ } -+ if ch != 0 { -+ return cryptoHashToMD(ch) ++ if h, ok := h.(*evpHash); ok { ++ return h.alg.md + } + return nil +} @@ -2486,78 +2475,110 @@ index 00000000000000..ef68bbfb8fb065 + return md, nil +} + -+// cryptoHashToMD converts a crypto.Hash to a GO_EVP_MD_PTR. -+func cryptoHashToMD(ch crypto.Hash) (md C.GO_EVP_MD_PTR) { ++type hashAlgorithm struct { ++ md C.GO_EVP_MD_PTR ++ ch crypto.Hash ++ size int ++ blockSize int ++ marshallable bool ++ magic string ++ marshalledSize int ++} ++ ++// loadHash converts a crypto.Hash to a EVP_MD. ++func loadHash(ch crypto.Hash) *hashAlgorithm { + if v, ok := cacheMD.Load(ch); ok { -+ return v.(C.GO_EVP_MD_PTR) -+ } -+ defer func() { -+ if md != nil { -+ switch vMajor { -+ case 1: -+ // On OpenSSL 1 EVP_MD objects can be not-nil even -+ // when they are not supported. We need to pass the md -+ // to a EVP_MD_CTX to really know if they can be used. -+ ctx := C.go_openssl_EVP_MD_CTX_new() -+ if C.go_openssl_EVP_DigestInit_ex(ctx, md, nil) != 1 { -+ md = nil -+ } -+ C.go_openssl_EVP_MD_CTX_free(ctx) -+ case 3: -+ // On OpenSSL 3, directly operating on a EVP_MD object -+ // not created by EVP_MD_fetch has negative performance -+ // implications, as digest operations will have -+ // to fetch it on every call. Better to just fetch it once here. -+ md = C.go_openssl_EVP_MD_fetch(nil, C.go_openssl_EVP_MD_get0_name(md), nil) -+ default: -+ panic(errUnsupportedVersion()) -+ } -+ } -+ cacheMD.Store(ch, md) -+ }() -+ // SupportsHash returns false for MD5SHA1 because we don't -+ // provide a hash.Hash implementation for it. Yet, it can -+ // still be used when signing/verifying with an RSA key. -+ if ch == crypto.MD5SHA1 { -+ if vMajor == 1 && vMinor == 0 { -+ return C.go_openssl_EVP_md5_sha1_backport() -+ } else { -+ return C.go_openssl_EVP_md5_sha1() -+ } ++ return v.(*hashAlgorithm) + } ++ ++ var hash hashAlgorithm + switch ch { ++ case crypto.RIPEMD160: ++ hash.md = C.go_openssl_EVP_ripemd160() + case crypto.MD4: -+ return C.go_openssl_EVP_md4() ++ hash.md = C.go_openssl_EVP_md4() + case crypto.MD5: -+ return C.go_openssl_EVP_md5() ++ hash.md = C.go_openssl_EVP_md5() ++ hash.magic = md5Magic ++ hash.marshalledSize = md5MarshaledSize ++ case crypto.MD5SHA1: ++ if vMajor == 1 && vMinor == 0 { ++ // OpenSSL 1.0.2 does not support MD5SHA1. ++ hash.md = nil ++ } else { ++ hash.md = C.go_openssl_EVP_md5_sha1() ++ } + case crypto.SHA1: -+ return C.go_openssl_EVP_sha1() ++ hash.md = C.go_openssl_EVP_sha1() ++ hash.magic = sha1Magic ++ hash.marshalledSize = sha1MarshaledSize + case crypto.SHA224: -+ return C.go_openssl_EVP_sha224() ++ hash.md = C.go_openssl_EVP_sha224() ++ hash.magic = magic224 ++ hash.marshalledSize = marshaledSize256 + case crypto.SHA256: -+ return C.go_openssl_EVP_sha256() ++ hash.md = C.go_openssl_EVP_sha256() ++ hash.magic = magic256 ++ hash.marshalledSize = marshaledSize256 + case crypto.SHA384: -+ return C.go_openssl_EVP_sha384() ++ hash.md = C.go_openssl_EVP_sha384() ++ hash.magic = magic384 ++ hash.marshalledSize = marshaledSize512 + case crypto.SHA512: -+ return C.go_openssl_EVP_sha512() ++ hash.md = C.go_openssl_EVP_sha512() ++ hash.magic = magic512 ++ hash.marshalledSize = marshaledSize512 ++ case crypto.SHA512_224: ++ if versionAtOrAbove(1, 1, 1) { ++ hash.md = C.go_openssl_EVP_sha512_224() ++ hash.magic = magic512_224 ++ hash.marshalledSize = marshaledSize512 ++ } ++ case crypto.SHA512_256: ++ if versionAtOrAbove(1, 1, 1) { ++ hash.md = C.go_openssl_EVP_sha512_256() ++ hash.magic = magic512_256 ++ hash.marshalledSize = marshaledSize512 ++ } + case crypto.SHA3_224: + if versionAtOrAbove(1, 1, 1) { -+ return C.go_openssl_EVP_sha3_224() ++ hash.md = C.go_openssl_EVP_sha3_224() + } + case crypto.SHA3_256: + if versionAtOrAbove(1, 1, 1) { -+ return C.go_openssl_EVP_sha3_256() ++ hash.md = C.go_openssl_EVP_sha3_256() + } + case crypto.SHA3_384: + if versionAtOrAbove(1, 1, 1) { -+ return C.go_openssl_EVP_sha3_384() ++ hash.md = C.go_openssl_EVP_sha3_384() + } + case crypto.SHA3_512: + if versionAtOrAbove(1, 1, 1) { -+ return C.go_openssl_EVP_sha3_512() ++ hash.md = C.go_openssl_EVP_sha3_512() + } + } -+ return nil ++ if hash.md == nil { ++ cacheMD.Store(ch, (*hashAlgorithm)(nil)) ++ return nil ++ } ++ hash.ch = ch ++ hash.size = int(C.go_openssl_EVP_MD_get_size(hash.md)) ++ hash.blockSize = int(C.go_openssl_EVP_MD_get_block_size(hash.md)) ++ if vMajor == 3 { ++ // On OpenSSL 3, directly operating on a EVP_MD object ++ // not created by EVP_MD_fetch has negative performance ++ // implications, as digest operations will have ++ // to fetch it on every call. Better to just fetch it once here. ++ md := C.go_openssl_EVP_MD_fetch(nil, C.go_openssl_EVP_MD_get0_name(hash.md), nil) ++ // Don't overwrite md in case it can't be fetched, as the md may still be used ++ // outside of EVP_MD_CTX, for example to sign and verify RSA signatures. ++ if md != nil { ++ hash.md = md ++ } ++ } ++ hash.marshallable = hash.magic != "" && isHashMarshallable(hash.md) ++ cacheMD.Store(ch, &hash) ++ return &hash +} + +// generateEVPPKey generates a new EVP_PKEY with the given id and properties. @@ -2699,11 +2720,11 @@ index 00000000000000..ef68bbfb8fb065 + } + } + case C.GO_RSA_PKCS1_PSS_PADDING: -+ md := cryptoHashToMD(ch) -+ if md == nil { ++ alg := loadHash(ch) ++ if alg == nil { + return nil, errors.New("crypto/rsa: unsupported hash function") + } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(alg.md)) != 1 { + return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + } + // setPadding must happen after setting EVP_PKEY_CTRL_MD. @@ -2719,11 +2740,11 @@ index 00000000000000..ef68bbfb8fb065 + case C.GO_RSA_PKCS1_PADDING: + if ch != 0 { + // We support unhashed messages. -+ md := cryptoHashToMD(ch) -+ if md == nil { ++ alg := loadHash(ch) ++ if alg == nil { + return nil, errors.New("crypto/rsa: unsupported hash function") + } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(alg.md)) != 1 { + return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + } + if err := setPadding(); err != nil { @@ -2838,8 +2859,8 @@ index 00000000000000..ef68bbfb8fb065 +} + +func evpHashSign(withKey withKeyFunc, h crypto.Hash, msg []byte) ([]byte, error) { -+ md := cryptoHashToMD(h) -+ if md == nil { ++ alg := loadHash(h) ++ if alg == nil { + return nil, errors.New("unsupported hash function: " + strconv.Itoa(int(h))) + } + var out []byte @@ -2850,7 +2871,7 @@ index 00000000000000..ef68bbfb8fb065 + } + defer C.go_openssl_EVP_MD_CTX_free(ctx) + if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { -+ return C.go_openssl_EVP_DigestSignInit(ctx, nil, md, nil, key) ++ return C.go_openssl_EVP_DigestSignInit(ctx, nil, alg.md, nil, key) + }) != 1 { + return nil, newOpenSSLError("EVP_DigestSignInit failed") + } @@ -2870,8 +2891,8 @@ index 00000000000000..ef68bbfb8fb065 +} + +func evpHashVerify(withKey withKeyFunc, h crypto.Hash, msg, sig []byte) error { -+ md := cryptoHashToMD(h) -+ if md == nil { ++ alg := loadHash(h) ++ if alg == nil { + return errors.New("unsupported hash function: " + strconv.Itoa(int(h))) + } + ctx := C.go_openssl_EVP_MD_CTX_new() @@ -2880,7 +2901,7 @@ index 00000000000000..ef68bbfb8fb065 + } + defer C.go_openssl_EVP_MD_CTX_free(ctx) + if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { -+ return C.go_openssl_EVP_DigestVerifyInit(ctx, nil, md, nil, key) ++ return C.go_openssl_EVP_DigestVerifyInit(ctx, nil, alg.md, nil, key) + }) != 1 { + return newOpenSSLError("EVP_DigestVerifyInit failed") + } @@ -3220,10 +3241,10 @@ index 00000000000000..626f184badc53d +} 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..1165f99157c663 +index 00000000000000..f5cdced630679f --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h -@@ -0,0 +1,262 @@ +@@ -0,0 +1,261 @@ +// This header file describes the OpenSSL ABI as built for use in Go. + +#include // size_t @@ -3253,7 +3274,6 @@ index 00000000000000..1165f99157c663 +int go_openssl_version_patch(void* handle); +int go_openssl_thread_setup(void); +void go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch); -+const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void); +void go_openssl_DSA_get0_pqg_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *p, GO_BIGNUM_PTR *q, GO_BIGNUM_PTR *g); +int go_openssl_DSA_set0_pqg_backport(GO_DSA_PTR d, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g); +void go_openssl_DSA_get0_key_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *pub_key, GO_BIGNUM_PTR *priv_key); @@ -3489,10 +3509,10 @@ index 00000000000000..1165f99157c663 \ 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..6fd3a518906004 +index 00000000000000..b2109857b49bdf --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/hash.go -@@ -0,0 +1,1041 @@ +@@ -0,0 +1,714 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -3509,6 +3529,9 @@ index 00000000000000..6fd3a518906004 + "unsafe" +) + ++// maxHashSize is the size of SHA52 and SHA3_512, the largest hashes we support. ++const maxHashSize = 64 ++ +// 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). @@ -3521,7 +3544,7 @@ index 00000000000000..6fd3a518906004 +// 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 ++ return C.go_openssl_EVP_Digest(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), (*C.uchar)(unsafe.Pointer(&*addr(sum))), nil, loadHash(ch).md, nil) != 0 +} + +func MD4(p []byte) (sum [16]byte) { @@ -3573,9 +3596,43 @@ index 00000000000000..6fd3a518906004 + return +} + -+// SupportsHash returns true if a hash.Hash implementation is supported for h. ++func SHA512_224(p []byte) (sum [28]byte) { ++ if !hashOneShot(crypto.SHA512_224, p, sum[:]) { ++ panic("openssl: SHA512 failed") ++ } ++ return ++} ++ ++func SHA512_256(p []byte) (sum [32]byte) { ++ if !hashOneShot(crypto.SHA512_256, p, sum[:]) { ++ panic("openssl: SHA512_256 failed") ++ } ++ return ++} ++ ++// cacheHashSupported is a cache of crypto.Hash support. ++var cacheHashSupported sync.Map ++ ++// SupportsHash reports whether the current OpenSSL version supports the given hash. +func SupportsHash(h crypto.Hash) bool { -+ return cryptoHashToMD(h) != nil ++ if v, ok := cacheHashSupported.Load(h); ok { ++ return v.(bool) ++ } ++ alg := loadHash(h) ++ if alg == nil { ++ cacheHashSupported.Store(h, false) ++ return false ++ } ++ // EVP_MD objects can be non-nil even when they can't be used ++ // in a EVP_MD_CTX, e.g. MD5 in FIPS mode. We need to prove ++ // if they can be used by passing them to a EVP_MD_CTX. ++ var supported bool ++ if ctx := C.go_openssl_EVP_MD_CTX_new(); ctx != nil { ++ supported = C.go_openssl_EVP_DigestInit_ex(ctx, alg.md, nil) == 1 ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ } ++ cacheHashSupported.Store(h, supported) ++ return supported +} + +func SHA3_224(p []byte) (sum [28]byte) { @@ -3606,21 +3663,79 @@ index 00000000000000..6fd3a518906004 + return +} + -+var isMarshallableCache sync.Map ++// NewMD4 returns a new MD4 hash. ++// The returned hash doesn't implement encoding.BinaryMarshaler and ++// encoding.BinaryUnmarshaler. ++func NewMD4() hash.Hash { ++ return newEvpHash(crypto.MD4) ++} ++ ++// NewMD5 returns a new MD5 hash. ++func NewMD5() hash.Hash { ++ return newEvpHash(crypto.MD5) ++} + -+// isHashMarshallable returns true if the memory layout of cb ++// NewSHA1 returns a new SHA1 hash. ++func NewSHA1() hash.Hash { ++ return newEvpHash(crypto.SHA1) ++} ++ ++// NewSHA224 returns a new SHA224 hash. ++func NewSHA224() hash.Hash { ++ return newEvpHash(crypto.SHA224) ++} ++ ++// NewSHA256 returns a new SHA256 hash. ++func NewSHA256() hash.Hash { ++ return newEvpHash(crypto.SHA256) ++} ++ ++// NewSHA384 returns a new SHA384 hash. ++func NewSHA384() hash.Hash { ++ return newEvpHash(crypto.SHA384) ++} ++ ++// NewSHA512 returns a new SHA512 hash. ++func NewSHA512() hash.Hash { ++ return newEvpHash(crypto.SHA512) ++} ++ ++// NewSHA512_224 returns a new SHA512_224 hash. ++func NewSHA512_224() hash.Hash { ++ return newEvpHash(crypto.SHA512_224) ++} ++ ++// NewSHA512_256 returns a new SHA512_256 hash. ++func NewSHA512_256() hash.Hash { ++ return newEvpHash(crypto.SHA512_256) ++} ++ ++// NewSHA3_224 returns a new SHA3-224 hash. ++func NewSHA3_224() hash.Hash { ++ return newEvpHash(crypto.SHA3_224) ++} ++ ++// NewSHA3_256 returns a new SHA3-256 hash. ++func NewSHA3_256() hash.Hash { ++ return newEvpHash(crypto.SHA3_256) ++} ++ ++// NewSHA3_384 returns a new SHA3-384 hash. ++func NewSHA3_384() hash.Hash { ++ return newEvpHash(crypto.SHA3_384) ++} ++ ++// NewSHA3_512 returns a new SHA3-512 hash. ++func NewSHA3_512() hash.Hash { ++ return newEvpHash(crypto.SHA3_512) ++} ++ ++// isHashMarshallable returns true if the memory layout of md +// is known by this library and can therefore be marshalled. -+func isHashMarshallable(ch crypto.Hash) bool { ++func isHashMarshallable(md C.GO_EVP_MD_PTR) bool { + if vMajor == 1 { + return true + } -+ if v, ok := isMarshallableCache.Load(ch); ok { -+ return v.(bool) -+ } -+ md := cryptoHashToMD(ch) -+ if md == nil { -+ return false -+ } + prov := C.go_openssl_EVP_MD_get0_provider(md) + if prov == nil { + return false @@ -3633,51 +3748,73 @@ index 00000000000000..6fd3a518906004 + // We only know the memory layout of the built-in providers. + // See evpHash.hashState for more details. + marshallable := name == "default" || name == "fips" -+ isMarshallableCache.Store(ch, marshallable) + return marshallable +} + ++// cloneHash is an interface that defines a Clone method. ++// ++// hahs.CloneHash will probably be added in Go 1.25, see https://golang.org/issue/69521, ++// but we need it now. ++type cloneHash interface { ++ hash.Hash ++ // Clone returns a separate Hash instance with the same state as h. ++ Clone() hash.Hash ++} ++ ++var _ hash.Hash = (*evpHash)(nil) ++var _ cloneHash = (*evpHash)(nil) ++ +// evpHash implements generic hash methods. +type evpHash struct { ++ alg *hashAlgorithm + 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 -+ marshallable bool ++ ctx2 C.GO_EVP_MD_CTX_PTR +} + +func newEvpHash(ch crypto.Hash) *evpHash { -+ md := cryptoHashToMD(ch) -+ if md == nil { ++ alg := loadHash(ch) ++ if alg == 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() -+ blockSize := int(C.go_openssl_EVP_MD_get_block_size(md)) -+ h := &evpHash{ -+ ctx: ctx, -+ ctx2: ctx2, -+ size: ch.Size(), -+ blockSize: blockSize, -+ marshallable: isHashMarshallable(ch), -+ } -+ runtime.SetFinalizer(h, (*evpHash).finalize) ++ h := &evpHash{alg: alg} ++ // Don't call init() yet, it would be wasteful ++ // if the caller only wants to know the hash type. This ++ // is a common pattern in this package, as some functions ++ // accept a `func() hash.Hash` parameter and call it just ++ // to know the hash type. + return h +} + +func (h *evpHash) finalize() { -+ C.go_openssl_EVP_MD_CTX_free(h.ctx) -+ C.go_openssl_EVP_MD_CTX_free(h.ctx2) ++ if h.ctx != nil { ++ C.go_openssl_EVP_MD_CTX_free(h.ctx) ++ } ++ if h.ctx2 != nil { ++ C.go_openssl_EVP_MD_CTX_free(h.ctx2) ++ } ++} ++ ++func (h *evpHash) init() { ++ if h.ctx != nil { ++ return ++ } ++ h.ctx = C.go_openssl_EVP_MD_CTX_new() ++ if C.go_openssl_EVP_DigestInit_ex(h.ctx, h.alg.md, nil) != 1 { ++ C.go_openssl_EVP_MD_CTX_free(h.ctx) ++ panic(newOpenSSLError("EVP_DigestInit_ex")) ++ } ++ h.ctx2 = C.go_openssl_EVP_MD_CTX_new() ++ runtime.SetFinalizer(h, (*evpHash).finalize) +} + +func (h *evpHash) Reset() { ++ if h.ctx == nil { ++ // The hash is not initialized yet, no need to reset. ++ return ++ } + // 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 { @@ -3687,7 +3824,11 @@ index 00000000000000..6fd3a518906004 +} + +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 { ++ if len(p) == 0 { ++ return 0, nil ++ } ++ h.init() ++ if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&*addr(p)), C.size_t(len(p))) != 1 { + panic(newOpenSSLError("EVP_DigestUpdate")) + } + runtime.KeepAlive(h) @@ -3695,7 +3836,11 @@ index 00000000000000..6fd3a518906004 +} + +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 { ++ if len(s) == 0 { ++ return 0, nil ++ } ++ h.init() ++ if 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) @@ -3703,6 +3848,7 @@ index 00000000000000..6fd3a518906004 +} + +func (h *evpHash) WriteByte(c byte) error { ++ h.init() + if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&c), 1) == 0 { + panic("openssl: EVP_DigestUpdate failed") + } @@ -3711,56 +3857,53 @@ index 00000000000000..6fd3a518906004 +} + +func (h *evpHash) Size() int { -+ return h.size ++ return h.alg.size +} + +func (h *evpHash) BlockSize() int { -+ return h.blockSize ++ return h.alg.blockSize +} + -+func (h *evpHash) sum(out []byte) { ++func (h *evpHash) Sum(in []byte) []byte { ++ h.init() ++ out := make([]byte, h.Size(), maxHashSize) // explicit cap to allow stack allocation + if C.go_hash_sum(h.ctx, h.ctx2, base(out)) != 1 { + panic(newOpenSSLError("go_hash_sum")) + } + runtime.KeepAlive(h) ++ return append(in, out...) +} + -+// clone returns a new evpHash object that is a deep clone of itself. ++// Clone returns a new evpHash object that is a deep clone of itself. +// The duplicate object contains all state and data contained in the +// original object at the point of duplication. -+func (h *evpHash) clone() (*evpHash, error) { -+ ctx := C.go_openssl_EVP_MD_CTX_new() -+ if ctx == nil { -+ return nil, newOpenSSLError("EVP_MD_CTX_new") -+ } -+ if C.go_openssl_EVP_MD_CTX_copy_ex(ctx, h.ctx) != 1 { -+ C.go_openssl_EVP_MD_CTX_free(ctx) -+ return nil, newOpenSSLError("EVP_MD_CTX_copy") -+ } -+ ctx2 := C.go_openssl_EVP_MD_CTX_new() -+ if ctx2 == nil { -+ C.go_openssl_EVP_MD_CTX_free(ctx) -+ return nil, newOpenSSLError("EVP_MD_CTX_new") -+ } -+ cloned := &evpHash{ -+ ctx: ctx, -+ ctx2: ctx2, -+ size: h.size, -+ blockSize: h.blockSize, -+ marshallable: h.marshallable, ++func (h *evpHash) Clone() hash.Hash { ++ h2 := &evpHash{alg: h.alg} ++ if h.ctx != nil { ++ h2.ctx = C.go_openssl_EVP_MD_CTX_new() ++ if h2.ctx == nil { ++ panic(newOpenSSLError("EVP_MD_CTX_new")) ++ } ++ if C.go_openssl_EVP_MD_CTX_copy_ex(h2.ctx, h.ctx) != 1 { ++ C.go_openssl_EVP_MD_CTX_free(h2.ctx) ++ panic(newOpenSSLError("EVP_MD_CTX_copy")) ++ } ++ h2.ctx2 = C.go_openssl_EVP_MD_CTX_new() ++ if h2.ctx2 == nil { ++ C.go_openssl_EVP_MD_CTX_free(h2.ctx) ++ panic(newOpenSSLError("EVP_MD_CTX_new")) ++ } ++ runtime.SetFinalizer(h2, (*evpHash).finalize) + } -+ runtime.SetFinalizer(cloned, (*evpHash).finalize) -+ return cloned, nil ++ runtime.KeepAlive(h) ++ return h2 +} + +// hashState returns a pointer to the internal hash structure. +// +// The EVP_MD_CTX memory layout has changed in OpenSSL 3 +// and the property holding the internal structure is no longer md_data but algctx. -+func (h *evpHash) hashState() unsafe.Pointer { -+ if !h.marshallable { -+ panic("openssl: hash state is not marshallable") -+ } ++func hashState(ctx C.GO_EVP_MD_CTX_PTR) unsafe.Pointer { + switch vMajor { + case 1: + // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. @@ -3769,7 +3912,7 @@ index 00000000000000..6fd3a518906004 + _ C.ulong + md_data unsafe.Pointer + } -+ return (*mdCtx)(unsafe.Pointer(h.ctx)).md_data ++ return (*mdCtx)(unsafe.Pointer(ctx)).md_data + case 3: + // https://github.com/openssl/openssl/blob/5675a5aaf6a2e489022bcfc18330dae9263e598e/crypto/evp/evp_local.h#L16. + type mdCtx struct { @@ -3778,49 +3921,98 @@ index 00000000000000..6fd3a518906004 + _ [3]unsafe.Pointer + algctx unsafe.Pointer + } -+ return (*mdCtx)(unsafe.Pointer(h.ctx)).algctx ++ return (*mdCtx)(unsafe.Pointer(ctx)).algctx + default: + panic(errUnsupportedVersion()) + } +} + -+// 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), ++func (d *evpHash) MarshalBinary() ([]byte, error) { ++ if !d.alg.marshallable { ++ return nil, errors.New("openssl: hash state is not marshallable") + } ++ buf := make([]byte, 0, d.alg.marshalledSize) ++ return d.AppendBinary(buf) +} + -+type md4Hash struct { -+ *evpHash -+ out [16]byte -+} -+ -+func (h *md4Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *md4Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err ++func (d *evpHash) AppendBinary(buf []byte) ([]byte, error) { ++ defer runtime.KeepAlive(d) ++ d.init() ++ if !d.alg.marshallable { ++ return nil, errors.New("openssl: hash state is not marshallable") ++ } ++ state := hashState(d.ctx) ++ if state == nil { ++ return nil, errors.New("openssl: can't retrieve hash state") ++ } ++ var appender interface { ++ AppendBinary([]byte) ([]byte, error) ++ } ++ switch d.alg.ch { ++ case crypto.MD5: ++ appender = (*md5State)(state) ++ case crypto.SHA1: ++ appender = (*sha1State)(state) ++ case crypto.SHA224: ++ appender = (*sha256State)(state) ++ case crypto.SHA256: ++ appender = (*sha256State)(state) ++ case crypto.SHA384: ++ appender = (*sha512State)(state) ++ case crypto.SHA512: ++ appender = (*sha512State)(state) ++ case crypto.SHA512_224: ++ appender = (*sha512State)(state) ++ case crypto.SHA512_256: ++ appender = (*sha512State)(state) ++ default: ++ panic("openssl: unsupported hash function: " + strconv.Itoa(int(d.alg.ch))) + } -+ return &md4Hash{evpHash: c}, nil ++ buf = append(buf, d.alg.magic[:]...) ++ return appender.AppendBinary(buf) +} + -+// NewMD5 returns a new MD5 hash. -+func NewMD5() hash.Hash { -+ h := md5Hash{evpHash: newEvpHash(crypto.MD5)} -+ if h.marshallable { -+ return &md5Marshal{h} ++func (d *evpHash) UnmarshalBinary(b []byte) error { ++ defer runtime.KeepAlive(d) ++ d.init() ++ if !d.alg.marshallable { ++ return errors.New("openssl: hash state is not marshallable") ++ } ++ if len(b) < len(d.alg.magic) || string(b[:len(d.alg.magic)]) != string(d.alg.magic[:]) { ++ return errors.New("openssl: invalid hash state identifier") ++ } ++ if len(b) != d.alg.marshalledSize { ++ return errors.New("openssl: invalid hash state size") ++ } ++ state := hashState(d.ctx) ++ if state == nil { ++ return errors.New("openssl: can't retrieve hash state") ++ } ++ b = b[len(d.alg.magic):] ++ var unmarshaler interface { ++ UnmarshalBinary([]byte) error ++ } ++ switch d.alg.ch { ++ case crypto.MD5: ++ unmarshaler = (*md5State)(state) ++ case crypto.SHA1: ++ unmarshaler = (*sha1State)(state) ++ case crypto.SHA224: ++ unmarshaler = (*sha256State)(state) ++ case crypto.SHA256: ++ unmarshaler = (*sha256State)(state) ++ case crypto.SHA384: ++ unmarshaler = (*sha512State)(state) ++ case crypto.SHA512: ++ unmarshaler = (*sha512State)(state) ++ case crypto.SHA512_224: ++ unmarshaler = (*sha512State)(state) ++ case crypto.SHA512_256: ++ unmarshaler = (*sha512State)(state) ++ default: ++ panic("openssl: unsupported hash function: " + strconv.Itoa(int(d.alg.ch))) + } -+ return &h ++ return unmarshaler.UnmarshalBinary(b) +} + +// md5State layout is taken from @@ -3832,53 +4024,12 @@ index 00000000000000..6fd3a518906004 + 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[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *md5Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &md5Hash{evpHash: c}, nil -+} -+ +const ( + md5Magic = "md5\x01" + md5MarshaledSize = len(md5Magic) + 4*4 + 64 + 8 +) + -+type md5Marshal struct { -+ md5Hash -+} -+ -+func (h *md5Marshal) MarshalBinary() ([]byte, error) { -+ buf := make([]byte, 0, md5MarshaledSize) -+ return h.AppendBinary(buf) -+} -+ -+func (h *md5Marshal) UnmarshalBinary(b []byte) error { -+ if len(b) < len(md5Magic) || string(b[:len(md5Magic)]) != md5Magic { -+ return errors.New("crypto/md5: invalid hash state identifier") -+ } -+ if len(b) != md5MarshaledSize { -+ return errors.New("crypto/md5: invalid hash state size") -+ } -+ d := (*md5State)(h.hashState()) -+ if d == nil { -+ return errors.New("crypto/md5: can't retrieve hash state") -+ } -+ b = b[len(md5Magic):] ++func (d *md5State) UnmarshalBinary(b []byte) error { + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) + b, d.h[2] = consumeUint32(b) @@ -3891,13 +4042,7 @@ index 00000000000000..6fd3a518906004 + return nil +} + -+func (h *md5Marshal) AppendBinary(buf []byte) ([]byte, error) { -+ d := (*md5State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/md5: can't retrieve hash state") -+ } -+ -+ buf = append(buf, md5Magic...) ++func (d *md5State) AppendBinary(buf []byte) ([]byte, error) { + buf = appendUint32(buf, d.h[0]) + buf = appendUint32(buf, d.h[1]) + buf = appendUint32(buf, d.h[2]) @@ -3908,36 +4053,6 @@ index 00000000000000..6fd3a518906004 + return buf, nil +} + -+// NewSHA1 returns a new SHA1 hash. -+func NewSHA1() hash.Hash { -+ h := sha1Hash{evpHash: newEvpHash(crypto.SHA1)} -+ if h.marshallable { -+ return &sha1Marshal{h} -+ } -+ return &h -+} -+ -+type sha1Hash struct { -+ *evpHash -+ out [20]byte -+} -+ -+func (h *sha1Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha1Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha1Hash{evpHash: c}, nil -+} -+ +// sha1State layout is taken from +// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34. +type sha1State struct { @@ -3950,29 +4065,9 @@ index 00000000000000..6fd3a518906004 +const ( + sha1Magic = "sha\x01" + sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 -+) -+ -+type sha1Marshal struct { -+ sha1Hash -+} -+ -+func (h *sha1Marshal) MarshalBinary() ([]byte, error) { -+ buf := make([]byte, 0, sha1MarshaledSize) -+ return h.AppendBinary(buf) -+} -+ -+func (h *sha1Marshal) UnmarshalBinary(b []byte) error { -+ if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { -+ return errors.New("crypto/sha1: invalid hash state identifier") -+ } -+ if len(b) != sha1MarshaledSize { -+ return errors.New("crypto/sha1: invalid hash state size") -+ } -+ d := (*sha1State)(h.hashState()) -+ if d == nil { -+ return errors.New("crypto/sha1: can't retrieve hash state") -+ } -+ b = b[len(sha1Magic):] ++) ++ ++func (d *sha1State) UnmarshalBinary(b []byte) error { + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) + b, d.h[2] = consumeUint32(b) @@ -3986,12 +4081,7 @@ index 00000000000000..6fd3a518906004 + return nil +} + -+func (h *sha1Marshal) AppendBinary(buf []byte) ([]byte, error) { -+ d := (*sha1State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha1: can't retrieve hash state") -+ } -+ buf = append(buf, sha1Magic...) ++func (d *sha1State) AppendBinary(buf []byte) ([]byte, error) { + buf = appendUint32(buf, d.h[0]) + buf = appendUint32(buf, d.h[1]) + buf = appendUint32(buf, d.h[2]) @@ -4003,66 +4093,6 @@ index 00000000000000..6fd3a518906004 + return buf, nil +} + -+// NewSHA224 returns a new SHA224 hash. -+func NewSHA224() hash.Hash { -+ h := sha224Hash{evpHash: newEvpHash(crypto.SHA224)} -+ if h.marshallable { -+ return &sha224Marshal{h} -+ } -+ return &h -+} -+ -+type sha224Hash struct { -+ *evpHash -+ out [224 / 8]byte -+} -+ -+func (h *sha224Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha224Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha224Hash{evpHash: c}, nil -+} -+ -+// NewSHA256 returns a new SHA256 hash. -+func NewSHA256() hash.Hash { -+ h := sha256Hash{evpHash: newEvpHash(crypto.SHA256)} -+ if h.marshallable { -+ return &sha256Marshal{h} -+ } -+ return &h -+} -+ -+type sha256Hash struct { -+ *evpHash -+ out [256 / 8]byte -+} -+ -+func (h *sha256Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha256Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha256Hash{evpHash: c}, nil -+} -+ +const ( + magic224 = "sha\x02" + magic256 = "sha\x03" @@ -4078,64 +4108,7 @@ index 00000000000000..6fd3a518906004 + nx uint32 +} + -+type sha224Marshal struct { -+ sha224Hash -+} -+ -+type sha256Marshal struct { -+ sha256Hash -+} -+ -+func (h *sha224Marshal) MarshalBinary() ([]byte, error) { -+ buf := make([]byte, 0, marshaledSize256) -+ return h.AppendBinary(buf) -+} -+ -+func (h *sha256Marshal) MarshalBinary() ([]byte, error) { -+ buf := make([]byte, 0, marshaledSize256) -+ return h.AppendBinary(buf) -+} -+ -+func (h *sha224Marshal) UnmarshalBinary(b []byte) error { -+ if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { -+ return errors.New("crypto/sha256: invalid hash state identifier") -+ } -+ 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 -+} -+ -+func (h *sha256Marshal) UnmarshalBinary(b []byte) error { -+ if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { -+ return errors.New("crypto/sha256: invalid hash state identifier") -+ } -+ 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):] ++func (d *sha256State) UnmarshalBinary(b []byte) error { + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) + b, d.h[2] = consumeUint32(b) @@ -4152,32 +4125,7 @@ index 00000000000000..6fd3a518906004 + return nil +} + -+func (h *sha224Marshal) AppendBinary(buf []byte) ([]byte, error) { -+ d := (*sha256State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") -+ } -+ buf = append(buf, magic224...) -+ buf = appendUint32(buf, d.h[0]) -+ buf = appendUint32(buf, d.h[1]) -+ buf = appendUint32(buf, d.h[2]) -+ buf = appendUint32(buf, d.h[3]) -+ buf = appendUint32(buf, d.h[4]) -+ buf = appendUint32(buf, d.h[5]) -+ buf = appendUint32(buf, d.h[6]) -+ buf = appendUint32(buf, d.h[7]) -+ buf = append(buf, d.x[:d.nx]...) -+ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) -+ buf = appendUint64(buf, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return buf, nil -+} -+ -+func (h *sha256Marshal) AppendBinary(buf []byte) ([]byte, error) { -+ d := (*sha256State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") -+ } -+ buf = append(buf, magic256...) ++func (d *sha256State) AppendBinary(buf []byte) ([]byte, error) { + buf = appendUint32(buf, d.h[0]) + buf = appendUint32(buf, d.h[1]) + buf = appendUint32(buf, d.h[2]) @@ -4192,66 +4140,6 @@ index 00000000000000..6fd3a518906004 + return buf, nil +} + -+// NewSHA384 returns a new SHA384 hash. -+func NewSHA384() hash.Hash { -+ h := sha384Hash{evpHash: newEvpHash(crypto.SHA384)} -+ if h.marshallable { -+ return &sha384Marshal{h} -+ } -+ return &h -+} -+ -+type sha384Hash struct { -+ *evpHash -+ out [384 / 8]byte -+} -+ -+func (h *sha384Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha384Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha384Hash{evpHash: c}, nil -+} -+ -+// NewSHA512 returns a new SHA512 hash. -+func NewSHA512() hash.Hash { -+ h := sha512Hash{evpHash: newEvpHash(crypto.SHA512)} -+ if h.marshallable { -+ return &sha512Marshal{h} -+ } -+ return &h -+} -+ -+type sha512Hash struct { -+ *evpHash -+ out [512 / 8]byte -+} -+ -+func (h *sha512Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha512Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha512Hash{evpHash: c}, nil -+} -+ +// sha512State layout is taken from +// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95. +type sha512State struct { @@ -4269,70 +4157,12 @@ index 00000000000000..6fd3a518906004 + marshaledSize512 = len(magic512) + 8*8 + 128 + 8 +) + -+type sha384Marshal struct { -+ sha384Hash -+} -+ -+type sha512Marshal struct { -+ sha512Hash -+} -+ -+func (h *sha384Marshal) MarshalBinary() ([]byte, error) { -+ buf := make([]byte, 0, marshaledSize512) -+ return h.AppendBinary(buf) -+} -+ -+func (h *sha512Marshal) MarshalBinary() ([]byte, error) { ++func (d *sha512State) MarshalBinary() ([]byte, error) { + buf := make([]byte, 0, marshaledSize512) -+ return h.AppendBinary(buf) ++ return d.AppendBinary(buf) +} + -+func (h *sha384Marshal) 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 -+} -+ -+func (h *sha512Marshal) UnmarshalBinary(b []byte) error { -+ if len(b) < len(magic512) { -+ return errors.New("crypto/sha512: invalid hash state identifier") -+ } -+ if string(b[:len(magic512)]) != magic512 { -+ return errors.New("crypto/sha512: invalid hash state identifier") -+ } -+ if len(b) != marshaledSize512 { -+ return errors.New("crypto/sha512: invalid hash state size") -+ } -+ d := (*sha512State)(h.hashState()) -+ if d == nil { -+ return errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ b = b[len(magic512):] ++func (d *sha512State) UnmarshalBinary(b []byte) error { + b, d.h[0] = consumeUint64(b) + b, d.h[1] = consumeUint64(b) + b, d.h[2] = consumeUint64(b) @@ -4349,32 +4179,7 @@ index 00000000000000..6fd3a518906004 + return nil +} + -+func (h *sha384Marshal) AppendBinary(buf []byte) ([]byte, error) { -+ d := (*sha512State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ buf = append(buf, magic384...) -+ buf = appendUint64(buf, d.h[0]) -+ buf = appendUint64(buf, d.h[1]) -+ buf = appendUint64(buf, d.h[2]) -+ buf = appendUint64(buf, d.h[3]) -+ buf = appendUint64(buf, d.h[4]) -+ buf = appendUint64(buf, d.h[5]) -+ buf = appendUint64(buf, d.h[6]) -+ buf = appendUint64(buf, d.h[7]) -+ buf = append(buf, d.x[:d.nx]...) -+ buf = append(buf, make([]byte, len(d.x)-int(d.nx))...) -+ buf = appendUint64(buf, d.nl>>3|d.nh<<61) -+ return buf, nil -+} -+ -+func (h *sha512Marshal) AppendBinary(buf []byte) ([]byte, error) { -+ d := (*sha512State)(h.hashState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ buf = append(buf, magic512...) ++func (d *sha512State) AppendBinary(buf []byte) ([]byte, error) { + buf = appendUint64(buf, d.h[0]) + buf = appendUint64(buf, d.h[1]) + buf = appendUint64(buf, d.h[2]) @@ -4389,118 +4194,6 @@ index 00000000000000..6fd3a518906004 + return buf, nil +} + -+// NewSHA3_224 returns a new SHA3-224 hash. -+func NewSHA3_224() hash.Hash { -+ return &sha3_224Hash{ -+ evpHash: newEvpHash(crypto.SHA3_224), -+ } -+} -+ -+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[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha3_224Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha3_224Hash{evpHash: c}, nil -+} -+ -+// NewSHA3_256 returns a new SHA3-256 hash. -+func NewSHA3_256() hash.Hash { -+ return &sha3_256Hash{ -+ evpHash: newEvpHash(crypto.SHA3_256), -+ } -+} -+ -+type sha3_256Hash struct { -+ *evpHash -+ out [256 / 8]byte -+} -+ -+func (h *sha3_256Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha3_256Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha3_256Hash{evpHash: c}, nil -+} -+ -+// NewSHA3_384 returns a new SHA3-384 hash. -+func NewSHA3_384() hash.Hash { -+ return &sha3_384Hash{ -+ evpHash: newEvpHash(crypto.SHA3_384), -+ } -+} -+ -+type sha3_384Hash struct { -+ *evpHash -+ out [384 / 8]byte -+} -+ -+func (h *sha3_384Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha3_384Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha3_384Hash{evpHash: c}, nil -+} -+ -+// NewSHA3_512 returns a new SHA3-512 hash. -+func NewSHA3_512() hash.Hash { -+ return &sha3_512Hash{ -+ evpHash: newEvpHash(crypto.SHA3_512), -+ } -+} -+ -+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[:]...) -+} -+ -+// Clone returns a new [hash.Hash] object that is a deep clone of itself. -+// The duplicate object contains all state and data contained in the -+// original object at the point of duplication. -+func (h *sha3_512Hash) Clone() (hash.Hash, error) { -+ c, err := h.clone() -+ if err != nil { -+ return nil, err -+ } -+ return &sha3_512Hash{evpHash: c}, nil -+} -+ +// appendUint64 appends x into b as a big endian byte sequence. +func appendUint64(b []byte, x uint64) []byte { + return append(b, @@ -6142,138 +5835,6 @@ index 00000000000000..5a948eafdbc6a7 + return 1; +} \ No newline at end of file -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c -new file mode 100644 -index 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 @@ -6788,10 +6349,10 @@ index 00000000000000..da5c7636173775 +} 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..c8f599f71c0b20 +index 00000000000000..437312ad795fc3 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/shims.h -@@ -0,0 +1,416 @@ +@@ -0,0 +1,413 @@ +#include // size_t +#include // uint64_t + @@ -7024,13 +6585,8 @@ index 00000000000000..c8f599f71c0b20 +DEFINEFUNC(int, EVP_DigestVerifyInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ +DEFINEFUNC(int, EVP_DigestVerifyFinal, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen), (ctx, sig, siglen)) \ +DEFINEFUNC_1_1_1(int, EVP_DigestVerify, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ -+DEFINEFUNC_LEGACY_1_0(int, MD5_Init, (GO_MD5_CTX_PTR c), (c)) \ -+DEFINEFUNC_LEGACY_1_0(int, MD5_Update, (GO_MD5_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ -+DEFINEFUNC_LEGACY_1_0(int, MD5_Final, (unsigned char *md, GO_MD5_CTX_PTR c), (md, c)) \ -+DEFINEFUNC_LEGACY_1_0(int, SHA1_Init, (GO_SHA_CTX_PTR c), (c)) \ -+DEFINEFUNC_LEGACY_1_0(int, SHA1_Update, (GO_SHA_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ -+DEFINEFUNC_LEGACY_1_0(int, SHA1_Final, (unsigned char *md, GO_SHA_CTX_PTR c), (md, c)) \ +DEFINEFUNC_1_1(const GO_EVP_MD_PTR, EVP_md5_sha1, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_ripemd160, (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), ()) \ @@ -7038,6 +6594,8 @@ index 00000000000000..c8f599f71c0b20 +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha256, (void), ()) \ +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha384, (void), ()) \ +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha512, (void), ()) \ ++DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha512_224, (void), ()) \ ++DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha512_256, (void), ()) \ +DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_224, (void), ()) \ +DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_256, (void), ()) \ +DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_384, (void), ()) \ @@ -7380,7 +6938,7 @@ index 00000000000000..93281d6cffc352 +} 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..f342f221ea0c92 +index 00000000000000..33134548830d3e --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go @@ -0,0 +1,160 @@ @@ -7421,7 +6979,7 @@ index 00000000000000..f342f221ea0c92 + // 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) ++ md = loadHash(crypto.MD5SHA1).md + } else { + h, err := hashFuncHash(fh) + if err != nil { @@ -7700,6 +7258,572 @@ index 00000000000000..73891afeab93d7 + } + return new(big.Int).SetBytes(b) +} +diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/CryptoKit.o b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/CryptoKit.o +new file mode 100644 +index 0000000000000000000000000000000000000000..cedd5b03bd3078586649300d1baa94c8b12549f1 +GIT binary patch +literal 100952 +zcmeFa3t&{$wLX3(6CglLq6CeKVN_J8jwHNHl++oMz(gk!Nr3dqWD=5rq=Y2qp+rSv +z1Da`|jf%b0>TPIkn{d6ow4z4E8pKDev<0zBtJa{XV5nk?7!=I!`_A5b=FCYZiH|<+ +z|IdMwZ`NLW?Z?_{uf6s@^Z4!OkN-x~vw_xM1 +zVZX1PfxBZQ{@8HiIvsZ@nPINUDT2{U8C;6yVFK?lOvL5&*7{b~ir0e9%goOU((2XD +z3&bmy7m1g)%QfvMY*?h$AUNW$*IQmz>#Hs*PoAYGc)g+Jsd9Ll!K>?HQJ$bQEk?bN +z==B!Y)K-^OEDO+~<#o$;c_n|3sl14O<<;C!wzPJpx3<2@SM6JBZl7ba5LhAQQl<+1 +zC%OB#jaksX%8Htx0?p<9QkJLM@pD<8EWRIjy}nZK((0lWKEX1Vw^^2#6eaj=D34~) +ziuUd3SK2`B%W&p7gBiP%#A}C4+H;90Ps`ObSw%22UU|KhOTJy~En88v%vV;iw9@Mh +zEzg!LvMbpH*rDosNI{bDdP|CGi-H_;d6Q*%tul)Z<*~mGv@bp=7I?++SW#6}T +zDqs`g%BigO&8e)bfHKP}D`YtX)rWk!zUu4CihVW66~4Uc`l{N>tI7g~9j4xlvYO@2 +z>Lq2h)w1F+`9j*J>b2p8sh?T%WSuOBrfK54D~pTDoprUPzKYtiV%1sXV}4uz{JFm3 +zy6UppdY#X4!DgK)GI{Zpb(F-v5uSna&PC3J&IQiAT-R*} +z_kfe_-;wQq-sR8kaQPQ>y8M67@_(M(C+hWQZg4d_dR_j^7NA2mrZd*n*nP+~yfAzVZLI30OKkb4n#&I(QUH*F# +zkRvmBpDf~MDIl}g?2BFV8@Nta^D2zEC&ATRH`!$orDXZpT%>e>+ZjxKF3bN%q{O)_ +zpQ+wrRK$=q-!C-!Cd4+on(q;#klEUo6UTm|BW$%zZ|jqjb*O8C3czS^`#(@^Td8x{ +ztt$PMXb{XZ%GG?5&d|II8vI($ESn&tnKyIJpKu24tgGjZsy +zyZK4Bsm=+#pvjrk4=gQnXQ1E(Xyqqpep{A*k1k0it-b?(L8QYBGh6y{qFn3J*b+U< +zZyb2_IKw-a|9MfJe|zlY5jRZIwAhm!ajxexyTH_39sG-{n^n5kt>}8n21-b*8_|uH +zx%l*nSA%QxbFQZn1)=BFvq|+CYnM%TH;-Uu*SaT#em{T(=pwOk?51G)(^FzkPPe%p +z7v*Yue`CX|#~79B>f0&W(!2^r^ErBok%P`xwYi!f7SlkV0(#<;G+(6W1EkcGg(4}( +zki@Y>E)JwBy9w%T5QP6t9o_!-bbNyD7xls9>N;hPJ+5`WJ=Z!HJ3Y<i{`h%cU+h@^bFI@o#^a}=h0YF#-p(gepzz12PCY-eP1FuT +zq8Im>V2#DS^y1iwtC0gfxh2#eHy)hq^8d{>X+t68J-338s|AKmC-@SD|(PUmAxcRtC#dOoL~(W%?Mp3Ava +z&!L;C+rOa0slRfqc`0`Fqu|i9iGDo-+lKeah<(KOLhK`%zr~BX7x8D+j@U;$zr%|a +zzmI(+dlwR30^!+>KMP*QpUgkHw(X6=TC>@;?Y+3HZEq)JZF|d>wXJ(HnAv~G+O{_( +zYuh_Xu5E8m&f4}K81E*ywsj-pz9{f_La_6@*{}52Gm~G+Onxo7586Nv^}n5&$uDFk +z|26rw%w#y+BgvrmCBK9vt;0R~GxzA8?9uPK#%6*zZ-`fxI-=*-!T*4!~zuaKWcO?efE!NLLb^0R8OWmE}K@<%j1Ii?N@}nRKCC +zI96@Ide#av+#vMXoZxDPrxf1EweF-p314)Z%hE+(vF(gw +zI-5LQO{-qOnvGY#&1lMgF{5e0j*KRle3S3@8BHtx(6nG@Q{AqNrp%X`vUfY0>Rxs< +zt@@*D-Gs@m#_d?*uwaU4f>Y_h5h%x9{I+Y`XEyhgw`13y!sd4frS@G8tqK9G{Can# +z4Ryw@{x1l^jS3f-K?IA%x=fj8Th82i!kq)J1TZ8ng&9&ICYOJ*1ZRjTK1YF +zS+N;d0!#s0U_kY7;?FR9SIG3Ew_Vzj1Rwee?u((ITXDxubo7g7>BZds7u|3QS^nQ+ +z^6$*@f1HIy%Mdo`@#%oUtgkH?e$tVPNH%QviRhOrZ%~G-t&|a~^gt1_Z$m&Jvq8qn +z2o(Bf&GNsOZFvW4v2W*5e0GAL+r`Rh8}{{LBtim)7t0?h$4GG>Z-X%5N} +z(Z1qpmd(UGZbsmTS?O+Ofc+uL-|TK))!_Djiiy?Lmy23IOg{2BS5deBXkTs$qOZw% +z%|Bx_gb<#=B!B@AY^TGuZk^6(ewgDyBSM&fXhOzj+5ThqLqCOE~!oSwR3NyPzaLEDYc#HNA6eeQOb{=Sj+Oqv02Q;T==eA|r +z``=7H0!REh^;#T%r_1u&zPB)l@TqX0AN8E$@^8ay8$HbT^*kT-#JHNP5?mKnA=tY` +z3pdL@x!MSy(PwhxjZpvuUM +zedI__j=Q-A*1jA|MSzh#QA5O)cjr&^MKgZpT`!~2XRH5P} +z7v>^13bP|>PoHh6%P=lV*r|V_pG+{OVm$SknJY*0FM1f{QQ5Z#!-u6UIcgTH>8y?T +z)^=C3zB`nTPRi@ky)Mg}$uA|p +zAcd^gLO`r9daS29VyPWHJEG1ea&@4mys%WGxHm;R^*)K0+x7TH^v&Q~a4-VT3rl*g +z?-~Rzdt_!+p9_Au`Rd;0tej7_@kFpTF7}ZZ)?E|#$*!|^xvUWA;!#jA9(6U}kl<>b +z(|g1*Kca3FR+1e#KVQ=KGoQ)j4hI`@wS&(YaJ37riybm& +z=fFANg^Slm06s{L*DevUeG?nfXK1j+vw!WfyqbKZ?>(3Qw{T1FK7XV4c^a>6Q=X1( +z*r4b7o6-B+!6c3gqSfp!_#m+@$2zI%K{TY-hqER9oaT=Rg5W$i(|I;-x9I^rN^tw( +z^A5fa17NI*=^Maj-WZIm4i)`8ccY>zCs9j%( +z#`g$gcpS#yZf3mYX~GtwBisL8Sj+fTf6Hh^QnvpYH@iaP=!9{ILB#aM+Mw(LdkHz} +zpJn-15#;SGN(p`JXBqq0Ked!7wu0gpI&l>NbnsH1jM`9?Iwuw>YiC +zj&}ghJyEm6PEv7a#jWc7-kU>5p +z+#vVN(YsAwf%6Z9v|>u}Bvc-&iPIPvu^4OwB~ppHct7og?B55QKlv{Iix{>n|6%Mx +z12f|}>@s^@%~v`Gm;zb;cLzvy`Ma^%ue}k6#yerNtsk&4TGr=CV$8{Pc96qurF{R{QP#TzkLVF@fgYV{C2$TJ5b2ioHc%0k_TZGqb1B7 +z_}0vhz8o8lOS1G6AlP`Pt8vv%t@e!UHGjQjJQjWIGmfihK{x1EPz+ka=o(>!*xyM* +z6+8BItI(6D)jZ&Y&NO5-yc9++8xf^CgF0#N()gd>eww(W7v4Os!IC_K2f>3`|SKnS3TsGz&cI`M=I@E(L1h!G#plwrnV;elk4z|1aP|vBr +z?B?1@3E3Cc;)zQ`23UG#G10ObKX+vNKWCwJ=d6CMc3Hz`me@6SLszo6j49o*4JYf> +z@9D`kNK$=DMR?uDX)ILE-YTu4L&p9dV}JigFP(>{She;*7UqLZvtdmMh#M>EnV-de +zWQl$>pb%`rMU;;4lTo-Zx#q>_EON%_&5(!udSgFOe#|}P@9c4vqhG^=tu=HaTp%g- +z?RBupHMoC_n`fcM_-!cvR4V2pwx3v1W)Nf!On%d981`rCs +zAU{;o7CA%%pYMcv`VO2yYkIyDFZ&L};I)3d*@0ZaO)=KMPHqQMFhHBR#qfVh(q@>+ +zoJl-J_OxIVzo9k}X4d3dgPHHyiMcJGHlb%7*cJ6eG8w+zp;mG*y6ArcU2pcl!{5&Z +z9n-%-coDtTqUq`Z5o~qc!(!S0ZI-_?i(Bs%VmdqN)aiVLMDS(6rOOa$1De_*i`CtM +z@aoRkN1kcywwM;apf#!Z=!?eN=JjAGI{5sw@nEUjpWTF~r}|;jZk#na{l@~!22VQl +zXQ!C^VIGD0ph+1>7_HL>OB^7%+imF)b`v;JR>NdA$1XTPU4_{e9NQXCZZX`>#%KDR +zjmNAvxZxq-J->l9;>zOaR(enW3fK!CvS88b+l#*_sBUMlOK@S*(aW9Ic$l_!V52^f +zc$9-ai!dfQzRH$=NxL3qi9Pd&opbVVb4t70E>BuiPs9^norzUO;?sQW=~h;aXQ;4Z +zs8n~?3*xY&M+kYy)tuewoR25zqGUvOm_}l5e1Hu=V*SgHEWE{i3 +zp%!$M-jUtBG)kWzA2|D7hA3BSOh2AsV}(13t_qLYj7QsC+IoA=6ID~NdS(iGx;uBJ_9rg3!4o)u-o4ePsiSS&{ +z3AHw-;D9Jfy!P`92uwLj9xQQn7$zV0&`AS4VBq=^oUgYXa%tSqAz{c +z8s6~$U8q^xf18THPE105W%!G1m5hMRlMvldlMpL5{>#Ody?E8x_#7tT=hoOe{2bbK +zBjR!Hidl#gT+G7%5ht1AX|Ml&?x*zWh$4C3c@{)4m&C3MJ{r3)F(2g{A&|7eEgZ30 +zT@b$o7DnvE2b#rMn4t78IIl9!V%ciBBIO4I%70ixI`!V^LF+%Njvg=E#y?V<%3!6b +zZc~=N4yWDzUVY7bOTF2_r6HJTO=G5Oghk_AXtETO6U|{782^!oy%ou1C%Yb*swhVWP8} +zZ)U)J^Q5>c56&4mopd+zmZ}n`@?z0vlMUw7tZ(^oCdm_MT{D;$s!w73%^3KbyK#Sl +zJ0JeW2hnQWjkv#$+vso9GzgiA`iY!8-;&ehU&VJWM0BDbLDroKPlhwdr~07%KKL{Y +zt#o*Pt9~NrEZ82H*5a)Oq9cX_y?*DJINtgc=b3+Y6(2%~rQ}mYV`*-6@zf$;&Bgj# +z3?&ng;VWhiyouGew5Y7yS7N)NthUtVtFErBzSO2^nH7WcBO*~qeSOtjO@HOBlITpH +z?yMEBbC-o;y`FO}PL?UFBtlceP}abEkS#aP*DNdJEOF7JqFT`DNhpfN^mt8rHJAIW$Q8^tx6#mw{_S7{u3xHLQ#;J%-!Mc!&F#)p +z?eWR+xS~?Alhj#F#na_6U7x;~6v$>wj4SapvWj*G6#&QPBH`!dCq|N1> +z6DFUz{djsCa+&$x2;m0bb3c^557$1g{DSs2+;UGE!hX#98g99tD1C&n%P(8*65aYx +z_}5(Sv@fWKaCR6k`~79deYkoVZa(w;j~GIK=KR;2$MLGc{n69r@=bo!Ja2}YSO09j +zS+DrmkhrdhiF3vzIAd&$*6+bq%>5Xr@<}xF`8gQ<3giF6*^{|F@?$wc`%iDgD$?Jd +zhRbJe*HG>Ls{DXo4Abwi2E7>9dzJiE&@pP1TJ7{=K0$oJ7e^(2Y@${AaO*rQx*tMj10)B7cJ1luKW>U%ij#nVEhIYbh^bFR(>b>VxzLc)kPKhbn(4zFtIVwE;@BFA(Mj($x!_ +zcoC^+Gs<}smLDes!s@3GoWb-zl)P<-@f%8>J^w28H^9ez75Sm;kK;4g_zu;-ugXsv +zqJIr&-(d6W&=B%A$m0rYKQ^8Huj5ny5mAw0=kHMMbFlq`%4zOCL`y|enc)7&Uz?YHlE!gdEEn3>Ez~6&@mUax9 +zpK{v?d=!WeYT17ctU@~<0KR~HtAXc&UIqLe=mkI+&-kl=-Jnx}l$!ypM7~pjzec(h +z_+ym&Ix^#piS|uE(mw{GYxdhErULQbK1pJX#P?w#TOfxzHJnY@yMUDAdBFc5eLe8M +zP~JKq%Z09Wz8A>yu97$v7!5ieh{s#@&oM5f_ep#K_%PBpOZrDZJP5Wwgi8Mc91Eqh +zpGVQj9|7M7-UECc$n@UXo~&Y5*J9kQsOry9*z}u_y-{KKO*rSi8o8k0pi_Y_NyeF0)#2p +zFOccy0BO%%F`D)$a61r9v$q3j*BgPf>mLGHj}J)u{U(t1I~_>-JsU{-Jp)Ml9S5Xd +zV}MoY7r(fH_S=o8SCc^h2}t|>6%cwJ{|g|;?;arKT7Z?v=LfPqHNc0!F9K3;-7p%C +z&r3ks-?KpK^*2EB9|dx}?f}wmt7Q68Ano^CK+0b(af-x~fcS6kg%QvW-vW|;9!Pur +zrKIl$(k@p?x(dj4F9%km-BVB2w0FTzl&DGc0V}{S0PX|-TR^sVJ`iu)Nz0J@yMb?k +z|1yyJe@x;>K-O~*$a)G+5&YYLP|aC&z(1m#=YW35S+OzaxbcQ$_hxBud>1$$@6KjDb0l62WIM(I*}hRS{TTAI9UlVQfZag0<4-`g<0T;5@feWp +z_%V>}Xa=&r>ru`c;M3U1v%W_q-Ys#p#7ZFRcS(A-#AKO1TGGeyg)S`TZHcc+ydTJR +zTq^0)B}N0;{v!!Ou1Df)z@H+02ax@E7RdR~31m6H0J1+<0$JbXK$bHN$niKANIgsd +zQhq#;a>vkL%Dn)j9v+g|3gmc5Bxduy$EFa&j8uJ +zr+}>I9w6(vS>k9QT#MZTr2LzxhwXg{$Z^{aWP7&)S>D4ymUADF<&*;1-h3d(EnU*H +zfShN^z#7b}BD9nAVj$_;fpEq4A4vQ;uo3b=vWfz<1E;B!dd3S5bN4+EbEy-A?G +z97uf@0O^nC1F83`fYkeJ$v+E7eUFs*A@oN2RUrLqDi%SwQ2T{ImNyZ|bu$w9BFZ@m +zJ?;RGK2Nmkb1Wuo-y1;6y$qzj`H^x$Es@bi; +zt;qkuxg!5QAjji%AjjiXAoaZyNPWKmq`sdLXnz=psb~KQ5URA_3%n8ez7M4R+ySfy +zeLaxlQVHa^lma;}1p@7PK$hbKvYb@lD&)Hu$a2mH-VFK_AjfYkkmDB#__^e71X92E0;$)#fzF{8SriNV*~I_;IlyLr4x7)_#-Y5v<4)7IgsUC3gmcB +z2XdUfGW|b*9G_eu$L&^`ej|{2t^wW#{1tE?>T3t$Oe^gtzyy^0ED(OiZqYRD4;C#O +zb3%Iwh~-?{4Mg4ABS2)+HUVb>p9M|@{x2{M_$%O5z^8$kGW}b?r$FaQdKnOVg6twm +z!yWT%Z!s|$Lu?aRKwM|hVlsf_6Q_ai5?DaI1N?HyCr$?+F(k2oxEB2Nl24og{sw^s +z#M{AtM)Ha1Q*@WW0wS)M!}!DciL=1(6<9!ou3{$O5BbDPz_$r3Ai}O=+>%dB0Y67z +z0nrNn&5}<{1;0UH0WlK%2PL0)Dfk#OVgYdk_=vIf`iYl;zeivJaU}SMC7(DO{9b_t +z#8KeKqmgVs5n~vgAh3WK1^#TwCw>!rhrj|N;_a9c$tPY8eyP9$BK&5|TFECmz;6*) +zK!lCOYyq-B94uTh7!{uPlSy`#|bPTwqSg@zfA|9 +z2%C&f5m-RyeTPs{^?w_K#T`}t>hE`1N;_&1;p{-KPdUcYr)?vuz-m5E#_s(CoTqmkH7-rY2Y80e4+<@ +zey<|1fS3S&JSI8&Pb>gGL0|##bns_OKG6%lLtp{%4Dd@NpI8WfslWo_nc%OLd}0y! +zEdmRO@aZuRN4zm92j%kGD`|(MPl7TjUnS{8Nw-M)Qc34PiM%Q#-EGrJEf#}7`NFdW{a=#K +zIZx0pNV-bWqcK>_-y-Q5lHM$7ucUWM`YsNxMbi#R`YFk`oiEBCi*aFj4oRm=x6;}z +z8k2(Zt0jGnr0w!kv}(VU^axI-k=Ub18ejLN(_JR|kcm!!ljWuIJ4|$y +ziEcH~T_(EML{Em(HkO}nq8m(ftBLM3(fdtw+=Zd#rfoq$ElSiZwVS4mp6e}jp?*+lO#(Od+L6Mb^ +zxfa{gAn7(qH%a=iq+29?_PHYe21(~jx>eE-NV-kZuSt5dq%W8xa_YbA;R{@z6I0ln0UgBXMS#RmD+SjQ$AXud?1+^g#s>8nkA +z$}9feQeM&FJFyl|0W~cqw@!pYkd`i^aOc_A8qCslNu?yp+6=Pk9y3Iin8iJXeD2$O9$nRe7*jY +zMTYfK-XUovpJb9Z@+q(4*R4`s(c$Ece9EhM_n?$lw32t2>NoQB{>%2BhIL)<{}Ao( +zHt;F0;_1tzyrNb8=KdS`lvnZhGAXa3ta +zUxd +zmr8j>hm$w*Dc>UH+oZgr!^s=@l;14ncT0Iihm$w*DZf+7e=g+}9ZufJr~Dx)pFC6O +zPti)=Jim;5%B%CQ0x7R(C2!WhkxzLC;(lJ6q`ab)yhG;($Ir;8e1nvKOUf%+$(!46 +zg>D|wr#|3*ILbFlB=^{A9r +zbU1k$eSl +zn|u||Es?Z}e;$&winn4SMgBsR&Fd^l3kuJ+B(2u36iGM8^(#}-D*pVIq*Xk4gQQh_ +zwpP+AUizV=Rs7NhnmSY0TP8YoL@56<6TQqt`%U!kO!N^Gos4q@WBvIidX0&`&qTj# +zqQ5yRw7dsR^eIuH{45iFvx)xDL}!i;mH(BAe#=CU8xxxU8Wa6p6a7aMeb_`#92;7m +z$3!=o=!odh{CAn?H%#>BCVJvYq4G;i^!+9}HYPOx3=_S}M0;XG^WR~je{7;3HPL%b +z^idOiG90VXzAiJ-xh8tKiN4=NKWU=hFwq~H=p!cjtdm3AGs#3dO?179zSl%QX`(+i +z(Gl2}8v7q-qG#*0Lrs6}Y7@=(#apx>f0K!R(L{e>qQ~LkvQd7ziOx6C*XwkkIod5I +z`gej2Xi +zDqlU4%2!;Olv`FaGpnL@`m}}K+?@KFnF~OqES#HL=Da$$EVruOnT^-Aa|UQfGJa{a +z8b8fAKtrb2;Co+uwf);tQ&e6n+cF)EWgEUy6KcwqRb-Y-n>jN%HTjY%bgih?hrX$b +zFIj<~s>4rPx{{Kzq&`w1az)+JrM_x(&(LA7Gb?wQ=&@^V?y>=UJiSDGosBaycW!!i +za?+Y3<_}=bO-d?5oii)&bAvt*-v%+gsHg-lm-A(9(K5U&=gZ2vTD)B0!a#&H +z2Lo_T=*_{%nTx-)g&pRXjuie}Ux +z<*M*ShuELy4H<8c0l&c4fw`%9`>RCr4%Q~YHK{=J8YY|O4H-?{J0t~vxiWb=e)tvh +zAh))%8q+U*=92naU(Kv?-6J{Ea~I|=^TMkXFD)KQa+X&Y&AmQ%+4akY%6y4e)R0>? +zoV=Awm)7`dhm$wEs9()9@oSm2Wy|U+>uRoG-*Vtv`PEhnDr$)0y2*>ndBaxm!->qMU)-eKnI)0}E4fQhHtW^*-Gb +z&$}cSZW+H2IxjgXX!i?~D +zo7}I{Ur)KtxhuW3R}~wJ@28~sH{| +z$e|v69sWYPa?Y(U{t}H7Ryb5msR2K^FnLy4&BCJcvJ#HH-YYM=mAho6_d0K_v3JSS +zX!yz;=ili3_Eqz})k)srbrOozdKiHQ>02D3({&2S;Y^_7JFNOXE- +ziEp7<7lUN2UpW^(@RDp14VGjkDJK}z#k84{+rOsls?gp~M}ReNIwHV%Gb*cm72cV3 +z{5j<08AXO4vIgDHBRMlubA3hl62vPiS1$BAoynnHUy13Sm6R1S-TxzO%{3@V)-1wI +zbNwN;t?XZ&GjrzE3{SBZV}f2~Y;M09dfj|EL&LU5mL)7<0H0}^^ZgxWP^q#gvnBM; +zV44fT3b4Z3cH|3ulSYFnMNGjjyhx5)ns9`>8bcPj}Dyadt +zGB;@fXxXjV4D_v*5u@)_JN +zI-NsK>|kpVPl%{%S!gpum5Mf&&oQ-SR<6rAZRV_noR)MsYE#|cQ>dI~RR_{dcFFYV +zDKmyyGII`8vYtLb$upCu4YOqC9H?YH-BfZ)Rt2{32u3USn?V +ztfDIT(31N4++01l$<4i*J}-BXamw{GGZmNSF4A+?Bqz(Cr=MF_TeEP+vg*nkP-2;0 +zVomZ)FOCK(YQ1$8<(0+DeW;8<$&Ix&$+Nh}ou`{We%{_!w89XH)J&W14MzFS>gu9; +zwVx47PtCMh8NQ`Ob>+2?#R`Cv6JK>zWw{=ZE))$LG|K?>*NAw#W@aY8B3G&BkEmIhN!Eu8sC*$;?13w%bhK*;?m_cwadLFMb$TyLE&Eg>v_F% +z=FLyf^t$IcGrW^TQhMczDl~gZS$SD)Jvxn{=We8aP?2h1aK|@D#*CpV&nT-w<;A6g +zlrgM|vgTb?Ry#-`^Ok(uhl8@~eTdb=Y9c=e+!ekR#Z~CMP*+ho%m!9N1GOYSn7p?GRRnVefbHmD%RgvwhEn;w$i(QVf;6-J% +z6$obXik6fIlB+|j$N5_k$6WNGt^!K{dhaXI4U1FEIKjknm^3S^qP(oacSX{|dc-)3 +zuyM#+I-{b*i(&@KpPb|_s$S;H#W{{|m=ZI+q5HOZ!>Xtr!DVr7-uxTYRJbIw+_wUI +zzxlQL-piTp&097TZC$3?8hT_pJ>;Y$ME%StJ!{fS~L&# +zIM5(Ci$iz!i^^f$a@5NzYHEvcP66ZLq=rfOXp%g8G8pB+<-%*4hHB9~*qU+EAB;c( +zq2!`@oW`>Hs_IJ4IPa3mmA(>hWmVC2bv~R-mDSW@=&-(flY@Cnd^NSzmGwj9HT$zr +z2j?v>zkUULedQ8ULkB*cFl@wfm+1}v_c&|sKQVI`v&DHSofWOwR!S+0))QK}D>fT#`FI +zS#zgP!#y4M48$AtE0$CuBCs+3^zyeGY=cD7=KS6&n~Z&N?i^Z_SO3umu*D-vGdp*g +zEoff-R;EF754k*;rR(*+%{5dwh&|haliOSldK+x>Ak(d%F1}0yIHAl9_%h{iGJVx@ +z%o8c-rK){P%NeCtR`3y14N%K;dFNCkcuv-q;z{?#zTs^Yu(b(1oxrb?poVappWwb= +z_%dQsGyMGNmB!uD@a5FrX!sJ?zzjdLzGWJI_Hf(8ekBYmP<3+w8N@fxcVuVinZ$P3 +zTct?h0_YL0s1<3!dDL(2=Pom68FIq+7g26{pg=_9KC+x;j}V!K@HsZ)atqlyd7ie4VBf)r!K3s>+esgw2Sko{t1G; +zysUQW#Y^hS%1fr=aIoArRXK>geRhLtH!#3!ZL +z`D=Txb#RY2j2*PT2!;CpkTbd=iwHem9x}VWXD?k|vh@GdG}If+Alvwc?f&LuV4FVl +z@elf}h4Ibg{hIUd@)4AONjt)yh4*(d|Lk-66OZSN4~7OivnxOGc#encd?)RR$8+J{ +zVr)F+9QdG1nvp5C_-9Z1L0nSk0{ms3_wbC@{JiJHgDd&Q$j}&NFo$D0r9JVGAnY6a +zhn{sNT@Lc(R6Q~ZMy@9w5>(=Cl7nlZ-zonWdtT8`d|=<{4u00bk1b;s{VI}>*ozDrQE;l_13ZvNI` +zxT_G~L&_@(-!I5Z(Ik1}Yy0%e>(xJ8C@K7woHs8sKQBNAUOafdc**kkot33&_}xdo +zh}0ScNBqSHrOWW)(xUQY(ExLKn`Jrp+ByB|!1tZwD;)zDzJ4#{!Y5Mku@rn(R;HTE +z>y+hrCBMs59-C;q|5fwwJ4VKWPnM_J@dH_2K*03E>-Cj-m-5Z)f?+OCeQ#?Q#(~!clt(k@M*E)8Q$qjrZ(oKp +z&l$|4e)q;9lV~TpSuNCmKQ5S2zVdo2mwda}Tebq<(!}qH!`C*2l(%83$cV3{)UQ^Q +zr}{3FLcoiU8rK#Dlg#C*-`#1IS=wa#9B3cD`mW!_{^FC#_zYoP1wO%y5AM4&jF}us +zg0gWg;d0^oZgu^kykwCS(p(Y=xDQ>6`amSD!tVpZ_NO7uhMTsb|Dv9DlKxuPon?j< +zKSQB^Cx22t33)#|TAHa(vWug&=?S1iHjZ1vv~9I%{_ +zPYbXP+>-|?r`nh6tG*tezpVi`d_I0H9FP6a}W{@J;3~p^Wvd*0|oN +z25)csx!SJD7Q8+i?XX5|!n)NG7vVUnMO^;M0jqXrR2uHT-h9_&OVo>P)>C^YTC_V= +z8K0rNc$Cp}&cL!`AnS(g6if7r?TzDmFNdtT4*cHmoo9gW1*&pet?_!>+N|S-Y}a(O +z>(&VTl&5t17>{G>+@tYduw$Wqrp`Hf0`f +zq|6z*%v&gXywvrAGqs0XF@_c`s+sveMgG5|Ep3gpfi%^=w#J3MXIrDt?$h=1k0S3U +z$h!q&+BC*-bW7s`v>|@e#>PdxPguwIzGXdglV-X66}Ip3c`5B3uO*>x324Kq=kte5@?R*UVgAQ77W4!T` +zs!kP +zWwAJa%{-k}+V-b^V_6Sd6GG~F3wl)TMm*NCn&XVVQwPk?a>pS3N{i#@l@qn2t_vcd +z$1^rrP;Z3o*h}e_hWU{|=AAqWve5rV>jJ$`ZPr}9pRLftMr)p))_TWvoX_i98|U|K +zY|Ld_)_3dnB*viijw+qcIs{MH*>vdQD8_VSV;;s?*Z}38O1JDfep4pqdIsivI_CZr +z@Bz;DW0lXfby~fz97g{>gPpY2T+u%H*e$yshn`2HKU1J1^egVd`nHZMEn}M<5xNErmepP8+e;Gh4w-&-hU44)-t;1-AFCZ$Yc6= +zq|ZV6Mr%&58t;3o+EF#;9B#>4=8; +z=R%i}urKz7dEndhSO;HOulw?IH0?$FT;NAN*6-YV>v8Kx2cxvSzD5mtw!oKacfvPq +z8jX7TinZQ8^sDDGEj1c+4DOR~$Ktl&j>CO2Zu&1PZfqG|8i9Kx?lHKd@H4uwzb)PH +zaeLuo*`D{Uj@1359H|E`aHRHJ=t!OV#>(9*o~+v4bDAUdqcf2{)scE|x+C?_C63gK +z?=RiGc2(i-(FOUt4^4EW#wEITCx0_%ccCYLcTcP%b?-Pw>bW-;?k+*Tp0S|Mb)@=G +z)<~4ua~bNfST;pjPQo37J9^Xdv$Rt%rkje+%6X_u8-uhFxFc~}acj6whEIvxbo?e~ +zJM?iU?Th+5JnuJHXM}EOZ&(j?{r%nAbg%N=mL$hx5v7iL_K|arK4mZL_pmiW@Auu7 +z-bX1L$dCD@=Kn;urF}2*v);q=p4RP}^&VODBxuxoQ$+i5w8sHm9)_*|9p%i_v>pVw +z+|dPm%2StWAN?*u%Zt)BpYl{hRL>ZlFV;O{``8XKC&k?3c(>kCxZ7g6;@9{Z^LUHa +zi*aTc&T;O=SZeVif4tt8vtM`I#d#Exra6Co{H80=UMJ@1cD)aM)`(rb-bm0RkUkRq +z7}b7!yX8)<0Ux7IVYiN>!lyZo?mgGq-u(xx_r=0Tjig44 +zSM8p195!(YXxQ=?$c=@}fy=ej{pnijXvjuG=KZ;lzl!|Q-BFM^Fi%T8n5(6tjyvC9 +zq@~WVOxD*`jw{Ex8|fUkWa#1&_>n2c3-6v~Ij!faQCeR7$Bw%=A5~uF=eV_EP2ubP +z5n9ijky>6&gjgFVYNz%@ZT`W%r=Tp#&hj|nhr`QvL4GNG5amCPIJM_FVGHXgYU5GP +zJ@=L(9r3|Odtsv-C+Il7?`_QIQ5x2zV7Yo9&=1u<+LzM58sFnL&Bgf5!8m5Z|7Nsf +zTmy51cB*drnfq|>$L+x24jHdu9Y2P6?Nb@A9mX2`8RpATv_ZsdLEC1`7Bxhyb_rsl +zKEy<7j!~w~n%q8=oF3yLPBX@MtyuqcdBi@$lMjs%TM;t~`O}7!55{t*2V%J+u$5lu +zp~xDKG~xSO5t~sr8zaup?T};EdPl0ho-(#l^NBGTW4O1l#;RCsyiI%fk+)OZA3==S +zjTmV!;up$ySWoH2zMv%m@whP#d<5(0enY-CtogU;@tKGn)wv +z&x`nS+@{A6TfN0~9BX0IM3Ig)WBxg~-^r-Wk +z?Ppt}dftuJ@)!f1ioMk1sGt4(3HWczwy}Mj%d}g*<{pLqU&QJn&SN^;#F(EpKTx}l +zAkJnC$JkKWt_AVjX=u-^O7=6DUSvJBXAWYT4(O9|$6z~L*DmWT+-=NPYCV1V`S8`M +zUq&AFLphf5_l)OGD*tgtrfV;3Axy`4zw8p)VD2jho5 +z0BF{u#$hR_&sA7Vw;#XKrTOhSSK +zHx_>_2lr&$Rk)2Y5XWlbXzjXIP0O1&Lc7js(ekDrcHD*iMLg%74X+^r`y3aDX+Xyt +zBcMmdrYxs0LOc2iVrM1GSeLe__XquGV1LlBZ9qN$5yxGsOwb|i4=saj +z2>PMDXp_EP>3cxfi9Y5*U9g{%xt?9)c&tlnnl&2jk2=e7*BGaEr^_<=yEaQyGxJ!Y +z9Y>jObe1!C34wKhfE#$hUuOS%I{g{iYuEWyTacw#P|3hEbgngKpSEKcDC~U-;31e@pGs;JmVt%T# +z12I-S%TRkz#___>4tLJQVQ{dfY8T;7!HsLsaq6>LcCoFk*3;qNg{|^z<%{TD$x$!%~U!eW^*$v0Cb=0Npq}BWk#0-s$IpTxy +zhJ|ai(3|jMLZ3FQRq4>jLpZ1CI)!>a6Z(zU*L&*zu#9#7D(yz>6R_vS8PnFrgs^-2 +zjc*A1Y18-iN%!NlTUB?^p2T@t+o+Y& +z$HTVK#zN>NXhXs$)5o(fJfG@sLyWh@IxO~uLWX1ZRcz|hWlta;w;(Q$Kzwe+{tD-z +zR-A=mFHd{o+*Ni#KY0f1!ZpPFpMiNyyD*MD*KeN1wT`-M;IU61Z0va^C;HB@$GXC$ +zWj)80_QY6J=yH5uPV?+U?Vp7%gJp=li;5edKg^xuH)Wvz>CnR!(1#P}L(i(UWbk>n +zUE9@*J;yQZIe3O7))F!QsJp@RrRGs8=E~)mD+A4=csa)sux~HY=aPsSR17ruTsl24 +zmllM~C7$1ka%O4`cl{XpM2vse{Xo|^rMJ^DpK#s=TRj~%#y$LJSYv-YO8e-)v9=ZI +zXT~C~V9fOx<}_mx>VRXzn`anmj<;fNGi^Zx=QQIiA!~dc95YdGaP9}&y8!KEe9ALw +zjz8s}fX`Fq{iyGj-93nL)OwHgAZ|?k6CG15W15d)zSoIhCQ>H&vtBtUtk~m_k(3AKNjpu +z9s1%x{eG-XQCOQ;?{kPb&1JJ**3Y_~$NKWlv}iMK9i?4&8_sD|+ZluM91^}Xz7G8p +zYZ1>RCmKQqW~Si~54!lozCPNi>S84pJ!^qh|~ +zgbuW|zYc=^4sFBuFC2$5)}#ZNg!=*9`M7ZnYo2~8&jx5akU^X%&Mov08Tql1YWQ^hn$2^$qB+O^wi$7 +zwSNqKtLKBCT$_&PHWvMCdhmH|*~Rw=9LBu<81uSUt}C1;%Jw<0&*Z*$h`)ga}&>E!p_ad-cD(U(`s1{UqE}K4qCA<0_wKL +zeUzSNP3UcHjL>5?<1;7vd}aSiM$Ln3U{|Gqy|P-5f@f-+&)-L$e`Fhy{=wzLF8`tJ +zr|yLfY3tvCuGMpQu9MswbMA59xlf*DbBxH-#|*epj@jd{-q23oUYU<$_yGKcdCc0j +zM+AJz+cNK#MRmF?%lx|h3D+E>KWUY19?V{ZKNL3pMg7ToH2yH|JQ%ClpC}zDJ686K +zbgt+6JosnvR2(AqjTj$`_AsCKc28`WZ__S+h39~3o)&)2v&-P~-O#q`{w&^Hp7~7k +zEu3i<;Y^d|tLN<~M?cp*((haoz6|GwdTfmI!zL|imdY#6-$TzMRo%za#hIw^8$zFy +z<9<*t>twEVe1DKQ?>3(C^2~DB<%}M@oPqQ++%(k&L;b98F(>pUe_(=x;l1mnGvwxva7_|X>|e^Sq;|2)j4HciW{ +zDCS!+!}9fd_$_&w{>ob=QUB_5@j7=|DAwya=gRlxDv8k4FqBoFXKcLX#`&6MWuhf6 +zdZNCLesICck5st?^Wru>dUmLM88NyV&3eFIQe3VWn^H3q%=t28HnYCW +z`5a;LncGD<<7MXCj7+>%wlCz3UN#=-1cW-iwB*2aY@2sC`r+fUkf{j2%rahiIbWbY +zlO37!xm0;yGT%_`|Ehd*djtI%qW=Lsx}@Eyetr$;7&S_*QhI54X5PmaMu1#I22#%F|0h}61-P7GEkuDg^WMK^64Mo+QafY!G}u- +z%V&InkA#KgGoBc%eK|wa?*Jc{@=Ag-{FU|?mY;#VgZ0lb1b>pKE3E!)L-3_y!pbua +z7)(Dy$#cE`D)L;{@!lg@jp&T=?@;w~{r)QTbDbVc-hsvpHhx33@2m11L-bFsuVL+v +z>*-+qqkqN~);|8#{GsO8Q2xoGcW?0dJJ|Sgef%o?q1yLV`NPytzxlJpTToLM%Gn^XP}J;REHKRmWI55m +zlTc42@MIvKG3eFOfI_h$`%n61l#S?grwvcLK+N +z-U_7L1HeBay#@GN>P4WZ3CQ|a3-mMq^?HCTFGu15wk2Qps{ka~9m@nI4-o(mAuTG2VIBlZ>``?ng%{_xft*iO0@G4}oCg<4oFFkyVx+`pPzmSLeL&`KkeDygA<+gzmF@`w)1ra$Ds-;ZB=vfVl)G18+CJd#z<(XM6Sx&fy>@vOR~#$#Q_4C$9s4kMtct+Etf8 +z&oe;kyHlWNE0A{eAdq&`0%U*I3iOmqx>VA6K=yBjOiz;O6M*cW1O0l0h&KwbUo#{o +z0NJl&;Im(cWdHX8+1@?CmyzBDWP6_x=;;Kqy;}u(I)H3%8&LPJK(@C*pr;(jc9fvL +zUjaK$7wy<0ajnD#iRD1H%O&aA5|d>5z64Rk$$O%h9iY?lp)A$Cs?m=-7b +zhwuRi%I^cRzdIz|DRDFK4`@dlko|o?pyxgyrj&gHkmauivfmD%u3sR_n+)W5CjhCx +zc!8ccAj^vu=!pWdoL=aMAE0E=`2eMx+0zEeaX%~xSdcI6|0qHj~fHz^>90Jqw&_AZ<0GaL+vdysw*$oB6S=-CH^s@>fJ(>j6g +zA>Vz1U%o-0rv*qoHUUwjeKqh^l+z&4b2AYByL_cUPc3j2%B>QZRtltC3GhSYD-`Hi +z47?fn@&%^l0S|$nBhcd#XiotiMEVSYo+RKckh@4=+GOBg!Jj11GeMv|8h8NdQ35@Y +zz*`}w2~0b7mZrTAey>2!A%XVSfz<0(;NQUS5a`(gY=Hb`foTr{{|yuS@I%VkxzE0BKiMK)5J(xxlnS +z$^08Ro%1M%O^Kl>rS{~RH|PoU>@AnopDAnj)- +zkoL1fpr;E+`*}uSS|^b9vsIvHi$HrD5dZD>;m>5?df;~;*CH^j3CMZZ0K5(9Hw#Rw +z0@Civ1$s(>w}4+FFs%?syIU;KlPA#b0^+}YHvX`_8NfA=OA?qi8OZuw!I|Zh70a;%s@OGqc6`1xQ +zQ1>4|+If>e&uU-;@-+xdyBSD3Un$U2CD2|1WWD)7)|&(LL(VNQEd$7UX9Js%o+2>K +z2E-EOo**zS5@EB8OdJ2K`Z;J(b@`0-$mnSf-2}rrsK-x=# +zK+nxU+Q&+Po?0O7r%GVj13=2P0y*yY3G{3La-7!-^t1qPh1^>{Ya|3C2E`e#Qf$V1k@O9|pW`UksAWY5P3dFi+w`iL7nMGTLK53r=5esO2 +zKEoO$~6K8{;A~2Eo5cqkLPedD{^93dnJHW4%eBw93Unww=_-pVVlzigl +z;BOX~NQ5q8UY2~K1N=P#6NwSv9|N-eL?`$Z0wxkMA7d^8l25z>{3L;i#7OWLOFl6j +z{6c|=#F5~ymwaLd_!|T!5=Vo-Rq~0@d32}1L?YISnAatrI0yW0fr&(naSYFu*goQ1 +z@S_AK65$79E|Pqr3rR@=6N%VI$K**qF$?^Bfr&({YcV|6V)?`?!RL7wFp-FLG^Py* +zo0&j#ga4qwL?ZeW^Ni#Zv%&8Ym`HpWe4e{eo_IC*R5~z`_$2rffaDYBfo~I-NW}gx +zhUb0c6LY}N7nn%=4fwT^PrL?vo+|z7yOGxi1LYx +z!A}yHNQA$MSuFWP5BP-w6N!lLW7bPPu>kxH0uza6fWJlZiC*wK1SS&C1pj5pCl-Rg +zM_?jx0{Dj|pI8KbufRm&S>VTG5>h|JCEzCrOe7|PKST0~#o(t1OeDf*#w?b6VhQ+# +z0uzZg@NbrUq7VEAfr-Sk!GA#ViA%w66PQRm2YjBFvVBDO*65uA6N%@7e^~N~rQr7p +zOe9VMf5IpsPb>r9CNPnB9{95*pZIO?9Rd@H=Yzjk@`=mAFBF(aya4>0fovbK9Q+1> +ziA1bhF%L*SaRvBo0uzZ-z=vDaMn-5cQNSo5&VV%ds+a_z6=(yF0HQ2yG%yJ`3YY?n +z08;J-)KA1(6;1h-poz#E&2s8N6O%#PfH#6BP6N$yZvsu64muxr8))JT(51je&_t|> +z(N)0Jpoz0UHvn%3O}qqj3$O_^F$FY0U*~KCy;)*8%Y1lLg{C1K>AY$kbbieNdMRX +zq#tYr(%*Fg>DRh}^j~ZY%8a2ur9W~2>30f&^e+uS`jJ*3{Y58`exV!4`Oi+A2DAY= +zpB+HX+d?4cX9JM)uocMp)(Pai>IT|?JcK_RXak-DbO6r<(tk_>HUQ59wgPFdoxlr# +z-N4B}Dvx#+6|vUZVvUMeZEeEewulEKq9P7kdM!~AJ1jf#x5a|5po=&h*&7)Zv1LTZ +z2;?8tG72dpdq+k^92|LQ-DE?I1N&#wcu~}>HAKPis(9h2mW^czxJ*^wyo>BGhA9J+ZuaG2G~oQF|eCtOKd$# +zq&_S;&=d7V>&x+zC2wf(Oo>kvV~S+>VT)N%2&l5Efd>eKv3Y~jYJjn+m@&ABfvSKD +zXsg?LMY=hKH#mR`c$v}Z4{tGsEJzA(*g5Z=L*94zA^M|9hWP?~e7|?@@7{C2&pq#v +zZ~KMq4c@cc&%yEd_T}wf@AYjP+aRxPZ^Lo%@ukNbyr-U6d7{C4^T`jM^m-S4OFq!S +zch=YFUGbfU<4NBsxN_;K%TG0UKiY9?N27Ob$9Xs|>{x{3#b@4r26B1k0vwM&vkb?L +zr*Ayn=so-Nxu>DL&z^s_(R<;!i_d|!&#l98;kiXPUfy+O7sT0h4vr^wpWF@H-OF%1 +z-L%>S`e-W})N1fVu+e)Za5d22T@PFczXAzE9JFay!co#YsJ0X7O`A(>Z&U0|S+Ia?!OI^piK-#s~)#&}G^A=n= +z*R=*$&UBrHE2q0w;drgzBg5$#8 +zML2%cbqnI$?D_!WAMal7h8FBzg5!pMLxu@})pVJ|oo|PWZA#^+hI)oNO!0ox! +z110LY1jn_W^B_ImyW9(H)VtK%=)DzMfb&bC%Mky3XdU9;=)DP7uJ>+$^lI-lI6vEa +z4vwdKSK!LqeV6(gychZ|_Cd|}t;6|p-w8P0>Ro{2jsBbcaJ_%MzrlO1e+|yB_iaGT +zi-T_uLTe6Q7z7;#&%^ok!3{WG9lQotE)QOT^M&wY7_=R{1y^nkegIcag;(IpiSWrV +z^s(?VoUet?!|`nR99&rqpMm4jzT^9#r27`(czS4c2y_^_3CGppGs6wumEqHHJU_e+ +z$8*DLaJ)2p8IBi+-yVjt4=;?sl;%0~7z{?3n-VZSF&qZ`E)4NXiKS{m}lOcv*5MCkdg-HtIpC!DDFh59jkZ|`_ +zhyOa^*9fEk7WwOh(Z7orZywkICO^bG2|tgMA(a0rIIl4T2y37h2G;l1b_aJ6zY8Wy +z3|xN~VUom{4U9H(#G&5SQIe5#|Xbfc%1MXgqI1g5xzqB +z=Y)MQ`D18?#Rb#D{WFHI5XOBnhM(f%1NwZKun+1LV#5IN^T6e?@qd@cV?n +zOc?#bm|m1H`lAtN2(J-dAlwN3NFAKaT@HK()rZWbv4Zd7X{uBxUos(N4OQoQ^Sgf-#73w;lm{V2H{!4|3ElR`13x8KTo)w +z@B(3r@Dkw@gqI2bGvbF9JS&9%hwv)l9Zxy(vxJ)ouMzGiyiPby_#)v`gf9{P5#cL@ +z8^B1%{I3yiCcHuTCBioe`W`$Esi52s?7-vjW8;(@}S!nzY>0N?2MRq=;_XMm;h +zcPsqAfOTT0g7FlxWOKvLZ&b*Uzm@XDbqV>5tMOGi@_od|bp!c~;ndC_%qlw|#{7K_ +zwDm!LfbdJiXN>Vt|Mt&05fCF^l_Q_+y<5a*%zRZ}~HoClK%p^;hM{ +zXZ!XV@fl8OZRXOt6KL1PNGiLsNyL6@cQ{~9#0rL*=88g3I@KrhTyQzR56Q42jy98gABcJyR +zzXR*O-G3=P=JyId$45Ex*D3xu@fkC}Tkuu6U4Ghs%oCsYC(Oq_gaPp=9w5N}34BA~C%`UI^BWiV4+VZp +z;P(XHxyzm2u)wbfjCPHh{|SK~fI5icfr4CLz60^2EQIeL0IsyY^iq4}z)r#b#Tb*u +z_IZ%fK#c99%CUV1iN8dA#>~h2QyB0I`KlcGyr2Cs@fl-$%%8e%k*~^;kI(C2_$l!j +zGhgbj%8`GQ_&15qnEBmaCw;`IzbZ#Q@4tt@4#E0kjPWb!ugZ~+&*Nb*h|ie$Qh!yB +zeDqsjm?b`A=KJsj0)C{8c&f +z*8OZRXOt6 +z-}oQIXIzc1%8}3h$?ZX>{uo!|t8(PCKeLzkjH~fgIr7>6d5rjsncwAfk7E6)a^$nW +z^fd7qGygHcSLMiO|LRTRGiH9b;Hz@vvp@FPR;T_LGhgbj%8}3h+k?bs%=|%-zbZ#Q +z`+L7ie8$!IsvP<3AO1G+88ctjpDIT_`;-5h_>8OZRXOt6{~T^}>W^_XzA8sP`>Wq1 +zK4a#~`d8)1Xa6?5^TnP&7&Bj%pXFa`hq|M-!LNT5xUs`6-!Jeca+ +zza{WhfgkO3r)LU$T;T5uyag&!EpNZT_~)al{2hU@KGpRe&5kV(_=@Y_8-#g%{Q?kB +z&i2%6gkhSq!{d+u%6WeOF5};Fd{bEduKT`#k2(tiM_PyFI^V&8H*D=-^OqzrT4l +zlAZ0(C#UhR^!!>nb7X%io`g4*YlE%BRx*~G)dKiF>#(LB*{5lKEox=rN3H0PRe(#0 +zxqX@u&j!QETubwWY3wg#g9ib$PYf7webk5>>4H82=ehn0dibq*ct7%Vu7V;hS@{1y +zD_5>dHj>DZE-j!e>Tp*oWaF`9U$i+G^mq8%(onQW&VsUW#%*)(ie7l7_n@YQsXjV@ +z(vzQ=u`*CRrNE{hHeybR2M3H;#S*tfoxe5I`;39mh+jKW%BjCt-T30~0ZofTp1~x% +zO4tJMGJuvyBnqcT@H7{R!D#|dQ~4a6&J99CxYU6Lc+vgA#@IgqMQ|L%q$M&;w6_U_eK=m-Tmzoqbp59-v +zU7Fi5!D8Q}6#Fx&Im5D|u3i+#!j+-wNxS-=$8@zfz~a1s=f$zircO+7la}eGVo{PuwseHBv%eEipR{V?8gUM`U +z#tLbLSE8ngA7gUpP~T9ZfBa>cMgVJQ!XG#gNye-L7R*S{o>r(lGbdulbSho2^J>ne +zg43ydGUx8h#c5h;2#2ccT2DK?usoNVP9=1Gq^#CCnqL-6*C+Q^)_W8$cN7;UzZS}8 +zj#~CiJl1Bwva?tq4!oMk&xCHfK5!*UMsoR#)iRUHs5v+Vz>M{M+P-4T +zK|c06d|P#;4-}^FKsl!uZkAI=ah{y;x5l#*kwiR-ZEu&##9|p!^X4mNPA#3k89P3A +z#{;kGFAp6sGn!dn;nXbeT{ozm>b>m*N?x~J%OgqA&6Cn%X1n@yG!2!2G&>$Sb$@JRN6|K!F(1bJAWXe +z=m=PuGH8D7>oBYc{26vnYJS4hb-%ml^Dx}QTG%z*f4^$ZSxAX;cFatfzpmysU!I-b +z7aT?N6xL!GphK#O*NcJ)y#!DaL&HgjuRoN=o*G@(5xqlp-kA%(iR} +z3?j9NmDh-hNuafUhg51AvZql8OiYh))tmEJ_3l9U=s-xdCwS3)9Oc@`R)rNL32J~^BVfK~;*mrEw~M;I>A)^&3-*L#b;aCjx+@iQ +zO!Ny~T8%-yIoLXZ!xE<)-c*;*6dY4lb@96Bmw3IUJy2)L7_(B!_Vo%W2mQ@;ri?Kw +zrEFgpDYu7{u!RTHWGn#M`|HR-GGtC=ayv)EXpN*{4viKHhG82whB1nBo-wHoxw3A? +zcBwIG$IklwrU8p!GB%LUWhVl$OzIe<7`Ic*`hzC829h~5pG>5tk64fy8YQphvi?@w +zePO(I?%`Ilh%GWcQNP+h=&eD@@Ztb;ZBKbtl$s0T;RwkWF*h|!eqgc%- +z74pwI_I5Vdm&v3u&dS64RmwH!6s99Mbi=Tor{CjmCC?76QZWkY~aq;G^b~e +zWOGN%Xe4ti4)twjkHu$lX8+iMP@g$GruUjVolBwATpF~ViYMZ^0+bnA9ycR}nv{%H +zGP!F+?A?5G8%dexdZv>&8%*4%U&3hz`` +zBmun!mTVVx65~tudo2!F2`iGd_*%@$jTh2Z56ouC7%cjukvS`z#0~{ruC7Sot4EtCfT=SH`-kzFKr(7Va+Tuywc$u6W*OklvFc<5P51U~tgeg-U}H`j +z;|E^l5z*F{u;#!lJdm@uV0y?Lj|D;380v~;Y@;%|J*X`%$BD}Wb6b8qHZE`yxkE=8 +zRxF2TlC*9Itx@}S(_f{=%j$1(4Ek%O#?hzUoBzoK^nU6U@nkj^0izl^7Y=&pG8T4O +zbWJIpwsN{Ksfs3?9D}~7`UFY_O3~7s9K&Hw*{3rp9FgW!YTk;PsdVI(yakS{cs7TY +zKA5*qdX5{lvbjvEP%AFhn4fAc;Iw+8tl)xjfc_RQExr*OuxY4ItZ0nJ%-fus5n*Mr?`nkXi$ktN_6;+FF}u +z#pW6e5NYvAt)%UuTboj9mU(>6UFuo}uC8-Z1A3^!KKAyTV{F?SS?VpDR|cBG)hk2oPMfENCjY%iOLmcak>+L%?{p(^ +zckq**2GjxSm=8QfCE$LeXE@XhpBDH8;1dLUq%b#?0!zUMQ@d&6E53X+3~d?TO#8?* +z2Dh|3Dbs#87>J!am{M%Se5F2CwldX>z3JK^*#*0714@Q9I-;*M!eu&8+LF#S##~ul +z+=&7>s-yyUk`9ijyG=)qrqWcEv1Srz#ix>Z2PzBSp1wh|KLf_K-!lU@!gpKsZ6sjp +zQ@nX$WMB>=qojOuRN6Px&v7g-O@$wN~~ +zyL(&u8S=GwO!53oxw5VZckUR%yFBO+x~m7g9ACtJAKl$OYj@vAr#vMy_G$a* +z#GdW5v;AZ9zry~4Mddq#(rt+{3-|tRqP)8P|Li6#=aJ;yw#{(2*1{*VoU_WXq*r=e +zv}~!o-RErCJHN?;r!t>=_wXz#VBZ#~@OUq7B8A;@w@(4P9+oXj-LHu6`Gf0NQoMy! +z;Tc_Fo4Fq1_208cvP*ltI(E|bEg`on&*iJzGzqt}dDH0j-hK8+bmsrk=(P1kYg>J+ +zyS!H^V)4_EU(zo!)JM+C)cI6ynH6tsJLdEKTY0cM-t5Oc_iyE?&wI(cf3;kDiTk(m +z&=-%-{2>TX}NZcK`mC+hDof`()Bh>Na6&O*q1td;eZS +o)t?7!KI%kW*0{mSca}!?T06*XUUsb2uT>t<8 + +literal 0 +HcmV?d00001 + diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.go b/src/vendor/github.com/microsoft/go-crypto-darwin/internal/cryptokit/cryptokit.go new file mode 100644 index 00000000000000..5d331b8ed22252 @@ -9078,7 +9202,7 @@ index 00000000000000..f59e6f9af58cd4 +} diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/evp.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/evp.go new file mode 100644 -index 00000000000000..f253eeac15bcc0 +index 00000000000000..fcdce4c49b6723 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/evp.go @@ -0,0 +1,338 @@ @@ -9326,7 +9450,7 @@ index 00000000000000..f253eeac15bcc0 +// bytesToCFData turns a byte slice into a CFDataRef. Caller then "owns" the +// CFDataRef and must CFRelease the CFDataRef when done. +func bytesToCFData(buf []byte) C.CFDataRef { -+ return C.CFDataCreate(C.kCFAllocatorDefault, (*C.UInt8)(unsafe.Pointer(&buf[0])), C.CFIndex(len(buf))) ++ return C.CFDataCreate(C.kCFAllocatorDefault, base(buf), C.CFIndex(len(buf))) +} + +// cfDataToBytes turns a CFDataRef into a byte slice. @@ -14803,15 +14927,15 @@ index 00000000000000..1722410e5af193 + return getSystemDirectory() + "\\" + dll +} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index 1c8de570cc2f1f..eff1538ca84b8a 100644 +index 1c8de570cc2f1f..aac6c2a60b6b80 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,19 @@ -+# github.com/golang-fips/openssl/v2 v2.0.4-0.20241211125030-65f2a3ae34cf ++# github.com/golang-fips/openssl/v2 v2.0.4-0.20250107115006-eb155dada337 +## explicit; go 1.22 +github.com/golang-fips/openssl/v2 +github.com/golang-fips/openssl/v2/bbig -+# github.com/microsoft/go-crypto-darwin v0.0.2-0.20250107204503-9cc4ff035cc1 ++# github.com/microsoft/go-crypto-darwin v0.0.2-0.20250109125424-5d0e67f47146 +## explicit; go 1.22 +github.com/microsoft/go-crypto-darwin/bbig +github.com/microsoft/go-crypto-darwin/internal/cryptokit From 12275764022bcd758b5a0ab52e23d2ee11f3fd55 Mon Sep 17 00:00:00 2001 From: George Adams Date: Thu, 9 Jan 2025 14:51:43 +0000 Subject: [PATCH 7/8] skip internal linking --- patches/0006-Add-Darwin-crypto-backend.patch | 28 +++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/patches/0006-Add-Darwin-crypto-backend.patch b/patches/0006-Add-Darwin-crypto-backend.patch index 9e5dbaec7d0..2cc1ae125a2 100644 --- a/patches/0006-Add-Darwin-crypto-backend.patch +++ b/patches/0006-Add-Darwin-crypto-backend.patch @@ -5,6 +5,7 @@ Subject: [PATCH] Add Darwin crypto backend --- .gitignore | 2 + + src/cmd/dist/test.go | 7 +- src/cmd/go/go_boring_test.go | 9 +- src/cmd/go/testdata/script/darwin_no_cgo.txt | 2 + src/crypto/ecdsa/ecdsa.go | 6 +- @@ -26,7 +27,7 @@ Subject: [PATCH] Add Darwin crypto backend src/internal/goexperiment/flags.go | 1 + src/net/lookup_test.go | 3 + src/runtime/pprof/vminfo_darwin_test.go | 6 + - 22 files changed, 523 insertions(+), 14 deletions(-) + 23 files changed, 529 insertions(+), 15 deletions(-) create mode 100644 src/crypto/internal/backend/bbig/big_darwin.go create mode 100644 src/crypto/internal/backend/darwin_darwin.go create mode 100644 src/crypto/internal/backend/fips140/darwin.go @@ -47,6 +48,31 @@ index c6512e64a4ef39..b3b01db73b009d 100644 # This file includes artifacts of Go build that should not be checked in. # For files created by specific development environment (e.g. editor), # use alternative ways to exclude files from git. +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 0de6e80fd985a3..783632120eada8 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -876,7 +876,7 @@ func (t *tester) registerTests() { + } + + if t.extLink() && !t.compileOnly { +- if goos != "android" { // Android does not support non-PIE linking ++ if goos != "android" && !(goos == "darwin" && (strings.Contains(goexperiment, "systemcrypto") || strings.Contains(goexperiment, "darwincrypto"))) { // Android does not support non-PIE linking + t.registerTest("external linking, -buildmode=exe", + &goTest{ + variant: "exe_external", +@@ -1161,6 +1161,11 @@ func (t *tester) internalLink() bool { + if goos == "windows" && goarch == "arm64" { + return false + } ++ if goos == "darwin" && (strings.Contains(goexperiment, "systemcrypto") || strings.Contains(goexperiment, "darwincrypto")) { ++ // linkmode=internal isn't supported with system/darwin crypto. ++ // see https://github.com/microsoft/go-crypto-darwin/issues/33 ++ return false ++ } + // Internally linking cgo is incomplete on some architectures. + // https://golang.org/issue/10373 + // https://golang.org/issue/14449 diff --git a/src/cmd/go/go_boring_test.go b/src/cmd/go/go_boring_test.go index 06478963f4be44..8111b143a1295b 100644 --- a/src/cmd/go/go_boring_test.go From bce2e77045cdf7f72c6ec1e027d18b166a7c2f6d Mon Sep 17 00:00:00 2001 From: George Adams Date: Fri, 10 Jan 2025 10:49:31 +0000 Subject: [PATCH 8/8] add arm64 testing --- .../stages/go-builder-matrix-stages.yml | 4 ++++ eng/pipeline/stages/pool-2.yml | 8 ++++++-- eng/pipeline/stages/run-stage.yml | 17 +++++++---------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/eng/pipeline/stages/go-builder-matrix-stages.yml b/eng/pipeline/stages/go-builder-matrix-stages.yml index e200cf15311..4b587642fa4 100644 --- a/eng/pipeline/stages/go-builder-matrix-stages.yml +++ b/eng/pipeline/stages/go-builder-matrix-stages.yml @@ -84,6 +84,10 @@ stages: - { os: darwin, arch: amd64, config: test } - { experiment: darwincrypto, os: darwin, arch: amd64, config: test } - { experiment: darwincrypto, os: darwin, arch: amd64, config: test, fips: true } + - { os: darwin, arch: arm64, config: devscript } + - { os: darwin, arch: arm64, config: test } + - { experiment: darwincrypto, os: darwin, arch: arm64, config: test } + - { experiment: darwincrypto, os: darwin, arch: arm64, config: test, fips: true } - { os: linux, arch: amd64, config: devscript } - { os: linux, arch: amd64, config: test } - { os: linux, arch: amd64, config: test, distro: ubuntu } diff --git a/eng/pipeline/stages/pool-2.yml b/eng/pipeline/stages/pool-2.yml index 1509f1194d5..5e9bbf76427 100644 --- a/eng/pipeline/stages/pool-2.yml +++ b/eng/pipeline/stages/pool-2.yml @@ -53,5 +53,9 @@ stages: ${{ elseif eq(parameters.os, 'darwin') }}: # https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml#software - vmImage: 'macos-14' - os: macOs + ${{ if eq(parameters.hostArch, 'amd64') }}: + vmImage: 'macos-14' + os: macOS + ${{ else }}: + vmImage: 'macos-latest-internal' + os: macOS diff --git a/eng/pipeline/stages/run-stage.yml b/eng/pipeline/stages/run-stage.yml index 3a5d7af9612..3cf0a0d0add 100644 --- a/eng/pipeline/stages/run-stage.yml +++ b/eng/pipeline/stages/run-stage.yml @@ -149,16 +149,13 @@ stages: # Initialize stage 0 toolset ahead of time so we can track timing data separately from the # build operations. When we call this script again later, it won't download Go again. - - ${{ if eq(parameters.builder.os, 'darwin') }}: - - task: GoTool@0 - inputs: - version: '1.23.3' - displayName: Init upstream stage 0 Go toolset - - ${{ else }}: - - pwsh: | - . eng/utilities.ps1 - Download-Stage0 - displayName: Init stage 0 Go toolset + - pwsh: | + . eng/utilities.ps1 + Download-Stage0 + env: + ${{ if eq(parameters.builder.os, 'darwin') }}: + MS_USE_PATH_GO: '1' + displayName: Init stage 0 Go toolset - template: ../steps/init-submodule-task.yml