use super::cpu::HaveCryptoExt;
use crate::low;
unsafe extern "C" {
#[link_name = aws_lc_symbol!("gcm_init_v8")]
fn gcm_init_v8(htable: *mut GhashTable, h: *const [u64; 2]);
#[link_name = aws_lc_symbol!("gcm_ghash_v8")]
fn gcm_ghash_v8(xi: *mut [u8; 16], htable: *const GhashTable, input: *const u8, len: usize);
}
core::arch::global_asm!(
".text",
".fpu neon",
".code 32",
include_str!("aws_lc/ghashv8-armx.s"),
".fpu vfpv3",
gcm_init_v8 = sym gcm_init_v8,
gcm_ghash_v8 = sym gcm_ghash_v8,
);
#[repr(C, align(16))]
pub(crate) struct GhashTable([[u64; 2]; 16]);
impl GhashTable {
pub(crate) fn new(h: &[u8; 16], _: HaveCryptoExt) -> Self {
let (hi, lo) = h.split_at(8);
let h = [
u64::from_be_bytes(hi.try_into().unwrap()),
u64::from_be_bytes(lo.try_into().unwrap()),
];
let mut r = Self([[0; 2]; 16]);
unsafe { gcm_init_v8(&mut r, &h) };
r
}
pub(crate) fn ghash(&self, xi: &mut [u8; 16], input: &[[u8; 16]]) {
if input.is_empty() {
return;
}
unsafe { gcm_ghash_v8(xi, self, input.as_ptr().cast(), size_of_val(input)) }
}
}
impl Drop for GhashTable {
fn drop(&mut self) {
low::zeroise_value(self);
}
}
impl low::generic::zeroise::Zeroable for GhashTable {}