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
16from hwsim import HWSimRadio
17import hwsim_utils
18from tshark import run_tshark
19from utils import *
20from test_ap_acs import wait_acs
21
22def test_owe(dev, apdev):
23    """Opportunistic Wireless Encryption"""
24    check_owe_capab(dev[0])
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    check_owe_capab(dev[0])
56    params = {"ssid": "owe",
57              "wpa": "2",
58              "wpa_key_mgmt": "OWE",
59              "rsn_pairwise": "CCMP"}
60    hapd = hostapd.add_ap(apdev[0], params)
61    bssid = hapd.own_addr()
62
63    dev[0].scan_for_bss(bssid, freq="2412")
64    for group in [19, 20, 21]:
65        dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group))
66        hapd.wait_sta()
67        hwsim_utils.test_connectivity(dev[0], hapd)
68        dev[0].request("REMOVE_NETWORK all")
69        dev[0].wait_disconnected()
70        dev[0].dump_monitor()
71        hapd.dump_monitor()
72
73def test_owe_pmksa_caching(dev, apdev):
74    """Opportunistic Wireless Encryption and PMKSA caching"""
75    try:
76        run_owe_pmksa_caching(dev, apdev)
77    finally:
78        dev[0].set("reassoc_same_bss_optim", "0")
79
80def test_owe_pmksa_caching_connect_cmd(dev, apdev):
81    """Opportunistic Wireless Encryption and PMKSA caching using cfg80211 connect command"""
82    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
83    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
84    try:
85        run_owe_pmksa_caching([wpas], apdev)
86    finally:
87        wpas.set("reassoc_same_bss_optim", "0")
88
89def run_owe_pmksa_caching(dev, apdev):
90    check_owe_capab(dev[0])
91    params = {"ssid": "owe",
92              "wpa": "2",
93              "wpa_key_mgmt": "OWE",
94              "rsn_pairwise": "CCMP"}
95    hapd = hostapd.add_ap(apdev[0], params)
96    bssid = hapd.own_addr()
97
98    dev[0].set("reassoc_same_bss_optim", "1")
99    dev[0].scan_for_bss(bssid, freq="2412")
100    id = dev[0].connect("owe", key_mgmt="OWE")
101    hapd.wait_sta()
102    hwsim_utils.test_connectivity(dev[0], hapd)
103    pmksa = dev[0].get_pmksa(bssid)
104    dev[0].request("DISCONNECT")
105    dev[0].wait_disconnected()
106    dev[0].dump_monitor()
107
108    dev[0].select_network(id, 2412)
109    dev[0].wait_connected()
110    hapd.wait_sta()
111    hwsim_utils.test_connectivity(dev[0], hapd)
112    pmksa2 = dev[0].get_pmksa(bssid)
113    dev[0].request("DISCONNECT")
114    dev[0].wait_disconnected()
115    dev[0].dump_monitor()
116
117    if "OK" not in hapd.request("PMKSA_FLUSH"):
118        raise Exception("PMKSA_FLUSH failed")
119
120    dev[0].select_network(id, 2412)
121    dev[0].wait_connected()
122    hapd.wait_sta()
123    hwsim_utils.test_connectivity(dev[0], hapd)
124    pmksa3 = dev[0].get_pmksa(bssid)
125
126    if pmksa is None or pmksa2 is None or pmksa3 is None:
127        raise Exception("PMKSA entry missing")
128    if pmksa['pmkid'] != pmksa2['pmkid']:
129        raise Exception("Unexpected PMKID change when using PMKSA caching")
130    if pmksa['pmkid'] == pmksa3['pmkid']:
131        raise Exception("PMKID did not change after PMKSA cache flush")
132
133    dev[0].request("REASSOCIATE")
134    dev[0].wait_connected()
135    pmksa4 = dev[0].get_pmksa(bssid)
136    if pmksa3['pmkid'] != pmksa4['pmkid']:
137        raise Exception("Unexpected PMKID change when using PMKSA caching [2]")
138
139def test_owe_and_psk(dev, apdev):
140    """Opportunistic Wireless Encryption and WPA2-PSK enabled"""
141    check_owe_capab(dev[0])
142    params = {"ssid": "owe+psk",
143              "wpa": "2",
144              "wpa_key_mgmt": "OWE WPA-PSK",
145              "rsn_pairwise": "CCMP",
146              "wpa_passphrase": "12345678"}
147    hapd = hostapd.add_ap(apdev[0], params)
148    bssid = hapd.own_addr()
149
150    dev[0].scan_for_bss(bssid, freq="2412")
151    dev[0].connect("owe+psk", psk="12345678")
152    hapd.wait_sta()
153    hwsim_utils.test_connectivity(dev[0], hapd)
154
155    dev[1].scan_for_bss(bssid, freq="2412")
156    dev[1].connect("owe+psk", key_mgmt="OWE")
157    hapd.wait_sta()
158    hwsim_utils.test_connectivity(dev[1], hapd)
159
160def test_owe_transition_mode(dev, apdev):
161    """Opportunistic Wireless Encryption transition mode"""
162    run_owe_transition_mode(dev, apdev)
163
164def test_owe_transition_mode_connect_cmd(dev, apdev):
165    """Opportunistic Wireless Encryption transition mode using cfg80211 connect command"""
166    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
167    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
168    run_owe_transition_mode([wpas], apdev)
169
170def test_owe_transition_mode_mismatch1(dev, apdev):
171    """Opportunistic Wireless Encryption transition mode (mismatch 1)"""
172    run_owe_transition_mode(dev, apdev, adv_bssid0="02:11:22:33:44:55")
173
174def test_owe_transition_mode_mismatch2(dev, apdev):
175    """Opportunistic Wireless Encryption transition mode (mismatch 2)"""
176    run_owe_transition_mode(dev, apdev, adv_bssid1="02:11:22:33:44:66")
177
178def test_owe_transition_mode_mismatch3(dev, apdev):
179    """Opportunistic Wireless Encryption transition mode (mismatch 3)"""
180    run_owe_transition_mode(dev, apdev, adv_bssid0="02:11:22:33:44:55",
181                            adv_bssid1="02:11:22:33:44:66")
182
183def test_owe_transition_mode_bss_limit(dev, apdev):
184    """Opportunistic Wireless Encryption transition mode (BSS limit)"""
185    try:
186        run_owe_transition_mode(dev, apdev, bss_limit=True)
187    finally:
188        dev[0].set("bss_max_count", "200")
189
190def run_owe_transition_mode(dev, apdev, adv_bssid0=None, adv_bssid1=None,
191                            bss_limit=False):
192    check_owe_capab(dev[0])
193    dev[0].flush_scan_cache()
194    adv_bssid = adv_bssid0 if adv_bssid0 else apdev[1]['bssid']
195    params = {"ssid": "owe-random",
196              "wpa": "2",
197              "wpa_key_mgmt": "OWE",
198              "rsn_pairwise": "CCMP",
199              "ieee80211w": "2",
200              "owe_transition_bssid": adv_bssid,
201              "owe_transition_ssid": '"owe-test"',
202              "ignore_broadcast_ssid": "1"}
203    hapd = hostapd.add_ap(apdev[0], params)
204    bssid = hapd.own_addr()
205
206    adv_bssid = adv_bssid1 if adv_bssid1 else apdev[0]['bssid']
207    params = {"ssid": "owe-test",
208              "owe_transition_bssid": adv_bssid,
209              "owe_transition_ssid": '"owe-random"'}
210    hapd2 = hostapd.add_ap(apdev[1], params)
211    bssid2 = hapd2.own_addr()
212
213    dev[0].scan_for_bss(bssid, freq="2412")
214    dev[0].scan_for_bss(bssid2, freq="2412")
215
216    bss = dev[0].get_bss(bssid)
217    if "[WPA2-OWE-CCMP]" not in bss['flags']:
218        raise Exception("OWE AKM not recognized: " + bss['flags'])
219    if "[OWE-TRANS]" not in bss['flags']:
220        raise Exception("OWE transition not recognized: " + bss['flags'])
221
222    bss = dev[0].get_bss(bssid2)
223    if "[OWE-TRANS-OPEN]" not in bss['flags']:
224        raise Exception("OWE transition (open) not recognized: " + bss['flags'])
225
226    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
227                        scan_freq="2412")
228    hapd.wait_sta()
229    hwsim_utils.test_connectivity(dev[0], hapd)
230    val = dev[0].get_status_field("key_mgmt")
231    if val != "OWE":
232        raise Exception("Unexpected key_mgmt: " + val)
233
234    if bss_limit:
235        id = dev[1].add_network()
236        dev[1].set_network(id, "mode", "2")
237        dev[1].set_network_quoted(id, "ssid", "owe-test")
238        dev[1].set_network(id, "key_mgmt", "NONE")
239        dev[1].set_network(id, "frequency", "2412")
240        dev[1].set_network(id, "scan_freq", "2412")
241        dev[1].select_network(id)
242        dev[1].wait_connected()
243
244        # Verify that wpa_s->current_bss does not become invalid if oldest BSS
245        # entries need to be removed.
246        dev[0].set("bss_max_count", "1")
247        dev[0].scan(freq=2412, type="ONLY")
248        dev[0].scan(freq=2412, type="ONLY")
249        logger.info("STATUS:\n" + dev[0].request("STATUS"))
250        logger.info("STATUS:\n" + dev[0].request("BSS CURRENT"))
251
252        dev[1].request("DISCONNECT")
253        dev[1].wait_disconnected()
254
255    logger.info("Move to OWE only mode (disable transition mode)")
256
257    dev[0].request("DISCONNECT")
258    dev[0].wait_disconnected()
259    dev[0].dump_monitor()
260
261    hapd2.disable()
262    hapd.disable()
263    dev[0].flush_scan_cache()
264    hapd.set("owe_transition_bssid", "00:00:00:00:00:00")
265    hapd.set("ignore_broadcast_ssid", '0')
266    hapd.set("ssid", 'owe-test')
267    hapd.enable()
268
269    dev[0].scan_for_bss(bssid, freq="2412")
270    dev[0].select_network(id, 2412)
271    dev[0].wait_connected()
272    hapd.wait_sta()
273    hwsim_utils.test_connectivity(dev[0], hapd)
274
275def test_owe_transition_mode_ifname(dev, apdev):
276    """Opportunistic Wireless Encryption transition mode (ifname)"""
277    check_owe_capab(dev[0])
278    dev[0].flush_scan_cache()
279    params = {"ssid": "owe-random",
280              "wpa": "2",
281              "wpa_key_mgmt": "OWE",
282              "rsn_pairwise": "CCMP",
283              "ieee80211w": "2",
284              "owe_transition_ifname": apdev[1]['ifname'],
285              "ignore_broadcast_ssid": "1"}
286    hapd = hostapd.add_ap(apdev[0], params)
287    bssid = hapd.own_addr()
288
289    params = {"ssid": "owe-test",
290              "owe_transition_ifname": apdev[0]['ifname']}
291    hapd2 = hostapd.add_ap(apdev[1], params)
292    bssid2 = hapd2.own_addr()
293
294    dev[0].scan_for_bss(bssid, freq="2412")
295    dev[0].scan_for_bss(bssid2, freq="2412")
296
297    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
298                        scan_freq="2412")
299    val = dev[0].get_status_field("key_mgmt")
300    if val != "OWE":
301        raise Exception("Unexpected key_mgmt: " + val)
302
303def test_owe_transition_mode_ifname_acs(dev, apdev):
304    """Opportunistic Wireless Encryption transition mode (ifname, ACS)"""
305    run_owe_transition_mode_ifname_acs(dev, apdev, wait_first=False)
306
307def test_owe_transition_mode_ifname_acs2(dev, apdev):
308    """Opportunistic Wireless Encryption transition mode (ifname, ACS)"""
309    run_owe_transition_mode_ifname_acs(dev, apdev, wait_first=True)
310
311def run_owe_transition_mode_ifname_acs(dev, apdev, wait_first):
312    check_owe_capab(dev[0])
313    dev[0].flush_scan_cache()
314    params = {"ssid": "owe-random",
315              "channel": "0",
316              "wpa": "2",
317              "wpa_key_mgmt": "OWE",
318              "rsn_pairwise": "CCMP",
319              "ieee80211w": "2",
320              "owe_transition_ifname": apdev[1]['ifname'],
321              "ignore_broadcast_ssid": "1"}
322    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
323    bssid = hapd.own_addr()
324
325    if wait_first:
326        wait_acs(hapd)
327
328    params = {"ssid": "owe-test",
329              "channel": "0",
330              "owe_transition_ifname": apdev[0]['ifname']}
331    hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False)
332    bssid2 = hapd2.own_addr()
333
334    wait_acs(hapd2)
335    if not wait_first:
336        state = hapd.get_status_field("state")
337        logger.info("AP1 state: " + state)
338        if state == "ACS-STARTED":
339            time.sleep(5)
340            state = hapd.get_status_field("state")
341            logger.info("AP1 state after 5 sec: " + state)
342        if state != "ENABLED":
343            time.sleep(1)
344            state = hapd.get_status_field("state")
345            logger.info("AP1 state after 1 sec: " + state)
346        if state != "ENABLED":
347            raise Exception("AP1 startup did not succeed")
348
349    freq = hapd.get_status_field("freq")
350    freq2 = hapd2.get_status_field("freq")
351
352    dev[0].scan_for_bss(bssid, freq=freq)
353    dev[0].scan_for_bss(bssid2, freq=freq2)
354
355    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
356                        scan_freq="%s %s" % (freq, freq2))
357    val = dev[0].get_status_field("key_mgmt")
358    if val != "OWE":
359        raise Exception("Unexpected key_mgmt: " + val)
360
361def test_owe_transition_mode_multi_assoc(dev, apdev):
362    """Opportunistic Wireless Encryption transition mode and multiple associations"""
363    check_owe_capab(dev[0])
364    dev[0].flush_scan_cache()
365    params = {"ssid": "owe-random",
366              "wpa": "2",
367              "wpa_key_mgmt": "OWE",
368              "rsn_pairwise": "CCMP",
369              "ieee80211w": "2",
370              "owe_transition_bssid": apdev[1]['bssid'],
371              "owe_transition_ssid": '"owe-test"',
372              "ignore_broadcast_ssid": "1"}
373    hapd = hostapd.add_ap(apdev[0], params)
374    bssid = hapd.own_addr()
375
376    params = {"ssid": "owe-test",
377              "owe_transition_bssid": apdev[0]['bssid'],
378              "owe_transition_ssid": '"owe-random"'}
379    hapd2 = hostapd.add_ap(apdev[1], params)
380    bssid2 = hapd2.own_addr()
381
382    dev[0].scan_for_bss(bssid, freq="2412")
383    dev[0].scan_for_bss(bssid2, freq="2412")
384
385    dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2")
386    hapd.wait_sta()
387
388    if dev[0].get_status_field("bssid") != bssid:
389        raise Exception("Unexpected BSSID")
390
391    for i in range(5):
392        dev[0].request("DISCONNECT")
393        dev[0].wait_disconnected()
394        dev[0].dump_monitor()
395
396        dev[0].scan(freq=2412)
397
398        dev[0].request("RECONNECT")
399        dev[0].wait_connected()
400        hapd.wait_sta()
401        if dev[0].get_status_field("bssid") != bssid:
402            raise Exception("Unexpected BSSID")
403        time.sleep(1)
404        dev[0].dump_monitor()
405
406    res = dev[0].request("SCAN_RESULTS").splitlines()
407    num = 0
408    for r in res:
409        if "owe-random" in r:
410            num += 1
411    if num != 1:
412        logger.info("SCAN_RESULTS:\n" + str(res))
413        raise Exception("Unexpected number of BSS entries for owe-random: %d" % num)
414
415def test_owe_transition_mode_open_only_ap(dev, apdev):
416    """Opportunistic Wireless Encryption transition mode connect to open-only AP"""
417    check_owe_capab(dev[0])
418    dev[0].flush_scan_cache()
419    params = {"ssid": "owe-test-open"}
420    hapd = hostapd.add_ap(apdev[0], params)
421    bssid = hapd.own_addr()
422
423    dev[0].scan_for_bss(bssid, freq="2412")
424
425    bss = dev[0].get_bss(bssid)
426
427    id = dev[0].connect("owe-test-open", key_mgmt="OWE", ieee80211w="2",
428                        scan_freq="2412")
429    hwsim_utils.test_connectivity(dev[0], hapd)
430    val = dev[0].get_status_field("key_mgmt")
431    if val != "NONE":
432        raise Exception("Unexpected key_mgmt: " + val)
433
434def test_owe_only_sta(dev, apdev):
435    """Opportunistic Wireless Encryption transition mode disabled on STA"""
436    check_owe_capab(dev[0])
437    dev[0].flush_scan_cache()
438    params = {"ssid": "owe-test-open"}
439    hapd = hostapd.add_ap(apdev[0], params)
440    bssid = hapd.own_addr()
441
442    dev[0].scan_for_bss(bssid, freq="2412")
443    id = dev[0].connect("owe-test-open", key_mgmt="OWE", ieee80211w="2",
444                        scan_freq="2412", owe_only="1", wait_connect=False)
445    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
446                            "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
447    if not ev:
448        raise Exception("Unknown result for the connection attempt")
449    if "CTRL-EVENT-CONNECTED" in ev:
450        raise Exception("Unexpected connection to open network")
451    dev[0].request("DISCONNECT")
452    dev[0].dump_monitor()
453
454    params = {"ssid": "owe-test-open",
455              "wpa": "2",
456              "ieee80211w": "2",
457              "wpa_key_mgmt": "OWE",
458              "rsn_pairwise": "CCMP"}
459    hapd2 = hostapd.add_ap(apdev[1], params)
460    dev[0].request("RECONNECT")
461    dev[0].wait_connected()
462
463def test_owe_only_sta_tm_ap(dev, apdev):
464    """Opportunistic Wireless Encryption transition mode disabled on STA and AP using transition mode"""
465    check_owe_capab(dev[0])
466    dev[0].flush_scan_cache()
467
468    adv_bssid = apdev[1]['bssid']
469    params = {"ssid": "owe-random",
470              "wpa": "2",
471              "wpa_key_mgmt": "OWE",
472              "rsn_pairwise": "CCMP",
473              "ieee80211w": "2",
474              "owe_transition_bssid": adv_bssid,
475              "owe_transition_ssid": '"owe-test"',
476              "ignore_broadcast_ssid": "1"}
477    hapd = hostapd.add_ap(apdev[0], params)
478    bssid = hapd.own_addr()
479
480    adv_bssid = apdev[0]['bssid']
481    params = {"ssid": "owe-test",
482              "owe_transition_bssid": adv_bssid,
483              "owe_transition_ssid": '"owe-random"'}
484    hapd2 = hostapd.add_ap(apdev[1], params)
485    bssid2 = hapd2.own_addr()
486
487    dev[0].scan_for_bss(bssid, freq="2412")
488    dev[0].scan_for_bss(bssid2, freq="2412")
489
490    dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2", owe_only="1")
491
492def test_owe_transition_mode_open_multiple_scans(dev, apdev):
493    """Opportunistic Wireless Encryption transition mode and need for multiple scans"""
494    check_owe_capab(dev[0])
495    dev[0].flush_scan_cache()
496    params = {"ssid": "owe-test",
497              "owe_transition_bssid": apdev[0]['bssid'],
498              "owe_transition_ssid": '"owe-random"'}
499    hapd2 = hostapd.add_ap(apdev[1], params)
500    bssid2 = hapd2.own_addr()
501
502    dev[0].scan_for_bss(bssid2, freq="2412")
503
504    dev[0].dump_monitor()
505    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
506                        scan_freq="2412", wait_connect=False)
507    ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=1)
508
509    params = {"ssid": "owe-random",
510              "wpa": "2",
511              "wpa_key_mgmt": "OWE",
512              "rsn_pairwise": "CCMP",
513              "ieee80211w": "2",
514              "owe_transition_bssid": apdev[1]['bssid'],
515              "owe_transition_ssid": '"owe-test"',
516              "ignore_broadcast_ssid": "1"}
517    hapd = hostapd.add_ap(apdev[0], params)
518    bssid = hapd.own_addr()
519
520    dev[0].wait_connected()
521
522    val = dev[0].get_status_field("key_mgmt")
523    if val != "OWE":
524        raise Exception("Unexpected key_mgmt: " + val)
525
526def test_owe_transition_mode_multi_bss(dev, apdev):
527    """Opportunistic Wireless Encryption transition mode (multi BSS)"""
528    try:
529        run_owe_transition_mode_multi_bss(dev, apdev)
530    finally:
531        dev[0].request("SCAN_INTERVAL 5")
532
533def run_owe_transition_mode_multi_bss(dev, apdev):
534    check_owe_capab(dev[0])
535    ifname1 = apdev[0]['ifname']
536    ifname2 = apdev[0]['ifname'] + '-2'
537    hapd1 = hostapd.add_bss(apdev[0], ifname1, 'owe-bss-1.conf')
538    hapd2 = hostapd.add_bss(apdev[0], ifname2, 'owe-bss-2.conf')
539    hapd2.bssidx = 1
540
541    bssid = hapd1.own_addr()
542    bssid2 = hapd2.own_addr()
543
544    # Beaconing with the OWE Transition Mode element can start only once both
545    # BSSs are enabled, so the very first Beacon frame may go out without this
546    # element. Wait a bit to avoid getting incomplete scan results.
547    time.sleep(0.1)
548
549    dev[0].request("SCAN_INTERVAL 1")
550    dev[0].scan_for_bss(bssid2, freq="2412")
551    dev[0].scan_for_bss(bssid, freq="2412")
552    dev[0].connect("transition-mode-open", key_mgmt="OWE")
553    val = dev[0].get_status_field("bssid")
554    if val != bssid2:
555        raise Exception("Unexpected bssid: " + val)
556    val = dev[0].get_status_field("key_mgmt")
557    if val != "OWE":
558        raise Exception("Unexpected key_mgmt: " + val)
559    hwsim_utils.test_connectivity(dev[0], hapd2)
560
561def test_owe_transition_mode_rsne_mismatch(dev, apdev):
562    """Opportunistic Wireless Encryption transition mode and RSNE mismatch"""
563    check_owe_capab(dev[0])
564    dev[0].flush_scan_cache()
565    params = {"ssid": "owe-random",
566              "wpa": "2",
567              "wpa_key_mgmt": "OWE",
568              "rsn_pairwise": "CCMP",
569              "ieee80211w": "2",
570              "rsne_override_eapol": "30140100000fac040100000fac040100000fac020c00",
571              "owe_transition_bssid": apdev[1]['bssid'],
572              "owe_transition_ssid": '"owe-test"',
573              "ignore_broadcast_ssid": "1"}
574    hapd = hostapd.add_ap(apdev[0], params)
575    bssid = hapd.own_addr()
576
577    params = {"ssid": "owe-test",
578              "owe_transition_bssid": apdev[0]['bssid'],
579              "owe_transition_ssid": '"owe-random"'}
580    hapd2 = hostapd.add_ap(apdev[1], params)
581    bssid2 = hapd2.own_addr()
582
583    dev[0].scan_for_bss(bssid, freq="2412")
584    dev[0].scan_for_bss(bssid2, freq="2412")
585
586    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
587                        scan_freq="2412", wait_connect=False)
588    ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5)
589    if ev is None:
590        raise Exception("OWE PMKSA not created")
591    ev = dev[0].wait_event(["WPA: IE in 3/4 msg does not match with IE in Beacon/ProbeResp"],
592                           timeout=5)
593    if ev is None:
594        raise Exception("RSNE mismatch not reported")
595    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
596                            "CTRL-EVENT-DISCONNECTED"], timeout=5)
597    dev[0].request("REMOVE_NETWORK all")
598    if ev is None:
599        raise Exception("No disconnection seen")
600    if "CTRL-EVENT-DISCONNECTED" not in ev:
601        raise Exception("Unexpected connection")
602    if "reason=17 locally_generated=1" not in ev:
603        raise Exception("Unexpected disconnection reason: " + ev)
604
605def test_owe_unsupported_group(dev, apdev):
606    """Opportunistic Wireless Encryption and unsupported group"""
607    try:
608        run_owe_unsupported_group(dev, apdev)
609    finally:
610        dev[0].request("VENDOR_ELEM_REMOVE 13 *")
611
612def test_owe_unsupported_group_connect_cmd(dev, apdev):
613    """Opportunistic Wireless Encryption and unsupported group using cfg80211 connect command"""
614    try:
615        wpas = None
616        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
617        wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
618        run_owe_unsupported_group([wpas], apdev)
619    finally:
620        if wpas:
621            wpas.request("VENDOR_ELEM_REMOVE 13 *")
622
623def run_owe_unsupported_group(dev, apdev):
624    check_owe_capab(dev[0])
625    # Override OWE Dh Parameters element with a payload that uses invalid group
626    # 0 (and actual group 19 data) to make the AP reject this with the specific
627    # status code 77.
628    dev[0].request("VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd")
629
630    params = {"ssid": "owe",
631              "wpa": "2",
632              "wpa_key_mgmt": "OWE",
633              "rsn_pairwise": "CCMP"}
634    hapd = hostapd.add_ap(apdev[0], params)
635    bssid = hapd.own_addr()
636
637    dev[0].scan_for_bss(bssid, freq="2412")
638    dev[0].connect("owe", key_mgmt="OWE", wait_connect=False)
639    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
640    dev[0].request("DISCONNECT")
641    if ev is None:
642        raise Exception("Association not rejected")
643    if "status_code=77" not in ev:
644        raise Exception("Unexpected rejection reason: " + ev)
645
646def test_owe_limited_group_set(dev, apdev):
647    """Opportunistic Wireless Encryption and limited group set"""
648    check_owe_capab(dev[0])
649    params = {"ssid": "owe",
650              "wpa": "2",
651              "wpa_key_mgmt": "OWE",
652              "rsn_pairwise": "CCMP",
653              "owe_groups": "20 21"}
654    hapd = hostapd.add_ap(apdev[0], params)
655    bssid = hapd.own_addr()
656
657    dev[0].scan_for_bss(bssid, freq="2412")
658    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", wait_connect=False)
659    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
660    dev[0].request("DISCONNECT")
661    if ev is None:
662        raise Exception("Association not rejected")
663    if "status_code=77" not in ev:
664        raise Exception("Unexpected rejection reason: " + ev)
665    dev[0].dump_monitor()
666
667    for group in [20, 21]:
668        dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group))
669        dev[0].request("REMOVE_NETWORK all")
670        dev[0].wait_disconnected()
671        dev[0].dump_monitor()
672
673def test_owe_limited_group_set_pmf(dev, apdev, params):
674    """Opportunistic Wireless Encryption and limited group set (PMF)"""
675    check_owe_capab(dev[0])
676    pcapng = os.path.join(params['logdir'], "hwsim0.pcapng")
677
678    params = {"ssid": "owe",
679              "wpa": "2",
680              "ieee80211w": "2",
681              "wpa_key_mgmt": "OWE",
682              "rsn_pairwise": "CCMP",
683              "owe_groups": "21"}
684    hapd = hostapd.add_ap(apdev[0], params)
685    bssid = hapd.own_addr()
686
687    dev[0].scan_for_bss(bssid, freq="2412")
688    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
689                   scan_freq="2412", wait_connect=False)
690    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
691    dev[0].request("DISCONNECT")
692    if ev is None:
693        raise Exception("Association not rejected")
694    if "status_code=77" not in ev:
695        raise Exception("Unexpected rejection reason: " + ev)
696    dev[0].dump_monitor()
697
698    dev[0].connect("owe", key_mgmt="OWE", owe_group="20", ieee80211w="2",
699                   scan_freq="2412", wait_connect=False)
700    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
701    dev[0].request("DISCONNECT")
702    if ev is None:
703        raise Exception("Association not rejected (2)")
704    if "status_code=77" not in ev:
705        raise Exception("Unexpected rejection reason (2): " + ev)
706    dev[0].dump_monitor()
707
708    dev[0].connect("owe", key_mgmt="OWE", owe_group="21", ieee80211w="2",
709                   scan_freq="2412")
710    dev[0].request("REMOVE_NETWORK all")
711    dev[0].wait_disconnected()
712    dev[0].dump_monitor()
713
714    out = run_tshark(pcapng,
715                     "wlan.fc.type_subtype == 1",
716                     display=['wlan_mgt.fixed.status_code'])
717    status = out.splitlines()
718    logger.info("Association Response frame status codes: " + str(status))
719    if len(status) != 3:
720        raise Exception("Unexpected number of Association Response frames")
721    if (int(status[0], base=0) != 77 or int(status[1], base=0) != 77 or
722        int(status[2], base=0) != 0):
723        raise Exception("Unexpected Association Response frame status code")
724
725def test_owe_group_negotiation(dev, apdev):
726    """Opportunistic Wireless Encryption and group negotiation"""
727    run_owe_group_negotiation(dev[0], apdev)
728
729def test_owe_group_negotiation_connect_cmd(dev, apdev):
730    """Opportunistic Wireless Encryption and group negotiation (connect command)"""
731    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
732    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
733    run_owe_group_negotiation(wpas, apdev)
734
735def run_owe_group_negotiation(dev, apdev):
736    check_owe_capab(dev)
737    params = {"ssid": "owe",
738              "wpa": "2",
739              "wpa_key_mgmt": "OWE",
740              "rsn_pairwise": "CCMP",
741              "owe_groups": "21"}
742    hapd = hostapd.add_ap(apdev[0], params)
743    bssid = hapd.own_addr()
744
745    dev.scan_for_bss(bssid, freq="2412")
746    dev.connect("owe", key_mgmt="OWE")
747
748def test_owe_assoc_reject(dev, apdev):
749    """Opportunistic Wireless Encryption association rejection handling"""
750    check_owe_capab(dev[0])
751    params = {"ssid": "owe",
752              "require_ht": "1",
753              "wpa": "2",
754              "ieee80211w": "2",
755              "wpa_key_mgmt": "OWE",
756              "rsn_pairwise": "CCMP",
757              "owe_groups": "19"}
758    hapd = hostapd.add_ap(apdev[0], params)
759    bssid = hapd.own_addr()
760
761    # First, reject two associations with HT-required (i.e., not OWE related)
762    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
763    wpas.interface_add("wlan5", drv_params="extra_bss_membership_selectors=127")
764    wpas.scan_for_bss(bssid, freq="2412")
765    wpas.connect("owe", key_mgmt="OWE", ieee80211w="2",
766                 disable_ht="1", scan_freq="2412", wait_connect=False)
767    for i in range(0, 2):
768        ev = wpas.wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
769        if ev is None:
770            raise Exception("Association rejection not reported")
771
772    # Then, verify that STA tries OWE with the default group (19) on the next
773    # attempt instead of having moved to testing another group.
774    hapd.set("require_ht", "0")
775    for i in range(0, 2):
776        ev = wpas.wait_event(["CTRL-EVENT-ASSOC-REJECT",
777                             "CTRL-EVENT-CONNECTED"], timeout=10)
778        if ev is None:
779            raise Exception("Association result not reported")
780        if "CTRL-EVENT-CONNECTED" in ev:
781            break
782        if "status_code=77" in ev:
783            raise Exception("Unexpected unsupport group rejection")
784    if "CTRL-EVENT-CONNECTED" not in ev:
785        raise Exception("Did not connect successfully")
786
787def test_owe_local_errors(dev, apdev):
788    """Opportunistic Wireless Encryption - local errors on supplicant"""
789    check_owe_capab(dev[0])
790    params = {"ssid": "owe",
791              "wpa": "2",
792              "ieee80211w": "2",
793              "wpa_key_mgmt": "OWE",
794              "rsn_pairwise": "CCMP"}
795    hapd = hostapd.add_ap(apdev[0], params)
796    bssid = hapd.own_addr()
797
798    dev[0].scan_for_bss(bssid, freq="2412")
799
800    tests = [(1, "crypto_ecdh_init;owe_build_assoc_req"),
801             (1, "crypto_ecdh_get_pubkey;owe_build_assoc_req"),
802             (1, "wpabuf_alloc;owe_build_assoc_req")]
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            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
809            dev[0].request("REMOVE_NETWORK all")
810            dev[0].dump_monitor()
811
812    tests = [(1, "crypto_ecdh_set_peerkey;owe_process_assoc_resp"),
813             (1, "crypto_ecdh_get_pubkey;owe_process_assoc_resp"),
814             (1, "wpabuf_alloc;=owe_process_assoc_resp")]
815    for count, func in tests:
816        with alloc_fail(dev[0], count, func):
817            dev[0].connect("owe", key_mgmt="OWE", owe_group="20",
818                           ieee80211w="2",
819                           scan_freq="2412", wait_connect=False)
820            dev[0].wait_disconnected()
821            dev[0].request("REMOVE_NETWORK all")
822            dev[0].dump_monitor()
823
824    tests = [(1, "hmac_sha256;owe_process_assoc_resp", 19),
825             (1, "hmac_sha256_kdf;owe_process_assoc_resp", 19),
826             (1, "hmac_sha384;owe_process_assoc_resp", 20),
827             (1, "hmac_sha384_kdf;owe_process_assoc_resp", 20),
828             (1, "hmac_sha512;owe_process_assoc_resp", 21),
829             (1, "hmac_sha512_kdf;owe_process_assoc_resp", 21)]
830    for count, func, group in tests:
831        with fail_test(dev[0], count, func):
832            dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group),
833                           ieee80211w="2",
834                           scan_freq="2412", wait_connect=False)
835            dev[0].wait_disconnected()
836            dev[0].request("REMOVE_NETWORK all")
837            dev[0].dump_monitor()
838
839    dev[0].connect("owe", key_mgmt="OWE", owe_group="18",
840                   ieee80211w="2",
841                   scan_freq="2412", wait_connect=False)
842    ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=5)
843    if ev is None:
844        raise Exception("No authentication attempt")
845    time.sleep(0.5)
846    dev[0].request("REMOVE_NETWORK all")
847    dev[0].dump_monitor()
848
849def hapd_auth(hapd):
850    for i in range(0, 10):
851        req = hapd.mgmt_rx()
852        if req is None:
853            raise Exception("MGMT RX wait timed out")
854        if req['subtype'] == 11:
855            break
856        req = None
857    if not req:
858        raise Exception("Authentication frame not received")
859
860    resp = {}
861    resp['fc'] = req['fc']
862    resp['da'] = req['sa']
863    resp['sa'] = req['da']
864    resp['bssid'] = req['bssid']
865    resp['payload'] = struct.pack('<HHH', 0, 2, 0)
866    hapd.mgmt_tx(resp)
867
868def hapd_assoc(hapd, extra):
869    for i in range(0, 10):
870        req = hapd.mgmt_rx()
871        if req is None:
872            raise Exception("MGMT RX wait timed out")
873        if req['subtype'] == 0:
874            break
875        req = None
876    if not req:
877        raise Exception("Association Request frame not received")
878
879    resp = {}
880    resp['fc'] = 0x0010
881    resp['da'] = req['sa']
882    resp['sa'] = req['da']
883    resp['bssid'] = req['bssid']
884    payload = struct.pack('<HHH', 0x0411, 0, 0xc001)
885    payload += binascii.unhexlify("010882848b960c121824")
886    resp['payload'] = payload + extra
887    hapd.mgmt_tx(resp)
888
889def test_owe_invalid_assoc_resp(dev, apdev):
890    """Opportunistic Wireless Encryption - invalid Association Response frame"""
891    check_owe_capab(dev[0])
892    params = {"ssid": "owe",
893              "ieee80211n": "0",
894              "wpa": "2",
895              "ieee80211w": "2",
896              "wpa_key_mgmt": "OWE",
897              "rsn_pairwise": "CCMP"}
898    hapd = hostapd.add_ap(apdev[0], params)
899    bssid = hapd.own_addr()
900
901    dev[0].scan_for_bss(bssid, freq="2412")
902
903    hapd.set("ext_mgmt_frame_handling", "1")
904    # OWE: No Diffie-Hellman Parameter element found in Association Response frame
905    tests = [b'']
906    # No room for group --> no DH Params
907    tests += [binascii.unhexlify('ff0120')]
908    # OWE: Unexpected Diffie-Hellman group in response: 18
909    tests += [binascii.unhexlify('ff03201200')]
910    # OWE: Invalid peer DH public key
911    tests += [binascii.unhexlify('ff23201300' + 31*'00' + '01')]
912    # OWE: Invalid peer DH public key
913    tests += [binascii.unhexlify('ff24201300' + 33*'ee')]
914    for extra in tests:
915        dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
916                       scan_freq="2412", wait_connect=False)
917        hapd_auth(hapd)
918        hapd_assoc(hapd, extra)
919        dev[0].wait_disconnected()
920        dev[0].request("REMOVE_NETWORK all")
921        dev[0].dump_monitor()
922
923    # OWE: Empty public key (this ends up getting padded to a valid point)
924    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
925                   scan_freq="2412", wait_connect=False)
926    hapd_auth(hapd)
927    hapd_assoc(hapd, binascii.unhexlify('ff03201300'))
928    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED", "PMKSA-CACHE-ADDED"],
929                           timeout=5)
930    if ev is None:
931        raise Exception("No result reported for empty public key")
932    dev[0].request("REMOVE_NETWORK all")
933    dev[0].dump_monitor()
934
935def test_owe_double_assoc(dev, apdev):
936    """Opportunistic Wireless Encryption - duplicated association attempt"""
937    check_owe_capab(dev[0])
938    params = {"ssid": "owe",
939              "wpa": "2",
940              "ieee80211w": "2",
941              "wpa_key_mgmt": "OWE",
942              "rsn_pairwise": "CCMP"}
943    hapd = hostapd.add_ap(apdev[0], params)
944    bssid = hapd.own_addr()
945
946    dev[0].scan_for_bss(bssid, freq="2412")
947
948    hapd.set("ext_mgmt_frame_handling", "1")
949    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
950                   scan_freq="2412", wait_connect=False)
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'] == 11:
957            break
958        req = None
959    if not req:
960        raise Exception("Authentication frame not received")
961    hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
962
963    for i in range(0, 10):
964        req = hapd.mgmt_rx()
965        if req is None:
966            raise Exception("MGMT RX wait timed out")
967        if req['subtype'] == 0:
968            break
969        req = None
970    if not req:
971        raise Exception("Association Request frame not received")
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=0 %s" % (ev.split(' ')[3])
980    if "OK" not in hapd.request(cmd):
981        raise Exception("MGMT_TX_STATUS_PROCESS failed")
982
983    hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
984
985    ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
986    if ev is None:
987        raise Exception("Management frame TX status not reported (1)")
988    if "stype=1 ok=1" not in ev:
989        raise Exception("Unexpected management frame TX status (1): " + ev)
990    cmd = "MGMT_TX_STATUS_PROCESS stype=1 ok=1 %s" % (ev.split(' ')[3])
991    if "OK" not in hapd.request(cmd):
992        raise Exception("MGMT_TX_STATUS_PROCESS failed")
993
994    ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5)
995    if ev is None:
996        raise Exception("No PMKSA cache entry from OWE added")
997
998    dev[0].wait_connected()
999
1000def start_owe(dev, apdev, workaround=0):
1001    check_owe_capab(dev[0])
1002    params = {"ssid": "owe",
1003              "wpa": "2",
1004              "ieee80211w": "2",
1005              "wpa_key_mgmt": "OWE",
1006              "owe_ptk_workaround": str(workaround),
1007              "rsn_pairwise": "CCMP"}
1008    hapd = hostapd.add_ap(apdev[0], params)
1009    dev[0].scan_for_bss(hapd.own_addr(), freq="2412")
1010    return hapd
1011
1012def owe_check_ok(dev, hapd, owe_group, owe_ptk_workaround):
1013    dev.connect("owe", key_mgmt="OWE", ieee80211w="2",
1014                owe_group=owe_group, owe_ptk_workaround=owe_ptk_workaround,
1015                scan_freq="2412")
1016    hapd.wait_sta()
1017    dev.request("REMOVE_NETWORK all")
1018    dev.wait_disconnected()
1019    dev.dump_monitor()
1020
1021def test_owe_ptk_workaround_ap(dev, apdev):
1022    """Opportunistic Wireless Encryption - AP using PTK workaround"""
1023    hapd = start_owe(dev, apdev, workaround=1)
1024    for group, workaround in [(19, 0), (20, 0), (21, 0),
1025                              (19, 1), (20, 1), (21, 1)]:
1026        owe_check_ok(dev[0], hapd, str(group), str(workaround))
1027
1028def test_owe_ptk_hash(dev, apdev):
1029    """Opportunistic Wireless Encryption - PTK derivation hash alg"""
1030    hapd = start_owe(dev, apdev)
1031    for group, workaround in [(19, 0), (20, 0), (21, 0), (19, 1)]:
1032        owe_check_ok(dev[0], hapd, str(group), str(workaround))
1033
1034    for group in [20, 21]:
1035        dev[0].connect("owe", key_mgmt="OWE", ieee80211w="2",
1036                       owe_group=str(group), owe_ptk_workaround="1",
1037                       scan_freq="2412", wait_connect=False)
1038        ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=10)
1039        if ev is None:
1040            raise Exception("Could not complete OWE association")
1041        ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1042                                "CTRL-EVENT-DISCONNECTED"], timeout=5)
1043        if ev is None:
1044            raise Exception("Unknown connection result")
1045        if "CTRL-EVENT-CONNECTED" in ev:
1046            raise Exception("Unexpected connection")
1047        dev[0].request("REMOVE_NETWORK all")
1048        ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], timeout=5)
1049        if ev is None:
1050            raise Exception("No PMKSA cache removal event seen")
1051        dev[0].dump_monitor()
1052
1053def test_owe_transition_mode_disable(dev, apdev):
1054    """Opportunistic Wireless Encryption transition mode disable"""
1055    check_owe_capab(dev[0])
1056    dev[0].flush_scan_cache()
1057    params = {"ssid": "owe-random",
1058              "wpa": "2",
1059              "wpa_key_mgmt": "OWE",
1060              "rsn_pairwise": "CCMP",
1061              "ieee80211w": "2",
1062              "transition_disable": '0x08',
1063              "owe_transition_bssid": apdev[1]['bssid'],
1064              "owe_transition_ssid": '"owe-test"',
1065              "ignore_broadcast_ssid": "1"}
1066    hapd = hostapd.add_ap(apdev[0], params)
1067    bssid = hapd.own_addr()
1068
1069    params = {"ssid": "owe-test",
1070              "owe_transition_bssid": apdev[0]['bssid'],
1071              "owe_transition_ssid": '"owe-random"'}
1072    hapd2 = hostapd.add_ap(apdev[1], params)
1073    bssid2 = hapd2.own_addr()
1074
1075    dev[0].scan_for_bss(bssid, freq="2412")
1076    dev[0].scan_for_bss(bssid2, freq="2412")
1077
1078    id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
1079                        scan_freq="2412", wait_connect=False)
1080
1081    ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=15)
1082    if ev is None:
1083        raise Exception("Transition disable not indicated")
1084    if ev.split(' ')[1] != "08":
1085        raise Exception("Unexpected transition disable bitmap: " + ev)
1086
1087    val = dev[0].get_network(id, "owe_only")
1088    if val != "1":
1089        raise Exception("Unexpected owe_only value: " + val)
1090
1091    dev[0].request("DISCONNECT")
1092    dev[0].wait_disconnected()
1093    dev[0].request("RECONNECT")
1094    dev[0].wait_connected()
1095
1096def test_owe_transition_mode_roam(dev, apdev):
1097    """Opportunistic Wireless Encryption transition mode roaming"""
1098    check_owe_capab(dev[0])
1099    dev[0].flush_scan_cache()
1100
1101    with HWSimRadio() as (radio, iface):
1102        params = {"ssid": "owe-random",
1103                  "wpa": "2",
1104                  "wpa_key_mgmt": "OWE",
1105                  "rsn_pairwise": "CCMP",
1106                  "ieee80211w": "2",
1107                  "owe_transition_bssid": apdev[1]['bssid'],
1108                  "owe_transition_ssid": '"owe-test"',
1109                  "ignore_broadcast_ssid": "1"}
1110        hapd = hostapd.add_ap(apdev[0], params)
1111        bssid = hapd.own_addr()
1112
1113        params = {"ssid": "owe-test",
1114                  "owe_transition_bssid": apdev[0]['bssid'],
1115                  "owe_transition_ssid": '"owe-random"'}
1116        hapd2 = hostapd.add_ap(apdev[1], params)
1117        bssid2 = hapd2.own_addr()
1118
1119        dev[0].scan_for_bss(bssid, freq="2412")
1120        dev[0].scan_for_bss(bssid2, freq="2412")
1121
1122        id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
1123                            scan_freq="2412")
1124        hapd.wait_sta()
1125        hwsim_utils.test_connectivity(dev[0], hapd)
1126
1127        val = dev[0].get_status_field("key_mgmt")
1128        if val != "OWE":
1129            raise Exception("Unexpected key_mgmt: " + val)
1130
1131        val = dev[0].get_status_field("bssid")
1132        if val != hapd.own_addr():
1133            raise Exception("Unexpected BSSID: " + val)
1134
1135        ap = {"ifname": iface}
1136        params = {"ssid": "owe-test",
1137                  "wpa": "2",
1138                  "ieee80211w": "2",
1139                  "wpa_key_mgmt": "OWE",
1140                  "rsn_pairwise": "CCMP"}
1141        hapd3 = hostapd.add_ap(ap, params)
1142        bssid3 = hapd3.own_addr()
1143
1144        logger.info("Roam from transition mode OWE AP to OWE only AP")
1145        dev[0].scan_for_bss(bssid3, freq="2412")
1146        dev[0].roam(bssid3)
1147        hapd3.wait_sta()
1148        hwsim_utils.test_connectivity(dev[0], hapd3)
1149
1150        val = dev[0].get_status_field("key_mgmt")
1151        if val != "OWE":
1152            raise Exception("Unexpected key_mgmt: " + val)
1153
1154        val = dev[0].get_status_field("bssid")
1155        if val != hapd3.own_addr():
1156            raise Exception("Unexpected BSSID: " + val)
1157
1158        logger.info("Roam from OWE only AP to transition mode OWE AP")
1159        dev[0].roam(bssid)
1160        hapd.wait_sta()
1161        hwsim_utils.test_connectivity(dev[0], hapd)
1162
1163        val = dev[0].get_status_field("key_mgmt")
1164        if val != "OWE":
1165            raise Exception("Unexpected key_mgmt: " + val)
1166
1167        val = dev[0].get_status_field("bssid")
1168        if val != hapd.own_addr():
1169            raise Exception("Unexpected BSSID: " + val)
1170
1171def test_owe_sa_query(dev, apdev):
1172    """Opportunistic Wireless Encryption - SA Query"""
1173    check_owe_capab(dev[0])
1174    params = {"ssid": "owe",
1175              "wpa": "2",
1176              "ieee80211w": "2",
1177              "wpa_key_mgmt": "OWE",
1178              "rsn_pairwise": "CCMP"}
1179    hapd = hostapd.add_ap(apdev[0], params)
1180    bssid = hapd.own_addr()
1181
1182    dev[0].scan_for_bss(bssid, freq="2412")
1183    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
1184                   scan_freq="2412")
1185    hapd.wait_sta()
1186
1187    hapd.set("ext_mgmt_frame_handling", "1")
1188    dev[0].request("DISCONNECT")
1189    dev[0].wait_disconnected(timeout=10)
1190    hapd.set("ext_mgmt_frame_handling", "0")
1191    dev[0].request("PMKSA_FLUSH")
1192    dev[0].request("REASSOCIATE")
1193    dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
1194