mirror of
https://github.com/G2-Games/minidisc-cli.git
synced 2025-04-19 03:32:53 -05:00
Improved encryption implementation
This commit is contained in:
parent
9172a524d3
commit
833eeb6158
2 changed files with 132 additions and 117 deletions
|
@ -9,9 +9,25 @@ use super::interface::DataEncryptorInput;
|
|||
type DesEcbEnc = ecb::Decryptor<des::Des>;
|
||||
type DesCbcEnc = cbc::Encryptor<des::Des>;
|
||||
|
||||
pub fn threaded_encryptor(
|
||||
input: DataEncryptorInput,
|
||||
) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
|
||||
pub struct Encryptor {
|
||||
channel: Option<UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>>,
|
||||
state: Option<EncryptorState>,
|
||||
}
|
||||
|
||||
struct EncryptorState {
|
||||
input_data: Vec<u8>,
|
||||
iv: [u8; 8],
|
||||
random_key: [u8; 8],
|
||||
encrypted_random_key: [u8; 8],
|
||||
default_chunk_size: usize,
|
||||
current_chunk_size: usize,
|
||||
offset: usize,
|
||||
packet_count: usize,
|
||||
closed: bool,
|
||||
}
|
||||
|
||||
impl Encryptor {
|
||||
pub fn new_threaded(input: DataEncryptorInput) -> Self {
|
||||
let (tx, rx) = unbounded_channel::<(Vec<u8>, Vec<u8>, Vec<u8>)>();
|
||||
|
||||
thread::spawn(move || {
|
||||
|
@ -73,22 +89,12 @@ pub fn threaded_encryptor(
|
|||
}
|
||||
});
|
||||
|
||||
rx
|
||||
Self {
|
||||
channel: Some(rx),
|
||||
state: None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Encryptor {
|
||||
input_data: Vec<u8>,
|
||||
iv: [u8; 8],
|
||||
random_key: [u8; 8],
|
||||
encrypted_random_key: [u8; 8],
|
||||
default_chunk_size: usize,
|
||||
current_chunk_size: usize,
|
||||
offset: usize,
|
||||
packet_count: usize,
|
||||
closed: bool,
|
||||
}
|
||||
|
||||
impl Encryptor {
|
||||
pub fn new(input: DataEncryptorInput) -> Self {
|
||||
let iv = [0u8; 8];
|
||||
|
||||
|
@ -120,7 +126,9 @@ impl Encryptor {
|
|||
|
||||
let offset: usize = 0;
|
||||
|
||||
Self {
|
||||
Encryptor {
|
||||
channel: None,
|
||||
state: Some(EncryptorState {
|
||||
input_data,
|
||||
iv,
|
||||
random_key,
|
||||
|
@ -130,48 +138,59 @@ impl Encryptor {
|
|||
default_chunk_size,
|
||||
packet_count,
|
||||
closed: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the next encrypted value
|
||||
pub async fn next(&mut self) -> Option<(Vec<u8>, Vec<u8>, Vec<u8>)> {
|
||||
if self.closed {
|
||||
let output;
|
||||
|
||||
if let Some(state) = self.state.as_mut() {
|
||||
if state.closed {
|
||||
return None
|
||||
}
|
||||
|
||||
if self.packet_count > 0 {
|
||||
self.current_chunk_size = self.default_chunk_size;
|
||||
if state.packet_count > 0 {
|
||||
state.current_chunk_size = state.default_chunk_size;
|
||||
} else {
|
||||
self.current_chunk_size = self.default_chunk_size - 24;
|
||||
state.current_chunk_size = state.default_chunk_size - 24;
|
||||
}
|
||||
|
||||
self.current_chunk_size = std::cmp::min(self.current_chunk_size, self.input_data.len() - self.offset);
|
||||
state.current_chunk_size = std::cmp::min(state.current_chunk_size, state.input_data.len() - state.offset);
|
||||
|
||||
let this_data_chunk = &mut self.input_data[self.offset..self.offset + self.current_chunk_size];
|
||||
DesCbcEnc::new(&self.random_key.into(), &self.iv.into())
|
||||
.encrypt_padded_mut::<NoPadding>(this_data_chunk, self.current_chunk_size)
|
||||
let this_data_chunk = &mut state.input_data[state.offset..state.offset + state.current_chunk_size];
|
||||
DesCbcEnc::new(&state.random_key.into(), &state.iv.into())
|
||||
.encrypt_padded_mut::<NoPadding>(this_data_chunk, state.current_chunk_size)
|
||||
.unwrap();
|
||||
|
||||
let output = (
|
||||
self.encrypted_random_key.to_vec(),
|
||||
self.iv.to_vec(),
|
||||
output = Some((
|
||||
state.encrypted_random_key.to_vec(),
|
||||
state.iv.to_vec(),
|
||||
this_data_chunk.to_vec(),
|
||||
);
|
||||
));
|
||||
|
||||
self.iv.copy_from_slice(&this_data_chunk[this_data_chunk.len() - 8..]);
|
||||
state.iv.copy_from_slice(&this_data_chunk[this_data_chunk.len() - 8..]);
|
||||
|
||||
self.packet_count += 1;
|
||||
self.offset += self.current_chunk_size;
|
||||
state.packet_count += 1;
|
||||
state.offset += state.current_chunk_size;
|
||||
} else if let Some(channel) = self.channel.as_mut() {
|
||||
output = channel.recv().await
|
||||
} else {
|
||||
unreachable!("If you got here, this is bad!");
|
||||
}
|
||||
|
||||
Some(output)
|
||||
output
|
||||
}
|
||||
|
||||
/// Call close to return none from subsequent calls
|
||||
pub fn close(&mut self) {
|
||||
self.closed = true;
|
||||
if let Some(state) = self.state.as_mut() {
|
||||
state.closed = true;
|
||||
} else if let Some(channel) = self.channel.as_mut() {
|
||||
channel.close()
|
||||
} else {
|
||||
unreachable!("If you got here, this is bad!");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encryptor() {
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::time::Duration;
|
|||
use thiserror::Error;
|
||||
|
||||
use super::base::NetMD;
|
||||
use super::encryption::{threaded_encryptor, EncryptorState};
|
||||
use super::encryption::Encryptor;
|
||||
use super::utils::{cross_sleep, to_sjis};
|
||||
|
||||
/// An action to take on the player
|
||||
|
@ -1690,11 +1690,7 @@ impl NetMDInterface {
|
|||
discformat: u8,
|
||||
frames: u32,
|
||||
pkt_size: u32,
|
||||
// key, iv, data
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
mut packets: UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>,
|
||||
#[cfg(target_family = "wasm")]
|
||||
mut packets: EncryptorState,
|
||||
mut packets: Encryptor,
|
||||
hex_session_key: &[u8],
|
||||
progress_callback: F,
|
||||
) -> Result<(u16, Vec<u8>, Vec<u8>), InterfaceError>
|
||||
|
@ -1733,7 +1729,7 @@ impl NetMDInterface {
|
|||
let mut written_bytes = 0;
|
||||
let mut packet_count = 0;
|
||||
|
||||
while let Some((key, iv, data)) = packets.recv().await {
|
||||
while let Some((key, iv, data)) = packets.next().await {
|
||||
let binpack = if packet_count == 0 {
|
||||
let packed_length: Vec<u8> = pkt_size.to_be_bytes().to_vec();
|
||||
[vec![0, 0, 0, 0], packed_length, key, iv, data].concat()
|
||||
|
@ -1921,8 +1917,8 @@ impl MDTrack {
|
|||
}
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
pub fn get_encrypting_iterator(&mut self) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
|
||||
threaded_encryptor(DataEncryptorInput {
|
||||
pub fn get_encrypting_iterator(&mut self) -> Encryptor {
|
||||
Encryptor::new_threaded(DataEncryptorInput {
|
||||
kek: self.get_kek(),
|
||||
frame_size: self.frame_size(),
|
||||
chunk_size: self.chunk_size(),
|
||||
|
@ -1931,8 +1927,8 @@ impl MDTrack {
|
|||
}
|
||||
|
||||
#[cfg(target_family = "wasm")]
|
||||
pub fn get_encrypting_iterator(&mut self) -> EncryptorState {
|
||||
EncryptorState::new(DataEncryptorInput {
|
||||
pub fn get_encrypting_iterator(&mut self) -> Encryptor {
|
||||
Encryptor::new(DataEncryptorInput {
|
||||
kek: self.get_kek(),
|
||||
frame_size: self.frame_size(),
|
||||
chunk_size: self.chunk_size(),
|
||||
|
|
Loading…
Reference in a new issue