1# Test cases for SAE 2# Copyright (c) 2013-2020, Jouni Malinen <j@w1.fi> 3# 4# This software may be distributed under the terms of the BSD license. 5# See README for more details. 6 7from remotehost import remote_compatible 8import binascii 9import os 10import time 11import logging 12logger = logging.getLogger() 13import socket 14import struct 15import subprocess 16import tempfile 17 18import hwsim_utils 19import hostapd 20from wpasupplicant import WpaSupplicant 21from utils import * 22from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations 23 24@remote_compatible 25def test_sae(dev, apdev): 26 """SAE with default group""" 27 check_sae_capab(dev[0]) 28 params = hostapd.wpa2_params(ssid="test-sae", 29 passphrase="12345678") 30 params['wpa_key_mgmt'] = 'SAE' 31 hapd = hostapd.add_ap(apdev[0], params) 32 key_mgmt = hapd.get_config()['key_mgmt'] 33 if key_mgmt.split(' ')[0] != "SAE": 34 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt) 35 36 dev[0].request("SET sae_groups ") 37 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 38 scan_freq="2412") 39 hapd.wait_sta() 40 if dev[0].get_status_field('sae_group') != '19': 41 raise Exception("Expected default SAE group not used") 42 bss = dev[0].get_bss(apdev[0]['bssid']) 43 if 'flags' not in bss: 44 raise Exception("Could not get BSS flags from BSS table") 45 if "[WPA2-SAE-CCMP]" not in bss['flags']: 46 raise Exception("Unexpected BSS flags: " + bss['flags']) 47 48 res = hapd.request("STA-FIRST") 49 if "sae_group=19" not in res.splitlines(): 50 raise Exception("hostapd STA output did not specify SAE group") 51 52 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr()) 53 pmk_w = dev[0].get_pmk(id) 54 if pmk_h != pmk_w: 55 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w)) 56 dev[0].request("DISCONNECT") 57 dev[0].wait_disconnected() 58 pmk_h2 = hapd.request("GET_PMK " + dev[0].own_addr()) 59 if pmk_h != pmk_h2: 60 raise Exception("Fetched PMK from PMKSA cache does not match: %s, %s" % (pmk_h, pmk_h2)) 61 if "FAIL" not in hapd.request("GET_PMK foo"): 62 raise Exception("Invalid GET_PMK did not return failure") 63 if "FAIL" not in hapd.request("GET_PMK 02:ff:ff:ff:ff:ff"): 64 raise Exception("GET_PMK for unknown STA did not return failure") 65 66@remote_compatible 67def test_sae_password_ecc(dev, apdev): 68 """SAE with number of different passwords (ECC)""" 69 check_sae_capab(dev[0]) 70 params = hostapd.wpa2_params(ssid="test-sae", 71 passphrase="12345678") 72 params['wpa_key_mgmt'] = 'SAE' 73 hapd = hostapd.add_ap(apdev[0], params) 74 75 dev[0].request("SET sae_groups 19") 76 77 for i in range(10): 78 password = "12345678-" + str(i) 79 hapd.set("wpa_passphrase", password) 80 dev[0].connect("test-sae", psk=password, key_mgmt="SAE", 81 scan_freq="2412") 82 dev[0].request("REMOVE_NETWORK all") 83 dev[0].wait_disconnected() 84 85@remote_compatible 86def test_sae_password_ffc(dev, apdev): 87 """SAE with number of different passwords (FFC)""" 88 check_sae_capab(dev[0]) 89 params = hostapd.wpa2_params(ssid="test-sae", 90 passphrase="12345678") 91 params['wpa_key_mgmt'] = 'SAE' 92 params['sae_groups'] = '15' 93 hapd = hostapd.add_ap(apdev[0], params) 94 95 dev[0].request("SET sae_groups 15") 96 97 for i in range(10): 98 password = "12345678-" + str(i) 99 hapd.set("wpa_passphrase", password) 100 dev[0].connect("test-sae", psk=password, key_mgmt="SAE", 101 scan_freq="2412") 102 dev[0].request("REMOVE_NETWORK all") 103 dev[0].wait_disconnected() 104 105@remote_compatible 106def test_sae_pmksa_caching(dev, apdev): 107 """SAE and PMKSA caching""" 108 run_sae_pmksa_caching(dev, apdev) 109 110@remote_compatible 111def test_sae_pmksa_caching_pmkid(dev, apdev): 112 """SAE and PMKSA caching (PMKID in AssocReq after SAE)""" 113 try: 114 dev[0].set("sae_pmkid_in_assoc", "1") 115 run_sae_pmksa_caching(dev, apdev) 116 finally: 117 dev[0].set("sae_pmkid_in_assoc", "0") 118 119def run_sae_pmksa_caching(dev, apdev): 120 check_sae_capab(dev[0]) 121 params = hostapd.wpa2_params(ssid="test-sae", 122 passphrase="12345678") 123 params['wpa_key_mgmt'] = 'SAE' 124 hapd = hostapd.add_ap(apdev[0], params) 125 126 dev[0].request("SET sae_groups ") 127 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 128 scan_freq="2412") 129 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 130 if ev is None: 131 raise Exception("No connection event received from hostapd") 132 sta0 = hapd.get_sta(dev[0].own_addr()) 133 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-8': 134 raise Exception("SAE STA(0) AKM suite selector reported incorrectly") 135 dev[0].request("DISCONNECT") 136 dev[0].wait_disconnected() 137 dev[0].request("RECONNECT") 138 dev[0].wait_connected(timeout=15, error="Reconnect timed out") 139 val = dev[0].get_status_field('sae_group') 140 if val is not None: 141 raise Exception("SAE group claimed to have been used: " + val) 142 sta0 = hapd.get_sta(dev[0].own_addr()) 143 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-8': 144 raise Exception("SAE STA(0) AKM suite selector reported incorrectly after PMKSA caching") 145 146@remote_compatible 147def test_sae_pmksa_caching_disabled(dev, apdev): 148 """SAE and PMKSA caching disabled""" 149 check_sae_capab(dev[0]) 150 params = hostapd.wpa2_params(ssid="test-sae", 151 passphrase="12345678") 152 params['wpa_key_mgmt'] = 'SAE' 153 params['disable_pmksa_caching'] = '1' 154 hapd = hostapd.add_ap(apdev[0], params) 155 156 dev[0].request("SET sae_groups ") 157 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 158 scan_freq="2412") 159 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 160 if ev is None: 161 raise Exception("No connection event received from hostapd") 162 dev[0].request("DISCONNECT") 163 dev[0].wait_disconnected() 164 dev[0].request("RECONNECT") 165 dev[0].wait_connected(timeout=15, error="Reconnect timed out") 166 if dev[0].get_status_field('sae_group') != '19': 167 raise Exception("Expected default SAE group not used") 168 169def test_sae_groups(dev, apdev): 170 """SAE with all supported groups""" 171 check_sae_capab(dev[0]) 172 # This is the full list of supported groups, but groups 14-16 (2048-4096 bit 173 # MODP) and group 21 (521-bit random ECP group) are a bit too slow on some 174 # VMs and can result in hitting the mac80211 authentication timeout, so 175 # allow them to fail and just report such failures in the debug log. 176 sae_groups = [19, 25, 26, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24] 177 tls = dev[0].request("GET tls_library") 178 if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls: 179 logger.info("Add Brainpool EC groups since OpenSSL is new enough") 180 sae_groups += [27, 28, 29, 30] 181 heavy_groups = [14, 15, 16] 182 suitable_groups = [15, 16, 17, 18, 19, 20, 21] 183 groups = [str(g) for g in sae_groups] 184 params = hostapd.wpa2_params(ssid="test-sae-groups", 185 passphrase="12345678") 186 params['wpa_key_mgmt'] = 'SAE' 187 params['sae_groups'] = ' '.join(groups) 188 hapd = hostapd.add_ap(apdev[0], params) 189 190 for g in groups: 191 logger.info("Testing SAE group " + g) 192 dev[0].request("SET sae_groups " + g) 193 id = dev[0].connect("test-sae-groups", psk="12345678", key_mgmt="SAE", 194 scan_freq="2412", wait_connect=False) 195 if int(g) in heavy_groups: 196 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5) 197 if ev is None: 198 logger.info("No connection with heavy SAE group %s did not connect - likely hitting timeout in mac80211" % g) 199 dev[0].remove_network(id) 200 time.sleep(0.1) 201 dev[0].dump_monitor() 202 continue 203 logger.info("Connection with heavy SAE group " + g) 204 else: 205 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10) 206 if ev is None: 207 if "BoringSSL" in tls and int(g) in [25]: 208 logger.info("Ignore connection failure with group " + g + " with BoringSSL") 209 dev[0].remove_network(id) 210 dev[0].dump_monitor() 211 continue 212 if int(g) not in suitable_groups: 213 logger.info("Ignore connection failure with unsuitable group " + g) 214 dev[0].remove_network(id) 215 dev[0].dump_monitor() 216 continue 217 raise Exception("Connection timed out with group " + g) 218 if dev[0].get_status_field('sae_group') != g: 219 raise Exception("Expected SAE group not used") 220 pmksa = dev[0].get_pmksa(hapd.own_addr()) 221 if not pmksa: 222 raise Exception("No PMKSA cache entry added") 223 if pmksa['pmkid'] == '00000000000000000000000000000000': 224 raise Exception("All zeros PMKID derived for group %s" % g) 225 dev[0].remove_network(id) 226 dev[0].wait_disconnected() 227 dev[0].dump_monitor() 228 229@remote_compatible 230def test_sae_group_nego(dev, apdev): 231 """SAE group negotiation""" 232 check_sae_capab(dev[0]) 233 params = hostapd.wpa2_params(ssid="test-sae-group-nego", 234 passphrase="12345678") 235 params['wpa_key_mgmt'] = 'SAE' 236 params['sae_groups'] = '19' 237 hostapd.add_ap(apdev[0], params) 238 239 dev[0].request("SET sae_groups 25 20 19") 240 dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE", 241 scan_freq="2412") 242 if dev[0].get_status_field('sae_group') != '19': 243 raise Exception("Expected SAE group not used") 244 245def test_sae_group_nego_no_match(dev, apdev): 246 """SAE group negotiation (no match)""" 247 check_sae_capab(dev[0]) 248 params = hostapd.wpa2_params(ssid="test-sae-group-nego", 249 passphrase="12345678") 250 params['wpa_key_mgmt'] = 'SAE' 251 # None-existing SAE group to force all attempts to be rejected 252 params['sae_groups'] = '0' 253 hostapd.add_ap(apdev[0], params) 254 255 dev[0].request("SET sae_groups ") 256 dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE", 257 scan_freq="2412", wait_connect=False) 258 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10) 259 dev[0].request("REMOVE_NETWORK all") 260 if ev is None: 261 raise Exception("Network profile disabling not reported") 262 263@remote_compatible 264def test_sae_anti_clogging(dev, apdev): 265 """SAE anti clogging""" 266 check_sae_capab(dev[0]) 267 check_sae_capab(dev[1]) 268 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 269 params['wpa_key_mgmt'] = 'SAE' 270 params['sae_anti_clogging_threshold'] = '1' 271 hostapd.add_ap(apdev[0], params) 272 273 dev[0].request("SET sae_groups ") 274 dev[1].request("SET sae_groups ") 275 id = {} 276 for i in range(0, 2): 277 dev[i].scan(freq="2412") 278 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 279 scan_freq="2412", only_add_network=True) 280 for i in range(0, 2): 281 dev[i].select_network(id[i]) 282 for i in range(0, 2): 283 dev[i].wait_connected(timeout=10) 284 285def test_sae_forced_anti_clogging(dev, apdev): 286 """SAE anti clogging (forced)""" 287 check_sae_capab(dev[0]) 288 check_sae_capab(dev[1]) 289 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 290 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 291 params['sae_anti_clogging_threshold'] = '0' 292 hostapd.add_ap(apdev[0], params) 293 dev[2].connect("test-sae", psk="12345678", scan_freq="2412") 294 for i in range(0, 2): 295 dev[i].request("SET sae_groups ") 296 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 297 scan_freq="2412") 298 299def test_sae_mixed(dev, apdev): 300 """Mixed SAE and non-SAE network""" 301 check_sae_capab(dev[0]) 302 check_sae_capab(dev[1]) 303 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 304 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 305 params['sae_anti_clogging_threshold'] = '0' 306 hapd = hostapd.add_ap(apdev[0], params) 307 308 dev[2].connect("test-sae", psk="12345678", scan_freq="2412") 309 for i in range(0, 2): 310 dev[i].request("SET sae_groups ") 311 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 312 scan_freq="2412") 313 sta0 = hapd.get_sta(dev[0].own_addr()) 314 sta2 = hapd.get_sta(dev[2].own_addr()) 315 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-8': 316 raise Exception("SAE STA(0) AKM suite selector reported incorrectly") 317 if sta2['wpa'] != '2' or sta2['AKMSuiteSelector'] != '00-0f-ac-2': 318 raise Exception("PSK STA(2) AKM suite selector reported incorrectly") 319 320def test_sae_and_psk(dev, apdev): 321 """SAE and PSK enabled in network profile""" 322 check_sae_capab(dev[0]) 323 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 324 params['wpa_key_mgmt'] = 'SAE' 325 hostapd.add_ap(apdev[0], params) 326 327 dev[0].request("SET sae_groups ") 328 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE WPA-PSK", 329 scan_freq="2412") 330 331def test_sae_and_psk2(dev, apdev): 332 """SAE and PSK enabled in network profile (use PSK)""" 333 check_sae_capab(dev[0]) 334 params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678") 335 hostapd.add_ap(apdev[0], params) 336 337 dev[0].request("SET sae_groups ") 338 dev[0].connect("test-psk", psk="12345678", key_mgmt="SAE WPA-PSK", 339 scan_freq="2412") 340 341def test_sae_wpa3_roam(dev, apdev): 342 """SAE and WPA3-Personal transition mode roaming""" 343 check_sae_capab(dev[0]) 344 345 # WPA3-Personal only AP 346 params = hostapd.wpa2_params(ssid="test", passphrase="12345678") 347 params['ieee80211w'] = '2' 348 params['wpa_key_mgmt'] = 'SAE' 349 hapd0 = hostapd.add_ap(apdev[0], params) 350 351 # WPA2-Personal only AP 352 params = hostapd.wpa2_params(ssid="test", passphrase="12345678") 353 hapd1 = hostapd.add_ap(apdev[1], params) 354 355 dev[0].set("sae_groups", "") 356 dev[0].connect("test", psk="12345678", key_mgmt="SAE WPA-PSK", 357 ieee80211w="1", scan_freq="2412") 358 bssid = dev[0].get_status_field('bssid') 359 360 # Disable the current AP to force roam to the other one 361 if bssid == apdev[0]['bssid']: 362 hapd0.disable() 363 else: 364 hapd1.disable() 365 dev[0].wait_connected() 366 367 # Disable the current AP to force roam to the other (previous) one 368 if bssid == apdev[0]['bssid']: 369 hapd0.enable() 370 hapd1.disable() 371 else: 372 hapd1.enable() 373 hapd0.disable() 374 dev[0].wait_connected() 375 376 # Force roam to an AP in WPA3-Personal transition mode 377 if bssid == apdev[0]['bssid']: 378 hapd1.set("ieee80211w", "1") 379 hapd1.set("sae_require_mfp", "1") 380 hapd1.set("wpa_key_mgmt", "SAE WPA-PSK") 381 hapd1.enable() 382 hapd0.disable() 383 else: 384 hapd0.set("ieee80211w", "1") 385 hapd0.set("sae_require_mfp", "1") 386 hapd0.set("wpa_key_mgmt", "SAE WPA-PSK") 387 hapd0.enable() 388 hapd1.disable() 389 dev[0].wait_connected() 390 status = dev[0].get_status() 391 if status['key_mgmt'] != "SAE": 392 raise Exception("Did not use SAE with WPA3-Personal transition mode AP") 393 if status['pmf'] != "1": 394 raise Exception("Did not use PMF with WPA3-Personal transition mode AP") 395 396def test_sae_mixed_mfp(dev, apdev): 397 """Mixed SAE and non-SAE network and MFP required with SAE""" 398 check_sae_capab(dev[0]) 399 check_sae_capab(dev[1]) 400 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 401 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 402 params["ieee80211w"] = "1" 403 params['sae_require_mfp'] = '1' 404 hostapd.add_ap(apdev[0], params) 405 406 dev[0].request("SET sae_groups ") 407 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2", 408 scan_freq="2412") 409 dev[0].dump_monitor() 410 411 dev[1].request("SET sae_groups ") 412 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="0", 413 scan_freq="2412", wait_connect=False) 414 ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED", 415 "CTRL-EVENT-ASSOC-REJECT"], timeout=10) 416 if ev is None: 417 raise Exception("No connection result reported") 418 if "CTRL-EVENT-ASSOC-REJECT" not in ev: 419 raise Exception("SAE connection without MFP was not rejected") 420 if "status_code=31" not in ev: 421 raise Exception("Unexpected status code in rejection: " + ev) 422 dev[1].request("DISCONNECT") 423 dev[1].dump_monitor() 424 425 dev[2].connect("test-sae", psk="12345678", ieee80211w="0", scan_freq="2412") 426 dev[2].dump_monitor() 427 428def _test_sae_mixed_check_mfp(dev, apdev): 429 """Mixed SAE and non-SAE network with the sae_check_mfp option""" 430 check_sae_capab(dev[0]) 431 check_sae_capab(dev[1]) 432 check_sae_capab(dev[2]) 433 434 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 435 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 436 params["ieee80211w"] = "1" 437 hostapd.add_ap(apdev[0], params) 438 439 params = hostapd.wpa2_params(ssid="test-sae-no-mfp", passphrase="12345678") 440 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 441 params["ieee80211w"] = "0" 442 hostapd.add_ap(apdev[1], params) 443 444 dev[0].set("sae_check_mfp", "0") 445 dev[0].set("sae_groups", "") 446 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE WPA-PSK", 447 ieee80211w="0", scan_freq="2412") 448 dev[0].dump_monitor() 449 status = dev[0].get_status() 450 if status['key_mgmt'] != "SAE": 451 raise Exception("SAE without sae_check_mfp was not allowed") 452 453 # Confirm SAE is used when sae_check_mfp is not set for non-PMF AP. 454 dev[2].set("sae_check_mfp", "0") 455 dev[2].set("sae_groups", "") 456 dev[2].connect("test-sae-no-mfp", psk="12345678", key_mgmt="SAE WPA-PSK", 457 ieee80211w="1", scan_freq="2412") 458 status = dev[2].get_status() 459 if status['key_mgmt'] != "SAE": 460 raise Exception("SAE without sae_check_mfp was not allowed") 461 dev[2].dump_monitor() 462 463 # Confirm SAE is not used with the PMF disabled network configuration. 464 dev[1].set("sae_check_mfp", "1") 465 dev[1].set("sae_groups", "") 466 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE WPA-PSK", 467 ieee80211w="0", scan_freq="2412") 468 status = dev[1].get_status() 469 dev[1].request("DISCONNECT") 470 dev[1].wait_disconnected() 471 dev[1].dump_monitor() 472 if status['key_mgmt'] != "WPA2-PSK": 473 raise Exception("SAE without MFP was allowed") 474 dev[1].request("REMOVE_NETWORK all") 475 476 # Confirm SAE is not used connecting to PMF disabled AP. 477 dev[1].set("sae_check_mfp", "1") 478 dev[1].set("sae_groups", "") 479 dev[1].connect("test-sae-no-mfp", psk="12345678", key_mgmt="SAE WPA-PSK", 480 ieee80211w="1", scan_freq="2412") 481 status = dev[1].get_status() 482 if status['key_mgmt'] != "WPA2-PSK": 483 raise Exception("SAE without MFP was allowed") 484 485def test_sae_mixed_check_mfp(dev, apdev): 486 """Mixed SAE and non-SAE network with the sae_check_mfp option""" 487 try: 488 _test_sae_mixed_check_mfp(dev, apdev) 489 finally: 490 dev[0].set("sae_check_mfp", "0") 491 dev[1].set("sae_check_mfp", "0") 492 dev[2].set("sae_check_mfp", "0") 493 494def test_sae_and_psk_transition_disable(dev, apdev): 495 """SAE and PSK transition disable indication""" 496 check_sae_capab(dev[0]) 497 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 498 params["ieee80211w"] = "1" 499 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 500 params['transition_disable'] = '0x01' 501 hapd = hostapd.add_ap(apdev[0], params) 502 503 dev[0].request("SET sae_groups ") 504 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE WPA-PSK", 505 ieee80211w="1", scan_freq="2412", wait_connect=False) 506 ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=15) 507 if ev is None: 508 raise Exception("Transition disable not indicated") 509 if ev.split(' ')[1] != "01": 510 raise Exception("Unexpected transition disable bitmap: " + ev) 511 512 val = dev[0].get_network(id, "ieee80211w") 513 if val != "2": 514 raise Exception("Unexpected ieee80211w value: " + val) 515 val = dev[0].get_network(id, "key_mgmt") 516 if val != "SAE": 517 raise Exception("Unexpected key_mgmt value: " + val) 518 val = dev[0].get_network(id, "group") 519 if val != "CCMP": 520 raise Exception("Unexpected group value: " + val) 521 val = dev[0].get_network(id, "proto") 522 if val != "RSN": 523 raise Exception("Unexpected proto value: " + val) 524 525 dev[0].request("DISCONNECT") 526 dev[0].wait_disconnected() 527 dev[0].request("RECONNECT") 528 dev[0].wait_connected() 529 530def test_sae_mfp(dev, apdev): 531 """SAE and MFP enabled without sae_require_mfp""" 532 check_sae_capab(dev[0]) 533 check_sae_capab(dev[1]) 534 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 535 params['wpa_key_mgmt'] = 'SAE' 536 params["ieee80211w"] = "1" 537 hostapd.add_ap(apdev[0], params) 538 539 dev[0].request("SET sae_groups ") 540 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2", 541 scan_freq="2412") 542 543 dev[1].request("SET sae_groups ") 544 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="0", 545 scan_freq="2412") 546 547@remote_compatible 548def test_sae_missing_password(dev, apdev): 549 """SAE and missing password""" 550 check_sae_capab(dev[0]) 551 params = hostapd.wpa2_params(ssid="test-sae", 552 passphrase="12345678") 553 params['wpa_key_mgmt'] = 'SAE' 554 hapd = hostapd.add_ap(apdev[0], params) 555 556 dev[0].request("SET sae_groups ") 557 id = dev[0].connect("test-sae", 558 raw_psk="46b4a73b8a951ad53ebd2e0afdb9c5483257edd4c21d12b7710759da70945858", 559 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 560 ev = dev[0].wait_event(['CTRL-EVENT-SSID-TEMP-DISABLED'], timeout=10) 561 if ev is None: 562 raise Exception("Invalid network not temporarily disabled") 563 564 565def test_sae_key_lifetime_in_memory(dev, apdev, params): 566 """SAE and key lifetime in memory""" 567 check_sae_capab(dev[0]) 568 password = "5ad144a7c1f5a5503baa6fa01dabc15b1843e8c01662d78d16b70b5cd23cf8b" 569 p = hostapd.wpa2_params(ssid="test-sae", passphrase=password) 570 p['wpa_key_mgmt'] = 'SAE' 571 hapd = hostapd.add_ap(apdev[0], p) 572 573 pid = find_wpas_process(dev[0]) 574 575 dev[0].request("SET sae_groups ") 576 id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE", 577 scan_freq="2412") 578 579 # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED 580 # event has been delivered, so verify that wpa_supplicant has returned to 581 # eloop before reading process memory. 582 time.sleep(1) 583 dev[0].ping() 584 password = password.encode() 585 buf = read_process_memory(pid, password) 586 587 dev[0].request("DISCONNECT") 588 dev[0].wait_disconnected() 589 590 dev[0].relog() 591 sae_k = None 592 sae_keyseed = None 593 sae_kck = None 594 pmk = None 595 ptk = None 596 gtk = None 597 with open(os.path.join(params['logdir'], 'log0'), 'r') as f: 598 for l in f.readlines(): 599 if "SAE: k - hexdump" in l: 600 val = l.strip().split(':')[3].replace(' ', '') 601 sae_k = binascii.unhexlify(val) 602 if "SAE: keyseed - hexdump" in l: 603 val = l.strip().split(':')[3].replace(' ', '') 604 sae_keyseed = binascii.unhexlify(val) 605 if "SAE: KCK - hexdump" in l: 606 val = l.strip().split(':')[3].replace(' ', '') 607 sae_kck = binascii.unhexlify(val) 608 if "SAE: PMK - hexdump" in l: 609 val = l.strip().split(':')[3].replace(' ', '') 610 pmk = binascii.unhexlify(val) 611 if "WPA: PTK - hexdump" in l: 612 val = l.strip().split(':')[3].replace(' ', '') 613 ptk = binascii.unhexlify(val) 614 if "WPA: Group Key - hexdump" in l: 615 val = l.strip().split(':')[3].replace(' ', '') 616 gtk = binascii.unhexlify(val) 617 if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk: 618 raise Exception("Could not find keys from debug log") 619 if len(gtk) != 16: 620 raise Exception("Unexpected GTK length") 621 622 kck = ptk[0:16] 623 kek = ptk[16:32] 624 tk = ptk[32:48] 625 626 fname = os.path.join(params['logdir'], 627 'sae_key_lifetime_in_memory.memctx-') 628 629 logger.info("Checking keys in memory while associated") 630 get_key_locations(buf, password, "Password") 631 get_key_locations(buf, pmk, "PMK") 632 if password not in buf: 633 raise HwsimSkip("Password not found while associated") 634 if pmk not in buf: 635 raise HwsimSkip("PMK not found while associated") 636 if kck not in buf: 637 raise Exception("KCK not found while associated") 638 if kek not in buf: 639 raise Exception("KEK not found while associated") 640 #if tk in buf: 641 # raise Exception("TK found from memory") 642 verify_not_present(buf, sae_k, fname, "SAE(k)") 643 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") 644 verify_not_present(buf, sae_kck, fname, "SAE(KCK)") 645 646 logger.info("Checking keys in memory after disassociation") 647 buf = read_process_memory(pid, password) 648 649 # Note: Password is still present in network configuration 650 # Note: PMK is in PMKSA cache 651 652 get_key_locations(buf, password, "Password") 653 get_key_locations(buf, pmk, "PMK") 654 verify_not_present(buf, kck, fname, "KCK") 655 verify_not_present(buf, kek, fname, "KEK") 656 verify_not_present(buf, tk, fname, "TK") 657 if gtk in buf: 658 get_key_locations(buf, gtk, "GTK") 659 verify_not_present(buf, gtk, fname, "GTK") 660 verify_not_present(buf, sae_k, fname, "SAE(k)") 661 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") 662 verify_not_present(buf, sae_kck, fname, "SAE(KCK)") 663 664 dev[0].request("PMKSA_FLUSH") 665 logger.info("Checking keys in memory after PMKSA cache flush") 666 buf = read_process_memory(pid, password) 667 get_key_locations(buf, password, "Password") 668 get_key_locations(buf, pmk, "PMK") 669 verify_not_present(buf, pmk, fname, "PMK") 670 671 dev[0].request("REMOVE_NETWORK all") 672 673 logger.info("Checking keys in memory after network profile removal") 674 buf = read_process_memory(pid, password) 675 676 get_key_locations(buf, password, "Password") 677 get_key_locations(buf, pmk, "PMK") 678 verify_not_present(buf, password, fname, "password") 679 verify_not_present(buf, pmk, fname, "PMK") 680 verify_not_present(buf, kck, fname, "KCK") 681 verify_not_present(buf, kek, fname, "KEK") 682 verify_not_present(buf, tk, fname, "TK") 683 verify_not_present(buf, gtk, fname, "GTK") 684 verify_not_present(buf, sae_k, fname, "SAE(k)") 685 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") 686 verify_not_present(buf, sae_kck, fname, "SAE(KCK)") 687 688@remote_compatible 689def test_sae_oom_wpas(dev, apdev): 690 """SAE and OOM in wpa_supplicant""" 691 check_sae_capab(dev[0]) 692 params = hostapd.wpa2_params(ssid="test-sae", 693 passphrase="12345678") 694 params['wpa_key_mgmt'] = 'SAE' 695 params['sae_groups'] = '19 25 26 20' 696 hapd = hostapd.add_ap(apdev[0], params) 697 698 dev[0].request("SET sae_groups 20") 699 with alloc_fail(dev[0], 1, "sae_set_group"): 700 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 701 scan_freq="2412") 702 dev[0].request("REMOVE_NETWORK all") 703 704 dev[0].request("SET sae_groups ") 705 with alloc_fail(dev[0], 2, "sae_set_group"): 706 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 707 scan_freq="2412") 708 dev[0].request("REMOVE_NETWORK all") 709 710 with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_commit"): 711 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 712 scan_freq="2412") 713 dev[0].request("REMOVE_NETWORK all") 714 715 with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_confirm"): 716 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 717 scan_freq="2412", wait_connect=False) 718 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 719 dev[0].request("REMOVE_NETWORK all") 720 721 with alloc_fail(dev[0], 1, "=sme_authenticate"): 722 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 723 scan_freq="2412", wait_connect=False) 724 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 725 dev[0].request("REMOVE_NETWORK all") 726 727 with alloc_fail(dev[0], 1, "radio_add_work;sme_authenticate"): 728 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 729 scan_freq="2412", wait_connect=False) 730 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 731 dev[0].request("REMOVE_NETWORK all") 732 733@remote_compatible 734def test_sae_proto_ecc(dev, apdev): 735 """SAE protocol testing (ECC)""" 736 check_sae_capab(dev[0]) 737 params = hostapd.wpa2_params(ssid="test-sae", 738 passphrase="12345678") 739 params['wpa_key_mgmt'] = 'SAE' 740 hapd = hostapd.add_ap(apdev[0], params) 741 bssid = apdev[0]['bssid'] 742 743 dev[0].request("SET sae_groups 19") 744 745 tests = [("Confirm mismatch", 746 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8", 747 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc4240"), 748 ("Commit without even full cyclic group field", 749 "13", 750 None), 751 ("Too short commit", 752 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02", 753 None), 754 ("Invalid commit scalar (0)", 755 "1300" + "0000000000000000000000000000000000000000000000000000000000000000" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8", 756 None), 757 ("Invalid commit scalar (1)", 758 "1300" + "0000000000000000000000000000000000000000000000000000000000000001" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8", 759 None), 760 ("Invalid commit scalar (> r)", 761 "1300" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8", 762 None), 763 ("Commit element not on curve", 764 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728d0000000000000000000000000000000000000000000000000000000000000000", 765 None), 766 ("Invalid commit element (y coordinate > P)", 767 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 768 None), 769 ("Invalid commit element (x coordinate > P)", 770 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8", 771 None), 772 ("Different group in commit", 773 "1400" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8", 774 None), 775 ("Too short confirm", 776 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8", 777 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc42")] 778 for (note, commit, confirm) in tests: 779 logger.info(note) 780 dev[0].scan_for_bss(bssid, freq=2412) 781 hapd.set("ext_mgmt_frame_handling", "1") 782 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 783 scan_freq="2412", wait_connect=False) 784 785 logger.info("Commit") 786 for i in range(0, 10): 787 req = hapd.mgmt_rx() 788 if req is None: 789 raise Exception("MGMT RX wait timed out (commit)") 790 if req['subtype'] == 11: 791 break 792 req = None 793 if not req: 794 raise Exception("Authentication frame (commit) not received") 795 796 hapd.dump_monitor() 797 resp = {} 798 resp['fc'] = req['fc'] 799 resp['da'] = req['sa'] 800 resp['sa'] = req['da'] 801 resp['bssid'] = req['bssid'] 802 resp['payload'] = binascii.unhexlify("030001000000" + commit) 803 hapd.mgmt_tx(resp) 804 805 if confirm: 806 logger.info("Confirm") 807 for i in range(0, 10): 808 req = hapd.mgmt_rx() 809 if req is None: 810 raise Exception("MGMT RX wait timed out (confirm)") 811 if req['subtype'] == 11: 812 break 813 req = None 814 if not req: 815 raise Exception("Authentication frame (confirm) not received") 816 817 hapd.dump_monitor() 818 resp = {} 819 resp['fc'] = req['fc'] 820 resp['da'] = req['sa'] 821 resp['sa'] = req['da'] 822 resp['bssid'] = req['bssid'] 823 resp['payload'] = binascii.unhexlify("030002000000" + confirm) 824 hapd.mgmt_tx(resp) 825 826 time.sleep(0.1) 827 dev[0].request("REMOVE_NETWORK all") 828 hapd.set("ext_mgmt_frame_handling", "0") 829 hapd.dump_monitor() 830 831@remote_compatible 832def test_sae_proto_ffc(dev, apdev): 833 """SAE protocol testing (FFC)""" 834 check_sae_capab(dev[0]) 835 params = hostapd.wpa2_params(ssid="test-sae", 836 passphrase="12345678") 837 params['wpa_key_mgmt'] = 'SAE' 838 hapd = hostapd.add_ap(apdev[0], params) 839 bssid = apdev[0]['bssid'] 840 841 dev[0].request("SET sae_groups 2") 842 843 tests = [("Confirm mismatch", 844 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a17486", 845 "0000f3116a9731f1259622e3eb55d4b3b50ba16f8c5f5565b28e609b180c51460251"), 846 ("Too short commit", 847 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a174", 848 None), 849 ("Invalid element (0) in commit", 850 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 851 None), 852 ("Invalid element (1) in commit", 853 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 854 None), 855 ("Invalid element (> P) in commit", 856 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 857 None)] 858 for (note, commit, confirm) in tests: 859 logger.info(note) 860 dev[0].scan_for_bss(bssid, freq=2412) 861 hapd.set("ext_mgmt_frame_handling", "1") 862 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 863 scan_freq="2412", wait_connect=False) 864 865 logger.info("Commit") 866 for i in range(0, 10): 867 req = hapd.mgmt_rx() 868 if req is None: 869 raise Exception("MGMT RX wait timed out (commit)") 870 if req['subtype'] == 11: 871 break 872 req = None 873 if not req: 874 raise Exception("Authentication frame (commit) not received") 875 876 hapd.dump_monitor() 877 resp = {} 878 resp['fc'] = req['fc'] 879 resp['da'] = req['sa'] 880 resp['sa'] = req['da'] 881 resp['bssid'] = req['bssid'] 882 resp['payload'] = binascii.unhexlify("030001000000" + commit) 883 hapd.mgmt_tx(resp) 884 885 if confirm: 886 logger.info("Confirm") 887 for i in range(0, 10): 888 req = hapd.mgmt_rx() 889 if req is None: 890 raise Exception("MGMT RX wait timed out (confirm)") 891 if req['subtype'] == 11: 892 break 893 req = None 894 if not req: 895 raise Exception("Authentication frame (confirm) not received") 896 897 hapd.dump_monitor() 898 resp = {} 899 resp['fc'] = req['fc'] 900 resp['da'] = req['sa'] 901 resp['sa'] = req['da'] 902 resp['bssid'] = req['bssid'] 903 resp['payload'] = binascii.unhexlify("030002000000" + confirm) 904 hapd.mgmt_tx(resp) 905 906 time.sleep(0.1) 907 dev[0].request("REMOVE_NETWORK all") 908 hapd.set("ext_mgmt_frame_handling", "0") 909 hapd.dump_monitor() 910 911 912def test_sae_proto_commit_delayed(dev, apdev): 913 """SAE protocol testing - Commit delayed""" 914 check_sae_capab(dev[0]) 915 params = hostapd.wpa2_params(ssid="test-sae", 916 passphrase="12345678") 917 params['wpa_key_mgmt'] = 'SAE' 918 hapd = hostapd.add_ap(apdev[0], params) 919 bssid = apdev[0]['bssid'] 920 921 dev[0].request("SET sae_groups 19") 922 923 dev[0].scan_for_bss(bssid, freq=2412) 924 hapd.set("ext_mgmt_frame_handling", "1") 925 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 926 scan_freq="2412", wait_connect=False) 927 928 logger.info("Commit") 929 for i in range(0, 10): 930 req = hapd.mgmt_rx() 931 if req is None: 932 raise Exception("MGMT RX wait timed out (commit)") 933 if req['subtype'] == 11: 934 break 935 req = None 936 if not req: 937 raise Exception("Authentication frame (commit) not received") 938 939 hapd.dump_monitor() 940 time.sleep(2.5) 941 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 942 943 logger.info("Commit/Confirm") 944 for i in range(0, 10): 945 req = hapd.mgmt_rx() 946 if req is None: 947 raise Exception("MGMT RX wait timed out (confirm)") 948 if req['subtype'] == 11: 949 trans, = struct.unpack('<H', req['payload'][2:4]) 950 if trans == 1: 951 logger.info("Extra Commit") 952 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 953 continue 954 break 955 req = None 956 if not req: 957 raise Exception("Authentication frame (confirm) not received") 958 959 hapd.dump_monitor() 960 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 961 962 logger.info("Association Request") 963 for i in range(0, 10): 964 req = hapd.mgmt_rx() 965 if req is None: 966 raise Exception("MGMT RX wait timed out (AssocReq)") 967 if req['subtype'] == 0: 968 break 969 req = None 970 if not req: 971 raise Exception("Association Request frame not received") 972 973 hapd.dump_monitor() 974 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 975 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 976 if ev is None: 977 raise Exception("Management frame TX status not reported (1)") 978 if "stype=1 ok=1" not in ev: 979 raise Exception("Unexpected management frame TX status (1): " + ev) 980 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4])) 981 if "OK" not in hapd.request(cmd): 982 raise Exception("MGMT_TX_STATUS_PROCESS failed") 983 984 hapd.set("ext_mgmt_frame_handling", "0") 985 986 dev[0].wait_connected() 987 988def test_sae_proto_commit_replay(dev, apdev): 989 """SAE protocol testing - Commit replay""" 990 check_sae_capab(dev[0]) 991 params = hostapd.wpa2_params(ssid="test-sae", 992 passphrase="12345678") 993 params['wpa_key_mgmt'] = 'SAE' 994 hapd = hostapd.add_ap(apdev[0], params) 995 bssid = apdev[0]['bssid'] 996 997 dev[0].request("SET sae_groups 19") 998 999 dev[0].scan_for_bss(bssid, freq=2412) 1000 hapd.set("ext_mgmt_frame_handling", "1") 1001 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1002 scan_freq="2412", wait_connect=False) 1003 1004 logger.info("Commit") 1005 for i in range(0, 10): 1006 req = hapd.mgmt_rx() 1007 if req is None: 1008 raise Exception("MGMT RX wait timed out (commit)") 1009 if req['subtype'] == 11: 1010 break 1011 req = None 1012 if not req: 1013 raise Exception("Authentication frame (commit) not received") 1014 1015 hapd.dump_monitor() 1016 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1017 logger.info("Replay Commit") 1018 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1019 1020 logger.info("Confirm") 1021 for i in range(0, 10): 1022 req = hapd.mgmt_rx() 1023 if req is None: 1024 raise Exception("MGMT RX wait timed out (confirm)") 1025 if req['subtype'] == 11: 1026 trans, = struct.unpack('<H', req['payload'][2:4]) 1027 if trans == 1: 1028 logger.info("Extra Commit") 1029 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1030 continue 1031 break 1032 req = None 1033 if not req: 1034 raise Exception("Authentication frame (confirm) not received") 1035 1036 hapd.dump_monitor() 1037 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1038 1039 logger.info("Association Request") 1040 for i in range(0, 10): 1041 req = hapd.mgmt_rx() 1042 if req is None: 1043 raise Exception("MGMT RX wait timed out (AssocReq)") 1044 if req['subtype'] == 0: 1045 break 1046 req = None 1047 if not req: 1048 raise Exception("Association Request frame not received") 1049 1050 hapd.dump_monitor() 1051 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1052 for i in range(0, 10): 1053 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1054 if ev is None: 1055 raise Exception("Management frame TX status not reported (1)") 1056 if "stype=11 ok=1" in ev: 1057 continue 1058 if "stype=12 ok=1" in ev: 1059 continue 1060 if "stype=1 ok=1" not in ev: 1061 raise Exception("Unexpected management frame TX status (1): " + ev) 1062 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4])) 1063 if "OK" not in hapd.request(cmd): 1064 raise Exception("MGMT_TX_STATUS_PROCESS failed") 1065 break 1066 1067 hapd.set("ext_mgmt_frame_handling", "0") 1068 1069 dev[0].wait_connected() 1070 1071def test_sae_proto_confirm_replay(dev, apdev): 1072 """SAE protocol testing - Confirm replay""" 1073 check_sae_capab(dev[0]) 1074 params = hostapd.wpa2_params(ssid="test-sae", 1075 passphrase="12345678") 1076 params['wpa_key_mgmt'] = 'SAE' 1077 hapd = hostapd.add_ap(apdev[0], params) 1078 bssid = apdev[0]['bssid'] 1079 1080 dev[0].request("SET sae_groups 19") 1081 1082 dev[0].scan_for_bss(bssid, freq=2412) 1083 hapd.set("ext_mgmt_frame_handling", "1") 1084 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1085 scan_freq="2412", wait_connect=False) 1086 1087 logger.info("Commit") 1088 for i in range(0, 10): 1089 req = hapd.mgmt_rx() 1090 if req is None: 1091 raise Exception("MGMT RX wait timed out (commit)") 1092 if req['subtype'] == 11: 1093 break 1094 req = None 1095 if not req: 1096 raise Exception("Authentication frame (commit) not received") 1097 1098 hapd.dump_monitor() 1099 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1100 1101 logger.info("Confirm") 1102 for i in range(0, 10): 1103 req = hapd.mgmt_rx() 1104 if req is None: 1105 raise Exception("MGMT RX wait timed out (confirm)") 1106 if req['subtype'] == 11: 1107 break 1108 req = None 1109 if not req: 1110 raise Exception("Authentication frame (confirm) not received") 1111 1112 hapd.dump_monitor() 1113 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1114 1115 logger.info("Replay Confirm") 1116 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1117 1118 logger.info("Association Request") 1119 for i in range(0, 10): 1120 req = hapd.mgmt_rx() 1121 if req is None: 1122 raise Exception("MGMT RX wait timed out (AssocReq)") 1123 if req['subtype'] == 0: 1124 break 1125 req = None 1126 if not req: 1127 raise Exception("Association Request frame not received") 1128 1129 hapd.dump_monitor() 1130 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode()) 1131 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1132 if ev is None: 1133 raise Exception("Management frame TX status not reported (1)") 1134 if "stype=1 ok=1" not in ev: 1135 raise Exception("Unexpected management frame TX status (1): " + ev) 1136 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4])) 1137 if "OK" not in hapd.request(cmd): 1138 raise Exception("MGMT_TX_STATUS_PROCESS failed") 1139 1140 hapd.set("ext_mgmt_frame_handling", "0") 1141 1142 dev[0].wait_connected() 1143 1144def test_sae_proto_hostapd(dev, apdev): 1145 """SAE protocol testing with hostapd""" 1146 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1147 params['wpa_key_mgmt'] = 'SAE' 1148 params['sae_groups'] = "19 65535" 1149 hapd = hostapd.add_ap(apdev[0], params) 1150 hapd.set("ext_mgmt_frame_handling", "1") 1151 bssid = hapd.own_addr().replace(':', '') 1152 addr = "020000000000" 1153 addr2 = "020000000001" 1154 hdr = "b0003a01" + bssid + addr + bssid + "1000" 1155 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000" 1156 group = "1300" 1157 scalar = "f7df19f4a7fef1d3b895ea1de150b7c5a7a705c8ebb31a52b623e0057908bd93" 1158 element_x = "21931572027f2e953e2a49fab3d992944102cc95aa19515fc068b394fb25ae3c" 1159 element_y = "cb4eeb94d7b0b789abfdb73a67ab9d6d5efa94dd553e0e724a6289821cbce530" 1160 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y) 1161 # "SAE: Not enough data for scalar" 1162 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar[:-2]) 1163 # "SAE: Do not allow group to be changed" 1164 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + "ffff" + scalar[:-2]) 1165 # "SAE: Unsupported Finite Cyclic Group 65535" 1166 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr2 + "030001000000" + "ffff" + scalar[:-2]) 1167 1168def test_sae_proto_hostapd_ecc(dev, apdev): 1169 """SAE protocol testing with hostapd (ECC)""" 1170 params = hostapd.wpa2_params(ssid="test-sae", passphrase="foofoofoo") 1171 params['wpa_key_mgmt'] = 'SAE' 1172 params['sae_groups'] = "19" 1173 hapd = hostapd.add_ap(apdev[0], params) 1174 hapd.set("ext_mgmt_frame_handling", "1") 1175 bssid = hapd.own_addr().replace(':', '') 1176 addr = "020000000000" 1177 addr2 = "020000000001" 1178 hdr = "b0003a01" + bssid + addr + bssid + "1000" 1179 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000" 1180 group = "1300" 1181 scalar = "9e9a959bf2dda875a4a29ce9b2afef46f2d83060930124cd9e39ddce798cd69a" 1182 element_x = "dfc55fd8622b91d362f4d1fc9646474d7fba0ff7cce6ca58b8e96a931e070220" 1183 element_y = "dac8a4e80724f167c1349cc9e1f9dd82a7c77b29d49789b63b72b4c849301a28" 1184 # sae_parse_commit_element_ecc() failure to parse peer element 1185 # (depending on crypto library, either crypto_ec_point_from_bin() failure 1186 # or crypto_ec_point_is_on_curve() returning 0) 1187 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y) 1188 # Unexpected continuation of the connection attempt with confirm 1189 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030002000000" + "0000" + "fd7b081ff4e8676f03612a4140eedcd3c179ab3a13b93863c6f7ca451340b9ae") 1190 1191def test_sae_proto_hostapd_ffc(dev, apdev): 1192 """SAE protocol testing with hostapd (FFC)""" 1193 params = hostapd.wpa2_params(ssid="test-sae", passphrase="foofoofoo") 1194 params['wpa_key_mgmt'] = 'SAE' 1195 params['sae_groups'] = "22" 1196 hapd = hostapd.add_ap(apdev[0], params) 1197 hapd.set("ext_mgmt_frame_handling", "1") 1198 bssid = hapd.own_addr().replace(':', '') 1199 addr = "020000000000" 1200 addr2 = "020000000001" 1201 hdr = "b0003a01" + bssid + addr + bssid + "1000" 1202 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000" 1203 group = "1600" 1204 scalar = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044cc46a73c07ef479dc66ec1f5e8ccf25131fa40" 1205 element = "0f1d67025e12fc874cf718c35b19d1ab2db858215623f1ce661cbd1d7b1d7a09ceda7dba46866cf37044259b5cac4db15e7feb778edc8098854b93a84347c1850c02ee4d7dac46db79c477c731085d5b39f56803cda1eeac4a2fbbccb9a546379e258c00ebe93dfdd0a34cf8ce5c55cf905a89564a590b7e159fb89198e9d5cd" 1206 # sae_parse_commit_element_ffc() failure to parse peer element 1207 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element) 1208 # Unexpected continuation of the connection attempt with confirm 1209 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030002000000" + "0000" + "fd7b081ff4e8676f03612a4140eedcd3c179ab3a13b93863c6f7ca451340b9ae") 1210 1211def sae_start_ap(apdev, sae_pwe): 1212 params = hostapd.wpa2_params(ssid="test-sae", passphrase="foofoofoo") 1213 params['wpa_key_mgmt'] = 'SAE' 1214 params['sae_groups'] = "19" 1215 params['sae_pwe'] = str(sae_pwe) 1216 return hostapd.add_ap(apdev, params) 1217 1218def check_commit_status(hapd, use_status, expect_status): 1219 hapd.set("ext_mgmt_frame_handling", "1") 1220 bssid = hapd.own_addr().replace(':', '') 1221 addr = "020000000000" 1222 addr2 = "020000000001" 1223 hdr = "b0003a01" + bssid + addr + bssid + "1000" 1224 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000" 1225 group = "1300" 1226 scalar = "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" 1227 element_x = "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728d" 1228 element_y = "d3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8" 1229 status = binascii.hexlify(struct.pack('<H', use_status)).decode() 1230 hapd.dump_monitor() 1231 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "03000100" + status + group + scalar + element_x + element_y) 1232 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1233 if ev: 1234 msg = ev.split(' ')[3].split('=')[1] 1235 if not msg.startswith("b0"): 1236 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1237 if ev is None: 1238 raise Exception("MGMT-TX-STATUS not seen") 1239 msg = ev.split(' ')[3].split('=')[1] 1240 body = msg[2 * 24:] 1241 status, = struct.unpack('<H', binascii.unhexlify(body[8:12])) 1242 if status != expect_status: 1243 raise Exception("Unexpected status code: %d" % status) 1244 1245def test_sae_proto_hostapd_status_126(dev, apdev): 1246 """SAE protocol testing with hostapd (status code 126)""" 1247 hapd = sae_start_ap(apdev[0], 0) 1248 check_commit_status(hapd, 126, 1) 1249 check_commit_status(hapd, 0, 0) 1250 1251def test_sae_proto_hostapd_status_127(dev, apdev): 1252 """SAE protocol testing with hostapd (status code 127)""" 1253 hapd = sae_start_ap(apdev[0], 2) 1254 check_commit_status(hapd, 127, 1) 1255 check_commit_status(hapd, 0, 0) 1256 1257def test_sae_proto_hostapd_valid_commit_after_fail(dev, apdev): 1258 """SAE protocol testing with hostapd and valid commit after failed one""" 1259 params = hostapd.wpa2_params(ssid="test-sae") 1260 params['sae_password'] = ["foofoofoo", "another|id=pw id"] 1261 params['wpa_key_mgmt'] = 'SAE' 1262 params['sae_groups'] = "19" 1263 hapd = hostapd.add_ap(apdev[0], params) 1264 hapd.set("ext_mgmt_frame_handling", "1") 1265 bssid = hapd.own_addr().replace(':', '') 1266 addr = "020000000000" 1267 addr2 = "020000000001" 1268 hdr = "b0003a01" + bssid + addr + bssid + "1000" 1269 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000" 1270 group = "1300" 1271 scalar = "f7df19f4a7fef1d3b895ea1de150b7c5a7a705c8ebb31a52b623e0057908bd93" 1272 element_x = "21931572027f2e953e2a49fab3d992944102cc95aa19515fc068b394fb25ae3c" 1273 element_y = "cb4eeb94d7b0b789abfdb73a67ab9d6d5efa94dd553e0e724a6289821cbce530" 1274 pw_id = "ff022130" 1275 1276 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y + pw_id) 1277 ev = hapd.wait_event(['MGMT-TX-STATUS'], timeout=1) 1278 buf = ev.split(' ')[3].split('=')[1] 1279 # Check for status = Unknown Password ID 1280 if buf[48:] != '0300' + '0100' + '7b00': 1281 raise Exception("Unexpected response to SAE commit with unknown password id: " + buf) 1282 1283 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y) 1284 1285 ev = hapd.wait_event(['MGMT-TX-STATUS'], timeout=1) 1286 if ev is None: 1287 raise Exception("No response to valid SAE commit") 1288 buf = ev.split(' ')[3].split('=')[1] 1289 # Check for status = Success 1290 payload = buf[48:] 1291 if payload[8:12] != '0000': 1292 raise Exception("Unexpected Status Code for valid SAE commit: " + buf) 1293 1294@remote_compatible 1295def test_sae_no_ffc_by_default(dev, apdev): 1296 """SAE and default groups rejecting FFC""" 1297 check_sae_capab(dev[0]) 1298 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1299 params['wpa_key_mgmt'] = 'SAE' 1300 hapd = hostapd.add_ap(apdev[0], params) 1301 1302 dev[0].request("SET sae_groups 15 16") 1303 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412", 1304 wait_connect=False) 1305 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3) 1306 if ev is None: 1307 raise Exception("Did not try to authenticate") 1308 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3) 1309 if ev is None: 1310 raise Exception("Did not try to authenticate (2)") 1311 dev[0].request("REMOVE_NETWORK all") 1312 1313def sae_reflection_attack(apdev, dev, group): 1314 check_sae_capab(dev) 1315 params = hostapd.wpa2_params(ssid="test-sae", 1316 passphrase="no-knowledge-of-passphrase") 1317 params['wpa_key_mgmt'] = 'SAE' 1318 hapd = hostapd.add_ap(apdev, params) 1319 bssid = apdev['bssid'] 1320 1321 dev.scan_for_bss(bssid, freq=2412) 1322 hapd.set("ext_mgmt_frame_handling", "1") 1323 1324 dev.request("SET sae_groups %d" % group) 1325 dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE", 1326 scan_freq="2412", wait_connect=False) 1327 1328 # Commit 1329 for i in range(0, 10): 1330 req = hapd.mgmt_rx() 1331 if req is None: 1332 raise Exception("MGMT RX wait timed out") 1333 if req['subtype'] == 11: 1334 break 1335 req = None 1336 if not req: 1337 raise Exception("Authentication frame not received") 1338 1339 resp = {} 1340 resp['fc'] = req['fc'] 1341 resp['da'] = req['sa'] 1342 resp['sa'] = req['da'] 1343 resp['bssid'] = req['bssid'] 1344 resp['payload'] = req['payload'] 1345 hapd.mgmt_tx(resp) 1346 1347 # Confirm 1348 req = hapd.mgmt_rx(timeout=0.5) 1349 if req is not None: 1350 if req['subtype'] == 11: 1351 raise Exception("Unexpected Authentication frame seen") 1352 1353@remote_compatible 1354def test_sae_reflection_attack_ecc(dev, apdev): 1355 """SAE reflection attack (ECC)""" 1356 sae_reflection_attack(apdev[0], dev[0], 19) 1357 1358@remote_compatible 1359def test_sae_reflection_attack_ffc(dev, apdev): 1360 """SAE reflection attack (FFC)""" 1361 sae_reflection_attack(apdev[0], dev[0], 15) 1362 1363def sae_reflection_attack_internal(apdev, dev, group): 1364 check_sae_capab(dev) 1365 params = hostapd.wpa2_params(ssid="test-sae", 1366 passphrase="no-knowledge-of-passphrase") 1367 params['wpa_key_mgmt'] = 'SAE' 1368 params['sae_reflection_attack'] = '1' 1369 hapd = hostapd.add_ap(apdev, params) 1370 bssid = apdev['bssid'] 1371 1372 dev.scan_for_bss(bssid, freq=2412) 1373 dev.request("SET sae_groups %d" % group) 1374 dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE", 1375 scan_freq="2412", wait_connect=False) 1376 ev = dev.wait_event(["SME: Trying to authenticate"], timeout=10) 1377 if ev is None: 1378 raise Exception("No authentication attempt seen") 1379 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 1380 if ev is not None: 1381 raise Exception("Unexpected connection") 1382 1383@remote_compatible 1384def test_sae_reflection_attack_ecc_internal(dev, apdev): 1385 """SAE reflection attack (ECC) - internal""" 1386 sae_reflection_attack_internal(apdev[0], dev[0], 19) 1387 1388@remote_compatible 1389def test_sae_reflection_attack_ffc_internal(dev, apdev): 1390 """SAE reflection attack (FFC) - internal""" 1391 sae_reflection_attack_internal(apdev[0], dev[0], 15) 1392 1393@remote_compatible 1394def test_sae_commit_override(dev, apdev): 1395 """SAE commit override (hostapd)""" 1396 check_sae_capab(dev[0]) 1397 params = hostapd.wpa2_params(ssid="test-sae", 1398 passphrase="12345678") 1399 params['wpa_key_mgmt'] = 'SAE' 1400 params['sae_commit_override'] = '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514' 1401 hapd = hostapd.add_ap(apdev[0], params) 1402 dev[0].request("SET sae_groups ") 1403 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE", 1404 scan_freq="2412", wait_connect=False) 1405 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 1406 if ev is not None: 1407 raise Exception("Unexpected connection") 1408 1409@remote_compatible 1410def test_sae_commit_override2(dev, apdev): 1411 """SAE commit override (wpa_supplicant)""" 1412 check_sae_capab(dev[0]) 1413 params = hostapd.wpa2_params(ssid="test-sae", 1414 passphrase="12345678") 1415 params['wpa_key_mgmt'] = 'SAE' 1416 hapd = hostapd.add_ap(apdev[0], params) 1417 dev[0].request("SET sae_groups ") 1418 dev[0].set('sae_commit_override', '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514') 1419 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE", 1420 scan_freq="2412", wait_connect=False) 1421 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 1422 if ev is not None: 1423 raise Exception("Unexpected connection") 1424 1425def test_sae_commit_invalid_scalar_element_ap(dev, apdev): 1426 """SAE commit invalid scalar/element from AP""" 1427 check_sae_capab(dev[0]) 1428 params = hostapd.wpa2_params(ssid="test-sae", 1429 passphrase="12345678") 1430 params['wpa_key_mgmt'] = 'SAE' 1431 params['sae_commit_override'] = '1300' + 96*'00' 1432 hapd = hostapd.add_ap(apdev[0], params) 1433 dev[0].request("SET sae_groups ") 1434 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE", 1435 scan_freq="2412", wait_connect=False) 1436 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 1437 if ev is not None: 1438 raise Exception("Unexpected connection") 1439 1440def test_sae_commit_invalid_element_ap(dev, apdev): 1441 """SAE commit invalid element from AP""" 1442 check_sae_capab(dev[0]) 1443 params = hostapd.wpa2_params(ssid="test-sae", 1444 passphrase="12345678") 1445 params['wpa_key_mgmt'] = 'SAE' 1446 params['sae_commit_override'] = '1300' + 31*'00' + '02' + 64*'00' 1447 hapd = hostapd.add_ap(apdev[0], params) 1448 dev[0].request("SET sae_groups ") 1449 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE", 1450 scan_freq="2412", wait_connect=False) 1451 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 1452 if ev is not None: 1453 raise Exception("Unexpected connection") 1454 1455def test_sae_commit_invalid_scalar_element_sta(dev, apdev): 1456 """SAE commit invalid scalar/element from STA""" 1457 check_sae_capab(dev[0]) 1458 params = hostapd.wpa2_params(ssid="test-sae", 1459 passphrase="12345678") 1460 params['wpa_key_mgmt'] = 'SAE' 1461 hapd = hostapd.add_ap(apdev[0], params) 1462 dev[0].request("SET sae_groups ") 1463 dev[0].set('sae_commit_override', '1300' + 96*'00') 1464 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE", 1465 scan_freq="2412", wait_connect=False) 1466 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 1467 if ev is not None: 1468 raise Exception("Unexpected connection") 1469 1470def test_sae_commit_invalid_element_sta(dev, apdev): 1471 """SAE commit invalid element from STA""" 1472 check_sae_capab(dev[0]) 1473 params = hostapd.wpa2_params(ssid="test-sae", 1474 passphrase="12345678") 1475 params['wpa_key_mgmt'] = 'SAE' 1476 hapd = hostapd.add_ap(apdev[0], params) 1477 dev[0].request("SET sae_groups ") 1478 dev[0].set('sae_commit_override', '1300' + 31*'00' + '02' + 64*'00') 1479 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE", 1480 scan_freq="2412", wait_connect=False) 1481 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 1482 if ev is not None: 1483 raise Exception("Unexpected connection") 1484 1485@remote_compatible 1486def test_sae_anti_clogging_proto(dev, apdev): 1487 """SAE anti clogging protocol testing""" 1488 check_sae_capab(dev[0]) 1489 params = hostapd.wpa2_params(ssid="test-sae", 1490 passphrase="no-knowledge-of-passphrase") 1491 params['wpa_key_mgmt'] = 'SAE' 1492 hapd = hostapd.add_ap(apdev[0], params) 1493 bssid = apdev[0]['bssid'] 1494 1495 dev[0].scan_for_bss(bssid, freq=2412) 1496 hapd.set("ext_mgmt_frame_handling", "1") 1497 1498 dev[0].request("SET sae_groups ") 1499 dev[0].connect("test-sae", psk="anti-cloggign", key_mgmt="SAE", 1500 scan_freq="2412", wait_connect=False) 1501 1502 # Commit 1503 for i in range(0, 10): 1504 req = hapd.mgmt_rx() 1505 if req is None: 1506 raise Exception("MGMT RX wait timed out") 1507 if req['subtype'] == 11: 1508 break 1509 req = None 1510 if not req: 1511 raise Exception("Authentication frame not received") 1512 1513 resp = {} 1514 resp['fc'] = req['fc'] 1515 resp['da'] = req['sa'] 1516 resp['sa'] = req['da'] 1517 resp['bssid'] = req['bssid'] 1518 resp['payload'] = binascii.unhexlify("030001004c00" + "ffff00") 1519 hapd.mgmt_tx(resp) 1520 1521 # Confirm (not received due to DH group being rejected) 1522 req = hapd.mgmt_rx(timeout=0.5) 1523 if req is not None: 1524 if req['subtype'] == 11: 1525 raise Exception("Unexpected Authentication frame seen") 1526 1527@remote_compatible 1528def test_sae_no_random(dev, apdev): 1529 """SAE and no random numbers available""" 1530 check_sae_capab(dev[0]) 1531 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1532 params['wpa_key_mgmt'] = 'SAE' 1533 hapd = hostapd.add_ap(apdev[0], params) 1534 1535 dev[0].request("SET sae_groups ") 1536 tests = [(1, "os_get_random;sae_derive_pwe_ecc")] 1537 for count, func in tests: 1538 with fail_test(dev[0], count, func): 1539 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1540 scan_freq="2412") 1541 dev[0].request("REMOVE_NETWORK all") 1542 dev[0].wait_disconnected() 1543 1544@remote_compatible 1545def test_sae_pwe_failure(dev, apdev): 1546 """SAE and pwe failure""" 1547 check_sae_capab(dev[0]) 1548 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1549 params['wpa_key_mgmt'] = 'SAE' 1550 params['sae_groups'] = '19 15' 1551 hapd = hostapd.add_ap(apdev[0], params) 1552 1553 dev[0].request("SET sae_groups 19") 1554 with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ecc"): 1555 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1556 scan_freq="2412") 1557 dev[0].request("REMOVE_NETWORK all") 1558 dev[0].wait_disconnected() 1559 with fail_test(dev[0], 1, "sae_test_pwd_seed_ecc"): 1560 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1561 scan_freq="2412") 1562 dev[0].request("REMOVE_NETWORK all") 1563 dev[0].wait_disconnected() 1564 1565 dev[0].request("SET sae_groups 15") 1566 with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ffc"): 1567 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1568 scan_freq="2412") 1569 dev[0].request("REMOVE_NETWORK all") 1570 dev[0].wait_disconnected() 1571 1572 dev[0].request("SET sae_groups 15") 1573 with fail_test(dev[0], 1, "sae_test_pwd_seed_ffc"): 1574 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1575 scan_freq="2412") 1576 dev[0].request("REMOVE_NETWORK all") 1577 dev[0].wait_disconnected() 1578 with fail_test(dev[0], 2, "sae_test_pwd_seed_ffc"): 1579 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1580 scan_freq="2412") 1581 dev[0].request("REMOVE_NETWORK all") 1582 dev[0].wait_disconnected() 1583 1584@remote_compatible 1585def test_sae_bignum_failure(dev, apdev): 1586 """SAE and bignum failure""" 1587 check_sae_capab(dev[0]) 1588 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1589 params['wpa_key_mgmt'] = 'SAE' 1590 params['sae_groups'] = '19 15 22' 1591 hapd = hostapd.add_ap(apdev[0], params) 1592 1593 dev[0].request("SET sae_groups 19") 1594 tests = [(1, "crypto_bignum_init_set;dragonfly_get_rand_1_to_p_1"), 1595 (1, "crypto_bignum_init;dragonfly_is_quadratic_residue_blind"), 1596 (1, "crypto_bignum_mulmod;dragonfly_is_quadratic_residue_blind"), 1597 (2, "crypto_bignum_mulmod;dragonfly_is_quadratic_residue_blind"), 1598 (3, "crypto_bignum_mulmod;dragonfly_is_quadratic_residue_blind"), 1599 (1, "crypto_bignum_legendre;dragonfly_is_quadratic_residue_blind"), 1600 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ecc"), 1601 (1, "crypto_ec_point_compute_y_sqr;sae_test_pwd_seed_ecc"), 1602 (1, "crypto_bignum_to_bin;sae_derive_pwe_ecc"), 1603 (1, "crypto_ec_point_compute_y_sqr;sae_derive_pwe_ecc"), 1604 (1, "crypto_ec_point_init;sae_derive_commit_element_ecc"), 1605 (1, "crypto_ec_point_mul;sae_derive_commit_element_ecc"), 1606 (1, "crypto_ec_point_invert;sae_derive_commit_element_ecc"), 1607 (1, "crypto_bignum_init;=sae_derive_commit"), 1608 (1, "crypto_ec_point_init;sae_derive_k_ecc"), 1609 (1, "crypto_ec_point_mul;sae_derive_k_ecc"), 1610 (1, "crypto_ec_point_add;sae_derive_k_ecc"), 1611 (2, "crypto_ec_point_mul;sae_derive_k_ecc"), 1612 (1, "crypto_ec_point_to_bin;sae_derive_k_ecc"), 1613 (1, "crypto_bignum_legendre;dragonfly_get_random_qr_qnr"), 1614 (1, "sha256_prf_bits;sae_derive_keys"), 1615 (1, "crypto_bignum_init;sae_derive_keys"), 1616 (1, "crypto_bignum_init_set;sae_parse_commit_scalar"), 1617 (1, "crypto_bignum_to_bin;sae_parse_commit_element_ecc"), 1618 (1, "crypto_ec_point_from_bin;sae_parse_commit_element_ecc")] 1619 for count, func in tests: 1620 with fail_test(dev[0], count, func): 1621 hapd.request("NOTE STA failure testing %d:%s" % (count, func)) 1622 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1623 scan_freq="2412", wait_connect=False) 1624 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1) 1625 dev[0].request("REMOVE_NETWORK all") 1626 dev[0].dump_monitor() 1627 hapd.dump_monitor() 1628 1629 dev[0].request("SET sae_groups 15") 1630 tests = [(1, "crypto_bignum_init_set;sae_set_group"), 1631 (2, "crypto_bignum_init_set;sae_set_group"), 1632 (1, "crypto_bignum_init;sae_derive_commit"), 1633 (2, "crypto_bignum_init;sae_derive_commit"), 1634 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"), 1635 (1, "crypto_bignum_exptmod;sae_test_pwd_seed_ffc"), 1636 (1, "crypto_bignum_init;sae_derive_pwe_ffc"), 1637 (1, "crypto_bignum_init;sae_derive_commit_element_ffc"), 1638 (1, "crypto_bignum_exptmod;sae_derive_commit_element_ffc"), 1639 (1, "crypto_bignum_inverse;sae_derive_commit_element_ffc"), 1640 (1, "crypto_bignum_init;sae_derive_k_ffc"), 1641 (1, "crypto_bignum_exptmod;sae_derive_k_ffc"), 1642 (1, "crypto_bignum_mulmod;sae_derive_k_ffc"), 1643 (2, "crypto_bignum_exptmod;sae_derive_k_ffc"), 1644 (1, "crypto_bignum_to_bin;sae_derive_k_ffc"), 1645 (1, "crypto_bignum_init_set;sae_parse_commit_element_ffc"), 1646 (1, "crypto_bignum_init;sae_parse_commit_element_ffc"), 1647 (2, "crypto_bignum_init_set;sae_parse_commit_element_ffc"), 1648 (1, "crypto_bignum_exptmod;sae_parse_commit_element_ffc")] 1649 for count, func in tests: 1650 with fail_test(dev[0], count, func): 1651 hapd.request("NOTE STA failure testing %d:%s" % (count, func)) 1652 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1653 scan_freq="2412", wait_connect=False) 1654 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1) 1655 dev[0].request("REMOVE_NETWORK all") 1656 dev[0].dump_monitor() 1657 hapd.dump_monitor() 1658 1659def test_sae_bignum_failure_unsafe_group(dev, apdev): 1660 """SAE and bignum failure unsafe group""" 1661 check_sae_capab(dev[0]) 1662 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1663 params['wpa_key_mgmt'] = 'SAE' 1664 params['sae_groups'] = '22' 1665 hapd = hostapd.add_ap(apdev[0], params) 1666 1667 dev[0].request("SET sae_groups 22") 1668 tests = [(1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"), 1669 (1, "crypto_bignum_sub;sae_test_pwd_seed_ffc"), 1670 (1, "crypto_bignum_div;sae_test_pwd_seed_ffc")] 1671 for count, func in tests: 1672 with fail_test(dev[0], count, func): 1673 hapd.request("NOTE STA failure testing %d:%s" % (count, func)) 1674 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1675 scan_freq="2412", wait_connect=False) 1676 wait_fail_trigger(dev[0], "GET_FAIL") 1677 dev[0].request("REMOVE_NETWORK all") 1678 dev[0].dump_monitor() 1679 hapd.dump_monitor() 1680 1681def test_sae_invalid_anti_clogging_token_req(dev, apdev): 1682 """SAE and invalid anti-clogging token request""" 1683 check_sae_capab(dev[0]) 1684 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1685 params['wpa_key_mgmt'] = 'SAE' 1686 # Beacon more frequently since Probe Request frames are practically ignored 1687 # in this test setup (ext_mgmt_frame_handled=1 on hostapd side) and 1688 # wpa_supplicant scans may end up getting ignored if no new results are 1689 # available due to the missing Probe Response frames. 1690 params['beacon_int'] = '20' 1691 hapd = hostapd.add_ap(apdev[0], params) 1692 bssid = apdev[0]['bssid'] 1693 1694 dev[0].request("SET sae_groups 19") 1695 dev[0].scan_for_bss(bssid, freq=2412) 1696 hapd.set("ext_mgmt_frame_handling", "1") 1697 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1698 scan_freq="2412", wait_connect=False) 1699 ev = dev[0].wait_event(["SME: Trying to authenticate"]) 1700 if ev is None: 1701 raise Exception("No authentication attempt seen (1)") 1702 dev[0].dump_monitor() 1703 1704 for i in range(0, 10): 1705 req = hapd.mgmt_rx() 1706 if req is None: 1707 raise Exception("MGMT RX wait timed out (commit)") 1708 if req['subtype'] == 11: 1709 break 1710 req = None 1711 if not req: 1712 raise Exception("Authentication frame (commit) not received") 1713 1714 hapd.dump_monitor() 1715 resp = {} 1716 resp['fc'] = req['fc'] 1717 resp['da'] = req['sa'] 1718 resp['sa'] = req['da'] 1719 resp['bssid'] = req['bssid'] 1720 resp['payload'] = binascii.unhexlify("030001004c0013") 1721 hapd.mgmt_tx(resp) 1722 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1723 if ev is None: 1724 raise Exception("Management frame TX status not reported (1)") 1725 if "stype=11 ok=1" not in ev: 1726 raise Exception("Unexpected management frame TX status (1): " + ev) 1727 1728 ev = dev[0].wait_event(["SME: Trying to authenticate"]) 1729 if ev is None: 1730 raise Exception("No authentication attempt seen (2)") 1731 dev[0].dump_monitor() 1732 1733 for i in range(0, 10): 1734 req = hapd.mgmt_rx() 1735 if req is None: 1736 raise Exception("MGMT RX wait timed out (commit) (2)") 1737 if req['subtype'] == 11: 1738 break 1739 req = None 1740 if not req: 1741 raise Exception("Authentication frame (commit) not received (2)") 1742 1743 hapd.dump_monitor() 1744 resp = {} 1745 resp['fc'] = req['fc'] 1746 resp['da'] = req['sa'] 1747 resp['sa'] = req['da'] 1748 resp['bssid'] = req['bssid'] 1749 resp['payload'] = binascii.unhexlify("030001000100") 1750 hapd.mgmt_tx(resp) 1751 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1752 if ev is None: 1753 raise Exception("Management frame TX status not reported (1)") 1754 if "stype=11 ok=1" not in ev: 1755 raise Exception("Unexpected management frame TX status (1): " + ev) 1756 1757 ev = dev[0].wait_event(["SME: Trying to authenticate"]) 1758 if ev is None: 1759 raise Exception("No authentication attempt seen (3)") 1760 dev[0].dump_monitor() 1761 1762 dev[0].request("DISCONNECT") 1763 1764def test_sae_password(dev, apdev): 1765 """SAE and sae_password in hostapd configuration""" 1766 check_sae_capab(dev[0]) 1767 params = hostapd.wpa2_params(ssid="test-sae", 1768 passphrase="12345678") 1769 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 1770 params['sae_password'] = "sae-password" 1771 hapd = hostapd.add_ap(apdev[0], params) 1772 1773 dev[0].request("SET sae_groups ") 1774 dev[0].connect("test-sae", psk="sae-password", key_mgmt="SAE", 1775 scan_freq="2412") 1776 dev[1].connect("test-sae", psk="12345678", scan_freq="2412") 1777 dev[2].request("SET sae_groups ") 1778 dev[2].connect("test-sae", sae_password="sae-password", key_mgmt="SAE", 1779 scan_freq="2412") 1780 1781def test_sae_password_short(dev, apdev): 1782 """SAE and short password""" 1783 check_sae_capab(dev[0]) 1784 params = hostapd.wpa2_params(ssid="test-sae") 1785 params['wpa_key_mgmt'] = 'SAE' 1786 params['sae_password'] = "secret" 1787 hapd = hostapd.add_ap(apdev[0], params) 1788 1789 dev[0].request("SET sae_groups ") 1790 dev[0].connect("test-sae", sae_password="secret", key_mgmt="SAE", 1791 scan_freq="2412") 1792 1793def test_sae_password_long(dev, apdev): 1794 """SAE and long password""" 1795 check_sae_capab(dev[0]) 1796 params = hostapd.wpa2_params(ssid="test-sae") 1797 params['wpa_key_mgmt'] = 'SAE' 1798 params['sae_password'] = 100*"A" 1799 hapd = hostapd.add_ap(apdev[0], params) 1800 1801 dev[0].request("SET sae_groups ") 1802 dev[0].connect("test-sae", sae_password=100*"A", key_mgmt="SAE", 1803 scan_freq="2412") 1804 1805def test_sae_password_multiple(dev, apdev): 1806 """SAE with multiple default password entries""" 1807 check_sae_capab(dev[0]) 1808 check_sae_capab(dev[1]) 1809 check_sae_capab(dev[2]) 1810 params = hostapd.wpa3_params(ssid="test-sae", 1811 password=["owner", "iot", "guest"]) 1812 params['sae_track_password'] = "10" 1813 params['sae_confirm_immediate'] = '1' 1814 hapd = hostapd.add_ap(apdev[0], params) 1815 1816 dev[0].set("sae_groups", "") 1817 dev[0].connect("test-sae", sae_password="owner", key_mgmt="SAE", 1818 ieee80211w="2", scan_freq="2412") 1819 1820 dev[1].set("sae_groups", "") 1821 dev[1].connect("test-sae", sae_password="iot", key_mgmt="SAE", 1822 ieee80211w="2", scan_freq="2412") 1823 1824 dev[2].set("sae_groups", "") 1825 dev[2].connect("test-sae", sae_password="guest", key_mgmt="SAE", 1826 ieee80211w="2", scan_freq="2412") 1827 1828def test_sae_connect_cmd(dev, apdev): 1829 """SAE with connect command""" 1830 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 1831 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 1832 check_sae_capab(wpas) 1833 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1834 params['wpa_key_mgmt'] = 'SAE' 1835 hapd = hostapd.add_ap(apdev[0], params) 1836 1837 wpas.request("SET sae_groups ") 1838 wpas.connect("test-sae", psk="12345678", key_mgmt="SAE", 1839 scan_freq="2412", wait_connect=False) 1840 # mac80211_hwsim does not support SAE offload, so accept both a successful 1841 # connection and association rejection. 1842 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-ASSOC-REJECT", 1843 "Association request to the driver failed"], 1844 timeout=15) 1845 if ev is None: 1846 raise Exception("No connection result reported") 1847 1848def run_sae_password_id(dev, apdev, groups=None): 1849 check_sae_capab(dev[0]) 1850 params = hostapd.wpa2_params(ssid="test-sae") 1851 params['wpa_key_mgmt'] = 'SAE' 1852 if groups: 1853 params['sae_groups'] = groups 1854 else: 1855 groups = "" 1856 params['sae_password'] = ['secret|mac=ff:ff:ff:ff:ff:ff|id=pw id', 1857 'foo|mac=02:02:02:02:02:02', 1858 'another secret|mac=ff:ff:ff:ff:ff:ff|id=' + 29*'A'] 1859 hapd = hostapd.add_ap(apdev[0], params) 1860 1861 dev[0].request("SET sae_groups " + groups) 1862 dev[0].connect("test-sae", sae_password="secret", sae_password_id="pw id", 1863 key_mgmt="SAE", scan_freq="2412") 1864 dev[0].request("REMOVE_NETWORK all") 1865 dev[0].wait_disconnected() 1866 1867 # SAE Password Identifier element with the exact same length as the 1868 # optional Anti-Clogging Token field 1869 dev[0].connect("test-sae", sae_password="another secret", 1870 sae_password_id=29*'A', 1871 key_mgmt="SAE", scan_freq="2412") 1872 dev[0].request("REMOVE_NETWORK all") 1873 dev[0].wait_disconnected() 1874 1875 dev[0].connect("test-sae", sae_password="secret", sae_password_id="unknown", 1876 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 1877 1878 ev = dev[0].wait_event(["CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER"], 1879 timeout=10) 1880 if ev is None: 1881 raise Exception("Unknown password identifier not reported") 1882 dev[0].request("REMOVE_NETWORK all") 1883 1884def test_sae_password_id(dev, apdev): 1885 """SAE and password identifier""" 1886 run_sae_password_id(dev, apdev, "") 1887 1888def test_sae_password_id_ecc(dev, apdev): 1889 """SAE and password identifier (ECC)""" 1890 run_sae_password_id(dev, apdev, "19") 1891 1892def test_sae_password_id_ffc(dev, apdev): 1893 """SAE and password identifier (FFC)""" 1894 run_sae_password_id(dev, apdev, "15") 1895 1896def test_sae_password_id_only(dev, apdev): 1897 """SAE and password identifier (exclusively)""" 1898 check_sae_capab(dev[0]) 1899 params = hostapd.wpa2_params(ssid="test-sae") 1900 params['wpa_key_mgmt'] = 'SAE' 1901 params['sae_password'] = 'secret|id=pw id' 1902 hapd = hostapd.add_ap(apdev[0], params) 1903 1904 dev[0].request("SET sae_groups ") 1905 dev[0].connect("test-sae", sae_password="secret", sae_password_id="pw id", 1906 key_mgmt="SAE", scan_freq="2412") 1907 1908def test_sae_password_id_pwe_looping(dev, apdev): 1909 """SAE and password identifier with forced PWE looping""" 1910 check_sae_capab(dev[0]) 1911 params = hostapd.wpa2_params(ssid="test-sae") 1912 params['wpa_key_mgmt'] = 'SAE' 1913 params['sae_password'] = 'secret|id=pw id' 1914 params['sae_pwe'] = "3" 1915 hapd = hostapd.add_ap(apdev[0], params) 1916 1917 dev[0].request("SET sae_groups ") 1918 try: 1919 dev[0].set("sae_pwe", "3") 1920 dev[0].connect("test-sae", sae_password="secret", 1921 sae_password_id="pw id", 1922 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 1923 ev = dev[0].wait_event(["CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER"], 1924 timeout=10) 1925 dev[0].request("DISCONNECT") 1926 if ev is None: 1927 raise Exception("Unknown password identifier not reported") 1928 finally: 1929 dev[0].set("sae_pwe", "0") 1930 1931def test_sae_password_id_pwe_check_ap(dev, apdev): 1932 """SAE and password identifier with STA using unexpected PWE derivation""" 1933 check_sae_capab(dev[0]) 1934 params = hostapd.wpa2_params(ssid="test-sae") 1935 params['wpa_key_mgmt'] = 'SAE' 1936 params['sae_password'] = 'secret|id=pw id' 1937 hapd = hostapd.add_ap(apdev[0], params) 1938 1939 dev[0].request("SET sae_groups ") 1940 try: 1941 dev[0].set("sae_pwe", "3") 1942 dev[0].connect("test-sae", sae_password="secret", 1943 sae_password_id="pw id", 1944 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 1945 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 1946 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10) 1947 if ev is None or "CTRL-EVENT-SSID-TEMP-DISABLED" not in ev: 1948 raise Exception("Connection failure not reported") 1949 finally: 1950 dev[0].set("sae_pwe", "0") 1951 1952def test_sae_password_id_pwe_check_sta(dev, apdev): 1953 """SAE and password identifier with AP using unexpected PWE derivation""" 1954 check_sae_capab(dev[0]) 1955 params = hostapd.wpa2_params(ssid="test-sae") 1956 params['wpa_key_mgmt'] = 'SAE' 1957 params['sae_pwe'] = "3" 1958 params['sae_password'] = 'secret|id=pw id' 1959 hapd = hostapd.add_ap(apdev[0], params) 1960 1961 dev[0].request("SET sae_groups ") 1962 dev[0].connect("test-sae", sae_password="secret", 1963 sae_password_id="pw id", 1964 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 1965 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 1966 "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 1967 if ev is None or "CTRL-EVENT-NETWORK-NOT-FOUND" not in ev: 1968 raise Exception("Connection failure not reported") 1969 1970def test_sae_forced_anti_clogging_pw_id(dev, apdev): 1971 """SAE anti clogging (forced and Password Identifier)""" 1972 check_sae_capab(dev[0]) 1973 params = hostapd.wpa2_params(ssid="test-sae") 1974 params['wpa_key_mgmt'] = 'SAE' 1975 params['sae_anti_clogging_threshold'] = '0' 1976 params['sae_password'] = 'secret|id=' + 29*'A' 1977 hostapd.add_ap(apdev[0], params) 1978 for i in range(0, 2): 1979 dev[i].request("SET sae_groups ") 1980 dev[i].connect("test-sae", sae_password="secret", 1981 sae_password_id=29*'A', key_mgmt="SAE", scan_freq="2412") 1982 1983def test_sae_reauth(dev, apdev): 1984 """SAE reauthentication""" 1985 check_sae_capab(dev[0]) 1986 params = hostapd.wpa2_params(ssid="test-sae", 1987 passphrase="12345678") 1988 params['wpa_key_mgmt'] = 'SAE' 1989 params["ieee80211w"] = "2" 1990 hapd = hostapd.add_ap(apdev[0], params) 1991 1992 dev[0].request("SET sae_groups ") 1993 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1994 ieee80211w="2", scan_freq="2412") 1995 1996 hapd.set("ext_mgmt_frame_handling", "1") 1997 dev[0].request("DISCONNECT") 1998 dev[0].wait_disconnected(timeout=10) 1999 hapd.set("ext_mgmt_frame_handling", "0") 2000 dev[0].request("PMKSA_FLUSH") 2001 dev[0].request("REASSOCIATE") 2002 dev[0].wait_connected(timeout=10, error="Timeout on re-connection") 2003 2004def test_sae_anti_clogging_during_attack(dev, apdev): 2005 """SAE anti clogging during an attack""" 2006 try: 2007 run_sae_anti_clogging_during_attack(dev, apdev) 2008 finally: 2009 stop_monitor(apdev[1]["ifname"]) 2010 2011def build_sae_commit(bssid, addr, group=21, token=None): 2012 if group == 19: 2013 scalar = binascii.unhexlify("7332d3ebff24804005ccd8c56141e3ed8d84f40638aa31cd2fac11d4d2e89e7b") 2014 element = binascii.unhexlify("954d0f4457066bff3168376a1d7174f4e66620d1792406f613055b98513a7f03a538c13dfbaf2029e2adc6aa96aa0ddcf08ac44887b02f004b7f29b9dbf4b7d9") 2015 elif group == 21: 2016 scalar = binascii.unhexlify("001eec673111b902f5c8a61c8cb4c1c4793031aeea8c8c319410903bc64bcbaea134ab01c4e016d51436f5b5426f7e2af635759a3033fb4031ea79f89a62a3e2f828") 2017 element = binascii.unhexlify("00580eb4b448ea600ea277d5e66e4ed37db82bb04ac90442e9c3727489f366ba4b82f0a472d02caf4cdd142e96baea5915d71374660ee23acbaca38cf3fe8c5fb94b01abbc5278121635d7c06911c5dad8f18d516e1fbe296c179b7c87a1dddfab393337d3d215ed333dd396da6d8f20f798c60d054f1093c24d9c2d98e15c030cc375f0") 2018 pass 2019 frame = binascii.unhexlify("b0003a01") 2020 frame += bssid + addr + bssid 2021 frame += binascii.unhexlify("1000") 2022 auth_alg = 3 2023 transact = 1 2024 status = 0 2025 frame += struct.pack("<HHHH", auth_alg, transact, status, group) 2026 if token: 2027 frame += token 2028 frame += scalar + element 2029 return frame 2030 2031def sae_rx_commit_token_req(sock, radiotap, send_two=False): 2032 try: 2033 msg = sock.recv(1500) 2034 except TimeoutError: 2035 return False 2036 ver, pad, length, present = struct.unpack('<BBHL', msg[0:8]) 2037 frame = msg[length:] 2038 if len(frame) < 4: 2039 return False 2040 fc, duration = struct.unpack('<HH', frame[0:4]) 2041 if fc != 0xb0: 2042 return False 2043 frame = frame[4:] 2044 da = frame[0:6] 2045 if da[0] != 0xf2: 2046 return False 2047 sa = frame[6:12] 2048 bssid = frame[12:18] 2049 body = frame[20:] 2050 2051 alg, seq, status, group = struct.unpack('<HHHH', body[0:8]) 2052 if alg != 3 or seq != 1 or status != 76: 2053 return False 2054 token = body[8:] 2055 2056 frame = build_sae_commit(bssid, da, token=token) 2057 sock.send(radiotap + frame) 2058 if send_two: 2059 sock.send(radiotap + frame) 2060 return True 2061 2062def run_sae_anti_clogging_during_attack(dev, apdev): 2063 check_sae_capab(dev[0]) 2064 2065 # Reset apdev[1] into known state before using it as monitor interface. 2066 # Issues were seen when the previous test case used it as a 5 GHz AP. 2067 params = {"ssid": "monitor"} 2068 hapd2 = hostapd.add_ap(apdev[1], params) 2069 hapd2.disable() 2070 2071 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2072 params['wpa_key_mgmt'] = 'SAE' 2073 params['sae_groups'] = '21' 2074 hapd = hostapd.add_ap(apdev[0], params) 2075 2076 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2077 dev[0].request("SET sae_groups 21") 2078 dev[1].scan_for_bss(hapd.own_addr(), freq=2412) 2079 dev[1].request("SET sae_groups 21") 2080 2081 sock = start_monitor(apdev[1]["ifname"]) 2082 radiotap = radiotap_build() 2083 2084 bssid = binascii.unhexlify(hapd.own_addr().replace(':', '')) 2085 for i in range(16): 2086 addr = binascii.unhexlify("f2%010x" % i) 2087 frame = build_sae_commit(bssid, addr) 2088 sock.send(radiotap + frame) 2089 sock.send(radiotap + frame) 2090 2091 count = 0 2092 for i in range(150): 2093 if sae_rx_commit_token_req(sock, radiotap, send_two=True): 2094 count += 1 2095 logger.info("Number of token responses sent: %d" % count) 2096 if count < 10: 2097 raise Exception("Too few token responses seen: %d" % count) 2098 2099 for i in range(16): 2100 addr = binascii.unhexlify("f201%08x" % i) 2101 frame = build_sae_commit(bssid, addr) 2102 sock.send(radiotap + frame) 2103 2104 count = 0 2105 for i in range(150): 2106 if sae_rx_commit_token_req(sock, radiotap): 2107 count += 1 2108 if count == 10: 2109 break 2110 if count < 5: 2111 raise Exception("Too few token responses in second round: %d" % count) 2112 2113 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2114 scan_freq="2412", wait_connect=False) 2115 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", 2116 scan_freq="2412", wait_connect=False) 2117 2118 count = 0 2119 connected0 = False 2120 connected1 = False 2121 for i in range(1000): 2122 if sae_rx_commit_token_req(sock, radiotap): 2123 count += 1 2124 addr = binascii.unhexlify("f202%08x" % i) 2125 frame = build_sae_commit(bssid, addr) 2126 sock.send(radiotap + frame) 2127 while dev[0].mon.pending(): 2128 ev = dev[0].mon.recv() 2129 logger.debug("EV0: " + ev) 2130 if "CTRL-EVENT-CONNECTED" in ev: 2131 connected0 = True 2132 while dev[1].mon.pending(): 2133 ev = dev[1].mon.recv() 2134 logger.debug("EV1: " + ev) 2135 if "CTRL-EVENT-CONNECTED" in ev: 2136 connected1 = True 2137 if connected0 and connected1: 2138 break 2139 time.sleep(0.00000001) 2140 if not connected0: 2141 raise Exception("Real station(0) did not get connected") 2142 if not connected1: 2143 raise Exception("Real station(1) did not get connected") 2144 if count < 1: 2145 raise Exception("Too few token responses in third round: %d" % count) 2146 2147def test_sae_sync(dev, apdev): 2148 """SAE dot11RSNASAESync""" 2149 check_sae_capab(dev[0]) 2150 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2151 params['wpa_key_mgmt'] = 'SAE' 2152 params['sae_sync'] = '1' 2153 hostapd.add_ap(apdev[0], params) 2154 2155 # TODO: More complete dot11RSNASAESync testing. For now, this is really only 2156 # checking that sae_sync config parameter is accepted. 2157 dev[0].request("SET sae_groups ") 2158 dev[1].request("SET sae_groups ") 2159 id = {} 2160 for i in range(0, 2): 2161 dev[i].scan(freq="2412") 2162 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 2163 scan_freq="2412", only_add_network=True) 2164 for i in range(0, 2): 2165 dev[i].select_network(id[i]) 2166 for i in range(0, 2): 2167 dev[i].wait_connected(timeout=10) 2168 2169def test_sae_confirm_immediate(dev, apdev): 2170 """SAE and AP sending Confirm message without waiting STA""" 2171 check_sae_capab(dev[0]) 2172 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2173 params['wpa_key_mgmt'] = 'SAE' 2174 params['sae_confirm_immediate'] = '1' 2175 hapd = hostapd.add_ap(apdev[0], params) 2176 2177 dev[0].request("SET sae_groups ") 2178 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412") 2179 2180def test_sae_confirm_immediate2(dev, apdev): 2181 """SAE and AP sending Confirm message without waiting STA (2)""" 2182 check_sae_capab(dev[0]) 2183 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2184 params['wpa_key_mgmt'] = 'SAE' 2185 params['sae_confirm_immediate'] = '2' 2186 hapd = hostapd.add_ap(apdev[0], params) 2187 2188 dev[0].request("SET sae_groups ") 2189 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412") 2190 2191def test_sae_pwe_group_19(dev, apdev): 2192 """SAE PWE derivation options with group 19""" 2193 run_sae_pwe_group(dev, apdev, 19) 2194 2195def test_sae_pwe_group_20(dev, apdev): 2196 """SAE PWE derivation options with group 20""" 2197 run_sae_pwe_group(dev, apdev, 20) 2198 2199def test_sae_pwe_group_21(dev, apdev): 2200 """SAE PWE derivation options with group 21""" 2201 run_sae_pwe_group(dev, apdev, 21) 2202 2203def test_sae_pwe_group_25(dev, apdev): 2204 """SAE PWE derivation options with group 25""" 2205 run_sae_pwe_group(dev, apdev, 25) 2206 2207def test_sae_pwe_group_28(dev, apdev): 2208 """SAE PWE derivation options with group 28""" 2209 run_sae_pwe_group(dev, apdev, 28) 2210 2211def test_sae_pwe_group_29(dev, apdev): 2212 """SAE PWE derivation options with group 29""" 2213 run_sae_pwe_group(dev, apdev, 29) 2214 2215def test_sae_pwe_group_30(dev, apdev): 2216 """SAE PWE derivation options with group 30""" 2217 run_sae_pwe_group(dev, apdev, 30) 2218 2219def test_sae_pwe_group_1(dev, apdev): 2220 """SAE PWE derivation options with group 1""" 2221 run_sae_pwe_group(dev, apdev, 1) 2222 2223def test_sae_pwe_group_2(dev, apdev): 2224 """SAE PWE derivation options with group 2""" 2225 run_sae_pwe_group(dev, apdev, 2) 2226 2227def test_sae_pwe_group_5(dev, apdev): 2228 """SAE PWE derivation options with group 5""" 2229 run_sae_pwe_group(dev, apdev, 5) 2230 2231def test_sae_pwe_group_14(dev, apdev): 2232 """SAE PWE derivation options with group 14""" 2233 run_sae_pwe_group(dev, apdev, 14) 2234 2235def test_sae_pwe_group_15(dev, apdev): 2236 """SAE PWE derivation options with group 15""" 2237 run_sae_pwe_group(dev, apdev, 15) 2238 2239def test_sae_pwe_group_16(dev, apdev): 2240 """SAE PWE derivation options with group 16""" 2241 run_sae_pwe_group(dev, apdev, 16) 2242 2243def test_sae_pwe_group_22(dev, apdev): 2244 """SAE PWE derivation options with group 22""" 2245 run_sae_pwe_group(dev, apdev, 22) 2246 2247def test_sae_pwe_group_23(dev, apdev): 2248 """SAE PWE derivation options with group 23""" 2249 run_sae_pwe_group(dev, apdev, 23) 2250 2251def test_sae_pwe_group_24(dev, apdev): 2252 """SAE PWE derivation options with group 24""" 2253 run_sae_pwe_group(dev, apdev, 24) 2254 2255def start_sae_pwe_ap(apdev, group, sae_pwe, pmf=False): 2256 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2257 params['wpa_key_mgmt'] = 'SAE' 2258 params['sae_groups'] = str(group) 2259 params['sae_pwe'] = str(sae_pwe) 2260 if pmf: 2261 params['ieee80211w'] = '2' 2262 return hostapd.add_ap(apdev, params) 2263 2264def run_sae_pwe_group(dev, apdev, group): 2265 check_sae_capab(dev[0]) 2266 tls = dev[0].request("GET tls_library") 2267 if group == 25 and "run=BoringSSL" in tls: 2268 raise HwsimSkip("Group 15 not supported") 2269 if group in [27, 28, 29, 30]: 2270 if tls.startswith("OpenSSL") and ("run=OpenSSL 1." in tls or "run=OpenSSL 3." in tls): 2271 logger.info("Add Brainpool EC groups since OpenSSL is new enough") 2272 elif tls.startswith("wolfSSL"): 2273 logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL") 2274 else: 2275 raise HwsimSkip("Brainpool curve not supported") 2276 start_sae_pwe_ap(apdev[0], group, 2) 2277 try: 2278 check_sae_pwe_group(dev[0], group, 0) 2279 check_sae_pwe_group(dev[0], group, 1) 2280 check_sae_pwe_group(dev[0], group, 2) 2281 finally: 2282 dev[0].set("sae_groups", "") 2283 dev[0].set("sae_pwe", "0") 2284 2285def check_sae_pwe_group(dev, group, sae_pwe, check_ssid=False): 2286 dev.set("sae_groups", str(group)) 2287 dev.set("sae_pwe", str(sae_pwe)) 2288 dev.connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412") 2289 if check_ssid and dev.get_status_field("ssid_verified") != "1": 2290 raise Exception("ssid_verified=1 not in STATUS") 2291 dev.request("REMOVE_NETWORK all") 2292 dev.wait_disconnected() 2293 dev.dump_monitor() 2294 2295def test_sae_pwe_h2e_only_ap(dev, apdev): 2296 """SAE PWE derivation with H2E-only AP""" 2297 check_sae_capab(dev[0]) 2298 start_sae_pwe_ap(apdev[0], 19, 1) 2299 try: 2300 check_sae_pwe_group(dev[0], 19, 1, check_ssid=True) 2301 check_sae_pwe_group(dev[0], 19, 2, check_ssid=True) 2302 finally: 2303 dev[0].set("sae_groups", "") 2304 dev[0].set("sae_pwe", "0") 2305 2306 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412", 2307 wait_connect=False) 2308 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 2309 if ev is None: 2310 raise Exception("No indication of mismatching network seen") 2311 2312def test_sae_pwe_h2e_only_ap_sta_forcing_loop(dev, apdev): 2313 """SAE PWE derivation with H2E-only AP and STA forcing loop""" 2314 check_sae_capab(dev[0]) 2315 start_sae_pwe_ap(apdev[0], 19, 1) 2316 dev[0].set("ignore_sae_h2e_only", "1") 2317 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412", 2318 wait_connect=False) 2319 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10) 2320 dev[0].request("DISCONNECT") 2321 if ev is None: 2322 raise Exception("No indication of temporary disabled network seen") 2323 2324def test_sae_pwe_loop_only_ap(dev, apdev): 2325 """SAE PWE derivation with loop-only AP""" 2326 check_sae_capab(dev[0]) 2327 start_sae_pwe_ap(apdev[0], 19, 0) 2328 try: 2329 check_sae_pwe_group(dev[0], 19, 0) 2330 check_sae_pwe_group(dev[0], 19, 2) 2331 dev[0].set("sae_pwe", "1") 2332 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2333 scan_freq="2412", wait_connect=False) 2334 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 2335 if ev is None: 2336 raise Exception("No indication of mismatching network seen") 2337 finally: 2338 dev[0].set("sae_groups", "") 2339 dev[0].set("sae_pwe", "0") 2340 2341def test_sae_pwe_both(dev, apdev): 2342 """SAE PWE derivation with both options""" 2343 check_sae_capab(dev[0]) 2344 check_sae_capab(dev[1]) 2345 hapd = start_sae_pwe_ap(apdev[0], 19, 2, pmf=True) 2346 try: 2347 dev[0].set("sae_groups", "") 2348 dev[0].set("sae_pwe", "1") 2349 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2350 ieee80211w="2", scan_freq="2412") 2351 dev[1].set("sae_groups", "") 2352 dev[1].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2353 ieee80211w="2", scan_freq="2412") 2354 if dev[0].get_status_field("sae_h2e") != "1": 2355 raise Exception("SAE H2E was not used on dev[0]") 2356 if dev[1].get_status_field("sae_h2e") != "0": 2357 raise Exception("SAE H2E was used on dev[1]") 2358 finally: 2359 dev[0].set("sae_groups", "") 2360 dev[0].set("sae_pwe", "0") 2361 dev[1].set("sae_groups", "") 2362 2363 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412", 2364 wait_connect=False) 2365 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 2366 if ev is None: 2367 raise Exception("No indication of mismatching network seen") 2368 2369def test_sae_h2e_rejected_groups(dev, apdev): 2370 """SAE H2E and rejected groups indication""" 2371 check_sae_capab(dev[0]) 2372 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2373 params['wpa_key_mgmt'] = 'SAE' 2374 params['sae_groups'] = "19" 2375 params['sae_pwe'] = "1" 2376 hapd = hostapd.add_ap(apdev[0], params) 2377 try: 2378 dev[0].set("sae_groups", "21 20 19") 2379 dev[0].set("sae_pwe", "1") 2380 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2381 scan_freq="2412") 2382 addr = dev[0].own_addr() 2383 hapd.wait_sta(addr) 2384 sta = hapd.get_sta(addr) 2385 if 'sae_rejected_groups' not in sta: 2386 raise Exception("No sae_rejected_groups") 2387 val = sta['sae_rejected_groups'] 2388 if val != "21 20": 2389 raise Exception("Unexpected sae_rejected_groups value: " + val) 2390 finally: 2391 dev[0].set("sae_groups", "") 2392 dev[0].set("sae_pwe", "0") 2393 2394def test_sae_h2e_rejected_groups_diff_ap(dev, apdev): 2395 """SAE H2E and rejected groups with different APs and different config""" 2396 check_sae_capab(dev[0]) 2397 2398 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2399 params['wpa_key_mgmt'] = 'SAE' 2400 params['sae_groups'] = "19" 2401 params['sae_pwe'] = "1" 2402 hapd = hostapd.add_ap(apdev[0], params) 2403 2404 try: 2405 dev[0].set("sae_groups", "21 20 19") 2406 dev[0].set("sae_pwe", "1") 2407 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2408 scan_freq="2412") 2409 addr = dev[0].own_addr() 2410 hapd.wait_sta(addr) 2411 2412 params['sae_groups'] = "20" 2413 hapd2 = hostapd.add_ap(apdev[1], params) 2414 bssid2 = hapd2.own_addr() 2415 2416 dev[0].scan_for_bss(bssid2, freq=2412) 2417 dev[0].roam(bssid2) 2418 hapd2.wait_sta(addr) 2419 sta = hapd2.get_sta(addr) 2420 if 'sae_rejected_groups' not in sta: 2421 raise Exception("No sae_rejected_groups") 2422 val = sta['sae_rejected_groups'] 2423 if val != "21": 2424 raise Exception("Unexpected sae_rejected_groups value: " + val) 2425 finally: 2426 dev[0].set("sae_groups", "") 2427 dev[0].set("sae_pwe", "0") 2428 2429def test_sae_h2e_rejected_groups_unexpected(dev, apdev): 2430 """SAE H2E and rejected groups indication (unexpected group)""" 2431 check_sae_capab(dev[0]) 2432 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2433 params['wpa_key_mgmt'] = 'SAE' 2434 params['sae_groups'] = "19 20" 2435 params['sae_pwe'] = "1" 2436 hapd = hostapd.add_ap(apdev[0], params) 2437 try: 2438 dev[0].set("sae_groups", "21 19") 2439 dev[0].set("extra_sae_rejected_groups", "19") 2440 dev[0].set("sae_pwe", "1") 2441 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2442 scan_freq="2412", wait_connect=False) 2443 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2444 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10) 2445 dev[0].request("DISCONNECT") 2446 if ev is None: 2447 raise Exception("No indication of temporary disabled network seen") 2448 if "CTRL-EVENT-CONNECTED" in ev: 2449 raise Exception("Unexpected connection") 2450 finally: 2451 dev[0].set("sae_groups", "") 2452 dev[0].set("sae_pwe", "0") 2453 2454def test_sae_h2e_rejected_groups_invalid(dev, apdev): 2455 """SAE protocol testing - Invalid Rejected Groups element""" 2456 check_sae_capab(dev[0]) 2457 params = hostapd.wpa2_params(ssid="test-sae", 2458 passphrase="12345678") 2459 params['wpa_key_mgmt'] = 'SAE' 2460 params['sae_groups'] = "19 20" 2461 params['sae_pwe'] = "1" 2462 hapd = hostapd.add_ap(apdev[0], params) 2463 2464 try: 2465 dev[0].set("sae_groups", "20 19") 2466 dev[0].set("sae_pwe", "1") 2467 run_sae_h2e_rejected_groups_invalid(dev[0], hapd) 2468 finally: 2469 dev[0].set("sae_groups", "") 2470 dev[0].set("sae_pwe", "0") 2471 2472def run_sae_h2e_rejected_groups_invalid(dev, hapd): 2473 addr = dev.own_addr() 2474 bssid = hapd.own_addr() 2475 2476 dev.scan_for_bss(bssid, freq=2412) 2477 hapd.set("ext_mgmt_frame_handling", "1") 2478 dev.connect("test-sae", psk="12345678", key_mgmt="SAE", 2479 scan_freq="2412", wait_connect=False) 2480 2481 logger.info("Commit (group 20)") 2482 for i in range(10): 2483 req = hapd.mgmt_rx() 2484 if req is None: 2485 raise Exception("MGMT RX wait timed out (commit)") 2486 if req['subtype'] == 11: 2487 break 2488 req = None 2489 if not req: 2490 raise Exception("Authentication frame (commit) not received") 2491 group, = struct.unpack('<H', req['payload'][6:8]) 2492 if group != 20: 2493 raise Exception("Unexpected group %d in SAE Commit" % group) 2494 hapd.dump_monitor() 2495 2496 # Discard this SAE Commit message without AP processing and instead, send 2497 # an unsupported group indication to the STA. 2498 resp = {} 2499 resp['fc'] = 0xb0 2500 resp['da'] = addr 2501 resp['sa'] = bssid 2502 resp['bssid'] = bssid 2503 resp['payload'] = binascii.unhexlify("030001004d001400") 2504 hapd.mgmt_tx(resp) 2505 2506 logger.info("Commit (group 19)") 2507 for i in range(10): 2508 req = hapd.mgmt_rx() 2509 if req is None: 2510 raise Exception("MGMT RX wait timed out (commit)") 2511 if req['subtype'] == 11: 2512 break 2513 req = None 2514 if not req: 2515 raise Exception("Authentication frame (commit) not received") 2516 group, = struct.unpack('<H', req['payload'][6:8]) 2517 if group != 19: 2518 raise Exception("Unexpected group %d in SAE Commit" % group) 2519 hapd.dump_monitor() 2520 2521 # Replace the Rejected Groups element with an invalid one and process the 2522 # modified SAE Commit message in hostapd. 2523 rej_groups = req['frame'][-5:] 2524 if rej_groups != binascii.unhexlify('ff035c1400'): 2525 raise Exception("No Rejected Groups element: " + binascii.hexlify(rej_groups).decode()) 2526 frame = req['frame'][:-5] + binascii.unhexlify('ff025c14') 2527 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(frame).decode()) 2528 2529 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 2530 if ev is None: 2531 raise Exception("Management frame TX status not reported") 2532 if "stype=11 ok=1" not in ev: 2533 raise Exception("Unexpected Management frame TX status: " + ev) 2534 buf = ev.split(' ')[3].split('=')[1] 2535 payload = buf[48:] 2536 if payload != "030001000100": 2537 raise Exception("Unexpected AP response to SAE Commit with invalid Rejected Groups element: " + payload) 2538 2539 # Stop modifying frames and verify that connection is eventually established 2540 # with automatic retries. 2541 hapd.set("ext_mgmt_frame_handling", "0") 2542 dev.wait_connected(timeout=60) 2543 2544def test_sae_h2e_password_id(dev, apdev): 2545 """SAE H2E and password identifier""" 2546 check_sae_capab(dev[0]) 2547 params = hostapd.wpa2_params(ssid="test-sae") 2548 params['wpa_key_mgmt'] = 'SAE' 2549 params['sae_pwe'] = '1' 2550 params['sae_password'] = 'secret|id=pw id' 2551 hapd = hostapd.add_ap(apdev[0], params) 2552 2553 try: 2554 dev[0].request("SET sae_groups ") 2555 dev[0].set("sae_pwe", "1") 2556 dev[0].connect("test-sae", sae_password="secret", 2557 sae_password_id="pw id", 2558 key_mgmt="SAE", scan_freq="2412") 2559 finally: 2560 dev[0].set("sae_groups", "") 2561 dev[0].set("sae_pwe", "0") 2562 2563def test_sae_pwe_in_psk_ap(dev, apdev): 2564 """sae_pwe parameter in PSK-only-AP""" 2565 params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678") 2566 params['sae_pwe'] = '1' 2567 hapd = hostapd.add_ap(apdev[0], params) 2568 2569 dev[0].connect("test-psk", psk="12345678", scan_freq="2412") 2570 2571def test_sae_auth_restart(dev, apdev): 2572 """SAE and authentication restarts with H2E/looping""" 2573 check_sae_capab(dev[0]) 2574 params = hostapd.wpa2_params(ssid="test-sae") 2575 params['wpa_key_mgmt'] = 'SAE' 2576 params['sae_pwe'] = '2' 2577 params['sae_password'] = 'secret|id=pw id' 2578 hapd = hostapd.add_ap(apdev[0], params) 2579 2580 try: 2581 dev[0].request("SET sae_groups ") 2582 for pwe in [1, 0, 1]: 2583 dev[0].set("sae_pwe", str(pwe)) 2584 dev[0].connect("test-sae", sae_password="secret", 2585 sae_password_id="pw id", 2586 key_mgmt="SAE", scan_freq="2412") 2587 # Disconnect without hostapd removing the STA entry so that the 2588 # following SAE authentication instance starts with an existing 2589 # STA entry that has maintained some SAE state. 2590 hapd.set("ext_mgmt_frame_handling", "1") 2591 dev[0].request("REMOVE_NETWORK all") 2592 req = hapd.mgmt_rx() 2593 dev[0].wait_disconnected() 2594 dev[0].dump_monitor() 2595 hapd.set("ext_mgmt_frame_handling", "0") 2596 finally: 2597 dev[0].set("sae_groups", "") 2598 dev[0].set("sae_pwe", "0") 2599 2600def test_sae_rsne_mismatch(dev, apdev): 2601 """SAE and RSNE mismatch in EAPOL-Key msg 2/4""" 2602 check_sae_capab(dev[0]) 2603 dev[0].set("sae_groups", "") 2604 2605 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2606 params['wpa_key_mgmt'] = 'SAE' 2607 hapd = hostapd.add_ap(apdev[0], params) 2608 2609 # First, test with matching RSNE to confirm testing capability 2610 dev[0].set("rsne_override_eapol", 2611 "30140100000fac040100000fac040100000fac080c00") 2612 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2613 scan_freq="2412") 2614 dev[0].request("REMOVE_NETWORK all") 2615 dev[0].wait_disconnected() 2616 dev[0].dump_monitor() 2617 2618 # Then, test with modified RSNE 2619 tests = ["30140100000fac040100000fac040100000fac080c10", "0000"] 2620 for ie in tests: 2621 dev[0].set("rsne_override_eapol", ie) 2622 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2623 scan_freq="2412", wait_connect=False) 2624 ev = dev[0].wait_event(["Associated with"], timeout=10) 2625 if ev is None: 2626 raise Exception("No indication of association seen") 2627 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2628 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2629 dev[0].request("REMOVE_NETWORK all") 2630 if ev is None: 2631 raise Exception("No disconnection seen") 2632 if "CTRL-EVENT-DISCONNECTED" not in ev: 2633 raise Exception("Unexpected connection") 2634 dev[0].dump_monitor() 2635 2636def test_sae_h2e_rsnxe_mismatch(dev, apdev): 2637 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4""" 2638 check_sae_capab(dev[0]) 2639 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2640 params['wpa_key_mgmt'] = 'SAE' 2641 params['sae_pwe'] = "1" 2642 hapd = hostapd.add_ap(apdev[0], params) 2643 try: 2644 dev[0].set("sae_groups", "19") 2645 dev[0].set("sae_pwe", "1") 2646 for rsnxe in ["F40100", "F400", ""]: 2647 dev[0].set("rsnxe_override_eapol", rsnxe) 2648 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2649 scan_freq="2412", wait_connect=False) 2650 ev = dev[0].wait_event(["Associated with"], timeout=10) 2651 if ev is None: 2652 raise Exception("No indication of association seen") 2653 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2654 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2655 dev[0].request("REMOVE_NETWORK all") 2656 if ev is None: 2657 raise Exception("No disconnection seen") 2658 if "CTRL-EVENT-DISCONNECTED" not in ev: 2659 raise Exception("Unexpected connection") 2660 dev[0].dump_monitor() 2661 finally: 2662 dev[0].set("sae_groups", "") 2663 dev[0].set("sae_pwe", "0") 2664 2665def test_sae_h2e_rsnxe_mismatch_retries(dev, apdev): 2666 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 retries""" 2667 check_sae_capab(dev[0]) 2668 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2669 params['wpa_key_mgmt'] = 'SAE' 2670 params['sae_pwe'] = "1" 2671 hapd = hostapd.add_ap(apdev[0], params) 2672 try: 2673 dev[0].set("sae_groups", "19") 2674 dev[0].set("sae_pwe", "1") 2675 rsnxe = "F40100" 2676 dev[0].set("rsnxe_override_eapol", rsnxe) 2677 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2678 scan_freq="2412", wait_connect=False) 2679 ev = dev[0].wait_event(["Associated with"], timeout=10) 2680 if ev is None: 2681 raise Exception("No indication of association seen") 2682 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2683 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2684 if ev is None: 2685 raise Exception("No disconnection seen") 2686 if "CTRL-EVENT-DISCONNECTED" not in ev: 2687 raise Exception("Unexpected connection") 2688 2689 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2690 "CTRL-EVENT-DISCONNECTED"], timeout=10) 2691 if ev is None: 2692 raise Exception("No disconnection seen (2)") 2693 if "CTRL-EVENT-DISCONNECTED" not in ev: 2694 raise Exception("Unexpected connection (2)") 2695 2696 dev[0].dump_monitor() 2697 finally: 2698 dev[0].set("sae_groups", "") 2699 dev[0].set("sae_pwe", "0") 2700 2701def test_sae_h2e_rsnxe_mismatch_assoc(dev, apdev): 2702 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 (assoc)""" 2703 check_sae_capab(dev[0]) 2704 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2705 params['wpa_key_mgmt'] = 'SAE' 2706 params['sae_pwe'] = "1" 2707 hapd = hostapd.add_ap(apdev[0], params) 2708 try: 2709 dev[0].set("sae_groups", "19") 2710 dev[0].set("sae_pwe", "1") 2711 for rsnxe in ["F40100", "F400", ""]: 2712 dev[0].set("rsnxe_override_assoc", rsnxe) 2713 dev[0].set("rsnxe_override_eapol", "F40120") 2714 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2715 scan_freq="2412", wait_connect=False) 2716 ev = dev[0].wait_event(["Associated with"], timeout=10) 2717 if ev is None: 2718 raise Exception("No indication of association seen") 2719 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2720 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2721 dev[0].request("REMOVE_NETWORK all") 2722 if ev is None: 2723 raise Exception("No disconnection seen") 2724 if "CTRL-EVENT-DISCONNECTED" not in ev: 2725 raise Exception("Unexpected connection") 2726 dev[0].dump_monitor() 2727 finally: 2728 dev[0].set("sae_groups", "") 2729 dev[0].set("sae_pwe", "0") 2730 2731def test_sae_h2e_rsnxe_mismatch_ap(dev, apdev): 2732 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4""" 2733 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F40100") 2734 2735def test_sae_h2e_rsnxe_mismatch_ap2(dev, apdev): 2736 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4""" 2737 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F400") 2738 2739def test_sae_h2e_rsnxe_mismatch_ap3(dev, apdev): 2740 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4""" 2741 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "") 2742 2743def run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, rsnxe): 2744 check_sae_capab(dev[0]) 2745 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2746 params['wpa_key_mgmt'] = 'SAE' 2747 params['sae_pwe'] = "1" 2748 params['rsnxe_override_eapol'] = rsnxe 2749 hapd = hostapd.add_ap(apdev[0], params) 2750 try: 2751 dev[0].set("sae_groups", "19") 2752 dev[0].set("sae_pwe", "1") 2753 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2754 scan_freq="2412", wait_connect=False) 2755 ev = dev[0].wait_event(["Associated with"], timeout=10) 2756 if ev is None: 2757 raise Exception("No indication of association seen") 2758 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2759 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2760 dev[0].request("REMOVE_NETWORK all") 2761 if ev is None: 2762 raise Exception("No disconnection seen") 2763 if "CTRL-EVENT-DISCONNECTED" not in ev: 2764 raise Exception("Unexpected connection") 2765 finally: 2766 dev[0].set("sae_groups", "") 2767 dev[0].set("sae_pwe", "0") 2768 2769def test_sae_forced_anti_clogging_h2e(dev, apdev): 2770 """SAE anti clogging (forced, H2E)""" 2771 check_sae_capab(dev[0]) 2772 check_sae_capab(dev[1]) 2773 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2774 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 2775 params['sae_pwe'] = "1" 2776 params['sae_anti_clogging_threshold'] = '0' 2777 hostapd.add_ap(apdev[0], params) 2778 dev[2].connect("test-sae", psk="12345678", scan_freq="2412") 2779 try: 2780 for i in range(2): 2781 dev[i].request("SET sae_groups ") 2782 dev[i].set("sae_pwe", "1") 2783 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 2784 scan_freq="2412") 2785 finally: 2786 for i in range(2): 2787 dev[i].set("sae_pwe", "0") 2788 2789def test_sae_forced_anti_clogging_h2e_loop(dev, apdev): 2790 """SAE anti clogging (forced, H2E + loop)""" 2791 check_sae_capab(dev[0]) 2792 check_sae_capab(dev[1]) 2793 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2794 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 2795 params['sae_pwe'] = "2" 2796 params['sae_anti_clogging_threshold'] = '0' 2797 hostapd.add_ap(apdev[0], params) 2798 dev[2].connect("test-sae", psk="12345678", scan_freq="2412") 2799 try: 2800 for i in range(2): 2801 dev[i].request("SET sae_groups ") 2802 dev[i].set("sae_pwe", "2") 2803 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 2804 scan_freq="2412") 2805 finally: 2806 for i in range(2): 2807 dev[i].set("sae_pwe", "0") 2808 2809def test_sae_okc(dev, apdev): 2810 """SAE and opportunistic key caching""" 2811 check_sae_capab(dev[0]) 2812 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2813 params['wpa_key_mgmt'] = 'SAE' 2814 params['okc'] = '1' 2815 hapd = hostapd.add_ap(apdev[0], params) 2816 bssid = hapd.own_addr() 2817 2818 dev[0].flush_scan_cache() 2819 dev[0].set("sae_groups", "") 2820 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2821 okc=True, scan_freq="2412") 2822 dev[0].dump_monitor() 2823 hapd.wait_sta() 2824 if "sae_group" not in dev[0].get_status(): 2825 raise Exception("SAE authentication not used") 2826 2827 hapd2 = hostapd.add_ap(apdev[1], params) 2828 bssid2 = hapd2.own_addr() 2829 2830 dev[0].scan_for_bss(bssid2, freq=2412) 2831 dev[0].roam(bssid2) 2832 dev[0].dump_monitor() 2833 hapd2.wait_sta() 2834 if "sae_group" in dev[0].get_status(): 2835 raise Exception("SAE authentication used during roam to AP2") 2836 2837 dev[0].roam(bssid) 2838 dev[0].dump_monitor() 2839 hapd.wait_sta() 2840 if "sae_group" in dev[0].get_status(): 2841 raise Exception("SAE authentication used during roam to AP1") 2842 2843def test_sae_okc_sta_only(dev, apdev): 2844 """SAE and opportunistic key caching only on STA""" 2845 check_sae_capab(dev[0]) 2846 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2847 params['wpa_key_mgmt'] = 'SAE' 2848 hapd = hostapd.add_ap(apdev[0], params) 2849 bssid = hapd.own_addr() 2850 2851 dev[0].flush_scan_cache() 2852 dev[0].set("sae_groups", "") 2853 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2854 okc=True, scan_freq="2412") 2855 dev[0].dump_monitor() 2856 hapd.wait_sta() 2857 if "sae_group" not in dev[0].get_status(): 2858 raise Exception("SAE authentication not used") 2859 2860 hapd2 = hostapd.add_ap(apdev[1], params) 2861 bssid2 = hapd2.own_addr() 2862 2863 dev[0].scan_for_bss(bssid2, freq=2412) 2864 dev[0].roam(bssid2, assoc_reject_ok=True) 2865 dev[0].dump_monitor() 2866 hapd2.wait_sta() 2867 if "sae_group" not in dev[0].get_status(): 2868 raise Exception("SAE authentication not used during roam to AP2") 2869 2870def test_sae_okc_pmk_lifetime(dev, apdev): 2871 """SAE and opportunistic key caching and PMK lifetime""" 2872 check_sae_capab(dev[0]) 2873 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2874 params['wpa_key_mgmt'] = 'SAE' 2875 params['okc'] = '1' 2876 hapd = hostapd.add_ap(apdev[0], params) 2877 bssid = hapd.own_addr() 2878 2879 dev[0].flush_scan_cache() 2880 dev[0].set("sae_groups", "") 2881 dev[0].set("dot11RSNAConfigPMKLifetime", "10") 2882 dev[0].set("dot11RSNAConfigPMKReauthThreshold", "30") 2883 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2884 okc=True, scan_freq="2412") 2885 dev[0].dump_monitor() 2886 hapd.wait_sta() 2887 if "sae_group" not in dev[0].get_status(): 2888 raise Exception("SAE authentication not used") 2889 2890 hapd2 = hostapd.add_ap(apdev[1], params) 2891 bssid2 = hapd2.own_addr() 2892 2893 time.sleep(5) 2894 dev[0].scan_for_bss(bssid2, freq=2412) 2895 dev[0].roam(bssid2) 2896 dev[0].dump_monitor() 2897 hapd2.wait_sta() 2898 if "sae_group" not in dev[0].get_status(): 2899 raise Exception("SAE authentication not used during roam to AP2 after reauth threshold") 2900 2901def test_sae_pmk_lifetime(dev, apdev): 2902 """SAE and PMK lifetime""" 2903 check_sae_capab(dev[0]) 2904 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2905 params['wpa_key_mgmt'] = 'SAE' 2906 hapd = hostapd.add_ap(apdev[0], params) 2907 bssid = hapd.own_addr() 2908 2909 dev[0].set("sae_groups", "") 2910 dev[0].set("dot11RSNAConfigPMKLifetime", "10") 2911 dev[0].set("dot11RSNAConfigPMKReauthThreshold", "50") 2912 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2913 scan_freq="2412") 2914 dev[0].dump_monitor() 2915 hapd.wait_sta() 2916 if "sae_group" not in dev[0].get_status(): 2917 raise Exception("SAE authentication not used") 2918 2919 hapd2 = hostapd.add_ap(apdev[1], params) 2920 bssid2 = hapd2.own_addr() 2921 2922 dev[0].flush_scan_cache() 2923 dev[0].scan_for_bss(bssid2, freq=2412) 2924 dev[0].roam(bssid2) 2925 dev[0].dump_monitor() 2926 hapd2.wait_sta() 2927 if "sae_group" not in dev[0].get_status(): 2928 raise Exception("SAE authentication not used during roam to AP2") 2929 2930 dev[0].roam(bssid) 2931 dev[0].dump_monitor() 2932 hapd.wait_sta() 2933 if "sae_group" in dev[0].get_status(): 2934 raise Exception("SAE authentication used during roam to AP1") 2935 2936 time.sleep(6) 2937 dev[0].scan_for_bss(bssid2, freq=2412) 2938 dev[0].roam(bssid2) 2939 dev[0].dump_monitor() 2940 hapd2.wait_sta() 2941 if "sae_group" not in dev[0].get_status(): 2942 raise Exception("SAE authentication not used during roam to AP2 after reauth threshold") 2943 2944 ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], 11) 2945 if ev is None: 2946 raise Exception("PMKSA cache entry did not expire") 2947 if bssid2 in ev: 2948 raise Exception("Unexpected expiration of the current SAE PMKSA cache entry") 2949 2950def test_sae_and_psk_multiple_passwords(dev, apdev, params): 2951 """SAE and PSK with multiple passwords/passphrases""" 2952 check_sae_capab(dev[0]) 2953 check_sae_capab(dev[1]) 2954 addr0 = dev[0].own_addr() 2955 addr1 = dev[1].own_addr() 2956 psk_file = os.path.join(params['logdir'], 2957 'sae_and_psk_multiple_passwords.wpa_psk') 2958 with open(psk_file, 'w') as f: 2959 f.write(addr0 + ' passphrase0\n') 2960 f.write(addr1 + ' passphrase1\n') 2961 params = hostapd.wpa2_params(ssid="test-sae") 2962 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 2963 params['sae_password'] = ['passphrase0|mac=' + addr0, 2964 'passphrase1|mac=' + addr1] 2965 params['wpa_psk_file'] = psk_file 2966 hapd = hostapd.add_ap(apdev[0], params) 2967 2968 dev[0].set("sae_groups", "") 2969 dev[0].connect("test-sae", sae_password="passphrase0", 2970 key_mgmt="SAE", scan_freq="2412") 2971 dev[0].request("REMOVE_NETWORK all") 2972 dev[0].wait_disconnected() 2973 2974 dev[0].connect("test-sae", psk="passphrase0", scan_freq="2412") 2975 dev[0].request("REMOVE_NETWORK all") 2976 dev[0].wait_disconnected() 2977 2978 dev[1].set("sae_groups", "") 2979 dev[1].connect("test-sae", sae_password="passphrase1", 2980 key_mgmt="SAE", scan_freq="2412") 2981 dev[1].request("REMOVE_NETWORK all") 2982 dev[1].wait_disconnected() 2983 2984 dev[1].connect("test-sae", psk="passphrase1", scan_freq="2412") 2985 dev[1].request("REMOVE_NETWORK all") 2986 dev[1].wait_disconnected() 2987 2988def test_sae_pmf_roam(dev, apdev): 2989 """SAE/PMF roam""" 2990 check_sae_capab(dev[0]) 2991 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2992 params['wpa_key_mgmt'] = 'SAE' 2993 params['ieee80211w'] = '2' 2994 params['skip_prune_assoc'] = '1' 2995 hapd = hostapd.add_ap(apdev[0], params) 2996 bssid = hapd.own_addr() 2997 2998 dev[0].flush_scan_cache() 2999 dev[0].set("sae_groups", "") 3000 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 3001 ieee80211w="2", scan_freq="2412") 3002 dev[0].dump_monitor() 3003 hapd.wait_sta() 3004 3005 hapd2 = hostapd.add_ap(apdev[1], params) 3006 bssid2 = hapd2.own_addr() 3007 3008 dev[0].scan_for_bss(bssid2, freq=2412) 3009 dev[0].roam(bssid2) 3010 dev[0].dump_monitor() 3011 hapd2.wait_sta() 3012 3013 dev[0].roam(bssid) 3014 dev[0].dump_monitor() 3015 3016def test_sae_ocv_pmk(dev, apdev): 3017 """SAE with OCV and fetching PMK (successful 4-way handshake)""" 3018 check_sae_capab(dev[0]) 3019 params = hostapd.wpa2_params(ssid="test-sae", 3020 passphrase="12345678") 3021 params['wpa_key_mgmt'] = 'SAE' 3022 params['ieee80211w'] = '2' 3023 params['ocv'] = '1' 3024 hapd = hostapd.add_ap(apdev[0], params) 3025 3026 dev[0].set("sae_groups", "") 3027 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ocv="1", 3028 ieee80211w="2", scan_freq="2412") 3029 hapd.wait_sta() 3030 3031 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr()) 3032 if "FAIL" in pmk_h or len(pmk_h) == 0: 3033 raise Exception("Failed to fetch PMK from hostapd during a successful authentication") 3034 3035 pmk_w = dev[0].get_pmk(id) 3036 if pmk_h != pmk_w: 3037 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w)) 3038 3039def test_sae_ocv_pmk_failure(dev, apdev): 3040 """SAE with OCV and fetching PMK (failed 4-way handshake)""" 3041 check_sae_capab(dev[0]) 3042 params = hostapd.wpa2_params(ssid="test-sae", 3043 passphrase="12345678") 3044 params['wpa_key_mgmt'] = 'SAE' 3045 params['ieee80211w'] = '2' 3046 params['ocv'] = '1' 3047 hapd = hostapd.add_ap(apdev[0], params) 3048 3049 dev[0].set("sae_groups", "") 3050 dev[0].set("oci_freq_override_eapol", "2462") 3051 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ocv="1", 3052 ieee80211w="2", scan_freq="2412", wait_connect=False) 3053 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 3054 "CTRL-EVENT-DISCONNECTED"], timeout=15) 3055 if ev is None: 3056 raise Exception("No connection result reported") 3057 if "CTRL-EVENT-CONNECTED" in ev: 3058 raise Exception("Unexpected connection") 3059 3060 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr()) 3061 if "FAIL" in pmk_h or len(pmk_h) == 0: 3062 raise Exception("Failed to fetch PMK from hostapd during a successful authentication") 3063 3064 res = dev[0].request("PMKSA_GET %d" % id) 3065 if not res.startswith(hapd.own_addr()): 3066 raise Exception("PMKSA from wpa_supplicant does not have matching BSSID") 3067 pmk_w = res.split(' ')[2] 3068 if pmk_h != pmk_w: 3069 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w)) 3070 3071 dev[0].request("DISCONNECT") 3072 time.sleep(0.1) 3073 pmk_h2 = hapd.request("GET_PMK " + dev[0].own_addr()) 3074 res = dev[0].request("PMKSA_GET %d" % id) 3075 pmk_w2 = res.split(' ')[2] 3076 if pmk_h2 != pmk_h: 3077 raise Exception("hostapd did not report correct PMK after disconnection") 3078 if pmk_w2 != pmk_w: 3079 raise Exception("wpa_supplicant did not report correct PMK after disconnection") 3080 3081def test_sae_reject(dev, apdev): 3082 """SAE and AP rejecting connection""" 3083 check_sae_capab(dev[0]) 3084 params = hostapd.wpa2_params(ssid="test-sae", 3085 passphrase="12345678") 3086 params['wpa_key_mgmt'] = 'SAE' 3087 params['max_num_sta'] = '0' 3088 hapd = hostapd.add_ap(apdev[0], params) 3089 dev[0].set("sae_groups", "") 3090 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 3091 scan_freq="2412", wait_connect=False) 3092 if not dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10): 3093 raise Exception("Authentication rejection not reported") 3094 dev[0].request("REMOVE_NETWORK all") 3095 dev[0].dump_monitor() 3096 3097def test_sae_ext_key_19(dev, apdev): 3098 """SAE with extended key AKM (group 19)""" 3099 run_sae_ext_key(dev, apdev, 19) 3100 3101def test_sae_ext_key_20(dev, apdev): 3102 """SAE with extended key AKM (group 20)""" 3103 run_sae_ext_key(dev, apdev, 20) 3104 3105def test_sae_ext_key_21(dev, apdev): 3106 """SAE with extended key AKM (group 21)""" 3107 run_sae_ext_key(dev, apdev, 21) 3108 3109def test_sae_ext_key_19_gcmp256(dev, apdev): 3110 """SAE with extended key AKM (group 19) with GCMP256 pairwise cipher""" 3111 run_sae_ext_key(dev, apdev, 19, cipher="GCMP-256") 3112 3113def test_sae_ext_key_20_gcmp256(dev, apdev): 3114 """SAE with extended key AKM (group 20) with GCMP-256 pairwise cipher""" 3115 run_sae_ext_key(dev, apdev, 20, cipher="GCMP-256") 3116 3117def test_sae_ext_key_21_gcmp256(dev, apdev): 3118 """SAE with extended key AKM (group 21) with GCMP-256 pairwise cipher""" 3119 run_sae_ext_key(dev, apdev, 21, cipher="GCMP-256") 3120 3121def test_sae_ext_key_21_gcmp256_gcmp256(dev, apdev): 3122 """SAE with extended key AKM (group 21) with GCMP-256 pairwise and group cipher""" 3123 run_sae_ext_key(dev, apdev, 21, cipher="GCMP-256", group_cipher="GCMP-256") 3124 3125def run_sae_ext_key(dev, apdev, group, cipher="CCMP", group_cipher="CCMP"): 3126 check_sae_capab(dev[0]) 3127 3128 if cipher not in dev[0].get_capability("pairwise"): 3129 raise HwsimSkip("Cipher %s not supported" % cipher) 3130 if group_cipher not in dev[0].get_capability("group"): 3131 raise HwsimSkip("Cipher %s not supported" % group_cipher) 3132 3133 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 3134 params['wpa_key_mgmt'] = 'SAE-EXT-KEY' 3135 params['sae_groups'] = str(group) 3136 params['ieee80211w'] = '2' 3137 params['rsn_pairwise'] = cipher 3138 params['group_cipher'] = group_cipher 3139 3140 hapd = hostapd.add_ap(apdev[0], params) 3141 key_mgmt = hapd.get_config()['key_mgmt'] 3142 if key_mgmt.split(' ')[0] != "SAE-EXT-KEY": 3143 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt) 3144 3145 dev[0].flush_scan_cache() 3146 dev[0].set("sae_groups", str(group)) 3147 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE-EXT-KEY", 3148 pairwise=cipher, group=group_cipher, 3149 ieee80211w="2", scan_freq="2412") 3150 hapd.wait_sta() 3151 if dev[0].get_status_field('sae_group') != str(group): 3152 raise Exception("Expected SAE group not used") 3153 bss = dev[0].get_bss(apdev[0]['bssid']) 3154 if 'flags' not in bss: 3155 raise Exception("Could not get BSS flags from BSS table") 3156 if "[WPA2-SAE-EXT-KEY-" + cipher + "]" not in bss['flags']: 3157 raise Exception("Unexpected BSS flags: " + bss['flags']) 3158 3159 res = hapd.request("STA-FIRST") 3160 if ("sae_group=%d" % group) not in res.splitlines(): 3161 raise Exception("hostapd STA output did not specify SAE group") 3162 3163 sta0 = hapd.get_sta(dev[0].own_addr()) 3164 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-24': 3165 raise Exception("SAE STA(0) AKM suite selector reported incorrectly") 3166 3167 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr()) 3168 pmk_w = dev[0].get_pmk(id) 3169 if pmk_h != pmk_w: 3170 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w)) 3171 if group == 19: 3172 pmk_len = 32 3173 elif group == 20: 3174 pmk_len = 48 3175 elif group == 21: 3176 pmk_len = 64 3177 if len(pmk_h) != 2 * pmk_len: 3178 raise Exception("Unexpected SAE PMK length: %d" % (len(pmk_h) / 2)) 3179 dev[0].request("DISCONNECT") 3180 dev[0].wait_disconnected() 3181 pmk_h2 = hapd.request("GET_PMK " + dev[0].own_addr()) 3182 if pmk_h != pmk_h2: 3183 raise Exception("Fetched PMK from PMKSA cache does not match: %s, %s" % (pmk_h, pmk_h2)) 3184 3185 dev[0].request("RECONNECT") 3186 dev[0].wait_connected(timeout=15, error="Reconnect timed out") 3187 val = dev[0].get_status_field('sae_group') 3188 if val is not None: 3189 raise Exception("SAE group claimed to have been used: " + val) 3190 sta0 = hapd.get_sta(dev[0].own_addr()) 3191 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-24': 3192 raise Exception("SAE STA(0) AKM suite selector reported incorrectly after PMKSA caching") 3193 3194def test_sae_akms(dev, apdev): 3195 """SAE with both AKMs)""" 3196 check_sae_capab(dev[0]) 3197 check_sae_capab(dev[1]) 3198 check_sae_capab(dev[2]) 3199 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 3200 params['wpa_key_mgmt'] = 'SAE SAE-EXT-KEY' 3201 params['sae_groups'] = "19 20" 3202 params['ieee80211w'] = '2' 3203 hapd = hostapd.add_ap(apdev[0], params) 3204 3205 dev[0].set("sae_groups", "20") 3206 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE-EXT-KEY", 3207 ieee80211w="2", scan_freq="2412") 3208 3209 dev[1].set("sae_groups", "20") 3210 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", 3211 ieee80211w="2", scan_freq="2412") 3212 3213 dev[2].set("sae_groups", "19") 3214 dev[2].connect("test-sae", psk="12345678", key_mgmt="SAE", 3215 ieee80211w="2", scan_freq="2412") 3216 3217def test_sae_ext_key_h2e_rejected_group(dev, apdev): 3218 """SAE-EXT-KEY, H2E, and rejected groups indication""" 3219 run_sae_ext_key_h2e_rejected_group(dev, apdev, "19", "20 19", "20") 3220 3221def test_sae_ext_key_h2e_rejected_group2(dev, apdev): 3222 """SAE-EXT-KEY, H2E, and rejected groups indication (2)""" 3223 run_sae_ext_key_h2e_rejected_group(dev, apdev, "20", "19 20", "19") 3224 3225def run_sae_ext_key_h2e_rejected_group(dev, apdev, ap_groups, sta_groups, 3226 rejected_groups): 3227 check_sae_capab(dev[0]) 3228 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 3229 params['wpa_key_mgmt'] = 'SAE-EXT-KEY' 3230 params['sae_groups'] = ap_groups 3231 params['sae_pwe'] = "1" 3232 params['ieee80211w'] = "2" 3233 hapd = hostapd.add_ap(apdev[0], params) 3234 try: 3235 dev[0].set("sae_groups", sta_groups) 3236 dev[0].set("sae_pwe", "1") 3237 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE-EXT-KEY", 3238 ieee80211w="2", scan_freq="2412") 3239 addr = dev[0].own_addr() 3240 hapd.wait_sta(addr) 3241 sta = hapd.get_sta(addr) 3242 if 'sae_rejected_groups' not in sta: 3243 raise Exception("No sae_rejected_groups") 3244 val = sta['sae_rejected_groups'] 3245 if val != rejected_groups: 3246 raise Exception("Unexpected sae_rejected_groups value: " + val) 3247 finally: 3248 dev[0].set("sae_groups", "") 3249 dev[0].set("sae_pwe", "0") 3250 3251def test_sae_pref_ap_wrong_password(dev, apdev): 3252 """SAE and preferred AP using wrong password""" 3253 check_sae_capab(dev[0]) 3254 3255 params = hostapd.wpa3_params(ssid="test-sae", password="correct") 3256 params['ieee80211n'] = '0' 3257 hapd = hostapd.add_ap(apdev[0], params) 3258 3259 params = hostapd.wpa3_params(ssid="test-sae", password="wrong") 3260 hapd2 = hostapd.add_ap(apdev[1], params) 3261 3262 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3263 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 3264 3265 dev[0].set("sae_groups", "") 3266 dev[0].connect("test-sae", sae_password="correct", key_mgmt="SAE", 3267 ieee80211w="2", scan_freq="2412") 3268 3269def test_sae_pref_ap_wrong_password2(dev, apdev): 3270 """SAE and preferred AP using wrong password (2)""" 3271 check_sae_capab(dev[0]) 3272 3273 params = hostapd.wpa3_params(ssid="test-sae", password="wrong") 3274 hapd2 = hostapd.add_ap(apdev[1], params) 3275 3276 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 3277 3278 dev[0].set("sae_groups", "") 3279 dev[0].connect("test-sae", sae_password="correct", key_mgmt="SAE", 3280 ieee80211w="2", scan_freq="2412", wait_connect=False) 3281 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=30) 3282 if ev is None: 3283 raise Exception("Temporary disabled of SSID not seen") 3284 3285 params = hostapd.wpa3_params(ssid="test-sae", password="correct") 3286 params['ieee80211n'] = '0' 3287 hapd = hostapd.add_ap(apdev[0], params) 3288 3289 dev[0].wait_connected(timeout=40) 3290 3291def test_sae_password_file(dev, apdev): 3292 """SAE and sae_password_file in hostapd configuration""" 3293 check_sae_capab(dev[0]) 3294 check_sae_capab(dev[1]) 3295 check_sae_capab(dev[2]) 3296 fd, fn = tempfile.mkstemp() 3297 try: 3298 f = os.fdopen(fd, 'w') 3299 f.write("pw1|id=id1\n") 3300 f.write("pw2|id=id2\n") 3301 f.write("pw3|id=id3\n") 3302 f.close() 3303 3304 params = hostapd.wpa2_params(ssid="test-sae", wpa_key_mgmt="SAE") 3305 params['sae_password_file'] = fn 3306 hapd = hostapd.add_ap(apdev[0], params) 3307 3308 dev[0].set("sae_groups", "") 3309 dev[0].connect("test-sae", sae_password="pw1", sae_password_id="id1", 3310 key_mgmt="SAE", scan_freq="2412") 3311 3312 dev[1].set("sae_groups", "") 3313 dev[1].connect("test-sae", sae_password="pw2", sae_password_id="id2", 3314 key_mgmt="SAE", scan_freq="2412") 3315 3316 dev[2].set("sae_groups", "") 3317 dev[2].connect("test-sae", sae_password="pw3", sae_password_id="id3", 3318 key_mgmt="SAE", scan_freq="2412") 3319 finally: 3320 os.unlink(fn) 3321 3322def test_sae_ssid_protection(dev, apdev): 3323 """SAE with SSID protection in 4-way handshake""" 3324 check_sae_capab(dev[0]) 3325 params = hostapd.wpa2_params(ssid="test-sae", 3326 passphrase="12345678") 3327 params['wpa_key_mgmt'] = 'SAE' 3328 params['ssid_protection'] = '1' 3329 hapd = hostapd.add_ap(apdev[0], params) 3330 3331 dev[0].set("sae_groups", "") 3332 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 3333 ssid_protection="1", 3334 scan_freq="2412", wait_connect=False) 3335 ev = dev[0].wait_event(["RSN: SSID matched expected value"], timeout=10) 3336 if ev is None: 3337 raise Exception("SSID protection event not seen") 3338 dev[0].wait_connected() 3339 hapd.wait_sta() 3340 3341 if dev[0].get_status_field("ssid_verified") != "1": 3342 raise Exception("ssid_verified=1 not in STATUS") 3343 3344def test_sae_eapol_key_reserved_random(dev, apdev): 3345 """SAE with EAPOL-Key Reserved field set to random value""" 3346 check_sae_capab(dev[0]) 3347 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 3348 params['wpa_key_mgmt'] = 'SAE' 3349 params['eapol_key_reserved_random'] = '1' 3350 hapd = hostapd.add_ap(apdev[0], params) 3351 3352 dev[0].set("sae_groups", "") 3353 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 3354 scan_freq="2412") 3355 3356def test_sae_eapol_key_2_reserved_key_info(dev, apdev): 3357 """SAE with EAPOL-Key msg 2/4 Key Info field reserved bits set""" 3358 check_sae_capab(dev[0]) 3359 params = hostapd.wpa3_params(ssid="test-sae", password="12345678") 3360 hapd = hostapd.add_ap(apdev[0], params) 3361 3362 dev[0].set("eapol_2_key_info_set_mask", "c000") 3363 dev[0].set("sae_groups", "") 3364 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2", 3365 scan_freq="2412") 3366 3367def test_sae_long_rsnxe(dev, apdev): 3368 """RSNXE extensibility""" 3369 check_sae_capab(dev[0]) 3370 3371 rsnxe = "F4FF2F0000000000000000000000000000FF" + 239*"EE" 3372 3373 params = hostapd.wpa3_params(ssid="sae-pwe", password="12345678") 3374 params['sae_pwe'] = "1" 3375 params['rsnxe_override'] = rsnxe 3376 hapd = hostapd.add_ap(apdev[0], params) 3377 3378 dev[0].set("sae_groups", "") 3379 dev[0].set("rsnxe_override_assoc", rsnxe) 3380 dev[0].set("rsnxe_override_eapol", rsnxe) 3381 try: 3382 dev[0].set("sae_pwe", "2") 3383 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 3384 scan_freq="2412", ieee80211w="2") 3385 if dev[0].get_status_field("sae_h2e") != "1": 3386 raise Exception("SAE H2E was not used") 3387 finally: 3388 dev[0].set("sae_groups", "") 3389 dev[0].set("sae_pwe", "0") 3390 3391def test_sae_dump_beacon(dev, apdev): 3392 """SAE and DUMP_BEACON""" 3393 check_sae_capab(dev[0]) 3394 params = hostapd.wpa3_params(ssid="test-sae", password="12345678") 3395 hapd = hostapd.add_ap(apdev[0], params) 3396 3397 dev[0].set("sae_groups", "") 3398 dev[0].connect("test-sae", sae_password="12345678", key_mgmt="SAE", 3399 ieee80211w="2", scan_freq="2412") 3400 hapd.wait_sta() 3401 res = hapd.request("DUMP_BEACON") 3402 if "FAIL" in res: 3403 raise Exception("DUMP_BEACON failed") 3404 logger.info("DUMP_BEACON: " + res) 3405 3406 # Make sure there is enough time to capture at least one Beacon frame 3407 time.sleep(0.2) 3408