decrypt.rs
1 use super::{ 2 EncryptedInfo, credentials::Credentials, encrypt::*, error::Error, 3 extract_encrypted_info_and_data, 4 }; 5 use bincode::{config::standard, decode_from_slice}; 6 use chacha20poly1305::aead::{Aead, Payload, generic_array::GenericArray}; 7 use secure_types::SecureBytes; 8 use zeroize::Zeroize; 9 10 /// Decrypts the data using the provided credentials 11 /// 12 /// ### Arguments 13 /// 14 /// - `data` - The data to decrypt 15 /// - `credentials` - The credentials to use for decryption 16 pub fn decrypt_data(data: Vec<u8>, credentials: Credentials) -> Result<SecureBytes, Error> { 17 // Verify Header 18 if &data[0..8] != HEADER { 19 return Err(Error::InvalidFileFormat); 20 } 21 22 let (encrypted_info, encrypted_data) = extract_encrypted_info_and_data(&data)?; 23 24 let info: (EncryptedInfo, usize) = decode_from_slice(&encrypted_info, standard()) 25 .map_err(|e| Error::DecodingFailed(e.to_string()))?; 26 27 let decrypted_data = decrypt(credentials, info.0, encrypted_data)?; 28 Ok(decrypted_data) 29 } 30 31 fn decrypt( 32 credentials: Credentials, 33 info: EncryptedInfo, 34 data: Vec<u8>, 35 ) -> Result<SecureBytes, Error> { 36 credentials.is_valid()?; 37 38 let password_hash = info 39 .argon2 40 .hash_password(&credentials.password, info.password_salt.clone())?; 41 42 let username_hash = info 43 .argon2 44 .hash_password(&credentials.username, info.username_salt.clone())?; 45 46 let nonce = GenericArray::from_slice(&info.cipher_nonce); 47 let mut aad = username_hash.unlock_slice(|bytes| bytes.to_vec()); 48 49 let payload = Payload { 50 msg: data.as_ref(), 51 aad: &aad, 52 }; 53 54 let cipher = xchacha20_poly_1305(password_hash); 55 let decrypted_data_res = cipher.decrypt(nonce, payload); 56 aad.zeroize(); 57 58 let decrypted_data = match decrypted_data_res { 59 Ok(data) => data, 60 Err(e) => { 61 return Err(Error::DecryptionFailed(e.to_string())); 62 } 63 }; 64 65 let secure_data = 66 SecureBytes::from_vec(decrypted_data).map_err(|e| Error::Custom(e.to_string()))?; 67 68 Ok(secure_data) 69 }