1use crate::Error;
7use anyhow::ensure;
8use hmac::Mac as _;
9
10type HmacSha1 = hmac::Hmac<sha1::Sha1>;
11
12const VALID_PRF_BIT_SIZES: [usize; 6] = [128, 192, 256, 384, 512, 704];
13
14pub(crate) fn prf(k: &[u8], a: &str, b: &[u8], bits: usize) -> Result<Vec<u8>, anyhow::Error> {
17 ensure!(VALID_PRF_BIT_SIZES.contains(&bits), Error::InvalidBitSize(bits));
18
19 let mut result = Vec::with_capacity(bits / 8);
20 let iterations = (bits + 159) / 160;
21 for i in 0..iterations {
22 let mut hmac = HmacSha1::new_from_slice(k).expect("create new HmacSha1");
23 hmac.update(a.as_bytes());
24 hmac.update(&[0u8]);
25 hmac.update(b);
26 hmac.update(&[i as u8]);
27 result.extend_from_slice(&hmac.finalize().into_bytes().as_ref());
28 }
29 result.resize(bits / 8, 0);
30 Ok(result)
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use hex::FromHex;
37
38 const VALID_BIT_SIZES: [usize; 6] = [128, 192, 256, 384, 512, 704];
39
40 #[test]
42 fn test_prf_test_case_1() {
43 let key = Vec::from_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
44 let actual = prf(&key[..], "prefix", "Hi There".as_bytes(), 512);
45 assert_eq!(actual.is_ok(), true);
46
47 let expected = Vec::from_hex("bcd4c650b30b9684951829e0d75f9d54b862175ed9f00606e17d8da35402ffee75df78c3d31e0f889f012120c0862beb67753e7439ae242edb8373698356cf5a").unwrap();
48 assert_eq!(actual.unwrap(), expected);
49 }
50
51 #[test]
53 fn test_prf_test_case_2() {
54 let key = "Jefe".as_bytes();
55 let actual = prf(&key[..], "prefix", "what do ya want for nothing?".as_bytes(), 512);
56 assert_eq!(actual.is_ok(), true);
57
58 let expected = Vec::from_hex("51f4de5b33f249adf81aeb713a3c20f4fe631446fabdfa58244759ae58ef9009a99abf4eac2ca5fa87e692c440eb40023e7babb206d61de7b92f41529092b8fc").unwrap();
59 assert_eq!(actual.unwrap(), expected);
60 }
61
62 #[test]
64 fn test_prf_test_case_3() {
65 let key = Vec::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap();
66 let data: [u8; 50] = [0xdd; 50];
67 let actual = prf(&key[..], "prefix", &data[..], 512);
68 assert_eq!(actual.is_ok(), true);
69
70 let expected = Vec::from_hex("e1ac546ec4cb636f9976487be5c86be17a0252ca5d8d8df12cfb0473525249ce9dd8d177ead710bc9b590547239107aef7b4abd43d87f0a68f1cbd9e2b6f7607").unwrap();
71 assert_eq!(actual.unwrap(), expected);
72 }
73
74 #[test]
76 fn test_prf_test_case_65_1() {
77 let key = Vec::from_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
78 let actual = prf(&key[..], "prefix", "Hi There".as_bytes(), 192);
79 assert_eq!(actual.is_ok(), true);
80
81 let expected = Vec::from_hex("bcd4c650b30b9684951829e0d75f9d54b862175ed9f00606").unwrap();
82 assert_eq!(actual.unwrap(), expected);
83 }
84
85 #[test]
87 fn test_prf_test_case_65_2() {
88 let key = "Jefe".as_bytes();
89 let actual = prf(&key[..], "prefix-2", "what do ya want for nothing?".as_bytes(), 256);
90 assert_eq!(actual.is_ok(), true);
91
92 let expected =
93 Vec::from_hex("47c4908e30c947521ad20be9053450ecbea23d3aa604b77326d8b3825ff7475c")
94 .unwrap();
95 assert_eq!(actual.unwrap(), expected);
96 }
97
98 #[test]
100 fn test_prf_test_case_65_3() {
101 let key = Vec::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap();
102 let actual = prf(
103 &key[..],
104 "prefix-3",
105 "Test Using Larger Than Block-Size Key - Hash Key First".as_bytes(),
106 384,
107 );
108 assert_eq!(actual.is_ok(), true);
109
110 let expected = Vec::from_hex("0ab6c33ccf70d0d736f4b04c8a7373255511abc5073713163bd0b8c9eeb7e1956fa066820a73ddee3f6d3bd407e0682a").unwrap();
111 assert_eq!(actual.unwrap(), expected);
112 }
113
114 #[test]
116 fn test_prf_test_case_65_4() {
117 let key = Vec::from_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
118 let actual = prf(&key[..], "prefix-4", "Hi There Again".as_bytes(), 512);
119 assert_eq!(actual.is_ok(), true);
120
121 let expected = Vec::from_hex("248cfbc532ab38ffa483c8a2e40bf170eb542a2e0916d7bf6d97da2c4c5ca877736c53a65b03fa4b3745ce7613f6ad68e0e4a798b7cf691c96176fd634a59a49").unwrap();
122 assert_eq!(actual.unwrap(), expected);
123 }
124
125 #[test]
126 fn test_prf_empty_key() {
127 let key: [u8; 0] = [];
128 let actual = prf(&key[..], "something is happening", "Lorem ipsum".as_bytes(), 256);
129 assert_eq!(actual.is_ok(), true);
130
131 let expected =
132 Vec::from_hex("5b154287399baeabd7d2c9682989e0933b3fdef8211ae7ae0c6586bb1e38de7c")
133 .unwrap();
134 assert_eq!(actual.unwrap(), expected);
135 }
136
137 #[test]
138 fn test_prf_empty_prefix() {
139 let key = Vec::from_hex("aaaa").unwrap();
140 let actual = prf(&key[..], "", "Lorem ipsum".as_bytes(), 256);
141 assert_eq!(actual.is_ok(), true);
142
143 let expected =
144 Vec::from_hex("1317523ae07f212fc4139ce9ebafe31ecf7c59cb07c7a7f04131afe7a59de60c")
145 .unwrap();
146 assert_eq!(actual.unwrap(), expected);
147 }
148
149 #[test]
150 fn test_prf_empty_data() {
151 let key = Vec::from_hex("aaaa").unwrap();
152 let actual = prf(&key[..], "some prefix", "".as_bytes(), 192);
153 assert_eq!(actual.is_ok(), true);
154
155 let expected = Vec::from_hex("785e095774cfea480c267e74130cb86d1e3fc80095b66554").unwrap();
156 assert_eq!(actual.unwrap(), expected);
157 }
158
159 #[test]
160 fn test_prf_all_empty() {
161 let key: [u8; 0] = [];
162 let actual = prf(&key[..], "", "".as_bytes(), 128);
163 assert_eq!(actual.is_ok(), true);
164
165 let expected = Vec::from_hex("310354661a5962d5b8cb76032d5a97e8").unwrap();
166 assert_eq!(actual.unwrap(), expected);
167 }
168
169 #[test]
170 fn test_prf_valid_bit_sizes() {
171 for bits in &VALID_BIT_SIZES {
172 let result = prf("".as_bytes(), "", "".as_bytes(), *bits as usize);
173 assert_eq!(result.is_ok(), true, "expected success with valid bit size: {:?}", *bits);
174 }
175 }
176
177 #[test]
178 fn test_prf_invalid_bit_sizes() {
179 for bits in 0..2048_usize {
180 if VALID_BIT_SIZES.contains(&bits) {
181 continue;
182 }
183 let result = prf("".as_bytes(), "", "".as_bytes(), bits as usize);
184 assert_eq!(result.is_err(), true, "expected failure with wrong bit size: {:?}", bits);
185 }
186 }
187}