security/random/mod.rs
1//! Cryptographically secure random bytes from `SecRandomCopyBytes`.
2
3use crate::error::{Result, SecurityError};
4use crate::ffi;
5use crate::private::sec_error_message;
6
7/// Stateless wrapper around Apple's default CSPRNG.
8pub struct SecureRandom;
9
10impl SecureRandom {
11 /// Fill an existing buffer with cryptographically secure random bytes.
12 ///
13 /// # Errors
14 ///
15 /// Returns an error if Security.framework rejects the random-byte request.
16 pub fn fill(buffer: &mut [u8]) -> Result<()> {
17 if buffer.is_empty() {
18 return Ok(());
19 }
20 let status = unsafe {
21 ffi::SecRandomCopyBytes(
22 ffi::kSecRandomDefault,
23 buffer.len(),
24 buffer.as_mut_ptr().cast(),
25 )
26 };
27 if status == ffi::status::SUCCESS {
28 Ok(())
29 } else {
30 Err(SecurityError::from_status(
31 "SecRandomCopyBytes",
32 status,
33 sec_error_message(status),
34 ))
35 }
36 }
37
38 /// Allocate a new `Vec<u8>` and fill it with cryptographically secure random bytes.
39 ///
40 /// # Errors
41 ///
42 /// Returns an error if Security.framework rejects the random-byte request.
43 pub fn bytes(length: usize) -> Result<Vec<u8>> {
44 let mut buffer = vec![0_u8; length];
45 Self::fill(&mut buffer)?;
46 Ok(buffer)
47 }
48}