Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for fuchsia's CPRNG source #765

Merged
merged 2 commits into from
Feb 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ pub(crate) fn features() -> Features {
{
arm::linux_setup();
}

#[cfg(all(
target_os = "fuchsia",
any(target_arch = "aarch64")
))]
{
arm::fuchsia_setup();
}
});
}

Expand Down Expand Up @@ -110,6 +118,47 @@ pub(crate) mod arm {
}
}

#[cfg(all(
target_os = "fuchsia",
any(target_arch = "aarch64")
))]
pub fn fuchsia_setup() {
type zx_status_t = i32;

#[link(name = "zircon")]
extern "C" {
fn zx_system_get_features(kind: u32, features: *mut u32) -> zx_status_t;
}

const ZX_OK: i32 = 0;
const ZX_FEATURE_KIND_CPU: u32 = 0;
const ZX_ARM64_FEATURE_ISA_ASIMD: u32 = 1 << 2;
const ZX_ARM64_FEATURE_ISA_AES: u32 = 1 << 3;
const ZX_ARM64_FEATURE_ISA_PMULL: u32 = 1 << 4;
const ZX_ARM64_FEATURE_ISA_SHA2: u32 = 1 << 6;

let mut caps = 0;
let rc = unsafe { zx_system_get_features(ZX_FEATURE_KIND_CPU, &mut caps) };

// OpenSSL and BoringSSL don't enable any other features if NEON isn't
// available.
if rc == ZX_OK && (caps & ZX_ARM64_FEATURE_ISA_ASIMD == ZX_ARM64_FEATURE_ISA_ASIMD) {
let mut features = NEON.mask;

if caps & ZX_ARM64_FEATURE_ISA_AES == ZX_ARM64_FEATURE_ISA_AES {
features |= AES.mask;
}
if caps & ZX_ARM64_FEATURE_ISA_PMULL == ZX_ARM64_FEATURE_ISA_PMULL {
features |= PMULL.mask;
}
if caps & ZX_ARM64_FEATURE_ISA_SHA2 == ZX_ARM64_FEATURE_ISA_SHA2 {
features |= 1 << 4;
}

unsafe { GFp_armcap_P = features };
}
}

pub(crate) struct Feature {
#[cfg_attr(
any(
Expand All @@ -133,7 +182,7 @@ pub(crate) mod arm {
}

#[cfg(all(
any(target_os = "android", target_os = "linux"),
any(target_os = "android", target_os = "linux", target_os = "fuchsia"),
any(target_arch = "arm", target_arch = "aarch64")
))]
{
Expand Down Expand Up @@ -167,7 +216,7 @@ pub(crate) mod arm {
};

#[cfg(all(
any(target_os = "android", target_os = "linux"),
any(target_os = "android", target_os = "linux", target_os = "fuchsia"),
any(target_arch = "arm", target_arch = "aarch64")
))]
extern "C" {
Expand Down
30 changes: 28 additions & 2 deletions src/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,13 @@ impl sealed::Sealed for SystemRandom {}

#[cfg(all(
feature = "use_heap",
not(any(target_os = "linux", target_os = "macos", target_os = "ios", windows))
not(any(
target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "fuchsia",
windows
))
))]
use self::urandom::fill as fill_impl;

Expand All @@ -110,6 +116,10 @@ use self::sysrand_or_urandom::fill as fill_impl;

#[cfg(any(target_os = "macos", target_os = "ios"))]
use self::darwin::fill as fill_impl;

#[cfg(any(target_os = "fuchsia"))]
use self::fuchsia::fill as fill_impl;

use crate::sealed;

#[cfg(target_os = "linux")]
Expand Down Expand Up @@ -188,7 +198,8 @@ mod sysrand {
feature = "use_heap",
any(target_os = "redox", unix),
not(any(target_os = "macos", target_os = "ios")),
not(all(target_os = "linux", not(feature = "dev_urandom_fallback")))
not(all(target_os = "linux", not(feature = "dev_urandom_fallback"))),
not(any(target_os = "fuchsia")),
))]
mod urandom {
use crate::error;
Expand Down Expand Up @@ -279,6 +290,21 @@ mod darwin {
}
}

#[cfg(any(target_os = "fuchsia"))]
mod fuchsia {
use crate::error;

pub fn fill(dest: &mut [u8]) -> Result<(), error::Unspecified> {
unsafe { zx_cprng_draw(dest.as_mut_ptr(), dest.len()); }
Ok(())
}

#[link(name = "zircon")]
extern "C" {
fn zx_cprng_draw(buffer: *mut u8, length: usize);
}
}

#[cfg(test)]
mod tests {
use crate::rand::{self, SecureRandom};
Expand Down