wlan_common/ie/rsn/
rsne.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
5use 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  // alt returns the first parser that succeeds
27  ($f:expr) => (alt((map(eof, |_| None), map($f, Some))));
28);
29
30// IEEE 802.11-2016, 9.4.2.25.1
31pub 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// IEEE 802.11-2016, 9.4.2.25.1
68#[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   _, // reserved
107)]
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    /// Returns true if RsnCapabilities contains a capability
131    /// which wlanstack cannot currently agree to handle.
132    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/// Used to identify the last field we will write into our RSNE buffer.
142#[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            // Always explicitly include a group management cipher suite. There
174            // is no reason to rely on the default group management cipher
175            // suite selection defined in IEEE 802.11-2016 9.4.2.25.2 if we are making
176            // the Rsne ourselves.
177            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            // Always explicitly include a group management cipher suite. There
201            // is no reason to rely on the default group management cipher
202            // suite selection defined in IEEE 802.11-2016 9.4.2.25.2 if we are making
203            // the Rsne ourselves.
204            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    /// Constructs Supplicant's RSNE with:
218    /// Group Data Cipher: same as A-RSNE (CCMP-128 or TKIP)
219    /// Pairwise Cipher: best from A-RSNE (prefer CCMP-128 over TKIP)
220    /// AKM: PSK
221    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        // Enable management frame protection if supported.
230        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        // CCMP-128 is better than TKIP
247        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    /// Constructs Supplicant's RSNE with:
268    /// Group Data Cipher: CCMP-128
269    /// Pairwise Cipher: CCMP-128
270    /// AKM: SAE
271    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    /// Validates this RSNE contains only one of each cipher type and only one AKM with
297    /// a defined number of MIC bytes.
298    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    /// Verify that Supplicant RSNE is a subset of Authenticator RSNE
315    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        // IEEE Std 802.11-2016, 12.6.3, Table 12-2
327        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            // the remaining cases fall into either of these buckets:
333            // 1 - spec mentions that "The AP may associate with the STA"
334            // 2 - it's not covered in the spec, which means presumably we can ignore it. For example,
335            //     if AP/client is not management frame protection capable, then it probably doesn't
336            //     matter whether the opposite party advertises an invalid setting
337            _ => (),
338        }
339
340        Ok(a_rsne
341            .group_data_cipher_suite
342            .iter()
343            // .unwrap() will succeed because .ensure_valid_s_rsne() was run at the beginning of this function.
344            .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    /// IEEE Std. 802.11-2016 9.4.2.25.1
350    ///    "All fields after the Version field are optional. If any
351    ///     nonzero-length field is absent, then none of the subsequent
352    ///     fields is included."
353    /// Determine the last field we will write to produce the smallest RSNE
354    /// that matches this specification.
355    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    /// IEEE Std. 802.11-2016 9.4.2.25.1 specifies lengths for all fields.
378    pub fn len(&self) -> usize {
379        let final_field = self.final_field();
380        let mut length: usize = 4; // Element Id (1) + Length (1) + Version (2)
381        if final_field == FinalField::Version {
382            return length;
383        }
384        length += 4; // Group data cipher (4)
385        if final_field == FinalField::GroupData {
386            return length;
387        }
388        // Pairwise cipher count (2) + pairwise ciphers (4 * count)
389        length += 2 + 4 * self.pairwise_cipher_suites.len();
390        if final_field == FinalField::Pairwise {
391            return length;
392        }
393        // AKM count (2) + AKMs (4 * count)
394        length += 2 + 4 * self.akm_suites.len();
395        if final_field == FinalField::Akm {
396            return length;
397        }
398        length += 2; // RSN capabilities (2)
399        if final_field == FinalField::Caps {
400            return length;
401        }
402        // PMKID count (2) + PMKIDs (16 * count)
403        length += 2 + 16 * self.pmkids.len();
404        if final_field == FinalField::Pmkid {
405            return length;
406        }
407        length + 4 // Group management cipher (4)
408    }
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    /// Supported Ciphers and AKMs:
482    /// Group Data Ciphers: CCMP-128, TKIP
483    /// Pairwise Cipher: CCMP-128, TKIP
484    /// AKM: PSK, SAE
485    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            // IEEE allows TKIP usage only for compatibility reasons.
488            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    /// Check if this is a supported WPA3-Personal or WPA3-Personal transition AP per the WFA WPA3 specification.
512    /// Supported Ciphers and AKMs:
513    /// Group Data Ciphers: CCMP-128, TKIP
514    /// Pairwise Cipher: CCMP-128
515    /// AKM: SAE (also PSK in transition mode)
516    /// The MFPR bit is required, except for transition mode.
517    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        // WFA WPA3 specification v3.0: 2.3 rule 7: Verify that we actually support MFP, regardless of whether
539        // the features bits indicate we need that support. SAE without MFP is not a valid configuration.
540        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
581/// convert bytes of an RSNE information element into an RSNE representation. This method
582/// does not depend on the information element length field (second byte) and thus does not
583/// validate that it's correct
584pub 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, // element id
689            0x2A, // length
690            0x01, 0x00, // version
691            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
692            0x01, 0x00, // pairwise cipher suite count
693            0x00, 0x0f, 0xac, 0x04, // pairwise cipher suite list
694            0x01, 0x00, // akm suite count
695            0x00, 0x0f, 0xac, 0x02, // akm suite list
696            0xa8, 0x04, // rsn capabilities
697            0x01, 0x00, // pmk id count
698            // pmk id list
699            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
700            0x10, 0x11, 0x00, 0x0f, 0xac, 0x04, // group management cipher suite
701        ];
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, // element id, 48 expressed as hexadecimal value
917            0x12, // length in octets, 18 expressed as hexadecimal value
918            0x01, 0x00, // Version 1
919            0x00, 0x0F, 0xac, 0x04, // CCMP-128 as group data cipher suite
920            0x01, 0x00, // pairwise cipher suite count
921            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
922            0x01, 0x00, // authentication count
923            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
924        ];
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, // element id, 48 expressed as hexadecimal value
943            0x12, // length in octets, 18 expressed as hexadecimal value
944            0x01, 0x00, // Version 1
945            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
946            0x01, 0x00, // pairwise cipher suite count
947            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
948            0x01, 0x00, // authentication count
949            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
950        ];
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, // element id, 48 expressed as hexadecimal value
969            0x12, // length in octets, 18 expressed as hexadecimal value
970            0x01, 0x00, // Version 1
971            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
972            0x01, 0x00, // pairwise cipher suite count
973            0x00, 0x0F, 0xAC, 0x02, // TKIP as pairwise cipher suite
974            0x01, 0x00, // authentication count
975            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
976        ];
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, // element id, 48 expressed as hexadecimal value
995            0x12, // length in octets, 18 expressed as hexadecimal value
996            0x01, 0x00, // Version 1
997            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
998            0x01, 0x00, // pairwise cipher suite count
999            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
1000            0x01, 0x00, // authentication count
1001            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
1002        ];
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, // element id, 48 expressed as hexadecimal value
1021            0x12, // length in octets, 18 expressed as hexadecimal value
1022            0x01, 0x00, // Version 1
1023            0x00, 0x0F, 0xac, 0x04, // CCMP-128 as group data cipher suite
1024            0x01, 0x00, // pairwise cipher suite count
1025            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
1026            0x01, 0x00, // authentication count
1027            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
1028        ];
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        // Compliant with IEEE Std 802.11-2016, 9.4.2.25.
1283        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        // AP only cares about client's invalid setting if AP is mgmt frame protection capable
1324        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        // client only cares about AP's invalid setting if client is mgmt frame protection capable
1335        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, // element id
1352            0x02, // length
1353            0x01, 0x00, // version
1354        ];
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, // element id
1363            0x06, // length
1364            0x01, 0x00, // version
1365            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1366        ];
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, // element id
1380            12,   // length
1381            0x01, 0x00, // version
1382            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1383            0x01, 0x00, // pairwise suite count
1384            0x00, 0x0f, 0xac, 0x04, // pairwise cipher suite
1385        ];
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, // element id
1400            14,   // length
1401            0x01, 0x00, // version
1402            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1403            0x00, 0x00, // pairwise suite count
1404            0x01, 0x00, // pairwise suite count
1405            0x00, 0x0f, 0xac, 0x02, // pairwise cipher suite
1406        ];
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, // element id
1421            12,   // length
1422            0x01, 0x00, // version
1423            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1424            0x00, 0x00, // pairwise suite count
1425            0x00, 0x00, // akm suite count
1426            0xcd, 0xab, // rsn capabilities
1427        ];
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, // element id
1444            30,   // length
1445            0x01, 0x00, // version
1446            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1447            0x00, 0x00, // pairwise suite count
1448            0x00, 0x00, // akm suite count
1449            0xcd, 0xab, // rsn capabilities
1450            0x01, 0x00, // pmkid count
1451            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, // pmkid
1452        ];
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, // element id
1468            18,   // length
1469            0x01, 0x00, // version
1470            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1471            0x00, 0x00, // pairwise suite count
1472            0x00, 0x00, // akm suite count
1473            0xcd, 0xab, // rsn capabilities
1474            0x00, 0x00, // pmkids count
1475            0x00, 0x0f, 0xac, 0x06, // group management cipher suite
1476        ];
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, // element id
1492            0x06, // length
1493            0x01, 0x00, // version
1494            0x00, 0x0f, 0xac,
1495            0x04, // group data cipher suite
1496                  // We don't write group management suite because caps are missing.
1497        ];
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}