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  

View as plain text