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