wlan_sme/client/
wpa.rs
1use wlan_common::ie::rsn::{akm, cipher};
6use wlan_common::ie::wpa::WpaIe;
7use wlan_common::organization::Oui;
8
9pub fn is_legacy_wpa_compatible(a_wpa: &WpaIe) -> bool {
13 let multicast_supported = a_wpa.multicast_cipher.has_known_usage()
14 && (a_wpa.multicast_cipher.suite_type == cipher::TKIP
15 || a_wpa.multicast_cipher.suite_type == cipher::CCMP_128);
16 let unicast_supported = a_wpa.unicast_cipher_list.iter().any(|c| {
17 c.has_known_usage() && (c.suite_type == cipher::TKIP || c.suite_type == cipher::CCMP_128)
18 });
19 let akm_supported =
20 a_wpa.akm_list.iter().any(|a| a.has_known_algorithm() && a.suite_type == akm::PSK);
21 multicast_supported && unicast_supported && akm_supported
22}
23
24pub fn construct_s_wpa(a_wpa: &WpaIe) -> WpaIe {
28 let unicast_cipher = if a_wpa
30 .unicast_cipher_list
31 .iter()
32 .any(|c| c.has_known_usage() && c.suite_type == cipher::CCMP_128)
33 {
34 cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::CCMP_128 }
35 } else {
36 cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::TKIP }
37 };
38 WpaIe {
39 multicast_cipher: a_wpa.multicast_cipher,
40 unicast_cipher_list: vec![unicast_cipher],
41 akm_list: vec![akm::Akm { oui: Oui::MSFT, suite_type: akm::PSK }],
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use crate::test_utils;
49
50 #[test]
51 fn test_incompatible_multicast_cipher() {
52 let mut a_wpa = test_utils::make_wpa1_ie();
53 a_wpa.multicast_cipher = cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::WEP_40 };
54 assert!(!is_legacy_wpa_compatible(&a_wpa));
55 }
56
57 #[test]
58 fn test_incompatible_unicast_cipher() {
59 let mut a_wpa = test_utils::make_wpa1_ie();
60 a_wpa.unicast_cipher_list =
61 vec![cipher::Cipher { oui: Oui::DOT11, suite_type: cipher::WEP_40 }];
62 assert!(!is_legacy_wpa_compatible(&a_wpa));
63 }
64
65 #[test]
66 fn test_incompatible_akm() {
67 let mut a_wpa = test_utils::make_wpa1_ie();
68 a_wpa.akm_list = vec![akm::Akm { oui: Oui::DOT11, suite_type: akm::EAP }];
69 assert!(!is_legacy_wpa_compatible(&a_wpa));
70 }
71
72 #[test]
73 fn get_supplicant_ie_tkip() {
74 let mut a_wpa = test_utils::make_wpa1_ie();
75 a_wpa.unicast_cipher_list =
76 vec![cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::TKIP }];
77 let s_wpa = construct_s_wpa(&a_wpa);
78 assert_eq!(
79 s_wpa.unicast_cipher_list,
80 vec![cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::TKIP }]
81 );
82 }
83
84 #[test]
85 fn get_supplicant_ie_ccmp() {
86 let mut a_wpa = test_utils::make_wpa1_ie();
87 a_wpa.unicast_cipher_list = vec![
88 cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::TKIP },
89 cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::CCMP_128 },
90 ];
91 let s_wpa = construct_s_wpa(&a_wpa);
92 assert_eq!(
93 s_wpa.unicast_cipher_list,
94 vec![cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::CCMP_128 }]
95 );
96 }
97
98 #[test]
99 fn test_no_unicast_cipher() {
100 let mut a_wpa = test_utils::make_wpa1_ie();
101 a_wpa.unicast_cipher_list = vec![];
102 assert!(!is_legacy_wpa_compatible(&a_wpa));
103 }
104
105 #[test]
106 fn test_no_akm() {
107 let mut a_wpa = test_utils::make_wpa1_ie();
108 a_wpa.akm_list = vec![];
109 assert!(!is_legacy_wpa_compatible(&a_wpa));
110 }
111}