diff --git a/eng/doc/fips/README.md b/eng/doc/fips/README.md index c448dcb7da..af8250d8c1 100644 --- a/eng/doc/fips/README.md +++ b/eng/doc/fips/README.md @@ -81,6 +81,7 @@ The following table summarizes common configurations and how suitable each one i | Default | Default | Compliant | Can be used to create a compliant app. FIPS mode is determined by system-wide configuration. Make sure you are familiar with your platform's system-wide FIPS switch, described in [Usage: Runtime](#usage-runtime). | | `GOEXPERIMENT=systemcrypto` | Default | Compliant | Can be used to create a compliant app. The `GOEXPERIMENT` setting is redundant because `systemcrypto` is enabled by default. | | Default | `GODEBUG=fips140=on` or `GOFIPS=1` | Compliant | Can be used to create a compliant app. Depending on platform, the app enables FIPS mode, ensures it is already enabled, or doesn't do any additional checks. The app panics if there is a problem. See [Usage: Runtime](#usage-runtime). | +| Default | `GODEBUG=fips140=only` | Compliant | Same as `fips140=on`, but also panics if a non-FIPS-approved algorithm is used. Note: if the backend does not support a particular algorithm, the call panics rather than falling back to Go standard library crypto. See [Usage: Runtime](#usage-runtime). | | Default | `GO_OPENSSL_VERSION_OVERRIDE=1.1.1k-fips` | Compliant | Can be used to create a compliant app. On Linux, this environment variable causes the runtime to load `libcrypto.so.1.1.1k-fips` instead of using the automatic search behavior. This environment variable has no effect on Windows or macOS. | | `-tags=requirefips` | Default | Compliant | Can be used to create a compliant app. The behavior is the same as `GODEBUG=fips140=on` and `GOFIPS=1`, but no runtime configuration is necessary. See [the `requirefips` section](#build-option-to-require-fips-mode) for more information on when this "locked-in" approach may be useful rather than the flexible approach. | | `MS_GO_NOSYSTEMCRYPTO=1` or `GOEXPERIMENT=nosystemcrypto` | Default | Not compliant | Crypto usage is not FIPS compliant. | @@ -165,8 +166,11 @@ The [Go Runtime FIPS mode](#go-runtime-fips-mode) section describes this in more There is also `GODEBUG=fips140=only`. It acts as `GODEBUG=fips140=on`, but also makes a best effort to panic if a non-FIPS 140-3 compliant algorithm is used. -The `only` setting is not yet supported in the Microsoft build of Go. -(See [microsoft/go#1656 Support `GODEBUG=fips140=only`](https://github.com/microsoft/go/issues/1656).) + +> [!NOTE] +> When `fips140=only` is set with a system crypto backend, the enforcement depends on the backend's algorithm support. +> If the backend does not support a particular FIPS-approved algorithm (e.g. SHA-512/224 on macOS, or CTR mode on macOS), a call to that algorithm will panic rather than falling back to the Go standard library implementation. +> This means that `fips140=only` may restrict the set of usable algorithms compared to `fips140=on`, depending on the platform. > [!NOTE] > The `GODEBUG`, `GOFIPS`, and `GOLANG_FIPS` options described in this section have no effect at build time, only runtime. When the Go program starts up, it examines its environment variables and other platform-specific configurations. This is normally the desired behavior. See [`requirefips`](#build-option-to-require-fips-mode) for info about an optional build tag that may affect FIPS mode. diff --git a/patches/0001-Vendor-external-dependencies.patch b/patches/0001-Vendor-external-dependencies.patch index 2b4156f9af..c76de32cb4 100644 --- a/patches/0001-Vendor-external-dependencies.patch +++ b/patches/0001-Vendor-external-dependencies.patch @@ -41,7 +41,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../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 | 145 + + .../github.com/golang-fips/openssl/v2/aes.go | 157 ++ .../golang-fips/openssl/v2/bbig/big.go | 37 + .../github.com/golang-fips/openssl/v2/big.go | 11 + .../openssl/v2/chacha20poly1305.go | 149 + @@ -55,7 +55,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../golang-fips/openssl/v2/ecdsa.go | 222 ++ .../golang-fips/openssl/v2/ed25519.go | 210 ++ .../github.com/golang-fips/openssl/v2/evp.go | 620 +++++ - .../github.com/golang-fips/openssl/v2/hash.go | 502 ++++ + .../github.com/golang-fips/openssl/v2/hash.go | 518 ++++ .../golang-fips/openssl/v2/hashclone.go | 14 + .../golang-fips/openssl/v2/hashclone_go125.go | 9 + .../github.com/golang-fips/openssl/v2/hkdf.go | 455 ++++ @@ -75,8 +75,10 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../openssl/v2/internal/fakecgo/callbacks.go | 93 + .../openssl/v2/internal/fakecgo/fakecgo.go | 29 + .../openssl/v2/internal/fakecgo/fakecgo.lock | 3 + + .../openssl/v2/internal/fakecgo/freebsd.go | 27 + .../openssl/v2/internal/fakecgo/generate.go | 3 + .../openssl/v2/internal/fakecgo/go_darwin.go | 88 + + .../openssl/v2/internal/fakecgo/go_freebsd.go | 100 + .../openssl/v2/internal/fakecgo/go_libinit.go | 72 + .../openssl/v2/internal/fakecgo/go_linux.go | 100 + .../openssl/v2/internal/fakecgo/go_setenv.go | 18 + @@ -84,6 +86,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../openssl/v2/internal/fakecgo/iscgo.go | 19 + .../openssl/v2/internal/fakecgo/libcgo.go | 39 + .../v2/internal/fakecgo/libcgo_darwin.go | 26 + + .../v2/internal/fakecgo/libcgo_freebsd.go | 20 + .../v2/internal/fakecgo/libcgo_linux.go | 20 + .../openssl/v2/internal/fakecgo/linux.go | 34 + .../openssl/v2/internal/fakecgo/setenv.go | 19 + @@ -97,8 +100,10 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../v2/internal/fakecgo/trampolines_s390x.s | 163 ++ .../openssl/v2/internal/fakecgo/zsymbols.go | 165 ++ .../v2/internal/fakecgo/zsymbols_darwin.go | 59 + + .../v2/internal/fakecgo/zsymbols_freebsd.go | 48 + .../v2/internal/fakecgo/zsymbols_linux.go | 294 ++ .../v2/internal/fakecgo/ztrampolines_darwin.s | 19 + + .../internal/fakecgo/ztrampolines_freebsd.s | 16 + .../v2/internal/fakecgo/ztrampolines_linux.s | 16 + .../internal/fakecgo/ztrampolines_linux_386.s | 110 + .../fakecgo/ztrampolines_linux_amd64.s | 102 + @@ -126,6 +131,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../openssl/v2/internal/ossl/shims.h | 434 +++ .../openssl/v2/internal/ossl/syscall_nocgo.go | 84 + .../v2/internal/ossl/syscall_nocgo_darwin.go | 5 + + .../v2/internal/ossl/syscall_nocgo_freebsd.go | 5 + .../v2/internal/ossl/syscall_nocgo_linux.go | 5 + .../v2/internal/ossl/syscall_nocgo_unix.go | 20 + .../v2/internal/ossl/syscall_nocgo_windows.go | 22 + @@ -226,7 +232,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../internal/xsyscall/xsyscall.go | 6 + .../go-crypto-darwin/internal/xsyscall/zdl.s | 56 + .../internal/xsyscall/zdl_nocgo.go | 48 + - .../microsoft/go-crypto-darwin/xcrypto/aes.go | 144 + + .../microsoft/go-crypto-darwin/xcrypto/aes.go | 152 ++ .../microsoft/go-crypto-darwin/xcrypto/big.go | 16 + .../xcrypto/chacha20poly1305.go | 88 + .../go-crypto-darwin/xcrypto/cipher.go | 114 + @@ -237,7 +243,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../go-crypto-darwin/xcrypto/ed25519.go | 124 + .../microsoft/go-crypto-darwin/xcrypto/evp.go | 339 +++ .../microsoft/go-crypto-darwin/xcrypto/gcm.go | 218 ++ - .../go-crypto-darwin/xcrypto/hash.go | 320 +++ + .../go-crypto-darwin/xcrypto/hash.go | 335 +++ .../go-crypto-darwin/xcrypto/hashclone.go | 17 + .../xcrypto/hashclone_go125.go | 12 + .../go-crypto-darwin/xcrypto/hkdf.go | 103 + @@ -248,7 +254,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../microsoft/go-crypto-darwin/xcrypto/rc4.go | 81 + .../microsoft/go-crypto-darwin/xcrypto/rsa.go | 208 ++ .../microsoft/go-crypto-winnative/LICENSE | 21 + - .../microsoft/go-crypto-winnative/cng/aes.go | 427 +++ + .../microsoft/go-crypto-winnative/cng/aes.go | 435 +++ .../go-crypto-winnative/cng/bbig/big.go | 31 + .../microsoft/go-crypto-winnative/cng/big.go | 30 + .../cng/chacha20poly1305.go | 119 + @@ -258,7 +264,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../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 | 327 +++ + .../microsoft/go-crypto-winnative/cng/hash.go | 342 +++ .../go-crypto-winnative/cng/hashclone.go | 18 + .../cng/hashclone_go125.go | 13 + .../microsoft/go-crypto-winnative/cng/hkdf.go | 133 + @@ -277,7 +283,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result .../internal/subtle/aliasing.go | 32 + .../internal/sysdll/sys_windows.go | 55 + src/vendor/modules.txt | 23 + - 269 files changed, 34097 insertions(+), 7 deletions(-) + 275 files changed, 34387 insertions(+), 7 deletions(-) create mode 100644 src/cmd/internal/telemetry/counter/deps_ignore.go create mode 100644 src/cmd/vendor/github.com/microsoft/go-infra/telemetry/LICENSE create mode 100644 src/cmd/vendor/github.com/microsoft/go-infra/telemetry/README.md @@ -338,8 +344,10 @@ Use a 'go' that was recently built by the current branch to ensure stable result create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/callbacks.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/fakecgo.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/fakecgo.lock + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/freebsd.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/generate.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_darwin.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_freebsd.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_libinit.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_linux.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_setenv.go @@ -347,6 +355,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/iscgo.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_darwin.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_freebsd.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_linux.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/linux.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/setenv.go @@ -360,8 +369,10 @@ Use a 'go' that was recently built by the current branch to ensure stable result create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_s390x.s create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_darwin.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_freebsd.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_linux.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_darwin.s + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_freebsd.s create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_linux.s create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_linux_386.s create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_linux_amd64.s @@ -389,6 +400,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/shims.h create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_darwin.go + create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_freebsd.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_linux.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_unix.go create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_windows.go @@ -2213,7 +2225,7 @@ index 00000000000000..ae4055d2d71303 +// that are used by the backend package. This allows to track +// their versions in a single patch file. diff --git a/src/go.mod b/src/go.mod -index d6c515017a7009..15ab996b3e47e5 100644 +index d6c515017a7009..348650059a4497 100644 --- a/src/go.mod +++ b/src/go.mod @@ -11,3 +11,9 @@ require ( @@ -2222,21 +2234,21 @@ index d6c515017a7009..15ab996b3e47e5 100644 ) + +require ( -+ github.com/golang-fips/openssl/v2 v2.0.4-0.20260217140351-4e237614ceb4 -+ github.com/microsoft/go-crypto-darwin v0.0.3-0.20260130143703-78cb726ef357 -+ github.com/microsoft/go-crypto-winnative v0.0.0-20260127024749-832b168a84e9 ++ github.com/golang-fips/openssl/v2 v2.0.4-0.20260224093412-4123abe33e35 ++ github.com/microsoft/go-crypto-darwin v0.0.3-0.20260224094848-e322614384c3 ++ github.com/microsoft/go-crypto-winnative v0.0.0-20260224091131-eabf5d4ea9cb +) diff --git a/src/go.sum b/src/go.sum -index 2223d2a7c231c1..11a1b9af830278 100644 +index 2223d2a7c231c1..55a77ae199a9af 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,3 +1,9 @@ -+github.com/golang-fips/openssl/v2 v2.0.4-0.20260217140351-4e237614ceb4 h1:2kbDvyeg2zT1dsjfp6I445SCP4ryK88vnIODU+x0W3o= -+github.com/golang-fips/openssl/v2 v2.0.4-0.20260217140351-4e237614ceb4/go.mod h1:EtVnMfLGkB4pihGOH+tXEV0WlXxewWdT1n3GLJEHvpw= -+github.com/microsoft/go-crypto-darwin v0.0.3-0.20260130143703-78cb726ef357 h1:ILqgGD8SGjjtSweSBanrXyX8Aco33yFSJEqsnJgmXHU= -+github.com/microsoft/go-crypto-darwin v0.0.3-0.20260130143703-78cb726ef357/go.mod h1:MTii5PQwRlfUjYpGoF8CPLGwXSHTbLHGRN9FVNML5N0= -+github.com/microsoft/go-crypto-winnative v0.0.0-20260127024749-832b168a84e9 h1:joliMChkkfHV3vAPKzu9kefdw0K+d89A8r9gTm3MFS4= -+github.com/microsoft/go-crypto-winnative v0.0.0-20260127024749-832b168a84e9/go.mod h1:gD686525Li/blRSYwSzFJ6/LJQVFJp7Y0MKp+dmqFbc= ++github.com/golang-fips/openssl/v2 v2.0.4-0.20260224093412-4123abe33e35 h1:SCC2CxzMO45+PyZ4wVN/pUqjjH6BSznbMuSDmIBoV6w= ++github.com/golang-fips/openssl/v2 v2.0.4-0.20260224093412-4123abe33e35/go.mod h1:EtVnMfLGkB4pihGOH+tXEV0WlXxewWdT1n3GLJEHvpw= ++github.com/microsoft/go-crypto-darwin v0.0.3-0.20260224094848-e322614384c3 h1:yV7XVN+idaUMe3FrnP72MJt6swY7inyE/a5lusmVuuA= ++github.com/microsoft/go-crypto-darwin v0.0.3-0.20260224094848-e322614384c3/go.mod h1:MTii5PQwRlfUjYpGoF8CPLGwXSHTbLHGRN9FVNML5N0= ++github.com/microsoft/go-crypto-winnative v0.0.0-20260224091131-eabf5d4ea9cb h1:i7oTrN4NEokm433J/M8EfxiSm/W0feEPtLZ62YzePtQ= ++github.com/microsoft/go-crypto-winnative v0.0.0-20260224091131-eabf5d4ea9cb/go.mod h1:gD686525Li/blRSYwSzFJ6/LJQVFJp7Y0MKp+dmqFbc= golang.org/x/crypto v0.47.1-0.20260113154411-7d0074ccc6f1 h1:peTBrYsTa5Rr+jB2pbgd7X08cFAun6ME4So3jfEkYL4= golang.org/x/crypto v0.47.1-0.20260113154411-7d0074ccc6f1/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/net v0.49.1-0.20260122225915-f2078620ee33 h1:pNHjOZ0w6qb8R9EDmEsBXmV4o2YKLvtRiEk4q5gN5Hg= @@ -2478,10 +2490,10 @@ index 00000000000000..0a6d0d0ef2c0c6 +This project adopts the Go code of conduct: https://go.dev/conduct. diff --git a/src/vendor/github.com/golang-fips/openssl/v2/aes.go b/src/vendor/github.com/golang-fips/openssl/v2/aes.go new file mode 100644 -index 00000000000000..654566d2bff4e0 +index 00000000000000..8d5d44db2ba360 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/aes.go -@@ -0,0 +1,145 @@ +@@ -0,0 +1,157 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -2574,14 +2586,26 @@ index 00000000000000..654566d2bff4e0 + return c.cipher.newCBC(iv, cipherOpEncrypt) +} + ++func (c cipherWithCBC) NewFIPSCBCEncrypter(iv []byte) cipher.BlockMode { ++ return c.cipher.newCBC(iv, cipherOpEncrypt) ++} ++ +func (c cipherWithCBC) NewCBCDecrypter(iv []byte) cipher.BlockMode { + return c.cipher.newCBC(iv, cipherOpDecrypt) +} + ++func (c cipherWithCBC) NewFIPSCBCDecrypter(iv []byte) cipher.BlockMode { ++ return c.cipher.newCBC(iv, cipherOpDecrypt) ++} ++ +func (c cipherWithCTR) NewCTR(iv []byte) cipher.Stream { + return c.cipher.newCTR(iv) +} + ++func (c cipherWithCTR) NewFIPSCTR(iv []byte) cipher.Stream { ++ return c.cipher.newCTR(iv) ++} ++ +func (c cipherWithGCM) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { + return c.cipher.newGCMChecked(nonceSize, tagSize) +} @@ -5858,10 +5882,10 @@ index 00000000000000..4c70cd75a1a553 +} 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..eb0a84acf2232f +index 00000000000000..a48a303bdc8147 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/hash.go -@@ -0,0 +1,502 @@ +@@ -0,0 +1,518 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -6089,6 +6113,22 @@ index 00000000000000..eb0a84acf2232f +var _ hash.Hash = (*Hash)(nil) +var _ HashCloner = (*Hash)(nil) + ++// FIPSApprovedHash reports whether this hash algorithm is FIPS 140-3 approved. ++func FIPSApprovedHash(h hash.Hash) bool { ++ xh, ok := h.(*Hash) ++ if !ok { ++ return false ++ } ++ switch xh.alg.ch { ++ case crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512, ++ crypto.SHA512_224, crypto.SHA512_256, ++ crypto.SHA3_224, crypto.SHA3_256, crypto.SHA3_384, crypto.SHA3_512: ++ return true ++ default: ++ return false ++ } ++} ++ +// hashBufSize is the size of the buffer used for hashing. +// 256 bytes is a reasonable compromise for general purpose use, +// and the resulting evpHash size is still similar to the @@ -8026,7 +8066,7 @@ index 00000000000000..b64466501dee38 + RET diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/callbacks.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/callbacks.go new file mode 100644 -index 00000000000000..5f70632fa7cc33 +index 00000000000000..f29e690cc15b3a --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/callbacks.go @@ -0,0 +1,93 @@ @@ -8034,7 +8074,7 @@ index 00000000000000..5f70632fa7cc33 +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -8125,14 +8165,14 @@ index 00000000000000..5f70632fa7cc33 +) diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/fakecgo.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/fakecgo.go new file mode 100644 -index 00000000000000..7927deb2785263 +index 00000000000000..0ff5482714439b --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/fakecgo.go @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2025 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -8167,6 +8207,39 @@ index 00000000000000..4e9bbeb5c4f3e3 +{ + "commit_hash": "585a4c527464bb6ef91b22aef08d55219c8fab09" +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/freebsd.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/freebsd.go +new file mode 100644 +index 00000000000000..bb73a709e69188 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/freebsd.go +@@ -0,0 +1,27 @@ ++// Copyright 2010 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 freebsd && !cgo ++ ++package fakecgo ++ ++import _ "unsafe" // for go:linkname ++ ++// Supply environ and __progname, because we don't ++// link against the standard FreeBSD crt0.o and the ++// libc dynamic library needs them. ++ ++// Note: when building with cross-compiling or CGO_ENABLED=0, add ++// the following argument to `go` so that these symbols are defined by ++// making fakecgo the Cgo. ++// -gcflags="github.com/ebitengine/purego/internal/fakecgo=-std" ++ ++//go:linkname _environ environ ++//go:linkname _progname __progname ++ ++//go:cgo_export_dynamic environ ++//go:cgo_export_dynamic __progname ++ ++var _environ uintptr ++var _progname uintptr diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/generate.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/generate.go new file mode 100644 index 00000000000000..ca8d5f843f8421 @@ -8270,16 +8343,122 @@ index 00000000000000..d0868f0f790351 + // init_working_dir(); + //#endif +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_freebsd.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_freebsd.go +new file mode 100644 +index 00000000000000..a3ba6bc8228757 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_freebsd.go +@@ -0,0 +1,100 @@ ++// Copyright 2011 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 !cgo ++ ++package fakecgo ++ ++import "unsafe" ++ ++//go:nosplit ++func _cgo_sys_thread_start(ts *ThreadStart) { ++ var attr pthread_attr_t ++ var ign, oset sigset_t ++ var p pthread_t ++ var size size_t ++ var err int ++ ++ // fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug ++ sigfillset(&ign) ++ pthread_sigmask(SIG_SETMASK, &ign, &oset) ++ ++ pthread_attr_init(&attr) ++ pthread_attr_getstacksize(&attr, &size) ++ // Leave stacklo=0 and set stackhi=size; mstart will do the rest. ++ ts.g.stackhi = uintptr(size) ++ ++ err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) ++ ++ pthread_sigmask(SIG_SETMASK, &oset, nil) ++ ++ if err != 0 { ++ print("fakecgo: pthread_create failed: ") ++ println(err) ++ abort() ++ } ++} ++ ++// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function ++// ++//go:linkname x_threadentry_trampoline threadentry_trampoline ++var x_threadentry_trampoline byte ++var threadentry_trampolineABI0 = &x_threadentry_trampoline ++ ++//go:nosplit ++func threadentry(v unsafe.Pointer) unsafe.Pointer { ++ ts := *(*ThreadStart)(v) ++ free(v) ++ ++ setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) ++ ++ // faking funcs in go is a bit a... involved - but the following works :) ++ fn := uintptr(unsafe.Pointer(&ts.fn)) ++ (*(*func())(unsafe.Pointer(&fn)))() ++ ++ return nil ++} ++ ++// here we will store a pointer to the provided setg func ++var setg_func uintptr ++ ++// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c) ++// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us ++// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup ++// This function can't be go:systemstack since go is not in a state where the systemcheck would work. ++// ++//go:nosplit ++func x_cgo_init(g *G, setg uintptr) { ++ var size size_t ++ var attr *pthread_attr_t ++ ++ /* The memory sanitizer distributed with versions of clang ++ before 3.8 has a bug: if you call mmap before malloc, mmap ++ may return an address that is later overwritten by the msan ++ library. Avoid this problem by forcing a call to malloc ++ here, before we ever call malloc. ++ ++ This is only required for the memory sanitizer, so it's ++ unfortunate that we always run it. It should be possible ++ to remove this when we no longer care about versions of ++ clang before 3.8. The test for this is ++ misc/cgo/testsanitizers. ++ ++ GCC works hard to eliminate a seemingly unnecessary call to ++ malloc, so we actually use the memory we allocate. */ ++ ++ setg_func = setg ++ attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) ++ if attr == nil { ++ println("fakecgo: malloc failed") ++ abort() ++ } ++ pthread_attr_init(attr) ++ pthread_attr_getstacksize(attr, &size) ++ // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` ++ // but this should be OK since we are taking the address of the first variable in this function. ++ g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 ++ pthread_attr_destroy(attr) ++ free(unsafe.Pointer(attr)) ++} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_libinit.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_libinit.go new file mode 100644 -index 00000000000000..0eadc51daecc75 +index 00000000000000..e5a66f39d4f3f5 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_libinit.go @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -8456,14 +8635,14 @@ index 00000000000000..9f380c1b431807 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_setenv.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_setenv.go new file mode 100644 -index 00000000000000..6c2f981d730980 +index 00000000000000..e42d84f0b75ea6 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_setenv.go @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -8480,14 +8659,14 @@ index 00000000000000..6c2f981d730980 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_util.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_util.go new file mode 100644 -index 00000000000000..8a71c5a558610a +index 00000000000000..ff190007e8b6c0 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/go_util.go @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -8524,7 +8703,7 @@ index 00000000000000..8a71c5a558610a +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/iscgo.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/iscgo.go new file mode 100644 -index 00000000000000..ba142ec481d026 +index 00000000000000..28af41cc640724 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/iscgo.go @@ -0,0 +1,19 @@ @@ -8532,7 +8711,7 @@ index 00000000000000..ba142ec481d026 +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +// The runtime package contains an uninitialized definition +// for runtime·iscgo. Override it to tell the runtime we're here. @@ -8549,14 +8728,14 @@ index 00000000000000..ba142ec481d026 +var _iscgo bool = true diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo.go new file mode 100644 -index 00000000000000..8a0790faf1d5d9 +index 00000000000000..38f94419397d8d --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo.go @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -8624,6 +8803,32 @@ index 00000000000000..ecdcb2e7852560 +type stack_t struct { + /* not implemented */ +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_freebsd.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_freebsd.go +new file mode 100644 +index 00000000000000..4bfb70c3d5ee9a +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_freebsd.go +@@ -0,0 +1,20 @@ ++// SPDX-License-Identifier: Apache-2.0 ++// SPDX-FileCopyrightText: 2022 The Ebitengine Authors ++ ++//go:build !cgo ++ ++package fakecgo ++ ++type ( ++ pthread_cond_t uintptr ++ pthread_mutex_t uintptr ++) ++ ++var ( ++ PTHREAD_COND_INITIALIZER = pthread_cond_t(0) ++ PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0) ++) ++ ++type stack_t struct { ++ /* not implemented */ ++} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_linux.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/libcgo_linux.go new file mode 100644 index 00000000000000..b08a44a1001bc0 @@ -8692,7 +8897,7 @@ index 00000000000000..42c2b7d0b8176f +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/setenv.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/setenv.go new file mode 100644 -index 00000000000000..8d7b9831d31fae +index 00000000000000..f30af0e1515699 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/setenv.go @@ -0,0 +1,19 @@ @@ -8700,7 +8905,7 @@ index 00000000000000..8d7b9831d31fae +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -8717,14 +8922,14 @@ index 00000000000000..8d7b9831d31fae +var _cgo_unsetenv = &x_cgo_unsetenv_trampoline diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_386.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_386.s new file mode 100644 -index 00000000000000..2e049260d4aad6 +index 00000000000000..43277f854d34aa --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_386.s @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2026 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +#include "textflag.h" +#include "go_asm.h" @@ -8830,14 +9035,14 @@ index 00000000000000..2e049260d4aad6 + RET diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_amd64.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_amd64.s new file mode 100644 -index 00000000000000..0e50f2a91f1b50 +index 00000000000000..a4ca5ea98214fd --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_amd64.s @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +/* +trampoline for emulating required C functions for cgo in go (see cgo.go) @@ -8943,14 +9148,14 @@ index 00000000000000..0e50f2a91f1b50 + RET diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_arm.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_arm.s new file mode 100644 -index 00000000000000..b30bff6c63f411 +index 00000000000000..9aa7eb0accb4c8 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_arm.s @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2026 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +#include "textflag.h" +#include "go_asm.h" @@ -9030,14 +9235,14 @@ index 00000000000000..b30bff6c63f411 + RET diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_arm64.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_arm64.s new file mode 100644 -index 00000000000000..ddd01434d04cda +index 00000000000000..dceb1cac6e821c --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_arm64.s @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +#include "textflag.h" +#include "go_asm.h" @@ -9120,14 +9325,14 @@ index 00000000000000..ddd01434d04cda + RET diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_loong64.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_loong64.s new file mode 100644 -index 00000000000000..89bf8813bade7a +index 00000000000000..72c58f3f4fe01a --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_loong64.s @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2025 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +#include "textflag.h" +#include "go_asm.h" @@ -9214,14 +9419,14 @@ index 00000000000000..89bf8813bade7a + RET diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_ppc64le.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_ppc64le.s new file mode 100644 -index 00000000000000..586ccaf91df1a4 +index 00000000000000..8a1434e60d756d --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_ppc64le.s @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2026 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +#include "textflag.h" +#include "go_asm.h" @@ -9447,14 +9652,14 @@ index 00000000000000..586ccaf91df1a4 + RET diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_riscv64.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_riscv64.s new file mode 100644 -index 00000000000000..50b364773606d1 +index 00000000000000..4154684b63ff51 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/trampolines_riscv64.s @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2026 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +#include "textflag.h" +#include "go_asm.h" @@ -9694,7 +9899,7 @@ index 00000000000000..49fec0cf2f1718 + BR R14 diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols.go new file mode 100644 -index 00000000000000..fb667453f207c0 +index 00000000000000..e1339193b9764d --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols.go @@ -0,0 +1,165 @@ @@ -9703,7 +9908,7 @@ index 00000000000000..fb667453f207c0 +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +package fakecgo + @@ -9928,6 +10133,60 @@ index 00000000000000..960f8168eb88d7 +//go:linkname _pthread_attr_setstacksize _pthread_attr_setstacksize +var _pthread_attr_setstacksize uint8 +var pthread_attr_setstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_setstacksize)) +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_freebsd.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_freebsd.go +new file mode 100644 +index 00000000000000..d69775596fddf3 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_freebsd.go +@@ -0,0 +1,48 @@ ++// Code generated by 'go generate' with gen.go. DO NOT EDIT. ++ ++// SPDX-License-Identifier: Apache-2.0 ++// SPDX-FileCopyrightText: 2022 The Ebitengine Authors ++ ++//go:build !cgo ++ ++package fakecgo ++ ++import "unsafe" ++ ++//go:cgo_import_dynamic purego_malloc malloc "libc.so.7" ++//go:cgo_import_dynamic purego_free free "libc.so.7" ++//go:cgo_import_dynamic purego_setenv setenv "libc.so.7" ++//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so.7" ++//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.7" ++//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.7" ++//go:cgo_import_dynamic purego_abort abort "libc.so.7" ++//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so" ++//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so" ++ ++//go:nosplit ++//go:norace ++func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 { ++ return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0)) ++} ++ ++//go:nosplit ++//go:norace ++func pthread_attr_destroy(attr *pthread_attr_t) int32 { ++ return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0)) ++} ++ ++//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize ++var _pthread_attr_getstacksize uint8 ++var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize)) ++ ++//go:linkname _pthread_attr_destroy _pthread_attr_destroy ++var _pthread_attr_destroy uint8 ++var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy)) diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_linux.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/zsymbols_linux.go new file mode 100644 index 00000000000000..38ee622a366042 @@ -10253,6 +10512,28 @@ index 00000000000000..35ef7ac11cb955 + +TEXT _pthread_attr_setstacksize(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_attr_setstacksize(SB) +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_freebsd.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_freebsd.s +new file mode 100644 +index 00000000000000..da07005c0bc988 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_freebsd.s +@@ -0,0 +1,16 @@ ++// Code generated by 'go generate' with gen.go. DO NOT EDIT. ++ ++// SPDX-License-Identifier: Apache-2.0 ++// SPDX-FileCopyrightText: 2022 The Ebitengine Authors ++ ++//go:build !cgo ++ ++#include "textflag.h" ++ ++// these stubs are here because it is not possible to go:linkname directly the C functions ++ ++TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0 ++ JMP purego_pthread_attr_getstacksize(SB) ++ ++TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0 ++ JMP purego_pthread_attr_destroy(SB) diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_linux.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_linux.s new file mode 100644 index 00000000000000..da07005c0bc988 @@ -11079,7 +11360,7 @@ index 00000000000000..edc21761ddd8ad + diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_stubs.s b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_stubs.s new file mode 100644 -index 00000000000000..6a073bea0944d1 +index 00000000000000..067583d68517a9 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/fakecgo/ztrampolines_stubs.s @@ -0,0 +1,55 @@ @@ -11088,7 +11369,7 @@ index 00000000000000..6a073bea0944d1 +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + -+//go:build !cgo && (darwin || linux) ++//go:build !cgo && (darwin || freebsd || linux) + +#include "textflag.h" + @@ -12798,22 +13079,33 @@ index 00000000000000..0e3e6ca7d87db2 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_darwin.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_darwin.go new file mode 100644 -index 00000000000000..d6a7523ba10197 +index 00000000000000..c5115146e74dc5 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_darwin.go @@ -0,0 +1,5 @@ -+//go:build !cgo && darwin ++//go:build !cgo + +package ossl + +//go:cgo_import_dynamic _ _ "/usr/lib/libSystem.B.dylib" +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_freebsd.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_freebsd.go +new file mode 100644 +index 00000000000000..c16ed6018f87c1 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_freebsd.go +@@ -0,0 +1,5 @@ ++//go:build !cgo ++ ++package ossl ++ ++//go:cgo_import_dynamic _ _ "libc.so.7" diff --git a/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_linux.go b/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_linux.go new file mode 100644 -index 00000000000000..20cb4556a12aa8 +index 00000000000000..9a5cf6f78a7b5b --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/internal/ossl/syscall_nocgo_linux.go @@ -0,0 +1,5 @@ -+//go:build !cgo && linux ++//go:build !cgo + +package ossl + @@ -30464,10 +30756,10 @@ index 00000000000000..a30d07b27ed848 +} 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..cc4bc4f25fefa4 +index 00000000000000..5f005eda956f2c --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go -@@ -0,0 +1,144 @@ +@@ -0,0 +1,152 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -30591,10 +30883,18 @@ index 00000000000000..cc4bc4f25fefa4 + return newCBC(commoncrypto.KCCEncrypt, c.kind, c.key, iv) +} + ++func (c *aesCipher) NewFIPSCBCEncrypter(iv []byte) cipher.BlockMode { ++ return newCBC(commoncrypto.KCCEncrypt, c.kind, c.key, iv) ++} ++ +func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { + return newCBC(commoncrypto.KCCDecrypt, c.kind, c.key, iv) +} + ++func (c *aesCipher) NewFIPSCBCDecrypter(iv []byte) cipher.BlockMode { ++ return newCBC(commoncrypto.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 { @@ -32023,10 +32323,10 @@ index 00000000000000..82a961d974f129 +} 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..e03ae435ac563f +index 00000000000000..f44e192ecbe548 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/hash.go -@@ -0,0 +1,320 @@ +@@ -0,0 +1,335 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -32264,6 +32564,21 @@ index 00000000000000..e03ae435ac563f + return h.alg.size +} + ++// FIPSApprovedHash reports whether this hash algorithm is FIPS 140-3 approved. ++func FIPSApprovedHash(h hash.Hash) bool { ++ xh, ok := h.(*Hash) ++ if !ok { ++ return false ++ } ++ switch xh.alg.ch { ++ case crypto.SHA256, crypto.SHA384, crypto.SHA512, ++ crypto.SHA3_256, crypto.SHA3_384, crypto.SHA3_512: ++ return true ++ default: ++ return false ++ } ++} ++ +var _ hash.Hash = (*Hash)(nil) +var _ HashCloner = (*Hash)(nil) + @@ -33327,10 +33642,10 @@ index 00000000000000..9e841e7a26e4eb + SOFTWARE diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go new file mode 100644 -index 00000000000000..99fe3c7189d9d2 +index 00000000000000..3c235d27562871 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go -@@ -0,0 +1,427 @@ +@@ -0,0 +1,435 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -33424,10 +33739,18 @@ index 00000000000000..99fe3c7189d9d2 + return newCBC(true, bcrypt.AES_ALGORITHM, c.key, iv) +} + ++func (c *aesCipher) NewFIPSCBCEncrypter(iv []byte) cipher.BlockMode { ++ return newCBC(true, bcrypt.AES_ALGORITHM, c.key, iv) ++} ++ +func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { + return newCBC(false, bcrypt.AES_ALGORITHM, c.key, iv) +} + ++func (c *aesCipher) NewFIPSCBCDecrypter(iv []byte) cipher.BlockMode { ++ return newCBC(false, bcrypt.AES_ALGORITHM, c.key, iv) ++} ++ +type noGCM struct { + cipher.Block +} @@ -35181,10 +35504,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..124f7418740ef4 +index 00000000000000..d1d018ccbffa8c --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/hash.go -@@ -0,0 +1,327 @@ +@@ -0,0 +1,342 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -35347,6 +35670,21 @@ index 00000000000000..124f7418740ef4 +var _ hash.Hash = (*Hash)(nil) +var _ HashCloner = (*Hash)(nil) + ++// FIPSApprovedHash reports whether this hash algorithm is FIPS 140-3 approved. ++func FIPSApprovedHash(h hash.Hash) bool { ++ xh, ok := h.(*Hash) ++ if !ok { ++ return false ++ } ++ switch xh.alg.id { ++ case bcrypt.SHA256_ALGORITHM, bcrypt.SHA384_ALGORITHM, bcrypt.SHA512_ALGORITHM, ++ bcrypt.SHA3_256_ALGORITHM, bcrypt.SHA3_384_ALGORITHM, bcrypt.SHA3_512_ALGORITHM: ++ return true ++ default: ++ return false ++ } ++} ++ +// Hash implements [hash.Hash]. +type Hash struct { + alg *hashAlgorithm @@ -38317,18 +38655,18 @@ index 00000000000000..1722410e5af193 + return getSystemDirectory() + "\\" + dll +} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index 48967bc9ee3bd2..1f87e000dbdbc9 100644 +index 48967bc9ee3bd2..b4491a043c1f3f 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,26 @@ -+# github.com/golang-fips/openssl/v2 v2.0.4-0.20260217140351-4e237614ceb4 ++# github.com/golang-fips/openssl/v2 v2.0.4-0.20260224093412-4123abe33e35 +## explicit; go 1.24 +github.com/golang-fips/openssl/v2 +github.com/golang-fips/openssl/v2/bbig +github.com/golang-fips/openssl/v2/internal/fakecgo +github.com/golang-fips/openssl/v2/internal/ossl +github.com/golang-fips/openssl/v2/osslsetup -+# github.com/microsoft/go-crypto-darwin v0.0.3-0.20260130143703-78cb726ef357 ++# github.com/microsoft/go-crypto-darwin v0.0.3-0.20260224094848-e322614384c3 +## explicit; go 1.24 +github.com/microsoft/go-crypto-darwin/bbig +github.com/microsoft/go-crypto-darwin/internal/commoncrypto @@ -38337,7 +38675,7 @@ index 48967bc9ee3bd2..1f87e000dbdbc9 100644 +github.com/microsoft/go-crypto-darwin/internal/security +github.com/microsoft/go-crypto-darwin/internal/xsyscall +github.com/microsoft/go-crypto-darwin/xcrypto -+# github.com/microsoft/go-crypto-winnative v0.0.0-20260127024749-832b168a84e9 ++# github.com/microsoft/go-crypto-winnative v0.0.0-20260224091131-eabf5d4ea9cb +## explicit; go 1.24 +github.com/microsoft/go-crypto-winnative/cng +github.com/microsoft/go-crypto-winnative/cng/bbig diff --git a/patches/0003-Implement-crypto-internal-backend.patch b/patches/0003-Implement-crypto-internal-backend.patch index d0069a1308..a6dcd29e96 100644 --- a/patches/0003-Implement-crypto-internal-backend.patch +++ b/patches/0003-Implement-crypto-internal-backend.patch @@ -29,9 +29,9 @@ desired goexperiments and build tags. src/crypto/internal/backend/bbig/big_cng.go | 12 + .../internal/backend/bbig/big_darwin.go | 12 + .../internal/backend/bbig/big_openssl.go | 12 + - src/crypto/internal/backend/cng_windows.go | 425 +++++++++++++++++ + src/crypto/internal/backend/cng_windows.go | 431 +++++++++++++++++ src/crypto/internal/backend/common.go | 46 ++ - src/crypto/internal/backend/darwin_darwin.go | 432 ++++++++++++++++++ + src/crypto/internal/backend/darwin_darwin.go | 438 ++++++++++++++++++ src/crypto/internal/backend/fips140/cng.go | 35 ++ src/crypto/internal/backend/fips140/darwin.go | 13 + .../internal/backend/fips140/fips140.go | 70 +++ @@ -45,14 +45,14 @@ desired goexperiments and build tags. .../internal/opensslsetup/opensslsetup.go | 68 +++ .../opensslsetup/opensslsetup_test.go | 92 ++++ .../backend/internal/opensslsetup/stub.go | 8 + - src/crypto/internal/backend/nobackend.go | 375 +++++++++++++++ - src/crypto/internal/backend/openssl_linux.go | 424 +++++++++++++++++ + src/crypto/internal/backend/nobackend.go | 376 +++++++++++++++ + src/crypto/internal/backend/openssl_linux.go | 430 +++++++++++++++++ src/crypto/internal/backend/stub.s | 10 + src/crypto/systemcrypto_nocgo_linux.go | 18 + src/go/build/deps_test.go | 24 +- src/internal/buildcfg/exp.go | 47 ++ src/runtime/runtime_boring.go | 5 + - 43 files changed, 2716 insertions(+), 14 deletions(-) + 43 files changed, 2735 insertions(+), 14 deletions(-) create mode 100644 src/cmd/go/systemcrypto_test.go create mode 100644 src/crypto/internal/backend/backend_test.go create mode 100644 src/crypto/internal/backend/bbig/big.go @@ -875,10 +875,10 @@ index 00000000000000..51396c3db1a871 +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..919f3482dcb3d6 +index 00000000000000..ba69d9f74c9fef --- /dev/null +++ b/src/crypto/internal/backend/cng_windows.go -@@ -0,0 +1,425 @@ +@@ -0,0 +1,431 @@ +// 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. @@ -895,6 +895,7 @@ index 00000000000000..919f3482dcb3d6 + "crypto/cipher" + "crypto/internal/backend/fips140" + "crypto/internal/boring/sig" ++ "crypto/internal/fips140only" + "hash" + _ "unsafe" + @@ -907,6 +908,7 @@ index 00000000000000..919f3482dcb3d6 + panic("cngcrypto: " + err.Error()) + } + sig.BoringCrypto() ++ fips140only.BackendApprovedHash = FIPSApprovedHash +} + +// Enabled controls whether FIPS crypto is enabled. @@ -920,6 +922,10 @@ index 00000000000000..919f3482dcb3d6 + return cng.SupportsHash(h) +} + ++func FIPSApprovedHash(h hash.Hash) bool { ++ return cng.FIPSApprovedHash(h) ++} ++ +func SupportsSHAKE(securityBits int) bool { + return cng.SupportsSHAKE(securityBits) +} @@ -1358,10 +1364,10 @@ index 00000000000000..a9682181ffa154 +} diff --git a/src/crypto/internal/backend/darwin_darwin.go b/src/crypto/internal/backend/darwin_darwin.go new file mode 100644 -index 00000000000000..a491519e864dc5 +index 00000000000000..805e95c926a1a1 --- /dev/null +++ b/src/crypto/internal/backend/darwin_darwin.go -@@ -0,0 +1,432 @@ +@@ -0,0 +1,438 @@ +// 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. @@ -1378,6 +1384,7 @@ index 00000000000000..a491519e864dc5 + "crypto/cipher" + "crypto/internal/backend/fips140" + "crypto/internal/boring/sig" ++ "crypto/internal/fips140only" + "hash" + "io" + _ "unsafe" @@ -1391,6 +1398,7 @@ index 00000000000000..a491519e864dc5 + panic("darwincrypto: " + err.Error()) + } + sig.BoringCrypto() ++ fips140only.BackendApprovedHash = FIPSApprovedHash +} + +// Enabled controls whether FIPS crypto is enabled. @@ -1404,6 +1412,10 @@ index 00000000000000..a491519e864dc5 + return xcrypto.SupportsHash(h) +} + ++func FIPSApprovedHash(h hash.Hash) bool { ++ return xcrypto.FIPSApprovedHash(h) ++} ++ +func SupportsSHAKE(securityBits int) bool { return false } +func SupportsCSHAKE(securityBits int) bool { return false } + @@ -2285,10 +2297,10 @@ index 00000000000000..19fd29e19e7b96 +package opensslsetup diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go new file mode 100644 -index 00000000000000..5e16f39dc107c7 +index 00000000000000..cdc768b1e4b57d --- /dev/null +++ b/src/crypto/internal/backend/nobackend.go -@@ -0,0 +1,375 @@ +@@ -0,0 +1,376 @@ +// 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. @@ -2321,7 +2333,8 @@ index 00000000000000..5e16f39dc107c7 + +const RandReader = randReader(0) + -+func SupportsHash(h crypto.Hash) bool { panic("cryptobackend: not available") } ++func SupportsHash(h crypto.Hash) bool { panic("cryptobackend: not available") } ++func FIPSApprovedHash(h hash.Hash) bool { panic("cryptobackend: not available") } + +func SupportsSHAKE(securityBits int) bool { panic("cryptobackend: not available") } +func SupportsCSHAKE(securityBits int) bool { panic("cryptobackend: not available") } @@ -2666,10 +2679,10 @@ index 00000000000000..5e16f39dc107c7 +} diff --git a/src/crypto/internal/backend/openssl_linux.go b/src/crypto/internal/backend/openssl_linux.go new file mode 100644 -index 00000000000000..6121670c0e3659 +index 00000000000000..ccac6ce8ad0b35 --- /dev/null +++ b/src/crypto/internal/backend/openssl_linux.go -@@ -0,0 +1,424 @@ +@@ -0,0 +1,430 @@ +// 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. @@ -2687,6 +2700,7 @@ index 00000000000000..6121670c0e3659 + "crypto/internal/backend/fips140" + _ "crypto/internal/backend/internal/opensslsetup" + "crypto/internal/boring/sig" ++ "crypto/internal/fips140only" + "hash" + + "github.com/golang-fips/openssl/v2" @@ -2711,6 +2725,7 @@ index 00000000000000..6121670c0e3659 + panic("opensslcrypto: " + err.Error() + ": " + openssl.VersionText()) + } + sig.BoringCrypto() ++ fips140only.BackendApprovedHash = FIPSApprovedHash +} + +const RandReader = openssl.RandReader @@ -2719,6 +2734,10 @@ index 00000000000000..6121670c0e3659 + return openssl.SupportsHash(h) +} + ++func FIPSApprovedHash(h hash.Hash) bool { ++ return openssl.FIPSApprovedHash(h) ++} ++ +func SupportsSHAKE(securityBits int) bool { + return openssl.SupportsSHAKE(securityBits) +} diff --git a/patches/0004-Use-crypto-backends.patch b/patches/0004-Use-crypto-backends.patch index 5d95483669..dcdd5b1b21 100644 --- a/patches/0004-Use-crypto-backends.patch +++ b/patches/0004-Use-crypto-backends.patch @@ -15,6 +15,8 @@ Subject: [PATCH] Use crypto backends src/crypto/aes/aes.go | 2 +- src/crypto/aes/aes_test.go | 2 +- src/crypto/boring/boring.go | 4 +- + src/crypto/cipher/cbc.go | 16 ++ + src/crypto/cipher/ctr.go | 7 + src/crypto/cipher/ctr_aes_test.go | 2 +- src/crypto/cipher/gcm.go | 59 +++++- src/crypto/cipher/gcm_test.go | 9 +- @@ -39,14 +41,16 @@ Subject: [PATCH] Use crypto backends src/crypto/fips140/fips140.go | 3 +- src/crypto/hkdf/hkdf.go | 14 ++ src/crypto/hkdf/hkdf_test.go | 2 +- - src/crypto/hmac/hmac.go | 2 +- + src/crypto/hmac/hmac.go | 16 +- src/crypto/hmac/hmac_test.go | 2 +- src/crypto/hpke/aead.go | 14 +- src/crypto/internal/cryptotest/allocations.go | 6 - src/crypto/internal/cryptotest/fips140.go | 8 + src/crypto/internal/cryptotest/hash.go | 3 +- .../internal/cryptotest/implementations.go | 2 +- - .../internal/fips140only/fips140only_test.go | 6 + + src/crypto/internal/fips140hash/hash.go | 3 +- + .../internal/fips140only/fips140only.go | 11 +- + .../internal/fips140only/fips140only_test.go | 52 +++-- src/crypto/internal/fips140test/acvp_test.go | 6 + src/crypto/internal/fips140test/cast_test.go | 2 + src/crypto/internal/fips140test/fips_test.go | 2 +- @@ -64,18 +68,18 @@ Subject: [PATCH] Use crypto backends src/crypto/rsa/boring.go | 13 +- src/crypto/rsa/boring_test.go | 2 +- src/crypto/rsa/darwin.go | 71 +++++++ - src/crypto/rsa/fips.go | 22 +- + src/crypto/rsa/fips.go | 84 ++++---- src/crypto/rsa/notboring.go | 4 +- src/crypto/rsa/pkcs1v15.go | 10 +- src/crypto/rsa/pkcs1v15_test.go | 5 + src/crypto/rsa/pss_test.go | 14 +- - src/crypto/rsa/rsa.go | 16 +- + src/crypto/rsa/rsa.go | 29 +-- src/crypto/rsa/rsa_test.go | 7 +- - src/crypto/sha1/sha1.go | 8 +- + src/crypto/sha1/sha1.go | 11 +- src/crypto/sha1/sha1_test.go | 11 +- src/crypto/sha256/sha256.go | 6 +- src/crypto/sha256/sha256_test.go | 44 ++-- - src/crypto/sha3/sha3.go | 124 +++++++++-- + src/crypto/sha3/sha3.go | 129 ++++++++++-- src/crypto/sha3/sha3_test.go | 18 +- src/crypto/sha512/sha512.go | 14 +- src/crypto/sha512/sha512_test.go | 32 ++- @@ -100,7 +104,7 @@ Subject: [PATCH] Use crypto backends src/hash/notboring_test.go | 9 + src/net/lookup_test.go | 3 + src/os/exec/exec_test.go | 9 + - 96 files changed, 1518 insertions(+), 180 deletions(-) + 100 files changed, 1629 insertions(+), 249 deletions(-) create mode 100644 src/crypto/dsa/boring.go create mode 100644 src/crypto/dsa/notboring.go create mode 100644 src/crypto/ecdsa/badlinkname.go @@ -307,6 +311,78 @@ index 097c37e343fdb8..a5d603896d3890 100644 // Enabled reports whether BoringCrypto handles supported crypto operations. func Enabled() bool { +diff --git a/src/crypto/cipher/cbc.go b/src/crypto/cipher/cbc.go +index 87bafee08ade4f..198de1d17b7e7c 100644 +--- a/src/crypto/cipher/cbc.go ++++ b/src/crypto/cipher/cbc.go +@@ -44,6 +44,12 @@ type cbcEncAble interface { + NewCBCEncrypter(iv []byte) BlockMode + } + ++// fipsCBCEncAble is an interface implemented by ciphers that have a specific ++// optimized implementation of CBC encryption that is compliant with FIPS 140-2. ++type fipsCBCEncAble interface { ++ NewFIPSCBCEncrypter(iv []byte) BlockMode ++} ++ + // NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining + // mode, using the given Block. The length of iv must be the same as the + // Block's block size. +@@ -54,6 +60,9 @@ func NewCBCEncrypter(b Block, iv []byte) BlockMode { + if b, ok := b.(*aes.Block); ok { + return aes.NewCBCEncrypter(b, [16]byte(iv)) + } ++ if cbc, ok := b.(fipsCBCEncAble); ok { ++ return cbc.NewFIPSCBCEncrypter(iv) ++ } + if fips140only.Enforced() { + panic("crypto/cipher: use of CBC with non-AES ciphers is not allowed in FIPS 140-only mode") + } +@@ -123,6 +132,10 @@ type cbcDecAble interface { + NewCBCDecrypter(iv []byte) BlockMode + } + ++type fipsCBCDecAble interface { ++ NewFIPSCBCDecrypter(iv []byte) BlockMode ++} ++ + // NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining + // mode, using the given Block. The length of iv must be the same as the + // Block's block size and must match the iv used to encrypt the data. +@@ -133,6 +146,9 @@ func NewCBCDecrypter(b Block, iv []byte) BlockMode { + if b, ok := b.(*aes.Block); ok { + return aes.NewCBCDecrypter(b, [16]byte(iv)) + } ++ if cbc, ok := b.(fipsCBCDecAble); ok { ++ return cbc.NewFIPSCBCDecrypter(iv) ++ } + if fips140only.Enforced() { + panic("crypto/cipher: use of CBC with non-AES ciphers is not allowed in FIPS 140-only mode") + } +diff --git a/src/crypto/cipher/ctr.go b/src/crypto/cipher/ctr.go +index 8e63ed7e668a4c..10ed72d2540b6e 100644 +--- a/src/crypto/cipher/ctr.go ++++ b/src/crypto/cipher/ctr.go +@@ -36,12 +36,19 @@ type ctrAble interface { + NewCTR(iv []byte) Stream + } + ++type fipsCTRAble interface { ++ NewFIPSCTR(iv []byte) Stream ++} ++ + // NewCTR returns a [Stream] which encrypts/decrypts using the given [Block] in + // counter mode. The length of iv must be the same as the [Block]'s block size. + func NewCTR(block Block, iv []byte) Stream { + if block, ok := block.(*aes.Block); ok { + return aesCtrWrapper{aes.NewCTR(block, iv)} + } ++ if ctr, ok := block.(fipsCTRAble); ok { ++ return ctr.NewFIPSCTR(iv) ++ } + if fips140only.Enforced() { + panic("crypto/cipher: use of CTR with non-AES ciphers is not allowed in FIPS 140-only mode") + } diff --git a/src/crypto/cipher/ctr_aes_test.go b/src/crypto/cipher/ctr_aes_test.go index 1d8ae78674ebe2..1ce8f093834d55 100644 --- a/src/crypto/cipher/ctr_aes_test.go @@ -1494,7 +1570,7 @@ index 57d90f88e93e75..4069ab057a2525 100644 "crypto/md5" "crypto/sha1" diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go -index e7976e25193dfe..9578e1e985c02d 100644 +index e7976e25193dfe..58b357ee52c328 100644 --- a/src/crypto/hmac/hmac.go +++ b/src/crypto/hmac/hmac.go @@ -22,7 +22,7 @@ timing side-channels: @@ -1506,6 +1582,34 @@ index e7976e25193dfe..9578e1e985c02d 100644 "crypto/internal/fips140/hmac" "crypto/internal/fips140hash" "crypto/internal/fips140only" +@@ -37,13 +37,6 @@ import ( + // the returned Hash does not implement [encoding.BinaryMarshaler] + // or [encoding.BinaryUnmarshaler]. + func New(h func() hash.Hash, key []byte) hash.Hash { +- if boring.Enabled { +- hm := boring.NewHMAC(h, key) +- if hm != nil { +- return hm +- } +- // BoringCrypto did not recognize h, so fall through to standard Go code. +- } + h = fips140hash.UnwrapNew(h) + if fips140only.Enforced() { + if len(key) < 112/8 { +@@ -53,6 +46,13 @@ func New(h func() hash.Hash, key []byte) hash.Hash { + panic("crypto/hmac: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode") + } + } ++ if boring.Enabled { ++ hm := boring.NewHMAC(h, key) ++ if hm != nil { ++ return hm ++ } ++ // BoringCrypto did not recognize h, so fall through to standard Go code. ++ } + return hmac.New(h, key) + } + diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go index 4046a9555a8e35..4721a2a7ac04f7 100644 --- a/src/crypto/hmac/hmac_test.go @@ -1635,8 +1739,55 @@ index 2b6cf4b75fc6b7..3a1b9e5cc67ecc 100644 "crypto/internal/impl" "internal/goarch" "internal/goos" +diff --git a/src/crypto/internal/fips140hash/hash.go b/src/crypto/internal/fips140hash/hash.go +index 6d67ee8b3429a1..8f8d5937ea913c 100644 +--- a/src/crypto/internal/fips140hash/hash.go ++++ b/src/crypto/internal/fips140hash/hash.go +@@ -5,14 +5,13 @@ + package fips140hash + + import ( +- fsha3 "crypto/internal/fips140/sha3" + "crypto/sha3" + "hash" + _ "unsafe" + ) + + //go:linkname sha3Unwrap +-func sha3Unwrap(*sha3.SHA3) *fsha3.Digest ++func sha3Unwrap(*sha3.SHA3) hash.Hash + + // Unwrap returns h, or a crypto/internal/fips140 inner implementation of h. + // +diff --git a/src/crypto/internal/fips140only/fips140only.go b/src/crypto/internal/fips140only/fips140only.go +index 1b0a4be6ba5897..72fea1cfa7eed8 100644 +--- a/src/crypto/internal/fips140only/fips140only.go ++++ b/src/crypto/internal/fips140only/fips140only.go +@@ -20,13 +20,20 @@ func Enforced() bool { + return fips140.Enforced() + } + ++// BackendApprovedHash is set by a crypto backend during init to provide ++// backend-specific FIPS hash approval checking. If nil, only the standard ++// library FIPS hash types are recognized as approved. ++var BackendApprovedHash func(h hash.Hash) bool ++ + func ApprovedHash(h hash.Hash) bool { + switch h.(type) { + case *sha256.Digest, *sha512.Digest, *sha3.Digest: + return true +- default: +- return false + } ++ if BackendApprovedHash != nil { ++ return BackendApprovedHash(h) ++ } ++ return false + } + + func ApprovedRandomReader(r io.Reader) bool { diff --git a/src/crypto/internal/fips140only/fips140only_test.go b/src/crypto/internal/fips140only/fips140only_test.go -index 96df536d56f345..5ed6026962a17c 100644 +index 96df536d56f345..13874c097447bd 100644 --- a/src/crypto/internal/fips140only/fips140only_test.go +++ b/src/crypto/internal/fips140only/fips140only_test.go @@ -17,6 +17,7 @@ import ( @@ -1647,18 +1798,85 @@ index 96df536d56f345..5ed6026962a17c 100644 "crypto/internal/cryptotest" "crypto/internal/fips140" "crypto/internal/fips140only" -@@ -47,6 +48,11 @@ import ( +@@ -39,6 +40,7 @@ import ( + "io" + "math/big" + "os" ++ "runtime" + "strings" + "testing" - func TestFIPS140Only(t *testing.T) { - cryptotest.MustSupportFIPS140(t) -+ // TODO: Remove this skip when SystemCrypto supports fips140=only mode. -+ // https://github.com/microsoft/go/issues/1656 -+ if boring.Enabled { -+ t.Skip("SystemCrypto does not support fips140=only mode") +@@ -89,7 +91,12 @@ func testFIPS140Only(t *testing.T) { + expectPanic(t, func() { cipher.NewCFBEncrypter(aesBlock, iv) }) + expectPanic(t, func() { cipher.NewCFBDecrypter(aesBlock, iv) }) + +- cipher.NewCTR(aesBlock, iv) ++ if boring.Enabled && runtime.GOOS == "darwin" { ++ // The darwin crypto backend doesn't support CTR. ++ expectPanic(t, func() { cipher.NewCTR(aesBlock, iv) }) ++ } else { ++ cipher.NewCTR(aesBlock, iv) ++ } + expectPanic(t, func() { cipher.NewCTR(notAESBlock, iv) }) + + expectPanic(t, func() { cipher.NewOFB(aesBlock, iv) }) +@@ -310,13 +317,16 @@ bXVL8iKLrG91IYQByUHZIn3WVAd2bfi4MfKagRt0ggd4 + expectErr(t, errRet2(hpke.DHKEM(ecdh.X25519()).NewPublicKey(make([]byte, 32)))) + hpkeK, err := hpke.MLKEM768().GenerateKey() + expectNoErr(t, err) +- expectErr(t, errRet2(hpke.Seal(hpkeK.PublicKey(), hpke.HKDFSHA256(), hpke.ChaCha20Poly1305(), nil, nil))) +- expectErr(t, errRet2(hpke.Open(hpkeK, hpke.HKDFSHA256(), hpke.ChaCha20Poly1305(), nil, make([]byte, 2000)))) +- +- // fips140=only mode should prevent any operation that would make the FIPS +- // 140-3 module set its service indicator to false. +- if !fips140.ServiceIndicator() { +- t.Errorf("service indicator not set") ++ if !boring.Enabled { ++ // TODO implement error handling in backends that check for fips140only.Enforced(). ++ expectErr(t, errRet2(hpke.Seal(hpkeK.PublicKey(), hpke.HKDFSHA256(), hpke.ChaCha20Poly1305(), nil, nil))) ++ expectErr(t, errRet2(hpke.Open(hpkeK, hpke.HKDFSHA256(), hpke.ChaCha20Poly1305(), nil, make([]byte, 2000)))) ++ ++ // fips140=only mode should prevent any operation that would make the FIPS ++ // 140-3 module set its service indicator to false. ++ if !fips140.ServiceIndicator() { ++ t.Errorf("service indicator not set") ++ } + } + } + +@@ -329,16 +339,22 @@ type readerWrap struct { + } + + func withApprovedHash(f func(crypto.Hash)) { +- f(crypto.SHA224) +- f(crypto.SHA256) +- f(crypto.SHA384) +- f(crypto.SHA512) +- f(crypto.SHA3_224) +- f(crypto.SHA3_256) +- f(crypto.SHA3_384) +- f(crypto.SHA3_512) +- f(crypto.SHA512_224) +- f(crypto.SHA512_256) ++ for _, h := range []crypto.Hash{ ++ crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512, ++ crypto.SHA512_224, crypto.SHA512_256, ++ } { ++ if boring.Enabled && !boring.SupportsHash(h) { ++ continue ++ } ++ f(h) ++ } ++ for _, h := range []crypto.Hash{crypto.SHA3_224, crypto.SHA3_256, crypto.SHA3_384, crypto.SHA3_512} { ++ if boring.Enabled { ++ // TODO implement fallbacks that checks hash.Hash ++ continue ++ } ++ f(h) + } - if !fips140only.Enforced() { - cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestFIPS140Only$", "-test.v") - cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=only") + } + + func withNonApprovedHash(f func(crypto.Hash)) { diff --git a/src/crypto/internal/fips140test/acvp_test.go b/src/crypto/internal/fips140test/acvp_test.go index 6a0b46af2bbe40..fbe7ba6992d0ce 100644 --- a/src/crypto/internal/fips140test/acvp_test.go @@ -1730,7 +1948,7 @@ index 29648b9f386ed7..b3113a3ee2e1fa 100644 "crypto/internal/randutil" "internal/godebug" diff --git a/src/crypto/md5/md5.go b/src/crypto/md5/md5.go -index f1287887ff5e25..b2e26308349566 100644 +index f1287887ff5e25..61e9cc23e5667f 100644 --- a/src/crypto/md5/md5.go +++ b/src/crypto/md5/md5.go @@ -12,6 +12,7 @@ package md5 @@ -1745,7 +1963,7 @@ index f1287887ff5e25..b2e26308349566 100644 // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal // state of the hash. func New() hash.Hash { -+ if boring.Enabled && boring.SupportsHash(crypto.MD5) { ++ if boring.Enabled && boring.SupportsHash(crypto.MD5) && !fips140only.Enforced() { + return boring.NewMD5() + } d := new(digest) @@ -2425,7 +2643,7 @@ index 00000000000000..bff8ac449c9a3b + return builder.Bytes() +} diff --git a/src/crypto/rsa/fips.go b/src/crypto/rsa/fips.go -index fb2395886b053b..ac0ad4f9490a8b 100644 +index fb2395886b053b..18334e731f9349 100644 --- a/src/crypto/rsa/fips.go +++ b/src/crypto/rsa/fips.go @@ -6,7 +6,7 @@ package rsa @@ -2437,24 +2655,72 @@ index fb2395886b053b..ac0ad4f9490a8b 100644 "crypto/internal/fips140/rsa" "crypto/internal/fips140hash" "crypto/internal/fips140only" -@@ -71,7 +71,7 @@ func SignPSS(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte +@@ -71,7 +71,17 @@ func SignPSS(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte hash = opts.Hash } - if boring.Enabled && rand.IsDefaultReader(random) { ++ if err := checkFIPS140OnlyPrivateKey(priv); err != nil { ++ return nil, err ++ } ++ if fips140only.Enforced() && !fips140only.ApprovedHash(hash.New()) { ++ 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 fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) { ++ return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode") ++ } ++ + if boring.Enabled && rand.IsDefaultReader(random) && boring.SupportsRSASaltLength(true, opts.saltLength()) && boring.SupportsRSAPrivateKey(priv.N.BitLen(), len(priv.Primes)) && boring.SupportsHash(hash) { bkey, err := boringPrivateKey(priv) if err != nil { return nil, err -@@ -134,7 +134,7 @@ func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts +@@ -82,16 +92,6 @@ func SignPSS(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte + + h := fips140hash.Unwrap(hash.New()) + +- if err := checkFIPS140OnlyPrivateKey(priv); err != nil { +- return nil, err +- } +- if fips140only.Enforced() && !fips140only.ApprovedHash(h) { +- 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 fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) { +- return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode") +- } +- + k, err := fipsPrivateKey(priv) + if err != nil { + return nil, err +@@ -134,7 +134,14 @@ func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts return err } - if boring.Enabled { ++ if err := checkFIPS140OnlyPublicKey(pub); err != nil { ++ return err ++ } ++ if fips140only.Enforced() && !fips140only.ApprovedHash(hash.New()) { ++ 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 && boring.SupportsRSASaltLength(false, opts.saltLength()) && boring.SupportsRSAPublicKey(pub.N.BitLen()) && boring.SupportsHash(hash) { bkey, err := boringPublicKey(pub) if err != nil { return err +@@ -147,13 +154,6 @@ func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts + + h := fips140hash.Unwrap(hash.New()) + +- if err := checkFIPS140OnlyPublicKey(pub); err != nil { +- return err +- } +- if fips140only.Enforced() && !fips140only.ApprovedHash(h) { +- return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode") +- } +- + k, err := fipsPublicKey(pub) + if err != nil { + return err @@ -203,10 +203,12 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l // // See [EncryptOAEP] for additional details. @@ -2489,24 +2755,66 @@ index fb2395886b053b..ac0ad4f9490a8b 100644 k := priv.Size() if len(ciphertext) > k || k < hash.Size()*2+2 { -@@ -331,7 +333,7 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ +@@ -331,7 +333,14 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ return nil, err } - if boring.Enabled { ++ if err := checkFIPS140OnlyPrivateKey(priv); err != nil { ++ return nil, err ++ } ++ if fips140only.Enforced() && hash != crypto.Hash(0) && !fips140only.ApprovedHash(hash.New()) { ++ 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.SupportsRSAPrivateKey(priv.N.BitLen(), len(priv.Primes)) && boring.SupportsRSAPKCS1v15Signature(hash) { bkey, err := boringPrivateKey(priv) if err != nil { return nil, err -@@ -374,7 +376,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) +@@ -339,13 +348,6 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [ + return boring.SignRSAPKCS1v15(bkey, hash, hashed) + } + +- if err := checkFIPS140OnlyPrivateKey(priv); err != nil { +- return nil, err +- } +- if fips140only.Enforced() && !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) { +- 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") +- } +- + k, err := fipsPrivateKey(priv) + if err != nil { + return nil, err +@@ -374,7 +376,14 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) return err } - if boring.Enabled { ++ if err := checkFIPS140OnlyPublicKey(pub); err != nil { ++ return err ++ } ++ if fips140only.Enforced() && hash != crypto.Hash(0) && !fips140only.ApprovedHash(hash.New()) { ++ 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 && boring.SupportsRSAPublicKey(pub.N.BitLen()) && boring.SupportsRSAPKCS1v15Signature(hash) { bkey, err := boringPublicKey(pub) if err != nil { return err +@@ -385,13 +394,6 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) + return nil + } + +- if err := checkFIPS140OnlyPublicKey(pub); err != nil { +- return err +- } +- if fips140only.Enforced() && !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) { +- return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode") +- } +- + k, err := fipsPublicKey(pub) + if err != nil { + return err diff --git a/src/crypto/rsa/notboring.go b/src/crypto/rsa/notboring.go index 2abc0436405f8a..3e4d6f3eef61e6 100644 --- a/src/crypto/rsa/notboring.go @@ -2652,7 +2960,7 @@ index e03f4ab06603c6..a9d9daba2fd6ce 100644 t.Fatal(err) } diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go -index b94b129867727b..9482325d58fe06 100644 +index b94b129867727b..149dd4321f8d72 100644 --- a/src/crypto/rsa/rsa.go +++ b/src/crypto/rsa/rsa.go @@ -43,8 +43,8 @@ package rsa @@ -2683,16 +2991,36 @@ index b94b129867727b..9482325d58fe06 100644 case *PKCS1v15DecryptOptions: if l := opts.SessionKeyLen; l > 0 { -@@ -314,8 +315,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { +@@ -314,8 +315,14 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { return nil, err } - if boring.Enabled && rand.IsDefaultReader(random) && - (bits == 2048 || bits == 3072 || bits == 4096) { ++ if fips140only.Enforced() && bits < 2048 { ++ return nil, errors.New("crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode") ++ } ++ if fips140only.Enforced() && bits%2 == 1 { ++ return nil, errors.New("crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode") ++ } ++ + if boring.Enabled && rand.IsDefaultReader(random) && boring.SupportsRSAPublicKey(bits) { bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits) if err != nil { return nil, err +@@ -352,12 +359,6 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { + + random = rand.CustomReader(random) + +- if fips140only.Enforced() && bits < 2048 { +- return nil, errors.New("crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode") +- } +- if fips140only.Enforced() && bits%2 == 1 { +- return nil, errors.New("crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode") +- } + if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) { + return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode") + } diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go index 124fba1e8a4faa..af6d8e9291af62 100644 --- a/src/crypto/rsa/rsa_test.go @@ -2719,7 +3047,7 @@ index 124fba1e8a4faa..af6d8e9291af62 100644 msg := []byte("hi!") enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg) diff --git a/src/crypto/sha1/sha1.go b/src/crypto/sha1/sha1.go -index 46e47df1d32cf2..0fb56a3831c8a2 100644 +index 46e47df1d32cf2..05a1368f9833e5 100644 --- a/src/crypto/sha1/sha1.go +++ b/src/crypto/sha1/sha1.go @@ -10,7 +10,7 @@ package sha1 @@ -2731,7 +3059,24 @@ index 46e47df1d32cf2..0fb56a3831c8a2 100644 "crypto/internal/fips140only" "errors" "hash" -@@ -271,12 +271,12 @@ func (d *digest) constSum() [Size]byte { +@@ -113,7 +113,7 @@ func (d *digest) Reset() { + // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal + // state of the hash. + func New() hash.Hash { +- if boring.Enabled { ++ if boring.Enabled && !fips140only.Enforced() { + return boring.NewSHA1() + } + d := new(digest) +@@ -153,7 +153,6 @@ func (d *digest) Write(p []byte) (nn int, err error) { + } + + func (d *digest) Sum(in []byte) []byte { +- boring.Unreachable() + // Make a copy of d so that caller can keep writing and summing. + d0 := *d + hash := d0.checkSum() +@@ -271,12 +270,12 @@ func (d *digest) constSum() [Size]byte { // Sum returns the SHA-1 checksum of the data. func Sum(data []byte) [Size]byte { @@ -2942,7 +3287,7 @@ index a18a536ba2896f..7b3b37c3b0c10d 100644 } } diff --git a/src/crypto/sha3/sha3.go b/src/crypto/sha3/sha3.go -index 48c67e9fe11005..3fe46309e0fda8 100644 +index 48c67e9fe11005..1ab7ae42462ef6 100644 --- a/src/crypto/sha3/sha3.go +++ b/src/crypto/sha3/sha3.go @@ -8,6 +8,7 @@ package sha3 @@ -3013,7 +3358,7 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 // Outline the allocation for up to 512 bits of output to the caller's stack. out := make([]byte, 64) return sumSHAKE256(out, data, length) -@@ -99,7 +118,9 @@ func sumSHAKE256(out, data []byte, length int) []byte { +@@ -99,36 +118,53 @@ func sumSHAKE256(out, data []byte, length int) []byte { // SHA3 is an instance of a SHA-3 hash. It implements [hash.Hash]. // The zero value is a usable SHA3-256 hash. type SHA3 struct { @@ -3024,7 +3369,13 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 } //go:linkname fips140hash_sha3Unwrap crypto/internal/fips140hash.sha3Unwrap -@@ -109,26 +130,38 @@ func fips140hash_sha3Unwrap(sha3 *SHA3) *sha3.Digest { +-func fips140hash_sha3Unwrap(sha3 *SHA3) *sha3.Digest { ++func fips140hash_sha3Unwrap(sha3 *SHA3) hash.Hash { ++ if sha3.boringS != nil { ++ return sha3.boringS ++ } + return &sha3.s + } // New224 creates a new SHA3-224 hash. func New224() *SHA3 { @@ -3068,7 +3419,7 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 *s = *New256() } } -@@ -136,53 +169,81 @@ func (s *SHA3) init() { +@@ -136,53 +172,81 @@ func (s *SHA3) init() { // Write absorbs more data into the hash's state. func (s *SHA3) Write(p []byte) (n int, err error) { s.init() @@ -3151,7 +3502,7 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 r := *d return &r, nil } -@@ -190,23 +251,30 @@ func (d *SHA3) Clone() (hash.Cloner, error) { +@@ -190,23 +254,30 @@ func (d *SHA3) Clone() (hash.Cloner, error) { // SHAKE is an instance of a SHAKE extendable output function. // The zero value is a usable SHAKE256 hash. type SHAKE struct { @@ -3186,7 +3537,7 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 } // NewCSHAKE128 creates a new cSHAKE128 XOF. -@@ -215,7 +283,10 @@ func NewSHAKE256() *SHAKE { +@@ -215,7 +286,10 @@ func NewSHAKE256() *SHAKE { // 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 { @@ -3198,7 +3549,7 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 } // NewCSHAKE256 creates a new cSHAKE256 XOF. -@@ -224,7 +295,10 @@ func NewCSHAKE128(N, S []byte) *SHAKE { +@@ -224,7 +298,10 @@ func NewCSHAKE128(N, S []byte) *SHAKE { // 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 { @@ -3210,7 +3561,7 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 } // Write absorbs more data into the XOF's state. -@@ -232,6 +306,9 @@ func NewCSHAKE256(N, S []byte) *SHAKE { +@@ -232,6 +309,9 @@ func NewCSHAKE256(N, S []byte) *SHAKE { // It panics if any output has already been read. func (s *SHAKE) Write(p []byte) (n int, err error) { s.init() @@ -3220,7 +3571,7 @@ index 48c67e9fe11005..3fe46309e0fda8 100644 return s.s.Write(p) } -@@ -240,35 +317,54 @@ func (s *SHAKE) Write(p []byte) (n int, err error) { +@@ -240,35 +320,54 @@ func (s *SHAKE) Write(p []byte) (n int, err error) { // Any call to Write after a call to Read will panic. func (s *SHAKE) Read(p []byte) (n int, err error) { s.init()