massa_cipher/
decrypt.rs

1// Copyright (c) 2022 MASSA LABS <info@massa.net>
2
3//! massa-cipher decryption module.
4//!
5//! Read `lib.rs` module documentation for more information.
6
7use aes_gcm::aead::Aead;
8use aes_gcm::{Aes256Gcm, KeyInit, Nonce};
9use pbkdf2::{
10    password_hash::{PasswordHasher, SaltString},
11    Pbkdf2,
12};
13
14use crate::constants::HASH_PARAMS;
15use crate::encrypt::CipherData;
16use crate::error::CipherError;
17
18/// Decryption function using AES-GCM cipher.
19///
20/// Read `lib.rs` module documentation for more information.
21pub fn decrypt(password: &str, data: CipherData) -> Result<Vec<u8>, CipherError> {
22    // get PBKDF2 salt
23    let salt = SaltString::encode_b64(&data.salt)
24        .map_err(|e| CipherError::DecryptionError(e.to_string()))?;
25
26    // compute PBKDF2 password hash
27    let password_hash = Pbkdf2
28        .hash_password_customized(password.as_bytes(), None, None, HASH_PARAMS, &salt)
29        .map_err(|e| CipherError::DecryptionError(e.to_string()))?
30        .hash
31        .expect("content is missing after a successful hash");
32
33    // parse AES-GCM nonce
34    let nonce = Nonce::from_slice(&data.nonce);
35
36    // decrypt the data
37    let cipher = Aes256Gcm::new_from_slice(password_hash.as_bytes()).expect("invalid size key");
38    let decrypted_bytes = cipher
39        .decrypt(nonce, data.encrypted_bytes.as_ref())
40        .map_err(|_| {
41            CipherError::DecryptionError("wrong password or corrupted data".to_string())
42        })?;
43    Ok(decrypted_bytes)
44}