]>
Commit | Line | Data |
---|---|---|
018d11bb DM |
1 | use failure::*; |
2 | use std::io::Write; | |
3 | ||
4 | use super::CryptConfig; | |
5 | ||
6 | pub struct CryptWriter<W> { | |
7 | writer: W, | |
8 | block_size: usize, | |
9 | encr_buf: Box<[u8; 64*1024]>, | |
10 | iv: [u8; 16], | |
11 | crypter: openssl::symm::Crypter, | |
12 | } | |
13 | ||
14 | impl <W: Write> CryptWriter<W> { | |
15 | ||
16 | pub fn new(writer: W, config: &CryptConfig) -> Result<Self, Error> { | |
17 | let mut iv = [0u8; 16]; | |
18 | proxmox::sys::linux::fill_with_random_data(&mut iv)?; | |
19 | let block_size = config.cipher().block_size(); | |
20 | ||
21 | let crypter = config.data_crypter(&iv, openssl::symm::Mode::Encrypt)?; | |
22 | ||
23 | Ok(Self { writer, iv, crypter, block_size, encr_buf: Box::new([0u8; 64*1024]) }) | |
24 | } | |
25 | ||
26 | pub fn finish(mut self) -> Result<(W, [u8; 16], [u8; 16]), Error> { | |
27 | let rest = self.crypter.finalize(self.encr_buf.as_mut())?; | |
28 | if rest > 0 { | |
29 | self.writer.write_all(&self.encr_buf[..rest])?; | |
30 | } | |
31 | ||
32 | self.writer.flush()?; | |
33 | ||
34 | let mut tag = [0u8; 16]; | |
35 | self.crypter.get_tag(&mut tag)?; | |
36 | ||
37 | Ok((self.writer, self.iv, tag)) | |
38 | } | |
39 | } | |
40 | ||
41 | impl <W: Write> Write for CryptWriter<W> { | |
42 | ||
43 | fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> { | |
44 | let mut write_size = buf.len(); | |
45 | if write_size > (self.encr_buf.len() - self.block_size) { | |
46 | write_size = self.encr_buf.len() - self.block_size; | |
47 | } | |
48 | let count = self.crypter.update(&buf[..write_size], self.encr_buf.as_mut()) | |
49 | .map_err(|err| { | |
50 | std::io::Error::new( | |
51 | std::io::ErrorKind::Other, | |
52 | format!("crypter update failed - {}", err)) | |
53 | })?; | |
54 | ||
55 | self.writer.write_all(&self.encr_buf[..count])?; | |
56 | ||
57 | Ok(write_size) | |
58 | } | |
59 | ||
60 | fn flush(&mut self) -> Result<(), std::io::Error> { | |
61 | Ok(()) | |
62 | } | |
63 | } |