Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion aes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ level = "warn"
check-cfg = [
'cfg(aes_backend_soft, values("compact"))',
'cfg(aes_backend, values("soft"))',
'cfg(cpubits, values("16", "32", "64"))'
'cfg(cpubits, values("16", "32", "64"))',
'cfg(__enable_aes_soft_backend)'
]

[package.metadata.docs.rs]
Expand Down
30 changes: 30 additions & 0 deletions aes/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::collections::HashSet;

fn main() {
let needs_soft = needs_soft();
if needs_soft {
println!("cargo::rustc-cfg=__enable_aes_soft_backend");
}
}

/// Returns whether the soft backend is required.
///
/// The soft backend may not be required if the target's features are
/// sufficient for one of the accelerated backends and the user did not
/// explicitly opt into the soft backend.
fn needs_soft() -> bool {
if std::env::var("CARGO_CFG_AES_BACKEND").is_ok_and(|value| value == "soft") {
return true;
}

let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").expect("missing target_arch");
let target_features = std::env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or_default();
let target_features = target_features.split(',').collect::<HashSet<_>>();
let miri = std::env::var("CARGO_CFG_MIRI").is_ok();

match &*target_arch {
"x86" | "x86_64" => !target_features.contains("aes"),
"aarch64" if !miri => !target_features.contains("aes"),
_ => true,
}
}
1 change: 1 addition & 0 deletions aes/src/backends.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(__enable_aes_soft_backend)]
pub(crate) mod soft;

cpubits::cfg_if! {
Expand Down
48 changes: 42 additions & 6 deletions aes/src/hazmat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! We do NOT recommend using it to implement any algorithm which has not
//! received extensive peer review by cryptographers.

#[cfg(__enable_aes_soft_backend)]
use crate::backends::soft::hazmat as soft;

pub use crate::Block;
Expand Down Expand Up @@ -42,6 +43,17 @@ macro_rules! if_intrinsics_available {
}};
}

/// Execute the provided body if the soft backend is available.
macro_rules! if_soft_backend_available {
($body:expr) => {{
#[cfg(__enable_aes_soft_backend)]
if true {
$body;
return;
}
}};
}

/// ⚠️ AES cipher (encrypt) round function.
///
/// This API performs the following steps as described in FIPS 197 Appendix C:
Expand All @@ -62,7 +74,11 @@ pub fn cipher_round(block: &mut Block, round_key: &Block) {
intrinsics::cipher_round(block, round_key)
}

soft::cipher_round(block, round_key);
if_soft_backend_available! {
soft::cipher_round(block, round_key)
}

unreachable!();
}

/// ⚠️ AES cipher (encrypt) round function: parallel version.
Expand All @@ -79,7 +95,11 @@ pub fn cipher_round_par(blocks: &mut Block8, round_keys: &Block8) {
intrinsics::cipher_round_par(blocks, round_keys)
}

soft::cipher_round_par(blocks, round_keys);
if_soft_backend_available! {
soft::cipher_round_par(blocks, round_keys)
}

unreachable!();
}

/// ⚠️ AES equivalent inverse cipher (decrypt) round function.
Expand All @@ -102,7 +122,11 @@ pub fn equiv_inv_cipher_round(block: &mut Block, round_key: &Block) {
intrinsics::equiv_inv_cipher_round(block, round_key)
}

soft::equiv_inv_cipher_round(block, round_key);
if_soft_backend_available! {
soft::equiv_inv_cipher_round(block, round_key)
}

unreachable!();
}

/// ⚠️ AES equivalent inverse cipher (decrypt) round function: parallel version.
Expand All @@ -119,7 +143,11 @@ pub fn equiv_inv_cipher_round_par(blocks: &mut Block8, round_keys: &Block8) {
intrinsics::equiv_inv_cipher_round_par(blocks, round_keys)
}

