diff --git a/build.rs b/build.rs index f7b94108b7..2f64de915a 100644 --- a/build.rs +++ b/build.rs @@ -83,6 +83,7 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[ARM], "crypto/curve25519/asm/x25519-asm-arm.S"), (&[ARM], "crypto/fipsmodule/modes/asm/ghash-armv4.pl"), (&[ARM], "crypto/poly1305/poly1305_arm.c"), + (&[ARM], "crypto/poly1305/poly1305.c"), // For Windows ARM32 only (&[ARM], "crypto/poly1305/poly1305_arm_asm.S"), (&[ARM], "crypto/fipsmodule/sha/asm/sha256-armv4.pl"), (&[ARM], "crypto/fipsmodule/sha/asm/sha512-armv4.pl"), @@ -223,6 +224,13 @@ const ASM_TARGETS: &[AsmTarget] = &[ asm_extension: "S", preassemble: false, }, + AsmTarget { + oss: &[WINDOWS], + arch: "arm", + perlasm_format: "win32", + asm_extension: "S", + preassemble: false, + }, ]; struct AsmTarget { @@ -432,8 +440,17 @@ fn build_c_code( generate_prefix_symbols_asm_headers(out_dir, ring_core_prefix).unwrap(); + let is_win_arm32 = target.arch == ARM && target.os == WINDOWS; let (asm_srcs, obj_srcs) = if let Some(asm_target) = asm_target { - let perlasm_src_dsts = perlasm_src_dsts(asm_dir, asm_target); + let perlasm_src_dsts = perlasm_src_dsts(asm_dir, asm_target) + .into_iter() + .filter(|(src, _)| { + if !is_win_arm32 { + return true; + } + !src.to_string_lossy().contains("armx") + }) + .collect::>(); if !use_pregenerated { perlasm(&perlasm_src_dsts[..], asm_target); @@ -472,6 +489,18 @@ fn build_c_code( } true }) + .filter(|p| { + let file_name = p.file_name().unwrap().to_string_lossy(); + if file_name.contains("poly1305.c") { + return is_win_arm32; + } + if !is_win_arm32 { + return true; + } + !["poly1305"] + .into_iter() + .any(|keyword| file_name.contains(keyword)) + }) .collect::>(); let test_srcs = RING_TEST_SRCS.iter().map(PathBuf::from).collect::>(); @@ -576,7 +605,10 @@ fn obj_path(out_dir: &Path, src: &Path) -> PathBuf { fn configure_cc(c: &mut cc::Build, target: &Target, include_dir: &Path) { // 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() { + if target.os == WINDOWS + && (target.arch == AARCH64 || target.arch == ARM) + && !c.get_compiler().is_like_clang() + { let _ = c.compiler("clang"); } @@ -619,7 +651,7 @@ fn configure_cc(c: &mut cc::Build, target: &Target, include_dir: &Path) { } } -/// Assembles the assemply language source `file` into the object file +/// Assembles the assembly language source `file` into the object file /// `out_file`. fn cc_asm(b: &cc::Build, file: &Path, out_file: &Path) -> Command { let cc = b.get_compiler(); diff --git a/crypto/perlasm/arm-xlate.pl b/crypto/perlasm/arm-xlate.pl index aa2f20f348..34b62661f4 100755 --- a/crypto/perlasm/arm-xlate.pl +++ b/crypto/perlasm/arm-xlate.pl @@ -31,7 +31,7 @@ }; my $hidden = sub { if ($flavour =~ /ios/) { ".private_extern\t".join(',',@_); } - elsif ($flavour =~ /win64/) { ""; } + elsif ($flavour =~ /win/) { ""; } else { ".hidden\t".join(',',@_); } }; my $comm = sub { diff --git a/src/aead/aes.rs b/src/aead/aes.rs index e5c6e62704..061b731318 100644 --- a/src/aead/aes.rs +++ b/src/aead/aes.rs @@ -146,7 +146,7 @@ impl Key { match detect_implementation(cpu_features) { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -181,7 +181,7 @@ impl Key { match detect_implementation(self.cpu_features) { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -220,7 +220,7 @@ impl Key { match detect_implementation(self.cpu_features) { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -370,7 +370,7 @@ impl Iv { pub enum Implementation { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -401,7 +401,7 @@ fn detect_implementation(cpu_features: cpu::Features) -> Implementation { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] diff --git a/src/aead/gcm.rs b/src/aead/gcm.rs index ab41db3bd4..2cb1f725ac 100644 --- a/src/aead/gcm.rs +++ b/src/aead/gcm.rs @@ -53,7 +53,7 @@ impl Key { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -154,7 +154,7 @@ impl Context { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -206,7 +206,7 @@ impl Context { match detect_implementation(self.cpu_features) { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -298,7 +298,7 @@ struct ContextInner { enum Implementation { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] @@ -324,7 +324,7 @@ fn detect_implementation(cpu_features: cpu::Features) -> Implementation { #[cfg(any( target_arch = "aarch64", - target_arch = "arm", + all(target_arch = "arm", not(target_os = "windows")), target_arch = "x86_64", target_arch = "x86" ))] diff --git a/src/aead/poly1305.rs b/src/aead/poly1305.rs index f7c202c49d..74cbcf9a0e 100644 --- a/src/aead/poly1305.rs +++ b/src/aead/poly1305.rs @@ -60,7 +60,7 @@ macro_rules! dispatch { ( $( $a:expr ),+ ) ) => { match () { // Apple's 32-bit ARM ABI is incompatible with the assembly code. - #[cfg(all(target_arch = "arm", not(target_vendor = "apple")))] + #[cfg(all(target_arch = "arm", not(any(target_vendor = "apple", target_os = "windows"))))] () if cpu::arm::NEON.available($features) => { prefixed_extern! { fn $neon_f( $( $p : $t ),+ ); diff --git a/src/cpu/arm.rs b/src/cpu/arm.rs index 9a568475a4..773828aeaa 100644 --- a/src/cpu/arm.rs +++ b/src/cpu/arm.rs @@ -122,6 +122,24 @@ fn detect_features() -> u32 { features } +#[cfg(all(target_os = "windows", target_arch = "arm"))] +fn detect_features() -> u32 { + extern "C" { + fn IsProcessorFeaturePresent(ProcessorFeature: u32) -> i32; + } + const PF_ARM_VFP_32_REGISTERS_AVAILABLE: u32 = 18; + + let mut features = 0; + + let result = unsafe { IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE) }; + + if result != 0 { + features |= NEON.mask; + } + + features +} + #[cfg(all(target_os = "windows", target_arch = "aarch64"))] fn detect_features() -> u32 { // We do not need to check for the presence of NEON, as Armv8-A always has it diff --git a/src/ec/curve25519/x25519.rs b/src/ec/curve25519/x25519.rs index fdfaa4c555..1b25c259ee 100644 --- a/src/ec/curve25519/x25519.rs +++ b/src/ec/curve25519/x25519.rs @@ -63,7 +63,10 @@ fn x25519_public_from_private( let private_key: &[u8; SCALAR_LEN] = private_key.bytes_less_safe().try_into()?; let private_key = ops::MaskedScalar::from_bytes_masked(*private_key); - #[cfg(all(not(target_os = "ios"), target_arch = "arm"))] + #[cfg(all( + not(any(target_os = "ios", target_os = "windows")), + target_arch = "arm" + ))] { if cpu::arm::NEON.available(cpu_features) { static MONTGOMERY_BASE_POINT: [u8; 32] = [ @@ -109,7 +112,10 @@ fn x25519_ecdh( point: &ops::EncodedPoint, #[allow(unused_variables)] cpu_features: cpu::Features, ) { - #[cfg(all(not(target_os = "ios"), target_arch = "arm"))] + #[cfg(all( + not(any(target_os = "ios", target_os = "windows")), + target_arch = "arm" + ))] { if cpu::arm::NEON.available(cpu_features) { return x25519_neon(out, scalar, point); @@ -158,7 +164,10 @@ fn x25519_ecdh( Ok(()) } -#[cfg(all(not(target_os = "ios"), target_arch = "arm"))] +#[cfg(all( + not(any(target_os = "ios", target_os = "windows")), + target_arch = "arm" +))] fn x25519_neon(out: &mut ops::EncodedPoint, scalar: &ops::MaskedScalar, point: &ops::EncodedPoint) { prefixed_extern! { fn x25519_NEON(