From 152c77391db5283040fc492c110ecc1aa3a23631 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Fri, 28 Jun 2019 18:46:29 -0700 Subject: [PATCH 1/2] Alternative way to detect AMD bug --- src/rdrand.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/rdrand.rs b/src/rdrand.rs index cdb2183eb..49722d284 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 + // future implementations that incorrectly 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"); From 7e5a3dac157aeaf88b8ef37c3849d630b68809d1 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Sat, 29 Jun 2019 15:24:37 -0700 Subject: [PATCH 2/2] Typo --- src/rdrand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rdrand.rs b/src/rdrand.rs index 49722d284..b9be85358 100644 --- a/src/rdrand.rs +++ b/src/rdrand.rs @@ -27,7 +27,7 @@ unsafe fn rdrand() -> Result<[u8; WORD_SIZE], Error> { // set CF on bogus random data, so we check these values explictly. // See https://github.com/systemd/systemd/issues/11810#issuecomment-489727505 // We perform this check regardless of target to guard against - // future implementations that incorrectly set CF. + // any implementation that incorrectly fails to set CF. if el != 0 && el != !0 { return Ok(el.to_ne_bytes()); }