8
8
9
9
//! Implementation for the Solaris family
10
10
//!
11
- //! Read from `/dev/random`, with chunks of limited size (256 bytes).
12
11
//! `/dev/random` uses the Hash_DRBG with SHA512 algorithm from NIST SP 800-90A.
13
12
//! `/dev/urandom` uses the FIPS 186-2 algorithm, which is considered less
14
- //! secure. We choose to read from `/dev/random`.
13
+ //! secure. We choose to read from `/dev/random` (and use GRND_RANDOM) .
15
14
//!
16
- //! Since Solaris 11.3 and mid-2015 illumos, the ` getrandom` syscall is available .
15
+ //! Solaris 11.3 and late-2018 illumos added the getrandom(2) libc function .
17
16
//! To make sure we can compile on both Solaris and its derivatives, as well as
18
17
//! function, we check for the existence of getrandom(2) in libc by calling
19
18
//! libc::dlsym.
@@ -24,21 +23,23 @@ use crate::{
24
23
} ;
25
24
use core:: mem:: { self , MaybeUninit } ;
26
25
27
- #[ cfg( target_os = "illumos" ) ]
28
- type GetRandomFn = unsafe extern "C" fn ( * mut u8 , libc:: size_t , libc:: c_uint ) -> libc:: ssize_t ;
29
- #[ cfg( target_os = "solaris" ) ]
30
- type GetRandomFn = unsafe extern "C" fn ( * mut u8 , libc:: size_t , libc:: c_uint ) -> libc:: c_int ;
26
+ static GETRANDOM : Weak = unsafe { Weak :: new ( "getrandom\0 " ) } ;
27
+ type GetRandomFn =
28
+ unsafe extern "C" fn ( * mut libc:: c_void , libc:: size_t , libc:: c_uint ) -> libc:: ssize_t ;
31
29
32
30
pub fn getrandom_inner ( dest : & mut [ MaybeUninit < u8 > ] ) -> Result < ( ) , Error > {
33
- // getrandom(2) was introduced in Solaris 11.3 for Illumos in 2015.
34
- static GETRANDOM : Weak = unsafe { Weak :: new ( "getrandom\0 " ) } ;
35
31
if let Some ( fptr) = GETRANDOM . ptr ( ) {
36
32
let func: GetRandomFn = unsafe { mem:: transmute ( fptr) } ;
37
33
// 256 bytes is the lowest common denominator across all the Solaris
38
34
// derived platforms for atomically obtaining random data.
39
35
for chunk in dest. chunks_mut ( 256 ) {
40
36
sys_fill_exact ( chunk, |buf| unsafe {
41
- func ( buf. as_mut_ptr ( ) as * mut u8 , buf. len ( ) , 0 ) as libc:: ssize_t
37
+ // A cast is needed for the flags as libc uses the wrong type.
38
+ func (
39
+ buf. as_mut_ptr ( ) as * mut libc:: c_void ,
40
+ buf. len ( ) ,
41
+ libc:: GRND_RANDOM as libc:: c_uint ,
42
+ )
42
43
} ) ?
43
44
}
44
45
Ok ( ( ) )
0 commit comments