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