]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/rand: batch large random reads on js
authorJohan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Tue, 31 Jan 2023 04:09:23 +0000 (20:09 -0800)
committerJohan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Wed, 1 Feb 2023 16:56:49 +0000 (16:56 +0000)
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 <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Auto-Submit: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>

src/crypto/rand/rand_js.go

index 91e69fae5d63fa778db48430429dc72d9be73268..39e8023504440af4c1da8be5ad0d1134f3f80865 100644 (file)
@@ -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
 }