Skip to content

Commit

Permalink
build.rs: Improve conditional compilation around PerlAsm.
Browse files Browse the repository at this point in the history
build.rs determines whether the target platform is supported by PerlAsm
using both target_arch and target_os. Instances of conditional
compilation in both src/ and crypto/ were using just target_arch to
determine whether PerlAsm symbols are present, resulting in link-time
build failures for certain targets, including, for example,
aarch64-unknown-none.

This commit fixes those instances of conditional compilation to align
with the build script.
  • Loading branch information
nspin committed Jan 27, 2024
1 parent ee5db43 commit 5412e5f
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 155 deletions.
18 changes: 13 additions & 5 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ const MACOS_ABI: &[&str] = &["ios", MACOS, "tvos"];
const MACOS: &str = "macos";
const WINDOWS: &str = "windows";

fn find_asm_target(target: &Target) -> Option<&'static AsmTarget> {
ASM_TARGETS.iter().find(|asm_target| {
asm_target.arch == target.arch && asm_target.oss.contains(&target.os.as_ref())
})
}

/// Read an environment variable and tell Cargo that we depend on it.
///
/// This needs to be used for any environment variable that isn't a standard
Expand Down Expand Up @@ -418,10 +424,6 @@ fn build_c_code(
) {
println!("cargo:rustc-env=RING_CORE_PREFIX={}", ring_core_prefix);

let asm_target = ASM_TARGETS.iter().find(|asm_target| {
asm_target.arch == target.arch && asm_target.oss.contains(&target.os.as_ref())
});

let asm_dir = if use_pregenerated {
&pregenerated
} else {
Expand All @@ -433,7 +435,9 @@ 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 (asm_srcs, obj_srcs) = if let Some(asm_target) = find_asm_target(target) {
println!("cargo:rustc-cfg=have_perlasm");

let perlasm_src_dsts = perlasm_src_dsts(asm_dir, asm_target);

if !use_pregenerated {
Expand Down Expand Up @@ -617,6 +621,10 @@ fn configure_cc(c: &mut cc::Build, target: &Target, include_dir: &Path) {
if target.force_warnings_into_errors {
c.warnings_into_errors(true);
}

if find_asm_target(target).is_some() {
let _ = c.define("RING_HAVE_PERLASM", "1");
}
}

/// Assembles the assemply language source `file` into the object file
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/ec/p256_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "../bn/internal.h"

#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
defined(RING_HAVE_PERLASM) && \
!defined(OPENSSL_SMALL)
# define OPENSSL_USE_NISTZ256
#endif
Expand Down
119 changes: 73 additions & 46 deletions src/aead/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,21 +145,27 @@ impl Key {
};

match detect_implementation(cpu_features) {
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
))]
Implementation::HWAES => {
set_encrypt_key!(aes_hw_set_encrypt_key, bytes, key_bits, &mut key)?
}

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
))]
Implementation::VPAES_BSAES => {
set_encrypt_key!(vpaes_set_encrypt_key, bytes, key_bits, &mut key)?
Expand All @@ -176,19 +182,25 @@ impl Key {
#[inline]
pub fn encrypt_block(&self, a: Block, cpu_features: cpu::Features) -> Block {
match detect_implementation(cpu_features) {
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
))]
Implementation::HWAES => encrypt_block!(aes_hw_encrypt, a, self),

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
))]
Implementation::VPAES_BSAES => encrypt_block!(vpaes_encrypt, a, self),

Expand All @@ -215,17 +227,23 @@ impl Key {
assert_eq!(in_out_len % BLOCK_LEN, 0);

match detect_implementation(cpu_features) {
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
))]
Implementation::HWAES => {
ctr32_encrypt_blocks!(aes_hw_ctr32_encrypt_blocks, in_out, src, &self.inner, ctr)
}

#[cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"))]
#[cfg(all(
have_perlasm,
any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64")
))]
Implementation::VPAES_BSAES => {
// 8 blocks is the cut-off point where it's faster to use BSAES.
#[cfg(target_arch = "arm")]
Expand Down Expand Up @@ -285,7 +303,7 @@ impl Key {
out
}

#[cfg(target_arch = "x86_64")]
#[cfg(all(have_perlasm, target_arch = "x86_64"))]
#[must_use]
pub fn is_aes_hw(&self, cpu_features: cpu::Features) -> bool {
matches!(detect_implementation(cpu_features), Implementation::HWAES)
Expand Down Expand Up @@ -361,20 +379,26 @@ impl Iv {
#[derive(Clone, Copy)]
#[allow(clippy::upper_case_acronyms)]
pub enum Implementation {
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
))]
HWAES = 1,

// On "arm" only, this indicates that the bsaes implementation may be used.
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
))]
VPAES_BSAES = 2,

