Skip to main content

wlan_rsn/rsna/
esssa.rs

1// Copyright 2021 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 crate::Error;
6use crate::key::exchange::handshake::fourway::Fourway;
7use crate::key::exchange::handshake::group_key::GroupKey;
8use crate::key::exchange::{self, Key};
9use crate::key::gtk::Gtk;
10use crate::key::igtk::Igtk;
11use crate::key::ptk::Ptk;
12use crate::rsna::{
13    Dot11VerifiedKeyFrame, NegotiatedProtection, Role, SecAssocStatus, SecAssocUpdate, UpdateSink,
14};
15use fidl_fuchsia_wlan_mlme::EapolResultCode;
16use log::{error, info};
17use std::collections::HashSet;
18use wlan_statemachine::StateMachine;
19
20use zerocopy::SplitByteSlice;
21
22const MAX_KEY_FRAME_RETRIES: u32 = 3;
23
24#[derive(Debug)]
25enum Pmksa {
26    Initialized { pmk: Option<Vec<u8>> },
27    Established { pmk: Vec<u8> },
28}
29
30impl Pmksa {
31    fn reset(self) -> Self {
32        match self {
33            Pmksa::Established { pmk } | Pmksa::Initialized { pmk: Some(pmk) } => {
34                Pmksa::Initialized { pmk: Some(pmk) }
35            }
36            _ => Pmksa::Initialized { pmk: None },
37        }
38    }
39}
40
41#[derive(Debug, PartialEq)]
42enum Ptksa {
43    Uninitialized { cfg: exchange::Config },
44    Initialized { method: exchange::Method },
45    Established { method: exchange::Method, ptk: Ptk },
46}
47
48impl Ptksa {
49    fn initialize(self, pmk: Vec<u8>) -> Self {
50        match self {
51            Ptksa::Uninitialized { cfg } => match cfg {
52                exchange::Config::FourWayHandshake(method_cfg) => {
53                    match Fourway::new(method_cfg.clone(), pmk) {
54                        Err(e) => {
55                            error!("error creating 4-Way Handshake from config: {}", e);
56                            Ptksa::Uninitialized {
57                                cfg: exchange::Config::FourWayHandshake(method_cfg),
58                            }
59                        }
60                        Ok(method) => Ptksa::Initialized {
61                            method: exchange::Method::FourWayHandshake(Box::new(method)),
62                        },
63                    }
64                }
65                _ => {
66                    panic!("unsupported method for PTKSA: {:?}", cfg);
67                }
68            },
69            other => other,
70        }
71    }
72
73    fn reset(self) -> Self {
74        match self {
75            Ptksa::Uninitialized { cfg } => Ptksa::Uninitialized { cfg },
76            Ptksa::Initialized { method } | Ptksa::Established { method, .. } => {
77                Ptksa::Uninitialized { cfg: method.destroy() }
78            }
79        }
80    }
81}
82
83/// A GTKSA is composed of a GTK and a key exchange method.
84/// While a key is required for successfully establishing a GTKSA, the key exchange method is
85/// optional as it's used only for re-keying the GTK.
86#[derive(Debug, PartialEq)]
87enum Gtksa {
88    Uninitialized {
89        cfg: Option<exchange::Config>,
90    },
91    Initialized {
92        method: Option<exchange::Method>,
93    },
94    Established {
95        method: Option<exchange::Method>,
96        // A key history of previously installed group keys.
97        // Keys which have been previously installed must never be re-installed.
98        installed_gtks: HashSet<Gtk>,
99    },
100}
101
102impl Gtksa {
103    fn initialize(self, kck: &[u8], kek: &[u8]) -> Self {
104        match self {
105            Gtksa::Uninitialized { cfg } => match cfg {
106                None => Gtksa::Initialized { method: None },
107                Some(exchange::Config::GroupKeyHandshake(method_cfg)) => {
108                    match GroupKey::new(method_cfg.clone(), kck, kek) {
109                        Err(e) => {
110                            error!("error creating Group KeyHandshake from config: {}", e);
111                            Gtksa::Uninitialized {
112                                cfg: Some(exchange::Config::GroupKeyHandshake(method_cfg)),
113                            }
114                        }
115                        Ok(method) => Gtksa::Initialized {
116                            method: Some(exchange::Method::GroupKeyHandshake(method)),
117                        },
118                    }
119                }
120                _ => {
121                    panic!("unsupported method for GTKSA: {:?}", cfg);
122                }
123            },
124            other => other,
125        }
126    }
127
128    fn reset(self) -> Self {
129        match self {
130            Gtksa::Uninitialized { cfg } => Gtksa::Uninitialized { cfg },
131            Gtksa::Initialized { method } | Gtksa::Established { method, .. } => {
132                Gtksa::Uninitialized { cfg: method.map(|m| m.destroy()) }
133            }
134        }
135    }
136}
137
138/// Igtksa is super simple because there's currently no method for populating it other than an adjacent Gtksa.
139#[derive(Debug)]
140enum Igtksa {
141    Uninitialized,
142    Established { installed_igtks: HashSet<Igtk> },
143}
144
145impl Igtksa {
146    fn reset(self) -> Self {
147        Igtksa::Uninitialized
148    }
149}
150
151/// An ESS Security Association is composed of three security associations, namely, PMKSA, PTKSA and
152/// GTKSA. The individual security associations have dependencies on each other. For example, the
153/// PMKSA must be established first as it yields the PMK used in the PTK and GTK key hierarchy.
154/// Depending on the selected PTKSA, it can yield not just the PTK but also GTK, and thus leaving
155/// the GTKSA's key exchange method only useful for re-keying.
156///
157/// Each association should spawn one ESSSA instance only.
158/// The security association correctly tracks and handles replays for robustness and
159/// prevents key re-installation to mitigate attacks such as described in KRACK.
160#[derive(Debug)]
161pub(crate) struct EssSa {
162    // Determines the device's role (Supplicant or Authenticator).
163    role: Role,
164    // The protection used for this association.
165    pub negotiated_protection: NegotiatedProtection,
166    // The last valid key replay counter. Messages with a key replay counter lower than this counter
167    // value will be dropped.
168    key_replay_counter: u64,
169    // A retry counter and key frame to resend if a timeout is received while waiting for a response.
170    last_key_frame_buf: Option<(u32, eapol::KeyFrameBuf)>,
171    // Updates to send after we receive an eapol send confirmation. This will contain an empty update
172    // sink if we're awaiting a confirm but do not have any subsequent updates to send.
173    updates_awaiting_confirm: Option<UpdateSink>,
174
175    // Individual Security Associations.
176    pmksa: StateMachine<Pmksa>,
177    ptksa: StateMachine<Ptksa>,
178    gtksa: StateMachine<Gtksa>,
179    igtksa: StateMachine<Igtksa>,
180}
181
182// IEEE Std 802.11-2016, 12.6.1.3.2
183impl EssSa {
184    pub fn new(
185        role: Role,
186        pmk: Option<Vec<u8>>,
187        negotiated_protection: NegotiatedProtection,
188        ptk_exch_cfg: exchange::Config,
189        gtk_exch_cfg: Option<exchange::Config>,
190    ) -> Result<EssSa, anyhow::Error> {
191        info!("spawned ESSSA for: {:?}", role);
192
193        let rsna = EssSa {
194            role,
195            negotiated_protection,
196            key_replay_counter: 0,
197            last_key_frame_buf: None,
198            updates_awaiting_confirm: None,
199            pmksa: StateMachine::new(Pmksa::Initialized { pmk }),
200            ptksa: StateMachine::new(Ptksa::Uninitialized { cfg: ptk_exch_cfg }),
201            gtksa: StateMachine::new(Gtksa::Uninitialized { cfg: gtk_exch_cfg }),
202            igtksa: StateMachine::new(Igtksa::Uninitialized),
203        };
204        Ok(rsna)
205    }
206
207    #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
208    /// This function will not succeed unless called on a new Esssa or one that was reset.
209    pub fn initiate(&mut self, update_sink: &mut UpdateSink) -> Result<(), Error> {
210        // TODO(https://fxbug.dev/42148516): Ptksa starts in Initialized when the EssSa
211        // computes the PMKSA from a PSK. When an EssSa is not initialized with a PSK,
212        // Ptksa start in Uninitialized since the PMKSA cannot be computed. For example,
213        // when using SAE for authentication, Ptksa starts in Uninitialized.
214        match (self.ptksa.as_ref(), self.gtksa.as_ref(), self.igtksa.as_ref()) {
215            (Ptksa::Uninitialized { .. }, Gtksa::Uninitialized { .. }, Igtksa::Uninitialized) => (),
216
217            (Ptksa::Initialized { .. }, Gtksa::Uninitialized { .. }, Igtksa::Uninitialized) => (),
218            _ => return Err(Error::UnexpectedEsssaInitiation),
219        };
220        info!("establishing ESSSA...");
221
222        // Immediately establish the PMKSA if the key is available. The PMK may be provided
223        // during ESSSA construction, or generated by a subsequent auth handshake such as SAE.
224        let pmk = match self.pmksa.as_ref() {
225            Pmksa::Initialized { pmk: Some(pmk) } => Some(pmk.clone()),
226            _ => None,
227        };
228        if let Some(pmk) = pmk { self.on_pmk_available(update_sink, pmk) } else { Ok(()) }
229    }
230
231    pub fn reset_replay_counter(&mut self) {
232        info!("resetting ESSSA replay counter");
233        self.key_replay_counter = 0;
234    }
235
236    pub fn reset_security_associations(&mut self) {
237        info!("resetting ESSSA security associations");
238        self.pmksa.replace_state(|state| state.reset());
239        self.ptksa.replace_state(|state| state.reset());
240        self.gtksa.replace_state(|state| state.reset());
241        self.igtksa.replace_state(|state| state.reset());
242    }
243
244    fn is_established(&self) -> bool {
245        match (self.ptksa.as_ref(), self.gtksa.as_ref()) {
246            (Ptksa::Established { .. }, Gtksa::Established { .. }) => true,
247            _ => false,
248        }
249    }
250
251    #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
252    fn on_key_confirmed(&mut self, update_sink: &mut UpdateSink, key: Key) -> Result<(), Error> {
253        let was_esssa_established = self.is_established();
254        match key {
255            Key::Pmk(pmk) => {
256                self.pmksa.replace_state(|state| match state {
257                    Pmksa::Initialized { .. } => {
258                        info!("established PMKSA");
259                        update_sink.push(SecAssocUpdate::Status(SecAssocStatus::PmkSaEstablished));
260                        Pmksa::Established { pmk: pmk.clone() }
261                    }
262                    other => {
263                        error!("received PMK with PMK already being established");
264                        other
265                    }
266                });
267
268                self.ptksa.replace_state(|state| state.initialize(pmk));
269                if let Ptksa::Initialized { method: exchange::Method::FourWayHandshake(hs) } =
270                    self.ptksa.as_mut()
271                {
272                    if let Fourway::Authenticator(authenticator_state_machine) = &mut **hs {
273                        authenticator_state_machine
274                            .try_replace_state(|state| {
275                                state.initiate(update_sink, self.key_replay_counter.into())
276                            })
277                            // Discard the mutable reference to the state machine since
278                            // this scope already has one.
279                            .map(|_state_machine| ())?;
280                    }
281                }
282            }
283            Key::Ptk(ptk) => {
284                // The PTK carries KEK and KCK which is used in the Group Key Handshake, thus,
285                // reset GTKSA whenever the PTK changed.
286                self.gtksa.replace_state(|state| state.reset().initialize(ptk.kck(), ptk.kek()));
287
288                self.ptksa.replace_state(|state| match state {
289                    Ptksa::Initialized { method } => {
290                        info!("established PTKSA");
291                        update_sink.push(SecAssocUpdate::Key(Key::Ptk(ptk.clone())));
292                        Ptksa::Established { method, ptk }
293                    }
294                    Ptksa::Established { method, .. } => {
295                        // PTK was already initialized.
296                        info!("re-established new PTKSA; invalidating previous one");
297                        info!("(this is likely a result of using a wrong password)");
298                        // Key can be re-established in two cases:
299                        // 1. Message gets replayed
300                        // 2. Key is being rotated
301                        // Checking that ESSSA is already established eliminates the first case.
302                        if was_esssa_established {
303                            update_sink.push(SecAssocUpdate::Key(Key::Ptk(ptk.clone())));
304                        }
305                        Ptksa::Established { method, ptk }
306                    }
307                    other @ Ptksa::Uninitialized { .. } => {
308                        error!("received PTK in unexpected PTKSA state");
309                        other
310                    }
311                });
312            }
313            Key::Gtk(gtk) => {
314                self.gtksa.replace_state(|state| match state {
315                    Gtksa::Initialized { method } => {
316                        info!("established GTKSA");
317
318                        let mut installed_gtks = HashSet::default();
319                        installed_gtks.insert(gtk.clone());
320                        update_sink.push(SecAssocUpdate::Key(Key::Gtk(gtk)));
321                        Gtksa::Established { method, installed_gtks }
322                    }
323                    Gtksa::Established { method, mut installed_gtks } => {
324                        info!("re-established new GTKSA; invalidating previous one");
325
326                        if !installed_gtks.contains(&gtk) {
327                            installed_gtks.insert(gtk.clone());
328                            update_sink.push(SecAssocUpdate::Key(Key::Gtk(gtk)));
329                        }
330                        Gtksa::Established { method, installed_gtks }
331                    }
332                    Gtksa::Uninitialized { cfg } => {
333                        error!("received GTK in unexpected GTKSA state");
334                        Gtksa::Uninitialized { cfg }
335                    }
336                });
337            }
338            Key::Igtk(igtk) => {
339                self.igtksa.replace_state(|state| match state {
340                    Igtksa::Uninitialized => {
341                        info!("established IGTKSA");
342                        let mut installed_igtks = HashSet::default();
343                        installed_igtks.insert(igtk.clone());
344                        update_sink.push(SecAssocUpdate::Key(Key::Igtk(igtk)));
345                        Igtksa::Established { installed_igtks }
346                    }
347                    Igtksa::Established { mut installed_igtks } => {
348                        info!("re-established new IGTKSA; invalidating previous one");
349
350                        if !installed_igtks.contains(&igtk) {
351                            installed_igtks.insert(igtk.clone());
352                            update_sink.push(SecAssocUpdate::Key(Key::Igtk(igtk)));
353                        }
354                        Igtksa::Established { installed_igtks }
355                    }
356                });
357            }
358            _ => {}
359        };
360        Ok(())
361    }
362
363    #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
364    pub fn on_pmk_available(
365        &mut self,
366        update_sink: &mut UpdateSink,
367        pmk: Vec<u8>,
368    ) -> Result<(), Error> {
369        let mut new_updates = UpdateSink::default();
370        let result = self.on_key_confirmed(&mut new_updates, Key::Pmk(pmk));
371        self.push_updates(update_sink, new_updates);
372        result
373    }
374
375    // Do any necessary final processing before passing updates to the higher layer.
376    fn push_updates(&mut self, update_sink: &mut UpdateSink, mut new_updates: UpdateSink) {
377        if let Some(updates_awaiting_confirm) = &mut self.updates_awaiting_confirm {
378            // We're still waiting on a previous eapol confirm, and are not ready
379            // to do anything with these new updates. This can happen if we receive
380            // 4-way message 3 before we've received a confirm for message 2, in which
381            // case we defer all updates. We'll go through the logic below after we
382            // receive the expected confirm.
383            updates_awaiting_confirm.append(&mut new_updates);
384            return;
385        }
386        for update in new_updates {
387            if let SecAssocUpdate::Key(_) = update {
388                // Always install keys immediately to avoid race conditions after the eapol
389                // exchange completes. This is a particular issue for WPA1, where we may miss
390                // the first PTK-encrypted frame of the group key handshake.
391                // TODO(https://fxbug.dev/42051016): Preemptively requesting the key to be set before
392                //                         receiving eapol confirm may not be necessary.
393                update_sink.push(update);
394            } else if let Some(updates_awaiting_confirm) = &mut self.updates_awaiting_confirm {
395                // If we've sent an eapol frame, buffer all other non-key
396                // updates until we receive a confirm.
397                updates_awaiting_confirm.push(update);
398            } else {
399                if let SecAssocUpdate::TxEapolKeyFrame { frame, expect_response } = &update {
400                    if *expect_response {
401                        self.last_key_frame_buf = Some((1, frame.clone()));
402                    } else {
403                        // We don't expect a response, so we don't need to keep the frame around.
404                        self.last_key_frame_buf = None;
405                    }
406                    // Subsequent non-key updates should be buffered until this frame is confirmed.
407                    self.updates_awaiting_confirm.replace(Default::default());
408                }
409                update_sink.push(update);
410            }
411        }
412    }
413
414    #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
415    pub fn on_eapol_conf(
416        &mut self,
417        update_sink: &mut UpdateSink,
418        result: EapolResultCode,
419    ) -> Result<(), Error> {
420        match self.updates_awaiting_confirm.take() {
421            Some(updates) => match result {
422                EapolResultCode::Success => {
423                    // We successfully sent a frame. Now send the resulting ESSSA updates.
424                    self.push_updates(update_sink, updates);
425                    Ok(())
426                }
427                EapolResultCode::TransmissionFailure => Err(Error::KeyFrameTransmissionFailed),
428            },
429            None => {
430                error!("Ignored unexpected eapol send confirm");
431                Ok(())
432            }
433        }
434    }
435
436    #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
437    pub fn on_rsna_retransmission_timeout(
438        &mut self,
439        update_sink: &mut UpdateSink,
440    ) -> Result<(), Error> {
441        // IEEE Std 802.11-2016 6.3.22.2.4: We should always receive a confirm in response to an eapol tx.
442        // If we never received an eapol conf, treat this as a fatal error.
443        if let Some(updates) = &self.updates_awaiting_confirm {
444            return Err(Error::NoKeyFrameTransmissionConfirm(updates.len()));
445        }
446        // Resend the last key frame if appropriate
447        if let Some((attempt, key_frame)) = self.last_key_frame_buf.as_mut() {
448            *attempt += 1;
449            if *attempt > MAX_KEY_FRAME_RETRIES {
450                // Only retry a limited number of times before going idle
451                return Ok(());
452            }
453            update_sink.push(SecAssocUpdate::TxEapolKeyFrame {
454                frame: key_frame.clone(),
455                expect_response: true,
456            });
457            // Always expect a confirm for a keyframe retransmission.
458            self.updates_awaiting_confirm = Some(Default::default());
459        }
460        Ok(())
461    }
462
463    pub fn incomplete_reason(&self) -> Error {
464        if let Some(updates) = &self.updates_awaiting_confirm {
465            return Error::NoKeyFrameTransmissionConfirm(updates.len());
466        }
467        match self.ptksa.as_ref() {
468            Ptksa::Uninitialized { .. } => {
469                return Error::EapolHandshakeIncomplete("PTKSA never initialized".to_string());
470            }
471            Ptksa::Initialized { method } | Ptksa::Established { method, .. } => {
472                if let Err(error) = method.on_rsna_response_timeout() {
473                    return error;
474                }
475            }
476        }
477        if !matches!(self.gtksa.as_ref(), Gtksa::Established { .. }) {
478            return Error::EapolHandshakeIncomplete("GTKSA never established".to_string());
479        }
480
481        // Unclear how we'd get an establishing RSNA timeout without hitting any of
482        // the previous cases.
483        Error::EapolHandshakeIncomplete("Unexpected timeout while establishing RSNA".to_string())
484    }
485
486    #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
487    pub fn on_eapol_frame<B: SplitByteSlice>(
488        &mut self,
489        update_sink: &mut UpdateSink,
490        frame: eapol::Frame<B>,
491    ) -> Result<(), Error> {
492        // Only processes EAPOL Key frames. Drop all other frames silently.
493        let on_eapol_key_frame_updates = match frame {
494            eapol::Frame::Key(key_frame) => {
495                let mut on_eapol_key_frame_updates = UpdateSink::default();
496                self.on_eapol_key_frame(&mut on_eapol_key_frame_updates, key_frame)?;
497                // Frame received. Don't retransmit the last one.
498                self.last_key_frame_buf.take();
499
500                // Authenticator updates its key replay counter with every outbound EAPOL frame.
501                if let Role::Authenticator = self.role {
502                    for update in &on_eapol_key_frame_updates {
503                        if let SecAssocUpdate::TxEapolKeyFrame { frame, .. } = update {
504                            let key_replay_counter =
505                                frame.keyframe().key_frame_fields.key_replay_counter.get();
506
507                            if key_replay_counter <= self.key_replay_counter {
508                                error!(
509                                    "tx EAPOL Key frame uses invalid key replay counter: {:?} ({:?})",
510                                    key_replay_counter, self.key_replay_counter
511                                );
512                            }
513                            self.key_replay_counter = key_replay_counter;
514                        }
515                    }
516                }
517
518                on_eapol_key_frame_updates
519            }
520            _ => UpdateSink::default(),
521        };
522
523        // Check if ESSSA established before processing key updates.
524        let was_esssa_established = self.is_established();
525
526        // Process and filter Key updates internally to correctly track security associations.
527        let mut new_updates = UpdateSink::default();
528        for update in on_eapol_key_frame_updates {
529            match update {
530                SecAssocUpdate::Key(key) => {
531                    if let Err(e) = self.on_key_confirmed(&mut new_updates, key) {
532                        error!("error while processing key: {}", e);
533                    };
534                }
535                // Forward all other updates.
536                _ => new_updates.push(update),
537            }
538        }
539
540        // Report if this EAPOL frame established the ESSSA.
541        if !was_esssa_established && self.is_established() {
542            info!("established ESSSA");
543            new_updates.push(SecAssocUpdate::Status(SecAssocStatus::EssSaEstablished));
544        }
545
546        self.push_updates(update_sink, new_updates);
547        Ok(())
548    }
549
550    #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
551    fn on_eapol_key_frame<B: SplitByteSlice>(
552        &mut self,
553        update_sink: &mut UpdateSink,
554        frame: eapol::KeyFrameRx<B>,
555    ) -> Result<(), Error> {
556        // Verify the frame complies with IEEE Std 802.11-2016, 12.7.2.
557        let verified_frame = match Dot11VerifiedKeyFrame::from_frame(
558            frame,
559            &self.role,
560            &self.negotiated_protection,
561            self.key_replay_counter,
562        ) {
563            // An invalid key replay counter means we should skip the frame, but may happen under
564            // normal circumstances and should not be logged as an error.
565            Err(e @ Error::InvalidKeyReplayCounter(_, _)) => {
566                info!("Ignoring eapol frame: {}", e);
567                return Ok(());
568            }
569            result => result?,
570        };
571
572        // Safe: frame was just verified.
573        let raw_frame = verified_frame.unsafe_get_raw();
574        let frame_has_mic = raw_frame.key_frame_fields.key_info().key_mic();
575        let frame_key_replay_counter = raw_frame.key_frame_fields.key_replay_counter.get();
576
577        // Forward frame to correct security association.
578        // PMKSA must be established before any other security association can be established. Because
579        // the PMKSA is handled outside our ESSSA this is just an early return.
580        match self.pmksa.as_mut() {
581            Pmksa::Initialized { .. } => return Ok(()),
582            Pmksa::Established { .. } => {}
583        };
584
585        // Once PMKSA was established PTKSA and GTKSA can process frames.
586        // IEEE Std 802.11-2016, 12.7.2 b.2)
587        let result = if raw_frame.key_frame_fields.key_info().key_type() == eapol::KeyType::PAIRWISE
588        {
589            match self.ptksa.as_mut() {
590                Ptksa::Uninitialized { .. } => Ok(()),
591                Ptksa::Initialized { method } | Ptksa::Established { method, .. } => {
592                    method.on_eapol_key_frame(update_sink, verified_frame)
593                }
594            }
595        } else if raw_frame.key_frame_fields.key_info().key_type() == eapol::KeyType::GROUP_SMK {
596            match self.gtksa.as_mut() {
597                Gtksa::Uninitialized { .. } => Ok(()),
598                Gtksa::Initialized { method } | Gtksa::Established { method, .. } => match method {
599                    Some(method) => method.on_eapol_key_frame(update_sink, verified_frame),
600                    None => {
601                        error!("received group key EAPOL Key frame with GTK re-keying disabled");
602                        Ok(())
603                    }
604                },
605            }
606        } else {
607            error!(
608                "unsupported EAPOL Key frame key type: {:?}",
609                raw_frame.key_frame_fields.key_info().key_type()
610            );
611            Ok(())
612        };
613
614        // IEEE Std 802.11-2016, 12.7.2, d)
615        // Update key replay counter if MIC was set and is valid. Only applicable for Supplicant.
616        // Eapol key frame being TX'd implies that MIC is valid.
617        if frame_has_mic {
618            if let Role::Supplicant = self.role {
619                for update in update_sink {
620                    if let SecAssocUpdate::TxEapolKeyFrame { .. } = update {
621                        self.key_replay_counter = frame_key_replay_counter;
622                        break;
623                    }
624                }
625            }
626        }
627
628        result
629    }
630}
631
632#[cfg(test)]
633mod tests {
634    use super::*;
635    use crate::key::exchange::compute_mic;
636    use crate::rsna::test_util::expect_eapol_resp;
637    use crate::rsna::{AuthStatus, test_util};
638    use crate::{Authenticator, Supplicant};
639    use assert_matches::assert_matches;
640    use wlan_common::ie::get_rsn_ie_bytes;
641    use wlan_common::ie::rsn::fake_wpa2_s_rsne;
642    use zerocopy::byteorder::big_endian::U64;
643
644    const ANONCE: [u8; 32] = [0x1A; 32];
645    const GTK: [u8; 16] = [0x1B; 16];
646    const GTK_REKEY: [u8; 16] = [0x1F; 16];
647    const GTK_REKEY_2: [u8; 16] = [0x2F; 16];
648
649    #[test]
650    fn test_supplicant_with_wpa3_authenticator() {
651        let mut supplicant = test_util::get_wpa3_supplicant();
652        let mut authenticator = test_util::get_wpa3_authenticator();
653        let mut s_updates = vec![];
654        supplicant.start(&mut s_updates).expect("Failed starting Supplicant");
655        assert!(s_updates.is_empty(), "{:?}", s_updates);
656
657        // Send Supplicant SAE commit
658        let result = supplicant.on_sae_handshake_ind(&mut s_updates);
659        assert!(result.is_ok(), "Supplicant failed to ind SAE handshake");
660        let s_sae_frame_vec = test_util::expect_sae_frame_vec(&s_updates[..]);
661        test_util::expect_schedule_sae_timeout(&s_updates[..]);
662        assert_eq!(s_updates.len(), 2, "{:?}", s_updates);
663
664        // Respond to Supplicant SAE commit
665        let mut a_updates = vec![];
666        for s_sae_frame in s_sae_frame_vec {
667            let result = authenticator.on_sae_frame_rx(&mut a_updates, s_sae_frame);
668            assert!(result.is_ok(), "Authenticator failed to rx SAE handshake message");
669        }
670        let a_sae_frame_vec = test_util::expect_sae_frame_vec(&a_updates[..]);
671        test_util::expect_schedule_sae_timeout(&a_updates[..]);
672        assert_eq!(a_updates.len(), 3, "{:?}", a_updates);
673
674        // Receive Authenticator SAE confirm
675        let mut s_updates = vec![];
676        for a_sae_frame in a_sae_frame_vec {
677            let result = supplicant.on_sae_frame_rx(&mut s_updates, a_sae_frame);
678            assert!(result.is_ok(), "Supplicant failed to rx SAE handshake message");
679        }
680        let s_sae_frame_vec = test_util::expect_sae_frame_vec(&s_updates[..]);
681        test_util::expect_schedule_sae_timeout(&s_updates[..]);
682        test_util::expect_reported_pmk(&s_updates[..]);
683        test_util::expect_reported_sae_auth_status(&s_updates[..], AuthStatus::Success);
684        test_util::expect_reported_status(&s_updates[..], SecAssocStatus::PmkSaEstablished);
685        assert_eq!(s_updates.len(), 5, "{:?}", s_updates);
686
687        // Receive Supplicant SAE confirm
688        let mut a_updates = vec![];
689        for s_sae_frame in s_sae_frame_vec {
690            let result = authenticator.on_sae_frame_rx(&mut a_updates, s_sae_frame);
691            assert!(result.is_ok(), "Authenticator failed to rx SAE handshake message");
692        }
693        test_util::expect_reported_pmk(&a_updates[..]);
694        test_util::expect_reported_sae_auth_status(&a_updates[..], AuthStatus::Success);
695        test_util::expect_reported_status(&a_updates[..], SecAssocStatus::PmkSaEstablished);
696        let msg1 = test_util::expect_eapol_resp(&a_updates[..]);
697        authenticator
698            .on_eapol_conf(&mut a_updates, EapolResultCode::Success)
699            .expect("Failed eapol conf");
700        assert_eq!(a_updates.len(), 4, "{:?}", a_updates);
701
702        test_eapol_exchange(&mut supplicant, &mut authenticator, Some(msg1), true);
703    }
704
705    #[test]
706    fn test_supplicant_with_wpa2_authenticator() {
707        let mut supplicant = test_util::get_wpa2_supplicant();
708        let mut authenticator = test_util::get_wpa2_authenticator();
709        let mut updates = vec![];
710        supplicant.start(&mut updates).expect("Failed starting Supplicant");
711        assert_eq!(updates.len(), 1, "{:?}", updates);
712        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
713        test_eapol_exchange(&mut supplicant, &mut authenticator, None, false);
714    }
715
716    #[test]
717    fn test_replay_first_message() {
718        let mut supplicant = test_util::get_wpa2_supplicant();
719        let mut updates = vec![];
720        supplicant.start(&mut updates).expect("Failed starting Supplicant");
721        assert_eq!(updates.len(), 1, "{:?}", updates);
722        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
723
724        // Send first message of handshake.
725        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
726            msg1.key_frame_fields.key_replay_counter.set(1);
727        });
728        assert!(result.is_ok());
729        let first_msg2 = expect_eapol_resp(&updates[..]);
730        let first_fields = first_msg2.keyframe().key_frame_fields;
731
732        // Replay first message which should restart the entire handshake.
733        // Verify the second message of the handshake was received.
734        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
735            msg1.key_frame_fields.key_replay_counter = U64::new(3);
736        });
737        assert!(result.is_ok());
738        let second_msg2 = expect_eapol_resp(&updates[..]);
739        let second_fields = second_msg2.keyframe().key_frame_fields;
740
741        // Verify Supplicant responded to the replayed first message and didn't change SNonce.
742        assert_eq!(second_fields.key_replay_counter.get(), 3);
743        assert_eq!(first_fields.key_nonce, second_fields.key_nonce);
744    }
745
746    #[test]
747    fn test_first_message_does_not_change_replay_counter() {
748        let mut supplicant = test_util::get_wpa2_supplicant();
749        let mut updates = vec![];
750        supplicant.start(&mut updates).expect("Failed starting Supplicant");
751        assert_eq!(updates.len(), 1, "{:?}", updates);
752        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
753
754        assert_eq!(0, supplicant.esssa.key_replay_counter);
755
756        // Send first message of handshake.
757        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
758            msg1.key_frame_fields.key_replay_counter.set(0);
759        });
760        assert!(result.is_ok());
761        expect_eapol_resp(&updates[..]);
762        assert_eq!(0, supplicant.esssa.key_replay_counter);
763
764        // Raise the replay counter of message 1.
765        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
766            msg1.key_frame_fields.key_replay_counter.set(1);
767        });
768        assert!(result.is_ok());
769        expect_eapol_resp(&updates[..]);
770        assert_eq!(0, supplicant.esssa.key_replay_counter);
771
772        // Lower the replay counter of message 1.
773        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
774            msg1.key_frame_fields.key_replay_counter.set(0);
775        });
776        assert!(result.is_ok());
777        assert_eq!(0, supplicant.esssa.key_replay_counter);
778        expect_eapol_resp(&updates[..]);
779    }
780
781    #[test]
782    fn test_zero_key_replay_counter_msg1() {
783        let mut supplicant = test_util::get_wpa2_supplicant();
784        let mut updates = vec![];
785        supplicant.start(&mut updates).expect("Failed starting Supplicant");
786        assert_eq!(updates.len(), 1, "{:?}", updates);
787        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
788
789        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
790            msg1.key_frame_fields.key_replay_counter.set(0);
791        });
792        assert!(result.is_ok());
793        expect_eapol_resp(&updates[..]);
794    }
795
796    #[test]
797    fn test_nonzero_key_replay_counter_msg1() {
798        let mut supplicant = test_util::get_wpa2_supplicant();
799        let mut updates = vec![];
800        supplicant.start(&mut updates).expect("Failed starting Supplicant");
801        assert_eq!(updates.len(), 1, "{:?}", updates);
802        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
803
804        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
805            msg1.key_frame_fields.key_replay_counter.set(1);
806        });
807        assert!(result.is_ok());
808        expect_eapol_resp(&updates[..]);
809    }
810
811    #[test]
812    fn test_zero_key_replay_counter_lower_msg3_counter() {
813        let mut supplicant = test_util::get_wpa2_supplicant();
814        let mut updates = vec![];
815        supplicant.start(&mut updates).expect("Failed starting Supplicant");
816        assert_eq!(updates.len(), 1, "{:?}", updates);
817        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
818        assert_eq!(0, supplicant.esssa.key_replay_counter);
819
820        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
821            msg1.key_frame_fields.key_replay_counter.set(1);
822        });
823        assert!(result.is_ok());
824        assert_eq!(0, supplicant.esssa.key_replay_counter);
825
826        let msg2 = expect_eapol_resp(&updates[..]);
827        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
828        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
829
830        // Intuitively, this should not succeed because the replay
831        // counter in message 3 is lower than in message 1. It is a
832        // quirk of IEEE 802.11-2016 12.7.2 that the replay counter in
833        // message 1 is in fact meaningless because replay counters
834        // are only updated when there is a MIC to verify. There is no
835        // MIC to verify in message 1, and so the replay counter
836        // doesn't matter.
837        let (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
838            msg3.key_frame_fields.key_replay_counter = U64::new(0);
839        });
840        assert!(result.is_ok());
841        assert_eq!(0, supplicant.esssa.key_replay_counter);
842        test_util::expect_reported_ptk(&updates[..]);
843    }
844
845    #[test]
846    fn test_key_replay_counter_updated_after_msg3() {
847        let mut supplicant = test_util::get_wpa2_supplicant();
848        let mut updates = vec![];
849        let mut result;
850        supplicant.start(&mut updates).expect("Failed starting Supplicant");
851        assert_eq!(updates.len(), 1, "{:?}", updates);
852        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
853
854        (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
855            msg1.key_frame_fields.key_replay_counter.set(1);
856        });
857        assert!(result.is_ok());
858        let msg2 = expect_eapol_resp(&updates[..]);
859        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
860        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
861
862        (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
863            msg3.key_frame_fields.key_replay_counter = U64::new(5);
864        });
865        assert!(result.is_ok());
866        assert_eq!(5, supplicant.esssa.key_replay_counter);
867        test_util::expect_reported_ptk(&updates[..]);
868
869        // First message should be dropped if replay counter too low.
870        (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
871            msg1.key_frame_fields.key_replay_counter.set(0);
872        });
873        assert!(result.is_ok());
874        assert_eq!(5, supplicant.esssa.key_replay_counter);
875        assert!(updates.is_empty(), "{:?}", updates);
876
877        // After reset, first message should not be dropped.
878        supplicant.reset();
879        updates = vec![];
880        supplicant.start(&mut updates).expect("Failed starting Supplicant");
881        assert_eq!(updates.len(), 1, "{:?}", updates);
882        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
883        assert_eq!(0, supplicant.esssa.key_replay_counter);
884        let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
885            msg1.key_frame_fields.key_replay_counter.set(0);
886        });
887        assert!(result.is_ok());
888        expect_eapol_resp(&updates[..]);
889    }
890
891    #[test]
892    fn test_key_replay_counter_not_updated_for_invalid_mic_msg3() {
893        let mut supplicant = test_util::get_wpa2_supplicant();
894        let mut updates = vec![];
895        let mut result: Result<(), Error>;
896        supplicant.start(&mut updates).expect("Failed starting Supplicant");
897        assert_eq!(updates.len(), 1, "{:?}", updates);
898        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
899
900        (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
901            msg1.key_frame_fields.key_replay_counter.set(1);
902        });
903        assert!(result.is_ok());
904        assert_eq!(0, supplicant.esssa.key_replay_counter);
905
906        let msg2 = expect_eapol_resp(&updates[..]);
907        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
908        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
909
910        let msg3 = test_util::get_wpa2_4whs_msg3_with_mic_modifier(
911            &ptk,
912            &ANONCE[..],
913            &GTK,
914            |msg3| {
915                msg3.key_frame_fields.key_replay_counter = U64::new(5);
916            },
917            |mic| {
918                mic[0] = mic[0].wrapping_add(1);
919            },
920        );
921        updates = UpdateSink::default();
922        result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg3.keyframe()));
923        assert!(result.is_ok());
924        // The key replay counter should not be updated
925        assert_eq!(0, supplicant.esssa.key_replay_counter);
926    }
927
928    #[test]
929    fn test_zero_key_replay_counter_valid_msg3() {
930        let mut supplicant = test_util::get_wpa2_supplicant();
931        let mut updates = vec![];
932        let mut result;
933        supplicant.start(&mut updates).expect("Failed starting Supplicant");
934        assert_eq!(updates.len(), 1, "{:?}", updates);
935        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
936
937        (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
938            msg1.key_frame_fields.key_replay_counter.set(0);
939        });
940        assert!(result.is_ok());
941        let msg2 = expect_eapol_resp(&updates[..]);
942        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
943        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
944
945        (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
946            msg3.key_frame_fields.key_replay_counter = U64::new(1);
947        });
948        assert!(result.is_ok());
949        test_util::expect_reported_ptk(&updates[..]);
950    }
951
952    #[test]
953    fn test_zero_key_replay_counter_replayed_msg3() {
954        let mut supplicant = test_util::get_wpa2_supplicant();
955        let mut updates = vec![];
956        let mut result;
957        supplicant.start(&mut updates).expect("Failed starting Supplicant");
958        assert_eq!(updates.len(), 1, "{:?}", updates);
959        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
960        assert_eq!(0, supplicant.esssa.key_replay_counter);
961
962        (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
963            msg1.key_frame_fields.key_replay_counter.set(0);
964        });
965        assert!(result.is_ok());
966        let msg2 = expect_eapol_resp(&updates[..]);
967        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
968        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
969
970        (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
971            msg3.key_frame_fields.key_replay_counter.set(2);
972        });
973        assert!(result.is_ok());
974        assert_eq!(2, supplicant.esssa.key_replay_counter);
975        test_util::expect_reported_ptk(&updates[..]);
976
977        // The just sent third message increased the key replay counter.
978        // All successive EAPOL frames are required to have a larger key replay counter.
979
980        // Send an invalid message.
981        (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
982            msg3.key_frame_fields.key_replay_counter.set(2);
983        });
984        assert!(result.is_ok());
985        assert_eq!(2, supplicant.esssa.key_replay_counter);
986        assert!(updates.is_empty(), "{:?}", updates);
987
988        // Send a valid message.
989        (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
990            msg3.key_frame_fields.key_replay_counter = U64::new(3);
991        });
992        assert!(result.is_ok());
993        assert_eq!(3, supplicant.esssa.key_replay_counter);
994        assert!(!updates.is_empty());
995    }
996
997    // Replays the first message of the 4-Way Handshake with an altered ANonce to verify that
998    // (1) the Supplicant discards the first derived PTK in favor of a new one, and
999    // (2) the Supplicant is not reusing a nonce from its previous message,
1000    // (3) the Supplicant only reports a new PTK if the 4-Way Handshake was completed successfully.
1001    #[test]
1002    fn test_replayed_msg1_ptk_installation_different_anonces() {
1003        let mut supplicant = test_util::get_wpa2_supplicant();
1004        let mut updates = vec![];
1005        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1006        assert_eq!(updates.len(), 1, "{:?}", updates);
1007        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1008
1009        // Send 1st message of 4-Way Handshake for the first time and derive PTK.
1010        let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1011            msg1.key_frame_fields.key_replay_counter.set(1);
1012        });
1013        assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1014        let msg2 = expect_eapol_resp(&updates[..]);
1015        let msg2_frame = msg2.keyframe();
1016        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1017        let first_ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1018        let first_nonce = msg2_frame.key_frame_fields.key_nonce;
1019
1020        // Send 1st message of 4-Way Handshake a second time and derive PTK.
1021        // Use a different ANonce than initially used.
1022        let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1023            msg1.key_frame_fields.key_replay_counter.set(2);
1024            msg1.key_frame_fields.key_nonce = [99; 32];
1025        });
1026        assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1027        let msg2 = expect_eapol_resp(&updates[..]);
1028        let msg2_frame = msg2.keyframe();
1029        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1030        let second_ptk = test_util::get_ptk(&[99; 32][..], &snonce[..]);
1031        let second_nonce = msg2_frame.key_frame_fields.key_nonce;
1032
1033        // Send 3rd message of 4-Way Handshake.
1034        // The Supplicant now finished the 4-Way Handshake and should report its PTK.
1035        // Use the same ANonce which was used in the replayed 1st message.
1036        let (_, updates) = send_fourway_msg3(&mut supplicant, &second_ptk, |msg3| {
1037            msg3.key_frame_fields.key_replay_counter.set(3);
1038            msg3.key_frame_fields.key_nonce = [99; 32];
1039        });
1040
1041        let installed_ptk = test_util::expect_reported_ptk(&updates[..]);
1042        assert_ne!(first_nonce, second_nonce);
1043        assert_ne!(&first_ptk, &second_ptk);
1044        assert_eq!(installed_ptk, second_ptk);
1045    }
1046
1047    // Replays the first message of the 4-Way Handshake without altering its ANonce to verify that
1048    // (1) the Supplicant derives the same PTK for the replayed message, and
1049    // (2) the Supplicant is reusing the nonce from its previous message,
1050    // (3) the Supplicant only reports a PTK if the 4-Way Handshake was completed successfully.
1051    // Regression test for: https://fxbug.dev/42104495
1052    #[test]
1053    fn test_replayed_msg1_ptk_installation_same_anonces() {
1054        let mut supplicant = test_util::get_wpa2_supplicant();
1055        let mut updates = vec![];
1056        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1057        assert_eq!(updates.len(), 1, "{:?}", updates);
1058        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1059
1060        // Send 1st message of 4-Way Handshake for the first time and derive PTK.
1061        let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1062            msg1.key_frame_fields.key_replay_counter.set(1);
1063        });
1064        assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1065        let msg2 = expect_eapol_resp(&updates[..]);
1066        let msg2_frame = msg2.keyframe();
1067        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1068        let first_ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1069        let first_nonce = msg2_frame.key_frame_fields.key_nonce;
1070
1071        // Send 1st message of 4-Way Handshake a second time and derive PTK.
1072        let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1073            msg1.key_frame_fields.key_replay_counter.set(2);
1074        });
1075        assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1076        let msg2 = expect_eapol_resp(&updates[..]);
1077        let msg2_frame = msg2.keyframe();
1078        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1079        let second_ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1080        let second_nonce = msg2_frame.key_frame_fields.key_nonce;
1081
1082        // Send 3rd message of 4-Way Handshake.
1083        // The Supplicant now finished the 4-Way Handshake and should report its PTK.
1084        let (_, updates) = send_fourway_msg3(&mut supplicant, &second_ptk, |msg3| {
1085            msg3.key_frame_fields.key_replay_counter.set(3);
1086        });
1087
1088        let installed_ptk = test_util::expect_reported_ptk(&updates[..]);
1089        assert_eq!(first_nonce, second_nonce);
1090        assert_eq!(&first_ptk, &second_ptk);
1091        assert_eq!(installed_ptk, second_ptk);
1092    }
1093
1094    // Test for WPA2-Personal (PSK CCMP-128) with a Supplicant role.
1095    #[test]
1096    fn test_supplicant_wpa2_ccmp128_psk() {
1097        // Create ESS Security Association
1098        let mut supplicant = test_util::get_wpa2_supplicant();
1099        let mut updates = vec![];
1100        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1101        assert_eq!(updates.len(), 1, "{:?}", updates);
1102        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1103
1104        // Send first message
1105        let (result, updates) = send_fourway_msg1(&mut supplicant, |_| {});
1106        assert!(result.is_ok());
1107
1108        // Verify 2nd message.
1109        let msg2_buf = expect_eapol_resp(&updates[..]);
1110        let msg2 = msg2_buf.keyframe();
1111        let s_rsne = fake_wpa2_s_rsne();
1112        let s_rsne_data = get_rsn_ie_bytes(&s_rsne);
1113        assert_eq!({ msg2.eapol_fields.version }, eapol::ProtocolVersion::IEEE802DOT1X2001);
1114        assert_eq!({ msg2.eapol_fields.packet_type }, eapol::PacketType::KEY);
1115        let buf = msg2.to_bytes(false);
1116        assert_eq!(msg2.eapol_fields.packet_body_len.get() as usize, buf.len() - 4);
1117        assert_eq!({ msg2.key_frame_fields.descriptor_type }, eapol::KeyDescriptor::IEEE802DOT11);
1118        assert_eq!(msg2.key_frame_fields.key_info(), eapol::KeyInformation(0x010A));
1119        assert_eq!(msg2.key_frame_fields.key_len.get(), 0);
1120        assert_eq!(msg2.key_frame_fields.key_replay_counter.get(), 1);
1121        assert!(!test_util::is_zero(&msg2.key_frame_fields.key_nonce[..]));
1122        assert!(test_util::is_zero(&msg2.key_frame_fields.key_iv[..]));
1123        assert_eq!(msg2.key_frame_fields.key_rsc.get(), 0);
1124        assert!(!test_util::is_zero(&msg2.key_mic[..]));
1125        assert_eq!(msg2.key_mic.len(), test_util::mic_len());
1126        assert_eq!(msg2.key_data.len(), 20);
1127        assert_eq!(&msg2.key_data[..], &s_rsne_data[..]);
1128
1129        // Send 3rd message.
1130        let snonce = msg2.key_frame_fields.key_nonce;
1131        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1132        let (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1133        assert!(result.is_ok());
1134
1135        // Verify 4th message was received and is correct.
1136        let msg4_buf = expect_eapol_resp(&updates[..]);
1137        let msg4 = msg4_buf.keyframe();
1138        assert_eq!({ msg4.eapol_fields.version }, eapol::ProtocolVersion::IEEE802DOT1X2001);
1139        assert_eq!({ msg4.eapol_fields.packet_type }, eapol::PacketType::KEY);
1140        assert_eq!(msg4.eapol_fields.packet_body_len.get() as usize, &msg4_buf[..].len() - 4);
1141        assert_eq!({ msg4.key_frame_fields.descriptor_type }, eapol::KeyDescriptor::IEEE802DOT11);
1142        assert_eq!(msg4.key_frame_fields.key_info(), eapol::KeyInformation(0x030A));
1143        assert_eq!(msg4.key_frame_fields.key_len.get(), 0);
1144        assert_eq!(msg4.key_frame_fields.key_replay_counter.get(), 2);
1145        assert!(test_util::is_zero(&msg4.key_frame_fields.key_nonce[..]));
1146        assert!(test_util::is_zero(&msg4.key_frame_fields.key_iv[..]));
1147        assert_eq!(msg4.key_frame_fields.key_rsc.get(), 0);
1148        assert!(!test_util::is_zero(&msg4.key_mic[..]));
1149        assert_eq!(msg4.key_mic.len(), test_util::mic_len());
1150        assert_eq!(msg4.key_data.len(), 0);
1151        assert!(test_util::is_zero(&msg4.key_data[..]));
1152        // Verify the message's MIC.
1153        let mic = compute_mic(ptk.kck(), &test_util::get_rsne_protection(), &msg4)
1154            .expect("error computing MIC");
1155        assert_eq!(&msg4.key_mic[..], &mic[..]);
1156
1157        // Verify PTK was reported.
1158        let reported_ptk = test_util::expect_reported_ptk(&updates[..]);
1159        assert_eq!(ptk.ptk, reported_ptk.ptk);
1160
1161        // Verify GTK was reported.
1162        let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1163        assert_eq!(&GTK[..], &reported_gtk.bytes[..]);
1164
1165        // Verify ESS was reported to be established.
1166        let reported_status =
1167            test_util::expect_reported_status(&updates[..], SecAssocStatus::EssSaEstablished);
1168        assert_eq!(reported_status, SecAssocStatus::EssSaEstablished);
1169
1170        // Cause re-keying of GTK via Group-Key Handshake.
1171
1172        let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY, 3, 3);
1173        assert!(result.is_ok());
1174
1175        // Verify 2th message was received and is correct.
1176        let msg2_buf = expect_eapol_resp(&updates[..]);
1177        let msg2 = msg2_buf.keyframe();
1178        assert_eq!({ msg2.eapol_fields.version }, eapol::ProtocolVersion::IEEE802DOT1X2001);
1179        assert_eq!({ msg2.eapol_fields.packet_type }, eapol::PacketType::KEY);
1180        assert_eq!(msg2.eapol_fields.packet_body_len.get() as usize, &msg2_buf[..].len() - 4);
1181        assert_eq!({ msg2.key_frame_fields.descriptor_type }, eapol::KeyDescriptor::IEEE802DOT11);
1182        assert_eq!(msg2.key_frame_fields.key_info(), eapol::KeyInformation(0x0302));
1183        assert_eq!(msg2.key_frame_fields.key_len.get(), 0);
1184        assert_eq!(msg2.key_frame_fields.key_replay_counter.get(), 3);
1185        assert!(test_util::is_zero(&msg2.key_frame_fields.key_nonce[..]));
1186        assert!(test_util::is_zero(&msg2.key_frame_fields.key_iv[..]));
1187        assert_eq!(msg2.key_frame_fields.key_rsc.get(), 0);
1188        assert!(!test_util::is_zero(&msg2.key_mic[..]));
1189        assert_eq!(msg2.key_mic.len(), test_util::mic_len());
1190        assert_eq!(msg2.key_data.len(), 0);
1191        assert!(test_util::is_zero(&msg2.key_data[..]));
1192        // Verify the message's MIC.
1193        let mic = compute_mic(ptk.kck(), &test_util::get_rsne_protection(), &msg2)
1194            .expect("error computing MIC");
1195        assert_eq!(&msg2.key_mic[..], &mic[..]);
1196
1197        // Verify PTK was NOT re-installed.
1198        assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1199
1200        // Verify GTK was installed.
1201        let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1202        assert_eq!(&GTK_REKEY[..], &reported_gtk.bytes[..]);
1203    }
1204
1205    // Test to verify that GTKs derived in the 4-Way Handshake are not being re-installed
1206    // through Group Key Handshakes.
1207    #[test]
1208    fn test_supplicant_no_gtk_reinstallation_from_4way() {
1209        // Create ESS Security Association
1210        let mut supplicant = test_util::get_wpa2_supplicant();
1211        let mut updates = vec![];
1212        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1213        assert_eq!(updates.len(), 1, "{:?}", updates);
1214        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1215
1216        // Complete 4-Way Handshake.
1217        let updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1218        let msg2 = test_util::expect_eapol_resp(&updates[..]);
1219        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1220        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1221        let _ = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1222
1223        // Cause re-keying of GTK via Group-Key Handshake.
1224        // Rekey same GTK which has been already installed via the 4-Way Handshake.
1225        // This GTK should not be re-installed.
1226        let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK, 2, 3);
1227        assert!(result.is_ok());
1228
1229        // Verify 2th message was received and is correct.
1230        let msg2 = test_util::expect_eapol_resp(&updates[..]);
1231        let keyframe = msg2.keyframe();
1232        assert_eq!(keyframe.eapol_fields.version, eapol::ProtocolVersion::IEEE802DOT1X2001);
1233        assert_eq!(keyframe.eapol_fields.packet_type, eapol::PacketType::KEY);
1234        assert_eq!(keyframe.eapol_fields.packet_body_len.get() as usize, msg2.len() - 4);
1235        assert_eq!(keyframe.key_frame_fields.descriptor_type, eapol::KeyDescriptor::IEEE802DOT11);
1236        assert_eq!(keyframe.key_frame_fields.key_info().0, 0x0302);
1237        assert_eq!(keyframe.key_frame_fields.key_len.get(), 0);
1238        assert_eq!(keyframe.key_frame_fields.key_replay_counter.get(), 3);
1239        assert!(test_util::is_zero(&keyframe.key_frame_fields.key_nonce[..]));
1240        assert!(test_util::is_zero(&keyframe.key_frame_fields.key_iv[..]));
1241        assert_eq!(keyframe.key_frame_fields.key_rsc.get(), 0);
1242        assert!(!test_util::is_zero(&keyframe.key_mic[..]));
1243        assert_eq!(keyframe.key_mic.len(), test_util::mic_len());
1244        assert_eq!(keyframe.key_data.len(), 0);
1245        assert!(test_util::is_zero(&keyframe.key_data[..]));
1246        // Verify the message's MIC.
1247        let mic = compute_mic(ptk.kck(), &test_util::get_rsne_protection(), &keyframe)
1248            .expect("error computing MIC");
1249        assert_eq!(&keyframe.key_mic[..], &mic[..]);
1250
1251        // Verify neither PTK nor GTK were re-installed.
1252        assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1253        assert_eq!(test_util::get_reported_gtk(&updates[..]), None);
1254    }
1255
1256    // Test to verify that already rotated GTKs are not being re-installed.
1257    #[test]
1258    fn test_supplicant_no_gtk_reinstallation() {
1259        // Create ESS Security Association
1260        let mut supplicant = test_util::get_wpa2_supplicant();
1261        let mut updates = vec![];
1262        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1263        assert_eq!(updates.len(), 1, "{:?}", updates);
1264        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1265
1266        // Complete 4-Way Handshake.
1267        let updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1268        let msg2 = test_util::expect_eapol_resp(&updates[..]);
1269        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1270        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1271        let _ = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1272
1273        // Cause re-keying of GTK via Group-Key Handshake.
1274        // Rekey same GTK which has been already installed via the 4-Way Handshake.
1275        // This GTK should not be re-installed.
1276
1277        // Rotate GTK.
1278        let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY, 3, 3);
1279        assert!(result.is_ok());
1280        let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1281        assert_eq!(&reported_gtk.bytes[..], &GTK_REKEY[..]);
1282
1283        let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY_2, 1, 4);
1284        assert!(result.is_ok(), "{:?}", result);
1285        let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1286        assert_eq!(&reported_gtk.bytes[..], &GTK_REKEY_2[..]);
1287
1288        // Rotate GTK to already installed key. Verify GTK was not re-installed.
1289        let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY, 3, 5);
1290        assert!(result.is_ok());
1291        assert_eq!(test_util::get_reported_gtk(&updates[..]), None);
1292    }
1293
1294    #[test]
1295    fn test_rsna_retransmission_timeout() {
1296        // Create ESS Security Association
1297        let mut supplicant = test_util::get_wpa2_supplicant();
1298        let mut updates = vec![];
1299        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1300        assert_eq!(updates.len(), 1, "{:?}", updates);
1301        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1302
1303        // Send the first frame.
1304        updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1305        let msg2 = test_util::expect_eapol_resp(&updates[..]);
1306
1307        // Acknowledge the second frame sent.
1308        updates = vec![];
1309        supplicant
1310            .on_eapol_conf(&mut updates, EapolResultCode::Success)
1311            .expect("Failed to send eapol conf");
1312        assert!(updates.is_empty());
1313
1314        // Timeout several times.
1315        for _ in 1..MAX_KEY_FRAME_RETRIES {
1316            updates = vec![];
1317            supplicant
1318                .on_rsna_retransmission_timeout(&mut updates)
1319                .expect("Failed to send key frame timeout");
1320            let msg2_retry = test_util::expect_eapol_resp(&updates[..]);
1321            supplicant
1322                .on_eapol_conf(&mut updates, EapolResultCode::Success)
1323                .expect("Failed to send eapol conf");
1324            assert_eq!(msg2, msg2_retry);
1325        }
1326
1327        // Go idle on the last retry.
1328        updates = vec![];
1329        assert_matches!(supplicant.on_rsna_retransmission_timeout(&mut updates), Ok(()));
1330        assert!(updates.is_empty(), "{:?}", updates);
1331    }
1332
1333    #[test]
1334    fn test_rsna_retransmission_timeout_retries_reset() {
1335        // Create ESS Security Association
1336        let mut supplicant = test_util::get_wpa2_supplicant();
1337        let mut updates = vec![];
1338        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1339        assert_eq!(updates.len(), 1, "{:?}", updates);
1340        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1341
1342        for _ in 0..3 {
1343            // Send the first frame.
1344            updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1345            let msg2 = test_util::expect_eapol_resp(&updates[..]);
1346            updates = vec![];
1347            supplicant
1348                .on_eapol_conf(&mut updates, EapolResultCode::Success)
1349                .expect("Failed to send eapol conf");
1350            assert!(updates.is_empty(), "{:?}", updates);
1351
1352            // Timeout several times.
1353            for _ in 1..MAX_KEY_FRAME_RETRIES {
1354                updates = vec![];
1355                supplicant
1356                    .on_rsna_retransmission_timeout(&mut updates)
1357                    .expect("Failed to send key frame timeout");
1358                let msg2_retry = test_util::expect_eapol_resp(&updates[..]);
1359                supplicant
1360                    .on_eapol_conf(&mut updates, EapolResultCode::Success)
1361                    .expect("Failed to send eapol conf");
1362                assert_eq!(msg2, msg2_retry);
1363            }
1364
1365            // Go idle on the last retry.
1366            updates = vec![];
1367            assert_matches!(supplicant.on_rsna_retransmission_timeout(&mut updates), Ok(()));
1368            assert!(updates.is_empty(), "{:?}", updates);
1369        }
1370    }
1371
1372    #[test]
1373    fn test_overall_timeout_before_msg1() {
1374        // Create ESS Security Association
1375        let mut supplicant = test_util::get_wpa2_supplicant();
1376        let mut updates = vec![];
1377        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1378        assert_eq!(updates.len(), 1, "{:?}", updates);
1379        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1380
1381        assert_matches!(supplicant.incomplete_reason(), Error::EapolHandshakeNotStarted);
1382    }
1383
1384    #[test]
1385    fn test_overall_timeout_after_msg2() {
1386        // Create ESS Security Association
1387        let mut supplicant = test_util::get_wpa2_supplicant();
1388        let mut updates = vec![];
1389        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1390        assert_eq!(updates.len(), 1, "{:?}", updates);
1391        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1392
1393        // Send the first frame.
1394        (_, updates) = send_fourway_msg1(&mut supplicant, |_| {});
1395        let _msg2 = test_util::expect_eapol_resp(&updates[..]);
1396
1397        // Acknowledge second frame sent
1398        updates = vec![];
1399        supplicant
1400            .on_eapol_conf(&mut updates, EapolResultCode::Success)
1401            .expect("Failed to send eapol conf");
1402        assert!(updates.is_empty(), "{:?}", updates);
1403
1404        assert_matches!(supplicant.incomplete_reason(), Error::LikelyWrongCredential);
1405    }
1406
1407    #[test]
1408    fn test_overall_timeout_before_conf() {
1409        // Create ESS Security Association
1410        let mut supplicant = test_util::get_wpa2_supplicant();
1411        let mut updates = UpdateSink::default();
1412        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1413        assert_eq!(updates.len(), 1, "{:?}", updates);
1414        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1415
1416        // Send the first frame but don't send a conf in response.
1417        let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], |_| {});
1418        supplicant
1419            .on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()))
1420            .expect("Failed to send eapol frame");
1421        let _msg2 = test_util::expect_eapol_resp(&updates[..]);
1422
1423        assert_matches!(supplicant.incomplete_reason(), Error::NoKeyFrameTransmissionConfirm(0));
1424    }
1425
1426    #[test]
1427    fn test_rsna_retransmission_timeout_retry_without_conf() {
1428        // Create ESS Security Association
1429        let mut supplicant = test_util::get_wpa2_supplicant();
1430        let mut updates = vec![];
1431        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1432        assert_eq!(updates.len(), 1, "{:?}", updates);
1433        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1434
1435        // Send the first frame.
1436        updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1437        let msg2 = test_util::expect_eapol_resp(&updates[..]);
1438
1439        // Acknowledge second frame sent.
1440        updates = vec![];
1441        supplicant
1442            .on_eapol_conf(&mut updates, EapolResultCode::Success)
1443            .expect("Failed to send eapol conf");
1444        assert!(updates.is_empty(), "{:?}", updates);
1445
1446        // Respond to one timeout, but don't confirm the retry.
1447        updates = vec![];
1448        supplicant
1449            .on_rsna_retransmission_timeout(&mut updates)
1450            .expect("Failed to send key frame timeout");
1451        let msg2_retry = test_util::expect_eapol_resp(&updates[..]);
1452        assert_eq!(msg2, msg2_retry);
1453
1454        // Failure on the next timeout.
1455        updates = vec![];
1456        assert_matches!(
1457            supplicant.on_rsna_retransmission_timeout(&mut updates),
1458            Err(Error::NoKeyFrameTransmissionConfirm(0))
1459        );
1460    }
1461
1462    #[test]
1463    fn test_msg2_out_of_order_conf() {
1464        // Create ESS Security Association
1465        let mut supplicant = test_util::get_wpa2_supplicant();
1466        let mut updates = UpdateSink::default();
1467        let result: Result<(), Error>;
1468        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1469        assert_eq!(updates.len(), 1, "{:?}", updates);
1470        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1471
1472        // Send the first frame but don't send a conf in response.
1473        let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], |_| {});
1474        supplicant
1475            .on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()))
1476            .expect("Failed to send eapol frame");
1477        let msg2 = test_util::expect_eapol_resp(&updates[..]);
1478
1479        // No key frame confirm means that we will buffer updates until the confirm is received.
1480        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1481        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1482        (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1483        result.expect("Failed to send msg3");
1484        assert!(updates.is_empty(), "{:?}", updates);
1485
1486        // When confirm is received we receive updates through msg4
1487        updates = UpdateSink::default();
1488        supplicant
1489            .on_eapol_conf(&mut updates, EapolResultCode::Success)
1490            .expect("Failed to send eapol conf");
1491        assert_eq!(updates.len(), 3);
1492        test_util::expect_eapol_resp(&updates[..]);
1493        test_util::expect_reported_ptk(&updates[..]);
1494        test_util::expect_reported_gtk(&updates[..]);
1495
1496        // On another confirm, we receive the remaining updates.
1497        supplicant
1498            .on_eapol_conf(&mut updates, EapolResultCode::Success)
1499            .expect("Failed to send eapol conf");
1500        test_util::expect_reported_status(&updates[..], SecAssocStatus::EssSaEstablished);
1501    }
1502
1503    #[test]
1504    fn test_msg2_no_conf() {
1505        // Create ESS Security Association
1506        let mut supplicant = test_util::get_wpa2_supplicant();
1507        let mut updates = UpdateSink::default();
1508        let result: Result<(), Error>;
1509        supplicant.start(&mut updates).expect("Failed starting Supplicant");
1510        assert_eq!(updates.len(), 1, "{:?}", updates);
1511        test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1512
1513        // Send the first frame but don't send a conf in response.
1514        let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], |_| {});
1515        supplicant
1516            .on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()))
1517            .expect("Failed to send eapol frame");
1518        let msg2 = test_util::expect_eapol_resp(&updates[..]);
1519
1520        // No key frame confirm means that we will buffer updates until the confirm is received.
1521        let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1522        let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1523        (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1524        result.expect("Failed to send msg3");
1525        assert!(updates.is_empty(), "{:?}", updates);
1526
1527        // We never receive a confirm, and report this on timeout.
1528        // There are 4 pending updates that we drop after this timeout:
1529        //   * EAPOL message 4
1530        //   * PTK
1531        //   * GTK
1532        //   * ESSSA Established
1533        updates = vec![];
1534        assert_matches!(
1535            supplicant.on_rsna_retransmission_timeout(&mut updates),
1536            Err(Error::NoKeyFrameTransmissionConfirm(4))
1537        );
1538    }
1539
1540    // TODO(hahnr): Add additional tests:
1541    // Invalid messages from Authenticator
1542    // Timeouts
1543    // Nonce reuse
1544    // (in)-compatible protocol and RSNE versions
1545
1546    fn test_eapol_exchange(
1547        supplicant: &mut Supplicant,
1548        authenticator: &mut Authenticator,
1549        msg1: Option<eapol::KeyFrameBuf>,
1550        wpa3: bool,
1551    ) {
1552        // Initiate Authenticator.
1553        let mut a_updates = vec![];
1554        let mut result: Result<(), Error>;
1555        result = authenticator.initiate(&mut a_updates);
1556        assert!(result.is_ok(), "Authenticator failed initiating: {}", result.unwrap_err());
1557
1558        if wpa3 {
1559            assert!(
1560                msg1.is_some(),
1561                "WPA3 EAPOL exchange starting without message constructed immediately after SAE"
1562            );
1563        }
1564        // If msg1 is provided, we expect no updates from the Authenticator. Otherwise, we
1565        // expect the Authenticator to establish the PmkSa and produce msg1.
1566        let msg1 = match msg1 {
1567            Some(msg1) => {
1568                assert_eq!(a_updates.len(), 0, "{:?}", a_updates);
1569                msg1
1570            }
1571            None => {
1572                assert_eq!(a_updates.len(), 2);
1573                test_util::expect_reported_status(&a_updates, SecAssocStatus::PmkSaEstablished);
1574                let resp = test_util::expect_eapol_resp(&a_updates[..]);
1575                authenticator
1576                    .on_eapol_conf(&mut a_updates, EapolResultCode::Success)
1577                    .expect("Failed eapol conf");
1578                resp
1579            }
1580        };
1581
1582        // Send msg #1 to Supplicant and wait for response.
1583        let mut s_updates = vec![];
1584        result = supplicant.on_eapol_frame(&mut s_updates, eapol::Frame::Key(msg1.keyframe()));
1585        assert!(result.is_ok(), "Supplicant failed processing msg #1: {}", result.unwrap_err());
1586        let msg2 = test_util::expect_eapol_resp(&s_updates[..]);
1587        supplicant
1588            .on_eapol_conf(&mut s_updates, EapolResultCode::Success)
1589            .expect("Failed eapol conf");
1590        assert_eq!(s_updates.len(), 1, "{:?}", s_updates);
1591
1592        // Send msg #2 to Authenticator and wait for response.
1593        let mut a_updates = vec![];
1594        result = authenticator.on_eapol_frame(&mut a_updates, eapol::Frame::Key(msg2.keyframe()));
1595        assert!(result.is_ok(), "Authenticator failed processing msg #2: {}", result.unwrap_err());
1596        let msg3 = test_util::expect_eapol_resp(&a_updates[..]);
1597        authenticator
1598            .on_eapol_conf(&mut a_updates, EapolResultCode::Success)
1599            .expect("Failed eapol conf");
1600        assert_eq!(a_updates.len(), 1, "{:?}", a_updates);
1601
1602        // Send msg #3 to Supplicant and wait for response.
1603        let mut s_updates = vec![];
1604        result = supplicant.on_eapol_frame(&mut s_updates, eapol::Frame::Key(msg3.keyframe()));
1605        assert!(result.is_ok(), "Supplicant failed processing msg #3: {}", result.unwrap_err());
1606
1607        let msg4 = test_util::expect_eapol_resp(&s_updates[..]);
1608        let s_ptk = test_util::expect_reported_ptk(&s_updates[..]);
1609        let s_gtk = test_util::expect_reported_gtk(&s_updates[..]);
1610        let s_igtk = if wpa3 {
1611            assert_eq!(s_updates.len(), 4, "{:?}", s_updates);
1612            Some(test_util::expect_reported_igtk(&s_updates[..]))
1613        } else {
1614            assert_eq!(s_updates.len(), 3, "{:?}", s_updates);
1615            None
1616        };
1617
1618        // We shouldn't see the esssa established until a confirm is received.
1619        supplicant
1620            .on_eapol_conf(&mut s_updates, EapolResultCode::Success)
1621            .expect("Failed eapol conf");
1622        test_util::expect_reported_status(&s_updates, SecAssocStatus::EssSaEstablished);
1623
1624        // Send msg #4 to Authenticator.
1625        let mut a_updates = vec![];
1626        result = authenticator.on_eapol_frame(&mut a_updates, eapol::Frame::Key(msg4.keyframe()));
1627        assert!(result.is_ok(), "Authenticator failed processing msg #4: {}", result.unwrap_err());
1628        let a_ptk = test_util::expect_reported_ptk(&a_updates[..]);
1629        let a_gtk = test_util::expect_reported_gtk(&a_updates[..]);
1630
1631        let a_igtk = if wpa3 {
1632            assert_eq!(a_updates.len(), 4, "{:?}", a_updates);
1633            Some(test_util::expect_reported_igtk(&a_updates[..]))
1634        } else {
1635            assert_eq!(a_updates.len(), 3, "{:?}", a_updates);
1636            None
1637        };
1638
1639        test_util::expect_reported_status(&a_updates, SecAssocStatus::EssSaEstablished);
1640
1641        // Verify derived keys match and status reports ESS-SA as established.
1642        assert_eq!(a_ptk, s_ptk);
1643        assert_eq!(a_gtk, s_gtk);
1644        assert_eq!(a_igtk, s_igtk);
1645    }
1646
1647    fn send_eapol_conf(supplicant: &mut Supplicant, updates: &mut UpdateSink) -> Result<(), Error> {
1648        let mut sent_frame = false;
1649        for update in &updates[..] {
1650            if let SecAssocUpdate::TxEapolKeyFrame { .. } = update {
1651                sent_frame = true;
1652            }
1653        }
1654        if sent_frame {
1655            supplicant.on_eapol_conf(updates, EapolResultCode::Success)
1656        } else {
1657            Ok(())
1658        }
1659    }
1660
1661    fn send_fourway_msg1<F>(
1662        supplicant: &mut Supplicant,
1663        msg_modifier: F,
1664    ) -> (Result<(), Error>, UpdateSink)
1665    where
1666        F: Fn(&mut eapol::KeyFrameTx),
1667    {
1668        let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], msg_modifier);
1669        let mut updates = UpdateSink::default();
1670        let result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()));
1671        let result = result.and_then(|_| send_eapol_conf(supplicant, &mut updates));
1672        (result, updates)
1673    }
1674
1675    fn send_fourway_msg3<F>(
1676        supplicant: &mut Supplicant,
1677        ptk: &Ptk,
1678        msg_modifier: F,
1679    ) -> (Result<(), Error>, UpdateSink)
1680    where
1681        F: Fn(&mut eapol::KeyFrameTx),
1682    {
1683        let msg = test_util::get_wpa2_4whs_msg3(ptk, &ANONCE[..], &GTK, msg_modifier);
1684        let mut updates = UpdateSink::default();
1685        let result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()));
1686        let result = result.and_then(|_| send_eapol_conf(supplicant, &mut updates));
1687        (result, updates)
1688    }
1689
1690    fn send_group_key_msg1(
1691        supplicant: &mut Supplicant,
1692        ptk: &Ptk,
1693        gtk: [u8; 16],
1694        key_id: u8,
1695        key_replay_counter: u64,
1696    ) -> (Result<(), Error>, UpdateSink) {
1697        let msg = test_util::get_group_key_hs_msg1(ptk, &gtk[..], key_id, key_replay_counter);
1698        let mut updates = UpdateSink::default();
1699        let result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()));
1700        let result = result.and_then(|_| send_eapol_conf(supplicant, &mut updates));
1701        (result, updates)
1702    }
1703}