From ae61549dda2364deb2c4a5bd973602e0c6266d4e Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 24 Feb 2016 17:01:03 +0000 Subject: [PATCH] Fix filling buffers 4 GiB or larger with OsRng::fill_bytes on Windows CryptGenRandom takes a DWORD (u32) for the length so it only supports writing u32::MAX bytes at a time. Casting the length from a usize caused truncation meaning the whole buffer was not always filled. --- src/os.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/os.rs b/src/os.rs index d804808f7a2..fc36012b827 100644 --- a/src/os.rs +++ b/src/os.rs @@ -311,13 +311,17 @@ mod imp { unsafe { mem::transmute(v) } } fn fill_bytes(&mut self, v: &mut [u8]) { - let ret = unsafe { - CryptGenRandom(self.hcryptprov, v.len() as DWORD, - v.as_mut_ptr()) - }; - if ret == 0 { - panic!("couldn't generate random bytes: {}", - io::Error::last_os_error()); + // CryptGenRandom takes a DWORD (u32) for the length so we need to + // split up the buffer. + for slice in v.chunks_mut(::max_value() as usize) { + let ret = unsafe { + CryptGenRandom(self.hcryptprov, slice.len() as DWORD, + slice.as_mut_ptr()) + }; + if ret == 0 { + panic!("couldn't generate random bytes: {}", + io::Error::last_os_error()); + } } } }