envvault/crypto/
encryption.rs1use aes_gcm::aead::{Aead, KeyInit, OsRng};
11use aes_gcm::{AeadCore, Aes256Gcm, Nonce};
12
13use crate::errors::{EnvVaultError, Result};
14
15const NONCE_LEN: usize = 12;
17
18pub fn encrypt(key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>> {
22 let cipher = Aes256Gcm::new_from_slice(key)
24 .map_err(|e| EnvVaultError::EncryptionFailed(format!("invalid key length: {e}")))?;
25
26 let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
28
29 let ciphertext = cipher
31 .encrypt(&nonce, plaintext)
32 .map_err(|e| EnvVaultError::EncryptionFailed(format!("encryption error: {e}")))?;
33
34 let mut output = Vec::with_capacity(NONCE_LEN + ciphertext.len());
36 output.extend_from_slice(&nonce);
37 output.extend_from_slice(&ciphertext);
38 Ok(output)
39}
40
41pub fn decrypt(key: &[u8], ciphertext_with_nonce: &[u8]) -> Result<Vec<u8>> {
45 if ciphertext_with_nonce.len() < NONCE_LEN {
47 return Err(EnvVaultError::DecryptionFailed);
48 }
49
50 let (nonce_bytes, ciphertext) = ciphertext_with_nonce.split_at(NONCE_LEN);
52 let nonce = Nonce::from_slice(nonce_bytes);
53
54 let cipher = Aes256Gcm::new_from_slice(key).map_err(|_| EnvVaultError::DecryptionFailed)?;
56
57 let plaintext = cipher
59 .decrypt(nonce, ciphertext)
60 .map_err(|_| EnvVaultError::DecryptionFailed)?;
61
62 Ok(plaintext)
63}