Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions eng/doc/AdditionalFeatures.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ See also the [Data Collection policy for the Microsoft build of Go](/README.md#d
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.

As of Go 1.25, this feature is enabled by default.
As of Go 1.25 on Linux and Windows, and Go 1.26 on macOS, this feature is enabled by default on supported platforms.

Prior to Go 1.25, this feature can be enabled by setting the `GOEXPERIMENT` environment variable to `systemcrypto` before building a Go program.
Other methods of changing goexperiment settings also work.
As of Go 1.27, `systemcrypto` is no longer configured with `GOEXPERIMENT`: `GOEXPERIMENT=systemcrypto` and `GOEXPERIMENT=nosystemcrypto` are rejected.
If you need to disable the system-provided cryptography backend, set `MS_GO_NOSYSTEMCRYPTO=1` before building the program.

See [the Migration Guide](/eng/doc/MigrationGuide.md) for more information about when, and how, to configure this feature.

Expand Down
5 changes: 3 additions & 2 deletions eng/doc/MicrosoftToolsetIdentification.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ Then, look for a line that contains `microsoft_toolset_version`.
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 also confirms that the binary was built with the Microsoft build of Go, but it shows that `systemcrypto` was explicitly disabled.
If `GOEXPERIMENT=nosystemcrypto` is present in a binary built with Go 1.26 or earlier (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.
In Go 1.27 and later, `systemcrypto` and `nosystemcrypto` are no longer `GOEXPERIMENT` values, so these strings are not expected.

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.
46 changes: 32 additions & 14 deletions eng/doc/MigrationGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,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.
Starting with Go 1.25 on Linux and Windows, and Go 1.26 on macOS, `systemcrypto` is enabled by default on supported platforms.
Most projects don't need to set anything to enable it.

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` is no longer a `GOEXPERIMENT` setting.
Remove `GOEXPERIMENT=systemcrypto` and `GOEXPERIMENT=nosystemcrypto` from build scripts when moving to Go 1.27 or later; the go command rejects both because system crypto is selected automatically on supported platforms and disabled with `MS_GO_NOSYSTEMCRYPTO=1`.

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

Expand All @@ -141,7 +142,8 @@ After switching to the Microsoft build of Go, you may encounter new build errors

#### Cgo is not enabled

You may see this error message if 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:

```
# crypto
Expand All @@ -167,25 +169,28 @@ In Go 1.25, you may see this similar error:

> [!NOTE]
> In Go 1.26, there is a cgo-less experiment available for Linux: `ms_nocgo_opensslcrypto`.
> In Go 1.27 and later, this behavior is part of `systemcrypto` and is selected automatically when cgo is disabled on a supported Linux architecture.
>
> For more details, see [cgo-less OpenSSL Backend](NocgoOpenSSL.md).

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.

When targeting Linux, `systemcrypto` requires cgo.
In Go 1.26 and earlier, targeting Linux with `systemcrypto` usually 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.

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, 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).

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.

```
Expand Down Expand Up @@ -229,7 +234,7 @@ Alternatively, the `build-essential` package contains all of these packages and

If this isn't feasible, see [disabling systemcrypto](#disabling-systemcrypto).

#### Unknown GOEXPERIMENT systemcrypto
#### Unknown or removed GOEXPERIMENT systemcrypto

```
go: unknown GOEXPERIMENT systemcrypto
Expand All @@ -239,14 +244,27 @@ 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.
In Go 1.27 or later, the Microsoft build of Go reports a different error for the same obsolete build setting:

```
GOEXPERIMENT=systemcrypto has been removed; system crypto is enabled automatically on supported platforms and can be disabled with MS_GO_NOSYSTEMCRYPTO=1
```

```
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
```

These errors happen when the `GOEXPERIMENT` environment variable includes `systemcrypto` or `nosystemcrypto`.
In Go 1.27 and later, remove both values from `GOEXPERIMENT`.
System crypto is enabled automatically on supported platforms, and it can be disabled with `MS_GO_NOSYSTEMCRYPTO=1` if you have an approved exception.

The `unknown GOEXPERIMENT systemcrypto` form 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**, remove `systemcrypto` from `GOEXPERIMENT`.
`systemcrypto` is enabled by default, so it's not necessary to specify it using `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.

Expand Down Expand Up @@ -315,7 +333,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:
Expand Down
15 changes: 9 additions & 6 deletions eng/doc/NocgoOpenSSL.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# No-cgo OpenSSL Backend

This document describes how to enable and use the cgo-less OpenSSL backend for the Microsoft build of Go, available as an experimental feature starting in Go 1.26.
This document describes how the Microsoft build of Go uses the cgo-less OpenSSL backend on Linux.

## Overview

In Go 1.26, there is a cgo-less experiment available for Linux: `ms_nocgo_opensslcrypto`.
In Go 1.27 and later, the cgo-less OpenSSL backend is part of `systemcrypto` on Linux.
It is selected automatically when cgo is disabled and the target architecture is supported.

> [!NOTE]
> While `systemcrypto` is a fully supported `GOEXPERIMENT` value (it is not "experimental"), `ms_nocgo_opensslcrypto` **is** experimental in Go 1.26 and may have limitations.

In Go 1.27, the experiment will be removed and the cgo requirement for `systemcrypto` on Linux will be lifted by default.
> In Go 1.26, this backend was available as the experimental `GOEXPERIMENT=ms_nocgo_opensslcrypto` feature.
> In Go 1.27, that experiment has been removed because the cgo-less backend is selected automatically when needed.

This allows the use of OpenSSL without requiring cgo.

## Supported architectures

Currently this experiment is supported on the following architectures:
The cgo-less OpenSSL backend is supported on the following architectures:

- 386
- **amd64**
Expand All @@ -32,6 +32,9 @@ To see existing requests or request support for additional architectures, use th

## 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.
Expand Down
2 changes: 1 addition & 1 deletion eng/doc/Telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ The counters and properties collected are defined in the [telemetry upload confi

| Counter | Description |
|---|---|
| `msgo/systemcrypto:{enabled,disabled}` | Whether the system cryptography backend is enabled on platforms that support it. |
| `msgo/systemcrypto:{enabled,disabled}` | Whether the system cryptography backend is enabled on platforms that support it. This reflects the default platform selection and the `MS_GO_NOSYSTEMCRYPTO=1` opt-out. |

## What is NOT collected

Expand Down
Loading
Loading