From 799ed85730b18912205265a045c48cb5513abe07 Mon Sep 17 00:00:00 2001 From: Johnathan Sharratt Date: Sun, 29 May 2022 15:19:57 +0200 Subject: [PATCH] Added support for compiling against wasm32-wasi --- Cargo.toml | 9 ++++++--- build.rs | 24 +++++++++++++++++++----- src/aead.rs | 1 + src/aead/chacha.rs | 2 +- src/cpu/arm.rs | 3 +++ src/ec.rs | 2 +- src/ec/curve25519.rs | 2 +- src/ec/keys.rs | 2 +- src/ec/suite_b.rs | 2 +- src/lib.rs | 2 +- src/rand.rs | 20 ++++++++++++++++++-- tests/aead_tests.rs | 8 ++++---- tests/agreement_tests.rs | 2 +- tests/constant_time_tests.rs | 4 ++-- tests/digest_tests.rs | 10 +++++----- tests/ed25519_tests.rs | 4 ++-- tests/hkdf_tests.rs | 4 ++-- tests/hmac_tests.rs | 4 ++-- tests/pbkdf2_tests.rs | 4 ++-- tests/rand_tests.rs | 4 ++-- tests/rsa_tests.rs | 4 ++-- tests/signature_tests.rs | 4 ++-- 22 files changed, 79 insertions(+), 42 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 97071e3a4c..ce260066d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -171,19 +171,22 @@ spin = { version = "0.9.2", default-features = false, features = ["once"] } libc = { version = "0.2.100", default-features = false } once_cell = { version = "1.8.0", default-features = false, features=["std"], optional = true } +[target.'cfg(target_os = "wasi")'.dependencies] +wasi = { version = "0.11.0" } + [target.'cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", target_os = "solaris"))'.dependencies] once_cell = { version = "1.8.0", default-features = false, features=["std"] } -[target.'cfg(all(target_arch = "wasm32", target_vendor = "unknown", target_os = "unknown", target_env = ""))'.dependencies] +[target.'cfg(all(target_family = "wasm", target_vendor = "unknown", target_os = "unknown", target_env = ""))'.dependencies] web-sys = { version = "0.3.51", default-features = false, features = ["Crypto", "Window"], optional = true } [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3.9", default-features = false, features = ["ntsecapi", "wtypesbase", "processthreadsapi"] } -[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +[target.'cfg(target_family = "wasm")'.dev-dependencies] wasm-bindgen-test = { version = "0.3.26", default-features = false } -[target.'cfg(any(unix, windows))'.dev-dependencies] +[target.'cfg(any(unix, windows, target_os = "wasi"))'.dev-dependencies] libc = { version = "0.2.100", default-features = false } [build-dependencies] diff --git a/build.rs b/build.rs index 2f47981dac..3ff593ee00 100644 --- a/build.rs +++ b/build.rs @@ -30,6 +30,8 @@ const X86: &str = "x86"; const X86_64: &str = "x86_64"; const AARCH64: &str = "aarch64"; const ARM: &str = "arm"; +const WASM32: &str = "wasm32"; +const WASM64: &str = "wasm64"; #[rustfmt::skip] const RING_SRCS: &[(&[&str], &str)] = &[ @@ -41,13 +43,13 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[], "crypto/mem.c"), (&[], "crypto/poly1305/poly1305.c"), - (&[AARCH64, ARM, X86_64, X86], "crypto/crypto.c"), + (&[AARCH64, ARM, X86_64, X86, WASM32, WASM64], "crypto/crypto.c"), (&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/ec/ecp_nistz.c"), (&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/ec/gfp_p256.c"), (&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/ec/gfp_p384.c"), (&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/ec/p256.c"), - (&[X86_64, X86], "crypto/cpu-intel.c"), + (&[X86_64, X86, WASM32, WASM64], "crypto/cpu-intel.c"), (&[X86], "crypto/fipsmodule/aes/asm/aesni-x86.pl"), (&[X86], "crypto/fipsmodule/aes/asm/vpaes-x86.pl"), @@ -64,7 +66,7 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[X86_64], "crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl"), (&[X86_64], "crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl"), (&[X86_64], "crypto/fipsmodule/modes/asm/ghash-x86_64.pl"), - (&[X86_64], "crypto/poly1305/poly1305_vec.c"), + (&[X86_64, WASM32, WASM64], "crypto/poly1305/poly1305_vec.c"), (&[X86_64], SHA512_X86_64), (&[X86_64], "crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl"), @@ -491,6 +493,17 @@ fn build_c_code( ); } +fn cc_builder() -> cc::Build { + let mut c = cc::Build::new(); + let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + if target_os == "wasi" { + let wasi_sdk_path = + &std::env::var("WASI_SDK_DIR").expect("missing environment variable: WASI_SDK_DIR"); + c.flag(format!("--sysroot={}", wasi_sdk_path).as_str()); + } + c +} + fn build_library( target: &Target, out_dir: &Path, @@ -508,7 +521,7 @@ fn build_library( // Rebuild the library if necessary. let lib_path = PathBuf::from(out_dir).join(format!("lib{}.a", lib_name)); - let mut c = cc::Build::new(); + let mut c = cc_builder(); for f in LD_FLAGS { let _ = c.flag(f); @@ -568,7 +581,7 @@ fn obj_path(out_dir: &Path, src: &Path) -> PathBuf { } fn cc(file: &Path, ext: &str, target: &Target, include_dir: &Path, out_file: &Path) -> Command { - let mut c = cc::Build::new(); + let mut c = cc_builder(); // FIXME: On Windows AArch64 we currently must use Clang to compile C code if target.os == WINDOWS && target.arch == AARCH64 && !c.get_compiler().is_like_clang() { @@ -595,6 +608,7 @@ fn cc(file: &Path, ext: &str, target: &Target, include_dir: &Path, out_file: &Pa && target.os != "redox" && target.os != "windows" && target.arch != "wasm32" + && target.arch != "wasm64" { let _ = c.flag("-fstack-protector"); } diff --git a/src/aead.rs b/src/aead.rs index 40f85e9e4f..d3d16e6995 100644 --- a/src/aead.rs +++ b/src/aead.rs @@ -189,6 +189,7 @@ derive_debug_via_id!(Algorithm); enum AlgorithmID { AES_128_GCM, AES_256_GCM, + #[allow(dead_code)] CHACHA20_POLY1305, } diff --git a/src/aead/chacha.rs b/src/aead/chacha.rs index 39479ede94..294b9d0ef0 100644 --- a/src/aead/chacha.rs +++ b/src/aead/chacha.rs @@ -12,7 +12,7 @@ // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +#![cfg_attr(target_os = "wasi", allow(unused, dead_code))] use super::{quic::Sample, Nonce}; use crate::{ cpu, diff --git a/src/cpu/arm.rs b/src/cpu/arm.rs index d523fe5f86..d29f0d8db0 100644 --- a/src/cpu/arm.rs +++ b/src/cpu/arm.rs @@ -181,6 +181,7 @@ macro_rules! features { const ARMCAP_STATIC: u32 = 0 $( | $name.mask )+; + #[cfg_attr(target_os = "wasi", allow(dead_code))] #[cfg(not(all(target_arch = "aarch64", target_vendor = "apple")))] const ARMCAP_STATIC: u32 = 0; @@ -196,10 +197,12 @@ macro_rules! features { } pub(crate) struct Feature { + #[cfg_attr(target_os = "wasi", allow(dead_code))] mask: u32, } impl Feature { + #[cfg_attr(target_os = "wasi", allow(dead_code))] #[inline(always)] pub fn available(&self, _: super::Features) -> bool { if self.mask == self.mask & ARMCAP_STATIC { diff --git a/src/ec.rs b/src/ec.rs index 56c823e13f..5906d99de6 100644 --- a/src/ec.rs +++ b/src/ec.rs @@ -36,7 +36,7 @@ derive_debug_via_id!(Curve); #[derive(Clone, Copy, Debug, PartialEq)] pub enum CurveID { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(target_family = "wasm"))] Curve25519, P256, P384, diff --git a/src/ec/curve25519.rs b/src/ec/curve25519.rs index 074f85c08c..1e97e96b9a 100644 --- a/src/ec/curve25519.rs +++ b/src/ec/curve25519.rs @@ -16,7 +16,7 @@ pub mod ed25519; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(target_family = "wasm"))] pub mod x25519; mod ops; diff --git a/src/ec/keys.rs b/src/ec/keys.rs index 83917ed226..2c94093089 100644 --- a/src/ec/keys.rs +++ b/src/ec/keys.rs @@ -23,7 +23,7 @@ impl KeyPair { pub struct Seed { bytes: [u8; SEED_MAX_BYTES], curve: &'static Curve, - #[cfg_attr(target_arch = "wasm32", allow(dead_code))] + #[cfg_attr(target_family = "wasm", allow(dead_code))] pub(crate) cpu_features: cpu::Features, } diff --git a/src/ec/suite_b.rs b/src/ec/suite_b.rs index 131df9e08a..f817b5e29d 100644 --- a/src/ec/suite_b.rs +++ b/src/ec/suite_b.rs @@ -229,7 +229,7 @@ pub(crate) fn key_pair_from_bytes( pub mod curve; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(target_family = "wasm"))] pub mod ecdh; pub mod ecdsa; diff --git a/src/lib.rs b/src/lib.rs index e4240c74e2..fe8ba589b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,7 +79,7 @@ mod polyfill; pub mod aead; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(target_family = "wasm"))] pub mod agreement; mod bits; diff --git a/src/rand.rs b/src/rand.rs index e7ebece216..61e7563063 100644 --- a/src/rand.rs +++ b/src/rand.rs @@ -168,7 +168,7 @@ impl crate::sealed::Sealed for SystemRandom {} any(target_os = "android", target_os = "linux"), not(feature = "dev_urandom_fallback") ), - target_arch = "wasm32", + target_family = "wasm", windows ))] use self::sysrand::fill as fill_impl; @@ -229,6 +229,22 @@ mod sysrand_chunk { } } +#[cfg(target_os = "wasi")] +mod sysrand_chunk { + use crate::{error}; + + #[inline] + pub fn chunk(dest: &mut [u8]) -> Result { + unsafe { + let base = dest as *mut [u8] as *mut u8; + let len = dest.len(); + wasi::random_get(base, len) + .map(|_| len as usize) + .map_err(|_| error::Unspecified) + } + } +} + #[cfg(all( feature = "wasm32_unknown_unknown_js", target_arch = "wasm32", @@ -285,7 +301,7 @@ mod sysrand_chunk { #[cfg(any( target_os = "android", target_os = "linux", - target_arch = "wasm32", + target_family = "wasm", windows ))] mod sysrand { diff --git a/tests/aead_tests.rs b/tests/aead_tests.rs index 74db661715..58b6fb69d6 100644 --- a/tests/aead_tests.rs +++ b/tests/aead_tests.rs @@ -12,10 +12,10 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); use core::{convert::TryInto, ops::RangeFrom}; @@ -48,10 +48,10 @@ macro_rules! test_aead { $( #[allow(non_snake_case)] mod $alg { // Provide a separate namespace for each algorithm's test. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] use super::super::*; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_family = "wasm", target_os = "unknown"))] use super::super::{*, test}; test_known_answer!( diff --git a/tests/agreement_tests.rs b/tests/agreement_tests.rs index edafdb1f37..1bf5afdbb6 100644 --- a/tests/agreement_tests.rs +++ b/tests/agreement_tests.rs @@ -12,7 +12,7 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![cfg(not(target_arch = "wasm32"))] +#![cfg(not(all(target_family = "wasm", target_os = "unknown")))] extern crate alloc; diff --git a/tests/constant_time_tests.rs b/tests/constant_time_tests.rs index ea2de3c326..ad900f8987 100644 --- a/tests/constant_time_tests.rs +++ b/tests/constant_time_tests.rs @@ -14,10 +14,10 @@ use ring::{constant_time, error, rand}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); // This logic is loosly based on BoringSSL's `TEST(ConstantTimeTest, MemCmp)`. diff --git a/tests/digest_tests.rs b/tests/digest_tests.rs index 85f136a3f7..dd94402505 100644 --- a/tests/digest_tests.rs +++ b/tests/digest_tests.rs @@ -14,10 +14,10 @@ use ring::{digest, test, test_file}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); /// Test vectors from BoringSSL, Go, and other sources. @@ -81,7 +81,7 @@ mod digest_shavs { use super::{run_known_answer_test, run_monte_carlo_test}; use ring::{digest, test_file}; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; #[test] @@ -183,7 +183,7 @@ macro_rules! test_i_u_f { ( $test_name:ident, $alg:expr) => { #[cfg(not(debug_assertions))] // TODO: Get this working on WebAssembly - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] #[test] fn $test_name() { let mut input = [0; (digest::MAX_BLOCK_LEN + 1) * 3]; @@ -245,7 +245,7 @@ macro_rules! test_large_digest { ( $test_name:ident, $alg:expr, $len:expr, $expected:expr) => { // TODO: get this working on WebAssembly. #[cfg(not(debug_assertions))] - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] #[test] fn $test_name() { let chunk = vec![123u8; 16 * 1024]; diff --git a/tests/ed25519_tests.rs b/tests/ed25519_tests.rs index 56291c2811..405eaba4bf 100644 --- a/tests/ed25519_tests.rs +++ b/tests/ed25519_tests.rs @@ -18,10 +18,10 @@ use ring::{ test, test_file, }; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); /// Test vectors from BoringSSL. diff --git a/tests/hkdf_tests.rs b/tests/hkdf_tests.rs index 53df5715dd..9d00b64081 100644 --- a/tests/hkdf_tests.rs +++ b/tests/hkdf_tests.rs @@ -14,10 +14,10 @@ use ring::{digest, error, hkdf, test, test_file}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); #[test] diff --git a/tests/hmac_tests.rs b/tests/hmac_tests.rs index 0da0db5f40..28d3f1db54 100644 --- a/tests/hmac_tests.rs +++ b/tests/hmac_tests.rs @@ -14,10 +14,10 @@ use ring::{digest, hmac, test, test_file}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); #[test] diff --git a/tests/pbkdf2_tests.rs b/tests/pbkdf2_tests.rs index d3fe6ee0e9..d5b5e90b37 100644 --- a/tests/pbkdf2_tests.rs +++ b/tests/pbkdf2_tests.rs @@ -15,10 +15,10 @@ use core::num::NonZeroU32; use ring::{digest, error, pbkdf2, test, test_file}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); /// Test vectors from BoringSSL, Go, and other sources. diff --git a/tests/rand_tests.rs b/tests/rand_tests.rs index 0685a6dcee..2e11fb0443 100644 --- a/tests/rand_tests.rs +++ b/tests/rand_tests.rs @@ -17,10 +17,10 @@ use ring::{ test, }; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); #[test] diff --git a/tests/rsa_tests.rs b/tests/rsa_tests.rs index 2935c6fcfc..05b837cb7d 100644 --- a/tests/rsa_tests.rs +++ b/tests/rsa_tests.rs @@ -23,10 +23,10 @@ use ring::{ }; use std::convert::TryFrom; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); #[test] diff --git a/tests/signature_tests.rs b/tests/signature_tests.rs index 383eaee3be..75bec53f29 100644 --- a/tests/signature_tests.rs +++ b/tests/signature_tests.rs @@ -1,9 +1,9 @@ use ring::{signature, test}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_family = "wasm", target_os = "unknown"))] wasm_bindgen_test_configure!(run_in_browser); #[test]