Source file src/crypto/internal/rand/rand.go

     1  // Copyright 2025 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 rand
     6  
     7  import (
     8  	"crypto/internal/boring"
     9  	"crypto/internal/fips140/drbg"
    10  	"crypto/internal/randutil"
    11  	"internal/godebug"
    12  	"io"
    13  	_ "unsafe"
    14  )
    15  
    16  // defaultReader aliases [drbg.DefaultReader], so that [reader]
    17  // does not have an exported DefaultReader field.
    18  type defaultReader = drbg.DefaultReader
    19  
    20  type reader struct{ defaultReader }
    21  
    22  func (r reader) Read(b []byte) (n int, err error) {
    23  	if boring.Enabled {
    24  		if _, err := boring.RandReader.Read(b); err != nil {
    25  			panic("crypto/rand: boring RandReader failed: " + err.Error())
    26  		}
    27  		return len(b), nil
    28  	}
    29  	drbg.Read(b)
    30  	return len(b), nil
    31  }
    32  
    33  // Reader is an io.Reader that calls [drbg.Read].
    34  //
    35  // It should be used internally instead of [crypto/rand.Reader], because the
    36  // latter can be set by applications outside of tests. These applications then
    37  // risk breaking between Go releases, if the way the Reader is used changes.
    38  var Reader io.Reader = reader{}
    39  
    40  // SetTestingReader overrides all calls to [drbg.Read]. The Read method of
    41  // r must never return an error or return short.
    42  //
    43  // SetTestingReader panics when building against Go Cryptographic Module v1.0.0.
    44  //
    45  // SetTestingReader is pulled by [testing/cryptotest.setGlobalRandom] via go:linkname.
    46  //
    47  //go:linkname SetTestingReader crypto/internal/rand.SetTestingReader
    48  func SetTestingReader(r io.Reader) {
    49  	fips140SetTestingReader(r)
    50  }
    51  
    52  var cryptocustomrand = godebug.New("cryptocustomrand")
    53  
    54  // CustomReader returns [Reader] or, only if the GODEBUG setting
    55  // "cryptocustomrand=1" is set, the provided io.Reader.
    56  //
    57  // If returning a non-default Reader, it calls [randutil.MaybeReadByte] on it.
    58  func CustomReader(r io.Reader) io.Reader {
    59  	if cryptocustomrand.Value() == "1" {
    60  		if !IsDefaultReader(r) {
    61  			randutil.MaybeReadByte(r)
    62  			cryptocustomrand.IncNonDefault()
    63  		}
    64  		return r
    65  	}
    66  	return Reader
    67  }
    68  

View as plain text