1# Test cases for Opportunistic Wireless Encryption (OWE) 2# Copyright (c) 2017, 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 7import binascii 8import logging 9logger = logging.getLogger() 10import time 11import os 12import struct 13 14import hostapd 15from wpasupplicant import WpaSupplicant 16import hwsim_utils 17from tshark import run_tshark 18from utils import HwsimSkip, fail_test, alloc_fail, wait_fail_trigger 19from test_ap_acs import wait_acs 20 21def test_owe(dev, apdev): 22 """Opportunistic Wireless Encryption""" 23 if "OWE" not in dev[0].get_capability("key_mgmt"): 24 raise HwsimSkip("OWE not supported") 25 params = {"ssid": "owe", 26 "wpa": "2", 27 "ieee80211w": "2", 28 "wpa_key_mgmt": "OWE", 29 "rsn_pairwise": "CCMP"} 30 hapd = hostapd.add_ap(apdev[0], params) 31 bssid = hapd.own_addr() 32 conf = hapd.request("GET_CONFIG") 33 if "key_mgmt=OWE" not in conf.splitlines(): 34 logger.info("GET_CONFIG:\n" + conf) 35 raise Exception("GET_CONFIG did not report correct key_mgmt") 36 37 dev[0].scan_for_bss(bssid, freq="2412") 38 bss = dev[0].get_bss(bssid) 39 if "[WPA2-OWE-CCMP]" not in bss['flags']: 40 raise Exception("OWE AKM not recognized: " + bss['flags']) 41 42 id = dev[0].connect("owe", key_mgmt="OWE", ieee80211w="2", scan_freq="2412") 43 hapd.wait_sta() 44 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr()) 45 pmk_w = dev[0].get_pmk(id) 46 if pmk_h != pmk_w: 47 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w)) 48 hwsim_utils.test_connectivity(dev[0], hapd) 49 val = dev[0].get_status_field("key_mgmt") 50 if val != "OWE": 51 raise Exception("Unexpected key_mgmt: " + val) 52 53def test_owe_groups(dev, apdev): 54 """Opportunistic Wireless Encryption - DH groups""" 55 if "OWE" not in dev[0].get_capability("key_mgmt"): 56 raise HwsimSkip("OWE not supported") 57 params = {"ssid": "owe", 58 "wpa": "2", 59 "wpa_key_mgmt": "OWE", 60 "rsn_pairwise": "CCMP"} 61 hapd = hostapd.add_ap(apdev[0], params) 62 bssid = hapd.own_addr() 63 64 dev[0].scan_for_bss(bssid, freq="2412") 65 for group in [19, 20, 21]: 66 dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group)) 67 hapd.wait_sta() 68 hwsim_utils.test_connectivity(dev[0], hapd) 69 dev[0].request("REMOVE_NETWORK all") 70 dev[0].wait_disconnected() 71 dev[0].dump_monitor() 72 hapd.dump_monitor() 73 74def test_owe_pmksa_caching(dev, apdev): 75 """Opportunistic Wireless Encryption and PMKSA caching""" 76 try: 77 run_owe_pmksa_caching(dev, apdev) 78 finally: 79 dev[0].set("reassoc_same_bss_optim", "0") 80 81def test_owe_pmksa_caching_connect_cmd(dev, apdev): 82 """Opportunistic Wireless Encryption and PMKSA caching using cfg80211 connect command""" 83 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 84 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 85 try: 86 run_owe_pmksa_caching([wpas], apdev) 87 finally: 88 wpas.set("reassoc_same_bss_optim", "0") 89 90def run_owe_pmksa_caching(dev, apdev): 91 if "OWE" not in dev[0].get_capability("key_mgmt"): 92 raise HwsimSkip("OWE not supported") 93 params = {"ssid": "owe", 94 "wpa": "2", 95 "wpa_key_mgmt": "OWE", 96 "rsn_pairwise": "CCMP"} 97 hapd = hostapd.add_ap(apdev[0], params) 98 bssid = hapd.own_addr() 99 100 dev[0].set("reassoc_same_bss_optim", "1") 101 dev[0].scan_for_bss(bssid, freq="2412") 102 id = dev[0].connect("owe", key_mgmt="OWE") 103 hapd.wait_sta() 104 hwsim_utils.test_connectivity(dev[0], hapd) 105 pmksa = dev[0].get_pmksa(bssid) 106 dev[0].request("DISCONNECT") 107 dev[0].wait_disconnected() 108 dev[0].dump_monitor() 109 110 dev[0].select_network(id, 2412) 111 dev[0].wait_connected() 112 hapd.wait_sta() 113 hwsim_utils.test_connectivity(dev[0], hapd) 114 pmksa2 = dev[0].get_pmksa(bssid) 115 dev[0].request("DISCONNECT") 116 dev[0].wait_disconnected() 117 dev[0].dump_monitor() 118 119 if "OK" not in hapd.request("PMKSA_FLUSH"): 120 raise Exception("PMKSA_FLUSH failed") 121 122 dev[0].select_network(id, 2412) 123 dev[0].wait_connected() 124 hapd.wait_sta() 125 hwsim_utils.test_connectivity(dev[0], hapd) 126 pmksa3 = dev[0].get_pmksa(bssid) 127 128 if pmksa is None or pmksa2 is None or pmksa3 is None: 129 raise Exception("PMKSA entry missing") 130 if pmksa['pmkid'] != pmksa2['pmkid']: 131 raise Exception("Unexpected PMKID change when using PMKSA caching") 132 if pmksa['pmkid'] == pmksa3['pmkid']: 133 raise Exception("PMKID did not change after PMKSA cache flush") 134 135 dev[0].request("REASSOCIATE") 136 dev[0].wait_connected() 137 pmksa4 = dev[0].get_pmksa(bssid) 138 if pmksa3['pmkid'] != pmksa4['pmkid']: 139 raise Exception("Unexpected PMKID change when using PMKSA caching [2]") 140 141def test_owe_and_psk(dev, apdev): 142 """Opportunistic Wireless Encryption and WPA2-PSK enabled""" 143 if "OWE" not in dev[0].get_capability("key_mgmt"): 144 raise HwsimSkip("OWE not supported") 145 params = {"ssid": "owe+psk", 146 "wpa": "2", 147 "wpa_key_mgmt": "OWE WPA-PSK", 148 "rsn_pairwise": "CCMP", 149 "wpa_passphrase": "12345678"} 150 hapd = hostapd.add_ap(apdev[0], params) 151 bssid = hapd.own_addr() 152 153 dev[0].scan_for_bss(bssid, freq="2412") 154 dev[0].connect("owe+psk", psk="12345678") 155 hapd.wait_sta() 156 hwsim_utils.test_connectivity(dev[0], hapd) 157 158 dev[1].scan_for_bss(bssid, freq="2412") 159 dev[1].connect("owe+psk", key_mgmt="OWE") 160 hapd.wait_sta() 161 hwsim_utils.test_connectivity(dev[1], hapd) 162 163def test_owe_transition_mode(dev, apdev): 164 """Opportunistic Wireless Encryption transition mode""" 165 run_owe_transition_mode(dev, apdev) 166 167def test_owe_transition_mode_connect_cmd(dev, apdev): 168 """Opportunistic Wireless Encryption transition mode using cfg80211 connect command""" 169 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 170 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 171 run_owe_transition_mode([wpas], apdev) 172 173def test_owe_transition_mode_mismatch1(dev, apdev): 174 """Opportunistic Wireless Encryption transition mode (mismatch 1)""" 175 run_owe_transition_mode(dev, apdev, adv_bssid0="02:11:22:33:44:55") 176 177def test_owe_transition_mode_mismatch2(dev, apdev): 178 """Opportunistic Wireless Encryption transition mode (mismatch 2)""" 179 run_owe_transition_mode(dev, apdev, adv_bssid1="02:11:22:33:44:66") 180 181def test_owe_transition_mode_mismatch3(dev, apdev): 182 """Opportunistic Wireless Encryption transition mode (mismatch 3)""" 183 run_owe_transition_mode(dev, apdev, adv_bssid0="02:11:22:33:44:55", 184 adv_bssid1="02:11:22:33:44:66") 185 186def run_owe_transition_mode(dev, apdev, adv_bssid0=None, adv_bssid1=None): 187 if "OWE" not in dev[0].get_capability("key_mgmt"): 188 raise HwsimSkip("OWE not supported") 189 dev[0].flush_scan_cache() 190 adv_bssid = adv_bssid0 if adv_bssid0 else apdev[1]['bssid'] 191 params = {"ssid": "owe-random", 192 "wpa": "2", 193 "wpa_key_mgmt": "OWE", 194 "rsn_pairwise": "CCMP", 195 "ieee80211w": "2", 196 "owe_transition_bssid": adv_bssid, 197 "owe_transition_ssid": '"owe-test"', 198 "ignore_broadcast_ssid": "1"} 199 hapd = hostapd.add_ap(apdev[0], params) 200 bssid = hapd.own_addr() 201 202 adv_bssid = adv_bssid1 if adv_bssid1 else apdev[0]['bssid'] 203 params = {"ssid": "owe-test", 204 "owe_transition_bssid": adv_bssid, 205 "owe_transition_ssid": '"owe-random"'} 206 hapd2 = hostapd.add_ap(apdev[1], params) 207 bssid2 = hapd2.own_addr() 208 209 dev[0].scan_for_bss(bssid, freq="2412") 210 dev[0].scan_for_bss(bssid2, freq="2412") 211 212 bss = dev[0].get_bss(bssid) 213 if "[WPA2-OWE-CCMP]" not in bss['flags']: 214 raise Exception("OWE AKM not recognized: " + bss['flags']) 215 if "[OWE-TRANS]" not in bss['flags']: 216 raise Exception("OWE transition not recognized: " + bss['flags']) 217 218 bss = dev[0].get_bss(bssid2) 219 if "[OWE-TRANS-OPEN]" not in bss['flags']: 220 raise Exception("OWE transition (open) not recognized: " + bss['flags']) 221 222 id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", 223 scan_freq="2412") 224 hapd.wait_sta() 225 hwsim_utils.test_connectivity(dev[0], hapd) 226 val = dev[0].get_status_field("key_mgmt") 227 if val != "OWE": 228 raise Exception("Unexpected key_mgmt: " + val) 229 230 logger.info("Move to OWE only mode (disable transition mode)") 231 232 dev[0].request("DISCONNECT") 233 dev[0].wait_disconnected() 234 dev[0].dump_monitor() 235 236 hapd2.disable() 237 hapd.disable() 238 dev[0].flush_scan_cache() 239 hapd.set("owe_transition_bssid", "00:00:00:00:00:00") 240 hapd.set("ignore_broadcast_ssid", '0') 241 hapd.set("ssid", 'owe-test') 242 hapd.enable() 243 244 dev[0].scan_for_bss(bssid, freq="2412") 245 dev[0].select_network(id, 2412) 246 dev[0].wait_connected() 247 hapd.wait_sta() 248 hwsim_utils.test_connectivity(dev[0], hapd) 249 250def test_owe_transition_mode_ifname(dev, apdev): 251 """Opportunistic Wireless Encryption transition mode (ifname)""" 252 if "OWE" not in dev[0].get_capability("key_mgmt"): 253 raise HwsimSkip("OWE not supported") 254 dev[0].flush_scan_cache() 255 params = {"ssid": "owe-random", 256 "wpa": "2", 257 "wpa_key_mgmt": "OWE", 258 "rsn_pairwise": "CCMP", 259 "ieee80211w": "2", 260 "owe_transition_ifname": apdev[1]['ifname'], 261 "ignore_broadcast_ssid": "1"} 262 hapd = hostapd.add_ap(apdev[0], params) 263 bssid = hapd.own_addr() 264 265 params = {"ssid": "owe-test", 266 "owe_transition_ifname": apdev[0]['ifname']} 267 hapd2 = hostapd.add_ap(apdev[1], params) 268 bssid2 = hapd2.own_addr() 269 270 dev[0].scan_for_bss(bssid, freq="2412") 271 dev[0].scan_for_bss(bssid2, freq="2412") 272 273 id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", 274 scan_freq="2412") 275 val = dev[0].get_status_field("key_mgmt") 276 if val != "OWE": 277 raise Exception("Unexpected key_mgmt: " + val) 278 279def test_owe_transition_mode_ifname_acs(dev, apdev): 280 """Opportunistic Wireless Encryption transition mode (ifname, ACS)""" 281 run_owe_transition_mode_ifname_acs(dev, apdev, wait_first=False) 282 283def test_owe_transition_mode_ifname_acs2(dev, apdev): 284 """Opportunistic Wireless Encryption transition mode (ifname, ACS)""" 285 run_owe_transition_mode_ifname_acs(dev, apdev, wait_first=True) 286 287def run_owe_transition_mode_ifname_acs(dev, apdev, wait_first): 288 if "OWE" not in dev[0].get_capability("key_mgmt"): 289 raise HwsimSkip("OWE not supported") 290 dev[0].flush_scan_cache() 291 params = {"ssid": "owe-random", 292 "channel": "0", 293 "wpa": "2", 294 "wpa_key_mgmt": "OWE", 295 "rsn_pairwise": "CCMP", 296 "ieee80211w": "2", 297 "owe_transition_ifname": apdev[1]['ifname'], 298 "ignore_broadcast_ssid": "1"} 299 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) 300 bssid = hapd.own_addr() 301 302 if wait_first: 303 wait_acs(hapd) 304 305 params = {"ssid": "owe-test", 306 "channel": "0", 307 "owe_transition_ifname": apdev[0]['ifname']} 308 hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False) 309 bssid2 = hapd2.own_addr() 310 311 wait_acs(hapd2) 312 if not wait_first: 313 state = hapd.get_status_field("state") 314 if state == "ACS-STARTED": 315 time.sleep(5) 316 state = hapd.get_status_field("state") 317 if state != "ENABLED": 318 raise Exception("AP1 startup did not succeed") 319 320 freq = hapd.get_status_field("freq") 321 freq2 = hapd2.get_status_field("freq") 322 323 dev[0].scan_for_bss(bssid, freq=freq) 324 dev[0].scan_for_bss(bssid2, freq=freq2) 325 326 id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", 327 scan_freq="%s %s" % (freq, freq2)) 328 val = dev[0].get_status_field("key_mgmt") 329 if val != "OWE": 330 raise Exception("Unexpected key_mgmt: " + val) 331 332def test_owe_transition_mode_open_only_ap(dev, apdev): 333 """Opportunistic Wireless Encryption transition mode connect to open-only AP""" 334 if "OWE" not in dev[0].get_capability("key_mgmt"): 335 raise HwsimSkip("OWE not supported") 336 dev[0].flush_scan_cache() 337 params = {"ssid": "owe-test-open"} 338 hapd = hostapd.add_ap(apdev[0], params) 339 bssid = hapd.own_addr() 340 341 dev[0].scan_for_bss(bssid, freq="2412") 342 343 bss = dev[0].get_bss(bssid) 344 345 id = dev[0].connect("owe-test-open", key_mgmt="OWE", ieee80211w="2", 346 scan_freq="2412") 347 hwsim_utils.test_connectivity(dev[0], hapd) 348 val = dev[0].get_status_field("key_mgmt") 349 if val != "NONE": 350 raise Exception("Unexpected key_mgmt: " + val) 351 352def test_owe_only_sta(dev, apdev): 353 """Opportunistic Wireless Encryption transition mode disabled on STA""" 354 if "OWE" not in dev[0].get_capability("key_mgmt"): 355 raise HwsimSkip("OWE not supported") 356 dev[0].flush_scan_cache() 357 params = {"ssid": "owe-test-open"} 358 hapd = hostapd.add_ap(apdev[0], params) 359 bssid = hapd.own_addr() 360 361 dev[0].scan_for_bss(bssid, freq="2412") 362 id = dev[0].connect("owe-test-open", key_mgmt="OWE", ieee80211w="2", 363 scan_freq="2412", owe_only="1", wait_connect=False) 364 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 365 "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10) 366 if not ev: 367 raise Exception("Unknown result for the connection attempt") 368 if "CTRL-EVENT-CONNECTED" in ev: 369 raise Exception("Unexpected connection to open network") 370 dev[0].request("DISCONNECT") 371 dev[0].dump_monitor() 372 373 params = {"ssid": "owe-test-open", 374 "wpa": "2", 375 "ieee80211w": "2", 376 "wpa_key_mgmt": "OWE", 377 "rsn_pairwise": "CCMP"} 378 hapd2 = hostapd.add_ap(apdev[1], params) 379 dev[0].request("RECONNECT") 380 dev[0].wait_connected() 381 382def test_owe_transition_mode_open_multiple_scans(dev, apdev): 383 """Opportunistic Wireless Encryption transition mode and need for multiple scans""" 384 if "OWE" not in dev[0].get_capability("key_mgmt"): 385 raise HwsimSkip("OWE not supported") 386 dev[0].flush_scan_cache() 387 params = {"ssid": "owe-test", 388 "owe_transition_bssid": apdev[0]['bssid'], 389 "owe_transition_ssid": '"owe-random"'} 390 hapd2 = hostapd.add_ap(apdev[1], params) 391 bssid2 = hapd2.own_addr() 392 393 dev[0].scan_for_bss(bssid2, freq="2412") 394 395 dev[0].dump_monitor() 396 id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", 397 scan_freq="2412", wait_connect=False) 398 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=1) 399 400 params = {"ssid": "owe-random", 401 "wpa": "2", 402 "wpa_key_mgmt": "OWE", 403 "rsn_pairwise": "CCMP", 404 "ieee80211w": "2", 405 "owe_transition_bssid": apdev[1]['bssid'], 406 "owe_transition_ssid": '"owe-test"', 407 "ignore_broadcast_ssid": "1"} 408 hapd = hostapd.add_ap(apdev[0], params) 409 bssid = hapd.own_addr() 410 411 dev[0].wait_connected() 412 413 val = dev[0].get_status_field("key_mgmt") 414 if val != "OWE": 415 raise Exception("Unexpected key_mgmt: " + val) 416 417def test_owe_transition_mode_multi_bss(dev, apdev): 418 """Opportunistic Wireless Encryption transition mode (multi BSS)""" 419 try: 420 run_owe_transition_mode_multi_bss(dev, apdev) 421 finally: 422 dev[0].request("SCAN_INTERVAL 5") 423 424def run_owe_transition_mode_multi_bss(dev, apdev): 425 if "OWE" not in dev[0].get_capability("key_mgmt"): 426 raise HwsimSkip("OWE not supported") 427 ifname1 = apdev[0]['ifname'] 428 ifname2 = apdev[0]['ifname'] + '-2' 429 hapd1 = hostapd.add_bss(apdev[0], ifname1, 'owe-bss-1.conf') 430 hapd2 = hostapd.add_bss(apdev[0], ifname2, 'owe-bss-2.conf') 431 hapd2.bssidx = 1 432 433 bssid = hapd1.own_addr() 434 bssid2 = hapd2.own_addr() 435 436 # Beaconing with the OWE Transition Mode element can start only once both 437 # BSSs are enabled, so the very first Beacon frame may go out without this 438 # element. Wait a bit to avoid getting incomplete scan results. 439 time.sleep(0.1) 440 441 dev[0].request("SCAN_INTERVAL 1") 442 dev[0].scan_for_bss(bssid2, freq="2412") 443 dev[0].scan_for_bss(bssid, freq="2412") 444 dev[0].connect("transition-mode-open", key_mgmt="OWE") 445 val = dev[0].get_status_field("bssid") 446 if val != bssid2: 447 raise Exception("Unexpected bssid: " + val) 448 val = dev[0].get_status_field("key_mgmt") 449 if val != "OWE": 450 raise Exception("Unexpected key_mgmt: " + val) 451 hwsim_utils.test_connectivity(dev[0], hapd2) 452 453def test_owe_transition_mode_rsne_mismatch(dev, apdev): 454 """Opportunistic Wireless Encryption transition mode and RSNE mismatch""" 455 if "OWE" not in dev[0].get_capability("key_mgmt"): 456 raise HwsimSkip("OWE not supported") 457 dev[0].flush_scan_cache() 458 params = {"ssid": "owe-random", 459 "wpa": "2", 460 "wpa_key_mgmt": "OWE", 461 "rsn_pairwise": "CCMP", 462 "ieee80211w": "2", 463 "rsne_override_eapol": "30140100000fac040100000fac040100000fac020c00", 464 "owe_transition_bssid": apdev[1]['bssid'], 465 "owe_transition_ssid": '"owe-test"', 466 "ignore_broadcast_ssid": "1"} 467 hapd = hostapd.add_ap(apdev[0], params) 468 bssid = hapd.own_addr() 469 470 params = {"ssid": "owe-test", 471 "owe_transition_bssid": apdev[0]['bssid'], 472 "owe_transition_ssid": '"owe-random"'} 473 hapd2 = hostapd.add_ap(apdev[1], params) 474 bssid2 = hapd2.own_addr() 475 476 dev[0].scan_for_bss(bssid, freq="2412") 477 dev[0].scan_for_bss(bssid2, freq="2412") 478 479 id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", 480 scan_freq="2412", wait_connect=False) 481 ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5) 482 if ev is None: 483 raise Exception("OWE PMKSA not created") 484 ev = dev[0].wait_event(["WPA: IE in 3/4 msg does not match with IE in Beacon/ProbeResp"], 485 timeout=5) 486 if ev is None: 487 raise Exception("RSNE mismatch not reported") 488 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 489 "CTRL-EVENT-DISCONNECTED"], timeout=5) 490 dev[0].request("REMOVE_NETWORK all") 491 if ev is None: 492 raise Exception("No disconnection seen") 493 if "CTRL-EVENT-DISCONNECTED" not in ev: 494 raise Exception("Unexpected connection") 495 if "reason=17 locally_generated=1" not in ev: 496 raise Exception("Unexpected disconnection reason: " + ev) 497 498def test_owe_unsupported_group(dev, apdev): 499 """Opportunistic Wireless Encryption and unsupported group""" 500 try: 501 run_owe_unsupported_group(dev, apdev) 502 finally: 503 dev[0].request("VENDOR_ELEM_REMOVE 13 *") 504 505def test_owe_unsupported_group_connect_cmd(dev, apdev): 506 """Opportunistic Wireless Encryption and unsupported group using cfg80211 connect command""" 507 try: 508 wpas = None 509 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 510 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 511 run_owe_unsupported_group([wpas], apdev) 512 finally: 513 if wpas: 514 wpas.request("VENDOR_ELEM_REMOVE 13 *") 515 516def run_owe_unsupported_group(dev, apdev): 517 if "OWE" not in dev[0].get_capability("key_mgmt"): 518 raise HwsimSkip("OWE not supported") 519 # Override OWE Dh Parameters element with a payload that uses invalid group 520 # 0 (and actual group 19 data) to make the AP reject this with the specific 521 # status code 77. 522 dev[0].request("VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") 523 524 params = {"ssid": "owe", 525 "wpa": "2", 526 "wpa_key_mgmt": "OWE", 527 "rsn_pairwise": "CCMP"} 528 hapd = hostapd.add_ap(apdev[0], params) 529 bssid = hapd.own_addr() 530 531 dev[0].scan_for_bss(bssid, freq="2412") 532 dev[0].connect("owe", key_mgmt="OWE", wait_connect=False) 533 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10) 534 dev[0].request("DISCONNECT") 535 if ev is None: 536 raise Exception("Association not rejected") 537 if "status_code=77" not in ev: 538 raise Exception("Unexpected rejection reason: " + ev) 539 540def test_owe_limited_group_set(dev, apdev): 541 """Opportunistic Wireless Encryption and limited group set""" 542 if "OWE" not in dev[0].get_capability("key_mgmt"): 543 raise HwsimSkip("OWE not supported") 544 params = {"ssid": "owe", 545 "wpa": "2", 546 "wpa_key_mgmt": "OWE", 547 "rsn_pairwise": "CCMP", 548 "owe_groups": "20 21"} 549 hapd = hostapd.add_ap(apdev[0], params) 550 bssid = hapd.own_addr() 551 552 dev[0].scan_for_bss(bssid, freq="2412") 553 dev[0].connect("owe", key_mgmt="OWE", owe_group="19", wait_connect=False) 554 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10) 555 dev[0].request("DISCONNECT") 556 if ev is None: 557 raise Exception("Association not rejected") 558 if "status_code=77" not in ev: 559 raise Exception("Unexpected rejection reason: " + ev) 560 dev[0].dump_monitor() 561 562 for group in [20, 21]: 563 dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group)) 564 dev[0].request("REMOVE_NETWORK all") 565 dev[0].wait_disconnected() 566 dev[0].dump_monitor() 567 568def test_owe_limited_group_set_pmf(dev, apdev, params): 569 """Opportunistic Wireless Encryption and limited group set (PMF)""" 570 if "OWE" not in dev[0].get_capability("key_mgmt"): 571 raise HwsimSkip("OWE not supported") 572 pcapng = os.path.join(params['logdir'], "hwsim0.pcapng") 573 574 params = {"ssid": "owe", 575 "wpa": "2", 576 "ieee80211w": "2", 577 "wpa_key_mgmt": "OWE", 578 "rsn_pairwise": "CCMP", 579 "owe_groups": "21"} 580 hapd = hostapd.add_ap(apdev[0], params) 581 bssid = hapd.own_addr() 582 583 dev[0].scan_for_bss(bssid, freq="2412") 584 dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2", 585 scan_freq="2412", wait_connect=False) 586 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10) 587 dev[0].request("DISCONNECT") 588 if ev is None: 589 raise Exception("Association not rejected") 590 if "status_code=77" not in ev: 591 raise Exception("Unexpected rejection reason: " + ev) 592 dev[0].dump_monitor() 593 594 dev[0].connect("owe", key_mgmt="OWE", owe_group="20", ieee80211w="2", 595 scan_freq="2412", wait_connect=False) 596 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10) 597 dev[0].request("DISCONNECT") 598 if ev is None: 599 raise Exception("Association not rejected (2)") 600 if "status_code=77" not in ev: 601 raise Exception("Unexpected rejection reason (2): " + ev) 602 dev[0].dump_monitor() 603 604 dev[0].connect("owe", key_mgmt="OWE", owe_group="21", ieee80211w="2", 605 scan_freq="2412") 606 dev[0].request("REMOVE_NETWORK all") 607 dev[0].wait_disconnected() 608 dev[0].dump_monitor() 609 610 out = run_tshark(pcapng, 611 "wlan.fc.type_subtype == 1", 612 display=['wlan_mgt.fixed.status_code']) 613 status = out.splitlines() 614 logger.info("Association Response frame status codes: " + str(status)) 615 if len(status) != 3: 616 raise Exception("Unexpected number of Association Response frames") 617 if (int(status[0], base=0) != 77 or int(status[1], base=0) != 77 or 618 int(status[2], base=0) != 0): 619 raise Exception("Unexpected Association Response frame status code") 620 621def test_owe_group_negotiation(dev, apdev): 622 """Opportunistic Wireless Encryption and group negotiation""" 623 run_owe_group_negotiation(dev[0], apdev) 624 625def test_owe_group_negotiation_connect_cmd(dev, apdev): 626 """Opportunistic Wireless Encryption and group negotiation (connect command)""" 627 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 628 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 629 run_owe_group_negotiation(wpas, apdev) 630 631def run_owe_group_negotiation(dev, apdev): 632 if "OWE" not in dev.get_capability("key_mgmt"): 633 raise HwsimSkip("OWE not supported") 634 params = {"ssid": "owe", 635 "wpa": "2", 636 "wpa_key_mgmt": "OWE", 637 "rsn_pairwise": "CCMP", 638 "owe_groups": "21"} 639 hapd = hostapd.add_ap(apdev[0], params) 640 bssid = hapd.own_addr() 641 642 dev.scan_for_bss(bssid, freq="2412") 643 dev.connect("owe", key_mgmt="OWE") 644 645def test_owe_assoc_reject(dev, apdev): 646 """Opportunistic Wireless Encryption association rejection handling""" 647 if "OWE" not in dev[0].get_capability("key_mgmt"): 648 raise HwsimSkip("OWE not supported") 649 params = {"ssid": "owe", 650 "require_ht": "1", 651 "wpa": "2", 652 "ieee80211w": "2", 653 "wpa_key_mgmt": "OWE", 654 "rsn_pairwise": "CCMP", 655 "owe_groups": "19"} 656 hapd = hostapd.add_ap(apdev[0], params) 657 bssid = hapd.own_addr() 658 659 # First, reject two associations with HT-required (i.e., not OWE related) 660 dev[0].scan_for_bss(bssid, freq="2412") 661 dev[0].connect("owe", key_mgmt="OWE", ieee80211w="2", 662 disable_ht="1", scan_freq="2412", wait_connect=False) 663 for i in range(0, 2): 664 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10) 665 if ev is None: 666 raise Exception("Association rejection not reported") 667 668 # Then, verify that STA tries OWE with the default group (19) on the next 669 # attempt instead of having moved to testing another group. 670 hapd.set("require_ht", "0") 671 for i in range(0, 2): 672 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT", 673 "CTRL-EVENT-CONNECTED"], timeout=10) 674 if ev is None: 675 raise Exception("Association result not reported") 676 if "CTRL-EVENT-CONNECTED" in ev: 677 break 678 if "status_code=77" in ev: 679 raise Exception("Unexpected unsupport group rejection") 680 if "CTRL-EVENT-CONNECTED" not in ev: 681 raise Exception("Did not connect successfully") 682 683def test_owe_local_errors(dev, apdev): 684 """Opportunistic Wireless Encryption - local errors on supplicant""" 685 if "OWE" not in dev[0].get_capability("key_mgmt"): 686 raise HwsimSkip("OWE not supported") 687 params = {"ssid": "owe", 688 "wpa": "2", 689 "ieee80211w": "2", 690 "wpa_key_mgmt": "OWE", 691 "rsn_pairwise": "CCMP"} 692 hapd = hostapd.add_ap(apdev[0], params) 693 bssid = hapd.own_addr() 694 695 dev[0].scan_for_bss(bssid, freq="2412") 696 697 tests = [(1, "crypto_ecdh_init;owe_build_assoc_req"), 698 (1, "crypto_ecdh_get_pubkey;owe_build_assoc_req"), 699 (1, "wpabuf_alloc;owe_build_assoc_req")] 700 for count, func in tests: 701 with alloc_fail(dev[0], count, func): 702 dev[0].connect("owe", key_mgmt="OWE", owe_group="20", 703 ieee80211w="2", 704 scan_freq="2412", wait_connect=False) 705 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 706 dev[0].request("REMOVE_NETWORK all") 707 dev[0].dump_monitor() 708 709 tests = [(1, "crypto_ecdh_set_peerkey;owe_process_assoc_resp"), 710 (1, "crypto_ecdh_get_pubkey;owe_process_assoc_resp"), 711 (1, "wpabuf_alloc;=owe_process_assoc_resp")] 712 for count, func in tests: 713 with alloc_fail(dev[0], count, func): 714 dev[0].connect("owe", key_mgmt="OWE", owe_group="20", 715 ieee80211w="2", 716 scan_freq="2412", wait_connect=False) 717 dev[0].wait_disconnected() 718 dev[0].request("REMOVE_NETWORK all") 719 dev[0].dump_monitor() 720 721 tests = [(1, "hmac_sha256;owe_process_assoc_resp", 19), 722 (1, "hmac_sha256_kdf;owe_process_assoc_resp", 19), 723 (1, "hmac_sha384;owe_process_assoc_resp", 20), 724 (1, "hmac_sha384_kdf;owe_process_assoc_resp", 20), 725 (1, "hmac_sha512;owe_process_assoc_resp", 21), 726 (1, "hmac_sha512_kdf;owe_process_assoc_resp", 21)] 727 for count, func, group in tests: 728 with fail_test(dev[0], count, func): 729 dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group), 730 ieee80211w="2", 731 scan_freq="2412", wait_connect=False) 732 dev[0].wait_disconnected() 733 dev[0].request("REMOVE_NETWORK all") 734 dev[0].dump_monitor() 735 736 dev[0].connect("owe", key_mgmt="OWE", owe_group="18", 737 ieee80211w="2", 738 scan_freq="2412", wait_connect=False) 739 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=5) 740 if ev is None: 741 raise Exception("No authentication attempt") 742 time.sleep(0.5) 743 dev[0].request("REMOVE_NETWORK all") 744 dev[0].dump_monitor() 745 746def hapd_auth(hapd): 747 for i in range(0, 10): 748 req = hapd.mgmt_rx() 749 if req is None: 750 raise Exception("MGMT RX wait timed out") 751 if req['subtype'] == 11: 752 break 753 req = None 754 if not req: 755 raise Exception("Authentication frame not received") 756 757 resp = {} 758 resp['fc'] = req['fc'] 759 resp['da'] = req['sa'] 760 resp['sa'] = req['da'] 761 resp['bssid'] = req['bssid'] 762 resp['payload'] = struct.pack('<HHH', 0, 2, 0) 763 hapd.mgmt_tx(resp) 764 765def hapd_assoc(hapd, extra): 766 for i in range(0, 10): 767 req = hapd.mgmt_rx() 768 if req is None: 769 raise Exception("MGMT RX wait timed out") 770 if req['subtype'] == 0: 771 break 772 req = None 773 if not req: 774 raise Exception("Association Request frame not received") 775 776 resp = {} 777 resp['fc'] = 0x0010 778 resp['da'] = req['sa'] 779 resp['sa'] = req['da'] 780 resp['bssid'] = req['bssid'] 781 payload = struct.pack('<HHH', 0x0411, 0, 0xc001) 782 payload += binascii.unhexlify("010882848b960c121824") 783 resp['payload'] = payload + extra 784 hapd.mgmt_tx(resp) 785 786def test_owe_invalid_assoc_resp(dev, apdev): 787 """Opportunistic Wireless Encryption - invalid Association Response frame""" 788 if "OWE" not in dev[0].get_capability("key_mgmt"): 789 raise HwsimSkip("OWE not supported") 790 params = {"ssid": "owe", 791 "wpa": "2", 792 "ieee80211w": "2", 793 "wpa_key_mgmt": "OWE", 794 "rsn_pairwise": "CCMP"} 795 hapd = hostapd.add_ap(apdev[0], params) 796 bssid = hapd.own_addr() 797 798 dev[0].scan_for_bss(bssid, freq="2412") 799 800 hapd.set("ext_mgmt_frame_handling", "1") 801 # OWE: No Diffie-Hellman Parameter element found in Association Response frame 802 tests = [b''] 803 # No room for group --> no DH Params 804 tests += [binascii.unhexlify('ff0120')] 805 # OWE: Unexpected Diffie-Hellman group in response: 18 806 tests += [binascii.unhexlify('ff03201200')] 807 # OWE: Invalid peer DH public key 808 tests += [binascii.unhexlify('ff23201300' + 31*'00' + '01')] 809 # OWE: Invalid peer DH public key 810 tests += [binascii.unhexlify('ff24201300' + 33*'ee')] 811 for extra in tests: 812 dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2", 813 scan_freq="2412", wait_connect=False) 814 hapd_auth(hapd) 815 hapd_assoc(hapd, extra) 816 dev[0].wait_disconnected() 817 dev[0].request("REMOVE_NETWORK all") 818 dev[0].dump_monitor() 819 820 # OWE: Empty public key (this ends up getting padded to a valid point) 821 dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2", 822 scan_freq="2412", wait_connect=False) 823 hapd_auth(hapd) 824 hapd_assoc(hapd, binascii.unhexlify('ff03201300')) 825 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED", "PMKSA-CACHE-ADDED"], 826 timeout=5) 827 if ev is None: 828 raise Exception("No result reported for empty public key") 829 dev[0].request("REMOVE_NETWORK all") 830 dev[0].dump_monitor() 831 832def start_owe(dev, apdev, workaround=0): 833 if "OWE" not in dev[0].get_capability("key_mgmt"): 834 raise HwsimSkip("OWE not supported") 835 params = {"ssid": "owe", 836 "wpa": "2", 837 "ieee80211w": "2", 838 "wpa_key_mgmt": "OWE", 839 "owe_ptk_workaround": str(workaround), 840 "rsn_pairwise": "CCMP"} 841 hapd = hostapd.add_ap(apdev[0], params) 842 dev[0].scan_for_bss(hapd.own_addr(), freq="2412") 843 return hapd 844 845def owe_check_ok(dev, hapd, owe_group, owe_ptk_workaround): 846 dev.connect("owe", key_mgmt="OWE", ieee80211w="2", 847 owe_group=owe_group, owe_ptk_workaround=owe_ptk_workaround, 848 scan_freq="2412") 849 hapd.wait_sta() 850 dev.request("REMOVE_NETWORK all") 851 dev.wait_disconnected() 852 dev.dump_monitor() 853 854def test_owe_ptk_workaround_ap(dev, apdev): 855 """Opportunistic Wireless Encryption - AP using PTK workaround""" 856 hapd = start_owe(dev, apdev, workaround=1) 857 for group, workaround in [(19, 0), (20, 0), (21, 0), 858 (19, 1), (20, 1), (21, 1)]: 859 owe_check_ok(dev[0], hapd, str(group), str(workaround)) 860 861def test_owe_ptk_hash(dev, apdev): 862 """Opportunistic Wireless Encryption - PTK derivation hash alg""" 863 hapd = start_owe(dev, apdev) 864 for group, workaround in [(19, 0), (20, 0), (21, 0), (19, 1)]: 865 owe_check_ok(dev[0], hapd, str(group), str(workaround)) 866 867 for group in [20, 21]: 868 dev[0].connect("owe", key_mgmt="OWE", ieee80211w="2", 869 owe_group=str(group), owe_ptk_workaround="1", 870 scan_freq="2412", wait_connect=False) 871 ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=10) 872 if ev is None: 873 raise Exception("Could not complete OWE association") 874 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 875 "CTRL-EVENT-DISCONNECTED"], timeout=5) 876 if ev is None: 877 raise Exception("Unknown connection result") 878 if "CTRL-EVENT-CONNECTED" in ev: 879 raise Exception("Unexpected connection") 880 dev[0].request("REMOVE_NETWORK all") 881 ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], timeout=5) 882 if ev is None: 883 raise Exception("No PMKSA cache removal event seen") 884 dev[0].dump_monitor() 885 886def test_owe_transition_mode_disable(dev, apdev): 887 """Opportunistic Wireless Encryption transition mode disable""" 888 if "OWE" not in dev[0].get_capability("key_mgmt"): 889 raise HwsimSkip("OWE not supported") 890 dev[0].flush_scan_cache() 891 params = {"ssid": "owe-random", 892 "wpa": "2", 893 "wpa_key_mgmt": "OWE", 894 "rsn_pairwise": "CCMP", 895 "ieee80211w": "2", 896 "transition_disable": '0x08', 897 "owe_transition_bssid": apdev[1]['bssid'], 898 "owe_transition_ssid": '"owe-test"', 899 "ignore_broadcast_ssid": "1"} 900 hapd = hostapd.add_ap(apdev[0], params) 901 bssid = hapd.own_addr() 902 903 params = {"ssid": "owe-test", 904 "owe_transition_bssid": apdev[0]['bssid'], 905 "owe_transition_ssid": '"owe-random"'} 906 hapd2 = hostapd.add_ap(apdev[1], params) 907 bssid2 = hapd2.own_addr() 908 909 dev[0].scan_for_bss(bssid, freq="2412") 910 dev[0].scan_for_bss(bssid2, freq="2412") 911 912 id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", 913 scan_freq="2412") 914 915 ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=1) 916 if ev is None: 917 raise Exception("Transition disable not indicated") 918 if ev.split(' ')[1] != "08": 919 raise Exception("Unexpected transition disable bitmap: " + ev) 920 921 val = dev[0].get_network(id, "owe_only") 922 if val != "1": 923 raise Exception("Unexpected owe_only value: " + val) 924 925 dev[0].request("DISCONNECT") 926 dev[0].wait_disconnected() 927 dev[0].request("RECONNECT") 928 dev[0].wait_connected() 929 930def test_owe_sa_query(dev, apdev): 931 """Opportunistic Wireless Encryption - SA Query""" 932 if "OWE" not in dev[0].get_capability("key_mgmt"): 933 raise HwsimSkip("OWE not supported") 934 params = {"ssid": "owe", 935 "wpa": "2", 936 "ieee80211w": "2", 937 "wpa_key_mgmt": "OWE", 938 "rsn_pairwise": "CCMP"} 939 hapd = hostapd.add_ap(apdev[0], params) 940 bssid = hapd.own_addr() 941 942 dev[0].scan_for_bss(bssid, freq="2412") 943 dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2", 944 scan_freq="2412") 945 hapd.wait_sta() 946 947 hapd.set("ext_mgmt_frame_handling", "1") 948 dev[0].request("DISCONNECT") 949 dev[0].wait_disconnected(timeout=10) 950 hapd.set("ext_mgmt_frame_handling", "0") 951 dev[0].request("PMKSA_FLUSH") 952 dev[0].request("REASSOCIATE") 953 dev[0].wait_connected(timeout=10, error="Timeout on re-connection") 954