Source file src/crypto/internal/fips140/drbg/entropy_fips140.go
1 // Copyright 2026 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Entropy generation in FIPS 140-3 mode uses a scratch buffer in the BSS 6 // section (see below), which usually doesn't cost much, except on Wasm, due to 7 // the way the linear memory works. FIPS 140-3 mode is not supported on Wasm, so 8 // we just use a build tag to exclude it. (Could also exclude other platforms 9 // that does not support FIPS 140-3 mode, but as the BSS variable doesn't cost 10 // much, don't bother.) 11 // 12 //go:build !wasm 13 14 package drbg 15 16 import entropy "crypto/internal/entropy/v1.0.0" 17 18 // memory is a scratch buffer that is accessed between samples by the entropy 19 // source to expose it to memory access timings. 20 // 21 // We reuse it and share it between Seed calls to avoid the significant (~500µs) 22 // cost of zeroing a new allocation every time. The entropy source accesses it 23 // using atomics (and doesn't care about its contents). 24 // 25 // It should end up in the .noptrbss section, and become backed by physical pages 26 // at first use. This ensures that programs that do not use the FIPS 140-3 module 27 // do not incur any memory use or initialization penalties. 28 var memory entropy.ScratchBuffer 29 30 func getEntropy() *[SeedSize]byte { 31 var retries int 32 seed, err := entropy.Seed(&memory) 33 for err != nil { 34 // The CPU jitter-based SP 800-90B entropy source has a non-negligible 35 // chance of failing the startup health tests. 36 // 37 // Each time it does, it enters a permanent failure state, and we 38 // restart it anew. This is not expected to happen more than a few times 39 // in a row. 40 if retries++; retries > 100 { 41 panic("fips140/drbg: failed to obtain initial entropy") 42 } 43 seed, err = entropy.Seed(&memory) 44 } 45 return &seed 46 } 47