use crate::aes::aes_g;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Vuk(pub [u8; 16]);
impl Vuk {
pub fn from_bytes(bytes: [u8; 16]) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8; 16] {
&self.0
}
}
pub fn derive_vuk(media_key: &[u8; 16], volume_id: &[u8; 16]) -> Vuk {
Vuk(aes_g(media_key, volume_id))
}
pub fn disc_id_from_unit_key_file_bytes(bytes: &[u8]) -> [u8; 20] {
use sha1::{Digest, Sha1};
let mut h = Sha1::new();
h.update(bytes);
let d = h.finalize();
let mut out = [0u8; 20];
out.copy_from_slice(&d);
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vuk_derivation_is_deterministic() {
let km = [0xAAu8; 16];
let idv = [0x55u8; 16];
let a = derive_vuk(&km, &idv);
let b = derive_vuk(&km, &idv);
assert_eq!(a, b);
}
#[test]
fn different_media_keys_yield_different_vuks() {
let km1 = [0x01u8; 16];
let km2 = [0x02u8; 16];
let idv = [0xFFu8; 16];
assert_ne!(derive_vuk(&km1, &idv), derive_vuk(&km2, &idv));
}
}