Expand description
Interface to the operating system’s random number generator.
§Supported targets
Target | Target Triple | Implementation |
---|---|---|
Linux, Android | *‑linux‑* | getrandom system call if available, otherwise /dev/urandom after successfully polling /dev/random |
Windows | *‑windows‑* | BCryptGenRandom |
macOS | *‑apple‑darwin | getentropy |
iOS, tvOS, watchOS | *‑apple‑ios , *-apple-tvos , *-apple-watchos | CCRandomGenerateBytes |
FreeBSD | *‑freebsd | getrandom if available, otherwise kern.arandom |
OpenBSD | *‑openbsd | getentropy |
NetBSD | *‑netbsd | getrandom if available, otherwise kern.arandom |
Dragonfly BSD | *‑dragonfly | getrandom if available, otherwise /dev/urandom (identical to /dev/random ) |
Solaris, illumos | *‑solaris , *‑illumos | getrandom if available, otherwise /dev/random |
Fuchsia OS | *‑fuchsia | cprng_draw |
Redox | *‑redox | /dev/urandom |
Haiku | *‑haiku | /dev/urandom (identical to /dev/random ) |
Hermit | *-hermit | sys_read_entropy |
Hurd | *-hurd-* | getrandom |
SGX | x86_64‑*‑sgx | RDRAND |
VxWorks | *‑wrs‑vxworks‑* | randABytes after checking entropy pool initialization with randSecure |
ESP-IDF | *‑espidf | esp_fill_random |
Emscripten | *‑emscripten | getentropy |
WASI | wasm32‑wasi | random_get |
Web Browser and Node.js | wasm*‑*‑unknown | Crypto.getRandomValues if available, then crypto.randomFillSync if on Node.js, see WebAssembly support |
SOLID | *-kmc-solid_* | SOLID_RNG_SampleRandomBytes |
Nintendo 3DS | armv6k-nintendo-3ds | getrandom |
PS Vita | armv7-sony-vita-newlibeabihf | getentropy |
QNX Neutrino | *‑nto-qnx* | /dev/urandom (identical to /dev/random ) |
AIX | *-ibm-aix | /dev/urandom |
There is no blanket implementation on unix
targets that reads from
/dev/urandom
. This ensures all supported targets are using the recommended
interface and respect maximum buffer sizes.
Pull Requests that add support for new targets to getrandom
are always welcome.
§Unsupported targets
By default, getrandom
will not compile on unsupported targets, but certain
features allow a user to select a “fallback” implementation if no supported
implementation exists.
All of the below mechanisms only affect unsupported targets. Supported targets will always use their supported implementations. This prevents a crate from overriding a secure source of randomness (either accidentally or intentionally).
§/dev/urandom
fallback on Linux and Android
On Linux targets the fallback is present only if either target_env
is musl
,
or target_arch
is one of the following: aarch64
, arm
, powerpc
, powerpc64
,
s390x
, x86
, x86_64
. Other supported targets require
kernel versions which support getrandom
system call, so fallback is not needed.
On Android targets the fallback is present only for the following target_arch
es:
aarch64
, arm
, x86
, x86_64
. Other target_arch
es (e.g. RISC-V) require
sufficiently high API levels.
The fallback can be disabled by enabling the linux_disable_fallback
crate feature.
Note that doing so will bump minimum supported Linux kernel version to 3.17 and
Android API level to 23 (Marshmallow).
§RDRAND on x86
If the rdrand
Cargo feature is enabled, getrandom
will fallback to using
the RDRAND
instruction to get randomness on no_std
x86
/x86_64
targets. This feature has no effect on other CPU architectures.
§WebAssembly support
This crate fully supports the
wasm32-wasi
and
wasm32-unknown-emscripten
targets. However, the wasm32-unknown-unknown
target (i.e. the target used
by wasm-pack
) is not automatically
supported since, from the target name alone, we cannot deduce which
JavaScript interface is in use (or if JavaScript is available at all).
Instead, if the js
Cargo feature is enabled, this crate will assume
that you are building for an environment containing JavaScript, and will
call the appropriate methods. Both web browser (main window and Web Workers)
and Node.js environments are supported, invoking the methods
described above using the wasm-bindgen
toolchain.
To enable the js
Cargo feature, add the following to the dependencies
section in your Cargo.toml
file:
[dependencies]
getrandom = { version = "0.2", features = ["js"] }
This can be done even if getrandom
is not a direct dependency. Cargo
allows crates to enable features for indirect dependencies.
This feature should only be enabled for binary, test, or benchmark crates.
Library crates should generally not enable this feature, leaving such a
decision to users of their library. Also, libraries should not introduce
their own js
features just to enable getrandom
’s js
feature.
This feature has no effect on targets other than wasm32-unknown-unknown
.
§Node.js ES module support
Node.js supports both CommonJS modules and ES modules. Due to
limitations in wasm-bindgen’s module
support, we cannot directly
support ES Modules running on Node.js. However, on Node v15 and later, the
module author can add a simple shim to support the Web Cryptography API:
import { webcrypto } from 'node:crypto'
globalThis.crypto = webcrypto
This crate will then use the provided webcrypto
implementation.
§Platform Support
This crate generally supports the same operating system and platform versions that the Rust standard library does. Additional targets may be supported using pluggable custom implementations.
This means that as Rust drops support for old versions of operating systems
(such as old Linux kernel versions, Android API levels, etc) in stable releases,
getrandom
may create new patch releases (0.N.x
) that remove support for
outdated platform versions.
§Custom implementations
The [register_custom_getrandom!
] macro allows a user to mark their own
function as the backing implementation for getrandom
. See the macro’s
documentation for more information about writing and registering your own
custom implementations.
Note that registering a custom implementation only has an effect on targets
that would otherwise not compile. Any supported targets (including those
using rdrand
and js
Cargo features) continue using their normal
implementations even if a function is registered.
§Early boot
Sometimes, early in the boot process, the OS has not collected enough entropy to securely seed its RNG. This is especially common on virtual machines, where standard “random” events are hard to come by.
Some operating system interfaces always block until the RNG is securely seeded. This can take anywhere from a few seconds to more than a minute. A few (Linux, NetBSD and Solaris) offer a choice between blocking and getting an error; in these cases, we always choose to block.
On Linux (when the getrandom
system call is not available), reading from
/dev/urandom
never blocks, even when the OS hasn’t collected enough
entropy yet. To avoid returning low-entropy bytes, we first poll
/dev/random
and only switch to /dev/urandom
once this has succeeded.
On OpenBSD, this kind of entropy accounting isn’t available, and on NetBSD, blocking on it is discouraged. On these platforms, nonblocking interfaces are used, even when reliable entropy may not be available. On the platforms where it is used, the reliability of entropy accounting itself isn’t free from controversy. This library provides randomness sourced according to the platform’s best practices, but each platform has its own limits on the grade of randomness it can promise in environments with few sources of entropy.
§Error handling
We always choose failure over returning known insecure “random” bytes. In
general, on supported platforms, failure is highly unlikely, though not
impossible. If an error does occur, then it is likely that it will occur
on every call to getrandom
, hence after the first successful call one
can be reasonably confident that no errors will occur.
Structs§
- A small and
no_std
compatible error type
Functions§
- Fill
dest
with random bytes from the system’s preferred random number source. - Version of the
getrandom
function which fillsdest
with random bytes returns a mutable reference to those bytes.