#[allow(warnings)]
#[cfg(feature = "sys_random")]
pub mod sys_random {
#[cfg(target_os = "linux")]
use libc::getrandom;
use std::io;
#[cfg(target_os = "windows")]
pub fn get_system_random_bytes(buffer: &mut [u8]) -> io::Result<()> {
use windows::{
core::Error,
Win32::Security::Cryptography::{
CryptAcquireContextA, CryptGenRandom, CryptReleaseContext, CRYPT_VERIFYCONTEXT,
PROV_RSA_FULL,
},
};
let mut hprov = 0;
unsafe {
let result = CryptAcquireContextA(
&mut hprov,
None, None, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT,
);
if !result.as_bool() {
return Err(Error::from_win32().into());
}
}
let result = unsafe { CryptGenRandom(hprov, buffer) };
unsafe {
CryptReleaseContext(hprov, 0);
}
if !result.as_bool() {
return Err(Error::from_win32().into());
}
Ok(())
}
#[cfg(target_os = "linux")]
pub fn get_system_random_bytes(buffer: &mut [u8]) -> io::Result<()> {
unsafe {
let ret = getrandom(buffer.as_mut_ptr() as *mut libc::c_void, buffer.len(), 0);
if ret == -1 {
return Err(io::Error::last_os_error());
}
}
Ok(())
}
#[cfg(target_os = "windows")]
pub fn uuid() -> String {
let mut bytes = [0u8; 16];
get_system_random_bytes(&mut bytes).unwrap();
format!(
"{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
bytes[0], bytes[1], bytes[2], bytes[3],
bytes[4], bytes[5],
bytes[6], (bytes[7] & 0x0F) | 0x40, (bytes[8] & 0x3F) | 0x80, bytes[9],
bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]
)
}
#[cfg(target_os = "linux")]
pub fn uuid() -> String {
let mut bytes = [0u8; 16];
get_system_random_bytes(&mut bytes).unwrap();
format!(
"{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
bytes[0], bytes[1], bytes[2], bytes[3],
bytes[4], bytes[5],
bytes[6], (bytes[7] & 0x0F) | 0x40, (bytes[8] & 0x3F) | 0x80, bytes[9],
bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_system_random_bytes() {
let mut buffer = [0u8; 16];
assert!(get_system_random_bytes(&mut buffer).is_ok());
}
}
}
#[cfg(feature = "sys_random")]
pub use sys_random::*;