|
6 | 6 | // option. This file may not be copied, modified, or distributed
|
7 | 7 | // except according to those terms.
|
8 | 8 |
|
9 |
| -//! Interface to the random number generator of the operating system. |
| 9 | +//! Interface to the operating system's random number generator. |
10 | 10 | //!
|
11 |
| -//! # Platform sources |
| 11 | +//! # Supported targets |
12 | 12 | //!
|
13 |
| -//! | OS | interface |
| 13 | +//! | Target | Implemnetation |
14 | 14 | //! |------------------|---------------------------------------------------------
|
15 | 15 | //! | Linux, Android | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
|
16 | 16 | //! | Windows | [`RtlGenRandom`][3]
|
|
27 | 27 | //! | Haiku | `/dev/random` (identical to `/dev/urandom`)
|
28 | 28 | //! | SGX | [RDRAND][18]
|
29 | 29 | //! | VxWorks | `randABytes` after checking entropy pool initialization with `randSecure`
|
30 |
| -//! | Web browsers | [`Crypto.getRandomValues`][14] (see [Support for WebAssembly and asm.js][16]) |
31 |
| -//! | Node.js | [`crypto.randomBytes`][15] (see [Support for WebAssembly and asm.js][16]) |
| 30 | +//! | Emcripten | `/dev/random` (identical to `/dev/urandom`) |
32 | 31 | //! | WASI | [`__wasi_random_get`][17]
|
33 | 32 | //!
|
34 |
| -//! Getrandom doesn't have a blanket implementation for all Unix-like operating |
35 |
| -//! systems that reads from `/dev/urandom`. This ensures all supported operating |
36 |
| -//! systems are using the recommended interface and respect maximum buffer |
37 |
| -//! sizes. |
| 33 | +//! This crate doesn't have a blanket implementation for all `unix` targets that |
| 34 | +//! reads from `/dev/urandom`. This ensures all supported targets are using the |
| 35 | +//! recommended interface and respect maximum buffer sizes. |
38 | 36 | //!
|
39 | 37 | //! ## Unsupported targets
|
40 | 38 | //!
|
41 |
| -//! By default, compiling `getrandom` for an unsupported target will result in |
42 |
| -//! a compilation error. If you want to build an application which uses `getrandom` |
43 |
| -//! for such target, you can either: |
44 |
| -//! - Use [`[replace]`][replace] or [`[patch]`][patch] section in your `Cargo.toml` |
45 |
| -//! to switch to a custom implementation with a support of your target. |
46 |
| -//! |
47 |
| -//! [replace]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-replace-section |
48 |
| -//! [patch]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-patch-section |
| 39 | +//! By default, `getrandom` will not compile on an unsupported target. If you |
| 40 | +//! want to use `getrandom` on such target, you can either: |
| 41 | +//! |
| 42 | +//! - Enable `getrandom`'s `"cpu"` feature |
| 43 | +//! - This makes `getrandom` fallback to using CPU-specific RNG instructions. |
| 44 | +//! - Currently only `x86`/`x86_64` targets are suppored. On these targets, |
| 45 | +//! [RDRAND][18] will be used to generate the random data. |
| 46 | +//! - If `getrandom` is not a direct dependancy of your crate, you can still |
| 47 | +//! enable this fallback by adding the following to your crate's |
| 48 | +//! `[dependancies]` section: |
| 49 | +//! ```toml |
| 50 | +//! getrandom = { version = "0.2", features = ["custom"] |
| 51 | +//! ``` |
| 52 | +//! |
| 53 | +//! - Use a custom `getrandom` implementation via an external crate. |
| 54 | +//! - Some external creates define `getrandom` implementations for specific |
| 55 | +//! unsupported targets. |
| 56 | +//! - To use one of these crates (for example [`stdweb-getradnom`][23]): |
| 57 | +//! - Add `stdweb-getrandom = "0.1"` to your crate's `[dependancies]` section. |
| 58 | +//! - Use `stdweb-getrandom` in your crate. This can be done by adding |
| 59 | +//! `use stdweb_getrandom as _;` to `src/lib.rs`. Explict usage is needed |
| 60 | +//! to avoid linker errors. |
| 61 | +//! - Using `getrandom` on `wasm32-unknown-unknown` will now call into the |
| 62 | +//! implementation defined by the `stdweb-getrandom` crate. |
| 63 | +//! - See [`register_custom_getrandom!`] for information about writing your |
| 64 | +//! own custom `getrandom` implementation for an unsupported target. |
| 65 | +//! - Custom implementations take precedence over the `"cpu"` feature. |
| 66 | +//! |
| 67 | +//! Both of these mechanisms only affect unsupported targets. Supported targets |
| 68 | +//! will always use their standard implementations. |
| 69 | +//! |
| 70 | +//! Of course, Pull Requests are welcome to add new targets to `getrandom`! |
49 | 71 | //!
|
50 | 72 | //! ## Support for WebAssembly and asm.js
|
51 | 73 | //!
|
52 |
| -//! Getrandom supports all of Rust's current `wasm32` targets, and it works with |
53 |
| -//! both Node.js and web browsers. The three Emscripten targets |
54 |
| -//! `asmjs-unknown-emscripten`, `wasm32-unknown-emscripten`, and |
55 |
| -//! `wasm32-experimental-emscripten` use Emscripten's `/dev/random` emulation. |
56 |
| -//! The WASI target `wasm32-wasi` uses the [`__wasi_random_get`][17] function |
57 |
| -//! defined by the WASI standard. |
58 |
| -//! |
59 |
| -//! Getrandom also supports `wasm32-unknown-unknown` by directly calling |
60 |
| -//! JavaScript methods. Rust currently has two ways to do this: [bindgen] and |
61 |
| -//! [stdweb]. Getrandom supports using either one by enabling the |
62 |
| -//! `wasm-bindgen` or `stdweb` crate features. Note that if both features are |
63 |
| -//! enabled, `wasm-bindgen` will be used. If neither feature is enabled, calls |
64 |
| -//! to `getrandom` will always fail at runtime. |
65 |
| -//! |
66 |
| -//! [bindgen]: https://github.com/rust-lang/rust-bindgen |
| 74 | +//! This crate supports the following `wasm32`/`asmjs` targets: |
| 75 | +//! - `wasm32-wasi` |
| 76 | +//! - `asmjs-unknown-emscripten` |
| 77 | +//! - `wasm32-unknown-emscripten` |
| 78 | +//! |
| 79 | +//! For `wasm32-unknown-unknown`, the story ismessy. This target can interface |
| 80 | +//! with JavaScript via either [wasm-bindgen] or [stdweb]. For this reason, |
| 81 | +//! **`wasm32-unknown-unknown` is an unsupported target**. |
| 82 | +//! |
| 83 | +//! However, as with any unsupported target, users can use custom `getrandom` |
| 84 | +//! implementation crates. For `wasm32-unknown-unknown`, there are: |
| 85 | +//! - [`wasm-bindgen-getrandom`][22], for use with [wasm-bindgen] |
| 86 | +//! - [`stdweb-getradnom`][23], for use with [stdweb] |
| 87 | +//! |
| 88 | +//! Both of these crates work with web browsers and Node.js by directly calling |
| 89 | +//! the appropriate JavaScript functions. Specifically, |
| 90 | +//! - On web browsers, [`Crypto.getRandomValues`][14] is used. |
| 91 | +//! - On Node.js [`crypto.randomBytes`][15] is used. |
| 92 | +//! |
| 93 | +//! [wasm-bindgen]: https://github.com/rust-lang/rust-bindgen |
67 | 94 | //! [stdweb]: https://github.com/koute/stdweb
|
68 | 95 | //!
|
69 | 96 | //! ## Early boot
|
70 | 97 | //!
|
71 |
| -//! It is possible that early in the boot process the OS hasn't had enough time |
72 |
| -//! yet to collect entropy to securely seed its RNG, especially on virtual |
73 |
| -//! machines. |
| 98 | +//! Sometimes, early in the boot process, the OS has not collected enough |
| 99 | +//! entropy to securely seed its RNG. This is especially common on virtual |
| 100 | +//! machines, where standard "random" events are hard to come by. |
74 | 101 | //!
|
75 |
| -//! Some operating systems always block the thread until the RNG is securely |
| 102 | +//! Some operating system interfaces always block until the RNG is securely |
76 | 103 | //! seeded. This can take anywhere from a few seconds to more than a minute.
|
77 |
| -//! Others make a best effort to use a seed from before the shutdown and don't |
78 |
| -//! document much. |
79 |
| -//! |
80 |
| -//! A few, Linux, NetBSD and Solaris, offer a choice between blocking and |
81 |
| -//! getting an error; in these cases we always choose to block. |
| 104 | +//! A few (Linux, NetBSD and Solaris) offer a choice between blocking and |
| 105 | +//! getting an error; in these cases, we always choose to block. |
82 | 106 | //!
|
83 |
| -//! On Linux (when the `getrandom` system call is not available) and on NetBSD |
84 |
| -//! reading from `/dev/urandom` never blocks, even when the OS hasn't collected |
85 |
| -//! enough entropy yet. To avoid returning low-entropy bytes, we first read from |
| 107 | +//! On Linux (when the `getrandom` system call is not available), reading from |
| 108 | +//! `/dev/urandom` never blocks, even when the OS hasn't collected enough |
| 109 | +//! entropy yet. To avoid returning low-entropy bytes, we first poll |
86 | 110 | //! `/dev/random` and only switch to `/dev/urandom` once this has succeeded.
|
87 | 111 | //!
|
88 |
| -//! # Error handling |
| 112 | +//! ## Error handling |
89 | 113 | //!
|
90 | 114 | //! We always choose failure over returning insecure "random" bytes. In general,
|
91 | 115 | //! on supported platforms, failure is highly unlikely, though not impossible.
|
92 | 116 | //! If an error does occur, then it is likely that it will occur on every call to
|
93 | 117 | //! `getrandom`, hence after the first successful call one can be reasonably
|
94 | 118 | //! confident that no errors will occur.
|
95 | 119 | //!
|
96 |
| -//! On unsupported platforms, `getrandom` always fails. See the [`Error`] type |
97 |
| -//! for more information on what data is returned on failure. |
98 |
| -//! |
99 | 120 | //! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
|
100 | 121 | //! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
|
101 | 122 | //! [3]: https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-rtlgenrandom
|
|
111 | 132 | //! [13]: https://github.com/nuxinl/cloudabi#random_get
|
112 | 133 | //! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
|
113 | 134 | //! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
|
114 |
| -//! [16]: #support-for-webassembly-and-asmjs |
115 | 135 | //! [17]: https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md#__wasi_random_get
|
116 | 136 | //! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
|
117 | 137 | //! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
|
118 | 138 | //! [20]: https://www.unix.com/man-page/mojave/4/random/
|
119 | 139 | //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
|
| 140 | +//! [22]: https://docs.rs/wasm-bindgen-getrandom/ |
| 141 | +//! [23]: https://docs.rs/stdweb-getrandom/ |
120 | 142 |
|
121 | 143 | #![doc(
|
122 | 144 | html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
|
|
0 commit comments