@@ -23,6 +23,13 @@ unsafe fn rdrand() -> Result<[u8; WORD_SIZE], Error> {
2323 for _ in 0 ..RETRY_LIMIT {
2424 let mut el = mem:: uninitialized ( ) ;
2525 if _rdrand64_step ( & mut el) == 1 {
26+ // AMD CPUs from families 14h to 16h (pre Ryzen) will sometimes give
27+ // bogus random data. Discard these values and warn the user.
28+ // See https://github.com/systemd/systemd/issues/11810#issuecomment-489727505
29+ if cfg ! ( not( target_env = "sgx" ) ) && ( el == 0 || el == !0 ) {
30+ error ! ( "RDRAND returned suspicious value {}, CPU RNG is broken" , el) ;
31+ return Err ( Error :: UNKNOWN )
32+ }
2633 return Ok ( el. to_ne_bytes ( ) ) ;
2734 }
2835 }
@@ -36,14 +43,14 @@ compile_error!(
3643 "SGX targets require 'rdrand' target feature. Enable by using -C target-feature=+rdrnd."
3744) ;
3845
39- #[ cfg( any ( target_env = "sgx" , target_feature = "rdrand" ) ) ]
46+ #[ cfg( target_feature = "rdrand" ) ]
4047fn is_rdrand_supported ( ) -> bool {
4148 true
4249}
4350
4451// TODO use is_x86_feature_detected!("rdrand") when that works in core. See:
4552// https://github.com/rust-lang-nursery/stdsimd/issues/464
46- #[ cfg( not( any ( target_env = "sgx" , target_feature = "rdrand" ) ) ) ]
53+ #[ cfg( not( target_feature = "rdrand" ) ) ]
4754fn is_rdrand_supported ( ) -> bool {
4855 use core:: arch:: x86_64:: __cpuid;
4956 use lazy_static:: lazy_static;
0 commit comments