Skip to content

Commit

Permalink
rdrand: Add 32-bit x86 support
Browse files Browse the repository at this point in the history
Also add tests for 32-bit x86
  • Loading branch information
josephlr committed Feb 20, 2020
1 parent 52e7e9f commit 2e39004
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 11 deletions.
16 changes: 15 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
language: rust
os: linux

# Targets that we just build (rather than run and test)
env:
global:
# All of the supported x86 Linux targets
- LINUX_TARGETS="x86_64-unknown-linux-gnu x86_64-unknown-linux-musl i686-unknown-linux-gnu i686-unknown-linux-musl"
# Targets that we just build (rather than run and test)
- STD_TARGETS="x86_64-sun-solaris x86_64-unknown-cloudabi x86_64-unknown-freebsd x86_64-fuchsia x86_64-unknown-netbsd x86_64-unknown-redox x86_64-fortanix-unknown-sgx"
- NO_STD_TARGETS="x86_64-unknown-uefi x86_64-unknown-hermit x86_64-unknown-l4re-uclibc x86_64-uwp-windows-gnu x86_64-wrs-vxworks"

Expand Down Expand Up @@ -112,6 +114,18 @@ jobs:
name: "OSX, nightly, docs"
os: osx

- name: "cross-platform tests"
rust: nightly
addons:
apt:
packages:
- gcc-multilib
install:
- echo $LINUX_TARGETS | xargs -n1 rustup target add
script:
# We run tests for all supported x86 Linux targets
- echo $LINUX_TARGETS | xargs -t -n1 cargo test --target

- name: "cross-platform build only"
rust: nightly
install:
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ cfg_if! {
#[path = "rdrand.rs"] mod imp;
} else if #[cfg(feature = "custom")] {
use custom as imp;
} else if #[cfg(all(feature = "cpu", target_arch = "x86_64"))] {
} else if #[cfg(all(feature = "cpu",
any(target_arch = "x86_64", target_arch = "x86")))] {
#[path = "rdrand.rs"] mod imp;
} else {
compile_error!("\
Expand Down
25 changes: 17 additions & 8 deletions src/rdrand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@
// except according to those terms.

//! Implementation for SGX using RDRAND instruction
#[cfg(not(target_feature = "rdrand"))]
use crate::util::LazyBool;
use crate::Error;
use core::arch::x86_64::_rdrand64_step;
use core::mem;

cfg_if! {
if #[cfg(target_arch = "x86_64")] {
use core::arch::x86_64 as arch;
use arch::_rdrand64_step as rdrand_step;
} else if #[cfg(target_arch = "x86")] {
use core::arch::x86 as arch;
use arch::_rdrand32_step as rdrand_step;
}
}

// Recommendation from "Intel® Digital Random Number Generator (DRNG) Software
// Implementation Guide" - Section 5.2.1 and "Intel® 64 and IA-32 Architectures
// Software Developer’s Manual" - Volume 1 - Section 7.3.17.1.
const RETRY_LIMIT: usize = 10;
const WORD_SIZE: usize = mem::size_of::<u64>();
const WORD_SIZE: usize = mem::size_of::<usize>();

#[target_feature(enable = "rdrand")]
unsafe fn rdrand() -> Result<[u8; WORD_SIZE], Error> {
for _ in 0..RETRY_LIMIT {
let mut el = mem::zeroed();
if _rdrand64_step(&mut el) == 1 {
if rdrand_step(&mut el) == 1 {
// AMD CPUs from families 14h to 16h (pre Ryzen) sometimes fail to
// set CF on bogus random data, so we check these values explicitly.
// See https://github.com/systemd/systemd/issues/11810#issuecomment-489727505
Expand Down Expand Up @@ -53,11 +60,13 @@ fn is_rdrand_supported() -> bool {
// https://github.com/rust-lang-nursery/stdsimd/issues/464
#[cfg(not(target_feature = "rdrand"))]
fn is_rdrand_supported() -> bool {
use core::arch::x86_64::__cpuid;
// SAFETY: All x86_64 CPUs support CPUID leaf 1
use crate::util::LazyBool;

// SAFETY: All Rust x86 targets are new enough to have CPUID, and if CPUID
// is supported, CPUID leaf 1 is always supported.
const FLAG: u32 = 1 << 30;
static HAS_RDRAND: LazyBool = LazyBool::new();
HAS_RDRAND.unsync_init(|| unsafe { (__cpuid(1).ecx & FLAG) != 0 })
HAS_RDRAND.unsync_init(|| unsafe { (arch::__cpuid(1).ecx & FLAG) != 0 })
}

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
Expand Down
2 changes: 1 addition & 1 deletion src/test_cpu.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// We only test the CPU-based RNG source on supported architectures.
#![cfg(target_arch = "x86_64")]
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]

#[path = "rdrand.rs"]
mod rdrand;
Expand Down

0 comments on commit 2e39004

Please sign in to comment.