use aesni::Aes128;
use byteorder::{BigEndian, ByteOrder};
use cmac::Cmac;
use cmac::crypto_mac::Mac;
use super::{Context, KEY_SIZE};
pub fn derive(
mac_key: &[u8; KEY_SIZE],
derivation_constant: u8,
context: &Context,
output: &mut [u8],
) {
let output_len = output.len();
assert!(
output_len <= 16,
"up to 16-bytes of data supported ({} requested)",
output_len
);
let mut derivation_data = [0u8; 32];
derivation_data[11] = derivation_constant;
derivation_data[12] = 0x00;
BigEndian::write_u16(&mut derivation_data[13..15], (output_len * 8) as u16);
derivation_data[15] = 0x01;
derivation_data[16..].copy_from_slice(context.as_slice());
let mut mac = Cmac::<Aes128>::new_varkey(mac_key.as_ref()).unwrap();
mac.input(&derivation_data);
output.copy_from_slice(&mac.result().code().as_slice()[..output_len]);
}