bss->oci_freq_override_wnm_sleep = atoi(pos);
} else if (os_strcmp(buf, "eap_skip_prot_success") == 0) {
bss->eap_skip_prot_success = atoi(pos);
+ } else if (os_strcmp(buf, "delay_eapol_tx") == 0) {
+ conf->delay_eapol_tx = atoi(pos);
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_SAE
} else if (os_strcmp(buf, "sae_password") == 0) {
# Include only ECSA IE without CSA IE where possible
# (channel switch operating class is needed)
#ecsa_ie_only=0
+#
+# Delay EAPOL-Key messages 1/4 and 3/4 by not sending the frame until the last
+# attempt (wpa_pairwise_update_count). This will trigger a timeout on all
+# previous attempts and thus delays the frame. (testing only)
+#delay_eapol_tx=0
##### Multiple BSSID support ##################################################
#
double ignore_reassoc_probability;
double corrupt_gtk_rekey_mic_probability;
int ecsa_ie_only;
+ bool delay_eapol_tx;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_ACS
if (!sm)
return;
+ ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr;
+
+#ifdef CONFIG_TESTING_OPTIONS
+ /* When delay_eapol_tx is true, delay the EAPOL-Key transmission by
+ * sending it only on the last attempt after all timeouts for the prior
+ * skipped attemps. */
+ if (wpa_auth->conf.delay_eapol_tx &&
+ ctr != wpa_auth->conf.wpa_pairwise_update_count) {
+ wpa_msg(sm->wpa_auth->conf.msg_ctx, MSG_INFO,
+ "DELAY-EAPOL-TX-%d", ctr);
+ goto skip_tx;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
__wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len,
keyidx, encr, 0);
+#ifdef CONFIG_TESTING_OPTIONS
+skip_tx:
+#endif /* CONFIG_TESTING_OPTIONS */
- ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr;
if (ctr == 1 && wpa_auth->conf.tx_status)
timeout_ms = pairwise ? eapol_key_timeout_first :
eapol_key_timeout_first_group;
unsigned int gtk_rsc_override_set:1;
unsigned int igtk_rsc_override_set:1;
int ft_rsnxe_used;
+ bool delay_eapol_tx;
#endif /* CONFIG_TESTING_OPTIONS */
unsigned int oci_freq_override_eapol_m3;
unsigned int oci_freq_override_eapol_g1;
#ifdef CONFIG_TESTING_OPTIONS
wconf->corrupt_gtk_rekey_mic_probability =
iconf->corrupt_gtk_rekey_mic_probability;
+ wconf->delay_eapol_tx = iconf->delay_eapol_tx;
if (conf->own_ie_override &&
wpabuf_len(conf->own_ie_override) <= MAX_OWN_IE_OVERRIDE) {
wconf->own_ie_override_len = wpabuf_len(conf->own_ie_override);
raise Exception("Unexpected connection")
finally:
dev[0].set("pmf", "0")
+
+def test_ap_pmf_drop_robust_mgmt_prior_to_keys_installation(dev, apdev):
+ """Drop non protected Robust Action frames prior to keys installation"""
+ ssid = "test-pmf-required"
+ passphrase = '12345678'
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+ params['delay_eapol_tx'] = '1'
+ params['ieee80211w'] = '2'
+ params['wpa_pairwise_update_count'] = '5'
+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+
+ # Spectrum management with Channel Switch element
+ msg = {'fc': 0x00d0,
+ 'sa': hapd.own_addr(),
+ 'da': dev[0].own_addr(),
+ 'bssid': hapd.own_addr(),
+ 'payload': binascii.unhexlify('00042503000608')
+ }
+
+ dev[0].connect(ssid, psk=passphrase, scan_freq='2412', ieee80211w='1',
+ wait_connect=False)
+
+ # wait for the first delay before sending the frame
+ ev = hapd.wait_event(['DELAY-EAPOL-TX-1'], timeout=10)
+ if ev is None:
+ raise Exception("EAPOL is not delayed")
+
+ # send the Action frame while connecting (prior to keys installation)
+ hapd.mgmt_tx(msg)
+
+ dev[0].wait_connected(timeout=10, error="Timeout on connection")
+ hapd.wait_sta()
+ hwsim_utils.test_connectivity(dev[0], hapd)
+
+ # Verify no channel switch event
+ ev = dev[0].wait_event(['CTRL-EVENT-STARTED-CHANNEL-SWITCH'], timeout=5)
+ if ev is not None:
+ raise Exception("Unexpected CSA prior to keys installation")
+
+ # Send the frame after keys installation and verify channel switch event
+ hapd.mgmt_tx(msg)
+ ev = dev[0].wait_event(['CTRL-EVENT-STARTED-CHANNEL-SWITCH'], timeout=5)
+ if ev is None:
+ raise Exception("Expected CSA handling after keys installation")