diff options
Diffstat (limited to 'src/apple-other.rs')
-rw-r--r-- | src/apple-other.rs | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/apple-other.rs b/src/apple-other.rs new file mode 100644 index 0000000..167d8cf --- /dev/null +++ b/src/apple-other.rs @@ -0,0 +1,24 @@ +//! Implementation for iOS, tvOS, and watchOS where `getentropy` is unavailable. +use crate::Error; +use core::{ffi::c_void, mem::MaybeUninit}; + +// libsystem contains the libc of Darwin, and every binary ends up linked against it either way. This +// makes it a more lightweight choice compared to `Security.framework`. +extern "C" { + // This RNG uses a thread-local CSPRNG to provide data, which is seeded by the operating system's root CSPRNG. + // Its the best option after `getentropy` on modern Darwin-based platforms that also avoids the + // high startup costs and linking of Security.framework. + // + // While its just an implementation detail, `Security.framework` just calls into this anyway. + fn CCRandomGenerateBytes(bytes: *mut c_void, size: usize) -> i32; +} + +pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { + let ret = unsafe { CCRandomGenerateBytes(dest.as_mut_ptr() as *mut c_void, dest.len()) }; + // kCCSuccess (from CommonCryptoError.h) is always zero. + if ret != 0 { + Err(Error::IOS_SEC_RANDOM) + } else { + Ok(()) + } +} |