1use crate::{
16 bb,
17 polyfill::{slice::AsChunks, ArraySplitMap},
18};
19
20pub(in super::super) const BLOCK_LEN: usize = 16;
21pub(in super::super) type Block = [u8; BLOCK_LEN];
22pub(super) const ZERO_BLOCK: Block = [0u8; BLOCK_LEN];
23
24#[cfg(any(
25 all(target_arch = "aarch64", target_endian = "little"),
26 all(target_arch = "arm", target_endian = "little"),
27 target_arch = "x86",
28 target_arch = "x86_64"
29))]
30macro_rules! htable_new {
31 ( $name:ident, $value:expr $(,)? ) => {{
32 use crate::aead::gcm::ffi::HTable;
33 prefixed_extern! {
34 fn $name(HTable: &mut HTable, h: &[u64; 2]);
35 }
36 HTable::new($name, $value)
37 }};
38}
39
40#[cfg(any(
44 all(target_arch = "aarch64", target_endian = "little"),
45 all(target_arch = "arm", target_endian = "little"),
46 target_arch = "x86",
47 target_arch = "x86_64"
48))]
49macro_rules! ghash {
50 ( $name:ident, $xi:expr, $h_table:expr, $input:expr $(,)? ) => {{
51 use crate::aead::gcm::ffi::{HTable, Xi};
52 prefixed_extern! {
53 fn $name(
54 xi: &mut Xi,
55 Htable: &HTable,
56 inp: *const u8,
57 len: crate::c::NonZero_size_t,
58 );
59 }
60 $h_table.ghash($name, $xi, $input)
61 }};
62}
63
64pub(in super::super) struct KeyValue([u64; 2]);
65
66impl KeyValue {
67 pub(in super::super) fn new(value: Block) -> Self {
68 Self(value.array_split_map(u64::from_be_bytes))
69 }
70
71 pub(super) fn into_inner(self) -> [u64; 2] {
72 self.0
73 }
74}
75
76#[cfg(any(
81 all(target_arch = "aarch64", target_endian = "little"),
82 all(target_arch = "arm", target_endian = "little"),
83 target_arch = "x86",
84 target_arch = "x86_64"
85))]
86impl HTable {
87 pub(super) unsafe fn new(
88 init: unsafe extern "C" fn(HTable: &mut HTable, &[u64; 2]),
89 value: KeyValue,
90 ) -> Self {
91 let mut r = Self {
92 Htable: [U128 { hi: 0, lo: 0 }; HTABLE_LEN],
93 };
94 unsafe { init(&mut r, &value.0) };
95 r
96 }
97
98 #[cfg(any(
99 all(target_arch = "aarch64", target_endian = "little"),
100 all(target_arch = "arm", target_endian = "little")
101 ))]
102 pub(super) unsafe fn gmult(
103 &self,
104 f: unsafe extern "C" fn(xi: &mut Xi, h_table: &HTable),
105 xi: &mut Xi,
106 ) {
107 unsafe { f(xi, self) }
108 }
109
110 pub(super) unsafe fn ghash(
111 &self,
112 f: unsafe extern "C" fn(
113 xi: &mut Xi,
114 Htable: &HTable,
115 inp: *const u8,
116 len: crate::c::NonZero_size_t,
117 ),
118 xi: &mut Xi,
119 input: AsChunks<u8, BLOCK_LEN>,
120 ) {
121 use core::num::NonZeroUsize;
122
123 let input = input.as_flattened();
124
125 let input_len = match NonZeroUsize::new(input.len()) {
126 Some(len) => len,
127 None => {
128 return;
129 }
130 };
131
132 unsafe {
136 f(xi, self, input.as_ptr(), input_len);
137 }
138 }
139}
140
141#[derive(Clone)]
143#[repr(C, align(16))]
144pub(in super::super) struct HTable {
145 Htable: [U128; HTABLE_LEN],
146}
147
148#[derive(Clone, Copy)]
149#[repr(C)]
150pub(super) struct U128 {
151 pub(super) hi: u64,
152 pub(super) lo: u64,
153}
154
155const HTABLE_LEN: usize = 16;
156
157#[repr(transparent)]
158pub(in super::super) struct Xi(pub(super) Block);
159
160impl Xi {
161 #[inline]
162 pub(super) fn bitxor_assign(&mut self, a: Block) {
163 self.0 = bb::xor_16(self.0, a)
164 }
165}