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()
487                && (c.suite_type == cipher::CCMP_128 || c.suite_type == cipher::TKIP)
488        });
489
490        let pairwise_supported = self.pairwise_cipher_suites.iter().any(|c| {
491            c.has_known_usage()
492                && (c.suite_type == cipher::CCMP_128 || c.suite_type == cipher::TKIP)
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            .map_or(true, |caps| caps.is_compatible_with_features(security_support));
502
503        group_data_supported
504            && pairwise_supported
505            && akm_supported
506            && caps_supported
507            && features_supported
508    }
509
510    /// Check if this is a supported WPA3-Personal or WPA3-Personal transition AP per the WFA WPA3 specification.
511    /// Supported Ciphers and AKMs:
512    /// Group Data Ciphers: CCMP-128, TKIP
513    /// Pairwise Cipher: CCMP-128
514    /// AKM: SAE (also PSK in transition mode)
515    /// The MFPR bit is required, except for transition mode.
516    pub fn is_wpa3_rsn_compatible(&self, security_support: &fidl_common::SecuritySupport) -> bool {
517        let group_data_supported = self.group_data_cipher_suite.as_ref().is_some_and(|c| {
518            c.has_known_usage()
519                && (c.suite_type == cipher::CCMP_128 || c.suite_type == cipher::TKIP)
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            .map_or(true, |caps| caps.is_compatible_with_features(security_support));
537        // WFA WPA3 specification v3.0: 2.3 rule 7: Verify that we actually support MFP, regardless of whether
538        // the features bits indicate we need that support. SAE without MFP is not a valid configuration.
539        features_supported &= security_support.mfp.supported;
540        group_data_supported
541            && pairwise_supported
542            && sae_supported
543            && caps_supported
544            && features_supported
545    }
546
547    fn with_caps(mut self, rsn_capabilities: RsnCapabilities) -> Self {
548        self.rsn_capabilities = Some(rsn_capabilities);
549        self
550    }
551}
552
553fn read_suite_selector<T>(input: &[u8]) -> IResult<&[u8], T>
554where
555    T: suite_selector::Factory<Suite = T>,
556{
557    let (i1, bytes) = take(4usize).parse(input)?;
558    let oui = Oui::new([bytes[0], bytes[1], bytes[2]]);
559    return Ok((i1, T::new(oui, bytes[3])));
560}
561
562fn read_pmkid(input: &[u8]) -> IResult<&[u8], pmkid::Pmkid> {
563    let f = |bytes| {
564        let pmkid_data = Bytes::copy_from_slice(bytes);
565        return pmkid::new(pmkid_data);
566    };
567
568    map_res(nom::bytes::streaming::take(16usize), f).parse(input)
569}
570
571fn akm(input: &[u8]) -> IResult<&[u8], akm::Akm> {
572    read_suite_selector::<akm::Akm>(input)
573}
574
575fn cipher(input: &[u8]) -> IResult<&[u8], cipher::Cipher> {
576    read_suite_selector::<cipher::Cipher>(input)
577}
578
579/// convert bytes of an RSNE information element into an RSNE representation. This method
580/// does not depend on the information element length field (second byte) and thus does not
581/// validate that it's correct
582pub fn from_bytes(input: &[u8]) -> IResult<&[u8], Rsne> {
583    map(
584        terminated(
585            (
586                le_u8,
587                le_u8,
588                le_u16,
589                if_remaining!(cipher),
590                if_remaining!(length_count(le_u16, cipher)),
591                if_remaining!(length_count(le_u16, akm)),
592                if_remaining!(map(le_u16, RsnCapabilities)),
593                if_remaining!(length_count(le_u16, read_pmkid)),
594                if_remaining!(cipher),
595            ),
596            eof,
597        ),
598        |(
599            _element_id,
600            _length,
601            version,
602            group_cipher,
603            pairwise_list,
604            akm_list,
605            rsn_capabilities,
606            pmkid_list,
607            group_mgmt_cipher_suite,
608        )| Rsne {
609            version: version,
610            group_data_cipher_suite: group_cipher,
611            pairwise_cipher_suites: pairwise_list.unwrap_or_default(),
612            akm_suites: akm_list.unwrap_or_default(),
613            rsn_capabilities: rsn_capabilities,
614            pmkids: pmkid_list.unwrap_or_default(),
615            group_mgmt_cipher_suite: group_mgmt_cipher_suite,
616        },
617    )
618    .parse(input)
619}
620
621#[cfg(test)]
622mod tests {
623    use super::akm::{AKM_EAP, AKM_FT_PSK};
624    use super::cipher::{CIPHER_BIP_CMAC_256, CIPHER_GCMP_256, CIPHER_TKIP};
625    use super::*;
626    use crate::append::TrackedAppend;
627    use crate::test_utils::fake_features::fake_security_support_empty;
628    use crate::test_utils::FixedSizedTestBuffer;
629    use test_case::test_case;
630
631    #[cfg(feature = "benchmark")]
632    mod bench {
633        use self::test::Bencher;
634        use super::*;
635        #[cfg()]
636        #[bench]
637        fn bench_parse_with_nom(b: &mut Bencher) {
638            let frame: Vec<u8> = vec![
639                0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
640                0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
641                0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
642                0xac, 0x04,
643            ];
644            b.iter(|| from_bytes(&frame));
645        }
646    }
647
648    #[test]
649    fn test_write_into() {
650        let frame: Vec<u8> = vec![
651            0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
652            0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
653            0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
654            0xac, 0x04,
655        ];
656        let result = from_bytes(&frame);
657        assert!(result.is_ok());
658        let rsne = result.unwrap().1;
659        let mut buf = Vec::with_capacity(128);
660        rsne.write_into(&mut buf).expect("failed writing RSNE");
661        let rsne_len = buf.len();
662        let left_over = buf.split_off(rsne_len);
663        assert_eq!(&buf[..], &frame[..]);
664        assert!(left_over.iter().all(|b| *b == 0));
665    }
666
667    #[test]
668    fn test_short_buffer() {
669        let frame: Vec<u8> = vec![
670            0x30, 0x2A, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
671            0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0xa8, 0x04, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04,
672            0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x0f,
673            0xac, 0x04,
674        ];
675        let mut buf = FixedSizedTestBuffer::new(32);
676        let result = from_bytes(&frame);
677        assert!(result.is_ok());
678        let rsne = result.unwrap().1;
679        rsne.write_into(&mut buf).expect_err("expected writing RSNE to fail");
680        assert_eq!(buf.bytes_appended(), 0);
681    }
682
683    #[test]
684    fn test_rsn_fields_representation() {
685        let frame: Vec<u8> = vec![
686            0x30, // element id
687            0x2A, // length
688            0x01, 0x00, // version
689            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
690            0x01, 0x00, // pairwise cipher suite count
691            0x00, 0x0f, 0xac, 0x04, // pairwise cipher suite list
692            0x01, 0x00, // akm suite count
693            0x00, 0x0f, 0xac, 0x02, // akm suite list
694            0xa8, 0x04, // rsn capabilities
695            0x01, 0x00, // pmk id count
696            // pmk id list
697            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
698            0x10, 0x11, 0x00, 0x0f, 0xac, 0x04, // group management cipher suite
699        ];
700        let result = from_bytes(&frame);
701        assert!(result.is_ok());
702        let rsne = result.unwrap().1;
703
704        assert_eq!(rsne.version, VERSION);
705        assert_eq!(rsne.len(), 0x2a + 2);
706
707        assert!(rsne.group_data_cipher_suite.is_some());
708        assert_eq!(rsne.group_data_cipher_suite, Some(CIPHER_CCMP_128));
709        assert_eq!(rsne.pairwise_cipher_suites.len(), 1);
710        assert_eq!(rsne.pairwise_cipher_suites[0].oui, Oui::DOT11);
711        assert_eq!(rsne.pairwise_cipher_suites[0].suite_type, cipher::CCMP_128);
712        assert_eq!(rsne.akm_suites.len(), 1);
713        assert_eq!(rsne.akm_suites[0].suite_type, akm::PSK);
714
715        let rsn_capabilities = rsne.rsn_capabilities.expect("should have RSN capabilities");
716        assert_eq!(rsn_capabilities.preauth(), false);
717        assert_eq!(rsn_capabilities.no_pairwise(), false);
718        assert_eq!(rsn_capabilities.ptksa_replay_counter(), 2);
719        assert_eq!(rsn_capabilities.gtksa_replay_counter(), 2);
720        assert!(!rsn_capabilities.mgmt_frame_protection_req());
721        assert!(rsn_capabilities.mgmt_frame_protection_cap());
722        assert!(!rsn_capabilities.joint_multiband());
723        assert!(!rsn_capabilities.peerkey_enabled());
724        assert!(rsn_capabilities.ssp_amsdu_cap());
725        assert!(!rsn_capabilities.ssp_amsdu_req());
726        assert!(!rsn_capabilities.pbac());
727        assert!(!rsn_capabilities.extended_key_id());
728
729        assert_eq!(rsn_capabilities.0, 0xa8 + (0x04 << 8));
730
731        let pmkids: &[u8] = &[
732            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
733            0x10, 0x11,
734        ];
735        assert_eq!(rsne.pmkids.len(), 1);
736        assert_eq!(rsne.pmkids[0], Bytes::from(pmkids));
737
738        assert_eq!(rsne.group_mgmt_cipher_suite, Some(CIPHER_CCMP_128));
739    }
740
741    #[test]
742    fn test_rsn_capabilities_setters() {
743        let mut rsn_caps = RsnCapabilities(0u16);
744        rsn_caps.set_ptksa_replay_counter(2);
745        rsn_caps.set_gtksa_replay_counter(2);
746        rsn_caps.set_mgmt_frame_protection_cap(true);
747        rsn_caps.set_ssp_amsdu_cap(true);
748
749        assert_eq!(rsn_caps.0, 0xa8 + (0x04 << 8));
750    }
751
752    #[test]
753    fn test_invalid_wpa2_caps() {
754        assert!(RsnCapabilities(0).is_wpa2_compatible());
755
756        let caps = RsnCapabilities(0).with_joint_multiband(true);
757        assert!(!caps.is_wpa2_compatible());
758
759        let caps = RsnCapabilities(0).with_peerkey_enabled(true);
760        assert!(!caps.is_wpa2_compatible());
761
762        let caps = RsnCapabilities(0).with_ssp_amsdu_req(true);
763        assert!(!caps.is_wpa2_compatible());
764
765        let caps = RsnCapabilities(0).with_pbac(true);
766        assert!(!caps.is_wpa2_compatible());
767
768        let caps = RsnCapabilities(0).with_extended_key_id(true);
769        assert!(!caps.is_wpa2_compatible());
770    }
771
772    static MFP_SUPPORT_ONLY: fidl_common::SecuritySupport = fidl_common::SecuritySupport {
773        mfp: fidl_common::MfpFeature { supported: true },
774        sae: fidl_common::SaeFeature {
775            driver_handler_supported: false,
776            sme_handler_supported: false,
777        },
778    };
779
780    #[test_case(MFP_SUPPORT_ONLY, true)]
781    #[test_case(fake_security_support_empty(), false)]
782    #[fuchsia::test]
783    fn test_wpa2_enables_pmf_if_supported(
784        security_support: fidl_common::SecuritySupport,
785        expect_mfp: bool,
786    ) {
787        let a_rsne =
788            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
789        assert!(a_rsne.is_wpa2_rsn_compatible(&security_support));
790
791        let s_rsne = a_rsne
792            .derive_wpa2_s_rsne(&security_support)
793            .expect("Should be able to derive s_rsne with PMF");
794        assert!(s_rsne.is_wpa2_rsn_compatible(&security_support));
795        assert_eq!(
796            expect_mfp,
797            s_rsne
798                .rsn_capabilities
799                .expect("PMF RSNE should have RSN capabilities")
800                .mgmt_frame_protection_req()
801        );
802    }
803
804    #[test]
805    fn test_invalid_wpa3_caps() {
806        assert!(!RsnCapabilities(0).is_wpa3_compatible(false));
807
808        let wpa3_caps = RsnCapabilities(0)
809            .with_mgmt_frame_protection_cap(true)
810            .with_mgmt_frame_protection_req(true);
811        assert!(wpa3_caps.is_wpa3_compatible(false));
812
813        let caps = wpa3_caps.clone().with_joint_multiband(true);
814        assert!(!caps.is_wpa3_compatible(false));
815
816        let caps = wpa3_caps.clone().with_peerkey_enabled(true);
817        assert!(!caps.is_wpa3_compatible(false));
818
819        let caps = wpa3_caps.clone().with_ssp_amsdu_req(true);
820        assert!(!caps.is_wpa3_compatible(false));
821
822        let caps = wpa3_caps.clone().with_pbac(true);
823        assert!(!caps.is_wpa3_compatible(false));
824
825        let caps = wpa3_caps.clone().with_extended_key_id(true);
826        assert!(!caps.is_wpa3_compatible(false));
827
828        let wpa2_wpa3_caps = RsnCapabilities(0).with_mgmt_frame_protection_cap(true);
829        assert!(wpa2_wpa3_caps.is_wpa3_compatible(true));
830
831        let caps = wpa2_wpa3_caps.clone().with_extended_key_id(true);
832        assert!(!caps.is_wpa3_compatible(true));
833    }
834
835    #[test]
836    fn test_with_caps() {
837        assert!(Rsne::wpa2_rsne().rsn_capabilities.is_none());
838        let rsne_with_caps =
839            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_peerkey_enabled(true));
840        assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
841
842        assert!(!Rsne::wpa2_wpa3_rsne().rsn_capabilities.unwrap().peerkey_enabled());
843        let rsne_with_caps =
844            Rsne::wpa2_wpa3_rsne_with_extra_caps(RsnCapabilities(0).with_peerkey_enabled(true));
845        assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().peerkey_enabled());
846        assert!(rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_cap());
847
848        assert!(!Rsne::wpa3_rsne().rsn_capabilities.unwrap().peerkey_enabled());
849        let rsne_with_caps =
850            Rsne::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!(
853            rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_cap()
854                && rsne_with_caps.rsn_capabilities.as_ref().unwrap().mgmt_frame_protection_req()
855        );
856    }
857
858    #[test]
859    fn test_incompatible_group_data_cipher() {
860        let rsne = Rsne {
861            group_data_cipher_suite: Some(CIPHER_GCMP_256),
862            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
863            akm_suites: vec![AKM_PSK],
864            ..Default::default()
865        };
866        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
867    }
868
869    #[test]
870    fn test_no_group_data_cipher() {
871        let rsne = Rsne {
872            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
873            akm_suites: vec![AKM_PSK],
874            ..Default::default()
875        };
876        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
877
878        let rsne = Rsne {
879            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
880            akm_suites: vec![AKM_SAE],
881            ..Default::default()
882        };
883        let mut security_support = fake_security_support_empty();
884        security_support.mfp.supported = true;
885        assert_eq!(rsne.is_wpa3_rsn_compatible(&security_support), false);
886    }
887
888    #[test]
889    fn test_rsne_unsupported_group_data_cipher() {
890        let s_rsne = Rsne::wpa2_rsne();
891        let mut a_rsne = Rsne::wpa2_rsne();
892        a_rsne.group_data_cipher_suite = Some(CIPHER_GCMP_256);
893        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
894    }
895
896    #[test]
897    fn test_ccmp_128_group_data_cipher_ccmp_128_pairwise_cipher() {
898        let a_rsne = Rsne {
899            group_data_cipher_suite: Some(CIPHER_CCMP_128),
900            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
901            akm_suites: vec![AKM_PSK],
902            ..Default::default()
903        };
904        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
905
906        let s_rsne = a_rsne
907            .derive_wpa2_s_rsne(&fake_security_support_empty())
908            .expect("could not derive WPA2 Supplicant RSNE");
909        let expected_rsne_bytes = vec![
910            0x30, // element id, 48 expressed as hexadecimal value
911            0x12, // length in octets, 18 expressed as hexadecimal value
912            0x01, 0x00, // Version 1
913            0x00, 0x0F, 0xac, 0x04, // CCMP-128 as group data cipher suite
914            0x01, 0x00, // pairwise cipher suite count
915            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
916            0x01, 0x00, // authentication count
917            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
918        ];
919        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
920    }
921
922    #[test]
923    fn test_tkip_group_data_cipher_ccmp_128_pairwise_cipher() {
924        let a_rsne = Rsne {
925            group_data_cipher_suite: Some(CIPHER_TKIP),
926            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
927            akm_suites: vec![AKM_PSK],
928            ..Default::default()
929        };
930        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
931
932        let s_rsne = a_rsne
933            .derive_wpa2_s_rsne(&fake_security_support_empty())
934            .expect("could not derive WPA2 Supplicant RSNE");
935        let expected_rsne_bytes = vec![
936            0x30, // element id, 48 expressed as hexadecimal value
937            0x12, // length in octets, 18 expressed as hexadecimal value
938            0x01, 0x00, // Version 1
939            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
940            0x01, 0x00, // pairwise cipher suite count
941            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
942            0x01, 0x00, // authentication count
943            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
944        ];
945        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
946    }
947
948    #[test]
949    fn test_tkip_group_data_cipher_tkip_pairwise_cipher() {
950        let a_rsne = Rsne {
951            group_data_cipher_suite: Some(CIPHER_TKIP),
952            pairwise_cipher_suites: vec![CIPHER_TKIP],
953            akm_suites: vec![AKM_PSK],
954            ..Default::default()
955        };
956        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
957
958        let s_rsne = a_rsne
959            .derive_wpa2_s_rsne(&fake_security_support_empty())
960            .expect("could not derive WPA2 Supplicant RSNE");
961        let expected_rsne_bytes = vec![
962            0x30, // element id, 48 expressed as hexadecimal value
963            0x12, // length in octets, 18 expressed as hexadecimal value
964            0x01, 0x00, // Version 1
965            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
966            0x01, 0x00, // pairwise cipher suite count
967            0x00, 0x0F, 0xAC, 0x02, // TKIP as pairwise cipher suite
968            0x01, 0x00, // authentication count
969            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
970        ];
971        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
972    }
973
974    #[test]
975    fn test_tkip_group_data_cipher_prefer_ccmp_128_pairwise_cipher() {
976        let a_rsne = Rsne {
977            group_data_cipher_suite: Some(CIPHER_TKIP),
978            pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
979            akm_suites: vec![AKM_PSK],
980            ..Default::default()
981        };
982        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
983
984        let s_rsne = a_rsne
985            .derive_wpa2_s_rsne(&fake_security_support_empty())
986            .expect("could not derive WPA2 Supplicant RSNE");
987        let expected_rsne_bytes = vec![
988            0x30, // element id, 48 expressed as hexadecimal value
989            0x12, // length in octets, 18 expressed as hexadecimal value
990            0x01, 0x00, // Version 1
991            0x00, 0x0F, 0xac, 0x02, // TKIP as group data cipher suite
992            0x01, 0x00, // pairwise cipher suite count
993            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
994            0x01, 0x00, // authentication count
995            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
996        ];
997        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
998    }
999
1000    #[test]
1001    fn test_ccmp_128_group_data_cipher_prefer_ccmp_128_pairwise_cipher() {
1002        let a_rsne = Rsne {
1003            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1004            pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
1005            akm_suites: vec![AKM_PSK],
1006            ..Default::default()
1007        };
1008        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1009
1010        let s_rsne = a_rsne
1011            .derive_wpa2_s_rsne(&fake_security_support_empty())
1012            .expect("could not derive WPA2 Supplicant RSNE");
1013        let expected_rsne_bytes = vec![
1014            0x30, // element id, 48 expressed as hexadecimal value
1015            0x12, // length in octets, 18 expressed as hexadecimal value
1016            0x01, 0x00, // Version 1
1017            0x00, 0x0F, 0xac, 0x04, // CCMP-128 as group data cipher suite
1018            0x01, 0x00, // pairwise cipher suite count
1019            0x00, 0x0F, 0xAC, 0x04, // CCMP-128 as pairwise cipher suite
1020            0x01, 0x00, // authentication count
1021            0x00, 0x0F, 0xAC, 0x02, // PSK authentication
1022        ];
1023        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1024    }
1025
1026    #[test]
1027    fn test_compatible_pairwise_cipher() {
1028        let rsne = Rsne {
1029            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1030            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1031            akm_suites: vec![AKM_PSK],
1032            ..Default::default()
1033        };
1034        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1035
1036        let rsne = Rsne {
1037            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1038            pairwise_cipher_suites: vec![CIPHER_TKIP],
1039            akm_suites: vec![AKM_PSK],
1040            ..Default::default()
1041        };
1042        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1043    }
1044
1045    #[test]
1046    fn test_incompatible_pairwise_cipher() {
1047        let rsne = Rsne {
1048            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1049            pairwise_cipher_suites: vec![CIPHER_BIP_CMAC_256],
1050            akm_suites: vec![AKM_PSK],
1051            ..Default::default()
1052        };
1053        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1054    }
1055
1056    #[test]
1057    fn test_no_pairwise_cipher() {
1058        let rsne = Rsne {
1059            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1060            akm_suites: vec![AKM_PSK],
1061            ..Default::default()
1062        };
1063        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1064
1065        let rsne = Rsne {
1066            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1067            akm_suites: vec![AKM_SAE],
1068            ..Default::default()
1069        };
1070        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1071    }
1072
1073    #[test]
1074    fn test_rsne_unsupported_pairwise_cipher() {
1075        let s_rsne = Rsne::wpa2_rsne();
1076        let mut a_rsne = Rsne::wpa2_rsne();
1077        a_rsne.pairwise_cipher_suites = vec![CIPHER_BIP_CMAC_256];
1078        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1079    }
1080
1081    #[test]
1082    fn test_incompatible_akm() {
1083        let rsne = Rsne {
1084            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1085            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1086            akm_suites: vec![AKM_EAP],
1087            ..Default::default()
1088        };
1089        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1090        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1091
1092        let rsne = Rsne {
1093            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1094            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1095            akm_suites: vec![AKM_PSK],
1096            ..Default::default()
1097        };
1098        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1099
1100        let rsne = Rsne {
1101            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1102            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1103            akm_suites: vec![AKM_SAE],
1104            ..Default::default()
1105        };
1106        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1107    }
1108
1109    #[test]
1110    fn test_no_akm() {
1111        let rsne = Rsne {
1112            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1113            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1114            ..Default::default()
1115        };
1116        assert_eq!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), false);
1117        assert_eq!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), false);
1118    }
1119
1120    #[test]
1121    fn test_rsne_unsupported_akm() {
1122        let s_rsne = Rsne::wpa2_rsne();
1123        let mut a_rsne = Rsne::wpa2_rsne();
1124        a_rsne.akm_suites = vec![AKM_EAP];
1125        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1126    }
1127
1128    #[test]
1129    fn test_ensure_valid_s_rsne() {
1130        let s_rsne = Rsne::wpa2_rsne();
1131        let result = s_rsne.ensure_valid_s_rsne();
1132        assert!(result.is_ok());
1133
1134        let mut s_rsne = Rsne::wpa2_rsne();
1135        s_rsne.group_data_cipher_suite = None;
1136        let result = s_rsne.ensure_valid_s_rsne();
1137        assert!(result.is_err());
1138        assert_eq!(result.unwrap_err(), Error::NoGroupDataCipherSuite);
1139
1140        let mut s_rsne = Rsne::wpa2_rsne();
1141        s_rsne.pairwise_cipher_suites = vec![];
1142        let result = s_rsne.ensure_valid_s_rsne();
1143        assert!(result.is_err());
1144        assert_eq!(result.unwrap_err(), Error::NoPairwiseCipherSuite);
1145
1146        let mut s_rsne = Rsne::wpa2_rsne();
1147        s_rsne.pairwise_cipher_suites.push(CIPHER_GCMP_256);
1148        let result = s_rsne.ensure_valid_s_rsne();
1149        assert!(result.is_err());
1150        assert_eq!(result.unwrap_err(), Error::TooManyPairwiseCipherSuites);
1151
1152        let mut s_rsne = Rsne::wpa2_rsne();
1153        s_rsne.akm_suites = vec![];
1154        let result = s_rsne.ensure_valid_s_rsne();
1155        assert!(result.is_err());
1156        assert_eq!(result.unwrap_err(), Error::NoAkmSuite);
1157
1158        let mut s_rsne = Rsne::wpa2_rsne();
1159        s_rsne.akm_suites.push(AKM_EAP);
1160        let result = s_rsne.ensure_valid_s_rsne();
1161        assert!(result.is_err());
1162        assert_eq!(result.unwrap_err(), Error::TooManyAkmSuites);
1163
1164        let mut s_rsne = Rsne::wpa2_rsne();
1165        s_rsne.akm_suites = vec![akm::Akm::new_dot11(200)];
1166        let result = s_rsne.ensure_valid_s_rsne();
1167        assert!(result.is_err());
1168        assert_eq!(result.unwrap_err(), Error::NoAkmMicBytes);
1169    }
1170
1171    #[test]
1172    fn test_compatible_wpa2_rsne() {
1173        let rsne = Rsne::wpa2_rsne();
1174        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1175    }
1176
1177    #[test]
1178    fn test_compatible_wpa2_wpa3_rsne() {
1179        let rsne = Rsne::wpa2_wpa3_rsne();
1180        assert!(rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()));
1181        assert!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY));
1182    }
1183
1184    #[test]
1185    fn test_compatible_wpa3_rsne() {
1186        let rsne = Rsne::wpa3_rsne();
1187        assert!(rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY));
1188    }
1189
1190    #[test]
1191    fn test_incompatible_wpa3_rsne_no_mfp() {
1192        let rsne = Rsne::wpa3_rsne();
1193        assert!(!rsne.is_wpa3_rsn_compatible(&fake_security_support_empty()));
1194    }
1195
1196    #[test]
1197    fn test_ccmp128_group_data_pairwise_cipher_psk() {
1198        let a_rsne = Rsne {
1199            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1200            pairwise_cipher_suites: vec![CIPHER_CCMP_128],
1201            akm_suites: vec![AKM_PSK],
1202            ..Default::default()
1203        };
1204        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1205
1206        let s_rsne = a_rsne
1207            .derive_wpa2_s_rsne(&fake_security_support_empty())
1208            .expect("could not derive WPA2 Supplicant RSNE");
1209        let expected_rsne_bytes =
1210            vec![48, 18, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2];
1211        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1212    }
1213
1214    #[test]
1215    fn test_valid_rsne() {
1216        let s_rsne = Rsne::wpa2_rsne();
1217        let a_rsne = Rsne::wpa2_rsne();
1218        assert!(s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1219    }
1220
1221    #[test]
1222    fn test_ccmp_tkip_mode() {
1223        let a_rsne = Rsne {
1224            group_data_cipher_suite: Some(CIPHER_CCMP_128),
1225            pairwise_cipher_suites: vec![CIPHER_CCMP_128, CIPHER_TKIP],
1226            akm_suites: vec![AKM_PSK, AKM_FT_PSK],
1227            ..Default::default()
1228        };
1229        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1230
1231        let s_rsne = a_rsne
1232            .derive_wpa2_s_rsne(&fake_security_support_empty())
1233            .expect("could not derive WPA2 Supplicant RSNE");
1234        let expected_rsne_bytes =
1235            vec![48, 18, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2];
1236        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1237    }
1238
1239    #[test]
1240    fn test_ccmp128_group_data_pairwise_cipher_sae() {
1241        let a_rsne = Rsne::wpa3_rsne();
1242        assert_eq!(a_rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), true);
1243
1244        let s_rsne = a_rsne
1245            .derive_wpa3_s_rsne(&MFP_SUPPORT_ONLY)
1246            .expect("could not derive WPA2 Supplicant RSNE");
1247        let expected_rsne_bytes =
1248            vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 8, 192, 0];
1249        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1250    }
1251
1252    #[test]
1253    fn test_wpa3_transition_mode() {
1254        let a_rsne = Rsne::wpa2_wpa3_rsne();
1255        assert_eq!(a_rsne.is_wpa2_rsn_compatible(&fake_security_support_empty()), true);
1256        assert_eq!(a_rsne.is_wpa3_rsn_compatible(&fake_security_support_empty()), false);
1257        assert_eq!(a_rsne.is_wpa3_rsn_compatible(&MFP_SUPPORT_ONLY), true);
1258
1259        let s_rsne = a_rsne
1260            .derive_wpa2_s_rsne(&MFP_SUPPORT_ONLY)
1261            .expect("could not derive WPA2 Supplicant RSNE");
1262        let expected_rsne_bytes =
1263            vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 2, 192, 0];
1264        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1265
1266        let s_rsne = a_rsne
1267            .derive_wpa3_s_rsne(&MFP_SUPPORT_ONLY)
1268            .expect("could not derive WPA3 Supplicant RSNE");
1269        let expected_rsne_bytes =
1270            vec![48, 20, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 4, 1, 0, 0, 15, 172, 8, 192, 0];
1271        assert_eq!(s_rsne.into_bytes(), expected_rsne_bytes);
1272    }
1273
1274    #[test]
1275    fn test_wpa2_psk_rsne_bytes() {
1276        // Compliant with IEEE Std 802.11-2016, 9.4.2.25.
1277        let expected: Vec<u8> = vec![
1278            0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
1279            0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00,
1280        ];
1281        let rsne = Rsne::wpa2_rsne_with_caps(RsnCapabilities(0));
1282        let mut actual = Vec::with_capacity(rsne.len());
1283        rsne.write_into(&mut actual).expect("error writing RSNE");
1284
1285        assert_eq!(&expected[..], &actual[..]);
1286    }
1287
1288    #[test]
1289    fn test_supplicant_missing_required_mpfc() {
1290        let s_rsne = Rsne::wpa2_rsne();
1291        let a_rsne = Rsne::wpa2_rsne_with_caps(
1292            RsnCapabilities(0)
1293                .with_mgmt_frame_protection_req(true)
1294                .with_mgmt_frame_protection_cap(true),
1295        );
1296        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1297    }
1298
1299    #[test]
1300    fn test_authenticator_missing_required_mpfc() {
1301        let s_rsne = Rsne::wpa2_rsne_with_caps(
1302            RsnCapabilities(0)
1303                .with_mgmt_frame_protection_req(true)
1304                .with_mgmt_frame_protection_cap(true),
1305        );
1306        let a_rsne = Rsne::wpa2_rsne();
1307        assert!(!s_rsne.is_valid_subset_of(&a_rsne).expect("expect Ok result"));
1308    }
1309
1310    #[test]
1311    fn test_supplicant_has_invalid_mgmt_frame_protection_fields() {
1312        let s_rsne = Rsne::wpa2_rsne_with_caps(
1313            RsnCapabilities(0)
1314                .with_mgmt_frame_protection_req(true)
1315                .with_mgmt_frame_protection_cap(false),
1316        );
1317        // AP only cares about client's invalid setting if AP is mgmt frame protection capable
1318        let a_rsne =
1319            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
1320
1321        let result = s_rsne.is_valid_subset_of(&a_rsne);
1322        assert!(result.is_err());
1323        assert_eq!(result.unwrap_err(), Error::InvalidSupplicantMgmtFrameProtection);
1324    }
1325
1326    #[test]
1327    fn test_authenticator_has_invalid_mgmt_frame_protection_fields() {
1328        // client only cares about AP's invalid setting if client is mgmt frame protection capable
1329        let s_rsne =
1330            Rsne::wpa2_rsne_with_caps(RsnCapabilities(0).with_mgmt_frame_protection_cap(true));
1331        let a_rsne = Rsne::wpa2_rsne_with_caps(
1332            RsnCapabilities(0)
1333                .with_mgmt_frame_protection_req(true)
1334                .with_mgmt_frame_protection_cap(false),
1335        );
1336
1337        let result = s_rsne.is_valid_subset_of(&a_rsne);
1338        assert!(result.is_err());
1339        assert_eq!(result.unwrap_err(), Error::InvalidAuthenticatorMgmtFrameProtection);
1340    }
1341
1342    #[test]
1343    fn test_write_until_version() {
1344        let expected_frame: Vec<u8> = vec![
1345            0x30, // element id
1346            0x02, // length
1347            0x01, 0x00, // version
1348        ];
1349        let buf = Rsne { version: VERSION, ..Default::default() }.into_bytes();
1350        assert_eq!(&buf[..], &expected_frame[..]);
1351    }
1352
1353    #[test]
1354    fn test_write_until_group_data() {
1355        let expected_frame: Vec<u8> = vec![
1356            0x30, // element id
1357            0x06, // length
1358            0x01, 0x00, // version
1359            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1360        ];
1361        let buf = Rsne {
1362            version: VERSION,
1363            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1364            ..Default::default()
1365        }
1366        .into_bytes();
1367        assert_eq!(&buf[..], &expected_frame[..]);
1368    }
1369
1370    #[test]
1371    fn test_write_until_pairwise() {
1372        let expected_frame: Vec<u8> = vec![
1373            0x30, // element id
1374            12,   // length
1375            0x01, 0x00, // version
1376            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1377            0x01, 0x00, // pairwise suite count
1378            0x00, 0x0f, 0xac, 0x04, // pairwise cipher suite
1379        ];
1380        let buf = Rsne {
1381            version: VERSION,
1382            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1383            pairwise_cipher_suites: vec![cipher::Cipher::new_dot11(cipher::CCMP_128)],
1384            ..Default::default()
1385        }
1386        .into_bytes();
1387        assert_eq!(&buf[..], &expected_frame[..]);
1388    }
1389
1390    #[test]
1391    fn test_write_until_akm() {
1392        let expected_frame: Vec<u8> = vec![
1393            0x30, // element id
1394            14,   // length
1395            0x01, 0x00, // version
1396            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1397            0x00, 0x00, // pairwise suite count
1398            0x01, 0x00, // pairwise suite count
1399            0x00, 0x0f, 0xac, 0x02, // pairwise cipher suite
1400        ];
1401        let buf = Rsne {
1402            version: VERSION,
1403            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1404            akm_suites: vec![akm::Akm::new_dot11(akm::PSK)],
1405            ..Default::default()
1406        }
1407        .into_bytes();
1408        assert_eq!(&buf[..], &expected_frame[..]);
1409    }
1410
1411    #[test]
1412    fn test_write_until_rsn_capabilities() {
1413        let expected_frame: Vec<u8> = vec![
1414            0x30, // element id
1415            12,   // length
1416            0x01, 0x00, // version
1417            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1418            0x00, 0x00, // pairwise suite count
1419            0x00, 0x00, // akm suite count
1420            0xcd, 0xab, // rsn capabilities
1421        ];
1422        let buf = Rsne {
1423            version: VERSION,
1424            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1425            rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1426            ..Default::default()
1427        }
1428        .into_bytes();
1429        assert_eq!(&buf[..], &expected_frame[..]);
1430    }
1431
1432    static PMKID_VAL: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
1433
1434    #[test]
1435    fn test_write_until_pmkids() {
1436        let expected_frame: Vec<u8> = vec![
1437            0x30, // element id
1438            30,   // length
1439            0x01, 0x00, // version
1440            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1441            0x00, 0x00, // pairwise suite count
1442            0x00, 0x00, // akm suite count
1443            0xcd, 0xab, // rsn capabilities
1444            0x01, 0x00, // pmkid count
1445            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, // pmkid
1446        ];
1447        let buf = Rsne {
1448            version: VERSION,
1449            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1450            rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1451            pmkids: vec![Bytes::from_static(&PMKID_VAL[..])],
1452            ..Default::default()
1453        }
1454        .into_bytes();
1455        assert_eq!(&buf[..], &expected_frame[..]);
1456    }
1457
1458    #[test]
1459    fn test_write_until_group_mgmt() {
1460        let expected_frame: Vec<u8> = vec![
1461            0x30, // element id
1462            18,   // length
1463            0x01, 0x00, // version
1464            0x00, 0x0f, 0xac, 0x04, // group data cipher suite
1465            0x00, 0x00, // pairwise suite count
1466            0x00, 0x00, // akm suite count
1467            0xcd, 0xab, // rsn capabilities
1468            0x00, 0x00, // pmkids count
1469            0x00, 0x0f, 0xac, 0x06, // group management cipher suite
1470        ];
1471        let buf = Rsne {
1472            version: VERSION,
1473            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1474            rsn_capabilities: Some(RsnCapabilities(0xabcd)),
1475            group_mgmt_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::BIP_CMAC_128)),
1476            ..Default::default()
1477        }
1478        .into_bytes();
1479        assert_eq!(&buf[..], &expected_frame[..]);
1480    }
1481
1482    #[test]
1483    fn test_end_write_on_missing_caps() {
1484        let expected_frame: Vec<u8> = vec![
1485            0x30, // element id
1486            0x06, // length
1487            0x01, 0x00, // version
1488            0x00, 0x0f, 0xac,
1489            0x04, // group data cipher suite
1490                  // We don't write group management suite because caps are missing.
1491        ];
1492        let buf = Rsne {
1493            version: VERSION,
1494            group_data_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::CCMP_128)),
1495            rsn_capabilities: None,
1496            group_mgmt_cipher_suite: Some(cipher::Cipher::new_dot11(cipher::BIP_CMAC_128)),
1497            ..Default::default()
1498        }
1499        .into_bytes();
1500        assert_eq!(&buf[..], &expected_frame[..]);
1501    }
1502}