]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.boringcrypto] crypto/rsa: drop random source reading emulation
authorFilippo Valsorda <filippo@golang.org>
Fri, 8 Jun 2018 22:58:30 +0000 (18:58 -0400)
committerFilippo Valsorda <filippo@golang.org>
Wed, 13 Jun 2018 21:59:09 +0000 (21:59 +0000)
Now that the standard library behavior in reading from the randomness
source is not reliable thanks to randutil.MaybeReadByte, we don't need
to emulate its behavior.

Also, since boring.RandReader is never deterministic, add an early exit
to randutil.MaybeReadByte.

Change-Id: Ie53e45ee64af635595181f71abd3c4340c600907
Reviewed-on: https://go-review.googlesource.com/117555
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/crypto/rsa/boring.go
src/crypto/rsa/boring_test.go
src/crypto/rsa/pkcs1v15.go
src/crypto/rsa/pss.go
src/crypto/rsa/rsa.go

index 0ddff014e60627c77942d06877cd6e132efd7391..0f362a2f165bd2a1480c3ec0b12046be047fd98a 100644 (file)
@@ -6,8 +6,6 @@ package rsa
 
 import (
        "crypto/internal/boring"
-       "crypto/rand"
-       "io"
        "math/big"
        "sync/atomic"
        "unsafe"
@@ -124,41 +122,3 @@ 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.
-       ir := new(big.Int)
-       for {
-               r, err := rand.Int(random, priv.N)
-               if err != nil {
-                       return
-               }
-               if r.Cmp(bigZero) == 0 {
-                       r = bigOne
-               }
-               ok := ir.ModInverse(r, priv.N)
-               if ok != nil {
-                       break
-               }
-       }
-}
index dfec83805f651db7caacbcbc40865e3a497a48e0..f68dfc9999721049161909f698ec8b6422c6093e 100644 (file)
@@ -8,13 +8,9 @@
 package rsa
 
 import (
-       "bytes"
        "crypto"
        "crypto/rand"
-       "crypto/sha1"
-       "crypto/sha256"
        "encoding/asn1"
-       "encoding/hex"
        "reflect"
        "runtime"
        "runtime/debug"
@@ -77,90 +73,11 @@ func TestBoringVerify(t *testing.T) {
        }
 }
 
