1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use crate::TinkError;
use digest::Digest;
use subtle::ConstantTimeEq;
use tink_proto::HashType;
mod hkdf;
pub use self::hkdf::*;
pub mod random;
pub fn get_hash_digest_size(hash: HashType) -> Result<usize, TinkError> {
match hash {
HashType::Sha1 => Ok(20),
HashType::Sha256 => Ok(32),
HashType::Sha384 => Ok(48),
HashType::Sha512 => Ok(64),
_ => Err("invalid hash algorithm".into()),
}
}
pub enum HashFunc {
Sha1(sha1::Sha1),
Sha256(sha2::Sha256),
Sha384(sha2::Sha384),
Sha512(sha2::Sha512),
}
pub fn get_hash_func(hash: HashType) -> Option<HashFunc> {
match hash {
HashType::Sha1 => Some(HashFunc::Sha1(sha1::Sha1::new())),
HashType::Sha256 => Some(HashFunc::Sha256(sha2::Sha256::new())),
HashType::Sha384 => Some(HashFunc::Sha384(sha2::Sha384::new())),
HashType::Sha512 => Some(HashFunc::Sha512(sha2::Sha512::new())),
_ => None,
}
}
pub fn compute_hash(hash_fn: &mut HashFunc, data: &[u8]) -> Result<Vec<u8>, TinkError> {
Ok(match hash_fn {
HashFunc::Sha1(h) => compute_hash_with(h, data),
HashFunc::Sha256(h) => compute_hash_with(h, data),
HashFunc::Sha384(h) => compute_hash_with(h, data),
HashFunc::Sha512(h) => compute_hash_with(h, data),
})
}
fn compute_hash_with<T>(hash_func: &mut T, data: &[u8]) -> Vec<u8>
where
T: digest::Digest,
{
hash_func.reset();
hash_func.update(data);
hash_func.finalize_reset().to_vec()
}
pub fn constant_time_compare(left: &[u8], right: &[u8]) -> bool {
left.ct_eq(right).into()
}