ice
        core::slice::from_raw_parts_mut(dest, len)
    };
    my_entropy_source(buf)
}
```

### Externally Implemented Interface

Using the nightly-only feature [`extern_item_impls`] it is possible to provide
a custom backend for `getrandom`, even to override an existing first-party implementation.
First, enable the `extern_impl` opt-in backend to allow usage of this nightly feature.
Then, you may provide implementations for `fill_uninit`, `u32`, and/or `u64`
with an attribute macro from the `implementation` module.

[`extern_item_impls`]: https://github.com/rust-lang/rust/issues/125418

```rust
use core::mem::MaybeUninit;

#[cfg(getrandom_backend = "extern_impl")]
#[getrandom::implementation::fill_uninit]
fn my_fill_uninit_implementation(
    dest: &mut [MaybeUninit<u8>]
) -> Result<(), getrandom::Error> {
    // ...
    Ok(())
}
```

For further details on what a suitable implementation for `fill_uninit` may look
like, see [custom backend].

`getrandom` will provide a default implementation for `u32` and `u64`, but does
not currently provide a default for `fill_uninit`, even if one is normally
available for the current target. If no implementation is available,
a compilation error will be raised with instructions for how to provide
an implementation.

### Unsupported backend

In some rare scenarios, you might be compiling this crate for an unsupported
target (e.g. `wasm32-unknown-unknown`), but this crate's functionality
is not actually used by your code. If you are confident that `getrandom` is
not used in your project, but it gets pulled nevertheless by one of your
dependencies, then you can enable the `unsupported` backend, which always
returns `Err(Error::UNSUPPORTED)`.

### 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
the opt-in custom backend.

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 that remove support for
outdated platform versions.

### `/dev/urandom` fallback on Linux and Android

On Linux targets, the `/dev/urandom` 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][platform-support]
kernel versions that support the `getrandom` system call, so the 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_getrandom` opt-in backend.
Note that doing so will bump minimum supported Linux kernel version to 3.17
and Android API level to 23 (Marshmallow).

### 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.

On ESP-IDF, if `esp_fill_random` is used before enabling WiFi, BT, or the
voltage noise entropy source (SAR ADC), the Hardware RNG will only be seeded
via RC_FAST_CLK. This can occur during early boot unless
`bootloader_random_enable()` is called. For more information see the
[ESP-IDF RNG Docs][esp-idf-rng] or the
[RNG section of the ESP32 Technical Reference Manual][esp-trng-docs].

## Error handling

We always prioritize failure over returning known insecure "random" bytes.
Generally, on supported platforms, failure is highly unlikely, though not
impossible. If an error does occur, it is likely that it will occur
on every call to `getrandom`. Therefore, after the first successful call,
one can be reasonably confident that no errors will occur.

## Panic handling

We strive to eliminate all potential panics from our backend implementations.
In other words, when compiled with optimizations enabled, the generated
binary code for `getrandom` functions should not contain any panic branches.
Even if the platform misbehaves and returns an unexpected result,
our code should correctly handle it and return an error, e.g.
[`Error::UNEXPECTED`].

## Sanitizer support

If your code uses [`fill_uninit`] and you enable
[MemorySanitizer](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#memorysanitizer)
(i.e. `-Zsanitizer=memory`), we will automatically handle unpoisoning
of the destination buffer filled by `fill_uninit`.

You can run sanitizer tests for your crate dependent on `getrandom` like this:
```sh
RUSTFLAGS="-Zsanitizer=memory" cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu
```

## Minimum Supported Rust Version

This crate requires Rust 1.85 or later.

## License

The `getrandom` library is distributed under either of

 * [Apache License, Version 2.0][LICENSE-APACHE]
 * [MIT license][LICENSE-MIT]

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

[//]: # (badges)

[GitHub Actions]: https://github.com/rust-random/getrandom/actions?query=branch:master
[Build Status]: https://github.com/rust-random/getrandom/actions/workflows/tests.yml/badge.svg?branch=master
[crates.io]: https://crates.io/crates/getrandom
[Crate]: https://img.shields.io/crates/v/getrandom
[docs.rs]: https://docs.rs/getrandom
[Documentation]: https://docs.rs/getrandom/badge.svg
[deps.rs]: https://deps.rs/repo/github/rust-random/getrandom
[Dependency Status]: https://deps.rs/repo/github/rust-random/getrandom/status.svg
[Downloads]: https://img.shields.io/crates/d/getrandom
[License]: https://img.shields.io/crates/l/getrandom

[//]: # (supported targets)

[1]: https://manned.org/getrandom.2
[2]: https://manned.org/urandom.4
[3]: https://www.unix.com/man-page/mojave/2/getentropy/
[4]: https://www.unix.com/man-page/mojave/4/urandom/
[5]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
[7]: https://man.openbsd.org/getentropy.2
[8]: https://man.netbsd.org/sysctl.7
[9]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
[11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
[12]: https://illumos.org/man/2/getrandom
[13]: https://github.com/emscripten-core/emscripten/pull/12240
[14]: https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/r/random.html
[15]: https://www.ibm.com/docs/en/aix/7.3?topic=files-random-urandom-devices
[16]: https://man.netbsd.org/getrandom.2
[17]: https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom
[18]: https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d
[19]: https://github.com/vitasdk/newlib/blob/2d869fe47aaf02b8e52d04e9a2b79d5b210fd016/newlib/libc/sys/vita/getentropy.c
[20]: https://github.com/cygwin/cygwin/blob/main/winsup/cygwin/libc/getentropy.cc

[`ProcessPrng`]: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng
[`RtlGenRandom`]: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
[`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
[`RDRAND`]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
[`RNDR`]: https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/RNDR--Random-Number
[`CCRandomGenerateBytes`]: https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html
[`cprng_draw`]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
[`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html#functions
[esp-idf-rng]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html
[esp-trng-docs]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#rng
[`EFI_RNG_PROTOCOL`]: https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#efi-rng-protocol
[`random_get`]: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno
[`get-random-u64`]: https://github.com/WebAssembly/WASI/blob/v0.2.1/wasip2/random/random.wit#L23-L28
[configuration flags]: #configuration-flags
[custom backend]: #custom-backend
[unsupported backend]: #unsupported-backend
[`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen
[`module`]: https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-js-imports/module.html
[`sys_read_entropy`]: https://github.com/hermit-os/kernel/blob/315f58ff5efc81d9bf0618af85a59963ff55f8b1/src/syscalls/entropy.rs#L47-L55
[platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html
[WASI]: https://github.com/WebAssembly/WASI
[Emscripten]: https://emscripten.org
[opt-in]: #opt-in-backends
[externally implemented interface]: #externally-implemented-interface

[//]: # (licenses)

[LICENSE-APACHE]: https://github.com/rust-random/getrandom/blob/master/LICENSE-APACHE
[LICENSE-MIT]: https://github.com/rust-random/getrandom/blob/master/LICENSE-MIT

[`Error::UNEXPECTED`]: https://docs.rs/getrandom/latest/getrandom/struct.Error.html#associatedconstant.UNEXPECTED
[`fill_uninit`]: https://docs.rs/getrandom/latest/getrandom/fn.fill_uninit.html
