[PATCH 17/20] tests: Extended EPPKE with caching to use random MAC addresses

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


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

In order to have privacy, using EPPKE and PMKSA caching enhancements
are not sufficient, as without randomizing the station MAC address,
the station can be tracked. Thus, extend the testing to use random
MAC address with each connection, to simulate real usage.

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

diff --git a/tests/hwsim/test_eppke.py b/tests/hwsim/test_eppke.py
index 1e6c39a968..8e5a5885db 100644
--- a/tests/hwsim/test_eppke.py
+++ b/tests/hwsim/test_eppke.py
@@ -257,27 +257,39 @@ def test_eppke_ap_with_base_akm_sae_ext_non_mld_client_pmksa_cached(dev, apdev):
     try:
         dev[0].set("pasn_groups", "")
         dev[0].set("sae_pwe", "1")
+        dev[0].set("preassoc_mac_addr", "1")
+        dev[0].set("rand_addr_lifetime", "0")
         dev[0].connect(ssid, sae_password=passphrase, scan_freq="2412",
                        key_mgmt="SAE-EXT-KEY EPPKE", ieee80211w="2",
-                       beacon_prot="1", pairwise="CCMP", pmksa_privacy="1")
+                       beacon_prot="1", pairwise="CCMP", pmksa_privacy="1",
+                       mac_addr="1")
         hapd.wait_sta();
         sta = hapd.get_sta(dev[0].own_addr())
         if sta["AKMSuiteSelector"] != '00-0f-ac-24' or sta["auth_alg"] != '9':
             raise Exception("Incorrect Auth Algo/AKMSuiteSelector value")
 
-        dev[0].request("DISCONNECT")
-        dev[0].wait_disconnected()
-        dev[0].request("RECONNECT")
-        dev[0].wait_connected(timeout=15, error="Reconnect timed out")
-        val = dev[0].get_status_field('sae_group')
-        if val is not None:
-            raise Exception("SAE group claimed to have been used: " + val)
-        sta = hapd.get_sta(dev[0].own_addr())
-        if sta['auth_alg'] != '9' or sta['AKMSuiteSelector'] != '00-0f-ac-24':
-            raise Exception("Incorrect Auth Algo/AKMSuiteSelector value after PMKSA caching")
+        for i in range(3):
+            prev_addr = dev[0].own_addr()
+            dev[0].request("DISCONNECT")
+            dev[0].wait_disconnected()
+            # Let driver fully process disconnect before MAC change
+            time.sleep(0.5)
+            dev[0].request("RECONNECT")
+            dev[0].wait_connected(timeout=15, error="Reconnect timed out")
+            new_addr = dev[0].own_addr()
+            if new_addr == prev_addr:
+                raise Exception("MAC address did not change on iteration %d" % i)
+            val = dev[0].get_status_field('sae_group')
+            if val is not None:
+                raise Exception("SAE group claimed to have been used: " + val)
+            sta = hapd.get_sta(new_addr)
+            if sta['auth_alg'] != '9' or sta['AKMSuiteSelector'] != '00-0f-ac-24':
+                raise Exception("Incorrect Auth Algo/AKMSuiteSelector value after PMKSA caching")
 
     finally:
         dev[0].set("pasn_groups", "")
+        dev[0].set("preassoc_mac_addr", "0")
+        dev[0].set("rand_addr_lifetime", "60")
         dev[0].set("sae_pwe", "0")
 
 def test_eppke_mld_ap_with_base_akm_sae_ext_non_mld_client_pmksa_cached(dev, apdev):
@@ -301,10 +313,12 @@ def test_eppke_mld_ap_with_base_akm_sae_ext_non_mld_client_pmksa_cached(dev, apd
         try:
             dev[0].set("pasn_groups", "")
             dev[0].set("sae_pwe", "1")
+            dev[0].set("preassoc_mac_addr", "1")
+            dev[0].set("rand_addr_lifetime", "0")
             dev[0].connect(ssid, sae_password=passphrase, scan_freq="2412",
                            key_mgmt="SAE-EXT-KEY EPPKE", ieee80211w="2",
                            beacon_prot="1", pairwise="CCMP GCMP-256",
-                           pmksa_privacy="1")
+                           pmksa_privacy="1", mac_addr="1")
             bssid = dev[0].get_status_field("bssid")
             if hapd0.own_addr() == bssid:
                 hapd0.wait_sta();