-// The goal for BoringCrypto is to be indistinguishable from standard Go crypto.
-// Test that when routines are passed a not-actually-random reader, they
-// consume and potentially expose the expected bits from that reader.
-// This is awful but it makes sure that golden tests based on deterministic
-// "randomness" sources are unchanged by BoringCrypto.
-//
-// For decryption and signing, r is only used for blinding,
-// so we can and do still use BoringCrypto with its own true
-// randomness source, but we must be careful to consume
-// from r as if we'd used it for blinding.
-
-type testRandReader struct {
-       t      *testing.T
-       offset int64
-       seq    [8]byte
-       data   []byte
-       buf    [32]byte
-}
-
-func (r *testRandReader) Read(b []byte) (int, error) {
-       if len(r.data) == 0 && len(b) > 0 {
-               for i := range r.seq {
-                       r.seq[i]++
-                       if r.seq[i] != 0 {
-                               break
-                       }
-               }
-               r.buf = sha256.Sum256(r.seq[:])
-               r.data = r.buf[:]
-       }
-       n := copy(b, r.data)
-       r.data = r.data[n:]
-       r.offset += int64(n)
-       return n, nil
-}
-
-func (r *testRandReader) checkOffset(offset int64) {
-       r.t.Helper()
-       if r.offset != offset {
-               r.t.Fatalf("r.offset = %d, expected %d", r.offset, offset)
-       }
-}
-
-func testRand(t *testing.T) *testRandReader {
-       return &testRandReader{t: t}
-}
-
-var testKeyCache struct {
-       once sync.Once
-       k    *PrivateKey
-}
-
-func testKey(t *testing.T) *PrivateKey {
-       testKeyCache.once.Do(func() {
-               // Note: Key must be 2048 bits in order to trigger
-               // BoringCrypto code paths.
-               k, err := GenerateKey(testRand(t), 2048)
-               if err != nil {
-                       t.Fatal(err)
-               }
-               testKeyCache.k = k
-       })
-       return testKeyCache.k
-}
-
-func bytesFromHex(t *testing.T, x string) []byte {
-       b, err := hex.DecodeString(x)
-       if err != nil {
-               t.Fatal(err)
-       }
-       return b
-}
-
-func TestBoringRandGenerateKey(t *testing.T) {
-       r := testRand(t)
-       k, err := GenerateKey(r, 2048) // 2048 is smallest size BoringCrypto might kick in for
+func TestBoringGenerateKey(t *testing.T) {
+       k, err := GenerateKey(rand.Reader, 2048) // 2048 is smallest size BoringCrypto might kick in for
        if err != nil {
                t.Fatal(err)
        }
-       n := bigFromHex("b2e9c4c8b1c0f03ba6994fe1e715a3e598f0571f4676da420615b7b997d431ea7535ceb98e6b52172fe0d2fccfc5f696d1b34144f7d19d85633fcbf56daff805a66457b360b1b0f40ec18fb83f4c9b86f1b5fe26b209cdfff26911a95047df797210969693226423915c9be53ff1c06f86fe2d228273ef25970b90a3c70979f9d68458d5dd38f6700436f7cd5939c04be3e1f2ff52272513171540a685c9e8c8e20694e529cc3e0cc13d2fb91ac499d44b920a03e42be89a15e7ca73c29f2e2a1a8a7d9be57516ccb95e878db6ce6096e386a793cccc19eba15a37cc0f1234b7a25ee7c87569bc74c7ef3d6ad8d84a5ddb1e8901ae593f945523fe5e0ed451a5")
-       if k.N.Cmp(n) != 0 {
-               t.Fatalf("GenerateKey: wrong N\nhave %x\nwant %x", k.N, n)
-       }
-       r.checkOffset(35200)
 
        // Non-Boring GenerateKey always sets CRTValues to a non-nil (possibly empty) slice.
        if k.Precomputed.CRTValues == nil {
@@ -168,132 +85,6 @@ func TestBoringRandGenerateKey(t *testing.T) {
        }
 }
 
-func TestBoringRandGenerateMultiPrimeKey(t *testing.T) {
-       r := testRand(t)
-       k, err := GenerateMultiPrimeKey(r, 2, 2048)
-       if err != nil {
-               t.Fatal(err)
-       }
-       n := bigFromHex("b2e9c4c8b1c0f03ba6994fe1e715a3e598f0571f4676da420615b7b997d431ea7535ceb98e6b52172fe0d2fccfc5f696d1b34144f7d19d85633fcbf56daff805a66457b360b1b0f40ec18fb83f4c9b86f1b5fe26b209cdfff26911a95047df797210969693226423915c9be53ff1c06f86fe2d228273ef25970b90a3c70979f9d68458d5dd38f6700436f7cd5939c04be3e1f2ff52272513171540a685c9e8c8e20694e529cc3e0cc13d2fb91ac499d44b920a03e42be89a15e7ca73c29f2e2a1a8a7d9be57516ccb95e878db6ce6096e386a793cccc19eba15a37cc0f1234b7a25ee7c87569bc74c7ef3d6ad8d84a5ddb1e8901ae593f945523fe5e0ed451a5")
-       if k.N.Cmp(n) != 0 {
-               t.Fatalf("GenerateKey: wrong N\nhave %x\nwant %x", k.N, n)
-       }
-       r.checkOffset(35200)
-}
-
-func TestBoringRandEncryptPKCS1v15(t *testing.T) {
-       r := testRand(t)
-       k := testKey(t)
-       enc, err := EncryptPKCS1v15(r, &k.PublicKey, []byte("hello world"))
-       if err != nil {
-               t.Fatal(err)
-       }
-       want := bytesFromHex(t, "a8c8c0d248e669942a140c1184e1112afbf794b7427d9ac966bd2dbb4c05a2fee76f311f7feec743b8a8715e34bf741b0d0c4226559daf4de258ff712178e3f25fecb7d3eee90251e8ae4b4b7b907cd2763948cc9da34ce83c69934b523830545a536c1ba4d3740f4687e877acee9c768bcd8e88d472ba5d905493121f4830d95dcea36ef0f1223ffb0a9008eddfc53aca36877328924a2c631dce4b67e745564301fe51ab2c768b39e525bda1e1a08e029b58c53a0b92285f734592d2deebda957bcfd29c697aee263fce5c5023c7d3495b6a9114a8ac691aa661721cf45973b68678bb1e15d6605b9040951163d5b6df0d7f0b20dcefa251a7a8947a090f4b")
-       if !bytes.Equal(enc, want) {
-               t.Fatalf("EncryptPKCS1v15: wrong enc\nhave %x\nwant %x", enc, want)
-       }
-       r.checkOffset(242)
-}
-
-func TestBoringRandDecryptPKCS1v15(t *testing.T) {
-       r := testRand(t)
-       k := testKey(t)
-       enc := bytesFromHex(t, "a8c8c0d248e669942a140c1184e1112afbf794b7427d9ac966bd2dbb4c05a2fee76f311f7feec743b8a8715e34bf741b0d0c4226559daf4de258ff712178e3f25fecb7d3eee90251e8ae4b4b7b907cd2763948cc9da34ce83c69934b523830545a536c1ba4d3740f4687e877acee9c768bcd8e88d472ba5d905493121f4830d95dcea36ef0f1223ffb0a9008eddfc53aca36877328924a2c631dce4b67e745564301fe51ab2c768b39e525bda1e1a08e029b58c53a0b92285f734592d2deebda957bcfd29c697aee263fce5c5023c7d3495b6a9114a8ac691aa661721cf45973b68678bb1e15d6605b9040951163d5b6df0d7f0b20dcefa251a7a8947a090f4b")
-       dec, err := DecryptPKCS1v15(r, k, enc)
-       if err != nil {
-               t.Fatal(err)
-       }
-       want := []byte("hello world")
-       if !bytes.Equal(dec, want) {
-               t.Fatalf("DecryptPKCS1v15: wrong dec\nhave %x\nwant %x", dec, want)
-       }
-       r.checkOffset(256)
-}
-
-func TestBoringRandDecryptPKCS1v15SessionKey(t *testing.T) {
-       r := testRand(t)
-       k := testKey(t)
-       enc := bytesFromHex(t, "a8c8c0d248e669942a140c1184e1112afbf794b7427d9ac966bd2dbb4c05a2fee76f311f7feec743b8a8715e34bf741b0d0c4226559daf4de258ff712178e3f25fecb7d3eee90251e8ae4b4b7b907cd2763948cc9da34ce83c69934b523830545a536c1ba4d3740f4687e877acee9c768bcd8e88d472ba5d905493121f4830d95dcea36ef0f1223ffb0a9008eddfc53aca36877328924a2c631dce4b67e745564301fe51ab2c768b39e525bda1e1a08e029b58c53a0b92285f734592d2deebda957bcfd29c697aee263fce5c5023c7d3495b6a9114a8ac691aa661721cf45973b68678bb1e15d6605b9040951163d5b6df0d7f0b20dcefa251a7a8947a090f4b")
-       dec := make([]byte, 11)
-       err := DecryptPKCS1v15SessionKey(r, k, enc, dec)
-       if err != nil {
-               t.Fatal(err)
-       }
-       want := []byte("hello world")
-       if !bytes.Equal(dec, want) {
-               t.Fatalf("DecryptPKCS1v15SessionKey: wrong dec\nhave %x\nwant %x", dec, want)
-       }
-       r.checkOffset(256)
-}
-
-func TestBoringRandSignPKCS1v15(t *testing.T) {
-       r := testRand(t)
-       k := testKey(t)
-       sum := sha1.Sum([]byte("hello"))
-       sig, err := SignPKCS1v15(r, k, crypto.SHA1, sum[:])
-       if err != nil {
-               t.Fatal(err)
-       }
-       want := bytesFromHex(t, "4a8da3c0c41af2b8a93d011d4e11f4da9b2d52641c6c3d78d863987e857295adcedfae0e0d3ec00352bd134dc3fbb93b23a1fbe3718775762d78165bbbd37c6ef8e07bfa44e16ed2f1b05ebc04ba7bd60162d8689edb8709349e06bc281d34c2a3ee75d3454bfd95053cbb27c10515fb9132290a6ecc858e0c003201a9e100aac7f66af967364a1176e4ed9ef672d41481c59580f98bb82f205f712153fd5e3035a811da9d6e56e50609d1d604857f6d8e958bb84f354cfa28e0b8bcbb1261f929382d431454f07cbf60c18ff1243b11c6b552f3a0aa7e936f45cded40688ee53b1b630f944139f4f51baae49cd039b57b2b82f58f5589335137f4b09bd315f5")
-       if !bytes.Equal(sig, want) {
-               t.Fatalf("SignPKCS1v15(hash=SHA1): wrong sig\nhave %x\nwant %x", sig, want)
-       }
-
-       sig, err = SignPKCS1v15(r, k, 0, sum[:])
-       if err != nil {
-               t.Fatal(err)
-       }
-       want = bytesFromHex(t, "5d3d34495ffade926adab2de0545aaf1f22a03def949b69e1c91d34a2f0c7f2d682af46034151a1b67aa22cb9c1a8cc24c1358fce9ac6a2141879bbe107371b14faa97b12494260d9602ed1355f22ab3495b0bb7c137bc6801c1113fc2bdc00d4c250bbd8fa17e4ff86f71544b30a78e9d62c0b949afd1159760282c2700ec8be24cd884efd585ec55b45506d90e66cc3c5911baaea961e6c4e8018c4b4feb04afdd71880e3d8eff120288e53289a1bfb9fe7a3b9aca1d4549f133063647bfd4c6f4c0f4038f1bbcb4d112aa601f1b15402595076adfdbefb1bb64d3193bafb0305145bb536cd949a03ebe0470c6a155369f784afab2e25e9d5c03d8e13dcf1a")
-       if !bytes.Equal(sig, want) {
-               t.Fatalf("SignPKCS1v15(hash=0): wrong sig\nhave %x\nwant %x", sig, want)
-       }
-       r.checkOffset(768)
-}
-
-func TestBoringRandSignPSS(t *testing.T) {
-       r := testRand(t)
-       k := testKey(t)
-       sum := sha1.Sum([]byte("hello"))
-       sig, err := SignPSS(r, k, crypto.SHA1, sum[:], nil)
-       if err != nil {
-               t.Fatal(err)
-       }
-       want := bytesFromHex(t, "a0de84c9654c2e78e33c899090f8dc0590046fda4ee29d133340800596401ae0df61bf8aa5689df3f873ad13cf55df5209c3a8c6450918b74c2017f87c2d588809740622c7752e3153a26d04bd3e9d9f6daa676e8e5e65a8a11d4fbd271d4693ab6a303652328dc1c923b484fa179fd6d9e8b523da74f3a307531c0dd75f243a041f7df22414dfdb83b3a241fe73e7af0f95cb6b60831bdd46dc05618e5cb3653476eb7d5405fa5ca98dad8f787ca86179055f305daa87eb424671878a93965e47d3002e2774be311d696b42e5691eddb2f788cd35246b408eb5d045c891ba1d57ce4c6fc935ceec90f7999406252f6266957cce4e7f12cf0ec94af358aeefa7")
-       if !bytes.Equal(sig, want) {
-               t.Fatalf("SignPSS: wrong sig\nhave %x\nwant %x", sig, want)
-       }
-       r.checkOffset(490)
-}
-
-func TestBoringRandEncryptOAEP(t *testing.T) {
-       r := testRand(t)
-       k := testKey(t)
-       enc, err := EncryptOAEP(sha256.New(), r, &k.PublicKey, []byte("hello"), []byte("label"))
-       if err != nil {
-               t.Fatal(err)
-       }
-       want := bytesFromHex(t, "55dc7b590a511c2d249232ecbb70040e8e0ec03206caae5ec0a401a0ad8013209ef546870f93d0946b9845ace092d456d092403f76f12ee65c2b8759731a25589d8a7e857407d09cfbe36ae36fc4daeb514ac597b1de2f7dc8450ab78a9e420c9b5dbbae3e402c8f378bd35505a47d556b705ab8985707a22e3583c172ef5730f05fd0845880d67c1ddd3c1525aa4c2c4e162bd6435a485609f6bd76c8ff73a7b5d043e4724458594703245fabdb479ef2786c757b35932a645399f2703647785b59b971970e6bccef3e6cd6fae39f9f135203eb104f0db20cf48e461cb7d824889c0d5d6a47cd0bf213c2f7acb3ddbd3effefebb4f60458ffc8b6ff1e4cc447")
-       if !bytes.Equal(enc, want) {
-               t.Fatalf("EncryptOAEP: wrong enc\nhave %x\nwant %x", enc, want)
-       }
-       r.checkOffset(32)
-}
-
-func TestBoringRandDecryptOAEP(t *testing.T) {
-       r := testRand(t)
-       k := testKey(t)
-       enc := bytesFromHex(t, "55dc7b590a511c2d249232ecbb70040e8e0ec03206caae5ec0a401a0ad8013209ef546870f93d0946b9845ace092d456d092403f76f12ee65c2b8759731a25589d8a7e857407d09cfbe36ae36fc4daeb514ac597b1de2f7dc8450ab78a9e420c9b5dbbae3e402c8f378bd35505a47d556b705ab8985707a22e3583c172ef5730f05fd0845880d67c1ddd3c1525aa4c2c4e162bd6435a485609f6bd76c8ff73a7b5d043e4724458594703245fabdb479ef2786c757b35932a645399f2703647785b59b971970e6bccef3e6cd6fae39f9f135203eb104f0db20cf48e461cb7d824889c0d5d6a47cd0bf213c2f7acb3ddbd3effefebb4f60458ffc8b6ff1e4cc447")
-       dec, err := DecryptOAEP(sha256.New(), r, k, enc, []byte("label"))
-       if err != nil {
-               t.Fatal(err)
-       }
-       want := []byte("hello")
-       if !bytes.Equal(dec, want) {
-               t.Fatalf("DecryptOAEP: wrong dec\nhave %x\nwant %x", dec, want)
-       }
-       r.checkOffset(256)
-}
-
 func TestBoringFinalizers(t *testing.T) {
        if runtime.GOOS == "nacl" {
                // Times out on nacl (without BoringCrypto)
@@ -302,7 +93,10 @@ func TestBoringFinalizers(t *testing.T) {
                t.Skip("skipping on nacl")
        }
 
-       k := testKey(t)
+       k, err := GenerateKey(rand.Reader, 2048)
+       if err != nil {
+               t.Fatal(err)
+       }
 
        // Run test with GOGC=10, to make bug more likely.
        // Without the KeepAlives, the loop usually dies after
index b617840c798330fefe8623f50d6d63b323a11859..5a0e9e2fb51fb86df54317ab1cdfb6b6138a0afa 100644 (file)
@@ -97,7 +97,6 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byt
        }
 
        if boring.Enabled {
-               boringFakeRandomBlind(rand, priv)
                bkey, err := boringPrivateKey(priv)
                if err != nil {
                        return nil, err
@@ -177,7 +176,6 @@ func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid
        }
 
        if boring.Enabled {
-               boringFakeRandomBlind(rand, priv)
                var bkey *boring.PrivateKeyRSA
                bkey, err = boringPrivateKey(priv)
                if err != nil {
@@ -288,7 +286,6 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [
        }
 
        if boring.Enabled {
-               boringFakeRandomBlind(random, priv)
                bkey, err := boringPrivateKey(priv)
                if err != nil {
                        return nil, err
index 67ab9646579badcf78befe1cbc81ac3c8ec02080..89f850ed0f976a001fa9704a903f764dc348e70e 100644 (file)
@@ -200,7 +200,6 @@ func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed,
        }
 
        if boring.Enabled {
-               boringFakeRandomBlind(rand, priv)
                bkey, err := boringPrivateKey(priv)
                if err != nil {
                        return nil, err
index 6cbcfe5449cc40319a7b8b4e6a062cb037adb3ae..755bd6d5dc848e48647fa8ca19b364c98bac4429 100644 (file)
@@ -636,7 +636,6 @@ 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