|
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 | Implementation |
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]
|
| 17 | +//! | [Windows UWP][22]| [`BCryptGenRandom`][23] |
17 | 18 | //! | macOS | [`getentropy()`][19] if available, otherwise [`/dev/random`][20] (identical to `/dev/urandom`)
|
18 | 19 | //! | iOS | [`SecRandomCopyBytes`][4]
|
19 | 20 | //! | FreeBSD | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
|
|
27 | 28 | //! | Haiku | `/dev/random` (identical to `/dev/urandom`)
|
28 | 29 | //! | SGX | [RDRAND][18]
|
29 | 30 | //! | 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]) |
| 31 | +//! | Emscripten | `/dev/random` (identical to `/dev/urandom`) |
32 | 32 | //! | WASI | [`__wasi_random_get`][17]
|
| 33 | +//! | Web Browser | [`Crypto.getRandomValues()`][14], see [support for WebAssembly][16] |
| 34 | +//! | Node.js | [`crypto.randomBytes`][15], see [support for WebAssembly][16] |
33 | 35 | //!
|
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. |
| 36 | +//! There is no blanket implementation on `unix` targets that reads from |
| 37 | +//! `/dev/urandom`. This ensures all supported targets are using the recommended |
| 38 | +//! interface and respect maximum buffer sizes. |
| 39 | +//! |
| 40 | +//! Pull Requests that add support for new targets to `getrandom` are always welcome. |
38 | 41 | //!
|
39 | 42 | //! ## Unsupported targets
|
40 | 43 | //!
|
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. |
| 44 | +//! By default, `getrandom` will not compile on unsupported targets, but certain |
| 45 | +//! features allow a user to select a "fallback" implementation if no supported |
| 46 | +//! implementation exists. |
| 47 | +//! |
| 48 | +//! All of the below mechanisms only affect unsupported |
| 49 | +//! targets. Supported targets will _always_ use their supported implementations. |
| 50 | +//! This prevents a crate from overriding a secure source of randomness |
| 51 | +//! (either accidentally or intentionally). |
| 52 | +//! |
| 53 | +//! ### RDRAND on x86 |
46 | 54 | //!
|
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 |
| 55 | +//! *If the `"rdrand"` Cargo feature is enabled*, `getrandom` will fallback to using |
| 56 | +//! the [`RDRAND`][18] instruction to get randomness on `no_std` `x86`/`x86_64` |
| 57 | +//! targets. This feature has no effect on other CPU architectures. |
49 | 58 | //!
|
50 |
| -//! ## Support for WebAssembly and asm.js |
| 59 | +//! ### Support for WebAssembly |
51 | 60 | //!
|
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. |
| 61 | +//! This crate fully supports the `wasm32-wasi` and `wasm32-unknown-emscripten` |
| 62 | +//! targets. However, the `wasm32-unknown-unknown` target is not supported since, |
| 63 | +//! from the target name alone, we cannot deduce which JavaScript interface is |
| 64 | +//! in use (or if JavaScript is available at all). |
58 | 65 | //!
|
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. |
| 66 | +//! Instead, *if the `"js"` Cargo feature is enabled*, this crate will assume |
| 67 | +//! that you are building for an environment containing JavaScript, and will |
| 68 | +//! call the appropriate methods. Both Browser and Node.js environments are |
| 69 | +//! supported (see above), and both [wasm-bindgen] and [stdweb] toolchains are |
| 70 | +//! supported. |
65 | 71 | //!
|
66 |
| -//! [bindgen]: https://github.com/rust-lang/rust-bindgen |
| 72 | +//! [wasm-bindgen]: https://github.com/rust-lang/rust-bindgen |
67 | 73 | //! [stdweb]: https://github.com/koute/stdweb
|
68 | 74 | //!
|
| 75 | +//! ### Use a custom implementation |
| 76 | +//! |
| 77 | +//! Some external crates define `getrandom` implementations for specific |
| 78 | +//! unsupported targets. If you depend on one of these external crates and you |
| 79 | +//! are building for an unsupported target, `getrandom` will use this external |
| 80 | +//! implementation instead of failing to compile. |
| 81 | +//! |
| 82 | +//! See [`register_custom_getrandom!`] for information about writing your own |
| 83 | +//! custom `getrandom` implementation for an unsupported target. |
| 84 | +//! |
| 85 | +//! ### Indirect Dependencies |
| 86 | +//! |
| 87 | +//! If `getrandom` is not a direct dependency of your crate, you can still |
| 88 | +//! enable any of above fallback behaviors by simply enabling the relevant |
| 89 | +//! feature in your root crate's `[dependencies]` section: |
| 90 | +//! ```toml |
| 91 | +//! getrandom = { version = "0.2", features = ["rdrand"] } |
| 92 | +//! ``` |
| 93 | +//! |
69 | 94 | //! ## Early boot
|
70 | 95 | //!
|
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. |
| 96 | +//! Sometimes, early in the boot process, the OS has not collected enough |
| 97 | +//! entropy to securely seed its RNG. This is especially common on virtual |
| 98 | +//! machines, where standard "random" events are hard to come by. |
74 | 99 | //!
|
75 |
| -//! Some operating systems always block the thread until the RNG is securely |
| 100 | +//! Some operating system interfaces always block until the RNG is securely |
76 | 101 | //! 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. |
| 102 | +//! A few (Linux, NetBSD and Solaris) offer a choice between blocking and |
| 103 | +//! getting an error; in these cases, we always choose to block. |
79 | 104 | //!
|
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. |
82 |
| -//! |
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 |
| 105 | +//! On Linux (when the `getrandom` system call is not available), reading from |
| 106 | +//! `/dev/urandom` never blocks, even when the OS hasn't collected enough |
| 107 | +//! entropy yet. To avoid returning low-entropy bytes, we first poll |
86 | 108 | //! `/dev/random` and only switch to `/dev/urandom` once this has succeeded.
|
87 | 109 | //!
|
88 |
| -//! # Error handling |
| 110 | +//! ## Error handling |
89 | 111 | //!
|
90 | 112 | //! We always choose failure over returning insecure "random" bytes. In general,
|
91 | 113 | //! on supported platforms, failure is highly unlikely, though not impossible.
|
92 | 114 | //! If an error does occur, then it is likely that it will occur on every call to
|
93 | 115 | //! `getrandom`, hence after the first successful call one can be reasonably
|
94 | 116 | //! confident that no errors will occur.
|
95 | 117 | //!
|
96 |
| -//! On unsupported platforms, `getrandom` always fails. See the [`Error`] type |
97 |
| -//! for more information on what data is returned on failure. |
98 |
| -//! |
99 | 118 | //! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
|
100 | 119 | //! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
|
101 | 120 | //! [3]: https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-rtlgenrandom
|
|
111 | 130 | //! [13]: https://github.com/nuxinl/cloudabi#random_get
|
112 | 131 | //! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
|
113 | 132 | //! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
|
114 |
| -//! [16]: #support-for-webassembly-and-asmjs |
| 133 | +//! [16]: #support-for-webassembly |
115 | 134 | //! [17]: https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md#__wasi_random_get
|
116 | 135 | //! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
|
117 | 136 | //! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
|
118 | 137 | //! [20]: https://www.unix.com/man-page/mojave/4/random/
|
119 | 138 | //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
|
| 139 | +//! [22]: https://docs.microsoft.com/en-us/windows/uwp/ |
| 140 | +//! [23]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom |
120 | 141 |
|
121 | 142 | #![doc(
|
122 | 143 | html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
|
|
0 commit comments