Skip to content
Open

G #1

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
cb8a435
build(deps): bump golang.org/x/net from 0.54.0 to 0.55.0 in /eng/_util
dependabot[bot] May 22, 2026
081f267
build(deps): bump microsoft/go-infra/.github/workflows/check-line-end…
dependabot[bot] May 22, 2026
a82ac87
Merge pull request #2298 from microsoft/dependabot/go_modules/eng/_ut…
karianna May 22, 2026
6764c85
build(deps): bump github.com/microsoft/go-infra in /eng/_util
dependabot[bot] May 22, 2026
e1a6a9f
Merge pull request #2300 from microsoft/dependabot/github_actions/mic…
karianna May 22, 2026
29843e3
Update submodule to latest master (cc623858): runtime/pprof: update t…
bot-for-go[bot] May 22, 2026
bba93ff
fix conflicts
qmuntal May 25, 2026
d7d0d5a
Merge pull request #2301 from microsoft/dev/auto-sync/microsoft/main
bot-for-go[bot] May 25, 2026
7168043
Merge pull request #2299 from microsoft/dependabot/go_modules/eng/_ut…
karianna May 25, 2026
6ffd85c
Update submodule to latest master (9da73fb7): cmd/go/internal/envcmd:…
bot-for-go[bot] May 25, 2026
040e938
build(deps): bump github/codeql-action from 4.35.5 to 4.36.0 (#2311)
dependabot[bot] May 25, 2026
466d3f4
resolve conflicts
gdams May 26, 2026
9df5391
Merge pull request #2312 from microsoft/dev/auto-sync/microsoft/main
bot-for-go[bot] May 26, 2026
eb04310
telemetry: add msgo/ci counter (#2314)
gdams May 26, 2026
873caac
use FIPSCapable
qmuntal May 26, 2026
79a8c53
Merge pull request #2315 from microsoft/dev/qmuntal/fipscapable
qmuntal May 26, 2026
c97ab25
Update blog post link description in Telemetry.md (#2316)
gdams May 27, 2026
61166d1
Update submodule to latest master (286c12b1): debug/elf: add FuzzReader
bot-for-go[bot] May 27, 2026
6e93cf6
resolve conflicts
gdams May 28, 2026
7d523ee
Merge pull request #2317 from microsoft/dev/auto-sync/microsoft/main
bot-for-go[bot] May 28, 2026
dfdb941
Update project documentation structure and clarity (#2318)
dagood May 28, 2026
8356327
Add msgo/module/hash telemetry counter (#2283)
gdams May 28, 2026
54c8cea
Update submodule to latest master (7e3a04fb): doc/next: delete
bot-for-go[bot] May 29, 2026
fbe1628
Merge pull request #2321 from microsoft/dev/auto-sync/microsoft/main
bot-for-go[bot] May 29, 2026
32418d6
Use env flag for nosystemcrypto builders
qmuntal May 29, 2026
474bbff
Potential fix for pull request finding
qmuntal May 29, 2026
39ff325
fix cmd/dist
qmuntal Jun 1, 2026
478616b
Make cmd/dist systemcrypto check bootstrap-safe
qmuntal Jun 1, 2026
f959fdf
Merge pull request #2319 from microsoft/pipeline-nosystemcrypto-env
qmuntal Jun 1, 2026
4a274e6
remove GOEXPERIMENT=systemcrypto support
qmuntal May 29, 2026
bd74ddb
Update submodule to latest master (01534385): cmd/go: allow defaults …
bot-for-go[bot] Jun 2, 2026
a695dba
Update script README for systemcrypto condition
qmuntal Jun 2, 2026
433834a
Merge pull request #2320 from microsoft/dev/qmuntal/removesystemcrypto
qmuntal Jun 2, 2026
7e2a07a
Merge remote-tracking branch 'upstream/microsoft/main' into dev/auto-…
gdams Jun 2, 2026
82f2cd5
merge backend patches
qmuntal Jun 2, 2026
a78083b
Merge pull request #2333 from microsoft/dev/auto-sync/microsoft/main
bot-for-go[bot] Jun 2, 2026
b35d1cc
Merge pull request #2334 from microsoft/dev/qmuntal/mergepatches
qmuntal Jun 2, 2026
ffcfe32
Support legacy crypto build tags
qmuntal Jun 2, 2026
0277422
Merge pull request #2335 from microsoft/dev/qmuntal/oldbuildtags
qmuntal Jun 2, 2026
99362e7
patches: unskip sanitizer tests (#2336)
gdams Jun 2, 2026
ca1f0f0
Update submodule to latest master (a81b20a4): crypto/internal/fips140…
bot-for-go[bot] Jun 2, 2026
fff7835
unskip patch 12
gdams Jun 2, 2026
280b782
Merge pull request #2338 from microsoft/dev/auto-sync/microsoft/main
bot-for-go[bot] Jun 2, 2026
d7d59b3
reduce crypto/internal/backend/fips140 API surface
qmuntal Jun 3, 2026
21a763c
Address FIPS backend review feedback
qmuntal Jun 3, 2026
0bab2e2
Fix FIPS backend patch hunk count
qmuntal Jun 3, 2026
3c48f15
Add copilot instructions for crypto backend implementation (#2344)
gdams Jun 3, 2026
c6ca7d0
Merge pull request #2343 from microsoft/dev/qmuntal/slimfips140
qmuntal Jun 3, 2026
48d8eaf
Update submodule to latest master (0252b4be): runtime: format generic…
bot-for-go[bot] Jun 3, 2026
824b148
Merge pull request #2345 from microsoft/dev/auto-sync/microsoft/main
bot-for-go[bot] Jun 3, 2026
8d85362
build(deps): bump github/codeql-action from 4.36.0 to 4.36.1
dependabot[bot] Jun 3, 2026
abfddd9
build(deps): bump actions/checkout from 6.0.2 to 6.0.3
dependabot[bot] Jun 3, 2026
b020048
Merge pull request #2347 from microsoft/dependabot/github_actions/act…
karianna Jun 4, 2026
1aaff69
Merge pull request #2346 from microsoft/dependabot/github_actions/git…
karianna Jun 4, 2026
1057e04
Fix references to Microsoft build of Go (#2349)
dagood Jun 4, 2026
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
240 changes: 240 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
# crypto-backend

Use when implementing, modifying, or adding crypto algorithms to the Microsoft build of Go crypto backend system. Covers the end-to-end workflow: editing Go source in the submodule, backend architecture patterns, and extracting changes into patches with git go-patch.

## Development workflow

See [eng/doc/DeveloperGuide.md](/eng/doc/DeveloperGuide.md) for the full development workflow, including how to set up the repository, build, test, and work with `git go-patch`.

## Architecture overview

The Microsoft build of Go replaces upstream BoringCrypto (`crypto/internal/boring`) with a pluggable backend system (`crypto/internal/backend`). The backend dispatches crypto operations to platform-native libraries:

- **Linux**: OpenSSL via `github.com/microsoft/go-crypto-openssl`
- **Windows**: CNG via `github.com/microsoft/go-crypto-winnative`
- **macOS**: CryptoKit/CommonCrypto via `github.com/microsoft/go-crypto-darwin`

The backend is gated by the `goexperiment.systemcrypto` build tag. When disabled, `nobackend.go` provides panic stubs so the code compiles but never executes.

## Build tag conventions

- All backend files use `//go:build goexperiment.systemcrypto`. The `nobackend.go` uses `//go:build !goexperiment.systemcrypto`.
- Prefer filename suffixes (`_linux.go`, `_windows.go`, `_darwin.go`) over build tag OS constraints.
- **Do**: `foo_linux.go` with `//go:build goexperiment.systemcrypto`
- **Don't**: `foo.go` with `//go:build goexperiment.systemcrypto && linux`
- The `boring.go` / `notboring.go` file pair in crypto packages uses `goexperiment.systemcrypto` / `!goexperiment.systemcrypto` build tags respectively.
- Legacy build tags (`goexperiment.opensslcrypto`, `goexperiment.cngcrypto`, `goexperiment.darwincrypto`) are still emitted for source compatibility but must not be used in new code.

## Import alias convention

Always import the backend package as `boring`:

```go
import (
boring "crypto/internal/backend"
"crypto/internal/backend/bbig"
)
```

This preserves compatibility with upstream BoringCrypto code paths and the `bcache` caching infrastructure.

## How to add a new crypto algorithm

### 1. Add backend shims (all four files)

For each platform backend file, add:
- A `Supports*()` function that delegates to the platform library
- Type aliases for key types
- Shim functions for each operation

```go
// backend_linux.go
func SupportsMLKEM768() bool { return openssl.SupportsMLKEM768() }
type DecapsulationKeyMLKEM768 = openssl.DecapsulationKeyMLKEM768
func GenerateKeyMLKEM768() (DecapsulationKeyMLKEM768, error) {
return openssl.GenerateKeyMLKEM768()
}
```

For `nobackend.go`, add matching panic stubs:

```go
func SupportsMLKEM768() bool { panic("cryptobackend: not available") }
type DecapsulationKeyMLKEM768 struct{}
func GenerateKeyMLKEM768() (DecapsulationKeyMLKEM768, error) {
panic("cryptobackend: not available")
}
```

**nobackend.go stub rules**:
- Functions: panic with `"cryptobackend: not available"`
- Types: empty structs (`struct{}` or `struct{ _ int }`)
- Methods on stub types: panic
- `Supports*()`: must panic (not return false) — they should never be called when `Enabled` is `false`
- Exception: `SupportsChaCha20Poly1305()` returns `false` (for FIPS-only mode checks)

If an operation is not supported on a platform (e.g., Darwin doesn't support DSA), the platform backend should also panic with `"cryptobackend: not available"` and the `Supports*` function should return `false`.

### 2. Integrate into the crypto package

Add a backend key field to the key struct. **Be conscious of allocations** — avoid unnecessary pointer indirection when the backend type can be stored by value, but note that some backend pointers' lifetimes may be tied to system-provided objects, so this must be a deliberate decision per type:

```go
// Prefer value types when the backend type allows it
type DecapsulationKey768 struct {
key *mlkem.DecapsulationKey768
boringKey boring.DecapsulationKeyMLKEM768
}
```

@qmuntal on PR #2342: *"Can we keep `boring` by value instead of by reference? Same as `k`."*

### 3. Create the gate function

The gate checks all prerequisites before dispatching to the backend:

```go
// For a single capability:
func supportsBoringMLKEM768() bool {
return boring.Enabled && rand.IsDefaultReader(rand.Reader) && boring.SupportsMLKEM768()
}

// For algorithms with parameter sets:
func useBoringMLDSA(params Parameters) (bparams boring.MLDSAParameters, ok bool) {
if !boring.Enabled || !rand.IsDefaultReader(rand.Reader) {
return boring.MLDSAParameters{}, false
}
bparams, ok = boringMLDSAParameters(params)
if !ok || !boring.SupportsMLDSA(bparams) {
return boring.MLDSAParameters{}, false
}
return bparams, true
}
```

**Always check capability**, not just `Enabled`:

```go
// CORRECT
if boring.Enabled && boring.SupportsCurve(c.Params().Name) { ... }

// WRONG — backend may not support all parameter variations
if boring.Enabled { ... }
```

### 4. Dispatch at the top of every public function

```go
func GenerateKey768() (*DecapsulationKey768, error) {
if supportsBoringMLKEM768() {
key, err := boring.GenerateKeyMLKEM768()
if err != nil {
return nil, err
}
return &DecapsulationKey768{boringKey: key}, nil
}
// ... existing Go implementation
}
```

For methods, check which key is populated:

```go
func (dk *DecapsulationKey768) Bytes() []byte {
if dk.key == nil {
return dk.boringKey.Bytes()
}
return dk.key.Bytes()
}
```

### 5. Handle unsupported operations with fallback

When an operation isn't supported by all backends (e.g., deterministic signing), reconstruct the upstream Go key from the seed:

```go
func (sk *PrivateKey) goKey() (*mldsa.PrivateKey, error) {
if sk.boringKey.Bytes() == nil {
return &sk.k, nil
}
// Cache the reconstructed key so subsequent calls reuse it.
if sk.k != (mldsa.PrivateKey{}) {
return &sk.k, nil
}
seed := sk.boringKey.Bytes()
var err error
switch sk.boringKey.Parameters().String() {
case "ML-DSA-44":
sk.k, err = mldsa.NewPrivateKey44(seed)
// ...
}
if err != nil {
return nil, err
}
return &sk.k, nil
}
```

**Cache the result** — reconstructing keys is expensive. Set `sk.k` on first call so subsequent calls reuse it. @qmuntal: *"Calling NewPrivate[44,65,87] is a bit slow. We could set `sk.k` the first time goKey is used so that the next call reuses the same upstream key."*

### 6. FIPS 140-only mode

When `GODEBUG=fips140=only` is set, non-FIPS-approved algorithms must return errors:

```go
func NewChaCha20Poly1305(key []byte) (cipher.AEAD, error) {
if fips140only.Enforced() {
return nil, errors.New("chacha20poly1305: use of ChaCha20Poly1305 is not allowed in FIPS 140-only mode")
}
return openssl.NewChaCha20Poly1305(key)
}
```

### 7. Update tests

- **Allocation tests**: Adjust expected allocation counts, don't skip. @qmuntal: *"Don't skip allocation tests. It's better to adjust the allocation expectations when systemcrypto is enabled. This way we catch regressions."*
- **`go/src/go/build/deps_test.go`**: Update if adding new package dependencies.

### 8. Update documentation

- Add the new algorithm's platform support status to `eng/_util/cmd/updatecryptodocs/docs.go`, then regenerate the doc:

```bash
cd eng/_util && go run ./cmd/updatecryptodocs
```

This regenerates `eng/doc/CrossPlatformCryptography.md` from the structured data in `docs.go`. **Do not edit `CrossPlatformCryptography.md` by hand** — it is auto-generated.

@qmuntal on the CSHAKE PR: *"LGTM, I'm only missing an update to CrossPlatformCryptography.md."*

## Design principles from @qmuntal

### Push operations into backends, not the integration layer

> "As a general rule (which has exceptions), we shouldn't implement in this layer operations that upstream implements in `internal/fips140`. For example, OpenSSL supports EVP_PKEY_eq. If CNG/CryptoKit don't provide similar helpers, we can always fallback to comparing the bytes in the backend."

If the native crypto library (OpenSSL, CNG, CryptoKit) provides a function for an operation like key comparison, implement it in the backend shim rather than reimplementing it in the crypto package integration code.

### Keep original variable names

When modifying existing upstream code, preserve the original variable names. @qmuntal on PR #2149: *"Keep the original variable name, `h`."*

### Use top-level functions over methods for approval checks

Prefer `func FIPSApprovedHash(h hash.Hash) bool` over adding a method to hash types. @qmuntal: *"This might be slightly better, because then we don't add new methods to the hash objects returned by sha256.New (and friends)."*

## Which patch gets which changes

- **`0001-Vendor-external-dependencies.patch`**: `vendor/` directory, `go.mod`, `go.sum`, `modules.txt`, `deps_ignore.go` — all module/vendor changes go here exclusively
- **`0002-Add-crypto-backends.patch`**: All crypto backend integration code — backend shims, algorithm integrations, test modifications, build system changes for systemcrypto
- **Other patches**: See their commit messages. Never duplicate changes across patches.

## Vendor changes workflow

If your crypto change requires a new or updated backend module dependency:

1. Make the vendor changes (`go.mod`, `go.sum`, `vendor/`) in the submodule
2. Commit them as a separate commit
3. Squash that commit into the `0001-Vendor-external-dependencies.patch` commit during `git go-patch rebase`
4. Squash the crypto code changes into the `0002-Add-crypto-backends.patch` commit
5. Run `git go-patch extract` to regenerate both patches
2 changes: 1 addition & 1 deletion .github/workflows/check-line-endings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ permissions:

jobs:
check-line-endings:
uses: microsoft/go-infra/.github/workflows/check-line-endings.yml@f4e3833067a0e64dbf9581e3e4d2df2a353f6dd0 # v0.0.13
uses: microsoft/go-infra/.github/workflows/check-line-endings.yml@eae52708dd530100eb695850bfc7f994dd9340d3 # v0.0.14
8 changes: 4 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- name: Initialize CodeQL
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1
with:
languages: go

- name: Autobuild
uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
uses: github/codeql-action/autobuild@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1
with:
working-directory: eng/_util

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1
with:
category: /language:go
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Run golangci-lint
working-directory: eng/_util
run: docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v2.10 golangci-lint run -v
4 changes: 2 additions & 2 deletions .github/workflows/patch-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
patches: ${{ steps.list.outputs.patches }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- name: Write patch matrix
id: list
Expand All @@ -38,7 +38,7 @@ jobs:
patch: ${{ fromJson(needs.list_patches.outputs.patches) }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
submodules: true

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- run: pwsh eng/run.ps1 submodule-refresh -shallow
41 changes: 21 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,33 @@ 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.
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:

* [(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.

## Release cycle and policy

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.
We announce each Microsoft build of Go release through the following channels:

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:
* [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).

* [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.
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.

## Download and install

Expand All @@ -76,7 +77,7 @@ The [Installation](eng/doc/Installation.md) documentation contains sections desc
* [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)
* [Binary archive](eng/doc/Installation.md#binary-archive) (`tar.gz` and `zip`)
* [Build from source](eng/doc/Installation.md#build-from-source)

## Contributing
Expand Down
3 changes: 3 additions & 0 deletions SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ For help and questions about the Go programming language and tools, visit the of

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
Expand Down
4 changes: 2 additions & 2 deletions eng/_util/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ go 1.25.0

require (
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/microsoft/go-infra v0.0.13
github.com/microsoft/go-infra v0.0.14
github.com/microsoft/go-infra/goinstallscript v1.2.0
golang.org/x/net v0.54.0
golang.org/x/net v0.55.0
)

require (
Expand Down
Loading