this repo has no description
1#[allow(deprecated)] 2use aes_gcm::{Aes256Gcm, KeyInit, Nonce, aead::Aead}; 3use hkdf::Hkdf; 4use sha2::Sha256; 5 6use crate::CryptoError; 7 8pub fn derive_key(master_key: &[u8], context: &[u8]) -> Result<[u8; 32], CryptoError> { 9 let hk = Hkdf::<Sha256>::new(None, master_key); 10 let mut output = [0u8; 32]; 11 hk.expand(context, &mut output) 12 .map_err(|e| CryptoError::KeyDerivationFailed(format!("{}", e)))?; 13 Ok(output) 14} 15 16pub fn encrypt_with_key(key: &[u8; 32], plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> { 17 use rand::RngCore; 18 19 let cipher = Aes256Gcm::new_from_slice(key) 20 .map_err(|e| CryptoError::EncryptionFailed(format!("Failed to create cipher: {}", e)))?; 21 22 let mut nonce_bytes = [0u8; 12]; 23 rand::thread_rng().fill_bytes(&mut nonce_bytes); 24 25 #[allow(deprecated)] 26 let nonce = Nonce::from_slice(&nonce_bytes); 27 28 let ciphertext = cipher 29 .encrypt(nonce, plaintext) 30 .map_err(|e| CryptoError::EncryptionFailed(format!("{}", e)))?; 31 32 let mut result = Vec::with_capacity(12 + ciphertext.len()); 33 result.extend_from_slice(&nonce_bytes); 34 result.extend_from_slice(&ciphertext); 35 36 Ok(result) 37} 38 39pub fn decrypt_with_key(key: &[u8; 32], encrypted: &[u8]) -> Result<Vec<u8>, CryptoError> { 40 if encrypted.len() < 12 { 41 return Err(CryptoError::DecryptionFailed( 42 "Encrypted data too short".to_string(), 43 )); 44 } 45 46 let cipher = Aes256Gcm::new_from_slice(key) 47 .map_err(|e| CryptoError::DecryptionFailed(format!("Failed to create cipher: {}", e)))?; 48 49 #[allow(deprecated)] 50 let nonce = Nonce::from_slice(&encrypted[..12]); 51 let ciphertext = &encrypted[12..]; 52 53 cipher 54 .decrypt(nonce, ciphertext) 55 .map_err(|e| CryptoError::DecryptionFailed(format!("{}", e))) 56} 57 58#[cfg(test)] 59mod tests { 60 use super::*; 61 62 #[test] 63 fn test_encrypt_decrypt() { 64 let key = [0u8; 32]; 65 let plaintext = b"hello world"; 66 let encrypted = encrypt_with_key(&key, plaintext).unwrap(); 67 let decrypted = decrypt_with_key(&key, &encrypted).unwrap(); 68 assert_eq!(plaintext.as_slice(), decrypted.as_slice()); 69 } 70 71 #[test] 72 fn test_derive_key() { 73 let master = b"master-key-for-testing"; 74 let key1 = derive_key(master, b"context-1").unwrap(); 75 let key2 = derive_key(master, b"context-2").unwrap(); 76 assert_ne!(key1, key2); 77 } 78}