Philipp Sauter has uploaded this change for review.
crypto/rand: buffer the entropy obtained by calling unix.GetRandom
On older versions of Linux, where entropy is obtained from /dev/urandom,
reading from the device is buffered. If available the newer
getrandom(2) syscall is used but without buffering.
With this change getrandom calls will be buffered aswell to improve
performance and consistency.
Fixes #16593
Change-Id: I9715a4f88a5bd2f32a7ca03f02eeac493c85a90d
---
M src/crypto/rand/rand_batched.go
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/crypto/rand/rand_batched.go b/src/crypto/rand/rand_batched.go
index d7c5bf3..9ffb885 100644
--- a/src/crypto/rand/rand_batched.go
+++ b/src/crypto/rand/rand_batched.go
@@ -8,12 +8,28 @@
package rand
import (
+ "bufio"
"internal/syscall/unix"
+ "io"
+ "sync"
)
+var bufferedGetRandomReader io.Reader
+
+type getRandomReader struct {
+ mu sync.Mutex
+}
+
+func (r *getRandomReader) Read(p []byte) (n int, err error) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ return unix.GetRandom(p, 0)
+}
+
// maxGetRandomRead is platform dependent.
func init() {
altGetRandom = batched(getRandomBatch, maxGetRandomRead)
+ bufferedGetRandomReader = bufio.NewReader(&getRandomReader{})
}
// batched returns a function that calls f to populate a []byte by chunking it
@@ -38,6 +54,6 @@
// until the kernel has sufficient randomness (as we don't use GRND_NONBLOCK).
// In this case, unix.GetRandom will not return an error.
func getRandomBatch(p []byte) (ok bool) {
- n, err := unix.GetRandom(p, 0)
+ n, err := bufferedGetRandomReader.Read(p)
return n == len(p) && err == nil
}
To view, visit change 331269. To unsubscribe, or for help writing mail filters, visit settings.