use crate::macros::precondition_memory_range;
cfg_if::cfg_if! {
if #[cfg(miri)] {
pub use fallback::zeroize_mem;
} else if #[cfg(feature = "nightly_core_intrinsics")] {
pub use nightly::zeroize_mem;
} else {
pub use asm_barier::zeroize_mem;
}
}
#[cfg(feature = "nightly_core_intrinsics")]
mod nightly {
use super::*;
pub unsafe fn zeroize_mem(ptr: *mut u8, len: usize) {
precondition_memory_range!(ptr, len);
unsafe {
core::intrinsics::volatile_set_memory(ptr, 0, len);
}
}
}
mod asm_barier {
use super::*;
pub unsafe fn zeroize_mem(ptr: *mut u8, len: usize) {
precondition_memory_range!(ptr, len);
unsafe { ptr.write_bytes(0, len) };
unsafe {
core::arch::asm!(
"/* {0} */",
in(reg) ptr,
options(nostack, readonly, preserves_flags),
)
};
}
}
mod fallback {
use super::*;
pub unsafe fn zeroize_mem(mut ptr: *mut u8, len: usize) {
precondition_memory_range!(ptr, len);
for _i in 0..len {
unsafe {
core::ptr::write_volatile(ptr, 0u8);
}
ptr = unsafe { ptr.add(1) };
}
}
}
#[cfg(test)]
mod tests;