Source File
rand.go
Belonging Package
crypto/internal/fips140/drbg
// Copyright 2024 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.
// Package drbg provides cryptographically secure random bytes
// usable by FIPS code. In FIPS mode it uses an SP 800-90A Rev. 1
// Deterministic Random Bit Generator (DRBG). Otherwise,
// it uses the operating system's random number generator.
package drbg
import (
)
var drbgs = sync.Pool{
New: func() any {
var *Counter
entropy.Depleted(func( *[48]byte) {
= NewCounter()
})
return
},
}
// Read fills b with cryptographically secure random bytes. In FIPS mode, it
// uses an SP 800-90A Rev. 1 Deterministic Random Bit Generator (DRBG).
// Otherwise, it uses the operating system's random number generator.
func ( []byte) {
if !fips140.Enabled {
sysrand.Read()
return
}
// At every read, 128 random bits from the operating system are mixed as
// additional input, to make the output as strong as non-FIPS randomness.
// This is not credited as entropy for FIPS purposes, as allowed by Section
// 8.7.2: "Note that a DRBG does not rely on additional input to provide
// entropy, even though entropy could be provided in the additional input".
:= new([SeedSize]byte)
sysrand.Read([:16])
:= drbgs.Get().(*Counter)
defer drbgs.Put()
for len() > 0 {
:= min(len(), maxRequestSize)
if := .Generate([:], ); {
// See SP 800-90A Rev. 1, Section 9.3.1, Steps 6-8, as explained in
// Section 9.3.2: if Generate reports a reseed is required, the
// additional input is passed to Reseed along with the entropy and
// then nulled before the next Generate call.
entropy.Depleted(func( *[48]byte) {
.Reseed(, )
})
= nil
continue
}
= [:]
}
}
// DefaultReader is a sentinel type, embedded in the default
// [crypto/rand.Reader], used to recognize it when passed to
// APIs that accept a rand io.Reader.
type DefaultReader interface{ defaultReader() }
// ReadWithReader uses Reader to fill b with cryptographically secure random
// bytes. It is intended for use in APIs that expose a rand io.Reader.
//
// If Reader is not the default Reader from crypto/rand,
// [randutil.MaybeReadByte] and [fips140.RecordNonApproved] are called.
func ( io.Reader, []byte) error {
if , := .(DefaultReader); {
Read()
return nil
}
fips140.RecordNonApproved()
randutil.MaybeReadByte()
, := io.ReadFull(, )
return
}
// ReadWithReaderDeterministic is like ReadWithReader, but it doesn't call
// [randutil.MaybeReadByte] on non-default Readers.
func ( io.Reader, []byte) error {
if , := .(DefaultReader); {
Read()
return nil
}
fips140.RecordNonApproved()
, := io.ReadFull(, )
return
}
![]() |
The pages are generated with Golds v0.7.7-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |