Patch source: * https://github.com/briansmith/ring/issues/1999 * https://salsa.debian.org/rust-team/debcargo-conf/-/commit/ace5e3fc96a8b0d85150c399d5f79c314abd4a60 This patch was modified from upstream in the following ways: * sed -e 's@rust-ring-0.17.8/@b/ring-0.17.8/@g' \ -e 's@rust-ring-0.17.8.orig/@a/ring-0.17.8/@g' * remove `use std`; replace `env` with `std::env` Description: Avoid using the x86-specific implementations on non-sse2 x86 Upstream has said that the x86-specific implementation requires sse2, and now enforces this via a static assert. This patch replaces all checks in "src" for x86 with checks for x86 with sse2 and also inhibits the build of assembler on x86 without sse2. This should cause the generic implementations to be used. The changes to "src" were created with the command for file in `find src -name '*.rs'` ; do sed -i 's/target_arch = "x86"/all(target_arch = "x86", target_feature = "sse2")/g' $file ; done Author: Peter Michael Green Index: b/ring-0.17.8/src/aead/aes.rs =================================================================== --- a/ring-0.17.8/src/aead/aes.rs +++ b/ring-0.17.8/src/aead/aes.rs @@ -149,7 +149,7 @@ impl Key { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::HWAES => { set_encrypt_key!(aes_hw_set_encrypt_key, bytes, key_bits, &mut key)? @@ -159,7 +159,7 @@ impl Key { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::VPAES_BSAES => { set_encrypt_key!(vpaes_set_encrypt_key, bytes, key_bits, &mut key)? @@ -180,7 +180,7 @@ impl Key { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::HWAES => encrypt_block!(aes_hw_encrypt, a, self), @@ -188,7 +188,7 @@ impl Key { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::VPAES_BSAES => encrypt_block!(vpaes_encrypt, a, self), @@ -219,7 +219,7 @@ impl Key { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::HWAES => { ctr32_encrypt_blocks!(aes_hw_ctr32_encrypt_blocks, in_out, src, &self.inner, ctr) @@ -263,7 +263,7 @@ impl Key { ctr32_encrypt_blocks!(vpaes_ctr32_encrypt_blocks, in_out, src, &self.inner, ctr) } - #[cfg(target_arch = "x86")] + #[cfg(all(target_arch = "x86", target_feature = "sse2"))] Implementation::VPAES_BSAES => { super::shift::shift_full_blocks(in_out, src, |input| { self.encrypt_iv_xor_block(ctr.increment(), Block::from(input), cpu_features) @@ -365,7 +365,7 @@ pub enum Implementation { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] HWAES = 1, @@ -374,7 +374,7 @@ pub enum Implementation { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] VPAES_BSAES = 2, @@ -387,7 +387,7 @@ fn detect_implementation(cpu_features: c target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") )))] let _cpu_features = cpu_features; @@ -398,14 +398,14 @@ fn detect_implementation(cpu_features: c } } - #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] + #[cfg(any(target_arch = "x86_64", all(target_arch = "x86", target_feature = "sse2")))] { if cpu::intel::AES.available(cpu_features) { return Implementation::HWAES; } } - #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] + #[cfg(any(target_arch = "x86_64", all(target_arch = "x86", target_feature = "sse2")))] { if cpu::intel::SSSE3.available(cpu_features) { return Implementation::VPAES_BSAES; Index: b/ring-0.17.8/src/aead/chacha.rs =================================================================== --- a/ring-0.17.8/src/aead/chacha.rs +++ b/ring-0.17.8/src/aead/chacha.rs @@ -20,7 +20,7 @@ use super::{quic::Sample, Nonce}; not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )) ))] @@ -75,7 +75,7 @@ impl Key { // has this limitation and come up with a better solution. // // https://rt.openssl.org/Ticket/Display.html?id=4362 - if cfg!(any(target_arch = "arm", target_arch = "x86")) && src.start != 0 { + if cfg!(any(target_arch = "arm", all(target_arch = "x86", target_feature = "sse2"))) && src.start != 0 { let len = in_out.len() - src.start; in_out.copy_within(src, 0); self.encrypt_in_place(counter, &mut in_out[..len]); @@ -91,7 +91,7 @@ impl Key { #[cfg(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" ))] #[inline(always)] @@ -128,7 +128,7 @@ impl Key { #[cfg(not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )))] use fallback::ChaCha20_ctr32; @@ -169,7 +169,7 @@ impl Counter { not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )) ))] @@ -219,7 +219,7 @@ mod tests { let max_offset = if cfg!(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )) { MAX_ALIGNMENT_AND_OFFSET Index: b/ring-0.17.8/src/aead/gcm.rs =================================================================== --- a/ring-0.17.8/src/aead/gcm.rs +++ b/ring-0.17.8/src/aead/gcm.rs @@ -57,7 +57,7 @@ impl Key { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::CLMUL => { prefixed_extern! { @@ -185,7 +185,7 @@ impl Context { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::CLMUL => { prefixed_extern! { @@ -236,7 +236,7 @@ impl Context { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] Implementation::CLMUL => { prefixed_extern! { @@ -339,7 +339,7 @@ enum Implementation { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] CLMUL, @@ -356,7 +356,7 @@ fn detect_implementation(cpu_features: c target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") )))] let _cpu_features = cpu_features; @@ -367,7 +367,7 @@ fn detect_implementation(cpu_features: c } } - #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] + #[cfg(any(target_arch = "x86_64", all(target_arch = "x86", target_feature = "sse2")))] { if cpu::intel::FXSR.available(cpu_features) && cpu::intel::PCLMULQDQ.available(cpu_features) { Index: b/ring-0.17.8/src/aead/shift.rs =================================================================== --- a/ring-0.17.8/src/aead/shift.rs +++ b/ring-0.17.8/src/aead/shift.rs @@ -14,7 +14,7 @@ use super::block::{Block, BLOCK_LEN}; -#[cfg(target_arch = "x86")] +#[cfg(all(target_arch = "x86", target_feature = "sse2"))] pub fn shift_full_blocks(in_out: &mut [u8], src: core::ops::RangeFrom, mut transform: F) where F: FnMut(&[u8; BLOCK_LEN]) -> Block, Index: b/ring-0.17.8/src/arithmetic/montgomery.rs =================================================================== --- a/ring-0.17.8/src/arithmetic/montgomery.rs +++ b/ring-0.17.8/src/arithmetic/montgomery.rs @@ -128,7 +128,7 @@ unsafe fn mul_mont( #[cfg(not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )))] // TODO: Stop calling this from C and un-export it. @@ -168,7 +168,7 @@ prefixed_export! { not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )) ))] @@ -201,7 +201,7 @@ pub(super) fn limbs_from_mont_in_place(r #[cfg(not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )))] fn limbs_mul(r: &mut [Limb], a: &[Limb], b: &[Limb]) { @@ -223,7 +223,7 @@ fn limbs_mul(r: &mut [Limb], a: &[Limb], target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") )) ))] prefixed_extern! { @@ -236,7 +236,7 @@ prefixed_extern! { target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64", - target_arch = "x86" + all(target_arch = "x86", target_feature = "sse2") ))] prefixed_extern! { // `r` and/or 'a' and/or 'b' may alias. Index: b/ring-0.17.8/src/cpu.rs =================================================================== --- a/ring-0.17.8/src/cpu.rs +++ b/ring-0.17.8/src/cpu.rs @@ -27,13 +27,13 @@ pub(crate) fn features() -> Features { #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] use arm::init_global_shared_with_assembly; - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + #[cfg(any(all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64"))] use intel::init_global_shared_with_assembly; #[cfg(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64", ))] { @@ -47,5 +47,5 @@ pub(crate) fn features() -> Features { #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] pub mod arm; -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(any(all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64"))] pub mod intel; Index: b/ring-0.17.8/src/cpu/intel.rs =================================================================== --- a/ring-0.17.8/src/cpu/intel.rs +++ b/ring-0.17.8/src/cpu/intel.rs @@ -13,11 +13,11 @@ // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #![cfg_attr( - not(any(target_arch = "x86", target_arch = "x86_64")), + not(any(all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64")), allow(dead_code) )] -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(any(all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64"))] mod abi_assumptions { // TOOD: Support targets that do not have SSE and SSE2 enabled, such as // x86_64-unknown-linux-none. See @@ -29,7 +29,7 @@ mod abi_assumptions { #[cfg(target_arch = "x86_64")] const _ASSUMED_POINTER_SIZE: usize = 8; - #[cfg(target_arch = "x86")] + #[cfg(all(target_arch = "x86", target_feature = "sse2"))] const _ASSUMED_POINTER_SIZE: usize = 4; const _ASSUMED_USIZE_SIZE: () = assert!(core::mem::size_of::() == _ASSUMED_POINTER_SIZE); const _ASSUMED_REF_SIZE: () = @@ -43,7 +43,7 @@ pub(crate) struct Feature { mask: u32, } -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[cfg(any(all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64"))] pub(super) unsafe fn init_global_shared_with_assembly() { prefixed_extern! { fn OPENSSL_cpuid_setup(); @@ -57,7 +57,7 @@ impl Feature { #[allow(clippy::needless_return)] #[inline(always)] pub fn available(&self, _: super::Features) -> bool { - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + #[cfg(any(all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64"))] { prefixed_extern! { static mut OPENSSL_ia32cap_P: [u32; 4]; @@ -65,7 +65,7 @@ impl Feature { return self.mask == self.mask & unsafe { OPENSSL_ia32cap_P[self.word] }; } - #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] + #[cfg(not(any(all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64")))] { return false; } Index: b/ring-0.17.8/src/prefixed.rs =================================================================== --- a/ring-0.17.8/src/prefixed.rs +++ b/ring-0.17.8/src/prefixed.rs @@ -44,7 +44,7 @@ macro_rules! prefixed_extern { #[cfg(not(any( target_arch = "aarch64", target_arch = "arm", - target_arch = "x86", + all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64" )))] macro_rules! prefixed_export { Index: b/ring-0.17.8/build.rs =================================================================== --- a/ring-0.17.8/build.rs +++ b/ring-0.17.8/build.rs @@ -430,7 +430,7 @@ fn build_c_code( generate_prefix_symbols_asm_headers(out_dir, ring_core_prefix).unwrap(); - let (asm_srcs, obj_srcs) = if let Some(asm_target) = asm_target { + let (mut asm_srcs, mut obj_srcs) = if let Some(asm_target) = asm_target { let perlasm_src_dsts = perlasm_src_dsts(asm_dir, asm_target); if !use_pregenerated { @@ -454,6 +454,19 @@ fn build_c_code( (vec![], vec![]) }; + if target.arch == "x86" { + let mut havesse2 = false; + for target_feature in std::env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or("".to_string()).split(",") { + if target_feature == "sse2" { + havesse2 = true; + } + } + if !havesse2 { + asm_srcs = vec![]; + obj_srcs = vec![]; + } + } + let core_srcs = sources_for_arch(&target.arch) .into_iter() .filter(|p| !is_perlasm(p))