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_u16, le_u8};
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() || security_support.mfp.supported
127    }
128
129    /// Returns true if RsnCapabilities contains a capability
130    /// which wlanstack cannot currently agree to handle.
131    fn contains_unsupported_capability(&self) -> bool {
132        self.joint_multiband()
133            || self.peerkey_enabled()
134            || self.ssp_amsdu_req()
135            || self.pbac()
136            || self.extended_key_id()
137    }
138}
139
140/// Used to identify the last field we will write into our RSNE buffer.
141#[derive(PartialEq)]
142enum FinalField {
143    Version,
144    GroupData,
145    Pairwise,
146    Akm,
147    Caps,
148    Pmkid,
149    GroupMgmt,
150}
151
152impl Rsne {
153    pub fn wpa2_rsne() -> Self {
154        Rsne {
155            group_data_cipher_suite: Some(CIPHER_CCMP_128),
156            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
157            akm_suites: vec![AKM_PSK],
158            ..Default::default()
159        }
160    }
161
162    pub fn wpa2_rsne_with_caps(rsn_capabilities: RsnCapabilities) -> Self {
163        Self::wpa2_rsne().with_caps(rsn_capabilities)
164    }
165
166    pub fn wpa2_wpa3_rsne() -> Self {
167        Rsne {
168            group_data_cipher_suite: Some(CIPHER_CCMP_128),
169            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
170            akm_suites: vec![AKM_SAE, AKM_PSK],
171            rsn_capabilities: Some(RsnCapabilities(0).with_mgmt_frame_protection_cap(true)),
172            // Always explicitly include a group management cipher suite. There
173            // is no reason to rely on the default group management cipher
174            // suite selection defined in IEEE 802.11-2016 9.4.2.25.2 if we are making
175            // the Rsne ourselves.
176            group_mgmt_cipher_suite: Some(DEFAULT_GROUP_MGMT_CIPHER),
177            ..Default::default()
178        }
179    }
180
181    pub fn wpa2_wpa3_rsne_with_extra_caps(rsn_capabilities: RsnCapabilities) -> Self {
182        let rsne = Self::wpa2_wpa3_rsne();
183        let wpa2_wpa3_minimum_rsn_capabilities = rsne.rsn_capabilities.as_ref().unwrap().clone();
184        rsne.with_caps(RsnCapabilities(
185            wpa2_wpa3_minimum_rsn_capabilities.raw() | rsn_capabilities.raw(),
186        ))
187    }
188
189    pub fn wpa3_rsne() -> Self {
190        Rsne {
191            group_data_cipher_suite: Some(CIPHER_CCMP_128),
192            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
193            akm_suites: vec![AKM_SAE],
194            rsn_capabilities: Some(
195                RsnCapabilities(0)
196                    .with_mgmt_frame_protection_cap(true)
197                    .with_mgmt_frame_protection_req(true),
198            ),
199            // Always explicitly include a group management cipher suite. There
200            // is no reason to rely on the default group management cipher
201            // suite selection defined in IEEE 802.11-2016 9.4.2.25.2 if we are making
202            // the Rsne ourselves.
203            group_mgmt_cipher_suite: Some(DEFAULT_GROUP_MGMT_CIPHER),
204            ..Default::default()
205        }
206    }
207
208    pub fn wpa3_rsne_with_extra_caps(rsn_capabilities: RsnCapabilities) -> Self {
209        let rsne = Self::wpa3_rsne();
210        let wpa3_minimum_rsn_capabilities = rsne.rsn_capabilities.as_ref().unwrap().clone();
211        rsne.with_caps(RsnCapabilities(
212            wpa3_minimum_rsn_capabilities.raw() | rsn_capabilities.raw(),
213        ))
214    }
215
216    /// Constructs Supplicant's RSNE with:
217    /// Group Data Cipher: same as A-RSNE (CCMP-128 or TKIP)
218    /// Pairwise Cipher: best from A-RSNE (prefer CCMP-128 over TKIP)
219    /// AKM: PSK
220    pub fn derive_wpa2_s_rsne(
221        &self,
222        security_support: &fidl_common::SecuritySupport,
223    ) -> Result<Self, Error> {
224        if !self.is_wpa2_rsn_compatible(&security_support) {
225            return Err(Error::CannotDeriveWpa2Rsne);
226        }
227
228        // Enable management frame protection if supported.
229        let rsn_capabilities = match self.rsn_capabilities.clone() {
230            Some(cap) => {
231                if cap.mgmt_frame_protection_cap() && security_support.mfp.supported {
232                    Some(cap.with_mgmt_frame_protection_req(true))
233                } else {
234                    Some(cap)
235                }
236            }
237            None => None,
238        };
239
240        // CCMP-128 is better than TKIP
241        let pairwise_cipher_suites =
242            vec![match self.pairwise_cipher_suites.iter().max_by_key(|cipher_suite| {
243                match **cipher_suite {
244                    CIPHER_CCMP_128 => 1,
245                    _ => 0,
246                }
247            }) {
248                Some(cipher_suite) => cipher_suite.clone(),
249                None => return Err(Error::NoPairwiseCipherSuite),
250            }];
251
252        Ok(Rsne {
253            group_data_cipher_suite: self.group_data_cipher_suite.clone(),
254            pairwise_cipher_suites,
255            akm_suites: vec![AKM_PSK],
256            rsn_capabilities,
257            ..Default::default()
258        })
259    }
260
261    /// Constructs Supplicant's RSNE with:
262    /// Group Data Cipher: CCMP-128
263    /// Pairwise Cipher: CCMP-128
264    /// AKM: SAE
265    pub fn derive_wpa3_s_rsne(
266        &self,
267        security_support: &fidl_common::SecuritySupport,
268    ) -> Result<Rsne, Error> {
269        if !self.is_wpa3_rsn_compatible(&security_support) {
270            return Err(Error::CannotDeriveWpa3Rsne);
271        }
272
273        let rsn_capabilities = match self.rsn_capabilities.clone() {
274            Some(cap) => Some(cap.with_mgmt_frame_protection_req(true)),
275            None => None,
276        };
277
278        Ok(Rsne {
279            group_data_cipher_suite: self.group_data_cipher_suite.clone(),
280            pairwise_cipher_suites: vec![cipher::Cipher {
281                oui: suite_selector::OUI,
282                suite_type: cipher::CCMP_128,
283            }],
284            akm_suites: vec![akm::Akm { oui: suite_selector::OUI, suite_type: akm::SAE }],
285            rsn_capabilities,
286            ..Default::default()
287        })
288    }
289
290    /// Validates this RSNE contains only one of each cipher type and only one AKM with
291    /// a defined number of MIC bytes.
292    pub fn ensure_valid_s_rsne(&self) -> Result<(), Error> {
293        let s_rsne = self;
294        s_rsne.group_data_cipher_suite.as_ref().ok_or(Error::NoGroupDataCipherSuite)?;
295
296        rsne_ensure!(s_rsne.pairwise_cipher_suites.len() >= 1, Error::NoPairwiseCipherSuite);
297        rsne_ensure!(s_rsne.pairwise_cipher_suites.len() <= 1, Error::TooManyPairwiseCipherSuites);
298
299        rsne_ensure!(s_rsne.akm_suites.len() >= 1, Error::NoAkmSuite);
300        rsne_ensure!(s_rsne.akm_suites.len() <= 1, Error::TooManyAkmSuites);
301
302        let akm = &s_rsne.akm_suites[0];
303        rsne_ensure!(akm.mic_bytes().is_some(), Error::NoAkmMicBytes);
304
305        Ok(())
306    }
307
308    /// Verify that Supplicant RSNE is a subset of Authenticator RSNE
309    pub fn is_valid_subset_of(&self, a_rsne: &Rsne) -> Result<bool, Error> {
310        let s_rsne = self;
311        s_rsne.ensure_valid_s_rsne()?;
312
313        let s_caps = s_rsne.rsn_capabilities.as_ref().unwrap_or(&RsnCapabilities(0));
314        let s_mgmt_req = s_caps.mgmt_frame_protection_req();
315        let s_mgmt_cap = s_caps.mgmt_frame_protection_cap();
316        let a_caps = a_rsne.rsn_capabilities.as_ref().unwrap_or(&RsnCapabilities(0));
317        let a_mgmt_req = a_caps.mgmt_frame_protection_req();
318        let a_mgmt_cap = a_caps.mgmt_frame_protection_cap();
319
320        // IEEE Std 802.11-2016, 12.6.3, Table 12-2
321        match (a_mgmt_cap, a_mgmt_req, s_mgmt_cap, s_mgmt_req) {
322            (true, _, false, true) => return Err(Error::InvalidSupplicantMgmtFrameProtection),
323            (false, true, true, _) => return Err(Error::InvalidAuthenticatorMgmtFrameProtection),
324            (true, true, false, false) => return Ok(false),
325            (false, false, true, true) => return Ok(false),
326            // the remaining cases fall into either of these buckets:
327            // 1 - spec mentions that "The AP may associate with the STA"
328            // 2 - it's not covered in the spec, which means presumably we can ignore it. For example,
329            //     if AP/client is not management frame protection capable, then it probably doesn't
330            //     matter whether the opposite party advertises an invalid setting
331            _ => (),
332        }
333
334        Ok(a_rsne
335            .group_data_cipher_suite
336            .iter()
337            // .unwrap() will succeed because .ensure_valid_s_rsne() was run at the beginning of this function.
338            .any(|c| c == s_rsne.group_data_cipher_suite.as_ref().unwrap())
339            && a_rsne.pairwise_cipher_suites.iter().any(|c| *c == s_rsne.pairwise_cipher_suites[0])
340            && a_rsne.akm_suites.iter().any(|c| *c == s_rsne.akm_suites[0]))
341    }
342
343    /// IEEE Std. 802.11-2016 9.4.2.25.1
344    ///    "All fields after the Version field are optional. If any
345    ///     nonzero-length field is absent, then none of the subsequent
346    ///     fields is included."
347    /// Determine the last field we will write to produce the smallest RSNE
348    /// that matches this specification.
349    fn final_field(&self) -> FinalField {
350        if self.group_data_cipher_suite.is_none() {
351            FinalField::Version
352        } else if self.rsn_capabilities.is_none() {
353            if self.akm_suites.is_empty() {
354                if self.pairwise_cipher_suites.is_empty() {
355                    FinalField::GroupData
356                } else {
357                    FinalField::Pairwise
358                }
359            } else {
360                FinalField::Akm
361            }
362        } else {
363            if self.group_mgmt_cipher_suite.is_none() {
364                if self.pmkids.is_empty() {
365                    FinalField::Caps
366                } else {
367                    FinalField::Pmkid
368                }
369            } else {
370                FinalField::GroupMgmt
371            }
372        }
373    }
374
375    /// IEEE Std. 802.11-2016 9.4.2.25.1 specifies lengths for all fields.
376    pub fn len(&self) -> usize {
377        let final_field = self.final_field();
378        let mut length: usize = 4; // Element Id (1) + Length (1) + Version (2)
379        if final_field == FinalField::Version {
380            return length;
381        }
382        length += 4; // Group data cipher (4)
383        if final_field == FinalField::GroupData {
384            return length;
385        }
386        // Pairwise cipher count (2) + pairwise ciphers (4 * count)
387        length += 2 + 4 * self.pairwise_cipher_suites.len();
388        if final_field == FinalField::Pairwise {
389            return length;
390        }
391        // AKM count (2) + AKMs (4 * count)
392        length += 2 + 4 * self.akm_suites.len();
393        if final_field == FinalField::Akm {
394            return length;
395        }
396        length += 2; // RSN capabilities (2)
397        if final_field == FinalField::Caps {
398            return length;
399        }
400        // PMKID count (2) + PMKIDs (16 * count)
401        length += 2 + 16 * self.pmkids.len();
402        if final_field == FinalField::Pmkid {
403            return length;
404        }
405        length + 4 // Group management cipher (4)
406    }
407
408    pub fn into_bytes(self) -> Vec<u8> {
409        let mut buf = Vec::with_capacity(self.len());
410        self.write_into(&mut buf).expect("error writing RSNE into buffer");
411        buf
412    }
413
414    pub fn write_into<A: Append>(&self, buf: &mut A) -> Result<(), BufferTooSmall> {
415        if !buf.can_append(self.len()) {
416            return Err(BufferTooSmall);
417        }
418        let final_field = self.final_field();
419
420        buf.append_byte(ID)?;
421        buf.append_byte((self.len() - 2) as u8)?;
422        buf.append_value(&self.version)?;
423        if final_field == FinalField::Version {
424            return Ok(());
425        }
426
427        match self.group_data_cipher_suite.as_ref() {
428            None => return Ok(()),
429            Some(cipher) => {
430                buf.append_bytes(&cipher.oui[..])?;
431                buf.append_byte(cipher.suite_type)?;
432            }
433        };
434        if final_field == FinalField::GroupData {
435            return Ok(());
436        }
437
438        buf.append_value(&(self.pairwise_cipher_suites.len() as u16))?;
439        for cipher in &self.pairwise_cipher_suites {
440            buf.append_bytes(&cipher.oui[..])?;
441            buf.append_byte(cipher.suite_type)?;
442        }
443        if final_field == FinalField::Pairwise {
444            return Ok(());
445        }
446
447        buf.append_value(&(self.akm_suites.len() as u16))?;
448        for akm in &self.akm_suites {
449            buf.append_bytes(&akm.oui[..])?;
450            buf.append_byte(akm.suite_type)?;
451        }
452        if final_field == FinalField::Akm {
453            return Ok(());
454        }
455
456        match self.rsn_capabilities.as_ref() {
457            None => return Ok(()),
458            Some(caps) => buf.append_value(&caps.0)?,
459        };
460        if final_field == FinalField::Caps {
461            return Ok(());
462        }
463
464        buf.append_value(&(self.pmkids.len() as u16))?;
465        for pmkid in &self.pmkids {
466            buf.append_bytes(&pmkid[..])?;
467        }
468        if final_field == FinalField::Pmkid {
469            return Ok(());
470        }
471
472        if let Some(cipher) = self.group_mgmt_cipher_suite.as_ref() {
473            buf.append_bytes(&cipher.oui[..])?;
474            buf.append_byte(cipher.suite_type)?;
475        }
476        Ok(())
477    }
478
479    /// Supported Ciphers and AKMs:
480    /// Group Data Ciphers: CCMP-128, TKIP
481    /// Pairwise Cipher: CCMP-128, TKIP
482    /// AKM: PSK, SAE
483    pub fn is_wpa2_rsn_compatible(&self, security_support: &fidl_common::SecuritySupport) -> bool {
484        let group_data_supported = self.group_data_cipher_suite.as_ref().is_some_and(|c| {
485            // IEEE allows TKIP usage only for compatibility reasons.
486            c.has_known_usage() && [cipher::CCMP_128, cipher::TKIP].contains(&c.suite_type)
487        });
488
489        let pairwise_supported = self.pairwise_cipher_suites.iter().any(|c| {
490            c.has_known_usage() && [cipher::CCMP_128, cipher::TKIP].contains(&c.suite_type)
491        });
492        let akm_supported =
493            self.akm_suites.iter().any(|a| a.has_known_algorithm() && a.suite_type == akm::PSK);
494        let caps_supported =
495            self.rsn_capabilities.as_ref().map_or(true, RsnCapabilities::is_wpa2_compatible);
496        let features_supported = self
497            .rsn_capabilities
498            .as_ref()
499            .unwrap_or(&RsnCapabilities(0))
500            .is_compatible_with_features(security_support);
501
502        group_data_supported
503            && pairwise_supported
504            && akm_supported
505            && caps_supported
506            && features_supported
507    }
508
509    /// Check if this is a supported WPA3-Personal or WPA3-Personal transition AP per the WFA WPA3 specification.
510    /// Supported Ciphers and AKMs:
511    /// Group Data Ciphers: CCMP-128, TKIP
512    /// Pairwise Cipher: CCMP-128
513    /// AKM: SAE (also PSK in transition mode)
514    /// The MFPR bit is required, except for transition mode.
515    pub fn is_wpa3_rsn_compatible(&self, security_support: &fidl_common::SecuritySupport) -> bool {
516        let group_data_supported = self.group_data_cipher_suite.as_ref().is_some_and(|c| {
517            c.has_known_usage() && [cipher::CCMP_128, cipher::TKIP].contains(&c.suite_type)
518        });
519        let pairwise_supported = self
520            .pairwise_cipher_suites
521            .iter()
522            .any(|c| c.has_known_usage() && c.suite_type == cipher::CCMP_128);
523        let sae_supported =
524            self.akm_suites.iter().any(|a| a.has_known_algorithm() && a.suite_type == akm::SAE);
525        let wpa2_compatibility_mode =
526            self.akm_suites.iter().any(|a| a.has_known_algorithm() && a.suite_type == akm::PSK);
527        let caps_supported = self
528            .rsn_capabilities
529            .as_ref()
530            .is_some_and(|caps| caps.is_wpa3_compatible(wpa2_compatibility_mode));
531        let mut features_supported = self
532            .rsn_capabilities
533            .as_ref()
534            .unwrap_or(&RsnCapabilities(0))
535            .is_compatible_with_features(security_support);
536        // WFA WPA3 specification v3.0: 2.3 rule 7: Verify that we actually support MFP, regardless of whether
537        // the features bits indicate we need that support. SAE without MFP is not a valid configuration.
538        features_supported &= security_support.mfp.supported;
539        group_data_supported
540            && pairwise_supported
541            && sae_supported
542            && caps_supported
543            && features_supported
544    }
545
546    fn with_caps(mut self, rsn_capabilities: RsnCapabilities) -> Self {
547        self.rsn_capabilities = Some(rsn_capabilities);
548        self
549    }
550}
551
552fn read_suite_selector<T>(input: &[u8]) -> IResult<&[u8], T>
553where
554    T: suite_selector::Factory<Suite = T>,
555{
556    let (i1, bytes) = take(4usize).parse(input)?;
557    let oui = Oui::new([bytes[0], bytes[1], bytes[2]]);
558    return Ok((i1, T::new(oui, bytes[3])));
559}
560
561fn read_pmkid(input: &[u8]) -> IResult<&[u8], pmkid::Pmkid> {
562    let f = |bytes| {
563        let pmkid_data = Bytes::copy_from_slice(bytes);
564        return pmkid::new(pmkid_data);
565    };
566
567    map_res(nom::bytes::streaming::take(16usize), f).parse(input)
568}
569
570fn akm(input: &[u8]) -> IResult<&[u8], akm::Akm> {
571    read_suite_selector::<akm::Akm>(input)
572}
573
574fn cipher(input: &[u8]) -> IResult<&[u8], cipher::Cipher> {
575    read_suite_selector::<cipher::Cipher>(input)
576}
577
578/// convert bytes of an RSNE information element into an RSNE representation. This method
579/// does not depend on the information element length field (second byte) and thus does not
580/// validate that it's correct
581pub fn from_bytes(input: &[u8]) -> IResult<&[u8], Rsne> {
582    map(
583        terminated(
584            (
585                le_u8,
586                le_u8,
587                le_u16,
588                if_remaining!(cipher),
589                if_remaining!(length_count(le_u16, cipher)),
590                if_remaining!(length_count(le_u16, akm)),
591                if_remaining!(map(le_u16, RsnCapabilities)),
592                if_remaining!(length_count(le_u16, read_pmkid)),
593                if_remaining!(cipher),
594            ),
595            eof,
596        ),
597        |(
598            _element_id,
599            _length,
600            version,
601            group_cipher,
602            pairwise_list,
603            akm_list,
604            rsn_capabilities,
605            pmkid_list,
606            group_mgmt_cipher_suite,
607        )| Rsne {
608            version: version,
609            group_data_cipher_suite: group_cipher,
610            pairwise_cipher_suites: pairwise_list.unwrap_or_default(),
611            akm_suites: akm_list.unwrap_or_default(),
612            rsn_capabilities: rsn_capabilities,
613            pmkids: pmkid_list.unwrap_or_default(),
614            group_mgmt_cipher_suite: group_mgmt_cipher_suite,
615        },
616    )
617    .parse(input)
618}
619
620#[cfg(test)]
621mod tests {
622    use super::akm::{AKM_EAP, AKM_FT_PSK};
623    use super::cipher::{CIPHER_BIP_CMAC_256, CIPHER_GCMP_256, CIPHER_TKIP};
624    use super::*;
625    use crate::append::TrackedAppend;
626    use crate::test_utils::fake_features::fake_security_support_empty;
627    use crate::test_utils::FixedSizedTestBuffer;
628    use test_case::test_case;
629
630    #[cfg(feature = "benchmark")]
631    mod bench {
632        use self::test::Bencher;
633        use super::*;
634        #[cfg()]
635        #[bench]
636        fn bench_parse_with_nom(b: &mut Bencher) {
637            let frame: Vec<u8> = vec![
638                0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
639                0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
640                0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
641                0xac, 0x04,
642            ];
643            b.iter(|| from_bytes(&frame));
644        }
645    }
646
647    #[test]
648    fn test_write_into() {
649        let frame: Vec<u8> = vec![
650            0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
651            0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
652            0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
653            0xac, 0x04,
654        ];
655        let result = from_bytes(&frame);
656        assert!(result.is_ok());
657        let rsne = result.unwrap().1;
658        let mut buf = Vec::with_capacity(128);
659        rsne.write_into(&mut buf).expect("failed writing RSNE");
660        let rsne_len = buf.len();
661        let left_over = buf.split_off(rsne_len);
662        assert_eq!(&buf[..], &frame[..]);
663        assert!(left_over.iter().all(|b| *b == 0));
664    }
665
666    #[test]
667    fn test_short_buffer() {
668        let frame: Vec<u8> = vec![
669            0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
670            0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
671            0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
672            0xac, 0x04,
673        ];
674        let mut buf = FixedSizedTestBuffer::new(32);
675        let result = from_bytes(&frame);
676        assert!(result.is_ok());
677        let rsne = result.unwrap().1;
678        rsne.write_into(&mut buf).expect_err("expected writing RSNE to fail");
679        assert_eq!(buf.bytes_appended(), 0);
680    }
681
682    #[test]
683    fn test_rsn_fields_representation() {
684        let frame: Vec<u8> = vec![
685            0x30, // element id
686            0x2A, // length
687            0x01, 0x00, // version
688            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
689            0x01, 0x00, // pairwise cipher suite count
690            0x00, 0x0f, 0xac, 0x04, // pairwise cipher suite list
691            0x01, 0x00, // akm suite count
692            0x00, 0x0f, 0xac, 0x02, // akm suite list
693            0xa8, 0x04, // rsn capabilities
694            0x01, 0x00, // pmk id count
695            // pmk id list
696            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
697            0x10, 0x11, 0x00, 0x0f, 0xac, 0x04, // group management cipher suite
698        ];
699        let result = from_bytes(&frame);
700        assert!(result.is_ok());
701        let rsne = result.unwrap().1;
702
703        assert_eq!(rsne.version, VERSION);
704        assert_eq!(rsne.len(), 0x2a + 2);
705
706        assert!(rsne.group_data_cipher_suite.is_some());
707        assert_eq!(rsne.group_data_cipher_suite, Some(CIPHER_CCMP_128));
708        assert_eq!(rsne.pairwise_cipher_suites.len(), 1);
709        assert_eq!(rsne.pairwise_cipher_suites[0].oui, Oui::DOT11);
710        assert_eq!(rsne.pairwise_cipher_suites[0].suite_type, cipher::CCMP_128);
711        assert_eq!(rsne.akm_suites.len(), 1);
712        assert_eq!(rsne.akm_suites[0].suite_type, akm::PSK);
713
714        let rsn_capabilities = rsne.rsn_capabilities.expect("should have RSN capabilities");
715        assert_eq!(rsn_capabilities.preauth(), false);
716        assert_eq!(rsn_capabilities.no_pairwise(), false);
717        assert_eq!(rsn_capabilities.ptksa_replay_counter(), 2);
718        assert_eq!(rsn_capabilities.gtksa_replay_counter(), 2);
719        assert!(!rsn_capabilities.mgmt_frame_protection_req());
720        assert!(rsn_capabilities.mgmt_frame_protection_cap());
721        assert!(!rsn_capabilities.joint_multiband());
722        assert!(!rsn_capabilities.peerkey_enabled());
723        assert!(rsn_capabilities.ssp_amsdu_cap());
724        assert!(!rsn_capabilities.ssp_amsdu_req());
725        assert!(!rsn_capabilities.pbac());
726        assert!(!rsn_capabilities.extended_key_id());
727
728        assert_eq!(rsn_capabilities.0, 0xa8 + (0x04 << 8));
729
730        let pmkids: &[u8] = &[
731            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
732            0x10, 0x11,
733        ];
734        assert_eq!(rsne.pmkids.len(), 1);
735        assert_eq!(rsne.pmkids[0], Bytes::from(pmkids));
736
737        assert_eq!(rsne.group_mgmt_cipher_suite, Some(CIPHER_CCMP_128));
738    }
739
740    #[test]
741    fn test_rsn_capabilities_setters() {
742        let mut rsn_caps = RsnCapabilities(0u16);
743        rsn_caps.set_ptksa_replay_counter(2);
744        rsn_caps.set_gtksa_replay_counter(2);
745        rsn_caps.set_mgmt_frame_protection_cap(true);
746        rsn_caps.set_ssp_amsdu_cap(true);
747
748        assert_eq!(rsn_caps.0, 0xa8 + (0x04 << 8));
749    }
750
751    #[test]
752    fn test_invalid_wpa2_caps() {
753        assert!(RsnCapabilities(0).is_wpa2_compatible());
754
755        let caps = RsnCapabilities(0).with_joint_multiband(true);
756        assert!(!caps.is_wpa2_compatible());
757
758        let caps = RsnCapabilities(0).with_peerkey_enabled(true);
759        assert!(!caps.is_wpa2_compatible());
760
761        let caps = RsnCapabilities(0).with_ssp_amsdu_req(true);
762        assert!(!caps.is_wpa2_compatible());
763
764        let caps = RsnCapabilities(0).with_pbac(true);
765        assert!(!caps.is_wpa2_compatible());
766
767        let caps = RsnCapabilities(0).with_extended_key_id(true);
768        assert!(!caps.is_wpa2_compatible());
769    }
770
771    static MFP_SUPPORT_ONLY: fidl_common::SecuritySupport = fidl_common::SecuritySupport {
772        mfp: fidl_common::MfpFeature { supported: true },
773        sae: fidl_common::SaeFeature {
774            driver_handler_supported: false,
775            sme_handler_supported: false,
776        },
777    };
778
779    #[test_case(MFP_SUPPORT_ONLY, true)]
780    #[test_case(fake_security_support_empty(), false)]
781    #[fuchsia::test]
782    fn test_wpa2_enables_pmf_if_supported(
783        security_support: fidl_common::SecuritySupport,
784        expect_mfp: bool,
785    ) {
786        let a_rsne =
787            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
788        assert!(a_rsne.is_wpa2_rsn_compatible(&security_support));
789
790        let s_rsne = a_rsne
791            .derive_wpa2_s_rsne(&security_support)
792            .expect("Should be able to derive s_rsne with PMF");
793        assert!(s_rsne.is_wpa2_rsn_compatible(&security_support));
794        assert_eq!(
795            expect_mfp,
796            s_rsne
797                .rsn_capabilities
798                .expect("PMF RSNE should have RSN capabilities")
799                .mgmt_frame_protection_req()
800        );
801    }
802
803    #[test]
804    fn test_invalid_wpa3_caps() {
805        assert!(!RsnCapabilities(0).is_wpa3_compatible(false));
806
807        let wpa3_caps = RsnCapabilities(0)
808            .with_mgmt_frame_protection_cap(true)
809            .with_mgmt_frame_protection_req(true);
810        assert!(wpa3_caps.is_wpa3_compatible(false));
811
812        let caps = wpa3_caps.clone().with_joint_multiband(true);
813        assert!(!caps.is_wpa3_compatible(false));
814
815        let caps = wpa3_caps.clone().with_peerkey_enabled(true);
816        assert!(!caps.is_wpa3_compatible(false));
817
818        let caps = wpa3_caps.clone().with_ssp_amsdu_req(true);
819        assert!(!caps.is_wpa3_compatible(false));
820
821        let caps = wpa3_caps.clone().with_pbac(true);
822        assert!(!caps.is_wpa3_compatible(false));
823
824        let caps = wpa3_caps.clone().with_extended_key_id(true);
825        assert!(!caps.is_wpa3_compatible(false));
826
827        let wpa2_wpa3_caps = RsnCapabilities(0).with_mgmt_frame_protection_cap(true);
828        assert!(wpa2_wpa3_caps.is_wpa3_compatible(true));
829
830        let caps = wpa2_wpa3_caps.clone().with_extended_key_id(true);
831        assert!(!caps.is_wpa3_compatible(true));
832    }
833
834    #[test]
835    fn test_with_caps() {
836        assert!(Rsne::wpa2_rsne().rsn_capabilities.is_none());
837        let rsne_with_caps =
838            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_peerkey_enabled(true));
839        assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
840
841        assert!(!Rsne::wpa2_wpa3_rsne().rsn_capabilities.unwrap().peerkey_enabled());
842        let rsne_with_caps =
843            Rsne::wpa2_wpa3_rsne_with_extra_caps(RsnCapabilities(0).with_peerkey_enabled(true));
844        assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
845        assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_cap());
846
847        assert!(!Rsne::wpa3_rsne().rsn_capabilities.unwrap().peerkey_enabled());
848        let rsne_with_caps =
849            Rsne::wpa3_rsne_with_extra_caps(RsnCapabilities(0).with_peerkey_enabled(true));
850        assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
851        assert!(
852            rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_cap()
853                && rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_req()
854        );
855    }
856
857    #[test]
858    fn test_incompatible_group_data_cipher() {
859        let rsne = Rsne {
860            group_data_cipher_suite: Some(CIPHER_GCMP_256),
861            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
862            akm_suites: vec![AKM_PSK],
863            ..Default::default()
864        };
865        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
866    }
867
868    #[test]
869    fn test_no_group_data_cipher() {
870        let rsne = Rsne {
871            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
872            akm_suites: vec![AKM_PSK],
873            ..Default::default()
874        };
875        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
876
877        let rsne = Rsne {
878            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
879            akm_suites: vec![AKM_SAE],
880            ..Default::default()
881        };
882        let mut security_support = fake_security_support_empty();
883        security_support.mfp.supported = true;
884        assert_eq!(rsne.is_wpa3_rsn_compatible(&security_support), false);
885    }
886
887    #[test]
888    fn test_rsne_unsupported_group_data_cipher() {
889        let s_rsne = Rsne::wpa2_rsne();
890        let mut a_rsne = Rsne::wpa2_rsne();
891        a_rsne.group_data_cipher_suite = Some(CIPHER_GCMP_256);
892        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
893    }
894
895    #[test]
896    fn test_ccmp_128_group_data_cipher_ccmp_128_pairwise_cipher() {
897        let a_rsne = Rsne {
898            group_data_cipher_suite: Some(CIPHER_CCMP_128),
899            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
900            akm_suites: vec![AKM_PSK],
901            ..Default::default()
902        };
903        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
904
905        let s_rsne = a_rsne
906            .derive_wpa2_s_rsne(&fake_security_support_empty())
907            .expect("could not derive WPA2 Supplicant RSNE");
908        let expected_rsne_bytes = vec![
909            0x30, // element id, 48 expressed as hexadecimal value
910            0x12, // length in octets, 18 expressed as hexadecimal value
911            0x01, 0x00, // Version 1
912            0x00, 0x0F, 0xac, 0x04, // CCMP-128 as group data cipher suite
913            0x01, 0x00, // pairwise cipher suite count
914            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
915            0x01, 0x00, // authentication count
916            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
917        ];
918        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
919    }
920
921    #[test]
922    fn test_tkip_group_data_cipher_ccmp_128_pairwise_cipher() {
923        let a_rsne = Rsne {
924            group_data_cipher_suite: Some(CIPHER_TKIP),
925            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
926            akm_suites: vec![AKM_PSK],
927            ..Default::default()
928        };
929        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
930
931        let s_rsne = a_rsne
932            .derive_wpa2_s_rsne(&fake_security_support_empty())
933            .expect("could not derive WPA2 Supplicant RSNE");
934        let expected_rsne_bytes = vec![
935            0x30, // element id, 48 expressed as hexadecimal value
936            0x12, // length in octets, 18 expressed as hexadecimal value
937            0x01, 0x00, // Version 1
938            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
939            0x01, 0x00, // pairwise cipher suite count
940            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
941            0x01, 0x00, // authentication count
942            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
943        ];
944        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
945    }
946
947    #[test]
948    fn test_tkip_group_data_cipher_tkip_pairwise_cipher() {
949        let a_rsne = Rsne {
950            group_data_cipher_suite: Some(CIPHER_TKIP),
951            pairwise_cipher_suites: vec![CIPHER_TKIP],
952            akm_suites: vec![AKM_PSK],
953            ..Default::default()
954        };
955        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
956
957        let s_rsne = a_rsne
958            .derive_wpa2_s_rsne(&fake_security_support_empty())
959            .expect("could not derive WPA2 Supplicant RSNE");
960        let expected_rsne_bytes = vec![
961            0x30, // element id, 48 expressed as hexadecimal value
962            0x12, // length in octets, 18 expressed as hexadecimal value
963            0x01, 0x00, // Version 1
964            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
965            0x01, 0x00, // pairwise cipher suite count
966            0x00, 0x0F, 0xAC, 0x02, // TKIP as pairwise cipher suite
967            0x01, 0x00, // authentication count
968            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
969        ];
970        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
971    }
972
973    #[test]
974    fn test_tkip_group_data_cipher_prefer_ccmp_128_pairwise_cipher() {
975        let a_rsne = Rsne {
976            group_data_cipher_suite: Some(CIPHER_TKIP),
977            pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
978            akm_suites: vec![AKM_PSK],
979            ..Default::default()
980        };
981        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
982
983        let s_rsne = a_rsne
984            .derive_wpa2_s_rsne(&fake_security_support_empty())
985            .expect("could not derive WPA2 Supplicant RSNE");
986        let expected_rsne_bytes = vec![
987            0x30, // element id, 48 expressed as hexadecimal value
988            0x12, // length in octets, 18 expressed as hexadecimal value
989            0x01, 0x00, // Version 1
990            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
991            0x01, 0x00, // pairwise cipher suite count
992            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
993            0x01, 0x00, // authentication count
994            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
995        ];
996        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
997    }
998
999    #[test]
1000    fn test_ccmp_128_group_data_cipher_prefer_ccmp_128_pairwise_cipher() {
1001        let a_rsne = Rsne {
1002            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1003            pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
1004            akm_suites: vec![AKM_PSK],
1005            ..Default::default()
1006        };
1007        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1008
1009        let s_rsne = a_rsne
1010            .derive_wpa2_s_rsne(&fake_security_support_empty())
1011            .expect("could not derive WPA2 Supplicant RSNE");
1012        let expected_rsne_bytes = vec![
1013            0x30, // element id, 48 expressed as hexadecimal value
1014            0x12, // length in octets, 18 expressed as hexadecimal value
1015            0x01, 0x00, // Version 1
1016            0x00, 0x0F, 0xac, 0x04, // CCMP-128 as group data cipher suite
1017            0x01, 0x00, // pairwise cipher suite count
1018            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
1019            0x01, 0x00, // authentication count
1020            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
1021        ];
1022        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1023    }
1024
1025    #[test]
1026    fn test_compatible_pairwise_cipher() {
1027        let rsne = Rsne {
1028            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1029            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1030            akm_suites: vec![AKM_PSK],
1031            ..Default::default()
1032        };
1033        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1034
1035        let rsne = Rsne {
1036            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1037            pairwise_cipher_suites: vec![CIPHER_TKIP],
1038            akm_suites: vec![AKM_PSK],
1039            ..Default::default()
1040        };
1041        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1042    }
1043
1044    #[test]
1045    fn test_incompatible_pairwise_cipher() {
1046        let rsne = Rsne {
1047            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1048            pairwise_cipher_suites: vec![CIPHER_BIP_CMAC_256],
1049            akm_suites: vec![AKM_PSK],
1050            ..Default::default()
1051        };
1052        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1053    }
1054
1055    #[test]
1056    fn test_no_pairwise_cipher() {
1057        let rsne = Rsne {
1058            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1059            akm_suites: vec![AKM_PSK],
1060            ..Default::default()
1061        };
1062        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1063
1064        let rsne = Rsne {
1065            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1066            akm_suites: vec![AKM_SAE],
1067            ..Default::default()
1068        };
1069        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1070    }
1071
1072    #[test]
1073    fn test_rsne_unsupported_pairwise_cipher() {
1074        let s_rsne = Rsne::wpa2_rsne();
1075        let mut a_rsne = Rsne::wpa2_rsne();
1076        a_rsne.pairwise_cipher_suites = vec![CIPHER_BIP_CMAC_256];
1077        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1078    }
1079
1080    #[test]
1081    fn test_incompatible_akm() {
1082        let rsne = Rsne {
1083            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1084            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1085            akm_suites: vec![AKM_EAP],
1086            ..Default::default()
1087        };
1088        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1089        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1090
1091        let rsne = Rsne {
1092            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1093            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1094            akm_suites: vec![AKM_PSK],
1095            ..Default::default()
1096        };
1097        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1098
1099        let rsne = Rsne {
1100            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1101            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1102            akm_suites: vec![AKM_SAE],
1103            ..Default::default()
1104        };
1105        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1106    }
1107
1108    #[test]
1109    fn test_no_akm() {
1110        let rsne = Rsne {
1111            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1112            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1113            ..Default::default()
1114        };
1115        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1116        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1117    }
1118
1119    #[test]
1120    fn test_rsne_unsupported_akm() {
1121        let s_rsne = Rsne::wpa2_rsne();
1122        let mut a_rsne = Rsne::wpa2_rsne();
1123        a_rsne.akm_suites = vec![AKM_EAP];
1124        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1125    }
1126
1127    #[test]
1128    fn test_ensure_valid_s_rsne() {
1129        let s_rsne = Rsne::wpa2_rsne();
1130        let result = s_rsne.ensure_valid_s_rsne();
1131        assert!(result.is_ok());
1132
1133        let mut s_rsne = Rsne::wpa2_rsne();
1134        s_rsne.group_data_cipher_suite = None;
1135        let result = s_rsne.ensure_valid_s_rsne();
1136        assert!(result.is_err());
1137        assert_eq!(result.unwrap_err(), Error::NoGroupDataCipherSuite);
1138
1139        let mut s_rsne = Rsne::wpa2_rsne();
1140        s_rsne.pairwise_cipher_suites = vec![];
1141        let result = s_rsne.ensure_valid_s_rsne();
1142        assert!(result.is_err());
1143        assert_eq!(result.unwrap_err(), Error::NoPairwiseCipherSuite);
1144
1145        let mut s_rsne = Rsne::wpa2_rsne();
1146        s_rsne.pairwise_cipher_suites.push(CIPHER_GCMP_256);
1147        let result = s_rsne.ensure_valid_s_rsne();
1148        assert!(result.is_err());
1149        assert_eq!(result.unwrap_err(), Error::TooManyPairwiseCipherSuites);
1150
1151        let mut s_rsne = Rsne::wpa2_rsne();
1152        s_rsne.akm_suites = vec![];
1153        let result = s_rsne.ensure_valid_s_rsne();
1154        assert!(result.is_err());
1155        assert_eq!(result.unwrap_err(), Error::NoAkmSuite);
1156
1157        let mut s_rsne = Rsne::wpa2_rsne();
1158        s_rsne.akm_suites.push(AKM_EAP);
1159        let result = s_rsne.ensure_valid_s_rsne();
1160        assert!(result.is_err());
1161        assert_eq!(result.unwrap_err(), Error::TooManyAkmSuites);
1162
1163        let mut s_rsne = Rsne::wpa2_rsne();
1164        s_rsne.akm_suites = vec![akm::Akm::new_dot11(200)];
1165        let result = s_rsne.ensure_valid_s_rsne();
1166        assert!(result.is_err());
1167        assert_eq!(result.unwrap_err(), Error::NoAkmMicBytes);
1168    }
1169
1170    #[test]
1171    fn test_compatible_wpa2_rsne() {
1172        let rsne = Rsne::wpa2_rsne();
1173        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1174    }
1175
1176    #[test]
1177    fn test_compatible_wpa2_wpa3_rsne() {
1178        let rsne = Rsne::wpa2_wpa3_rsne();
1179        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1180        assert!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY));
1181    }
1182
1183    #[test]
1184    fn test_compatible_wpa3_rsne() {
1185        let rsne = Rsne::wpa3_rsne();
1186        assert!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY));
1187    }
1188
1189    #[test]
1190    fn test_incompatible_wpa3_rsne_no_mfp() {
1191        let rsne = Rsne::wpa3_rsne();
1192        assert!(!rsne.is_wpa3_rsn_compatible(&fake_security_support_empty()));
1193    }
1194
1195    #[test]
1196    fn test_ccmp128_group_data_pairwise_cipher_psk() {
1197        let a_rsne = Rsne {
1198            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1199            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1200            akm_suites: vec![AKM_PSK],
1201            ..Default::default()
1202        };
1203        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1204
1205        let s_rsne = a_rsne
1206            .derive_wpa2_s_rsne(&fake_security_support_empty())
1207            .expect("could not derive WPA2 Supplicant RSNE");
1208        let expected_rsne_bytes =
1209            vec![48, 18, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2];
1210        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1211    }
1212
1213    #[test]
1214    fn test_valid_rsne() {
1215        let s_rsne = Rsne::wpa2_rsne();
1216        let a_rsne = Rsne::wpa2_rsne();
1217        assert!(s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1218    }
1219
1220    #[test]
1221    fn test_ccmp_tkip_mode() {
1222        let a_rsne = Rsne {
1223            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1224            pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
1225            akm_suites: vec![AKM_PSK, AKM_FT_PSK],
1226            ..Default::default()
1227        };
1228        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1229
1230        let s_rsne = a_rsne
1231            .derive_wpa2_s_rsne(&fake_security_support_empty())
1232            .expect("could not derive WPA2 Supplicant RSNE");
1233        let expected_rsne_bytes =
1234            vec![48, 18, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2];
1235        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1236    }
1237
1238    #[test]
1239    fn test_ccmp128_group_data_pairwise_cipher_sae() {
1240        let a_rsne = Rsne::wpa3_rsne();
1241        assert_eq!(a_rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), true);
1242
1243        let s_rsne = a_rsne
1244            .derive_wpa3_s_rsne(&MFP_SUPPORT_ONLY)
1245            .expect("could not derive WPA2 Supplicant RSNE");
1246        let expected_rsne_bytes =
1247            vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 8, 192, 0];
1248        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1249    }
1250
1251    #[test]
1252    fn test_wpa3_transition_mode() {
1253        let a_rsne = Rsne::wpa2_wpa3_rsne();
1254        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1255        assert_eq!(a_rsne.is_wpa3_rsn_compatible(&fake_security_support_empty()), false);
1256        assert_eq!(a_rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), true);
1257
1258        let s_rsne = a_rsne
1259            .derive_wpa2_s_rsne(&MFP_SUPPORT_ONLY)
1260            .expect("could not derive WPA2 Supplicant RSNE");
1261        let expected_rsne_bytes =
1262            vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2, 192, 0];
1263        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1264
1265        let s_rsne = a_rsne
1266            .derive_wpa3_s_rsne(&MFP_SUPPORT_ONLY)
1267            .expect("could not derive WPA3 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, 8, 192, 0];
1270        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1271    }
1272
1273    #[test]
1274    fn test_wpa2_psk_rsne_bytes() {
1275        // Compliant with IEEE Std 802.11-2016, 9.4.2.25.
1276        let expected: Vec<u8> = vec![
1277            0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
1278            0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00,
1279        ];
1280        let rsne = Rsne::wpa2_rsne_with_caps(RsnCapabilities(0));
1281        let mut actual = Vec::with_capacity(rsne.len());
1282        rsne.write_into(&mut actual).expect("error writing RSNE");
1283
1284        assert_eq!(&expected[..], &actual[..]);
1285    }
1286
1287    #[test]
1288    fn test_supplicant_missing_required_mpfc() {
1289        let s_rsne = Rsne::wpa2_rsne();
1290        let a_rsne = Rsne::wpa2_rsne_with_caps(
1291            RsnCapabilities(0)
1292                .with_mgmt_frame_protection_req(true)
1293                .with_mgmt_frame_protection_cap(true),
1294        );
1295        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1296    }
1297
1298    #[test]
1299    fn test_authenticator_missing_required_mpfc() {
1300        let s_rsne = Rsne::wpa2_rsne_with_caps(
1301            RsnCapabilities(0)
1302                .with_mgmt_frame_protection_req(true)
1303                .with_mgmt_frame_protection_cap(true),
1304        );
1305        let a_rsne = Rsne::wpa2_rsne();
1306        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1307    }
1308
1309    #[test]
1310    fn test_supplicant_has_invalid_mgmt_frame_protection_fields() {
1311        let s_rsne = Rsne::wpa2_rsne_with_caps(
1312            RsnCapabilities(0)
1313                .with_mgmt_frame_protection_req(true)
1314                .with_mgmt_frame_protection_cap(false),
1315        );
1316        // AP only cares about client's invalid setting if AP is mgmt frame protection capable
1317        let a_rsne =
1318            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
1319
1320        let result = s_rsne.is_valid_subset_of(&a_rsne);
1321        assert!(result.is_err());
1322        assert_eq!(result.unwrap_err(), Error::InvalidSupplicantMgmtFrameProtection);
1323    }
1324
1325    #[test]
1326    fn test_authenticator_has_invalid_mgmt_frame_protection_fields() {
1327        // client only cares about AP's invalid setting if client is mgmt frame protection capable
1328        let s_rsne =
1329            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
1330        let a_rsne = Rsne::wpa2_rsne_with_caps(
1331            RsnCapabilities(0)
1332                .with_mgmt_frame_protection_req(true)
1333                .with_mgmt_frame_protection_cap(false),
1334        );
1335
1336        let result = s_rsne.is_valid_subset_of(&a_rsne);
1337        assert!(result.is_err());
1338        assert_eq!(result.unwrap_err(), Error::InvalidAuthenticatorMgmtFrameProtection);
1339    }
1340
1341    #[test]
1342    fn test_write_until_version() {
1343        let expected_frame: Vec<u8> = vec![
1344            0x30, // element id
1345            0x02, // length
1346            0x01, 0x00, // version
1347        ];
1348        let buf = Rsne { version: VERSION, ..Default::default() }.into_bytes();
1349        assert_eq!(&buf[..], &expected_frame[..]);
1350    }
1351
1352    #[test]
1353    fn test_write_until_group_data() {
1354        let expected_frame: Vec<u8> = vec![
1355            0x30, // element id
1356            0x06, // length
1357            0x01, 0x00, // version
1358            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1359        ];
1360        let buf = Rsne {
1361            version: VERSION,
1362            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1363            ..Default::default()
1364        }
1365        .into_bytes();
1366        assert_eq!(&buf[..], &expected_frame[..]);
1367    }
1368
1369    #[test]
1370    fn test_write_until_pairwise() {
1371        let expected_frame: Vec<u8> = vec![
1372            0x30, // element id
1373            12,   // length
1374            0x01, 0x00, // version
1375            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1376            0x01, 0x00, // pairwise suite count
1377            0x00, 0x0f, 0xac, 0x04, // pairwise cipher suite
1378        ];
1379        let buf = Rsne {
1380            version: VERSION,
1381            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1382            pairwise_cipher_suites: vec![cipher::Cipher::new_dot11(cipher::CCMP_128)],
1383            ..Default::default()
1384        }
1385        .into_bytes();
1386        assert_eq!(&buf[..], &expected_frame[..]);
1387    }
1388
1389    #[test]
1390    fn test_write_until_akm() {
1391        let expected_frame: Vec<u8> = vec![
1392            0x30, // element id
1393            14,   // length
1394            0x01, 0x00, // version
1395            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1396            0x00, 0x00, // pairwise suite count
1397            0x01, 0x00, // pairwise suite count
1398            0x00, 0x0f, 0xac, 0x02, // pairwise cipher suite
1399        ];
1400        let buf = Rsne {
1401            version: VERSION,
1402            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1403            akm_suites: vec![akm::Akm::new_dot11(akm::PSK)],
1404            ..Default::default()
1405        }
1406        .into_bytes();
1407        assert_eq!(&buf[..], &expected_frame[..]);
1408    }
1409
1410    #[test]
1411    fn test_write_until_rsn_capabilities() {
1412        let expected_frame: Vec<u8> = vec![
1413            0x30, // element id
1414            12,   // length
1415            0x01, 0x00, // version
1416            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1417            0x00, 0x00, // pairwise suite count
1418            0x00, 0x00, // akm suite count
1419            0xcd, 0xab, // rsn capabilities
1420        ];
1421        let buf = Rsne {
1422            version: VERSION,
1423            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1424            rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1425            ..Default::default()
1426        }
1427        .into_bytes();
1428        assert_eq!(&buf[..], &expected_frame[..]);
1429    }
1430
1431    static PMKID_VAL: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
1432
1433    #[test]
1434    fn test_write_until_pmkids() {
1435        let expected_frame: Vec<u8> = vec![
1436            0x30, // element id
1437            30,   // length
1438            0x01, 0x00, // version
1439            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1440            0x00, 0x00, // pairwise suite count
1441            0x00, 0x00, // akm suite count
1442            0xcd, 0xab, // rsn capabilities
1443            0x01, 0x00, // pmkid count
1444            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, // pmkid
1445        ];
1446        let buf = Rsne {
1447            version: VERSION,
1448            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1449            rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1450            pmkids: vec![Bytes::from_static(&PMKID_VAL[..])],
1451            ..Default::default()
1452        }
1453        .into_bytes();
1454        assert_eq!(&buf[..], &expected_frame[..]);
1455    }
1456
1457    #[test]
1458    fn test_write_until_group_mgmt() {
1459        let expected_frame: Vec<u8> = vec![
1460            0x30, // element id
1461            18,   // length
1462            0x01, 0x00, // version
1463            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1464            0x00, 0x00, // pairwise suite count
1465            0x00, 0x00, // akm suite count
1466            0xcd, 0xab, // rsn capabilities
1467            0x00, 0x00, // pmkids count
1468            0x00, 0x0f, 0xac, 0x06, // group management cipher suite
1469        ];
1470        let buf = Rsne {
1471            version: VERSION,
1472            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1473            rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1474            group_mgmt_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::BIP_CMAC_128)),
1475            ..Default::default()
1476        }
1477        .into_bytes();
1478        assert_eq!(&buf[..], &expected_frame[..]);
1479    }
1480
1481    #[test]
1482    fn test_end_write_on_missing_caps() {
1483        let expected_frame: Vec<u8> = vec![
1484            0x30, // element id
1485            0x06, // length
1486            0x01, 0x00, // version
1487            0x00, 0x0f, 0xac,
1488            0x04, // group data cipher suite
1489                  // We don't write group management suite because caps are missing.
1490        ];
1491        let buf = Rsne {
1492            version: VERSION,
1493            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1494            rsn_capabilities: None,
1495            group_mgmt_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::BIP_CMAC_128)),
1496            ..Default::default()
1497        }
1498        .into_bytes();
1499        assert_eq!(&buf[..], &expected_frame[..]);
1500    }
1501}