From 92a52c1565d35c34fa899798b6c44657da8dd45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E6=A0=91=E4=BA=BA?= Date: Sun, 15 Sep 2024 23:53:00 +0100 Subject: [PATCH] [kgm] feat: add decipher self-test on startup --- um_crypto/kgm/src/header.rs | 36 ++++++++++++++++++++++++++++++++++++ um_crypto/kgm/src/lib.rs | 6 ++++++ 2 files changed, 42 insertions(+) diff --git a/um_crypto/kgm/src/header.rs b/um_crypto/kgm/src/header.rs index 5526049..b1ef1eb 100644 --- a/um_crypto/kgm/src/header.rs +++ b/um_crypto/kgm/src/header.rs @@ -11,6 +11,8 @@ pub struct Header { pub key_slot: u32, pub decrypt_test_data: [u8; 0x10], pub file_key: [u8; 0x10], + + challenge_data: [u8; 0x10], } impl Header { @@ -25,6 +27,8 @@ impl Header { let mut magic = [0u8; 0x10]; magic.copy_from_slice(&buffer[..0x10]); + let challenge_data = get_challenge_data(&magic)?; + 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]); @@ -40,6 +44,7 @@ impl Header { key_slot, decrypt_test_data, file_key, + challenge_data, }) } @@ -54,6 +59,37 @@ impl Header { 3 => Box::from(DecipherV3::new(self, slot_key)?), version => Err(KugouError::UnsupportedCipherVersion(version))?, }; + + let mut test_data = self.decrypt_test_data; + decipher.decrypt(&mut test_data, 0); + if self.challenge_data != test_data { + Err(KugouError::SelfTestFailed)?; + } + Ok(decipher) } } + +fn get_challenge_data(magic_header: &[u8; 0x10]) -> Result<[u8; 0x10], KugouError> { + match magic_header { + &KGM_HEADER => Ok(KGM_TEST_DATA), + &VPR_HEADER => Ok(VPR_TEST_DATA), + _ => Err(KugouError::NotKGMFile)?, + } +} + +pub const KGM_HEADER: [u8; 16] = [ + 0x7C, 0xD5, 0x32, 0xEB, 0x86, 0x02, 0x7F, 0x4B, 0xA8, 0xAF, 0xA6, 0x8E, 0x0F, 0xFF, 0x99, 0x14, +]; + +pub const KGM_TEST_DATA: [u8; 16] = [ + 0x38, 0x85, 0xED, 0x92, 0x79, 0x5F, 0xF8, 0x4C, 0xB3, 0x03, 0x61, 0x41, 0x16, 0xA0, 0x1D, 0x47, +]; + +pub const VPR_HEADER: [u8; 16] = [ + 0x05, 0x28, 0xBC, 0x96, 0xE9, 0xE4, 0x5A, 0x43, 0x91, 0xAA, 0xBD, 0xD0, 0x7A, 0xF5, 0x36, 0x31, +]; + +pub const VPR_TEST_DATA: [u8; 16] = [ + 0x1D, 0x5A, 0x05, 0x34, 0x0C, 0x41, 0x8D, 0x42, 0x9C, 0x83, 0x92, 0x6C, 0xAE, 0x16, 0xFE, 0x56, +]; diff --git a/um_crypto/kgm/src/lib.rs b/um_crypto/kgm/src/lib.rs index 80ccaaa..7af6573 100644 --- a/um_crypto/kgm/src/lib.rs +++ b/um_crypto/kgm/src/lib.rs @@ -14,6 +14,12 @@ pub enum KugouError { #[error("Unsupported cipher version: {0}")] UnsupportedCipherVersion(u32), + + #[error("Not KGM File (magic mismatch)")] + NotKGMFile, + + #[error("Unsupported cipher (self-test failed)")] + SelfTestFailed, } pub trait Decipher {