1use 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::pmk::Pmk;
11use crate::key::ptk::Ptk;
12use crate::rsna::{
13 Dot11VerifiedKeyFrame, NegotiatedProtection, Role, SecAssocStatus, SecAssocUpdate, UpdateSink,
14};
15use crate::{Error, ProtectionInfo};
16use fidl_fuchsia_wlan_mlme::EapolResultCode;
17use log::{error, info};
18use std::collections::HashSet;
19use wlan_statemachine::StateMachine;
20
21use zerocopy::SplitByteSlice;
22
23const MAX_KEY_FRAME_RETRIES: u32 = 3;
24
25#[derive(Debug)]
26enum Pmksa {
27 Initialized { pmk: Option<Pmk> },
28 Established { pmk: Pmk },
29}
30
31impl Pmksa {
32 fn reset(self) -> Self {
33 match self {
34 Pmksa::Established { pmk } | Pmksa::Initialized { pmk: Some(pmk) } => {
35 Pmksa::Initialized { pmk: Some(pmk) }
36 }
37 _ => Pmksa::Initialized { pmk: None },
38 }
39 }
40}
41
42#[derive(Debug, PartialEq)]
43enum Ptksa {
44 Uninitialized { cfg: exchange::Config },
45 Initialized { method: exchange::Method },
46 Established { method: exchange::Method, ptk: Ptk },
47}
48
49impl Ptksa {
50 fn initialize(self, pmk: Pmk) -> Self {
51 match self {
52 Ptksa::Uninitialized { cfg } => match cfg {
53 exchange::Config::FourWayHandshake(mut method_cfg) => {
54 if method_cfg.pmksa_caching_supported {
55 if let Some(ref pmkid) = pmk.pmkid {
56 if let ProtectionInfo::Rsne { rsne: ref mut s_rsne, .. } =
57 method_cfg.s_protection
58 {
59 s_rsne.pmkids = vec![bytes::Bytes::copy_from_slice(pmkid)];
60 }
61 }
62 }
63 match Fourway::new(method_cfg.clone(), pmk.pmk) {
64 Err(e) => {
65 error!("error creating 4-Way Handshake from config: {}", e);
66 Ptksa::Uninitialized {
67 cfg: exchange::Config::FourWayHandshake(method_cfg),
68 }
69 }
70 Ok(method) => Ptksa::Initialized {
71 method: exchange::Method::FourWayHandshake(Box::new(method)),
72 },
73 }
74 }
75 _ => {
76 panic!("unsupported method for PTKSA: {:?}", cfg);
77 }
78 },
79 other => other,
80 }
81 }
82
83 fn reset(self) -> Self {
84 match self {
85 Ptksa::Uninitialized { cfg } => Ptksa::Uninitialized { cfg },
86 Ptksa::Initialized { method } | Ptksa::Established { method, .. } => {
87 Ptksa::Uninitialized { cfg: method.destroy() }
88 }
89 }
90 }
91}
92
93#[derive(Debug, PartialEq)]
97enum Gtksa {
98 Uninitialized {
99 cfg: Option<exchange::Config>,
100 },
101 Initialized {
102 method: Option<exchange::Method>,
103 },
104 Established {
105 method: Option<exchange::Method>,
106 installed_gtks: HashSet<Gtk>,
109 },
110}
111
112impl Gtksa {
113 fn initialize(self, kck: &[u8], kek: &[u8]) -> Self {
114 match self {
115 Gtksa::Uninitialized { cfg } => match cfg {
116 None => Gtksa::Initialized { method: None },
117 Some(exchange::Config::GroupKeyHandshake(method_cfg)) => {
118 match GroupKey::new(method_cfg.clone(), kck, kek) {
119 Err(e) => {
120 error!("error creating Group KeyHandshake from config: {}", e);
121 Gtksa::Uninitialized {
122 cfg: Some(exchange::Config::GroupKeyHandshake(method_cfg)),
123 }
124 }
125 Ok(method) => Gtksa::Initialized {
126 method: Some(exchange::Method::GroupKeyHandshake(method)),
127 },
128 }
129 }
130 _ => {
131 panic!("unsupported method for GTKSA: {:?}", cfg);
132 }
133 },
134 other => other,
135 }
136 }
137
138 fn reset(self) -> Self {
139 match self {
140 Gtksa::Uninitialized { cfg } => Gtksa::Uninitialized { cfg },
141 Gtksa::Initialized { method } | Gtksa::Established { method, .. } => {
142 Gtksa::Uninitialized { cfg: method.map(|m| m.destroy()) }
143 }
144 }
145 }
146}
147
148#[derive(Debug)]
150enum Igtksa {
151 Uninitialized,
152 Established { installed_igtks: HashSet<Igtk> },
153}
154
155impl Igtksa {
156 fn reset(self) -> Self {
157 Igtksa::Uninitialized
158 }
159}
160
161#[derive(Debug)]
171pub(crate) struct EssSa {
172 role: Role,
174 pub negotiated_protection: NegotiatedProtection,
176 key_replay_counter: u64,
179 last_key_frame_buf: Option<(u32, eapol::KeyFrameBuf)>,
181 updates_awaiting_confirm: Option<UpdateSink>,
184
185 pmksa: StateMachine<Pmksa>,
187 ptksa: StateMachine<Ptksa>,
188 gtksa: StateMachine<Gtksa>,
189 igtksa: StateMachine<Igtksa>,
190}
191
192impl EssSa {
194 pub fn new(
195 role: Role,
196 pmk: Option<Pmk>,
197 negotiated_protection: NegotiatedProtection,
198 ptk_exch_cfg: exchange::Config,
199 gtk_exch_cfg: Option<exchange::Config>,
200 ) -> Result<EssSa, anyhow::Error> {
201 info!("spawned ESSSA for: {:?}", role);
202
203 let rsna = EssSa {
204 role,
205 negotiated_protection,
206 key_replay_counter: 0,
207 last_key_frame_buf: None,
208 updates_awaiting_confirm: None,
209 pmksa: StateMachine::new(Pmksa::Initialized { pmk }),
210 ptksa: StateMachine::new(Ptksa::Uninitialized { cfg: ptk_exch_cfg }),
211 gtksa: StateMachine::new(Gtksa::Uninitialized { cfg: gtk_exch_cfg }),
212 igtksa: StateMachine::new(Igtksa::Uninitialized),
213 };
214 Ok(rsna)
215 }
216
217 #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
218 pub fn initiate(&mut self, update_sink: &mut UpdateSink) -> Result<(), Error> {
220 match (self.ptksa.as_ref(), self.gtksa.as_ref(), self.igtksa.as_ref()) {
225 (Ptksa::Uninitialized { .. }, Gtksa::Uninitialized { .. }, Igtksa::Uninitialized) => (),
226
227 (Ptksa::Initialized { .. }, Gtksa::Uninitialized { .. }, Igtksa::Uninitialized) => (),
228 _ => return Err(Error::UnexpectedEsssaInitiation),
229 };
230 info!("establishing ESSSA...");
231
232 let pmk = match self.pmksa.as_ref() {
235 Pmksa::Initialized { pmk: Some(pmk) } => Some(pmk.clone()),
236 _ => None,
237 };
238 if let Some(pmk) = pmk { self.on_pmk_available(update_sink, pmk) } else { Ok(()) }
239 }
240
241 pub fn reset_replay_counter(&mut self) {
242 info!("resetting ESSSA replay counter");
243 self.key_replay_counter = 0;
244 }
245
246 pub fn reset_security_associations(&mut self) {
247 info!("resetting ESSSA security associations");
248 self.pmksa.replace_state(|state| state.reset());
249 self.ptksa.replace_state(|state| state.reset());
250 self.gtksa.replace_state(|state| state.reset());
251 self.igtksa.replace_state(|state| state.reset());
252 }
253
254 fn is_established(&self) -> bool {
255 match (self.ptksa.as_ref(), self.gtksa.as_ref()) {
256 (Ptksa::Established { .. }, Gtksa::Established { .. }) => true,
257 _ => false,
258 }
259 }
260
261 #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
262 fn on_key_confirmed(&mut self, update_sink: &mut UpdateSink, key: Key) -> Result<(), Error> {
263 let was_esssa_established = self.is_established();
264 match key {
265 Key::Pmk(pmk) => {
266 self.pmksa.replace_state(|state| match state {
267 Pmksa::Initialized { .. } => {
268 info!("established PMKSA");
269 update_sink.push(SecAssocUpdate::Status(SecAssocStatus::PmkSaEstablished));
270 Pmksa::Established { pmk: pmk.clone() }
271 }
272 other => {
273 error!("received PMK with PMK already being established");
274 other
275 }
276 });
277
278 self.ptksa.replace_state(|state| state.initialize(pmk));
279 if let Ptksa::Initialized { method: exchange::Method::FourWayHandshake(hs) } =
280 self.ptksa.as_mut()
281 {
282 if let Fourway::Authenticator(authenticator_state_machine) = &mut **hs {
283 authenticator_state_machine
284 .try_replace_state(|state| {
285 state.initiate(update_sink, self.key_replay_counter.into())
286 })
287 .map(|_state_machine| ())?;
290 }
291 }
292 }
293 Key::Ptk(ptk) => {
294 self.gtksa.replace_state(|state| state.reset().initialize(ptk.kck(), ptk.kek()));
297
298 self.ptksa.replace_state(|state| match state {
299 Ptksa::Initialized { method } => {
300 info!("established PTKSA");
301 update_sink.push(SecAssocUpdate::Key(Key::Ptk(ptk.clone())));
302 Ptksa::Established { method, ptk }
303 }
304 Ptksa::Established { method, .. } => {
305 info!("re-established new PTKSA; invalidating previous one");
307 info!("(this is likely a result of using a wrong password)");
308 if was_esssa_established {
313 update_sink.push(SecAssocUpdate::Key(Key::Ptk(ptk.clone())));
314 }
315 Ptksa::Established { method, ptk }
316 }
317 other @ Ptksa::Uninitialized { .. } => {
318 error!("received PTK in unexpected PTKSA state");
319 other
320 }
321 });
322 }
323 Key::Gtk(gtk) => {
324 self.gtksa.replace_state(|state| match state {
325 Gtksa::Initialized { method } => {
326 info!("established GTKSA");
327
328 let mut installed_gtks = HashSet::default();
329 installed_gtks.insert(gtk.clone());
330 update_sink.push(SecAssocUpdate::Key(Key::Gtk(gtk)));
331 Gtksa::Established { method, installed_gtks }
332 }
333 Gtksa::Established { method, mut installed_gtks } => {
334 info!("re-established new GTKSA; invalidating previous one");
335
336 if !installed_gtks.contains(>k) {
337 installed_gtks.insert(gtk.clone());
338 update_sink.push(SecAssocUpdate::Key(Key::Gtk(gtk)));
339 }
340 Gtksa::Established { method, installed_gtks }
341 }
342 Gtksa::Uninitialized { cfg } => {
343 error!("received GTK in unexpected GTKSA state");
344 Gtksa::Uninitialized { cfg }
345 }
346 });
347 }
348 Key::Igtk(igtk) => {
349 self.igtksa.replace_state(|state| match state {
350 Igtksa::Uninitialized => {
351 info!("established IGTKSA");
352 let mut installed_igtks = HashSet::default();
353 installed_igtks.insert(igtk.clone());
354 update_sink.push(SecAssocUpdate::Key(Key::Igtk(igtk)));
355 Igtksa::Established { installed_igtks }
356 }
357 Igtksa::Established { mut installed_igtks } => {
358 info!("re-established new IGTKSA; invalidating previous one");
359
360 if !installed_igtks.contains(&igtk) {
361 installed_igtks.insert(igtk.clone());
362 update_sink.push(SecAssocUpdate::Key(Key::Igtk(igtk)));
363 }
364 Igtksa::Established { installed_igtks }
365 }
366 });
367 }
368 _ => {}
369 };
370 Ok(())
371 }
372
373 #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
374 pub fn on_pmk_available(
375 &mut self,
376 update_sink: &mut UpdateSink,
377 pmk: Pmk,
378 ) -> Result<(), Error> {
379 let mut new_updates = UpdateSink::default();
380 let result = self.on_key_confirmed(&mut new_updates, Key::Pmk(pmk));
381 self.push_updates(update_sink, new_updates);
382 result
383 }
384
385 fn push_updates(&mut self, update_sink: &mut UpdateSink, mut new_updates: UpdateSink) {
387 if let Some(updates_awaiting_confirm) = &mut self.updates_awaiting_confirm {
388 updates_awaiting_confirm.append(&mut new_updates);
394 return;
395 }
396 for update in new_updates {
397 if let SecAssocUpdate::Key(_) = update {
398 update_sink.push(update);
404 } else if let Some(updates_awaiting_confirm) = &mut self.updates_awaiting_confirm {
405 updates_awaiting_confirm.push(update);
408 } else {
409 if let SecAssocUpdate::TxEapolKeyFrame { frame, expect_response } = &update {
410 if *expect_response {
411 self.last_key_frame_buf = Some((1, frame.clone()));
412 } else {
413 self.last_key_frame_buf = None;
415 }
416 self.updates_awaiting_confirm.replace(Default::default());
418 }
419 update_sink.push(update);
420 }
421 }
422 }
423
424 #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
425 pub fn on_eapol_conf(
426 &mut self,
427 update_sink: &mut UpdateSink,
428 result: EapolResultCode,
429 ) -> Result<(), Error> {
430 match self.updates_awaiting_confirm.take() {
431 Some(updates) => match result {
432 EapolResultCode::Success => {
433 self.push_updates(update_sink, updates);
435 Ok(())
436 }
437 EapolResultCode::TransmissionFailure => Err(Error::KeyFrameTransmissionFailed),
438 },
439 None => {
440 error!("Ignored unexpected eapol send confirm");
441 Ok(())
442 }
443 }
444 }
445
446 #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
447 pub fn on_rsna_retransmission_timeout(
448 &mut self,
449 update_sink: &mut UpdateSink,
450 ) -> Result<(), Error> {
451 if let Some(updates) = &self.updates_awaiting_confirm {
454 return Err(Error::NoKeyFrameTransmissionConfirm(updates.len()));
455 }
456 if let Some((attempt, key_frame)) = self.last_key_frame_buf.as_mut() {
458 *attempt += 1;
459 if *attempt > MAX_KEY_FRAME_RETRIES {
460 return Ok(());
462 }
463 update_sink.push(SecAssocUpdate::TxEapolKeyFrame {
464 frame: key_frame.clone(),
465 expect_response: true,
466 });
467 self.updates_awaiting_confirm = Some(Default::default());
469 }
470 Ok(())
471 }
472
473 pub fn incomplete_reason(&self) -> Error {
474 if let Some(updates) = &self.updates_awaiting_confirm {
475 return Error::NoKeyFrameTransmissionConfirm(updates.len());
476 }
477 match self.ptksa.as_ref() {
478 Ptksa::Uninitialized { .. } => {
479 return Error::EapolHandshakeIncomplete("PTKSA never initialized".to_string());
480 }
481 Ptksa::Initialized { method } | Ptksa::Established { method, .. } => {
482 if let Err(error) = method.on_rsna_response_timeout() {
483 return error;
484 }
485 }
486 }
487 if !matches!(self.gtksa.as_ref(), Gtksa::Established { .. }) {
488 return Error::EapolHandshakeIncomplete("GTKSA never established".to_string());
489 }
490
491 Error::EapolHandshakeIncomplete("Unexpected timeout while establishing RSNA".to_string())
494 }
495
496 #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
497 pub fn on_eapol_frame<B: SplitByteSlice>(
498 &mut self,
499 update_sink: &mut UpdateSink,
500 frame: eapol::Frame<B>,
501 ) -> Result<(), Error> {
502 let on_eapol_key_frame_updates = match frame {
504 eapol::Frame::Key(key_frame) => {
505 let mut on_eapol_key_frame_updates = UpdateSink::default();
506 self.on_eapol_key_frame(&mut on_eapol_key_frame_updates, key_frame)?;
507 self.last_key_frame_buf.take();
509
510 if let Role::Authenticator = self.role {
512 for update in &on_eapol_key_frame_updates {
513 if let SecAssocUpdate::TxEapolKeyFrame { frame, .. } = update {
514 let key_replay_counter =
515 frame.keyframe().key_frame_fields.key_replay_counter.get();
516
517 if key_replay_counter <= self.key_replay_counter {
518 error!(
519 "tx EAPOL Key frame uses invalid key replay counter: {:?} ({:?})",
520 key_replay_counter, self.key_replay_counter
521 );
522 }
523 self.key_replay_counter = key_replay_counter;
524 }
525 }
526 }
527
528 on_eapol_key_frame_updates
529 }
530 _ => UpdateSink::default(),
531 };
532
533 let was_esssa_established = self.is_established();
535
536 let mut new_updates = UpdateSink::default();
538 for update in on_eapol_key_frame_updates {
539 match update {
540 SecAssocUpdate::Key(key) => {
541 if let Err(e) = self.on_key_confirmed(&mut new_updates, key) {
542 error!("error while processing key: {}", e);
543 };
544 }
545 _ => new_updates.push(update),
547 }
548 }
549
550 if !was_esssa_established && self.is_established() {
552 info!("established ESSSA");
553 new_updates.push(SecAssocUpdate::Status(SecAssocStatus::EssSaEstablished));
554 }
555
556 self.push_updates(update_sink, new_updates);
557 Ok(())
558 }
559
560 #[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
561 fn on_eapol_key_frame<B: SplitByteSlice>(
562 &mut self,
563 update_sink: &mut UpdateSink,
564 frame: eapol::KeyFrameRx<B>,
565 ) -> Result<(), Error> {
566 let verified_frame = match Dot11VerifiedKeyFrame::from_frame(
568 frame,
569 &self.role,
570 &self.negotiated_protection,
571 self.key_replay_counter,
572 ) {
573 Err(e @ Error::InvalidKeyReplayCounter(_, _)) => {
576 info!("Ignoring eapol frame: {}", e);
577 return Ok(());
578 }
579 result => result?,
580 };
581
582 let raw_frame = verified_frame.unsafe_get_raw();
584 let frame_has_mic = raw_frame.key_frame_fields.key_info().key_mic();
585 let frame_key_replay_counter = raw_frame.key_frame_fields.key_replay_counter.get();
586
587 match self.pmksa.as_mut() {
591 Pmksa::Initialized { .. } => return Ok(()),
592 Pmksa::Established { .. } => {}
593 };
594
595 let result = if raw_frame.key_frame_fields.key_info().key_type() == eapol::KeyType::PAIRWISE
598 {
599 match self.ptksa.as_mut() {
600 Ptksa::Uninitialized { .. } => Ok(()),
601 Ptksa::Initialized { method } | Ptksa::Established { method, .. } => {
602 method.on_eapol_key_frame(update_sink, verified_frame)
603 }
604 }
605 } else if raw_frame.key_frame_fields.key_info().key_type() == eapol::KeyType::GROUP_SMK {
606 match self.gtksa.as_mut() {
607 Gtksa::Uninitialized { .. } => Ok(()),
608 Gtksa::Initialized { method } | Gtksa::Established { method, .. } => match method {
609 Some(method) => method.on_eapol_key_frame(update_sink, verified_frame),
610 None => {
611 error!("received group key EAPOL Key frame with GTK re-keying disabled");
612 Ok(())
613 }
614 },
615 }
616 } else {
617 error!(
618 "unsupported EAPOL Key frame key type: {:?}",
619 raw_frame.key_frame_fields.key_info().key_type()
620 );
621 Ok(())
622 };
623
624 if frame_has_mic {
628 if let Role::Supplicant = self.role {
629 for update in update_sink {
630 if let SecAssocUpdate::TxEapolKeyFrame { .. } = update {
631 self.key_replay_counter = frame_key_replay_counter;
632 break;
633 }
634 }
635 }
636 }
637
638 result
639 }
640}
641
642#[cfg(test)]
643mod tests {
644 use super::*;
645 use crate::key::exchange::compute_mic;
646 use crate::rsna::test_util::expect_eapol_resp;
647 use crate::rsna::{AuthStatus, test_util};
648 use crate::{Authenticator, Supplicant};
649 use assert_matches::assert_matches;
650 use wlan_common::ie::get_rsn_ie_bytes;
651 use wlan_common::ie::rsn::fake_wpa2_s_rsne;
652 use zerocopy::byteorder::big_endian::U64;
653
654 const ANONCE: [u8; 32] = [0x1A; 32];
655 const GTK: [u8; 16] = [0x1B; 16];
656 const GTK_REKEY: [u8; 16] = [0x1F; 16];
657 const GTK_REKEY_2: [u8; 16] = [0x2F; 16];
658
659 #[test]
660 fn test_supplicant_with_wpa3_authenticator() {
661 let mut supplicant = test_util::get_wpa3_supplicant();
662 let mut authenticator = test_util::get_wpa3_authenticator();
663 let mut s_updates = vec![];
664 supplicant.start(&mut s_updates).expect("Failed starting Supplicant");
665 assert!(s_updates.is_empty(), "{:?}", s_updates);
666
667 let result = supplicant.on_sae_handshake_ind(&mut s_updates);
669 assert!(result.is_ok(), "Supplicant failed to ind SAE handshake");
670 let s_sae_frame_vec = test_util::expect_sae_frame_vec(&s_updates[..]);
671 test_util::expect_schedule_sae_timeout(&s_updates[..]);
672 assert_eq!(s_updates.len(), 2, "{:?}", s_updates);
673
674 let mut a_updates = vec![];
676 for s_sae_frame in s_sae_frame_vec {
677 let result = authenticator.on_sae_frame_rx(&mut a_updates, s_sae_frame);
678 assert!(result.is_ok(), "Authenticator failed to rx SAE handshake message");
679 }
680 let a_sae_frame_vec = test_util::expect_sae_frame_vec(&a_updates[..]);
681 test_util::expect_schedule_sae_timeout(&a_updates[..]);
682 assert_eq!(a_updates.len(), 3, "{:?}", a_updates);
683
684 let mut s_updates = vec![];
686 for a_sae_frame in a_sae_frame_vec {
687 let result = supplicant.on_sae_frame_rx(&mut s_updates, a_sae_frame);
688 assert!(result.is_ok(), "Supplicant failed to rx SAE handshake message");
689 }
690 let s_sae_frame_vec = test_util::expect_sae_frame_vec(&s_updates[..]);
691 test_util::expect_schedule_sae_timeout(&s_updates[..]);
692 test_util::expect_reported_pmk(&s_updates[..]);
693 test_util::expect_reported_sae_auth_status(&s_updates[..], AuthStatus::Success);
694 test_util::expect_reported_status(&s_updates[..], SecAssocStatus::PmkSaEstablished);
695 assert_eq!(s_updates.len(), 5, "{:?}", s_updates);
696
697 let mut a_updates = vec![];
699 for s_sae_frame in s_sae_frame_vec {
700 let result = authenticator.on_sae_frame_rx(&mut a_updates, s_sae_frame);
701 assert!(result.is_ok(), "Authenticator failed to rx SAE handshake message");
702 }
703 test_util::expect_reported_pmk(&a_updates[..]);
704 test_util::expect_reported_sae_auth_status(&a_updates[..], AuthStatus::Success);
705 test_util::expect_reported_status(&a_updates[..], SecAssocStatus::PmkSaEstablished);
706 let msg1 = test_util::expect_eapol_resp(&a_updates[..]);
707 authenticator
708 .on_eapol_conf(&mut a_updates, EapolResultCode::Success)
709 .expect("Failed eapol conf");
710 assert_eq!(a_updates.len(), 4, "{:?}", a_updates);
711
712 test_eapol_exchange(&mut supplicant, &mut authenticator, Some(msg1), true);
713 }
714
715 #[test]
716 fn test_supplicant_with_wpa2_authenticator() {
717 let mut supplicant = test_util::get_wpa2_supplicant();
718 let mut authenticator = test_util::get_wpa2_authenticator();
719 let mut updates = vec![];
720 supplicant.start(&mut updates).expect("Failed starting Supplicant");
721 assert_eq!(updates.len(), 1, "{:?}", updates);
722 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
723 test_eapol_exchange(&mut supplicant, &mut authenticator, None, false);
724 }
725
726 #[test]
727 fn test_replay_first_message() {
728 let mut supplicant = test_util::get_wpa2_supplicant();
729 let mut updates = vec![];
730 supplicant.start(&mut updates).expect("Failed starting Supplicant");
731 assert_eq!(updates.len(), 1, "{:?}", updates);
732 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
733
734 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
736 msg1.key_frame_fields.key_replay_counter.set(1);
737 });
738 assert!(result.is_ok());
739 let first_msg2 = expect_eapol_resp(&updates[..]);
740 let first_fields = first_msg2.keyframe().key_frame_fields;
741
742 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
745 msg1.key_frame_fields.key_replay_counter = U64::new(3);
746 });
747 assert!(result.is_ok());
748 let second_msg2 = expect_eapol_resp(&updates[..]);
749 let second_fields = second_msg2.keyframe().key_frame_fields;
750
751 assert_eq!(second_fields.key_replay_counter.get(), 3);
753 assert_eq!(first_fields.key_nonce, second_fields.key_nonce);
754 }
755
756 #[test]
757 fn test_first_message_does_not_change_replay_counter() {
758 let mut supplicant = test_util::get_wpa2_supplicant();
759 let mut updates = vec![];
760 supplicant.start(&mut updates).expect("Failed starting Supplicant");
761 assert_eq!(updates.len(), 1, "{:?}", updates);
762 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
763
764 assert_eq!(0, supplicant.esssa.key_replay_counter);
765
766 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
768 msg1.key_frame_fields.key_replay_counter.set(0);
769 });
770 assert!(result.is_ok());
771 expect_eapol_resp(&updates[..]);
772 assert_eq!(0, supplicant.esssa.key_replay_counter);
773
774 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
776 msg1.key_frame_fields.key_replay_counter.set(1);
777 });
778 assert!(result.is_ok());
779 expect_eapol_resp(&updates[..]);
780 assert_eq!(0, supplicant.esssa.key_replay_counter);
781
782 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
784 msg1.key_frame_fields.key_replay_counter.set(0);
785 });
786 assert!(result.is_ok());
787 assert_eq!(0, supplicant.esssa.key_replay_counter);
788 expect_eapol_resp(&updates[..]);
789 }
790
791 #[test]
792 fn test_zero_key_replay_counter_msg1() {
793 let mut supplicant = test_util::get_wpa2_supplicant();
794 let mut updates = vec![];
795 supplicant.start(&mut updates).expect("Failed starting Supplicant");
796 assert_eq!(updates.len(), 1, "{:?}", updates);
797 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
798
799 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
800 msg1.key_frame_fields.key_replay_counter.set(0);
801 });
802 assert!(result.is_ok());
803 expect_eapol_resp(&updates[..]);
804 }
805
806 #[test]
807 fn test_nonzero_key_replay_counter_msg1() {
808 let mut supplicant = test_util::get_wpa2_supplicant();
809 let mut updates = vec![];
810 supplicant.start(&mut updates).expect("Failed starting Supplicant");
811 assert_eq!(updates.len(), 1, "{:?}", updates);
812 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
813
814 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
815 msg1.key_frame_fields.key_replay_counter.set(1);
816 });
817 assert!(result.is_ok());
818 expect_eapol_resp(&updates[..]);
819 }
820
821 #[test]
822 fn test_zero_key_replay_counter_lower_msg3_counter() {
823 let mut supplicant = test_util::get_wpa2_supplicant();
824 let mut updates = vec![];
825 supplicant.start(&mut updates).expect("Failed starting Supplicant");
826 assert_eq!(updates.len(), 1, "{:?}", updates);
827 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
828 assert_eq!(0, supplicant.esssa.key_replay_counter);
829
830 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
831 msg1.key_frame_fields.key_replay_counter.set(1);
832 });
833 assert!(result.is_ok());
834 assert_eq!(0, supplicant.esssa.key_replay_counter);
835
836 let msg2 = expect_eapol_resp(&updates[..]);
837 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
838 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
839
840 let (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
848 msg3.key_frame_fields.key_replay_counter = U64::new(0);
849 });
850 assert!(result.is_ok());
851 assert_eq!(0, supplicant.esssa.key_replay_counter);
852 test_util::expect_reported_ptk(&updates[..]);
853 }
854
855 #[test]
856 fn test_key_replay_counter_updated_after_msg3() {
857 let mut supplicant = test_util::get_wpa2_supplicant();
858 let mut updates = vec![];
859 let mut result;
860 supplicant.start(&mut updates).expect("Failed starting Supplicant");
861 assert_eq!(updates.len(), 1, "{:?}", updates);
862 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
863
864 (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
865 msg1.key_frame_fields.key_replay_counter.set(1);
866 });
867 assert!(result.is_ok());
868 let msg2 = expect_eapol_resp(&updates[..]);
869 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
870 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
871
872 (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
873 msg3.key_frame_fields.key_replay_counter = U64::new(5);
874 });
875 assert!(result.is_ok());
876 assert_eq!(5, supplicant.esssa.key_replay_counter);
877 test_util::expect_reported_ptk(&updates[..]);
878
879 (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
881 msg1.key_frame_fields.key_replay_counter.set(0);
882 });
883 assert!(result.is_ok());
884 assert_eq!(5, supplicant.esssa.key_replay_counter);
885 assert!(updates.is_empty(), "{:?}", updates);
886
887 supplicant.reset();
889 updates = vec![];
890 supplicant.start(&mut updates).expect("Failed starting Supplicant");
891 assert_eq!(updates.len(), 1, "{:?}", updates);
892 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
893 assert_eq!(0, supplicant.esssa.key_replay_counter);
894 let (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
895 msg1.key_frame_fields.key_replay_counter.set(0);
896 });
897 assert!(result.is_ok());
898 expect_eapol_resp(&updates[..]);
899 }
900
901 #[test]
902 fn test_key_replay_counter_not_updated_for_invalid_mic_msg3() {
903 let mut supplicant = test_util::get_wpa2_supplicant();
904 let mut updates = vec![];
905 let mut result: Result<(), Error>;
906 supplicant.start(&mut updates).expect("Failed starting Supplicant");
907 assert_eq!(updates.len(), 1, "{:?}", updates);
908 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
909
910 (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
911 msg1.key_frame_fields.key_replay_counter.set(1);
912 });
913 assert!(result.is_ok());
914 assert_eq!(0, supplicant.esssa.key_replay_counter);
915
916 let msg2 = expect_eapol_resp(&updates[..]);
917 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
918 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
919
920 let msg3 = test_util::get_wpa2_4whs_msg3_with_mic_modifier(
921 &ptk,
922 &ANONCE[..],
923 >K,
924 |msg3| {
925 msg3.key_frame_fields.key_replay_counter = U64::new(5);
926 },
927 |mic| {
928 mic[0] = mic[0].wrapping_add(1);
929 },
930 );
931 updates = UpdateSink::default();
932 result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg3.keyframe()));
933 assert!(result.is_ok());
934 assert_eq!(0, supplicant.esssa.key_replay_counter);
936 }
937
938 #[test]
939 fn test_zero_key_replay_counter_valid_msg3() {
940 let mut supplicant = test_util::get_wpa2_supplicant();
941 let mut updates = vec![];
942 let mut result;
943 supplicant.start(&mut updates).expect("Failed starting Supplicant");
944 assert_eq!(updates.len(), 1, "{:?}", updates);
945 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
946
947 (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
948 msg1.key_frame_fields.key_replay_counter.set(0);
949 });
950 assert!(result.is_ok());
951 let msg2 = expect_eapol_resp(&updates[..]);
952 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
953 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
954
955 (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
956 msg3.key_frame_fields.key_replay_counter = U64::new(1);
957 });
958 assert!(result.is_ok());
959 test_util::expect_reported_ptk(&updates[..]);
960 }
961
962 #[test]
963 fn test_zero_key_replay_counter_replayed_msg3() {
964 let mut supplicant = test_util::get_wpa2_supplicant();
965 let mut updates = vec![];
966 let mut result;
967 supplicant.start(&mut updates).expect("Failed starting Supplicant");
968 assert_eq!(updates.len(), 1, "{:?}", updates);
969 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
970 assert_eq!(0, supplicant.esssa.key_replay_counter);
971
972 (result, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
973 msg1.key_frame_fields.key_replay_counter.set(0);
974 });
975 assert!(result.is_ok());
976 let msg2 = expect_eapol_resp(&updates[..]);
977 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
978 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
979
980 (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
981 msg3.key_frame_fields.key_replay_counter.set(2);
982 });
983 assert!(result.is_ok());
984 assert_eq!(2, supplicant.esssa.key_replay_counter);
985 test_util::expect_reported_ptk(&updates[..]);
986
987 (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
992 msg3.key_frame_fields.key_replay_counter.set(2);
993 });
994 assert!(result.is_ok());
995 assert_eq!(2, supplicant.esssa.key_replay_counter);
996 assert!(updates.is_empty(), "{:?}", updates);
997
998 (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |msg3| {
1000 msg3.key_frame_fields.key_replay_counter = U64::new(3);
1001 });
1002 assert!(result.is_ok());
1003 assert_eq!(3, supplicant.esssa.key_replay_counter);
1004 assert!(!updates.is_empty());
1005 }
1006
1007 #[test]
1012 fn test_replayed_msg1_ptk_installation_different_anonces() {
1013 let mut supplicant = test_util::get_wpa2_supplicant();
1014 let mut updates = vec![];
1015 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1016 assert_eq!(updates.len(), 1, "{:?}", updates);
1017 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1018
1019 let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1021 msg1.key_frame_fields.key_replay_counter.set(1);
1022 });
1023 assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1024 let msg2 = expect_eapol_resp(&updates[..]);
1025 let msg2_frame = msg2.keyframe();
1026 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1027 let first_ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1028 let first_nonce = msg2_frame.key_frame_fields.key_nonce;
1029
1030 let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1033 msg1.key_frame_fields.key_replay_counter.set(2);
1034 msg1.key_frame_fields.key_nonce = [99; 32];
1035 });
1036 assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1037 let msg2 = expect_eapol_resp(&updates[..]);
1038 let msg2_frame = msg2.keyframe();
1039 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1040 let second_ptk = test_util::get_ptk(&[99; 32][..], &snonce[..]);
1041 let second_nonce = msg2_frame.key_frame_fields.key_nonce;
1042
1043 let (_, updates) = send_fourway_msg3(&mut supplicant, &second_ptk, |msg3| {
1047 msg3.key_frame_fields.key_replay_counter.set(3);
1048 msg3.key_frame_fields.key_nonce = [99; 32];
1049 });
1050
1051 let installed_ptk = test_util::expect_reported_ptk(&updates[..]);
1052 assert_ne!(first_nonce, second_nonce);
1053 assert_ne!(&first_ptk, &second_ptk);
1054 assert_eq!(installed_ptk, second_ptk);
1055 }
1056
1057 #[test]
1063 fn test_replayed_msg1_ptk_installation_same_anonces() {
1064 let mut supplicant = test_util::get_wpa2_supplicant();
1065 let mut updates = vec![];
1066 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1067 assert_eq!(updates.len(), 1, "{:?}", updates);
1068 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1069
1070 let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1072 msg1.key_frame_fields.key_replay_counter.set(1);
1073 });
1074 assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1075 let msg2 = expect_eapol_resp(&updates[..]);
1076 let msg2_frame = msg2.keyframe();
1077 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1078 let first_ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1079 let first_nonce = msg2_frame.key_frame_fields.key_nonce;
1080
1081 let (_, updates) = send_fourway_msg1(&mut supplicant, |msg1| {
1083 msg1.key_frame_fields.key_replay_counter.set(2);
1084 });
1085 assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1086 let msg2 = expect_eapol_resp(&updates[..]);
1087 let msg2_frame = msg2.keyframe();
1088 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1089 let second_ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1090 let second_nonce = msg2_frame.key_frame_fields.key_nonce;
1091
1092 let (_, updates) = send_fourway_msg3(&mut supplicant, &second_ptk, |msg3| {
1095 msg3.key_frame_fields.key_replay_counter.set(3);
1096 });
1097
1098 let installed_ptk = test_util::expect_reported_ptk(&updates[..]);
1099 assert_eq!(first_nonce, second_nonce);
1100 assert_eq!(&first_ptk, &second_ptk);
1101 assert_eq!(installed_ptk, second_ptk);
1102 }
1103
1104 #[test]
1106 fn test_supplicant_wpa2_ccmp128_psk() {
1107 let mut supplicant = test_util::get_wpa2_supplicant();
1109 let mut updates = vec![];
1110 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1111 assert_eq!(updates.len(), 1, "{:?}", updates);
1112 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1113
1114 let (result, updates) = send_fourway_msg1(&mut supplicant, |_| {});
1116 assert!(result.is_ok());
1117
1118 let msg2_buf = expect_eapol_resp(&updates[..]);
1120 let msg2 = msg2_buf.keyframe();
1121 let s_rsne = fake_wpa2_s_rsne();
1122 let s_rsne_data = get_rsn_ie_bytes(&s_rsne);
1123 assert_eq!({ msg2.eapol_fields.version }, eapol::ProtocolVersion::IEEE802DOT1X2001);
1124 assert_eq!({ msg2.eapol_fields.packet_type }, eapol::PacketType::KEY);
1125 let buf = msg2.to_bytes(false);
1126 assert_eq!(msg2.eapol_fields.packet_body_len.get() as usize, buf.len() - 4);
1127 assert_eq!({ msg2.key_frame_fields.descriptor_type }, eapol::KeyDescriptor::IEEE802DOT11);
1128 assert_eq!(msg2.key_frame_fields.key_info(), eapol::KeyInformation(0x010A));
1129 assert_eq!(msg2.key_frame_fields.key_len.get(), 0);
1130 assert_eq!(msg2.key_frame_fields.key_replay_counter.get(), 1);
1131 assert!(!test_util::is_zero(&msg2.key_frame_fields.key_nonce[..]));
1132 assert!(test_util::is_zero(&msg2.key_frame_fields.key_iv[..]));
1133 assert_eq!(msg2.key_frame_fields.key_rsc.get(), 0);
1134 assert!(!test_util::is_zero(&msg2.key_mic[..]));
1135 assert_eq!(msg2.key_mic.len(), test_util::mic_len());
1136 assert_eq!(msg2.key_data.len(), 20);
1137 assert_eq!(&msg2.key_data[..], &s_rsne_data[..]);
1138
1139 let snonce = msg2.key_frame_fields.key_nonce;
1141 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1142 let (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1143 assert!(result.is_ok());
1144
1145 let msg4_buf = expect_eapol_resp(&updates[..]);
1147 let msg4 = msg4_buf.keyframe();
1148 assert_eq!({ msg4.eapol_fields.version }, eapol::ProtocolVersion::IEEE802DOT1X2001);
1149 assert_eq!({ msg4.eapol_fields.packet_type }, eapol::PacketType::KEY);
1150 assert_eq!(msg4.eapol_fields.packet_body_len.get() as usize, &msg4_buf[..].len() - 4);
1151 assert_eq!({ msg4.key_frame_fields.descriptor_type }, eapol::KeyDescriptor::IEEE802DOT11);
1152 assert_eq!(msg4.key_frame_fields.key_info(), eapol::KeyInformation(0x030A));
1153 assert_eq!(msg4.key_frame_fields.key_len.get(), 0);
1154 assert_eq!(msg4.key_frame_fields.key_replay_counter.get(), 2);
1155 assert!(test_util::is_zero(&msg4.key_frame_fields.key_nonce[..]));
1156 assert!(test_util::is_zero(&msg4.key_frame_fields.key_iv[..]));
1157 assert_eq!(msg4.key_frame_fields.key_rsc.get(), 0);
1158 assert!(!test_util::is_zero(&msg4.key_mic[..]));
1159 assert_eq!(msg4.key_mic.len(), test_util::mic_len());
1160 assert_eq!(msg4.key_data.len(), 0);
1161 assert!(test_util::is_zero(&msg4.key_data[..]));
1162 let mic = compute_mic(ptk.kck(), &test_util::get_rsne_protection(), &msg4)
1164 .expect("error computing MIC");
1165 assert_eq!(&msg4.key_mic[..], &mic[..]);
1166
1167 let reported_ptk = test_util::expect_reported_ptk(&updates[..]);
1169 assert_eq!(ptk.ptk, reported_ptk.ptk);
1170
1171 let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1173 assert_eq!(>K[..], &reported_gtk.bytes[..]);
1174
1175 let reported_status =
1177 test_util::expect_reported_status(&updates[..], SecAssocStatus::EssSaEstablished);
1178 assert_eq!(reported_status, SecAssocStatus::EssSaEstablished);
1179
1180 let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY, 3, 3);
1183 assert!(result.is_ok());
1184
1185 let msg2_buf = expect_eapol_resp(&updates[..]);
1187 let msg2 = msg2_buf.keyframe();
1188 assert_eq!({ msg2.eapol_fields.version }, eapol::ProtocolVersion::IEEE802DOT1X2001);
1189 assert_eq!({ msg2.eapol_fields.packet_type }, eapol::PacketType::KEY);
1190 assert_eq!(msg2.eapol_fields.packet_body_len.get() as usize, &msg2_buf[..].len() - 4);
1191 assert_eq!({ msg2.key_frame_fields.descriptor_type }, eapol::KeyDescriptor::IEEE802DOT11);
1192 assert_eq!(msg2.key_frame_fields.key_info(), eapol::KeyInformation(0x0302));
1193 assert_eq!(msg2.key_frame_fields.key_len.get(), 0);
1194 assert_eq!(msg2.key_frame_fields.key_replay_counter.get(), 3);
1195 assert!(test_util::is_zero(&msg2.key_frame_fields.key_nonce[..]));
1196 assert!(test_util::is_zero(&msg2.key_frame_fields.key_iv[..]));
1197 assert_eq!(msg2.key_frame_fields.key_rsc.get(), 0);
1198 assert!(!test_util::is_zero(&msg2.key_mic[..]));
1199 assert_eq!(msg2.key_mic.len(), test_util::mic_len());
1200 assert_eq!(msg2.key_data.len(), 0);
1201 assert!(test_util::is_zero(&msg2.key_data[..]));
1202 let mic = compute_mic(ptk.kck(), &test_util::get_rsne_protection(), &msg2)
1204 .expect("error computing MIC");
1205 assert_eq!(&msg2.key_mic[..], &mic[..]);
1206
1207 assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1209
1210 let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1212 assert_eq!(>K_REKEY[..], &reported_gtk.bytes[..]);
1213 }
1214
1215 #[test]
1218 fn test_supplicant_no_gtk_reinstallation_from_4way() {
1219 let mut supplicant = test_util::get_wpa2_supplicant();
1221 let mut updates = vec![];
1222 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1223 assert_eq!(updates.len(), 1, "{:?}", updates);
1224 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1225
1226 let updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1228 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1229 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1230 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1231 let _ = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1232
1233 let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK, 2, 3);
1237 assert!(result.is_ok());
1238
1239 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1241 let keyframe = msg2.keyframe();
1242 assert_eq!(keyframe.eapol_fields.version, eapol::ProtocolVersion::IEEE802DOT1X2001);
1243 assert_eq!(keyframe.eapol_fields.packet_type, eapol::PacketType::KEY);
1244 assert_eq!(keyframe.eapol_fields.packet_body_len.get() as usize, msg2.len() - 4);
1245 assert_eq!(keyframe.key_frame_fields.descriptor_type, eapol::KeyDescriptor::IEEE802DOT11);
1246 assert_eq!(keyframe.key_frame_fields.key_info().0, 0x0302);
1247 assert_eq!(keyframe.key_frame_fields.key_len.get(), 0);
1248 assert_eq!(keyframe.key_frame_fields.key_replay_counter.get(), 3);
1249 assert!(test_util::is_zero(&keyframe.key_frame_fields.key_nonce[..]));
1250 assert!(test_util::is_zero(&keyframe.key_frame_fields.key_iv[..]));
1251 assert_eq!(keyframe.key_frame_fields.key_rsc.get(), 0);
1252 assert!(!test_util::is_zero(&keyframe.key_mic[..]));
1253 assert_eq!(keyframe.key_mic.len(), test_util::mic_len());
1254 assert_eq!(keyframe.key_data.len(), 0);
1255 assert!(test_util::is_zero(&keyframe.key_data[..]));
1256 let mic = compute_mic(ptk.kck(), &test_util::get_rsne_protection(), &keyframe)
1258 .expect("error computing MIC");
1259 assert_eq!(&keyframe.key_mic[..], &mic[..]);
1260
1261 assert_eq!(test_util::get_reported_ptk(&updates[..]), None);
1263 assert_eq!(test_util::get_reported_gtk(&updates[..]), None);
1264 }
1265
1266 #[test]
1268 fn test_supplicant_no_gtk_reinstallation() {
1269 let mut supplicant = test_util::get_wpa2_supplicant();
1271 let mut updates = vec![];
1272 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1273 assert_eq!(updates.len(), 1, "{:?}", updates);
1274 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1275
1276 let updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1278 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1279 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1280 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1281 let _ = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1282
1283 let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY, 3, 3);
1289 assert!(result.is_ok());
1290 let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1291 assert_eq!(&reported_gtk.bytes[..], >K_REKEY[..]);
1292
1293 let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY_2, 1, 4);
1294 assert!(result.is_ok(), "{:?}", result);
1295 let reported_gtk = test_util::expect_reported_gtk(&updates[..]);
1296 assert_eq!(&reported_gtk.bytes[..], >K_REKEY_2[..]);
1297
1298 let (result, updates) = send_group_key_msg1(&mut supplicant, &ptk, GTK_REKEY, 3, 5);
1300 assert!(result.is_ok());
1301 assert_eq!(test_util::get_reported_gtk(&updates[..]), None);
1302 }
1303
1304 #[test]
1305 fn test_rsna_retransmission_timeout() {
1306 let mut supplicant = test_util::get_wpa2_supplicant();
1308 let mut updates = vec![];
1309 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1310 assert_eq!(updates.len(), 1, "{:?}", updates);
1311 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1312
1313 updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1315 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1316
1317 updates = vec![];
1319 supplicant
1320 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1321 .expect("Failed to send eapol conf");
1322 assert!(updates.is_empty());
1323
1324 for _ in 1..MAX_KEY_FRAME_RETRIES {
1326 updates = vec![];
1327 supplicant
1328 .on_rsna_retransmission_timeout(&mut updates)
1329 .expect("Failed to send key frame timeout");
1330 let msg2_retry = test_util::expect_eapol_resp(&updates[..]);
1331 supplicant
1332 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1333 .expect("Failed to send eapol conf");
1334 assert_eq!(msg2, msg2_retry);
1335 }
1336
1337 updates = vec![];
1339 assert_matches!(supplicant.on_rsna_retransmission_timeout(&mut updates), Ok(()));
1340 assert!(updates.is_empty(), "{:?}", updates);
1341 }
1342
1343 #[test]
1344 fn test_rsna_retransmission_timeout_retries_reset() {
1345 let mut supplicant = test_util::get_wpa2_supplicant();
1347 let mut updates = vec![];
1348 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1349 assert_eq!(updates.len(), 1, "{:?}", updates);
1350 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1351
1352 for _ in 0..3 {
1353 updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1355 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1356 updates = vec![];
1357 supplicant
1358 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1359 .expect("Failed to send eapol conf");
1360 assert!(updates.is_empty(), "{:?}", updates);
1361
1362 for _ in 1..MAX_KEY_FRAME_RETRIES {
1364 updates = vec![];
1365 supplicant
1366 .on_rsna_retransmission_timeout(&mut updates)
1367 .expect("Failed to send key frame timeout");
1368 let msg2_retry = test_util::expect_eapol_resp(&updates[..]);
1369 supplicant
1370 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1371 .expect("Failed to send eapol conf");
1372 assert_eq!(msg2, msg2_retry);
1373 }
1374
1375 updates = vec![];
1377 assert_matches!(supplicant.on_rsna_retransmission_timeout(&mut updates), Ok(()));
1378 assert!(updates.is_empty(), "{:?}", updates);
1379 }
1380 }
1381
1382 #[test]
1383 fn test_overall_timeout_before_msg1() {
1384 let mut supplicant = test_util::get_wpa2_supplicant();
1386 let mut updates = vec![];
1387 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1388 assert_eq!(updates.len(), 1, "{:?}", updates);
1389 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1390
1391 assert_matches!(supplicant.incomplete_reason(), Error::EapolHandshakeNotStarted);
1392 }
1393
1394 #[test]
1395 fn test_overall_timeout_after_msg2() {
1396 let mut supplicant = test_util::get_wpa2_supplicant();
1398 let mut updates = vec![];
1399 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1400 assert_eq!(updates.len(), 1, "{:?}", updates);
1401 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1402
1403 (_, updates) = send_fourway_msg1(&mut supplicant, |_| {});
1405 let _msg2 = test_util::expect_eapol_resp(&updates[..]);
1406
1407 updates = vec![];
1409 supplicant
1410 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1411 .expect("Failed to send eapol conf");
1412 assert!(updates.is_empty(), "{:?}", updates);
1413
1414 assert_matches!(supplicant.incomplete_reason(), Error::LikelyWrongCredential);
1415 }
1416
1417 #[test]
1418 fn test_overall_timeout_before_conf() {
1419 let mut supplicant = test_util::get_wpa2_supplicant();
1421 let mut updates = UpdateSink::default();
1422 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1423 assert_eq!(updates.len(), 1, "{:?}", updates);
1424 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1425
1426 let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], |_| {});
1428 supplicant
1429 .on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()))
1430 .expect("Failed to send eapol frame");
1431 let _msg2 = test_util::expect_eapol_resp(&updates[..]);
1432
1433 assert_matches!(supplicant.incomplete_reason(), Error::NoKeyFrameTransmissionConfirm(0));
1434 }
1435
1436 #[test]
1437 fn test_rsna_retransmission_timeout_retry_without_conf() {
1438 let mut supplicant = test_util::get_wpa2_supplicant();
1440 let mut updates = vec![];
1441 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1442 assert_eq!(updates.len(), 1, "{:?}", updates);
1443 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1444
1445 updates = send_fourway_msg1(&mut supplicant, |_| {}).1;
1447 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1448
1449 updates = vec![];
1451 supplicant
1452 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1453 .expect("Failed to send eapol conf");
1454 assert!(updates.is_empty(), "{:?}", updates);
1455
1456 updates = vec![];
1458 supplicant
1459 .on_rsna_retransmission_timeout(&mut updates)
1460 .expect("Failed to send key frame timeout");
1461 let msg2_retry = test_util::expect_eapol_resp(&updates[..]);
1462 assert_eq!(msg2, msg2_retry);
1463
1464 updates = vec![];
1466 assert_matches!(
1467 supplicant.on_rsna_retransmission_timeout(&mut updates),
1468 Err(Error::NoKeyFrameTransmissionConfirm(0))
1469 );
1470 }
1471
1472 #[test]
1473 fn test_msg2_out_of_order_conf() {
1474 let mut supplicant = test_util::get_wpa2_supplicant();
1476 let mut updates = UpdateSink::default();
1477 let result: Result<(), Error>;
1478 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1479 assert_eq!(updates.len(), 1, "{:?}", updates);
1480 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1481
1482 let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], |_| {});
1484 supplicant
1485 .on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()))
1486 .expect("Failed to send eapol frame");
1487 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1488
1489 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1491 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1492 (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1493 result.expect("Failed to send msg3");
1494 assert!(updates.is_empty(), "{:?}", updates);
1495
1496 updates = UpdateSink::default();
1498 supplicant
1499 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1500 .expect("Failed to send eapol conf");
1501 assert_eq!(updates.len(), 3);
1502 test_util::expect_eapol_resp(&updates[..]);
1503 test_util::expect_reported_ptk(&updates[..]);
1504 test_util::expect_reported_gtk(&updates[..]);
1505
1506 supplicant
1508 .on_eapol_conf(&mut updates, EapolResultCode::Success)
1509 .expect("Failed to send eapol conf");
1510 test_util::expect_reported_status(&updates[..], SecAssocStatus::EssSaEstablished);
1511 }
1512
1513 #[test]
1514 fn test_msg2_no_conf() {
1515 let mut supplicant = test_util::get_wpa2_supplicant();
1517 let mut updates = UpdateSink::default();
1518 let result: Result<(), Error>;
1519 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1520 assert_eq!(updates.len(), 1, "{:?}", updates);
1521 test_util::expect_reported_status(&updates[..], SecAssocStatus::PmkSaEstablished);
1522
1523 let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], |_| {});
1525 supplicant
1526 .on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()))
1527 .expect("Failed to send eapol frame");
1528 let msg2 = test_util::expect_eapol_resp(&updates[..]);
1529
1530 let snonce = msg2.keyframe().key_frame_fields.key_nonce;
1532 let ptk = test_util::get_ptk(&ANONCE[..], &snonce[..]);
1533 (result, updates) = send_fourway_msg3(&mut supplicant, &ptk, |_| {});
1534 result.expect("Failed to send msg3");
1535 assert!(updates.is_empty(), "{:?}", updates);
1536
1537 updates = vec![];
1544 assert_matches!(
1545 supplicant.on_rsna_retransmission_timeout(&mut updates),
1546 Err(Error::NoKeyFrameTransmissionConfirm(4))
1547 );
1548 }
1549
1550 fn test_eapol_exchange(
1557 supplicant: &mut Supplicant,
1558 authenticator: &mut Authenticator,
1559 msg1: Option<eapol::KeyFrameBuf>,
1560 wpa3: bool,
1561 ) {
1562 let mut a_updates = vec![];
1564 let mut result: Result<(), Error>;
1565 result = authenticator.initiate(&mut a_updates);
1566 assert!(result.is_ok(), "Authenticator failed initiating: {}", result.unwrap_err());
1567
1568 if wpa3 {
1569 assert!(
1570 msg1.is_some(),
1571 "WPA3 EAPOL exchange starting without message constructed immediately after SAE"
1572 );
1573 }
1574 let msg1 = match msg1 {
1577 Some(msg1) => {
1578 assert_eq!(a_updates.len(), 0, "{:?}", a_updates);
1579 msg1
1580 }
1581 None => {
1582 assert_eq!(a_updates.len(), 2);
1583 test_util::expect_reported_status(&a_updates, SecAssocStatus::PmkSaEstablished);
1584 let resp = test_util::expect_eapol_resp(&a_updates[..]);
1585 authenticator
1586 .on_eapol_conf(&mut a_updates, EapolResultCode::Success)
1587 .expect("Failed eapol conf");
1588 resp
1589 }
1590 };
1591
1592 let mut s_updates = vec![];
1594 result = supplicant.on_eapol_frame(&mut s_updates, eapol::Frame::Key(msg1.keyframe()));
1595 assert!(result.is_ok(), "Supplicant failed processing msg #1: {}", result.unwrap_err());
1596 let msg2 = test_util::expect_eapol_resp(&s_updates[..]);
1597 supplicant
1598 .on_eapol_conf(&mut s_updates, EapolResultCode::Success)
1599 .expect("Failed eapol conf");
1600 assert_eq!(s_updates.len(), 1, "{:?}", s_updates);
1601
1602 let mut a_updates = vec![];
1604 result = authenticator.on_eapol_frame(&mut a_updates, eapol::Frame::Key(msg2.keyframe()));
1605 assert!(result.is_ok(), "Authenticator failed processing msg #2: {}", result.unwrap_err());
1606 let msg3 = test_util::expect_eapol_resp(&a_updates[..]);
1607 authenticator
1608 .on_eapol_conf(&mut a_updates, EapolResultCode::Success)
1609 .expect("Failed eapol conf");
1610 assert_eq!(a_updates.len(), 1, "{:?}", a_updates);
1611
1612 let mut s_updates = vec![];
1614 result = supplicant.on_eapol_frame(&mut s_updates, eapol::Frame::Key(msg3.keyframe()));
1615 assert!(result.is_ok(), "Supplicant failed processing msg #3: {}", result.unwrap_err());
1616
1617 let msg4 = test_util::expect_eapol_resp(&s_updates[..]);
1618 let s_ptk = test_util::expect_reported_ptk(&s_updates[..]);
1619 let s_gtk = test_util::expect_reported_gtk(&s_updates[..]);
1620 let s_igtk = if wpa3 {
1621 assert_eq!(s_updates.len(), 4, "{:?}", s_updates);
1622 Some(test_util::expect_reported_igtk(&s_updates[..]))
1623 } else {
1624 assert_eq!(s_updates.len(), 3, "{:?}", s_updates);
1625 None
1626 };
1627
1628 supplicant
1630 .on_eapol_conf(&mut s_updates, EapolResultCode::Success)
1631 .expect("Failed eapol conf");
1632 test_util::expect_reported_status(&s_updates, SecAssocStatus::EssSaEstablished);
1633
1634 let mut a_updates = vec![];
1636 result = authenticator.on_eapol_frame(&mut a_updates, eapol::Frame::Key(msg4.keyframe()));
1637 assert!(result.is_ok(), "Authenticator failed processing msg #4: {}", result.unwrap_err());
1638 let a_ptk = test_util::expect_reported_ptk(&a_updates[..]);
1639 let a_gtk = test_util::expect_reported_gtk(&a_updates[..]);
1640
1641 let a_igtk = if wpa3 {
1642 assert_eq!(a_updates.len(), 4, "{:?}", a_updates);
1643 Some(test_util::expect_reported_igtk(&a_updates[..]))
1644 } else {
1645 assert_eq!(a_updates.len(), 3, "{:?}", a_updates);
1646 None
1647 };
1648
1649 test_util::expect_reported_status(&a_updates, SecAssocStatus::EssSaEstablished);
1650
1651 assert_eq!(a_ptk, s_ptk);
1653 assert_eq!(a_gtk, s_gtk);
1654 assert_eq!(a_igtk, s_igtk);
1655 }
1656
1657 fn send_eapol_conf(supplicant: &mut Supplicant, updates: &mut UpdateSink) -> Result<(), Error> {
1658 let mut sent_frame = false;
1659 for update in &updates[..] {
1660 if let SecAssocUpdate::TxEapolKeyFrame { .. } = update {
1661 sent_frame = true;
1662 }
1663 }
1664 if sent_frame {
1665 supplicant.on_eapol_conf(updates, EapolResultCode::Success)
1666 } else {
1667 Ok(())
1668 }
1669 }
1670
1671 fn send_fourway_msg1<F>(
1672 supplicant: &mut Supplicant,
1673 msg_modifier: F,
1674 ) -> (Result<(), Error>, UpdateSink)
1675 where
1676 F: Fn(&mut eapol::KeyFrameTx),
1677 {
1678 let msg = test_util::get_wpa2_4whs_msg1(&ANONCE[..], msg_modifier);
1679 let mut updates = UpdateSink::default();
1680 let result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()));
1681 let result = result.and_then(|_| send_eapol_conf(supplicant, &mut updates));
1682 (result, updates)
1683 }
1684
1685 fn send_fourway_msg3<F>(
1686 supplicant: &mut Supplicant,
1687 ptk: &Ptk,
1688 msg_modifier: F,
1689 ) -> (Result<(), Error>, UpdateSink)
1690 where
1691 F: Fn(&mut eapol::KeyFrameTx),
1692 {
1693 let msg = test_util::get_wpa2_4whs_msg3(ptk, &ANONCE[..], >K, msg_modifier);
1694 let mut updates = UpdateSink::default();
1695 let result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()));
1696 let result = result.and_then(|_| send_eapol_conf(supplicant, &mut updates));
1697 (result, updates)
1698 }
1699
1700 fn send_group_key_msg1(
1701 supplicant: &mut Supplicant,
1702 ptk: &Ptk,
1703 gtk: [u8; 16],
1704 key_id: u8,
1705 key_replay_counter: u64,
1706 ) -> (Result<(), Error>, UpdateSink) {
1707 let msg = test_util::get_group_key_hs_msg1(ptk, >k[..], key_id, key_replay_counter);
1708 let mut updates = UpdateSink::default();
1709 let result = supplicant.on_eapol_frame(&mut updates, eapol::Frame::Key(msg.keyframe()));
1710 let result = result.and_then(|_| send_eapol_conf(supplicant, &mut updates));
1711 (result, updates)
1712 }
1713
1714 #[test]
1715 fn test_key_confirmed_gtk_replay_prevention() {
1716 let mut supplicant = test_util::get_wpa2_supplicant();
1717 let mut authenticator = test_util::get_wpa2_authenticator();
1718 let mut updates = vec![];
1719 supplicant.start(&mut updates).expect("Failed starting Supplicant");
1720
1721 test_eapol_exchange(&mut supplicant, &mut authenticator, None, false);
1723
1724 updates.clear();
1726
1727 let installed_gtk = match &*supplicant.esssa.gtksa {
1729 Gtksa::Established { installed_gtks, .. } => {
1730 installed_gtks.iter().next().expect("no GTK installed").clone()
1731 }
1732 _ => panic!("GTKSA not established"),
1733 };
1734
1735 let gtk_reinstall = Gtk::from_bytes(
1737 installed_gtk.bytes.clone(),
1738 installed_gtk.cipher().clone(),
1739 installed_gtk.key_id(),
1740 installed_gtk.key_rsc() + 10, )
1742 .expect("failed to create GTK");
1743
1744 let result = supplicant.esssa.on_key_confirmed(&mut updates, Key::Gtk(gtk_reinstall));
1746 assert!(result.is_ok());
1747
1748 assert!(
1750 updates.is_empty(),
1751 "Expected no key update for reinstalled GTK with different RSC, got: {:?}",
1752 updates
1753 );
1754 }
1755
1756 #[test]
1757 fn test_key_confirmed_igtk_replay_prevention() {
1758 let mut supplicant = test_util::get_wpa3_supplicant();
1759
1760 let igtk_bytes = vec![0x11; 16];
1762 let ipn1 = [0xaa; 6];
1763 let cipher = wlan_common::ie::rsn::cipher::CIPHER_BIP_CMAC_128;
1764
1765 let igtk1 = Igtk { igtk: igtk_bytes.clone(), key_id: 4, ipn: ipn1, cipher: cipher.clone() };
1766
1767 let mut updates = vec![];
1768
1769 let result = supplicant.esssa.on_key_confirmed(&mut updates, Key::Igtk(igtk1));
1771 assert!(result.is_ok());
1772 assert_eq!(updates.len(), 1);
1773 assert_matches!(updates[0], SecAssocUpdate::Key(Key::Igtk(_)));
1774
1775 updates.clear();
1776
1777 let ipn2 = [0xbb; 6];
1780 let igtk2 = Igtk { igtk: igtk_bytes, key_id: 4, ipn: ipn2, cipher };
1781
1782 let result = supplicant.esssa.on_key_confirmed(&mut updates, Key::Igtk(igtk2));
1783 assert!(result.is_ok());
1784 assert!(
1785 updates.is_empty(),
1786 "Expected no key update for reinstalled IGTK with different IPN, got: {:?}",
1787 updates
1788 );
1789 }
1790}