1use super::akm::{self, AKM_PSK, AKM_SAE};
6use super::cipher::{self, CIPHER_CCMP_128};
7use super::suite_filter::DEFAULT_GROUP_MGMT_CIPHER;
8use super::{pmkid, suite_selector};
9
10use crate::append::{Append, BufferTooSmall};
11use crate::organization::Oui;
12use bytes::Bytes;
13use fidl_fuchsia_wlan_common as fidl_common;
14use nom::branch::alt;
15use nom::bytes::streaming::take;
16use nom::combinator::{eof, map, map_res};
17use nom::multi::length_count;
18use nom::number::streaming::{le_u8, le_u16};
19use nom::sequence::terminated;
20use nom::{IResult, Parser};
21use wlan_bitfield::bitfield;
22
23use thiserror::Error;
24
25macro_rules! if_remaining (
26 ($f:expr) => (alt((map(eof, |_| None), map($f, Some))));
28);
29
30pub const ID: u8 = 48;
32pub const VERSION: u16 = 1;
33
34#[derive(Debug, Error, Eq, PartialEq)]
35pub enum Error {
36 #[error("no group data cipher suite")]
37 NoGroupDataCipherSuite,
38 #[error("no pairwise cipher suite")]
39 NoPairwiseCipherSuite,
40 #[error("too many pairwise cipher suites")]
41 TooManyPairwiseCipherSuites,
42 #[error("no akm suite")]
43 NoAkmSuite,
44 #[error("too many akm suites")]
45 TooManyAkmSuites,
46 #[error("AKM suite does not have mic_bytes")]
47 NoAkmMicBytes,
48 #[error("invalid supplicant management frame protection")]
49 InvalidSupplicantMgmtFrameProtection,
50 #[error("invalid authenticator management frame protection")]
51 InvalidAuthenticatorMgmtFrameProtection,
52 #[error("cannot derive WPA2 RSNE")]
53 CannotDeriveWpa2Rsne,
54 #[error("cannot derive WPA3 RSNE")]
55 CannotDeriveWpa3Rsne,
56}
57
58#[macro_export]
59macro_rules! rsne_ensure {
60 ($cond:expr, $err:expr $(,)?) => {
61 if !$cond {
62 return std::result::Result::Err($err);
63 }
64 };
65}
66
67#[derive(Debug, PartialOrd, PartialEq, Clone)]
69pub struct Rsne {
70 pub version: u16,
71 pub group_data_cipher_suite: Option<cipher::Cipher>,
72 pub pairwise_cipher_suites: Vec<cipher::Cipher>,
73 pub akm_suites: Vec<akm::Akm>,
74 pub rsn_capabilities: Option<RsnCapabilities>,
75 pub pmkids: Vec<pmkid::Pmkid>,
76 pub group_mgmt_cipher_suite: Option<cipher::Cipher>,
77}
78
79impl Default for Rsne {
80 fn default() -> Self {
81 Rsne {
82 version: VERSION,
83 group_data_cipher_suite: None,
84 pairwise_cipher_suites: vec![],
85 akm_suites: vec![],
86 rsn_capabilities: None,
87 pmkids: vec![],
88 group_mgmt_cipher_suite: None,
89 }
90 }
91}
92
93#[bitfield(
94 0 preauth,
95 1 no_pairwise,
96 2..=3 ptksa_replay_counter,
97 4..=5 gtksa_replay_counter,
98 6 mgmt_frame_protection_req,
99 7 mgmt_frame_protection_cap,
100 8 joint_multiband,
101 9 peerkey_enabled,
102 10 ssp_amsdu_cap,
103 11 ssp_amsdu_req,
104 12 pbac,
105 13 extended_key_id,
106 14..=15 _, )]
108#[derive(PartialOrd, PartialEq, Clone)]
109pub struct RsnCapabilities(pub u16);
110
111impl RsnCapabilities {
112 pub fn is_wpa2_compatible(&self) -> bool {
113 !self.contains_unsupported_capability()
114 }
115
116 pub fn is_wpa3_compatible(&self, wpa2_compatibility_mode: bool) -> bool {
117 self.mgmt_frame_protection_cap()
118 && (self.mgmt_frame_protection_req() || wpa2_compatibility_mode)
119 && !self.contains_unsupported_capability()
120 }
121
122 pub fn is_compatible_with_features(
123 &self,
124 security_support: &fidl_common::SecuritySupport,
125 ) -> bool {
126 !self.mgmt_frame_protection_req()
127 || security_support.mfp.as_ref().map_or(false, |mfp| mfp.supported.unwrap_or(false))
128 }
129
130 fn contains_unsupported_capability(&self) -> bool {
133 self.joint_multiband()
134 || self.peerkey_enabled()
135 || self.ssp_amsdu_req()
136 || self.pbac()
137 || self.extended_key_id()
138 }
139}
140
141#[derive(PartialEq)]
143enum FinalField {
144 Version,
145 GroupData,
146 Pairwise,
147 Akm,
148 Caps,
149 Pmkid,
150 GroupMgmt,
151}
152
153impl Rsne {
154 pub fn wpa2_rsne() -> Self {
155 Rsne {
156 group_data_cipher_suite: Some(CIPHER_CCMP_128),
157 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
158 akm_suites: vec![AKM_PSK],
159 ..Default::default()
160 }
161 }
162
163 pub fn wpa2_rsne_with_caps(rsn_capabilities: RsnCapabilities) -> Self {
164 Self::wpa2_rsne().with_caps(rsn_capabilities)
165 }
166
167 pub fn wpa2_wpa3_rsne() -> Self {
168 Rsne {
169 group_data_cipher_suite: Some(CIPHER_CCMP_128),
170 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
171 akm_suites: vec![AKM_SAE, AKM_PSK],
172 rsn_capabilities: Some(RsnCapabilities(0).with_mgmt_frame_protection_cap(true)),
173 group_mgmt_cipher_suite: Some(DEFAULT_GROUP_MGMT_CIPHER),
178 ..Default::default()
179 }
180 }
181
182 pub fn wpa2_wpa3_rsne_with_extra_caps(rsn_capabilities: RsnCapabilities) -> Self {
183 let rsne = Self::wpa2_wpa3_rsne();
184 let wpa2_wpa3_minimum_rsn_capabilities = rsne.rsn_capabilities.as_ref().unwrap().clone();
185 rsne.with_caps(RsnCapabilities(
186 wpa2_wpa3_minimum_rsn_capabilities.raw() | rsn_capabilities.raw(),
187 ))
188 }
189
190 pub fn wpa3_rsne() -> Self {
191 Rsne {
192 group_data_cipher_suite: Some(CIPHER_CCMP_128),
193 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
194 akm_suites: vec![AKM_SAE],
195 rsn_capabilities: Some(
196 RsnCapabilities(0)
197 .with_mgmt_frame_protection_cap(true)
198 .with_mgmt_frame_protection_req(true),
199 ),
200 group_mgmt_cipher_suite: Some(DEFAULT_GROUP_MGMT_CIPHER),
205 ..Default::default()
206 }
207 }
208
209 pub fn wpa3_rsne_with_extra_caps(rsn_capabilities: RsnCapabilities) -> Self {
210 let rsne = Self::wpa3_rsne();
211 let wpa3_minimum_rsn_capabilities = rsne.rsn_capabilities.as_ref().unwrap().clone();
212 rsne.with_caps(RsnCapabilities(
213 wpa3_minimum_rsn_capabilities.raw() | rsn_capabilities.raw(),
214 ))
215 }
216
217 pub fn derive_wpa2_s_rsne(
222 &self,
223 security_support: &fidl_common::SecuritySupport,
224 ) -> Result<Self, Error> {
225 if !self.is_wpa2_rsn_compatible(&security_support) {
226 return Err(Error::CannotDeriveWpa2Rsne);
227 }
228
229 let rsn_capabilities = match self.rsn_capabilities.clone() {
231 Some(cap) => {
232 if cap.mgmt_frame_protection_cap()
233 && security_support
234 .mfp
235 .as_ref()
236 .map_or(false, |mfp| mfp.supported.unwrap_or(false))
237 {
238 Some(cap.with_mgmt_frame_protection_req(true))
239 } else {
240 Some(cap)
241 }
242 }
243 None => None,
244 };
245
246 let pairwise_cipher_suites =
248 vec![match self.pairwise_cipher_suites.iter().max_by_key(|cipher_suite| {
249 match **cipher_suite {
250 CIPHER_CCMP_128 => 1,
251 _ => 0,
252 }
253 }) {
254 Some(cipher_suite) => cipher_suite.clone(),
255 None => return Err(Error::NoPairwiseCipherSuite),
256 }];
257
258 Ok(Rsne {
259 group_data_cipher_suite: self.group_data_cipher_suite.clone(),
260 pairwise_cipher_suites,
261 akm_suites: vec![AKM_PSK],
262 rsn_capabilities,
263 ..Default::default()
264 })
265 }
266
267 pub fn derive_wpa3_s_rsne(
272 &self,
273 security_support: &fidl_common::SecuritySupport,
274 ) -> Result<Rsne, Error> {
275 if !self.is_wpa3_rsn_compatible(&security_support) {
276 return Err(Error::CannotDeriveWpa3Rsne);
277 }
278
279 let rsn_capabilities = match self.rsn_capabilities.clone() {
280 Some(cap) => Some(cap.with_mgmt_frame_protection_req(true)),
281 None => None,
282 };
283
284 Ok(Rsne {
285 group_data_cipher_suite: self.group_data_cipher_suite.clone(),
286 pairwise_cipher_suites: vec![cipher::Cipher {
287 oui: suite_selector::OUI,
288 suite_type: cipher::CCMP_128,
289 }],
290 akm_suites: vec![akm::Akm { oui: suite_selector::OUI, suite_type: akm::SAE }],
291 rsn_capabilities,
292 ..Default::default()
293 })
294 }
295
296 pub fn ensure_valid_s_rsne(&self) -> Result<(), Error> {
299 let s_rsne = self;
300 s_rsne.group_data_cipher_suite.as_ref().ok_or(Error::NoGroupDataCipherSuite)?;
301
302 rsne_ensure!(s_rsne.pairwise_cipher_suites.len() >= 1, Error::NoPairwiseCipherSuite);
303 rsne_ensure!(s_rsne.pairwise_cipher_suites.len() <= 1, Error::TooManyPairwiseCipherSuites);
304
305 rsne_ensure!(s_rsne.akm_suites.len() >= 1, Error::NoAkmSuite);
306 rsne_ensure!(s_rsne.akm_suites.len() <= 1, Error::TooManyAkmSuites);
307
308 let akm = &s_rsne.akm_suites[0];
309 rsne_ensure!(akm.mic_bytes().is_some(), Error::NoAkmMicBytes);
310
311 Ok(())
312 }
313
314 pub fn is_valid_subset_of(&self, a_rsne: &Rsne) -> Result<bool, Error> {
316 let s_rsne = self;
317 s_rsne.ensure_valid_s_rsne()?;
318
319 let s_caps = s_rsne.rsn_capabilities.as_ref().unwrap_or(&RsnCapabilities(0));
320 let s_mgmt_req = s_caps.mgmt_frame_protection_req();
321 let s_mgmt_cap = s_caps.mgmt_frame_protection_cap();
322 let a_caps = a_rsne.rsn_capabilities.as_ref().unwrap_or(&RsnCapabilities(0));
323 let a_mgmt_req = a_caps.mgmt_frame_protection_req();
324 let a_mgmt_cap = a_caps.mgmt_frame_protection_cap();
325
326 match (a_mgmt_cap, a_mgmt_req, s_mgmt_cap, s_mgmt_req) {
328 (true, _, false, true) => return Err(Error::InvalidSupplicantMgmtFrameProtection),
329 (false, true, true, _) => return Err(Error::InvalidAuthenticatorMgmtFrameProtection),
330 (true, true, false, false) => return Ok(false),
331 (false, false, true, true) => return Ok(false),
332 _ => (),
338 }
339
340 Ok(a_rsne
341 .group_data_cipher_suite
342 .iter()
343 .any(|c| c == s_rsne.group_data_cipher_suite.as_ref().unwrap())
345 && a_rsne.pairwise_cipher_suites.iter().any(|c| *c == s_rsne.pairwise_cipher_suites[0])
346 && a_rsne.akm_suites.iter().any(|c| *c == s_rsne.akm_suites[0]))
347 }
348
349 fn final_field(&self) -> FinalField {
356 if self.group_data_cipher_suite.is_none() {
357 FinalField::Version
358 } else if self.rsn_capabilities.is_none() {
359 if self.akm_suites.is_empty() {
360 if self.pairwise_cipher_suites.is_empty() {
361 FinalField::GroupData
362 } else {
363 FinalField::Pairwise
364 }
365 } else {
366 FinalField::Akm
367 }
368 } else {
369 if self.group_mgmt_cipher_suite.is_none() {
370 if self.pmkids.is_empty() { FinalField::Caps } else { FinalField::Pmkid }
371 } else {
372 FinalField::GroupMgmt
373 }
374 }
375 }
376
377 pub fn len(&self) -> usize {
379 let final_field = self.final_field();
380 let mut length: usize = 4; if final_field == FinalField::Version {
382 return length;
383 }
384 length += 4; if final_field == FinalField::GroupData {
386 return length;
387 }
388 length += 2 + 4 * self.pairwise_cipher_suites.len();
390 if final_field == FinalField::Pairwise {
391 return length;
392 }
393 length += 2 + 4 * self.akm_suites.len();
395 if final_field == FinalField::Akm {
396 return length;
397 }
398 length += 2; if final_field == FinalField::Caps {
400 return length;
401 }
402 length += 2 + 16 * self.pmkids.len();
404 if final_field == FinalField::Pmkid {
405 return length;
406 }
407 length + 4 }
409
410 pub fn into_bytes(self) -> Vec<u8> {
411 let mut buf = Vec::with_capacity(self.len());
412 self.write_into(&mut buf).expect("error writing RSNE into buffer");
413 buf
414 }
415
416 pub fn write_into<A: Append>(&self, buf: &mut A) -> Result<(), BufferTooSmall> {
417 if !buf.can_append(self.len()) {
418 return Err(BufferTooSmall);
419 }
420 let final_field = self.final_field();
421
422 buf.append_byte(ID)?;
423 buf.append_byte((self.len() - 2) as u8)?;
424 buf.append_value(&self.version)?;
425 if final_field == FinalField::Version {
426 return Ok(());
427 }
428
429 match self.group_data_cipher_suite.as_ref() {
430 None => return Ok(()),
431 Some(cipher) => {
432 buf.append_bytes(&cipher.oui[..])?;
433 buf.append_byte(cipher.suite_type)?;
434 }
435 };
436 if final_field == FinalField::GroupData {
437 return Ok(());
438 }
439
440 buf.append_value(&(self.pairwise_cipher_suites.len() as u16))?;
441 for cipher in &self.pairwise_cipher_suites {
442 buf.append_bytes(&cipher.oui[..])?;
443 buf.append_byte(cipher.suite_type)?;
444 }
445 if final_field == FinalField::Pairwise {
446 return Ok(());
447 }
448
449 buf.append_value(&(self.akm_suites.len() as u16))?;
450 for akm in &self.akm_suites {
451 buf.append_bytes(&akm.oui[..])?;
452 buf.append_byte(akm.suite_type)?;
453 }
454 if final_field == FinalField::Akm {
455 return Ok(());
456 }
457
458 match self.rsn_capabilities.as_ref() {
459 None => return Ok(()),
460 Some(caps) => buf.append_value(&caps.0)?,
461 };
462 if final_field == FinalField::Caps {
463 return Ok(());
464 }
465
466 buf.append_value(&(self.pmkids.len() as u16))?;
467 for pmkid in &self.pmkids {
468 buf.append_bytes(&pmkid[..])?;
469 }
470 if final_field == FinalField::Pmkid {
471 return Ok(());
472 }
473
474 if let Some(cipher) = self.group_mgmt_cipher_suite.as_ref() {
475 buf.append_bytes(&cipher.oui[..])?;
476 buf.append_byte(cipher.suite_type)?;
477 }
478 Ok(())
479 }
480
481 pub fn is_wpa2_rsn_compatible(&self, security_support: &fidl_common::SecuritySupport) -> bool {
486 let group_data_supported = self.group_data_cipher_suite.as_ref().is_some_and(|c| {
487 c.has_known_usage() && [cipher::CCMP_128, cipher::TKIP].contains(&c.suite_type)
489 });
490
491 let pairwise_supported = self.pairwise_cipher_suites.iter().any(|c| {
492 c.has_known_usage() && [cipher::CCMP_128, cipher::TKIP].contains(&c.suite_type)
493 });
494 let akm_supported =
495 self.akm_suites.iter().any(|a| a.has_known_algorithm() && a.suite_type == akm::PSK);
496 let caps_supported =
497 self.rsn_capabilities.as_ref().map_or(true, RsnCapabilities::is_wpa2_compatible);
498 let features_supported = self
499 .rsn_capabilities
500 .as_ref()
501 .unwrap_or(&RsnCapabilities(0))
502 .is_compatible_with_features(security_support);
503
504 group_data_supported
505 && pairwise_supported
506 && akm_supported
507 && caps_supported
508 && features_supported
509 }
510
511 pub fn is_wpa3_rsn_compatible(&self, security_support: &fidl_common::SecuritySupport) -> bool {
518 let group_data_supported = self.group_data_cipher_suite.as_ref().is_some_and(|c| {
519 c.has_known_usage() && [cipher::CCMP_128, cipher::TKIP].contains(&c.suite_type)
520 });
521 let pairwise_supported = self
522 .pairwise_cipher_suites
523 .iter()
524 .any(|c| c.has_known_usage() && c.suite_type == cipher::CCMP_128);
525 let sae_supported =
526 self.akm_suites.iter().any(|a| a.has_known_algorithm() && a.suite_type == akm::SAE);
527 let wpa2_compatibility_mode =
528 self.akm_suites.iter().any(|a| a.has_known_algorithm() && a.suite_type == akm::PSK);
529 let caps_supported = self
530 .rsn_capabilities
531 .as_ref()
532 .is_some_and(|caps| caps.is_wpa3_compatible(wpa2_compatibility_mode));
533 let mut features_supported = self
534 .rsn_capabilities
535 .as_ref()
536 .unwrap_or(&RsnCapabilities(0))
537 .is_compatible_with_features(security_support);
538 features_supported &=
541 security_support.mfp.as_ref().map_or(false, |mfp| mfp.supported.unwrap_or(false));
542 group_data_supported
543 && pairwise_supported
544 && sae_supported
545 && caps_supported
546 && features_supported
547 }
548
549 fn with_caps(mut self, rsn_capabilities: RsnCapabilities) -> Self {
550 self.rsn_capabilities = Some(rsn_capabilities);
551 self
552 }
553}
554
555fn read_suite_selector<T>(input: &[u8]) -> IResult<&[u8], T>
556where
557 T: suite_selector::Factory<Suite = T>,
558{
559 let (i1, bytes) = take(4usize).parse(input)?;
560 let oui = Oui::new([bytes[0], bytes[1], bytes[2]]);
561 return Ok((i1, T::new(oui, bytes[3])));
562}
563
564fn read_pmkid(input: &[u8]) -> IResult<&[u8], pmkid::Pmkid> {
565 let f = |bytes| {
566 let pmkid_data = Bytes::copy_from_slice(bytes);
567 return pmkid::new(pmkid_data);
568 };
569
570 map_res(nom::bytes::streaming::take(16usize), f).parse(input)
571}
572
573fn akm(input: &[u8]) -> IResult<&[u8], akm::Akm> {
574 read_suite_selector::<akm::Akm>(input)
575}
576
577fn cipher(input: &[u8]) -> IResult<&[u8], cipher::Cipher> {
578 read_suite_selector::<cipher::Cipher>(input)
579}
580
581pub fn from_bytes(input: &[u8]) -> IResult<&[u8], Rsne> {
585 map(
586 terminated(
587 (
588 le_u8,
589 le_u8,
590 le_u16,
591 if_remaining!(cipher),
592 if_remaining!(length_count(le_u16, cipher)),
593 if_remaining!(length_count(le_u16, akm)),
594 if_remaining!(map(le_u16, RsnCapabilities)),
595 if_remaining!(length_count(le_u16, read_pmkid)),
596 if_remaining!(cipher),
597 ),
598 eof,
599 ),
600 |(
601 _element_id,
602 _length,
603 version,
604 group_cipher,
605 pairwise_list,
606 akm_list,
607 rsn_capabilities,
608 pmkid_list,
609 group_mgmt_cipher_suite,
610 )| Rsne {
611 version: version,
612 group_data_cipher_suite: group_cipher,
613 pairwise_cipher_suites: pairwise_list.unwrap_or_default(),
614 akm_suites: akm_list.unwrap_or_default(),
615 rsn_capabilities: rsn_capabilities,
616 pmkids: pmkid_list.unwrap_or_default(),
617 group_mgmt_cipher_suite: group_mgmt_cipher_suite,
618 },
619 )
620 .parse(input)
621}
622
623#[cfg(test)]
624mod tests {
625 use super::akm::{AKM_EAP, AKM_FT_PSK};
626 use super::cipher::{CIPHER_BIP_CMAC_256, CIPHER_GCMP_256, CIPHER_TKIP};
627 use super::*;
628 use crate::append::TrackedAppend;
629 use crate::test_utils::FixedSizedTestBuffer;
630 use crate::test_utils::fake_features::fake_security_support_empty;
631 use test_case::test_case;
632
633 #[cfg(feature = "benchmark")]
634 mod bench {
635 use self::test::Bencher;
636 use super::*;
637 #[cfg()]
638 #[bench]
639 fn bench_parse_with_nom(b: &mut Bencher) {
640 let frame: Vec<u8> = vec![
641 0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
642 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
643 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
644 0xac, 0x04,
645 ];
646 b.iter(|| from_bytes(&frame));
647 }
648 }
649
650 #[test]
651 fn test_write_into() {
652 let frame: Vec<u8> = vec![
653 0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
654 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
655 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
656 0xac, 0x04,
657 ];
658 let result = from_bytes(&frame);
659 assert!(result.is_ok());
660 let rsne = result.unwrap().1;
661 let mut buf = Vec::with_capacity(128);
662 rsne.write_into(&mut buf).expect("failed writing RSNE");
663 let rsne_len = buf.len();
664 let left_over = buf.split_off(rsne_len);
665 assert_eq!(&buf[..], &frame[..]);
666 assert!(left_over.iter().all(|b| *b == 0));
667 }
668
669 #[test]
670 fn test_short_buffer() {
671 let frame: Vec<u8> = vec![
672 0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
673 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
674 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
675 0xac, 0x04,
676 ];
677 let mut buf = FixedSizedTestBuffer::new(32);
678 let result = from_bytes(&frame);
679 assert!(result.is_ok());
680 let rsne = result.unwrap().1;
681 rsne.write_into(&mut buf).expect_err("expected writing RSNE to fail");
682 assert_eq!(buf.bytes_appended(), 0);
683 }
684
685 #[test]
686 fn test_rsn_fields_representation() {
687 let frame: Vec<u8> = vec![
688 0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
700 0x10, 0x11, 0x00, 0x0f, 0xac, 0x04, ];
702 let result = from_bytes(&frame);
703 assert!(result.is_ok());
704 let rsne = result.unwrap().1;
705
706 assert_eq!(rsne.version, VERSION);
707 assert_eq!(rsne.len(), 0x2a + 2);
708
709 assert!(rsne.group_data_cipher_suite.is_some());
710 assert_eq!(rsne.group_data_cipher_suite, Some(CIPHER_CCMP_128));
711 assert_eq!(rsne.pairwise_cipher_suites.len(), 1);
712 assert_eq!(rsne.pairwise_cipher_suites[0].oui, Oui::DOT11);
713 assert_eq!(rsne.pairwise_cipher_suites[0].suite_type, cipher::CCMP_128);
714 assert_eq!(rsne.akm_suites.len(), 1);
715 assert_eq!(rsne.akm_suites[0].suite_type, akm::PSK);
716
717 let rsn_capabilities = rsne.rsn_capabilities.expect("should have RSN capabilities");
718 assert_eq!(rsn_capabilities.preauth(), false);
719 assert_eq!(rsn_capabilities.no_pairwise(), false);
720 assert_eq!(rsn_capabilities.ptksa_replay_counter(), 2);
721 assert_eq!(rsn_capabilities.gtksa_replay_counter(), 2);
722 assert!(!rsn_capabilities.mgmt_frame_protection_req());
723 assert!(rsn_capabilities.mgmt_frame_protection_cap());
724 assert!(!rsn_capabilities.joint_multiband());
725 assert!(!rsn_capabilities.peerkey_enabled());
726 assert!(rsn_capabilities.ssp_amsdu_cap());
727 assert!(!rsn_capabilities.ssp_amsdu_req());
728 assert!(!rsn_capabilities.pbac());
729 assert!(!rsn_capabilities.extended_key_id());
730
731 assert_eq!(rsn_capabilities.0, 0xa8 + (0x04 << 8));
732
733 let pmkids: &[u8] = &[
734 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
735 0x10, 0x11,
736 ];
737 assert_eq!(rsne.pmkids.len(), 1);
738 assert_eq!(rsne.pmkids[0], Bytes::from(pmkids));
739
740 assert_eq!(rsne.group_mgmt_cipher_suite, Some(CIPHER_CCMP_128));
741 }
742
743 #[test]
744 fn test_rsn_capabilities_setters() {
745 let mut rsn_caps = RsnCapabilities(0u16);
746 rsn_caps.set_ptksa_replay_counter(2);
747 rsn_caps.set_gtksa_replay_counter(2);
748 rsn_caps.set_mgmt_frame_protection_cap(true);
749 rsn_caps.set_ssp_amsdu_cap(true);
750
751 assert_eq!(rsn_caps.0, 0xa8 + (0x04 << 8));
752 }
753
754 #[test]
755 fn test_invalid_wpa2_caps() {
756 assert!(RsnCapabilities(0).is_wpa2_compatible());
757
758 let caps = RsnCapabilities(0).with_joint_multiband(true);
759 assert!(!caps.is_wpa2_compatible());
760
761 let caps = RsnCapabilities(0).with_peerkey_enabled(true);
762 assert!(!caps.is_wpa2_compatible());
763
764 let caps = RsnCapabilities(0).with_ssp_amsdu_req(true);
765 assert!(!caps.is_wpa2_compatible());
766
767 let caps = RsnCapabilities(0).with_pbac(true);
768 assert!(!caps.is_wpa2_compatible());
769
770 let caps = RsnCapabilities(0).with_extended_key_id(true);
771 assert!(!caps.is_wpa2_compatible());
772 }
773
774 use std::sync::LazyLock;
775 static MFP_SUPPORT_ONLY: LazyLock<fidl_common::SecuritySupport> =
776 LazyLock::new(|| fidl_common::SecuritySupport {
777 mfp: Some(fidl_common::MfpFeature { supported: Some(true), ..Default::default() }),
778 sae: Some(fidl_common::SaeFeature {
779 driver_handler_supported: Some(false),
780 sme_handler_supported: Some(false),
781 ..Default::default()
782 }),
783 ..Default::default()
784 });
785
786 #[test_case(MFP_SUPPORT_ONLY.clone(), true)]
787 #[test_case(fake_security_support_empty(), false)]
788 #[fuchsia::test]
789 fn test_wpa2_enables_pmf_if_supported(
790 security_support: fidl_common::SecuritySupport,
791 expect_mfp: bool,
792 ) {
793 let a_rsne =
794 Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
795 assert!(a_rsne.is_wpa2_rsn_compatible(&security_support));
796
797 let s_rsne = a_rsne
798 .derive_wpa2_s_rsne(&security_support)
799 .expect("Should be able to derive s_rsne with PMF");
800 assert!(s_rsne.is_wpa2_rsn_compatible(&security_support));
801 assert_eq!(
802 expect_mfp,
803 s_rsne
804 .rsn_capabilities
805 .expect("PMF RSNE should have RSN capabilities")
806 .mgmt_frame_protection_req()
807 );
808 }
809
810 #[test]
811 fn test_invalid_wpa3_caps() {
812 assert!(!RsnCapabilities(0).is_wpa3_compatible(false));
813
814 let wpa3_caps = RsnCapabilities(0)
815 .with_mgmt_frame_protection_cap(true)
816 .with_mgmt_frame_protection_req(true);
817 assert!(wpa3_caps.is_wpa3_compatible(false));
818
819 let caps = wpa3_caps.clone().with_joint_multiband(true);
820 assert!(!caps.is_wpa3_compatible(false));
821
822 let caps = wpa3_caps.clone().with_peerkey_enabled(true);
823 assert!(!caps.is_wpa3_compatible(false));
824
825 let caps = wpa3_caps.clone().with_ssp_amsdu_req(true);
826 assert!(!caps.is_wpa3_compatible(false));
827
828 let caps = wpa3_caps.clone().with_pbac(true);
829 assert!(!caps.is_wpa3_compatible(false));
830
831 let caps = wpa3_caps.clone().with_extended_key_id(true);
832 assert!(!caps.is_wpa3_compatible(false));
833
834 let wpa2_wpa3_caps = RsnCapabilities(0).with_mgmt_frame_protection_cap(true);
835 assert!(wpa2_wpa3_caps.is_wpa3_compatible(true));
836
837 let caps = wpa2_wpa3_caps.clone().with_extended_key_id(true);
838 assert!(!caps.is_wpa3_compatible(true));
839 }
840
841 #[test]
842 fn test_with_caps() {
843 assert!(Rsne::wpa2_rsne().rsn_capabilities.is_none());
844 let rsne_with_caps =
845 Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_peerkey_enabled(true));
846 assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
847
848 assert!(!Rsne::wpa2_wpa3_rsne().rsn_capabilities.unwrap().peerkey_enabled());
849 let rsne_with_caps =
850 Rsne::wpa2_wpa3_rsne_with_extra_caps(RsnCapabilities(0).with_peerkey_enabled(true));
851 assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
852 assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_cap());
853
854 assert!(!Rsne::wpa3_rsne().rsn_capabilities.unwrap().peerkey_enabled());
855 let rsne_with_caps =
856 Rsne::wpa3_rsne_with_extra_caps(RsnCapabilities(0).with_peerkey_enabled(true));
857 assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
858 assert!(
859 rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_cap()
860 && rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_req()
861 );
862 }
863
864 #[test]
865 fn test_incompatible_group_data_cipher() {
866 let rsne = Rsne {
867 group_data_cipher_suite: Some(CIPHER_GCMP_256),
868 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
869 akm_suites: vec![AKM_PSK],
870 ..Default::default()
871 };
872 assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
873 }
874
875 #[test]
876 fn test_no_group_data_cipher() {
877 let rsne = Rsne {
878 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
879 akm_suites: vec![AKM_PSK],
880 ..Default::default()
881 };
882 assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
883
884 let rsne = Rsne {
885 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
886 akm_suites: vec![AKM_SAE],
887 ..Default::default()
888 };
889 let mut security_support = fake_security_support_empty();
890 security_support.mfp.as_mut().unwrap().supported = Some(true);
891 assert_eq!(rsne.is_wpa3_rsn_compatible(&security_support), false);
892 }
893
894 #[test]
895 fn test_rsne_unsupported_group_data_cipher() {
896 let s_rsne = Rsne::wpa2_rsne();
897 let mut a_rsne = Rsne::wpa2_rsne();
898 a_rsne.group_data_cipher_suite = Some(CIPHER_GCMP_256);
899 assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
900 }
901
902 #[test]
903 fn test_ccmp_128_group_data_cipher_ccmp_128_pairwise_cipher() {
904 let a_rsne = Rsne {
905 group_data_cipher_suite: Some(CIPHER_CCMP_128),
906 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
907 akm_suites: vec![AKM_PSK],
908 ..Default::default()
909 };
910 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
911
912 let s_rsne = a_rsne
913 .derive_wpa2_s_rsne(&fake_security_support_empty())
914 .expect("could not derive WPA2 Supplicant RSNE");
915 let expected_rsne_bytes = vec![
916 0x30, 0x12, 0x01, 0x00, 0x00, 0x0F, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x04, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x02, ];
925 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
926 }
927
928 #[test]
929 fn test_tkip_group_data_cipher_ccmp_128_pairwise_cipher() {
930 let a_rsne = Rsne {
931 group_data_cipher_suite: Some(CIPHER_TKIP),
932 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
933 akm_suites: vec![AKM_PSK],
934 ..Default::default()
935 };
936 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
937
938 let s_rsne = a_rsne
939 .derive_wpa2_s_rsne(&fake_security_support_empty())
940 .expect("could not derive WPA2 Supplicant RSNE");
941 let expected_rsne_bytes = vec![
942 0x30, 0x12, 0x01, 0x00, 0x00, 0x0F, 0xac, 0x02, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x04, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x02, ];
951 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
952 }
953
954 #[test]
955 fn test_tkip_group_data_cipher_tkip_pairwise_cipher() {
956 let a_rsne = Rsne {
957 group_data_cipher_suite: Some(CIPHER_TKIP),
958 pairwise_cipher_suites: vec![CIPHER_TKIP],
959 akm_suites: vec![AKM_PSK],
960 ..Default::default()
961 };
962 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
963
964 let s_rsne = a_rsne
965 .derive_wpa2_s_rsne(&fake_security_support_empty())
966 .expect("could not derive WPA2 Supplicant RSNE");
967 let expected_rsne_bytes = vec![
968 0x30, 0x12, 0x01, 0x00, 0x00, 0x0F, 0xac, 0x02, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x02, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x02, ];
977 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
978 }
979
980 #[test]
981 fn test_tkip_group_data_cipher_prefer_ccmp_128_pairwise_cipher() {
982 let a_rsne = Rsne {
983 group_data_cipher_suite: Some(CIPHER_TKIP),
984 pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
985 akm_suites: vec![AKM_PSK],
986 ..Default::default()
987 };
988 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
989
990 let s_rsne = a_rsne
991 .derive_wpa2_s_rsne(&fake_security_support_empty())
992 .expect("could not derive WPA2 Supplicant RSNE");
993 let expected_rsne_bytes = vec![
994 0x30, 0x12, 0x01, 0x00, 0x00, 0x0F, 0xac, 0x02, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x04, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x02, ];
1003 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1004 }
1005
1006 #[test]
1007 fn test_ccmp_128_group_data_cipher_prefer_ccmp_128_pairwise_cipher() {
1008 let a_rsne = Rsne {
1009 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1010 pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
1011 akm_suites: vec![AKM_PSK],
1012 ..Default::default()
1013 };
1014 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1015
1016 let s_rsne = a_rsne
1017 .derive_wpa2_s_rsne(&fake_security_support_empty())
1018 .expect("could not derive WPA2 Supplicant RSNE");
1019 let expected_rsne_bytes = vec![
1020 0x30, 0x12, 0x01, 0x00, 0x00, 0x0F, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x04, 0x01, 0x00, 0x00, 0x0F, 0xAC, 0x02, ];
1029 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1030 }
1031
1032 #[test]
1033 fn test_compatible_pairwise_cipher() {
1034 let rsne = Rsne {
1035 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1036 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1037 akm_suites: vec![AKM_PSK],
1038 ..Default::default()
1039 };
1040 assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1041
1042 let rsne = Rsne {
1043 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1044 pairwise_cipher_suites: vec![CIPHER_TKIP],
1045 akm_suites: vec![AKM_PSK],
1046 ..Default::default()
1047 };
1048 assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1049 }
1050
1051 #[test]
1052 fn test_incompatible_pairwise_cipher() {
1053 let rsne = Rsne {
1054 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1055 pairwise_cipher_suites: vec![CIPHER_BIP_CMAC_256],
1056 akm_suites: vec![AKM_PSK],
1057 ..Default::default()
1058 };
1059 assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1060 }
1061
1062 #[test]
1063 fn test_no_pairwise_cipher() {
1064 let rsne = Rsne {
1065 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1066 akm_suites: vec![AKM_PSK],
1067 ..Default::default()
1068 };
1069 assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1070
1071 let rsne = Rsne {
1072 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1073 akm_suites: vec![AKM_SAE],
1074 ..Default::default()
1075 };
1076 assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1077 }
1078
1079 #[test]
1080 fn test_rsne_unsupported_pairwise_cipher() {
1081 let s_rsne = Rsne::wpa2_rsne();
1082 let mut a_rsne = Rsne::wpa2_rsne();
1083 a_rsne.pairwise_cipher_suites = vec![CIPHER_BIP_CMAC_256];
1084 assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1085 }
1086
1087 #[test]
1088 fn test_incompatible_akm() {
1089 let rsne = Rsne {
1090 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1091 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1092 akm_suites: vec![AKM_EAP],
1093 ..Default::default()
1094 };
1095 assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1096 assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1097
1098 let rsne = Rsne {
1099 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1100 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1101 akm_suites: vec![AKM_PSK],
1102 ..Default::default()
1103 };
1104 assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1105
1106 let rsne = Rsne {
1107 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1108 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1109 akm_suites: vec![AKM_SAE],
1110 ..Default::default()
1111 };
1112 assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1113 }
1114
1115 #[test]
1116 fn test_no_akm() {
1117 let rsne = Rsne {
1118 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1119 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1120 ..Default::default()
1121 };
1122 assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1123 assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1124 }
1125
1126 #[test]
1127 fn test_rsne_unsupported_akm() {
1128 let s_rsne = Rsne::wpa2_rsne();
1129 let mut a_rsne = Rsne::wpa2_rsne();
1130 a_rsne.akm_suites = vec![AKM_EAP];
1131 assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1132 }
1133
1134 #[test]
1135 fn test_ensure_valid_s_rsne() {
1136 let s_rsne = Rsne::wpa2_rsne();
1137 let result = s_rsne.ensure_valid_s_rsne();
1138 assert!(result.is_ok());
1139
1140 let mut s_rsne = Rsne::wpa2_rsne();
1141 s_rsne.group_data_cipher_suite = None;
1142 let result = s_rsne.ensure_valid_s_rsne();
1143 assert!(result.is_err());
1144 assert_eq!(result.unwrap_err(), Error::NoGroupDataCipherSuite);
1145
1146 let mut s_rsne = Rsne::wpa2_rsne();
1147 s_rsne.pairwise_cipher_suites = vec![];
1148 let result = s_rsne.ensure_valid_s_rsne();
1149 assert!(result.is_err());
1150 assert_eq!(result.unwrap_err(), Error::NoPairwiseCipherSuite);
1151
1152 let mut s_rsne = Rsne::wpa2_rsne();
1153 s_rsne.pairwise_cipher_suites.push(CIPHER_GCMP_256);
1154 let result = s_rsne.ensure_valid_s_rsne();
1155 assert!(result.is_err());
1156 assert_eq!(result.unwrap_err(), Error::TooManyPairwiseCipherSuites);
1157
1158 let mut s_rsne = Rsne::wpa2_rsne();
1159 s_rsne.akm_suites = vec![];
1160 let result = s_rsne.ensure_valid_s_rsne();
1161 assert!(result.is_err());
1162 assert_eq!(result.unwrap_err(), Error::NoAkmSuite);
1163
1164 let mut s_rsne = Rsne::wpa2_rsne();
1165 s_rsne.akm_suites.push(AKM_EAP);
1166 let result = s_rsne.ensure_valid_s_rsne();
1167 assert!(result.is_err());
1168 assert_eq!(result.unwrap_err(), Error::TooManyAkmSuites);
1169
1170 let mut s_rsne = Rsne::wpa2_rsne();
1171 s_rsne.akm_suites = vec![akm::Akm::new_dot11(200)];
1172 let result = s_rsne.ensure_valid_s_rsne();
1173 assert!(result.is_err());
1174 assert_eq!(result.unwrap_err(), Error::NoAkmMicBytes);
1175 }
1176
1177 #[test]
1178 fn test_compatible_wpa2_rsne() {
1179 let rsne = Rsne::wpa2_rsne();
1180 assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1181 }
1182
1183 #[test]
1184 fn test_compatible_wpa2_wpa3_rsne() {
1185 let rsne = Rsne::wpa2_wpa3_rsne();
1186 assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1187 assert!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY));
1188 }
1189
1190 #[test]
1191 fn test_compatible_wpa3_rsne() {
1192 let rsne = Rsne::wpa3_rsne();
1193 assert!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY));
1194 }
1195
1196 #[test]
1197 fn test_incompatible_wpa3_rsne_no_mfp() {
1198 let rsne = Rsne::wpa3_rsne();
1199 assert!(!rsne.is_wpa3_rsn_compatible(&fake_security_support_empty()));
1200 }
1201
1202 #[test]
1203 fn test_ccmp128_group_data_pairwise_cipher_psk() {
1204 let a_rsne = Rsne {
1205 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1206 pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1207 akm_suites: vec![AKM_PSK],
1208 ..Default::default()
1209 };
1210 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1211
1212 let s_rsne = a_rsne
1213 .derive_wpa2_s_rsne(&fake_security_support_empty())
1214 .expect("could not derive WPA2 Supplicant RSNE");
1215 let expected_rsne_bytes =
1216 vec![48, 18, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2];
1217 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1218 }
1219
1220 #[test]
1221 fn test_valid_rsne() {
1222 let s_rsne = Rsne::wpa2_rsne();
1223 let a_rsne = Rsne::wpa2_rsne();
1224 assert!(s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1225 }
1226
1227 #[test]
1228 fn test_ccmp_tkip_mode() {
1229 let a_rsne = Rsne {
1230 group_data_cipher_suite: Some(CIPHER_CCMP_128),
1231 pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
1232 akm_suites: vec![AKM_PSK, AKM_FT_PSK],
1233 ..Default::default()
1234 };
1235 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1236
1237 let s_rsne = a_rsne
1238 .derive_wpa2_s_rsne(&fake_security_support_empty())
1239 .expect("could not derive WPA2 Supplicant RSNE");
1240 let expected_rsne_bytes =
1241 vec![48, 18, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2];
1242 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1243 }
1244
1245 #[test]
1246 fn test_ccmp128_group_data_pairwise_cipher_sae() {
1247 let a_rsne = Rsne::wpa3_rsne();
1248 assert_eq!(a_rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), true);
1249
1250 let s_rsne = a_rsne
1251 .derive_wpa3_s_rsne(&MFP_SUPPORT_ONLY)
1252 .expect("could not derive WPA2 Supplicant RSNE");
1253 let expected_rsne_bytes =
1254 vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 8, 192, 0];
1255 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1256 }
1257
1258 #[test]
1259 fn test_wpa3_transition_mode() {
1260 let a_rsne = Rsne::wpa2_wpa3_rsne();
1261 assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1262 assert_eq!(a_rsne.is_wpa3_rsn_compatible(&fake_security_support_empty()), false);
1263 assert_eq!(a_rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), true);
1264
1265 let s_rsne = a_rsne
1266 .derive_wpa2_s_rsne(&MFP_SUPPORT_ONLY)
1267 .expect("could not derive WPA2 Supplicant RSNE");
1268 let expected_rsne_bytes =
1269 vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2, 192, 0];
1270 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1271
1272 let s_rsne = a_rsne
1273 .derive_wpa3_s_rsne(&MFP_SUPPORT_ONLY)
1274 .expect("could not derive WPA3 Supplicant RSNE");
1275 let expected_rsne_bytes =
1276 vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 8, 192, 0];
1277 assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1278 }
1279
1280 #[test]
1281 fn test_wpa2_psk_rsne_bytes() {
1282 let expected: Vec<u8> = vec![
1284 0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
1285 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00,
1286 ];
1287 let rsne = Rsne::wpa2_rsne_with_caps(RsnCapabilities(0));
1288 let mut actual = Vec::with_capacity(rsne.len());
1289 rsne.write_into(&mut actual).expect("error writing RSNE");
1290
1291 assert_eq!(&expected[..], &actual[..]);
1292 }
1293
1294 #[test]
1295 fn test_supplicant_missing_required_mpfc() {
1296 let s_rsne = Rsne::wpa2_rsne();
1297 let a_rsne = Rsne::wpa2_rsne_with_caps(
1298 RsnCapabilities(0)
1299 .with_mgmt_frame_protection_req(true)
1300 .with_mgmt_frame_protection_cap(true),
1301 );
1302 assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1303 }
1304
1305 #[test]
1306 fn test_authenticator_missing_required_mpfc() {
1307 let s_rsne = Rsne::wpa2_rsne_with_caps(
1308 RsnCapabilities(0)
1309 .with_mgmt_frame_protection_req(true)
1310 .with_mgmt_frame_protection_cap(true),
1311 );
1312 let a_rsne = Rsne::wpa2_rsne();
1313 assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1314 }
1315
1316 #[test]
1317 fn test_supplicant_has_invalid_mgmt_frame_protection_fields() {
1318 let s_rsne = Rsne::wpa2_rsne_with_caps(
1319 RsnCapabilities(0)
1320 .with_mgmt_frame_protection_req(true)
1321 .with_mgmt_frame_protection_cap(false),
1322 );
1323 let a_rsne =
1325 Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
1326
1327 let result = s_rsne.is_valid_subset_of(&a_rsne);
1328 assert!(result.is_err());
1329 assert_eq!(result.unwrap_err(), Error::InvalidSupplicantMgmtFrameProtection);
1330 }
1331
1332 #[test]
1333 fn test_authenticator_has_invalid_mgmt_frame_protection_fields() {
1334 let s_rsne =
1336 Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
1337 let a_rsne = Rsne::wpa2_rsne_with_caps(
1338 RsnCapabilities(0)
1339 .with_mgmt_frame_protection_req(true)
1340 .with_mgmt_frame_protection_cap(false),
1341 );
1342
1343 let result = s_rsne.is_valid_subset_of(&a_rsne);
1344 assert!(result.is_err());
1345 assert_eq!(result.unwrap_err(), Error::InvalidAuthenticatorMgmtFrameProtection);
1346 }
1347
1348 #[test]
1349 fn test_write_until_version() {
1350 let expected_frame: Vec<u8> = vec![
1351 0x30, 0x02, 0x01, 0x00, ];
1355 let buf = Rsne { version: VERSION, ..Default::default() }.into_bytes();
1356 assert_eq!(&buf[..], &expected_frame[..]);
1357 }
1358
1359 #[test]
1360 fn test_write_until_group_data() {
1361 let expected_frame: Vec<u8> = vec![
1362 0x30, 0x06, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, ];
1367 let buf = Rsne {
1368 version: VERSION,
1369 group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1370 ..Default::default()
1371 }
1372 .into_bytes();
1373 assert_eq!(&buf[..], &expected_frame[..]);
1374 }
1375
1376 #[test]
1377 fn test_write_until_pairwise() {
1378 let expected_frame: Vec<u8> = vec![
1379 0x30, 12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, ];
1386 let buf = Rsne {
1387 version: VERSION,
1388 group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1389 pairwise_cipher_suites: vec![cipher::Cipher::new_dot11(cipher::CCMP_128)],
1390 ..Default::default()
1391 }
1392 .into_bytes();
1393 assert_eq!(&buf[..], &expected_frame[..]);
1394 }
1395
1396 #[test]
1397 fn test_write_until_akm() {
1398 let expected_frame: Vec<u8> = vec![
1399 0x30, 14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, ];
1407 let buf = Rsne {
1408 version: VERSION,
1409 group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1410 akm_suites: vec![akm::Akm::new_dot11(akm::PSK)],
1411 ..Default::default()
1412 }
1413 .into_bytes();
1414 assert_eq!(&buf[..], &expected_frame[..]);
1415 }
1416
1417 #[test]
1418 fn test_write_until_rsn_capabilities() {
1419 let expected_frame: Vec<u8> = vec![
1420 0x30, 12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xab, ];
1428 let buf = Rsne {
1429 version: VERSION,
1430 group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1431 rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1432 ..Default::default()
1433 }
1434 .into_bytes();
1435 assert_eq!(&buf[..], &expected_frame[..]);
1436 }
1437
1438 static PMKID_VAL: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
1439
1440 #[test]
1441 fn test_write_until_pmkids() {
1442 let expected_frame: Vec<u8> = vec![
1443 0x30, 30, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xab, 0x01, 0x00, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ];
1453 let buf = Rsne {
1454 version: VERSION,
1455 group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1456 rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1457 pmkids: vec![Bytes::from_static(&PMKID_VAL[..])],
1458 ..Default::default()
1459 }
1460 .into_bytes();
1461 assert_eq!(&buf[..], &expected_frame[..]);
1462 }
1463
1464 #[test]
1465 fn test_write_until_group_mgmt() {
1466 let expected_frame: Vec<u8> = vec![
1467 0x30, 18, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xab, 0x00, 0x00, 0x00, 0x0f, 0xac, 0x06, ];
1477 let buf = Rsne {
1478 version: VERSION,
1479 group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1480 rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1481 group_mgmt_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::BIP_CMAC_128)),
1482 ..Default::default()
1483 }
1484 .into_bytes();
1485 assert_eq!(&buf[..], &expected_frame[..]);
1486 }
1487
1488 #[test]
1489 fn test_end_write_on_missing_caps() {
1490 let expected_frame: Vec<u8> = vec![
1491 0x30, 0x06, 0x01, 0x00, 0x00, 0x0f, 0xac,
1495 0x04, ];
1498 let buf = Rsne {
1499 version: VERSION,
1500 group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1501 rsn_capabilities: None,
1502 group_mgmt_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::BIP_CMAC_128)),
1503 ..Default::default()
1504 }
1505 .into_bytes();
1506 assert_eq!(&buf[..], &expected_frame[..]);
1507 }
1508}