From patchwork Thu Dec 1 16:54:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrei Otcheretianski X-Patchwork-Id: 1711099 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=W4NEyjR/; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=Lt7Yg9Zn; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NNMdk5Jw2z23nT for ; Fri, 2 Dec 2022 03:55:38 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=fGoHvU+zqdFdxYYLxg4QPVUML+Mc0RbxLxMt14ttzUg=; b=W4NEyjR/LomzvI HVkNxOf5aObV7QIypbrjrxNbWmJrDL07XMyXILhGlcP68IgwT/4P7Lsoc9HYPrxw0WnxbsgrHxXDo +16/wo03pQ0T0sUPFwJ7ypK9BIw08v5r1YIqvT59bthivkg46d20gF/6B+JagY18/A+kQ5gwszyYL qTSYjRIYptlSlim87EkqhmeUIl9F44ntBpgCh1wLMEghQt0KS0T8iFiO45AGiM/lCKnV/oe4WfkYp HQ2TUBNGS7/5I41dfU8DdpKr4Wp+alITQ7bmNbYa6keQH8KbQDWuvJ+SfCzdsLuR4HJ4Go2ERdt8z BWspaE3TCThaEfogSRcw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1p0mpp-008iPb-Dw; Thu, 01 Dec 2022 16:54:53 +0000 Received: from mga18.intel.com ([134.134.136.126]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1p0mpl-008iOD-VP for hostap@lists.infradead.org; Thu, 01 Dec 2022 16:54:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669913689; x=1701449689; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=uR6vA06SIyIjlVdt30HBfrpiC2BUYaI6W5Z6EFU4nK0=; b=Lt7Yg9ZnGcaoXlQHzCt5jzcz/Qk873PyAOuOi2vWB2x46tv49aPJhHob R3gObYv26aH8z3NF0TE3c9MdgHBf7l6jWEVCUAsUxSp2S7feQsqpiBCZF 0qicrdrik2zvIgBCrh91izUYRyWlsC3EY8LrfzCaJEjjeNiQjaR7vrnbz dUAcGXJvNfCVRklS3D9jhWGTt+smz6tPEAM5KM8avummTBkek+EFF9XBD j1ycQbXGru3HieZY64zztTz2b8kL9NOy5stcducfXwxZwFTKQvzoRqKJj XPqliGgiv/X3W3sO5p9XmbOOmeNILkUp21PBV3JNEugAH4F19AfbkYp1V A==; X-IronPort-AV: E=McAfee;i="6500,9779,10548"; a="299106892" X-IronPort-AV: E=Sophos;i="5.96,209,1665471600"; d="scan'208";a="299106892" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Dec 2022 08:54:46 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10548"; a="889806590" X-IronPort-AV: E=Sophos;i="5.96,209,1665471600"; d="scan'208";a="889806590" Received: from aotchere-desk.jer.intel.com ([10.13.21.31]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Dec 2022 08:54:45 -0800 From: Andrei Otcheretianski To: hostap@lists.infradead.org Cc: Daniel Gabay , Andrei Otcheretianski Subject: [PATCH] AP: Add testing option to delay EAPOL Tx Date: Thu, 1 Dec 2022 18:54:35 +0200 Message-Id: <20221201165435.18764-1-andrei.otcheretianski@intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221201_085450_085710_2ECE0003 X-CRM114-Status: GOOD ( 19.90 ) X-Spam-Score: -0.4 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Daniel Gabay Add a testing option to delay EAPOL messages 1/4 and 3/4. By setting delay_eapol_tx=1, the actual EAPOL Tx will occur on the last possible attempt (wpa_pairwise_update_count) thus all previous attempt [...] Content analysis details: (-0.4 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.2 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Daniel Gabay Add a testing option to delay EAPOL messages 1/4 and 3/4. By setting delay_eapol_tx=1, the actual EAPOL Tx will occur on the last possible attempt (wpa_pairwise_update_count) thus all previous attempts will fail on timeout which is the wanted delay. In addition, add an hwsim test that uses this testing option to verify that non protected robust management frames are dropped prior to keys installation in MFP. Signed-off-by: Daniel Gabay Signed-off-by: Andrei Otcheretianski --- hostapd/config_file.c | 2 ++ hostapd/hostapd.conf | 5 +++++ src/ap/ap_config.c | 1 + src/ap/ap_config.h | 1 + src/ap/wpa_auth.c | 19 ++++++++++++++++- src/ap/wpa_auth.h | 1 + src/ap/wpa_auth_glue.c | 1 + tests/hwsim/test_ap_pmf.py | 43 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 72 insertions(+), 1 deletion(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 8a3357c26a..d5953bb048 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4269,6 +4269,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, 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) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 01abd585e6..21c0f8d671 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -3080,6 +3080,11 @@ own_ip_addr=127.0.0.1 # Include only ECSA IE without CSA IE where possible # (channel switch operating class is needed) #ecsa_ie_only=0 +# +# Delay EAPOL messages 1/4 and 3/4 Tx by not sending the frame until the last +# attempt (wpa_pairwise_update_count). This will trigger a timeout on all +# previous attempts and thus delay the frame. (testing only) +#delay_eapol_tx=0 ##### Multiple BSSID support ################################################## # diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index e83347b832..839b892b2a 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -258,6 +258,7 @@ struct hostapd_config * hostapd_config_defaults(void) conf->ignore_reassoc_probability = 0.0; conf->corrupt_gtk_rekey_mic_probability = 0.0; conf->ecsa_ie_only = 0; + conf->delay_eapol_tx = 0; #endif /* CONFIG_TESTING_OPTIONS */ conf->acs = 0; diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 330c9ed659..2f0424994f 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -1075,6 +1075,7 @@ struct hostapd_config { 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 diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index e3dfd8a6a9..c9cd51b1a5 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -1736,10 +1736,27 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth, if (!sm) return; + ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr; + +#ifdef CONFIG_TESTING_OPTIONS + /* in case delay_eapol_tx is true, delay the EAPOL by actually + * sending it on the last attempt and therefore all the previous + * attempts will fail on timeout. + */ + if (!wpa_auth->conf.delay_eapol_tx || + (wpa_auth->conf.delay_eapol_tx && + ctr == wpa_auth->conf.wpa_pairwise_update_count)) + __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, + kde_len, keyidx, encr, 0); + else + wpa_msg(sm->wpa_auth->conf.msg_ctx, MSG_INFO, + "DELAY-EAPOL-TX-%d", ctr); + +#else __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len, keyidx, encr, 0); +#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; diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index d95b2567e0..eed016accb 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -240,6 +240,7 @@ struct wpa_auth_config { 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; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 250d5a1580..a87d2f3899 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -117,6 +117,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, #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); diff --git a/tests/hwsim/test_ap_pmf.py b/tests/hwsim/test_ap_pmf.py index d83df5d74e..90e629c5ce 100644 --- a/tests/hwsim/test_ap_pmf.py +++ b/tests/hwsim/test_ap_pmf.py @@ -1470,3 +1470,46 @@ def test_ap_pmf_sta_global_require2(dev, apdev): 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 management frame 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 mgmt with channel switch IE + 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") + 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("Excpeted CSA handling after keys installation")