wlan_rsn/integrity/
cmac_aes128.rs

1// Copyright 2020 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
5use crate::aes::{self, SizedKey};
6use crate::integrity::Algorithm;
7use crate::Error;
8use log::error;
9
10/// The AES CMAC-128 algorithm is used for integrity checks on AKMS 00-0F-AC:3 through 00-0F-AC:9.
11/// https://tools.ietf.org/html/rfc4493
12pub struct CmacAes128;
13
14impl CmacAes128 {
15    pub fn new() -> Self {
16        Self
17    }
18}
19
20impl Algorithm for CmacAes128 {
21    fn verify(&self, key: &[u8], data: &[u8], expected: &[u8]) -> bool {
22        match self.compute(key, data) {
23            Ok(output) => output == expected,
24            Err(error) => {
25                error!("message integrity verification failed: {:?}", error);
26                false
27            }
28        }
29    }
30
31    fn compute(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Error> {
32        let key = SizedKey::try_from_slice(key)?;
33        let mac = aes::cmac(&key, data)?;
34        Ok(mac.into())
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use crate::aes::AesError;
42    use hex::FromHex;
43    use wlan_common::assert_variant;
44
45    const K: &str = "2b7e151628aed2a6abf7158809cf4f3c";
46
47    // RFC 4493, 4. Test Vectors: Example 1
48    #[test]
49    fn test_len_0() {
50        let key = Vec::from_hex(K).unwrap();
51        let data = vec![];
52        let expected = Vec::from_hex("bb1d6929e95937287fa37d129b756746").unwrap();
53        let actual = CmacAes128::new().compute(&key[..], &data[..]).unwrap();
54        assert_eq!(actual, expected);
55    }
56
57    // RFC 4493, 4. Test Vectors: Example 2
58    #[test]
59    fn test_len_16() {
60        let key = Vec::from_hex(K).unwrap();
61        let data = Vec::from_hex("6bc1bee22e409f96e93d7e117393172a").unwrap();
62        let expected = Vec::from_hex("070a16b46b4d4144f79bdd9dd04a287c").unwrap();
63        let actual = CmacAes128::new().compute(&key[..], &data[..]).unwrap();
64        assert_eq!(actual, expected);
65    }
66
67    // RFC 4493, 4. Test Vectors: Example 3
68    #[test]
69    fn test_len_40() {
70        let key = Vec::from_hex(K).unwrap();
71        let data = Vec::from_hex(
72            "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411",
73        )
74        .unwrap();
75        let expected = Vec::from_hex("dfa66747de9ae63030ca32611497c827").unwrap();
76        let actual = CmacAes128::new().compute(&key[..], &data[..]).unwrap();
77        assert_eq!(actual, expected);
78    }
79
80    // RFC 4493, 4. Test Vectors: Example 4
81    #[test]
82    fn test_len_64() {
83        let key = Vec::from_hex(K).unwrap();
84        let data = Vec::from_hex("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710").unwrap();
85        let expected = Vec::from_hex("51f0bebf7e3b9d92fc49741779363cfe").unwrap();
86        let actual = CmacAes128::new().compute(&key[..], &data[..]).unwrap();
87        assert_eq!(actual, expected);
88    }
89
90    #[test]
91    fn test_wrong_key_len() {
92        let key = Vec::from_hex("123456").unwrap();
93        let data = vec![];
94        assert_variant!(
95            CmacAes128::new().compute(&key[..], &data[..]),
96            Err(Error::Aes(AesError::KeySize(3)))
97        );
98    }
99
100    #[test]
101    fn test_verify_len_0() {
102        let key = Vec::from_hex(K).unwrap();
103        let data = vec![];
104        let expected = Vec::from_hex("bb1d6929e95937287fa37d129b756746").unwrap();
105        assert!(CmacAes128::new().verify(&key[..], &data[..], &expected[..]));
106    }
107}