@@ -28,10 +28,19 @@ static RDRAND_GOOD: lazy::LazyBool = lazy::LazyBool::new();
2828const RETRY_LIMIT : usize = 10 ;
2929
3030#[ target_feature( enable = "rdrand" ) ]
31- #[ cfg_attr( target_os = "uefi" , allow( unused_unsafe) ) ] // HACK: Rust lint gives false positive on uefi
32- unsafe fn rdrand ( ) -> Option < Word > {
31+ fn rdrand ( ) -> Option < Word > {
3332 for _ in 0 ..RETRY_LIMIT {
3433 let mut val = 0 ;
34+ // SAFETY: this function is safe to call from a `[target_feature(enable
35+ // = "rdrand")]` context (it itself is annotated with
36+ // `target_feature(enable = "rdrand")`) but was marked unsafe until
37+ // https://github.com/rust-lang/stdarch/commit/59864cd which was pulled
38+ // in via https://github.com/rust-lang/rust/commit/f2eb88b which is
39+ // expected to be included in 1.93.0. Since our MSRV is 1.85, we need to
40+ // use unsafe here and suppress the lint.
41+ //
42+ // TODO(MSRV 1.93): remove allow(unused_unsafe) and the unsafe block.
43+ #[ allow( unused_unsafe) ]
3544 if unsafe { rdrand_step ( & mut val) } == 1 {
3645 return Some ( val) ;
3746 }
@@ -49,12 +58,12 @@ compile_error!(
4958// Adapted from Linux's test in arch/x86/kernel/cpu/rdrand.c
5059// Fails with probability < 2^(-90) on 32-bit systems
5160#[ target_feature( enable = "rdrand" ) ]
52- unsafe fn self_test ( ) -> bool {
61+ fn self_test ( ) -> bool {
5362 // On AMD, RDRAND returns 0xFF...FF on failure, count it as a collision.
5463 let mut prev = Word :: MAX ;
5564 let mut fails = 0 ;
5665 for _ in 0 ..8 {
57- match unsafe { rdrand ( ) } {
66+ match rdrand ( ) {
5867 Some ( val) if val == prev => fails += 1 ,
5968 Some ( val) => prev = val,
6069 None => return false ,
@@ -102,49 +111,48 @@ fn is_rdrand_good() -> bool {
102111 unsafe { self_test ( ) }
103112}
104113
105- // TODO: make this function safe when we have feature(target_feature_11)
106114#[ target_feature( enable = "rdrand" ) ]
107- unsafe fn rdrand_exact ( dest : & mut [ MaybeUninit < u8 > ] ) -> Option < ( ) > {
115+ fn rdrand_exact ( dest : & mut [ MaybeUninit < u8 > ] ) -> Option < ( ) > {
108116 // We use chunks_exact_mut instead of chunks_mut as it allows almost all
109117 // calls to memcpy to be elided by the compiler.
110118 let mut chunks = dest. chunks_exact_mut ( size_of :: < Word > ( ) ) ;
111119 for chunk in chunks. by_ref ( ) {
112- let src = unsafe { rdrand ( ) } ?. to_ne_bytes ( ) ;
120+ let src = rdrand ( ) ?. to_ne_bytes ( ) ;
113121 chunk. copy_from_slice ( slice_as_uninit ( & src) ) ;
114122 }
115123
116124 let tail = chunks. into_remainder ( ) ;
117125 let n = tail. len ( ) ;
118126 if n > 0 {
119- let src = unsafe { rdrand ( ) } ?. to_ne_bytes ( ) ;
127+ let src = rdrand ( ) ?. to_ne_bytes ( ) ;
120128 tail. copy_from_slice ( slice_as_uninit ( & src[ ..n] ) ) ;
121129 }
122130 Some ( ( ) )
123131}
124132
125133#[ cfg( target_arch = "x86_64" ) ]
126134#[ target_feature( enable = "rdrand" ) ]
127- unsafe fn rdrand_u32 ( ) -> Option < u32 > {
128- unsafe { rdrand ( ) } . map ( crate :: util:: truncate)
135+ fn rdrand_u32 ( ) -> Option < u32 > {
136+ rdrand ( ) . map ( crate :: util:: truncate)
129137}
130138
131139#[ cfg( target_arch = "x86_64" ) ]
132140#[ target_feature( enable = "rdrand" ) ]
133- unsafe fn rdrand_u64 ( ) -> Option < u64 > {
134- unsafe { rdrand ( ) }
141+ fn rdrand_u64 ( ) -> Option < u64 > {
142+ rdrand ( )
135143}
136144
137145#[ cfg( target_arch = "x86" ) ]
138146#[ target_feature( enable = "rdrand" ) ]
139- unsafe fn rdrand_u32 ( ) -> Option < u32 > {
140- unsafe { rdrand ( ) }
147+ fn rdrand_u32 ( ) -> Option < u32 > {
148+ rdrand ( )
141149}
142150
143151#[ cfg( target_arch = "x86" ) ]
144152#[ target_feature( enable = "rdrand" ) ]
145- unsafe fn rdrand_u64 ( ) -> Option < u64 > {
146- let a = unsafe { rdrand ( ) } ?;
147- let b = unsafe { rdrand ( ) } ?;
153+ fn rdrand_u64 ( ) -> Option < u64 > {
154+ let a = rdrand ( ) ?;
155+ let b = rdrand ( ) ?;
148156 Some ( ( u64:: from ( a) << 32 ) | u64:: from ( b) )
149157}
150158
0 commit comments