sentc_crypto_std_keys/core/hmac/
hmac_sha256.rs1use alloc::vec::Vec;
2
3use hmac::{Hmac, Mac};
4use sentc_crypto_core::cryptomat::{SearchableKey, SearchableKeyGen, SymKey};
5use sentc_crypto_core::{as_ref_bytes_single_value, crypto_alg_str_impl, try_from_bytes_owned_single_value, Error};
6use sha2::Sha256;
7
8use crate::core::hmac::HmacKey;
9use crate::core::sym;
10use crate::core::sym::aes_gcm::AesKey;
11
12pub const HMAC_SHA256_OUTPUT: &str = "HMAC-SHA256";
13
14type HmacSha256 = Hmac<Sha256>;
15
16pub struct HmacSha256Key(AesKey);
17
18try_from_bytes_owned_single_value!(HmacSha256Key);
19as_ref_bytes_single_value!(HmacSha256Key);
20crypto_alg_str_impl!(HmacSha256Key, HMAC_SHA256_OUTPUT);
21
22impl Into<HmacKey> for HmacSha256Key
23{
24 fn into(self) -> HmacKey
25 {
26 HmacKey::HmacSha256(self)
27 }
28}
29
30impl SearchableKey for HmacSha256Key
31{
32 fn encrypt_key_with_master_key<M: SymKey>(&self, master_key: &M) -> Result<Vec<u8>, Error>
33 {
34 master_key.encrypt(&self.0)
35 }
36
37 fn encrypt_searchable(&self, data: &[u8]) -> Result<Vec<u8>, Error>
38 {
39 let mut mac = HmacSha256::new_from_slice(&self.0).map_err(|_| Error::HmacAuthFailedLength)?;
40
41 mac.update(data);
42
43 let result = mac.finalize();
44 let result = result.into_bytes();
45
46 Ok(result.to_vec())
47 }
48
49 fn verify_encrypted_searchable(&self, data: &[u8], check: &[u8]) -> Result<bool, Error>
50 {
51 let mut mac = HmacSha256::new_from_slice(&self.0).map_err(|_| Error::HmacAuthFailedLength)?;
52
53 mac.update(data);
54
55 Ok(mac.verify_slice(check).is_ok())
56 }
57}
58
59impl SearchableKeyGen for HmacSha256Key
60{
61 type SearchableKey = Self;
62
63 fn generate() -> Result<Self::SearchableKey, Error>
64 {
65 Ok(Self(sym::aes_gcm::raw_generate()?))
66 }
67}
68
69#[cfg(test)]
70mod test
71{
72 use super::*;
73
74 #[test]
75 fn test_create_hmac_key()
76 {
77 let _ = HmacSha256Key::generate().unwrap();
78 }
79
80 #[test]
81 fn test_plain_auth_msg()
82 {
83 let msg = "Hello world üöäéèßê°";
84
85 let out = HmacSha256Key::generate().unwrap();
86
87 let mac = out.encrypt_searchable(msg.as_bytes()).unwrap();
88
89 let verify = out
90 .verify_encrypted_searchable(msg.as_bytes(), &mac)
91 .unwrap();
92
93 assert!(verify);
94 }
95
96 #[test]
97 fn test_not_verify_with_wrong_key()
98 {
99 let msg = "Hello world üöäéèßê°";
100
101 let out = HmacSha256Key::generate().unwrap();
102 let out2 = HmacSha256Key::generate().unwrap();
103
104 let mac = out.encrypt_searchable(msg.as_bytes()).unwrap();
105
106 let verify = out2
107 .verify_encrypted_searchable(msg.as_bytes(), &mac)
108 .unwrap();
109
110 assert!(!verify);
111 }
112
113 #[test]
114 fn test_not_producing_the_same_output_with_different_keys()
115 {
116 let msg = "Hello world üöäéèßê°";
117
118 let out = HmacSha256Key::generate().unwrap();
119 let out2 = HmacSha256Key::generate().unwrap();
120
121 let mac1 = out.encrypt_searchable(msg.as_bytes()).unwrap();
122
123 let mac2 = out2.encrypt_searchable(msg.as_bytes()).unwrap();
124
125 assert_ne!(mac1, mac2);
126 }
127
128 #[test]
129 fn test_producing_the_same_output_with_same_keys()
130 {
131 let msg = "Hello world üöäéèßê°";
132
133 let out = HmacSha256Key::generate().unwrap();
134
135 let mac1 = out.encrypt_searchable(msg.as_bytes()).unwrap();
136
137 let mac2 = out.encrypt_searchable(msg.as_bytes()).unwrap();
138
139 assert_eq!(mac1, mac2);
140 }
141}