diff --git a/tests/hwsim/test_pasn.py b/tests/hwsim/test_pasn.py index f2c7b3b22..bf9343833 100644 --- a/tests/hwsim/test_pasn.py +++ b/tests/hwsim/test_pasn.py @@ -13,6 +13,7 @@ logger = logging.getLogger() import socket import struct import subprocess +import re import hwsim_utils import hostapd @@ -681,3 +682,124 @@ def test_pasn_ap_mic_error(dev, apdev): check_pasn_akmp_cipher(dev[0], hapd1, "PASN", "CCMP", status=1) check_pasn_akmp_cipher(dev[0], hapd0, "PASN", "CCMP") + +@remote_compatible +def test_pasn_comeback(dev, apdev, params): + """PASN authentication with comeback flow""" + check_pasn_capab(dev[0]) + + params = pasn_ap_params("PASN", "CCMP", "19") + params['sae_anti_clogging_threshold'] = '0' + hapd = hostapd.add_ap(apdev[0], params) + bssid = hapd.own_addr() + + dev[0].scan(type="ONLY", freq=2412) + cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19" % bssid + + resp = dev[0].request(cmd) + if "OK" not in resp: + raise Exception("Failed to start PASN authentication") + + ev = dev[0].wait_event(["PASN-AUTH-STATUS"], 3) + if not ev: + raise Exception("PASN: PASN-AUTH-STATUS not seen") + + if bssid + " akmp=PASN, status=30 comeback_after=" not in ev: + raise Exception("PASN: unexpected status") + + comeback = re.split("comeback=", ev)[1] + + cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19 comeback=%s" % \ + (bssid, comeback) + + resp = dev[0].request(cmd) + if "OK" not in resp: + raise Exception("Failed to start PASN authentication") + + ev = dev[0].wait_event(["PASN-AUTH-STATUS"], 3) + if not ev: + raise Exception("PASN: PASN-AUTH-STATUS not seen") + + if bssid + " akmp=PASN, status=0" not in ev: + raise Exception("PASN: unexpected status with comeback token") + + check_pasn_ptk(dev[0], hapd, "CCMP") + +@remote_compatible +def test_pasn_comeback_after_0(dev, apdev, params): + """PASN authentication with comeback flow with comeback after set to 0""" + check_pasn_capab(dev[0]) + + params = pasn_ap_params("PASN", "CCMP", "19") + params['anti_clogging_threshold'] = '0' + params['pasn_comeback_after'] = '0' + hapd = start_pasn_ap(apdev[0], params) + + check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP") + +@remote_compatible +def test_pasn_comeback_after_0_sae(dev, apdev): + """PASN authentication with SAE, with comeback flow where comeback after is set to 0""" + check_pasn_capab(dev[0]) + check_sae_capab(dev[0]) + + params = hostapd.wpa2_params(ssid="test-pasn-sae", + passphrase="12345678") + params['wpa_key_mgmt'] = 'SAE PASN' + params['anti_clogging_threshold'] = '0' + params['pasn_comeback_after'] = '0' + hapd = start_pasn_ap(apdev[0], params) + + dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412", + only_add_network=True) + + # first test with a valid PSK + check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", nid="0") + + # And now with PMKSA caching + check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP") + + # And now with a wrong passphrase + if "FAIL" in dev[0].request("PMKSA_FLUSH"): + raise Exception("PMKSA_FLUSH failed") + + dev[0].set_network_quoted(0, "psk", "12345678787") + check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", status=1, nid="0") + +@remote_compatible +def test_pasn_comeback_multi(dev, apdev): + """PASN authentication with SAE, with multiple stations with comeback""" + check_pasn_capab(dev[0]) + check_sae_capab(dev[0]) + + params = hostapd.wpa2_params(ssid="test-pasn-sae", + passphrase="12345678") + params['wpa_key_mgmt'] = 'SAE PASN' + params['anti_clogging_threshold'] = '1' + params['pasn_comeback_after'] = '0' + hapd = start_pasn_ap(apdev[0], params) + bssid = hapd.own_addr() + + id = {} + for i in range(0, 2): + dev[i].flush_scan_cache() + dev[i].scan(type="ONLY", freq=2412) + id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", + scan_freq="2412", only_add_network=True) + + for i in range(0, 2): + cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19, nid=%s" % (bssid, id[i]) + resp = dev[i].request(cmd) + + if "OK" not in resp: + raise Exception("Failed to start pasn authentication") + + for i in range(0, 2): + ev = dev[i].wait_event(["PASN-AUTH-STATUS"], 3) + if not ev: + raise Exception("PASN: PASN-AUTH-STATUS not seen") + + if bssid + " akmp=PASN, status=0" not in ev: + raise Exception("PASN: unexpected status") + + check_pasn_ptk(dev[i], hapd, "CCMP")