From 45df4d0d9b577fecee798d672695fe24ff57fb1b Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 15 Jul 2025 16:37:08 -0600 Subject: feat: migrate from Cedar to SpiceDB authorization system This is a major architectural change that replaces the Cedar policy-based authorization system with SpiceDB's relation-based authorization. Key changes: - Migrate from Rust to Go implementation - Replace Cedar policies with SpiceDB schema and relationships - Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks - Update build system and dependencies for Go ecosystem - Maintain Envoy integration for external authorization This change enables more flexible permission modeling through SpiceDB's Google Zanzibar inspired relation-based system, supporting complex hierarchical permissions that were difficult to express in Cedar. Breaking change: Existing Cedar policies and Rust-based configuration will no longer work and need to be migrated to SpiceDB schema. --- vendor/getrandom/src/backends/apple_other.rs | 21 -- vendor/getrandom/src/backends/custom.rs | 13 -- vendor/getrandom/src/backends/efi_rng.rs | 124 ----------- vendor/getrandom/src/backends/esp_idf.rs | 21 -- vendor/getrandom/src/backends/fuchsia.rs | 16 -- vendor/getrandom/src/backends/getentropy.rs | 27 --- vendor/getrandom/src/backends/getrandom.rs | 31 --- vendor/getrandom/src/backends/hermit.rs | 53 ----- .../src/backends/linux_android_with_fallback.rs | 101 --------- vendor/getrandom/src/backends/linux_raw.rs | 136 ------------ vendor/getrandom/src/backends/netbsd.rs | 78 ------- vendor/getrandom/src/backends/rdrand.rs | 182 ---------------- vendor/getrandom/src/backends/rndr.rs | 145 ------------- vendor/getrandom/src/backends/solaris.rs | 42 ---- vendor/getrandom/src/backends/solid.rs | 19 -- vendor/getrandom/src/backends/use_file.rs | 234 --------------------- vendor/getrandom/src/backends/vxworks.rs | 54 ----- vendor/getrandom/src/backends/wasi_p1.rs | 32 --- vendor/getrandom/src/backends/wasi_p2.rs | 50 ----- vendor/getrandom/src/backends/wasm_js.rs | 72 ------- vendor/getrandom/src/backends/windows.rs | 61 ------ vendor/getrandom/src/backends/windows7.rs | 45 ---- 22 files changed, 1557 deletions(-) delete mode 100644 vendor/getrandom/src/backends/apple_other.rs delete mode 100644 vendor/getrandom/src/backends/custom.rs delete mode 100644 vendor/getrandom/src/backends/efi_rng.rs delete mode 100644 vendor/getrandom/src/backends/esp_idf.rs delete mode 100644 vendor/getrandom/src/backends/fuchsia.rs delete mode 100644 vendor/getrandom/src/backends/getentropy.rs delete mode 100644 vendor/getrandom/src/backends/getrandom.rs delete mode 100644 vendor/getrandom/src/backends/hermit.rs delete mode 100644 vendor/getrandom/src/backends/linux_android_with_fallback.rs delete mode 100644 vendor/getrandom/src/backends/linux_raw.rs delete mode 100644 vendor/getrandom/src/backends/netbsd.rs delete mode 100644 vendor/getrandom/src/backends/rdrand.rs delete mode 100644 vendor/getrandom/src/backends/rndr.rs delete mode 100644 vendor/getrandom/src/backends/solaris.rs delete mode 100644 vendor/getrandom/src/backends/solid.rs delete mode 100644 vendor/getrandom/src/backends/use_file.rs delete mode 100644 vendor/getrandom/src/backends/vxworks.rs delete mode 100644 vendor/getrandom/src/backends/wasi_p1.rs delete mode 100644 vendor/getrandom/src/backends/wasi_p2.rs delete mode 100644 vendor/getrandom/src/backends/wasm_js.rs delete mode 100644 vendor/getrandom/src/backends/windows.rs delete mode 100644 vendor/getrandom/src/backends/windows7.rs (limited to 'vendor/getrandom/src/backends') diff --git a/vendor/getrandom/src/backends/apple_other.rs b/vendor/getrandom/src/backends/apple_other.rs deleted file mode 100644 index c7b51c0e..00000000 --- a/vendor/getrandom/src/backends/apple_other.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Implementation for iOS, tvOS, and watchOS where `getentropy` is unavailable. -use crate::Error; -use core::{ffi::c_void, mem::MaybeUninit}; - -pub use crate::util::{inner_u32, inner_u64}; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - let dst_ptr = dest.as_mut_ptr().cast::(); - let ret = unsafe { libc::CCRandomGenerateBytes(dst_ptr, dest.len()) }; - if ret == libc::kCCSuccess { - Ok(()) - } else { - Err(Error::IOS_RANDOM_GEN) - } -} - -impl Error { - /// Call to `CCRandomGenerateBytes` failed. - pub(crate) const IOS_RANDOM_GEN: Error = Self::new_internal(10); -} diff --git a/vendor/getrandom/src/backends/custom.rs b/vendor/getrandom/src/backends/custom.rs deleted file mode 100644 index c505481a..00000000 --- a/vendor/getrandom/src/backends/custom.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! An implementation which calls out to an externally defined function. -use crate::Error; -use core::mem::MaybeUninit; - -pub use crate::util::{inner_u32, inner_u64}; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - extern "Rust" { - fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error>; - } - unsafe { __getrandom_v03_custom(dest.as_mut_ptr().cast(), dest.len()) } -} diff --git a/vendor/getrandom/src/backends/efi_rng.rs b/vendor/getrandom/src/backends/efi_rng.rs deleted file mode 100644 index 768c8cc8..00000000 --- a/vendor/getrandom/src/backends/efi_rng.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! Implementation for UEFI using EFI_RNG_PROTOCOL -use crate::Error; -use core::{ - mem::MaybeUninit, - ptr::{self, null_mut, NonNull}, - sync::atomic::{AtomicPtr, Ordering::Relaxed}, -}; -use r_efi::{ - efi::{BootServices, Handle}, - protocols::rng, -}; - -extern crate std; - -pub use crate::util::{inner_u32, inner_u64}; - -#[cfg(not(target_os = "uefi"))] -compile_error!("`efi_rng` backend can be enabled only for UEFI targets!"); - -static RNG_PROTOCOL: AtomicPtr = AtomicPtr::new(null_mut()); - -#[cold] -#[inline(never)] -fn init() -> Result, Error> { - const HANDLE_SIZE: usize = size_of::(); - - let boot_services = std::os::uefi::env::boot_services() - .ok_or(Error::BOOT_SERVICES_UNAVAILABLE)? - .cast::(); - - let mut handles = [ptr::null_mut(); 16]; - // `locate_handle` operates with length in bytes - let mut buf_size = handles.len() * HANDLE_SIZE; - let mut guid = rng::PROTOCOL_GUID; - let ret = unsafe { - ((*boot_services.as_ptr()).locate_handle)( - r_efi::efi::BY_PROTOCOL, - &mut guid, - null_mut(), - &mut buf_size, - handles.as_mut_ptr(), - ) - }; - - if ret.is_error() { - return Err(Error::from_uefi_code(ret.as_usize())); - } - - let handles_len = buf_size / HANDLE_SIZE; - let handles = handles.get(..handles_len).ok_or(Error::UNEXPECTED)?; - - let system_handle = std::os::uefi::env::image_handle(); - for &handle in handles { - let mut protocol: MaybeUninit<*mut rng::Protocol> = MaybeUninit::uninit(); - - let mut protocol_guid = rng::PROTOCOL_GUID; - let ret = unsafe { - ((*boot_services.as_ptr()).open_protocol)( - handle, - &mut protocol_guid, - protocol.as_mut_ptr().cast(), - system_handle.as_ptr(), - ptr::null_mut(), - r_efi::system::OPEN_PROTOCOL_GET_PROTOCOL, - ) - }; - - let protocol = if ret.is_error() { - continue; - } else { - let protocol = unsafe { protocol.assume_init() }; - NonNull::new(protocol).ok_or(Error::UNEXPECTED)? - }; - - // Try to use the acquired protocol handle - let mut buf = [0u8; 8]; - let mut alg_guid = rng::ALGORITHM_RAW; - let ret = unsafe { - ((*protocol.as_ptr()).get_rng)( - protocol.as_ptr(), - &mut alg_guid, - buf.len(), - buf.as_mut_ptr(), - ) - }; - - if ret.is_error() { - continue; - } - - RNG_PROTOCOL.store(protocol.as_ptr(), Relaxed); - return Ok(protocol); - } - Err(Error::NO_RNG_HANDLE) -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - let protocol = match NonNull::new(RNG_PROTOCOL.load(Relaxed)) { - Some(p) => p, - None => init()?, - }; - - let mut alg_guid = rng::ALGORITHM_RAW; - let ret = unsafe { - ((*protocol.as_ptr()).get_rng)( - protocol.as_ptr(), - &mut alg_guid, - dest.len(), - dest.as_mut_ptr().cast::(), - ) - }; - - if ret.is_error() { - Err(Error::from_uefi_code(ret.as_usize())) - } else { - Ok(()) - } -} - -impl Error { - pub(crate) const BOOT_SERVICES_UNAVAILABLE: Error = Self::new_internal(10); - pub(crate) const NO_RNG_HANDLE: Error = Self::new_internal(11); -} diff --git a/vendor/getrandom/src/backends/esp_idf.rs b/vendor/getrandom/src/backends/esp_idf.rs deleted file mode 100644 index 4d1689dc..00000000 --- a/vendor/getrandom/src/backends/esp_idf.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Implementation for ESP-IDF -use crate::Error; -use core::{ffi::c_void, mem::MaybeUninit}; - -pub use crate::util::{inner_u32, inner_u64}; - -extern "C" { - fn esp_fill_random(buf: *mut c_void, len: usize) -> u32; -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> 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/vendor/getrandom/src/backends/fuchsia.rs b/vendor/getrandom/src/backends/fuchsia.rs deleted file mode 100644 index b5f1ade5..00000000 --- a/vendor/getrandom/src/backends/fuchsia.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! Implementation for Fuchsia Zircon -use crate::Error; -use core::mem::MaybeUninit; - -pub use crate::util::{inner_u32, inner_u64}; - -#[link(name = "zircon")] -extern "C" { - fn zx_cprng_draw(buffer: *mut u8, length: usize); -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - unsafe { zx_cprng_draw(dest.as_mut_ptr().cast::(), dest.len()) } - Ok(()) -} diff --git a/vendor/getrandom/src/backends/getentropy.rs b/vendor/getrandom/src/backends/getentropy.rs deleted file mode 100644 index ed181f01..00000000 --- a/vendor/getrandom/src/backends/getentropy.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! Implementation using getentropy(2) -//! -//! Available since: -//! - macOS 10.12 -//! - OpenBSD 5.6 -//! - Emscripten 2.0.5 -//! - vita newlib since Dec 2021 -//! -//! For these targets, we use getentropy(2) because getrandom(2) doesn't exist. -use crate::Error; -use core::{ffi::c_void, mem::MaybeUninit}; - -pub use crate::util::{inner_u32, inner_u64}; - -#[path = "../util_libc.rs"] -mod util_libc; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - for chunk in dest.chunks_mut(256) { - let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::(), chunk.len()) }; - if ret != 0 { - return Err(util_libc::last_os_error()); - } - } - Ok(()) -} diff --git a/vendor/getrandom/src/backends/getrandom.rs b/vendor/getrandom/src/backends/getrandom.rs deleted file mode 100644 index 27d5a1f5..00000000 --- a/vendor/getrandom/src/backends/getrandom.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! Implementation using getrandom(2). -//! -//! Available since: -//! - Linux Kernel 3.17, Glibc 2.25, Musl 1.1.20 -//! - Android API level 23 (Marshmallow) -//! - NetBSD 10.0 -//! - FreeBSD 12.0 -//! - illumos since Dec 2018 -//! - DragonFly 5.7 -//! - Hurd Glibc 2.31 -//! - shim-3ds since Feb 2022 -//! -//! For these platforms, we always use the default pool and never set the -//! GRND_RANDOM flag to use the /dev/random pool. On Linux/Android/Hurd, using -//! GRND_RANDOM is not recommended. On NetBSD/FreeBSD/Dragonfly/3ds, it does -//! nothing. On illumos, the default pool is used to implement getentropy(2), -//! so we assume it is acceptable here. -use crate::Error; -use core::mem::MaybeUninit; - -pub use crate::util::{inner_u32, inner_u64}; - -#[path = "../util_libc.rs"] -mod util_libc; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - util_libc::sys_fill_exact(dest, |buf| unsafe { - libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) - }) -} diff --git a/vendor/getrandom/src/backends/hermit.rs b/vendor/getrandom/src/backends/hermit.rs deleted file mode 100644 index 34d7cdbb..00000000 --- a/vendor/getrandom/src/backends/hermit.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Implementation for Hermit -use crate::Error; -use core::mem::MaybeUninit; - -extern "C" { - fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize; - // Note that `sys_secure_rand32/64` are implemented using `sys_read_entropy`: - // https://github.com/hermit-os/kernel/blob/430da84/src/syscalls/entropy.rs#L62-L104 - // But this may change in future and can depend on compilation target, - // so to future-proof we use these "syscalls". - fn sys_secure_rand32(value: *mut u32) -> i32; - fn sys_secure_rand64(value: *mut u64) -> i32; -} - -#[inline] -pub fn inner_u32() -> Result { - let mut res = MaybeUninit::uninit(); - let ret = unsafe { sys_secure_rand32(res.as_mut_ptr()) }; - match ret { - 0 => Ok(unsafe { res.assume_init() }), - -1 => Err(Error::UNSUPPORTED), - _ => Err(Error::UNEXPECTED), - } -} - -#[inline] -pub fn inner_u64() -> Result { - let mut res = MaybeUninit::uninit(); - let ret = unsafe { sys_secure_rand64(res.as_mut_ptr()) }; - match ret { - 0 => Ok(unsafe { res.assume_init() }), - -1 => Err(Error::UNSUPPORTED), - _ => Err(Error::UNEXPECTED), - } -} - -#[inline] -pub fn fill_inner(mut dest: &mut [MaybeUninit]) -> Result<(), Error> { - while !dest.is_empty() { - let res = unsafe { sys_read_entropy(dest.as_mut_ptr().cast::(), dest.len(), 0) }; - match res { - res if res > 0 => { - let len = usize::try_from(res).map_err(|_| Error::UNEXPECTED)?; - dest = dest.get_mut(len..).ok_or(Error::UNEXPECTED)?; - } - code => { - let code = i32::try_from(code).map_err(|_| Error::UNEXPECTED)?; - return Err(Error::from_neg_error_code(code)); - } - } - } - Ok(()) -} diff --git a/vendor/getrandom/src/backends/linux_android_with_fallback.rs b/vendor/getrandom/src/backends/linux_android_with_fallback.rs deleted file mode 100644 index 2ad8f0a4..00000000 --- a/vendor/getrandom/src/backends/linux_android_with_fallback.rs +++ /dev/null @@ -1,101 +0,0 @@ -//! Implementation for Linux / Android with `/dev/urandom` fallback -use super::use_file; -use crate::Error; -use core::{ - ffi::c_void, - mem::{transmute, MaybeUninit}, - ptr::NonNull, - sync::atomic::{AtomicPtr, Ordering}, -}; -use use_file::util_libc; - -pub use crate::util::{inner_u32, inner_u64}; - -type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint) -> libc::ssize_t; - -/// Sentinel value which indicates that `libc::getrandom` either not available, -/// or not supported by kernel. -const NOT_AVAILABLE: NonNull = unsafe { NonNull::new_unchecked(usize::MAX as *mut c_void) }; - -static GETRANDOM_FN: AtomicPtr = AtomicPtr::new(core::ptr::null_mut()); - -#[cold] -#[inline(never)] -fn init() -> NonNull { - // Use static linking to `libc::getrandom` on MUSL targets and `dlsym` everywhere else - #[cfg(not(target_env = "musl"))] - let raw_ptr = { - static NAME: &[u8] = b"getrandom\0"; - let name_ptr = NAME.as_ptr().cast::(); - unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) } - }; - #[cfg(target_env = "musl")] - let raw_ptr = { - let fptr: GetRandomFn = libc::getrandom; - unsafe { transmute::(fptr) } - }; - - let res_ptr = match NonNull::new(raw_ptr) { - Some(fptr) => { - let getrandom_fn = unsafe { transmute::, GetRandomFn>(fptr) }; - let dangling_ptr = NonNull::dangling().as_ptr(); - // Check that `getrandom` syscall is supported by kernel - let res = unsafe { getrandom_fn(dangling_ptr, 0, 0) }; - if cfg!(getrandom_test_linux_fallback) { - NOT_AVAILABLE - } else if res.is_negative() { - match util_libc::last_os_error().raw_os_error() { - Some(libc::ENOSYS) => NOT_AVAILABLE, // No kernel support - // The fallback on EPERM is intentionally not done on Android since this workaround - // seems to be needed only for specific Linux-based products that aren't based - // on Android. See https://github.com/rust-random/getrandom/issues/229. - #[cfg(target_os = "linux")] - Some(libc::EPERM) => NOT_AVAILABLE, // Blocked by seccomp - _ => fptr, - } - } else { - fptr - } - } - None => NOT_AVAILABLE, - }; - - #[cfg(getrandom_test_linux_without_fallback)] - if res_ptr == NOT_AVAILABLE { - panic!("Fallback is triggered with enabled `getrandom_test_linux_without_fallback`") - } - - GETRANDOM_FN.store(res_ptr.as_ptr(), Ordering::Release); - res_ptr -} - -// Prevent inlining of the fallback implementation -#[inline(never)] -fn use_file_fallback(dest: &mut [MaybeUninit]) -> Result<(), Error> { - use_file::fill_inner(dest) -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - // Despite being only a single atomic variable, we still cannot always use - // Ordering::Relaxed, as we need to make sure a successful call to `init` - // is "ordered before" any data read through the returned pointer (which - // occurs when the function is called). Our implementation mirrors that of - // the one in libstd, meaning that the use of non-Relaxed operations is - // probably unnecessary. - let raw_ptr = GETRANDOM_FN.load(Ordering::Acquire); - let fptr = match NonNull::new(raw_ptr) { - Some(p) => p, - None => init(), - }; - - if fptr == NOT_AVAILABLE { - use_file_fallback(dest) - } else { - // note: `transmute` is currently the only way to convert a pointer into a function reference - let getrandom_fn = unsafe { transmute::, GetRandomFn>(fptr) }; - util_libc::sys_fill_exact(dest, |buf| unsafe { - getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0) - }) - } -} diff --git a/vendor/getrandom/src/backends/linux_raw.rs b/vendor/getrandom/src/backends/linux_raw.rs deleted file mode 100644 index 4a59eef0..00000000 --- a/vendor/getrandom/src/backends/linux_raw.rs +++ /dev/null @@ -1,136 +0,0 @@ -//! Implementation for Linux / Android using `asm!`-based syscalls. -use crate::{Error, MaybeUninit}; - -pub use crate::util::{inner_u32, inner_u64}; - -#[cfg(not(any(target_os = "android", target_os = "linux")))] -compile_error!("`linux_raw` backend can be enabled only for Linux/Android targets!"); - -#[allow(non_upper_case_globals)] -unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize { - let r0; - - // Based on `rustix` and `linux-raw-sys` code. - cfg_if! { - if #[cfg(target_arch = "arm")] { - const __NR_getrandom: u32 = 384; - // In thumb-mode, r7 is the frame pointer and is not permitted to be used in - // an inline asm operand, so we have to use a different register and copy it - // into r7 inside the inline asm. - // Theoretically, we could detect thumb mode in the build script, but several - // register moves are cheap enough compared to the syscall cost, so we do not - // bother with it. - core::arch::asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = const __NR_getrandom, - tmp = out(reg) _, - inlateout("r0") buf => r0, - in("r1") buflen, - in("r2") flags, - options(nostack, preserves_flags) - ); - } else if #[cfg(target_arch = "aarch64")] { - const __NR_getrandom: u32 = 278; - core::arch::asm!( - "svc 0", - in("x8") __NR_getrandom, - inlateout("x0") buf => r0, - in("x1") buflen, - in("x2") flags, - options(nostack, preserves_flags) - ); - } else if #[cfg(target_arch = "loongarch64")] { - const __NR_getrandom: u32 = 278; - core::arch::asm!( - "syscall 0", - in("$a7") __NR_getrandom, - inlateout("$a0") buf => r0, - in("$a1") buflen, - in("$a2") flags, - options(nostack, preserves_flags) - ); - } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { - const __NR_getrandom: u32 = 278; - core::arch::asm!( - "ecall", - in("a7") __NR_getrandom, - inlateout("a0") buf => r0, - in("a1") buflen, - in("a2") flags, - options(nostack, preserves_flags) - ); - } else if #[cfg(target_arch = "s390x")] { - const __NR_getrandom: u32 = 349; - core::arch::asm!( - "svc 0", - in("r1") __NR_getrandom, - inlateout("r2") buf => r0, - in("r3") buflen, - in("r4") flags, - options(nostack, preserves_flags) - ); - } else if #[cfg(target_arch = "x86")] { - const __NR_getrandom: u32 = 355; - // `int 0x80` is famously slow, but implementing vDSO is too complex - // and `sysenter`/`syscall` have their own portability issues, - // so we use the simple "legacy" way of doing syscalls. - core::arch::asm!( - "int $$0x80", - in("eax") __NR_getrandom, - in("ebx") buf, - in("ecx") buflen, - in("edx") flags, - lateout("eax") r0, - options(nostack, preserves_flags) - ); - } else if #[cfg(target_arch = "x86_64")] { - #[cfg(target_pointer_width = "64")] - const __NR_getrandom: u32 = 318; - #[cfg(target_pointer_width = "32")] - const __NR_getrandom: u32 = (1 << 30) + 318; - - core::arch::asm!( - "syscall", - in("rax") __NR_getrandom, - in("rdi") buf, - in("rsi") buflen, - in("rdx") flags, - lateout("rax") r0, - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - } else { - compile_error!("`linux_raw` backend does not support this target arch"); - } - } - - r0 -} - -#[inline] -pub fn fill_inner(mut dest: &mut [MaybeUninit]) -> Result<(), Error> { - // Value of this error code is stable across all target arches. - const EINTR: isize = -4; - - loop { - let ret = unsafe { getrandom_syscall(dest.as_mut_ptr().cast(), dest.len(), 0) }; - match usize::try_from(ret) { - Ok(0) => return Err(Error::UNEXPECTED), - Ok(len) => { - dest = dest.get_mut(len..).ok_or(Error::UNEXPECTED)?; - if dest.is_empty() { - return Ok(()); - } - } - Err(_) if ret == EINTR => continue, - Err(_) => { - let code = i32::try_from(ret).map_err(|_| Error::UNEXPECTED)?; - return Err(Error::from_neg_error_code(code)); - } - } - } -} diff --git a/vendor/getrandom/src/backends/netbsd.rs b/vendor/getrandom/src/backends/netbsd.rs deleted file mode 100644 index f228a8b1..00000000 --- a/vendor/getrandom/src/backends/netbsd.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! Implementation for NetBSD -//! -//! `getrandom(2)` was introduced in NetBSD 10. To support older versions we -//! implement our own weak linkage to it, and provide a fallback based on the -//! KERN_ARND sysctl. -use crate::Error; -use core::{ - cmp, - ffi::c_void, - mem::{self, MaybeUninit}, - ptr, - sync::atomic::{AtomicPtr, Ordering}, -}; - -pub use crate::util::{inner_u32, inner_u64}; - -#[path = "../util_libc.rs"] -mod util_libc; - -unsafe extern "C" fn polyfill_using_kern_arand( - buf: *mut c_void, - buflen: libc::size_t, - flags: libc::c_uint, -) -> libc::ssize_t { - debug_assert_eq!(flags, 0); - - const MIB_LEN: libc::c_uint = 2; - static MIB: [libc::c_int; MIB_LEN as usize] = [libc::CTL_KERN, libc::KERN_ARND]; - - // NetBSD will only return up to 256 bytes at a time, and - // older NetBSD kernels will fail on longer buffers. - let mut len = cmp::min(buflen, 256); - let ret = unsafe { libc::sysctl(MIB.as_ptr(), MIB_LEN, buf, &mut len, ptr::null(), 0) }; - - match ret { - 0 if len <= 256 => libc::ssize_t::try_from(len).expect("len is in the range of 0..=256"), - -1 => -1, - // Zero return result will be converted into `Error::UNEXPECTED` by `sys_fill_exact` - _ => 0, - } -} - -type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint) -> libc::ssize_t; - -static GETRANDOM: AtomicPtr = AtomicPtr::new(ptr::null_mut()); - -#[cold] -#[inline(never)] -fn init() -> *mut c_void { - static NAME: &[u8] = b"getrandom\0"; - let name_ptr = NAME.as_ptr().cast::(); - let mut ptr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) }; - if ptr.is_null() || cfg!(getrandom_test_netbsd_fallback) { - // Verify `polyfill_using_kern_arand` has the right signature. - const POLYFILL: GetRandomFn = polyfill_using_kern_arand; - ptr = POLYFILL as *mut c_void; - } - GETRANDOM.store(ptr, Ordering::Release); - ptr -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - // Despite being only a single atomic variable, we still cannot always use - // Ordering::Relaxed, as we need to make sure a successful call to `init` - // is "ordered before" any data read through the returned pointer (which - // occurs when the function is called). Our implementation mirrors that of - // the one in libstd, meaning that the use of non-Relaxed operations is - // probably unnecessary. - let mut fptr = GETRANDOM.load(Ordering::Acquire); - if fptr.is_null() { - fptr = init(); - } - let fptr = unsafe { mem::transmute::<*mut c_void, GetRandomFn>(fptr) }; - util_libc::sys_fill_exact(dest, |buf| unsafe { - fptr(buf.as_mut_ptr().cast::(), buf.len(), 0) - }) -} diff --git a/vendor/getrandom/src/backends/rdrand.rs b/vendor/getrandom/src/backends/rdrand.rs deleted file mode 100644 index 609fcc38..00000000 --- a/vendor/getrandom/src/backends/rdrand.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! RDRAND backend for x86(-64) targets -use crate::{util::slice_as_uninit, Error}; -use core::mem::{size_of, MaybeUninit}; - -#[path = "../lazy.rs"] -mod lazy; - -#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] -compile_error!("`rdrand` backend can be enabled only for x86 and x86-64 targets!"); - -cfg_if! { - if #[cfg(target_arch = "x86_64")] { - use core::arch::x86_64 as arch; - use arch::_rdrand64_step as rdrand_step; - type Word = u64; - } else if #[cfg(target_arch = "x86")] { - use core::arch::x86 as arch; - use arch::_rdrand32_step as rdrand_step; - type Word = u32; - } -} - -static RDRAND_GOOD: lazy::LazyBool = lazy::LazyBool::new(); - -// Recommendation from "Intel® Digital Random Number Generator (DRNG) Software -// Implementation Guide" - Section 5.2.1 and "Intel® 64 and IA-32 Architectures -// Software Developer’s Manual" - Volume 1 - Section 7.3.17.1. -const RETRY_LIMIT: usize = 10; - -#[target_feature(enable = "rdrand")] -unsafe fn rdrand() -> Option { - for _ in 0..RETRY_LIMIT { - let mut val = 0; - if rdrand_step(&mut val) == 1 { - return Some(val); - } - } - None -} - -// "rdrand" target feature requires "+rdrand" flag, see https://github.com/rust-lang/rust/issues/49653. -#[cfg(all(target_env = "sgx", not(target_feature = "rdrand")))] -compile_error!( - "SGX targets require 'rdrand' target feature. Enable by using -C target-feature=+rdrand." -); - -// Run a small self-test to make sure we aren't repeating values -// Adapted from Linux's test in arch/x86/kernel/cpu/rdrand.c -// Fails with probability < 2^(-90) on 32-bit systems -#[target_feature(enable = "rdrand")] -unsafe fn self_test() -> bool { - // On AMD, RDRAND returns 0xFF...FF on failure, count it as a collision. - let mut prev = !0; // TODO(MSRV 1.43): Move to usize::MAX - let mut fails = 0; - for _ in 0..8 { - match rdrand() { - Some(val) if val == prev => fails += 1, - Some(val) => prev = val, - None => return false, - }; - } - fails <= 2 -} - -fn is_rdrand_good() -> bool { - #[cfg(not(target_feature = "rdrand"))] - { - // SAFETY: All Rust x86 targets are new enough to have CPUID, and we - // check that leaf 1 is supported before using it. - let cpuid0 = unsafe { arch::__cpuid(0) }; - if cpuid0.eax < 1 { - return false; - } - let cpuid1 = unsafe { arch::__cpuid(1) }; - - let vendor_id = [ - cpuid0.ebx.to_le_bytes(), - cpuid0.edx.to_le_bytes(), - cpuid0.ecx.to_le_bytes(), - ]; - if vendor_id == [*b"Auth", *b"enti", *b"cAMD"] { - let mut family = (cpuid1.eax >> 8) & 0xF; - if family == 0xF { - family += (cpuid1.eax >> 20) & 0xFF; - } - // AMD CPUs families before 17h (Zen) sometimes fail to set CF when - // RDRAND fails after suspend. Don't use RDRAND on those families. - // See https://bugzilla.redhat.com/show_bug.cgi?id=1150286 - if family < 0x17 { - return false; - } - } - - const RDRAND_FLAG: u32 = 1 << 30; - if cpuid1.ecx & RDRAND_FLAG == 0 { - return false; - } - } - - // SAFETY: We have already checked that rdrand is available. - unsafe { self_test() } -} - -// TODO: make this function safe when we have feature(target_feature_11) -#[target_feature(enable = "rdrand")] -unsafe fn rdrand_exact(dest: &mut [MaybeUninit]) -> Option<()> { - // We use chunks_exact_mut instead of chunks_mut as it allows almost all - // calls to memcpy to be elided by the compiler. - let mut chunks = dest.chunks_exact_mut(size_of::()); - for chunk in chunks.by_ref() { - let src = rdrand()?.to_ne_bytes(); - chunk.copy_from_slice(slice_as_uninit(&src)); - } - - let tail = chunks.into_remainder(); - let n = tail.len(); - if n > 0 { - let src = rdrand()?.to_ne_bytes(); - tail.copy_from_slice(slice_as_uninit(&src[..n])); - } - Some(()) -} - -#[cfg(target_arch = "x86_64")] -#[target_feature(enable = "rdrand")] -unsafe fn rdrand_u32() -> Option { - rdrand().map(crate::util::truncate) -} - -#[cfg(target_arch = "x86_64")] -#[target_feature(enable = "rdrand")] -unsafe fn rdrand_u64() -> Option { - rdrand() -} - -#[cfg(target_arch = "x86")] -#[target_feature(enable = "rdrand")] -unsafe fn rdrand_u32() -> Option { - rdrand() -} - -#[cfg(target_arch = "x86")] -#[target_feature(enable = "rdrand")] -unsafe fn rdrand_u64() -> Option { - let a = rdrand()?; - let b = rdrand()?; - Some((u64::from(a) << 32) | u64::from(b)) -} - -#[inline] -pub fn inner_u32() -> Result { - if !RDRAND_GOOD.unsync_init(is_rdrand_good) { - return Err(Error::NO_RDRAND); - } - // SAFETY: After this point, we know rdrand is supported. - unsafe { rdrand_u32() }.ok_or(Error::FAILED_RDRAND) -} - -#[inline] -pub fn inner_u64() -> Result { - if !RDRAND_GOOD.unsync_init(is_rdrand_good) { - return Err(Error::NO_RDRAND); - } - // SAFETY: After this point, we know rdrand is supported. - unsafe { rdrand_u64() }.ok_or(Error::FAILED_RDRAND) -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - if !RDRAND_GOOD.unsync_init(is_rdrand_good) { - return Err(Error::NO_RDRAND); - } - // SAFETY: After this point, we know rdrand is supported. - unsafe { rdrand_exact(dest) }.ok_or(Error::FAILED_RDRAND) -} - -impl Error { - /// RDRAND instruction failed due to a hardware issue. - pub(crate) const FAILED_RDRAND: Error = Self::new_internal(10); - /// RDRAND instruction unsupported on this target. - pub(crate) const NO_RDRAND: Error = Self::new_internal(11); -} diff --git a/vendor/getrandom/src/backends/rndr.rs b/vendor/getrandom/src/backends/rndr.rs deleted file mode 100644 index eea741a2..00000000 --- a/vendor/getrandom/src/backends/rndr.rs +++ /dev/null @@ -1,145 +0,0 @@ -//! RNDR register backend for aarch64 targets -//! -//! Arm Architecture Reference Manual for A-profile architecture: -//! ARM DDI 0487K.a, ID032224, D23.2.147 RNDR, Random Number -use crate::{ - util::{slice_as_uninit, truncate}, - Error, -}; -use core::arch::asm; -use core::mem::{size_of, MaybeUninit}; - -#[cfg(not(target_arch = "aarch64"))] -compile_error!("the `rndr` backend can be enabled only for AArch64 targets!"); - -const RETRY_LIMIT: usize = 5; - -/// Read a random number from the aarch64 RNDR register -/// -/// Callers must ensure that FEAT_RNG is available on the system -/// The function assumes that the RNDR register is available -/// If it fails to read a random number, it will retry up to 5 times -/// After 5 failed reads the function will return `None` -#[target_feature(enable = "rand")] -unsafe fn rndr() -> Option { - for _ in 0..RETRY_LIMIT { - let mut x: u64; - let mut nzcv: u64; - - // AArch64 RNDR register is accessible by s3_3_c2_c4_0 - asm!( - "mrs {x}, RNDR", - "mrs {nzcv}, NZCV", - x = out(reg) x, - nzcv = out(reg) nzcv, - ); - - // If the hardware returns a genuine random number, PSTATE.NZCV is set to 0b0000 - if nzcv == 0 { - return Some(x); - } - } - - None -} - -#[target_feature(enable = "rand")] -unsafe fn rndr_fill(dest: &mut [MaybeUninit]) -> Option<()> { - let mut chunks = dest.chunks_exact_mut(size_of::()); - for chunk in chunks.by_ref() { - let src = rndr()?.to_ne_bytes(); - chunk.copy_from_slice(slice_as_uninit(&src)); - } - - let tail = chunks.into_remainder(); - let n = tail.len(); - if n > 0 { - let src = rndr()?.to_ne_bytes(); - tail.copy_from_slice(slice_as_uninit(&src[..n])); - } - Some(()) -} - -#[cfg(target_feature = "rand")] -fn is_rndr_available() -> bool { - true -} - -#[cfg(not(target_feature = "rand"))] -fn is_rndr_available() -> bool { - #[path = "../lazy.rs"] - mod lazy; - static RNDR_GOOD: lazy::LazyBool = lazy::LazyBool::new(); - - cfg_if::cfg_if! { - if #[cfg(feature = "std")] { - extern crate std; - RNDR_GOOD.unsync_init(|| std::arch::is_aarch64_feature_detected!("rand")) - } else if #[cfg(target_os = "linux")] { - /// Check whether FEAT_RNG is available on the system - /// - /// Requires the caller either be running in EL1 or be on a system supporting MRS - /// emulation. Due to the above, the implementation is currently restricted to Linux. - /// - /// Relying on runtime detection bumps minimum supported Linux kernel version to 4.11. - fn mrs_check() -> bool { - let mut id_aa64isar0: u64; - - // If FEAT_RNG is implemented, ID_AA64ISAR0_EL1.RNDR (bits 60-63) are 0b0001 - // This is okay to do from EL0 in Linux because Linux will emulate MRS as per - // https://docs.kernel.org/arch/arm64/cpu-feature-registers.html - unsafe { - asm!( - "mrs {id}, ID_AA64ISAR0_EL1", - id = out(reg) id_aa64isar0, - ); - } - - (id_aa64isar0 >> 60) & 0xf >= 1 - } - - RNDR_GOOD.unsync_init(mrs_check) - } else { - compile_error!( - "RNDR `no_std` runtime detection is currently supported only on Linux targets. \ - Either enable the `std` crate feature, or `rand` target feature at compile time." - ); - } - } -} - -#[inline] -pub fn inner_u32() -> Result { - if !is_rndr_available() { - return Err(Error::RNDR_NOT_AVAILABLE); - } - // SAFETY: after this point, we know the `rand` target feature is enabled - let res = unsafe { rndr() }; - res.map(truncate).ok_or(Error::RNDR_FAILURE) -} - -#[inline] -pub fn inner_u64() -> Result { - if !is_rndr_available() { - return Err(Error::RNDR_NOT_AVAILABLE); - } - // SAFETY: after this point, we know the `rand` target feature is enabled - let res = unsafe { rndr() }; - res.ok_or(Error::RNDR_FAILURE) -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - if !is_rndr_available() { - return Err(Error::RNDR_NOT_AVAILABLE); - } - // SAFETY: after this point, we know the `rand` target feature is enabled - unsafe { rndr_fill(dest).ok_or(Error::RNDR_FAILURE) } -} - -impl Error { - /// RNDR register read failed due to a hardware issue. - pub(crate) const RNDR_FAILURE: Error = Self::new_internal(10); - /// RNDR register is not supported on this target. - pub(crate) const RNDR_NOT_AVAILABLE: Error = Self::new_internal(11); -} diff --git a/vendor/getrandom/src/backends/solaris.rs b/vendor/getrandom/src/backends/solaris.rs deleted file mode 100644 index c27f91a5..00000000 --- a/vendor/getrandom/src/backends/solaris.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! Solaris implementation using getrandom(2). -//! -//! While getrandom(2) has been available since Solaris 11.3, it has a few -//! quirks not present on other OSes. First, on Solaris 11.3, calls will always -//! fail if bufsz > 1024. Second, it will always either fail or completely fill -//! the buffer (returning bufsz). Third, error is indicated by returning 0, -//! rather than by returning -1. Finally, "if GRND_RANDOM is not specified -//! then getrandom(2) is always a non blocking call". This _might_ imply that -//! in early-boot scenarios with low entropy, getrandom(2) will not properly -//! block. To be safe, we set GRND_RANDOM, mirroring the man page examples. -//! -//! For more information, see the man page linked in lib.rs and this blog post: -//! https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2 -//! which also explains why this crate should not use getentropy(2). -use crate::Error; -use core::{ffi::c_void, mem::MaybeUninit}; - -pub use crate::util::{inner_u32, inner_u64}; - -#[path = "../util_libc.rs"] -mod util_libc; - -const MAX_BYTES: usize = 1024; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - for chunk in dest.chunks_mut(MAX_BYTES) { - let ptr = chunk.as_mut_ptr().cast::(); - let ret = unsafe { libc::getrandom(ptr, chunk.len(), libc::GRND_RANDOM) }; - // In case the man page has a typo, we also check for negative ret. - // If getrandom(2) succeeds, it should have completely filled chunk. - match usize::try_from(ret) { - // Good. Keep going. - Ok(ret) if ret == chunk.len() => {} - // The syscall failed. - Ok(0) => return Err(util_libc::last_os_error()), - // All other cases should be impossible. - _ => return Err(Error::UNEXPECTED), - } - } - Ok(()) -} diff --git a/vendor/getrandom/src/backends/solid.rs b/vendor/getrandom/src/backends/solid.rs deleted file mode 100644 index caa773f8..00000000 --- a/vendor/getrandom/src/backends/solid.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! Implementation for SOLID -use crate::Error; -use core::mem::MaybeUninit; - -pub use crate::util::{inner_u32, inner_u64}; - -extern "C" { - pub fn SOLID_RNG_SampleRandomBytes(buffer: *mut u8, length: usize) -> i32; -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - let ret = unsafe { SOLID_RNG_SampleRandomBytes(dest.as_mut_ptr().cast::(), dest.len()) }; - if ret >= 0 { - Ok(()) - } else { - Err(Error::from_neg_error_code(ret)) - } -} diff --git a/vendor/getrandom/src/backends/use_file.rs b/vendor/getrandom/src/backends/use_file.rs deleted file mode 100644 index 7b48d433..00000000 --- a/vendor/getrandom/src/backends/use_file.rs +++ /dev/null @@ -1,234 +0,0 @@ -//! Implementations that just need to read from a file -use crate::Error; -use core::{ - ffi::c_void, - mem::MaybeUninit, - sync::atomic::{AtomicI32, Ordering}, -}; - -#[cfg(not(any(target_os = "android", target_os = "linux")))] -pub use crate::util::{inner_u32, inner_u64}; - -#[path = "../util_libc.rs"] -pub(super) mod util_libc; - -/// For all platforms, we use `/dev/urandom` rather than `/dev/random`. -/// For more information see the linked man pages in lib.rs. -/// - On Linux, "/dev/urandom is preferred and sufficient in all use cases". -/// - On Redox, only /dev/urandom is provided. -/// - On AIX, /dev/urandom will "provide cryptographically secure output". -/// - On Haiku and QNX Neutrino they are identical. -const FILE_PATH: &[u8] = b"/dev/urandom\0"; - -// File descriptor is a "nonnegative integer", so we can safely use negative sentinel values. -const FD_UNINIT: libc::c_int = -1; -const FD_ONGOING_INIT: libc::c_int = -2; - -// In theory `libc::c_int` could be something other than `i32`, but for the -// targets we currently support that use `use_file`, it is always `i32`. -// If/when we add support for a target where that isn't the case, we may -// need to use a different atomic type or make other accomodations. The -// compiler will let us know if/when that is the case, because the -// `FD.store(fd)` would fail to compile. -// -// The opening of the file, by libc/libstd/etc. may write some unknown -// state into in-process memory. (Such state may include some sanitizer -// bookkeeping, or we might be operating in a unikernal-like environment -// where all the "kernel" file descriptor bookkeeping is done in our -// process.) `get_fd_locked` stores into FD using `Ordering::Release` to -// ensure any such state is synchronized. `get_fd` loads from `FD` with -// `Ordering::Acquire` to synchronize with it. -static FD: AtomicI32 = AtomicI32::new(FD_UNINIT); - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - let mut fd = FD.load(Ordering::Acquire); - if fd == FD_UNINIT || fd == FD_ONGOING_INIT { - fd = open_or_wait()?; - } - util_libc::sys_fill_exact(dest, |buf| unsafe { - libc::read(fd, buf.as_mut_ptr().cast::(), buf.len()) - }) -} - -/// Open a file in read-only mode. -/// -/// # Panics -/// If `path` does not contain any zeros. -// TODO: Move `path` to `CStr` and use `CStr::from_bytes_until_nul` (MSRV 1.69) -// or C-string literals (MSRV 1.77) for statics -fn open_readonly(path: &[u8]) -> Result { - assert!(path.contains(&0)); - loop { - let fd = unsafe { - libc::open( - path.as_ptr().cast::(), - libc::O_RDONLY | libc::O_CLOEXEC, - ) - }; - if fd >= 0 { - return Ok(fd); - } - let err = util_libc::last_os_error(); - // We should try again if open() was interrupted. - if err.raw_os_error() != Some(libc::EINTR) { - return Err(err); - } - } -} - -#[cold] -#[inline(never)] -fn open_or_wait() -> Result { - loop { - match FD.load(Ordering::Acquire) { - FD_UNINIT => { - let res = FD.compare_exchange_weak( - FD_UNINIT, - FD_ONGOING_INIT, - Ordering::AcqRel, - Ordering::Relaxed, - ); - if res.is_ok() { - break; - } - } - FD_ONGOING_INIT => sync::wait(), - fd => return Ok(fd), - } - } - - let res = open_fd(); - let val = match res { - Ok(fd) => fd, - Err(_) => FD_UNINIT, - }; - FD.store(val, Ordering::Release); - - // On non-Linux targets `wait` is just 1 ms sleep, - // so we don't need any explicit wake up in addition - // to updating value of `FD`. - #[cfg(any(target_os = "android", target_os = "linux"))] - sync::wake(); - - res -} - -fn open_fd() -> Result { - #[cfg(any(target_os = "android", target_os = "linux"))] - sync::wait_until_rng_ready()?; - let fd = open_readonly(FILE_PATH)?; - debug_assert!(fd >= 0); - Ok(fd) -} - -#[cfg(not(any(target_os = "android", target_os = "linux")))] -mod sync { - /// Sleep 1 ms before checking `FD` again. - /// - /// On non-Linux targets the critical section only opens file, - /// which should not block, so in the unlikely contended case, - /// we can sleep-wait for the opening operation to finish. - pub(super) fn wait() { - let rqtp = libc::timespec { - tv_sec: 0, - tv_nsec: 1_000_000, - }; - let mut rmtp = libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }; - // We do not care if sleep gets interrupted, so the return value is ignored - unsafe { - libc::nanosleep(&rqtp, &mut rmtp); - } - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -mod sync { - use super::{open_readonly, util_libc::last_os_error, Error, FD, FD_ONGOING_INIT}; - - /// Wait for atomic `FD` to change value from `FD_ONGOING_INIT` to something else. - /// - /// Futex syscall with `FUTEX_WAIT` op puts the current thread to sleep - /// until futex syscall with `FUTEX_WAKE` op gets executed for `FD`. - /// - /// For more information read: https://www.man7.org/linux/man-pages/man2/futex.2.html - pub(super) fn wait() { - let op = libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG; - let timeout_ptr = core::ptr::null::(); - let ret = unsafe { libc::syscall(libc::SYS_futex, &FD, op, FD_ONGOING_INIT, timeout_ptr) }; - // FUTEX_WAIT should return either 0 or EAGAIN error - debug_assert!({ - match ret { - 0 => true, - -1 => last_os_error().raw_os_error() == Some(libc::EAGAIN), - _ => false, - } - }); - } - - /// Wake up all threads which wait for value of atomic `FD` to change. - pub(super) fn wake() { - let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG; - let ret = unsafe { libc::syscall(libc::SYS_futex, &FD, op, libc::INT_MAX) }; - debug_assert!(ret >= 0); - } - - // Polls /dev/random to make sure it is ok to read from /dev/urandom. - // - // Polling avoids draining the estimated entropy from /dev/random; - // short-lived processes reading even a single byte from /dev/random could - // be problematic if they are being executed faster than entropy is being - // collected. - // - // OTOH, reading a byte instead of polling is more compatible with - // sandboxes that disallow `poll()` but which allow reading /dev/random, - // e.g. sandboxes that assume that `poll()` is for network I/O. This way, - // fewer applications will have to insert pre-sandbox-initialization logic. - // Often (blocking) file I/O is not allowed in such early phases of an - // application for performance and/or security reasons. - // - // It is hard to write a sandbox policy to support `libc::poll()` because - // it may invoke the `poll`, `ppoll`, `ppoll_time64` (since Linux 5.1, with - // newer versions of glibc), and/or (rarely, and probably only on ancient - // systems) `select`. depending on the libc implementation (e.g. glibc vs - // musl), libc version, potentially the kernel version at runtime, and/or - // the target architecture. - // - // BoringSSL and libstd don't try to protect against insecure output from - // `/dev/urandom'; they don't open `/dev/random` at all. - // - // OpenSSL uses `libc::select()` unless the `dev/random` file descriptor - // is too large; if it is too large then it does what we do here. - // - // libsodium uses `libc::poll` similarly to this. - pub(super) fn wait_until_rng_ready() -> Result<(), Error> { - let fd = open_readonly(b"/dev/random\0")?; - let mut pfd = libc::pollfd { - fd, - events: libc::POLLIN, - revents: 0, - }; - - let res = loop { - // A negative timeout means an infinite timeout. - let res = unsafe { libc::poll(&mut pfd, 1, -1) }; - if res >= 0 { - // We only used one fd, and cannot timeout. - debug_assert_eq!(res, 1); - break Ok(()); - } - let err = last_os_error(); - // Assuming that `poll` is called correctly, - // on Linux it can return only EINTR and ENOMEM errors. - match err.raw_os_error() { - Some(libc::EINTR) => continue, - _ => break Err(err), - } - }; - unsafe { libc::close(fd) }; - res - } -} diff --git a/vendor/getrandom/src/backends/vxworks.rs b/vendor/getrandom/src/backends/vxworks.rs deleted file mode 100644 index 5f5e6773..00000000 --- a/vendor/getrandom/src/backends/vxworks.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! Implementation for VxWorks -use crate::Error; -use core::{ - cmp::Ordering::{Equal, Greater, Less}, - mem::MaybeUninit, - sync::atomic::{AtomicBool, Ordering::Relaxed}, -}; - -#[path = "../util_libc.rs"] -mod util_libc; - -pub use crate::util::{inner_u32, inner_u64}; - -static RNG_INIT: AtomicBool = AtomicBool::new(false); - -#[cold] -fn init() -> Result<(), Error> { - let ret = unsafe { libc::randSecure() }; - match ret.cmp(&0) { - Greater => RNG_INIT.store(true, Relaxed), - Equal => unsafe { - libc::usleep(10); - }, - Less => return Err(Error::VXWORKS_RAND_SECURE), - } - Ok(()) -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - while !RNG_INIT.load(Relaxed) { - init()?; - } - - // Prevent overflow of i32 - let chunk_size = usize::try_from(i32::MAX).expect("VxWorks does not support 16-bit targets"); - for chunk in dest.chunks_mut(chunk_size) { - let chunk_len: libc::c_int = chunk - .len() - .try_into() - .expect("chunk size is bounded by i32::MAX"); - let p: *mut libc::c_uchar = chunk.as_mut_ptr().cast(); - let ret = unsafe { libc::randABytes(p, chunk_len) }; - if ret != 0 { - return Err(util_libc::last_os_error()); - } - } - Ok(()) -} - -impl Error { - /// On VxWorks, call to `randSecure` failed (random number generator is not yet initialized). - pub(crate) const VXWORKS_RAND_SECURE: Error = Self::new_internal(10); -} diff --git a/vendor/getrandom/src/backends/wasi_p1.rs b/vendor/getrandom/src/backends/wasi_p1.rs deleted file mode 100644 index 25b5ca3b..00000000 --- a/vendor/getrandom/src/backends/wasi_p1.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Implementation for WASI Preview 1 -use crate::Error; -use core::mem::MaybeUninit; - -pub use crate::util::{inner_u32, inner_u64}; - -// This linking is vendored from the wasi crate: -// https://docs.rs/wasi/0.11.0+wasi-snapshot-preview1/src/wasi/lib_generated.rs.html#2344-2350 -#[link(wasm_import_module = "wasi_snapshot_preview1")] -extern "C" { - fn random_get(arg0: i32, arg1: i32) -> i32; -} - -/// WASI p1 uses `u16` for error codes in its witx definitions: -/// https://github.com/WebAssembly/WASI/blob/38454e9e/legacy/preview1/witx/typenames.witx#L34-L39 -const MAX_ERROR_CODE: i32 = u16::MAX as i32; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - // Based on the wasi code: - // https://docs.rs/wasi/0.11.0+wasi-snapshot-preview1/src/wasi/lib_generated.rs.html#2046-2062 - // Note that size of an allocated object can not be bigger than isize::MAX bytes. - // WASI 0.1 supports only 32-bit WASM, so casting length to `i32` is safe. - #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)] - let ret = unsafe { random_get(dest.as_mut_ptr() as i32, dest.len() as i32) }; - match ret { - 0 => Ok(()), - // WASI functions should return positive error codes which are smaller than `MAX_ERROR_CODE` - code if code <= MAX_ERROR_CODE => Err(Error::from_neg_error_code(-code)), - _ => Err(Error::UNEXPECTED), - } -} diff --git a/vendor/getrandom/src/backends/wasi_p2.rs b/vendor/getrandom/src/backends/wasi_p2.rs deleted file mode 100644 index 63bd2d7c..00000000 --- a/vendor/getrandom/src/backends/wasi_p2.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! Implementation for WASI Preview 2. -use crate::Error; -use core::mem::MaybeUninit; -use wasi::random::random::get_random_u64; - -#[inline] -pub fn inner_u32() -> Result { - let val = get_random_u64(); - Ok(crate::util::truncate(val)) -} - -#[inline] -pub fn inner_u64() -> Result { - Ok(get_random_u64()) -} - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - use core::ptr::copy_nonoverlapping; - use wasi::random::random::get_random_u64; - - let (prefix, chunks, suffix) = unsafe { dest.align_to_mut::>() }; - - // We use `get_random_u64` instead of `get_random_bytes` because the latter creates - // an allocation due to the Wit IDL [restrictions][0]. This should be fine since - // the main use case of `getrandom` is seed generation. - // - // [0]: https://github.com/WebAssembly/wasi-random/issues/27 - if !prefix.is_empty() { - let val = get_random_u64(); - let src = (&val as *const u64).cast(); - unsafe { - copy_nonoverlapping(src, prefix.as_mut_ptr(), prefix.len()); - } - } - - for dst in chunks { - dst.write(get_random_u64()); - } - - if !suffix.is_empty() { - let val = get_random_u64(); - let src = (&val as *const u64).cast(); - unsafe { - copy_nonoverlapping(src, suffix.as_mut_ptr(), suffix.len()); - } - } - - Ok(()) -} diff --git a/vendor/getrandom/src/backends/wasm_js.rs b/vendor/getrandom/src/backends/wasm_js.rs deleted file mode 100644 index 1320d9fc..00000000 --- a/vendor/getrandom/src/backends/wasm_js.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! Implementation for WASM based on Web and Node.js -use crate::Error; -use core::mem::MaybeUninit; - -pub use crate::util::{inner_u32, inner_u64}; - -#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))] -compile_error!("`wasm_js` backend can be enabled only for OS-less WASM targets!"); - -use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; - -// Maximum buffer size allowed in `Crypto.getRandomValuesSize` is 65536 bytes. -// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues -const MAX_BUFFER_SIZE: usize = 65536; - -#[cfg(not(target_feature = "atomics"))] -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - for chunk in dest.chunks_mut(MAX_BUFFER_SIZE) { - if get_random_values(chunk).is_err() { - return Err(Error::WEB_CRYPTO); - } - } - Ok(()) -} - -#[cfg(target_feature = "atomics")] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - // getRandomValues does not work with all types of WASM memory, - // so we initially write to browser memory to avoid exceptions. - let buf_len = usize::min(dest.len(), MAX_BUFFER_SIZE); - let buf_len_u32 = buf_len - .try_into() - .expect("buffer length is bounded by MAX_BUFFER_SIZE"); - let buf = js_sys::Uint8Array::new_with_length(buf_len_u32); - for chunk in dest.chunks_mut(buf_len) { - let chunk_len = chunk - .len() - .try_into() - .expect("chunk length is bounded by MAX_BUFFER_SIZE"); - // The chunk can be smaller than buf's length, so we call to - // JS to create a smaller view of buf without allocation. - let sub_buf = if chunk_len == buf_len_u32 { - &buf - } else { - &buf.subarray(0, chunk_len) - }; - - if get_random_values(sub_buf).is_err() { - return Err(Error::WEB_CRYPTO); - } - - sub_buf.copy_to_uninit(chunk); - } - Ok(()) -} - -#[wasm_bindgen] -extern "C" { - // Crypto.getRandomValues() - #[cfg(not(target_feature = "atomics"))] - #[wasm_bindgen(js_namespace = ["globalThis", "crypto"], js_name = getRandomValues, catch)] - fn get_random_values(buf: &mut [MaybeUninit]) -> Result<(), JsValue>; - #[cfg(target_feature = "atomics")] - #[wasm_bindgen(js_namespace = ["globalThis", "crypto"], js_name = getRandomValues, catch)] - fn get_random_values(buf: &js_sys::Uint8Array) -> Result<(), JsValue>; -} - -impl Error { - /// The environment does not support the Web Crypto API. - pub(crate) const WEB_CRYPTO: Error = Self::new_internal(10); -} diff --git a/vendor/getrandom/src/backends/windows.rs b/vendor/getrandom/src/backends/windows.rs deleted file mode 100644 index b5cd504f..00000000 --- a/vendor/getrandom/src/backends/windows.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Implementation for Windows 10 and later -//! -//! On Windows 10 and later, ProcessPrng "is the primary interface to the -//! user-mode per-processor PRNGs" and only requires bcryptprimitives.dll, -//! making it a better option than the other Windows RNG APIs: -//! - BCryptGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom -//! - Requires bcrypt.dll (which loads bcryptprimitives.dll anyway) -//! - Can cause crashes/hangs as BCrypt accesses the Windows Registry: -//! https://github.com/rust-lang/rust/issues/99341 -//! - Causes issues inside sandboxed code: -//! https://issues.chromium.org/issues/40277768 -//! - CryptGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom -//! - Deprecated and not available on UWP targets -//! - Requires advapi32.lib/advapi32.dll (in addition to bcryptprimitives.dll) -//! - Thin wrapper around ProcessPrng -//! - RtlGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom -//! - Deprecated and not available on UWP targets -//! - Requires advapi32.dll (in addition to bcryptprimitives.dll) -//! - Requires using name "SystemFunction036" -//! - Thin wrapper around ProcessPrng -//! -//! For more information see the Windows RNG Whitepaper: https://aka.ms/win10rng -use crate::Error; -use core::mem::MaybeUninit; - -pub use crate::util::{inner_u32, inner_u64}; - -// Binding to the Windows.Win32.Security.Cryptography.ProcessPrng API. As -// bcryptprimitives.dll lacks an import library, we use "raw-dylib". This -// was added in Rust 1.65 for x86_64/aarch64 and in Rust 1.71 for x86. -// We don't need MSRV 1.71, as we only use this backend on Rust 1.78 and later. -#[cfg_attr( - target_arch = "x86", - link( - name = "bcryptprimitives", - kind = "raw-dylib", - import_name_type = "undecorated" - ) -)] -#[cfg_attr( - not(target_arch = "x86"), - link(name = "bcryptprimitives", kind = "raw-dylib") -)] -extern "system" { - fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL; -} -#[allow(clippy::upper_case_acronyms)] -type BOOL = core::ffi::c_int; // MSRV 1.64, similarly OK for this backend. -const TRUE: BOOL = 1; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - let result = unsafe { ProcessPrng(dest.as_mut_ptr().cast::(), dest.len()) }; - // Since Windows 10, calls to the user-mode RNG are guaranteed to never - // fail during runtime (rare windows W); `ProcessPrng` will only ever - // return 1 (which is how windows represents TRUE). - // See the bottom of page 6 of the aforementioned Windows RNG - // whitepaper for more information. - debug_assert!(result == TRUE); - Ok(()) -} diff --git a/vendor/getrandom/src/backends/windows7.rs b/vendor/getrandom/src/backends/windows7.rs deleted file mode 100644 index 8a353a9f..00000000 --- a/vendor/getrandom/src/backends/windows7.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Legacy implementation for Windows XP and later -//! -//! For targets where we cannot use ProcessPrng (added in Windows 10), we use -//! RtlGenRandom. See windows.rs for a more detailed discussion of the Windows -//! RNG APIs (and why we don't use BCryptGenRandom). On versions prior to -//! Windows 10, this implementation is secure. On Windows 10 and later, this -//! implementation behaves identically to the windows.rs implementation, except -//! that it forces the loading of an additonal DLL (advapi32.dll). -//! -//! This implementation will not work on UWP targets (which lack advapi32.dll), -//! but such targets require Windows 10, so can use the standard implementation. -use crate::Error; -use core::{ffi::c_void, mem::MaybeUninit}; - -pub use crate::util::{inner_u32, inner_u64}; - -// Binding to the Windows.Win32.Security.Authentication.Identity.RtlGenRandom -// API. Don't use windows-targets as it doesn't support Windows 7 targets. -#[link(name = "advapi32")] -extern "system" { - #[link_name = "SystemFunction036"] - fn RtlGenRandom(randombuffer: *mut c_void, randombufferlength: u32) -> BOOLEAN; -} -#[allow(clippy::upper_case_acronyms)] -type BOOLEAN = u8; -const TRUE: BOOLEAN = 1u8; - -#[inline] -pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - // Prevent overflow of u32 - let chunk_size = usize::try_from(i32::MAX).expect("Windows does not support 16-bit targets"); - for chunk in dest.chunks_mut(chunk_size) { - let chunk_len = u32::try_from(chunk.len()).expect("chunk size is bounded by i32::MAX"); - let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr().cast::(), chunk_len) }; - if ret != TRUE { - return Err(Error::WINDOWS_RTL_GEN_RANDOM); - } - } - Ok(()) -} - -impl Error { - /// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed. - pub(crate) const WINDOWS_RTL_GEN_RANDOM: Error = Self::new_internal(10); -} -- cgit v1.2.3