diff --git a/tests/hwsim/dictionary.radius b/tests/hwsim/dictionary.radius
index d2112dad3..923c1220e 100644
--- a/tests/hwsim/dictionary.radius
+++ b/tests/hwsim/dictionary.radius
@@ -17,4 +17,5 @@ ATTRIBUTE	Message-Authenticator	80	octets
 ATTRIBUTE	Tunnel-Private-Group-ID	81	string
 ATTRIBUTE	Acct-Interim-Interval	85	integer
 ATTRIBUTE	Chargeable-User-Identity 89	string
+ATTRIBUTE	Tunnel-Client-Auth-ID	90	octets
 ATTRIBUTE	Error-Cause		101	integer
diff --git a/tests/hwsim/test_radius.py b/tests/hwsim/test_radius.py
index ca96c979e..ec359bd0e 100644
--- a/tests/hwsim/test_radius.py
+++ b/tests/hwsim/test_radius.py
@@ -1167,8 +1167,12 @@ def build_tunnel_password(secret, authenticator, psk):
     data = b'\x00' + a + bytes(cc_all)
     return data
 
+def build_tunnel_identity(id):
+   return b'\x00' + id.encode()
+
 def start_radius_psk_server(psk, invalid_code=False, acct_interim_interval=0,
-                            session_timeout=0, reject=False):
+                            session_timeout=0, reject=False, sae_identity=None,
+                            sae_identity2=None):
     try:
         import pyrad.server
         import pyrad.packet
