Skip to main content

ncrypt_me/
decrypt.rs

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