Generate a new random Data Encryption Key (DEK). Returns the raw DEK (for data encryption) and the encrypted DEK (for storage in the file header). The DEK is encrypted using AES-256-GCM with the master key for authenticated key wrapping.
(&self)
| 173 | /// (for storage in the file header). The DEK is encrypted using |
| 174 | /// AES-256-GCM with the master key for authenticated key wrapping. |
| 175 | pub fn generate_dek(&self) -> crate::Result<([u8; 32], Vec<u8>)> { |
| 176 | let master = self |
| 177 | .master_key |
| 178 | .as_ref() |
| 179 | .ok_or_else(|| crate::Error::Encryption { |
| 180 | detail: "master key not loaded".into(), |
| 181 | })?; |
| 182 | |
| 183 | let mut dek = [0u8; 32]; |
| 184 | getrandom::fill(&mut dek).map_err(|e| crate::Error::Encryption { |
| 185 | detail: format!("failed to generate DEK: {e}"), |
| 186 | })?; |
| 187 | |
| 188 | // Encrypt DEK with master key using AES-256-GCM (authenticated encryption). |
| 189 | let mut nonce_bytes = [0u8; 12]; |
| 190 | getrandom::fill(&mut nonce_bytes).map_err(|e| crate::Error::Encryption { |
| 191 | detail: format!("failed to generate nonce: {e}"), |
| 192 | })?; |
| 193 | |
| 194 | let cipher = Aes256Gcm::new_from_slice(master).map_err(|e| crate::Error::Encryption { |
| 195 | detail: format!("AES-GCM key init failed: {e}"), |
| 196 | })?; |
| 197 | let nonce = Nonce::from(nonce_bytes); |
| 198 | |
| 199 | let ciphertext = |
| 200 | cipher |
| 201 | .encrypt(&nonce, dek.as_ref()) |
| 202 | .map_err(|e| crate::Error::Encryption { |
| 203 | detail: format!("DEK encryption failed: {e}"), |
| 204 | })?; |
| 205 | |
| 206 | // Prepend nonce to ciphertext for storage: [nonce:12B][ciphertext+tag] |
| 207 | let mut encrypted_dek = Vec::with_capacity(12 + ciphertext.len()); |
| 208 | encrypted_dek.extend_from_slice(&nonce_bytes); |
| 209 | encrypted_dek.extend_from_slice(&ciphertext); |
| 210 | |
| 211 | self.files_encrypted |
| 212 | .fetch_add(1, std::sync::atomic::Ordering::Relaxed); |
| 213 | |
| 214 | Ok((dek, encrypted_dek)) |
| 215 | } |
| 216 | |
| 217 | /// Decrypt a DEK from a file header using the master key. |
| 218 | /// |