Crate getrandom

source ·
Expand description

Interface to the operating system’s random number generator.

§Supported targets

TargetTarget TripleImplementation
Linux, Android*‑linux‑*getrandom system call if available, otherwise /dev/urandom after successfully polling /dev/random
Windows*‑windows‑*BCryptGenRandom
macOS*‑apple‑darwingetentropy
iOS, tvOS, watchOS*‑apple‑ios, *-apple-tvos, *-apple-watchosCCRandomGenerateBytes
FreeBSD*‑freebsdgetrandom if available, otherwise kern.arandom
OpenBSD*‑openbsdgetentropy
NetBSD*‑netbsdgetrandom if available, otherwise kern.arandom
Dragonfly BSD*‑dragonflygetrandom if available, otherwise /dev/urandom (identical to /dev/random)
Solaris, illumos*‑solaris, *‑illumosgetrandom if available, otherwise /dev/random
Fuchsia OS*‑fuchsiacprng_draw
Redox*‑redox/dev/urandom
Haiku*‑haiku/dev/urandom (identical to /dev/random)
Hermit*-hermitsys_read_entropy
Hurd*-hurd-*getrandom
SGXx86_64‑*‑sgxRDRAND
VxWorks*‑wrs‑vxworks‑*randABytes after checking entropy pool initialization with randSecure
ESP-IDF*‑espidfesp_fill_random
Emscripten*‑emscriptengetentropy
WASIwasm32‑wasirandom_get
Web Browser and Node.jswasm*‑*‑unknownCrypto.getRandomValues if available, then crypto.randomFillSync if on Node.js, see WebAssembly support
SOLID*-kmc-solid_*SOLID_RNG_SampleRandomBytes
Nintendo 3DSarmv6k-nintendo-3dsgetrandom
PS Vitaarmv7-sony-vita-newlibeabihfgetentropy
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_arches: aarch64, arm, x86, x86_64. Other target_arches (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 fills dest with random bytes returns a mutable reference to those bytes.