diff options
author | Russ Cox <rsc@golang.org> | 2017-09-12 16:19:24 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2017-09-18 00:26:15 +0000 |
commit | c9e2d9eb06d2c57cb2a78707fb60a639a94efb42 (patch) | |
tree | c2a9285f4c6ad710ebed6f3568965b5d5ac9d87d /src/crypto/rsa/rsa.go | |
parent | e773ea9aa33a574796c256930870af9e84dbfd5a (diff) | |
download | go-c9e2d9eb06d2c57cb2a78707fb60a639a94efb42.tar.gz go-c9e2d9eb06d2c57cb2a78707fb60a639a94efb42.zip |
[dev.boringcrypto] crypto/rsa: add test for, fix observable reads from custom randomness
In routines like GenerateKey, where bits from the randomness source have a
visible effect on the output, we bypass BoringCrypto if given a non-standard
randomness source (and also assert that this happens only during tests).
In the decryption paths, the randomness source is only for blinding and has
no effect on the output, so we unconditionally invoke BoringCrypto, letting it
use its own randomness source as it sees fit. This in turn lets us verify that
the non-BoringCrypto decryption function is never called, not even in tests.
Unfortunately, while the randomness source has no visible effect on the
decrypt operation, the decrypt operation does have a visible effect on
the randomness source. If decryption doesn't use the randomness source,
and it's a synthetic stream, then a future operation will read a different
position in the stream and may produce different output. This happens
in tests more often than you'd hope.
To keep behavior of those future operations unchanged while still
ensuring that the original decrypt is never called, this CL adds a
simulation of the blinding preparation, to discard the right amount
from the random source before invoking BoringCrypto.
Change-Id: If2f87b856c811b59b536187c93efa99a97721419
Reviewed-on: https://go-review.googlesource.com/63912
Reviewed-by: Adam Langley <agl@golang.org>
Diffstat (limited to 'src/crypto/rsa/rsa.go')
-rw-r--r-- | src/crypto/rsa/rsa.go | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go index 8a074e6869..53b8f963f6 100644 --- a/src/crypto/rsa/rsa.go +++ b/src/crypto/rsa/rsa.go @@ -201,7 +201,22 @@ func (priv *PrivateKey) Validate() error { // GenerateKey generates an RSA keypair of the given bit size using the // random source random (for example, crypto/rand.Reader). func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { - if boring.Enabled && (bits == 2048 || bits == 3072) { + return GenerateMultiPrimeKey(random, 2, bits) +} + +// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit +// size and the given random source, as suggested in [1]. Although the public +// keys are compatible (actually, indistinguishable) from the 2-prime case, +// the private keys are not. Thus it may not be possible to export multi-prime +// private keys in certain formats or to subsequently import them into other +// code. +// +// Table 1 in [2] suggests maximum numbers of primes for a given size. +// +// [1] US patent 4405829 (1972, expired) +// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf +func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { + if boring.Enabled && random == boring.RandReader && nprimes == 2 && (bits == 2048 || bits == 3072) { N, E, D, P, Q, Dp, Dq, Qinv, err := boring.GenerateKeyRSA(bits) if err != nil { return nil, err @@ -226,21 +241,6 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { return key, nil } - return GenerateMultiPrimeKey(random, 2, bits) -} - -// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit -// size and the given random source, as suggested in [1]. Although the public -// keys are compatible (actually, indistinguishable) from the 2-prime case, -// the private keys are not. Thus it may not be possible to export multi-prime -// private keys in certain formats or to subsequently import them into other -// code. -// -// Table 1 in [2] suggests maximum numbers of primes for a given size. -// -// [1] US patent 4405829 (1972, expired) -// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf -func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { priv := new(PrivateKey) priv.E = 65537 @@ -651,6 +651,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext } if boring.Enabled { + boringFakeRandomBlind(random, priv) bkey, err := boringPrivateKey(priv) if err != nil { return nil, err |