1# Test cases for PASN 2# Copyright (C) 2019 Intel Corporation 3# 4# This software may be distributed under the terms of the BSD license. 5# See README for more details. 6 7from remotehost import remote_compatible 8import binascii 9import os 10import time 11import logging 12logger = logging.getLogger() 13import socket 14import struct 15import subprocess 16import re 17 18import hwsim_utils 19import hostapd 20from wpasupplicant import WpaSupplicant 21from utils import * 22from hwsim import HWSimRadio 23from test_erp import start_erp_as 24from test_ap_ft import run_roams, ft_params1, ft_params2 25 26def check_pasn_capab(dev): 27 if "PASN" not in dev.get_capability("auth_alg"): 28 raise HwsimSkip("PASN not supported") 29 30def pasn_ap_params(akmp="PASN", cipher="CCMP", group="19"): 31 params = {"ssid": "test-wpa2-pasn", 32 "wpa_passphrase": "12345678", 33 "wpa": "2", 34 "ieee80211w": "2", 35 "wpa_key_mgmt": "WPA-PSK " + akmp, 36 "rsn_pairwise": cipher, 37 "pasn_groups" : group} 38 39 return params 40 41def start_pasn_ap(apdev, params): 42 try: 43 return hostapd.add_ap(apdev, params) 44 except Exception as e: 45 if "Failed to set hostapd parameter wpa_key_mgmt" in str(e) or \ 46 "Failed to set hostapd parameter force_kdk_derivation" in str(e): 47 raise HwsimSkip("PASN not supported") 48 raise 49 50def check_pasn_ptk(dev, hapd, cipher, fail_ptk=False, clear_keys=True, 51 require_kdk=False): 52 sta_ptksa = dev.get_ptksa(hapd.own_addr(), cipher) 53 ap_ptksa = hapd.get_ptksa(dev.own_addr(), cipher) 54 55 # There's no event indicating hostapd has finished 56 # processing - so just try once more if it isn't 57 # yet available, it might become available still. 58 for i in range(10): 59 if ap_ptksa: 60 break 61 time.sleep(0.1) 62 ap_ptksa = hapd.get_ptksa(dev.own_addr(), cipher) 63 64 if not (sta_ptksa and ap_ptksa): 65 if fail_ptk: 66 return 67 if not sta_ptksa and not ap_ptksa: 68 source = 'both' 69 elif sta_ptksa: 70 source = 'ap' 71 else: 72 source = 'sta' 73 raise Exception("Could not get PTKSA entry from %s" % source) 74 75 logger.info("sta: TK: %s KDK: %s" % (sta_ptksa['tk'], sta_ptksa['kdk'])) 76 logger.info("ap : TK: %s KDK: %s" % (ap_ptksa['tk'], ap_ptksa['kdk'])) 77 78 if sta_ptksa['tk'] != ap_ptksa['tk'] or sta_ptksa['kdk'] != ap_ptksa['kdk']: 79 raise Exception("TK/KDK mismatch") 80 if fail_ptk: 81 raise Exception("TK/KDK match although key derivation should have failed") 82 if require_kdk and sta_ptksa['kdk'] == '': 83 raise Exception("KDK was not derived") 84 if clear_keys: 85 cmd = "PASN_DEAUTH bssid=%s" % hapd.own_addr() 86 dev.request(cmd) 87 88 # Wait a little to let the AP process the deauth 89 time.sleep(0.2) 90 91 sta_ptksa = dev.get_ptksa(hapd.own_addr(), cipher) 92 ap_ptksa = hapd.get_ptksa(dev.own_addr(), cipher) 93 if sta_ptksa or ap_ptksa: 94 raise Exception("TK/KDK not deleted as expected") 95 96def check_pasn_akmp_cipher(dev, hapd, akmp="PASN", cipher="CCMP", 97 group="19", status=0, fail=0, nid="", 98 fail_ptk=False): 99 dev.flush_scan_cache() 100 dev.scan(type="ONLY", freq=2412) 101 102 cmd = "PASN_START bssid=%s akmp=%s cipher=%s group=%s" % (hapd.own_addr(), akmp, cipher, group) 103 104 if nid != "": 105 cmd += " nid=%s" % nid 106 107 resp = dev.request(cmd) 108 109 if fail: 110 if "OK" in resp: 111 raise Exception("Unexpected success to start PASN authentication") 112 return 113 114 if "OK" not in resp: 115 raise Exception("Failed to start PASN authentication") 116 117 ev = dev.wait_event(["PASN-AUTH-STATUS"], 3) 118 if not ev: 119 raise Exception("PASN: PASN-AUTH-STATUS not seen") 120 121 if hapd.own_addr() + " akmp=" + akmp + ", status=" + str(status) not in ev: 122 raise Exception("PASN: unexpected status") 123 124 if status: 125 return 126 127 # There is a small window for a race condition here since the hostapd side 128 # might not yet have processed the PASN message 3 and added the PTKSA entry, 129 # so wait a bit before checking the results. 130 time.sleep(0.1) 131 132 check_pasn_ptk(dev, hapd, cipher, fail_ptk) 133 134@remote_compatible 135def test_pasn_ccmp(dev, apdev): 136 """PASN authentication with WPA2/CCMP AP""" 137 check_pasn_capab(dev[0]) 138 139 params = pasn_ap_params("PASN", "CCMP", "19") 140 hapd = start_pasn_ap(apdev[0], params) 141 142 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP") 143 144@remote_compatible 145def test_pasn_gcmp(dev, apdev): 146 """PASN authentication with WPA2/GCMP AP""" 147 check_pasn_capab(dev[0]) 148 149 params = pasn_ap_params("PASN", "GCMP", "19") 150 hapd = start_pasn_ap(apdev[0], params) 151 152 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "GCMP") 153 154@remote_compatible 155def test_pasn_ccmp_256(dev, apdev): 156 """PASN authentication with WPA2/CCMP256 AP""" 157 check_pasn_capab(dev[0]) 158 159 params = pasn_ap_params("PASN", "CCMP-256", "19") 160 hapd = start_pasn_ap(apdev[0], params) 161 162 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP-256") 163 164@remote_compatible 165def test_pasn_gcmp_256(dev, apdev): 166 """PASN authentication with WPA2/GCMP-256 AP""" 167 check_pasn_capab(dev[0]) 168 169 params = pasn_ap_params("PASN", "GCMP-256", "19") 170 hapd = start_pasn_ap(apdev[0], params) 171 172 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "GCMP-256") 173 174@remote_compatible 175def test_pasn_group_mismatch(dev, apdev): 176 """PASN authentication with WPA2/CCMP AP with group mismatch""" 177 check_pasn_capab(dev[0]) 178 179 params = pasn_ap_params("PASN", "CCMP", "20") 180 hapd = start_pasn_ap(apdev[0], params) 181 182 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", status=77) 183 184@remote_compatible 185def test_pasn_channel_mismatch(dev, apdev): 186 """PASN authentication with WPA2/CCMP AP with channel mismatch""" 187 check_pasn_capab(dev[0]) 188 189 params = pasn_ap_params("PASN", "CCMP") 190 params['channel'] = "6" 191 hapd = start_pasn_ap(apdev[0], params) 192 193 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", fail=1) 194 195@remote_compatible 196def test_pasn_while_connected_same_channel(dev, apdev): 197 """PASN authentication with WPA2/CCMP AP while connected same channel""" 198 check_pasn_capab(dev[0]) 199 200 ssid = "test-wpa2-psk" 201 psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6' 202 params = hostapd.wpa2_params(ssid=ssid) 203 params['wpa_psk'] = psk 204 hapd = start_pasn_ap(apdev[0], params) 205 206 dev[0].connect(ssid, raw_psk=psk, scan_freq="2412") 207 208 params = pasn_ap_params("PASN", "CCMP") 209 hapd = start_pasn_ap(apdev[1], params) 210 211 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP") 212 213@remote_compatible 214def test_pasn_while_connected_same_ap(dev, apdev): 215 """PASN authentication with WPA2/CCMP AP while connected to it""" 216 check_pasn_capab(dev[0]) 217 218 params = hostapd.wpa2_params(ssid="test-wpa2-psk", 219 passphrase="12345678") 220 hapd = start_pasn_ap(apdev[0], params) 221 222 dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412") 223 224 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", fail=1) 225 226@remote_compatible 227def test_pasn_while_connected_diff_channel(dev, apdev): 228 """PASN authentication with WPA2/CCMP AP while connected diff channel""" 229 check_pasn_capab(dev[0]) 230 231 with HWSimRadio(n_channels=2) as (radio, iface): 232 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 233 wpas.interface_add(iface) 234 235 if wpas.get_mcc() < 2: 236 raise HwsimSkip("PASN: New radio does not support MCC") 237 238 params = hostapd.wpa2_params(ssid="test-wpa2-psk", 239 passphrase="12345678") 240 params['channel'] = "6" 241 hapd = start_pasn_ap(apdev[0], params) 242 wpas.connect("test-wpa2-psk", psk="12345678", scan_freq="2437") 243 244 params = pasn_ap_params("PASN", "CCMP") 245 hapd2 = start_pasn_ap(apdev[1], params) 246 247 check_pasn_akmp_cipher(wpas, hapd2, "PASN", "CCMP") 248 249@remote_compatible 250def test_pasn_sae_pmksa_cache(dev, apdev): 251 """PASN authentication with SAE AP with PMKSA caching""" 252 check_pasn_capab(dev[0]) 253 check_sae_capab(dev[0]) 254 255 params = hostapd.wpa2_params(ssid="test-sae", 256 passphrase="12345678") 257 params['wpa_key_mgmt'] = 'SAE PASN' 258 params['sae_pwe'] = "2" 259 hapd = start_pasn_ap(apdev[0], params) 260 261 try: 262 dev[0].set("sae_groups", "19") 263 dev[0].set("sae_pwe", "2") 264 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412") 265 266 hapd.wait_sta() 267 hwsim_utils.test_connectivity(dev[0], hapd) 268 269 dev[0].request("DISCONNECT") 270 dev[0].wait_disconnected() 271 272 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP") 273 finally: 274 dev[0].set("sae_pwe", "0") 275 276def check_pasn_fils_pmksa_cache(dev, apdev, params, key_mgmt): 277 check_fils_capa(dev[0]) 278 check_erp_capa(dev[0]) 279 check_pasn_capab(dev[0]) 280 281 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst")) 282 283 bssid = apdev[0]['bssid'] 284 params = hostapd.wpa2_eap_params(ssid="fils") 285 params['wpa_key_mgmt'] = key_mgmt + " PASN" 286 params['auth_server_port'] = "18128" 287 params['erp_domain'] = 'example.com' 288 params['fils_realm'] = 'example.com' 289 hapd = start_pasn_ap(apdev[0], params) 290 291 dev[0].scan_for_bss(bssid, freq=2412) 292 dev[0].request("ERP_FLUSH") 293 294 id = dev[0].connect("fils", key_mgmt=key_mgmt, 295 eap="PSK", identity="psk.user@example.com", 296 password_hex="0123456789abcdef0123456789abcdef", 297 erp="1", scan_freq="2412") 298 pmksa = dev[0].get_pmksa(bssid) 299 if pmksa is None: 300 raise Exception("No PMKSA cache entry created") 301 302 hapd.wait_sta() 303 hwsim_utils.test_connectivity(dev[0], hapd) 304 305 dev[0].request("DISCONNECT") 306 dev[0].wait_disconnected() 307 308 check_pasn_akmp_cipher(dev[0], hapd, key_mgmt, "CCMP") 309 310@remote_compatible 311def test_pasn_fils_sha256_pmksa_cache(dev, apdev, params): 312 """PASN authentication with FILS-SHA256 with PMKSA caching""" 313 check_pasn_fils_pmksa_cache(dev, apdev, params, "FILS-SHA256") 314 315@remote_compatible 316def test_pasn_fils_sha384_pmksa_cache(dev, apdev, params): 317 """PASN authentication with FILS-SHA384 with PMKSA caching""" 318 check_pasn_fils_pmksa_cache(dev, apdev, params, "FILS-SHA384") 319 320@remote_compatible 321def test_pasn_sae_kdk(dev, apdev): 322 """Station authentication with SAE AP with KDK derivation during connection""" 323 check_pasn_capab(dev[0]) 324 check_sae_capab(dev[0]) 325 326 try: 327 params = hostapd.wpa2_params(ssid="test-sae", 328 passphrase="12345678") 329 params['wpa_key_mgmt'] = 'SAE PASN' 330 params['sae_pwe'] = "2" 331 params['force_kdk_derivation'] = "1" 332 hapd = start_pasn_ap(apdev[0], params) 333 334 dev[0].set("force_kdk_derivation", "1") 335 dev[0].set("sae_groups", "") 336 dev[0].set("sae_pwe", "2") 337 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 338 scan_freq="2412") 339 340 check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False) 341 finally: 342 dev[0].set("force_kdk_derivation", "0") 343 dev[0].set("sae_pwe", "0") 344 345def test_pasn_sae_kdk_ft(dev, apdev): 346 """Station authentication with SAE AP with KDK derivation during connection with FT protocol""" 347 check_pasn_capab(dev[0]) 348 check_sae_capab(dev[0]) 349 350 try: 351 params = hostapd.wpa2_params(ssid="test-sae", 352 passphrase="12345678") 353 params['wpa_key_mgmt'] = 'FT-SAE' 354 params['sae_pwe'] = "2" 355 params['force_kdk_derivation'] = "1" 356 params['nas_identifier'] = "nas1.w1.fi" 357 params['r1_key_holder'] = "000102030405" 358 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f", 359 "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"] 360 params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f" 361 hapd = start_pasn_ap(apdev[0], params) 362 363 dev[0].set("force_kdk_derivation", "1") 364 dev[0].set("sae_groups", "") 365 dev[0].set("sae_pwe", "2") 366 dev[0].connect("test-sae", psk="12345678", key_mgmt="FT-SAE", 367 scan_freq="2412") 368 369 check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False) 370 371 params = hostapd.wpa2_params(ssid="test-sae", 372 passphrase="12345678") 373 params['wpa_key_mgmt'] = 'FT-SAE' 374 params['sae_pwe'] = "2" 375 params['force_kdk_derivation'] = "1" 376 params['nas_identifier'] = "nas2.w1.fi" 377 params['r1_key_holder'] = "000102030406" 378 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f", 379 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"] 380 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f" 381 hapd2 = start_pasn_ap(apdev[1], params) 382 383 bssid = hapd2.own_addr() 384 dev[0].scan_for_bss(bssid, freq="2412") 385 dev[0].roam(bssid) 386 387 check_pasn_ptk(dev[0], hapd2, "CCMP", clear_keys=False) 388 389 bssid = hapd.own_addr() 390 dev[0].roam(bssid) 391 392 check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False) 393 finally: 394 dev[0].set("force_kdk_derivation", "0") 395 dev[0].set("sae_pwe", "0") 396 397def check_pasn_fils_kdk(dev, apdev, params, key_mgmt): 398 check_fils_capa(dev[0]) 399 check_erp_capa(dev[0]) 400 check_pasn_capab(dev[0]) 401 402 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst")) 403 404 try: 405 bssid = apdev[0]['bssid'] 406 params = hostapd.wpa2_eap_params(ssid="fils") 407 params['wpa_key_mgmt'] = key_mgmt 408 params['auth_server_port'] = "18128" 409 params['erp_domain'] = 'example.com' 410 params['fils_realm'] = 'example.com' 411 params['disable_pmksa_caching'] = '1' 412 params['force_kdk_derivation'] = "1" 413 hapd = start_pasn_ap(apdev[0], params) 414 415 dev[0].scan_for_bss(bssid, freq=2412) 416 dev[0].request("ERP_FLUSH") 417 dev[0].set("force_kdk_derivation", "1") 418 419 id = dev[0].connect("fils", key_mgmt=key_mgmt, 420 eap="PSK", identity="psk.user@example.com", 421 password_hex="0123456789abcdef0123456789abcdef", 422 erp="1", scan_freq="2412") 423 424 hapd.wait_sta() 425 hwsim_utils.test_connectivity(dev[0], hapd) 426 427 check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False) 428 429 dev[0].request("DISCONNECT") 430 dev[0].wait_disconnected() 431 432 dev[0].dump_monitor() 433 dev[0].select_network(id, freq=2412) 434 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", 435 "EVENT-ASSOC-REJECT", 436 "CTRL-EVENT-CONNECTED"], timeout=10) 437 if ev is None: 438 raise Exception("Connection using FILS/ERP timed out") 439 if "CTRL-EVENT-EAP-STARTED" in ev: 440 raise Exception("Unexpected EAP exchange") 441 if "EVENT-ASSOC-REJECT" in ev: 442 raise Exception("Association failed") 443 444 hapd.wait_sta() 445 hwsim_utils.test_connectivity(dev[0], hapd) 446 447 check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False) 448 finally: 449 dev[0].set("force_kdk_derivation", "0") 450 451@remote_compatible 452def test_pasn_fils_sha256_kdk(dev, apdev, params): 453 """Station authentication with FILS-SHA256 with KDK derivation during connection""" 454 check_pasn_fils_kdk(dev, apdev, params, "FILS-SHA256") 455 456@remote_compatible 457def test_pasn_fils_sha384_kdk(dev, apdev, params): 458 """Station authentication with FILS-SHA384 with KDK derivation during connection""" 459 check_pasn_fils_kdk(dev, apdev, params, "FILS-SHA384") 460 461@remote_compatible 462def test_pasn_sae(dev, apdev): 463 """PASN authentication with SAE AP with PMK derivation + PMKSA caching""" 464 check_pasn_capab(dev[0]) 465 check_sae_capab(dev[0]) 466 467 params = hostapd.wpa2_params(ssid="test-pasn-sae", 468 passphrase="12345678") 469 params['wpa_key_mgmt'] = 'SAE PASN' 470 params['sae_pwe'] = "2" 471 hapd = start_pasn_ap(apdev[0], params) 472 473 try: 474 dev[0].set("sae_pwe", "2") 475 dev[0].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE", 476 scan_freq="2412", only_add_network=True) 477 478 # first test with a valid PSK 479 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", nid="0") 480 481 # And now with PMKSA caching 482 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP") 483 484 # And now with a wrong passphrase 485 if "FAIL" in dev[0].request("PMKSA_FLUSH"): 486 raise Exception("PMKSA_FLUSH failed") 487 488 dev[0].set_network_quoted(0, "psk", "12345678787") 489 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", status=1, nid="0") 490 finally: 491 dev[0].set("sae_pwe", "0") 492 493@remote_compatible 494def test_pasn_sae_while_connected_same_channel(dev, apdev): 495 """PASN SAE authentication while connected same channel""" 496 check_pasn_capab(dev[0]) 497 check_sae_capab(dev[0]) 498 499 params = hostapd.wpa2_params(ssid="test-pasn-wpa2-psk", 500 passphrase="12345678") 501 hapd = hostapd.add_ap(apdev[0], params) 502 503 try: 504 dev[0].set("sae_pwe", "2") 505 dev[0].connect("test-pasn-wpa2-psk", psk="12345678", scan_freq="2412") 506 507 params = hostapd.wpa2_params(ssid="test-pasn-sae", 508 passphrase="12345678") 509 510 params['wpa_key_mgmt'] = 'SAE PASN' 511 params['sae_pwe'] = "2" 512 hapd = start_pasn_ap(apdev[1], params) 513 514 dev[0].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE", 515 scan_freq="2412", only_add_network=True) 516 517 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", nid="1") 518 finally: 519 dev[0].set("sae_pwe", "0") 520 521@remote_compatible 522def test_pasn_sae_while_connected_diff_channel(dev, apdev): 523 """PASN SAE authentication while connected diff channel""" 524 check_pasn_capab(dev[0]) 525 check_sae_capab(dev[0]) 526 527 with HWSimRadio(n_channels=2) as (radio, iface): 528 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 529 wpas.interface_add(iface) 530 531 if wpas.get_mcc() < 2: 532 raise HwsimSkip("PASN: New radio does not support MCC") 533 534 params = hostapd.wpa2_params(ssid="test-pasn-wpa2-psk", 535 passphrase="12345678") 536 params['channel'] = "6" 537 hapd = hostapd.add_ap(apdev[0], params) 538 539 try: 540 wpas.set("sae_pwe", "2") 541 wpas.connect("test-pasn-wpa2-psk", psk="12345678", scan_freq="2437") 542 543 params = hostapd.wpa2_params(ssid="test-pasn-sae", 544 passphrase="12345678") 545 546 params['wpa_key_mgmt'] = 'SAE PASN' 547 params['sae_pwe'] = "2" 548 hapd = start_pasn_ap(apdev[1], params) 549 550 wpas.connect("test-pasn-sae", psk="12345678", key_mgmt="SAE", 551 scan_freq="2412", only_add_network=True) 552 553 check_pasn_akmp_cipher(wpas, hapd, "SAE", "CCMP", nid="1") 554 finally: 555 wpas.set("sae_pwe", "0") 556 557def pasn_fils_setup(wpas, apdev, params, key_mgmt): 558 check_fils_capa(wpas) 559 check_erp_capa(wpas) 560 561 wpas.flush_scan_cache() 562 563 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst")) 564 565 bssid = apdev[0]['bssid'] 566 params = hostapd.wpa2_eap_params(ssid="fils") 567 params['wpa_key_mgmt'] = key_mgmt + " PASN" 568 params['auth_server_port'] = "18128" 569 params['erp_domain'] = 'example.com' 570 params['fils_realm'] = 'example.com' 571 params['disable_pmksa_caching'] = '1' 572 hapd = hostapd.add_ap(apdev[0], params) 573 574 id = wpas.connect("fils", key_mgmt=key_mgmt, 575 eap="PSK", identity="psk.user@example.com", 576 password_hex="0123456789abcdef0123456789abcdef", 577 erp="1", scan_freq="2412") 578 579 wpas.request("DISCONNECT") 580 wpas.wait_disconnected() 581 wpas.dump_monitor() 582 583 if "FAIL" in wpas.request("PMKSA_FLUSH"): 584 raise Exception("PMKSA_FLUSH failed") 585 586 return hapd 587 588def check_pasn_fils(dev, apdev, params, key_mgmt): 589 check_pasn_capab(dev[0]) 590 591 hapd = pasn_fils_setup(dev[0], apdev, params, key_mgmt); 592 check_pasn_akmp_cipher(dev[0], hapd, key_mgmt, "CCMP", nid="0") 593 594@remote_compatible 595def test_pasn_fils_sha256(dev, apdev, params): 596 """PASN FILS authentication using SHA-256""" 597 check_pasn_fils(dev, apdev, params, "FILS-SHA256") 598 599@remote_compatible 600def test_pasn_fils_sha384(dev, apdev, params): 601 """PASN FILS authentication using SHA-384""" 602 check_pasn_fils(dev, apdev, params, "FILS-SHA384") 603 604def check_pasn_fils_connected_same_channel(dev, apdev, params, key_mgmt): 605 check_pasn_capab(dev[0]) 606 607 hapd = pasn_fils_setup(dev[0], apdev, params, key_mgmt); 608 609 # Connect to another AP on the same channel 610 hapd1 = hostapd.add_ap(apdev[1], {"ssid": "open"}) 611 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", 612 bg_scan_period="0") 613 614 hwsim_utils.test_connectivity(dev[0], hapd1) 615 616 # And perform the PASN authentication with FILS 617 check_pasn_akmp_cipher(dev[0], hapd, key_mgmt, "CCMP", nid="0") 618 619@remote_compatible 620def test_pasn_fils_sha256_connected_same_channel(dev, apdev, params): 621 """PASN FILS authentication using SHA-256 while connected same channel""" 622 check_pasn_fils_connected_same_channel(dev, apdev, params, "FILS-SHA256") 623 624@remote_compatible 625def test_pasn_fils_sha384_connected_same_channel(dev, apdev, params): 626 """PASN FILS authentication using SHA-384 while connected same channel""" 627 check_pasn_fils_connected_same_channel(dev, apdev, params, "FILS-SHA384") 628 629def check_pasn_fils_connected_diff_channel(dev, apdev, params, key_mgmt): 630 check_pasn_capab(dev[0]) 631 632 with HWSimRadio(n_channels=2) as (radio, iface): 633 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 634 wpas.interface_add(iface) 635 if wpas.get_mcc() < 2: 636 raise Exception("New radio does not support MCC") 637 638 hapd = pasn_fils_setup(wpas, apdev, params, key_mgmt); 639 640 # Connect to another AP on a different channel 641 hapd1 = hostapd.add_ap(apdev[1], {"ssid": "open", "channel" : "6"}) 642 wpas.connect("open", key_mgmt="NONE", scan_freq="2437", 643 bg_scan_period="0") 644 645 hwsim_utils.test_connectivity(wpas, hapd1) 646 647 # And perform the PASN authentication with FILS 648 check_pasn_akmp_cipher(wpas, hapd, key_mgmt, "CCMP", nid="0") 649 650@remote_compatible 651def test_pasn_fils_sha256_connected_diff_channel(dev, apdev, params): 652 """PASN FILS authentication using SHA-256 while connected diff channel""" 653 check_pasn_fils_connected_diff_channel(dev, apdev, params, "FILS-SHA256") 654 655@remote_compatible 656def test_pasn_fils_sha384_connected_diff_channel(dev, apdev, params): 657 """PASN FILS authentication using SHA-384 while connected diff channel""" 658 check_pasn_fils_connected_diff_channel(dev, apdev, params, "FILS-SHA384") 659 660def test_pasn_ft_psk(dev, apdev): 661 """PASN authentication with FT-PSK""" 662 check_pasn_capab(dev[0]) 663 664 ssid = "test-pasn-ft-psk" 665 passphrase = "12345678" 666 667 params = ft_params1(ssid=ssid, passphrase=passphrase) 668 params['wpa_key_mgmt'] += " PASN" 669 hapd0 = hostapd.add_ap(apdev[0], params) 670 params = ft_params2(ssid=ssid, passphrase=passphrase) 671 params['wpa_key_mgmt'] += " PASN" 672 hapd1 = hostapd.add_ap(apdev[1], params) 673 674 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase) 675 676 if dev[0].get_status_field('bssid') == apdev[0]['bssid']: 677 pasn_hapd = hapd1 678 else: 679 pasn_hapd = hapd0 680 681 check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-PSK", "CCMP") 682 683 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, only_one_way=1) 684 685 if dev[0].get_status_field('bssid') == apdev[0]['bssid']: 686 pasn_hapd = hapd1 687 else: 688 pasn_hapd = hapd0 689 690 check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-PSK", "CCMP") 691 692def test_pasn_ft_eap(dev, apdev): 693 """PASN authentication with FT-EAP""" 694 check_pasn_capab(dev[0]) 695 696 ssid = "test-pasn-ft-psk" 697 passphrase = "12345678" 698 identity = "gpsk user" 699 700 radius = hostapd.radius_params() 701 params = ft_params1(ssid=ssid, passphrase=passphrase) 702 params['wpa_key_mgmt'] = "FT-EAP PASN" 703 params["ieee8021x"] = "1" 704 params = dict(list(radius.items()) + list(params.items())) 705 hapd0 = hostapd.add_ap(apdev[0], params) 706 707 params = ft_params2(ssid=ssid, passphrase=passphrase) 708 params['wpa_key_mgmt'] = "FT-EAP PASN" 709 params["ieee8021x"] = "1" 710 params = dict(list(radius.items()) + list(params.items())) 711 hapd1 = hostapd.add_ap(apdev[1], params) 712 713 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True, 714 eap_identity=identity) 715 716 if dev[0].get_status_field('bssid') == apdev[0]['bssid']: 717 pasn_hapd = hapd1 718 else: 719 pasn_hapd = hapd0 720 721 check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-EAP", "CCMP") 722 723def test_pasn_ft_eap_sha384(dev, apdev): 724 """PASN authentication with FT-EAP-SHA-384""" 725 check_pasn_capab(dev[0]) 726 727 ssid = "test-pasn-ft-psk" 728 passphrase = "12345678" 729 identity = "gpsk user" 730 731 radius = hostapd.radius_params() 732 params = ft_params1(ssid=ssid, passphrase=passphrase) 733 params["ieee80211w"] = "2" 734 params['wpa_key_mgmt'] = "FT-EAP-SHA384 PASN" 735 params["ieee8021x"] = "1" 736 params = dict(list(radius.items()) + list(params.items())) 737 hapd0 = hostapd.add_ap(apdev[0], params) 738 739 params = ft_params2(ssid=ssid, passphrase=passphrase) 740 params["ieee80211w"] = "2" 741 params['wpa_key_mgmt'] = "FT-EAP-SHA384 PASN" 742 params["ieee8021x"] = "1" 743 params = dict(list(radius.items()) + list(params.items())) 744 hapd1 = hostapd.add_ap(apdev[1], params) 745 746 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True, 747 sha384=True) 748 749 if dev[0].get_status_field('bssid') == apdev[0]['bssid']: 750 pasn_hapd = hapd1 751 else: 752 pasn_hapd = hapd0 753 754 check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-EAP-SHA384", "CCMP") 755 756def test_pasn_sta_mic_error(dev, apdev): 757 """PASN authentication with WPA2/CCMP AP with corrupted MIC on station""" 758 check_pasn_capab(dev[0]) 759 760 params = pasn_ap_params("PASN", "CCMP", "19") 761 hapd = hostapd.add_ap(apdev[0], params) 762 763 try: 764 # When forcing MIC corruption, the exchange would be still successful 765 # on the station side, but the AP would fail the exchange and would not 766 # store the keys. 767 dev[0].set("pasn_corrupt_mic", "1") 768 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", fail_ptk=True) 769 finally: 770 dev[0].set("pasn_corrupt_mic", "0") 771 772 # Now verify the successful case 773 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP") 774 775def test_pasn_ap_mic_error(dev, apdev): 776 """PASN authentication with WPA2/CCMP AP with corrupted MIC on AP""" 777 check_pasn_capab(dev[0]) 778 779 params = pasn_ap_params("PASN", "CCMP", "19") 780 hapd0 = hostapd.add_ap(apdev[0], params) 781 782 params['pasn_corrupt_mic'] = "1" 783 hapd1 = hostapd.add_ap(apdev[1], params) 784 785 check_pasn_akmp_cipher(dev[0], hapd1, "PASN", "CCMP", status=1) 786 check_pasn_akmp_cipher(dev[0], hapd0, "PASN", "CCMP") 787 788@remote_compatible 789def test_pasn_comeback(dev, apdev, params): 790 """PASN authentication with comeback flow""" 791 check_pasn_capab(dev[0]) 792 793 params = pasn_ap_params("PASN", "CCMP", "19") 794 params['sae_anti_clogging_threshold'] = '0' 795 hapd = hostapd.add_ap(apdev[0], params) 796 bssid = hapd.own_addr() 797 798 dev[0].scan(type="ONLY", freq=2412) 799 cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19" % bssid 800 801 resp = dev[0].request(cmd) 802 if "OK" not in resp: 803 raise Exception("Failed to start PASN authentication") 804 805 ev = dev[0].wait_event(["PASN-AUTH-STATUS"], 3) 806 if not ev: 807 raise Exception("PASN: PASN-AUTH-STATUS not seen") 808 809 if bssid + " akmp=PASN, status=30 comeback_after=" not in ev: 810 raise Exception("PASN: unexpected status") 811 812 comeback = re.split("comeback=", ev)[1] 813 814 cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19 comeback=%s" % \ 815 (bssid, comeback) 816 817 resp = dev[0].request(cmd) 818 if "OK" not in resp: 819 raise Exception("Failed to start PASN authentication") 820 821 ev = dev[0].wait_event(["PASN-AUTH-STATUS"], 3) 822 if not ev: 823 raise Exception("PASN: PASN-AUTH-STATUS not seen") 824 825 if bssid + " akmp=PASN, status=0" not in ev: 826 raise Exception("PASN: unexpected status with comeback token") 827 828 check_pasn_ptk(dev[0], hapd, "CCMP") 829 830@remote_compatible 831def test_pasn_comeback_after_0(dev, apdev, params): 832 """PASN authentication with comeback flow with comeback after set to 0""" 833 check_pasn_capab(dev[0]) 834 835 params = pasn_ap_params("PASN", "CCMP", "19") 836 params['anti_clogging_threshold'] = '0' 837 params['pasn_comeback_after'] = '0' 838 hapd = start_pasn_ap(apdev[0], params) 839 840 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP") 841 842@remote_compatible 843def test_pasn_comeback_after_0_sae(dev, apdev): 844 """PASN authentication with SAE, with comeback flow where comeback after is set to 0""" 845 check_pasn_capab(dev[0]) 846 check_sae_capab(dev[0]) 847 848 params = hostapd.wpa2_params(ssid="test-pasn-sae", 849 passphrase="12345678") 850 params['wpa_key_mgmt'] = 'SAE PASN' 851 params['anti_clogging_threshold'] = '0' 852 params['pasn_comeback_after'] = '0' 853 params['sae_pwe'] = "2" 854 hapd = start_pasn_ap(apdev[0], params) 855 856 try: 857 dev[0].set("sae_pwe", "2") 858 dev[0].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE", 859 scan_freq="2412", only_add_network=True) 860 861 # first test with a valid PSK 862 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", nid="0") 863 864 # And now with PMKSA caching 865 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP") 866 867 # And now with a wrong passphrase 868 if "FAIL" in dev[0].request("PMKSA_FLUSH"): 869 raise Exception("PMKSA_FLUSH failed") 870 871 dev[0].set_network_quoted(0, "psk", "12345678787") 872 check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", status=1, nid="0") 873 finally: 874 dev[0].set("sae_pwe", "0") 875 876@remote_compatible 877def test_pasn_comeback_multi(dev, apdev): 878 """PASN authentication with SAE, with multiple stations with comeback""" 879 check_pasn_capab(dev[0]) 880 check_sae_capab(dev[0]) 881 882 params = hostapd.wpa2_params(ssid="test-pasn-sae", 883 passphrase="12345678") 884 params['wpa_key_mgmt'] = 'SAE PASN' 885 params['anti_clogging_threshold'] = '1' 886 params['pasn_comeback_after'] = '0' 887 hapd = start_pasn_ap(apdev[0], params) 888 bssid = hapd.own_addr() 889 890 id = {} 891 for i in range(0, 2): 892 dev[i].flush_scan_cache() 893 dev[i].scan(type="ONLY", freq=2412) 894 id[i] = dev[i].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE", 895 scan_freq="2412", only_add_network=True) 896 897 for i in range(0, 2): 898 cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19, nid=%s" % (bssid, id[i]) 899 resp = dev[i].request(cmd) 900 901 if "OK" not in resp: 902 raise Exception("Failed to start pasn authentication") 903 904 for i in range(0, 2): 905 ev = dev[i].wait_event(["PASN-AUTH-STATUS"], 3) 906 if not ev: 907 raise Exception("PASN: PASN-AUTH-STATUS not seen") 908 909 if bssid + " akmp=PASN, status=0" not in ev: 910 raise Exception("PASN: unexpected status") 911 912 check_pasn_ptk(dev[i], hapd, "CCMP") 913 914def test_pasn_kdk_derivation(dev, apdev): 915 """PASN authentication with forced KDK derivation""" 916 check_pasn_capab(dev[0]) 917 918 params = pasn_ap_params("PASN", "CCMP", "19") 919 hapd0 = start_pasn_ap(apdev[0], params) 920 921 params['force_kdk_derivation'] = "1" 922 hapd1 = start_pasn_ap(apdev[1], params) 923 924 try: 925 check_pasn_akmp_cipher(dev[0], hapd0, "PASN", "CCMP") 926 dev[0].set("force_kdk_derivation", "1") 927 check_pasn_akmp_cipher(dev[0], hapd1, "PASN", "CCMP") 928 finally: 929 dev[0].set("force_kdk_derivation", "0") 930 931def test_pasn_sae_kdk_secure_ltf(dev, apdev): 932 """Station authentication with SAE AP with KDK derivation during connection based on Secure LTF support""" 933 params = hostapd.wpa2_params(ssid="test-sae", 934 passphrase="12345678") 935 params['wpa_key_mgmt'] = 'SAE' 936 params['sae_pwe'] = "2" 937 params['driver_params'] = "secure_ltf=1" 938 hapd = start_pasn_ap(apdev[0], params) 939 940 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 941 wpas.interface_add("wlan5", drv_params="secure_ltf=1") 942 check_pasn_capab(wpas) 943 check_sae_capab(wpas) 944 945 try: 946 wpas.set("sae_groups", "") 947 wpas.set("sae_pwe", "2") 948 wpas.connect("test-sae", psk="12345678", key_mgmt="SAE", 949 scan_freq="2412") 950 951 check_pasn_ptk(wpas, hapd, "CCMP", clear_keys=False, require_kdk=True) 952 finally: 953 wpas.set("sae_pwe", "0") 954 955def test_pasn_owe_kdk_secure_ltf(dev, apdev): 956 """Station authentication with OWE AP with KDK derivation during connection based on Secure LTF support""" 957 params = {"ssid": "owe", 958 "wpa": "2", 959 "ieee80211w": "2", 960 "wpa_key_mgmt": "OWE", 961 "rsn_pairwise": "CCMP"} 962 params['driver_params'] = "secure_ltf=1" 963 hapd = start_pasn_ap(apdev[0], params) 964 965 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 966 wpas.interface_add("wlan5", drv_params="secure_ltf=1") 967 check_pasn_capab(wpas) 968 check_owe_capab(wpas) 969 970 wpas.connect("owe", key_mgmt="OWE", ieee80211w="2", scan_freq="2412") 971 972 check_pasn_ptk(wpas, hapd, "CCMP", clear_keys=False, require_kdk=True) 973 974def test_pasn_owe_tm_kdk_secure_ltf(dev, apdev): 975 """Station authentication with OWE transition mode AP with KDK derivation during connection based on Secure LTF support""" 976 params = {"ssid": "owe-random", 977 "wpa": "2", 978 "ieee80211w": "2", 979 "wpa_key_mgmt": "OWE", 980 "rsn_pairwise": "CCMP", 981 "owe_transition_bssid": apdev[1]['bssid'], 982 "owe_transition_ssid": '"owe-test"', 983 "ignore_broadcast_ssid": "1", 984 'driver_params': "secure_ltf=1"} 985 hapd = start_pasn_ap(apdev[0], params) 986 bssid = hapd.own_addr() 987 988 params = {"ssid": "owe-test", 989 "owe_transition_bssid": apdev[0]['bssid'], 990 "owe_transition_ssid": '"owe-random"', 991 'driver_params': "secure_ltf=1"} 992 hapd2 = hostapd.add_ap(apdev[1], params) 993 bssid2 = hapd2.own_addr() 994 995 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 996 wpas.interface_add("wlan5", drv_params="secure_ltf=1") 997 check_pasn_capab(wpas) 998 check_owe_capab(wpas) 999 wpas.flush_scan_cache() 1000 1001 wpas.scan_for_bss(bssid, freq="2412") 1002 wpas.scan_for_bss(bssid2, freq="2412") 1003 1004 wpas.connect("owe-test", key_mgmt="OWE", ieee80211w="2", scan_freq="2412") 1005 1006 check_pasn_ptk(wpas, hapd, "CCMP", clear_keys=False, require_kdk=True) 1007 1008 wpas.scan(type="ONLY", freq=2412) 1009 1010 wpas.request("DISCONNECT") 1011 wpas.wait_disconnected() 1012 wpas.request("RECONNECT") 1013 wpas.wait_connected() 1014 check_pasn_ptk(wpas, hapd, "CCMP", clear_keys=False, require_kdk=True) 1015 1016def test_pasn_noauth_0(dev, apdev): 1017 """PASN without mutual authentication disabled on the AP""" 1018 check_pasn_capab(dev[0]) 1019 1020 params = pasn_ap_params("PASN", "CCMP", "19") 1021 params["pasn_noauth"] = "0" 1022 hapd = start_pasn_ap(apdev[0], params) 1023 1024 check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", status=1) 1025 1026def test_pasn_sae_driver(dev, apdev): 1027 """PASN authentication using driver event as trigger""" 1028 check_pasn_capab(dev[0]) 1029 check_sae_capab(dev[0]) 1030 1031 params = hostapd.wpa2_params(ssid="test-pasn-sae", 1032 passphrase="12345678") 1033 params['ieee80211w'] = "2" 1034 params['wpa_key_mgmt'] = 'SAE SAE-EXT-KEY PASN' 1035 params['sae_pwe'] = "2" 1036 hapd = start_pasn_ap(apdev[0], params) 1037 bssid = hapd.own_addr() 1038 1039 params = hostapd.wpa2_params(ssid="test-pasn-sae", 1040 passphrase="12345678") 1041 params['wpa_key_mgmt'] = 'SAE PASN' 1042 params['sae_pwe'] = "0" 1043 hapd2 = start_pasn_ap(apdev[1], params) 1044 bssid2 = hapd2.own_addr() 1045 1046 dev[0].scan_for_bss(bssid, freq=2412) 1047 dev[0].scan_for_bss(bssid2, freq=2412) 1048 1049 try: 1050 dev[0].set("sae_pwe", "2") 1051 cmd = f"PASN_DRIVER auth {bssid} 02:11:22:33:44:55 {bssid2}" 1052 if "OK" not in dev[0].request(cmd): 1053 raise Exception("PASN_DRIVER failed") 1054 1055 ev = dev[0].wait_event(["PASN-AUTH-STATUS"], timeout=10) 1056 if ev is None: 1057 raise Exception("No PASN-AUTH-STATUS event (1)") 1058 if f"{bssid} akmp=PASN, status=0" not in ev: 1059 raise Exception("Unexpected event 1 contents: " + ev) 1060 1061 ev = dev[0].wait_event(["PASN-AUTH-STATUS"], timeout=10) 1062 if ev is None: 1063 raise Exception("No PASN-AUTH-STATUS event (2)") 1064 if f"{bssid2} akmp=PASN, status=0" not in ev: 1065 raise Exception("Unexpected event 2 contents: " + ev) 1066 1067 hapd2.disable() 1068 time.sleep(1) 1069 dev[0].dump_monitor() 1070 1071 if "OK" not in dev[0].request(cmd): 1072 raise Exception("PASN_DRIVER failed") 1073 1074 ev = dev[0].wait_event(["PASN-AUTH-STATUS"], timeout=10) 1075 if ev is None: 1076 raise Exception("No PASN-AUTH-STATUS event (1b)") 1077 if f"{bssid} akmp=PASN, status=0" not in ev: 1078 raise Exception("Unexpected event 1b contents: " + ev) 1079 1080 ev = dev[0].wait_event(["PASN-AUTH-STATUS"], timeout=10) 1081 if ev is None: 1082 raise Exception("No PASN-AUTH-STATUS event (2b)") 1083 if f"{bssid2} akmp=PASN, status=1" not in ev: 1084 raise Exception("Unexpected event 2b contents: " + ev) 1085 finally: 1086 dev[0].set("sae_pwe", "0") 1087