diff --git a/msg_tool_xp3data/crypt.json b/msg_tool_xp3data/crypt.json index 97e8d4e..d8c3c6e 100644 --- a/msg_tool_xp3data/crypt.json +++ b/msg_tool_xp3data/crypt.json @@ -1554,7 +1554,8 @@ }, { "Key": "kHMdDweFjeDFVTwQA10XQAPUAOfXzKp2ukygeLzGzHg=", - "Nonce": "CSBjzSXQNTioPhDp710WCQ==" + "Nonce": "CSBjzSXQNTioPhDp710WCQ==", + "FilterKey": 13089994567570788352 } ], "FilterKey": 8093658935271803197, @@ -1668,6 +1669,33 @@ "$type": "HashCrypt", "Title": "愛娘は、マゾ性隷 ~娘だからって遠慮しないでね?~" }, + "Mashiro-iro Symphony": { + "$type": "HxCrypt", + "Mask": 284, + "Offset": 389, + "PrologOrder": "AQIA", + "OddBranchOrder": "BQABBAID", + "EvenBranchOrder": "AQYFAAcCBAM=", + "IndexKey1": { + "Key": "pWVnGBsl5MFeR3EH2yJwHx2ZvHkWDxQhIhODqqdxMMo=", + "Nonce": "JClYlfgFkP8dN6oa3iOrAw==" + }, + "IndexKey2": [ + { + "Key": "q0lPvHOK7Qa4OM615uOvyTInTJf8aYpS/jcpM1uNnuo=", + "Nonce": "1KoS7cnIicdp1hZ0bjlduw==" + }, + { + "Key": "kUUY3z8D94i85yssB5xRBZmSiKRNABPPAl88Qtf7Ix0=", + "Nonce": "+Hg91OLLC9E4ET7YbHMHsA==", + "FilterKey": 14361241883570560968 + } + ], + "FilterKey": 1449527129867772322, + "RandomType": 1, + "ControlBlockName": "mashiro.bin", + "Title": "Mashiro-iro Symphony -Love is pure white- Remake for FHD | Mashiro-iro Symphony: Sana Edition | ましろ色シンフォニー -Love is pure white- Remake for FHD | 纯白交响曲 -Love is pure white- HD Remake | 純白交響曲 -Love is pure white- HD Remake | ましろ色シンフォニー SANA EDITION | 纯白交响曲 SANA EDITION | 純白交響曲 SANA EDITION" + }, "Me ga Sametara Seieki ga 100 Bai...": { "$type": "DieselmineCrypt", "Title": "目が覚めたら精液が100倍溜まる身体になってた→大量注入!" diff --git a/msg_tool_xp3data/cx_cb/mashiro.bin b/msg_tool_xp3data/cx_cb/mashiro.bin new file mode 100644 index 0000000..43ddb72 Binary files /dev/null and b/msg_tool_xp3data/cx_cb/mashiro.bin differ diff --git a/src/scripts/kirikiri/archive/xp3/crypt/cx.rs b/src/scripts/kirikiri/archive/xp3/crypt/cx.rs index bf2bcf2..b50e2cc 100644 --- a/src/scripts/kirikiri/archive/xp3/crypt/cx.rs +++ b/src/scripts/kirikiri/archive/xp3/crypt/cx.rs @@ -1,4 +1,5 @@ use super::*; +use crate::ext::atomic::AtomicQuick; use crate::ext::mutex::MutexExt; use crate::utils::files::*; use crate::utils::struct_pack::*; @@ -8,6 +9,7 @@ use serde::{Deserializer, de}; use std::collections::HashSet; use std::ops::{Deref, DerefMut, Index}; use std::path::PathBuf; +use std::sync::atomic::AtomicU64; use std::sync::{Mutex, Weak}; const S_CTL_BLOCK_SIGNATURE: &[u8] = b" Encryption control block"; @@ -2032,7 +2034,7 @@ pub struct HxCrypt { base: CxEncryption, key1: IndexKey, key2: IndexKeys, - filter_key: u64, + filter_key: AtomicU64, file_mapping: HashMap, path_mapping: HashMap, info_map: Mutex>, @@ -2042,6 +2044,7 @@ pub struct HxCrypt { pub struct IndexKey { key: [u8; 32], nonce: [u8; 16], + filter_key: Option, } impl std::fmt::Debug for IndexKey { @@ -2049,6 +2052,7 @@ impl std::fmt::Debug for IndexKey { f.debug_struct("IndexKey") .field("key", &hex::encode(&self.key)) .field("nonce", &hex::encode(&self.nonce)) + .field("filter_key", &self.filter_key) .finish() } } @@ -2058,6 +2062,8 @@ impl std::fmt::Debug for IndexKey { struct IndexKeyTmp { key: String, nonce: String, + #[serde(default)] + filter_key: Option, } impl<'de> Deserialize<'de> for IndexKey { @@ -2081,7 +2087,11 @@ impl<'de> Deserialize<'de> for IndexKey { bytes.len() )) })?; - Ok(Self { key, nonce }) + Ok(Self { + key, + nonce, + filter_key: s.filter_key, + }) } } @@ -2168,7 +2178,7 @@ impl HxCrypt { )?, key1: index_key1.clone(), key2: index_key2.clone(), - filter_key, + filter_key: AtomicU64::new(filter_key), file_mapping: file_map, path_mapping: path_map, info_map: Mutex::new(HashMap::new()), @@ -2262,6 +2272,9 @@ impl HxCrypt { 1 => &self.key1, _ => anyhow::bail!("Unknown hxv4 flags: {}", flags), }; + if let Some(filter_key) = &key.filter_key { + self.filter_key.qsave(*filter_key); + } let mut nonce = [0; 8]; nonce.copy_from_slice(&key.nonce[..8]); let mut crypt = ChaCha20Legacy::new((&key.key).into(), (&nonce).into()); @@ -2494,7 +2507,7 @@ impl Crypt for HxCrypt { .ok_or_else(|| anyhow::anyhow!("extra info is not hx entry."))?; let mut entry_key = info.key; if (info.id & 0x100000000) == 0 { - entry_key ^= self.filter_key; + entry_key ^= self.filter_key.qload(); } let header_key = !entry_key; let key = self.create_filter_key(entry_key, header_key)?; @@ -2521,7 +2534,7 @@ impl Crypt for HxCrypt { .ok_or_else(|| anyhow::anyhow!("extra info is not hx entry."))?; let mut entry_key = info.key; if (info.id & 0x100000000) == 0 { - entry_key ^= self.filter_key; + entry_key ^= self.filter_key.qload(); } let header_key = !entry_key; let key = self.create_filter_key(entry_key, header_key)?;