From c846964df5eeab05c8620d34fcd3e56d5b6cbcfa Mon Sep 17 00:00:00 2001 From: Johan Brandhorst-Satzkorn Date: Mon, 30 Jan 2023 20:09:23 -0800 Subject: [PATCH] crypto/rand: batch large random reads on js CL 463975 replaced the use of the NodeJS crypto.randomFillSync API with a direct call to crypto.getRandomValues. This function rejects any requests to fill a buffer larger than 65536 bytes, so we need to batch reads larger than this size. This reuses the batching functions used on other platforms to perform this batching. Fixes #58145 Change-Id: Ic0acf3be7c9e994bc345d6614867c9b0c47bd26d Reviewed-on: https://go-review.googlesource.com/c/go/+/463993 Reviewed-by: Roland Shoemaker TryBot-Result: Gopher Robot Reviewed-by: Dmitri Shuralyov Reviewed-by: Dmitri Shuralyov Run-TryBot: Johan Brandhorst-Satzkorn Auto-Submit: Johan Brandhorst-Satzkorn --- src/crypto/rand/rand_js.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/crypto/rand/rand_js.go b/src/crypto/rand/rand_js.go index 91e69fae5d..39e8023504 100644 --- a/src/crypto/rand/rand_js.go +++ b/src/crypto/rand/rand_js.go @@ -8,8 +8,15 @@ package rand import "syscall/js" +// The maximum buffer size for crypto.getRandomValues is 65536 bytes. +// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#exceptions +const maxGetRandomRead = 1 << 16 + +var batchedGetRandom func([]byte) error + func init() { Reader = &reader{} + batchedGetRandom = batched(getRandom, maxGetRandomRead) } var jsCrypto = js.Global().Get("crypto") @@ -21,8 +28,15 @@ var uint8Array = js.Global().Get("Uint8Array") type reader struct{} func (r *reader) Read(b []byte) (int, error) { + if err := batchedGetRandom(b); err != nil { + return 0, err + } + return len(b), nil +} + +func getRandom(b []byte) error { a := uint8Array.New(len(b)) jsCrypto.Call("getRandomValues", a) js.CopyBytesToGo(b, a) - return len(b), nil + return nil } -- 2.48.1