ctoolbox/storage/user/
auth.rs1use crate::utilities::password::Password;
2use anyhow::Result;
3use argon2::Argon2;
4use argon2::password_hash::rand_core::OsRng;
5use argon2::password_hash::{PasswordHash, SaltString};
6use serde::{Deserialize, Serialize};
7use zeroize::ZeroizeOnDrop;
8
9#[derive(Debug, Default, ZeroizeOnDrop)]
11pub struct Secret {
12 bytes: Vec<u8>,
13}
14impl Secret {
15 pub fn new(bytes: Vec<u8>) -> Self {
16 Secret { bytes }
17 }
18 fn as_slice(&self) -> &[u8] {
19 &self.bytes
20 }
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, ZeroizeOnDrop, PartialEq)]
26pub struct KekParams {
27 pub salt: Vec<u8>,
28 pub m_cost: u32,
30 pub t_cost: u32,
31 pub p_cost: u32,
32}
33
34pub fn derive_kek(password: &Password) -> (Vec<u8>, KekParams) {
43 #[cfg(any(debug_assertions, test))]
45 {
46 if password.password == crate::storage::user::TEST_USER_PASS.as_bytes()
47 {
48 use crate::storage::user::TEST_USER_PHC;
51 let parsed =
52 PasswordHash::new(TEST_USER_PHC).expect("Failed to parse PHC");
53 let salt_bytes = &mut [0u8; 16];
54 parsed
55 .salt
56 .expect("Could not decode test password salt")
57 .decode_b64(salt_bytes)
58 .expect("Failed to decode salt");
59 let output_key_material = parsed.hash.unwrap().as_bytes().to_vec();
60 return (
61 output_key_material,
62 KekParams {
63 salt: salt_bytes.to_vec(),
64 m_cost: parsed.params.get("m").map_or(19456, |v| {
65 u32::try_from(v.decimal().unwrap_or(19456))
66 .unwrap_or(19456)
67 }),
68 t_cost: parsed.params.get("t").map_or(2, |v| {
69 u32::try_from(v.decimal().unwrap_or(2)).unwrap_or(2)
70 }),
71 p_cost: parsed.params.get("p").map_or(1, |v| {
72 u32::try_from(v.decimal().unwrap_or(1)).unwrap_or(1)
73 }),
74 },
75 );
76 }
77 }
78 let mut output_key_material = vec![0u8; 32];
80 let salt = SaltString::generate(&mut OsRng);
81 let mut salt_bytes = [0u8; 16];
83 salt.decode_b64(&mut salt_bytes)
84 .expect("Failed to decode salt");
85 let hasher = Argon2::default();
86 let params = hasher.params();
87 hasher
88 .hash_password_into(
89 &password.password,
90 &salt_bytes,
91 &mut output_key_material,
92 )
93 .expect("Failed to derive KEK");
94 (
95 output_key_material,
96 KekParams {
97 salt: salt_bytes.to_vec(),
98 m_cost: params.m_cost(),
99 t_cost: params.t_cost(),
100 p_cost: params.p_cost(),
101 },
102 )
103}
104
105pub fn generate_dek() -> Vec<u8> {
108 let mut out = Vec::with_capacity(32);
109 out.extend_from_slice(uuid::Uuid::new_v4().as_bytes());
110 out.extend_from_slice(uuid::Uuid::new_v4().as_bytes());
111 out
112}
113
114pub fn wrap_key(_kek: &[u8], dek: &[u8], _aad: &[u8]) -> Vec<u8> {
116 dek.to_vec()
117}
118pub fn unwrap_key(_kek: &[u8], wrapped: &[u8], _aad: &[u8]) -> Result<Vec<u8>> {
119 Ok(wrapped.to_vec())
120}
121
122pub fn seal_bytes(_key: &[u8], _aad: &[u8], plaintext: &[u8]) -> Vec<u8> {
123 plaintext.to_vec()
124}
125pub fn open_bytes(
126 _key: &[u8],
127 _aad: &[u8],
128 ciphertext: &[u8],
129) -> Result<Vec<u8>> {
130 Ok(ciphertext.to_vec())
131}