1
- # getrandom
1
+ # getrandom: (operating) system's random number generator
2
2
3
3
[ ![ Build Status]] [ GitHub Actions ] [ ![ Crate]] [ crates.io ] [ ![ Documentation]] [ docs.rs ] [ ![ Dependency Status]] [ deps.rs ] [ ![ Downloads]] [ crates.io ] [ ![ License]] [ LICENSE-MIT ]
4
4
5
- [ GitHub Actions ] : https://github.com/rust-random/getrandom/actions?query=workflow:Tests+branch:master
6
- [ Build Status ] : https://github.com/rust-random/getrandom/actions/workflows/tests.yml/badge.svg?branch=master
7
- [ crates.io ] : https://crates.io/crates/getrandom
8
- [ Crate ] : https://img.shields.io/crates/v/getrandom
9
- [ docs.rs ] : https://docs.rs/getrandom
10
- [ Documentation ] : https://docs.rs/getrandom/badge.svg
11
- [ deps.rs ] : https://deps.rs/repo/github/rust-random/getrandom
12
- [ Dependency Status ] : https://deps.rs/repo/github/rust-random/getrandom/status.svg
13
- [ Downloads ] : https://img.shields.io/crates/d/getrandom
14
- [ LICENSE-MIT ] : https://raw.githubusercontent.com/rust-random/getrandom/master/LICENSE-MIT
15
- [ License ] : https://img.shields.io/crates/l/getrandom
16
-
5
+ ` getrandom ` is a Rust library for retrieving random data from (operating) system sources.
17
6
18
- A Rust library for retrieving random data from (operating) system sources. It is
19
- assumed that the system always provides high-quality cryptographically secure random
7
+ It is assumed that the system always provides high-quality cryptographically secure random
20
8
data, ideally backed by hardware entropy sources. This crate derives its name
21
9
from Linux's ` getrandom ` function, but is cross-platform, roughly supporting
22
10
the same set of platforms as Rust's ` std ` lib.
@@ -35,7 +23,7 @@ Add this to your `Cargo.toml`:
35
23
getrandom = " 0.2"
36
24
```
37
25
38
- Then invoke the ` getrandom ` function:
26
+ Then invoke the ` fill ` function:
39
27
40
28
``` rust
41
29
fn get_random_buf () -> Result <[u8 ; 32 ], getrandom :: Error > {
@@ -45,22 +33,231 @@ fn get_random_buf() -> Result<[u8; 32], getrandom::Error> {
45
33
}
46
34
```
47
35
48
- For more information about supported targets, entropy sources, ` no_std ` targets,
49
- crate features, WASM support and Custom RNGs see the
50
- [ ` getrandom ` documentation] ( https://docs.rs/getrandom/latest ) and
51
- [ ` getrandom::Error ` documentation] ( https://docs.rs/getrandom/latest/getrandom/struct.Error.html ) .
36
+ ## Supported targets
52
37
53
- ## Minimum Supported Rust Version
38
+ | Target | Target Triple | Implementation
39
+ | ------------------ | ------------------ | --------------
40
+ | Linux, Android | ` *‑linux‑* ` | [ ` getrandom ` ] [ 1 ] system call if available, otherwise [ ` /dev/urandom ` ] [ 2 ] after successfully polling ` /dev/random `
41
+ | Windows 10+ | ` *‑windows‑* ` | [ ` ProcessPrng ` ]
42
+ | Windows 7, 8 | ` *-win7‑windows‑* ` | [ ` RtlGenRandom ` ]
43
+ | macOS | ` *‑apple‑darwin ` | [ ` getentropy ` ] [ 3 ]
44
+ | iOS, tvOS, watchOS | ` *‑apple‑{ios,tvos,watchos} ` | [ ` CCRandomGenerateBytes ` ]
45
+ | FreeBSD | ` *‑freebsd ` | [ ` getrandom ` ] [ 5 ]
46
+ | OpenBSD | ` *‑openbsd ` | [ ` getentropy ` ] [ 7 ]
47
+ | NetBSD | ` *‑netbsd ` | [ ` getrandom ` ] [ 16 ] if available, otherwise [ ` kern.arandom ` ] [ 8 ]
48
+ | Dragonfly BSD | ` *‑dragonfly ` | [ ` getrandom ` ] [ 9 ]
49
+ | Solaris | ` *‑solaris ` | [ ` getrandom ` ] [ 11 ] with ` GRND_RANDOM `
50
+ | illumos | ` *‑illumos ` | [ ` getrandom ` ] [ 12 ]
51
+ | Fuchsia OS | ` *‑fuchsia ` | [ ` cprng_draw ` ]
52
+ | Redox | ` *‑redox ` | ` /dev/urandom `
53
+ | Haiku | ` *‑haiku ` | ` /dev/urandom ` (identical to ` /dev/random ` )
54
+ | Hermit | ` *-hermit ` | [ ` sys_read_entropy ` ]
55
+ | Hurd | ` *-hurd-* ` | [ ` getrandom ` ] [ 17 ]
56
+ | SGX | ` x86_64‑*‑sgx ` | [ ` RDRAND ` ]
57
+ | VxWorks | ` *‑wrs‑vxworks‑* ` | ` randABytes ` after checking entropy pool initialization with ` randSecure `
58
+ | Emscripten | ` *‑emscripten ` | [ ` getentropy ` ] [ 13 ]
59
+ | WASI 0.1 | ` wasm32‑wasip1 ` | [ ` random_get ` ]
60
+ | WASI 0.2 | ` wasm32‑wasip2 ` | [ ` get-random-u64 ` ]
61
+ | SOLID | ` *-kmc-solid_* ` | ` SOLID_RNG_SampleRandomBytes `
62
+ | Nintendo 3DS | ` *-nintendo-3ds ` | [ ` getrandom ` ] [ 18 ]
63
+ | PS Vita | ` *-vita-* ` | [ ` getentropy ` ] [ 13 ]
64
+ | QNX Neutrino | ` *‑nto-qnx* ` | [ ` /dev/urandom ` ] [ 14 ] (identical to ` /dev/random ` )
65
+ | AIX | ` *-ibm-aix ` | [ ` /dev/urandom ` ] [ 15 ]
54
66
55
- This crate requires Rust 1.60.0 or later.
67
+ Pull Requests that add support for new targets to ` getrandom ` are always welcome.
68
+
69
+ ### Opt-in backends
70
+
71
+ ` getrandom ` also provides optional backends which can be enabled using ` getrandom_backend `
72
+ configuration flag:
73
+
74
+ | Backend name | Target | Target Triple | Implementation
75
+ | ----------------- | -------------------- | -------------------- | --------------
76
+ | ` linux_getrandom ` | Linux, Android | ` *‑linux‑* ` | [ ` getrandom ` ] [ 1 ] system call (without ` /dev/urandom ` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow).
77
+ | ` linux_rustix ` | Linux, Android | ` *‑linux‑* ` | Same as ` linux_getrandom ` , but uses [ ` rustix ` ] instead of ` libc ` .
78
+ | ` rdrand ` | x86, x86-64 | ` x86_64-* ` , ` i686-* ` | [ ` RDRAND ` ] instruction
79
+ | ` rndr ` | AArch64 | ` aarch64-* ` | [ ` RNDR ` ] register
80
+ | ` esp_idf ` | ESP-IDF | ` *‑espidf ` | [ ` esp_fill_random ` ] . WARNING: can return low quality entropy without proper hardware configuration!
81
+ | ` wasm_js ` | Web Browser, Node.js | ` wasm*‑*‑unknown ` | [ ` Crypto.getRandomValues ` ] if available, then [ ` crypto.randomFillSync ` ] if on Node.js (see [ WebAssembly support] )
82
+ | ` custom ` | All targets | ` * ` | User-provided custom implementation (see [ custom backend] )
83
+
84
+ The configuration flag can be enabled either by specifying the ` rustflags ` field in
85
+ [ ` .cargo/config.toml ` ] (note that it can be done on a per-target basis), or by using
86
+ ` RUSTFLAGS ` environment variable:
87
+
88
+ ``` sh
89
+ RUSTFLAGS=' --cfg getrandom_backend="linux_getrandom"' cargo build
90
+ ```
91
+
92
+ Enabling an opt-in backend will replace backend used by default. Doing it for a wrong target
93
+ (e.g. using ` linux_getrandom ` while compiling for a Windows target) will result
94
+ in a compilation error. Be extremely carefull while using opt-in backends, since incorrect
95
+ configuration may result in vulnerable or in always panicking applications.
96
+
97
+ Note that using an opt-in backend in a library (e.g. for tests or benchmarks)
98
+ WILL NOT have any effect on its downstream users.
99
+
100
+ [ `.cargo/config.toml` ] : https://doc.rust-lang.org/cargo/reference/config.html
101
+
102
+ ### WebAssembly support
103
+
104
+ This crate fully supports the [ WASI] and [ Emscripten] targets. However,
105
+ the ` wasm32-unknown-unknown ` target (i.e. the target used by ` wasm-pack ` )
106
+ is not automatically supported since, from the target name alone, we cannot deduce
107
+ which JavaScript interface should be used (or if JavaScript is available at all).
108
+
109
+ Instead, * if the ` wasm_js ` backend is enabled* , this crate will assume
110
+ that you are building for an environment containing JavaScript, and will
111
+ call the appropriate methods. Both web browser (main window and Web Workers)
112
+ and Node.js environments are supported, invoking the methods
113
+ [ described above] ( #opt-in-backends ) using the [ ` wasm-bindgen ` ] toolchain.
114
+
115
+ To enable the ` wasm_js ` backend, you can add the following lines to your
116
+ project's ` .cargo/config.toml ` file:
117
+ ``` toml
118
+ [target .wasm32-unknown-unknown ]
119
+ rustflags = [' --cfg' , ' getrandom_backend="wasm_js"' ]
120
+ ```
121
+
122
+ #### Node.js ES module support
123
+
124
+ Node.js supports both [ CommonJS modules] and [ ES modules] . Due to
125
+ limitations in wasm-bindgen's [ ` module ` ] support, we cannot directly
126
+ support ES Modules running on Node.js. However, on Node v15 and later, the
127
+ module author can add a simple shim to support the Web Cryptography API:
128
+ ``` js
129
+ import { webcrypto } from ' node:crypto'
130
+ globalThis .crypto = webcrypto
131
+ ```
132
+ This crate will then use the provided ` webcrypto ` implementation.
133
+
134
+ ### Custom backend
135
+
136
+ If this crate does not support your target out of box or you have to use
137
+ a non-default entropy source, then you can provide a custom implementation.
138
+ You need to enable the custom backend as described in the [ configuration flags]
139
+ section. Next, you need to define an ` extern ` function with the following
140
+ signature:
141
+
142
+ ``` rust
143
+ use getrandom :: Error ;
144
+
145
+ #[no_mangle]
146
+ unsafe extern " Rust" fn __getrandom_v03_custom (
147
+ dest : * mut u8 ,
148
+ len : usize ,
149
+ ) -> Result <(), Error > {
150
+ todo! ()
151
+ }
152
+ ```
153
+
154
+ This function ideally should be defined in the root crate of your project,
155
+ e.g. in your ` main.rs ` . This function MUST be defined only once for your
156
+ project, i.e. upstream library crates SHOULD NOT define it outside of
157
+ tests and benchmarks. Improper configuration of this backend may result
158
+ in linking errors.
159
+
160
+ The function accepts pointer to buffer which should be filled with random
161
+ data and length in bytes. Note that the buffer MAY be uninitialized.
162
+ On success the function should return 0 and fully fill the input buffer,
163
+ every other return result will be interpreted as an error code.
164
+
165
+ If you are confident that ` getrandom ` is not used in your project, but
166
+ it gets pulled nevertheless by one of your dependencies, then you can
167
+ use the following custom backend which always returns "unsupported" error:
168
+ ``` rust
169
+ use getrandom :: Error ;
170
+
171
+ #[no_mangle]
172
+ unsafe extern " Rust" fn __getrandom_v03_custom (
173
+ dest : * mut u8 ,
174
+ len : usize ,
175
+ ) -> Result <(), Error > {
176
+ Err (Error :: UNSUPPORTED )
177
+ }
178
+ ```
179
+
180
+ ### Platform Support
181
+ This crate generally supports the same operating system and platform versions
182
+ that the Rust standard library does. Additional targets may be supported using
183
+ pluggable custom implementations.
184
+
185
+ This means that as Rust drops support for old versions of operating systems
186
+ (such as old Linux kernel versions, Android API levels, etc) in stable releases,
187
+ ` getrandom ` may create new patch releases (` 0.N.x ` ) that remove support for
188
+ outdated platform versions.
189
+
190
+ ### ` /dev/urandom ` fallback on Linux and Android
191
+
192
+ On Linux targets the fallback is present only if either ` target_env ` is ` musl ` ,
193
+ or ` target_arch ` is one of the following: ` aarch64 ` , ` arm ` , ` powerpc ` , ` powerpc64 ` ,
194
+ ` s390x ` , ` x86 ` , ` x86_64 ` . Other supported targets [ require] [ platform-support ]
195
+ kernel versions which support ` getrandom ` system call, so fallback is not needed.
196
+
197
+ On Android targets the fallback is present only for the following ` target_arch ` es:
198
+ ` aarch64 ` , ` arm ` , ` x86 ` , ` x86_64 ` . Other ` target_arch ` es (e.g. RISC-V) require
199
+ sufficiently high API levels.
200
+
201
+ The fallback can be disabled by enabling the ` linux_getrandom ` opt-in backend.
202
+ Note that doing so will bump minimum supported Linux kernel version to 3.17 and
203
+ Android API level to 23 (Marshmallow).
204
+
205
+ ### Early boot
56
206
57
- ## Platform Support
207
+ Sometimes, early in the boot process, the OS has not collected enough
208
+ entropy to securely seed its RNG. This is especially common on virtual
209
+ machines, where standard "random" events are hard to come by.
58
210
59
- This crate generally supports the same operating system and platform versions that the Rust standard library does.
60
- Additional targets may be supported using pluggable custom implementations.
211
+ Some operating system interfaces always block until the RNG is securely
212
+ seeded. This can take anywhere from a few seconds to more than a minute.
213
+ A few (Linux, NetBSD and Solaris) offer a choice between blocking and
214
+ getting an error; in these cases, we always choose to block.
61
215
62
- This means that as Rust drops support for old versions of operating systems (such as old Linux kernel versions, Android API levels, etc)
63
- in stable releases, ` getrandom ` may create new patch releases (` 0.N.x ` ) that remove support for outdated platform versions.
216
+ On Linux (when the ` getrandom ` system call is not available), reading from
217
+ ` /dev/urandom ` never blocks, even when the OS hasn't collected enough
218
+ entropy yet. To avoid returning low-entropy bytes, we first poll
219
+ ` /dev/random ` and only switch to ` /dev/urandom ` once this has succeeded.
220
+
221
+ On OpenBSD, this kind of entropy accounting isn't available, and on
222
+ NetBSD, blocking on it is discouraged. On these platforms, nonblocking
223
+ interfaces are used, even when reliable entropy may not be available.
224
+ On the platforms where it is used, the reliability of entropy accounting
225
+ itself isn't free from controversy. This library provides randomness
226
+ sourced according to the platform's best practices, but each platform has
227
+ its own limits on the grade of randomness it can promise in environments
228
+ with few sources of entropy.
229
+
230
+ ## Error handling
231
+
232
+ We always choose failure over returning known insecure "random" bytes. In
233
+ general, on supported platforms, failure is highly unlikely, though not
234
+ impossible. If an error does occur, then it is likely that it will occur
235
+ on every call to ` getrandom ` , hence after the first successful call one
236
+ can be reasonably confident that no errors will occur.
237
+
238
+ ## Panic handling
239
+
240
+ We strive to eliminate all potential panics from our implementation.
241
+ In other words, when compiled with enabled optimizations, generated
242
+ binary code for ` getrandom ` functions should not contain any panic
243
+ branches. Even if platform misbiheaves and returns an unexpected
244
+ result, our code should correctly handle it and return an error like
245
+ [ ` Error::UNEXPECTED ` ] .
246
+
247
+ ## Sanitizer support
248
+
249
+ If your code uses [ ` fill_uninit ` ] and you use memory sanitizer
250
+ (i.e. ` -Zsanitizer=memory ` ), then you need to pass ` getrandom_sanitize `
251
+ configuration flag for ` fill_uninit ` to unpoison destination buffer.
252
+
253
+ For example, it can be done like this (requires Nightly compiler):
254
+ ``` sh
255
+ RUSTFLAGS=" -Zsanitizer=memory --cfg getrandom_sanitize" cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu
256
+ ```
257
+
258
+ ## Minimum Supported Rust Version
259
+
260
+ This crate requires Rust 1.60.0 or later.
64
261
65
262
## License
66
263
@@ -77,5 +274,66 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
77
274
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
78
275
dual licensed as above, without any additional terms or conditions.
79
276
277
+ [ // ] : # ( badges )
278
+
279
+ [ GitHub Actions ] : https://github.com/rust-random/getrandom/actions?query=workflow:Tests+branch:master
280
+ [ Build Status ] : https://github.com/rust-random/getrandom/actions/workflows/tests.yml/badge.svg?branch=master
281
+ [ crates.io ] : https://crates.io/crates/getrandom
282
+ [ Crate ] : https://img.shields.io/crates/v/getrandom
283
+ [ docs.rs ] : https://docs.rs/getrandom
284
+ [ Documentation ] : https://docs.rs/getrandom/badge.svg
285
+ [ deps.rs ] : https://deps.rs/repo/github/rust-random/getrandom
286
+ [ Dependency Status ] : https://deps.rs/repo/github/rust-random/getrandom/status.svg
287
+ [ Downloads ] : https://img.shields.io/crates/d/getrandom
288
+ [ License ] : https://img.shields.io/crates/l/getrandom
289
+
290
+ [ // ] : # ( supported targets )
291
+
292
+ [ 1 ] : https://manned.org/getrandom.2
293
+ [ 2 ] : https://manned.org/urandom.4
294
+ [ 3 ] : https://www.unix.com/man-page/mojave/2/getentropy/
295
+ [ 4 ] : https://www.unix.com/man-page/mojave/4/urandom/
296
+ [ 5 ] : https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
297
+ [ 7 ] : https://man.openbsd.org/getentropy.2
298
+ [ 8 ] : https://man.netbsd.org/sysctl.7
299
+ [ 9 ] : https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
300
+ [ 11 ] : https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
301
+ [ 12 ] : https://illumos.org/man/2/getrandom
302
+ [ 13 ] : https://github.com/emscripten-core/emscripten/pull/12240
303
+ [ 14 ] : https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/r/random.html
304
+ [ 15 ] : https://www.ibm.com/docs/en/aix/7.3?topic=files-random-urandom-devices
305
+ [ 16 ] : https://man.netbsd.org/getrandom.2
306
+ [ 17 ] : https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom
307
+ [ 18 ] : https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d
308
+
309
+ [ `ProcessPrng` ] : https://learn.microsoft.com/en-us/windows/win32/seccng/processprng
310
+ [ `RtlGenRandom` ] : https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
311
+ [ `Crypto.getRandomValues` ] : https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
312
+ [ `RDRAND` ] : https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
313
+ [ `RNDR` ] : https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/RNDR--Random-Number
314
+ [ `CCRandomGenerateBytes` ] : https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html
315
+ [ `cprng_draw` ] : https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
316
+ [ `crypto.randomFillSync` ] : https://nodejs.org/api/crypto.html#cryptorandomfillsyncbuffer-offset-size
317
+ [ `esp_fill_random` ] : https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t
318
+ [ `random_get` ] : https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno
319
+ [ `get-random-u64` ] : https://github.com/WebAssembly/WASI/blob/v0.2.1/wasip2/random/random.wit#L23-L28
320
+ [ WebAssembly support ] : #webassembly-support
321
+ [ configuration flags ] : #configuration-flags
322
+ [ custom backend ] : #custom-backend
323
+ [ `wasm-bindgen` ] : https://github.com/rustwasm/wasm-bindgen
324
+ [ `module` ] : https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-js-imports/module.html
325
+ [ CommonJS modules ] : https://nodejs.org/api/modules.html
326
+ [ ES modules ] : https://nodejs.org/api/esm.html
327
+ [ `sys_read_entropy` ] : https://github.com/hermit-os/kernel/blob/315f58ff5efc81d9bf0618af85a59963ff55f8b1/src/syscalls/entropy.rs#L47-L55
328
+ [ platform-support ] : https://doc.rust-lang.org/stable/rustc/platform-support.html
329
+ [ WASI ] : https://github.com/CraneStation/wasi
330
+ [ Emscripten ] : https://www.hellorust.com/setup/emscripten/
331
+ [ `rustix` ] : https://docs.rs/rustix
332
+
333
+ [ // ] : # ( licenses )
334
+
80
335
[ LICENSE-APACHE ] : https://github.com/rust-random/getrandom/blob/master/LICENSE-APACHE
81
336
[ LICENSE-MIT ] : https://github.com/rust-random/getrandom/blob/master/LICENSE-MIT
337
+
338
+ [ `Error::UNEXPECTED` ] : https://docs.rs/getrandom/latest/getrandom/struct.Error.html#associatedconstant.UNEXPECTED
339
+ [ `fill_uninit` ] : https://docs.rs/getrandom/latest/getrandom/fn.fill_uninit.html
0 commit comments