@@ -1195,6 +1199,13 @@ def start_radius_psk_server(psk, invalid_code=False, acct_interim_interval=0,
             if self.t_events['session_timeout']:
                 reply.AddAttribute("Session-Timeout",
                                    self.t_events['session_timeout'])
+            if self.t_events['sae_identity']:
+                data = build_tunnel_identity(self.t_events['sae_identity'])
+                reply.AddAttribute("Tunnel-Client-Auth-ID", data)
+            if self.t_events['sae_identity2']:
+                data = build_tunnel_identity(self.t_events['sae_identity2'])
+                reply.AddAttribute("Tunnel-Client-Auth-ID", data)
+
             self.SendReplyPacket(pkt.fd, reply)
 
         def RunWithStop(self, t_events):
@@ -1231,6 +1242,8 @@ def start_radius_psk_server(psk, invalid_code=False, acct_interim_interval=0,
     t_events['invalid_code'] = invalid_code
     t_events['acct_interim_interval'] = acct_interim_interval
     t_events['session_timeout'] = session_timeout
+    t_events['sae_identity'] = sae_identity
+    t_events['sae_identity2'] = sae_identity2
     t_events['reject'] = reject
     t = threading.Thread(target=run_pyrad_server, args=(srv, t_events))
     t.start()
@@ -1247,6 +1260,28 @@ def hostapd_radius_psk_test_params():
     params['auth_server_port'] = "18138"
     return params
 
+def hostapd_radius_sae_test_params():
+    params = hostapd.radius_params()
+    params['ssid'] = "test-wpa3-sae"
+    params["wpa"] = "2"
+    params["wpa_key_mgmt"] = "SAE"
+    params["rsn_pairwise"] = "CCMP"
+    params['macaddr_acl'] = '2'
+    params['wpa_psk_radius'] = '2'
+    params['auth_server_port'] = "18138"
+    return params
+
+def hostapd_radius_sae_ft_test_params():
+    params = hostapd.radius_params()
+    params['ssid'] = "test-wpa3-sae-ft"
+    params["wpa"] = "2"
+    params["wpa_key_mgmt"] = "FT-SAE"
+    params["rsn_pairwise"] = "CCMP"
+    params['macaddr_acl'] = '2'
+    params['wpa_psk_radius'] = '2'
+    params['auth_server_port'] = "18138"
+    return params
+
 def test_radius_psk(dev, apdev):
     """WPA2 with PSK from RADIUS"""
     t, t_events = start_radius_psk_server("12345678")
@@ -1708,3 +1743,85 @@ def test_radius_acct_failure_sta_data(dev, apdev):
         dev[0].request("DISCONNECT")
         dev[0].wait_disconnected()
         hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=1)
+
+def test_radius_sae(dev, apdev):
+    """WPA3 with SAE from RADIUS"""
+    t, t_events = start_radius_psk_server("12345678")
+
+    try:
+        params = hostapd_radius_sae_test_params()
+        hapd = hostapd.add_ap(apdev[0], params)
+        dev[0].connect("test-wpa3-sae", sae_password="12345678", key_mgmt="SAE",
+                       scan_freq="2412")
+        t_events['psk'] = "0123456789abcdef"
+        dev[1].connect("test-wpa3-sae", sae_password="0123456789abcdef", key_mgmt="SAE",
+                       scan_freq="2412")
+    finally:
+        t_events['stop'].set()
+        t.join()
+
+def test_radius_sae_ft(dev, apdev):
+    """WPA3 with FT-SAE from RADIUS"""
+    t, t_events = start_radius_psk_server("12345678")
+
+    try:
+        params = hostapd_radius_sae_ft_test_params()
+        hapd = hostapd.add_ap(apdev[0], params)
+        dev[0].connect("test-wpa3-sae-ft", sae_password="12345678", key_mgmt="FT-SAE",
+                       scan_freq="2412")
+        t_events['psk'] = "0123456789abcdef"
+        dev[1].connect("test-wpa3-sae-ft", sae_password="0123456789abcdef", key_mgmt="FT-SAE",
+                       scan_freq="2412")
+    finally:
+        t_events['stop'].set()
+        t.join()
+
+def test_radius_sae_id(dev, apdev):
+    """WPA3 with SAE from RADIUS with SAE password identity"""
+    t, t_events = start_radius_psk_server("12345678", sae_identity="user0")
+
+    try:
+        params = hostapd_radius_sae_test_params()
+        hapd = hostapd.add_ap(apdev[0], params)
+        dev[0].connect("test-wpa3-sae", sae_password="12345678", key_mgmt="SAE",
+                       scan_freq="2412", sae_password_id="user0")
+        t_events['psk'] = "0123456789abcdef"
+        t_events['sae_identity'] = "user1"
+        dev[1].connect("test-wpa3-sae", sae_password="0123456789abcdef", key_mgmt="SAE",
+                       scan_freq="2412", sae_password_id="user1")
+    finally:
+        t_events['stop'].set()
+        t.join()
+
+def test_radius_sae_id_ft(dev, apdev):
+    """WPA3 with FT-SAE from RADIUS with SAE password identity"""
+    t, t_events = start_radius_psk_server("12345678", sae_identity="user0")
+
+    try:
+        params = hostapd_radius_sae_ft_test_params()
+        hapd = hostapd.add_ap(apdev[0], params)
+        dev[0].connect("test-wpa3-sae-ft", sae_password="12345678", key_mgmt="FT-SAE",
+                       scan_freq="2412", sae_password_id="user0")
+        t_events['psk'] = "0123456789abcdef"
+        t_events['sae_identity'] = "user1"
+        dev[1].connect("test-wpa3-sae-ft", sae_password="0123456789abcdef", key_mgmt="FT-SAE",
+                       scan_freq="2412", sae_password_id="user1")
+    finally:
+        t_events['stop'].set()
+        t.join()
+
+def test_radius_sae_multi_id(dev, apdev):
+    """WPA3 with SAE from RADIUS with multiple SAE password identity"""
+    t, t_events = start_radius_psk_server("12345678", sae_identity="user0", sae_identity2="user1")
+
+    try:
+        params = hostapd_radius_sae_test_params()
+        hapd = hostapd.add_ap(apdev[0], params)
+        dev[0].connect("test-wpa3-sae", sae_password="12345678", key_mgmt="SAE",
+                       scan_freq="2412", sae_password_id="user0")
+        dev[1].connect("test-wpa3-sae", sae_password="12345678", key_mgmt="SAE",
+                       scan_freq="2412", sae_password_id="user1")
+    finally:
+        t_events['stop'].set()
+        t.join()
+
