Skip to content

Commit b2bca0f

Browse files
authored
rdrand: Avoid assuming usize is the native word size. (#442)
`x86_64-unknown-linux-gnux32` has target_pointer_width = "32", so usize is 32-bits. In this case, we were throwing away half of each RDRAND result and doing twice as many RDRAND invocations as necessary. This wasn't noticed because `as` silently does a lossy conversion.
1 parent f8899bd commit b2bca0f

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

src/rdrand.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ cfg_if! {
66
if #[cfg(target_arch = "x86_64")] {
77
use core::arch::x86_64 as arch;
88
use arch::_rdrand64_step as rdrand_step;
9+
type Word = u64;
910
} else if #[cfg(target_arch = "x86")] {
1011
use core::arch::x86 as arch;
1112
use arch::_rdrand32_step as rdrand_step;
13+
type Word = u32;
1214
}
1315
}
1416

@@ -18,11 +20,11 @@ cfg_if! {
1820
const RETRY_LIMIT: usize = 10;
1921

2022
#[target_feature(enable = "rdrand")]
21-
unsafe fn rdrand() -> Option<usize> {
23+
unsafe fn rdrand() -> Option<Word> {
2224
for _ in 0..RETRY_LIMIT {
2325
let mut val = 0;
2426
if rdrand_step(&mut val) == 1 {
25-
return Some(val as usize);
27+
return Some(val);
2628
}
2729
}
2830
None
@@ -105,7 +107,7 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
105107
unsafe fn rdrand_exact(dest: &mut [MaybeUninit<u8>]) -> Option<()> {
106108
// We use chunks_exact_mut instead of chunks_mut as it allows almost all
107109
// calls to memcpy to be elided by the compiler.
108-
let mut chunks = dest.chunks_exact_mut(size_of::<usize>());
110+
let mut chunks = dest.chunks_exact_mut(size_of::<Word>());
109111
for chunk in chunks.by_ref() {
110112
let src = rdrand()?.to_ne_bytes();
111113
chunk.copy_from_slice(slice_as_uninit(&src));

0 commit comments

Comments
 (0)