[kgm] feat #2: basic kgm support

This commit is contained in:
鲁树人
2024-09-15 22:15:02 +01:00
parent 2222e7bc50
commit 7b4464bacd
16 changed files with 273 additions and 3 deletions

View File

@@ -0,0 +1,59 @@
use crate::v2::DecipherV2;
use crate::v3::DecipherV3;
use crate::{Decipher, KugouError};
use byteorder::{ByteOrder, LE};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Header {
pub magic: [u8; 0x10],
pub offset_to_data: usize,
pub crypto_version: u32,
pub key_slot: u32,
pub decrypt_test_data: [u8; 0x10],
pub file_key: [u8; 0x10],
}
impl Header {
pub fn from_buffer<T>(buffer: T) -> Result<Self, KugouError>
where
T: AsRef<[u8]>,
{
let buffer = buffer.as_ref();
if buffer.len() < 0x3c {
Err(KugouError::HeaderTooSmall(0x3c))?;
}
let mut magic = [0u8; 0x10];
magic.copy_from_slice(&buffer[..0x10]);
let offset_to_data = LE::read_u32(&buffer[0x10..0x14]) as usize;
let crypto_version = LE::read_u32(&buffer[0x14..0x18]);
let key_slot = LE::read_u32(&buffer[0x18..0x1C]);
let mut decrypt_test_data = [0u8; 0x10];
decrypt_test_data.copy_from_slice(&buffer[0x1c..0x2c]);
let mut file_key = [0u8; 0x10];
file_key.copy_from_slice(&buffer[0x2c..0x3c]);
Ok(Self {
magic,
offset_to_data,
crypto_version,
key_slot,
decrypt_test_data,
file_key,
})
}
pub fn make_decipher(&self) -> Result<Box<dyn Decipher>, KugouError> {
let slot_key: &[u8] = match self.key_slot {
1 => b"l,/'",
slot => Err(KugouError::UnsupportedKeySlot(slot))?,
};
let decipher: Box<dyn Decipher> = match self.crypto_version {
2 => Box::from(DecipherV2::new(self, slot_key)?),
3 => Box::from(DecipherV3::new(self, slot_key)?),
version => Err(KugouError::UnsupportedCipherVersion(version))?,
};
Ok(decipher)
}
}