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