From 0066c6d9729ee0937294b814cc36aaf3feab3eb7 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 22 Jun 2019 13:02:53 +0200 Subject: [PATCH] src/backup/crypt_config.rs: remove encode_chunk, use encrypt_to instead --- src/backup/crypt_config.rs | 55 -------------------------------------- src/backup/data_blob.rs | 39 ++++++++++++++++++++++----- src/backup/data_chunk.rs | 39 +++++++++++++++++++++------ 3 files changed, 63 insertions(+), 70 deletions(-) diff --git a/src/backup/crypt_config.rs b/src/backup/crypt_config.rs index 15dbc31b..49aab44b 100644 --- a/src/backup/crypt_config.rs +++ b/src/backup/crypt_config.rs @@ -106,61 +106,6 @@ impl CryptConfig { Ok((iv, tag)) } - /// Compress and encrypt data using a random 16 byte IV. - /// - /// Return the encrypted data, including IV and MAC (MAGIC || IV || MAC || ENC_DATA). - /// If compression does not help, we return the uncompresssed, encrypted data. - pub fn encode_chunk( - &self, - // The data you want to encode - data: &[u8], - // Whether try to compress data before encryption - compress: bool, - // Magic number used for uncompressed results - uncomp_magic: &[u8; 8], - // Magic number used for compressed results - comp_magic: &[u8; 8], - ) -> Result, Error> { - - let iv = proxmox::sys::linux::random_data(16)?; - let mut c = Crypter::new(self.cipher, Mode::Encrypt, &self.enc_key, Some(&iv))?; - c.aad_update(b"")?; //?? - - if compress { - let compr_data = zstd::block::compress(data, 1)?; - // Note: We only use compression if result is shorter - if compr_data.len() < data.len() { - let mut enc = vec![0; compr_data.len()+44+self.cipher.block_size()]; - - enc[0..8].copy_from_slice(comp_magic); - enc[8..12].copy_from_slice(&[0u8; 4]); - enc[12..28].copy_from_slice(&iv); - - let count = c.update(&compr_data, &mut enc[44..])?; - let rest = c.finalize(&mut enc[(44+count)..])?; - enc.truncate(44 + count + rest); - - c.get_tag(&mut enc[28..44])?; - - return Ok(enc) - } - } - - let mut enc = vec![0; data.len()+44+self.cipher.block_size()]; - - enc[0..8].copy_from_slice(uncomp_magic); - enc[8..12].copy_from_slice(&[0u8; 4]); - enc[12..28].copy_from_slice(&iv); - - let count = c.update(data, &mut enc[44..])?; - let rest = c.finalize(&mut enc[(44+count)..])?; - enc.truncate(44 + count + rest); - - c.get_tag(&mut enc[28..44])?; - - Ok(enc) - } - /// Decompress and decrypt chunk, verify MAC. /// /// Binrary ``data`` is expected to be in format returned by encode_chunk. The magic number diff --git a/src/backup/data_blob.rs b/src/backup/data_blob.rs index 6dd0be66..9842f650 100644 --- a/src/backup/data_blob.rs +++ b/src/backup/data_blob.rs @@ -77,13 +77,38 @@ impl DataBlob { if let Some(config) = config { - let enc_data = config.encode_chunk( - data, - compress, - &ENCRYPTED_BLOB_MAGIC_1_0, - &ENCR_COMPR_BLOB_MAGIC_1_0, - )?; - return Ok(DataBlob { raw_data: enc_data }); + let compr_data; + let (_compress, data, magic) = if compress { + compr_data = zstd::block::compress(data, 1)?; + // Note: We only use compression if result is shorter + if compr_data.len() < data.len() { + (true, &compr_data[..], ENCR_COMPR_BLOB_MAGIC_1_0) + } else { + (false, data, ENCRYPTED_BLOB_MAGIC_1_0) + } + } else { + (false, data, ENCRYPTED_BLOB_MAGIC_1_0) + }; + + let header_len = std::mem::size_of::(); + let mut raw_data = Vec::with_capacity(data.len() + header_len); + + let dummy_head = EncryptedDataBlobHeader { + head: DataBlobHeader { magic: [0u8; 8], crc: [0; 4] }, + iv: [0u8; 16], + tag: [0u8; 16], + }; + raw_data.write_value(&dummy_head)?; + + let (iv, tag) = config.encrypt_to(data, &mut raw_data)?; + + let head = EncryptedDataBlobHeader { + head: DataBlobHeader { magic, crc: [0; 4] }, iv, tag, + }; + + (&mut raw_data[0..header_len]).write_value(&head)?; + + return Ok(DataBlob { raw_data }); } else { let max_data_len = data.len() + std::mem::size_of::(); diff --git a/src/backup/data_chunk.rs b/src/backup/data_chunk.rs index 48feeab7..608e2ff0 100644 --- a/src/backup/data_chunk.rs +++ b/src/backup/data_chunk.rs @@ -84,15 +84,38 @@ impl DataChunk { if let Some(config) = config { - let enc_data = config.encode_chunk( - data, - compress, - &ENCRYPTED_CHUNK_MAGIC_1_0, - &ENCR_COMPR_CHUNK_MAGIC_1_0, - )?; - let chunk = DataChunk { digest, raw_data: enc_data }; + let compr_data; + let (_compress, data, magic) = if compress { + compr_data = zstd::block::compress(data, 1)?; + // Note: We only use compression if result is shorter + if compr_data.len() < data.len() { + (true, &compr_data[..], ENCR_COMPR_CHUNK_MAGIC_1_0) + } else { + (false, data, ENCRYPTED_CHUNK_MAGIC_1_0) + } + } else { + (false, data, ENCRYPTED_CHUNK_MAGIC_1_0) + }; - Ok(chunk) + let header_len = std::mem::size_of::(); + let mut raw_data = Vec::with_capacity(data.len() + header_len); + + let dummy_head = EncryptedDataChunkHeader { + head: DataChunkHeader { magic: [0u8; 8], crc: [0; 4] }, + iv: [0u8; 16], + tag: [0u8; 16], + }; + raw_data.write_value(&dummy_head)?; + + let (iv, tag) = config.encrypt_to(data, &mut raw_data)?; + + let head = EncryptedDataChunkHeader { + head: DataChunkHeader { magic, crc: [0; 4] }, iv, tag, + }; + + (&mut raw_data[0..header_len]).write_value(&head)?; + + return Ok(DataChunk { digest, raw_data }); } else { let max_data_len = data.len() + std::mem::size_of::();