reddb_server/storage/encryption/
header.rs1use super::key::SecureKey;
16use super::page_encryptor::{PageEncryptor, NONCE_SIZE, TAG_SIZE};
17use crate::crypto::uuid::Uuid;
18
19pub const SALT_SIZE: usize = 32;
20pub const KEY_CHECK_LEN: usize = 32; #[derive(Debug, Clone)]
24pub struct EncryptionHeader {
25 pub salt: [u8; SALT_SIZE],
27
28 pub key_check: Vec<u8>,
32}
33
34impl EncryptionHeader {
35 pub fn new(key: &SecureKey) -> Self {
37 let uuid = Uuid::new_v4();
39 let mut salt = [0u8; SALT_SIZE];
40 let b = uuid.as_bytes();
42 salt[0..16].copy_from_slice(b);
43 let uuid2 = Uuid::new_v4();
44 salt[16..32].copy_from_slice(uuid2.as_bytes());
45
46 let known_value = [0xAAu8; KEY_CHECK_LEN];
49 let encryptor = PageEncryptor::new(key.clone());
50
51 let check_blob = encryptor.encrypt(u32::MAX, &known_value);
53
54 Self {
55 salt,
56 key_check: check_blob,
57 }
58 }
59
60 pub fn validate(&self, key: &SecureKey) -> bool {
62 let encryptor = PageEncryptor::new(key.clone());
63
64 match encryptor.decrypt(u32::MAX, &self.key_check) {
65 Ok(plaintext) => {
66 let expected = [0xAAu8; KEY_CHECK_LEN];
67 plaintext == expected
68 }
69 Err(_) => false,
70 }
71 }
72
73 pub fn to_bytes(&self) -> Vec<u8> {
75 let mut buf = Vec::new();
76 buf.extend_from_slice(&self.salt);
77 buf.extend_from_slice(&self.key_check);
81 buf
82 }
83
84 pub fn from_bytes(data: &[u8]) -> Result<Self, String> {
86 let check_size = NONCE_SIZE + KEY_CHECK_LEN + TAG_SIZE;
87 let expected_len = SALT_SIZE + check_size;
88
89 if data.len() < expected_len {
90 return Err("Data too short for EncryptionHeader".to_string());
91 }
92
93 let mut salt = [0u8; SALT_SIZE];
94 salt.copy_from_slice(&data[0..SALT_SIZE]);
95
96 let key_check = data[SALT_SIZE..SALT_SIZE + check_size].to_vec();
97
98 Ok(Self { salt, key_check })
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_header_validation() {
108 let key = SecureKey::new(&[0x11u8; 32]);
109 let header = EncryptionHeader::new(&key);
110
111 assert!(header.validate(&key));
112
113 let wrong_key = SecureKey::new(&[0x22u8; 32]);
114 assert!(!header.validate(&wrong_key));
115 }
116
117 #[test]
118 fn test_header_serialization() {
119 let key = SecureKey::new(&[0x33u8; 32]);
120 let header = EncryptionHeader::new(&key);
121
122 let bytes = header.to_bytes();
123 let loaded = EncryptionHeader::from_bytes(&bytes).unwrap();
124
125 assert_eq!(header.salt, loaded.salt);
126 assert_eq!(header.key_check, loaded.key_check);
127 assert!(loaded.validate(&key));
128 }
129}