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  

View as plain text