diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f9ba8cf65f3..74be02057b7 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,9 @@ + + # Microsoft Open Source Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..54aff816cab --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ + + +# Contributing + +This project welcomes contributions and suggestions. + +## Reporting bugs and requesting features + +See [SUPPORT.md](SUPPORT.md) for how to report bugs, request features, and ask questions. +Please search existing issues before opening a new one. +Report security vulnerabilities privately by following [SECURITY.md](SECURITY.md), rather than opening a public issue. + +## Contributing changes + +We submit changes to the upstream Go project rather than patching it when possible. +If your change also applies to upstream Go, see the [Go contribution guide](https://go.dev/doc/contribute). + +For changes specific to the Microsoft build of Go: + +1. Read the [Developer Guide](eng/doc/DeveloperGuide.md) for repository setup, building, and testing instructions. + Changes to the Go source are maintained as patch files; the guide explains how to work with the `go` submodule and generate those patches. +2. Make your changes and run the relevant tests. +3. Submit a pull request with a short description of the change and links to any related issues. + See [Submitting changes](eng/doc/DeveloperGuide.md#submitting-changes) for details. + +## Contributor License Agreement + +Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +## Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/README.md b/README.md index 80895435dd7..c7f0107904f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ + + # The Microsoft build of Go Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. @@ -28,140 +34,64 @@ The submodule is updated regularly to the latest commit available in both the up ## Support -This project follows the upstream Go -[Release Policy](https://go.dev/doc/devel/release#policy). -This means we support each major release (1.X) until there are two newer major -releases. A new Go major version is -[released every six months](https://github.com/golang/go/wiki/Go-Release-Cycle), -so each Go major version is supported for about one year. - -When upstream Go releases a new minor version (1.X.Y), we release a -corresponding microsoft/go version that may also include fork-specific changes. -This normally happens once a month. - -At any time, we may release a new revision (1.X.Y-Z) to fix an issue without waiting for the next upstream minor release. -Revision releases are uncommon. - -Each microsoft/go release is announced at the -[Microsoft for Go Developers](https://devblogs.microsoft.com/go/) blog. -Check out the upstream [golang-announce mailing list](https://groups.google.com/g/golang-announce) -for a summary of the changes in each upstream Go version. - See [SUPPORT.md](SUPPORT.md) for more information about reporting bugs, requesting features, and asking questions. There are a few additional support resources internal to Microsoft: -* [Languages at Microsoft: Go](https://eng.ms/docs/more/languages-at-microsoft/go/articles/overview). -* [A Microsoft-internal email distribution list 📧 (instant join link)](https://idwebelements.microsoft.com/GroupManagement.aspx?Group=golang-announce&Operation=join) - for release announcements. - -## Download and install - -We build the forked Go toolset with the following list of OS/Arch combinations: - -* `linux_amd64` -* `linux_armv6l` -* `linux_arm64` -* `windows_amd64` -* `darwin_amd64` -* `darwin_arm64` - -> [!NOTE] -> Cross-compilation to Windows is supported. -> For other OS targets, cgo makes cross-compilation difficult, but it may still be possible. -> -> For example, to build a program for `windows_arm64`, you can cross-compile on a `windows_amd64` or `linux_amd64` host. - -Visit the [Migration Guide](eng/doc/MigrationGuide.md) for guidance about how we -recommend migrating existing Go projects to use the Microsoft build of Go. This -guide also helps resolve commonly encountered issues. - -The following sections list the ways to get the Microsoft build of Go. - -> [!NOTE] -> Don't see an option that works for you? Let us know! -> File a GitHub issue, or comment on an existing issue in this tag: - [![](https://img.shields.io/github/labels/microsoft/go/Area-Acquisition)](https://github.com/microsoft/go/labels/Area-Acquisition) +* [(Microsoft-internal) Languages at Microsoft: Introduction to Go](https://eng.ms/docs/more/languages-at-microsoft/go/articles/overview). +* [(Microsoft-internal) Languages at Microsoft: Get Help with Go](https://eng.ms/docs/more/languages-at-microsoft/go/articles/support). + * Includes internal Microsoft support channels such as an email contact for our team and a community Teams group. -### Docker Container Images +## Release cycle and policy -**[microsoft/go-images](https://github.com/microsoft/go-images)** maintains and -documents container images that are available on Microsoft Artifact Registry. +This project follows the upstream Go [Release Policy](https://go.dev/doc/devel/release#policy). +This means we support each major release (1.X) until there are two newer major releases. +A new Go major version is [released every six months](https://github.com/golang/go/wiki/Go-Release-Cycle), so each Go major version is supported for about one year. -### Azure Linux - -The **[Azure Linux](https://github.com/microsoft/azurelinux)** distribution -includes the `golang` package, a build of this fork of Go. - -For more information about how to manage the `systemcrypto` migration from 1.24 -to 1.25 in Azure Linux 3, see -[the `systemcrypto` section of the Migration Guide](eng/doc/MigrationGuide.md#migration-to-systemcrypto). - -### Ubuntu - -To install the Microsoft build of Go using an Ubuntu package, first set up the [Linux package repository for Microsoft Products](https://learn.microsoft.com/en-us/linux/packages). -Packages are available in the Ubuntu 22.04 and 24.04 repositories. - -After the repository is added, install the Microsoft build of Go by running the following commands: - -```bash -sudo apt-get update && sudo apt-get install msft-golang -``` - -### Binary archive - -[Signed builds of Go](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/Downloads.md) -for several platforms are available as `zip` and `tar.gz` files. - -### The `go-install.ps1` script +When upstream Go releases a new minor version (1.X.Y), we release a corresponding microsoft/go version that may also include fork-specific changes. +This normally happens once a month. -The [cross-platform `go-install.ps1` script](https://github.com/microsoft/go-infra/tree/main/goinstallscript) installs the Microsoft build of Go. -It can install specific versions or the latest releases. +At any time, we may release a new revision (1.X.Y-Z) to fix an issue without waiting for the next upstream minor release. +Revision releases are uncommon. -If you use Azure Pipelines, try running the script in a [script step](https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/cmd-line-v2?view=azure-pipelines) and pass the `-AzurePipelinePath` argument to automatically set up `go` in the environment for future steps. +We announce each Microsoft build of Go release through the following channels: -### Build from source +* [Microsoft for Go Developers blog](https://devblogs.microsoft.com/go/). +* [Microsoft-internal email distribution list 📧 (instant join link)](https://idwebelements.microsoft.com/GroupManagement.aspx?Group=golang-announce&Operation=join). -#### Pre-patched source tarball +The Go team announces upstream releases on the [golang-announce mailing list](https://groups.google.com/g/golang-announce). +These announcement emails include a carefully written summary of the changes that may not be found elsewhere. -[The microsoft/go GitHub releases](https://github.com/microsoft/go/releases) -include a source tarball file ending in `.src.tar.gz`. After downloading and -extracting the tar.gz file, build it using the -[upstream instructions](https://go.dev/doc/install/source). +## Download and install -> [!NOTE] -> The `zip` file that GitHub offers for download on the [microsoft/go releases page](https://github.com/microsoft/go/releases) is incomplete: it doesn't include the `go` submodule. -> Make sure to download the `.src.tar.gz` file instead, or [clone the repository using Git and set up the patched submodule](#clone-and-build). +We build the Microsoft build of Go toolset with the following OS/Arch combinations: -#### Clone and build +| OS | `amd64` | `arm64` | `armv6l` | +| --- | :---: | :---: | :---: | +| `darwin` (macOS) | ✓ | ✓ | | +| `linux` | ✓ | ✓ | ✓ | +| `windows` | ✓ | ✓ | | -First, clone this repository using Git and check out the desired tag or commit. +Check out the [Supported Platforms](eng/doc/SupportedPlatforms.md) documentation for detailed platform support information across different Go versions. -If you want to contribute to the Microsoft build of Go project, read the [Developer Guide](eng/doc/DeveloperGuide.md). -It lists the steps we recommend to set up a Microsoft build of Go development environment, execute your first build, run the standard library test suite, and contribute a PR. +Visit the [Migration Guide](eng/doc/MigrationGuide.md) for guidance about how we recommend migrating existing Go projects to use the Microsoft build of Go. +This guide also helps resolve commonly encountered issues. -If you just want to build on your own machine, you may find it more -convenient to use the tools provided by the `eng/run.ps1` script. We use this -script for CI builds. See [eng/README.md](eng/README.md) for more details about -`eng/run.ps1` and other repository infrastructure. +The [Installation](eng/doc/Installation.md) documentation contains sections describing each of the following installation methods: -Once built, the Microsoft build of Go binary is found at `go/bin/go`. +* [Docker Container Images](eng/doc/Installation.md#docker-container-images) +* [Azure Linux](eng/doc/Installation.md#azure-linux) +* [Ubuntu](eng/doc/Installation.md#ubuntu) +* [Azure Pipelines `GoTool@0` task](eng/doc/Installation.md#azure-pipelines-gotool0-task) +* [GitHub Actions `setup-go` action](eng/doc/Installation.md#github-actions-setup-go-action) +* [The `go-install.ps1` script](eng/doc/Installation.md#the-go-installps1-script) +* [Binary archive](eng/doc/Installation.md#binary-archive) (`tar.gz` and `zip`) +* [Build from source](eng/doc/Installation.md#build-from-source) ## Contributing -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. - -When you submit a pull request, a CLA bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -Please read the [Developer Guide](eng/doc/DeveloperGuide.md) for more information about contributing to this project. +This project welcomes contributions and suggestions. +Please read [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines, including the Contributor License Agreement and Code of Conduct. ## Trademarks diff --git a/SECURITY.md b/SECURITY.md index f7b89984f0f..b81d4fac351 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,9 @@ + + ## Security diff --git a/SUPPORT.md b/SUPPORT.md index 115f96c43fc..f264286a691 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -1,21 +1,30 @@ -# Support - -For help and questions about the Go programming language and tools, visit the official website: . - -Take a look at the [Migration Guide](eng/doc/MigrationGuide.md) for more information about migrating from the official build of Go to the Microsoft build of Go, specifically. - -## How to file issues and get help - -This project uses GitHub Issues to track bugs and feature requests. Please search the existing -issues before filing new issues to avoid duplicates. For new issues, [file your bug or -feature request as a new Issue][file]. - -For help and questions about the microsoft/go project, please [file an issue][file]. - -If you believe you have found a security vulnerability, please report it privately following the instructions in [SECURITY.md](SECURITY.md). - -## Microsoft Support Policy - -Support for this project is limited to the resources listed above. - -[file]: https://github.com/microsoft/go/issues/new/choose + + +# Support + +For help and questions about the Go programming language and tools, visit the official website: . + +Take a look at the [Migration Guide](eng/doc/MigrationGuide.md) for more information about migrating from the official build of Go to the Microsoft build of Go, specifically. + +> [!TIP] +> Additional support options internal to Microsoft are listed in the ["Support" section of the README file](README.md#support). + +## How to file issues and get help + +This project uses GitHub Issues to track bugs and feature requests. Please search the existing +issues before filing new issues to avoid duplicates. For new issues, [file your bug or +feature request as a new Issue][file]. + +For help and questions about the microsoft/go project, please [file an issue][file]. + +If you believe you have found a security vulnerability, please report it privately following the instructions in [SECURITY.md](SECURITY.md). + +## Microsoft Support Policy + +Support for this project is limited to the resources listed above. + +[file]: https://github.com/microsoft/go/issues/new/choose diff --git a/eng/doc/AdditionalFeatures.md b/eng/doc/AdditionalFeatures.md new file mode 100644 index 00000000000..11f3e75d646 --- /dev/null +++ b/eng/doc/AdditionalFeatures.md @@ -0,0 +1,219 @@ + + +# Additional Features Provided by the Microsoft build of Go + +This document provides a comprehensive overview of all features currently implemented in the Microsoft build of Go that are not part of the official Go distribution. + +If you are trying to use the Microsoft build of Go but aren't looking for a precise guide to every feature, see [the Migration Guide](/eng/doc/MigrationGuide.md). + +The `patches` directory at each Git tag specifies the exact code changes we have made to the official Go toolchain of that version. +If it's critical to you to understand the exact implementation details of all changes we've made, please review the patch files. + +## Telemetry + +The Microsoft build of Go collects [opt-out (enabled by default) toolset telemetry](https://devblogs.microsoft.com/go/microsoft-go-telemetry/). + +See the [Telemetry documentation](/eng/doc/Telemetry.md) for details on what is collected and how to opt out. +See also the [Data Collection policy for the Microsoft build of Go](/README.md#data-collection). + +## System-provided cryptography backend + +We have implemented changes to the Go standard library to call a platform-specific system-provided cryptography library rather than running the pure Go implementation. +Its main purposes are to comply with Microsoft's internal cryptography policies and implement FIPS 140 compliance. + +This feature is enabled by default on supported platforms. + + +See [the Migration Guide](/eng/doc/MigrationGuide.md) for more information about when, and how, to configure this feature. + +More details are available in the [FIPS README](/eng/doc/fips/README.md). +These changes also include improvements to crypto library behavior to make it easier to comply with some FIPS requirements. + +> [!NOTE] +> The purpose of this feature is to comply with the Microsoft internal cryptography policies, which mandate using system-provided cryptography modules. +> We encourage Go developers who aren't subject to those policies to continue using the official Go cryptography implementation. + +## TLS setting alignment with Microsoft internal policies + +The Microsoft build of Go can align the default TLS settings with Microsoft internal cryptography policies. +This allows developers to comply without changing application code that uses (or indirectly uses) the `crypto/tls` package. + +Go 1.26 introduces `ms_tlsprofile`. +The possible values are: + +- `default`: (default) use the recommended Microsoft TLS settings. +- `off`: use the upstream Go TLS settings. + +Go 1.26 also introduces `ms_tlsx25519`. +The possible values of `ms_tlsx25519` are: + +- `0` disables the X25519 and X25519MLKEM768 TLS groups. +- `1` (default) enables these groups. + +Microsoft build of Go 1.28 introduces the `MS_GOTLSMLKEM` environment variable, which controls the default use of ML-KEM TLS key exchange in built programs. +The build-time values are: + +- `0`: sets the program's `tlsmlkem` GODEBUG default to `0`. +- Unset or any other value: leaves the default unchanged. + +With `tlsmlkem=0`, programs disable the X25519MLKEM768, SecP256r1MLKEM768, and SecP384r1MLKEM1024 TLS groups by default. +The default use of classical groups, including X25519, is unchanged. +This setting applies independently of `ms_tlsprofile` and does not override explicit `tls.Config.CurvePreferences`. + +`MS_GOTLSMLKEM` takes effect when the program is built, not when it runs. +The following command persists the setting for subsequent builds: + +```sh +go env -w MS_GOTLSMLKEM=0 +``` + +`go env -u MS_GOTLSMLKEM` removes the persisted setting. +Neither command changes programs that have already been built. + +Explicit `godebug` directives in `go.mod` or `go.work` and `//go:debug` directives take precedence over this build-time default. +At runtime, `GODEBUG=tlsmlkem=1` overrides the built-in default and re-enables the ML-KEM groups, subject to the other TLS settings. + +Microsoft build of Go `v1.27.2-2` introduces `ms_tlsmldsacert`, which controls ML-DSA advertisement in the `signature_algorithms_cert` extension. +The possible values are: + +- `1` (default) advertises ML-DSA certificate signature algorithms, subject to the existing TLS version and FIPS restrictions. +- `0` omits ML-DSA-44, ML-DSA-65, and ML-DSA-87 from this extension in ClientHello and CertificateRequest messages to avoid a [known compatibility issue with TLS-inspecting middleboxes](https://github.com/golang/go/issues/81199). + +The extension remains present, with its other algorithms and existing FIPS restrictions unchanged. +ML-DSA handshake signatures and ML-KEM key exchange remain available, subject to their existing restrictions. +This setting applies independently of `ms_tlsprofile`. +Certificate verification is unchanged, but disabling advertisement may cause peers to select a different certificate chain or fail if they require ML-DSA certificate signatures to be advertised. + +These features operate independently from the system-provided cryptography backend feature. +They work the same way when the pure Go cryptography implementation is used. + +## Version string changes to identify the Microsoft build of Go + +### Embed Microsoft build of Go version information in binaries + +This feature embeds Microsoft-specific version information into built Go binaries, making it easy to [identify the Microsoft build of Go toolset](/eng/doc/MicrosoftToolsetIdentification.md) and its specific version. + +As of Go 1.26, this feature is enabled. + +Every binary built by the Microsoft build of Go has a `microsoft_toolset_version` field in its list of buildinfo settings. +This string indicates the Microsoft build of Go version used to create the binary. +This information is accessible through `go version -m ` and the `debug/buildinfo` package's [BuildInfo](https://pkg.go.dev/runtime/debug#BuildInfo) struct `Settings` field. + +For example, `go version -m ` produces output with a line like this, indicating that `program` was built by revision 1 of the Microsoft build of Go 1.26.0: + +``` +build microsoft_toolset_version=go1.26.0-1-microsoft +``` + +The opt-in features described in the following sections can embed this string more deeply into built binaries, and change `runtime.Version()` to return the Microsoft version rather than the upstream version. + +> [!NOTE] +> The Microsoft version string format is designed to be compatible with tools that rely on version parsing. +> It follows the expectations of the [go/version](https://pkg.go.dev/go/version) package. + +### Runtime identification of Microsoft build + +Microsoft build of Go 1.26 adds a new GODEBUG setting named `ms_version`. +It controls whether the Go runtime uses a Microsoft-specific version string in the output of `runtime.Version()`. + +As of Go 1.26, this feature is available, but disabled by default. + +In Go 1.27, we plan to change this feature to be enabled by default. + +If you build a program that reports the Go version it uses, you may find this feature useful to provide more accurate data for diagnosis and status reporting. +This setting also affects the output of the `go version` command. + +The possible values of `ms_version` are: + +- `0`: `runtime.Version()` returns the upstream version string, for example: `go1.26.0`. +- `1`: `runtime.Version()` returns the Microsoft build of Go version string, for example: `go1.26.0-1-microsoft`. + +> [!TIP] +> GODEBUG settings can be changed by setting the `GODEBUG` environment variable, but the default values of the settings can also be changed in several other ways, such as modifying the `go.mod` file. +> See [Go, Backwards Compatibility, and GODEBUG](https://go.dev/doc/godebug) for more information. + +Using `ms_version` with the `go version` command allows you to easily determine if a given toolset is an up to date version of the Microsoft build of Go. +For example, in a Linux shell: + +``` +$ GODEBUG=ms_version=1 go version +go version go1.26.0-1-microsoft linux/amd64 +``` + +> [!NOTE] +> To implement the `ms_version` feature, the Microsoft build of Go as of 1.26 always embeds *both* the upstream version string and the Microsoft version string into built binaries. +> This is independent from the `-ms_upstreamversion` linker flag described in the next section. + +### Assign GoVersion to use Microsoft build identity + +The Microsoft build of Go includes a feature to bake in the version string of the Microsoft build of Go instead of the upstream version. + +As of Go 1.26, this feature is available, but disabled by default. + +In Go 1.27, we plan to change this feature to be enabled by default. + +> [!NOTE] +> Building `` then running `go version ` shows a version baked into the program's binary, such as `go1.26.0`. +> This baked-in version is represented by `GoVersion` in [`debug/buildinfo.BuildInfo`](https://pkg.go.dev/runtime/debug#BuildInfo), so we call it the binary's `GoVersion`. +> +> The `GoVersion` is not necessarily the same version that `runtime.Version()` returns at runtime. +> These versions are controlled separately. + +We added a linker flag `-ms_upstreamversion` that configures this behavior. +The possible values are: + +- `0`: the `GoVersion` is assigned the Microsoft build of Go version string, for example: `go1.26.0-1-microsoft`. +- `1`: the `GoVersion` is assigned the upstream version string, for example: `go1.26.0`. + +By default, as of Go 1.26, the `-ms_upstreamversion` flag is set to `1`. +Changing it from `1` to `0` to use this feature is done by passing the `-ms_upstreamversion=0` linker flag. +For example, use `-ldflags` with `go build`: + +``` +$ go build -ldflags="-ms_upstreamversion=0" program.go +$ go version program +program: go1.26.0-1-microsoft +``` + +> [!NOTE] +> The linker flag's value is inverted compared to the question "is this feature enabled". +> This is because our goal is to set it to `0` by default in Go 1.27 and beyond. +> `0` is a more ergonomic default for boolean Go flags than `1` is. + +## Disable `GOTOOLCHAIN` + +The Microsoft build of Go disables the `GOTOOLCHAIN` feature by default to ensure consistent builds and toolchain usage. +Specifically, the default `GOTOOLCHAIN` value is `local` rather than `auto`. + +See for more information about `GOTOOLCHAIN`. + +This change [is recommended by the Go team](https://github.com/golang/go/issues/57001#issuecomment-1332657428) for Linux distributions of Go, and the reasoning applies to the Microsoft build of Go as well. +We anticipate that otherwise, many who use the Microsoft build of Go would find themselves in a situation where their build switched to the official Go toolchain without their knowledge, and they would silently lose features they rely on for compliance. + +As an additional safeguard against this risk, when the Microsoft build of Go detects that `GOTOOLCHAIN` has been manually changed to anything other than `local`, it prints a warning message to stderr and immediately exits with a non-zero status code. +This safeguard prevents forgotten or unintentional `GOTOOLCHAIN` settings from causing silent changes in toolchain behavior. +The printed message includes instructions to override the safeguard if necessary. + +## Additional Windows support + +### Use Windows Schannel settings for TLS + +This Windows-only feature filters and orders cipher suites according to Windows Schannel settings. +It ensures TLS configuration matches the system's security policies at runtime. + +> [!WARNING] +> This feature may reduce compatibility between TLS clients or servers and other implementations. +> Enable it only if your use case specifically requires alignment with Windows Schannel configuration settings. + +It is not supported and has no effect on Windows 8 and earlier and (the equivalent) Windows Server 2012 and earlier. + +### Remove use of undocumented Windows APIs + +For compatibility, security, and compliance reasons, we have removed the use of undocumented Windows APIs in the Microsoft build of Go. + +Unfortunately, this may result in some loss of long-path functionality on some Windows systems. +See [the long-path troubleshooting section of the Migration Guide](/eng/doc/MigrationGuide.md#long-path-errors-on-windows) for an example. diff --git a/eng/doc/CrossPlatformCryptography.md b/eng/doc/CrossPlatformCryptography.md index 17b727ccb1c..02dc7f8b00b 100644 --- a/eng/doc/CrossPlatformCryptography.md +++ b/eng/doc/CrossPlatformCryptography.md @@ -1,3 +1,9 @@ + + # Cross-Platform Cryptography in the Microsoft build of Go @@ -28,12 +34,45 @@ OpenSSL 3 implements all the cryptographic algorithms using [Providers](https:// The Microsoft build of Go officially supports the built-in providers and [SCOSSL (SymCrypt provider for OpenSSL)](https://github.com/microsoft/SymCrypt-OpenSSL) v1.6.1 or later. SCOSSL is expected to be used with the default built-in provider enabled as a fallback (which is the case when using [Azure Linux 3](https://github.com/microsoft/AzureLinux)). +### FreeBSD + +Since Go 1.27, the Microsoft build of Go uses the [OpenSSL crypto library](https://docs.openssl.org/3.0/man7/crypto/) on FreeBSD, the same backend as on Linux. +The algorithm support listed in the Linux column of the tables below also applies to FreeBSD. + ### macOS On macOS, the Microsoft build of Go uses [CommonCrypto](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/Common%20Crypto.3cc.html) and [CryptoKit](https://developer.apple.com/documentation/cryptokit) for cryptographic operations. CommonCrypto and CryptoKit are shipped with macOS and don't require any additional installation nor configuration. Currently macOS 13 and above is supported. +## Cgo + +Sometimes, cgo is not available: + +* When performing a cross-platform build, a suitable C compiler for cgo is often not available or very difficult to set up correctly. +* Cgo may be intentionally disabled to simplify the build process, or for security or performance reasons. +* Cgo may be intentionally disabled to avoid producing a binary that depends on the build system's glibc version. The dependency may be too new, causing the program to fail to run on some target systems. See ["glibc resolution failure on Linux" in the Migration Guide](MigrationGuide.md#glibc-resolution-failure-on-linux). + +The Microsoft build of Go attempts to use a cgo-less `systemcrypto` backend when cgo is not enabled, but on some uncommon OS and architecture combinations, this is not supported: + +| Target platform | Cgo enabled | Cgo disabled | +| --- | --- | --- | +| Linux | ✔️ | ⚠️1 | +| FreeBSD (since Go 1.27) | ⚠️2,3 | ⚠️2 | +| Windows | ✔️ | ✔️ | +| macOS | ✔️ | ✔️ | + +1 Supported on **amd64**, **arm64**, and [many other architectures](NocgoOpenSSL.md#supported-architectures). + +2 Supported on **amd64** and **arm64** architectures. + +3 Support with cgo for all FreeBSD architectures is [expected in Go 1.27.1](https://github.com/microsoft/go/pull/2477). + +> [!IMPORTANT] +> When using Go 1.26 and targeting Linux or FreeBSD, the table only applies if `GOEXPERIMENT=ms_nocgo_opensslcrypto` is set. +> Otherwise, cgo is always required. +> See [No-cgo OpenSSL Backend](NocgoOpenSSL.md) for details. + ## Table legend The following legend describes the symbols used in the tables to indicate the level of support for each cryptographic algorithm: @@ -57,39 +96,37 @@ This section includes the following packages: - [crypto/sha3](https://pkg.go.dev/crypto/sha3) - [crypto/hmac](https://pkg.go.dev/crypto/hmac) -| Algorithm | Windows | Linux | macOS | -| --------------------- | -------------- | ---------------- | -------------- | -| MD5 | ✔️ | ✔️ | ✔️ | -| SHA-1 | ✔️ | ✔️ | ✔️ | -| SHA-2-224 | ❌️ | ✔️ | ✔️ | -| SHA-2-256 | ✔️ | ✔️ | ✔️ | -| SHA-2-384 | ✔️ | ✔️ | ✔️ | -| SHA-2-512 | ✔️ | ✔️ | ✔️ | -| SHA-2-512_224 | ❌️ | ✔️1,2 | ❌️ | -| SHA-2-512_256 | ❌️ | ✔️1,2 | ❌️ | -| SHA-3-2243 | ❌️ | ✔️2 | ❌️ | -| SHA-3-2563 | ✔️4 | ✔️2 | ✔️5 | -| SHA-3-3843 | ✔️4 | ✔️2 | ✔️5 | -| SHA-3-5123 | ✔️4 | ✔️2 | ✔️5 | -| SHAKE-128 | ✔️ | ✔️6 | ❌️ | -| SHAKE-256 | ✔️ | ✔️6 | ❌️ | -| CSHAKE-128 | ✔️ | ❌️ | ❌️ | -| CSHAKE-256 | ✔️ | ❌️ | ❌️ | -| HMAC7 | ✔️ | ✔️ | ✔️ | - -1Available starting in the Microsoft build of Go 1.24. +| Algorithm | Windows | Linux | macOS | +| --------------------- | -------------- | -------------- | -------------- | +| MD5 | ✔️ | ✔️ | ✔️ | +| SHA-1 | ✔️ | ✔️ | ✔️ | +| SHA-2-224 | ❌️ | ✔️ | ❌️ | +| SHA-2-256 | ✔️ | ✔️ | ✔️ | +| SHA-2-384 | ✔️ | ✔️ | ✔️ | +| SHA-2-512 | ✔️ | ✔️ | ✔️ | +| SHA-2-512_224 | ❌️ | ✔️1 | ❌️ | +| SHA-2-512_256 | ❌️ | ✔️1 | ❌️ | +| SHA-3-2242 | ❌️ | ✔️1 | ❌️ | +| SHA-3-2562 | ✔️3 | ✔️1 | ✔️4 | +| SHA-3-3842 | ✔️3 | ✔️1 | ✔️4 | +| SHA-3-5122 | ✔️3 | ✔️1 | ✔️4 | +| SHAKE-128 | ✔️ | ✔️5 | ❌️ | +| SHAKE-256 | ✔️ | ✔️5 | ❌️ | +| CSHAKE-128 | ✔️ | ❌️ | ❌️ | +| CSHAKE-256 | ✔️ | ❌️ | ❌️ | +| HMAC6 | ✔️ | ✔️ | ✔️ | + +1Requires OpenSSL 1.1.1 or later. -2Requires OpenSSL 1.1.1 or later. - -3Available starting in the Microsoft build of Go 1.26. +2Available starting in the Microsoft build of Go 1.26. -4Requires Windows 11 (24H2) or later. +3Requires Windows 11 (24H2) or later. -5Requires macOS 26 or later. +4Requires macOS 26 or later. -6Requires OpenSSL 3.3 or later. +5Requires OpenSSL 3.3 or later. -7Supports only hash algorithms that are supported as standalone hash functions. +6Supports only hash algorithms that are supported as standalone hash functions. ## Symmetric encryption @@ -138,6 +175,7 @@ This section includes the following subsections: - [ECDSA](#ecdsa) - [ECDH](#ecdh) - [Ed25519](#ed25519) +- [ML-DSA](#ml-dsa) - [DSA](#dsa) ### RSA @@ -165,12 +203,12 @@ Operations that require random numbers (rand io.Reader) only support [rand.Reade | PSS (SHA-2)2 | ✔️4 | ✔️ | ✔️5 | | PSS (SHA-3)2 | ✔️3 | ✔️ | ❌️ | | PKCS1v15 Signature (Unhashed) | ✔️ | ✔️ | ✔️ | -| PKCS1v15 Signature (RIPMED160) | ❌️ | ✔️6 | ❌️ | +| PKCS1v15 Signature (RIPMED160) | ❌️ | ✔️ | ❌️ | | PKCS1v15 Signature (MD5) | ✔️ | ✔️ | ❌️ | -| PKCS1v15 Signature (MD5-SHA1) | ✔️6 | ✔️6 | ❌️ | +| PKCS1v15 Signature (MD5-SHA1) | ✔️ | ✔️ | ❌️ | | PKCS1v15 Signature (SHA-1) | ✔️ | ✔️ | ✔️ | | PKCS1v15 Signature (SHA-2)2 | ✔️ | ✔️ | ✔️ | -| PKCS1v15 Signature (SHA-3) | ✔️3,7 | ✔️8 | ❌️ | +| PKCS1v15 Signature (SHA-3) | ✔️3,6 | ✔️7 | ❌️ | 1macOS doesn't support passing a custom label to OAEP functions. @@ -182,11 +220,9 @@ Operations that require random numbers (rand io.Reader) only support [rand.Reade 5Custom salt lengths are not supported. PSS always uses the [`rsa.PSSSaltLengthEqualsHash`](https://pkg.go.dev/crypto/rsa#pkg-constants). -6Available starting in the Microsoft build of Go 1.24. +6Requires Windows 11 (24H2) or later. -7Requires Windows 11 (24H2) or later. - -8Requires OpenSSL 1.1.1 or later. +7Requires OpenSSL 1.1.1 or later. ### ECDSA @@ -238,6 +274,28 @@ Operations that require random numbers (rand io.Reader) only support [rand.Reade | Ed25519ctx | ❌️ | ❌️ | ❌️ | | Ed25519ph | ❌️ | ❌️ | ❌️ | +### ML-DSA + +This section includes the following packages: + +- [crypto/mldsa](https://pkg.go.dev/crypto/mldsa) + +ML-DSA is available starting from the Microsoft build of Go 1.27. + +Operations that require random numbers (rand io.Reader) only support [rand.Reader](https://pkg.go.dev/crypto/rand#Reader). Deterministic signing is always performed by the Go cryptographic module. External-mu signing falls back to the Go cryptographic module on platforms whose backend does not implement it (currently macOS). + +| Parameters | Windows | Linux | macOS | +| ---------- | -------------- | -------------- | -------------- | +| 44 | ✔️1 | ✔️2 | ❌️ | +| 65 | ✔️1 | ✔️2 | ✔️3 | +| 87 | ✔️1 | ✔️2 | ✔️3 | + +1Requires Windows 11 (24H2) or later. + +2Requires OpenSSL 3.5.0 or later. + +3Requires macOS 26 or later. + ### DSA | Parameters | Windows | Linux | macOS | diff --git a/eng/doc/DeveloperGuide.md b/eng/doc/DeveloperGuide.md index 3035b1dc90d..4e6bffc1352 100644 --- a/eng/doc/DeveloperGuide.md +++ b/eng/doc/DeveloperGuide.md @@ -1,3 +1,9 @@ + + # Developer Guide This document is a guide for developers who want to contribute to the Microsoft build of Go repository. @@ -163,6 +169,19 @@ A Git GUI that supports submodules shows the statuses of both the main repositor At this point, you can make changes, run tests, rebuild, and use the built Go toolchain in external projects. Most of the interesting Go code to modify is in `go/src`. +### Working with `cryptobackend` + +Most Microsoft build of Go changes live in `go/src`, but `cryptobackend` has two copies to know about: + +* [`cryptobackend`](../../cryptobackend) is the source module in this repository. +* `go/src/vendor/github.com/microsoft/go/cryptobackend` is the copy that gets built into the Go standard library. + +If you change cryptobackend code, run `go mod vendor` from `go/src` before running `git go-patch extract`; that copies the source module into `go/src/vendor/github.com/microsoft/go/cryptobackend` and updates the vendor metadata. + +The vendored copy has one special rule: it is allowed to import selected `crypto/internal/...` packages because the Microsoft `go` command treats it as part of the standard-library build. +The source module under [`cryptobackend`](../../cryptobackend) does not get that special access when it is built like a normal external module. +See the [`cryptobackend` README](../../cryptobackend/README.md) for more detail. + Once you have made changes that work as you expect, move on to the next step. ### Generating new patch files diff --git a/eng/doc/Downloads.md b/eng/doc/Downloads.md index a997dfd0682..30992972b6b 100644 --- a/eng/doc/Downloads.md +++ b/eng/doc/Downloads.md @@ -1,3 +1,9 @@ + + # Downloading a binary release of the Microsoft build of Go > [!IMPORTANT] @@ -13,16 +19,17 @@ For example, a 1.20 link will download 1.20.8-1 if that is the latest version of -| | 1.25 | 1.24 | +| | 1.27 | 1.26 | | --- | --- | --- | -| Source code | - [Source (tar.gz)](https://aka.ms/golang/release/latest/go1.25.src.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.25.src.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.25.src.tar.gz.sig)
| - [Source (tar.gz)](https://aka.ms/golang/release/latest/go1.24.src.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.24.src.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.24.src.tar.gz.sig)
| - Metadata | - [Asset manifest (json)](https://aka.ms/golang/release/latest/go1.25.assets.json)
| - [Asset manifest (json)](https://aka.ms/golang/release/latest/go1.24.assets.json)
| - darwin-amd64 (macOS) **Preview**2 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.25.darwin-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.25.darwin-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.25.darwin-amd64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.24.darwin-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.24.darwin-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.24.darwin-amd64.tar.gz.sig)
| - darwin-arm64 (macOS) **Preview**2 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.25.darwin-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.25.darwin-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.25.darwin-arm64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.24.darwin-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.24.darwin-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.24.darwin-arm64.tar.gz.sig)
| - linux-amd64 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.25.linux-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.25.linux-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.25.linux-amd64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.24.linux-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.24.linux-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.24.linux-amd64.tar.gz.sig)
| - linux-arm64 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.25.linux-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.25.linux-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.25.linux-arm64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.24.linux-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.24.linux-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.24.linux-arm64.tar.gz.sig)
| - linux-armv6l | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.25.linux-armv6l.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.25.linux-armv6l.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.25.linux-armv6l.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.24.linux-armv6l.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.24.linux-armv6l.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.24.linux-armv6l.tar.gz.sig)
| - windows-amd64 | - [Binaries (zip)](https://aka.ms/golang/release/latest/go1.25.windows-amd64.zip)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.25.windows-amd64.zip.sha256)
| - [Binaries (zip)](https://aka.ms/golang/release/latest/go1.24.windows-amd64.zip)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.24.windows-amd64.zip.sha256)
| +| Source code | - [Source (tar.gz)](https://aka.ms/golang/release/latest/go1.27.src.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.src.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.27.src.tar.gz.sig)
| - [Source (tar.gz)](https://aka.ms/golang/release/latest/go1.26.src.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.src.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.26.src.tar.gz.sig)
| + Metadata | - [Asset manifest (json)](https://aka.ms/golang/release/latest/go1.27.assets.json)
| - [Asset manifest (json)](https://aka.ms/golang/release/latest/go1.26.assets.json)
| + darwin-amd64 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.27.darwin-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.darwin-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.27.darwin-amd64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.26.darwin-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.darwin-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.26.darwin-amd64.tar.gz.sig)
| + darwin-arm64 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.27.darwin-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.darwin-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.27.darwin-arm64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.26.darwin-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.darwin-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.26.darwin-arm64.tar.gz.sig)
| + linux-amd64 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.27.linux-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.linux-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.27.linux-amd64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.26.linux-amd64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.linux-amd64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.26.linux-amd64.tar.gz.sig)
| + linux-arm64 | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.27.linux-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.linux-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.27.linux-arm64.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.26.linux-arm64.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.linux-arm64.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.26.linux-arm64.tar.gz.sig)
| + linux-armv6l | - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.27.linux-armv6l.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.linux-armv6l.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.27.linux-armv6l.tar.gz.sig)
| - [Binaries (tar.gz)](https://aka.ms/golang/release/latest/go1.26.linux-armv6l.tar.gz)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.linux-armv6l.tar.gz.sha256)
- [Signature1](https://aka.ms/golang/release/latest/go1.26.linux-armv6l.tar.gz.sig)
| + windows-amd64 | - [Binaries (zip)](https://aka.ms/golang/release/latest/go1.27.windows-amd64.zip)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.windows-amd64.zip.sha256)
| - [Binaries (zip)](https://aka.ms/golang/release/latest/go1.26.windows-amd64.zip)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.windows-amd64.zip.sha256)
| + windows-arm64 | - [Binaries (zip)](https://aka.ms/golang/release/latest/go1.27.windows-arm64.zip)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.27.windows-arm64.zip.sha256)
| - [Binaries (zip)](https://aka.ms/golang/release/latest/go1.26.windows-arm64.zip)
- [Checksum (SHA256)](https://aka.ms/golang/release/latest/go1.26.windows-arm64.zip.sha256)
| @@ -31,9 +38,6 @@ For example, a 1.20 link will download 1.20.8-1 if that is the latest version of > * https://download.microsoft.com/download/f/a/2/fa2420dd-3f08-4621-82cf-5a22abcbc8f9/microsoft-managed-lang-compiler.asc > * Shortened link for sharing: https://aka.ms/managed-lang-compiler-public-key -> 2 - The macOS builds and `systemcrypto` support are currently in preview and shouldn't be used in production. -> Please [open an issue](https://github.com/microsoft/go/issues/new) if you encounter any problems. - ## Downloading a specific version The table only shows a small subset of the aka.ms links we generate. diff --git a/eng/doc/Installation.md b/eng/doc/Installation.md new file mode 100644 index 00000000000..0fc910a8fad --- /dev/null +++ b/eng/doc/Installation.md @@ -0,0 +1,126 @@ + + +# Installation + +These are the installation methods available for the Microsoft build of Go. + +This document allows you to choose an installation method based on your own needs. +For an opinionated guide about how to migrate an existing project from the official build of Go to the Microsoft build of Go in a Microsoft build environment, visit the [Migration Guide](MigrationGuide.md). + +If you try to use the Microsoft build of Go and encounter problems, check the [Migration Guide](MigrationGuide.md) for solutions to commonly encountered issues. + +> [!NOTE] +> Don't see an installation option that works for you? Let us know! +> +> Look for an existing issue with the [![](https://img.shields.io/github/labels/microsoft/go/Area-Acquisition)](https://github.com/microsoft/go/labels/Area-Acquisition) tag and leave a comment, or file a new issue. +> You can also get in contact using our other [support resources](/README.md#support). + +## Docker Container Images + +[microsoft/go-images](https://github.com/microsoft/go-images) maintains and documents container images that are available on Microsoft Artifact Registry. + +## Azure Linux + +The Azure Linux 3 `golang` package is the Microsoft build of Go. +Azure Linux is maintained at [microsoft/azurelinux](https://github.com/microsoft/azurelinux). + +## Ubuntu + +To install the Microsoft build of Go using an Ubuntu package, first set up the [Linux package repository for Microsoft Products](https://learn.microsoft.com/en-us/linux/packages). +Packages are available in the Ubuntu 22.04 and 24.04 repositories. + +After the repository is added, install the Microsoft build of Go by running the following commands: + +```bash +sudo apt-get update && sudo apt-get install msft-golang +``` + +## Azure Pipelines `GoTool@0` task + +The [`GoTool@0`](https://learn.microsoft.com/azure/devops/pipelines/tasks/reference/go-tool-v0) Azure Pipelines build task supports installing the Microsoft build of Go. + +To use it, set these inputs: + +* `version`: the version of Go to install. + * The task supports the version formats `1.X`, `1.X.Y`, and `1.X.Y-Z`, and if there is a partial match, it installs the latest matching version. +* `goDownloadUrl`: use `https://aka.ms/golang/release/latest` to select the Microsoft build of Go. + +The resulting step in a yml-based Azure Pipeline looks like this: + +```yml +- task: GoTool@0 + displayName: 'Install Go' + inputs: + version: '1.26' + goDownloadUrl: 'https://aka.ms/golang/release/latest' +``` + +## GitHub Actions `setup-go` action + +The [`actions/setup-go`](https://github.com/actions/setup-go) GitHub Action supports installing the Microsoft build of Go. + +To use it, set these inputs: + +* `go-version`: the version of Go to install. + * The action supports the version formats `1.X`, `1.X.Y`, and `1.X.Y-Z`, and if there is a partial match, it installs the latest matching version. + * The `stable` and `oldstable` aliases are not supported when installing the Microsoft build of Go. +* `go-download-base-url`: use `https://aka.ms/golang/release/latest` to select the Microsoft build of Go. + +The resulting step in a GitHub Actions workflow looks like this: + +```yml +- uses: actions/setup-go@v6 + with: + go-version: '1.26' + go-download-base-url: 'https://aka.ms/golang/release/latest' +``` + +## The `go-install.ps1` script + +The [cross-platform `go-install.ps1` script](https://github.com/microsoft/go-infra/tree/main/goinstallscript) installs the Microsoft build of Go. +It can install specific versions or the latest releases. + +If you use Azure Pipelines, try running the script in a [script step](https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/cmd-line-v2?view=azure-pipelines) and pass the `-AzurePipelinePath` argument to automatically set up `go` in the environment for future steps. + +If you use GitHub Actions, pass the `-GitHubActionsPath` argument to automatically set up `go` in the environment for future steps. + +## Binary archive + +[Signed builds of Go](Downloads.md) are available as `zip` and `tar.gz` files. + +After downloading the appropriate archive for your platform, extract it to the directory of your choice. +Use the `go` (or `go.exe`) executable in the `go/bin` directory. + +## Build from source + +To build the Microsoft build of Go from source with minimal system dependencies, we recommend that you use a [pre-patched source tarball](#pre-patched-source-tarball). +For example, a maintainer of a Microsoft build of Go package for a Linux distro might prefer this method. + +If you expect to contribute to the Microsoft build of Go project in the future, you should [clone and build](#clone-and-build). + +### Pre-patched source tarball + +Each [microsoft/go GitHub release](https://github.com/microsoft/go/releases) includes a source tarball file ending in `.src.tar.gz`. +Download and extract that `.src.tar.gz` file, then use the [official Go build from source instructions](https://go.dev/doc/install/source). + +> [!WARNING] +> The `Source code (zip)` and `Source code (tar.gz)` files that GitHub offers for download on the [microsoft/go releases page](https://github.com/microsoft/go/releases) are incomplete: they don't include the `go` submodule, and don't include a pointer to the correct upstream Go commit to use. +> Make sure to download the `.src.tar.gz` file. + +### Clone and build + +First, clone this repository using Git and check out the desired tag or commit. + +If you want to contribute to the Microsoft build of Go project, read the [Developer Guide](DeveloperGuide.md). +It lists the steps we recommend to set up a Microsoft build of Go development environment, execute your first build, run the standard library test suite, and contribute a PR. +This creates a patched `go/` directory containing the `src/make.bash` script that can be used with the standard Go build from source instructions. + +If you want to build on your own machine with minimal extra steps, run `pwsh eng/run.ps1 build --refresh`. +We use this script for CI builds. +See [eng/README.md](../../eng/README.md) for more details about `eng/run.ps1` and the prerequisites necessary to run it. + +Once built, the Microsoft build of Go binary is found at `go/bin/go`. diff --git a/eng/doc/MicrosoftToolsetIdentification.md b/eng/doc/MicrosoftToolsetIdentification.md index 9887d72e6a4..049595da568 100644 --- a/eng/doc/MicrosoftToolsetIdentification.md +++ b/eng/doc/MicrosoftToolsetIdentification.md @@ -1,14 +1,36 @@ + + # Microsoft Toolset Identification Identifying whether a Go binary or toolset is from the Microsoft build of Go or the official Go distribution can be important for diagnostics and verifying expectations. As of Go 1.25, `go version` and `go version -m` don't clearly indicate the source of the toolset or binary. -We plan to address this: see [microsoft/go#262](https://github.com/microsoft/go/issues/262). -In the meantime, this document describes how to identify a Go program or Go toolset. + +As of Go 1.26, setting `GODEBUG=ms_version=1` makes `go version` report the Microsoft build version string. +`go version -m ` on a `program` built by the Microsoft build of Go always includes a `microsoft_toolset_version` line specifying the Microsoft version. + +> [!TIP] +> If you always set `GODEBUG=ms_version=1`, you will always have the most reliable information available. +> If the toolset doesn't support this setting, it will simply be ignored. + +The below sections provide step-by-step processes to help identify a Microsoft build of Go toolset and binaries built by it. ## Identifying a Go toolset -If you are able to run `go` commands but aren't sure which distribution `go` is from, you can identify it with these steps. +If you are able to run `go` commands but aren't sure which distribution `go` is from, you can identify it with these lists of steps. + +First, run `go version`. +If the output is 1.26 or later, then: + +1. Run `GODEBUG=ms_version=1 go version`. + * If the output includes the `-microsoft` suffix, it's the Microsoft build of Go. + * Otherwise, it isn't. + +If the output is 1.25 or earlier, then: 1. Run `go env GOROOT` to find the root directory of the toolset. * If the path contains clues, it might be clear already which toolset this is. @@ -26,14 +48,22 @@ First, read the version data from your application binary: go version -m ``` -Then, look for a line that contains one of these values: +Then, look for a line that contains `microsoft_toolset_version`. + + * The presence of this line confirms that the binary was built by the Microsoft build of Go. It also shows you the version and revision used. + * Unfortunately, this is only available if the binary was built with Microsoft build of Go 1.26 or later. + +Otherwise, look for one of these clues: * `microsoft_systemcrypto=1` -* `GOEXPERIMENT=systemcrypto` +* `GOEXPERIMENT=systemcrypto` in binaries built with Go 1.26 or earlier `systemcrypto` is unique to the Microsoft build of Go, so if either of these strings is present, it confirms that the binary is built by the Microsoft build of Go. -If `GOEXPERIMENT=nosystemcrypto` is present (note the `no` prefix), it confirms that the binary was built with the Microsoft build of Go, but `systemcrypto` was explicitly disabled. +If `GOEXPERIMENT=nosystemcrypto` is present (note the `no` prefix), it also confirms that the binary was built with the Microsoft build of Go, but it shows that `systemcrypto` was explicitly disabled. + +> [!NOTE] +> In Go 1.27 and later, `systemcrypto` and `nosystemcrypto` are no longer `GOEXPERIMENT` values, so it is expected that `microsoft_systemcrypto=1` will appear without a `GOEXPERIMENT` string. If none of the above are present, we can't confirm which build of Go was used. However, this situation means that the application doesn't meet Microsoft internal crypto policy, which may be enough information in some cases. diff --git a/eng/doc/MigrationGuide.md b/eng/doc/MigrationGuide.md index b78057760d9..46853788447 100644 --- a/eng/doc/MigrationGuide.md +++ b/eng/doc/MigrationGuide.md @@ -1,3 +1,9 @@ + + # Migration Guide: Microsoft build of Go This guide provides high-level guidance to help migrate from the [official Go distribution](https://go.dev/) to the [Microsoft build of Go](https://github.com/microsoft/go), comply with Microsoft internal cryptography policy, and (in some cases) build a FIPS compliant Go program. @@ -8,7 +14,8 @@ It's a fork, and some runtime behavior slightly differs, but in most cases it ha We expect that most projects don't require any Go code changes to work with the Microsoft build of Go. Note that the Microsoft build of Go has [toolset telemetry enabled by default](https://devblogs.microsoft.com/go/microsoft-go-telemetry/) (opt-out telemetry). -See [the Data Collection policy for the Microsoft build of Go](/README.md#data-collection). +See the [Telemetry documentation](/eng/doc/Telemetry.md) for details on what is collected and how to opt out. +See also [the Data Collection policy for the Microsoft build of Go](/README.md#data-collection). ## Quick start @@ -16,8 +23,7 @@ To comply with Microsoft internal policy for the use of Go, most projects need t 1. [Use the Microsoft build of Go **for CI (Continuous Integration) and build environments.**](#ci-and-build-environment-migration-steps) - See [Microsoft Toolset Identification](./MicrosoftToolsetIdentification.md) if it's not clear which distribution of Go you're currently using. -1. If you use a version of Go prior to 1.25, [enable `systemcrypto`](#enable-systemcrypto). - - Starting with 1.25 (Linux and Windows) and 1.26 (macOS), `systemcrypto` is enabled by default, and no action is required. + - Not sure what version to use? See [What version should I use?](#what-version-should-i-use) 1. [**Test** your program.](#testing) - It's important to test on all target platforms. The changes to runtime behavior are platform-specific. 1. Consider **whether your project must be FIPS compliant** and if so, [**review your project**](#review-project-for-fips-compliance). @@ -31,10 +37,6 @@ Like the official Go distribution, the Microsoft build of Go has no Go runtime c Your Go application is still a single executable binary. However, in some cases, it may now have additional dependencies. -Regardless of which method you use to install Go, we recommend picking a specific major version of Go and setting up your build system to use the latest update to that major version, a.k.a. pinning the major version. -Both official Go and the Microsoft build of Go occasionally have breaking changes in new major versions, and pinning lets you plan for and execute migrations at your own pace. -However, we recognize that pinning increases maintenance burden when there are no breaking changes, and ultimately the risk must be evaluated in the context of each project. - ## What's different? The Microsoft build of Go includes [patches](/patches/) that: @@ -45,31 +47,80 @@ The Microsoft build of Go includes [patches](/patches/) that: - **Add [toolset telemetry](https://devblogs.microsoft.com/go/microsoft-go-telemetry/)**, enabled by default. - **Disable [GOTOOLCHAIN](https://go.dev/doc/toolchain) by default** to avoid mixups with the official Go distribution. - **Remove use of undocumented Windows APIs** for compatibility, security, and compliance. +- **Embed Microsoft-specific version information** into built Go binaries for [easier identification](./MicrosoftToolsetIdentification.md). + +For a detailed description of every feature, see the [Additional Features](./AdditionalFeatures.md) document. + +## What version should I use? + +We support two major versions of the Microsoft build of Go. +They are called the *current* and *previous* major versions. +See the [Microsoft build of Go release cycle and policy](https://github.com/microsoft/go#release-cycle-and-policy) for details. + +> [!NOTE] +> "Current" and "previous" are also known as `N` and `N-1`, "stable" and "oldstable", and "latest" and "previous". +> These terms refer only to the major version. +> Do not use old patch versions. + +Check the [Microsoft build of Go binary archives table](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/Downloads.md) to see the currently supported *current* and *previous* versions. + +If you don't already have a reason to pick *current* or *previous*, you can use these criteria to help decide: + +1. For an existing project using a supported major version of Go: use the same major version of the Microsoft build of Go. +1. For an existing project using an unsupported, old version of Go: use *previous*. + * It's very important that you migrate quickly to get security fixes. Using *previous* lets you avoid a few things that could delay your migration: + * A recently-released major version (for example, `1.26.0`) may have some initial bugs that will be fixed in the next handful of patch releases. + * If there have been breaking changes that affect your project, *current* may have more breaking changes than *previous*. You will need to resolve these changes eventually, but using *previous* as a stepping stone gives you security support in the meantime. +1. For a new project or a project in early development: use the *current* version to take advantage of new features. + * If you encounter issues with *current*, please investigate and report the issue in the correct location based on your findings. You can try using *previous* to unblock your development workflow while the problem is worked out. -The patches directory at each Git tag specifies the exact code changes we have made to the official Go toolchain of that version. -If it's critical to you to understand the exact set of changes we've made, please review the patch files. +In all cases, after migration to the Microsoft build of Go is completed, we recommend that you upgrade from *previous* to *current* as soon as you can. +It's important to discover compatibility issues before *previous* reaches end of support, so the sooner you attempt to upgrade, the better. +Delaying the upgrade until *previous* is out of support allows compatibility issues to compound with security issues, delaying your ability to address Go security vulnerabilities. + +> [!NOTE] +> If you maintain a Go library, we recommend keeping it compatible with both the *previous* and *current* versions so the choice of version is left up to the library's users. +> Testing libraries against both *previous* and *current* is recommended. + +> [!TIP] +> If it seems like pointless effort to use *previous* and then quickly upgrade to *current*, simply use *current*. +> The suggested migration path is intended to help risk-averse or complex projects, but there may be cases where even in that context, this approach doesn't make sense. +> It's ok to use any supported version of the Microsoft build of Go. + +## Dependency pinning + +In ["What version should I use?"](#what-version-should-i-use), we described how to pick between *previous* and *current*. +Once you do, we recommend that you use the numeric version, so that when a new major version is released, you can upgrade your project at your own pace. +For example, if *current* is 1.26, we recommend that you configure your dependency upgrade tool to use the latest `1.26.*` version. + +Both official Go and the Microsoft build of Go occasionally have breaking changes in new major versions, and pinning lets you migrate to the next major version at your own pace while continuing to receive security updates. + +However, we recognize that in some situations, pinning may not be feasible. +The dependency update system may not provide all features necessary to pin a dependency in the desired way. +The maintenance cost of updating a major version pin may be too high compared to the risk and impact of encountering "live" compatibility breaks. +Ultimately, these risks and costs must be evaluated in the context of each project. ## CI and build environment migration steps This section describes some migration scenarios we know about and the path we recommend following for each one. > [!NOTE] -> Any method of installing the Microsoft build of Go specified [in the project README file](/README.md#download-and-install) is valid. +> Any method of installing the Microsoft build of Go specified [in the Installation guide](Installation.md) is valid. > If you see a good fit, go ahead and use it. > > The scenarios in the following sections simply offer targeted guidance to help find the easiest approach. -### The `GoTool@0` Azure Pipelines step +### A CI task or action that installs Go -The `GoTool@0` step doesn't currently support the Microsoft build of Go, and there is no equivalent step. -(See [microsoft/go#483](https://github.com/microsoft/go/issues/483).) +If your CI system has a built-in task or action that installs Go, it may support installing the Microsoft build of Go: -The most universal replacement is to use a `script` step to run [the cross-platform `go-install.ps1` script](/README.md#the-go-installps1-script). +* **Azure Pipelines:** use the [`GoTool@0` task](Installation.md#azure-pipelines-gotool0-task). +* **GitHub Actions:** use the [`actions/setup-go` action](Installation.md#github-actions-setup-go-action). ### A `go` toolset that happens to be on my build agent Some build agents (VMs, containers, etc.) have `go` conveniently pre-installed, but it's the official distribution of Go rather than the Microsoft build. -A universal migration is to use [the cross-platform `go-install.ps1` script](/README.md#the-go-installps1-script). +A universal migration is to use [the cross-platform `go-install.ps1` script](Installation.md#the-go-installps1-script). However, we recommend looking at these options first: * Request that your agent provider includes the Microsoft build of Go. @@ -101,12 +152,12 @@ If you're using it, no action is needed. ### An Ubuntu `golang` package Ubuntu packages for the Microsoft build of Go are `msft-golang` on the [Linux Software Repository for Microsoft Products](https://learn.microsoft.com/en-us/linux/packages), also known as PMC (packages.microsoft.com). -Install instructions [are in the project README file](/README.md#ubuntu). +Install instructions [are in the Installation Guide](Installation.md#ubuntu). ### A OneBranch Azure Pipeline We are not aware of an enhanced migration path for OneBranch pipelines that should be preferred over the Azure Pipelines migrations mentioned above. -See the above sections for [`GoTool@0`](#the-gotool0-azure-pipelines-step) and [container jobs](#an-azure-pipelines-container-job-referring-to-the-official-golang-container-image) to find the best fit for your project. +See the above sections for [`GoTool@0`](#the-gotool0-azure-pipelines-task) and [container jobs](#an-azure-pipelines-container-job-referring-to-the-official-golang-container-image) to find the best fit for your project. ### Direct download of the Go `tar.gz` or `zip` file @@ -115,14 +166,15 @@ That page provides links that redirect to the latest version and also immutable ## Enable `systemcrypto` -These instructions are for projects using versions of Go that don't enable `systemcrypto` by default. -Starting with 1.25 (Linux and Windows) and 1.26 (macOS), `systemcrypto` is enabled by default. +`systemcrypto` is enabled by default on supported platforms in currently supported versions of the Microsoft build of Go. +You don't need to set `GOEXPERIMENT=systemcrypto`. -To comply with Microsoft internal cryptography policy, enable the `systemcrypto` feature in your build environment before building your project. -This is done by setting the `GOEXPERIMENT` environment variable to `systemcrypto`. +Starting with Go 1.27, `systemcrypto` and `nosystemcrypto` are no longer `GOEXPERIMENT` values. +Remove them from `GOEXPERIMENT` when moving to Go 1.27 or later. +If you need to opt out of `systemcrypto`, see [Disabling `systemcrypto`](#disabling-systemcrypto). See [the FIPS documentation sections about build configuration](fips/README.md#usage-common-configurations) for more detailed instructions. -Even if you don't need FIPS compliance, the `GOEXPERIMENT` instructions are located in that document. +Even if you don't need FIPS compliance, the `systemcrypto` build configuration instructions are located in that document. ## Testing @@ -137,27 +189,36 @@ After switching to the Microsoft build of Go, you may encounter new build errors #### Cgo is not enabled +In Go 1.27 and later, Linux `systemcrypto` can build with `CGO_ENABLED=0` on supported cgo-less OpenSSL architectures. +If you're using Go 1.26 or earlier, you may see this error message if cgo is not enabled: + ``` -Using GOEXPERIMENT=systemcrypto on Linux requires CGO_ENABLED=1. +# crypto +../../../sdk/msgo1.26.0-1/src/crypto/systemcrypto_nocgo_linux.go:10:2: ` + Using GOEXPERIMENT=systemcrypto on Linux requires CGO_ENABLED=1. -Consider using our cgo-less experiment by setting GOEXPERIMENT=ms_nocgo_opensslcrypto. + Consider using our cgo-less experiment by setting GOEXPERIMENT=ms_nocgo_opensslcrypto. -For more information, visit https://github.com/microsoft/go/blob/microsoft/main/eng/doc/MigrationGuide.md#cgo-is-not-enabled + For more information, visit https://github.com/microsoft/go/blob/microsoft/main/eng/doc/MigrationGuide.md#cgo-is-not-enabled + ` (untyped string constant "\n\tUsing GOEXPERIMENT=systemcrypto on Linux requires CGO_ENABLED=1....) is not used ``` > [!NOTE] -> As of Go 1.26, there is a cgo-less experiment available for Linux: `ms_nocgo_opensslcrypto`. -> This allows the use of OpenSSL without requiring cgo. -> Currently this experiment is supported on the following architectures: `386`, `amd64`, `arm`, `arm64`, `ppc64le` and `riscv64`. +> In Go 1.26, there is a cgo-less experiment available for Linux: `ms_nocgo_opensslcrypto`. +> +> In Go 1.27 and later, cgo-less behavior is part of `systemcrypto` and is selected automatically when cgo is disabled on a supported Linux architecture. > -> While `systemcrypto` is a fully supported `GOEXPERIMENT` value (it is not "experimental"), `ms_nocgo_opensslcrypto` **is** experimental as of Go 1.26 and may have limitations. +> For more details, see [cgo-less OpenSSL Backend](NocgoOpenSSL.md). -When targeting Linux, `systemcrypto` requires cgo. -Cgo is disabled by default on some platforms or when a C compiler is not detected +When building a Go program that imports a `crypto` package (or has a dependency that imports a `crypto` package), the build will check that the build environment and target are compatible with the crypto backend being used. +If it's incompatible, the build will fail with an error like the above. + +In Go 1.26 and earlier, using `systemcrypto` on Linux requires cgo unless the `ms_nocgo_opensslcrypto` experiment is enabled. +Cgo is disabled by default on some platforms or when a C compiler is not detected. Sometimes a project's build scripts might explicitly disable cgo. -There are good reasons to disable cgo, but unfortunately, cgo is currently necessary to use `systemcrypto` on Linux. -In this case, you should first try to install a C compiler, like `gcc`. +In this case, you should first try upgrading to Go 1.27 or later. +If you need or want the cgo-based OpenSSL backend or the pre-1.27 Go version, install a C compiler, like `gcc`. You may also need to set the `CGO_ENABLED` environment variable to `1` or [otherwise enable cgo](https://pkg.go.dev/cmd/cgo). @@ -165,7 +226,8 @@ If this isn't feasible, see [disabling systemcrypto](#disabling-systemcrypto). #### Missing C toolchain and dependencies -A C toolchain is required to build programs that use `systemcrypto` on Linux. +A C toolchain is required to build programs that use the cgo-based `systemcrypto` backend on Linux. +In Go 1.27 and later, Linux builds with `CGO_ENABLED=0` use the cgo-less OpenSSL backend on supported architectures and don't require a C toolchain. The errors shown with a partially missing C toolchain can be unintuitive, so some errors and corresponding missing packages with the names they have on Azure Linux 3 are listed below. ``` @@ -219,35 +281,31 @@ go: unknown GOEXPERIMENT systemcrypto go.exe: unknown GOEXPERIMENT systemcrypto ``` -This error indicates you aren't using the Microsoft build of Go. -It happens when the `GOEXPERIMENT` environment variable includes `systemcrypto` (or `nosystemcrypto`) and the Go toolset doesn't recognize it. +This error usually indicates you aren't using the Microsoft build of Go. If you're trying to migrate to the Microsoft build of Go, check your build environment to ensure that the `go` command is the Microsoft build of Go. See [Microsoft Toolset Identification](./MicrosoftToolsetIdentification.md). -If you're trying to make a build command compliant with Microsoft crypto policy but still compatible with **both the Microsoft build of Go and the official Go distribution**, this is possible: +If you're trying to make a build command compliant with Microsoft crypto policy but still compatible with **both the Microsoft build of Go and the official Go distribution**, remove `systemcrypto` from `GOEXPERIMENT`. +`systemcrypto` is enabled by default in the Microsoft build of Go, so it's not necessary to specify it using `GOEXPERIMENT`. + +See [Disabling `systemcrypto`](#disabling-systemcrypto) for information about how to disable `systemcrypto` if you need to temporarily avoid migrating to it. -- If you're using Go 1.25 or later, remove `systemcrypto` from `GOEXPERIMENT`. Starting in 1.25, `systemcrypto` is enabled by default. - - If `GOEXPERIMENT` only contains `systemcrypto`, delete the assignment entirely. - - If it's not possible to find the `GOEXPERIMENT` setting in your build scripts and remove `systemcrypto`, reassign `GOEXPERIMENT` to remove `systemcrypto` just before your build commands. -- If you're using Go 1.24 or earlier, or want to use both 1.24 and 1.25, use build tags instead of `GOEXPERIMENT`. - - Manually enabling `systemcrypto` in the Microsoft build of Go 1.25 is unnecessary, but harmless. +#### Removed GOEXPERIMENT systemcrypto or nosystemcrypto -**Build tags** (also known as build constraints) are more flexible than `GOEXPERIMENT`: build tag names are not verified against the list of known experiments. -You can pass build tags to a `go build` command using the `-tags` flag: +In Go 1.27 or later, the Microsoft build of Go reports these errors when obsolete `GOEXPERIMENT` values are used: ``` -go build -tags=goexperiment.systemcrypto . +GOEXPERIMENT=systemcrypto has been removed; system crypto is enabled automatically on supported platforms and can be disabled with MS_GO_NOSYSTEMCRYPTO=1 ``` -See [Build Tags](fips/README.md#build-tags) in the FIPS README documentation for more information about using build tags with `systemcrypto`. - -If passing additional arguments to `go build` is undesirable, you can alternatively set up the `GOFLAGS` environment variable to include `-tags=goexperiment.systemcrypto`. -This makes all subsequent `go` commands automatically use that build tag. -See [`cmd/go` documentation](https://pkg.go.dev/cmd/go#hdr-Environment_variables) and [the FIPS readme](fips/README.md#assign-goflags-environment-variable-to-automatically-pass--tags-to-go-build) for more information about using GOFLAGS. +``` +GOEXPERIMENT=nosystemcrypto has been removed; use MS_GO_NOSYSTEMCRYPTO=1 to disable system crypto; note that systemcrypto supports CGO_ENABLED=0 since Go 1.27 +``` -> [!WARNING] -> `nosystemcrypto` can't be specified as a build tag. +These errors happen when the `GOEXPERIMENT` environment variable includes `systemcrypto` or `nosystemcrypto`. +In Go 1.27 and later, remove both values from `GOEXPERIMENT`. +The `systemcrypto` backend is enabled automatically on supported platforms, and it can be disabled with `MS_GO_NOSYSTEMCRYPTO=1` if you have an approved exception. See [Disabling `systemcrypto`](#disabling-systemcrypto) for information about how to disable `systemcrypto` if you need to temporarily avoid migrating to it. @@ -316,7 +374,7 @@ Application code and libraries that use Windows paths may need to be updated to ./app: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./app) ``` -When building a program with cgo on Linux (required when using `systemcrypto`), the system's glibc version is linked into the binary. +When building a program with the cgo-based `systemcrypto` backend on Linux, the system's glibc version is linked into the binary. When the program runs on a different system with an older version of glibc, it may fail to start with an error like the above. There are several approaches to resolve this problem: @@ -361,50 +419,17 @@ For specific guidance within Microsoft: ## Disabling `systemcrypto` The difficulty of migrating to using `systemcrypto` can vary significantly depending on the Go project. -If the change requires further planning and if it's acceptable for your project to be temporarily out of compliance with Microsoft cryptography policy, you can disable `systemcrypto` by following these instructions: - -- If you're using Go 1.25.2 or later, set the `MS_GO_NOSYSTEMCRYPTO` environment variable to 1. -- Otherwise, set the `GOEXPERIMENT` environment variable to `nosystemcrypto`. - - If you have already set `GOEXPERIMENT`, append `,nosystemcrypto` to the existing value. - -After that, build commands won't encounter errors related to `systemcrypto`, and the resulting program won't attempt to use system-provided cryptography at runtime. - -For more information about these options, see [the "Build option to use Go crypto" section of the FIPS README](fips/README.md#build-option-to-use-go-crypto-if-the-backend-compatibility-check-fails). - -Alternatively, if you experienced an unexpected auto-update to 1.25 that broke your project, you should downgrade to the latest version of 1.24. -This will disable `systemcrypto` by default and give you time to plan the migration. -You can choose to upgrade at your own pace, as long as you complete the migration before 1.24 reaches EOL (End of Life). -**1.24 EOL is expected in February 2025.** +If this change requires further planning, and if it's acceptable for your project to be temporarily out of compliance with Microsoft cryptography policy, you can disable `systemcrypto`. -For most installation methods, specify 1.24, and you will get the latest, most secure version of 1.24. +After disabling `systemcrypto`, build commands won't encounter errors related to `systemcrypto`, and the built program won't attempt to use system-provided cryptography at runtime, instead using the ordinary Go crypto implementation. -> [!TIP] -> To update to the latest version of 1.24 in Azure Linux 3, use this command: -> -> ```bash -> sudo tdnf install -y 'golang < 1.25' -> ``` -> -> Using the constraint `< 1.25` rather than a specific version ensures that you get the latest, most secure version of Go 1.24. -> -> Some care may be needed: the above command installs, downgrades, or updates `golang`, but it doesn't lock the version to 1.24. -> `golang` will be updated to the latest version of 1.25 the next time you run `tdnf update`. -> This command may only be suitable for some situations, such as CI, and may need to be run just before any steps that use `go`. -> -> `dnf` has `versionlock` capabilities, but it doesn't enable upgrades to newer patches within the major version. -> It will only lock to a specific version. - -If you're unable to complete migration to `systemcrypto` right away, we recommend disabling systemcrypto with 1.25 rather than using 1.24, if possible. -This approach lets you benefit from other changes in 1.25. -It also avoids setting the migration deadline of 1.24 EOL. - -More information about exceptions to the Microsoft cryptography policy can be found at [Microsoft.Security.Cryptography.10010 on the Liquid Microsoft-internal site.][msc10010] +To disable `systemcrypto`, see the instructions in [the "Build option to use Go crypto" section of the FIPS README](fips/README.md#build-option-to-use-go-crypto). > [!NOTE] -> Like any major version of Go, there may be more breaking changes that you need to evaluate before upgrading, not only `systemcrypto`. - -> [!NOTE] -> The Microsoft build of Go does apply [other changes](#whats-different) to the official Go distribution, but `systemcrypto` is the most impactful, and the only one that adds additional dependencies. +> `systemcrypto` is the most impactful change in the Microsoft build of Go compared to upstream Go, and the only change that adds additional runtime dependencies. +> +> However, the Microsoft build of Go does apply [other changes](#whats-different) to the official Go distribution that may cause an issue. +> If you disable `systemcrypto` and still encounter a problem, it may be caused by another change. ## Additional Resources diff --git a/eng/doc/NocgoOpenSSL.md b/eng/doc/NocgoOpenSSL.md new file mode 100644 index 00000000000..8b36ca6811b --- /dev/null +++ b/eng/doc/NocgoOpenSSL.md @@ -0,0 +1,85 @@ + + +# No-cgo OpenSSL Backend + +This document describes how the Microsoft build of Go uses the no-cgo OpenSSL backend on Linux and FreeBSD. + +> [!NOTE] +> The **no-cgo OpenSSL backend** is also known as the **cgo-less OpenSSL backend**. + +The no-cgo backend complements, rather than replaces, the cgo OpenSSL backend. +The cgo backend is still available and is used when cgo is enabled. + +## Overview + +In Go 1.27 and later, the cgo-less OpenSSL backend is part of `systemcrypto` on Linux and FreeBSD. +It is selected automatically when cgo is disabled and the target architecture is supported. + +> [!NOTE] +> In Go 1.26, this backend was available as the experimental `GOEXPERIMENT=ms_nocgo_opensslcrypto` feature on Linux only. +> +> In Go 1.27, the cgo-less backend is no longer experimental. The experiment has been removed and the cgo-less backend is selected automatically when needed. + +This allows the use of OpenSSL without requiring cgo. + +## Supported architectures + +The cgo-less OpenSSL backend is supported on the following architectures. + +On Linux: + +- 386 +- **amd64** +- arm +- **arm64** +- loong64 +- ppc64le +- riscv64 +- s390x (added in Go 1.27) + +On FreeBSD (added in Go 1.27): + +- **amd64** +- **arm64** + +The set of supported architectures is limited because each architecture requires a unique assembly implementation to call OpenSSL. +Architectures are added based on demand and available resources. +To see existing requests or request support for additional architectures, use the [![](https://img.shields.io/github/labels/microsoft/go/Area-Nocgo)](https://github.com/microsoft/go/labels/Area-Nocgo) label. + +## How the backend is selected + +Starting in Go 1.27, these rules apply without any additional `GOEXPERIMENT` value. +In Go 1.26, they apply when `GOEXPERIMENT=ms_nocgo_opensslcrypto` is set. + +* If cgo is explicitly enabled with `CGO_ENABLED=1`, the cgo-based OpenSSL backend is used. +* If cgo is disabled with `CGO_ENABLED=0`, then: + * If you're on a supported architecture, the cgo-less OpenSSL backend is used. + * If you're on an unsupported architecture, the build fails. +* If cgo is not explicitly enabled or disabled, then the cgo-less OpenSSL backend is used if the Go toolchain decides that cgo should be disabled. The rules are officially described by [cmd/cgo](https://pkg.go.dev/cmd/cgo). This is a summary, at the time of writing (2026-03-19): + * cgo is disabled if the Go toolchain is built with `CGO_ENABLED=0`. Note that that's not currently the case for the Microsoft build of Go. + * cgo is disabled when cross-compiling. + * cgo is disabled if the `CC` environment variable is not set to an existing executable. + +## Runtime dependencies + +The cgo-less OpenSSL backend still relies on the C machinery to load OpenSSL at runtime and manage threads. + +The following are the expected runtime dependencies other than OpenSSL itself on glibc-based systems: + +* `libc.so.6` for various C library functions. +* `libdl.so.2` for loading OpenSSL at runtime using `dlopen`. +* `libpthread.so.0` for managing Go's threads. + +> [!NOTE] +> The `libdl.so.2` and `libpthread.so.0` functionality is already provided by `libc.so.6` since glibc 2.34. +> The Microsoft build of Go supports platforms with older versions of glibc, so it still links to `libdl.so.2` and `libpthread.so.0` directly. +> +> There is no runtime dependency on the same libc that the program was built with. You can, for example, build a program on a system with glibc 2.34 or later and run it on a system with an older glibc version. +> +> If your platform doesn't provide these libraries, the preferred solution is to install the appropriate runtime or compatibility packages so that `libdl.so.2` and `libpthread.so.0` are available in standard system library directories (for example `/lib` or `/usr/lib`). +> +> As an advanced workaround, you may instead symlink `libdl.so.2` and `libpthread.so.0` to `libc.so.6` in a directory searched by the dynamic linker (for example, a system library directory) and update the loader cache if required (for example by running `ldconfig`); this typically requires root privileges and should only be done if you understand the implications for your system's C library. diff --git a/eng/doc/README.md b/eng/doc/README.md index 6c07ed6b63c..05ad6a62ebb 100644 --- a/eng/doc/README.md +++ b/eng/doc/README.md @@ -1,9 +1,29 @@ -This directory, `/eng/doc`, contains documents describing the Microsoft -infrastructure used to build Go, in particular any designs that are not obvious -by reading the infrastructure code itself. - -For cryptography information, see the [CrossPlatformCryptography.md](CrossPlatformCryptography.md) doc. -For dev scenario documentation, see the [DeveloperGuide.md](DeveloperGuide.md) doc. - -The [Downloads.md](Downloads.md) doc contains a table of links to the latest assets for each supported Go release branch. -The [release-branch-links.json](release-branch-links.json) file contains the same data in JSON format suitable for parsing. + + +# `/eng/doc` - Documentation for the Microsoft build of Go + +This directory, `/eng/doc`, contains detailed documents describing the Microsoft build of Go. + +> [!IMPORTANT] +> These documents are only actively maintained in the `microsoft/main` branch. +> If you're viewing this file in a release branch, it may be stale. +> [If you're not sure, click here to go to the maintained version of this document.](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/README.md) + +## Setup + +* [Migration Guide](MigrationGuide.md) +* [Installation](Installation.md) + * [Downloading a binary release](Downloads.md) +* [Developer Guide](DeveloperGuide.md) (for new contributors to the Microsoft build of Go) + +## Features + +* [Additional Features Provided by the Microsoft build of Go](AdditionalFeatures.md) +* [Cross-Platform Cryptography in the Microsoft build of Go](CrossPlatformCryptography.md) +* [Microsoft Toolset Identification](MicrosoftToolsetIdentification.md) +* [No-cgo OpenSSL Backend](NocgoOpenSSL.md) +* [Telemetry in the Microsoft build of Go](Telemetry.md) diff --git a/eng/doc/SupportedPlatforms.md b/eng/doc/SupportedPlatforms.md new file mode 100644 index 00000000000..bae22795f6e --- /dev/null +++ b/eng/doc/SupportedPlatforms.md @@ -0,0 +1,45 @@ + + +# Supported Platforms + +This document describes the platforms supported by the Microsoft build of Go. + +"Support" means that Microsoft will accept bug reports for these platforms and investigate issues. +Platforms outside this scope are supported on a best-effort basis with no guarantees. + +> [!NOTE] +> This document describes the platforms that a program built by the Microsoft build of Go can run on. +> We don't necessarily provide a toolset for every platform we support. +> See the [Downloads](./Downloads.md) table for the list of prebuilt Go toolsets we provide, and [Installation](./Installation.md) for the list of ways we recommend installing them. + +## Platform Support Matrix + +| Go OS/Arch | Minimum Versions | +|---|---| +| darwin/amd64 | macOS 13 | +| darwin/arm64 | macOS 13 | +| linux/amd64 | Azure Linux 3.0, Ubuntu 22.04 | +| linux/arm64 | Azure Linux 3.0, Ubuntu 22.04 | +| linux/arm | Ubuntu 22.04 | +| windows/386 | Windows 10, Windows Server 2016 (since Go 1.28) | +| windows/amd64 | Windows 10, Windows Server 2016 | +| windows/arm64 | Windows 11, Windows Server 2025 | + +## OpenSSL Versions + +The following OpenSSL versions are supported on Linux platforms: + +- OpenSSL 1.1.1 +- OpenSSL 3.x (built-in providers, or SymCrypt provider v1.6.1+) + +## Getting Help + +If the Microsoft build of Go doesn't support a platform you need, please let us know. +Look for an existing issue with the [![Area-Acquisition](https://img.shields.io/github/labels/microsoft/go/Area-Acquisition)](https://github.com/microsoft/go/labels/Area-Acquisition) label and leave a comment. +Otherwise, [file a new issue](https://github.com/microsoft/go/issues/new/choose). + +You can also get in contact using our other [support resources](/README.md#support). diff --git a/eng/doc/Telemetry.md b/eng/doc/Telemetry.md new file mode 100644 index 00000000000..7514c7049a8 --- /dev/null +++ b/eng/doc/Telemetry.md @@ -0,0 +1,106 @@ + + +# Telemetry in the Microsoft build of Go + +The Microsoft build of Go collects opt-out (enabled by default) toolset telemetry. +Telemetry is sent to Microsoft via Azure Application Insights when `go build`, `go install`, or `go run` is executed. +No telemetry is collected for other `go` subcommands (e.g. `go test`, `go vet`, `go fmt`). + +For the blog post announcing this feature, see [Microsoft build of Go Telemetry](https://devblogs.microsoft.com/go/microsoft-go-telemetry/). + +## What is collected + +Telemetry data consists of **counters** (simple event names that are incremented) and **properties** (key-value custom dimensions attached to a counter event). +No source code, file paths, module contents, or personally identifiable information is collected. +Each telemetry session is assigned a random session ID that cannot be linked back to a user. + +The counters and properties collected are defined in the [telemetry upload configuration](https://github.com/microsoft/go-infra/blob/main/telemetry/config/config.json) and are listed below. + +### Invocation counter + +| Counter | Description | +|---|---| +| `go/invocations` | Incremented once per `go` command invocation. | + +#### Properties on `go/invocations` + +| Property | Description | +|---|---| +| `msgo/module/hash` | A SHA-256 hash of the Go module path from the nearest `go.mod` file, found using [`modload.FindGoMod`](https://pkg.go.dev/cmd/go/internal/modload#FindGoMod). Only sent when a `go.mod` file is found. | + +### Subcommand + +| Counter | Description | +|---|---| +| `go/subcommand:{build,install,run}` | Which subcommand was used. | + +### Target platform + +| Counter | Description | +|---|---| +| `go/platform/target/port:-` | The target platform port (e.g. `linux-amd64`, `windows-arm64`). | +| `go/cgo:{enabled,disabled}` | Whether cgo was enabled for the build. | + +### GOEXPERIMENT settings + +| Counter | Description | +|---|---| +| `go/goexperiment:` | Each active `GOEXPERIMENT` value that differs from the baseline. Only Microsoft-specific experiments are uploaded: `systemcrypto`, `nosystemcrypto`, `opensslcrypto`, `cngcrypto`, `darwincrypto`, `ms_nocgo_opensslcrypto`, and `ms_tls_config_schannel`. | + +### CI environment detection + +| Counter | Description | +|---|---| +| `msgo/ci:` | Detected CI provider, if any. Values: `azdo`, `github`, `gitlab`, `appveyor`, `travis`, `circleci`, `aws_codebuild`, `jenkins`, `teamcity`, `google_cloud_build`. Detection is based on well-known environment variables set by each CI system. | + +### System cryptography + +| Counter | Description | +|---|---| +| `msgo/systemcrypto:{enabled,disabled}` | Whether the system cryptography backend is enabled. | + +## What is NOT collected + +- No source code or file contents. +- No file paths from the local file system. +- No textual module names or paths (a one-way SHA-256 hash of the module path is collected). +- No environment variable values (only the presence of specific CI-related variables is checked). +- No network or authentication information. +- No personally identifiable information (PII). + +## How to opt out + +The Microsoft build of Go sets `MS_GOTOOLCHAIN_TELEMETRY_ENABLED=1` in `$GOROOT/go.env`. +An effective value of `1` enables telemetry collection and sends data to Application Insights. +An effective value of `0` completely disables telemetry collection and sends no data. + +Users can override the installation default with the standard Go environment configuration: + +```shell +go env -w MS_GOTOOLCHAIN_TELEMETRY_ENABLED=0 +``` + +To override the setting for an individual process, set the `MS_GOTOOLCHAIN_TELEMETRY_ENABLED` environment variable to `0` when starting the process. + +> [!NOTE] +> The ability to opt out using `go env -w` and `$GOROOT/go.env` was added in 1.27.2-2 and 1.26.10-1. +> Earlier versions support configuration only through the MS_GOTOOLCHAIN_TELEMETRY_ENABLED process environment variable. + +Configuration is resolved in this order, from highest to lowest precedence: + +1. The process environment. +2. The user's `GOENV` file, managed with `go env -w` and `go env -u`. +3. The installation-wide `$GOROOT/go.env` file. + +> [!NOTE] +> This setting only controls Microsoft-specific telemetry. The upstream Go toolchain has its own [telemetry system](https://go.dev/doc/telemetry) controlled separately via `go telemetry`. + +## Privacy + +Microsoft's privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. + +See the [Data Collection policy](/README.md#data-collection) in the repository README for more information. diff --git a/eng/doc/fips/README.md b/eng/doc/fips/README.md index 7b91dbef995..01c20f001e5 100644 --- a/eng/doc/fips/README.md +++ b/eng/doc/fips/README.md @@ -1,3 +1,9 @@ + + This directory contains documentation about FIPS, details about the FIPS implementation in the Microsoft build of Go, and using system-provided cryptography via the Go standard library. * README.md (this file): an overview of the design and how to use it. @@ -50,8 +56,8 @@ The Microsoft build of Go provides several ways to configure the crypto backend These are described in the following sections in detail. - Build-time configuration (`go build`): - - [`GOEXPERIMENT=crypto` environment variable](#usage-build) - - [`goexperiment.crypto` build tag](#usage-build) + - Default [`systemcrypto` backend selection](#usage-build) + - [`MS_GO_NOSYSTEMCRYPTO=1` environment variable](#build-option-to-use-go-crypto) - [`requirefips` build tag](#build-option-to-require-fips-mode) - [`GOFIPS140=latest` environment variable](#build-option-to-require-fips-mode) - [`import _ "crypto/tls/fipsonly"` source change](#tls-with-fips-compliant-settings) @@ -68,231 +74,140 @@ The modified Go runtime is typically used to accomplish one of two goals: comply The following table summarizes common configurations and how suitable each one is for these goals. > [!NOTE] -> This document assumes the use of a supported version of the Microsoft build of Go: 1.24 or later. - -> [!NOTE] -> Since Go 1.25, `systemcrypto` is enabled by default on Linux and Windows. There is no need to manually enable using OpenSSL/CNG under the hood anymore. See also [the Go 1.25 changelog](#go-125-aug-2025). Since Go 1.26, `systemcrypto` is also enabled by default on macOS. +> This document assumes the use of a supported version of the Microsoft build of Go: 1.26 or later. > [!TIP] > If an app uses no cryptography, FIPS compliance is not relevant and the internal Microsoft crypto policy doesn't apply. | Build-time config | Runtime config | Internal Microsoft crypto policy | FIPS behavior | | --- | --- | --- | --- | -| Default, Go 1.24 | Default | Not compliant | Crypto usage is not FIPS compliant. | -| Default, Go 1.25 or later | 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. | -| `GOEXPERIMENT=systemcrypto` | `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). | -| `GOEXPERIMENT=systemcrypto` | `GO_OPENSSL_VERSION_OVERRIDE=1.1.1k-fips` | Compliant | Can be used to create a compliant app. If the app is built for Linux, `systemcrypto` chooses `opensslcrypto`, and the environment variable causes it to load `libcrypto.so.1.1.1k-fips` instead of using the automatic search behavior. This environment variable has no effect with `cngcrypto`. | -| `GOEXPERIMENT=systemcrypto` and `-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` (since Go 1.25.2) or `GOEXPERIMENT=nosystemcrypto` | Default | Not compliant | Crypto usage is not FIPS compliant. | - -A [Docker base image](#dockerfile-base-image) is available that includes suitable build-time config in the environment. +| 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). | +| 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`, Go 1.27+ | 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 [Cross-Platform Cryptography](../CrossPlatformCryptography.md) to check algorithm support per platform, and [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` | Default | Not compliant | Crypto usage is not FIPS compliant. | +| `GOOS=linux CGO_ENABLED=0`, Go 1.27+ | Default | Compliant | Can be used to create a compliant app. Uses the [cgo-less OpenSSL backend](../NocgoOpenSSL.md) on supported architectures. | +| `GOOS=linux CGO_ENABLED=0 GOEXPERIMENT=ms_nocgo_opensslcrypto`, Go 1.26 only | Default | Compliant | Can be used to create a compliant app with the [experimental cgo-less OpenSSL backend](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/NocgoOpenSSL.md). | Some configurations are invalid and intentionally result in a build error or runtime panic: | Build-time config | Runtime config | Behavior | | --- | --- | --- | -| `-tags=requirefips`, Go 1.24 | | The build fails. A crypto backend must be specified to enable FIPS features. | -| `GOEXPERIMENT=cngcrypto,opensslcrypto` | | The build fails. Only one crypto backend can be enabled at a time. | -| `GOOS=linux CGO_ENABLED=0 GOEXPERIMENT=systemcrypto` | | The build fails. Cgo is required to use the OpenSSL backend. | +| `MS_GO_NOSYSTEMCRYPTO=1` and `-tags=requirefips` | | The build fails. A crypto backend must be specified to enable FIPS features. | +| `GOOS=linux CGO_ENABLED=0` on a Linux architecture without cgo-less OpenSSL support | | The build fails. Cgo must be enabled unless the target architecture has a cgo-less OpenSSL implementation. | ## Usage: Build -The `GOEXPERIMENT` environment variable is used at build time to select a cryptographic library backend. This modifies the Go runtime included in the program to use the specified platform-provided cryptographic library whenever it calls a Go standard library crypto API. The `GOEXPERIMENT` values that pick a crypto backend are: - -- `systemcrypto` automatically selects the suggested crypto backend for the target platform - - Since Go 1.25, this experiment is enabled automatically on Windows and Linux. To disable it, see [Disabling `systemcrypto`](../MigrationGuide.md#disabling-systemcrypto). -- `opensslcrypto` selects OpenSSL, for Linux -- `cngcrypto` selects CNG, for Windows -- `darwincrypto` selects CommonCrypto & CryptoKit for macOS -- If no option is selected (and `systemcrypto` has been disabled if using Go 1.25 or later), Go standard library cryptography is used. - -The options are exclusive and must not be enabled at the same time as one another. - -The selection made by `systemcrypto` matches the internal Microsoft crypto policy for Go. If no compliant backend exists matching the target platform, the build fails. - -| Target platform | `systemcrypto` selection | Library | -| --- | --- | --- | -| Linux | `opensslcrypto` | OpenSSL | -| Windows (amd64 and arm64) | `cngcrypto` | CNG | -| macOS | `darwincrypto` | CommonCrypto & CryptoKit | - -The crypto backend selection must match the target platform. In a cross-build scenario, such as using Linux to build an app that will run on Windows, `GOOS=windows GOEXPERIMENT=systemcrypto` will correctly select `cngcrypto`. - -The Microsoft build of Go must be used for these `GOEXPERIMENT` values to work. See setup instructions in [the distribution section of the microsoft/go readme][microsoft-go-download]. - -A cross-build to Windows amd64 or arm64 will typically work, because `cngcrypto` uses syscalls to call CNG rather than cgo. -A cross-build to Linux or macOS, however, is more complicated (perhaps infeasible), because their backends use cgo. - -The Linux backends' use of cgo also introduces the glibc compatibility problem. -Building a cgo program on a distro that uses a new glibc version and running that program on a distro with an older glibc version may fail due to missing glibc symbols. -This is often mitigated by building on a distro with the oldest expected glibc version. -We have also successfully used a rootfs to build on an older glibc version (and cross-compile arm64 binaries on an amd64 machine), with rough notes available in [microsoft/go#1866](https://github.com/microsoft/go/issues/1866). - -> [!NOTE] -> "Experiment" doesn't indicate the FIPS features are experimental. The original intent of `GOEXPERIMENT` is to use it to enable experimental features in the Go runtime and toolchain, but we and Google are now using `GOEXPERIMENT` for this FIPS-related feature because the mechanism itself perfectly fits our needs. - -Setting the `goexperiment.