use core::arch::asm;
#[derive(Clone)]
#[repr(C, align(16))]
pub(super) struct RvRoundKeys {
rk: [[u8; 16]; 15],
}
impl RvRoundKeys {
pub(super) fn zeroize(&mut self) {
let bytes = unsafe { core::slice::from_raw_parts_mut(self.rk.as_mut_ptr().cast::<u8>(), 15usize.strict_mul(16)) };
crate::traits::ct::zeroize(bytes);
}
}
pub(super) fn from_portable(rk: &[u32; 60]) -> RvRoundKeys {
let mut keys = [[0u8; 16]; 15];
let mut i = 0usize;
while i < 15 {
let base = i.strict_mul(4);
keys[i][0..4].copy_from_slice(&rk[base].to_be_bytes());
keys[i][4..8].copy_from_slice(&rk[base.strict_add(1)].to_be_bytes());
keys[i][8..12].copy_from_slice(&rk[base.strict_add(2)].to_be_bytes());
keys[i][12..16].copy_from_slice(&rk[base.strict_add(3)].to_be_bytes());
i = i.strict_add(1);
}
RvRoundKeys { rk: keys }
}
#[target_feature(enable = "v", enable = "zvkned")]
pub(super) unsafe fn encrypt_block(keys: &RvRoundKeys, block: &mut [u8; 16]) {
unsafe {
let block_ptr = block.as_mut_ptr();
let rk = &keys.rk;
asm!(
"vsetivli zero, 4, e32, m1, ta, ma",
"vle32.v v1, ({block})",
"vle32.v v2, ({rk0})",
"vaesz.vs v1, v2",
"vle32.v v2, ({rk1})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk2})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk3})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk4})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk5})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk6})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk7})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk8})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk9})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk10})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk11})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk12})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk13})",
"vaesem.vs v1, v2",
"vle32.v v2, ({rk14})",
"vaesef.vs v1, v2",
"vse32.v v1, ({block})",
block = in(reg) block_ptr,
rk0 = in(reg) rk[0].as_ptr(),
rk1 = in(reg) rk[1].as_ptr(),
rk2 = in(reg) rk[2].as_ptr(),
rk3 = in(reg) rk[3].as_ptr(),
rk4 = in(reg) rk[4].as_ptr(),
rk5 = in(reg) rk[5].as_ptr(),
rk6 = in(reg) rk[6].as_ptr(),
rk7 = in(reg) rk[7].as_ptr(),
rk8 = in(reg) rk[8].as_ptr(),
rk9 = in(reg) rk[9].as_ptr(),
rk10 = in(reg) rk[10].as_ptr(),
rk11 = in(reg) rk[11].as_ptr(),
rk12 = in(reg) rk[12].as_ptr(),
rk13 = in(reg) rk[13].as_ptr(),
rk14 = in(reg) rk[14].as_ptr(),
out("v1") _,
out("v2") _,
options(nostack),
);
}
}