diff --git a/lib/protocol/encryption.go b/lib/protocol/encryption.go index 71a853446..6125f1850 100644 --- a/lib/protocol/encryption.go +++ b/lib/protocol/encryption.go @@ -8,7 +8,6 @@ package protocol import ( "context" - "crypto/rand" "crypto/sha256" "encoding/base32" "encoding/binary" @@ -20,6 +19,7 @@ import ( "github.com/gogo/protobuf/proto" "github.com/miscreant/miscreant.go" + "github.com/syncthing/syncthing/lib/rand" "golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/hkdf" "golang.org/x/crypto/scrypt" diff --git a/lib/rand/random.go b/lib/rand/random.go index 1775de160..98ff76f53 100644 --- a/lib/rand/random.go +++ b/lib/rand/random.go @@ -9,13 +9,17 @@ package rand import ( - cryptoRand "crypto/rand" + "io" mathRand "math/rand" "reflect" ) -// Reader is the standard crypto/rand.Reader, re-exported for convenience -var Reader = cryptoRand.Reader +// Reader is the standard crypto/rand.Reader with added buffering. +var Reader = defaultSecureSource + +func Read(p []byte) (int, error) { + return io.ReadFull(defaultSecureSource, p) +} // randomCharset contains the characters that can make up a rand.String(). const randomCharset = "2345679abcdefghijkmnopqrstuvwxyzACDEFGHJKLMNPQRSTUVWXYZ" diff --git a/lib/rand/securesource.go b/lib/rand/securesource.go index 7315c04bb..bc2c87b85 100644 --- a/lib/rand/securesource.go +++ b/lib/rand/securesource.go @@ -14,7 +14,7 @@ import ( "sync" ) -// The secureSource is a math/rand.Source that reads bytes from +// The secureSource is a math/rand.Source + io.Reader that reads bytes from // crypto/rand.Reader. It means we can use the convenience functions // provided by math/rand.Rand on top of a secure source of numbers. It is // concurrency safe for ease of use. @@ -40,6 +40,12 @@ func (s *secureSource) Int63() int64 { return int64(s.Uint64() & (1<<63 - 1)) } +func (s *secureSource) Read(p []byte) (int, error) { + s.mut.Lock() + defer s.mut.Unlock() + return s.rd.Read(p) +} + func (s *secureSource) Uint64() uint64 { var buf [8]byte diff --git a/lib/sha256/sha256.go b/lib/sha256/sha256.go index 30f7dc9c8..04aba1ff5 100644 --- a/lib/sha256/sha256.go +++ b/lib/sha256/sha256.go @@ -7,11 +7,11 @@ package sha256 import ( - "crypto/rand" cryptoSha256 "crypto/sha256" "encoding/hex" "fmt" "hash" + "math/rand" "os" "time" @@ -111,7 +111,8 @@ func cpuBenchOnce(duration time.Duration, newFn func() hash.Hash) float64 { chunkSize := 100 * 1 << 10 h := newFn() bs := make([]byte, chunkSize) - rand.Reader.Read(bs) + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Read(bs) t0 := time.Now() b := 0 diff --git a/lib/signature/signature.go b/lib/signature/signature.go index 1391a0282..06d6784cd 100644 --- a/lib/signature/signature.go +++ b/lib/signature/signature.go @@ -11,7 +11,6 @@ package signature import ( "crypto/ecdsa" "crypto/elliptic" - "crypto/rand" "crypto/x509" "encoding/asn1" "encoding/pem" @@ -20,6 +19,7 @@ import ( "io" "math/big" + "github.com/syncthing/syncthing/lib/rand" "github.com/syncthing/syncthing/lib/sha256" ) diff --git a/lib/ur/usage_report.go b/lib/ur/usage_report.go index b4cbb67dd..a0b978ef5 100644 --- a/lib/ur/usage_report.go +++ b/lib/ur/usage_report.go @@ -9,9 +9,9 @@ package ur import ( "bytes" "context" - "crypto/rand" "crypto/tls" "encoding/json" + "math/rand" "net" "net/http" "runtime" @@ -414,7 +414,8 @@ func CpuBench(ctx context.Context, iterations int, duration time.Duration, useWe dataSize := 16 * protocol.MinBlockSize bs := make([]byte, dataSize) - rand.Reader.Read(bs) + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Read(bs) var perf float64 for i := 0; i < iterations; i++ {