blob: 00e736a579859afc4d87c432a1522b749f995f62 [file] [log] [blame] [edit]
// Copyright 2025 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 rand
import (
"crypto/internal/boring"
"crypto/internal/fips140/drbg"
"crypto/internal/randutil"
"internal/godebug"
"io"
_ "unsafe"
)
// defaultReader aliases [drbg.DefaultReader], so that [reader]
// does not have an exported DefaultReader field.
type defaultReader = drbg.DefaultReader
type reader struct{ defaultReader }
func (r reader) Read(b []byte) (n int, err error) {
if boring.Enabled {
if _, err := boring.RandReader.Read(b); err != nil {
panic("crypto/rand: boring RandReader failed: " + err.Error())
}
return len(b), nil
}
drbg.Read(b)
return len(b), nil
}
// Reader is an io.Reader that calls [drbg.Read].
//
// It should be used internally instead of [crypto/rand.Reader], because the
// latter can be set by applications outside of tests. These applications then
// risk breaking between Go releases, if the way the Reader is used changes.
var Reader io.Reader = reader{}
// SetTestingReader overrides all calls to [drbg.Read]. The Read method of
// r must never return an error or return short.
//
// SetTestingReader panics when building against Go Cryptographic Module v1.0.0.
//
// SetTestingReader is pulled by [testing/cryptotest.setGlobalRandom] via go:linkname.
//
//go:linkname SetTestingReader crypto/internal/rand.SetTestingReader
func SetTestingReader(r io.Reader) {
fips140SetTestingReader(r)
}
var cryptocustomrand = godebug.New("cryptocustomrand")
// CustomReader returns [Reader] or, only if the GODEBUG setting
// "cryptocustomrand=1" is set, the provided io.Reader.
//
// If returning a non-default Reader, it calls [randutil.MaybeReadByte] on it.
func CustomReader(r io.Reader) io.Reader {
if cryptocustomrand.Value() == "1" {
if !IsDefaultReader(r) {
randutil.MaybeReadByte(r)
cryptocustomrand.IncNonDefault()
}
return r
}
return Reader
}