file_encrypt/encryption_algos/
aes256_gcm.rs1use aes_gcm::{
2 aead::{Aead, AeadCore, KeyInit},
3 Aes256Gcm, Key, Nonce,
4};
5use anyhow::{anyhow, Result};
6use argon2::PasswordHash;
7use base64::prelude::*;
8use rand_core::OsRng;
9use std::{ffi::OsString, fs, path::PathBuf};
10
11use crate::hash_algos::argon_hash;
12
13pub fn encrypt_file(
14 file_path: String,
15 passphrase: String,
16 output_file: String,
17) -> Result<(OsString, String)> {
18 let argon_pch: String = argon_hash::hash_passphrase(passphrase);
20 let hash = PasswordHash::new(&argon_pch).unwrap();
21 let hash = match hash.hash {
22 Some(hash) => hash.to_string(),
23 None => {
24 eprintln!("[-] Error with argon2 hash");
25 return Err(anyhow!("Unable to get hash from Argon2 PCH"));
26 }
27 };
28
29 let hash = BASE64_STANDARD_NO_PAD.decode(hash)?;
32
33 let key = Key::<Aes256Gcm>::from_slice(&hash);
35 let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
36 let cipher = Aes256Gcm::new(&key);
37
38 let file_data = fs::read(file_path.clone())?;
40 let mut enc_data = match cipher.encrypt(&nonce, file_data.as_ref()) {
41 Ok(enc_data) => enc_data,
42 Err(e) => {
43 let e = e.to_string();
44 return Err(anyhow!("Unable to encrypt data: {e}"));
45 }
46 };
47
48 let mut nonce_and_data = nonce.to_vec();
51 nonce_and_data.append(&mut enc_data);
52
53 let new_file = PathBuf::from(output_file);
55 fs::write(new_file.clone(), nonce_and_data)?;
56
57 Ok((new_file.into(), argon_pch))
58}
59
60pub fn decrypt_file(
61 file_path: String,
62 passphrase: String,
63 expected_pch: String,
64 output_file: String,
65) -> Result<()> {
66 let (res, hash_opt) = argon_hash::check_hash(passphrase, expected_pch);
68 if res == false {
69 eprintln!("[-] Invalid passphrase provided");
70 return Err(anyhow!("Invalid passphrase"));
71 }
72
73 let hash = hash_opt.unwrap();
75 let hash = PasswordHash::new(&hash).unwrap();
76 let hash = hash.hash.unwrap().to_string();
77
78 let hash = BASE64_STANDARD_NO_PAD.decode(hash)?;
79
80 let key = Key::<Aes256Gcm>::from_slice(&hash);
82 let cipher = Aes256Gcm::new(&key);
83
84 let mut nonce_and_data = fs::read(file_path.clone())?;
86 let data = nonce_and_data.split_off(12);
87 let nonce = nonce_and_data;
88 let nonce = Nonce::from_slice(&nonce);
89
90 let plain_data = match cipher.decrypt(nonce, data.as_ref()) {
91 Ok(data) => data,
92 Err(e) => {
93 let e = e.to_string();
94 return Err(anyhow!("Unable to decrypt file: {e}"));
95 }
96 };
97
98 let new_file = PathBuf::from(output_file);
99 fs::write(new_file, plain_data)?;
100
101 Ok(())
102}