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