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