Skip to main content

sentc_crypto_std_keys/core/pw_hash/
mod.rs

1use alloc::vec::Vec;
2
3use sentc_crypto_core::cryptomat::{ClientRandomValueComposer, PwHash, PwPrepareExport, SymKey};
4use sentc_crypto_core::{crypto_alg_str_impl, cryptomat, Error};
5
6use crate::core::pw_hash::argon2::ARGON_2_OUTPUT;
7
8pub(crate) mod argon2;
9
10macro_rules! prepare_export_single_value {
11	($st:ty) => {
12		impl $st
13		{
14			pub fn argon2_from_bytes_owned(bytes: Vec<u8>) -> Result<Self, Error>
15			{
16				Ok(Self::Argon2(bytes.try_into().map_err(|_| Error::KeyDecryptFailed)?))
17			}
18		}
19	};
20}
21
22macro_rules! prepare_export {
23	($st:ty) => {
24		impl PwPrepareExport for $st
25		{
26			fn prepare_export(&self) -> &[u8]
27			{
28				match self {
29					Self::Argon2(v) => v,
30				}
31			}
32		}
33	};
34}
35
36pub struct PwHasherGetter;
37
38impl PwHash for PwHasherGetter
39{
40	type CRV = ClientRandomValue;
41	type HAK = HashedAuthenticationKey;
42	type DMK = DeriveMasterKeyForAuth;
43	type DAK = DeriveAuthKeyForAuth;
44	type PWS = PasswordEncryptSalt;
45
46	fn derived_keys_from_password<M: SymKey>(
47		password: &[u8],
48		master_key: &M,
49		alg: Option<&str>,
50	) -> Result<(Self::CRV, Self::HAK, Vec<u8>, &'static str), Error>
51	{
52		if let Some(alg) = alg {
53			match alg {
54				ARGON_2_OUTPUT => argon2::derived_keys_from_password(password, master_key),
55				_ => Err(Error::AlgNotFound),
56			}
57		} else {
58			argon2::derived_keys_from_password(password, master_key)
59		}
60	}
61
62	fn derive_keys_for_auth(password: &[u8], salt_bytes: &[u8], alg: &str) -> Result<(Self::DMK, Self::DAK), Error>
63	{
64		match alg {
65			ARGON_2_OUTPUT => argon2::derive_keys_for_auth(password, salt_bytes),
66			_ => Err(Error::AlgNotFound),
67		}
68	}
69
70	fn password_to_encrypt(password: &[u8]) -> Result<(Self::PWS, impl SymKey), Error>
71	{
72		argon2::password_to_encrypt(password)
73	}
74
75	fn password_to_decrypt(password: &[u8], salt: &[u8]) -> Result<impl SymKey, Error>
76	{
77		argon2::password_to_decrypt(password, salt)
78	}
79}
80
81pub enum ClientRandomValue
82{
83	Argon2([u8; 16]),
84}
85
86crypto_alg_str_impl!(ClientRandomValue, ARGON_2_OUTPUT);
87
88prepare_export!(ClientRandomValue);
89prepare_export_single_value!(ClientRandomValue);
90
91impl cryptomat::ClientRandomValue for ClientRandomValue
92{
93	fn generate_salt(self, add_str: &str) -> Vec<u8>
94	{
95		match self {
96			ClientRandomValue::Argon2(v) => argon2::generate_salt(v, add_str),
97		}
98	}
99}
100
101impl ClientRandomValueComposer for ClientRandomValue
102{
103	type Value = Self;
104
105	fn from_bytes(vec: Vec<u8>, alg: &str) -> Result<Self::Value, Error>
106	{
107		match alg {
108			ARGON_2_OUTPUT => {
109				let v = vec.try_into().map_err(|_| Error::KeyDecryptFailed)?;
110
111				Ok(Self::Argon2(v))
112			},
113			_ => Err(Error::AlgNotFound),
114		}
115	}
116}
117
118pub enum HashedAuthenticationKey
119{
120	Argon2([u8; 16]), //16 bytes of the org. hashed key
121}
122
123prepare_export!(HashedAuthenticationKey);
124prepare_export_single_value!(HashedAuthenticationKey);
125
126impl cryptomat::HashedAuthenticationKey for HashedAuthenticationKey {}
127
128pub enum DeriveMasterKeyForAuth
129{
130	Argon2([u8; 32]),
131}
132
133prepare_export!(DeriveMasterKeyForAuth);
134prepare_export_single_value!(DeriveMasterKeyForAuth);
135
136impl cryptomat::DeriveMasterKeyForAuth for DeriveMasterKeyForAuth
137{
138	fn get_master_key(&self, encrypted_master_key: &[u8]) -> Result<impl SymKey, Error>
139	{
140		match self {
141			DeriveMasterKeyForAuth::Argon2(k) => argon2::get_master_key(k, encrypted_master_key),
142		}
143	}
144}
145
146pub enum DeriveAuthKeyForAuth
147{
148	Argon2([u8; 32]),
149}
150
151prepare_export!(DeriveAuthKeyForAuth);
152prepare_export_single_value!(DeriveAuthKeyForAuth);
153
154impl cryptomat::DeriveAuthKeyForAuth for DeriveAuthKeyForAuth
155{
156	fn hash_auth_key(&self) -> Result<Vec<u8>, Error>
157	{
158		match self {
159			DeriveAuthKeyForAuth::Argon2(k) => argon2::get_hashed_auth_key(k),
160		}
161	}
162}
163
164impl cryptomat::DeriveAuthKeyForAuthComposer for DeriveAuthKeyForAuth
165{
166	type Value = Self;
167
168	fn from_bytes(vec: Vec<u8>, alg: &str) -> Result<Self::Value, Error>
169	{
170		match alg {
171			ARGON_2_OUTPUT => {
172				let v = vec.try_into().map_err(|_| Error::KeyDecryptFailed)?;
173
174				Ok(Self::Argon2(v))
175			},
176			_ => Err(Error::AlgNotFound),
177		}
178	}
179}
180
181pub enum PasswordEncryptSalt
182{
183	Argon2([u8; 16]), //export salt as enum because we can't know the length for every alg
184}
185
186prepare_export!(PasswordEncryptSalt);
187prepare_export_single_value!(PasswordEncryptSalt);
188
189impl cryptomat::PasswordEncryptSalt for PasswordEncryptSalt {}