use crate::v1::key::KeyDerivationParams;
#[derive(Debug, Clone)]
pub struct FileHeader {
pub magic: [u8; 6], pub version: u8, pub header_length: u32, pub salt: [u8; 16], pub kdf_memory: u32, pub kdf_iterations: u32, pub kdf_parallelism: u32, pub kdf_key_length: u8, pub content_nonce: [u8; 24], pub filename_nonce: [u8; 24], pub filename_ciphertext_length: u16, pub filename_ciphertext: Vec<u8>, }
impl FileHeader {
pub fn new(
salt: [u8; 16],
kdf_params: KeyDerivationParams,
content_nonce: [u8; 24],
filename_nonce: [u8; 24],
filename_ciphertext: Vec<u8>,
) -> Self {
let filename_ciphertext_length = filename_ciphertext.len() as u16;
let size = Self::min_length() + filename_ciphertext.len();
FileHeader {
magic: *b"SHADOW",
version: 1,
header_length: size as u32,
salt,
kdf_memory: kdf_params.memory_cost,
kdf_iterations: kdf_params.time_cost,
kdf_parallelism: kdf_params.parallelism,
kdf_key_length: kdf_params.key_size,
content_nonce,
filename_nonce,
filename_ciphertext_length,
filename_ciphertext,
}
}
pub fn min_length() -> usize {
90 }
}
#[cfg(test)]
mod tests {
use crate::profile;
use super::*;
fn get_test_params() -> KeyDerivationParams {
let profile = profile::SecurityProfile::Test;
KeyDerivationParams::from(profile)
}
#[test]
fn default_values_are_correct() {
let header = FileHeader::new(
[0u8; 16],
get_test_params(),
[0u8; 24],
[0u8; 24],
vec![1, 2, 3, 4],
);
assert_eq!(&header.magic, b"SHADOW");
assert_eq!(header.version, 1);
}
#[test]
fn header_size_is_calculated_correctly() {
let filename_ciphertext = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let header = FileHeader::new(
[0u8; 16],
get_test_params(),
[0u8; 24],
[0u8; 24],
filename_ciphertext.clone(),
);
let expected_size: u32 = 90 + filename_ciphertext.len() as u32;
assert_eq!(header.header_length, expected_size);
}
}