Add new "wasm32_c" feature to enable more functionality for wasm32 targets.
This commit is contained in:
parent
42f110abe5
commit
10c4b68e63
@ -331,6 +331,7 @@ internal_benches = []
|
||||
slow_tests = []
|
||||
std = ["alloc"]
|
||||
test_logging = []
|
||||
wasm32_c = []
|
||||
|
||||
# XXX: debug = false because of https://github.com/rust-lang/rust/issues/34122
|
||||
|
||||
|
131
build.rs
131
build.rs
@ -54,17 +54,18 @@ const ARM: &str = "arm";
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
const RING_SRCS: &[(&[&str], &str)] = &[
|
||||
(&[], "crypto/fipsmodule/bn/generic.c"),
|
||||
(&[], "crypto/fipsmodule/bn/montgomery.c"),
|
||||
(&[], "crypto/fipsmodule/bn/montgomery_inv.c"),
|
||||
(&[], "crypto/crypto.c"),
|
||||
(&[], "crypto/fipsmodule/ec/ecp_nistz.c"),
|
||||
(&[], "crypto/fipsmodule/ec/ecp_nistz256.c"),
|
||||
(&[], "crypto/fipsmodule/ec/gfp_p256.c"),
|
||||
(&[], "crypto/fipsmodule/ec/gfp_p384.c"),
|
||||
(&[], "crypto/limbs/limbs.c"),
|
||||
(&[], "crypto/mem.c"),
|
||||
(&[], "third_party/fiat/curve25519.c"),
|
||||
|
||||
(&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/bn/generic.c"),
|
||||
(&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/bn/montgomery.c"),
|
||||
(&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/bn/montgomery_inv.c"),
|
||||
(&[AARCH64, ARM, X86_64, X86], "crypto/crypto.c"),
|
||||
(&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/ec/ecp_nistz.c"),
|
||||
(&[AARCH64, ARM, X86_64, X86], "crypto/fipsmodule/ec/ecp_nistz256.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/limbs/limbs.c"),
|
||||
(&[AARCH64, ARM, X86_64, X86], "third_party/fiat/curve25519.c"),
|
||||
|
||||
(&[X86_64, X86], "crypto/cpu-intel.c"),
|
||||
|
||||
@ -229,18 +230,19 @@ const LD_FLAGS: &[&str] = &[];
|
||||
|
||||
// None means "any OS" or "any target". The first match in sequence order is
|
||||
// taken.
|
||||
const ASM_TARGETS: &[(&str, Option<&str>, &str)] = &[
|
||||
("x86_64", Some("ios"), "macosx"),
|
||||
("x86_64", Some("macos"), "macosx"),
|
||||
("x86_64", Some(WINDOWS), "nasm"),
|
||||
("x86_64", None, "elf"),
|
||||
("aarch64", Some("ios"), "ios64"),
|
||||
("aarch64", None, "linux64"),
|
||||
("x86", Some(WINDOWS), "win32n"),
|
||||
("x86", Some("ios"), "macosx"),
|
||||
("x86", None, "elf"),
|
||||
("arm", Some("ios"), "ios32"),
|
||||
("arm", None, "linux32"),
|
||||
const ASM_TARGETS: &[(&str, Option<&str>, Option<&str>)] = &[
|
||||
("x86_64", Some("ios"), Some("macosx")),
|
||||
("x86_64", Some("macos"), Some("macosx")),
|
||||
("x86_64", Some(WINDOWS), Some("nasm")),
|
||||
("x86_64", None, Some("elf")),
|
||||
("aarch64", Some("ios"), Some("ios64")),
|
||||
("aarch64", None, Some("linux64")),
|
||||
("x86", Some(WINDOWS), Some("win32n")),
|
||||
("x86", Some("ios"), Some("macosx")),
|
||||
("x86", None, Some("elf")),
|
||||
("arm", Some("ios"), Some("ios32")),
|
||||
("arm", None, Some("linux32")),
|
||||
("wasm32", None, None),
|
||||
];
|
||||
|
||||
const WINDOWS: &str = "windows";
|
||||
@ -314,15 +316,18 @@ fn pregenerate_asm_main() {
|
||||
&pregenerated
|
||||
};
|
||||
|
||||
let perlasm_src_dsts = perlasm_src_dsts(&asm_dir, target_arch, target_os, perlasm_format);
|
||||
perlasm(&perlasm_src_dsts, target_arch, perlasm_format, None);
|
||||
if let Some(perlasm_format) = perlasm_format {
|
||||
let perlasm_src_dsts =
|
||||
perlasm_src_dsts(&asm_dir, target_arch, target_os, perlasm_format);
|
||||
perlasm(&perlasm_src_dsts, target_arch, perlasm_format, None);
|
||||
|
||||
if target_os == Some(WINDOWS) {
|
||||
let srcs = asm_srcs(perlasm_src_dsts);
|
||||
for src in srcs {
|
||||
let src_path = PathBuf::from(src);
|
||||
let obj_path = obj_path(&pregenerated, &src_path, MSVC_OBJ_EXT);
|
||||
run_command(yasm(&src_path, target_arch, &obj_path));
|
||||
if target_os == Some(WINDOWS) {
|
||||
let srcs = asm_srcs(perlasm_src_dsts);
|
||||
for src in srcs {
|
||||
let src_path = PathBuf::from(src);
|
||||
let obj_path = obj_path(&pregenerated, &src_path, MSVC_OBJ_EXT);
|
||||
run_command(yasm(&src_path, target_arch, &obj_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -339,8 +344,11 @@ struct Target {
|
||||
}
|
||||
|
||||
fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) {
|
||||
if &target.arch == "wasm32" {
|
||||
return;
|
||||
#[cfg(not(feature = "wasm32_c"))]
|
||||
{
|
||||
if &target.arch == "wasm32" {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let includes_modified = RING_INCLUDES
|
||||
@ -379,31 +387,37 @@ fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) {
|
||||
out_dir
|
||||
};
|
||||
|
||||
let perlasm_src_dsts =
|
||||
perlasm_src_dsts(asm_dir, &target.arch, Some(&target.os), perlasm_format);
|
||||
let asm_srcs = if let Some(perlasm_format) = perlasm_format {
|
||||
let perlasm_src_dsts =
|
||||
perlasm_src_dsts(asm_dir, &target.arch, Some(&target.os), perlasm_format);
|
||||
|
||||
if !use_pregenerated {
|
||||
perlasm(
|
||||
&perlasm_src_dsts[..],
|
||||
&target.arch,
|
||||
perlasm_format,
|
||||
Some(includes_modified),
|
||||
);
|
||||
}
|
||||
if !use_pregenerated {
|
||||
perlasm(
|
||||
&perlasm_src_dsts[..],
|
||||
&target.arch,
|
||||
perlasm_format,
|
||||
Some(includes_modified),
|
||||
);
|
||||
}
|
||||
|
||||
let mut asm_srcs = asm_srcs(perlasm_src_dsts);
|
||||
let mut asm_srcs = asm_srcs(perlasm_src_dsts);
|
||||
|
||||
// For Windows we also pregenerate the object files for non-Git builds so
|
||||
// the user doesn't need to install the assembler. On other platforms we
|
||||
// assume the C compiler also assembles.
|
||||
if use_pregenerated && &target.os == WINDOWS {
|
||||
// The pregenerated object files always use ".obj" as the extension,
|
||||
// even when the C/C++ compiler outputs files with the ".o" extension.
|
||||
asm_srcs = asm_srcs
|
||||
.iter()
|
||||
.map(|src| obj_path(&pregenerated, src.as_path(), "obj"))
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
// For Windows we also pregenerate the object files for non-Git builds so
|
||||
// the user doesn't need to install the assembler. On other platforms we
|
||||
// assume the C compiler also assembles.
|
||||
if use_pregenerated && &target.os == WINDOWS {
|
||||
// The pregenerated object files always use ".obj" as the extension,
|
||||
// even when the C/C++ compiler outputs files with the ".o" extension.
|
||||
asm_srcs = asm_srcs
|
||||
.iter()
|
||||
.map(|src| obj_path(&pregenerated, src.as_path(), "obj"))
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
|
||||
asm_srcs
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let core_srcs = sources_for_arch(&target.arch)
|
||||
.into_iter()
|
||||
@ -549,7 +563,11 @@ fn cc(
|
||||
for f in cpp_flags(target) {
|
||||
let _ = c.flag(&f);
|
||||
}
|
||||
if &target.os != "none" && &target.os != "redox" && &target.os != "windows" {
|
||||
if &target.os != "none"
|
||||
&& &target.os != "redox"
|
||||
&& &target.os != "windows"
|
||||
&& target.arch != "wasm32"
|
||||
{
|
||||
let _ = c.flag("-fstack-protector");
|
||||
}
|
||||
|
||||
@ -563,7 +581,8 @@ fn cc(
|
||||
let _ = c.flag("-g3");
|
||||
}
|
||||
};
|
||||
if !target.is_debug {
|
||||
// We don't have assert.h for wasm32 targets.
|
||||
if !target.is_debug || target.arch == "wasm32" {
|
||||
let _ = c.define("NDEBUG", None);
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,8 @@
|
||||
#elif defined(__mips__) && defined(__LP64__)
|
||||
#define OPENSSL_64_BIT
|
||||
#define OPENSSL_MIPS64
|
||||
#elif defined(__wasm__)
|
||||
#define OPENSSL_32_BIT
|
||||
#else
|
||||
// Note BoringSSL only supports standard 32-bit and 64-bit two's-complement,
|
||||
// little-endian architectures. Functions will not produce the correct answer
|
||||
|
10
src/lib.rs
10
src/lib.rs
@ -35,6 +35,16 @@
|
||||
//! <tr><td><code>std</code>
|
||||
//! <td>Enable features that use libstd, in particular `std::error::Error`
|
||||
//! integration.
|
||||
//! <tr><td><code>wasm32_c</code>
|
||||
//! <td>Enables features that require a C compiler on wasm32 targets, such as
|
||||
//! the <code>constant_time</code> module, HMAC verification, and PBKDF2
|
||||
//! verification. Without this feature, only a subset of functionality
|
||||
//! is provided to wasm32 targets so that a C compiler isn't needed. A
|
||||
//! typical invocation would be:
|
||||
//! <code>TARGET_AR=llvm-ar cargo test --target=wasm32-unknown-unknown --features=wasm32_c</code>
|
||||
//! with <code>llvm-ar</code> and <code>clang</code> in <code>$PATH</code>.
|
||||
//! (Going forward more functionality should be enabled by default, without
|
||||
//! requiring these hacks, and without requiring a C compiler.)
|
||||
//! </table>
|
||||
|
||||
#![doc(html_root_url = "https://briansmith.org/rustdoc/")]
|
||||
|
@ -14,8 +14,18 @@
|
||||
|
||||
use ring::{constant_time, error, rand};
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "wasm32_c"))]
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "wasm32_c"))]
|
||||
use wasm_bindgen_test::wasm_bindgen_test_configure;
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "wasm32_c"))]
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
// This logic is loosly based on BoringSSL's `TEST(ConstantTimeTest, MemCmp)`.
|
||||
#[test]
|
||||
#[cfg_attr(all(target_arch = "wasm32", feature = "wasm32_c"), wasm_bindgen_test)]
|
||||
fn test_verify_slices_are_equal() {
|
||||
let initial: [u8; 256] = rand::generate(&rand::SystemRandom::new()).unwrap().expose();
|
||||
|
||||
|
@ -77,6 +77,7 @@ fn hkdf_tests() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn hkdf_output_len_tests() {
|
||||
for &alg in &[hkdf::HKDF_SHA256, hkdf::HKDF_SHA384, hkdf::HKDF_SHA512] {
|
||||
const MAX_BLOCKS: usize = 255;
|
||||
|
@ -32,7 +32,17 @@
|
||||
|
||||
use ring::{digest, error, hmac, test, test_file};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen_test::wasm_bindgen_test_configure;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn hmac_tests() {
|
||||
test::run(test_file!("hmac_tests.txt"), |section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
@ -87,6 +97,8 @@ fn hmac_test_case_inner(
|
||||
{
|
||||
let signature = hmac::sign(&key, input);
|
||||
assert_eq!(is_ok, signature.as_ref() == output);
|
||||
|
||||
#[cfg(any(not(target_arch = "wasm32"), feature = "wasm32_c"))]
|
||||
assert_eq!(is_ok, hmac::verify(&key, input, output).is_ok());
|
||||
}
|
||||
|
||||
@ -112,6 +124,7 @@ fn hmac_test_case_inner(
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn hmac_debug() {
|
||||
let key = hmac::Key::new(hmac::HMAC_SHA256, &[0; 32]);
|
||||
assert_eq!("Key { algorithm: SHA256 }", format!("{:?}", &key));
|
||||
|
@ -33,7 +33,18 @@
|
||||
use core::num::NonZeroU32;
|
||||
use ring::{digest, error, pbkdf2, test, test_file};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen_test::wasm_bindgen_test_configure;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
/// Test vectors from BoringSSL, Go, and other sources.
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
pub fn pbkdf2_tests() {
|
||||
test::run(test_file!("pbkdf2_tests.txt"), |section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
@ -69,6 +80,7 @@ pub fn pbkdf2_tests() {
|
||||
assert_eq!(dk == out, verify_expected_result.is_ok() || dk.is_empty());
|
||||
}
|
||||
|
||||
#[cfg(any(not(target_arch = "wasm32"), feature = "wasm32_c"))]
|
||||
assert_eq!(
|
||||
pbkdf2::verify(algorithm, iterations, &salt, &secret, &dk),
|
||||
verify_expected_result
|
||||
|
Loading…
x
Reference in New Issue
Block a user