-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: crypto: ignore rand io.Reader where behavior is not specified #70942
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
it seems quite rare to override rand.Reader outside of tests https://github.com/search?q=language%3Ago+%2Frand.Reader+%3D+%2F+-path%3A*_test.go&type=code |
Are there any real world use-cases where it is currently necessary to provide a different random source, than |
This is actually a pretty common requirement in tests, and it feels wrong to get tests forever stuck to a combination of We discussed a solution with @rsc: let's just acknowledge that tests need this, and that in tests it might make sense to take the tradeoff of losing backwards compatibility, and provide an explicit way to get to the same result, which only works in tests and which is also useful for other things.
|
Overall this seems reasonable, though it will be a difficult transition. We've been trying to keep niche things out of the testing package proper. How about |
I proposed it as a generically named thing because "a reproducible sequence of pseudo-tandom bytes, for testing" is something I've needed quite a few times, not only when testing crypto, and I jury-rigged it with AES-CTR or ChaCha8. I wonder if that's my selection bias, but I've heard from others that they would have needed this for generic purposes. With the testing.Testing check and such a small seed, I am not really worried about folks using it thinking it's secure. Ultimately, no strong opinion, although a new package feels like a big lift. |
This proposal has been added to the active column of the proposals project |
There are a lot of other APIs that take random io.Readers, too, like EncryptOAEP, EncryptPKCS1v15, etc. Though I also see there are a lot of functions that take a random io.Reader but are documented to ignore it. What's your ideal final state here? It seems really odd that these APIs are going to take an io.Reader that they nearly always ignore. Another option is that we introduce new APIs that don't take the io.Reader and we deprecate the APIs that do. This would let us keep the old APIs working the way they do today, at least for another release or two, but give a strong signal that people need to move off the old APIs. I'd be much more comfortable with further changing the behavior of these APIs if people had a strong signal that this was coming. Though this wouldn't help with the testing issue. This may be retreading old ground, but another option would be a vet check that requires the reader to be crypto/rand.Reader except in a test. Can you give more context, or point to a past discussion, on why we decided it was okay to break backwards compatibility for these random sources? |
If |
To clarify my question, I mean that, if I understand correctly, originally we were using the bytes from these readers in a semi-deterministic way: if you always provided the same bytes, you'd get the same results, unless you upgraded Go and there was an algorithm implementation change. At some point we moved to using those bytes but randomly shifting the stream in |
There are a few crypto APIs that take an
io.Reader
as a source of random bytes, but that don't commit to how those bytes are used. This caused issues over and over, for example any time we wanted to change the algorithm. These days we both document that they are not deterministic, and userandutil.MaybeReadByte
to somewhat enforce it. See #58637.Now that we have GODEBUGs, it might be time to rip the band-aid off. I propose we start ignoring the random
io.Reader
parameter of the following APIs, and always use the system random source (crypto/internal/sysrand.Read
, notcrypto/rand.Reader
which may be overridden by the application).rsa.GenerateKey
andrsa.GenerateMultiPrimeKey
rsa.EncryptPKCS1v15
ecdsa.GenerateKey
ecdsa.SignASN1
,ecdsa.Sign
, andecdsa.PrivateKey.Sign
ecdh.Curve.GenerateKey
Using
GODEBUG=cryptocustomrand=1
restores the old behavior. (Suggestions for a better name welcome.) This is a GODEBUG that I would like to remove in a few releases.rsa.SignPKCS1v15
is not randomized, whilersa.SignPSS
andrsa.EncryptOAEP
have a fairly well-specified way to use random bytes. Aside from those anded25519.GenerateKey
(see below), I think I listed all APIs in non-deprecated packages that take a randomio.Reader
.This might be an issue for the crypto/tls tests, which defuse
MaybeReadByte
by producing a stream of identical bytes. That's an abuse of GenerateKey anyway, because there is no guarantee that algorithms that expect random inputs will work with constant repeating streams. See for example #70643.ed25519.GenerateKey
is a weird exception in that it is well defined, but also documented to usecrypto/rand.Reader
if nil is passed. This is annoying because it forces a dependency oncrypto/rand
and therefore onmath/big
. We can't just usecrypto/internal/sysrand.Read
because the user might have overriddencrypto/rand.Reader
. I am tempted to also propose replacing "crypto/rand.Reader
" with "the system random source" but it's probably not worth the risk./cc @golang/security
The text was updated successfully, but these errors were encountered: