Source file src/crypto/internal/fips140/drbg/rand.go
1 // Copyright 2024 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 // Package drbg provides cryptographically secure random bytes 6 // usable by FIPS code. In FIPS mode it uses an SP 800-90A Rev. 1 7 // Deterministic Random Bit Generator (DRBG). Otherwise, 8 // it uses the operating system's random number generator. 9 package drbg 10 11 import ( 12 "crypto/internal/fips140" 13 "crypto/internal/sysrand" 14 "io" 15 ) 16 17 // Read fills b with cryptographically secure random bytes. In FIPS mode, it 18 // uses an SP 800-90A Rev. 1 Deterministic Random Bit Generator (DRBG). 19 // Otherwise, it uses the operating system's random number generator. 20 func Read(b []byte) { 21 if testingReader != nil { 22 fips140.RecordNonApproved() 23 // Avoid letting b escape in the non-testing case. 24 bb := make([]byte, len(b)) 25 testingReader.Read(bb) 26 copy(b, bb) 27 return 28 } 29 30 if !fips140.Enabled { 31 sysrand.Read(b) 32 return 33 } 34 35 readFromEntropy(b) 36 } 37 38 var testingReader io.Reader 39 40 // SetTestingReader sets a global, deterministic cryptographic randomness source 41 // for testing purposes. Its Read method must never return an error, it must 42 // never return short, and it must be safe for concurrent use. 43 // 44 // This is only intended to be used by the testing/cryptotest package. 45 func SetTestingReader(r io.Reader) { 46 testingReader = r 47 } 48 49 // DefaultReader is a sentinel type, embedded in the default 50 // [crypto/rand.Reader], used to recognize it when passed to 51 // APIs that accept a rand io.Reader. 52 // 53 // Any Reader that implements this interface is assumed to 54 // call [Read] as its Read method. 55 type DefaultReader interface{ defaultReader() } 56 57 // ReadWithReader uses Reader to fill b with cryptographically secure random 58 // bytes. It is intended for use in APIs that expose a rand io.Reader. 59 func ReadWithReader(r io.Reader, b []byte) error { 60 if _, ok := r.(DefaultReader); ok { 61 Read(b) 62 return nil 63 } 64 65 fips140.RecordNonApproved() 66 _, err := io.ReadFull(r, b) 67 return err 68 } 69