Expand All @@ -383,36 +407,39 @@ pub enum Implementation {

fn detect_implementation(cpu_features: cpu::Features) -> Implementation {
// `cpu_features` is only used for specific platforms.
#[cfg(not(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
#[cfg(not(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "x86"
)
)))]
let _cpu_features = cpu_features;

#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
#[cfg(all(have_perlasm, any(target_arch = "aarch64", target_arch = "arm")))]
{
if cpu::arm::AES.available(cpu_features) {
return Implementation::HWAES;
}
}

#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
#[cfg(all(have_perlasm, any(target_arch = "x86_64", target_arch = "x86")))]
{
if cpu::intel::AES.available(cpu_features) {
return Implementation::HWAES;
}
}

#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
#[cfg(all(have_perlasm, any(target_arch = "x86_64", target_arch = "x86")))]
{
if cpu::intel::SSSE3.available(cpu_features) {
return Implementation::VPAES_BSAES;
}
}

#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
#[cfg(all(have_perlasm, any(target_arch = "aarch64", target_arch = "arm")))]
{
if cpu::arm::NEON.available(cpu_features) {
return Implementation::VPAES_BSAES;
Expand Down
4 changes: 2 additions & 2 deletions src/aead/aes_gcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fn aes_gcm_seal(
let aad_len = aad.0.len();
let mut auth = gcm::Context::new(gcm_key, aad, cpu_features);

#[cfg(target_arch = "x86_64")]
#[cfg(all(have_perlasm, target_arch = "x86_64"))]
let in_out = {
if !aes_key.is_aes_hw(cpu_features) || !auth.is_avx() {
in_out
Expand Down Expand Up @@ -179,7 +179,7 @@ fn aes_gcm_open(

let total_in_out_len = in_out.len() - in_prefix_len;

#[cfg(target_arch = "x86_64")]
#[cfg(all(have_perlasm, target_arch = "x86_64"))]
let in_out = {
if !aes_key.is_aes_hw(cpu_features) || !auth.is_avx() {
in_out
Expand Down
52 changes: 32 additions & 20 deletions src/aead/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ use super::{quic::Sample, Nonce};

#[cfg(any(
test,
not(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
not(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
)
))
))]
mod fallback;
Expand Down Expand Up @@ -88,11 +91,14 @@ impl Key {
/// Only call this with `src` equal to `0..` or from `encrypt_within`.
#[inline]
fn encrypt_less_safe(&self, counter: Counter, in_out: &mut [u8], src: RangeFrom<usize>) {
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
#[cfg(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
)
))]
#[inline(always)]
pub(super) fn ChaCha20_ctr32(
Expand Down Expand Up @@ -125,11 +131,14 @@ impl Key {
}
}

#[cfg(not(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
#[cfg(not(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
)
)))]
use fallback::ChaCha20_ctr32;

Expand Down Expand Up @@ -166,11 +175,14 @@ impl Counter {
/// the caller.
#[cfg(any(
test,
not(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
not(all(
have_perlasm,
any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "x86",
target_arch = "x86_64"
)
))
))]
fn into_words_less_safe(self) -> [u32; 4] {
Expand Down
6 changes: 3 additions & 3 deletions src/aead/chacha20_poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn chacha20_poly1305_seal(
_ => unreachable!(),
};

#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
#[cfg(all(have_perlasm, any(target_arch = "aarch64", target_arch = "x86_64")))]
if has_integrated(cpu_features) {
// XXX: BoringSSL uses `alignas(16)` on `key` instead of on the
// structure, but Rust can't do that yet; see
Expand Down Expand Up @@ -137,7 +137,7 @@ fn chacha20_poly1305_open(
_ => unreachable!(),
};

#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
#[cfg(all(have_perlasm, any(target_arch = "aarch64", target_arch = "x86_64")))]
if has_integrated(cpu_features) {
// XXX: BoringSSL uses `alignas(16)` on `key` instead of on the
// structure, but Rust can't do that yet; see
Expand Down Expand Up @@ -200,7 +200,7 @@ fn chacha20_poly1305_open(
finish(auth, aad.as_ref().len(), in_out[src].len())
}

#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
#[cfg(all(have_perlasm, any(target_arch = "aarch64", target_arch = "x86_64")))]
#[allow(clippy::needless_return)]
#[inline(always)]
fn has_integrated(cpu_features: cpu::Features) -> bool {
Expand Down
Loading

0 comments on commit 5412e5f

Please sign in to comment.