wlan_rsn/
prf.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Used in PRF as specified in IEEE Std 802.11-2016, 12.7.1.2.
6use 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
14// IEEE Std 802.11-2016, 12.7.1.2
15// HMAC-SHA1 is considered insecure but is required to be used in IEEE 802.11's PRF.
16pub(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    // IEEE Std 802.11-2016, J.3.2, Test case 1
41    #[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    // IEEE Std 802.11-2016, J.3.2, Test case 2
52    #[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    // IEEE Std 802.11-2016, J.3.2, Test case 3
63    #[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    // IEEE Std 802.11-2016, J.6.5, Test case 1
75    #[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    // IEEE Std 802.11-2016, J.6.5, Test case 2
86    #[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    // IEEE Std 802.11-2016, J.6.5, Test case 3
99    #[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    // IEEE Std 802.11-2016, J.6.5, Test case 4
115    #[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}