From 7bcdc3b4ca460aec2b98fb2dca6165788c562b05 Mon Sep 17 00:00:00 2001 From: Igor Tolmachev Date: Sat, 20 Jul 2024 16:52:39 +0900 Subject: Partial aes implementation and others improvements --- src/zip/encryption/weak.rs | 105 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/zip/encryption/weak.rs (limited to 'src/zip/encryption/weak.rs') diff --git a/src/zip/encryption/weak.rs b/src/zip/encryption/weak.rs new file mode 100644 index 0000000..144cd53 --- /dev/null +++ b/src/zip/encryption/weak.rs @@ -0,0 +1,105 @@ +use std::io::{Read, Result as IoResult}; + +const TABLE: [u32; 256] = generate_table(); + +const fn generate_table() -> [u32; 256] { + let mut table = [0; 256]; + + let mut i = 0; + while i <= 255 { + let mut t = i as u32; + + let mut j = 0; + while j < 8 { + if (t & 1) > 0 { + t = (t >> 1) ^ 0xEDB88320 + } else { + t >>= 1 + } + j += 1; + } + + table[i] = t; + i += 1 + } + + table +} + +fn crc32(byte: u8, crc: u32) -> u32 { + (crc >> 8) ^ TABLE[((crc & 0xFF) as u8 ^ byte) as usize] +} + +pub struct Keys { + key0: u32, + key1: u32, + key2: u32, +} + +impl Keys { + pub fn new() -> Self { + Self { + key0: 305419896, + key1: 591751049, + key2: 878082192, + } + } + + fn update(&mut self, byte: u8) { + self.key0 = crc32(byte, self.key0); + self.key1 = self + .key1 + .wrapping_add(self.key0 & 0xFF) + .wrapping_mul(134775813) + .wrapping_add(1); + self.key2 = crc32((self.key1 >> 24) as u8, self.key2); + } + + pub fn set_password(&mut self, passwd: &[u8]) { + for b in passwd { + self.update(*b) + } + } + + pub fn set_header(&mut self, header: [u8; 12]) -> u8 { + for b in &header[..11] { + self.decode_byte(*b); + } + self.decode_byte(header[11]) + } + + #[allow(dead_code)] + pub fn encode_bytes(&mut self, byte: u8) -> u8 { + let key = self.key2 | 2; + self.update(byte); + byte ^ ((key.wrapping_mul(key ^ 1)) >> 8) as u8 + } + + pub fn decode_byte(&mut self, byte: u8) -> u8 { + let key = self.key2 | 2; + let byte = byte ^ ((key.wrapping_mul(key ^ 1)) >> 8) as u8; + self.update(byte); + byte + } +} + +pub struct WeakDecoder { + io: Io, + keys: Keys, +} + +impl WeakDecoder { + pub fn new(io: Io, keys: Keys) -> Self { + WeakDecoder { io, keys } + } +} + +impl Read for WeakDecoder { + fn read(&mut self, buf: &mut [u8]) -> IoResult { + let bytes = self.io.read(buf)?; + for i in 0..bytes { + buf[i] = self.keys.decode_byte(buf[i]); + } + Ok(bytes) + } +} -- cgit v1.2.3