deadbolt_crypto/
hash.rs

1extern crate argon2;
2extern crate hmac;
3extern crate secrecy;
4extern crate sha2;
5
6use argon2::{Argon2, Params, Version};
7use hkdf::Hkdf as HkdfWrapper;
8use hmac::{digest::MacError, Hmac as HmacWrapper, Mac};
9use secrecy::{ExposeSecret, Secret};
10use sha2::{Digest, Sha256};
11
12pub struct Hash {}
13
14impl Hash {
15    pub fn sha256(message: &Vec<u8>) -> Vec<u8> {
16        let mut hasher = Sha256::new();
17        hasher.update(message);
18        hasher.finalize().to_vec()
19    }
20}
21
22pub struct PasswordHash {}
23
24impl PasswordHash {
25    pub fn argon2(
26        algorithm: argon2::Algorithm,
27        params: argon2::Params,
28        password: Secret<String>,
29        salt: &[u8],
30    ) -> Secret<Vec<u8>> {
31        let mut key_material: [u8; 32] = [0u8; 32];
32        Argon2::new(algorithm, Version::default(), params)
33            .hash_password_into(password.expose_secret().as_bytes(), salt, &mut key_material)
34            .unwrap();
35
36        Secret::new(key_material.to_vec())
37    }
38
39    pub fn argon2d(
40        password: Secret<String>,
41        salt: &[u8],
42        iterations: u8,
43        threads: u8,
44        memory: u32,
45    ) -> Secret<Vec<u8>> {
46        let params: argon2::Params =
47            argon2::Params::new(memory, iterations.into(), threads.into(), Some(32))
48                .expect("cannot build argon2 params");
49
50        PasswordHash::argon2(argon2::Algorithm::Argon2d, params, password, salt)
51    }
52
53    pub fn argon2id(
54        password: Secret<String>,
55        salt: &[u8],
56        iterations: u8,
57        threads: u8,
58        memory: u32,
59    ) -> Secret<Vec<u8>> {
60        let params: argon2::Params =
61            argon2::Params::new(memory, iterations.into(), threads.into(), Some(32))
62                .expect("cannot build argon2 params");
63
64        PasswordHash::argon2(argon2::Algorithm::Argon2id, params, password, salt)
65    }
66}
67
68pub struct Hkdf {}
69
70impl Hkdf {
71    pub fn expand(input_key_material: Secret<Vec<u8>>) -> Secret<Vec<u8>> {
72        let mut okm: [u8; 64] = [0u8; 64];
73        let info = vec![0xde, 0xad, 0xb0, 0x1d];
74        let hk = HkdfWrapper::<Sha256>::from_prk(input_key_material.expose_secret())
75            .expect("PRK should be large enough");
76        hk.expand(&info, &mut okm).unwrap();
77
78        Secret::new(okm.to_vec())
79    }
80}
81
82pub struct Hmac {
83    mac: HmacWrapper<Sha256>,
84}
85
86impl Hmac {
87    pub fn new(secret: &Secret<Vec<u8>>) -> Hmac {
88        type HmacSha256 = HmacWrapper<Sha256>;
89        Hmac {
90            mac: HmacSha256::new_from_slice(secret.expose_secret()).unwrap(),
91        }
92    }
93
94    pub fn update(&mut self, message: &[u8]) {
95        self.mac.update(message);
96    }
97
98    pub fn finalize(&mut self) -> Vec<u8> {
99        let result = self.mac.clone();
100        result.finalize().into_bytes().to_vec()
101    }
102
103    pub fn verify(&mut self, expected: &[u8]) -> Result<(), MacError> {
104        let result = self.mac.clone();
105        result.verify_slice(expected)
106    }
107}