From 5f7aadf0ea90c202b41a911447b869444d6b56dc Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Wed, 8 Feb 2023 14:37:21 -0800 Subject: [PATCH] Make rdrand_exact #[target_feature(enable = "rdrand")] Signed-off-by: Joe Richey --- src/rdrand.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/rdrand.rs b/src/rdrand.rs index 64ae38a..69f6a5d 100644 --- a/src/rdrand.rs +++ b/src/rdrand.rs @@ -105,24 +105,25 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { if !RDRAND_GOOD.unsync_init(is_rdrand_good) { return Err(Error::NO_RDRAND); } - rdrand_exact(dest).ok_or(Error::FAILED_RDRAND) + // SAFETY: After this point, we know rdrand is supported. + unsafe { rdrand_exact(dest) }.ok_or(Error::FAILED_RDRAND) } -fn rdrand_exact(dest: &mut [MaybeUninit]) -> Option<()> { +// 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() { - // SAFETY: After this point, we know rdrand is supported, so calling - // rdrand is not undefined behavior. - let src = unsafe { rdrand() }?.to_ne_bytes(); + 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 = unsafe { rdrand() }?.to_ne_bytes(); + let src = rdrand()?.to_ne_bytes(); tail.copy_from_slice(slice_as_uninit(&src[..n])); } Some(())