From dddedbf8e98847d29c2b480592e92449257e46f4 Mon Sep 17 00:00:00 2001 From: George Adams Date: Thu, 16 Jan 2025 16:59:23 +0000 Subject: [PATCH] Check that each patch file is buildable (#1495) * Check that each patch file is buildable * merge patch 5 and 3 * group outputs --- .github/workflows/patch-build.yml | 38 + .github/workflows/test.yml | 7 +- ...03-Implement-crypto-internal-backend.patch | 707 ++++++++++++++++- patches/0005-Add-backend-code-gen.patch | 744 ------------------ ...patch => 0005-Update-default-go.env.patch} | 0 ... 0006-Skip-failing-tests-on-Windows.patch} | 0 ...OFIPS-when-running-the-Go-toolchain.patch} | 0 ...pport-for-logging-used-Windows-APIs.patch} | 0 ... 0009-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 11 files changed, 748 insertions(+), 748 deletions(-) create mode 100644 .github/workflows/patch-build.yml delete mode 100644 patches/0005-Add-backend-code-gen.patch rename patches/{0006-Update-default-go.env.patch => 0005-Update-default-go.env.patch} (100%) rename patches/{0007-Skip-failing-tests-on-Windows.patch => 0006-Skip-failing-tests-on-Windows.patch} (100%) rename patches/{0008-unset-GOFIPS-when-running-the-Go-toolchain.patch => 0007-unset-GOFIPS-when-running-the-Go-toolchain.patch} (100%) rename patches/{0009-add-support-for-logging-used-Windows-APIs.patch => 0008-add-support-for-logging-used-Windows-APIs.patch} (100%) rename patches/{0010-remove-long-path-support-hack.patch => 0009-remove-long-path-support-hack.patch} (100%) rename patches/{0011-Omit-internal-go.mod-files-used-for-codegen.patch => 0010-Omit-internal-go.mod-files-used-for-codegen.patch} (100%) rename patches/{0012-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch => 0011-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch} (100%) diff --git a/.github/workflows/patch-build.yml b/.github/workflows/patch-build.yml new file mode 100644 index 00000000000..7d3db5e09e8 --- /dev/null +++ b/.github/workflows/patch-build.yml @@ -0,0 +1,38 @@ +# Copyright (c) Microsoft Corporation. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# This job tests that each patch file is buildable (in numerical order) + +name: "Patch Build" + +on: + pull_request: + branches: [ microsoft/* ] + +jobs: + build_patches: + name: Patches Build in Order + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + submodules: true + + - name: Set mock git config name/email + run: | + git config --global user.email "joe@blogs.com" + git config --global user.name "Joe Blogs" + + - name: Build patches + run: | + for file in $(ls -v patches/*.patch); do + echo "::group::Building $file" + cd go + git am --whitespace=nowarn ../$file + cd src + bash make.bash + cd ../../ + echo "::endgroup::" + done diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 922fae84320..b72cd125c4f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,12 +17,17 @@ on: pull_request: branches: [ microsoft/* ] +# Cancel existing runs if user makes another push. +concurrency: + group: "${{ github.ref }}" + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: check_patches: name: Patches Apply Cleanly runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - run: pwsh eng/run.ps1 submodule-refresh -shallow diff --git a/patches/0003-Implement-crypto-internal-backend.patch b/patches/0003-Implement-crypto-internal-backend.patch index 5f7843d851e..1d0c32f60f6 100644 --- a/patches/0003-Implement-crypto-internal-backend.patch +++ b/patches/0003-Implement-crypto-internal-backend.patch @@ -6,6 +6,8 @@ Subject: [PATCH] Implement crypto/internal/backend --- .gitignore | 2 + src/crypto/internal/backend/backend_test.go | 30 ++ + src/crypto/internal/backend/backendgen.go | 20 + + .../internal/backend/backendgen_test.go | 284 ++++++++++++++ src/crypto/internal/backend/bbig/big.go | 17 + .../internal/backend/bbig/big_boring.go | 12 + src/crypto/internal/backend/bbig/big_cng.go | 12 + @@ -27,9 +29,26 @@ Subject: [PATCH] Implement crypto/internal/backend src/crypto/internal/backend/openssl_linux.go | 362 ++++++++++++++++++ src/crypto/internal/backend/stub.s | 10 + src/go/build/deps_test.go | 7 +- + .../exp_allowcryptofallback_off.go | 9 + + .../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 + src/runtime/runtime_boring.go | 5 + - 24 files changed, 1932 insertions(+), 1 deletion(-) + 41 files changed, 2493 insertions(+), 1 deletion(-) create mode 100644 src/crypto/internal/backend/backend_test.go + create mode 100644 src/crypto/internal/backend/backendgen.go + create mode 100644 src/crypto/internal/backend/backendgen_test.go create mode 100644 src/crypto/internal/backend/bbig/big.go create mode 100644 src/crypto/internal/backend/bbig/big_boring.go create mode 100644 src/crypto/internal/backend/bbig/big_cng.go @@ -50,6 +69,20 @@ Subject: [PATCH] Implement crypto/internal/backend create mode 100644 src/crypto/internal/backend/nobackend.go create mode 100644 src/crypto/internal/backend/openssl_linux.go create mode 100644 src/crypto/internal/backend/stub.s + 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 diff --git a/.gitignore b/.gitignore index c6512e64a4ef39..b3b01db73b009d 100644 @@ -100,6 +133,322 @@ index 00000000000000..c2c06d3bff8c74 +func TestUnreachableExceptTests(t *testing.T) { + UnreachableExceptTests() +} +diff --git a/src/crypto/internal/backend/backendgen.go b/src/crypto/internal/backend/backendgen.go +new file mode 100644 +index 00000000000000..acf0113bbefb6c +--- /dev/null ++++ b/src/crypto/internal/backend/backendgen.go +@@ -0,0 +1,20 @@ ++// 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. ++ ++package backend ++ ++// Generate files and Go code based on the set of backends: ++// ++// - The build constraint in nobackend.go. ++// - Go files in the runtime package that detect issues with backend selection ++// and report an error at compile time. ++// ++// Runs in -mod=readonly mode so that it is able to run during each crypto ++// backend patch. This is before the final vendoring refresh patch, so it would ++// normally fail to build due to inconsistent vendoring. ++ ++// Use "go generate -run TestGenerated crypto/internal/backend" ++// to run only this generator. ++ ++//go:generate go test -run TestGenerated -fix +diff --git a/src/crypto/internal/backend/backendgen_test.go b/src/crypto/internal/backend/backendgen_test.go +new file mode 100644 +index 00000000000000..1ba948c8f207e5 +--- /dev/null ++++ b/src/crypto/internal/backend/backendgen_test.go +@@ -0,0 +1,284 @@ ++// 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. ++ ++package backend ++ ++import ( ++ "bytes" ++ "flag" ++ "go/build/constraint" ++ "go/parser" ++ "go/token" ++ "os" ++ "path/filepath" ++ "sort" ++ "strings" ++ "testing" ++) ++ ++var fix = flag.Bool("fix", false, "if true, update the generated files to the wanted value") ++ ++const runtimePackageDir = "../../../runtime" ++ ++// backendErrPrefix is the prefix of the generated backend error files. Any file ++// in the runtime package with this prefix will be considered a backend error ++// file, so it's important that this prefix is unique or this generator may ++// delete unexpected files. ++const backendErrPrefix = "backenderr_gen_" ++ ++const generateInstruction = "run 'go generate crypto/internal/backend' to fix" ++ ++// TestGeneratedBackendErrorFiles tests that the current nobackend constraint ++// is correct. ++// ++// Generate the build constraint in nobackend.go. This build constraint enables ++// nobackend when all of the backends are not enabled. This constraint is fairly ++// long and would not be trivial to maintain manually. ++func TestGeneratedNobackendConstraint(t *testing.T) { ++ backends := parseBackends(t) ++ // none is a constraint that is met when all crypto backend constraints are ++ // unmet. (That is: no backend constraint is met.) ++ var none constraint.Expr ++ for _, b := range backends { ++ notB := &constraint.NotExpr{X: b.constraint} ++ if none == nil { ++ none = notB ++ } else { ++ none = &constraint.AndExpr{ ++ X: none, ++ Y: notB, ++ } ++ } ++ } ++ bytes, err := os.ReadFile("nobackend.go") ++ if err != nil { ++ t.Fatal(err) ++ } ++ lines := strings.Split(string(bytes), "\n") ++ ++ var gotIndex int ++ var gotLine string ++ for i, line := range lines { ++ if strings.HasPrefix(line, "//go:build ") { ++ gotIndex, gotLine = i, line ++ break ++ } ++ } ++ _ = gotIndex ++ ++ var wantLine string ++ if none == nil { ++ // If there are no backends yet, use a trivially true constraint. ++ // We could remove the constraint line, but this would make generation ++ // more complicated. ++ wantLine = "//go:build go1.1" ++ } else { ++ wantLine = "//go:build " + none.String() ++ } ++ if wantLine != gotLine { ++ if *fix { ++ lines[gotIndex] = wantLine ++ want := strings.Join(lines, "\n") ++ if err := os.WriteFile("nobackend.go", []byte(want), 0o666); err != nil { ++ t.Fatal(err) ++ } ++ } else { ++ t.Errorf("nobackend.go build constraint:\ngot %q\nwant %q\n%v", gotLine, wantLine, generateInstruction) ++ } ++ } ++} ++ ++// TestGeneratedBackendErrorFiles tests that the current backend error files are ++// the same as what would generated under the current conditions. ++// ++// The error files are Go files that detect issues with the backend selection ++// and report an error at compile time. ++// ++// The issue detection files are placed in the runtime package rather than the ++// crypto/internal/backend package to make sure these helpful errors will show ++// up. If the files were in the backend package, DuplicateDecl and other errors ++// would show up first, causing these informative errors to be skipped because ++// there are too many total errors already reported. The errors would also show ++// up if we put the files in the crypto package rather than the runtime package. ++// (Crypto is imported before the backend backage, so the errors would show up.) ++// However, then these errors would show up only if the Go program is using ++// crypto. This could cause a confusing situation: if the user has a ++// misconfigured backend and doesn't use crypto in their Go app, they will not ++// get any errors. If they start using crypto later, they would only then get an ++// error, but the cause would be much less apparent. ++func TestGeneratedBackendErrorFiles(t *testing.T) { ++ // Chip away at a list of files that should come from this generator. ++ // Any remaining are unexpected. ++ existingFiles := make(map[string]struct{}) ++ entries, err := os.ReadDir(runtimePackageDir) ++ if err != nil { ++ t.Fatal(err) ++ } ++ for _, e := range entries { ++ if strings.HasPrefix(e.Name(), backendErrPrefix) && strings.HasSuffix(e.Name(), ".go") { ++ existingFiles[filepath.Join(runtimePackageDir, e.Name())] = struct{}{} ++ } ++ } ++ ++ backends := parseBackends(t) ++ for i := 0; i < len(backends); i++ { ++ for j := i + 1; j < len(backends); j++ { ++ f := testConflict(t, backends[i].name, backends[j].name) ++ delete(existingFiles, f) ++ } ++ f := testPreventUnintendedFallback(t, backends[i]) ++ delete(existingFiles, f) ++ } ++ f := testUnsatisfied(t, backends) ++ delete(existingFiles, f) ++ f = testRequireFIPSWithoutBackend(t) ++ delete(existingFiles, f) ++ ++ for f := range existingFiles { ++ if *fix { ++ if err := os.Remove(f); err != nil { ++ t.Fatal(err) ++ } ++ } else { ++ t.Errorf("unexpected file: %q", f) ++ } ++ } ++ if !*fix && len(existingFiles) > 0 { ++ t.Log(generateInstruction) ++ } ++} ++ ++// testConflict checks/generates a file that fails if two backends are enabled ++// at the same time. ++func testConflict(t *testing.T, a, b string) string { ++ return testErrorFile( ++ t, ++ filepath.Join(runtimePackageDir, backendErrPrefix+"conflict_"+a+"_"+b+".go"), ++ "//go:build goexperiment."+a+"crypto && goexperiment."+b+"crypto", ++ "The "+a+" and "+b+" backends are both enabled, but they are mutually exclusive.", ++ "Please make sure only one crypto backend experiment is enabled by GOEXPERIMENT or '-tags'.") ++} ++ ++func testPreventUnintendedFallback(t *testing.T, backend *backend) string { ++ expTag := &constraint.TagExpr{Tag: "goexperiment." + backend.name + "crypto"} ++ optOutTag := &constraint.TagExpr{Tag: "goexperiment.allowcryptofallback"} ++ c := constraint.AndExpr{ ++ X: &constraint.AndExpr{ ++ X: expTag, ++ Y: &constraint.NotExpr{X: backend.constraint}, ++ }, ++ Y: &constraint.NotExpr{X: optOutTag}, ++ } ++ return testErrorFile( ++ t, ++ filepath.Join(runtimePackageDir, backendErrPrefix+"nofallback_"+backend.name+".go"), ++ "//go:build "+c.String(), ++ "The "+expTag.String()+" tag is specified, but other tags required to enable that backend were not met.", ++ "Required build tags:", ++ " "+backend.constraint.String(), ++ "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 "+backend.name+"crypto will restore pre-1.21 behavior by intentionally using Go standard library crypto.", ++ "") ++} ++ ++// testUnsatisfied checks/generates a file that fails if systemcrypto is enabled ++// on an OS with no suitable backend. ++func testUnsatisfied(t *testing.T, backends []*backend) string { ++ constraint := "//go:build goexperiment.systemcrypto" ++ for _, b := range backends { ++ constraint += ` && !goexperiment.` + b.name + "crypto" ++ } ++ return testErrorFile( ++ t, ++ filepath.Join(runtimePackageDir, backendErrPrefix+"systemcrypto_nobackend.go"), ++ constraint, ++ "The systemcrypto feature is enabled, but it was unable to enable an appropriate crypto backend for the target GOOS.") ++} ++ ++func testRequireFIPSWithoutBackend(t *testing.T) string { ++ return testErrorFile( ++ t, ++ filepath.Join(runtimePackageDir, backendErrPrefix+"requirefips_nosystemcrypto.go"), ++ "//go:build requirefips && !goexperiment.systemcrypto", ++ "The requirefips tag is enabled, but no crypto backend is enabled.", ++ "A crypto backend is required to enable FIPS mode.") ++} ++ ++// testErrorFile checks/generates a Go file with a given build constraint that ++// fails to compile. The file uses an unused string to convey an error message ++// to the dev on the "go build" command line. ++func testErrorFile(t *testing.T, file, constraint string, message ...string) string { ++ const header = `// 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 "` + backendErrPrefix + `".` ++ c := header + "\n\n" + constraint + "\n\npackage runtime\n\nfunc init() {\n\t`\n" ++ for _, m := range message { ++ c += "\t" + m + "\n" ++ } ++ c += "\tFor more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips\n" ++ c += "\t`" + "\n}\n" ++ if *fix { ++ if err := os.WriteFile(file, []byte(c), 0o666); err != nil { ++ t.Fatal(err) ++ } ++ } else { ++ existing, err := os.ReadFile(file) ++ if err != nil { ++ t.Fatal(err) ++ } ++ if !bytes.Equal(existing, []byte(c)) { ++ t.Errorf("file %v doesn't match expected value; %v", file, generateInstruction) ++ t.Log("found:", string(existing)) ++ t.Log("would generate:", c) ++ } ++ } ++ return file ++} ++ ++type backend struct { ++ filename string ++ name string ++ constraint constraint.Expr ++} ++ ++func parseBackends(t *testing.T) []*backend { ++ fs := token.NewFileSet() ++ pkgs, err := parser.ParseDir(fs, ".", nil, parser.ParseComments) ++ if err != nil { ++ t.Fatal(err) ++ } ++ var bs []*backend ++ // Any file in this dir that defines "Enabled" is a backend. ++ for k, v := range pkgs["backend"].Files { ++ if en := v.Scope.Lookup("Enabled"); en != nil { ++ // nobackend defines Enabled, but it is specifically not a backend. ++ if k == "nobackend.go" { ++ continue ++ } ++ b := backend{filename: k} ++ b.name, _, _ = strings.Cut(strings.TrimSuffix(k, ".go"), "_") ++ for _, comment := range v.Comments { ++ for _, c := range comment.List { ++ if strings.HasPrefix(c.Text, "//go:build ") { ++ if c, err := constraint.Parse(c.Text); err == nil { ++ b.constraint = c ++ } else { ++ t.Fatal(err) ++ } ++ } ++ } ++ } ++ bs = append(bs, &b) ++ } ++ } ++ sort.Slice(bs, func(i, j int) bool { ++ return bs[i].name < bs[j].name ++ }) ++ return bs ++} diff --git a/src/crypto/internal/backend/bbig/big.go b/src/crypto/internal/backend/bbig/big.go new file mode 100644 index 00000000000000..ab3f30825dcfa1 @@ -1484,7 +1833,7 @@ index 00000000000000..118efa3a492a7d +} diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go new file mode 100644 -index 00000000000000..eca1ceab2a04b9 +index 00000000000000..7c3a95c2c64a2d --- /dev/null +++ b/src/crypto/internal/backend/nobackend.go @@ -0,0 +1,240 @@ @@ -1494,7 +1843,7 @@ index 00000000000000..eca1ceab2a04b9 + +// 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.darwincrypto && darwin && cgo) && !(goexperiment.opensslcrypto && linux && cgo) + +package backend + @@ -2151,6 +2500,358 @@ index e017efb1562379..ab5539f978a266 100644 < crypto/rand < crypto/ed25519 # depends on crypto/rand.Reader < encoding/asn1 +diff --git a/src/internal/goexperiment/exp_allowcryptofallback_off.go b/src/internal/goexperiment/exp_allowcryptofallback_off.go +new file mode 100644 +index 00000000000000..dfce36d834c46e +--- /dev/null ++++ b/src/internal/goexperiment/exp_allowcryptofallback_off.go +@@ -0,0 +1,9 @@ ++// Code generated by mkconsts.go. DO NOT EDIT. ++ ++//go:build !goexperiment.allowcryptofallback ++// +build !goexperiment.allowcryptofallback ++ ++package goexperiment ++ ++const AllowCryptoFallback = false ++const AllowCryptoFallbackInt = 0 +diff --git a/src/internal/goexperiment/exp_allowcryptofallback_on.go b/src/internal/goexperiment/exp_allowcryptofallback_on.go +new file mode 100644 +index 00000000000000..8d0c3fde9ab5e8 +--- /dev/null ++++ b/src/internal/goexperiment/exp_allowcryptofallback_on.go +@@ -0,0 +1,9 @@ ++// Code generated by mkconsts.go. DO NOT EDIT. ++ ++//go:build goexperiment.allowcryptofallback ++// +build goexperiment.allowcryptofallback ++ ++package goexperiment ++ ++const AllowCryptoFallback = true ++const AllowCryptoFallbackInt = 1 +diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go +index e6c9b7d5e62dc0..65d339be7dde32 100644 +--- a/src/internal/goexperiment/flags.go ++++ b/src/internal/goexperiment/flags.go +@@ -78,6 +78,14 @@ type Flags struct { + // being used to build the Go program. + SystemCrypto bool + ++ // AllowCryptoFallback allows the use of pure Go crypto if a crypto backend ++ // experiment is enabled but the backend's requirements are not met. This is ++ // used during the Go build itself to allow running the test suite with a ++ // backend experiment enabled. Some parts of the Go build (bootstrapping) ++ // and parts of the test suite run without cgo, so ++ // GOEXPERIMENT=opensslcrypto,allowcryptofallback must be used to succeed. ++ AllowCryptoFallback bool ++ + // Regabi is split into several sub-experiments that can be + // enabled individually. Not all combinations work. + // The "regabi" GOEXPERIMENT is an alias for all "working" +diff --git a/src/runtime/backenderr_gen_conflict_boring_cng.go b/src/runtime/backenderr_gen_conflict_boring_cng.go +new file mode 100644 +index 00000000000000..361db2a962d60f +--- /dev/null ++++ b/src/runtime/backenderr_gen_conflict_boring_cng.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.cngcrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The boring and cng 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_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 +--- /dev/null ++++ b/src/runtime/backenderr_gen_conflict_boring_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.boringcrypto && goexperiment.opensslcrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The boring 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_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 +--- /dev/null ++++ b/src/runtime/backenderr_gen_conflict_cng_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.cngcrypto && goexperiment.opensslcrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The cng 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_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 +--- /dev/null ++++ b/src/runtime/backenderr_gen_nofallback_boring.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.boringcrypto && !(goexperiment.boringcrypto && linux && cgo && (amd64 || arm64) && !android && !msan) && !goexperiment.allowcryptofallback ++ ++package runtime ++ ++func init() { ++ ` ++ The goexperiment.boringcrypto tag is specified, but other tags required to enable that backend were not met. ++ Required build tags: ++ goexperiment.boringcrypto && linux && cgo && (amd64 || arm64) && !android && !msan ++ 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 boringcrypto 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_cng.go b/src/runtime/backenderr_gen_nofallback_cng.go +new file mode 100644 +index 00000000000000..ae7f798ea41225 +--- /dev/null ++++ b/src/runtime/backenderr_gen_nofallback_cng.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.cngcrypto && !(goexperiment.cngcrypto && windows) && !goexperiment.allowcryptofallback ++ ++package runtime ++ ++func init() { ++ ` ++ The goexperiment.cngcrypto tag is specified, but other tags required to enable that backend were not met. ++ Required build tags: ++ goexperiment.cngcrypto && windows ++ 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 cngcrypto 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_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..7e1679dfc37a23 +--- /dev/null ++++ b/src/runtime/backenderr_gen_nofallback_openssl.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.opensslcrypto && !(goexperiment.opensslcrypto && linux && cgo) && !goexperiment.allowcryptofallback ++ ++package runtime ++ ++func init() { ++ ` ++ The goexperiment.opensslcrypto tag is specified, but other tags required to enable that backend were not met. ++ Required build tags: ++ goexperiment.opensslcrypto && linux && 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 opensslcrypto 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_requirefips_nosystemcrypto.go b/src/runtime/backenderr_gen_requirefips_nosystemcrypto.go +new file mode 100644 +index 00000000000000..1c015dd2b08972 +--- /dev/null ++++ b/src/runtime/backenderr_gen_requirefips_nosystemcrypto.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 requirefips && !goexperiment.systemcrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The requirefips tag is enabled, but no crypto backend is enabled. ++ A crypto backend is required to enable FIPS mode. ++ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips ++ ` ++} +diff --git a/src/runtime/backenderr_gen_systemcrypto_nobackend.go b/src/runtime/backenderr_gen_systemcrypto_nobackend.go +new file mode 100644 +index 00000000000000..95be7ad8d38cae +--- /dev/null ++++ b/src/runtime/backenderr_gen_systemcrypto_nobackend.go +@@ -0,0 +1,16 @@ ++// 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.systemcrypto && !goexperiment.boringcrypto && !goexperiment.cngcrypto && !goexperiment.darwincrypto && !goexperiment.opensslcrypto ++ ++package runtime ++ ++func init() { ++ ` ++ The systemcrypto feature is enabled, but it was unable to enable an appropriate crypto backend for the target GOOS. ++ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips ++ ` ++} diff --git a/src/runtime/runtime_boring.go b/src/runtime/runtime_boring.go index 5a98b20253181c..9042f2c2795e19 100644 --- a/src/runtime/runtime_boring.go diff --git a/patches/0005-Add-backend-code-gen.patch b/patches/0005-Add-backend-code-gen.patch deleted file mode 100644 index 966a918bcbb..00000000000 --- a/patches/0005-Add-backend-code-gen.patch +++ /dev/null @@ -1,744 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Davis Goodin -Date: Fri, 23 Jun 2023 11:58:31 -0500 -Subject: [PATCH] Add backend code gen - -Adds code generation that works with the final list of crypto backends -to add extra features and tie up loose ends in an easily maintained way. - -Backend conflict error generator: creates files that generate -informative build errors when the backends aren't configured correctly. - -"nobackend" build constraint generator: gathers the build constraints -for all the backends to create the "nobackend" constraint. - -The generators also run during standard test runs in validation mode to -ensure the generated content is not out of date when backends are -added/removed or when their build constraints change. - -To simplify patch maintenance, the generators are only run once, in this -patch. An alternative would be adding the generators in an earlier patch -and re-running the generators immediately for each backend patch. This -would make the direct connection between changes clearer, but make it -harder to update the generators and to deal with conflicts. - -Use "go/bin/go generate crypto/internal/backend" after recently building -the repository to run the generators. ---- - src/crypto/internal/backend/backendgen.go | 20 ++ - .../internal/backend/backendgen_test.go | 284 ++++++++++++++++++ - src/crypto/internal/backend/nobackend.go | 2 +- - .../exp_allowcryptofallback_off.go | 9 + - .../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 + - 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 - -diff --git a/src/crypto/internal/backend/backendgen.go b/src/crypto/internal/backend/backendgen.go -new file mode 100644 -index 00000000000000..acf0113bbefb6c ---- /dev/null -+++ b/src/crypto/internal/backend/backendgen.go -@@ -0,0 +1,20 @@ -+// 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. -+ -+package backend -+ -+// Generate files and Go code based on the set of backends: -+// -+// - The build constraint in nobackend.go. -+// - Go files in the runtime package that detect issues with backend selection -+// and report an error at compile time. -+// -+// Runs in -mod=readonly mode so that it is able to run during each crypto -+// backend patch. This is before the final vendoring refresh patch, so it would -+// normally fail to build due to inconsistent vendoring. -+ -+// Use "go generate -run TestGenerated crypto/internal/backend" -+// to run only this generator. -+ -+//go:generate go test -run TestGenerated -fix -diff --git a/src/crypto/internal/backend/backendgen_test.go b/src/crypto/internal/backend/backendgen_test.go -new file mode 100644 -index 00000000000000..1ba948c8f207e5 ---- /dev/null -+++ b/src/crypto/internal/backend/backendgen_test.go -@@ -0,0 +1,284 @@ -+// 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. -+ -+package backend -+ -+import ( -+ "bytes" -+ "flag" -+ "go/build/constraint" -+ "go/parser" -+ "go/token" -+ "os" -+ "path/filepath" -+ "sort" -+ "strings" -+ "testing" -+) -+ -+var fix = flag.Bool("fix", false, "if true, update the generated files to the wanted value") -+ -+const runtimePackageDir = "../../../runtime" -+ -+// backendErrPrefix is the prefix of the generated backend error files. Any file -+// in the runtime package with this prefix will be considered a backend error -+// file, so it's important that this prefix is unique or this generator may -+// delete unexpected files. -+const backendErrPrefix = "backenderr_gen_" -+ -+const generateInstruction = "run 'go generate crypto/internal/backend' to fix" -+ -+// TestGeneratedBackendErrorFiles tests that the current nobackend constraint -+// is correct. -+// -+// Generate the build constraint in nobackend.go. This build constraint enables -+// nobackend when all of the backends are not enabled. This constraint is fairly -+// long and would not be trivial to maintain manually. -+func TestGeneratedNobackendConstraint(t *testing.T) { -+ backends := parseBackends(t) -+ // none is a constraint that is met when all crypto backend constraints are -+ // unmet. (That is: no backend constraint is met.) -+ var none constraint.Expr -+ for _, b := range backends { -+ notB := &constraint.NotExpr{X: b.constraint} -+ if none == nil { -+ none = notB -+ } else { -+ none = &constraint.AndExpr{ -+ X: none, -+ Y: notB, -+ } -+ } -+ } -+ bytes, err := os.ReadFile("nobackend.go") -+ if err != nil { -+ t.Fatal(err) -+ } -+ lines := strings.Split(string(bytes), "\n") -+ -+ var gotIndex int -+ var gotLine string -+ for i, line := range lines { -+ if strings.HasPrefix(line, "//go:build ") { -+ gotIndex, gotLine = i, line -+ break -+ } -+ } -+ _ = gotIndex -+ -+ var wantLine string -+ if none == nil { -+ // If there are no backends yet, use a trivially true constraint. -+ // We could remove the constraint line, but this would make generation -+ // more complicated. -+ wantLine = "//go:build go1.1" -+ } else { -+ wantLine = "//go:build " + none.String() -+ } -+ if wantLine != gotLine { -+ if *fix { -+ lines[gotIndex] = wantLine -+ want := strings.Join(lines, "\n") -+ if err := os.WriteFile("nobackend.go", []byte(want), 0o666); err != nil { -+ t.Fatal(err) -+ } -+ } else { -+ t.Errorf("nobackend.go build constraint:\ngot %q\nwant %q\n%v", gotLine, wantLine, generateInstruction) -+ } -+ } -+} -+ -+// TestGeneratedBackendErrorFiles tests that the current backend error files are -+// the same as what would generated under the current conditions. -+// -+// The error files are Go files that detect issues with the backend selection -+// and report an error at compile time. -+// -+// The issue detection files are placed in the runtime package rather than the -+// crypto/internal/backend package to make sure these helpful errors will show -+// up. If the files were in the backend package, DuplicateDecl and other errors -+// would show up first, causing these informative errors to be skipped because -+// there are too many total errors already reported. The errors would also show -+// up if we put the files in the crypto package rather than the runtime package. -+// (Crypto is imported before the backend backage, so the errors would show up.) -+// However, then these errors would show up only if the Go program is using -+// crypto. This could cause a confusing situation: if the user has a -+// misconfigured backend and doesn't use crypto in their Go app, they will not -+// get any errors. If they start using crypto later, they would only then get an -+// error, but the cause would be much less apparent. -+func TestGeneratedBackendErrorFiles(t *testing.T) { -+ // Chip away at a list of files that should come from this generator. -+ // Any remaining are unexpected. -+ existingFiles := make(map[string]struct{}) -+ entries, err := os.ReadDir(runtimePackageDir) -+ if err != nil { -+ t.Fatal(err) -+ } -+ for _, e := range entries { -+ if strings.HasPrefix(e.Name(), backendErrPrefix) && strings.HasSuffix(e.Name(), ".go") { -+ existingFiles[filepath.Join(runtimePackageDir, e.Name())] = struct{}{} -+ } -+ } -+ -+ backends := parseBackends(t) -+ for i := 0; i < len(backends); i++ { -+ for j := i + 1; j < len(backends); j++ { -+ f := testConflict(t, backends[i].name, backends[j].name) -+ delete(existingFiles, f) -+ } -+ f := testPreventUnintendedFallback(t, backends[i]) -+ delete(existingFiles, f) -+ } -+ f := testUnsatisfied(t, backends) -+ delete(existingFiles, f) -+ f = testRequireFIPSWithoutBackend(t) -+ delete(existingFiles, f) -+ -+ for f := range existingFiles { -+ if *fix { -+ if err := os.Remove(f); err != nil { -+ t.Fatal(err) -+ } -+ } else { -+ t.Errorf("unexpected file: %q", f) -+ } -+ } -+ if !*fix && len(existingFiles) > 0 { -+ t.Log(generateInstruction) -+ } -+} -+ -+// testConflict checks/generates a file that fails if two backends are enabled -+// at the same time. -+func testConflict(t *testing.T, a, b string) string { -+ return testErrorFile( -+ t, -+ filepath.Join(runtimePackageDir, backendErrPrefix+"conflict_"+a+"_"+b+".go"), -+ "//go:build goexperiment."+a+"crypto && goexperiment."+b+"crypto", -+ "The "+a+" and "+b+" backends are both enabled, but they are mutually exclusive.", -+ "Please make sure only one crypto backend experiment is enabled by GOEXPERIMENT or '-tags'.") -+} -+ -+func testPreventUnintendedFallback(t *testing.T, backend *backend) string { -+ expTag := &constraint.TagExpr{Tag: "goexperiment." + backend.name + "crypto"} -+ optOutTag := &constraint.TagExpr{Tag: "goexperiment.allowcryptofallback"} -+ c := constraint.AndExpr{ -+ X: &constraint.AndExpr{ -+ X: expTag, -+ Y: &constraint.NotExpr{X: backend.constraint}, -+ }, -+ Y: &constraint.NotExpr{X: optOutTag}, -+ } -+ return testErrorFile( -+ t, -+ filepath.Join(runtimePackageDir, backendErrPrefix+"nofallback_"+backend.name+".go"), -+ "//go:build "+c.String(), -+ "The "+expTag.String()+" tag is specified, but other tags required to enable that backend were not met.", -+ "Required build tags:", -+ " "+backend.constraint.String(), -+ "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 "+backend.name+"crypto will restore pre-1.21 behavior by intentionally using Go standard library crypto.", -+ "") -+} -+ -+// testUnsatisfied checks/generates a file that fails if systemcrypto is enabled -+// on an OS with no suitable backend. -+func testUnsatisfied(t *testing.T, backends []*backend) string { -+ constraint := "//go:build goexperiment.systemcrypto" -+ for _, b := range backends { -+ constraint += ` && !goexperiment.` + b.name + "crypto" -+ } -+ return testErrorFile( -+ t, -+ filepath.Join(runtimePackageDir, backendErrPrefix+"systemcrypto_nobackend.go"), -+ constraint, -+ "The systemcrypto feature is enabled, but it was unable to enable an appropriate crypto backend for the target GOOS.") -+} -+ -+func testRequireFIPSWithoutBackend(t *testing.T) string { -+ return testErrorFile( -+ t, -+ filepath.Join(runtimePackageDir, backendErrPrefix+"requirefips_nosystemcrypto.go"), -+ "//go:build requirefips && !goexperiment.systemcrypto", -+ "The requirefips tag is enabled, but no crypto backend is enabled.", -+ "A crypto backend is required to enable FIPS mode.") -+} -+ -+// testErrorFile checks/generates a Go file with a given build constraint that -+// fails to compile. The file uses an unused string to convey an error message -+// to the dev on the "go build" command line. -+func testErrorFile(t *testing.T, file, constraint string, message ...string) string { -+ const header = `// 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 "` + backendErrPrefix + `".` -+ c := header + "\n\n" + constraint + "\n\npackage runtime\n\nfunc init() {\n\t`\n" -+ for _, m := range message { -+ c += "\t" + m + "\n" -+ } -+ c += "\tFor more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips\n" -+ c += "\t`" + "\n}\n" -+ if *fix { -+ if err := os.WriteFile(file, []byte(c), 0o666); err != nil { -+ t.Fatal(err) -+ } -+ } else { -+ existing, err := os.ReadFile(file) -+ if err != nil { -+ t.Fatal(err) -+ } -+ if !bytes.Equal(existing, []byte(c)) { -+ t.Errorf("file %v doesn't match expected value; %v", file, generateInstruction) -+ t.Log("found:", string(existing)) -+ t.Log("would generate:", c) -+ } -+ } -+ return file -+} -+ -+type backend struct { -+ filename string -+ name string -+ constraint constraint.Expr -+} -+ -+func parseBackends(t *testing.T) []*backend { -+ fs := token.NewFileSet() -+ pkgs, err := parser.ParseDir(fs, ".", nil, parser.ParseComments) -+ if err != nil { -+ t.Fatal(err) -+ } -+ var bs []*backend -+ // Any file in this dir that defines "Enabled" is a backend. -+ for k, v := range pkgs["backend"].Files { -+ if en := v.Scope.Lookup("Enabled"); en != nil { -+ // nobackend defines Enabled, but it is specifically not a backend. -+ if k == "nobackend.go" { -+ continue -+ } -+ b := backend{filename: k} -+ b.name, _, _ = strings.Cut(strings.TrimSuffix(k, ".go"), "_") -+ for _, comment := range v.Comments { -+ for _, c := range comment.List { -+ if strings.HasPrefix(c.Text, "//go:build ") { -+ if c, err := constraint.Parse(c.Text); err == nil { -+ b.constraint = c -+ } else { -+ t.Fatal(err) -+ } -+ } -+ } -+ } -+ bs = append(bs, &b) -+ } -+ } -+ sort.Slice(bs, func(i, j int) bool { -+ return bs[i].name < bs[j].name -+ }) -+ return bs -+} -diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go -index 5c2f56d000a2a8..6f87fc053bb4b1 100644 ---- a/src/crypto/internal/backend/nobackend.go -+++ b/src/crypto/internal/backend/nobackend.go -@@ -4,7 +4,7 @@ - - // 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.darwincrypto && darwin && cgo) && !(goexperiment.opensslcrypto && linux && cgo) - - package backend - -diff --git a/src/internal/goexperiment/exp_allowcryptofallback_off.go b/src/internal/goexperiment/exp_allowcryptofallback_off.go -new file mode 100644 -index 00000000000000..dfce36d834c46e ---- /dev/null -+++ b/src/internal/goexperiment/exp_allowcryptofallback_off.go -@@ -0,0 +1,9 @@ -+// Code generated by mkconsts.go. DO NOT EDIT. -+ -+//go:build !goexperiment.allowcryptofallback -+// +build !goexperiment.allowcryptofallback -+ -+package goexperiment -+ -+const AllowCryptoFallback = false -+const AllowCryptoFallbackInt = 0 -diff --git a/src/internal/goexperiment/exp_allowcryptofallback_on.go b/src/internal/goexperiment/exp_allowcryptofallback_on.go -new file mode 100644 -index 00000000000000..8d0c3fde9ab5e8 ---- /dev/null -+++ b/src/internal/goexperiment/exp_allowcryptofallback_on.go -@@ -0,0 +1,9 @@ -+// Code generated by mkconsts.go. DO NOT EDIT. -+ -+//go:build goexperiment.allowcryptofallback -+// +build goexperiment.allowcryptofallback -+ -+package goexperiment -+ -+const AllowCryptoFallback = true -+const AllowCryptoFallbackInt = 1 -diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go -index e6c9b7d5e62dc0..65d339be7dde32 100644 ---- a/src/internal/goexperiment/flags.go -+++ b/src/internal/goexperiment/flags.go -@@ -78,6 +78,14 @@ type Flags struct { - // being used to build the Go program. - SystemCrypto bool - -+ // AllowCryptoFallback allows the use of pure Go crypto if a crypto backend -+ // experiment is enabled but the backend's requirements are not met. This is -+ // used during the Go build itself to allow running the test suite with a -+ // backend experiment enabled. Some parts of the Go build (bootstrapping) -+ // and parts of the test suite run without cgo, so -+ // GOEXPERIMENT=opensslcrypto,allowcryptofallback must be used to succeed. -+ AllowCryptoFallback bool -+ - // Regabi is split into several sub-experiments that can be - // enabled individually. Not all combinations work. - // The "regabi" GOEXPERIMENT is an alias for all "working" -diff --git a/src/runtime/backenderr_gen_conflict_boring_cng.go b/src/runtime/backenderr_gen_conflict_boring_cng.go -new file mode 100644 -index 00000000000000..361db2a962d60f ---- /dev/null -+++ b/src/runtime/backenderr_gen_conflict_boring_cng.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.cngcrypto -+ -+package runtime -+ -+func init() { -+ ` -+ The boring and cng 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_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 ---- /dev/null -+++ b/src/runtime/backenderr_gen_conflict_boring_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.boringcrypto && goexperiment.opensslcrypto -+ -+package runtime -+ -+func init() { -+ ` -+ The boring 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_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 ---- /dev/null -+++ b/src/runtime/backenderr_gen_conflict_cng_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.cngcrypto && goexperiment.opensslcrypto -+ -+package runtime -+ -+func init() { -+ ` -+ The cng 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_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 ---- /dev/null -+++ b/src/runtime/backenderr_gen_nofallback_boring.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.boringcrypto && !(goexperiment.boringcrypto && linux && cgo && (amd64 || arm64) && !android && !msan) && !goexperiment.allowcryptofallback -+ -+package runtime -+ -+func init() { -+ ` -+ The goexperiment.boringcrypto tag is specified, but other tags required to enable that backend were not met. -+ Required build tags: -+ goexperiment.boringcrypto && linux && cgo && (amd64 || arm64) && !android && !msan -+ 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 boringcrypto 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_cng.go b/src/runtime/backenderr_gen_nofallback_cng.go -new file mode 100644 -index 00000000000000..ae7f798ea41225 ---- /dev/null -+++ b/src/runtime/backenderr_gen_nofallback_cng.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.cngcrypto && !(goexperiment.cngcrypto && windows) && !goexperiment.allowcryptofallback -+ -+package runtime -+ -+func init() { -+ ` -+ The goexperiment.cngcrypto tag is specified, but other tags required to enable that backend were not met. -+ Required build tags: -+ goexperiment.cngcrypto && windows -+ 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 cngcrypto 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_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..7e1679dfc37a23 ---- /dev/null -+++ b/src/runtime/backenderr_gen_nofallback_openssl.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.opensslcrypto && !(goexperiment.opensslcrypto && linux && cgo) && !goexperiment.allowcryptofallback -+ -+package runtime -+ -+func init() { -+ ` -+ The goexperiment.opensslcrypto tag is specified, but other tags required to enable that backend were not met. -+ Required build tags: -+ goexperiment.opensslcrypto && linux && 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 opensslcrypto 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_requirefips_nosystemcrypto.go b/src/runtime/backenderr_gen_requirefips_nosystemcrypto.go -new file mode 100644 -index 00000000000000..1c015dd2b08972 ---- /dev/null -+++ b/src/runtime/backenderr_gen_requirefips_nosystemcrypto.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 requirefips && !goexperiment.systemcrypto -+ -+package runtime -+ -+func init() { -+ ` -+ The requirefips tag is enabled, but no crypto backend is enabled. -+ A crypto backend is required to enable FIPS mode. -+ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips -+ ` -+} -diff --git a/src/runtime/backenderr_gen_systemcrypto_nobackend.go b/src/runtime/backenderr_gen_systemcrypto_nobackend.go -new file mode 100644 -index 00000000000000..95be7ad8d38cae ---- /dev/null -+++ b/src/runtime/backenderr_gen_systemcrypto_nobackend.go -@@ -0,0 +1,16 @@ -+// 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.systemcrypto && !goexperiment.boringcrypto && !goexperiment.cngcrypto && !goexperiment.darwincrypto && !goexperiment.opensslcrypto -+ -+package runtime -+ -+func init() { -+ ` -+ The systemcrypto feature is enabled, but it was unable to enable an appropriate crypto backend for the target GOOS. -+ For more information, visit https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips -+ ` -+} diff --git a/patches/0006-Update-default-go.env.patch b/patches/0005-Update-default-go.env.patch similarity index 100% rename from patches/0006-Update-default-go.env.patch rename to patches/0005-Update-default-go.env.patch diff --git a/patches/0007-Skip-failing-tests-on-Windows.patch b/patches/0006-Skip-failing-tests-on-Windows.patch similarity index 100% rename from patches/0007-Skip-failing-tests-on-Windows.patch rename to patches/0006-Skip-failing-tests-on-Windows.patch diff --git a/patches/0008-unset-GOFIPS-when-running-the-Go-toolchain.patch b/patches/0007-unset-GOFIPS-when-running-the-Go-toolchain.patch similarity index 100% rename from patches/0008-unset-GOFIPS-when-running-the-Go-toolchain.patch rename to patches/0007-unset-GOFIPS-when-running-the-Go-toolchain.patch diff --git a/patches/0009-add-support-for-logging-used-Windows-APIs.patch b/patches/0008-add-support-for-logging-used-Windows-APIs.patch similarity index 100% rename from patches/0009-add-support-for-logging-used-Windows-APIs.patch rename to patches/0008-add-support-for-logging-used-Windows-APIs.patch diff --git a/patches/0010-remove-long-path-support-hack.patch b/patches/0009-remove-long-path-support-hack.patch similarity index 100% rename from patches/0010-remove-long-path-support-hack.patch rename to patches/0009-remove-long-path-support-hack.patch diff --git a/patches/0011-Omit-internal-go.mod-files-used-for-codegen.patch b/patches/0010-Omit-internal-go.mod-files-used-for-codegen.patch similarity index 100% rename from patches/0011-Omit-internal-go.mod-files-used-for-codegen.patch rename to patches/0010-Omit-internal-go.mod-files-used-for-codegen.patch diff --git a/patches/0012-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch b/patches/0011-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch similarity index 100% rename from patches/0012-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch rename to patches/0011-Support-curve-P-521-when-TLS-fipsonly-mode-is-enable.patch