use soft_aes::aes::aes_cmac;
use std::error::Error;
const AES_128_KDI_KBEK: [u8; 8] = [0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80];
const AES_128_KDI_KBAK: [u8; 8] = [0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x80];
const AES_192_KDI_KBEK_1: [u8; 8] = [0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xC0];
const AES_192_KDI_KBEK_2: [u8; 8] = [0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xC0];
const AES_192_KDI_KBAK_1: [u8; 8] = [0x01, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0xC0];
const AES_192_KDI_KBAK_2: [u8; 8] = [0x02, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0xC0];
const AES_256_KDI_KBEK_1: [u8; 8] = [0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00];
const AES_256_KDI_KBEK_2: [u8; 8] = [0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00];
const AES_256_KDI_KBAK_1: [u8; 8] = [0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00];
const AES_256_KDI_KBAK_2: [u8; 8] = [0x02, 0x00, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00];
pub fn derive_keys_version_d(kbpk: &[u8]) -> Result<(Vec<u8>, Vec<u8>), Box<dyn Error>> {
match kbpk.len() {
16 => {
let kbek = aes_cmac(&AES_128_KDI_KBEK, kbpk)?.to_vec();
let kbak = aes_cmac(&AES_128_KDI_KBAK, kbpk)?.to_vec();
Ok((kbek, kbak))
}
24 => {
let mut kbek = aes_cmac(&AES_192_KDI_KBEK_1, kbpk)?.to_vec();
kbek.extend_from_slice(&aes_cmac(&AES_192_KDI_KBEK_2, kbpk)?.to_vec());
kbek.truncate(24);
let mut kbak = aes_cmac(&AES_192_KDI_KBAK_1, kbpk)?.to_vec();
kbak.extend_from_slice(&aes_cmac(&AES_192_KDI_KBAK_2, kbpk)?.to_vec());
kbak.truncate(24);
Ok((kbek, kbak))
}
32 => {
let mut kbek = aes_cmac(&AES_256_KDI_KBEK_1, kbpk)?.to_vec();
kbek.extend_from_slice(&aes_cmac(&AES_256_KDI_KBEK_2, kbpk)?.to_vec());
let mut kbak = aes_cmac(&AES_256_KDI_KBAK_1, kbpk)?.to_vec();
kbak.extend_from_slice(&aes_cmac(&AES_256_KDI_KBAK_2, kbpk)?.to_vec());
Ok((kbek, kbak))
}
_ => Err("ERROR TR-31: Invalid KBPK length".into()),
}
}