soft::equiv_inv_cipher_round_par(blocks, round_keys);
if_soft_backend_available! {
soft::equiv_inv_cipher_round_par(blocks, round_keys)
}

unreachable!();
}

/// ⚠️ AES mix columns function.
Expand All @@ -133,7 +161,11 @@ pub fn mix_columns(block: &mut Block) {
intrinsics::mix_columns(block)
}

soft::mix_columns(block);
if_soft_backend_available! {
soft::mix_columns(block)
}

unreachable!();
}

/// ⚠️ AES inverse mix columns function.
Expand All @@ -149,5 +181,9 @@ pub fn inv_mix_columns(block: &mut Block) {
intrinsics::inv_mix_columns(block)
}

soft::inv_mix_columns(block);
if_soft_backend_available! {
soft::inv_mix_columns(block)
}

unreachable!();
}
53 changes: 40 additions & 13 deletions aes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,15 @@ macro_rules! impl_key_init {
}
}

let soft = backends::soft::$soft_name::new(key);
let inner = Inner { soft };
Self { inner, token }
cfg_if! {
if #[cfg(__enable_aes_soft_backend)] {
let soft = backends::soft::$soft_name::new(key);
let inner = Inner { soft };
return Self { inner, token };
} else {
unreachable!();
}
}
}
}
};
Expand Down Expand Up @@ -297,9 +303,15 @@ macro_rules! impl_encrypt {
}
}

// SAFETY: we access correct union variant
let backend = unsafe { &self.inner.soft };
f.call(backend);
cfg_if! {
if #[cfg(__enable_aes_soft_backend)] {
// SAFETY: we access correct union variant
let backend = unsafe { &self.inner.soft };
f.call(backend);
} else {
unreachable!();
}
}
}
}
};
Expand Down Expand Up @@ -347,9 +359,15 @@ macro_rules! impl_decrypt {
}
}

// SAFETY: we access correct union variant
let backend = unsafe { &self.inner.soft };
f.call(backend);
cfg_if! {
if #[cfg(__enable_aes_soft_backend)] {
// SAFETY: we access correct union variant
let backend = unsafe { &self.inner.soft };
f.call(backend);
} else {
unreachable!();
}
}
}
}
};
Expand Down Expand Up @@ -387,10 +405,16 @@ macro_rules! impl_from_enc {
}
}

// SAFETY: we access correct union variant
let soft = unsafe { enc.inner.soft };
let inner = Inner { soft };
Self { inner, token }
cfg_if! {
if #[cfg(__enable_aes_soft_backend)] {
// SAFETY: we access correct union variant
let soft = unsafe { enc.inner.soft };
let inner = Inner { soft };
Self { inner, token }
} else {
unreachable!();
}
}
}
}

Expand Down Expand Up @@ -457,6 +481,7 @@ macro_rules! define_aes_impl {
pub(super) aes: backends::x86_aes::$name,
#[cfg(all(target_arch = "aarch64", not(miri), not(aes_backend = "soft")))]
pub(super) aes: backends::aarch64_aes::$name,
#[cfg(__enable_aes_soft_backend)]
pub(super) soft: backends::soft::$name,
}

Expand All @@ -469,6 +494,7 @@ macro_rules! define_aes_impl {
pub(super) aes: backends::x86_aes::$name_enc,
#[cfg(all(target_arch = "aarch64", not(miri), not(aes_backend = "soft")))]
pub(super) aes: backends::aarch64_aes::$name_enc,
#[cfg(__enable_aes_soft_backend)]
pub(super) soft: backends::soft::$name,
}

Expand All @@ -481,6 +507,7 @@ macro_rules! define_aes_impl {
pub(super) aes: backends::x86_aes::$name_dec,
#[cfg(all(target_arch = "aarch64", not(miri), not(aes_backend = "soft")))]
pub(super) aes: backends::aarch64_aes::$name_dec,
#[cfg(__enable_aes_soft_backend)]
pub(super) soft: backends::soft::$name,
}
}
Expand Down