sendcipher_core/crypto/
cypher_key.rs1use crate::crypto::Argon2idParams;
6use crate::crypto::random::*;
7use argon2::Argon2;
8use hmac::Mac;
9use serde::Deserialize;
10use serde::Serialize;
11
12impl From<argon2::Error> for crate::error::Error {
13 fn from(argon2_error: argon2::Error) -> Self {
14 crate::error::Error::Any(argon2_error.to_string())
15 }
16}
17
18#[derive(Clone, Serialize, Deserialize)]
19pub(crate) struct CypherKey {
20 key: Vec<u8>,
21}
22
23impl CypherKey {
24 pub fn with_key(key: Vec<u8>) -> Self {
25 Self { key: key }
26 }
27 pub fn new() -> Result<Self, crate::error::Error> {
28 Ok(Self {
29 key: crate::crypto::random::get_rand_bytes(32)?,
30 })
31 }
32
33 pub fn get_key(&self) -> &Vec<u8> {
34 &self.key
35 }
36
37 pub fn derive_key(&self, context: &[u8]) -> Vec<u8> {
38 let output_len = self.key.len();
39 hmac::Hmac::<sha2::Sha256>::new_from_slice(&self.key)
40 .expect("Expected a key valid for HMAC-SHA256")
41 .chain_update(context)
42 .finalize()
43 .into_bytes()[..output_len]
44 .to_vec()
45 }
46
47 pub fn from_bytes(bytes: &[u8]) -> Self {
48 Self {
49 key: bytes.to_vec(),
50 }
51 }
52
53 pub fn to_bytes(&self) -> &Vec<u8> {
54 &self.key
55 }
56}
57
58#[derive(Clone)]
59pub struct Argon2IdKeyProducer {
60 argon2id_params: Argon2idParams,
61 key: Vec<u8>,
62}
63
64impl Argon2IdKeyProducer {
65 pub fn get_key(&self) -> &Vec<u8> {
66 &self.key
67 }
68
69 pub fn get_parameters(&self) -> &Argon2idParams {
70 &self.argon2id_params
71 }
72
73 pub(crate) fn with_default_parameters(password: &str) -> Self {
74 Self::new(
75 password,
76 &Argon2idParams {
77 m_cost: 50 * 1024, t_cost: 3, p_cost: 1, salt: get_rand_bytes(32).expect("Failed to get random bytes"),
81 },
82 )
83 }
84
85 pub fn new(password: &str, parameters: &Argon2idParams) -> Self {
86 let key = Self::derive_key(password, ¶meters).expect("").to_vec();
87 let inst = Argon2IdKeyProducer {
88 argon2id_params: parameters.clone(),
89 key: key,
90 };
91 inst
92 }
93
94 fn derive_key(
95 password: &str,
96 params: &Argon2idParams,
97 ) -> Result<[u8; 32], crate::error::Error> {
98 let argon2_params = argon2::Params::new(
99 params.m_cost, params.t_cost, params.p_cost, Some(params.salt.len()),
103 )?;
104
105 let argon2_inst = Argon2::new(
106 argon2::Algorithm::Argon2id,
107 argon2::Version::V0x13,
108 argon2_params,
109 );
110
111 let mut key = [0u8; 32];
112 argon2_inst.hash_password_into(password.as_bytes(), ¶ms.salt, &mut key)?;
113
114 Ok(key)
115 }
116}