From c9eda5b495e52f8cf659ff1c4e64592ff039c147 Mon Sep 17 00:00:00 2001 From: George Adams Date: Wed, 18 Dec 2024 16:19:59 +0000 Subject: [PATCH] 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} | 5290 +++++++++++++---- ....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, 5110 insertions(+), 1266 deletions(-) create mode 100644 patches/0006-Add-Darwin-crypto-backend.patch rename patches/{0006-Vendor-crypto-backends.patch => 0007-Vendor-crypto-backends.patch} (74%) 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 9b01a2e7b5e..254bfe7351a 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 c2c4ab8e704..2e57e22fc67 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 74% rename from patches/0006-Vendor-crypto-backends.patch rename to patches/0007-Vendor-crypto-backends.patch index 5a08acdfbfc..7cc65ab1998 100644 --- a/patches/0006-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 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