|
5 | 5 | // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
6 | 6 | // option. This file may not be copied, modified, or distributed
|
7 | 7 | // except according to those terms.
|
8 |
| -use crate::{util::uninit_slice_fill_zero, Error}; |
| 8 | +use crate::Error; |
9 | 9 |
|
10 | 10 | extern crate std;
|
11 | 11 | use std::{mem::MaybeUninit, thread_local};
|
@@ -36,12 +36,19 @@ pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>
|
36 | 36 |
|
37 | 37 | match source {
|
38 | 38 | RngSource::Node(n) => {
|
39 |
| - // XXX(perf): `random_fill_sync` requires a `&mut [u8]` so we |
40 |
| - // have to ensure the memory in `dest` is initialized. |
41 |
| - let dest = uninit_slice_fill_zero(dest); |
42 |
| - |
43 | 39 | for chunk in dest.chunks_mut(NODE_MAX_BUFFER_SIZE) {
|
44 |
| - if n.random_fill_sync(chunk).is_err() { |
| 40 | + // SAFETY: chunk is never used directly, the memory is only |
| 41 | + // modified via the Uint8Array view, which is passed |
| 42 | + // directly to JavaScript. Also, crypto.randomFillSync does |
| 43 | + // not resize the buffer. We know the length is less than |
| 44 | + // u32::MAX because of the chunking above. |
| 45 | + // Note that this uses the fact that JavaScript doesn't |
| 46 | + // have a notion of "uninitialized memory", this is purely |
| 47 | + // a Rust/C/C++ concept. |
| 48 | + let res = n.random_fill_sync(unsafe { |
| 49 | + Uint8Array::view_mut_raw(chunk.as_mut_ptr() as *mut u8, chunk.len()) |
| 50 | + }); |
| 51 | + if res.is_err() { |
45 | 52 | return Err(Error::NODE_RANDOM_FILL_SYNC);
|
46 | 53 | }
|
47 | 54 | }
|
@@ -130,7 +137,7 @@ extern "C" {
|
130 | 137 | type NodeCrypto;
|
131 | 138 | // crypto.randomFillSync()
|
132 | 139 | #[wasm_bindgen(method, js_name = randomFillSync, catch)]
|
133 |
| - fn random_fill_sync(this: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>; |
| 140 | + fn random_fill_sync(this: &NodeCrypto, buf: Uint8Array) -> Result<(), JsValue>; |
134 | 141 |
|
135 | 142 | // Ideally, we would just use `fn require(s: &str)` here. However, doing
|
136 | 143 | // this causes a Webpack warning. So we instead return the function itself
|
|
0 commit comments