aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/rsa/boring.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2017-09-12 16:19:24 -0400
committerRuss Cox <rsc@golang.org>2017-09-18 00:26:15 +0000
commitc9e2d9eb06d2c57cb2a78707fb60a639a94efb42 (patch)
treec2a9285f4c6ad710ebed6f3568965b5d5ac9d87d /src/crypto/rsa/boring.go
parente773ea9aa33a574796c256930870af9e84dbfd5a (diff)
downloadgo-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/boring.go')
-rw-r--r--src/crypto/rsa/boring.go39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go
index 0f362a2f16..f25f4a5274 100644
--- a/src/crypto/rsa/boring.go
+++ b/src/crypto/rsa/boring.go
@@ -6,6 +6,8 @@ package rsa
import (
"crypto/internal/boring"
+ "crypto/rand"
+ "io"
"math/big"
"sync/atomic"
"unsafe"
@@ -122,3 +124,40 @@ func copyPrivateKey(k *PrivateKey) PrivateKey {
}
return dst
}
+
+// boringFakeRandomBlind consumes from random to mimic the
+// blinding operation done in the standard Go func decrypt.
+// When we are using BoringCrypto, we always let it handle decrypt
+// regardless of random source, because the blind doesn't affect
+// the visible output of decryption, but if the random source is not
+// true randomness then the caller might still observe the side effect
+// of consuming from the source. We consume from the source
+// to give the same side effect. This should only happen during tests
+// (verified by the UnreachableExceptTests call below).
+//
+// We go to the trouble of doing this so that we can verify that
+// func decrypt (standard RSA decryption) is dropped from
+// BoringCrypto-linked binaries entirely; otherwise we'd have to
+// keep it in the binary just in case a call happened with a
+// non-standard randomness source.
+func boringFakeRandomBlind(random io.Reader, priv *PrivateKey) {
+ if random == nil || random == boring.RandReader {
+ return
+ }
+ boring.UnreachableExceptTests()
+
+ // Copied from func decrypt.
+ for {
+ r, err := rand.Int(random, priv.N)
+ if err != nil {
+ return
+ }
+ if r.Cmp(bigZero) == 0 {
+ r = bigOne
+ }
+ _, ok := modInverse(r, priv.N)
+ if ok {
+ break
+ }
+ }
+}