1# Test cases for RSNE/RSNXE overriding 2# Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. 3# 4# This software may be distributed under the terms of the BSD license. 5# See README for more details. 6 7import hostapd 8from utils import * 9from hwsim import HWSimRadio 10from wpasupplicant import WpaSupplicant 11from test_eht import eht_mld_enable_ap, eht_verify_status, eht_verify_wifi_version, traffic_test 12 13def test_rsn_override(dev, apdev): 14 """RSNE=WPA2-Personal/PMF-optional override=WPA3-Personal/PMF-required (with MLO parameters)""" 15 check_sae_capab(dev[0]) 16 17 ssid = "test-rsn-override" 18 params = hostapd.wpa2_params(ssid=ssid, 19 passphrase="12345678", 20 ieee80211w='1') 21 params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY' 22 params['rsn_override_pairwise'] = 'CCMP GCMP-256' 23 params['rsn_override_mfp'] = '2' 24 params['beacon_prot'] = '1' 25 params['sae_groups'] = '19 20' 26 params['sae_require_mfp'] = '1' 27 params['sae_pwe'] = '2' 28 hapd = hostapd.add_ap(apdev[0], params) 29 bssid = hapd.own_addr() 30 31 try: 32 dev[0].set("rsn_overriding", "1") 33 dev[0].scan_for_bss(bssid, freq=2412) 34 bss = dev[0].get_bss(bssid) 35 flags = bss['flags'] 36 if "PSK" in flags: 37 raise Exception("Unexpected BSS flags: " + flags) 38 if "-SAE+SAE-EXT-KEY-" not in flags: 39 raise Exception("Unexpected BSS flags: " + flags) 40 if "-GCMP-256+CCMP" not in flags: 41 raise Exception("Unexpected BSS flags: " + flags) 42 43 dev[0].set("sae_pwe", "2") 44 dev[0].set("sae_groups", "") 45 dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE", 46 ieee80211w="2", scan_freq="2412") 47 finally: 48 dev[0].set("sae_pwe", "0") 49 dev[0].set("rsn_overriding", "0") 50 51def test_rsn_override2(dev, apdev): 52 """RSNE=WPA2-Personal/PMF-disabled override=WPA3-Personal/PMF-required (with MLO parameters)""" 53 check_sae_capab(dev[0]) 54 55 ssid = "test-rsn-override" 56 params = hostapd.wpa2_params(ssid=ssid, 57 passphrase="12345678", 58 ieee80211w='0') 59 params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY' 60 params['rsn_override_pairwise'] = 'CCMP GCMP-256' 61 params['rsn_override_mfp'] = '2' 62 params['beacon_prot'] = '1' 63 params['sae_groups'] = '19 20' 64 params['sae_require_mfp'] = '1' 65 params['sae_pwe'] = '2' 66 hapd = hostapd.add_ap(apdev[0], params) 67 bssid = hapd.own_addr() 68 69 try: 70 dev[0].set("rsn_overriding", "1") 71 dev[0].scan_for_bss(bssid, freq=2412) 72 bss = dev[0].get_bss(bssid) 73 flags = bss['flags'] 74 if "PSK" in flags: 75 raise Exception("Unexpected BSS flags: " + flags) 76 if "-SAE+SAE-EXT-KEY-" not in flags: 77 raise Exception("Unexpected BSS flags: " + flags) 78 if "-GCMP-256+CCMP" not in flags: 79 raise Exception("Unexpected BSS flags: " + flags) 80 81 dev[0].set("sae_pwe", "2") 82 dev[0].set("sae_groups", "") 83 dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE", 84 ieee80211w="2", scan_freq="2412") 85 finally: 86 dev[0].set("sae_pwe", "0") 87 dev[0].set("rsn_overriding", "0") 88 89def test_rsn_override_no_pairwise(dev, apdev): 90 """RSN overriding and no pairwise cipher match in RSNEO""" 91 check_sae_capab(dev[0]) 92 93 ssid = "test-rsn-override" 94 params = hostapd.wpa2_params(ssid=ssid, 95 passphrase="12345678", 96 ieee80211w='1') 97 params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY' 98 params['rsn_override_pairwise'] = 'GCMP-256' 99 params['rsn_override_mfp'] = '2' 100 params['beacon_prot'] = '1' 101 params['sae_groups'] = '19 20' 102 params['sae_require_mfp'] = '1' 103 hapd = hostapd.add_ap(apdev[0], params) 104 bssid = hapd.own_addr() 105 106 try: 107 dev[0].set("rsn_overriding", "1") 108 dev[0].scan_for_bss(bssid, freq=2412) 109 110 dev[0].set("sae_groups", "") 111 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK SAE", 112 pairwise="CCMP", ieee80211w="1", scan_freq="2412") 113 finally: 114 dev[0].set("sae_pwe", "0") 115 dev[0].set("rsn_overriding", "0") 116 117def test_rsn_override_mld(dev, apdev): 118 """AP MLD and RSNE=WPA2-Personal/PMF-disabled override=WPA3-Personal/PMF-required""" 119 run_rsn_override_mld(dev, apdev, False) 120 121def test_rsn_override_mld_mixed(dev, apdev): 122 """AP MLD and RSNE=WPA2-Personal/PMF-disabled override=WPA3-Personal/PMF-required on one link""" 123 run_rsn_override_mld(dev, apdev, True) 124 125def test_rsn_override_mld_only_sta(dev, apdev): 126 """AP MLD and RSN overriding only on STA""" 127 run_rsn_override_mld(dev, apdev, False, only_sta=True) 128 129def test_rsn_override_mld_too_long_elems(dev, apdev): 130 """AP MLD and RSN overriding with too long elements""" 131 run_rsn_override_mld(dev, apdev, False, too_long_elems=True) 132 133def run_rsn_override_mld(dev, apdev, mixed, only_sta=False, 134 too_long_elems=False): 135 with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \ 136 HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface): 137 138 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 139 wpas.interface_add(wpas_iface) 140 check_sae_capab(wpas) 141 142 passphrase = 'qwertyuiop' 143 ssid = "AP MLD RSN override" 144 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 145 params['ieee80211n'] = '1' 146 params['ieee80211ax'] = '1' 147 params['ieee80211be'] = '1' 148 params['channel'] = '1' 149 params['hw_mode'] = 'g' 150 params['beacon_prot'] = '1' 151 params['sae_groups'] = '19 20' 152 params['sae_require_mfp'] = '1' 153 params['sae_pwe'] = '2' 154 if only_sta: 155 params['wpa_key_mgmt'] = 'SAE SAE-EXT-KEY' 156 params['rsn_pairwise'] = 'CCMP GCMP-256' 157 params['ieee80211w'] = '2' 158 elif not mixed: 159 params['rsn_override_key_mgmt'] = 'SAE' 160 params['rsn_override_key_mgmt_2'] = 'SAE-EXT-KEY' 161 params['rsn_override_pairwise'] = 'CCMP' 162 params['rsn_override_pairwise_2'] = 'GCMP-256' 163 params['rsn_override_mfp'] = '1' 164 params['rsn_override_mfp_2'] = '2' 165 166 params1 = dict(params) 167 168 if mixed: 169 params['wpa_key_mgmt'] = 'SAE SAE-EXT-KEY' 170 params['rsn_pairwise'] = 'CCMP GCMP-256' 171 params['ieee80211w'] = '2' 172 params['rsn_override_key_mgmt_2'] = 'SAE SAE-EXT-KEY' 173 params['rsn_override_pairwise_2'] = 'CCMP GCMP-256' 174 params['rsn_override_mfp_2'] = '2' 175 176 params1['rsn_override_key_mgmt_2'] = 'SAE SAE-EXT-KEY' 177 params1['rsn_override_pairwise_2'] = 'CCMP GCMP-256' 178 params1['rsn_override_mfp_2'] = '2' 179 180 hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) 181 182 params1['channel'] = '6' 183 if too_long_elems: 184 params1['rsnoe_override'] = 'ddff506f9a29' + 251*'cc' 185 hapd1 = eht_mld_enable_ap(hapd_iface, 1, params1) 186 187 wpas.set("sae_pwe", "1") 188 wpas.set("rsn_overriding", "1") 189 wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437", 190 key_mgmt="SAE-EXT-KEY", ieee80211w="2", beacon_prot="1", 191 pairwise="GCMP-256 CCMP", wait_connect=not too_long_elems) 192 if too_long_elems: 193 ev = wpas.wait_event(['Associated with'], timeout=10) 194 if ev is None: 195 raise Exception("Association not reported") 196 ev = wpas.wait_event(['EAPOL-RX'], timeout=1) 197 if ev is None: 198 raise Exception("EAPOL-Key M1 not reported") 199 ev = wpas.wait_event(['EAPOL-RX', 'CTRL-EVENT-DISCONNECTED'], 200 timeout=20) 201 if ev is None: 202 raise Exception("Disconnection not reported") 203 # The AP is expected to fail to send M3 due to RSNOE/RSNO2E/RSNXOE 204 # being too long to fit into the RSN Override Link KDE. 205 if 'EAPOL-RX' in ev: 206 raise Exception("Unexpected EAPOL-Key M3 reported") 207 return 208 209 eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True, 210 valid_links=3, active_links=3) 211 eht_verify_wifi_version(wpas) 212 traffic_test(wpas, hapd0) 213 traffic_test(wpas, hapd1) 214 if only_sta: 215 return 216 217 dev[0].set("rsn_overriding", "0") 218 dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", 219 scan_freq="2412 2437") 220 221 status = wpas.get_status() 222 logger.debug("wpas STATUS:\n" + str(status)) 223 if status['key_mgmt'] != 'SAE-EXT-KEY' or \ 224 'pmf' not in status or \ 225 status['pmf'] != '2' or \ 226 status['pairwise_cipher'] != 'GCMP-256': 227 raise Exception("Unexpected result for new STA") 228 229 status = dev[0].get_status() 230 logger.debug("dev[0] STATUS:\n" + str(status)) 231 if status['key_mgmt'] != 'WPA2-PSK' or \ 232 status['pairwise_cipher'] != 'CCMP': 233 raise Exception("Unexpected result for legacy STA") 234 235def test_rsn_override_connect_cmd(dev, apdev): 236 """RSNE=WPA2-Personal/PMF-optional override=WPA3-Personal/PMF-required using cfg80211 connect command""" 237 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 238 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1 rsn_override_in_driver=1") 239 check_sae_capab(wpas) 240 241 ssid = "test-rsn-override" 242 params = hostapd.wpa2_params(ssid=ssid, 243 passphrase="12345678", 244 ieee80211w='1') 245 params['rsn_override_key_mgmt'] = 'WPA-PSK-SHA256' 246 params['rsn_override_pairwise'] = 'CCMP GCMP-256' 247 params['rsn_override_mfp'] = '2' 248 params['beacon_prot'] = '1' 249 hapd = hostapd.add_ap(apdev[0], params) 250 251 wpas.set("rsn_overriding", "1") 252 wpas.connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256", 253 ieee80211w="2", scan_freq="2412") 254 255def test_rsn_override_omit_rsnxe(dev, apdev): 256 """RSN overriding with RSNXE explicitly omitted""" 257 check_sae_capab(dev[0]) 258 259 ssid = "test-rsn-override" 260 params = hostapd.wpa2_params(ssid=ssid, 261 passphrase="12345678", 262 ieee80211w='1') 263 params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY' 264 params['rsn_override_pairwise'] = 'CCMP GCMP-256' 265 params['rsn_override_mfp'] = '2' 266 params['beacon_prot'] = '1' 267 params['sae_groups'] = '19 20' 268 params['sae_require_mfp'] = '1' 269 params['sae_pwe'] = '2' 270 params['ssid_protection'] = '1' 271 params['rsn_override_omit_rsnxe'] = '1' 272 hapd = hostapd.add_ap(apdev[0], params) 273 bssid = hapd.own_addr() 274 275 try: 276 dev[0].set("rsn_overriding", "1") 277 dev[0].scan_for_bss(bssid, freq=2412) 278 dev[0].set("sae_pwe", "2") 279 dev[0].set("sae_groups", "") 280 dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE", 281 ieee80211w="2", ssid_protection="1", 282 scan_freq="2412") 283 finally: 284 dev[0].set("sae_pwe", "0") 285 dev[0].set("rsn_overriding", "0") 286 287def test_rsn_override_replace_ies(dev, apdev): 288 """RSN overriding and replaced AP IEs""" 289 check_sae_capab(dev[0]) 290 291 ssid = "test-rsn-override" 292 params = hostapd.wpa2_params(ssid=ssid, 293 passphrase="12345678", 294 ieee80211w='1') 295 params['rsn_override_key_mgmt'] = 'SAE' 296 params['rsn_override_key_mgmt_2'] = 'SAE-EXT-KEY' 297 params['rsn_override_pairwise'] = 'CCMP' 298 params['rsn_override_pairwise_2'] = 'GCMP-256' 299 params['rsn_override_mfp'] = '1' 300 params['rsn_override_mfp_2'] = '2' 301 params['beacon_prot'] = '1' 302 params['sae_groups'] = '19 20' 303 params['sae_require_mfp'] = '1' 304 params['sae_pwe'] = '2' 305 params['ssid_protection'] = '1' 306 params['rsne_override'] = '30180100000fac040100000fac040200000facff000fac020c00' 307 params['rsnxe_override'] = 'f40320eeee' 308 params['rsnoe_override'] = 'dd1c506f9a290100000fac040100000fac040200000facff000fac088c00' 309 params['rsno2e_override'] = 'dd1c506f9a2a0100000fac040100000fac090200000facff000fac18cc00' 310 params['rsnxoe_override'] = 'dd07506f9a2b20bbbb' 311 hapd = hostapd.add_ap(apdev[0], params) 312 bssid = hapd.own_addr() 313 314 try: 315 dev[0].set("rsn_overriding", "1") 316 dev[0].scan_for_bss(bssid, freq=2412) 317 dev[0].set("sae_pwe", "2") 318 dev[0].set("sae_groups", "") 319 dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE", 320 ieee80211w="2", ssid_protection="1", 321 scan_freq="2412") 322 finally: 323 dev[0].set("sae_pwe", "0") 324 dev[0].set("rsn_overriding", "0") 325 326def test_rsn_override_rsnxe_extensibility(dev, apdev): 327 """RSN overriding and RSNXE extensibility""" 328 check_sae_capab(dev[0]) 329 330 ssid = "test-rsn-override" 331 params = hostapd.wpa2_params(ssid=ssid, 332 passphrase="12345678", 333 ieee80211w='1') 334 params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY' 335 params['rsn_override_pairwise'] = 'CCMP GCMP-256' 336 params['rsn_override_mfp'] = '2' 337 params['beacon_prot'] = '1' 338 params['sae_groups'] = '19 20' 339 params['sae_require_mfp'] = '1' 340 params['sae_pwe'] = '2' 341 params['rsnxe_override'] = 'f4182f0000ffffffffffffffffffffffffffeeeeeeeeeeeeeeee' 342 params['rsnxoe_override'] = 'dd1c506f9a2b2f0000ffffffffffffffffffffffffffeeeeeeeeeeeeeeee' 343 hapd = hostapd.add_ap(apdev[0], params) 344 bssid = hapd.own_addr() 345 346 try: 347 dev[0].set("rsn_overriding", "1") 348 dev[0].scan_for_bss(bssid, freq=2412) 349 dev[0].set("sae_pwe", "2") 350 dev[0].set("sae_groups", "") 351 dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE", 352 ieee80211w="2", ssid_protection="1", 353 scan_freq="2412") 354 finally: 355 dev[0].set("sae_pwe", "0") 356 dev[0].set("rsn_overriding", "0") 357 358def test_rsn_override_sta_only(dev, apdev): 359 """RSN overriding enabled only on the STA""" 360 check_sae_capab(dev[0]) 361 params = hostapd.wpa2_params(ssid="test-sae", 362 passphrase="12345678") 363 params['wpa_key_mgmt'] = 'SAE' 364 hapd = hostapd.add_ap(apdev[0], params) 365 366 dev[0].set("sae_groups", "") 367 try: 368 dev[0].set("rsn_overriding", "1") 369 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", 370 scan_freq="2412") 371 finally: 372 dev[0].set("rsn_overriding", "0") 373 374def test_rsn_override_compatibility_mode(dev, apdev): 375 """RSN overriding and WPA3-Personal Compatibility Mode""" 376 check_sae_capab(dev[0]) 377 378 ssid = "test-rsn-override" 379 params = hostapd.wpa2_params(ssid=ssid, 380 passphrase="12345678") 381 params['rsn_override_key_mgmt'] = 'SAE' 382 params['rsn_override_key_mgmt_2'] = 'SAE-EXT-KEY' 383 params['rsn_override_pairwise'] = 'CCMP' 384 params['rsn_override_pairwise_2'] = 'GCMP-256' 385 params['rsn_override_mfp'] = '2' 386 params['rsn_override_mfp_2'] = '2' 387 params['beacon_prot'] = '1' 388 params['sae_groups'] = '19 20' 389 params['sae_require_mfp'] = '1' 390 params['sae_pwe'] = '2' 391 hapd = hostapd.add_ap(apdev[0], params) 392 bssid = hapd.own_addr() 393 394 try: 395 logger.info("RSN overriding capable STA using RSNO2E") 396 dev[0].set("rsn_overriding", "1") 397 dev[0].scan_for_bss(bssid, freq=2412) 398 dev[0].set("sae_pwe", "2") 399 dev[0].set("sae_groups", "") 400 dev[0].connect(ssid, sae_password="12345678", 401 pairwise="GCMP-256", key_mgmt="SAE-EXT-KEY", 402 ieee80211w="2", scan_freq="2412") 403 hapd.wait_sta() 404 dev[0].request("REMOVE_NETWORK all") 405 dev[0].wait_disconnected() 406 hapd.wait_sta_disconnect() 407 408 logger.info("RSN overriding capable STA using RSNOE") 409 dev[0].set("sae_pwe", "0") 410 dev[0].connect(ssid, sae_password="12345678", 411 pairwise="CCMP", key_mgmt="SAE", 412 ieee80211w="2", scan_freq="2412") 413 hapd.wait_sta() 414 dev[0].request("REMOVE_NETWORK all") 415 dev[0].wait_disconnected() 416 hapd.wait_sta_disconnect() 417 418 logger.info("RSN overriding capable STA using RSNE") 419 dev[0].connect(ssid, psk="12345678", 420 pairwise="CCMP", key_mgmt="WPA-PSK", 421 ieee80211w="0", scan_freq="2412") 422 hapd.wait_sta() 423 dev[0].request("REMOVE_NETWORK all") 424 dev[0].wait_disconnected() 425 hapd.wait_sta_disconnect() 426 427 logger.info("RSN overriding uncapable STA using RSNE") 428 dev[0].set("rsn_overriding", "0") 429 dev[0].connect(ssid, psk="12345678", 430 pairwise="CCMP", key_mgmt="WPA-PSK", 431 ieee80211w="0", scan_freq="2412") 432 hapd.wait_sta() 433 dev[0].request("REMOVE_NETWORK all") 434 dev[0].wait_disconnected() 435 hapd.wait_sta_disconnect() 436 finally: 437 dev[0].set("sae_pwe", "0") 438 dev[0].set("rsn_overriding", "0") 439