diff --git a/tests/hwsim/test_ap_ft.py b/tests/hwsim/test_ap_ft.py index 624451e90..b8fecda80 100644 --- a/tests/hwsim/test_ap_ft.py +++ b/tests/hwsim/test_ap_ft.py @@ -18,7 +18,7 @@ import hwsim_utils from hwsim import HWSimRadio import hostapd from tshark import run_tshark -from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger, skip_with_fips, parse_ie +from utils import * from wlantest import Wlantest from test_ap_psk import check_mib, find_wpas_process, read_process_memory, verify_not_present, get_key_locations from test_rrm import check_beacon_req @@ -995,7 +995,7 @@ def test_ap_ft_over_ds_pull_vlan(dev, apdev): def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None, rsne_override=None, rsnxe_override=None, - no_beacon_rsnxe2=False): + no_beacon_rsnxe2=False, ext_key_id=False): if "SAE" not in dev.get_capability("auth_alg"): raise HwsimSkip("SAE not supported") ssid = "test-ft" @@ -1011,6 +1011,8 @@ def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None, params['rsne_override_ft'] = rsne_override if rsnxe_override: params['rsnxe_override_ft'] = rsnxe_override + if ext_key_id: + params['extended_key_id'] = '1' hapd0 = hostapd.add_ap(apdev[0], params) params = ft_params2(ssid=ssid, passphrase=passphrase) params['wpa_key_mgmt'] = "FT-SAE" @@ -1024,6 +1026,8 @@ def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None, params['rsnxe_override_ft'] = rsnxe_override if no_beacon_rsnxe2: params['no_beacon_rsnxe'] = "1" + if ext_key_id: + params['extended_key_id'] = '1' hapd1 = hostapd.add_ap(apdev[1], params) key_mgmt = hapd1.get_config()['key_mgmt'] if key_mgmt.split(' ')[0] != "FT-SAE": @@ -1099,6 +1103,24 @@ def test_ap_ft_sae_ptk_rekey_ap(dev, apdev): only_one_way=True) check_ptk_rekey(dev[0], hapd0, hapd1) +def test_ap_ft_sae_ptk_rekey_ap_ext_key_id(dev, apdev): + """WPA2-PSK-FT-SAE AP and PTK rekey triggered by AP (Ext Key ID)""" + check_ext_key_id_capa(dev[0]) + try: + dev[0].set("extended_key_id", "1") + hapd0, hapd1 = start_ft_sae(dev[0], apdev, wpa_ptk_rekey=2, + ext_key_id=True) + check_ext_key_id_capa(hapd0) + check_ext_key_id_capa(hapd1) + run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True, + only_one_way=True) + check_ptk_rekey(dev[0], hapd0, hapd1) + idx = int(dev[0].request("GET last_tk_key_idx")) + if idx != 1: + raise Exception("Unexpected Key ID after TK rekey: %d" % idx) + finally: + dev[0].set("extended_key_id", "0") + def test_ap_ft_sae_over_ds(dev, apdev): """WPA2-PSK-FT-SAE AP over DS""" hapd0, hapd1 = start_ft_sae(dev[0], apdev) diff --git a/tests/hwsim/test_ap_psk.py b/tests/hwsim/test_ap_psk.py index febbc07fe..b9abf5d82 100644 --- a/tests/hwsim/test_ap_psk.py +++ b/tests/hwsim/test_ap_psk.py @@ -19,7 +19,7 @@ import subprocess import time import hostapd -from utils import HwsimSkip, fail_test, skip_with_fips, start_monitor, stop_monitor, radiotap_build +from utils import * import hwsim_utils from wpasupplicant import WpaSupplicant from tshark import run_tshark @@ -3404,3 +3404,91 @@ 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_psk_ext_key_id_ptk_rekey_ap0(dev, apdev): + """WPA2-PSK AP and PTK rekey by AP (disabled on STA)""" + run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, 1, 0) + +def test_ap_wpa2_psk_ext_key_id_ptk_rekey_ap1(dev, apdev): + """WPA2-PSK AP and PTK rekey by AP (start with Key ID 0)""" + run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, 1, 1) + +def test_ap_wpa2_psk_ext_key_id_ptk_rekey_ap2(dev, apdev): + """WPA2-PSK AP and PTK rekey by AP (start with Key ID 1)""" + run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, 2, 1) + +def run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, ap_ext_key_id, + sta_ext_key_id): + check_ext_key_id_capa(dev[0]) + ssid = "test-wpa2-psk" + passphrase = 'qwertyuiop' + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) + params['wpa_ptk_rekey'] = '2' + params['extended_key_id'] = str(ap_ext_key_id) + hapd = hostapd.add_ap(apdev[0], params) + check_ext_key_id_capa(hapd) + try: + dev[0].set("extended_key_id", str(sta_ext_key_id)) + dev[0].connect(ssid, psk=passphrase, scan_freq="2412") + idx = int(dev[0].request("GET last_tk_key_idx")) + expect_idx = 1 if ap_ext_key_id == 2 and sta_ext_key_id else 0 + if idx != expect_idx: + raise Exception("Unexpected Key ID for the first TK: %d (expected %d)" % (idx, expect_idx)) + ev = dev[0].wait_event(["WPA: Key negotiation completed"]) + if ev is None: + raise Exception("PTK rekey timed out") + idx = int(dev[0].request("GET last_tk_key_idx")) + expect_idx = 1 if ap_ext_key_id == 1 and sta_ext_key_id else 0 + if idx != expect_idx: + raise Exception("Unexpected Key ID for the second TK: %d (expected %d)" % (idx, expect_idx)) + hwsim_utils.test_connectivity(dev[0], hapd) + finally: + dev[0].set("extended_key_id", "0") + +def test_ap_wpa2_psk_ext_key_id_ptk_rekey_sta0(dev, apdev): + """Extended Key ID and PTK rekey by station (Ext Key ID disabled on AP)""" + run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, 0) + +def test_ap_wpa2_psk_ext_key_id_ptk_rekey_sta1(dev, apdev): + """Extended Key ID and PTK rekey by station (start with Key ID 0)""" + run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, 1) + +def test_ap_wpa2_psk_ext_key_id_ptk_rekey_sta2(dev, apdev): + """Extended Key ID and PTK rekey by station (start with Key ID 1)""" + run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, 2) + +def run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, ext_key_id): + check_ext_key_id_capa(dev[0]) + ssid = "test-wpa2-psk" + passphrase = 'qwertyuiop' + params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) + params['extended_key_id'] = str(ext_key_id) + hapd = hostapd.add_ap(apdev[0], params) + check_ext_key_id_capa(hapd) + + Wlantest.setup(hapd) + wt = Wlantest() + wt.flush() + wt.add_passphrase(passphrase) + + try: + dev[0].set("extended_key_id", "1") + dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", + scan_freq="2412") + idx = int(dev[0].request("GET last_tk_key_idx")) + expect_idx = 1 if ext_key_id == 2 else 0 + if idx != expect_idx: + raise Exception("Unexpected Key ID for the first TK: %d (expected %d)" % (idx, expect_idx)) + ev = dev[0].wait_event(["WPA: Key negotiation completed", + "CTRL-EVENT-DISCONNECTED"]) + if ev is None: + raise Exception("PTK rekey timed out") + if "CTRL-EVENT-DISCONNECTED" in ev: + raise Exception("Disconnect instead of rekey") + idx = int(dev[0].request("GET last_tk_key_idx")) + expect_idx = 1 if ext_key_id == 1 else 0 + if idx != expect_idx: + raise Exception("Unexpected Key ID for the second TK: %d (expected %d)" % (idx, expect_idx)) + hwsim_utils.test_connectivity(dev[0], hapd) + finally: + dev[0].set("extended_key_id", "0") diff --git a/tests/hwsim/test_fils.py b/tests/hwsim/test_fils.py index 16fc03852..8e4df655e 100644 --- a/tests/hwsim/test_fils.py +++ b/tests/hwsim/test_fils.py @@ -17,7 +17,7 @@ import hostapd from tshark import run_tshark from wpasupplicant import WpaSupplicant import hwsim_utils -from utils import HwsimSkip, alloc_fail +from utils import * from test_erp import check_erp_capa, start_erp_as from test_ap_hs20 import ip_checksum @@ -1655,7 +1655,7 @@ 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, ext_key_id=False): check_fils_capa(dev[0]) check_erp_capa(dev[0]) @@ -1673,6 +1673,8 @@ def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0, params['wpa_group_rekey'] = str(wpa_group_rekey) if not pmksa_caching: params['disable_pmksa_caching'] = '1' + if ext_key_id: + params['extended_key_id'] = '1' hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].scan_for_bss(bssid, freq=2412) @@ -2302,3 +2304,29 @@ def test_fils_sk_erp_roam_diff_akm(dev, apdev, params): raise Exception("Failed to connect to the second AP") hwsim_utils.test_connectivity(dev[0], hapd2) + +def test_fils_auth_ptk_rekey_ap_ext_key_id(dev, apdev, params): + """PTK rekeying after FILS authentication triggered by AP (Ext Key ID)""" + check_ext_key_id_capa(dev[0]) + try: + dev[0].set("extended_key_id", "1") + hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2, + ext_key_id=True) + check_ext_key_id_capa(hapd) + idx = int(dev[0].request("GET last_tk_key_idx")) + if idx != 0: + raise Exception("Unexpected Key ID before TK rekey: %d" % idx) + ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3) + if ev is None: + raise Exception("PTK rekey timed out") + idx = int(dev[0].request("GET last_tk_key_idx")) + if idx != 1: + raise Exception("Unexpected Key ID after TK rekey: %d" % idx) + 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) + finally: + dev[0].set("extended_key_id", "0") diff --git a/tests/hwsim/utils.py b/tests/hwsim/utils.py index fdd95eebf..1e7e56c3a 100644 --- a/tests/hwsim/utils.py +++ b/tests/hwsim/utils.py @@ -89,6 +89,11 @@ def skip_with_fips(dev, reason="Not supported in FIPS mode"): if res and 'FIPS' in res: raise HwsimSkip(reason) +def check_ext_key_id_capa(dev): + res = dev.get_driver_status_field('capa.flags') + if (int(res, 0) & 0x8000000000000000) == 0: + raise HwsimSkip("Extended Key ID not supported") + def get_phy(ap, ifname=None): phy = "phy3" try: