1# WPA2-Personal OCV tests 2# Copyright (c) 2018, Mathy Vanhoef 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, struct 9import logging, time 10logger = logging.getLogger() 11 12import hostapd 13from wpasupplicant import WpaSupplicant 14import hwsim_utils 15from utils import * 16from test_erp import start_erp_as 17from test_ap_ft import ft_params1, ft_params2 18from test_ap_psk import parse_eapol, build_eapol, pmk_to_ptk, eapol_key_mic, recv_eapol, send_eapol, reply_eapol, build_eapol_key_3_4, aes_wrap, pad_key_data 19 20#TODO: Refuse setting up AP with OCV but without MFP support 21#TODO: Refuse to connect to AP that advertises OCV but not MFP 22 23def make_ocikde(op_class, channel, seg1_idx): 24 WLAN_EID_VENDOR_SPECIFIC = 221 25 RSN_KEY_DATA_OCI = b"\x00\x0f\xac\x0d" 26 27 data = RSN_KEY_DATA_OCI + struct.pack("<BBB", op_class, channel, seg1_idx) 28 ocikde = struct.pack("<BB", WLAN_EID_VENDOR_SPECIFIC, len(data)) + data 29 30 return ocikde 31 32def ocv_setup_ap(apdev, params): 33 ssid = "test-wpa2-ocv" 34 passphrase = "qwertyuiop" 35 params.update(hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)) 36 try: 37 hapd = hostapd.add_ap(apdev, params) 38 except Exception as e: 39 if "Failed to set hostapd parameter ocv" in str(e): 40 raise HwsimSkip("OCV not supported") 41 raise 42 return hapd, ssid, passphrase 43 44def build_eapol_key_1_2(kck, key_data, replay_counter=3, key_info=0x1382, 45 extra_len=0, descr_type=2, key_len=16): 46 msg = {} 47 msg['version'] = 2 48 msg['type'] = 3 49 msg['length'] = 95 + len(key_data) + extra_len 50 51 msg['descr_type'] = descr_type 52 msg['rsn_key_info'] = key_info 53 msg['rsn_key_len'] = key_len 54 msg['rsn_replay_counter'] = struct.pack('>Q', replay_counter) 55 msg['rsn_key_nonce'] = binascii.unhexlify('0000000000000000000000000000000000000000000000000000000000000000') 56 msg['rsn_key_iv'] = binascii.unhexlify('00000000000000000000000000000000') 57 msg['rsn_key_rsc'] = binascii.unhexlify('0000000000000000') 58 msg['rsn_key_id'] = binascii.unhexlify('0000000000000000') 59 msg['rsn_key_data_len'] = len(key_data) 60 msg['rsn_key_data'] = key_data 61 eapol_key_mic(kck, msg) 62 return msg 63 64def build_eapol_key_2_2(kck, key_data, replay_counter=3, key_info=0x0302, 65 extra_len=0, descr_type=2, key_len=16): 66 return build_eapol_key_1_2(kck, key_data, replay_counter, key_info, 67 extra_len, descr_type, key_len) 68 69@remote_compatible 70def test_wpa2_ocv(dev, apdev): 71 """OCV on 2.4 GHz""" 72 params = {"channel": "1", 73 "ieee80211w": "2", 74 "ocv": "1"} 75 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 76 for ocv in range(2): 77 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv=str(ocv), 78 ieee80211w="1") 79 dev[0].request("REMOVE_NETWORK all") 80 dev[0].wait_disconnected() 81 82@remote_compatible 83def test_wpa2_ocv_5ghz(dev, apdev): 84 """OCV on 5 GHz""" 85 try: 86 run_wpa2_ocv_5ghz(dev, apdev) 87 finally: 88 set_world_reg(apdev[0], apdev[1], dev[0]) 89 dev[0].flush_scan_cache() 90 91def run_wpa2_ocv_5ghz(dev, apdev): 92 params = {"hw_mode": "a", 93 "channel": "40", 94 "ieee80211w": "2", 95 "country_code": "US", 96 "ocv": "1"} 97 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 98 for ocv in range(2): 99 dev[0].connect(ssid, psk=passphrase, scan_freq="5200", ocv=str(ocv), 100 ieee80211w="1") 101 dev[0].wait_regdom(country_ie=True) 102 dev[0].request("REMOVE_NETWORK all") 103 dev[0].wait_disconnected() 104 105@remote_compatible 106def test_wpa2_ocv_ht20(dev, apdev): 107 """OCV with HT20 channel""" 108 params = {"channel": "6", 109 "ieee80211n": "1", 110 "ieee80211w": "1", 111 "ocv": "1"} 112 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 113 for ocv in range(2): 114 dev[0].connect(ssid, psk=passphrase, scan_freq="2437", ocv=str(ocv), 115 ieee80211w="1", disable_ht="1") 116 dev[1].connect(ssid, psk=passphrase, scan_freq="2437", ocv=str(ocv), 117 ieee80211w="1") 118 dev[0].request("REMOVE_NETWORK all") 119 dev[1].request("REMOVE_NETWORK all") 120 dev[0].wait_disconnected() 121 dev[1].wait_disconnected() 122 123@remote_compatible 124def test_wpa2_ocv_ht40(dev, apdev): 125 """OCV with HT40 channel""" 126 try: 127 run_wpa2_ocv_ht40(dev, apdev) 128 finally: 129 set_world_reg(apdev[0], apdev[1], dev[0]) 130 dev[0].flush_scan_cache() 131 dev[1].flush_scan_cache() 132 133def run_wpa2_ocv_ht40(dev, apdev): 134 for channel, capab, freq, mode in [("6", "[HT40-]", "2437", "g"), 135 ("6", "[HT40+]", "2437", "g"), 136 ("40", "[HT40-]", "5200", "a"), 137 ("36", "[HT40+]", "5180", "a")]: 138 params = {"hw_mode": mode, 139 "channel": channel, 140 "country_code": "US", 141 "ieee80211n": "1", 142 "ht_capab": capab, 143 "ieee80211w": "1", 144 "ocv": "1"} 145 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 146 dev[0].flush_scan_cache() 147 dev[1].flush_scan_cache() 148 for ocv in range(2): 149 dev[0].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 150 ieee80211w="1", disable_ht="1") 151 dev[1].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 152 ieee80211w="1") 153 dev[0].wait_regdom(country_ie=True) 154 dev[0].request("REMOVE_NETWORK all") 155 dev[1].request("REMOVE_NETWORK all") 156 dev[0].wait_disconnected() 157 dev[1].wait_disconnected() 158 hapd.disable() 159 160@remote_compatible 161def test_wpa2_ocv_vht40(dev, apdev): 162 """OCV with VHT40 channel""" 163 try: 164 run_wpa2_ocv_vht40(dev, apdev) 165 finally: 166 set_world_reg(apdev[0], apdev[1], dev[0]) 167 dev[0].flush_scan_cache() 168 dev[1].flush_scan_cache() 169 dev[2].flush_scan_cache() 170 171def run_wpa2_ocv_vht40(dev, apdev): 172 for channel, capab, freq in [("40", "[HT40-]", "5200"), 173 ("36", "[HT40+]", "5180")]: 174 params = {"hw_mode": "a", 175 "channel": channel, 176 "country_code": "US", 177 "ht_capab": capab, 178 "ieee80211n": "1", 179 "ieee80211ac": "1", 180 "vht_oper_chwidth": "0", 181 "vht_oper_centr_freq_seg0_idx": "38", 182 "ieee80211w": "1", 183 "ocv": "1"} 184 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 185 dev[0].flush_scan_cache() 186 dev[1].flush_scan_cache() 187 dev[2].flush_scan_cache() 188 for ocv in range(2): 189 dev[0].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 190 ieee80211w="1", disable_ht="1") 191 dev[1].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 192 ieee80211w="1", disable_vht="1") 193 dev[2].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 194 ieee80211w="1") 195 dev[0].wait_regdom(country_ie=True) 196 dev[0].request("REMOVE_NETWORK all") 197 dev[1].request("REMOVE_NETWORK all") 198 dev[2].request("REMOVE_NETWORK all") 199 dev[0].wait_disconnected() 200 dev[1].wait_disconnected() 201 dev[2].wait_disconnected() 202 hapd.disable() 203 204@remote_compatible 205def test_wpa2_ocv_vht80(dev, apdev): 206 """OCV with VHT80 channel""" 207 try: 208 run_wpa2_ocv_vht80(dev, apdev) 209 finally: 210 set_world_reg(apdev[0], apdev[1], dev[0]) 211 dev[0].flush_scan_cache() 212 dev[1].flush_scan_cache() 213 dev[2].flush_scan_cache() 214 215def run_wpa2_ocv_vht80(dev, apdev): 216 for channel, capab, freq in [("40", "[HT40-]", "5200"), 217 ("36", "[HT40+]", "5180")]: 218 params = {"hw_mode": "a", 219 "channel": channel, 220 "country_code": "US", 221 "ht_capab": capab, 222 "ieee80211n": "1", 223 "ieee80211ac": "1", 224 "vht_oper_chwidth": "1", 225 "vht_oper_centr_freq_seg0_idx": "42", 226 "ieee80211w": "1", 227 "ocv": "1"} 228 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 229 for ocv in range(2): 230 dev[0].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 231 ieee80211w="1", disable_ht="1") 232 dev[1].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 233 ieee80211w="1", disable_vht="1") 234 dev[2].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 235 ieee80211w="1") 236 dev[0].wait_regdom(country_ie=True) 237 dev[0].request("REMOVE_NETWORK all") 238 dev[1].request("REMOVE_NETWORK all") 239 dev[2].request("REMOVE_NETWORK all") 240 dev[0].wait_disconnected() 241 dev[1].wait_disconnected() 242 dev[2].wait_disconnected() 243 hapd.disable() 244 245@remote_compatible 246def test_wpa2_ocv_vht160(dev, apdev): 247 """OCV with VHT160 channel""" 248 try: 249 run_wpa2_ocv_vht160(dev, apdev) 250 finally: 251 set_world_reg(apdev[0], apdev[1], dev[0]) 252 dev[0].flush_scan_cache() 253 dev[1].flush_scan_cache() 254 dev[2].flush_scan_cache() 255 256def run_wpa2_ocv_vht160(dev, apdev): 257 for channel, capab, freq in [("100", "[HT40+]", "5500"), 258 ("104", "[HT40-]", "5520")]: 259 params = {"hw_mode": "a", 260 "channel": channel, 261 "country_code": "ZA", 262 "ht_capab": capab, 263 "vht_capab": "[VHT160]", 264 "ieee80211n": "1", 265 "ieee80211ac": "1", 266 "vht_oper_chwidth": "2", 267 "vht_oper_centr_freq_seg0_idx": "114", 268 "ieee80211w": "1", 269 "ocv": "1"} 270 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 271 for ocv in range(2): 272 dev[0].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 273 ieee80211w="1", disable_ht="1") 274 dev[1].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 275 ieee80211w="1", disable_vht="1") 276 dev[2].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 277 ieee80211w="1") 278 dev[0].wait_regdom(country_ie=True) 279 dev[0].request("REMOVE_NETWORK all") 280 dev[1].request("REMOVE_NETWORK all") 281 dev[2].request("REMOVE_NETWORK all") 282 dev[0].wait_disconnected() 283 dev[1].wait_disconnected() 284 dev[2].wait_disconnected() 285 hapd.disable() 286 287@remote_compatible 288def test_wpa2_ocv_vht80plus80(dev, apdev): 289 """OCV with VHT80+80 channel""" 290 try: 291 run_wpa2_ocv_vht80plus80(dev, apdev) 292 finally: 293 set_world_reg(apdev[0], apdev[1], dev[0]) 294 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 295 dev[0].flush_scan_cache() 296 dev[1].flush_scan_cache() 297 dev[2].flush_scan_cache() 298 299def run_wpa2_ocv_vht80plus80(dev, apdev): 300 for channel, capab, freq in [("36", "[HT40+]", "5180"), 301 ("40", "[HT40-]", "5200")]: 302 params = {"hw_mode": "a", 303 "channel": channel, 304 "country_code": "US", 305 "ht_capab": capab, 306 "vht_capab": "[VHT160-80PLUS80]", 307 "ieee80211n": "1", 308 "ieee80211ac": "1", 309 "vht_oper_chwidth": "3", 310 "vht_oper_centr_freq_seg0_idx": "42", 311 "vht_oper_centr_freq_seg1_idx": "155", 312 "ieee80211w": "1", 313 "ieee80211d": "1", 314 "ieee80211h": "1", 315 "ocv": "1"} 316 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 317 for ocv in range(2): 318 dev[0].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 319 ieee80211w="1", disable_ht="1") 320 dev[1].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 321 ieee80211w="1", disable_vht="1") 322 dev[2].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 323 ieee80211w="1") 324 dev[0].wait_regdom(country_ie=True) 325 dev[0].request("REMOVE_NETWORK all") 326 dev[1].request("REMOVE_NETWORK all") 327 dev[2].request("REMOVE_NETWORK all") 328 dev[0].wait_disconnected() 329 dev[1].wait_disconnected() 330 dev[2].wait_disconnected() 331 for i in range(3): 332 dev[i].connect(ssid, psk=passphrase, scan_freq=freq, ocv=str(ocv), 333 ieee80211w="1") 334 if i == 0: 335 dev[i].wait_regdom(country_ie=True) 336 hapd.disable() 337 for i in range(3): 338 dev[i].request("DISCONNECT") 339 for i in range(3): 340 dev[i].disconnect_and_stop_scan() 341 342class APConnection: 343 def init_params(self): 344 # Static parameters 345 self.ssid = "test-wpa2-ocv" 346 self.passphrase = "qwertyuiop" 347 self.psk = "c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7" 348 349 # Dynamic parameters 350 self.hapd = None 351 self.addr = None 352 self.rsne = None 353 self.kck = None 354 self.kek = None 355 self.msg = None 356 self.bssid = None 357 self.anonce = None 358 self.snonce = None 359 360 def __init__(self, apdev, dev, params): 361 self.init_params() 362 363 # By default, OCV is enabled for both the client and AP. The following 364 # parameters can be used to disable OCV for the client or AP. 365 ap_ocv = params.pop("ap_ocv", "1") 366 sta_ocv = params.pop("sta_ocv", "1") 367 368 freq = params.pop("freq") 369 params.update(hostapd.wpa2_params(ssid=self.ssid, 370 passphrase=self.passphrase)) 371 params["wpa_pairwise_update_count"] = "10" 372 params["ocv"] = ap_ocv 373 try: 374 self.hapd = hostapd.add_ap(apdev, params) 375 except Exception as e: 376 if "Failed to set hostapd parameter ocv" in str(e): 377 raise HwsimSkip("OCV not supported") 378 raise 379 self.hapd.request("SET ext_eapol_frame_io 1") 380 dev.request("SET ext_eapol_frame_io 1") 381 382 self.bssid = apdev['bssid'] 383 pmk = binascii.unhexlify("c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7") 384 385 if sta_ocv != "0": 386 self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280400000000fac06") 387 else: 388 self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280000000000fac06") 389 self.snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111') 390 391 dev.connect(self.ssid, raw_psk=self.psk, scan_freq=freq, ocv=sta_ocv, 392 ieee80211w="1", wait_connect=False) 393 if "country_code" in params: 394 dev.wait_regdom(country_ie=True) 395 self.addr = dev.p2p_interface_addr() 396 397 # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated 398 self.msg = recv_eapol(self.hapd) 399 self.anonce = self.msg['rsn_key_nonce'] 400 (ptk, self.kck, self.kek) = pmk_to_ptk(pmk, self.addr, self.bssid, 401 self.snonce, self.anonce) 402 403 # hapd, addr, rsne, kck, msg, anonce, snonce 404 def test_bad_oci(self, logmsg, op_class, channel, seg1_idx): 405 logger.debug("Bad OCI element: " + logmsg) 406 if op_class is None: 407 ocikde = b'' 408 else: 409 ocikde = make_ocikde(op_class, channel, seg1_idx) 410 411 reply_eapol("2/4", self.hapd, self.addr, self.msg, 0x010a, self.snonce, 412 self.rsne + ocikde, self.kck) 413 self.msg = recv_eapol(self.hapd) 414 if self.anonce != self.msg['rsn_key_nonce'] or self.msg["rsn_key_info"] != 138: 415 raise Exception("Didn't receive retransmitted 1/4") 416 417 def confirm_valid_oci(self, op_class, channel, seg1_idx): 418 logger.debug("Valid OCI element to complete handshake") 419 ocikde = make_ocikde(op_class, channel, seg1_idx) 420 421 reply_eapol("2/4", self.hapd, self.addr, self.msg, 0x010a, self.snonce, 422 self.rsne + ocikde, self.kck) 423 self.msg = recv_eapol(self.hapd) 424 if self.anonce != self.msg['rsn_key_nonce'] or self.msg["rsn_key_info"] != 5066: 425 raise Exception("Didn't receive 3/4 in response to valid 2/4") 426 427 reply_eapol("4/4", self.hapd, self.addr, self.msg, 0x030a, None, None, 428 self.kck) 429 self.hapd.wait_sta(timeout=15) 430 431@remote_compatible 432def test_wpa2_ocv_ap_mismatch(dev, apdev): 433 """OCV AP mismatch""" 434 params = {"channel": "1", 435 "ieee80211w": "1", 436 "freq": "2412"} 437 conn = APConnection(apdev[0], dev[0], params) 438 conn.test_bad_oci("element missing", None, 0, 0) 439 conn.test_bad_oci("wrong channel number", 81, 6, 0) 440 conn.test_bad_oci("invalid channel number", 81, 0, 0) 441 conn.test_bad_oci("wrong operating class", 80, 0, 0) 442 conn.test_bad_oci("invalid operating class", 0, 0, 0) 443 conn.confirm_valid_oci(81, 1, 0) 444 445@remote_compatible 446def test_wpa2_ocv_ap_ht_mismatch(dev, apdev): 447 """OCV AP mismatch (HT)""" 448 params = {"channel": "6", 449 "ht_capab": "[HT40-]", 450 "ieee80211w": "1", 451 "freq": "2437"} 452 conn = APConnection(apdev[0], dev[0], params) 453 conn.test_bad_oci("wrong primary channel", 84, 5, 0) 454 conn.test_bad_oci("lower bandwidth than negotiated", 81, 6, 0) 455 conn.test_bad_oci("bad upper/lower channel", 83, 6, 0) 456 conn.confirm_valid_oci(84, 6, 0) 457 458@remote_compatible 459def test_wpa2_ocv_ap_vht80_mismatch(dev, apdev): 460 """OCV AP mismatch (VHT80)""" 461 try: 462 run_wpa2_ocv_ap_vht80_mismatch(dev, apdev) 463 finally: 464 set_world_reg(apdev[0], apdev[1], dev[0]) 465 dev[0].flush_scan_cache() 466 467def run_wpa2_ocv_ap_vht80_mismatch(dev, apdev): 468 params = {"hw_mode": "a", 469 "channel": "36", 470 "country_code": "US", 471 "ht_capab": "[HT40+]", 472 "ieee80211w": "1", 473 "ieee80211n": "1", 474 "ieee80211ac": "1", 475 "vht_oper_chwidth": "1", 476 "freq": "5180", 477 "vht_oper_centr_freq_seg0_idx": "42"} 478 conn = APConnection(apdev[0], dev[0], params) 479 conn.test_bad_oci("wrong primary channel", 128, 38, 0) 480 conn.test_bad_oci("wrong primary channel", 128, 32, 0) 481 conn.test_bad_oci("smaller bandwidth than negotiated", 116, 36, 0) 482 conn.test_bad_oci("smaller bandwidth than negotiated", 115, 36, 0) 483 conn.confirm_valid_oci(128, 36, 0) 484 485 dev[0].dump_monitor() 486 dev[0].request("DISCONNECT") 487 dev[0].wait_disconnected() 488 489@remote_compatible 490def test_wpa2_ocv_ap_vht160_mismatch(dev, apdev): 491 """OCV AP mismatch (VHT160)""" 492 try: 493 run_wpa2_ocv_ap_vht160_mismatch(dev, apdev) 494 finally: 495 set_world_reg(apdev[0], apdev[1], dev[0]) 496 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 497 dev[0].flush_scan_cache() 498 499def run_wpa2_ocv_ap_vht160_mismatch(dev, apdev): 500 params = {"hw_mode": "a", 501 "channel": "100", 502 "country_code": "ZA", 503 "ht_capab": "[HT40+]", 504 "ieee80211w": "1", 505 "ieee80211n": "1", 506 "ieee80211ac": "1", 507 "vht_oper_chwidth": "2", 508 "freq": "5500", 509 "vht_oper_centr_freq_seg0_idx": "114", 510 "ieee80211d": "1", 511 "ieee80211h": "1"} 512 conn = APConnection(apdev[0], dev[0], params) 513 conn.test_bad_oci("wrong primary channel", 129, 36, 0) 514 conn.test_bad_oci("wrong primary channel", 129, 114, 0) 515 conn.test_bad_oci("smaller bandwidth (20 Mhz) than negotiated", 121, 100, 0) 516 conn.test_bad_oci("smaller bandwidth (40 Mhz) than negotiated", 122, 100, 0) 517 conn.test_bad_oci("smaller bandwidth (80 Mhz) than negotiated", 128, 100, 0) 518 conn.test_bad_oci("using 80+80 channel instead of 160", 130, 100, 155) 519 conn.confirm_valid_oci(129, 100, 0) 520 521 dev[0].dump_monitor() 522 if conn.hapd: 523 conn.hapd.request("DISABLE") 524 dev[0].disconnect_and_stop_scan() 525 526@remote_compatible 527def test_wpa2_ocv_ap_vht80plus80_mismatch(dev, apdev): 528 """OCV AP mismatch (VHT80+80)""" 529 try: 530 run_wpa2_ocv_ap_vht80plus80_mismatch(dev, apdev) 531 finally: 532 set_world_reg(apdev[0], apdev[1], dev[0]) 533 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 534 dev[0].flush_scan_cache() 535 536def run_wpa2_ocv_ap_vht80plus80_mismatch(dev, apdev): 537 params = {"hw_mode": "a", 538 "channel": "36", 539 "country_code": "US", 540 "ht_capab": "[HT40+]", 541 "ieee80211w": "1", 542 "ieee80211n": "1", 543 "ieee80211ac": "1", 544 "vht_oper_chwidth": "3", 545 "freq": "5180", 546 "vht_oper_centr_freq_seg0_idx": "42", 547 "ieee80211d": "1", 548 "vht_oper_centr_freq_seg1_idx": "155", 549 "ieee80211h": "1"} 550 conn = APConnection(apdev[0], dev[0], params) 551 conn.test_bad_oci("using 80 MHz operating class", 128, 36, 155) 552 conn.test_bad_oci("wrong frequency segment 1", 130, 36, 138) 553 conn.confirm_valid_oci(130, 36, 155) 554 555 dev[0].dump_monitor() 556 if conn.hapd: 557 conn.hapd.request("DISABLE") 558 dev[0].disconnect_and_stop_scan() 559 560@remote_compatible 561def test_wpa2_ocv_ap_unexpected1(dev, apdev): 562 """OCV and unexpected OCI KDE from station""" 563 params = {"channel": "1", 564 "ieee80211w": "1", 565 "ap_ocv": "0", 566 "sta_ocv": "1", 567 "freq": "2412"} 568 conn = APConnection(apdev[0], dev[0], params) 569 logger.debug("Client will send OCI KDE even if it was not negotiated") 570 conn.confirm_valid_oci(81, 1, 0) 571 572@remote_compatible 573def test_wpa2_ocv_ap_unexpected2(dev, apdev): 574 """OCV and unexpected OCI KDE from station""" 575 params = {"channel": "1", 576 "ieee80211w": "1", 577 "ap_ocv": "1", 578 "sta_ocv": "0", 579 "freq": "2412"} 580 conn = APConnection(apdev[0], dev[0], params) 581 logger.debug("Client will send OCI KDE even if it was not negotiated") 582 conn.confirm_valid_oci(81, 1, 0) 583 584@remote_compatible 585def test_wpa2_ocv_ap_retransmit_msg3(dev, apdev): 586 """Verify that manually retransmitted msg 3/4 contain a correct OCI""" 587 bssid = apdev[0]['bssid'] 588 ssid = "test-wpa2-ocv" 589 passphrase = "qwertyuiop" 590 psk = "c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7" 591 params = hostapd.wpa2_params(ssid=ssid) 592 params["wpa_psk"] = psk 593 params["ieee80211w"] = "1" 594 params["ocv"] = "1" 595 params['wpa_disable_eapol_key_retries'] = "1" 596 try: 597 hapd = hostapd.add_ap(apdev[0], params) 598 except Exception as e: 599 if "Failed to set hostapd parameter ocv" in str(e): 600 raise HwsimSkip("OCV not supported") 601 raise 602 hapd.request("SET ext_eapol_frame_io 1") 603 dev[0].request("SET ext_eapol_frame_io 1") 604 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", wait_connect=False, 605 ocv="1", ieee80211w="1") 606 addr = dev[0].own_addr() 607 608 # EAPOL-Key msg 1/4 609 ev = hapd.wait_event(["EAPOL-TX"], timeout=15) 610 if ev is None: 611 raise Exception("Timeout on EAPOL-TX from hostapd") 612 res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2]) 613 if "OK" not in res: 614 raise Exception("EAPOL_RX to wpa_supplicant failed") 615 616 # EAPOL-Key msg 2/4 617 ev = dev[0].wait_event(["EAPOL-TX"], timeout=15) 618 if ev is None: 619 raise Exception("Timeout on EAPOL-TX from wpa_supplicant") 620 res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2]) 621 if "OK" not in res: 622 raise Exception("EAPOL_RX to hostapd failed") 623 624 # EAPOL-Key msg 3/4 625 ev = hapd.wait_event(["EAPOL-TX"], timeout=15) 626 if ev is None: 627 raise Exception("Timeout on EAPOL-TX from hostapd") 628 logger.info("Drop the first EAPOL-Key msg 3/4") 629 630 # Use normal EAPOL TX/RX to handle retries. 631 hapd.request("SET ext_eapol_frame_io 0") 632 dev[0].request("SET ext_eapol_frame_io 0") 633 634 # Manually retransmit EAPOL-Key msg 3/4 635 if "OK" not in hapd.request("RESEND_M3 " + addr): 636 raise Exception("RESEND_M3 failed") 637 638 dev[0].wait_connected() 639 hwsim_utils.test_connectivity(dev[0], hapd) 640 641def test_wpa2_ocv_ap_group_hs(dev, apdev): 642 """OCV group handshake (AP)""" 643 params = {"channel": "1", 644 "ieee80211w": "1", 645 "freq": "2412", 646 "wpa_strict_rekey": "1"} 647 conn = APConnection(apdev[0], dev[0], params) 648 conn.confirm_valid_oci(81, 1, 0) 649 650 conn.hapd.request("SET ext_eapol_frame_io 0") 651 dev[1].connect(conn.ssid, psk=conn.passphrase, scan_freq="2412", ocv="1", 652 ieee80211w="1") 653 conn.hapd.wait_sta() 654 conn.hapd.request("SET ext_eapol_frame_io 1") 655 656 # Trigger a group key handshake 657 dev[1].request("DISCONNECT") 658 dev[0].dump_monitor() 659 660 # Wait for EAPOL-Key msg 1/2 661 conn.msg = recv_eapol(conn.hapd) 662 if conn.msg["rsn_key_info"] != 4994: 663 raise Exception("Didn't receive 1/2 of group key handshake") 664 665 # Send a EAPOL-Key msg 2/2 with a bad OCI 666 logger.info("Bad OCI element") 667 ocikde = make_ocikde(1, 1, 1) 668 msg = build_eapol_key_2_2(conn.kck, ocikde, replay_counter=3) 669 conn.hapd.dump_monitor() 670 send_eapol(conn.hapd, conn.addr, build_eapol(msg)) 671 672 # Wait for retransmitted EAPOL-Key msg 1/2 673 conn.msg = recv_eapol(conn.hapd) 674 if conn.msg["rsn_key_info"] != 4994: 675 raise Exception("Didn't receive 1/2 of group key handshake") 676 677 # Send a EAPOL-Key msg 2/2 with a good OCI 678 logger.info("Good OCI element") 679 ocikde = make_ocikde(81, 1, 0) 680 msg = build_eapol_key_2_2(conn.kck, ocikde, replay_counter=4) 681 conn.hapd.dump_monitor() 682 send_eapol(conn.hapd, conn.addr, build_eapol(msg)) 683 684 # Verify that group key handshake has completed 685 ev = conn.hapd.wait_event(["EAPOL-TX"], timeout=1) 686 if ev is not None: 687 eapol = binascii.unhexlify(ev.split(' ')[2]) 688 msg = parse_eapol(eapol) 689 if msg["rsn_key_info"] == 4994: 690 raise Exception("AP didn't accept 2/2 of group key handshake") 691 692class STAConnection: 693 def init_params(self): 694 # Static parameters 695 self.ssid = "test-wpa2-ocv" 696 self.passphrase = "qwertyuiop" 697 self.psk = "c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7" 698 699 # Dynamic parameters 700 self.hapd = None 701 self.dev = None 702 self.addr = None 703 self.rsne = None 704 self.kck = None 705 self.kek = None 706 self.msg = None 707 self.bssid = None 708 self.anonce = None 709 self.snonce = None 710 self.gtkie = None 711 self.counter = None 712 713 def __init__(self, apdev, dev, params, sta_params=None): 714 self.init_params() 715 self.dev = dev 716 self.bssid = apdev['bssid'] 717 718 freq = params.pop("freq") 719 if sta_params is None: 720 sta_params = dict() 721 if "ocv" not in sta_params: 722 sta_params["ocv"] = "1" 723 if "ieee80211w" not in sta_params: 724 sta_params["ieee80211w"] = "1" 725 726 params.update(hostapd.wpa2_params(ssid=self.ssid, 727 passphrase=self.passphrase)) 728 params['wpa_pairwise_update_count'] = "10" 729 730 try: 731 self.hapd = hostapd.add_ap(apdev, params) 732 except Exception as e: 733 if "Failed to set hostapd parameter ocv" in str(e): 734 raise HwsimSkip("OCV not supported") 735 raise 736 self.hapd.request("SET ext_eapol_frame_io 1") 737 self.dev.request("SET ext_eapol_frame_io 1") 738 pmk = binascii.unhexlify("c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7") 739 740 self.gtkie = binascii.unhexlify("dd16000fac010100dc11188831bf4aa4a8678d2b41498618") 741 if sta_params["ocv"] != "0": 742 self.rsne = binascii.unhexlify("30140100000fac040100000fac040100000fac028c40") 743 else: 744 self.rsne = binascii.unhexlify("30140100000fac040100000fac040100000fac028c00") 745 746 self.dev.connect(self.ssid, raw_psk=self.psk, scan_freq=freq, 747 wait_connect=False, **sta_params) 748 if "country_code" in params: 749 self.dev.wait_regdom(country_ie=True) 750 self.addr = dev.p2p_interface_addr() 751 752 # Forward msg 1/4 from AP to STA 753 self.msg = recv_eapol(self.hapd) 754 self.anonce = self.msg['rsn_key_nonce'] 755 send_eapol(self.dev, self.bssid, build_eapol(self.msg)) 756 757 # Capture msg 2/4 from the STA so we can derive the session keys 758 self.msg = recv_eapol(dev) 759 self.snonce = self.msg['rsn_key_nonce'] 760 (ptk, self.kck, self.kek) = pmk_to_ptk(pmk, self.addr, self.bssid, 761 self.snonce, self.anonce) 762 763 self.counter = struct.unpack('>Q', 764 self.msg['rsn_replay_counter'])[0] + 1 765 766 def test_bad_oci(self, logmsg, op_class, channel, seg1_idx, errmsg): 767 logger.info("Bad OCI element: " + logmsg) 768 if op_class is None: 769 ocikde = b'' 770 else: 771 ocikde = make_ocikde(op_class, channel, seg1_idx) 772 773 plain = self.rsne + self.gtkie + ocikde 774 wrapped = aes_wrap(self.kek, pad_key_data(plain)) 775 msg = build_eapol_key_3_4(self.anonce, self.kck, wrapped, 776 replay_counter=self.counter) 777 778 self.dev.dump_monitor() 779 send_eapol(self.dev, self.bssid, build_eapol(msg)) 780 self.counter += 1 781 782 ev = self.dev.wait_event([errmsg], timeout=5) 783 if ev is None: 784 raise Exception("Bad OCI not reported") 785 786 def confirm_valid_oci(self, op_class, channel, seg1_idx): 787 logger.debug("Valid OCI element to complete handshake") 788 ocikde = make_ocikde(op_class, channel, seg1_idx) 789 790 plain = self.rsne + self.gtkie + ocikde 791 wrapped = aes_wrap(self.kek, pad_key_data(plain)) 792 msg = build_eapol_key_3_4(self.anonce, self.kck, wrapped, 793 replay_counter=self.counter) 794 795 self.dev.dump_monitor() 796 send_eapol(self.dev, self.bssid, build_eapol(msg)) 797 self.counter += 1 798 799 self.dev.wait_connected(timeout=1) 800 801@remote_compatible 802def test_wpa2_ocv_mismatch_client(dev, apdev): 803 """OCV client mismatch""" 804 params = {"channel": "1", 805 "ieee80211w": "1", 806 "ocv": "1", 807 "freq": "2412"} 808 conn = STAConnection(apdev[0], dev[0], params) 809 conn.test_bad_oci("element missing", None, 0, 0, 810 "did not receive mandatory OCI") 811 conn.test_bad_oci("wrong channel number", 81, 6, 0, 812 "primary channel mismatch") 813 conn.test_bad_oci("invalid channel number", 81, 0, 0, 814 "unable to interpret received OCI") 815 conn.test_bad_oci("wrong operating class", 80, 0, 0, 816 "unable to interpret received OCI") 817 conn.test_bad_oci("invalid operating class", 0, 0, 0, 818 "unable to interpret received OCI") 819 conn.confirm_valid_oci(81, 1, 0) 820 821@remote_compatible 822def test_wpa2_ocv_vht160_mismatch_client(dev, apdev): 823 """OCV client mismatch (VHT160)""" 824 try: 825 run_wpa2_ocv_vht160_mismatch_client(dev, apdev) 826 finally: 827 set_world_reg(apdev[0], apdev[1], dev[0]) 828 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 829 dev[0].flush_scan_cache() 830 831def run_wpa2_ocv_vht160_mismatch_client(dev, apdev): 832 params = {"hw_mode": "a", 833 "channel": "100", 834 "country_code": "ZA", 835 "ht_capab": "[HT40+]", 836 "ieee80211w": "1", 837 "ieee80211n": "1", 838 "ieee80211ac": "1", 839 "vht_oper_chwidth": "2", 840 "ocv": "1", 841 "vht_oper_centr_freq_seg0_idx": "114", 842 "freq": "5500", 843 "ieee80211d": "1", 844 "ieee80211h": "1"} 845 sta_params = {"disable_vht": "1"} 846 conn = STAConnection(apdev[0], dev[0], params, sta_params) 847 conn.test_bad_oci("smaller bandwidth (20 Mhz) than negotiated", 848 121, 100, 0, "channel bandwidth mismatch") 849 conn.test_bad_oci("wrong frequency, bandwith, and secondary channel", 850 123, 104, 0, "primary channel mismatch") 851 conn.test_bad_oci("wrong upper/lower behaviour", 852 129, 104, 0, "primary channel mismatch") 853 conn.confirm_valid_oci(122, 100, 0) 854 855 dev[0].dump_monitor() 856 if conn.hapd: 857 conn.hapd.request("DISABLE") 858 dev[0].disconnect_and_stop_scan() 859 860def test_wpa2_ocv_sta_group_hs(dev, apdev): 861 """OCV group handshake (STA)""" 862 params = {"channel": "1", 863 "ieee80211w": "1", 864 "ocv": "1", 865 "freq": "2412", 866 "wpa_strict_rekey": "1"} 867 conn = STAConnection(apdev[0], dev[0], params.copy()) 868 conn.confirm_valid_oci(81, 1, 0) 869 870 # Send a EAPOL-Key msg 1/2 with a bad OCI 871 logger.info("Bad OCI element") 872 plain = conn.gtkie + make_ocikde(1, 1, 1) 873 wrapped = aes_wrap(conn.kek, pad_key_data(plain)) 874 msg = build_eapol_key_1_2(conn.kck, wrapped, replay_counter=3) 875 send_eapol(dev[0], conn.bssid, build_eapol(msg)) 876 877 # We shouldn't get a EAPOL-Key message back 878 ev = dev[0].wait_event(["EAPOL-TX"], timeout=1) 879 if ev is not None: 880 raise Exception("Received response to invalid EAPOL-Key 1/2") 881 882 # Reset AP to try with valid OCI 883 conn.hapd.disable() 884 conn = STAConnection(apdev[0], dev[0], params.copy()) 885 conn.confirm_valid_oci(81, 1, 0) 886 887 # Send a EAPOL-Key msg 1/2 with a good OCI 888 logger.info("Good OCI element") 889 plain = conn.gtkie + make_ocikde(81, 1, 0) 890 wrapped = aes_wrap(conn.kek, pad_key_data(plain)) 891 msg = build_eapol_key_1_2(conn.kck, wrapped, replay_counter=4) 892 send_eapol(dev[0], conn.bssid, build_eapol(msg)) 893 894 # Wait for EAPOL-Key msg 2/2 895 conn.msg = recv_eapol(dev[0]) 896 if conn.msg["rsn_key_info"] != 0x0302: 897 raise Exception("Didn't receive 2/2 of group key handshake") 898 899def test_wpa2_ocv_auto_enable_pmf(dev, apdev): 900 """OCV on 2.4 GHz with PMF getting enabled automatically""" 901 params = {"channel": "1", 902 "ocv": "1"} 903 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 904 for ocv in range(2): 905 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv=str(ocv), 906 ieee80211w="2") 907 dev[0].request("REMOVE_NETWORK all") 908 dev[0].wait_disconnected() 909 910def test_wpa2_ocv_sta_override_eapol(dev, apdev): 911 """OCV on 2.4 GHz and STA override EAPOL-Key msg 2/4""" 912 params = {"channel": "1", 913 "ieee80211w": "2", 914 "ocv": "1"} 915 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 916 dev[0].set("oci_freq_override_eapol", "2462") 917 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1", 918 ieee80211w="2", wait_connect=False) 919 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 920 "CTRL-EVENT-DISCONNECTED"], timeout=15) 921 dev[0].request("DISCONNECT") 922 if ev is None: 923 raise Exception("No connection result reported") 924 if "CTRL-EVENT-CONNECTED" in ev: 925 raise Exception("Unexpected connection") 926 if "reason=15" not in ev: 927 raise Exception("Unexpected disconnection reason: " + ev) 928 929 check_ocv_failure(hapd, "EAPOL-Key msg 2/4", "eapol-key-m2", 930 dev[0].own_addr()) 931 932def test_wpa2_ocv_sta_override_sa_query_req(dev, apdev): 933 """OCV on 2.4 GHz and STA override SA Query Request""" 934 params = {"channel": "1", 935 "ieee80211w": "2", 936 "ocv": "1"} 937 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 938 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1", 939 ieee80211w="2") 940 hapd.wait_sta() 941 dev[0].set("oci_freq_override_saquery_req", "2462") 942 if "OK" not in dev[0].request("UNPROT_DEAUTH"): 943 raise Exception("Triggering SA Query from the STA failed") 944 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=3) 945 if ev is None: 946 raise Exception("Disconnection after failed SA Query not reported") 947 dev[0].set("oci_freq_override_saquery_req", "0") 948 dev[0].wait_connected() 949 if "OK" not in dev[0].request("UNPROT_DEAUTH"): 950 raise Exception("Triggering SA Query from the STA failed") 951 check_ocv_failure(hapd, "SA Query Request", "saqueryreq", 952 dev[0].own_addr()) 953 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=3) 954 if ev is not None: 955 raise Exception("SA Query from the STA failed") 956 957def test_wpa2_ocv_sta_override_sa_query_resp(dev, apdev): 958 """OCV on 2.4 GHz and STA override SA Query Response""" 959 params = {"channel": "1", 960 "ieee80211w": "2", 961 "ocv": "1"} 962 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 963 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1", 964 ieee80211w="2") 965 dev[0].set("oci_freq_override_saquery_resp", "2462") 966 hapd.wait_sta() 967 if "OK" not in hapd.request("SA_QUERY " + dev[0].own_addr()): 968 raise Exception("SA_QUERY failed") 969 check_ocv_failure(hapd, "SA Query Response", "saqueryresp", 970 dev[0].own_addr()) 971 972def check_ocv_failure(dev, frame_txt, frame, addr): 973 ev = dev.wait_event(["OCV-FAILURE"], timeout=3) 974 if ev is None: 975 raise Exception("OCV failure for %s not reported" % frame_txt) 976 if "addr=" + addr not in ev: 977 raise Exception("Unexpected OCV failure addr: " + ev) 978 if "frame=" + frame not in ev: 979 raise Exception("Unexpected OCV failure frame: " + ev) 980 if "error=primary channel mismatch" not in ev: 981 raise Exception("Unexpected OCV failure error: " + ev) 982 983def test_wpa2_ocv_ap_override_eapol_m3(dev, apdev): 984 """OCV on 2.4 GHz and AP override EAPOL-Key msg 3/4""" 985 run_wpa2_ocv_ap_override_eapol_m3(dev, apdev) 986 987def test_wpa2_ocv_ap_override_eapol_m3_post_enable(dev, apdev): 988 """OCV on 2.4 GHz and AP override EAPOL-Key msg 3/4 (post enable)""" 989 run_wpa2_ocv_ap_override_eapol_m3(dev, apdev, True) 990 991def run_wpa2_ocv_ap_override_eapol_m3(dev, apdev, post_enable=False): 992 params = {"channel": "1", 993 "ieee80211w": "2", 994 "ocv": "1"} 995 if not post_enable: 996 params["oci_freq_override_eapol_m3"] = "2462" 997 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 998 bssid = hapd.own_addr() 999 if post_enable: 1000 hapd.set("oci_freq_override_eapol_m3", "2462") 1001 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1", 1002 ieee80211w="2", wait_connect=False) 1003 1004 check_ocv_failure(dev[0], "EAPOL-Key msg 3/4", "eapol-key-m3", bssid) 1005 1006 ev = dev[0].wait_disconnected() 1007 if "reason=15" not in ev: 1008 raise Exception("Unexpected disconnection reason: " + ev) 1009 1010def test_wpa2_ocv_ap_override_eapol_g1(dev, apdev): 1011 """OCV on 2.4 GHz and AP override EAPOL-Key group msg 1/2""" 1012 run_wpa2_ocv_ap_override_eapol_g1(dev, apdev) 1013 1014def test_wpa2_ocv_ap_override_eapol_g1_post_enable(dev, apdev): 1015 """OCV on 2.4 GHz and AP override EAPOL-Key group msg 1/2 (post enable)""" 1016 run_wpa2_ocv_ap_override_eapol_g1(dev, apdev, True) 1017 1018def run_wpa2_ocv_ap_override_eapol_g1(dev, apdev, post_enable=False): 1019 params = {"channel": "1", 1020 "ieee80211w": "2", 1021 "ocv": "1"} 1022 if not post_enable: 1023 params["oci_freq_override_eapol_g1"] = "2462" 1024 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1025 bssid = hapd.own_addr() 1026 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1", 1027 ieee80211w="2") 1028 1029 if post_enable: 1030 hapd.set("oci_freq_override_eapol_g1", "2462") 1031 if "OK" not in hapd.request("REKEY_GTK"): 1032 raise Exception("REKEY_GTK failed") 1033 check_ocv_failure(dev[0], "EAPOL-Key group msg 1/2", "eapol-key-g1", bssid) 1034 1035def test_wpa2_ocv_ap_override_saquery_req(dev, apdev): 1036 """OCV on 2.4 GHz and AP override SA Query Request""" 1037 params = {"channel": "1", 1038 "ieee80211w": "2", 1039 "ocv": "1", 1040 "oci_freq_override_saquery_req": "2462"} 1041 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1042 bssid = hapd.own_addr() 1043 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1", 1044 ieee80211w="2") 1045 1046 if "OK" not in hapd.request("SA_QUERY " + dev[0].own_addr()): 1047 raise Exception("SA_QUERY failed") 1048 check_ocv_failure(dev[0], "SA Query Request", "saqueryreq", bssid) 1049 1050def test_wpa2_ocv_ap_override_saquery_resp(dev, apdev): 1051 """OCV on 2.4 GHz and AP override SA Query Response""" 1052 params = {"channel": "1", 1053 "ieee80211w": "2", 1054 "ocv": "1", 1055 "oci_freq_override_saquery_resp": "2462"} 1056 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1057 bssid = hapd.own_addr() 1058 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1", 1059 ieee80211w="2") 1060 1061 if "OK" not in dev[0].request("UNPROT_DEAUTH"): 1062 raise Exception("Triggering SA Query from the STA failed") 1063 check_ocv_failure(dev[0], "SA Query Response", "saqueryresp", bssid) 1064 1065def test_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params): 1066 """OCV on 2.4 GHz and AP override FILS association""" 1067 run_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params) 1068 1069def test_wpa2_ocv_ap_override_fils_assoc_post_enable(dev, apdev, params): 1070 """OCV on 2.4 GHz and AP override FILS association (post enable)""" 1071 run_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params, True) 1072 1073def run_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params, post_enable=False): 1074 check_fils_capa(dev[0]) 1075 check_erp_capa(dev[0]) 1076 1077 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst")) 1078 1079 bssid = apdev[0]['bssid'] 1080 ssid = "test-wpa2-ocv" 1081 params = hostapd.wpa2_eap_params(ssid=ssid) 1082 params['wpa_key_mgmt'] = "FILS-SHA256" 1083 params['auth_server_port'] = "18128" 1084 params['erp_send_reauth_start'] = '1' 1085 params['erp_domain'] = 'example.com' 1086 params['fils_realm'] = 'example.com' 1087 params['wpa_group_rekey'] = '1' 1088 params["ieee80211w"] = "2" 1089 params["ocv"] = "1" 1090 if not post_enable: 1091 params["oci_freq_override_fils_assoc"] = "2462" 1092 try: 1093 hapd = hostapd.add_ap(apdev[0], params) 1094 except Exception as e: 1095 if "Failed to set hostapd parameter ocv" in str(e): 1096 raise HwsimSkip("OCV not supported") 1097 raise 1098 bssid = hapd.own_addr() 1099 if post_enable: 1100 hapd.set("oci_freq_override_fils_assoc", "2462") 1101 dev[0].request("ERP_FLUSH") 1102 id = dev[0].connect(ssid, key_mgmt="FILS-SHA256", 1103 eap="PSK", identity="psk.user@example.com", 1104 password_hex="0123456789abcdef0123456789abcdef", 1105 erp="1", scan_freq="2412", ocv="1", ieee80211w="2") 1106 1107 dev[0].request("DISCONNECT") 1108 dev[0].wait_disconnected() 1109 1110 dev[0].dump_monitor() 1111 dev[0].select_network(id, freq=2412) 1112 1113 check_ocv_failure(dev[0], "FILS Association Response", "fils-assoc", bssid) 1114 dev[0].request("DISCONNECT") 1115 1116def test_wpa2_ocv_ap_override_ft_assoc(dev, apdev): 1117 """OCV on 2.4 GHz and AP override FT reassociation""" 1118 run_wpa2_ocv_ap_override_ft_assoc(dev, apdev) 1119 1120def test_wpa2_ocv_ap_override_ft_assoc_post_enable(dev, apdev): 1121 """OCV on 2.4 GHz and AP override FT reassociation (post enable)""" 1122 run_wpa2_ocv_ap_override_ft_assoc(dev, apdev, True) 1123 1124def run_wpa2_ocv_ap_override_ft_assoc(dev, apdev, post_enable=False): 1125 ssid = "test-wpa2-ocv" 1126 passphrase = "qwertyuiop" 1127 params = ft_params1(ssid=ssid, passphrase=passphrase) 1128 params["ieee80211w"] = "2" 1129 params["ocv"] = "1" 1130 if not post_enable: 1131 params["oci_freq_override_ft_assoc"] = "2462" 1132 try: 1133 hapd0 = hostapd.add_ap(apdev[0], params) 1134 except Exception as e: 1135 if "Failed to set hostapd parameter ocv" in str(e): 1136 raise HwsimSkip("OCV not supported") 1137 raise 1138 params = ft_params2(ssid=ssid, passphrase=passphrase) 1139 params["ieee80211w"] = "2" 1140 params["ocv"] = "1" 1141 if not post_enable: 1142 params["oci_freq_override_ft_assoc"] = "2462" 1143 hapd1 = hostapd.add_ap(apdev[1], params) 1144 1145 if post_enable: 1146 hapd0.set("oci_freq_override_ft_assoc", "2462") 1147 hapd1.set("oci_freq_override_ft_assoc", "2462") 1148 1149 dev[0].connect(ssid, key_mgmt="FT-PSK", psk=passphrase, 1150 scan_freq="2412", ocv="1", ieee80211w="2") 1151 1152 bssid = dev[0].get_status_field("bssid") 1153 bssid0 = hapd0.own_addr() 1154 bssid1 = hapd1.own_addr() 1155 target = bssid0 if bssid == bssid1 else bssid1 1156 1157 dev[0].scan_for_bss(target, freq="2412") 1158 if "OK" not in dev[0].request("ROAM " + target): 1159 raise Exception("ROAM failed") 1160 1161 check_ocv_failure(dev[0], "FT Reassociation Response", "ft-assoc", target) 1162 dev[0].request("DISCONNECT") 1163 1164@remote_compatible 1165def test_wpa2_ocv_no_pmf(dev, apdev): 1166 """OCV on 2.4 GHz and no PMF on STA""" 1167 params = {"channel": "1", 1168 "ieee80211w": "1", 1169 "ocv": "1"} 1170 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1171 ie = "301a0100000fac040100000fac040100000fac0200400000000fac06" 1172 if "OK" not in dev[0].request("TEST_ASSOC_IE " + ie): 1173 raise Exception("Could not set TEST_ASSOC_IE") 1174 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="0", 1175 ieee80211w="0", wait_connect=False) 1176 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-ASSOC-REJECT"], 1177 timeout=10) 1178 dev[0].request("DISCONNECT") 1179 if ev is None: 1180 raise Exception("No connection result seen") 1181 if "CTRL-EVENT-CONNECTED" in ev: 1182 raise Exception("Unexpected connection") 1183 if "status_code=31" not in ev: 1184 raise Exception("Unexpected status code: " + ev) 1185 1186@remote_compatible 1187def test_wpa2_ocv_no_pmf_workaround(dev, apdev): 1188 """OCV on 2.4 GHz and no PMF on STA with workaround""" 1189 params = {"channel": "1", 1190 "ieee80211w": "1", 1191 "ocv": "2"} 1192 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1193 ie = "301a0100000fac040100000fac040100000fac0200400000000fac06" 1194 if "OK" not in dev[0].request("TEST_ASSOC_IE " + ie): 1195 raise Exception("Could not set TEST_ASSOC_IE") 1196 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="0", 1197 ieee80211w="0") 1198 1199@remote_compatible 1200def test_wpa2_ocv_no_oci(dev, apdev): 1201 """OCV on 2.4 GHz and no OCI from STA""" 1202 params = {"channel": "1", 1203 "ieee80211w": "1", 1204 "ocv": "1"} 1205 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1206 ie = "301a0100000fac040100000fac040100000fac0280400000000fac06" 1207 if "OK" not in dev[0].request("TEST_ASSOC_IE " + ie): 1208 raise Exception("Could not set TEST_ASSOC_IE") 1209 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="0", 1210 ieee80211w="1", wait_connect=False) 1211 ev = hapd.wait_event(["OCV-FAILURE"], timeout=10) 1212 if ev is None: 1213 raise Exception("No OCV failure reported") 1214 if "frame=eapol-key-m2 error=did not receive mandatory OCI" not in ev: 1215 raise Exception("Unexpected error: " + ev) 1216 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 1217 "WPA: 4-Way Handshake failed"], timeout=10) 1218 dev[0].request("DISCONNECT") 1219 if "CTRL-EVENT-CONNECTED" in ev: 1220 raise Exception("Unexpected connection") 1221 if ev is None: 1222 raise Exception("4-way handshake failure not reported") 1223 1224@remote_compatible 1225def test_wpa2_ocv_no_oci_workaround(dev, apdev): 1226 """OCV on 2.4 GHz and no OCI from STA with workaround""" 1227 params = {"channel": "1", 1228 "ieee80211w": "1", 1229 "ocv": "2"} 1230 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1231 ie = "301a0100000fac040100000fac040100000fac0280400000000fac06" 1232 if "OK" not in dev[0].request("TEST_ASSOC_IE " + ie): 1233 raise Exception("Could not set TEST_ASSOC_IE") 1234 dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="0", 1235 ieee80211w="1") 1236 1237def test_wpa2_ocv_without_pmf(dev, apdev): 1238 """OCV without PMF""" 1239 params = {"channel": "6", 1240 "ieee80211n": "1", 1241 "ieee80211w": "1", 1242 "ocv": "1"} 1243 hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params) 1244 hapd.disable() 1245 hapd.set("ieee80211w", "0") 1246 if "FAIL" not in hapd.request("ENABLE"): 1247 raise Exception("OCV without PMF accepted") 1248