Merge 8338e18f11201d009dd466f8bba6ecf1a24479a4 on remote branch

Change-Id: I6675046e08a2a309b5d22da425dfb74d1238593d
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index d80d39e..279a9af 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
 {
   "git": {
-    "sha1": "de51e2961d05c7af3f19c0c78f9a414cdcb83b67"
-  }
-}
+    "sha1": "ffd22552daa7d21b77ec20c1623bb4789b02122a"
+  },
+  "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index a7618e6..897f8a2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,7 +42,7 @@
     host_supported: true,
     crate_name: "getrandom",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.3",
+    cargo_pkg_version: "0.2.5",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -61,7 +61,7 @@
     name: "getrandom_test_defaults",
     crate_name: "getrandom",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.3",
+    cargo_pkg_version: "0.2.5",
     test_suites: ["general-tests"],
     auto_gen_config: true,
     edition: "2018",
@@ -98,7 +98,7 @@
     host_supported: true,
     crate_name: "getrandom",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.3",
+    cargo_pkg_version: "0.2.5",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: ["std"],
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0ae351a..99b442b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,34 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.2.5] - 2022-02-22
+### Added
+- ESP-IDF targets (`*‑espidf`) support [#245]
+
+### Fixed
+- Webpack warning caused by dynamic require [#234]
+- Error checking on iOS for `SecRandomCopyBytes` [#244]
+
+[#234]: https://github.com/rust-random/getrandom/pull/234
+[#244]: https://github.com/rust-random/getrandom/pull/244
+[#245]: https://github.com/rust-random/getrandom/pull/245
+
+## [0.2.4] - 2021-12-13
+### Changed
+- Use explicit imports in the `js` backend [#220]
+- Use `/dev/urandom` on Redox instead of `rand:` [#222]
+- Use `NonZeroU32::new_unchecked` to convert wasi error [#233]
+
+### Added
+- SOLID targets (`*-kmc-solid_*`) support [#235]
+- Limited Hermit (`x86_64-unknown-hermit`) support [#236]
+
+[#220]: https://github.com/rust-random/getrandom/pull/220
+[#222]: https://github.com/rust-random/getrandom/pull/222
+[#233]: https://github.com/rust-random/getrandom/pull/233
+[#235]: https://github.com/rust-random/getrandom/pull/235
+[#236]: https://github.com/rust-random/getrandom/pull/236
+
 ## [0.2.3] - 2021-04-10
 ### Changed
 - Replace build.rs with link attributes. [#205]
@@ -55,8 +83,8 @@
 - Unsupported targets no longer compile [#107]
 - Change/Add `Error` constants [#120]
 - Only impl `std` traits when the `"std"` Cargo feature is specified [#106]
-- Remove offical support for Hermit, L4Re, and UEFI [#133]
-- Remove optional `"log"` dependancy [#131]
+- Remove official support for Hermit, L4Re, and UEFI [#133]
+- Remove optional `"log"` dependency [#131]
 - Update minimum supported Linux kernel to 2.6.32 [#153]
 - Update MSRV to 1.34 [#159]
 
@@ -252,3 +280,28 @@
 
 ## [0.0.0] - 2019-01-19
 Publish an empty template library.
+
+[0.2.5]: https://github.com/rust-random/getrandom/compare/v0.2.4...v0.2.5
+[0.2.4]: https://github.com/rust-random/getrandom/compare/v0.2.3...v0.2.4
+[0.2.3]: https://github.com/rust-random/getrandom/compare/v0.2.2...v0.2.3
+[0.2.2]: https://github.com/rust-random/getrandom/compare/v0.2.1...v0.2.2
+[0.2.1]: https://github.com/rust-random/getrandom/compare/v0.2.0...v0.2.1
+[0.2.0]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.2.0
+[0.1.16]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.1.16
+[0.1.15]: https://github.com/rust-random/getrandom/compare/v0.1.14...v0.1.15
+[0.1.14]: https://github.com/rust-random/getrandom/compare/v0.1.13...v0.1.14
+[0.1.13]: https://github.com/rust-random/getrandom/compare/v0.1.12...v0.1.13
+[0.1.12]: https://github.com/rust-random/getrandom/compare/v0.1.11...v0.1.12
+[0.1.11]: https://github.com/rust-random/getrandom/compare/v0.1.10...v0.1.11
+[0.1.10]: https://github.com/rust-random/getrandom/compare/v0.1.9...v0.1.10
+[0.1.9]: https://github.com/rust-random/getrandom/compare/v0.1.8...v0.1.9
+[0.1.8]: https://github.com/rust-random/getrandom/compare/v0.1.7...v0.1.8
+[0.1.7]: https://github.com/rust-random/getrandom/compare/v0.1.6...v0.1.7
+[0.1.6]: https://github.com/rust-random/getrandom/compare/v0.1.5...v0.1.6
+[0.1.5]: https://github.com/rust-random/getrandom/compare/v0.1.4...v0.1.5
+[0.1.4]: https://github.com/rust-random/getrandom/compare/v0.1.3...v0.1.4
+[0.1.3]: https://github.com/rust-random/getrandom/compare/v0.1.2...v0.1.3
+[0.1.2]: https://github.com/rust-random/getrandom/compare/v0.1.1...v0.1.2
+[0.1.1]: https://github.com/rust-random/getrandom/compare/v0.1.0...v0.1.1
+[0.1.0]: https://github.com/rust-random/getrandom/compare/v0.0.0...v0.1.0
+[0.0.0]: https://github.com/rust-random/getrandom/releases/tag/v0.0.0
diff --git a/Cargo.toml b/Cargo.toml
index 8c0d4f4..b3d191b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,27 +3,37 @@
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
 #
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
 
 [package]
 edition = "2018"
 name = "getrandom"
-version = "0.2.3"
+version = "0.2.5"
 authors = ["The Rand Project Developers"]
 exclude = [".*"]
 description = "A small cross-platform library for retrieving random data from system source"
 documentation = "https://docs.rs/getrandom"
-categories = ["os", "no-std"]
+categories = [
+    "os",
+    "no-std",
+]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-random/getrandom"
+
 [package.metadata.docs.rs]
-features = ["std", "custom"]
-rustdoc-args = ["--cfg", "docsrs"]
+features = [
+    "std",
+    "custom",
+]
+rustdoc-args = [
+    "--cfg",
+    "docsrs",
+]
+
 [dependencies.cfg-if]
 version = "1"
 
@@ -38,11 +48,20 @@
 
 [features]
 custom = []
-js = ["wasm-bindgen", "js-sys"]
+js = [
+    "wasm-bindgen",
+    "js-sys",
+]
 rdrand = []
-rustc-dep-of-std = ["compiler_builtins", "core", "libc/rustc-dep-of-std", "wasi/rustc-dep-of-std"]
+rustc-dep-of-std = [
+    "compiler_builtins",
+    "core",
+    "libc/rustc-dep-of-std",
+    "wasi/rustc-dep-of-std",
+]
 std = []
 test-in-browser = []
+
 [target."cfg(all(target_arch = \"wasm32\", target_os = \"unknown\"))".dependencies.js-sys]
 version = "0.3"
 optional = true
@@ -51,10 +70,13 @@
 version = "0.2.62"
 optional = true
 default-features = false
+
 [target."cfg(all(target_arch = \"wasm32\", target_os = \"unknown\"))".dev-dependencies.wasm-bindgen-test]
 version = "0.3.18"
+
 [target."cfg(target_os = \"wasi\")".dependencies.wasi]
 version = "0.10"
+
 [target."cfg(unix)".dependencies.libc]
 version = "0.2.64"
 default-features = false
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 4ab9ad6..eb51149 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "getrandom"
-version = "0.2.3" # Also update html_root_url in lib.rs when bumping this
+version = "0.2.5" # Also update html_root_url in lib.rs when bumping this
 edition = "2018"
 authors = ["The Rand Project Developers"]
 license = "MIT OR Apache-2.0"
diff --git a/METADATA b/METADATA
index aaa5815..f9af3d4 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/getrandom/getrandom-0.2.3.crate"
+    value: "https://static.crates.io/crates/getrandom/getrandom-0.2.5.crate"
   }
-  version: "0.2.3"
+  version: "0.2.5"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2021
-    month: 6
-    day: 21
+    year: 2022
+    month: 3
+    day: 1
   }
 }
diff --git a/src/custom.rs b/src/custom.rs
index 0d3123c..6110b05 100644
--- a/src/custom.rs
+++ b/src/custom.rs
@@ -16,7 +16,7 @@
 ///
 /// The function to register must have the same signature as
 /// [`getrandom::getrandom`](crate::getrandom). The function can be defined
-/// wherever you want, either in root crate or a dependant crate.
+/// wherever you want, either in root crate or a dependent crate.
 ///
 /// For example, if we wanted a `failure-getrandom` crate containing an
 /// implementation that always fails, we would first depend on `getrandom`
diff --git a/src/error.rs b/src/error.rs
index 0f52186..6615753 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -73,7 +73,14 @@
     #[inline]
     pub fn raw_os_error(self) -> Option<i32> {
         if self.0.get() < Self::INTERNAL_START {
-            Some(self.0.get() as i32)
+            match () {
+                #[cfg(target_os = "solid_asp3")]
+                // On SOLID, negate the error code again to obtain the original
+                // error code.
+                () => Some(-(self.0.get() as i32)),
+                #[cfg(not(target_os = "solid_asp3"))]
+                () => Some(self.0.get() as i32),
+            }
         } else {
             None
         }
diff --git a/src/espidf.rs b/src/espidf.rs
new file mode 100644
index 0000000..dce8a2a
--- /dev/null
+++ b/src/espidf.rs
@@ -0,0 +1,26 @@
+// Copyright 2021 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Implementation for ESP-IDF
+use crate::Error;
+use core::ffi::c_void;
+
+extern "C" {
+    fn esp_fill_random(buf: *mut c_void, len: usize) -> u32;
+}
+
+pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+    // Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`)
+    // will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process:
+    // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html
+    //
+    // However tracking if some of these entropy sources is enabled is way too difficult to implement here
+    unsafe { esp_fill_random(dest.as_mut_ptr().cast(), dest.len()) };
+
+    Ok(())
+}
diff --git a/src/ios.rs b/src/ios.rs
index 5e38474..226de16 100644
--- a/src/ios.rs
+++ b/src/ios.rs
@@ -18,7 +18,8 @@
 pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
     // Apple's documentation guarantees kSecRandomDefault is a synonym for NULL.
     let ret = unsafe { SecRandomCopyBytes(null(), dest.len(), dest.as_mut_ptr()) };
-    if ret == -1 {
+    // errSecSuccess (from SecBase.h) is always zero.
+    if ret != 0 {
         Err(Error::IOS_SEC_RANDOM)
     } else {
         Ok(())
diff --git a/src/js.rs b/src/js.rs
index 657d2ac..e910f2b 100644
--- a/src/js.rs
+++ b/src/js.rs
@@ -10,8 +10,8 @@
 extern crate std;
 use std::thread_local;
 
-use js_sys::Uint8Array;
-use wasm_bindgen::{prelude::*, JsCast};
+use js_sys::{global, Uint8Array};
+use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
 
 // Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
 const BROWSER_CRYPTO_BUFFER_SIZE: usize = 256;
@@ -57,9 +57,11 @@
 }
 
 fn getrandom_init() -> Result<RngSource, Error> {
-    let global: Global = js_sys::global().unchecked_into();
+    let global: Global = global().unchecked_into();
     if is_node(&global) {
-        let crypto = require("crypto").map_err(|_| Error::NODE_CRYPTO)?;
+        let crypto = NODE_MODULE
+            .require("crypto")
+            .map_err(|_| Error::NODE_CRYPTO)?;
         return Ok(RngSource::Node(crypto));
     }
 
@@ -102,9 +104,15 @@
     #[wasm_bindgen(method, js_name = getRandomValues, catch)]
     fn get_random_values(this: &BrowserCrypto, buf: &Uint8Array) -> Result<(), JsValue>;
 
+    // We use a "module" object here instead of just annotating require() with
+    // js_name = "module.require", so that Webpack doesn't give a warning. See:
+    //   https://github.com/rust-random/getrandom/issues/224
+    type NodeModule;
+    #[wasm_bindgen(js_name = module)]
+    static NODE_MODULE: NodeModule;
     // Node JS crypto module (https://nodejs.org/api/crypto.html)
-    #[wasm_bindgen(catch, js_name = "module.require")]
-    fn require(s: &str) -> Result<NodeCrypto, JsValue>;
+    #[wasm_bindgen(method, catch)]
+    fn require(this: &NodeModule, s: &str) -> Result<NodeCrypto, JsValue>;
     type NodeCrypto;
     #[wasm_bindgen(method, js_name = randomFillSync, catch)]
     fn random_fill_sync(this: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>;
diff --git a/src/lib.rs b/src/lib.rs
index 107b2d3..175da47 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,24 +12,27 @@
 //!
 //! | Target            | Target Triple      | Implementation
 //! | ----------------- | ------------------ | --------------
-//! | Linux, Android    | `*‑linux‑*`        | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random` |
-//! | Windows           | `*‑windows‑*`      | [`BCryptGenRandom`][3] |
-//! | macOS             | `*‑apple‑darwin`   | [`getentropy()`][19] if available, otherwise [`/dev/random`][20] (identical to `/dev/urandom`)
-//! | iOS               | `*‑apple‑ios`      | [`SecRandomCopyBytes`][4]
-//! | FreeBSD           | `*‑freebsd`        | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
-//! | OpenBSD           | `*‑openbsd`        | [`getentropy`][6]
-//! | NetBSD            | `*‑netbsd`         | [`kern.arandom`][7]
-//! | Dragonfly BSD     | `*‑dragonfly`      | [`getrandom()`][22] if available, otherwise [`/dev/random`][8]
-//! | Solaris, illumos  | `*‑solaris`, `*‑illumos` | [`getrandom()`][9] if available, otherwise [`/dev/random`][10]
-//! | Fuchsia OS        | `*‑fuchsia`        | [`cprng_draw`][11]
-//! | Redox             | `*‑redox`          | [`rand:`][12]
+//! | Linux, Android    | `*‑linux‑*`        | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
+//! | Windows           | `*‑windows‑*`      | [`BCryptGenRandom`]
+//! | macOS             | `*‑apple‑darwin`   | [`getentropy`][3] if available, otherwise [`/dev/random`][4] (identical to `/dev/urandom`)
+//! | iOS               | `*‑apple‑ios`      | [`SecRandomCopyBytes`]
+//! | FreeBSD           | `*‑freebsd`        | [`getrandom`][5] if available, otherwise [`kern.arandom`][6]
+//! | OpenBSD           | `*‑openbsd`        | [`getentropy`][7]
+//! | NetBSD            | `*‑netbsd`         | [`kern.arandom`][8]
+//! | Dragonfly BSD     | `*‑dragonfly`      | [`getrandom`][9] if available, otherwise [`/dev/random`][10]
+//! | Solaris, illumos  | `*‑solaris`, `*‑illumos` | [`getrandom`][11] if available, otherwise [`/dev/random`][12]
+//! | Fuchsia OS        | `*‑fuchsia`        | [`cprng_draw`]
+//! | Redox             | `*‑redox`          | `/dev/urandom`
 //! | Haiku             | `*‑haiku`          | `/dev/random` (identical to `/dev/urandom`)
-//! | SGX               | `x86_64‑*‑sgx`     | [RDRAND][18]
+//! | Hermit            | `x86_64-*-hermit`  | [`RDRAND`]
+//! | SGX               | `x86_64‑*‑sgx`     | [`RDRAND`]
 //! | VxWorks           | `*‑wrs‑vxworks‑*`  | `randABytes` after checking entropy pool initialization with `randSecure`
+//! | ESP-IDF           | `*‑espidf`         | [`esp_fill_random`]
 //! | Emscripten        | `*‑emscripten`     | `/dev/random` (identical to `/dev/urandom`)
-//! | WASI              | `wasm32‑wasi`      | [`random_get`][17]
-//! | Web Browser       | `wasm32‑*‑unknown` | [`Crypto.getRandomValues()`][14], see [WebAssembly support][16]
-//! | Node.js           | `wasm32‑*‑unknown` | [`crypto.randomBytes`][15], see [WebAssembly support][16]
+//! | WASI              | `wasm32‑wasi`      | [`random_get`]
+//! | Web Browser       | `wasm32‑*‑unknown` | [`Crypto.getRandomValues`], see [WebAssembly support]
+//! | Node.js           | `wasm32‑*‑unknown` | [`crypto.randomBytes`], see [WebAssembly support]
+//! | SOLID             | `*-kmc-solid_*`    | `SOLID_RNG_SampleRandomBytes`
 //!
 //! There is no blanket implementation on `unix` targets that reads from
 //! `/dev/urandom`. This ensures all supported targets are using the recommended
@@ -50,8 +53,8 @@
 //!
 //! ### RDRAND on x86
 //!
-//! *If the `"rdrand"` Cargo feature is enabled*, `getrandom` will fallback to using
-//! the [`RDRAND`][18] instruction to get randomness on `no_std` `x86`/`x86_64`
+//! *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
@@ -64,7 +67,7 @@
 //! 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
+//! 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
@@ -82,7 +85,7 @@
 //!
 //! 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
+//! using `rdrand` and `js` Cargo features) continue using their normal
 //! implementations even if a function is registered.
 //!
 //! ### Indirect Dependencies
@@ -121,30 +124,31 @@
 //!
 //! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
 //! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
-//! [3]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
-//! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
-//! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
-//! [6]: https://man.openbsd.org/getentropy.2
-//! [7]: https://man.netbsd.org/sysctl.7
-//! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
-//! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
-//! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
-//! [11]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
-//! [12]: https://github.com/redox-os/randd/blob/master/src/main.rs
-//! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
-//! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
-//! [16]: #webassembly-support
-//! [17]: https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno
-//! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
-//! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
-//! [20]: https://www.unix.com/man-page/mojave/4/random/
-//! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
-//! [22]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
+//! [3]: https://www.unix.com/man-page/mojave/2/getentropy/
+//! [4]: https://www.unix.com/man-page/mojave/4/random/
+//! [5]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
+//! [6]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
+//! [7]: https://man.openbsd.org/getentropy.2
+//! [8]: https://man.netbsd.org/sysctl.7
+//! [9]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
+//! [10]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
+//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
+//! [12]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
+//!
+//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
+//! [`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
+//! [`SecRandomCopyBytes`]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
+//! [`cprng_draw`]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
+//! [`crypto.randomBytes`]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
+//! [`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t
+//! [`random_get`]: https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno
+//! [WebAssembly support]: #webassembly-support
 
 #![doc(
     html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
     html_favicon_url = "https://www.rust-lang.org/favicon.ico",
-    html_root_url = "https://docs.rs/getrandom/0.2.3"
+    html_root_url = "https://docs.rs/getrandom/0.2.5"
 )]
 #![no_std]
 #![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
@@ -200,9 +204,15 @@
         #[path = "openbsd.rs"] mod imp;
     } else if #[cfg(target_os = "wasi")] {
         #[path = "wasi.rs"] mod imp;
+    } else if #[cfg(all(target_arch = "x86_64", target_os = "hermit"))] {
+        #[path = "rdrand.rs"] mod imp;
     } else if #[cfg(target_os = "vxworks")] {
         mod util_libc;
         #[path = "vxworks.rs"] mod imp;
+    } else if #[cfg(target_os = "solid_asp3")] {
+        #[path = "solid.rs"] mod imp;
+    } else if #[cfg(target_os = "espidf")] {
+        #[path = "espidf.rs"] mod imp;
     } else if #[cfg(windows)] {
         #[path = "windows.rs"] mod imp;
     } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
diff --git a/src/solid.rs b/src/solid.rs
new file mode 100644
index 0000000..dc76aac
--- /dev/null
+++ b/src/solid.rs
@@ -0,0 +1,26 @@
+// Copyright 2021 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Implementation for SOLID
+use crate::Error;
+use core::num::NonZeroU32;
+
+extern "C" {
+    pub fn SOLID_RNG_SampleRandomBytes(buffer: *mut u8, length: usize) -> i32;
+}
+
+pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+    let ret = unsafe { SOLID_RNG_SampleRandomBytes(dest.as_mut_ptr(), dest.len()) };
+    if ret >= 0 {
+        Ok(())
+    } else {
+        // ITRON error numbers are always negative, so we negate it so that it
+        // falls in the dedicated OS error range (1..INTERNAL_START).
+        Err(NonZeroU32::new((-ret) as u32).unwrap().into())
+    }
+}
diff --git a/src/use_file.rs b/src/use_file.rs
index 465c069..16c0216 100644
--- a/src/use_file.rs
+++ b/src/use_file.rs
@@ -17,8 +17,6 @@
     sync::atomic::{AtomicUsize, Ordering::Relaxed},
 };
 
-#[cfg(target_os = "redox")]
-const FILE_PATH: &str = "rand:\0";
 #[cfg(any(
     target_os = "dragonfly",
     target_os = "emscripten",
@@ -28,7 +26,7 @@
     target_os = "illumos"
 ))]
 const FILE_PATH: &str = "/dev/random\0";
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
 const FILE_PATH: &str = "/dev/urandom\0";
 
 pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
@@ -47,7 +45,7 @@
 }
 
 // Returns the file descriptor for the device file used to retrieve random
-// bytes. The file will be opened exactly once. All successful calls will
+// bytes. The file will be opened exactly once. All subsequent calls will
 // return the same file descriptor. This file descriptor is never closed.
 fn get_rng_fd() -> Result<libc::c_int, Error> {
     static FD: AtomicUsize = AtomicUsize::new(LazyUsize::UNINIT);
diff --git a/src/wasi.rs b/src/wasi.rs
index 4674f43..2d413e0 100644
--- a/src/wasi.rs
+++ b/src/wasi.rs
@@ -12,8 +12,12 @@
 use wasi::random_get;
 
 pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
-    unsafe { random_get(dest.as_mut_ptr(), dest.len()) }.map_err(|e: wasi::Error| {
-        // convert wasi's Error into getrandom's NonZeroU32 error
-        NonZeroU32::new(e.raw_error() as u32).unwrap().into()
-    })
+    unsafe {
+        random_get(dest.as_mut_ptr(), dest.len()).map_err(|e: wasi::Error| {
+            // convert wasi's Error into getrandom's NonZeroU32 error
+            // SAFETY: `wasi::Error` is `NonZeroU16` internally, so `e.raw_error()`
+            // will never return 0
+            NonZeroU32::new_unchecked(e.raw_error() as u32).into()
+        })
+    }
 }