aboutsummaryrefslogtreecommitdiff
path: root/src/zip/encryption/weak.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/zip/encryption/weak.rs')
-rw-r--r--src/zip/encryption/weak.rs105
1 files changed, 105 insertions, 0 deletions
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 @@
1use std::io::{Read, Result as IoResult};
2
3const TABLE: [u32; 256] = generate_table();
4
5const fn generate_table() -> [u32; 256] {
6 let mut table = [0; 256];
7
8 let mut i = 0;
9 while i <= 255 {
10 let mut t = i as u32;
11
12 let mut j = 0;
13 while j < 8 {
14 if (t & 1) > 0 {
15 t = (t >> 1) ^ 0xEDB88320
16 } else {
17 t >>= 1
18 }
19 j += 1;
20 }
21
22 table[i] = t;
23 i += 1
24 }
25
26 table
27}
28
29fn crc32(byte: u8, crc: u32) -> u32 {
30 (crc >> 8) ^ TABLE[((crc & 0xFF) as u8 ^ byte) as usize]
31}
32
33pub struct Keys {
34 key0: u32,
35 key1: u32,
36 key2: u32,
37}
38
39impl Keys {
40 pub fn new() -> Self {
41 Self {
42 key0: 305419896,
43 key1: 591751049,
44 key2: 878082192,
45 }
46 }
47
48 fn update(&mut self, byte: u8) {
49 self.key0 = crc32(byte, self.key0);
50 self.key1 = self
51 .key1
52 .wrapping_add(self.key0 & 0xFF)
53 .wrapping_mul(134775813)
54 .wrapping_add(1);
55 self.key2 = crc32((self.key1 >> 24) as u8, self.key2);
56 }
57
58 pub fn set_password(&mut self, passwd: &[u8]) {
59 for b in passwd {
60 self.update(*b)
61 }
62 }
63
64 pub fn set_header(&mut self, header: [u8; 12]) -> u8 {
65 for b in &header[..11] {
66 self.decode_byte(*b);
67 }
68 self.decode_byte(header[11])
69 }
70
71 #[allow(dead_code)]
72 pub fn encode_bytes(&mut self, byte: u8) -> u8 {
73 let key = self.key2 | 2;
74 self.update(byte);
75 byte ^ ((key.wrapping_mul(key ^ 1)) >> 8) as u8
76 }
77
78 pub fn decode_byte(&mut self, byte: u8) -> u8 {
79 let key = self.key2 | 2;
80 let byte = byte ^ ((key.wrapping_mul(key ^ 1)) >> 8) as u8;
81 self.update(byte);
82 byte
83 }
84}
85
86pub struct WeakDecoder<Io: Read> {
87 io: Io,
88 keys: Keys,
89}
90
91impl<Io: Read> WeakDecoder<Io> {
92 pub fn new(io: Io, keys: Keys) -> Self {
93 WeakDecoder { io, keys }
94 }
95}
96
97impl<Io: Read> Read for WeakDecoder<Io> {
98 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
99 let bytes = self.io.read(buf)?;
100 for i in 0..bytes {
101 buf[i] = self.keys.decode_byte(buf[i]);
102 }
103 Ok(bytes)
104 }
105}