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