-
Notifications
You must be signed in to change notification settings - Fork 18k
crypto/rand: Reader is internally buffered inconsistently on different platforms #16593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Dup of #16124 ? |
Not a dup, I think. That was math/rand; this is crypto/rand. |
Not buffering is actually a nice feature of the What's the situation where the syscall performance is a problem? (Is it CBC-mode in TLS again?) |
Still applies to 1.12 and tip. See #33256 for benchmarks showing order-of-magnitude differences for small reads via a bufio.Reader.
Don't these apply equally to the entropy pool in the kernel? Why is it a concern only for entropy buffered in process? (Also note that the /dev/urandom fallback already buffers.)
We ran into this in the profile of a workload where we need to generate tokens for authentication (unrelated to TLS). |
Change https://golang.org/cl/331269 mentions this issue: |
I'd like to mildly object to CL 331269. Not buffering has nice security properties that agl mentioned above, |
I think its better to never buffer it, then clients can decide to buffer it without accidentally double buffering on some platforms. |
CC @golang/security Doesn't look like this is happening for 1.19. Moving milestone to backlog. Please recategorize if appropriate. |
Yes, I believe this was fixed (and is included in 1.19.) |
Please answer these questions before submitting your issue. Thanks!
go version
)?1.6.3
go env
)?GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/tyho/go"
GORACE=""
GOROOT="/usr/lib/golang"
GOTOOLDIR="/usr/lib/golang/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
rand.Reader to consistently internally buffer, or not internally buffer calls to Read regardless of platform.
On generic Unix, including old versions of Linux (without a getrandom syscall), rand.Reader reads from /dev/urandom, and buffers calls to Read using the bufio package. On modern Linux however, rand.Read requests are implemented using the new getrandom syscall, but the calls are not buffered.
I tested to see if internally buffering output on platforms with the getrandom syscall available would make a significant difference to the performance of small 16B reads:
https://play.golang.org/p/80fyLlBFQb
On my machine, internally buffering the output of Read doubled performance compared with raw Reads. Tv` suggested that the unbuffered Reads may be quicker when multithreaded due to bufio adding a mutex. He wrote a benchmark to test this theory but it turned out not to be true:
https://play.golang.org/p/3sO47iNhK5
The text was updated successfully, but these errors were encountered: