// Copyright 2026 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Patched copy of $GOROOT/src/crypto/internal/fips140/drbg/entropy_fips140.go // from Go 1.27.2, applied by tools/go-overlay. The only change is that the // 32 MiB entropy scratch buffer is allocated on first use instead of being a // package-level variable. On Windows, the package-level variable is part of // the writable .data section of the executable image, which is charged as // commit for every process even if FIPS 140-3 mode is never enabled. // See https://github.com/golang/go/issues/81956. // //go:build !wasm package drbg import ( entropy "crypto/internal/entropy/v1.0.0" "sync" ) // scratchMemory returns a scratch buffer that is accessed between samples by the // entropy source to expose it to memory access timings. // // It is allocated once and shared between Seed calls to avoid the cost of // zeroing a new allocation every time. The entropy source accesses it using // atomics (and doesn't care about its contents). var scratchMemory = sync.OnceValue(func() *entropy.ScratchBuffer { return new(entropy.ScratchBuffer) }) func getEntropy() *[SeedSize]byte { var retries int seed, err := entropy.Seed(scratchMemory()) for err != nil { // The CPU jitter-based SP 800-90B entropy source has a non-negligible // chance of failing the startup health tests. // // Each time it does, it enters a permanent failure state, and we // restart it anew. This is not expected to happen more than a few times // in a row. if retries++; retries > 100 { panic("fips140/drbg: failed to obtain initial entropy") } seed, err = entropy.Seed(scratchMemory()) } return &seed }