diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-07-21 16:59:14 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-07-21 16:59:14 +0900 |
| commit | 4c411b76cad9cc735687dc739d2e2db5d00e5eac (patch) | |
| tree | 818168ca5726ad3f9d24089dba31a24ff6b1b1f4 /src/zip/encryption/aes.rs | |
| parent | 7bcdc3b4ca460aec2b98fb2dca6165788c562b05 (diff) | |
| download | archivator-4c411b76cad9cc735687dc739d2e2db5d00e5eac.tar.gz archivator-4c411b76cad9cc735687dc739d2e2db5d00e5eac.zip | |
Add AES encryption
Diffstat (limited to 'src/zip/encryption/aes.rs')
| -rw-r--r-- | src/zip/encryption/aes.rs | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/src/zip/encryption/aes.rs b/src/zip/encryption/aes.rs index 6f41aaa..b690482 100644 --- a/src/zip/encryption/aes.rs +++ b/src/zip/encryption/aes.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use crate::utils::ReadUtils; | ||
| 2 | use aes::cipher::generic_array::GenericArray; | 1 | use aes::cipher::generic_array::GenericArray; |
| 3 | use aes::cipher::BlockEncrypt; | 2 | use aes::cipher::BlockEncrypt; |
| 4 | use std::io::{Read, Result as IoResult}; | 3 | use std::io::{Read, Result as IoResult}; |
| @@ -10,37 +9,63 @@ pub struct AesDecoder<Io: Read, Aes: BlockEncrypt> { | |||
| 10 | 9 | ||
| 11 | counter: u128, | 10 | counter: u128, |
| 12 | block: [u8; 16], | 11 | block: [u8; 16], |
| 13 | cursor: usize, | 12 | lower: usize, |
| 13 | upper: usize, | ||
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | impl<Io: Read, Aes: BlockEncrypt> AesDecoder<Io, Aes> { | 16 | impl<Io: Read, Aes: BlockEncrypt> AesDecoder<Io, Aes> { |
| 17 | pub fn new(mut io: Io, aes: Aes) -> IoResult<Self> { | 17 | pub fn new(io: Io, aes: Aes) -> IoResult<Self> { |
| 18 | let block = io.read_arr::<16>()?; | ||
| 19 | let mut decoder = Self { | 18 | let mut decoder = Self { |
| 20 | io, | 19 | io, |
| 21 | aes, | 20 | aes, |
| 22 | counter: 1, | 21 | |
| 23 | block, | 22 | counter: 0, |
| 24 | cursor: 0, | 23 | block: [0; 16], |
| 24 | lower: 0, | ||
| 25 | upper: 0, | ||
| 25 | }; | 26 | }; |
| 26 | decoder.decrypt_block(); | 27 | |
| 28 | decoder.update_block()?; | ||
| 29 | |||
| 27 | Ok(decoder) | 30 | Ok(decoder) |
| 28 | } | 31 | } |
| 29 | 32 | ||
| 30 | #[inline] | 33 | #[inline] |
| 31 | fn decrypt_block(&mut self) { | 34 | fn update_block(&mut self) -> IoResult<()> { |
| 35 | self.upper = self.io.read(&mut self.block)?; | ||
| 36 | self.lower = 0; | ||
| 37 | |||
| 38 | self.counter += 1; | ||
| 32 | let mut mask = self.counter.to_le_bytes(); | 39 | let mut mask = self.counter.to_le_bytes(); |
| 40 | |||
| 33 | self.aes | 41 | self.aes |
| 34 | .encrypt_block(GenericArray::from_mut_slice(&mut mask)); | 42 | .encrypt_block(GenericArray::from_mut_slice(&mut mask)); |
| 43 | |||
| 35 | for (b, m) in self.block.iter_mut().zip(mask) { | 44 | for (b, m) in self.block.iter_mut().zip(mask) { |
| 36 | *b ^= m | 45 | *b ^= m |
| 37 | } | 46 | } |
| 38 | self.counter += 1; | 47 | |
| 48 | Ok(()) | ||
| 39 | } | 49 | } |
| 40 | } | 50 | } |
| 41 | 51 | ||
| 42 | impl<Io: Read, Aes: BlockEncrypt> Read for AesDecoder<Io, Aes> { | 52 | impl<Io: Read, Aes: BlockEncrypt> Read for AesDecoder<Io, Aes> { |
| 43 | fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { | 53 | fn read(&mut self, mut buf: &mut [u8]) -> IoResult<usize> { |
| 44 | todo!() | 54 | let mut bytes = 0; |
| 55 | while !buf.is_empty() && self.lower != self.upper { | ||
| 56 | for (to, fr) in buf.iter_mut().zip(&self.block[self.lower..self.upper]) { | ||
| 57 | *to = *fr | ||
| 58 | } | ||
| 59 | |||
| 60 | let consumed = buf.len().min(self.upper - self.lower); | ||
| 61 | buf = &mut buf[consumed..]; | ||
| 62 | self.lower += consumed; | ||
| 63 | bytes += consumed; | ||
| 64 | |||
| 65 | if self.lower == 16 { | ||
| 66 | self.update_block()?; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | Ok(bytes) | ||
| 45 | } | 70 | } |
| 46 | } | 71 | } |
