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        logger.info("AP1 state: " + state)
315        if state == "ACS-STARTED":
316            time.sleep(5)
317            state = hapd.get_status_field("state")
318            logger.info("AP1 state after 5 sec: " + state)
319        if state != "ENABLED":
320            time.sleep(1)
321            state = hapd.get_status_field("state")
322            logger.info("AP1 state after 1 sec: " + state)
323        if state != "ENABLED":
324            raise Exception("AP1 startup did not succeed")
325
326    freq = hapd.get_status_field("freq")
327    freq2 = hapd2.get_status_field("freq")
328
329    dev[0].scan_for_bss(bssid, freq=freq)
330    dev[0].scan_for_bss(bssid2, freq=freq2)
331
332    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
333                        scan_freq="%s %s" % (freq, freq2))
334    val = dev[0].get_status_field("key_mgmt")
335    if val != "OWE":
336        raise Exception("Unexpected key_mgmt: " + val)
337
338def test_owe_transition_mode_multi_assoc(dev, apdev):
339    """Opportunistic Wireless Encryption transition mode and multiple associations"""
340    if "OWE" not in dev[0].get_capability("key_mgmt"):
341        raise HwsimSkip("OWE not supported")
342    dev[0].flush_scan_cache()
343    params = {"ssid": "owe-random",
344              "wpa": "2",
345              "wpa_key_mgmt": "OWE",
346              "rsn_pairwise": "CCMP",
347              "ieee80211w": "2",
348              "owe_transition_bssid": apdev[1]['bssid'],
349              "owe_transition_ssid": '"owe-test"',
350              "ignore_broadcast_ssid": "1"}
351    hapd = hostapd.add_ap(apdev[0], params)
352    bssid = hapd.own_addr()
353
354    params = {"ssid": "owe-test",
355              "owe_transition_bssid": apdev[0]['bssid'],
356              "owe_transition_ssid": '"owe-random"'}
357    hapd2 = hostapd.add_ap(apdev[1], params)
358    bssid2 = hapd2.own_addr()
359
360    dev[0].scan_for_bss(bssid, freq="2412")
361    dev[0].scan_for_bss(bssid2, freq="2412")
362
363    dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2")
364    hapd.wait_sta()
365
366    if dev[0].get_status_field("bssid") != bssid:
367        raise Exception("Unexpected BSSID")
368
369    for i in range(5):
370        dev[0].request("DISCONNECT")
371        dev[0].wait_disconnected()
372        dev[0].dump_monitor()
373
374        dev[0].scan(freq=2412)
375
376        dev[0].request("RECONNECT")
377        dev[0].wait_connected()
378        hapd.wait_sta()
379        if dev[0].get_status_field("bssid") != bssid:
380            raise Exception("Unexpected BSSID")
381        time.sleep(1)
382        dev[0].dump_monitor()
383
384    res = dev[0].request("SCAN_RESULTS").splitlines()
385    num = 0
386    for r in res:
387        if "owe-random" in r:
388            num += 1
389    if num != 1:
390        logger.info("SCAN_RESULTS:\n" + str(res))
391        raise Exception("Unexpected number of BSS entries for owe-random: %d" % num)
392
393def test_owe_transition_mode_open_only_ap(dev, apdev):
394    """Opportunistic Wireless Encryption transition mode connect to open-only AP"""
395    if "OWE" not in dev[0].get_capability("key_mgmt"):
396        raise HwsimSkip("OWE not supported")
397    dev[0].flush_scan_cache()
398    params = {"ssid": "owe-test-open"}
399    hapd = hostapd.add_ap(apdev[0], params)
400    bssid = hapd.own_addr()
401
402    dev[0].scan_for_bss(bssid, freq="2412")
403
404    bss = dev[0].get_bss(bssid)
405
406    id = dev[0].connect("owe-test-open", key_mgmt="OWE", ieee80211w="2",
407                        scan_freq="2412")
408    hwsim_utils.test_connectivity(dev[0], hapd)
409    val = dev[0].get_status_field("key_mgmt")
410    if val != "NONE":
411        raise Exception("Unexpected key_mgmt: " + val)
412
413def test_owe_only_sta(dev, apdev):
414    """Opportunistic Wireless Encryption transition mode disabled on STA"""
415    if "OWE" not in dev[0].get_capability("key_mgmt"):
416        raise HwsimSkip("OWE not supported")
417    dev[0].flush_scan_cache()
418    params = {"ssid": "owe-test-open"}
419    hapd = hostapd.add_ap(apdev[0], params)
420    bssid = hapd.own_addr()
421
422    dev[0].scan_for_bss(bssid, freq="2412")
423    id = dev[0].connect("owe-test-open", key_mgmt="OWE", ieee80211w="2",
424                        scan_freq="2412", owe_only="1", wait_connect=False)
425    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
426                            "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
427    if not ev:
428        raise Exception("Unknown result for the connection attempt")
429    if "CTRL-EVENT-CONNECTED" in ev:
430        raise Exception("Unexpected connection to open network")
431    dev[0].request("DISCONNECT")
432    dev[0].dump_monitor()
433
434    params = {"ssid": "owe-test-open",
435              "wpa": "2",
436              "ieee80211w": "2",
437              "wpa_key_mgmt": "OWE",
438              "rsn_pairwise": "CCMP"}
439    hapd2 = hostapd.add_ap(apdev[1], params)
440    dev[0].request("RECONNECT")
441    dev[0].wait_connected()
442
443def test_owe_only_sta_tm_ap(dev, apdev):
444    """Opportunistic Wireless Encryption transition mode disabled on STA and AP using transition mode"""
445    if "OWE" not in dev[0].get_capability("key_mgmt"):
446        raise HwsimSkip("OWE not supported")
447    dev[0].flush_scan_cache()
448
449    adv_bssid = apdev[1]['bssid']
450    params = {"ssid": "owe-random",
451              "wpa": "2",
452              "wpa_key_mgmt": "OWE",
453              "rsn_pairwise": "CCMP",
454              "ieee80211w": "2",
455              "owe_transition_bssid": adv_bssid,
456              "owe_transition_ssid": '"owe-test"',
457              "ignore_broadcast_ssid": "1"}
458    hapd = hostapd.add_ap(apdev[0], params)
459    bssid = hapd.own_addr()
460
461    adv_bssid = apdev[0]['bssid']
462    params = {"ssid": "owe-test",
463              "owe_transition_bssid": adv_bssid,
464              "owe_transition_ssid": '"owe-random"'}
465    hapd2 = hostapd.add_ap(apdev[1], params)
466    bssid2 = hapd2.own_addr()
467
468    dev[0].scan_for_bss(bssid, freq="2412")
469    dev[0].scan_for_bss(bssid2, freq="2412")
470
471    dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", owe_only="1")
472
473def test_owe_transition_mode_open_multiple_scans(dev, apdev):
474    """Opportunistic Wireless Encryption transition mode and need for multiple scans"""
475    if "OWE" not in dev[0].get_capability("key_mgmt"):
476        raise HwsimSkip("OWE not supported")
477    dev[0].flush_scan_cache()
478    params = {"ssid": "owe-test",
479              "owe_transition_bssid": apdev[0]['bssid'],
480              "owe_transition_ssid": '"owe-random"'}
481    hapd2 = hostapd.add_ap(apdev[1], params)
482    bssid2 = hapd2.own_addr()
483
484    dev[0].scan_for_bss(bssid2, freq="2412")
485
486    dev[0].dump_monitor()
487    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
488                        scan_freq="2412", wait_connect=False)
489    ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=1)
490
491    params = {"ssid": "owe-random",
492              "wpa": "2",
493              "wpa_key_mgmt": "OWE",
494              "rsn_pairwise": "CCMP",
495              "ieee80211w": "2",
496              "owe_transition_bssid": apdev[1]['bssid'],
497              "owe_transition_ssid": '"owe-test"',
498              "ignore_broadcast_ssid": "1"}
499    hapd = hostapd.add_ap(apdev[0], params)
500    bssid = hapd.own_addr()
501
502    dev[0].wait_connected()
503
504    val = dev[0].get_status_field("key_mgmt")
505    if val != "OWE":
506        raise Exception("Unexpected key_mgmt: " + val)
507
508def test_owe_transition_mode_multi_bss(dev, apdev):
509    """Opportunistic Wireless Encryption transition mode (multi BSS)"""
510    try:
511        run_owe_transition_mode_multi_bss(dev, apdev)
512    finally:
513        dev[0].request("SCAN_INTERVAL 5")
514
515def run_owe_transition_mode_multi_bss(dev, apdev):
516    if "OWE" not in dev[0].get_capability("key_mgmt"):
517        raise HwsimSkip("OWE not supported")
518    ifname1 = apdev[0]['ifname']
519    ifname2 = apdev[0]['ifname'] + '-2'
520    hapd1 = hostapd.add_bss(apdev[0], ifname1, 'owe-bss-1.conf')
521    hapd2 = hostapd.add_bss(apdev[0], ifname2, 'owe-bss-2.conf')
522    hapd2.bssidx = 1
523
524    bssid = hapd1.own_addr()
525    bssid2 = hapd2.own_addr()
526
527    # Beaconing with the OWE Transition Mode element can start only once both
528    # BSSs are enabled, so the very first Beacon frame may go out without this
529    # element. Wait a bit to avoid getting incomplete scan results.
530    time.sleep(0.1)
531
532    dev[0].request("SCAN_INTERVAL 1")
533    dev[0].scan_for_bss(bssid2, freq="2412")
534    dev[0].scan_for_bss(bssid, freq="2412")
535    dev[0].connect("transition-mode-open", key_mgmt="OWE")
536    val = dev[0].get_status_field("bssid")
537    if val != bssid2:
538        raise Exception("Unexpected bssid: " + val)
539    val = dev[0].get_status_field("key_mgmt")
540    if val != "OWE":
541        raise Exception("Unexpected key_mgmt: " + val)
542    hwsim_utils.test_connectivity(dev[0], hapd2)
543
544def test_owe_transition_mode_rsne_mismatch(dev, apdev):
545    """Opportunistic Wireless Encryption transition mode and RSNE mismatch"""
546    if "OWE" not in dev[0].get_capability("key_mgmt"):
547        raise HwsimSkip("OWE not supported")
548    dev[0].flush_scan_cache()
549    params = {"ssid": "owe-random",
550              "wpa": "2",
551              "wpa_key_mgmt": "OWE",
552              "rsn_pairwise": "CCMP",
553              "ieee80211w": "2",
554              "rsne_override_eapol": "30140100000fac040100000fac040100000fac020c00",
555              "owe_transition_bssid": apdev[1]['bssid'],
556              "owe_transition_ssid": '"owe-test"',
557              "ignore_broadcast_ssid": "1"}
558    hapd = hostapd.add_ap(apdev[0], params)
559    bssid = hapd.own_addr()
560
561    params = {"ssid": "owe-test",
562              "owe_transition_bssid": apdev[0]['bssid'],
563              "owe_transition_ssid": '"owe-random"'}
564    hapd2 = hostapd.add_ap(apdev[1], params)
565    bssid2 = hapd2.own_addr()
566
567    dev[0].scan_for_bss(bssid, freq="2412")
568    dev[0].scan_for_bss(bssid2, freq="2412")
569
570    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
571                        scan_freq="2412", wait_connect=False)
572    ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5)
573    if ev is None:
574        raise Exception("OWE PMKSA not created")
575    ev = dev[0].wait_event(["WPA: IE in 3/4 msg does not match with IE in Beacon/ProbeResp"],
576                           timeout=5)
577    if ev is None:
578        raise Exception("RSNE mismatch not reported")
579    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
580                            "CTRL-EVENT-DISCONNECTED"], timeout=5)
581    dev[0].request("REMOVE_NETWORK all")
582    if ev is None:
583        raise Exception("No disconnection seen")
584    if "CTRL-EVENT-DISCONNECTED" not in ev:
585        raise Exception("Unexpected connection")
586    if "reason=17 locally_generated=1" not in ev:
587        raise Exception("Unexpected disconnection reason: " + ev)
588
589def test_owe_unsupported_group(dev, apdev):
590    """Opportunistic Wireless Encryption and unsupported group"""
591    try:
592        run_owe_unsupported_group(dev, apdev)
593    finally:
594        dev[0].request("VENDOR_ELEM_REMOVE 13 *")
595
596def test_owe_unsupported_group_connect_cmd(dev, apdev):
597    """Opportunistic Wireless Encryption and unsupported group using cfg80211 connect command"""
598    try:
599        wpas = None
600        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
601        wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
602        run_owe_unsupported_group([wpas], apdev)
603    finally:
604        if wpas:
605            wpas.request("VENDOR_ELEM_REMOVE 13 *")
606
607def run_owe_unsupported_group(dev, apdev):
608    if "OWE" not in dev[0].get_capability("key_mgmt"):
609        raise HwsimSkip("OWE not supported")
610    # Override OWE Dh Parameters element with a payload that uses invalid group
611    # 0 (and actual group 19 data) to make the AP reject this with the specific
612    # status code 77.
613    dev[0].request("VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd")
614
615    params = {"ssid": "owe",
616              "wpa": "2",
617              "wpa_key_mgmt": "OWE",
618              "rsn_pairwise": "CCMP"}
619    hapd = hostapd.add_ap(apdev[0], params)
620    bssid = hapd.own_addr()
621
622    dev[0].scan_for_bss(bssid, freq="2412")
623    dev[0].connect("owe", key_mgmt="OWE", wait_connect=False)
624    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
625    dev[0].request("DISCONNECT")
626    if ev is None:
627        raise Exception("Association not rejected")
628    if "status_code=77" not in ev:
629        raise Exception("Unexpected rejection reason: " + ev)
630
631def test_owe_limited_group_set(dev, apdev):
632    """Opportunistic Wireless Encryption and limited group set"""
633    if "OWE" not in dev[0].get_capability("key_mgmt"):
634        raise HwsimSkip("OWE not supported")
635    params = {"ssid": "owe",
636              "wpa": "2",
637              "wpa_key_mgmt": "OWE",
638              "rsn_pairwise": "CCMP",
639              "owe_groups": "20 21"}
640    hapd = hostapd.add_ap(apdev[0], params)
641    bssid = hapd.own_addr()
642
643    dev[0].scan_for_bss(bssid, freq="2412")
644    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", wait_connect=False)
645    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
646    dev[0].request("DISCONNECT")
647    if ev is None:
648        raise Exception("Association not rejected")
649    if "status_code=77" not in ev:
650        raise Exception("Unexpected rejection reason: " + ev)
651    dev[0].dump_monitor()
652
653    for group in [20, 21]:
654        dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group))
655        dev[0].request("REMOVE_NETWORK all")
656        dev[0].wait_disconnected()
657        dev[0].dump_monitor()
658
659def test_owe_limited_group_set_pmf(dev, apdev, params):
660    """Opportunistic Wireless Encryption and limited group set (PMF)"""
661    if "OWE" not in dev[0].get_capability("key_mgmt"):
662        raise HwsimSkip("OWE not supported")
663    pcapng = os.path.join(params['logdir'], "hwsim0.pcapng")
664
665    params = {"ssid": "owe",
666              "wpa": "2",
667              "ieee80211w": "2",
668              "wpa_key_mgmt": "OWE",
669              "rsn_pairwise": "CCMP",
670              "owe_groups": "21"}
671    hapd = hostapd.add_ap(apdev[0], params)
672    bssid = hapd.own_addr()
673
674    dev[0].scan_for_bss(bssid, freq="2412")
675    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
676                   scan_freq="2412", wait_connect=False)
677    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
678    dev[0].request("DISCONNECT")
679    if ev is None:
680        raise Exception("Association not rejected")
681    if "status_code=77" not in ev:
682        raise Exception("Unexpected rejection reason: " + ev)
683    dev[0].dump_monitor()
684
685    dev[0].connect("owe", key_mgmt="OWE", owe_group="20", ieee80211w="2",
686                   scan_freq="2412", wait_connect=False)
687    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
688    dev[0].request("DISCONNECT")
689    if ev is None:
690        raise Exception("Association not rejected (2)")
691    if "status_code=77" not in ev:
692        raise Exception("Unexpected rejection reason (2): " + ev)
693    dev[0].dump_monitor()
694
695    dev[0].connect("owe", key_mgmt="OWE", owe_group="21", ieee80211w="2",
696                   scan_freq="2412")
697    dev[0].request("REMOVE_NETWORK all")
698    dev[0].wait_disconnected()
699    dev[0].dump_monitor()
700
701    out = run_tshark(pcapng,
702                     "wlan.fc.type_subtype == 1",
703                     display=['wlan_mgt.fixed.status_code'])
704    status = out.splitlines()
705    logger.info("Association Response frame status codes: " + str(status))
706    if len(status) != 3:
707        raise Exception("Unexpected number of Association Response frames")
708    if (int(status[0], base=0) != 77 or int(status[1], base=0) != 77 or
709        int(status[2], base=0) != 0):
710        raise Exception("Unexpected Association Response frame status code")
711
712def test_owe_group_negotiation(dev, apdev):
713    """Opportunistic Wireless Encryption and group negotiation"""
714    run_owe_group_negotiation(dev[0], apdev)
715
716def test_owe_group_negotiation_connect_cmd(dev, apdev):
717    """Opportunistic Wireless Encryption and group negotiation (connect command)"""
718    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
719    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
720    run_owe_group_negotiation(wpas, apdev)
721
722def run_owe_group_negotiation(dev, apdev):
723    if "OWE" not in dev.get_capability("key_mgmt"):
724        raise HwsimSkip("OWE not supported")
725    params = {"ssid": "owe",
726              "wpa": "2",
727              "wpa_key_mgmt": "OWE",
728              "rsn_pairwise": "CCMP",
729              "owe_groups": "21"}
730    hapd = hostapd.add_ap(apdev[0], params)
731    bssid = hapd.own_addr()
732
733    dev.scan_for_bss(bssid, freq="2412")
734    dev.connect("owe", key_mgmt="OWE")
735
736def test_owe_assoc_reject(dev, apdev):
737    """Opportunistic Wireless Encryption association rejection handling"""
738    if "OWE" not in dev[0].get_capability("key_mgmt"):
739        raise HwsimSkip("OWE not supported")
740    params = {"ssid": "owe",
741              "require_ht": "1",
742              "wpa": "2",
743              "ieee80211w": "2",
744              "wpa_key_mgmt": "OWE",
745              "rsn_pairwise": "CCMP",
746              "owe_groups": "19"}
747    hapd = hostapd.add_ap(apdev[0], params)
748    bssid = hapd.own_addr()
749
750    # First, reject two associations with HT-required (i.e., not OWE related)
751    dev[0].scan_for_bss(bssid, freq="2412")
752    dev[0].connect("owe", key_mgmt="OWE", ieee80211w="2",
753                   disable_ht="1", scan_freq="2412", wait_connect=False)
754    for i in range(0, 2):
755        ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
756        if ev is None:
757            raise Exception("Association rejection not reported")
758
759    # Then, verify that STA tries OWE with the default group (19) on the next
760    # attempt instead of having moved to testing another group.
761    hapd.set("require_ht", "0")
762    for i in range(0, 2):
763        ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT",
764                                "CTRL-EVENT-CONNECTED"], timeout=10)
765        if ev is None:
766            raise Exception("Association result not reported")
767        if "CTRL-EVENT-CONNECTED" in ev:
768            break
769        if "status_code=77" in ev:
770            raise Exception("Unexpected unsupport group rejection")
771    if "CTRL-EVENT-CONNECTED" not in ev:
772        raise Exception("Did not connect successfully")
773
774def test_owe_local_errors(dev, apdev):
775    """Opportunistic Wireless Encryption - local errors on supplicant"""
776    if "OWE" not in dev[0].get_capability("key_mgmt"):
777        raise HwsimSkip("OWE not supported")
778    params = {"ssid": "owe",
779              "wpa": "2",
780              "ieee80211w": "2",
781              "wpa_key_mgmt": "OWE",
782              "rsn_pairwise": "CCMP"}
783    hapd = hostapd.add_ap(apdev[0], params)
784    bssid = hapd.own_addr()
785
786    dev[0].scan_for_bss(bssid, freq="2412")
787
788    tests = [(1, "crypto_ecdh_init;owe_build_assoc_req"),
789             (1, "crypto_ecdh_get_pubkey;owe_build_assoc_req"),
790             (1, "wpabuf_alloc;owe_build_assoc_req")]
791    for count, func in tests:
792        with alloc_fail(dev[0], count, func):
793            dev[0].connect("owe", key_mgmt="OWE", owe_group="20",
794                           ieee80211w="2",
795                           scan_freq="2412", wait_connect=False)
796            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
797            dev[0].request("REMOVE_NETWORK all")
798            dev[0].dump_monitor()
799
800    tests = [(1, "crypto_ecdh_set_peerkey;owe_process_assoc_resp"),
801             (1, "crypto_ecdh_get_pubkey;owe_process_assoc_resp"),
802             (1, "wpabuf_alloc;=owe_process_assoc_resp")]
803    for count, func in tests:
804        with alloc_fail(dev[0], count, func):
805            dev[0].connect("owe", key_mgmt="OWE", owe_group="20",
806                           ieee80211w="2",
807                           scan_freq="2412", wait_connect=False)
808            dev[0].wait_disconnected()
809            dev[0].request("REMOVE_NETWORK all")
810            dev[0].dump_monitor()
811
812    tests = [(1, "hmac_sha256;owe_process_assoc_resp", 19),
813             (1, "hmac_sha256_kdf;owe_process_assoc_resp", 19),
814             (1, "hmac_sha384;owe_process_assoc_resp", 20),
815             (1, "hmac_sha384_kdf;owe_process_assoc_resp", 20),
816             (1, "hmac_sha512;owe_process_assoc_resp", 21),
817             (1, "hmac_sha512_kdf;owe_process_assoc_resp", 21)]
818    for count, func, group in tests:
819        with fail_test(dev[0], count, func):
820            dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group),
821                           ieee80211w="2",
822                           scan_freq="2412", wait_connect=False)
823            dev[0].wait_disconnected()
824            dev[0].request("REMOVE_NETWORK all")
825            dev[0].dump_monitor()
826
827    dev[0].connect("owe", key_mgmt="OWE", owe_group="18",
828                   ieee80211w="2",
829                   scan_freq="2412", wait_connect=False)
830    ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=5)
831    if ev is None:
832        raise Exception("No authentication attempt")
833    time.sleep(0.5)
834    dev[0].request("REMOVE_NETWORK all")
835    dev[0].dump_monitor()
836
837def hapd_auth(hapd):
838    for i in range(0, 10):
839        req = hapd.mgmt_rx()
840        if req is None:
841            raise Exception("MGMT RX wait timed out")
842        if req['subtype'] == 11:
843            break
844        req = None
845    if not req:
846        raise Exception("Authentication frame not received")
847
848    resp = {}
849    resp['fc'] = req['fc']
850    resp['da'] = req['sa']
851    resp['sa'] = req['da']
852    resp['bssid'] = req['bssid']
853    resp['payload'] = struct.pack('<HHH', 0, 2, 0)
854    hapd.mgmt_tx(resp)
855
856def hapd_assoc(hapd, extra):
857    for i in range(0, 10):
858        req = hapd.mgmt_rx()
859        if req is None:
860            raise Exception("MGMT RX wait timed out")
861        if req['subtype'] == 0:
862            break
863        req = None
864    if not req:
865        raise Exception("Association Request frame not received")
866
867    resp = {}
868    resp['fc'] = 0x0010
869    resp['da'] = req['sa']
870    resp['sa'] = req['da']
871    resp['bssid'] = req['bssid']
872    payload = struct.pack('<HHH', 0x0411, 0, 0xc001)
873    payload += binascii.unhexlify("010882848b960c121824")
874    resp['payload'] = payload + extra
875    hapd.mgmt_tx(resp)
876
877def test_owe_invalid_assoc_resp(dev, apdev):
878    """Opportunistic Wireless Encryption - invalid Association Response frame"""
879    if "OWE" not in dev[0].get_capability("key_mgmt"):
880        raise HwsimSkip("OWE not supported")
881    params = {"ssid": "owe",
882              "wpa": "2",
883              "ieee80211w": "2",
884              "wpa_key_mgmt": "OWE",
885              "rsn_pairwise": "CCMP"}
886    hapd = hostapd.add_ap(apdev[0], params)
887    bssid = hapd.own_addr()
888
889    dev[0].scan_for_bss(bssid, freq="2412")
890
891    hapd.set("ext_mgmt_frame_handling", "1")
892    # OWE: No Diffie-Hellman Parameter element found in Association Response frame
893    tests = [b'']
894    # No room for group --> no DH Params
895    tests += [binascii.unhexlify('ff0120')]
896    # OWE: Unexpected Diffie-Hellman group in response: 18
897    tests += [binascii.unhexlify('ff03201200')]
898    # OWE: Invalid peer DH public key
899    tests += [binascii.unhexlify('ff23201300' + 31*'00' + '01')]
900    # OWE: Invalid peer DH public key
901    tests += [binascii.unhexlify('ff24201300' + 33*'ee')]
902    for extra in tests:
903        dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
904                       scan_freq="2412", wait_connect=False)
905        hapd_auth(hapd)
906        hapd_assoc(hapd, extra)
907        dev[0].wait_disconnected()
908        dev[0].request("REMOVE_NETWORK all")
909        dev[0].dump_monitor()
910
911    # OWE: Empty public key (this ends up getting padded to a valid point)
912    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
913                   scan_freq="2412", wait_connect=False)
914    hapd_auth(hapd)
915    hapd_assoc(hapd, binascii.unhexlify('ff03201300'))
916    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED", "PMKSA-CACHE-ADDED"],
917                           timeout=5)
918    if ev is None:
919        raise Exception("No result reported for empty public key")
920    dev[0].request("REMOVE_NETWORK all")
921    dev[0].dump_monitor()
922
923def test_owe_double_assoc(dev, apdev):
924    """Opportunistic Wireless Encryption - duplicated association attempt"""
925    if "OWE" not in dev[0].get_capability("key_mgmt"):
926        raise HwsimSkip("OWE not supported")
927    params = {"ssid": "owe",
928              "wpa": "2",
929              "ieee80211w": "2",
930              "wpa_key_mgmt": "OWE",
931              "rsn_pairwise": "CCMP"}
932    hapd = hostapd.add_ap(apdev[0], params)
933    bssid = hapd.own_addr()
934
935    dev[0].scan_for_bss(bssid, freq="2412")
936
937    hapd.set("ext_mgmt_frame_handling", "1")
938    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
939                   scan_freq="2412", wait_connect=False)
940
941    for i in range(0, 10):
942        req = hapd.mgmt_rx()
943        if req is None:
944            raise Exception("MGMT RX wait timed out")
945        if req['subtype'] == 11:
946            break
947        req = None
948    if not req:
949        raise Exception("Authentication frame not received")
950    hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
951
952    for i in range(0, 10):
953        req = hapd.mgmt_rx()
954        if req is None:
955            raise Exception("MGMT RX wait timed out")
956        if req['subtype'] == 0:
957            break
958        req = None
959    if not req:
960        raise Exception("Association Request frame not received")
961    hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
962
963    ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
964    if ev is None:
965        raise Exception("Management frame TX status not reported (1)")
966    if "stype=1 ok=1" not in ev:
967        raise Exception("Unexpected management frame TX status (1): " + ev)
968    cmd = "MGMT_TX_STATUS_PROCESS stype=1 ok=0 %s" % (ev.split(' ')[3])
969    if "OK" not in hapd.request(cmd):
970        raise Exception("MGMT_TX_STATUS_PROCESS failed")
971
972    hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
973
974    ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
975    if ev is None:
976        raise Exception("Management frame TX status not reported (1)")
977    if "stype=1 ok=1" not in ev:
978        raise Exception("Unexpected management frame TX status (1): " + ev)
979    cmd = "MGMT_TX_STATUS_PROCESS stype=1 ok=1 %s" % (ev.split(' ')[3])
980    if "OK" not in hapd.request(cmd):
981        raise Exception("MGMT_TX_STATUS_PROCESS failed")
982
983    ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5)
984    if ev is None:
985        raise Exception("No PMKSA cache entry from OWE added")
986
987    dev[0].wait_connected()
988
989def start_owe(dev, apdev, workaround=0):
990    if "OWE" not in dev[0].get_capability("key_mgmt"):
991        raise HwsimSkip("OWE not supported")
992    params = {"ssid": "owe",
993              "wpa": "2",
994              "ieee80211w": "2",
995              "wpa_key_mgmt": "OWE",
996              "owe_ptk_workaround": str(workaround),
997              "rsn_pairwise": "CCMP"}
998    hapd = hostapd.add_ap(apdev[0], params)
999    dev[0].scan_for_bss(hapd.own_addr(), freq="2412")
1000    return hapd
1001
1002def owe_check_ok(dev, hapd, owe_group, owe_ptk_workaround):
1003    dev.connect("owe", key_mgmt="OWE", ieee80211w="2",
1004                owe_group=owe_group, owe_ptk_workaround=owe_ptk_workaround,
1005                scan_freq="2412")
1006    hapd.wait_sta()
1007    dev.request("REMOVE_NETWORK all")
1008    dev.wait_disconnected()
1009    dev.dump_monitor()
1010
1011def test_owe_ptk_workaround_ap(dev, apdev):
1012    """Opportunistic Wireless Encryption - AP using PTK workaround"""
1013    hapd = start_owe(dev, apdev, workaround=1)
1014    for group, workaround in [(19, 0), (20, 0), (21, 0),
1015                              (19, 1), (20, 1), (21, 1)]:
1016        owe_check_ok(dev[0], hapd, str(group), str(workaround))
1017
1018def test_owe_ptk_hash(dev, apdev):
1019    """Opportunistic Wireless Encryption - PTK derivation hash alg"""
1020    hapd = start_owe(dev, apdev)
1021    for group, workaround in [(19, 0), (20, 0), (21, 0), (19, 1)]:
1022        owe_check_ok(dev[0], hapd, str(group), str(workaround))
1023
1024    for group in [20, 21]:
1025        dev[0].connect("owe", key_mgmt="OWE", ieee80211w="2",
1026                       owe_group=str(group), owe_ptk_workaround="1",
1027                       scan_freq="2412", wait_connect=False)
1028        ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=10)
1029        if ev is None:
1030            raise Exception("Could not complete OWE association")
1031        ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1032                                "CTRL-EVENT-DISCONNECTED"], timeout=5)
1033        if ev is None:
1034            raise Exception("Unknown connection result")
1035        if "CTRL-EVENT-CONNECTED" in ev:
1036            raise Exception("Unexpected connection")
1037        dev[0].request("REMOVE_NETWORK all")
1038        ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], timeout=5)
1039        if ev is None:
1040            raise Exception("No PMKSA cache removal event seen")
1041        dev[0].dump_monitor()
1042
1043def test_owe_transition_mode_disable(dev, apdev):
1044    """Opportunistic Wireless Encryption transition mode disable"""
1045    if "OWE" not in dev[0].get_capability("key_mgmt"):
1046        raise HwsimSkip("OWE not supported")
1047    dev[0].flush_scan_cache()
1048    params = {"ssid": "owe-random",
1049              "wpa": "2",
1050              "wpa_key_mgmt": "OWE",
1051              "rsn_pairwise": "CCMP",
1052              "ieee80211w": "2",
1053              "transition_disable": '0x08',
1054              "owe_transition_bssid": apdev[1]['bssid'],
1055              "owe_transition_ssid": '"owe-test"',
1056              "ignore_broadcast_ssid": "1"}
1057    hapd = hostapd.add_ap(apdev[0], params)
1058    bssid = hapd.own_addr()
1059
1060    params = {"ssid": "owe-test",
1061              "owe_transition_bssid": apdev[0]['bssid'],
1062              "owe_transition_ssid": '"owe-random"'}
1063    hapd2 = hostapd.add_ap(apdev[1], params)
1064    bssid2 = hapd2.own_addr()
1065
1066    dev[0].scan_for_bss(bssid, freq="2412")
1067    dev[0].scan_for_bss(bssid2, freq="2412")
1068
1069    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
1070                        scan_freq="2412", wait_connect=False)
1071
1072    ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=15)
1073    if ev is None:
1074        raise Exception("Transition disable not indicated")
1075    if ev.split(' ')[1] != "08":
1076        raise Exception("Unexpected transition disable bitmap: " + ev)
1077
1078    val = dev[0].get_network(id, "owe_only")
1079    if val != "1":
1080        raise Exception("Unexpected owe_only value: " + val)
1081
1082    dev[0].request("DISCONNECT")
1083    dev[0].wait_disconnected()
1084    dev[0].request("RECONNECT")
1085    dev[0].wait_connected()
1086
1087def test_owe_sa_query(dev, apdev):
1088    """Opportunistic Wireless Encryption - SA Query"""
1089    if "OWE" not in dev[0].get_capability("key_mgmt"):
1090        raise HwsimSkip("OWE not supported")
1091    params = {"ssid": "owe",
1092              "wpa": "2",
1093              "ieee80211w": "2",
1094              "wpa_key_mgmt": "OWE",
1095              "rsn_pairwise": "CCMP"}
1096    hapd = hostapd.add_ap(apdev[0], params)
1097    bssid = hapd.own_addr()
1098
1099    dev[0].scan_for_bss(bssid, freq="2412")
1100    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
1101                   scan_freq="2412")
1102    hapd.wait_sta()
1103
1104    hapd.set("ext_mgmt_frame_handling", "1")
1105    dev[0].request("DISCONNECT")
1106    dev[0].wait_disconnected(timeout=10)
1107    hapd.set("ext_mgmt_frame_handling", "0")
1108    dev[0].request("PMKSA_FLUSH")
1109    dev[0].request("REASSOCIATE")
1110    dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
1111