@@ -319,29 +333,38 @@ def test_eppke_mld_ap_with_base_akm_sae_ext_non_mld_client_pmksa_cached(dev, apd
             else:
                 raise Exception("Unknown BSSID: " + bssid)
 
-            dev[0].request("DISCONNECT")
-            dev[0].wait_disconnected()
-            dev[0].request("RECONNECT")
-            dev[0].wait_connected(timeout=15, error="Reconnect timed out")
-            val = dev[0].get_status_field('sae_group')
-            if val is not None:
-                raise Exception("SAE group claimed to have been used: " + val)
-
-            bssid = dev[0].get_status_field("bssid")
-            if hapd0.own_addr() == bssid:
-                hapd0.wait_sta();
-                sta = hapd0.get_sta(dev[0].own_addr())
-            elif hapd1.own_addr() == bssid:
-                hapd1.wait_sta();
-                sta = hapd1.get_sta(dev[0].own_addr())
-            else:
-                raise Exception("Unknown BSSID: " + bssid)
-
-            if sta['auth_alg'] != '9' or sta['AKMSuiteSelector'] != '00-0f-ac-24':
-                raise Exception("Incorrect Auth Algo/AKMSuiteSelector value after PMKSA caching")
+            for i in range(3):
+                prev_addr = dev[0].own_addr()
+                dev[0].request("DISCONNECT")
+                dev[0].wait_disconnected()
+                # Let driver fully process disconnect before MAC change
+                time.sleep(0.5)
+                dev[0].request("RECONNECT")
+                dev[0].wait_connected(timeout=15, error="Reconnect timed out")
+                new_addr = dev[0].own_addr()
+                if new_addr == prev_addr:
+                    raise Exception("MAC address did not change on iteration %d" % i)
+                val = dev[0].get_status_field('sae_group')
+                if val is not None:
+                    raise Exception("SAE group claimed to have been used: " + val)
+
+                bssid = dev[0].get_status_field("bssid")
+                if hapd0.own_addr() == bssid:
+                    hapd0.wait_sta();
+                    sta = hapd0.get_sta(new_addr)
+                elif hapd1.own_addr() == bssid:
+                    hapd1.wait_sta();
+                    sta = hapd1.get_sta(new_addr)
+                else:
+                    raise Exception("Unknown BSSID: " + bssid)
+
+                if sta['auth_alg'] != '9' or sta['AKMSuiteSelector'] != '00-0f-ac-24':
+                    raise Exception("Incorrect Auth Algo/AKMSuiteSelector value after PMKSA caching")
 
         finally:
             dev[0].set("pasn_groups", "")
+            dev[0].set("preassoc_mac_addr", "0")
+            dev[0].set("rand_addr_lifetime", "60")
             dev[0].set("sae_pwe", "0")
 
 def run_eppke_mld_one_link_pmksa_cached(dev, apdev, key_mgmt):
@@ -366,25 +389,40 @@ def run_eppke_mld_one_link_pmksa_cached(dev, apdev, key_mgmt):
 
         wpas.set("pasn_groups", "")
         wpas.set("sae_pwe", "1")
-        wpas.connect(ssid, sae_password=passphrase, scan_freq="2412",
-                     key_mgmt=key_mgmt, ieee80211w="2", beacon_prot="1",
-                     pairwise="CCMP GCMP-256", pmksa_privacy="1")
-        eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
-                          valid_links=1, active_links=1)
-        hapd0.wait_sta();
-        sta = hapd0.get_sta(wpas.own_addr())
-        if sta["AKMSuiteSelector"] != '00-0f-ac-24' or sta["auth_alg"] != '9':
-            raise Exception("Incorrect Auth Algo/AKMSuiteSelector value")
+        wpas.set("preassoc_mac_addr", "1")
+        wpas.set("rand_addr_lifetime", "0")
+        try:
+            wpas.connect(ssid, sae_password=passphrase, scan_freq="2412",
+                         key_mgmt=key_mgmt, ieee80211w="2", beacon_prot="1",
+                         pairwise="CCMP GCMP-256", pmksa_privacy="1",
+                         mac_addr="1")
+            eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
+                              valid_links=1, active_links=1)
+            hapd0.wait_sta();
+            sta = hapd0.get_sta(wpas.own_addr())
+            if sta["AKMSuiteSelector"] != '00-0f-ac-24' or sta["auth_alg"] != '9':
+                raise Exception("Incorrect Auth Algo/AKMSuiteSelector value")
 
