mirror of
https://github.com/redstrate/Kawari.git
synced 2025-06-30 19:57:46 +00:00
This reads the unknown packet data, just throwing it in a byte buffer. This allows us to read the rest of the segmenets in the packet, and fixes parsing. Note that this still log spams with "wrong size" as we can't determine the size of the unknown packet ahead of time. This is easy to fix, but it's not a high priority yet. Fixes #73
80 lines
2.2 KiB
Rust
80 lines
2.2 KiB
Rust
use std::io::Cursor;
|
|
|
|
use binrw::BinResult;
|
|
|
|
use crate::{GAME_VERSION, blowfish::Blowfish};
|
|
|
|
use super::ReadWriteIpcSegment;
|
|
|
|
pub fn generate_encryption_key(key: &[u8], phrase: &str) -> [u8; 16] {
|
|
let mut base_key = vec![0x78, 0x56, 0x34, 0x12];
|
|
base_key.extend_from_slice(key);
|
|
base_key.extend_from_slice(&GAME_VERSION.to_le_bytes());
|
|
base_key.extend_from_slice(&[0; 2]); // padding (possibly for game version?)
|
|
base_key.extend_from_slice(phrase.as_bytes());
|
|
|
|
md5::compute(&base_key).0
|
|
}
|
|
|
|
#[binrw::parser(reader, endian)]
|
|
pub(crate) fn decrypt<T: ReadWriteIpcSegment>(
|
|
size: u32,
|
|
encryption_key: Option<&[u8]>,
|
|
) -> BinResult<T> {
|
|
if let Some(encryption_key) = encryption_key {
|
|
let size = size - (std::mem::size_of::<u32>() * 4) as u32; // 16 = header size
|
|
|
|
let mut data = vec![0; size as usize];
|
|
reader.read_exact(&mut data)?;
|
|
|
|
let blowfish = Blowfish::new(encryption_key);
|
|
blowfish.decrypt(&mut data);
|
|
|
|
let mut cursor = Cursor::new(&data);
|
|
T::read_options(&mut cursor, endian, (&size,))
|
|
} else {
|
|
T::read_options(reader, endian, (&size,))
|
|
}
|
|
}
|
|
|
|
#[binrw::writer(writer, endian)]
|
|
pub(crate) fn encrypt<T: ReadWriteIpcSegment>(
|
|
value: &T,
|
|
size: u32,
|
|
encryption_key: Option<&[u8]>,
|
|
) -> BinResult<()> {
|
|
if let Some(encryption_key) = encryption_key {
|
|
let size = size - (std::mem::size_of::<u32>() * 4) as u32; // 16 = header size
|
|
|
|
let mut cursor = Cursor::new(Vec::new());
|
|
value.write_options(&mut cursor, endian, ())?;
|
|
|
|
let mut buffer = cursor.into_inner();
|
|
buffer.resize(size as usize, 0);
|
|
|
|
let blowfish = Blowfish::new(encryption_key);
|
|
blowfish.encrypt(&mut buffer);
|
|
|
|
writer.write_all(&buffer)?;
|
|
|
|
Ok(())
|
|
} else {
|
|
value.write_options(writer, endian, ())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_encryption_key() {
|
|
let key = generate_encryption_key(&[0x00, 0x00, 0x00, 0x00], "foobar");
|
|
assert_eq!(
|
|
key,
|
|
[
|
|
169, 78, 235, 31, 57, 151, 26, 74, 250, 196, 1, 120, 206, 173, 202, 48
|
|
]
|
|
);
|
|
}
|
|
}
|