]> git.proxmox.com Git - proxmox-backup.git/blame - src/backup/crypt_writer.rs
src/backup/data_blob.rs: move parts into single files
[proxmox-backup.git] / src / backup / crypt_writer.rs
CommitLineData
018d11bb
DM
1use failure::*;
2use std::io::Write;
3
4use super::CryptConfig;
5
6pub 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
14impl <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
41impl <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}