#![no_std]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg"
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![warn(missing_docs, rust_2018_idioms)]
#[cfg(feature = "hazmat")]
pub mod hazmat;
#[macro_use]
mod macros;
mod soft;
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(all(target_arch = "aarch64", not(aes_force_soft)))] {
mod armv8;
mod autodetect;
pub use autodetect::*;
} else if #[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(aes_force_soft)
))] {
mod autodetect;
mod ni;
pub use autodetect::*;
} else {
pub use soft::*;
}
}
pub use cipher;
use cipher::{array::Array, consts::U16, crypto_common::WeakKeyError};
pub type Block = Array<u8, U16>;
pub(crate) fn weak_key_test<const N: usize>(key: &[u8; N]) -> Result<(), WeakKeyError> {
let t = match N {
16 => u64::from_ne_bytes(key[..8].try_into().unwrap()),
24 => {
let t1 = u64::from_ne_bytes(key[..8].try_into().unwrap());
let t2 = u32::from_ne_bytes(key[8..12].try_into().unwrap());
t1 | u64::from(t2)
}
32 => {
let t1 = u64::from_ne_bytes(key[..8].try_into().unwrap());
let t2 = u64::from_ne_bytes(key[8..16].try_into().unwrap());
t1 | t2
}
_ => unreachable!(),
};
match t {
0 => Err(WeakKeyError),
_ => Ok(()),
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "zeroize")]
#[test]
fn zeroize_works() {
use super::soft;
fn test_for<T: zeroize::ZeroizeOnDrop>(val: T) {
use core::mem::{ManuallyDrop, size_of};
let mut val = ManuallyDrop::new(val);
let ptr = &val as *const _ as *const u8;
let len = size_of::<ManuallyDrop<T>>();
unsafe { ManuallyDrop::drop(&mut val) };
let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
assert!(slice.iter().all(|&byte| byte == 0));
}
let key_128 = [42; 16].into();
let key_192 = [42; 24].into();
let key_256 = [42; 32].into();
use cipher::KeyInit as _;
test_for(soft::Aes128::new(&key_128));
test_for(soft::Aes128Enc::new(&key_128));
test_for(soft::Aes128Dec::new(&key_128));
test_for(soft::Aes192::new(&key_192));
test_for(soft::Aes192Enc::new(&key_192));
test_for(soft::Aes192Dec::new(&key_192));
test_for(soft::Aes256::new(&key_256));
test_for(soft::Aes256Enc::new(&key_256));
test_for(soft::Aes256Dec::new(&key_256));
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), not(aes_force_soft)))]
{
use super::ni;
cpufeatures::new!(aes_intrinsics, "aes");
if aes_intrinsics::get() {
test_for(ni::Aes128::new(&key_128));
test_for(ni::Aes128Enc::new(&key_128));
test_for(ni::Aes128Dec::new(&key_128));
test_for(ni::Aes192::new(&key_192));
test_for(ni::Aes192Enc::new(&key_192));
test_for(ni::Aes192Dec::new(&key_192));
test_for(ni::Aes256::new(&key_256));
test_for(ni::Aes256Enc::new(&key_256));
test_for(ni::Aes256Dec::new(&key_256));
}
}
#[cfg(all(target_arch = "aarch64", not(aes_force_soft)))]
{
use super::armv8;
cpufeatures::new!(aes_intrinsics, "aes");
if aes_intrinsics::get() {
test_for(armv8::Aes128::new(&key_128));
test_for(armv8::Aes128Enc::new(&key_128));
test_for(armv8::Aes128Dec::new(&key_128));
test_for(armv8::Aes192::new(&key_192));
test_for(armv8::Aes192Enc::new(&key_192));
test_for(armv8::Aes192Dec::new(&key_192));
test_for(armv8::Aes256::new(&key_256));
test_for(armv8::Aes256Enc::new(&key_256));
test_for(armv8::Aes256Dec::new(&key_256));
}
}
}
}