[PATCH 18/20] tests: Add EPPKE testing coverage for security profile flows

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Jun 10 06:12:11 PDT 2026


From: Ilan Peer <ilan.peer at intel.com>

Add testing coverage for the EPPKE use cases with AP and
station support for security profile flows. The tests verify:

- Secure profile 1 (EPPKE + SAE-EXT-KEY with GCMP-256 etc.).
- Secure profile 0 (EPPKE without base AKM with GCMP-256).
- Both non MLO and MLO cases are covered.

Once a connection is established, on the station side verify that
the expected profile number was used and on the AP side verify
that security profile element was included in association request.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 tests/hwsim/test_eppke.py | 235 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 235 insertions(+)

diff --git a/tests/hwsim/test_eppke.py b/tests/hwsim/test_eppke.py
index 8e5a5885db..99f18f1557 100644
--- a/tests/hwsim/test_eppke.py
+++ b/tests/hwsim/test_eppke.py
@@ -1266,3 +1266,238 @@ def test_eppke_without_base_akm_mld_ap(dev, apdev):
         if "MLD not supported" in str(e) or "Failed to add" in str(e):
             raise HwsimSkip("MLD not supported")
         raise
+
+def _eppke_sec_profile_apply(params, group, base_akm=True):
+    params['rsn_pairwise'] = 'GCMP-256'
+    params['group_cipher'] = 'GCMP-256'
+    params['assoc_frame_encryption'] = '1'
+    params['pmksa_caching_privacy'] = '1'
+    params['pasn_groups'] = str(group)
+    params['sec_profile_enabled'] = '1'
+    if base_akm:
+        params['wpa_key_mgmt'] = params['wpa_key_mgmt'] + ' EPPKE'
+        params['sae_groups'] = str(group)
+        params['ieee80211w'] = '2'
+    else:
+        params['eppke_unauth'] = '1'
+
+def _eppke_sec_profile_verify_sta(hapd, addr, expected_akm='00-0f-ac-24'):
+    hapd.wait_sta()
+    sta = hapd.get_sta(addr)
+    if sta["AKMSuiteSelector"] != expected_akm or sta["auth_alg"] != '9':
+        raise Exception("Incorrect Auth Algo/AKMSuiteSelector value")
+    if sta.get("sec_profile_in_assoc_req") != '1':
+        raise Exception("Security Profile element not used in association")
+
+def _eppke_sec_profile_connect(sta, ssid, passphrase, group, scan_freq):
+    sta.set("sae_groups", str(group))
+    sta.set("sae_pwe", "1")
+    sta.connect(ssid, sae_password=passphrase, scan_freq=scan_freq,
+                key_mgmt="SAE-EXT-KEY EPPKE", ieee80211w="2", pmksa_privacy="1",
+                beacon_prot="1", pairwise="GCMP-256", group="GCMP-256")
+
+    val = sta.get_status_field("matched_sec_profile")
+    if val != "1":
+        raise Exception("Unexpected matched_sec_profile: " + str(val))
+
+def test_eppke_sae_security_profile(dev, apdev):
+    """EPPKE + SAE-EXT-KEY with AP advertising Security Profile element"""
+    check_eppke_capab(dev[0])
+    ssid = "test-eppke-sec-profile"
+    passphrase = '1234567890'
+    group = 19
+    params = hostapd.wpa3_params(ssid=ssid, password=passphrase)
+    params['wpa_key_mgmt'] = params['wpa_key_mgmt'] + ' SAE-EXT-KEY'
+    params['sae_pwe'] = '2'
+    _eppke_sec_profile_apply(params, group)
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    try:
+        _eppke_sec_profile_connect(dev[0], ssid, passphrase, group, "2412")
+        _eppke_sec_profile_verify_sta(hapd, dev[0].own_addr())
+    finally:
+        dev[0].set("sae_groups", "")
+        dev[0].set("sae_pwe", "0")
+
+def _eppke_sec_profile_mld_ap_params(ssid, passphrase, group):
+    params = eht_mld_ap_wpa2_params(ssid, passphrase,
+                                    key_mgmt="SAE-EXT-KEY", mfp="2", pwe='2',
+                                    beacon_prot=1)
+    _eppke_sec_profile_apply(params, group)
+    return params
+
+def test_eppke_sae_security_profile_mld_ap_non_mld_client(dev, apdev):
+    """EPPKE + SAE-EXT-KEY Security Profile element with MLD AP and non-MLD client"""
+    check_eppke_capab(dev[0])
+    with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface):
+        ssid = "test-eppke-sec-profile-mld"
+        passphrase = '1234567890'
+        group = 19
+        params = _eppke_sec_profile_mld_ap_params(ssid, passphrase, group)
+        hapd0 = eht_mld_enable_ap(hapd_iface, 0, params)
+
+        params['channel'] = '6'
+        hapd1 = eht_mld_enable_ap(hapd_iface, 1, params)
+
+        try:
+            _eppke_sec_profile_connect(dev[0], ssid, passphrase, group,
+                                       "2412 2437")
+            bssid = dev[0].get_status_field("bssid")
+            if hapd0.own_addr() == bssid:
+                hapd = hapd0
+            elif hapd1.own_addr() == bssid:
+                hapd = hapd1
+            else:
+                raise Exception("Unknown BSSID: " + bssid)
+            _eppke_sec_profile_verify_sta(hapd, dev[0].own_addr())
+        finally:
+            dev[0].set("sae_groups", "")
+            dev[0].set("sae_pwe", "0")
+
+def _run_eppke_sae_security_profile_mld(num_links):
+    with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
+        HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):
+
+        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+        wpas.interface_add(wpas_iface)
+
+        ssid = "test-eppke-sec-profile-mld"
+        passphrase = '1234567890'
+        group = 19
+        params = _eppke_sec_profile_mld_ap_params(ssid, passphrase, group)
+        hapd0 = eht_mld_enable_ap(hapd_iface, 0, params)
+
+        scan_freq = "2412"
+        if num_links >= 2:
+            params['channel'] = '6'
+            eht_mld_enable_ap(hapd_iface, 1, params)
+            scan_freq = "2412 2437"
+
+        _eppke_sec_profile_connect(wpas, ssid, passphrase, group, scan_freq)
+        valid_links = (1 << num_links) - 1
+        eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
+                          valid_links=valid_links, active_links=valid_links)
+        _eppke_sec_profile_verify_sta(hapd0, wpas.own_addr())
+
+def test_eppke_sae_security_profile_mld_one_link(dev, apdev):
+    """EPPKE + SAE-EXT-KEY Security Profile element with MLD AP and MLD client, one link"""
+    check_eppke_capab(dev[0])
+    _run_eppke_sae_security_profile_mld(1)
+
+def test_eppke_sae_security_profile_mld_two_links(dev, apdev):
+    """EPPKE + SAE-EXT-KEY Security Profile element with MLD AP and MLD client, two links"""
+    check_eppke_capab(dev[0])
+    _run_eppke_sae_security_profile_mld(2)
+
+def _eppke_no_base_akm_sec_profile_connect(sta, ssid, scan_freq):
+    sta.connect(ssid, scan_freq=scan_freq,
+                key_mgmt="EPPKE", ieee80211w="2", pmksa_privacy="1",
+                beacon_prot="1", pairwise="GCMP-256", group="GCMP-256")
+
+    val = sta.get_status_field("matched_sec_profile")
+    if val != "0":
+        raise Exception("Unexpected matched_sec_profile: " + str(val))
+
+def test_eppke_security_profile_no_base_akm_group_19(dev, apdev):
+    """EPPKE without base AKM with Security Profile element (profile 0), group 19"""
+    check_eppke_capab(dev[0])
+    ssid = "test-eppke-sec-profile-nobase"
+    group = 19
+    params = hostapd.wpa2_params(ssid=ssid, wpa_key_mgmt="EPPKE",
+                                 ieee80211w="2")
+
+    _eppke_sec_profile_apply(params, group, base_akm=False)
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    _eppke_no_base_akm_sec_profile_connect(dev[0], ssid, "2412")
+    _eppke_sec_profile_verify_sta(hapd, dev[0].own_addr(),
+                                  expected_akm='00-0f-ac-29')
+
+def test_eppke_security_profile_no_base_akm_group_20(dev, apdev):
+    """EPPKE without base AKM with Security Profile element (profile 0), group 20"""
+    check_eppke_capab(dev[0])
+    ssid = "test-eppke-sec-profile-nobase"
+    group = 20
+    params = hostapd.wpa2_params(ssid=ssid, wpa_key_mgmt="EPPKE",
+                                 ieee80211w="2")
+    _eppke_sec_profile_apply(params, group, base_akm=False)
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    _eppke_no_base_akm_sec_profile_connect(dev[0], ssid, "2412")
+    _eppke_sec_profile_verify_sta(hapd, dev[0].own_addr(),
+                                  expected_akm='00-0f-ac-29')
+
+def _eppke_no_base_akm_sec_profile_mld_ap_params(ssid, group):
+    params = hostapd.wpa2_params(ssid=ssid, wpa_key_mgmt="EPPKE",
+                                 ieee80211w="2")
+    params['ieee80211n'] = '1'
+    params['ieee80211ax'] = '1'
+    params['ieee80211be'] = '1'
+    params['channel'] = '1'
+    params['hw_mode'] = 'g'
+    params['group_mgmt_cipher'] = "AES-128-CMAC"
+    params['beacon_prot'] = '1'
+    _eppke_sec_profile_apply(params, group, base_akm=False)
+    return params
+
+def test_eppke_security_profile_no_base_akm_mld_ap_non_mld_client(dev, apdev):
+    """EPPKE without base AKM Security Profile element with MLD AP and non-MLD client"""
+    check_eppke_capab(dev[0])
+
+    with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface):
+        ssid = "test-eppke-sp-nobase-mld"
+        group = 19
+        params = _eppke_no_base_akm_sec_profile_mld_ap_params(ssid, group)
+        hapd0 = eht_mld_enable_ap(hapd_iface, 0, params)
+
+        params['channel'] = '6'
+        hapd1 = eht_mld_enable_ap(hapd_iface, 1, params)
+
+        _eppke_no_base_akm_sec_profile_connect(dev[0], ssid, "2412 2437")
+        bssid = dev[0].get_status_field("bssid")
+        if hapd0.own_addr() == bssid:
+            hapd = hapd0
+        elif hapd1.own_addr() == bssid:
+            hapd = hapd1
+        else:
+            raise Exception("Unknown BSSID: " + bssid)
+
+        _eppke_sec_profile_verify_sta(hapd, dev[0].own_addr(),
+                                      expected_akm='00-0f-ac-29')
+
+def _run_eppke_no_base_akm_sec_profile_mld(num_links):
+    with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
+        HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):
+        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+        wpas.interface_add(wpas_iface)
+
+        ssid = "test-eppke-sp-nobase-mld"
+        group = 19
+        params = _eppke_no_base_akm_sec_profile_mld_ap_params(ssid, group)
+        hapd0 = eht_mld_enable_ap(hapd_iface, 0, params)
+
+        scan_freq = "2412"
+        if num_links >= 2:
+            params['channel'] = '6'
+            eht_mld_enable_ap(hapd_iface, 1, params)
+            scan_freq = "2412 2437"
+
+        _eppke_no_base_akm_sec_profile_connect(wpas, ssid, scan_freq)
+
+        valid_links = (1 << num_links) - 1
+
+        eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
+                          valid_links=valid_links, active_links=valid_links)
+
+        _eppke_sec_profile_verify_sta(hapd0, wpas.own_addr(),
+                                      expected_akm='00-0f-ac-29')
+
+def test_eppke_security_profile_no_base_akm_mld_one_link(dev, apdev):
+    """EPPKE without base AKM Security Profile element with MLD AP and MLD client, one link"""
+    check_eppke_capab(dev[0])
+    _run_eppke_no_base_akm_sec_profile_mld(1)
+
+def test_eppke_security_profile_no_base_akm_mld_two_links(dev, apdev):
+    """EPPKE without base AKM Security Profile element with MLD AP and MLD client, two links"""
+    check_eppke_capab(dev[0])
+    _run_eppke_no_base_akm_sec_profile_mld(2)
\ No newline at end of file
-- 
2.53.0




More information about the Hostap mailing list