use super::keys;
pub use generic_array;
use generic_array::GenericArray;
pub fn calculate_data_mic<M: keys::Mac>(data: &[u8], key: M, fcnt: u32) -> keys::MIC {
let mut header = [0; 16];
generate_helper_block(data, 0x49, fcnt, &mut header[..16]);
header[15] = data.len() as u8;
calculate_mic_with_header(&header[..], data, key)
}
fn generate_helper_block(data: &[u8], first: u8, fcnt: u32, res: &mut [u8]) {
res[0] = first;
res[5] = (data[0] & 0x20) >> 5;
res[6..10].copy_from_slice(&data[1..5]);
res[10] = (fcnt & 0xff) as u8;
res[11] = ((fcnt >> 8) & 0xff) as u8;
res[12] = ((fcnt >> 16) & 0xff) as u8;
res[13] = ((fcnt >> 24) & 0xff) as u8;
}
fn calculate_mic_with_header<M: keys::Mac>(header: &[u8], data: &[u8], mic: M) -> keys::MIC {
let mut cipher = mic;
cipher.input(header);
cipher.input(data);
let result = cipher.result();
let mut mic = [0u8; 4];
mic.copy_from_slice(&result[0..4]);
keys::MIC(mic)
}
pub fn calculate_mic<M: keys::Mac>(data: &[u8], key: M) -> keys::MIC {
calculate_mic_with_header(&[], data, key)
}
pub fn encrypt_frm_data_payload(
phy_payload: &mut [u8],
start: usize,
end: usize,
fcnt: u32,
aes_enc: &dyn keys::Encrypter,
) {
let len = end - start;
let mut a = [0u8; 16];
generate_helper_block(phy_payload, 0x01, fcnt, &mut a[..]);
let mut s = [0u8; 16];
let mut s_block = GenericArray::from_mut_slice(&mut s[..]);
let mut ctr = 1;
for i in 0..len {
let j = i & 0x0f;
if j == 0 {
a[15] = ctr;
ctr += 1;
s_block.copy_from_slice(&a);
aes_enc.encrypt_block(&mut s_block);
}
phy_payload[start + i] ^= s_block[j]
}
}