]> git.proxmox.com Git - proxmox-backup.git/blame - pbs-datastore/src/crypt_writer.rs
update to proxmox-sys 0.2 crate
[proxmox-backup.git] / pbs-datastore / src / crypt_writer.rs
CommitLineData
9025312a 1use std::sync::Arc;
018d11bb
DM
2use std::io::Write;
3
f323e906
WB
4use anyhow::Error;
5
bbdda58b 6use pbs_tools::crypt_config::CryptConfig;
018d11bb
DM
7
8pub 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
16impl <W: Write> CryptWriter<W> {
17
9025312a 18 pub fn new(writer: W, config: Arc<CryptConfig>) -> Result<Self, Error> {
018d11bb 19 let mut iv = [0u8; 16];
25877d05 20 proxmox_sys::linux::fill_with_random_data(&mut iv)?;
018d11bb
DM
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
43impl <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}