diff --git a/Cargo.toml b/Cargo.toml index 92c460f1e..0f5a7dd1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,12 @@ exclude = ["/tests"] [lib] crate-type = ["staticlib", "cdylib", "lib"] +[build-dependencies] +libcrux_platform = { version = "=0.0.1", path = "sys/platform" } + [dependencies] hacl = { version = "=0.0.2", features = ["hazmat"] } +libcrux_platform = { version = "=0.0.1", path = "sys/platform" } rand = { version = "0.8" } log = "0.4" diff --git a/build.rs b/build.rs index 5bffbe100..2e8a0bcfb 100644 --- a/build.rs +++ b/build.rs @@ -1,57 +1,9 @@ -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -fn simd128_support() -> bool { - std::arch::is_x86_feature_detected!("sse2") - && std::arch::is_x86_feature_detected!("sse3") - && std::arch::is_x86_feature_detected!("sse4.1") - && std::arch::is_x86_feature_detected!("avx") -} - -#[cfg(target_arch = "aarch64")] -fn simd128_support() -> bool { - true -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")))] -fn simd128_support() -> bool { - // XXX: Check for z14 or z15 - false -} - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -fn simd256_support() -> bool { - std::arch::is_x86_feature_detected!("avx2") -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn simd256_support() -> bool { - // XXX: Check for z14 or z15 - false -} - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -fn bmi2_adx_support() -> bool { - std::arch::is_x86_feature_detected!("bmi2") && std::arch::is_x86_feature_detected!("adx") -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn bmi2_adx_support() -> bool { - false -} - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -fn aes_ni_support() -> bool { - // FIXME: std::arch::is_x86_feature_detected!("movbe") is not supported yet - // we assume here that it is supported :| - std::arch::is_x86_feature_detected!("avx") - && std::arch::is_x86_feature_detected!("sse") - && std::arch::is_x86_feature_detected!("aes") - && std::arch::is_x86_feature_detected!("pclmulqdq") -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn aes_ni_support() -> bool { - false -} +use libcrux_platform::{ + simd128_support, + simd256_support, + bmi2_adx_support, + aes_ni_support +}; fn main() { if simd128_support() { diff --git a/src/aead.rs b/src/aead.rs index 3adaeb638..068c988a2 100644 --- a/src/aead.rs +++ b/src/aead.rs @@ -15,7 +15,7 @@ use hacl::hazmat; use hacl::hazmat::chacha20_poly1305; -use crate::hw_detection::{aes_ni_support, simd128_support, simd256_support}; +use libcrux_platform::{aes_ni_support, simd128_support, simd256_support}; /// The AEAD Errors. #[derive(Debug, PartialEq, Eq, Clone, Copy)] diff --git a/src/digest.rs b/src/digest.rs index 067bda99b..e7203cda9 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -22,7 +22,7 @@ use hacl::hazmat::{ sha3, }; -use crate::hw_detection::{simd128_support, simd256_support}; +use libcrux_platform::{simd128_support, simd256_support}; #[derive(Debug)] pub enum Error { diff --git a/src/ecdh.rs b/src/ecdh.rs index 64d9c39f6..3f67dc75f 100644 --- a/src/ecdh.rs +++ b/src/ecdh.rs @@ -50,12 +50,12 @@ pub(crate) mod x25519 { #[cfg(all(bmi2, adx, target_arch = "x86_64"))] pub(super) fn derive(p: &[u8; 32], s: &[u8; 32]) -> Result<[u8; 32], Error> { - use crate::hw_detection::x25519_cpu_support; + use libcrux_platform::x25519_support; use hacl::hazmat::curve25519; // On x64 we use vale if available or hacl as fallback. // Jasmin exists but is not verified yet. - if x25519_cpu_support() { + if x25519_support() { curve25519::vale::ecdh(s, p).map_err(|e| Error::Custom(format!("HACL Error {:?}", e))) // XXX: not verified yet // crate::jasmin::x25519::mulx::derive(s, p) diff --git a/src/hacl/chacha20poly1305.rs b/src/hacl/chacha20poly1305.rs index 1b38bc25a..26f4289fe 100644 --- a/src/hacl/chacha20poly1305.rs +++ b/src/hacl/chacha20poly1305.rs @@ -1,9 +1,7 @@ use libcrux_hacl::*; -use crate::{ - aead::*, - hw_detection::{simd128_support, simd256_support}, -}; +use crate::aead::*; +use libcrux_platform::{simd128_support, simd256_support}; #[cfg(simd256)] fn encrypt_256(key: &Chacha20Key, msg_ctxt: &mut [u8], iv: &Iv, aad: &[u8]) -> Tag { diff --git a/src/hacl/curve25519.rs b/src/hacl/curve25519.rs index 3baab8a55..b5d2f7bce 100644 --- a/src/hacl/curve25519.rs +++ b/src/hacl/curve25519.rs @@ -1,6 +1,6 @@ use libcrux_hacl::*; -use crate::hw_detection::x25519_cpu_support; +use libcrux_platform::x25519_support; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn fast_x25519(result: &mut [u8], private: &[u8], public: &[u8]) -> bool { @@ -19,7 +19,7 @@ fn fast_x25519(_: &mut [u8], _: &[u8], _: &[u8]) -> bool { pub fn derive(p: &[u8], s: &[u8]) -> Result<[u8; 32], &'static str> { let mut result = [0u8; 32]; - let r = if x25519_cpu_support() { + let r = if x25519_support() { log::trace!("HACL x25519 mulx"); fast_x25519(&mut result, s, p) } else { diff --git a/src/hacl/hash.rs b/src/hacl/hash.rs index a62271ab2..644e28e0f 100644 --- a/src/hacl/hash.rs +++ b/src/hacl/hash.rs @@ -2,10 +2,8 @@ use std::ptr::null_mut; use libcrux_hacl::*; -use crate::{ - digest::{digest_size, Algorithm}, - hw_detection::{simd128_support, simd256_support}, -}; +use crate::digest::{digest_size, Algorithm}; +use libcrux_platform::{simd128_support, simd256_support}; #[cfg(not(simd128))] unsafe fn Hacl_Blake2s_128_blake2s( diff --git a/src/hw_detection.rs b/src/hw_detection.rs deleted file mode 100644 index 7e91eb9ca..000000000 --- a/src/hw_detection.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! Helper to check for required CPU feattures. -#![allow(unused)] - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -mod cpuid; -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -use cpuid::{self as cpu_id, Feature}; - -#[cfg(test)] -mod test; - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub(super) fn simd128_support() -> bool { - cpu_id::supported(Feature::sse2) - && cpu_id::supported(Feature::sse3) - && cpu_id::supported(Feature::sse4_1) - && cpu_id::supported(Feature::avx) -} - -#[cfg(target_arch = "aarch64")] -pub(super) fn simd128_support() -> bool { - true -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")))] -pub(super) fn simd128_support() -> bool { - // XXX: Check for z14 or z15 - false -} - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub(super) fn simd256_support() -> bool { - cpu_id::supported(Feature::avx2) -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -pub(super) fn simd256_support() -> bool { - // XXX: Check for z14 or z15 - false -} - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub(super) fn x25519_cpu_support() -> bool { - cpu_id::supported(Feature::bmi2) && cpu_id::supported(Feature::adx) -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -#[allow(unused)] -pub(super) fn x25519_cpu_support() -> bool { - false -} - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub(super) fn bmi2_adx_support() -> bool { - cpu_id::supported(Feature::bmi2) && cpu_id::supported(Feature::adx) -} - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -pub(super) fn bmi2_adx_support() -> bool { - false -} - -/// Check whether AES is supported -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub fn aes_ni_support() -> bool { - cpu_id::supported(Feature::avx) - && cpu_id::supported(Feature::sse) - && cpu_id::supported(Feature::aes) - && cpu_id::supported(Feature::pclmulqdq) - && cpu_id::supported(Feature::movbe) -} - -/// Check whether AES is supported -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -pub fn aes_ni_support() -> bool { - false -} diff --git a/src/hw_detection/cpuid.rs b/src/hw_detection/cpuid.rs deleted file mode 100644 index 25a903c30..000000000 --- a/src/hw_detection/cpuid.rs +++ /dev/null @@ -1,139 +0,0 @@ -#![allow(non_upper_case_globals)] - -#[cfg(target_arch = "x86")] -use core::arch::x86::{CpuidResult, __cpuid, __cpuid_count}; -#[cfg(target_arch = "x86_64")] -use core::arch::x86_64::{CpuidResult, __cpuid, __cpuid_count}; - -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -pub(super) enum Feature { - mmx, - sse, - sse2, - sse3, - pclmulqdq, - ssse3, - fma, - movbe, - sse4_1, - sse4_2, - popcnt, - aes, - xsave, - osxsave, - avx, - rdrand, - sgx, - bmi1, - avx2, - bmi2, - avx512f, - avx512dq, - rdseed, - adx, - avx512ifma, - avx512pf, - avx512er, - avx512cd, - sha, - avx512bw, - avx512vl, -} - -/// Check hardware [`Feature`] support. -pub(super) fn supported(feature: Feature) -> bool { - init(); - let cpu_id_0 = unsafe { CPU_ID[0] }; - let cpu_id_1 = unsafe { CPU_ID[1] }; - match feature { - Feature::mmx => cpu_id_0.edx & (1 << 23) != 0, - Feature::sse => cpu_id_0.edx & (1 << 25) != 0, - Feature::sse2 => cpu_id_0.edx & (1 << 26) != 0, - Feature::sse3 => cpu_id_0.ecx & (1 << 0) != 0, - Feature::pclmulqdq => cpu_id_0.ecx & (1 << 1) != 0, - Feature::ssse3 => cpu_id_0.ecx & (1 << 9) != 0, - Feature::fma => cpu_id_0.ecx & (1 << 12) != 0, - Feature::movbe => cpu_id_0.ecx & (1 << 22) != 0, - Feature::sse4_1 => cpu_id_0.ecx & (1 << 19) != 0, - Feature::sse4_2 => cpu_id_0.ecx & (1 << 20) != 0, - Feature::popcnt => cpu_id_0.ecx & (1 << 23) != 0, - Feature::aes => cpu_id_0.ecx & (1 << 25) != 0, - Feature::xsave => cpu_id_0.ecx & (1 << 26) != 0, - Feature::osxsave => cpu_id_0.ecx & (1 << 27) != 0, - Feature::avx => { - cpu_id_0.ecx & (1 << 28) != 0 - && supported(Feature::xsave) - && supported(Feature::osxsave) - } - Feature::rdrand => cpu_id_0.ecx & (1 << 30) != 0, - Feature::sgx => cpu_id_1.ebx & (1 << 2) != 0, - Feature::bmi1 => cpu_id_1.ebx & (1 << 3) != 0, - Feature::avx2 => { - cpu_id_1.ebx & (1 << 5) != 0 - && supported(Feature::bmi1) - && supported(Feature::bmi2) - && supported(Feature::fma) - && supported(Feature::movbe) - } - Feature::bmi2 => cpu_id_1.ebx & (1 << 8) != 0, - Feature::avx512f => cpu_id_1.ebx & (1 << 16) != 0, - Feature::avx512dq => cpu_id_1.ebx & (1 << 17) != 0, - Feature::rdseed => cpu_id_1.ebx & (1 << 18) != 0, - Feature::adx => cpu_id_1.ebx & (1 << 19) != 0, - Feature::avx512ifma => cpu_id_1.ebx & (1 << 21) != 0, - Feature::avx512pf => cpu_id_1.ebx & (1 << 26) != 0, - Feature::avx512er => cpu_id_1.ebx & (1 << 27) != 0, - Feature::avx512cd => cpu_id_1.ebx & (1 << 28) != 0, - Feature::sha => cpu_id_1.ebx & (1 << 29) != 0, - Feature::avx512bw => cpu_id_1.ebx & (1 << 30) != 0, - Feature::avx512vl => cpu_id_1.ebx & (1 << 31) != 0, - } -} - -static mut CPU_ID: [CpuidResult; 2] = [ - CpuidResult { - eax: 0, - ebx: 0, - ecx: 0, - edx: 0, - }, - CpuidResult { - eax: 0, - ebx: 0, - ecx: 0, - edx: 0, - }, -]; -static mut INITIALIZED: bool = false; - -/// Initialize CPU detection. -#[inline(always)] -pub(super) fn init() { - if unsafe { INITIALIZED } { - return; - } - - // XXX: https://github.com/rust-lang/rust/issues/101346 - #[inline(never)] - unsafe fn cpuid(leaf: u32) -> CpuidResult { - __cpuid(leaf) - } - - #[inline(never)] - unsafe fn cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult { - __cpuid_count(leaf, sub_leaf) - } - - // XXX[no_std]: no good way to do this in no_std - std::panic::catch_unwind(|| { - // If there's no CPU ID because we're in SGX or whatever other reason, - // we'll consider the hw detection as initialized but always return false. - unsafe { - CPU_ID = [cpuid(1), cpuid_count(7, 0)]; - } - }); - unsafe { - INITIALIZED = true; - } -} diff --git a/src/hw_detection/test.rs b/src/hw_detection/test.rs deleted file mode 100644 index 774a570e1..000000000 --- a/src/hw_detection/test.rs +++ /dev/null @@ -1,81 +0,0 @@ -use super::*; - -#[test] -fn dump_features() { - eprintln!("simd128\t\t{:?}", simd128_support()); - eprintln!("simd256\t\t{:?}", simd256_support()); - eprintln!("x25519\t\t{:?}", x25519_cpu_support()); - eprintln!("bmi2 & adx\t{:?}", bmi2_adx_support()); - eprintln!("aes\t\t{:?}", aes_ni_support()); -} - -// XXX[windows]: Something is running into a STATUS_ACCESS_VIOLATION here. -#[cfg(all( - any(target_arch = "x86", target_arch = "x86_64"), - not(target_os = "windows") -))] -#[test] -fn dump_raw() { - use super::cpuid::{supported, Feature}; - eprintln!("mmx\t\t{:?}", supported(Feature::mmx)); - eprintln!("sse\t\t{:?}", supported(Feature::sse)); - eprintln!("sse2\t\t{:?}", supported(Feature::sse2)); - eprintln!("sse3\t\t{:?}", supported(Feature::sse3)); - eprintln!("pclmulqdq\t{:?}", supported(Feature::pclmulqdq)); - eprintln!("ssse3\t\t{:?}", supported(Feature::ssse3)); - eprintln!("fma\t\t{:?}", supported(Feature::fma)); - eprintln!("movbe\t\t{:?}", supported(Feature::movbe)); - eprintln!("sse4_1\t\t{:?}", supported(Feature::sse4_1)); - eprintln!("sse4_2\t\t{:?}", supported(Feature::sse4_2)); - eprintln!("popcnt\t\t{:?}", supported(Feature::popcnt)); - eprintln!("aes\t\t{:?}", supported(Feature::aes)); - eprintln!("xsave\t\t{:?}", supported(Feature::xsave)); - eprintln!("osxsave\t\t{:?}", supported(Feature::osxsave)); - eprintln!("avx\t\t{:?}", supported(Feature::avx)); - eprintln!("rdrand\t\t{:?}", supported(Feature::rdrand)); - eprintln!("sgx\t\t{:?}", supported(Feature::sgx)); - eprintln!("bmi1\t\t{:?}", supported(Feature::bmi1)); - eprintln!("avx2\t\t{:?}", supported(Feature::avx2)); - eprintln!("bmi2\t\t{:?}", supported(Feature::bmi2)); - eprintln!("avx512f\t\t{:?}", supported(Feature::avx512f)); - eprintln!("avx512dq\t{:?}", supported(Feature::avx512dq)); - eprintln!("rdseed\t\t{:?}", supported(Feature::rdseed)); - eprintln!("adx\t\t{:?}", supported(Feature::adx)); - eprintln!("avx512ifma\t{:?}", supported(Feature::avx512ifma)); - eprintln!("avx512pf\t{:?}", supported(Feature::avx512pf)); - eprintln!("avx512er\t{:?}", supported(Feature::avx512er)); - eprintln!("avx512cd\t{:?}", supported(Feature::avx512cd)); - eprintln!("sha\t\t{:?}", supported(Feature::sha)); - eprintln!("avx512bw\t{:?}", supported(Feature::avx512bw)); - eprintln!("avx512vl\t{:?}", supported(Feature::avx512vl)); -} - -#[cfg(all( - any(target_arch = "x86", target_arch = "x86_64"), - not(target_os = "windows") -))] -#[test] -fn cpuid() { - use super::cpuid::supported; - use std::time::Instant; - - let now = Instant::now(); - let _avx2 = supported(Feature::avx2); - let elapsed = now.elapsed(); - eprintln!("libcrux init: {elapsed:.2?}"); - - let now = Instant::now(); - let _avx2 = supported(Feature::avx2); - let elapsed = now.elapsed(); - eprintln!("libcrux after: {elapsed:.2?}"); - - let now = Instant::now(); - let _avx2 = std::arch::is_x86_feature_detected!("avx2"); - let elapsed = now.elapsed(); - eprintln!("std init: {elapsed:.2?}"); - - let now = Instant::now(); - let _avx2 = std::arch::is_x86_feature_detected!("avx2"); - let elapsed = now.elapsed(); - eprintln!("std after: {elapsed:.2?}"); -} diff --git a/src/jasmin/sha.rs b/src/jasmin/sha.rs index 01ce2644e..1124f8e1e 100644 --- a/src/jasmin/sha.rs +++ b/src/jasmin/sha.rs @@ -1,6 +1,7 @@ use libjade::*; -use crate::{digest::Algorithm, hw_detection::simd256_support}; +use crate::digest::Algorithm; +use libcrux_platform::simd256_support; pub fn hash(alg: Algorithm, payload: &[u8]) -> Result<[u8; LEN], &'static str> { let mut digest = [0u8; LEN]; diff --git a/src/jasmin/sha3.rs b/src/jasmin/sha3.rs index 427301a4c..72e7a83fd 100644 --- a/src/jasmin/sha3.rs +++ b/src/jasmin/sha3.rs @@ -8,7 +8,7 @@ macro_rules! sha3_simd256 { ($name:ident, $alg:expr, $avx2_fun:expr, $ref_fun:expr) => { pub fn $name(input: &[u8]) -> [u8; digest_size($alg)] { let mut digest = [0u8; digest_size($alg)]; - let r = if crate::hw_detection::simd256_support() { + let r = if libcrux_platform::simd256_support() { log::trace!("Jasmin SHA3 avx2"); unsafe { $avx2_fun( diff --git a/src/lib.rs b/src/lib.rs index c0f19af3a..22e451621 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,7 @@ //! //! The unified, formally verified, cryptography library. -pub(crate) mod hw_detection; -pub use hw_detection::aes_ni_support; +pub use libcrux_platform::aes_ni_support; // Jasmin #[cfg(all(