use crate::aacs;
use crate::css;
#[derive(Clone)]
pub enum DecryptKeys {
None,
Aacs {
unit_keys: Vec<(u32, [u8; 16])>,
read_data_key: Option<[u8; 16]>,
},
Css { title_key: [u8; 5] },
}
impl DecryptKeys {
pub fn is_encrypted(&self) -> bool {
!matches!(self, DecryptKeys::None)
}
}
pub fn decrypt_sectors(
buf: &mut [u8],
keys: &DecryptKeys,
unit_key_idx: usize,
) -> Result<(), crate::error::Error> {
match keys {
DecryptKeys::None => {}
DecryptKeys::Aacs {
unit_keys,
read_data_key,
} => {
let uk = match unit_keys.get(unit_key_idx) {
Some((_, k)) => *k,
None => {
return Err(crate::error::Error::DecryptFailed {
reason: format!(
"unit_key_idx {} out of range (have {} keys)",
unit_key_idx,
unit_keys.len()
),
});
}
};
let rdk = read_data_key.as_ref();
let unit_len = aacs::ALIGNED_UNIT_LEN;
for chunk in buf.chunks_mut(unit_len) {
if chunk.len() == unit_len && aacs::is_unit_encrypted(chunk) {
aacs::decrypt_unit_full(chunk, &uk, rdk);
}
}
}
DecryptKeys::Css { title_key } => {
for chunk in buf.chunks_mut(2048) {
css::lfsr::descramble_sector(title_key, chunk);
}
}
}
Ok(())
}