From cbc44ee350dd9c9bb4ba71646ddf263fa47668f3 Mon Sep 17 00:00:00 2001 From: Joseph Richey Date: Sat, 29 Jun 2019 20:32:01 -0700 Subject: [PATCH] Alternative way to detect AMD bug (#48) --- src/rdrand.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/rdrand.rs b/src/rdrand.rs index cdb2183..b9be853 100644 --- a/src/rdrand.rs +++ b/src/rdrand.rs @@ -23,14 +23,16 @@ unsafe fn rdrand() -> Result<[u8; WORD_SIZE], Error> { for _ in 0..RETRY_LIMIT { let mut el = mem::uninitialized(); if _rdrand64_step(&mut el) == 1 { - // AMD CPUs from families 14h to 16h (pre Ryzen) will sometimes give - // bogus random data. Discard these values and warn the user. + // AMD CPUs from families 14h to 16h (pre Ryzen) sometimes fail to + // set CF on bogus random data, so we check these values explictly. // See https://github.com/systemd/systemd/issues/11810#issuecomment-489727505 - if cfg!(not(target_env = "sgx")) && (el == 0 || el == !0) { - error!("RDRAND returned suspicious value {}, CPU RNG is broken", el); - return Err(Error::UNKNOWN); + // We perform this check regardless of target to guard against + // any implementation that incorrectly fails to set CF. + if el != 0 && el != !0 { + return Ok(el.to_ne_bytes()); } - return Ok(el.to_ne_bytes()); + error!("RDRAND returned {:X}, CPU RNG may be broken", el); + // Keep looping in case this was a false positive. } } error!("RDRAND failed, CPU issue likely");