-        wpas.request("DISCONNECT")
-        wpas.wait_disconnected()
-        wpas.request("RECONNECT")
-        wpas.wait_connected(timeout=15, error="Reconnect timed out")
-        val = wpas.get_status_field('sae_group')
-        if val is not None:
-            raise Exception("SAE group claimed to have been used: " + val)
-        eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
-                          valid_links=1, active_links=1)
+            for i in range(3):
+                prev_addr = wpas.own_addr()
+                wpas.request("DISCONNECT")
+                wpas.wait_disconnected()
+                # Let driver fully process disconnect before MAC change
+                time.sleep(0.5)
+                wpas.request("RECONNECT")
+                wpas.wait_connected(timeout=15, error="Reconnect timed out")
+                new_addr = wpas.own_addr()
+                if new_addr == prev_addr:
+                    raise Exception("MAC address did not change on iteration %d" % i)
+                val = wpas.get_status_field('sae_group')
+                if val is not None:
+                    raise Exception("SAE group claimed to have been used: " + val)
+                eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
+                                  valid_links=1, active_links=1)
+        finally:
+            wpas.set("preassoc_mac_addr", "0")
+            wpas.set("rand_addr_lifetime", "60")
+            wpas.set("sae_pwe", "0")
 
 def test_eppke_with_base_akm_sae_ext_single_link_pmksa_cached(dev, apdev):
     """EPPKE authentication with an MLD AP with base AKM SAE-EXT and MLD client using single link"""
@@ -415,25 +453,40 @@ def run_eppke_mld_two_links_pmksa_cached(dev, apdev, key_mgmt):
 
         wpas.set("pasn_groups", "")
         wpas.set("sae_pwe", "1")
-        wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
-                     key_mgmt=key_mgmt, ieee80211w="2", beacon_prot="1",
-                     pairwise="CCMP GCMP-256", pmksa_privacy="1")
-        eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
-                          valid_links=3, active_links=3)
-        hapd0.wait_sta();
-        sta = hapd0.get_sta(wpas.own_addr())
-        if sta["AKMSuiteSelector"] != '00-0f-ac-24' or sta["auth_alg"] != '9':
-            raise Exception("Incorrect Auth Algo/AKMSuiteSelector value")
+        wpas.set("preassoc_mac_addr", "1")
+        wpas.set("rand_addr_lifetime", "0")
+        try:
+            wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
+                         key_mgmt=key_mgmt, ieee80211w="2", beacon_prot="1",
+                         pairwise="CCMP GCMP-256", pmksa_privacy="1",
+                         mac_addr="1")
+            eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
+                              valid_links=3, active_links=3)
+            hapd0.wait_sta();
+            sta = hapd0.get_sta(wpas.own_addr())
+            if sta["AKMSuiteSelector"] != '00-0f-ac-24' or sta["auth_alg"] != '9':
+                raise Exception("Incorrect Auth Algo/AKMSuiteSelector value")
 
-        wpas.request("DISCONNECT")
-        wpas.wait_disconnected()
-        wpas.request("RECONNECT")
-        wpas.wait_connected(timeout=15, error="Reconnect timed out")
-        val = wpas.get_status_field('sae_group')
-        if val is not None:
-            raise Exception("SAE group claimed to have been used: " + val)
-        eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
-                          valid_links=3, active_links=3)
+            for i in range(3):
+                prev_addr = wpas.own_addr()
+                wpas.request("DISCONNECT")
+                wpas.wait_disconnected()
+                # Let driver fully process disconnect before MAC change
+                time.sleep(0.5)
+                wpas.request("RECONNECT")
+                wpas.wait_connected(timeout=15, error="Reconnect timed out")
+                new_addr = wpas.own_addr()
+                if new_addr == prev_addr:
+                    raise Exception("MAC address did not change on iteration %d" % i)
+                val = wpas.get_status_field('sae_group')
+                if val is not None:
+                    raise Exception("SAE group claimed to have been used: " + val)
+                eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
+                                  valid_links=3, active_links=3)
+        finally:
+            wpas.set("preassoc_mac_addr", "0")
+            wpas.set("rand_addr_lifetime", "60")
+            wpas.set("sae_pwe", "0")
 
 def test_eppke_with_base_akm_sae_ext_two_link_pmksa_cached(dev, apdev):
     """EPPKE authentication with an MLD AP with base AKM SAE-EXT and MLD client using two links"""
-- 
2.53.0




More information about the Hostap mailing list