use crate::low;
#[repr(C, align(16))]
pub(crate) struct VpaesKey {
rd_key: [u32; 60],
rounds: u32,
}
impl VpaesKey {
pub(crate) fn new(key: &[u8]) -> Self {
let bits = match key.len() {
16 => 128,
32 => 256,
_ => unreachable!("callers check the AES key length"),
};
let mut r = Self {
rd_key: [0; 60],
rounds: 0,
};
let ret = unsafe { vpaes_set_encrypt_key(key.as_ptr(), bits, &mut r) };
debug_assert_eq!(ret, 0);
r
}
pub(crate) fn encrypt_block(&self, inout: &mut [u8; 16]) {
unsafe { vpaes_encrypt(inout.as_ptr(), inout.as_mut_ptr(), self) }
}
pub(crate) fn ctr32(&self, ivec: &[u8; 16], inout: &mut [[u8; 16]]) {
unsafe {
vpaes_ctr32_encrypt_blocks(
inout.as_ptr().cast(),
inout.as_mut_ptr().cast(),
inout.len(),
self,
ivec,
)
}
}
}
impl Drop for VpaesKey {
fn drop(&mut self) {
low::zeroise_value(self);
}
}
impl low::generic::zeroise::Zeroable for VpaesKey {}
#[repr(C, align(128))]
struct Consts([u64; 94]);
static VPAES_CONSTS: Consts = Consts(include!("aws_lc/vpaes-armv8.vpaes_consts.rs"));
macro_rules! vpaes_routine {
($name:ident($($arg:ident: $ty:ty),*) $(-> $ret:ty)? { $($op:ident = $sym:ident),* }) => {
#[unsafe(naked)]
unsafe extern "C" fn $name($($arg: $ty),*) $(-> $ret)? {
#[cfg(not(target_vendor = "apple"))]
core::arch::naked_asm!(
include_str!(concat!("aws_lc/", stringify!($name), ".linux.s"))
$(, $op = sym $sym)*
);
#[cfg(target_vendor = "apple")]
core::arch::naked_asm!(
include_str!(concat!("aws_lc/", stringify!($name), ".apple.s"))
$(, $op = sym $sym)*
);
}
};
}
vpaes_routine!(vpaes_set_encrypt_key(user_key: *const u8, bits: u32, key: *mut VpaesKey) -> i32 {
vpaes_schedule_core = vpaes_schedule_core
});
vpaes_routine!(vpaes_encrypt(input: *const u8, output: *mut u8, key: *const VpaesKey) {
vpaes_encrypt_preheat = vpaes_encrypt_preheat,
vpaes_encrypt_core = vpaes_encrypt_core
});
vpaes_routine!(vpaes_ctr32_encrypt_blocks(
input: *const u8,
output: *mut u8,
blocks: usize,
key: *const VpaesKey,
ivec: *const [u8; 16]
) {
vpaes_encrypt_preheat = vpaes_encrypt_preheat,
vpaes_encrypt_core = vpaes_encrypt_core,
vpaes_encrypt_2x = vpaes_encrypt_2x
});
vpaes_routine!(vpaes_encrypt_preheat() { vpaes_consts = VPAES_CONSTS });
vpaes_routine!(vpaes_encrypt_core() { vpaes_consts = VPAES_CONSTS });
vpaes_routine!(vpaes_encrypt_2x() { vpaes_consts = VPAES_CONSTS });
vpaes_routine!(vpaes_key_preheat() { vpaes_consts = VPAES_CONSTS });
vpaes_routine!(vpaes_schedule_core() {
vpaes_consts = VPAES_CONSTS,
vpaes_key_preheat = vpaes_key_preheat,
vpaes_schedule_192_smear = vpaes_schedule_192_smear,
vpaes_schedule_round = vpaes_schedule_round,
vpaes_schedule_low_round = vpaes_schedule_low_round,
vpaes_schedule_transform = vpaes_schedule_transform,
vpaes_schedule_mangle = vpaes_schedule_mangle
});
vpaes_routine!(vpaes_schedule_192_smear() {});
vpaes_routine!(vpaes_schedule_round() {});
vpaes_routine!(vpaes_schedule_low_round() {});
vpaes_routine!(vpaes_schedule_transform() {});
vpaes_routine!(vpaes_schedule_mangle() {});