From patchwork Sun Mar 15 19:04:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 1255147 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20170209 header.b=fyEqEMd2; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=wetzel-home.de header.i=@wetzel-home.de header.a=rsa-sha256 header.s=wetzel-home header.b=gDaKD1G6; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48gTSM3K9hz9sPR for ; Mon, 16 Mar 2020 06:06:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zIkNDC4rojNkJWQDdKg489RiBuiqeBYjGa6gZOUig3E=; b=fyEqEMd2wZsC2g 7np2Rcirj796Zvfh4PXF+le0TQCS03yyZQ98aM6B6jxv/aThMvK8AAA3TrYmMeHXSzZfdzHLy61T/ ovjtkBoWK/+OOZjjEe8xsvlBs/jpTxN5SMGUTHgT+5gTeUnGGM1agSjp/GcHjkbY/Z8i+sZoV3ERx bTYe1QU6ZuynqREE93iE0TX5zBz24HXZysTlEGNDn4/v7juizsMANxYXHZyN2Hm9JSajnFEPxiR2j h6A/0obG2Nh5S/D+EjcRvkqEifHOJ6z/t/v9dvRIrxD7kv4xai2CjBigAcwEFyIrfoU17Fnxza4gN JFW7ZZhslucRyzhy8A5A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jDYap-0000Mx-Jp; Sun, 15 Mar 2020 19:06:35 +0000 Received: from 4.mo69.mail-out.ovh.net ([46.105.42.102]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jDYZQ-000606-6G for hostap@lists.infradead.org; Sun, 15 Mar 2020 19:05:15 +0000 Received: from player697.ha.ovh.net (unknown [10.108.54.133]) by mo69.mail-out.ovh.net (Postfix) with ESMTP id D68A9877AB for ; Sun, 15 Mar 2020 20:04:54 +0100 (CET) Received: from awhome.eu (p4FF9153C.dip0.t-ipconnect.de [79.249.21.60]) (Authenticated sender: postmaster@awhome.eu) by player697.ha.ovh.net (Postfix) with ESMTPSA id EE5061072BD86; Sun, 15 Mar 2020 19:04:52 +0000 (UTC) From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1584299088; bh=fA8170mrixOmd2YBlkRZShjtQ//BJg1wu1uYmXR7xDQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gDaKD1G6tG51Xtsdp0lZXr3jTttQ3qiyFsTwsstm9yNEVGMVE2EICEwS2duzSZiqq mhc6grlF+SXsqha2hznxEoYPSSKeQK3JG6qY9mrzDfAAi9diIMMwUSEFyC8osTbgs5 5a7vvsmkMwVEWnI8a33soM6JpemAzt7XKKImaOxc= To: j@w1.fi Subject: [PATCH 8/8] tests: Extended Key ID tests Date: Sun, 15 Mar 2020 20:04:26 +0100 Message-Id: <20200315190426.163478-9-alexander@wetzel-home.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200315190426.163478-1-alexander@wetzel-home.de> References: <20200315190426.163478-1-alexander@wetzel-home.de> MIME-Version: 1.0 X-Ovh-Tracer-Id: 8959348512867294400 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedugedrudefuddgvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomheptehlvgigrghnuggvrhcuhggvthiivghluceorghlvgigrghnuggvrhesfigvthiivghlqdhhohhmvgdruggvqeenucffohhmrghinhepvgigrghmphhlvgdrtghomhdpfidurdhfihenucfkpheptddrtddrtddrtddpjeelrddvgeelrddvuddriedtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmohguvgepshhmthhpqdhouhhtpdhhvghlohepphhlrgihvghrieeljedrhhgrrdhovhhhrdhnvghtpdhinhgvtheptddrtddrtddrtddpmhgrihhlfhhrohhmpegrlhgvgigrnhguvghrseifvghtiigvlhdqhhhomhgvrdguvgdprhgtphhtthhopehhohhsthgrpheslhhishhtshdrihhnfhhrrgguvggrugdrohhrgh X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200315_120508_686224_0A84B17A X-CRM114-Status: GOOD ( 12.68 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [46.105.42.102 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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 X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: hostap@lists.infradead.org, Alexander Wetzel Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add the needed infrastructure for the Extended Key ID tests, update tests overriding RSN Capabilities to work with and without Extended Key ID support and add additional interoperability tests for Extended Key ID. All tests will use BASIC Extended Key ID by default when possible. When Extended Key ID is not supported only ap_wpa2_ptk_extended_key_id will fail and all other tests depending on it will be skipped. Signed-off-by: Alexander Wetzel --- tests/hwsim/hostapd.py | 12 ++- tests/hwsim/test_ap_eap.py | 24 ++++- tests/hwsim/test_ap_ft.py | 14 ++- tests/hwsim/test_ap_psk.py | 145 +++++++++++++++++++++++-- tests/hwsim/test_fils.py | 203 ++++++++++++++++++++++++++++++++++- tests/hwsim/test_ocv.py | 13 ++- tests/hwsim/test_rrm.py | 7 +- tests/hwsim/wpasupplicant.py | 2 +- 8 files changed, 398 insertions(+), 22 deletions(-) diff --git a/tests/hwsim/hostapd.py b/tests/hwsim/hostapd.py index 62b3302be..a9a6c1c04 100644 --- a/tests/hwsim/hostapd.py +++ b/tests/hwsim/hostapd.py @@ -321,6 +321,12 @@ class Hostapd: return vals[field] return None + def extended_key_id(self): + res = self.get_driver_status_field('capa.flags') + if (int(res, 0) & 0x8000000000000000) != 0: + return True + return False + def get_config(self): res = self.request("GET_CONFIG") lines = res.splitlines() @@ -559,7 +565,7 @@ def add_ap(apdev, params, wait_enabled=True, no_enable=False, timeout=30, raise Exception("Could not ping hostapd") hapd.set_defaults() fields = ["ssid", "wpa_passphrase", "nas_identifier", "wpa_key_mgmt", - "wpa", "wpa_deny_ptk0_rekey", + "wpa", "wpa_deny_ptk0_rekey", "extended_key_id", "wpa_pairwise", "rsn_pairwise", "auth_server_addr", "acct_server_addr", "osu_server_uri"] for field in fields: @@ -647,7 +653,7 @@ def terminate(apdev): hapd_global.terminate() def wpa2_params(ssid=None, passphrase=None, wpa_key_mgmt="WPA-PSK", - ieee80211w=None): + extended_key_id=None, ieee80211w=None): params = {"wpa": "2", "wpa_key_mgmt": wpa_key_mgmt, "rsn_pairwise": "CCMP"} @@ -657,6 +663,8 @@ def wpa2_params(ssid=None, passphrase=None, wpa_key_mgmt="WPA-PSK", params["wpa_passphrase"] = passphrase if ieee80211w is not None: params["ieee80211w"] = ieee80211w + if extended_key_id: + params["extended_key_id"] = extended_key_id return params def wpa_params(ssid=None, passphrase=None): diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py index bdfe96111..b102ccecd 100644 --- a/tests/hwsim/test_ap_eap.py +++ b/tests/hwsim/test_ap_eap.py @@ -5136,6 +5136,7 @@ def test_ap_wpa2_eap_reauth_ptk_rekey_blocked_ap(dev, apdev): params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") params['eap_reauth_period'] = '2' params['wpa_deny_ptk0_rekey'] = '2' + params['extended_key_id'] = 'OFF' hapd = hostapd.add_ap(apdev[0], params) eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", password_hex="0123456789abcdef0123456789abcdef") @@ -5158,7 +5159,8 @@ def test_ap_wpa2_eap_reauth_ptk_rekey_blocked_sta(dev, apdev): hapd = hostapd.add_ap(apdev[0], params) eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", password_hex="0123456789abcdef0123456789abcdef", - wpa_deny_ptk0_rekey="2") + wpa_deny_ptk0_rekey="2", extended_key_id="OFF") + logger.info("Wait for disconnect due to reauth") ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-DISCONNECTED"], timeout=10) @@ -6692,7 +6694,7 @@ def test_eap_tls_sha384(dev, apdev, params): def test_ap_wpa2_eap_assoc_rsn(dev, apdev): """WPA2-Enterprise AP and association request RSN IE differences""" params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") - hostapd.add_ap(apdev[0], params) + hapd = hostapd.add_ap(apdev[0], params) params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap-11w") params["ieee80211w"] = "2" @@ -6712,6 +6714,17 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apdev): ("RSN IE without AKM", "300c0100000fac040100000fac04"), ("RSN IE without pairwise", "30060100000fac04"), ("RSN IE without group", "30020100")] + + if hapd.extended_key_id(): + tests += [("Normal wpa_supplicant assoc req RSN IE with Extended Key ID", + "30140100000fac040100000fac040100000fac010020"), + ("Extra PMKIDCount field in RSN IE with Extended Key ID", + "30160100000fac040100000fac040100000fac0100200000"), + ("Extra Group Management Cipher Suite in RSN IE with Extended Key ID", + "301a0100000fac040100000fac040100000fac0100200000000fac06"), + ("Extra undefined extension field in RSN IE with Extended Key ID", + "301c0100000fac040100000fac040100000fac0100200000000fac061122")] + for title, ie in tests: logger.info(title) set_test_assoc_ie(dev[0], ie) @@ -6726,6 +6739,13 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apdev): "30140100000fac040100000fac040100000fac01cc00"), ("Group management cipher included in assoc req RSN IE", "301a0100000fac040100000fac040100000fac01cc000000000fac06")] + + if hapd.extended_key_id(): + tests += [("Normal wpa_supplicant assoc req RSN IE with Extended Key ID", + "30140100000fac040100000fac040100000fac01cc20"), + ("Group management cipher included in assoc req RSN IE with Extended Key ID", + "301a0100000fac040100000fac040100000fac01cc200000000fac06")] + for title, ie in tests: logger.info(title) set_test_assoc_ie(dev[0], ie) diff --git a/tests/hwsim/test_ap_ft.py b/tests/hwsim/test_ap_ft.py index 3153bff93..53eb1b90a 100644 --- a/tests/hwsim/test_ap_ft.py +++ b/tests/hwsim/test_ap_ft.py @@ -136,7 +136,8 @@ def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False, group_mgmt=None, ocv=None, sae_password=None, sae_password_id=None, sae_and_psk=False, pmksa_caching=False, roam_with_reassoc=False, also_non_ft=False, only_one_way=False, - wait_before_roam=0, return_after_initial=False, ieee80211w="1"): + wait_before_roam=0, return_after_initial=False, ieee80211w="1", + sta_extended_key_id="BASIC", using_extended_key_id=False): logger.info("Connect to first AP") copts = {} @@ -146,6 +147,7 @@ def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False, copts["pairwise"] = pairwise_cipher copts["group"] = group_cipher copts["wpa_ptk_rekey"] = ptk_rekey + copts["extended_key_key"] = sta_extended_key_id if group_mgmt: copts["group_mgmt"] = group_mgmt if ocv: @@ -257,6 +259,7 @@ def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False, dev.roam(ap1['bssid']) if dev.get_status_field('bssid') != ap1['bssid']: raise Exception("Did not connect to correct AP") + if (i == 0 or i == roams - 1) and test_connectivity: hapd1ap.wait_sta() if conndev: @@ -1207,7 +1210,8 @@ def test_ap_ft_sae_pmksa_caching_h2e(dev, apdev): def generic_ap_ft_eap(dev, apdev, vlan=False, cui=False, over_ds=False, discovery=False, roams=1, wpa_ptk_rekey=0, - only_one_way=False): + only_one_way=False, ap_extended_key_id="BASIC", + sta_extended_key_id="BASIC", using_extended_key_id=False): ssid = "test-ft" passphrase = "12345678" if vlan: @@ -1224,6 +1228,7 @@ def generic_ap_ft_eap(dev, apdev, vlan=False, cui=False, over_ds=False, params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=discovery) params['wpa_key_mgmt'] = "FT-EAP" params["ieee8021x"] = "1" + params["extended_key_id"] = ap_extended_key_id if vlan: params["dynamic_vlan"] = "1" params = dict(list(radius.items()) + list(params.items())) @@ -1234,6 +1239,7 @@ def generic_ap_ft_eap(dev, apdev, vlan=False, cui=False, over_ds=False, params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=discovery) params['wpa_key_mgmt'] = "FT-EAP" params["ieee8021x"] = "1" + params["extended_key_id"] = ap_extended_key_id if vlan: params["dynamic_vlan"] = "1" if wpa_ptk_rekey: @@ -1243,7 +1249,9 @@ def generic_ap_ft_eap(dev, apdev, vlan=False, cui=False, over_ds=False, run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True, over_ds=over_ds, roams=roams, eap_identity=identity, - conndev=conndev, only_one_way=only_one_way) + conndev=conndev, only_one_way=only_one_way, + sta_extended_key_id=sta_extended_key_id, + using_extended_key_id=using_extended_key_id) if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"): raise Exception("Scan results missing RSN element info") check_mib(dev[0], [("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"), diff --git a/tests/hwsim/test_ap_psk.py b/tests/hwsim/test_ap_psk.py index febbc07fe..49e413d42 100644 --- a/tests/hwsim/test_ap_psk.py +++ b/tests/hwsim/test_ap_psk.py @@ -205,10 +205,11 @@ def _test_ap_wpa2_psk_mem(dev, apdev): @remote_compatible def test_ap_wpa2_ptk_rekey(dev, apdev): - """WPA2-PSK AP and PTK rekey enforced by station""" + """WPA2-PSK AP and PTK rekey enforced by station without Extended Key ID""" ssid = "test-wpa2-psk" passphrase = 'qwertyuiop' - params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase, + extended_key_id="OFF") hapd = hostapd.add_ap(apdev[0], params) Wlantest.setup(hapd) @@ -216,7 +217,8 @@ def test_ap_wpa2_ptk_rekey(dev, apdev): wt.flush() wt.add_passphrase(passphrase) - dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412") + dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412", + extended_key_id="OFF") ev = dev[0].wait_event(["WPA: Key negotiation completed", "CTRL-EVENT-DISCONNECTED"]) if ev is None: @@ -231,6 +233,7 @@ def test_ap_wpa2_ptk_rekey_blocked_ap(dev, apdev): passphrase = 'qwertyuiop' params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) params['wpa_deny_ptk0_rekey'] = "2" + params['extended_key_id'] = "OFF" hapd = hostapd.add_ap(apdev[0], params) dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412") ev = dev[0].wait_event(["WPA: Key negotiation completed", @@ -250,7 +253,7 @@ def test_ap_wpa2_ptk_rekey_blocked_sta(dev, apdev): params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) hapd = hostapd.add_ap(apdev[0], params) dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412", - wpa_deny_ptk0_rekey="2") + wpa_deny_ptk0_rekey="2", extended_key_id="OFF") ev = dev[0].wait_event(["WPA: Key negotiation completed", "CTRL-EVENT-DISCONNECTED"]) if ev is None: @@ -1397,10 +1400,16 @@ def eapol_test(apdev, dev, wpa2=True, ieee80211w=0): ieee80211w=str(ieee80211w)) addr = dev.p2p_interface_addr() if wpa2: - if ieee80211w == 2: - rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac02cc00') + extended_key_id = hapd.extended_key_id() + if extended_key_id and ieee80211w == 2: + cap = "cc20" + elif extended_key_id: + cap = "0020" + elif ieee80211w == 2: + cap = "cc00" else: - rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020000') + cap = "0000" + rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac02'+cap) else: rsne = binascii.unhexlify('dd160050f20101000050f20201000050f20201000050f202') snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111') @@ -2970,6 +2979,11 @@ def test_ap_wpa2_psk_assoc_rsn(dev, apdev): "30140100000fac040100000fac040100000fac020000"), ("RSN IE without RSN Capabilities", "30120100000fac040100000fac040100000fac02")] + + if hapd.extended_key_id(): + tests += [("Normal wpa_supplicant assoc req RSN IE with Extended Key ID", + "30140100000fac040100000fac040100000fac020020")] + for title, ie in tests: logger.info(title) set_test_assoc_ie(dev[0], ie) @@ -3013,9 +3027,13 @@ def test_ap_wpa2_psk_ft_workaround(dev, apdev): params['r1_key_holder'] = "000102030405" hapd = hostapd.add_ap(apdev[0], params) + if hapd.extended_key_id(): + ie = "30180100000fac040100000fac040200000fac02000fac040020" + else: + ie = "30180100000fac040100000fac040200000fac02000fac040000" + # Include both WPA-PSK and FT-PSK AKMs in Association Request frame - set_test_assoc_ie(dev[0], - "30180100000fac040100000fac040200000fac02000fac040000") + set_test_assoc_ie(dev[0], ie) dev[0].connect(ssid, psk=passphrase, scan_freq="2412") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() @@ -3032,6 +3050,14 @@ def test_ap_wpa2_psk_assoc_rsn_pmkid(dev, apdev): dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() + if not hapd.extended_key_id(): + return + + set_test_assoc_ie(dev[0], "30260100000fac040100000fac040100000fac0200200100" + 16*'00') + dev[0].connect(ssid, psk=passphrase, scan_freq="2412") + dev[0].request("REMOVE_NETWORK all") + dev[0].wait_disconnected() + def test_ap_wpa_psk_rsn_pairwise(dev, apdev): """WPA-PSK AP and only rsn_pairwise set""" params = {"ssid": "wpapsk", "wpa": "1", "wpa_key_mgmt": "WPA-PSK", @@ -3404,3 +3430,104 @@ def test_ap_wpa2_psk_rsnxe_mismatch_ap(dev, apdev): raise Exception("Unexpected connection") if "reason=17 locally_generated=1" not in ev: raise Exception("Unexpected disconnection reason: " + ev) + +def test_ap_wpa2_ptk_extended_key_id(dev, apdev): + """Extended Key ID WPA2-PSK AP and PTK rekey enforced by station""" + ssid = "test-wpa2-psk" + passphrase = 'qwertyuiop' + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) + hapd = hostapd.add_ap(apdev[0], params) + if not hapd.extended_key_id(): + raise Exception("No Extended Key ID support") + + dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412") + ev = dev[0].wait_event(["WPA: Key negotiation completed"]) + if ev is None: + raise Exception("PTK rekey timed out (STA with Extended Key ID)") + elif "Extended_Key_ID" not in ev: + raise Exception("Extended Key ID not used") + hwsim_utils.test_connectivity(dev[0], hapd) + ev = dev[0].wait_event(["WPA: Key negotiation completed"]) + if ev is None: + raise Exception("PTK rekey timed out 2 (STA with Extended Key ID)") + elif "Extended_Key_ID" not in ev: + raise Exception("Extended Key ID not used") + hwsim_utils.test_connectivity(dev[0], hapd) + dev[0].reset() + +def test_ap_wpa2_ptk_extended_key_id_compat_ap(dev, apdev): + """Extended Key ID WPA2-PSK AP and station not supporting Extended Key ID""" + ssid = "test-wpa2-psk" + passphrase = 'qwertyuiop' + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) + hapd = hostapd.add_ap(apdev[0], params) + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412", + extended_key_id="OFF") + ev = dev[0].wait_event(["WPA: Key negotiation completed"]) + if ev is None: + raise Exception("PTK rekey timed out (STA without Extended Key ID)") + elif "Extended_Key_ID" in ev: + raise Exception("Invalid Extended Key ID usage") + hwsim_utils.test_connectivity(dev[0], hapd) + dev[0].reset() + +def test_ap_wpa2_ptk_extended_key_id_compat_sta(dev, apdev): + """WPA2-PSK AP not supporting Extended Key ID and station supporting it""" + ssid = "test-wpa2-psk" + passphrase = 'qwertyuiop' + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase, + extended_key_id="OFF") + hapd = hostapd.add_ap(apdev[0], params) + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412") + ev = dev[0].wait_event(["WPA: Key negotiation completed"]) + if ev is None: + raise Exception("PTK rekey timed out (AP without Extended Key ID") + elif "Extended_Key_ID" in ev: + raise Exception("Extended Key ID used when AP not supporting it") + hwsim_utils.test_connectivity(dev[0], hapd) + dev[0].reset() + +def test_ap_wpa2_ptk_extended_key_id_tkip(dev, apdev): + """Extended Key ID with TKIP only AP""" + ssid = "test-wpa2-psk" + passphrase = 'qwertyuiop' + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) + params["rsn_pairwise"] = "TKIP" + hapd = hostapd.add_ap(apdev[0], params) + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412") + ev = dev[0].wait_event(["WPA: Key negotiation completed"]) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" in ev: + raise Exception("Extended Key ID used with TKIP") + hwsim_utils.test_connectivity(dev[0], hapd) + dev[0].reset() + +def test_ap_wpa2_ptk_extended_key_id_tkip_sta(dev, apdev): + """Extended Key ID WPA2-PSK AP and station using WPA2 with TKIP only""" + ssid = "test-wpa2-psk" + passphrase = 'qwertyuiop' + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) + params["rsn_pairwise"] = "TKIP CCMP" + hapd = hostapd.add_ap(apdev[0], params) + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", pairwise="TKIP", + scan_freq="2412") + ev = dev[0].wait_event(["WPA: Key negotiation completed"]) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" in ev: + raise Exception("Extended Key ID used with TKIP") + hwsim_utils.test_connectivity(dev[0], hapd) + dev[0].reset() diff --git a/tests/hwsim/test_fils.py b/tests/hwsim/test_fils.py index 16fc03852..ba0255c64 100644 --- a/tests/hwsim/test_fils.py +++ b/tests/hwsim/test_fils.py @@ -1655,7 +1655,8 @@ def test_fils_sk_auth_mismatch(dev, apdev, params): hwsim_utils.test_connectivity(dev[0], hapd) def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0, - pmksa_caching=True): + pmksa_caching=True, + ap_extended_key_id=None, sta_extended_key_id=None): check_fils_capa(dev[0]) check_erp_capa(dev[0]) @@ -1671,6 +1672,10 @@ def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0, params['wpa_ptk_rekey'] = str(wpa_ptk_rekey) if wpa_group_rekey: params['wpa_group_rekey'] = str(wpa_group_rekey) + if ap_extended_key_id: + params['extended_key_id'] = str(ap_extended_key_id) + if not sta_extended_key_id: + sta_extended_key_id="BASIC" if not pmksa_caching: params['disable_pmksa_caching'] = '1' hapd = hostapd.add_ap(apdev[0]['ifname'], params) @@ -1678,6 +1683,7 @@ def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0, dev[0].scan_for_bss(bssid, freq=2412) dev[0].request("ERP_FLUSH") id = dev[0].connect("fils", key_mgmt="FILS-SHA256", + extended_key_id=str(sta_extended_key_id), eap="PSK", identity="psk.user@example.com", password_hex="0123456789abcdef0123456789abcdef", erp="1", scan_freq="2412") @@ -1717,6 +1723,108 @@ def test_fils_auth_ptk_rekey_ap(dev, apdev, params): ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) if ev is None: raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" in ev: + raise Exception("PTK rekey using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_fils0(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID FILS0)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + ap_extended_key_id="BASIC+FILS0", + sta_extended_key_id="BASIC+FILS0") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_fils0_compat(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (only AP supporting Extended Key ID FILS0)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + ap_extended_key_id="BASIC+FILS0", + sta_extended_key_id="OFF") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" in ev: + raise Exception("PTK rekey using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_fils_custom(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID FILS_CUSTOM)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + ap_extended_key_id="BASIC+FILS_CUSTOM", + sta_extended_key_id="BASIC+FILS_CUSTOM") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_fils0_fils_custom(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID mix FILS0/FILS_CUSTOM)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + ap_extended_key_id="BASIC+FILS0", + sta_extended_key_id="BASIC+FILS_CUSTOM") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_fils_custom_fils0(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID mix FILS_CUSTOM/FILS0)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + ap_extended_key_id="BASIC+FILS_CUSTOM", + sta_extended_key_id="BASIC+FILS0") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") hwsim_utils.test_connectivity(dev[0], hapd) ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) @@ -1738,6 +1846,90 @@ def test_fils_auth_ptk_rekey_ap_erp(dev, apdev, params): raise Exception("Rekeying failed - disconnected") hwsim_utils.test_connectivity(dev[0], hapd) +def test_fils_auth_ptk_rekey_ap_erp_fils0(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID FILS0 with ERP)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + pmksa_caching=False, + ap_extended_key_id="BASIC+FILS0", + sta_extended_key_id="BASIC+FILS0") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_erp_fils_custom(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID FILS_CUSTOM with ERP)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + pmksa_caching=False, + ap_extended_key_id="BASIC+FILS_CUSTOM", + sta_extended_key_id="BASIC+FILS_CUSTOM") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_erp_fils0_fils_custom(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID mix FILS0/FILS_CUSTOM with ERP)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + pmksa_caching=False, + ap_extended_key_id="BASIC+FILS0", + sta_extended_key_id="BASIC+FILS_CUSTOM") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + +def test_fils_auth_ptk_rekey_ap_erp_fils_custom_fils0(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (using Extended Key ID mix FILS_CUSTOM/FILS0 with ERP)""" + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + pmksa_caching=False, + ap_extended_key_id="BASIC+FILS_CUSTOM", + sta_extended_key_id="BASIC+FILS0") + if not hapd.extended_key_id(): + raise HwsimSkip("No Extended Key ID support") + + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + elif "Extended_Key_ID" not in ev: + raise Exception("PTK rekey not using Extended Key ID") + hwsim_utils.test_connectivity(dev[0], hapd) + + ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) + if ev is not None: + raise Exception("Rekeying failed - disconnected") + hwsim_utils.test_connectivity(dev[0], hapd) + def test_fils_and_ft(dev, apdev, params): """FILS SK using ERP and FT initial mobility domain association""" check_fils_capa(dev[0]) @@ -1752,11 +1944,13 @@ def test_fils_and_ft(dev, apdev, params): params['erp_domain'] = 'example.com' params['fils_realm'] = 'example.com' params['disable_pmksa_caching'] = '1' + params['extended_key_id'] = 'BASIC+FT0+FILS0' hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].scan_for_bss(bssid, freq=2412) dev[0].request("ERP_FLUSH") id = dev[0].connect("fils", key_mgmt="FILS-SHA256", + extended_key_id="BASIC+FT0+FILS0", eap="PSK", identity="psk.user@example.com", password_hex="0123456789abcdef0123456789abcdef", erp="1", scan_freq="2412") @@ -1783,12 +1977,14 @@ def test_fils_and_ft(dev, apdev, params): params['r0kh'] = ["02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"] params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f" params['ieee80211w'] = "1" + params['extended_key_id'] = 'BASIC+FT0+FILS0' hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].scan_for_bss(bssid, freq=2412) dev[0].dump_monitor() id = dev[0].connect("fils-ft", key_mgmt="FILS-SHA256 FT-FILS-SHA256 FT-EAP", ieee80211w="1", + extended_key_id="BASIC+FT0+FILS0", eap="PSK", identity="psk.user@example.com", password_hex="0123456789abcdef0123456789abcdef", erp="1", scan_freq="2412", wait_connect=False) @@ -1819,6 +2015,7 @@ def test_fils_and_ft(dev, apdev, params): params['r1_key_holder'] = "000102030406" params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f"] params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f" + params['extended_key_id'] = 'BASIC+FT0+FILS0' hapd2 = hostapd.add_ap(apdev[1]['ifname'], params) dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True) @@ -1897,6 +2094,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt): params['fils_realm'] = 'example.com' params['disable_pmksa_caching'] = '1' params['ieee80211w'] = "2" + params['extended_key_id'] = 'BASIC+FT0+FILS0' hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].scan_for_bss(bssid, freq=2412) @@ -1904,6 +2102,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt): hapd.request("NOTE Initial association to establish ERP keys") id = dev[0].connect("fils", key_mgmt=key_mgmt, ieee80211w="2", eap="PSK", identity="psk.user@example.com", + extended_key_id="BASIC+FT0+FILS0", password_hex="0123456789abcdef0123456789abcdef", erp="1", scan_freq="2412") hapd.wait_sta() @@ -1933,6 +2132,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt): "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"] params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f" params['ieee80211w'] = "2" + params['extended_key_id'] = 'BASIC+FT0+FILS0' hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].scan_for_bss(bssid, freq=2412) @@ -1964,6 +2164,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt): params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f", "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"] params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f" + params['extended_key_id'] = 'BASIC+FT0+FILS0' hapd2 = hostapd.add_ap(apdev[1]['ifname'], params) return hapd, hapd2 diff --git a/tests/hwsim/test_ocv.py b/tests/hwsim/test_ocv.py index df84e7124..75eca7590 100644 --- a/tests/hwsim/test_ocv.py +++ b/tests/hwsim/test_ocv.py @@ -380,10 +380,17 @@ class APConnection: self.bssid = apdev['bssid'] pmk = binascii.unhexlify("c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7") - if sta_ocv != "0": - self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280400000000fac06") + if self.hapd.extended_key_id(): + if sta_ocv != "0": + cap = "8060" + else: + cap = "8020" else: - self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280000000000fac06") + if sta_ocv != "0": + cap = "8040" + else: + cap = "8000" + self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac02"+cap+"0000000fac06") self.snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111') dev.connect(self.ssid, raw_psk=self.psk, scan_freq=freq, ocv=sta_ocv, diff --git a/tests/hwsim/test_rrm.py b/tests/hwsim/test_rrm.py index dde98932b..610efe1f6 100644 --- a/tests/hwsim/test_rrm.py +++ b/tests/hwsim/test_rrm.py @@ -1233,6 +1233,11 @@ def test_rrm_beacon_req_table_rsne(dev, apdev): params["rrm_beacon_report"] = "1" hapd = hostapd.add_ap(apdev[0], params) + if hapd.extended_key_id(): + cap = "0c20" + else: + cap = "0c00" + dev[0].connect("rrm-rsn", psk="12345678", scan_freq="2412") addr = dev[0].own_addr() @@ -1247,7 +1252,7 @@ def test_rrm_beacon_req_table_rsne(dev, apdev): raise Exception("Reported Frame Body subelement missing") if len(report.frame_body) != 12 + 22: raise Exception("Unexpected Reported Frame Body subelement length with Reporting Detail 1 and requested element RSNE") - if binascii.unhexlify("30140100000fac040100000fac040100000fac020c00") not in report.frame_body: + if binascii.unhexlify("30140100000fac040100000fac040100000fac02"+cap) not in report.frame_body: raise Exception("Full RSNE not found") def test_rrm_beacon_req_table_vht(dev, apdev): diff --git a/tests/hwsim/wpasupplicant.py b/tests/hwsim/wpasupplicant.py index e245c3a93..f0c55070b 100644 --- a/tests/hwsim/wpasupplicant.py +++ b/tests/hwsim/wpasupplicant.py @@ -1105,7 +1105,7 @@ class WpaSupplicant: "roaming_consortium_selection", "ocv", "multi_ap_backhaul_sta", "rx_stbc", "tx_stbc", "ft_eap_pmksa_caching", "beacon_prot", - "wpa_deny_ptk0_rekey"] + "wpa_deny_ptk0_rekey", "extended_key_id"] for field in not_quoted: if field in kwargs and kwargs[field]: self.set_network(id, field, kwargs[field])