From: qmuntal Date: Wed, 3 Dec 2025 10:20:41 +0000 (+0100) Subject: crypto: use rand.IsDefaultReader instead of comparing to boring.RandReader X-Git-Tag: go1.26rc1~4 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1681c3b67fe5f95377fd33b98dc1f7007cf28acf;p=gostls13.git crypto: use rand.IsDefaultReader instead of comparing to boring.RandReader Several crypto functions accepting a rand parameter skip calling boringcrypto when the rand is not boring.RandReader. The new crypto/internal/rand package currently defines its own Reader that wraps boring.RandReader. That will unintentionally bypass boringcrypto when used with the aforementioned functions. Fixes #76672 Change-Id: Ie0c1345530c734a23815f9593590b5d32604f54d Reviewed-on: https://go-review.googlesource.com/c/go/+/726220 Reviewed-by: Dmitri Shuralyov Reviewed-by: Filippo Valsorda Reviewed-by: Roland Shoemaker LUCI-TryBot-Result: Go LUCI --- diff --git a/src/crypto/ecdh/nist.go b/src/crypto/ecdh/nist.go index de7348d923..13865ea701 100644 --- a/src/crypto/ecdh/nist.go +++ b/src/crypto/ecdh/nist.go @@ -27,7 +27,7 @@ func (c *nistCurve) String() string { } func (c *nistCurve) GenerateKey(r io.Reader) (*PrivateKey, error) { - if boring.Enabled && r == boring.RandReader { + if boring.Enabled && rand.IsDefaultReader(r) { key, bytes, err := boring.GenerateKeyECDH(c.name) if err != nil { return nil, err diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go index aee15b9283..b336f32eb6 100644 --- a/src/crypto/ecdsa/ecdsa.go +++ b/src/crypto/ecdsa/ecdsa.go @@ -334,7 +334,7 @@ func (priv *PrivateKey) Sign(random io.Reader, digest []byte, opts crypto.Signer // ignored unless GODEBUG=cryptocustomrand=1 is set. This setting will be removed // in a future Go release. Instead, use [testing/cryptotest.SetGlobalRandom]. func GenerateKey(c elliptic.Curve, r io.Reader) (*PrivateKey, error) { - if boring.Enabled && r == boring.RandReader { + if boring.Enabled && rand.IsDefaultReader(r) { x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name) if err != nil { return nil, err @@ -380,7 +380,7 @@ func generateFIPS[P ecdsa.Point[P]](curve elliptic.Curve, c *ecdsa.Curve[P], ran // is set. This setting will be removed in a future Go release. Instead, use // [testing/cryptotest.SetGlobalRandom]. func SignASN1(r io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { - if boring.Enabled && r == boring.RandReader { + if boring.Enabled && rand.IsDefaultReader(r) { b, err := boringPrivateKey(priv) if err != nil { return nil, err diff --git a/src/crypto/ed25519/ed25519.go b/src/crypto/ed25519/ed25519.go index f09dabe23e..a0263638ef 100644 --- a/src/crypto/ed25519/ed25519.go +++ b/src/crypto/ed25519/ed25519.go @@ -17,7 +17,6 @@ package ed25519 import ( "crypto" - "crypto/internal/fips140/drbg" "crypto/internal/fips140/ed25519" "crypto/internal/fips140cache" "crypto/internal/fips140only" @@ -153,7 +152,7 @@ func GenerateKey(random io.Reader) (PublicKey, PrivateKey, error) { if random == nil { if cryptocustomrand.Value() == "1" { random = cryptorand.Reader - if _, ok := random.(drbg.DefaultReader); !ok { + if !rand.IsDefaultReader(random) { cryptocustomrand.IncNonDefault() } } else { diff --git a/src/crypto/internal/rand/rand.go b/src/crypto/internal/rand/rand.go index 3a780952e7..29648b9f38 100644 --- a/src/crypto/internal/rand/rand.go +++ b/src/crypto/internal/rand/rand.go @@ -55,7 +55,7 @@ var cryptocustomrand = godebug.New("cryptocustomrand") // If returning a non-default Reader, it calls [randutil.MaybeReadByte] on it. func CustomReader(r io.Reader) io.Reader { if cryptocustomrand.Value() == "1" { - if _, ok := r.(drbg.DefaultReader); !ok { + if !IsDefaultReader(r) { randutil.MaybeReadByte(r) cryptocustomrand.IncNonDefault() } @@ -63,3 +63,11 @@ func CustomReader(r io.Reader) io.Reader { } return Reader } + +// IsDefaultReader reports whether r is the default [crypto/rand.Reader]. +// +// If true, the Read method of r can be assumed to call [drbg.Read]. +func IsDefaultReader(r io.Reader) bool { + _, ok := r.(drbg.DefaultReader) + return ok +} diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go index 004e6b6fed..018fe013ce 100644 --- a/src/crypto/rand/rand.go +++ b/src/crypto/rand/rand.go @@ -31,15 +31,7 @@ import ( // // In FIPS 140-3 mode, the output passes through an SP 800-90A Rev. 1 // Deterministric Random Bit Generator (DRBG). -var Reader io.Reader - -func init() { - if boring.Enabled { - Reader = boring.RandReader - return - } - Reader = rand.Reader -} +var Reader io.Reader = rand.Reader // fatal is [runtime.fatal], pushed via linkname. // @@ -57,9 +49,12 @@ func Read(b []byte) (n int, err error) { // through a potentially overridden Reader, so we special-case the default // case which we can keep non-escaping, and in the general case we read into // a heap buffer and copy from it. - if _, ok := Reader.(drbg.DefaultReader); ok { - boring.Unreachable() - drbg.Read(b) + if rand.IsDefaultReader(Reader) { + if boring.Enabled { + _, err = io.ReadFull(boring.RandReader, b) + } else { + drbg.Read(b) + } } else { bb := make([]byte, len(b)) _, err = io.ReadFull(Reader, bb) diff --git a/src/crypto/rsa/fips.go b/src/crypto/rsa/fips.go index 75aa3d3d72..fb2395886b 100644 --- a/src/crypto/rsa/fips.go +++ b/src/crypto/rsa/fips.go @@ -10,6 +10,7 @@ import ( "crypto/internal/fips140/rsa" "crypto/internal/fips140hash" "crypto/internal/fips140only" + "crypto/internal/rand" "errors" "hash" "io" @@ -59,9 +60,9 @@ func (opts *PSSOptions) saltLength() int { // used. If opts.Hash is set, it overrides hash. // // The signature is randomized depending on the message, key, and salt size, -// using bytes from rand. Most applications should use [crypto/rand.Reader] as -// rand. -func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) { +// using bytes from random. Most applications should use [crypto/rand.Reader] as +// random. +func SignPSS(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) { if err := checkPublicKeySize(&priv.PublicKey); err != nil { return nil, err } @@ -70,7 +71,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, hash = opts.Hash } - if boring.Enabled && rand == boring.RandReader { + if boring.Enabled && rand.IsDefaultReader(random) { bkey, err := boringPrivateKey(priv) if err != nil { return nil, err @@ -87,7 +88,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, if fips140only.Enforced() && !fips140only.ApprovedHash(h) { return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode") } - if fips140only.Enforced() && !fips140only.ApprovedRandomReader(rand) { + if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) { return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode") } @@ -116,7 +117,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, } } - return fipsError2(rsa.SignPSS(rand, k, h, digest, saltLength)) + return fipsError2(rsa.SignPSS(random, k, h, digest, saltLength)) } // VerifyPSS verifies a PSS signature. @@ -216,7 +217,7 @@ func encryptOAEP(hash hash.Hash, mgfHash hash.Hash, random io.Reader, pub *Publi defer hash.Reset() defer mgfHash.Reset() - if boring.Enabled && random == boring.RandReader { + if boring.Enabled && rand.IsDefaultReader(random) { k := pub.Size() if len(msg) > k-2*hash.Size()-2 { return nil, ErrMessageTooLong diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go index 0f216e0193..5269d7b971 100644 --- a/src/crypto/rsa/pkcs1v15.go +++ b/src/crypto/rsa/pkcs1v15.go @@ -61,7 +61,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro return nil, ErrMessageTooLong } - if boring.Enabled && random == boring.RandReader { + if boring.Enabled && rand.IsDefaultReader(random) { bkey, err := boringPublicKey(pub) if err != nil { return nil, err diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go index 62f2de30b0..b94b129867 100644 --- a/src/crypto/rsa/rsa.go +++ b/src/crypto/rsa/rsa.go @@ -314,7 +314,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { return nil, err } - if boring.Enabled && random == boring.RandReader && + if boring.Enabled && rand.IsDefaultReader(random) && (bits == 2048 || bits == 3072 || bits == 4096) { bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits) if err != nil {