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 26 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_init;sae_derive_pwe_ecc"), 1494 (1, "crypto_ec_point_solve_y_coord;sae_derive_pwe_ecc"), 1495 (1, "crypto_ec_point_init;sae_derive_commit_element_ecc"), 1496 (1, "crypto_ec_point_mul;sae_derive_commit_element_ecc"), 1497 (1, "crypto_ec_point_invert;sae_derive_commit_element_ecc"), 1498 (1, "crypto_bignum_init;=sae_derive_commit"), 1499 (1, "crypto_ec_point_init;sae_derive_k_ecc"), 1500 (1, "crypto_ec_point_mul;sae_derive_k_ecc"), 1501 (1, "crypto_ec_point_add;sae_derive_k_ecc"), 1502 (2, "crypto_ec_point_mul;sae_derive_k_ecc"), 1503 (1, "crypto_ec_point_to_bin;sae_derive_k_ecc"), 1504 (1, "crypto_bignum_legendre;dragonfly_get_random_qr_qnr"), 1505 (1, "sha256_prf;sae_derive_keys"), 1506 (1, "crypto_bignum_init;sae_derive_keys"), 1507 (1, "crypto_bignum_init_set;sae_parse_commit_scalar"), 1508 (1, "crypto_bignum_to_bin;sae_parse_commit_element_ecc"), 1509 (1, "crypto_ec_point_from_bin;sae_parse_commit_element_ecc")] 1510 for count, func in tests: 1511 with fail_test(dev[0], count, func): 1512 hapd.request("NOTE STA failure testing %d:%s" % (count, func)) 1513 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1514 scan_freq="2412", wait_connect=False) 1515 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1) 1516 dev[0].request("REMOVE_NETWORK all") 1517 dev[0].dump_monitor() 1518 hapd.dump_monitor() 1519 1520 dev[0].request("SET sae_groups 15") 1521 tests = [(1, "crypto_bignum_init_set;sae_set_group"), 1522 (2, "crypto_bignum_init_set;sae_set_group"), 1523 (1, "crypto_bignum_init;sae_derive_commit"), 1524 (2, "crypto_bignum_init;sae_derive_commit"), 1525 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"), 1526 (1, "crypto_bignum_exptmod;sae_test_pwd_seed_ffc"), 1527 (1, "crypto_bignum_init;sae_derive_pwe_ffc"), 1528 (1, "crypto_bignum_init;sae_derive_commit_element_ffc"), 1529 (1, "crypto_bignum_exptmod;sae_derive_commit_element_ffc"), 1530 (1, "crypto_bignum_inverse;sae_derive_commit_element_ffc"), 1531 (1, "crypto_bignum_init;sae_derive_k_ffc"), 1532 (1, "crypto_bignum_exptmod;sae_derive_k_ffc"), 1533 (1, "crypto_bignum_mulmod;sae_derive_k_ffc"), 1534 (2, "crypto_bignum_exptmod;sae_derive_k_ffc"), 1535 (1, "crypto_bignum_to_bin;sae_derive_k_ffc"), 1536 (1, "crypto_bignum_init_set;sae_parse_commit_element_ffc"), 1537 (1, "crypto_bignum_init;sae_parse_commit_element_ffc"), 1538 (2, "crypto_bignum_init_set;sae_parse_commit_element_ffc"), 1539 (1, "crypto_bignum_exptmod;sae_parse_commit_element_ffc")] 1540 for count, func in tests: 1541 with fail_test(dev[0], count, func): 1542 hapd.request("NOTE STA failure testing %d:%s" % (count, func)) 1543 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1544 scan_freq="2412", wait_connect=False) 1545 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1) 1546 dev[0].request("REMOVE_NETWORK all") 1547 dev[0].dump_monitor() 1548 hapd.dump_monitor() 1549 1550def test_sae_bignum_failure_unsafe_group(dev, apdev): 1551 """SAE and bignum failure unsafe group""" 1552 check_sae_capab(dev[0]) 1553 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1554 params['wpa_key_mgmt'] = 'SAE' 1555 params['sae_groups'] = '22' 1556 hapd = hostapd.add_ap(apdev[0], params) 1557 1558 dev[0].request("SET sae_groups 22") 1559 tests = [(1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"), 1560 (1, "crypto_bignum_sub;sae_test_pwd_seed_ffc"), 1561 (1, "crypto_bignum_div;sae_test_pwd_seed_ffc")] 1562 for count, func in tests: 1563 with fail_test(dev[0], count, func): 1564 hapd.request("NOTE STA failure testing %d:%s" % (count, func)) 1565 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1566 scan_freq="2412", wait_connect=False) 1567 wait_fail_trigger(dev[0], "GET_FAIL") 1568 dev[0].request("REMOVE_NETWORK all") 1569 dev[0].dump_monitor() 1570 hapd.dump_monitor() 1571 1572def test_sae_invalid_anti_clogging_token_req(dev, apdev): 1573 """SAE and invalid anti-clogging token request""" 1574 check_sae_capab(dev[0]) 1575 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1576 params['wpa_key_mgmt'] = 'SAE' 1577 # Beacon more frequently since Probe Request frames are practically ignored 1578 # in this test setup (ext_mgmt_frame_handled=1 on hostapd side) and 1579 # wpa_supplicant scans may end up getting ignored if no new results are 1580 # available due to the missing Probe Response frames. 1581 params['beacon_int'] = '20' 1582 hapd = hostapd.add_ap(apdev[0], params) 1583 bssid = apdev[0]['bssid'] 1584 1585 dev[0].request("SET sae_groups 19") 1586 dev[0].scan_for_bss(bssid, freq=2412) 1587 hapd.set("ext_mgmt_frame_handling", "1") 1588 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1589 scan_freq="2412", wait_connect=False) 1590 ev = dev[0].wait_event(["SME: Trying to authenticate"]) 1591 if ev is None: 1592 raise Exception("No authentication attempt seen (1)") 1593 dev[0].dump_monitor() 1594 1595 for i in range(0, 10): 1596 req = hapd.mgmt_rx() 1597 if req is None: 1598 raise Exception("MGMT RX wait timed out (commit)") 1599 if req['subtype'] == 11: 1600 break 1601 req = None 1602 if not req: 1603 raise Exception("Authentication frame (commit) not received") 1604 1605 hapd.dump_monitor() 1606 resp = {} 1607 resp['fc'] = req['fc'] 1608 resp['da'] = req['sa'] 1609 resp['sa'] = req['da'] 1610 resp['bssid'] = req['bssid'] 1611 resp['payload'] = binascii.unhexlify("030001004c0013") 1612 hapd.mgmt_tx(resp) 1613 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1614 if ev is None: 1615 raise Exception("Management frame TX status not reported (1)") 1616 if "stype=11 ok=1" not in ev: 1617 raise Exception("Unexpected management frame TX status (1): " + ev) 1618 1619 ev = dev[0].wait_event(["SME: Trying to authenticate"]) 1620 if ev is None: 1621 raise Exception("No authentication attempt seen (2)") 1622 dev[0].dump_monitor() 1623 1624 for i in range(0, 10): 1625 req = hapd.mgmt_rx() 1626 if req is None: 1627 raise Exception("MGMT RX wait timed out (commit) (2)") 1628 if req['subtype'] == 11: 1629 break 1630 req = None 1631 if not req: 1632 raise Exception("Authentication frame (commit) not received (2)") 1633 1634 hapd.dump_monitor() 1635 resp = {} 1636 resp['fc'] = req['fc'] 1637 resp['da'] = req['sa'] 1638 resp['sa'] = req['da'] 1639 resp['bssid'] = req['bssid'] 1640 resp['payload'] = binascii.unhexlify("030001000100") 1641 hapd.mgmt_tx(resp) 1642 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 1643 if ev is None: 1644 raise Exception("Management frame TX status not reported (1)") 1645 if "stype=11 ok=1" not in ev: 1646 raise Exception("Unexpected management frame TX status (1): " + ev) 1647 1648 ev = dev[0].wait_event(["SME: Trying to authenticate"]) 1649 if ev is None: 1650 raise Exception("No authentication attempt seen (3)") 1651 dev[0].dump_monitor() 1652 1653 dev[0].request("DISCONNECT") 1654 1655def test_sae_password(dev, apdev): 1656 """SAE and sae_password in hostapd configuration""" 1657 check_sae_capab(dev[0]) 1658 params = hostapd.wpa2_params(ssid="test-sae", 1659 passphrase="12345678") 1660 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 1661 params['sae_password'] = "sae-password" 1662 hapd = hostapd.add_ap(apdev[0], params) 1663 1664 dev[0].request("SET sae_groups ") 1665 dev[0].connect("test-sae", psk="sae-password", key_mgmt="SAE", 1666 scan_freq="2412") 1667 dev[1].connect("test-sae", psk="12345678", scan_freq="2412") 1668 dev[2].request("SET sae_groups ") 1669 dev[2].connect("test-sae", sae_password="sae-password", key_mgmt="SAE", 1670 scan_freq="2412") 1671 1672def test_sae_password_short(dev, apdev): 1673 """SAE and short password""" 1674 check_sae_capab(dev[0]) 1675 params = hostapd.wpa2_params(ssid="test-sae") 1676 params['wpa_key_mgmt'] = 'SAE' 1677 params['sae_password'] = "secret" 1678 hapd = hostapd.add_ap(apdev[0], params) 1679 1680 dev[0].request("SET sae_groups ") 1681 dev[0].connect("test-sae", sae_password="secret", key_mgmt="SAE", 1682 scan_freq="2412") 1683 1684def test_sae_password_long(dev, apdev): 1685 """SAE and long password""" 1686 check_sae_capab(dev[0]) 1687 params = hostapd.wpa2_params(ssid="test-sae") 1688 params['wpa_key_mgmt'] = 'SAE' 1689 params['sae_password'] = 100*"A" 1690 hapd = hostapd.add_ap(apdev[0], params) 1691 1692 dev[0].request("SET sae_groups ") 1693 dev[0].connect("test-sae", sae_password=100*"A", key_mgmt="SAE", 1694 scan_freq="2412") 1695 1696def test_sae_connect_cmd(dev, apdev): 1697 """SAE with connect command""" 1698 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 1699 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 1700 check_sae_capab(wpas) 1701 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1702 params['wpa_key_mgmt'] = 'SAE' 1703 hapd = hostapd.add_ap(apdev[0], params) 1704 1705 wpas.request("SET sae_groups ") 1706 wpas.connect("test-sae", psk="12345678", key_mgmt="SAE", 1707 scan_freq="2412", wait_connect=False) 1708 # mac80211_hwsim does not support SAE offload, so accept both a successful 1709 # connection and association rejection. 1710 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-ASSOC-REJECT", 1711 "Association request to the driver failed"], 1712 timeout=15) 1713 if ev is None: 1714 raise Exception("No connection result reported") 1715 1716def run_sae_password_id(dev, apdev, groups=None): 1717 check_sae_capab(dev[0]) 1718 params = hostapd.wpa2_params(ssid="test-sae") 1719 params['wpa_key_mgmt'] = 'SAE' 1720 if groups: 1721 params['sae_groups'] = groups 1722 else: 1723 groups = "" 1724 params['sae_password'] = ['secret|mac=ff:ff:ff:ff:ff:ff|id=pw id', 1725 'foo|mac=02:02:02:02:02:02', 1726 'another secret|mac=ff:ff:ff:ff:ff:ff|id=' + 29*'A'] 1727 hapd = hostapd.add_ap(apdev[0], params) 1728 1729 dev[0].request("SET sae_groups " + groups) 1730 dev[0].connect("test-sae", sae_password="secret", sae_password_id="pw id", 1731 key_mgmt="SAE", scan_freq="2412") 1732 dev[0].request("REMOVE_NETWORK all") 1733 dev[0].wait_disconnected() 1734 1735 # SAE Password Identifier element with the exact same length as the 1736 # optional Anti-Clogging Token field 1737 dev[0].connect("test-sae", sae_password="another secret", 1738 sae_password_id=29*'A', 1739 key_mgmt="SAE", scan_freq="2412") 1740 dev[0].request("REMOVE_NETWORK all") 1741 dev[0].wait_disconnected() 1742 1743 dev[0].connect("test-sae", sae_password="secret", sae_password_id="unknown", 1744 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 1745 1746 ev = dev[0].wait_event(["CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER"], 1747 timeout=10) 1748 if ev is None: 1749 raise Exception("Unknown password identifier not reported") 1750 dev[0].request("REMOVE_NETWORK all") 1751 1752def test_sae_password_id(dev, apdev): 1753 """SAE and password identifier""" 1754 run_sae_password_id(dev, apdev, "") 1755 1756def test_sae_password_id_ecc(dev, apdev): 1757 """SAE and password identifier (ECC)""" 1758 run_sae_password_id(dev, apdev, "19") 1759 1760def test_sae_password_id_ffc(dev, apdev): 1761 """SAE and password identifier (FFC)""" 1762 run_sae_password_id(dev, apdev, "15") 1763 1764def test_sae_password_id_only(dev, apdev): 1765 """SAE and password identifier (exclusively)""" 1766 check_sae_capab(dev[0]) 1767 params = hostapd.wpa2_params(ssid="test-sae") 1768 params['wpa_key_mgmt'] = 'SAE' 1769 params['sae_password'] = 'secret|id=pw id' 1770 hapd = hostapd.add_ap(apdev[0], params) 1771 1772 dev[0].request("SET sae_groups ") 1773 dev[0].connect("test-sae", sae_password="secret", sae_password_id="pw id", 1774 key_mgmt="SAE", scan_freq="2412") 1775 1776def test_sae_password_id_pwe_looping(dev, apdev): 1777 """SAE and password identifier with forced PWE looping""" 1778 check_sae_capab(dev[0]) 1779 params = hostapd.wpa2_params(ssid="test-sae") 1780 params['wpa_key_mgmt'] = 'SAE' 1781 params['sae_password'] = 'secret|id=pw id' 1782 params['sae_pwe'] = "3" 1783 hapd = hostapd.add_ap(apdev[0], params) 1784 1785 dev[0].request("SET sae_groups ") 1786 try: 1787 dev[0].set("sae_pwe", "3") 1788 dev[0].connect("test-sae", sae_password="secret", 1789 sae_password_id="pw id", 1790 key_mgmt="SAE", scan_freq="2412") 1791 finally: 1792 dev[0].set("sae_pwe", "0") 1793 1794def test_sae_password_id_pwe_check_ap(dev, apdev): 1795 """SAE and password identifier with STA using unexpected PWE derivation""" 1796 check_sae_capab(dev[0]) 1797 params = hostapd.wpa2_params(ssid="test-sae") 1798 params['wpa_key_mgmt'] = 'SAE' 1799 params['sae_password'] = 'secret|id=pw id' 1800 hapd = hostapd.add_ap(apdev[0], params) 1801 1802 dev[0].request("SET sae_groups ") 1803 try: 1804 dev[0].set("sae_pwe", "3") 1805 dev[0].connect("test-sae", sae_password="secret", 1806 sae_password_id="pw id", 1807 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 1808 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 1809 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10) 1810 if ev is None or "CTRL-EVENT-SSID-TEMP-DISABLED" not in ev: 1811 raise Exception("Connection failure not reported") 1812 finally: 1813 dev[0].set("sae_pwe", "0") 1814 1815def test_sae_password_id_pwe_check_sta(dev, apdev): 1816 """SAE and password identifier with AP using unexpected PWE derivation""" 1817 check_sae_capab(dev[0]) 1818 params = hostapd.wpa2_params(ssid="test-sae") 1819 params['wpa_key_mgmt'] = 'SAE' 1820 params['sae_pwe'] = "3" 1821 params['sae_password'] = 'secret|id=pw id' 1822 hapd = hostapd.add_ap(apdev[0], params) 1823 1824 dev[0].request("SET sae_groups ") 1825 dev[0].connect("test-sae", sae_password="secret", 1826 sae_password_id="pw id", 1827 key_mgmt="SAE", scan_freq="2412", wait_connect=False) 1828 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 1829 "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 1830 if ev is None or "CTRL-EVENT-NETWORK-NOT-FOUND" not in ev: 1831 raise Exception("Connection failure not reported") 1832 1833def test_sae_forced_anti_clogging_pw_id(dev, apdev): 1834 """SAE anti clogging (forced and Password Identifier)""" 1835 check_sae_capab(dev[0]) 1836 params = hostapd.wpa2_params(ssid="test-sae") 1837 params['wpa_key_mgmt'] = 'SAE' 1838 params['sae_anti_clogging_threshold'] = '0' 1839 params['sae_password'] = 'secret|id=' + 29*'A' 1840 hostapd.add_ap(apdev[0], params) 1841 for i in range(0, 2): 1842 dev[i].request("SET sae_groups ") 1843 dev[i].connect("test-sae", sae_password="secret", 1844 sae_password_id=29*'A', key_mgmt="SAE", scan_freq="2412") 1845 1846def test_sae_reauth(dev, apdev): 1847 """SAE reauthentication""" 1848 check_sae_capab(dev[0]) 1849 params = hostapd.wpa2_params(ssid="test-sae", 1850 passphrase="12345678") 1851 params['wpa_key_mgmt'] = 'SAE' 1852 params["ieee80211w"] = "2" 1853 hapd = hostapd.add_ap(apdev[0], params) 1854 1855 dev[0].request("SET sae_groups ") 1856 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1857 ieee80211w="2", scan_freq="2412") 1858 1859 hapd.set("ext_mgmt_frame_handling", "1") 1860 dev[0].request("DISCONNECT") 1861 dev[0].wait_disconnected(timeout=10) 1862 hapd.set("ext_mgmt_frame_handling", "0") 1863 dev[0].request("PMKSA_FLUSH") 1864 dev[0].request("REASSOCIATE") 1865 dev[0].wait_connected(timeout=10, error="Timeout on re-connection") 1866 1867def test_sae_anti_clogging_during_attack(dev, apdev): 1868 """SAE anti clogging during an attack""" 1869 try: 1870 run_sae_anti_clogging_during_attack(dev, apdev) 1871 finally: 1872 stop_monitor(apdev[1]["ifname"]) 1873 1874def build_sae_commit(bssid, addr, group=21, token=None): 1875 if group == 19: 1876 scalar = binascii.unhexlify("7332d3ebff24804005ccd8c56141e3ed8d84f40638aa31cd2fac11d4d2e89e7b") 1877 element = binascii.unhexlify("954d0f4457066bff3168376a1d7174f4e66620d1792406f613055b98513a7f03a538c13dfbaf2029e2adc6aa96aa0ddcf08ac44887b02f004b7f29b9dbf4b7d9") 1878 elif group == 21: 1879 scalar = binascii.unhexlify("001eec673111b902f5c8a61c8cb4c1c4793031aeea8c8c319410903bc64bcbaea134ab01c4e016d51436f5b5426f7e2af635759a3033fb4031ea79f89a62a3e2f828") 1880 element = binascii.unhexlify("00580eb4b448ea600ea277d5e66e4ed37db82bb04ac90442e9c3727489f366ba4b82f0a472d02caf4cdd142e96baea5915d71374660ee23acbaca38cf3fe8c5fb94b01abbc5278121635d7c06911c5dad8f18d516e1fbe296c179b7c87a1dddfab393337d3d215ed333dd396da6d8f20f798c60d054f1093c24d9c2d98e15c030cc375f0") 1881 pass 1882 frame = binascii.unhexlify("b0003a01") 1883 frame += bssid + addr + bssid 1884 frame += binascii.unhexlify("1000") 1885 auth_alg = 3 1886 transact = 1 1887 status = 0 1888 frame += struct.pack("<HHHH", auth_alg, transact, status, group) 1889 if token: 1890 frame += token 1891 frame += scalar + element 1892 return frame 1893 1894def sae_rx_commit_token_req(sock, radiotap, send_two=False): 1895 msg = sock.recv(1500) 1896 ver, pad, length, present = struct.unpack('<BBHL', msg[0:8]) 1897 frame = msg[length:] 1898 if len(frame) < 4: 1899 return False 1900 fc, duration = struct.unpack('<HH', frame[0:4]) 1901 if fc != 0xb0: 1902 return False 1903 frame = frame[4:] 1904 da = frame[0:6] 1905 if da[0] != 0xf2: 1906 return False 1907 sa = frame[6:12] 1908 bssid = frame[12:18] 1909 body = frame[20:] 1910 1911 alg, seq, status, group = struct.unpack('<HHHH', body[0:8]) 1912 if alg != 3 or seq != 1 or status != 76: 1913 return False 1914 token = body[8:] 1915 1916 frame = build_sae_commit(bssid, da, token=token) 1917 sock.send(radiotap + frame) 1918 if send_two: 1919 sock.send(radiotap + frame) 1920 return True 1921 1922def run_sae_anti_clogging_during_attack(dev, apdev): 1923 check_sae_capab(dev[0]) 1924 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 1925 params['wpa_key_mgmt'] = 'SAE' 1926 params['sae_groups'] = '21' 1927 hapd = hostapd.add_ap(apdev[0], params) 1928 1929 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1930 dev[0].request("SET sae_groups 21") 1931 dev[1].scan_for_bss(hapd.own_addr(), freq=2412) 1932 dev[1].request("SET sae_groups 21") 1933 1934 sock = start_monitor(apdev[1]["ifname"]) 1935 radiotap = radiotap_build() 1936 1937 bssid = binascii.unhexlify(hapd.own_addr().replace(':', '')) 1938 for i in range(16): 1939 addr = binascii.unhexlify("f2%010x" % i) 1940 frame = build_sae_commit(bssid, addr) 1941 sock.send(radiotap + frame) 1942 sock.send(radiotap + frame) 1943 1944 count = 0 1945 for i in range(150): 1946 if sae_rx_commit_token_req(sock, radiotap, send_two=True): 1947 count += 1 1948 logger.info("Number of token responses sent: %d" % count) 1949 if count < 10: 1950 raise Exception("Too few token responses seen: %d" % count) 1951 1952 for i in range(16): 1953 addr = binascii.unhexlify("f201%08x" % i) 1954 frame = build_sae_commit(bssid, addr) 1955 sock.send(radiotap + frame) 1956 1957 count = 0 1958 for i in range(150): 1959 if sae_rx_commit_token_req(sock, radiotap): 1960 count += 1 1961 if count == 10: 1962 break 1963 if count < 5: 1964 raise Exception("Too few token responses in second round: %d" % count) 1965 1966 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 1967 scan_freq="2412", wait_connect=False) 1968 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", 1969 scan_freq="2412", wait_connect=False) 1970 1971 count = 0 1972 connected0 = False 1973 connected1 = False 1974 for i in range(1000): 1975 if sae_rx_commit_token_req(sock, radiotap): 1976 count += 1 1977 addr = binascii.unhexlify("f202%08x" % i) 1978 frame = build_sae_commit(bssid, addr) 1979 sock.send(radiotap + frame) 1980 while dev[0].mon.pending(): 1981 ev = dev[0].mon.recv() 1982 logger.debug("EV0: " + ev) 1983 if "CTRL-EVENT-CONNECTED" in ev: 1984 connected0 = True 1985 while dev[1].mon.pending(): 1986 ev = dev[1].mon.recv() 1987 logger.debug("EV1: " + ev) 1988 if "CTRL-EVENT-CONNECTED" in ev: 1989 connected1 = True 1990 if connected0 and connected1: 1991 break 1992 time.sleep(0.00000001) 1993 if not connected0: 1994 raise Exception("Real station(0) did not get connected") 1995 if not connected1: 1996 raise Exception("Real station(1) did not get connected") 1997 if count < 1: 1998 raise Exception("Too few token responses in third round: %d" % count) 1999 2000def test_sae_sync(dev, apdev): 2001 """SAE dot11RSNASAESync""" 2002 check_sae_capab(dev[0]) 2003 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2004 params['wpa_key_mgmt'] = 'SAE' 2005 params['sae_sync'] = '1' 2006 hostapd.add_ap(apdev[0], params) 2007 2008 # TODO: More complete dot11RSNASAESync testing. For now, this is really only 2009 # checking that sae_sync config parameter is accepted. 2010 dev[0].request("SET sae_groups ") 2011 dev[1].request("SET sae_groups ") 2012 id = {} 2013 for i in range(0, 2): 2014 dev[i].scan(freq="2412") 2015 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 2016 scan_freq="2412", only_add_network=True) 2017 for i in range(0, 2): 2018 dev[i].select_network(id[i]) 2019 for i in range(0, 2): 2020 dev[i].wait_connected(timeout=10) 2021 2022def test_sae_confirm_immediate(dev, apdev): 2023 """SAE and AP sending Confirm message without waiting STA""" 2024 check_sae_capab(dev[0]) 2025 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2026 params['wpa_key_mgmt'] = 'SAE' 2027 params['sae_confirm_immediate'] = '1' 2028 hapd = hostapd.add_ap(apdev[0], params) 2029 2030 dev[0].request("SET sae_groups ") 2031 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412") 2032 2033def test_sae_confirm_immediate2(dev, apdev): 2034 """SAE and AP sending Confirm message without waiting STA (2)""" 2035 check_sae_capab(dev[0]) 2036 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2037 params['wpa_key_mgmt'] = 'SAE' 2038 params['sae_confirm_immediate'] = '2' 2039 hapd = hostapd.add_ap(apdev[0], params) 2040 2041 dev[0].request("SET sae_groups ") 2042 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412") 2043 2044def test_sae_pwe_group_19(dev, apdev): 2045 """SAE PWE derivation options with group 19""" 2046 run_sae_pwe_group(dev, apdev, 19) 2047 2048def test_sae_pwe_group_20(dev, apdev): 2049 """SAE PWE derivation options with group 20""" 2050 run_sae_pwe_group(dev, apdev, 20) 2051 2052def test_sae_pwe_group_21(dev, apdev): 2053 """SAE PWE derivation options with group 21""" 2054 run_sae_pwe_group(dev, apdev, 21) 2055 2056def test_sae_pwe_group_25(dev, apdev): 2057 """SAE PWE derivation options with group 25""" 2058 run_sae_pwe_group(dev, apdev, 25) 2059 2060def test_sae_pwe_group_28(dev, apdev): 2061 """SAE PWE derivation options with group 28""" 2062 run_sae_pwe_group(dev, apdev, 28) 2063 2064def test_sae_pwe_group_29(dev, apdev): 2065 """SAE PWE derivation options with group 29""" 2066 run_sae_pwe_group(dev, apdev, 29) 2067 2068def test_sae_pwe_group_30(dev, apdev): 2069 """SAE PWE derivation options with group 30""" 2070 run_sae_pwe_group(dev, apdev, 30) 2071 2072def test_sae_pwe_group_1(dev, apdev): 2073 """SAE PWE derivation options with group 1""" 2074 run_sae_pwe_group(dev, apdev, 1) 2075 2076def test_sae_pwe_group_2(dev, apdev): 2077 """SAE PWE derivation options with group 2""" 2078 run_sae_pwe_group(dev, apdev, 2) 2079 2080def test_sae_pwe_group_5(dev, apdev): 2081 """SAE PWE derivation options with group 5""" 2082 run_sae_pwe_group(dev, apdev, 5) 2083 2084def test_sae_pwe_group_14(dev, apdev): 2085 """SAE PWE derivation options with group 14""" 2086 run_sae_pwe_group(dev, apdev, 14) 2087 2088def test_sae_pwe_group_15(dev, apdev): 2089 """SAE PWE derivation options with group 15""" 2090 run_sae_pwe_group(dev, apdev, 15) 2091 2092def test_sae_pwe_group_16(dev, apdev): 2093 """SAE PWE derivation options with group 16""" 2094 run_sae_pwe_group(dev, apdev, 16) 2095 2096def test_sae_pwe_group_22(dev, apdev): 2097 """SAE PWE derivation options with group 22""" 2098 run_sae_pwe_group(dev, apdev, 22) 2099 2100def test_sae_pwe_group_23(dev, apdev): 2101 """SAE PWE derivation options with group 23""" 2102 run_sae_pwe_group(dev, apdev, 23) 2103 2104def test_sae_pwe_group_24(dev, apdev): 2105 """SAE PWE derivation options with group 24""" 2106 run_sae_pwe_group(dev, apdev, 24) 2107 2108def start_sae_pwe_ap(apdev, group, sae_pwe): 2109 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2110 params['wpa_key_mgmt'] = 'SAE' 2111 params['sae_groups'] = str(group) 2112 params['sae_pwe'] = str(sae_pwe) 2113 return hostapd.add_ap(apdev, params) 2114 2115def run_sae_pwe_group(dev, apdev, group): 2116 check_sae_capab(dev[0]) 2117 tls = dev[0].request("GET tls_library") 2118 if group in [27, 28, 29, 30]: 2119 if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls: 2120 logger.info("Add Brainpool EC groups since OpenSSL is new enough") 2121 else: 2122 raise HwsimSkip("Brainpool curve not supported") 2123 start_sae_pwe_ap(apdev[0], group, 2) 2124 try: 2125 check_sae_pwe_group(dev[0], group, 0) 2126 check_sae_pwe_group(dev[0], group, 1) 2127 check_sae_pwe_group(dev[0], group, 2) 2128 finally: 2129 dev[0].set("sae_groups", "") 2130 dev[0].set("sae_pwe", "0") 2131 2132def check_sae_pwe_group(dev, group, sae_pwe): 2133 dev.set("sae_groups", str(group)) 2134 dev.set("sae_pwe", str(sae_pwe)) 2135 dev.connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412") 2136 dev.request("REMOVE_NETWORK all") 2137 dev.wait_disconnected() 2138 dev.dump_monitor() 2139 2140def test_sae_pwe_h2e_only_ap(dev, apdev): 2141 """SAE PWE derivation with H2E-only AP""" 2142 check_sae_capab(dev[0]) 2143 start_sae_pwe_ap(apdev[0], 19, 1) 2144 try: 2145 check_sae_pwe_group(dev[0], 19, 1) 2146 check_sae_pwe_group(dev[0], 19, 2) 2147 finally: 2148 dev[0].set("sae_groups", "") 2149 dev[0].set("sae_pwe", "0") 2150 2151 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412", 2152 wait_connect=False) 2153 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 2154 if ev is None: 2155 raise Exception("No indication of mismatching network seen") 2156 2157def test_sae_pwe_h2e_only_ap_sta_forcing_loop(dev, apdev): 2158 """SAE PWE derivation with H2E-only AP and STA forcing loop""" 2159 check_sae_capab(dev[0]) 2160 start_sae_pwe_ap(apdev[0], 19, 1) 2161 dev[0].set("ignore_sae_h2e_only", "1") 2162 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412", 2163 wait_connect=False) 2164 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10) 2165 dev[0].request("DISCONNECT") 2166 if ev is None: 2167 raise Exception("No indication of temporary disabled network seen") 2168 2169def test_sae_pwe_loop_only_ap(dev, apdev): 2170 """SAE PWE derivation with loop-only AP""" 2171 check_sae_capab(dev[0]) 2172 start_sae_pwe_ap(apdev[0], 19, 0) 2173 try: 2174 check_sae_pwe_group(dev[0], 19, 0) 2175 check_sae_pwe_group(dev[0], 19, 2) 2176 dev[0].set("sae_pwe", "1") 2177 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2178 scan_freq="2412", wait_connect=False) 2179 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 2180 if ev is None: 2181 raise Exception("No indication of mismatching network seen") 2182 finally: 2183 dev[0].set("sae_groups", "") 2184 dev[0].set("sae_pwe", "0") 2185 2186def test_sae_h2e_rejected_groups(dev, apdev): 2187 """SAE H2E and rejected groups indication""" 2188 check_sae_capab(dev[0]) 2189 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2190 params['wpa_key_mgmt'] = 'SAE' 2191 params['sae_groups'] = "19" 2192 params['sae_pwe'] = "1" 2193 hapd = hostapd.add_ap(apdev[0], params) 2194 try: 2195 dev[0].set("sae_groups", "21 20 19") 2196 dev[0].set("sae_pwe", "1") 2197 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2198 scan_freq="2412") 2199 addr = dev[0].own_addr() 2200 hapd.wait_sta(addr) 2201 sta = hapd.get_sta(addr) 2202 if 'sae_rejected_groups' not in sta: 2203 raise Exception("No sae_rejected_groups") 2204 val = sta['sae_rejected_groups'] 2205 if val != "21 20": 2206 raise Exception("Unexpected sae_rejected_groups value: " + val) 2207 finally: 2208 dev[0].set("sae_groups", "") 2209 dev[0].set("sae_pwe", "0") 2210 2211def test_sae_h2e_rejected_groups_unexpected(dev, apdev): 2212 """SAE H2E and rejected groups indication (unexpected group)""" 2213 check_sae_capab(dev[0]) 2214 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2215 params['wpa_key_mgmt'] = 'SAE' 2216 params['sae_groups'] = "19 20" 2217 params['sae_pwe'] = "1" 2218 hapd = hostapd.add_ap(apdev[0], params) 2219 try: 2220 dev[0].set("sae_groups", "21 19") 2221 dev[0].set("extra_sae_rejected_groups", "19") 2222 dev[0].set("sae_pwe", "1") 2223 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2224 scan_freq="2412", wait_connect=False) 2225 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2226 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10) 2227 dev[0].request("DISCONNECT") 2228 if ev is None: 2229 raise Exception("No indication of temporary disabled network seen") 2230 if "CTRL-EVENT-CONNECTED" in ev: 2231 raise Exception("Unexpected connection") 2232 finally: 2233 dev[0].set("sae_groups", "") 2234 dev[0].set("sae_pwe", "0") 2235 2236def test_sae_h2e_password_id(dev, apdev): 2237 """SAE H2E and password identifier""" 2238 check_sae_capab(dev[0]) 2239 params = hostapd.wpa2_params(ssid="test-sae") 2240 params['wpa_key_mgmt'] = 'SAE' 2241 params['sae_pwe'] = '1' 2242 params['sae_password'] = 'secret|id=pw id' 2243 hapd = hostapd.add_ap(apdev[0], params) 2244 2245 try: 2246 dev[0].request("SET sae_groups ") 2247 dev[0].set("sae_pwe", "1") 2248 dev[0].connect("test-sae", sae_password="secret", 2249 sae_password_id="pw id", 2250 key_mgmt="SAE", scan_freq="2412") 2251 finally: 2252 dev[0].set("sae_groups", "") 2253 dev[0].set("sae_pwe", "0") 2254 2255def test_sae_pwe_in_psk_ap(dev, apdev): 2256 """sae_pwe parameter in PSK-only-AP""" 2257 params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678") 2258 params['sae_pwe'] = '1' 2259 hapd = hostapd.add_ap(apdev[0], params) 2260 2261 dev[0].connect("test-psk", psk="12345678", scan_freq="2412") 2262 2263def test_sae_auth_restart(dev, apdev): 2264 """SAE and authentication restarts with H2E/looping""" 2265 check_sae_capab(dev[0]) 2266 params = hostapd.wpa2_params(ssid="test-sae") 2267 params['wpa_key_mgmt'] = 'SAE' 2268 params['sae_pwe'] = '2' 2269 params['sae_password'] = 'secret|id=pw id' 2270 hapd = hostapd.add_ap(apdev[0], params) 2271 2272 try: 2273 dev[0].request("SET sae_groups ") 2274 for pwe in [1, 0, 1]: 2275 dev[0].set("sae_pwe", str(pwe)) 2276 dev[0].connect("test-sae", sae_password="secret", 2277 sae_password_id="pw id", 2278 key_mgmt="SAE", scan_freq="2412") 2279 # Disconnect without hostapd removing the STA entry so that the 2280 # following SAE authentication instance starts with an existing 2281 # STA entry that has maintained some SAE state. 2282 hapd.set("ext_mgmt_frame_handling", "1") 2283 dev[0].request("REMOVE_NETWORK all") 2284 req = hapd.mgmt_rx() 2285 dev[0].wait_disconnected() 2286 dev[0].dump_monitor() 2287 hapd.set("ext_mgmt_frame_handling", "0") 2288 finally: 2289 dev[0].set("sae_groups", "") 2290 dev[0].set("sae_pwe", "0") 2291 2292def test_sae_rsne_mismatch(dev, apdev): 2293 """SAE and RSNE mismatch in EAPOL-Key msg 2/4""" 2294 check_sae_capab(dev[0]) 2295 dev[0].set("sae_groups", "") 2296 2297 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2298 params['wpa_key_mgmt'] = 'SAE' 2299 hapd = hostapd.add_ap(apdev[0], params) 2300 2301 # First, test with matching RSNE to confirm testing capability 2302 dev[0].set("rsne_override_eapol", 2303 "30140100000fac040100000fac040100000fac080000") 2304 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2305 scan_freq="2412") 2306 dev[0].request("REMOVE_NETWORK all") 2307 dev[0].wait_disconnected() 2308 dev[0].dump_monitor() 2309 2310 # Then, test with modified RSNE 2311 tests = ["30140100000fac040100000fac040100000fac080010", "0000"] 2312 for ie in tests: 2313 dev[0].set("rsne_override_eapol", ie) 2314 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2315 scan_freq="2412", wait_connect=False) 2316 ev = dev[0].wait_event(["Associated with"], timeout=10) 2317 if ev is None: 2318 raise Exception("No indication of association seen") 2319 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2320 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2321 dev[0].request("REMOVE_NETWORK all") 2322 if ev is None: 2323 raise Exception("No disconnection seen") 2324 if "CTRL-EVENT-DISCONNECTED" not in ev: 2325 raise Exception("Unexpected connection") 2326 dev[0].dump_monitor() 2327 2328def test_sae_h2e_rsnxe_mismatch(dev, apdev): 2329 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4""" 2330 check_sae_capab(dev[0]) 2331 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2332 params['wpa_key_mgmt'] = 'SAE' 2333 params['sae_pwe'] = "1" 2334 hapd = hostapd.add_ap(apdev[0], params) 2335 try: 2336 dev[0].set("sae_groups", "19") 2337 dev[0].set("sae_pwe", "1") 2338 for rsnxe in ["F40100", "F400", ""]: 2339 dev[0].set("rsnxe_override_eapol", rsnxe) 2340 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2341 scan_freq="2412", wait_connect=False) 2342 ev = dev[0].wait_event(["Associated with"], timeout=10) 2343 if ev is None: 2344 raise Exception("No indication of association seen") 2345 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2346 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2347 dev[0].request("REMOVE_NETWORK all") 2348 if ev is None: 2349 raise Exception("No disconnection seen") 2350 if "CTRL-EVENT-DISCONNECTED" not in ev: 2351 raise Exception("Unexpected connection") 2352 dev[0].dump_monitor() 2353 finally: 2354 dev[0].set("sae_groups", "") 2355 dev[0].set("sae_pwe", "0") 2356 2357def test_sae_h2e_rsnxe_mismatch_retries(dev, apdev): 2358 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 retries""" 2359 check_sae_capab(dev[0]) 2360 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2361 params['wpa_key_mgmt'] = 'SAE' 2362 params['sae_pwe'] = "1" 2363 hapd = hostapd.add_ap(apdev[0], params) 2364 try: 2365 dev[0].set("sae_groups", "19") 2366 dev[0].set("sae_pwe", "1") 2367 rsnxe = "F40100" 2368 dev[0].set("rsnxe_override_eapol", rsnxe) 2369 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2370 scan_freq="2412", wait_connect=False) 2371 ev = dev[0].wait_event(["Associated with"], timeout=10) 2372 if ev is None: 2373 raise Exception("No indication of association seen") 2374 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2375 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2376 if ev is None: 2377 raise Exception("No disconnection seen") 2378 if "CTRL-EVENT-DISCONNECTED" not in ev: 2379 raise Exception("Unexpected connection") 2380 2381 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2382 "CTRL-EVENT-DISCONNECTED"], timeout=10) 2383 if ev is None: 2384 raise Exception("No disconnection seen (2)") 2385 if "CTRL-EVENT-DISCONNECTED" not in ev: 2386 raise Exception("Unexpected connection (2)") 2387 2388 dev[0].dump_monitor() 2389 finally: 2390 dev[0].set("sae_groups", "") 2391 dev[0].set("sae_pwe", "0") 2392 2393def test_sae_h2e_rsnxe_mismatch_assoc(dev, apdev): 2394 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 (assoc)""" 2395 check_sae_capab(dev[0]) 2396 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2397 params['wpa_key_mgmt'] = 'SAE' 2398 params['sae_pwe'] = "1" 2399 hapd = hostapd.add_ap(apdev[0], params) 2400 try: 2401 dev[0].set("sae_groups", "19") 2402 dev[0].set("sae_pwe", "1") 2403 for rsnxe in ["F40100", "F400", ""]: 2404 dev[0].set("rsnxe_override_assoc", rsnxe) 2405 dev[0].set("rsnxe_override_eapol", "F40120") 2406 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2407 scan_freq="2412", wait_connect=False) 2408 ev = dev[0].wait_event(["Associated with"], timeout=10) 2409 if ev is None: 2410 raise Exception("No indication of association seen") 2411 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2412 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2413 dev[0].request("REMOVE_NETWORK all") 2414 if ev is None: 2415 raise Exception("No disconnection seen") 2416 if "CTRL-EVENT-DISCONNECTED" not in ev: 2417 raise Exception("Unexpected connection") 2418 dev[0].dump_monitor() 2419 finally: 2420 dev[0].set("sae_groups", "") 2421 dev[0].set("sae_pwe", "0") 2422 2423def test_sae_h2e_rsnxe_mismatch_ap(dev, apdev): 2424 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4""" 2425 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F40100") 2426 2427def test_sae_h2e_rsnxe_mismatch_ap2(dev, apdev): 2428 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4""" 2429 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F400") 2430 2431def test_sae_h2e_rsnxe_mismatch_ap3(dev, apdev): 2432 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4""" 2433 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "") 2434 2435def run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, rsnxe): 2436 check_sae_capab(dev[0]) 2437 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678") 2438 params['wpa_key_mgmt'] = 'SAE' 2439 params['sae_pwe'] = "1" 2440 params['rsnxe_override_eapol'] = rsnxe 2441 hapd = hostapd.add_ap(apdev[0], params) 2442 try: 2443 dev[0].set("sae_groups", "19") 2444 dev[0].set("sae_pwe", "1") 2445 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", 2446 scan_freq="2412", wait_connect=False) 2447 ev = dev[0].wait_event(["Associated with"], timeout=10) 2448 if ev is None: 2449 raise Exception("No indication of association seen") 2450 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2451 "CTRL-EVENT-DISCONNECTED"], timeout=5) 2452 dev[0].request("REMOVE_NETWORK all") 2453 if ev is None: 2454 raise Exception("No disconnection seen") 2455 if "CTRL-EVENT-DISCONNECTED" not in ev: 2456 raise Exception("Unexpected connection") 2457 finally: 2458 dev[0].set("sae_groups", "") 2459 dev[0].set("sae_pwe", "0") 2460 2461def test_sae_forced_anti_clogging_h2e(dev, apdev): 2462 """SAE anti clogging (forced, H2E)""" 2463 check_sae_capab(dev[0]) 2464 check_sae_capab(dev[1]) 2465 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2466 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 2467 params['sae_pwe'] = "1" 2468 params['sae_anti_clogging_threshold'] = '0' 2469 hostapd.add_ap(apdev[0], params) 2470 dev[2].connect("test-sae", psk="12345678", scan_freq="2412") 2471 try: 2472 for i in range(2): 2473 dev[i].request("SET sae_groups ") 2474 dev[i].set("sae_pwe", "1") 2475 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 2476 scan_freq="2412") 2477 finally: 2478 for i in range(2): 2479 dev[i].set("sae_pwe", "0") 2480 2481def test_sae_forced_anti_clogging_h2e_loop(dev, apdev): 2482 """SAE anti clogging (forced, H2E + loop)""" 2483 check_sae_capab(dev[0]) 2484 check_sae_capab(dev[1]) 2485 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2486 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 2487 params['sae_pwe'] = "2" 2488 params['sae_anti_clogging_threshold'] = '0' 2489 hostapd.add_ap(apdev[0], params) 2490 dev[2].connect("test-sae", psk="12345678", scan_freq="2412") 2491 try: 2492 for i in range(2): 2493 dev[i].request("SET sae_groups ") 2494 dev[i].set("sae_pwe", "2") 2495 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE", 2496 scan_freq="2412") 2497 finally: 2498 for i in range(2): 2499 dev[i].set("sae_pwe", "0") 2500 2501def test_sae_okc(dev, apdev): 2502 """SAE and opportunistic key caching""" 2503 check_sae_capab(dev[0]) 2504 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2505 params['wpa_key_mgmt'] = 'SAE' 2506 params['okc'] = '1' 2507 hapd = hostapd.add_ap(apdev[0], params) 2508 bssid = hapd.own_addr() 2509 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].set("sae_groups", "") 2543 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2544 okc=True, scan_freq="2412") 2545 dev[0].dump_monitor() 2546 hapd.wait_sta() 2547 if "sae_group" not in dev[0].get_status(): 2548 raise Exception("SAE authentication not used") 2549 2550 hapd2 = hostapd.add_ap(apdev[1], params) 2551 bssid2 = hapd2.own_addr() 2552 2553 dev[0].scan_for_bss(bssid2, freq=2412) 2554 dev[0].roam(bssid2, assoc_reject_ok=True) 2555 dev[0].dump_monitor() 2556 hapd2.wait_sta() 2557 if "sae_group" not in dev[0].get_status(): 2558 raise Exception("SAE authentication not used during roam to AP2") 2559 2560def test_sae_okc_pmk_lifetime(dev, apdev): 2561 """SAE and opportunistic key caching and PMK lifetime""" 2562 check_sae_capab(dev[0]) 2563 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2564 params['wpa_key_mgmt'] = 'SAE' 2565 params['okc'] = '1' 2566 hapd = hostapd.add_ap(apdev[0], params) 2567 bssid = hapd.own_addr() 2568 2569 dev[0].set("sae_groups", "") 2570 dev[0].set("dot11RSNAConfigPMKLifetime", "10") 2571 dev[0].set("dot11RSNAConfigPMKReauthThreshold", "30") 2572 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2573 okc=True, scan_freq="2412") 2574 dev[0].dump_monitor() 2575 hapd.wait_sta() 2576 if "sae_group" not in dev[0].get_status(): 2577 raise Exception("SAE authentication not used") 2578 2579 hapd2 = hostapd.add_ap(apdev[1], params) 2580 bssid2 = hapd2.own_addr() 2581 2582 time.sleep(5) 2583 dev[0].scan_for_bss(bssid2, freq=2412) 2584 dev[0].roam(bssid2) 2585 dev[0].dump_monitor() 2586 hapd2.wait_sta() 2587 if "sae_group" not in dev[0].get_status(): 2588 raise Exception("SAE authentication not used during roam to AP2 after reauth threshold") 2589 2590def test_sae_pmk_lifetime(dev, apdev): 2591 """SAE and PMK lifetime""" 2592 check_sae_capab(dev[0]) 2593 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2594 params['wpa_key_mgmt'] = 'SAE' 2595 hapd = hostapd.add_ap(apdev[0], params) 2596 bssid = hapd.own_addr() 2597 2598 dev[0].set("sae_groups", "") 2599 dev[0].set("dot11RSNAConfigPMKLifetime", "10") 2600 dev[0].set("dot11RSNAConfigPMKReauthThreshold", "50") 2601 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2602 scan_freq="2412") 2603 dev[0].dump_monitor() 2604 hapd.wait_sta() 2605 if "sae_group" not in dev[0].get_status(): 2606 raise Exception("SAE authentication not used") 2607 2608 hapd2 = hostapd.add_ap(apdev[1], params) 2609 bssid2 = hapd2.own_addr() 2610 2611 dev[0].scan_for_bss(bssid2, freq=2412) 2612 dev[0].roam(bssid2) 2613 dev[0].dump_monitor() 2614 hapd2.wait_sta() 2615 if "sae_group" not in dev[0].get_status(): 2616 raise Exception("SAE authentication not used during roam to AP2") 2617 2618 dev[0].roam(bssid) 2619 dev[0].dump_monitor() 2620 hapd.wait_sta() 2621 if "sae_group" in dev[0].get_status(): 2622 raise Exception("SAE authentication used during roam to AP1") 2623 2624 time.sleep(6) 2625 dev[0].scan_for_bss(bssid2, freq=2412) 2626 dev[0].roam(bssid2) 2627 dev[0].dump_monitor() 2628 hapd2.wait_sta() 2629 if "sae_group" not in dev[0].get_status(): 2630 raise Exception("SAE authentication not used during roam to AP2 after reauth threshold") 2631 2632 ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], 11) 2633 if ev is None: 2634 raise Exception("PMKSA cache entry did not expire") 2635 if bssid2 in ev: 2636 raise Exception("Unexpected expiration of the current SAE PMKSA cache entry") 2637 2638def test_sae_and_psk_multiple_passwords(dev, apdev, params): 2639 """SAE and PSK with multiple passwords/passphrases""" 2640 check_sae_capab(dev[0]) 2641 check_sae_capab(dev[1]) 2642 addr0 = dev[0].own_addr() 2643 addr1 = dev[1].own_addr() 2644 psk_file = os.path.join(params['logdir'], 2645 'sae_and_psk_multiple_passwords.wpa_psk') 2646 with open(psk_file, 'w') as f: 2647 f.write(addr0 + ' passphrase0\n') 2648 f.write(addr1 + ' passphrase1\n') 2649 params = hostapd.wpa2_params(ssid="test-sae") 2650 params['wpa_key_mgmt'] = 'SAE WPA-PSK' 2651 params['sae_password'] = ['passphrase0|mac=' + addr0, 2652 'passphrase1|mac=' + addr1] 2653 params['wpa_psk_file'] = psk_file 2654 hapd = hostapd.add_ap(apdev[0], params) 2655 2656 dev[0].set("sae_groups", "") 2657 dev[0].connect("test-sae", sae_password="passphrase0", 2658 key_mgmt="SAE", scan_freq="2412") 2659 dev[0].request("REMOVE_NETWORK all") 2660 dev[0].wait_disconnected() 2661 2662 dev[0].connect("test-sae", psk="passphrase0", scan_freq="2412") 2663 dev[0].request("REMOVE_NETWORK all") 2664 dev[0].wait_disconnected() 2665 2666 dev[1].set("sae_groups", "") 2667 dev[1].connect("test-sae", sae_password="passphrase1", 2668 key_mgmt="SAE", scan_freq="2412") 2669 dev[1].request("REMOVE_NETWORK all") 2670 dev[1].wait_disconnected() 2671 2672 dev[1].connect("test-sae", psk="passphrase1", scan_freq="2412") 2673 dev[1].request("REMOVE_NETWORK all") 2674 dev[1].wait_disconnected() 2675 2676def test_sae_pmf_roam(dev, apdev): 2677 """SAE/PMF roam""" 2678 check_sae_capab(dev[0]) 2679 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678") 2680 params['wpa_key_mgmt'] = 'SAE' 2681 params['ieee80211w'] = '2' 2682 params['skip_prune_assoc'] = '1' 2683 hapd = hostapd.add_ap(apdev[0], params) 2684 bssid = hapd.own_addr() 2685 2686 dev[0].set("sae_groups", "") 2687 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2688 ieee80211w="2", scan_freq="2412") 2689 dev[0].dump_monitor() 2690 hapd.wait_sta() 2691 2692 hapd2 = hostapd.add_ap(apdev[1], params) 2693 bssid2 = hapd2.own_addr() 2694 2695 dev[0].scan_for_bss(bssid2, freq=2412) 2696 dev[0].roam(bssid2) 2697 dev[0].dump_monitor() 2698 hapd2.wait_sta() 2699 2700 dev[0].roam(bssid) 2701 dev[0].dump_monitor() 2702 2703def test_sae_ocv_pmk(dev, apdev): 2704 """SAE with OCV and fetching PMK (successful 4-way handshake)""" 2705 check_sae_capab(dev[0]) 2706 params = hostapd.wpa2_params(ssid="test-sae", 2707 passphrase="12345678") 2708 params['wpa_key_mgmt'] = 'SAE' 2709 params['ieee80211w'] = '2' 2710 params['ocv'] = '1' 2711 hapd = hostapd.add_ap(apdev[0], params) 2712 2713 dev[0].set("sae_groups", "") 2714 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ocv="1", 2715 ieee80211w="2", scan_freq="2412") 2716 hapd.wait_sta() 2717 2718 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr()) 2719 if "FAIL" in pmk_h or len(pmk_h) == 0: 2720 raise Exception("Failed to fetch PMK from hostapd during a successful authentication") 2721 2722 pmk_w = dev[0].get_pmk(id) 2723 if pmk_h != pmk_w: 2724 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w)) 2725 2726def test_sae_ocv_pmk_failure(dev, apdev): 2727 """SAE with OCV and fetching PMK (failed 4-way handshake)""" 2728 check_sae_capab(dev[0]) 2729 params = hostapd.wpa2_params(ssid="test-sae", 2730 passphrase="12345678") 2731 params['wpa_key_mgmt'] = 'SAE' 2732 params['ieee80211w'] = '2' 2733 params['ocv'] = '1' 2734 hapd = hostapd.add_ap(apdev[0], params) 2735 2736 dev[0].set("sae_groups", "") 2737 dev[0].set("oci_freq_override_eapol", "2462") 2738 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ocv="1", 2739 ieee80211w="2", scan_freq="2412", wait_connect=False) 2740 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2741 "CTRL-EVENT-DISCONNECTED"], timeout=15) 2742 if ev is None: 2743 raise Exception("No connection result reported") 2744 if "CTRL-EVENT-CONNECTED" in ev: 2745 raise Exception("Unexpected connection") 2746 2747 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr()) 2748 if "FAIL" in pmk_h or len(pmk_h) == 0: 2749 raise Exception("Failed to fetch PMK from hostapd during a successful authentication") 2750 2751 res = dev[0].request("PMKSA_GET %d" % id) 2752 if not res.startswith(hapd.own_addr()): 2753 raise Exception("PMKSA from wpa_supplicant does not have matching BSSID") 2754 pmk_w = res.split(' ')[2] 2755 if pmk_h != pmk_w: 2756 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w)) 2757 2758 dev[0].request("DISCONNECT") 2759 time.sleep(0.1) 2760 pmk_h2 = hapd.request("GET_PMK " + dev[0].own_addr()) 2761 res = dev[0].request("PMKSA_GET %d" % id) 2762 pmk_w2 = res.split(' ')[2] 2763 if pmk_h2 != pmk_h: 2764 raise Exception("hostapd did not report correct PMK after disconnection") 2765 if pmk_w2 != pmk_w: 2766 raise Exception("wpa_supplicant did not report correct PMK after disconnection") 2767 2768def test_sae_reject(dev, apdev): 2769 """SAE and AP rejecting connection""" 2770 check_sae_capab(dev[0]) 2771 params = hostapd.wpa2_params(ssid="test-sae", 2772 passphrase="12345678") 2773 params['wpa_key_mgmt'] = 'SAE' 2774 params['max_num_sta'] = '0' 2775 hapd = hostapd.add_ap(apdev[0], params) 2776 dev[0].set("sae_groups", "") 2777 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 2778 scan_freq="2412", wait_connect=False) 2779 if not dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10): 2780 raise Exception("Authentication rejection not reported") 2781 dev[0].request("REMOVE_NETWORK all") 2782 dev[0].dump_monitor() 2783