49741f4e3c4676c442f2bede1f1efa9eb1af8790
[thirdparty/hostap.git] / tests / hwsim / test_ap_ft.py
1 # Fast BSS Transition tests
2 # Copyright (c) 2013-2019, 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
7 from remotehost import remote_compatible
8 import binascii
9 import os
10 import time
11 import logging
12 logger = logging.getLogger()
13 import signal
14 import struct
15 import subprocess
16
17 import hwsim_utils
18 from hwsim import HWSimRadio
19 import hostapd
20 from tshark import run_tshark
21 from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger, skip_with_fips, parse_ie
22 from wlantest import Wlantest
23 from test_ap_psk import check_mib, find_wpas_process, read_process_memory, verify_not_present, get_key_locations
24 from test_rrm import check_beacon_req
25 from test_suite_b import check_suite_b_192_capa
26
27 def ft_base_rsn():
28     params = {"wpa": "2",
29               "wpa_key_mgmt": "FT-PSK",
30               "rsn_pairwise": "CCMP"}
31     return params
32
33 def ft_base_mixed():
34     params = {"wpa": "3",
35               "wpa_key_mgmt": "WPA-PSK FT-PSK",
36               "wpa_pairwise": "TKIP",
37               "rsn_pairwise": "CCMP"}
38     return params
39
40 def ft_params(rsn=True, ssid=None, passphrase=None):
41     if rsn:
42         params = ft_base_rsn()
43     else:
44         params = ft_base_mixed()
45     if ssid:
46         params["ssid"] = ssid
47     if passphrase:
48         params["wpa_passphrase"] = passphrase
49
50     params["mobility_domain"] = "a1b2"
51     params["r0_key_lifetime"] = "10000"
52     params["pmk_r1_push"] = "1"
53     params["reassociation_deadline"] = "1000"
54     return params
55
56 def ft_params1a(rsn=True, ssid=None, passphrase=None):
57     params = ft_params(rsn, ssid, passphrase)
58     params['nas_identifier'] = "nas1.w1.fi"
59     params['r1_key_holder'] = "000102030405"
60     return params
61
62 def ft_params1(rsn=True, ssid=None, passphrase=None, discovery=False):
63     params = ft_params1a(rsn, ssid, passphrase)
64     if discovery:
65         params['r0kh'] = "ff:ff:ff:ff:ff:ff * 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
66         params['r1kh'] = "00:00:00:00:00:00 00:00:00:00:00:00 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
67     else:
68         params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f",
69                           "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"]
70         params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f"
71     return params
72
73 def ft_params1_old_key(rsn=True, ssid=None, passphrase=None):
74     params = ft_params1a(rsn, ssid, passphrase)
75     params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
76                       "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"]
77     params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
78     return params
79
80 def ft_params2a(rsn=True, ssid=None, passphrase=None):
81     params = ft_params(rsn, ssid, passphrase)
82     params['nas_identifier'] = "nas2.w1.fi"
83     params['r1_key_holder'] = "000102030406"
84     return params
85
86 def ft_params2(rsn=True, ssid=None, passphrase=None, discovery=False):
87     params = ft_params2a(rsn, ssid, passphrase)
88     if discovery:
89         params['r0kh'] = "ff:ff:ff:ff:ff:ff * 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
90         params['r1kh'] = "00:00:00:00:00:00 00:00:00:00:00:00 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
91     else:
92         params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f",
93                           "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"]
94         params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"
95     return params
96
97 def ft_params2_old_key(rsn=True, ssid=None, passphrase=None):
98     params = ft_params2a(rsn, ssid, passphrase)
99     params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
100                       "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f"]
101     params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
102     return params
103
104 def ft_params1_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
105     params = ft_params(rsn, ssid, passphrase)
106     params['nas_identifier'] = "nas1.w1.fi"
107     params['r1_key_holder'] = "000102030405"
108     params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f",
109                       "12:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"]
110     params['r1kh'] = "12:00:00:00:04:00 10:01:02:03:04:06 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f"
111     return params
112
113 def ft_params2_incorrect_rrb_key(rsn=True, ssid=None, passphrase=None):
114     params = ft_params(rsn, ssid, passphrase)
115     params['nas_identifier'] = "nas2.w1.fi"
116     params['r1_key_holder'] = "000102030406"
117     params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0ef1200102030405060708090a0b0c0d0ef1",
118                       "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0ef2000102030405060708090a0b0c0d0ef2"]
119     params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0ef3300102030405060708090a0b0c0d0ef3"
120     return params
121
122 def ft_params2_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
123     params = ft_params(rsn, ssid, passphrase)
124     params['nas_identifier'] = "nas2.w1.fi"
125     params['r1_key_holder'] = "000102030406"
126     params['r0kh'] = ["12:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f",
127                       "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"]
128     params['r1kh'] = "12:00:00:00:03:00 10:01:02:03:04:05 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"
129     return params
130
131 def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False,
132               sae=False, eap=False, fail_test=False, roams=1,
133               pairwise_cipher="CCMP", group_cipher="TKIP CCMP", ptk_rekey="0",
134               test_connectivity=True, eap_identity="gpsk user", conndev=False,
135               force_initial_conn_to_first_ap=False, sha384=False,
136               group_mgmt=None, ocv=None, sae_password=None,
137               sae_password_id=None, sae_and_psk=False, pmksa_caching=False,
138               roam_with_reassoc=False, also_non_ft=False, only_one_way=False,
139               wait_before_roam=0, return_after_initial=False, ieee80211w="1"):
140     logger.info("Connect to first AP")
141
142     copts = {}
143     copts["proto"] = "WPA2"
144     copts["ieee80211w"] = ieee80211w
145     copts["scan_freq"] = "2412"
146     copts["pairwise"] = pairwise_cipher
147     copts["group"] = group_cipher
148     copts["wpa_ptk_rekey"] = ptk_rekey
149     if group_mgmt:
150         copts["group_mgmt"] = group_mgmt
151     if ocv:
152         copts["ocv"] = ocv
153     if eap:
154         if pmksa_caching:
155             copts["ft_eap_pmksa_caching"] = "1"
156         if also_non_ft:
157             copts["key_mgmt"] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384" if sha384 else "WPA-EAP FT-EAP"
158         else:
159             copts["key_mgmt"] = "FT-EAP-SHA384" if sha384 else "FT-EAP"
160         copts["eap"] = "GPSK"
161         copts["identity"] = eap_identity
162         copts["password"] = "abcdefghijklmnop0123456789abcdef"
163     else:
164         if sae:
165             copts["key_mgmt"] = "SAE FT-SAE" if sae_and_psk else "FT-SAE"
166         else:
167             copts["key_mgmt"] = "FT-PSK"
168         if passphrase:
169             copts["psk"] = passphrase
170         if sae_password:
171             copts["sae_password"] = sae_password
172         if sae_password_id:
173             copts["sae_password_id"] = sae_password_id
174     if force_initial_conn_to_first_ap:
175         copts["bssid"] = apdev[0]['bssid']
176     netw = dev.connect(ssid, **copts)
177     if pmksa_caching:
178         dev.request("DISCONNECT")
179         dev.wait_disconnected()
180         dev.request("RECONNECT")
181         ev = dev.wait_event(["CTRL-EVENT-CONNECTED",
182                              "CTRL-EVENT-DISCONNECTED",
183                              "CTRL-EVENT-EAP-STARTED"],
184                             timeout=15)
185         if ev is None:
186             raise Exception("Reconnect timed out")
187         if "CTRL-EVENT-DISCONNECTED" in ev:
188             raise Exception("Unexpected disconnection after RECONNECT")
189         if "CTRL-EVENT-EAP-STARTED" in ev:
190             raise Exception("Unexpected EAP start after RECONNECT")
191
192     if dev.get_status_field('bssid') == apdev[0]['bssid']:
193         ap1 = apdev[0]
194         ap2 = apdev[1]
195         hapd1ap = hapd0
196         hapd2ap = hapd1
197     else:
198         ap1 = apdev[1]
199         ap2 = apdev[0]
200         hapd1ap = hapd1
201         hapd2ap = hapd0
202     if test_connectivity:
203         hapd1ap.wait_sta()
204         if conndev:
205             hwsim_utils.test_connectivity_iface(dev, hapd1ap, conndev)
206         else:
207             hwsim_utils.test_connectivity(dev, hapd1ap)
208
209     if return_after_initial:
210         return ap2['bssid']
211
212     if wait_before_roam:
213         time.sleep(wait_before_roam)
214     dev.scan_for_bss(ap2['bssid'], freq="2412")
215
216     for i in range(0, roams):
217         # Roaming artificially fast can make data test fail because the key is
218         # set later.
219         time.sleep(0.01)
220         logger.info("Roam to the second AP")
221         if roam_with_reassoc:
222             dev.set_network(netw, "bssid", ap2['bssid'])
223             dev.request("REASSOCIATE")
224             dev.wait_connected()
225         elif over_ds:
226             dev.roam_over_ds(ap2['bssid'], fail_test=fail_test)
227         else:
228             dev.roam(ap2['bssid'], fail_test=fail_test)
229         if fail_test:
230             return
231         if dev.get_status_field('bssid') != ap2['bssid']:
232             raise Exception("Did not connect to correct AP")
233         if (i == 0 or i == roams - 1) and test_connectivity:
234             hapd2ap.wait_sta()
235             if conndev:
236                 hwsim_utils.test_connectivity_iface(dev, hapd2ap, conndev)
237             else:
238                 hwsim_utils.test_connectivity(dev, hapd2ap)
239
240         if only_one_way:
241             return
242         # Roaming artificially fast can make data test fail because the key is
243         # set later.
244         time.sleep(0.01)
245         logger.info("Roam back to the first AP")
246         if roam_with_reassoc:
247             dev.set_network(netw, "bssid", ap1['bssid'])
248             dev.request("REASSOCIATE")
249             dev.wait_connected()
250         elif over_ds:
251             dev.roam_over_ds(ap1['bssid'])
252         else:
253             dev.roam(ap1['bssid'])
254         if dev.get_status_field('bssid') != ap1['bssid']:
255             raise Exception("Did not connect to correct AP")
256         if (i == 0 or i == roams - 1) and test_connectivity:
257             hapd1ap.wait_sta()
258             if conndev:
259                 hwsim_utils.test_connectivity_iface(dev, hapd1ap, conndev)
260             else:
261                 hwsim_utils.test_connectivity(dev, hapd1ap)
262
263 def test_ap_ft(dev, apdev):
264     """WPA2-PSK-FT AP"""
265     ssid = "test-ft"
266     passphrase = "12345678"
267
268     params = ft_params1(ssid=ssid, passphrase=passphrase)
269     hapd0 = hostapd.add_ap(apdev[0], params)
270     params = ft_params2(ssid=ssid, passphrase=passphrase)
271     hapd1 = hostapd.add_ap(apdev[1], params)
272
273     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
274     if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
275         raise Exception("Scan results missing RSN element info")
276
277 def test_ap_ft_old_key(dev, apdev):
278     """WPA2-PSK-FT AP (old key)"""
279     ssid = "test-ft"
280     passphrase = "12345678"
281
282     params = ft_params1_old_key(ssid=ssid, passphrase=passphrase)
283     hapd0 = hostapd.add_ap(apdev[0], params)
284     params = ft_params2_old_key(ssid=ssid, passphrase=passphrase)
285     hapd1 = hostapd.add_ap(apdev[1], params)
286
287     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
288
289 def test_ap_ft_multi_akm(dev, apdev):
290     """WPA2-PSK-FT AP with non-FT AKMs enabled"""
291     ssid = "test-ft"
292     passphrase = "12345678"
293
294     params = ft_params1(ssid=ssid, passphrase=passphrase)
295     params["wpa_key_mgmt"] = "FT-PSK WPA-PSK WPA-PSK-SHA256"
296     hapd0 = hostapd.add_ap(apdev[0], params)
297     params = ft_params2(ssid=ssid, passphrase=passphrase)
298     params["wpa_key_mgmt"] = "FT-PSK WPA-PSK WPA-PSK-SHA256"
299     hapd1 = hostapd.add_ap(apdev[1], params)
300
301     Wlantest.setup(hapd0)
302     wt = Wlantest()
303     wt.flush()
304     wt.add_passphrase(passphrase)
305
306     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
307     if "[WPA2-PSK+FT/PSK+PSK-SHA256-CCMP]" not in dev[0].request("SCAN_RESULTS"):
308         raise Exception("Scan results missing RSN element info")
309     dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
310     dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
311                    scan_freq="2412")
312
313 def test_ap_ft_local_key_gen(dev, apdev):
314     """WPA2-PSK-FT AP with local key generation (without pull/push)"""
315     ssid = "test-ft"
316     passphrase = "12345678"
317
318     params = ft_params1a(ssid=ssid, passphrase=passphrase)
319     params['ft_psk_generate_local'] = "1"
320     del params['pmk_r1_push']
321     hapd0 = hostapd.add_ap(apdev[0], params)
322     params = ft_params2a(ssid=ssid, passphrase=passphrase)
323     params['ft_psk_generate_local'] = "1"
324     del params['pmk_r1_push']
325     hapd1 = hostapd.add_ap(apdev[1], params)
326
327     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
328     if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
329         raise Exception("Scan results missing RSN element info")
330
331 def test_ap_ft_vlan(dev, apdev):
332     """WPA2-PSK-FT AP with VLAN"""
333     ssid = "test-ft"
334     passphrase = "12345678"
335
336     params = ft_params1(ssid=ssid, passphrase=passphrase)
337     params['dynamic_vlan'] = "1"
338     params['accept_mac_file'] = "hostapd.accept"
339     hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
340
341     params = ft_params2(ssid=ssid, passphrase=passphrase)
342     params['dynamic_vlan'] = "1"
343     params['accept_mac_file'] = "hostapd.accept"
344     hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
345
346     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1")
347     if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
348         raise Exception("Scan results missing RSN element info")
349
350 def test_ap_ft_vlan_disconnected(dev, apdev):
351     """WPA2-PSK-FT AP with VLAN and local key generation"""
352     ssid = "test-ft"
353     passphrase = "12345678"
354
355     params = ft_params1a(ssid=ssid, passphrase=passphrase)
356     params['dynamic_vlan'] = "1"
357     params['accept_mac_file'] = "hostapd.accept"
358     params['ft_psk_generate_local'] = "1"
359     hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
360
361     params = ft_params2a(ssid=ssid, passphrase=passphrase)
362     params['dynamic_vlan'] = "1"
363     params['accept_mac_file'] = "hostapd.accept"
364     params['ft_psk_generate_local'] = "1"
365     hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
366
367     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1")
368     if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
369         raise Exception("Scan results missing RSN element info")
370
371 def test_ap_ft_vlan_2(dev, apdev):
372     """WPA2-PSK-FT AP with VLAN and dest-AP does not have VLAN info locally"""
373     ssid = "test-ft"
374     passphrase = "12345678"
375
376     params = ft_params1(ssid=ssid, passphrase=passphrase)
377     params['dynamic_vlan'] = "1"
378     params['accept_mac_file'] = "hostapd.accept"
379     hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
380
381     params = ft_params2(ssid=ssid, passphrase=passphrase)
382     params['dynamic_vlan'] = "1"
383     hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
384
385     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1",
386               force_initial_conn_to_first_ap=True)
387     if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
388         raise Exception("Scan results missing RSN element info")
389
390 def test_ap_ft_many(dev, apdev):
391     """WPA2-PSK-FT AP multiple times"""
392     ssid = "test-ft"
393     passphrase = "12345678"
394
395     params = ft_params1(ssid=ssid, passphrase=passphrase)
396     hapd0 = hostapd.add_ap(apdev[0], params)
397     params = ft_params2(ssid=ssid, passphrase=passphrase)
398     hapd1 = hostapd.add_ap(apdev[1], params)
399
400     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50)
401
402 def test_ap_ft_many_vlan(dev, apdev):
403     """WPA2-PSK-FT AP with VLAN multiple times"""
404     ssid = "test-ft"
405     passphrase = "12345678"
406
407     params = ft_params1(ssid=ssid, passphrase=passphrase)
408     params['dynamic_vlan'] = "1"
409     params['accept_mac_file'] = "hostapd.accept"
410     hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
411
412     params = ft_params2(ssid=ssid, passphrase=passphrase)
413     params['dynamic_vlan'] = "1"
414     params['accept_mac_file'] = "hostapd.accept"
415     hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
416
417     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50,
418               conndev="brvlan1")
419
420 def test_ap_ft_mixed(dev, apdev):
421     """WPA2-PSK-FT mixed-mode AP"""
422     ssid = "test-ft-mixed"
423     passphrase = "12345678"
424
425     params = ft_params1(rsn=False, ssid=ssid, passphrase=passphrase)
426     hapd = hostapd.add_ap(apdev[0], params)
427     key_mgmt = hapd.get_config()['key_mgmt']
428     vals = key_mgmt.split(' ')
429     if vals[0] != "WPA-PSK" or vals[1] != "FT-PSK":
430         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
431     params = ft_params2(rsn=False, ssid=ssid, passphrase=passphrase)
432     hapd1 = hostapd.add_ap(apdev[1], params)
433
434     run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase)
435
436 def test_ap_ft_pmf(dev, apdev):
437     """WPA2-PSK-FT AP with PMF"""
438     run_ap_ft_pmf(dev, apdev, "1")
439
440 def test_ap_ft_pmf_over_ds(dev, apdev):
441     """WPA2-PSK-FT AP with PMF (over DS)"""
442     run_ap_ft_pmf(dev, apdev, "1", over_ds=True)
443
444 def test_ap_ft_pmf_required(dev, apdev):
445     """WPA2-PSK-FT AP with PMF required on STA"""
446     run_ap_ft_pmf(dev, apdev, "2")
447
448 def test_ap_ft_pmf_required_over_ds(dev, apdev):
449     """WPA2-PSK-FT AP with PMF required on STA (over DS)"""
450     run_ap_ft_pmf(dev, apdev, "2", over_ds=True)
451
452 def run_ap_ft_pmf(dev, apdev, ieee80211w, over_ds=False):
453     ssid = "test-ft"
454     passphrase = "12345678"
455
456     params = ft_params1(ssid=ssid, passphrase=passphrase)
457     params["ieee80211w"] = "2"
458     hapd0 = hostapd.add_ap(apdev[0], params)
459     params = ft_params2(ssid=ssid, passphrase=passphrase)
460     params["ieee80211w"] = "2"
461     hapd1 = hostapd.add_ap(apdev[1], params)
462
463     Wlantest.setup(hapd0)
464     wt = Wlantest()
465     wt.flush()
466     wt.add_passphrase(passphrase)
467
468     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
469               ieee80211w=ieee80211w, over_ds=over_ds)
470
471 def test_ap_ft_pmf_required_mismatch(dev, apdev):
472     """WPA2-PSK-FT AP with PMF required on STA but AP2 not enabling PMF"""
473     run_ap_ft_pmf_required_mismatch(dev, apdev)
474
475 def test_ap_ft_pmf_required_mismatch_over_ds(dev, apdev):
476     """WPA2-PSK-FT AP with PMF required on STA but AP2 not enabling PMF (over DS)"""
477     run_ap_ft_pmf_required_mismatch(dev, apdev, over_ds=True)
478
479 def run_ap_ft_pmf_required_mismatch(dev, apdev, over_ds=False):
480     ssid = "test-ft"
481     passphrase = "12345678"
482
483     params = ft_params1(ssid=ssid, passphrase=passphrase)
484     params["ieee80211w"] = "2"
485     hapd0 = hostapd.add_ap(apdev[0], params)
486     params = ft_params2(ssid=ssid, passphrase=passphrase)
487     params["ieee80211w"] = "0"
488     hapd1 = hostapd.add_ap(apdev[1], params)
489
490     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ieee80211w="2",
491               force_initial_conn_to_first_ap=True, fail_test=True,
492               over_ds=over_ds)
493
494 def test_ap_ft_pmf_bip_cmac_128(dev, apdev):
495     """WPA2-PSK-FT AP with PMF/BIP-CMAC-128"""
496     run_ap_ft_pmf_bip(dev, apdev, "AES-128-CMAC")
497
498 def test_ap_ft_pmf_bip_gmac_128(dev, apdev):
499     """WPA2-PSK-FT AP with PMF/BIP-GMAC-128"""
500     run_ap_ft_pmf_bip(dev, apdev, "BIP-GMAC-128")
501
502 def test_ap_ft_pmf_bip_gmac_256(dev, apdev):
503     """WPA2-PSK-FT AP with PMF/BIP-GMAC-256"""
504     run_ap_ft_pmf_bip(dev, apdev, "BIP-GMAC-256")
505
506 def test_ap_ft_pmf_bip_cmac_256(dev, apdev):
507     """WPA2-PSK-FT AP with PMF/BIP-CMAC-256"""
508     run_ap_ft_pmf_bip(dev, apdev, "BIP-CMAC-256")
509
510 def run_ap_ft_pmf_bip(dev, apdev, cipher):
511     if cipher not in dev[0].get_capability("group_mgmt"):
512         raise HwsimSkip("Cipher %s not supported" % cipher)
513
514     ssid = "test-ft"
515     passphrase = "12345678"
516
517     params = ft_params1(ssid=ssid, passphrase=passphrase)
518     params["ieee80211w"] = "2"
519     params["group_mgmt_cipher"] = cipher
520     hapd0 = hostapd.add_ap(apdev[0], params)
521     params = ft_params2(ssid=ssid, passphrase=passphrase)
522     params["ieee80211w"] = "2"
523     params["group_mgmt_cipher"] = cipher
524     hapd1 = hostapd.add_ap(apdev[1], params)
525
526     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
527               group_mgmt=cipher)
528
529 def test_ap_ft_ocv(dev, apdev):
530     """WPA2-PSK-FT AP with OCV"""
531     ssid = "test-ft"
532     passphrase = "12345678"
533
534     params = ft_params1(ssid=ssid, passphrase=passphrase)
535     params["ieee80211w"] = "2"
536     params["ocv"] = "1"
537     try:
538         hapd0 = hostapd.add_ap(apdev[0], params)
539     except Exception as e:
540         if "Failed to set hostapd parameter ocv" in str(e):
541             raise HwsimSkip("OCV not supported")
542         raise
543     params = ft_params2(ssid=ssid, passphrase=passphrase)
544     params["ieee80211w"] = "2"
545     params["ocv"] = "1"
546     hapd1 = hostapd.add_ap(apdev[1], params)
547
548     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ocv="1")
549
550 def test_ap_ft_over_ds(dev, apdev):
551     """WPA2-PSK-FT AP over DS"""
552     ssid = "test-ft"
553     passphrase = "12345678"
554
555     params = ft_params1(ssid=ssid, passphrase=passphrase)
556     hapd0 = hostapd.add_ap(apdev[0], params)
557     params = ft_params2(ssid=ssid, passphrase=passphrase)
558     hapd1 = hostapd.add_ap(apdev[1], params)
559
560     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
561     check_mib(dev[0], [("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
562                        ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4")])
563
564 def cleanup_ap_ft_separate_hostapd():
565     subprocess.call(["brctl", "delif", "br0ft", "veth0"],
566                     stderr=open('/dev/null', 'w'))
567     subprocess.call(["brctl", "delif", "br1ft", "veth1"],
568                     stderr=open('/dev/null', 'w'))
569     subprocess.call(["ip", "link", "del", "veth0"],
570                     stderr=open('/dev/null', 'w'))
571     subprocess.call(["ip", "link", "del", "veth1"],
572                     stderr=open('/dev/null', 'w'))
573     for ifname in ['br0ft', 'br1ft', 'br-ft']:
574         subprocess.call(['ip', 'link', 'set', 'dev', ifname, 'down'],
575                         stderr=open('/dev/null', 'w'))
576         subprocess.call(['brctl', 'delbr', ifname],
577                         stderr=open('/dev/null', 'w'))
578
579 def test_ap_ft_separate_hostapd(dev, apdev, params):
580     """WPA2-PSK-FT AP and separate hostapd process"""
581     try:
582         run_ap_ft_separate_hostapd(dev, apdev, params, False)
583     finally:
584         cleanup_ap_ft_separate_hostapd()
585
586 def test_ap_ft_over_ds_separate_hostapd(dev, apdev, params):
587     """WPA2-PSK-FT AP over DS and separate hostapd process"""
588     try:
589         run_ap_ft_separate_hostapd(dev, apdev, params, True)
590     finally:
591         cleanup_ap_ft_separate_hostapd()
592
593 def run_ap_ft_separate_hostapd(dev, apdev, params, over_ds):
594     ssid = "test-ft"
595     passphrase = "12345678"
596     logdir = params['logdir']
597     pidfile = os.path.join(logdir, 'ap_ft_over_ds_separate_hostapd.pid')
598     logfile = os.path.join(logdir, 'ap_ft_over_ds_separate_hostapd.hapd')
599     global_ctrl = '/var/run/hostapd-ft'
600     br_ifname = 'br-ft'
601
602     try:
603         subprocess.check_call(['brctl', 'addbr', br_ifname])
604         subprocess.check_call(['brctl', 'setfd', br_ifname, '0'])
605         subprocess.check_call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
606
607         subprocess.check_call(["ip", "link", "add", "veth0", "type", "veth",
608                                "peer", "name", "veth0br"])
609         subprocess.check_call(["ip", "link", "add", "veth1", "type", "veth",
610                                "peer", "name", "veth1br"])
611         subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth0br', 'up'])
612         subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth1br', 'up'])
613         subprocess.check_call(['brctl', 'addif', br_ifname, 'veth0br'])
614         subprocess.check_call(['brctl', 'addif', br_ifname, 'veth1br'])
615
616         subprocess.check_call(['brctl', 'addbr', 'br0ft'])
617         subprocess.check_call(['brctl', 'setfd', 'br0ft', '0'])
618         subprocess.check_call(['ip', 'link', 'set', 'dev', 'br0ft', 'up'])
619         subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth0', 'up'])
620         subprocess.check_call(['brctl', 'addif', 'br0ft', 'veth0'])
621         subprocess.check_call(['brctl', 'addbr', 'br1ft'])
622         subprocess.check_call(['brctl', 'setfd', 'br1ft', '0'])
623         subprocess.check_call(['ip', 'link', 'set', 'dev', 'br1ft', 'up'])
624         subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth1', 'up'])
625         subprocess.check_call(['brctl', 'addif', 'br1ft', 'veth1'])
626     except subprocess.CalledProcessError:
627         raise HwsimSkip("Bridge or veth not supported (kernel CONFIG_VETH)")
628
629     with HWSimRadio() as (radio, iface):
630         prg = os.path.join(logdir, 'alt-hostapd/hostapd/hostapd')
631         if not os.path.exists(prg):
632             prg = '../../hostapd/hostapd'
633         cmd = [prg, '-B', '-ddKt',
634                '-P', pidfile, '-f', logfile, '-g', global_ctrl]
635         subprocess.check_call(cmd)
636
637         hglobal = hostapd.HostapdGlobal(global_ctrl_override=global_ctrl)
638         apdev_ft = {'ifname': iface}
639         apdev2 = [apdev_ft, apdev[1]]
640
641         params = ft_params1(ssid=ssid, passphrase=passphrase)
642         params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
643         params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
644         params['bridge'] = 'br0ft'
645         hapd0 = hostapd.add_ap(apdev2[0], params,
646                                global_ctrl_override=global_ctrl)
647         apdev2[0]['bssid'] = hapd0.own_addr()
648         params = ft_params2(ssid=ssid, passphrase=passphrase)
649         params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
650         params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
651         params['bridge'] = 'br1ft'
652         hapd1 = hostapd.add_ap(apdev2[1], params)
653
654         run_roams(dev[0], apdev2, hapd0, hapd1, ssid, passphrase,
655                   over_ds=over_ds, test_connectivity=False)
656
657         hglobal.terminate()
658
659     if os.path.exists(pidfile):
660         with open(pidfile, 'r') as f:
661             pid = int(f.read())
662             f.close()
663         os.kill(pid, signal.SIGTERM)
664
665 def test_ap_ft_over_ds_ocv(dev, apdev):
666     """WPA2-PSK-FT AP over DS"""
667     ssid = "test-ft"
668     passphrase = "12345678"
669
670     params = ft_params1(ssid=ssid, passphrase=passphrase)
671     params["ieee80211w"] = "2"
672     params["ocv"] = "1"
673     try:
674         hapd0 = hostapd.add_ap(apdev[0], params)
675     except Exception as e:
676         if "Failed to set hostapd parameter ocv" in str(e):
677             raise HwsimSkip("OCV not supported")
678         raise
679     params = ft_params2(ssid=ssid, passphrase=passphrase)
680     params["ieee80211w"] = "2"
681     params["ocv"] = "1"
682     hapd1 = hostapd.add_ap(apdev[1], params)
683
684     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
685               ocv="1")
686
687 def test_ap_ft_over_ds_disabled(dev, apdev):
688     """WPA2-PSK-FT AP over DS disabled"""
689     ssid = "test-ft"
690     passphrase = "12345678"
691
692     params = ft_params1(ssid=ssid, passphrase=passphrase)
693     params['ft_over_ds'] = '0'
694     hapd0 = hostapd.add_ap(apdev[0], params)
695     params = ft_params2(ssid=ssid, passphrase=passphrase)
696     params['ft_over_ds'] = '0'
697     hapd1 = hostapd.add_ap(apdev[1], params)
698
699     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
700               fail_test=True)
701
702 def test_ap_ft_vlan_over_ds(dev, apdev):
703     """WPA2-PSK-FT AP over DS with VLAN"""
704     ssid = "test-ft"
705     passphrase = "12345678"
706
707     params = ft_params1(ssid=ssid, passphrase=passphrase)
708     params['dynamic_vlan'] = "1"
709     params['accept_mac_file'] = "hostapd.accept"
710     hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
711     params = ft_params2(ssid=ssid, passphrase=passphrase)
712     params['dynamic_vlan'] = "1"
713     params['accept_mac_file'] = "hostapd.accept"
714     hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
715
716     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
717               conndev="brvlan1")
718     check_mib(dev[0], [("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
719                        ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4")])
720
721 def test_ap_ft_over_ds_many(dev, apdev):
722     """WPA2-PSK-FT AP over DS multiple times"""
723     ssid = "test-ft"
724     passphrase = "12345678"
725
726     params = ft_params1(ssid=ssid, passphrase=passphrase)
727     hapd0 = hostapd.add_ap(apdev[0], params)
728     params = ft_params2(ssid=ssid, passphrase=passphrase)
729     hapd1 = hostapd.add_ap(apdev[1], params)
730
731     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
732               roams=50)
733
734 def test_ap_ft_vlan_over_ds_many(dev, apdev):
735     """WPA2-PSK-FT AP over DS with VLAN multiple times"""
736     ssid = "test-ft"
737     passphrase = "12345678"
738
739     params = ft_params1(ssid=ssid, passphrase=passphrase)
740     params['dynamic_vlan'] = "1"
741     params['accept_mac_file'] = "hostapd.accept"
742     hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
743     params = ft_params2(ssid=ssid, passphrase=passphrase)
744     params['dynamic_vlan'] = "1"
745     params['accept_mac_file'] = "hostapd.accept"
746     hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
747
748     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
749               roams=50, conndev="brvlan1")
750
751 @remote_compatible
752 def test_ap_ft_over_ds_unknown_target(dev, apdev):
753     """WPA2-PSK-FT AP"""
754     ssid = "test-ft"
755     passphrase = "12345678"
756
757     params = ft_params1(ssid=ssid, passphrase=passphrase)
758     hapd0 = hostapd.add_ap(apdev[0], params)
759
760     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
761                    scan_freq="2412")
762     dev[0].roam_over_ds("02:11:22:33:44:55", fail_test=True)
763
764 @remote_compatible
765 def test_ap_ft_over_ds_unexpected(dev, apdev):
766     """WPA2-PSK-FT AP over DS and unexpected response"""
767     ssid = "test-ft"
768     passphrase = "12345678"
769
770     params = ft_params1(ssid=ssid, passphrase=passphrase)
771     hapd0 = hostapd.add_ap(apdev[0], params)
772     params = ft_params2(ssid=ssid, passphrase=passphrase)
773     hapd1 = hostapd.add_ap(apdev[1], params)
774
775     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
776                    scan_freq="2412")
777     if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
778         ap1 = apdev[0]
779         ap2 = apdev[1]
780         hapd1ap = hapd0
781         hapd2ap = hapd1
782     else:
783         ap1 = apdev[1]
784         ap2 = apdev[0]
785         hapd1ap = hapd1
786         hapd2ap = hapd0
787
788     addr = dev[0].own_addr()
789     hapd1ap.set("ext_mgmt_frame_handling", "1")
790     logger.info("Foreign STA address")
791     msg = {}
792     msg['fc'] = 13 << 4
793     msg['da'] = addr
794     msg['sa'] = ap1['bssid']
795     msg['bssid'] = ap1['bssid']
796     msg['payload'] = binascii.unhexlify("06021122334455660102030405060000")
797     hapd1ap.mgmt_tx(msg)
798
799     logger.info("No over-the-DS in progress")
800     msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
801     hapd1ap.mgmt_tx(msg)
802
803     logger.info("Non-zero status code")
804     msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060100")
805     hapd1ap.mgmt_tx(msg)
806
807     hapd1ap.dump_monitor()
808
809     dev[0].scan_for_bss(ap2['bssid'], freq="2412")
810     if "OK" not in dev[0].request("FT_DS " + ap2['bssid']):
811             raise Exception("FT_DS failed")
812
813     req = hapd1ap.mgmt_rx()
814
815     logger.info("Foreign Target AP")
816     msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
817     hapd1ap.mgmt_tx(msg)
818
819     addrs = addr.replace(':', '') + ap2['bssid'].replace(':', '')
820
821     logger.info("No IEs")
822     msg['payload'] = binascii.unhexlify("0602" + addrs + "0000")
823     hapd1ap.mgmt_tx(msg)
824
825     logger.info("Invalid IEs (trigger parsing failure)")
826     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003700")
827     hapd1ap.mgmt_tx(msg)
828
829     logger.info("Too short MDIE")
830     msg['payload'] = binascii.unhexlify("0602" + addrs + "000036021122")
831     hapd1ap.mgmt_tx(msg)
832
833     logger.info("Mobility domain mismatch")
834     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603112201")
835     hapd1ap.mgmt_tx(msg)
836
837     logger.info("No FTIE")
838     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201")
839     hapd1ap.mgmt_tx(msg)
840
841     logger.info("FTIE SNonce mismatch")
842     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "1000000000000000000000000000000000000000000000000000000000000001" + "030a6e6173322e77312e6669")
843     hapd1ap.mgmt_tx(msg)
844
845     logger.info("No R0KH-ID subelem in FTIE")
846     snonce = binascii.hexlify(req['payload'][111:111+32]).decode()
847     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137520000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce)
848     hapd1ap.mgmt_tx(msg)
849
850     logger.info("No R0KH-ID subelem mismatch in FTIE")
851     snonce = binascii.hexlify(req['payload'][111:111+32]).decode()
852     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a11223344556677889900")
853     hapd1ap.mgmt_tx(msg)
854
855     logger.info("No R1KH-ID subelem in FTIE")
856     r0khid = binascii.hexlify(req['payload'][145:145+10]).decode()
857     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid)
858     hapd1ap.mgmt_tx(msg)
859
860     logger.info("No RSNE")
861     r0khid = binascii.hexlify(req['payload'][145:145+10]).decode()
862     msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137660000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid + "0106000102030405")
863     hapd1ap.mgmt_tx(msg)
864
865 def test_ap_ft_pmf_over_ds(dev, apdev):
866     """WPA2-PSK-FT AP over DS with PMF"""
867     run_ap_ft_pmf_bip_over_ds(dev, apdev, None)
868
869 def test_ap_ft_pmf_bip_cmac_128_over_ds(dev, apdev):
870     """WPA2-PSK-FT AP over DS with PMF/BIP-CMAC-128"""
871     run_ap_ft_pmf_bip_over_ds(dev, apdev, "AES-128-CMAC")
872
873 def test_ap_ft_pmf_bip_gmac_128_over_ds(dev, apdev):
874     """WPA2-PSK-FT AP over DS with PMF/BIP-GMAC-128"""
875     run_ap_ft_pmf_bip_over_ds(dev, apdev, "BIP-GMAC-128")
876
877 def test_ap_ft_pmf_bip_gmac_256_over_ds(dev, apdev):
878     """WPA2-PSK-FT AP over DS with PMF/BIP-GMAC-256"""
879     run_ap_ft_pmf_bip_over_ds(dev, apdev, "BIP-GMAC-256")
880
881 def test_ap_ft_pmf_bip_cmac_256_over_ds(dev, apdev):
882     """WPA2-PSK-FT AP over DS with PMF/BIP-CMAC-256"""
883     run_ap_ft_pmf_bip_over_ds(dev, apdev, "BIP-CMAC-256")
884
885 def run_ap_ft_pmf_bip_over_ds(dev, apdev, cipher):
886     if cipher and cipher not in dev[0].get_capability("group_mgmt"):
887         raise HwsimSkip("Cipher %s not supported" % cipher)
888
889     ssid = "test-ft"
890     passphrase = "12345678"
891
892     params = ft_params1(ssid=ssid, passphrase=passphrase)
893     params["ieee80211w"] = "2"
894     if cipher:
895         params["group_mgmt_cipher"] = cipher
896     hapd0 = hostapd.add_ap(apdev[0], params)
897     params = ft_params2(ssid=ssid, passphrase=passphrase)
898     params["ieee80211w"] = "2"
899     if cipher:
900         params["group_mgmt_cipher"] = cipher
901     hapd1 = hostapd.add_ap(apdev[1], params)
902
903     Wlantest.setup(hapd0)
904     wt = Wlantest()
905     wt.flush()
906     wt.add_passphrase(passphrase)
907
908     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
909               group_mgmt=cipher)
910
911 def test_ap_ft_over_ds_pull(dev, apdev):
912     """WPA2-PSK-FT AP over DS (pull PMK)"""
913     ssid = "test-ft"
914     passphrase = "12345678"
915
916     params = ft_params1(ssid=ssid, passphrase=passphrase)
917     params["pmk_r1_push"] = "0"
918     hapd0 = hostapd.add_ap(apdev[0], params)
919     params = ft_params2(ssid=ssid, passphrase=passphrase)
920     params["pmk_r1_push"] = "0"
921     hapd1 = hostapd.add_ap(apdev[1], params)
922
923     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
924
925 def test_ap_ft_over_ds_pull_old_key(dev, apdev):
926     """WPA2-PSK-FT AP over DS (pull PMK; old key)"""
927     ssid = "test-ft"
928     passphrase = "12345678"
929
930     params = ft_params1_old_key(ssid=ssid, passphrase=passphrase)
931     params["pmk_r1_push"] = "0"
932     hapd0 = hostapd.add_ap(apdev[0], params)
933     params = ft_params2_old_key(ssid=ssid, passphrase=passphrase)
934     params["pmk_r1_push"] = "0"
935     hapd1 = hostapd.add_ap(apdev[1], params)
936
937     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
938
939 def test_ap_ft_over_ds_pull_vlan(dev, apdev):
940     """WPA2-PSK-FT AP over DS (pull PMK) with VLAN"""
941     ssid = "test-ft"
942     passphrase = "12345678"
943
944     params = ft_params1(ssid=ssid, passphrase=passphrase)
945     params["pmk_r1_push"] = "0"
946     params['dynamic_vlan'] = "1"
947     params['accept_mac_file'] = "hostapd.accept"
948     hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
949     params = ft_params2(ssid=ssid, passphrase=passphrase)
950     params["pmk_r1_push"] = "0"
951     params['dynamic_vlan'] = "1"
952     params['accept_mac_file'] = "hostapd.accept"
953     hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
954
955     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
956               conndev="brvlan1")
957
958 def start_ft_sae(dev, apdev, wpa_ptk_rekey=None):
959     if "SAE" not in dev.get_capability("auth_alg"):
960         raise HwsimSkip("SAE not supported")
961     ssid = "test-ft"
962     passphrase = "12345678"
963
964     params = ft_params1(ssid=ssid, passphrase=passphrase)
965     params['wpa_key_mgmt'] = "FT-SAE"
966     if wpa_ptk_rekey:
967         params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
968     hapd0 = hostapd.add_ap(apdev[0], params)
969     params = ft_params2(ssid=ssid, passphrase=passphrase)
970     params['wpa_key_mgmt'] = "FT-SAE"
971     if wpa_ptk_rekey:
972         params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
973     hapd1 = hostapd.add_ap(apdev[1], params)
974     key_mgmt = hapd1.get_config()['key_mgmt']
975     if key_mgmt.split(' ')[0] != "FT-SAE":
976         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
977
978     dev.request("SET sae_groups ")
979     return hapd0, hapd1
980
981 def test_ap_ft_sae(dev, apdev):
982     """WPA2-PSK-FT-SAE AP"""
983     hapd0, hapd1 = start_ft_sae(dev[0], apdev)
984     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
985
986 def test_ap_ft_sae_ptk_rekey0(dev, apdev):
987     """WPA2-PSK-FT-SAE AP and PTK rekey triggered by station"""
988     hapd0, hapd1 = start_ft_sae(dev[0], apdev)
989     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
990               ptk_rekey="1", roams=0)
991     check_ptk_rekey(dev[0], hapd0, hapd1)
992
993 def test_ap_ft_sae_ptk_rekey1(dev, apdev):
994     """WPA2-PSK-FT-SAE AP and PTK rekey triggered by station"""
995     hapd0, hapd1 = start_ft_sae(dev[0], apdev)
996     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
997               ptk_rekey="1", only_one_way=True)
998     check_ptk_rekey(dev[0], hapd0, hapd1)
999
1000 def test_ap_ft_sae_ptk_rekey_ap(dev, apdev):
1001     """WPA2-PSK-FT-SAE AP and PTK rekey triggered by AP"""
1002     hapd0, hapd1 = start_ft_sae(dev[0], apdev, wpa_ptk_rekey=2)
1003     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1004               only_one_way=True)
1005     check_ptk_rekey(dev[0], hapd0, hapd1)
1006
1007 def test_ap_ft_sae_over_ds(dev, apdev):
1008     """WPA2-PSK-FT-SAE AP over DS"""
1009     hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1010     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1011               over_ds=True)
1012
1013 def test_ap_ft_sae_over_ds_ptk_rekey0(dev, apdev):
1014     """WPA2-PSK-FT-SAE AP over DS and PTK rekey triggered by station"""
1015     hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1016     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1017               over_ds=True, ptk_rekey="1", roams=0)
1018     check_ptk_rekey(dev[0], hapd0, hapd1)
1019
1020 def test_ap_ft_sae_over_ds_ptk_rekey1(dev, apdev):
1021     """WPA2-PSK-FT-SAE AP over DS and PTK rekey triggered by station"""
1022     hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1023     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1024               over_ds=True, ptk_rekey="1", only_one_way=True)
1025     check_ptk_rekey(dev[0], hapd0, hapd1)
1026
1027 def test_ap_ft_sae_over_ds_ptk_rekey_ap(dev, apdev):
1028     """WPA2-PSK-FT-SAE AP over DS and PTK rekey triggered by AP"""
1029     hapd0, hapd1 = start_ft_sae(dev[0], apdev, wpa_ptk_rekey=2)
1030     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1031               over_ds=True, only_one_way=True)
1032     check_ptk_rekey(dev[0], hapd0, hapd1)
1033
1034 def test_ap_ft_sae_pw_id(dev, apdev):
1035     """FT-SAE with Password Identifier"""
1036     if "SAE" not in dev[0].get_capability("auth_alg"):
1037         raise HwsimSkip("SAE not supported")
1038     ssid = "test-ft"
1039
1040     params = ft_params1(ssid=ssid)
1041     params["ieee80211w"] = "2"
1042     params['wpa_key_mgmt'] = "FT-SAE"
1043     params['sae_password'] = 'secret|id=pwid'
1044     hapd0 = hostapd.add_ap(apdev[0], params)
1045     params = ft_params2(ssid=ssid)
1046     params["ieee80211w"] = "2"
1047     params['wpa_key_mgmt'] = "FT-SAE"
1048     params['sae_password'] = 'secret|id=pwid'
1049     hapd = hostapd.add_ap(apdev[1], params)
1050
1051     dev[0].request("SET sae_groups ")
1052     run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase=None, sae=True,
1053               sae_password="secret", sae_password_id="pwid")
1054
1055 def test_ap_ft_sae_with_both_akms(dev, apdev):
1056     """SAE + FT-SAE configuration"""
1057     if "SAE" not in dev[0].get_capability("auth_alg"):
1058         raise HwsimSkip("SAE not supported")
1059     ssid = "test-ft"
1060     passphrase = "12345678"
1061
1062     params = ft_params1(ssid=ssid, passphrase=passphrase)
1063     params['wpa_key_mgmt'] = "FT-SAE SAE"
1064     hapd0 = hostapd.add_ap(apdev[0], params)
1065     params = ft_params2(ssid=ssid, passphrase=passphrase)
1066     params['wpa_key_mgmt'] = "FT-SAE SAE"
1067     hapd = hostapd.add_ap(apdev[1], params)
1068     key_mgmt = hapd.get_config()['key_mgmt']
1069     if key_mgmt.split(' ')[0] != "FT-SAE":
1070         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1071
1072     dev[0].request("SET sae_groups ")
1073     run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
1074               sae_and_psk=True)
1075
1076 def test_ap_ft_sae_pmksa_caching(dev, apdev):
1077     """WPA2-FT-SAE AP and PMKSA caching for initial mobility domain association"""
1078     if "SAE" not in dev[0].get_capability("auth_alg"):
1079         raise HwsimSkip("SAE not supported")
1080     ssid = "test-ft"
1081     passphrase = "12345678"
1082
1083     params = ft_params1(ssid=ssid, passphrase=passphrase)
1084     params['wpa_key_mgmt'] = "FT-SAE"
1085     hapd0 = hostapd.add_ap(apdev[0], params)
1086     params = ft_params2(ssid=ssid, passphrase=passphrase)
1087     params['wpa_key_mgmt'] = "FT-SAE"
1088     hapd = hostapd.add_ap(apdev[1], params)
1089     key_mgmt = hapd.get_config()['key_mgmt']
1090     if key_mgmt.split(' ')[0] != "FT-SAE":
1091         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1092
1093     dev[0].request("SET sae_groups ")
1094     run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
1095               pmksa_caching=True)
1096
1097 def generic_ap_ft_eap(dev, apdev, vlan=False, cui=False, over_ds=False,
1098                       discovery=False, roams=1, wpa_ptk_rekey=0,
1099                       only_one_way=False):
1100     ssid = "test-ft"
1101     passphrase = "12345678"
1102     if vlan:
1103         identity = "gpsk-vlan1"
1104         conndev = "brvlan1"
1105     elif cui:
1106         identity = "gpsk-cui"
1107         conndev = False
1108     else:
1109         identity = "gpsk user"
1110         conndev = False
1111
1112     radius = hostapd.radius_params()
1113     params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=discovery)
1114     params['wpa_key_mgmt'] = "FT-EAP"
1115     params["ieee8021x"] = "1"
1116     if vlan:
1117         params["dynamic_vlan"] = "1"
1118     params = dict(list(radius.items()) + list(params.items()))
1119     hapd = hostapd.add_ap(apdev[0], params)
1120     key_mgmt = hapd.get_config()['key_mgmt']
1121     if key_mgmt.split(' ')[0] != "FT-EAP":
1122         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1123     params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=discovery)
1124     params['wpa_key_mgmt'] = "FT-EAP"
1125     params["ieee8021x"] = "1"
1126     if vlan:
1127         params["dynamic_vlan"] = "1"
1128     if wpa_ptk_rekey:
1129         params["wpa_ptk_rekey"] = str(wpa_ptk_rekey)
1130     params = dict(list(radius.items()) + list(params.items()))
1131     hapd1 = hostapd.add_ap(apdev[1], params)
1132
1133     run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True,
1134               over_ds=over_ds, roams=roams, eap_identity=identity,
1135               conndev=conndev, only_one_way=only_one_way)
1136     if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"):
1137         raise Exception("Scan results missing RSN element info")
1138     check_mib(dev[0], [("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"),
1139                        ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3")])
1140     if only_one_way:
1141         return
1142
1143     # Verify EAPOL reauthentication after FT protocol
1144     if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
1145         ap = hapd
1146     else:
1147         ap = hapd1
1148     ap.request("EAPOL_REAUTH " + dev[0].own_addr())
1149     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
1150     if ev is None:
1151         raise Exception("EAP authentication did not start")
1152     ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
1153     if ev is None:
1154         raise Exception("EAP authentication did not succeed")
1155     time.sleep(0.1)
1156     if conndev:
1157         hwsim_utils.test_connectivity_iface(dev[0], ap, conndev)
1158     else:
1159         hwsim_utils.test_connectivity(dev[0], ap)
1160
1161 def test_ap_ft_eap(dev, apdev):
1162     """WPA2-EAP-FT AP"""
1163     generic_ap_ft_eap(dev, apdev)
1164
1165 def test_ap_ft_eap_cui(dev, apdev):
1166     """WPA2-EAP-FT AP with CUI"""
1167     generic_ap_ft_eap(dev, apdev, vlan=False, cui=True)
1168
1169 def test_ap_ft_eap_vlan(dev, apdev):
1170     """WPA2-EAP-FT AP with VLAN"""
1171     generic_ap_ft_eap(dev, apdev, vlan=True)
1172
1173 def test_ap_ft_eap_vlan_multi(dev, apdev):
1174     """WPA2-EAP-FT AP with VLAN"""
1175     generic_ap_ft_eap(dev, apdev, vlan=True, roams=50)
1176
1177 def test_ap_ft_eap_over_ds(dev, apdev):
1178     """WPA2-EAP-FT AP using over-the-DS"""
1179     generic_ap_ft_eap(dev, apdev, over_ds=True)
1180
1181 def test_ap_ft_eap_dis(dev, apdev):
1182     """WPA2-EAP-FT AP with AP discovery"""
1183     generic_ap_ft_eap(dev, apdev, discovery=True)
1184
1185 def test_ap_ft_eap_dis_over_ds(dev, apdev):
1186     """WPA2-EAP-FT AP with AP discovery and over-the-DS"""
1187     generic_ap_ft_eap(dev, apdev, over_ds=True, discovery=True)
1188
1189 def test_ap_ft_eap_vlan(dev, apdev):
1190     """WPA2-EAP-FT AP with VLAN"""
1191     generic_ap_ft_eap(dev, apdev, vlan=True)
1192
1193 def test_ap_ft_eap_vlan_multi(dev, apdev):
1194     """WPA2-EAP-FT AP with VLAN"""
1195     generic_ap_ft_eap(dev, apdev, vlan=True, roams=50)
1196
1197 def test_ap_ft_eap_vlan_over_ds(dev, apdev):
1198     """WPA2-EAP-FT AP with VLAN + over_ds"""
1199     generic_ap_ft_eap(dev, apdev, vlan=True, over_ds=True)
1200
1201 def test_ap_ft_eap_vlan_over_ds_multi(dev, apdev):
1202     """WPA2-EAP-FT AP with VLAN + over_ds"""
1203     generic_ap_ft_eap(dev, apdev, vlan=True, over_ds=True, roams=50)
1204
1205 def generic_ap_ft_eap_pull(dev, apdev, vlan=False):
1206     """WPA2-EAP-FT AP (pull PMK)"""
1207     ssid = "test-ft"
1208     passphrase = "12345678"
1209     if vlan:
1210         identity = "gpsk-vlan1"
1211         conndev = "brvlan1"
1212     else:
1213         identity = "gpsk user"
1214         conndev = False
1215
1216     radius = hostapd.radius_params()
1217     params = ft_params1(ssid=ssid, passphrase=passphrase)
1218     params['wpa_key_mgmt'] = "FT-EAP"
1219     params["ieee8021x"] = "1"
1220     params["pmk_r1_push"] = "0"
1221     if vlan:
1222         params["dynamic_vlan"] = "1"
1223     params = dict(list(radius.items()) + list(params.items()))
1224     hapd = hostapd.add_ap(apdev[0], params)
1225     key_mgmt = hapd.get_config()['key_mgmt']
1226     if key_mgmt.split(' ')[0] != "FT-EAP":
1227         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1228     params = ft_params2(ssid=ssid, passphrase=passphrase)
1229     params['wpa_key_mgmt'] = "FT-EAP"
1230     params["ieee8021x"] = "1"
1231     params["pmk_r1_push"] = "0"
1232     if vlan:
1233         params["dynamic_vlan"] = "1"
1234     params = dict(list(radius.items()) + list(params.items()))
1235     hapd1 = hostapd.add_ap(apdev[1], params)
1236
1237     run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True,
1238               eap_identity=identity, conndev=conndev)
1239
1240 def test_ap_ft_eap_pull(dev, apdev):
1241     """WPA2-EAP-FT AP (pull PMK)"""
1242     generic_ap_ft_eap_pull(dev, apdev)
1243
1244 def test_ap_ft_eap_pull_vlan(dev, apdev):
1245     generic_ap_ft_eap_pull(dev, apdev, vlan=True)
1246
1247 def test_ap_ft_eap_pull_wildcard(dev, apdev):
1248     """WPA2-EAP-FT AP (pull PMK) - wildcard R0KH/R1KH"""
1249     ssid = "test-ft"
1250     passphrase = "12345678"
1251
1252     radius = hostapd.radius_params()
1253     params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
1254     params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
1255     params["ieee8021x"] = "1"
1256     params["pmk_r1_push"] = "0"
1257     params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1258     params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1259     params["ft_psk_generate_local"] = "1"
1260     params["eap_server"] = "0"
1261     params["rkh_pos_timeout"] = "100"
1262     params["rkh_neg_timeout"] = "50"
1263     params["rkh_pull_timeout"] = "1234"
1264     params["rkh_pull_retries"] = "10"
1265     params = dict(list(radius.items()) + list(params.items()))
1266     hapd = hostapd.add_ap(apdev[0], params)
1267     params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=True)
1268     params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
1269     params["ieee8021x"] = "1"
1270     params["pmk_r1_push"] = "0"
1271     params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1272     params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1273     params["ft_psk_generate_local"] = "1"
1274     params["eap_server"] = "0"
1275     params = dict(list(radius.items()) + list(params.items()))
1276     hapd1 = hostapd.add_ap(apdev[1], params)
1277
1278     run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
1279
1280 @remote_compatible
1281 def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
1282     """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
1283     ssid = "test-ft"
1284     passphrase = "12345678"
1285
1286     params = ft_params1(ssid=ssid, passphrase=passphrase)
1287     params["ieee80211w"] = "2"
1288     hapd0 = hostapd.add_ap(apdev[0], params)
1289     params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
1290     params["ieee80211w"] = "2"
1291     hapd1 = hostapd.add_ap(apdev[1], params)
1292
1293     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1294               fail_test=True)
1295
1296 @remote_compatible
1297 def test_ap_ft_mismatching_rrb_key_pull(dev, apdev):
1298     """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
1299     ssid = "test-ft"
1300     passphrase = "12345678"
1301
1302     params = ft_params1(ssid=ssid, passphrase=passphrase)
1303     params["pmk_r1_push"] = "0"
1304     hapd0 = hostapd.add_ap(apdev[0], params)
1305     params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
1306     params["pmk_r1_push"] = "0"
1307     hapd1 = hostapd.add_ap(apdev[1], params)
1308
1309     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1310               fail_test=True)
1311
1312 @remote_compatible
1313 def test_ap_ft_mismatching_r0kh_id_pull(dev, apdev):
1314     """WPA2-PSK-FT AP over DS with mismatching R0KH-ID (pull)"""
1315     ssid = "test-ft"
1316     passphrase = "12345678"
1317
1318     params = ft_params1(ssid=ssid, passphrase=passphrase)
1319     params["pmk_r1_push"] = "0"
1320     params["nas_identifier"] = "nas0.w1.fi"
1321     hostapd.add_ap(apdev[0], params)
1322     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1323                    scan_freq="2412")
1324
1325     params = ft_params2(ssid=ssid, passphrase=passphrase)
1326     params["pmk_r1_push"] = "0"
1327     hostapd.add_ap(apdev[1], params)
1328
1329     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1330     dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
1331
1332 @remote_compatible
1333 def test_ap_ft_mismatching_rrb_r0kh_push(dev, apdev):
1334     """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
1335     ssid = "test-ft"
1336     passphrase = "12345678"
1337
1338     params = ft_params1(ssid=ssid, passphrase=passphrase)
1339     params["ieee80211w"] = "2"
1340     hapd0 = hostapd.add_ap(apdev[0], params)
1341     params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
1342     params["ieee80211w"] = "2"
1343     hapd1 = hostapd.add_ap(apdev[1], params)
1344
1345     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1346               fail_test=True)
1347
1348 @remote_compatible
1349 def test_ap_ft_mismatching_rrb_r0kh_pull(dev, apdev):
1350     """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
1351     ssid = "test-ft"
1352     passphrase = "12345678"
1353
1354     params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
1355     params["pmk_r1_push"] = "0"
1356     hapd0 = hostapd.add_ap(apdev[0], params)
1357     params = ft_params2(ssid=ssid, passphrase=passphrase)
1358     params["pmk_r1_push"] = "0"
1359     hapd1 = hostapd.add_ap(apdev[1], params)
1360
1361     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1362               fail_test=True)
1363
1364 def test_ap_ft_mismatching_rrb_key_push_eap(dev, apdev):
1365     """WPA2-EAP-FT AP over DS with mismatching RRB key (push)"""
1366     ssid = "test-ft"
1367     passphrase = "12345678"
1368
1369     radius = hostapd.radius_params()
1370     params = ft_params1(ssid=ssid, passphrase=passphrase)
1371     params["ieee80211w"] = "2"
1372     params['wpa_key_mgmt'] = "FT-EAP"
1373     params["ieee8021x"] = "1"
1374     params = dict(list(radius.items()) + list(params.items()))
1375     hapd0 = hostapd.add_ap(apdev[0], params)
1376     params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
1377     params["ieee80211w"] = "2"
1378     params['wpa_key_mgmt'] = "FT-EAP"
1379     params["ieee8021x"] = "1"
1380     params = dict(list(radius.items()) + list(params.items()))
1381     hapd1 = hostapd.add_ap(apdev[1], params)
1382
1383     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1384               fail_test=True, eap=True)
1385
1386 def test_ap_ft_mismatching_rrb_key_pull_eap(dev, apdev):
1387     """WPA2-EAP-FT AP over DS with mismatching RRB key (pull)"""
1388     ssid = "test-ft"
1389     passphrase = "12345678"
1390
1391     radius = hostapd.radius_params()
1392     params = ft_params1(ssid=ssid, passphrase=passphrase)
1393     params["pmk_r1_push"] = "0"
1394     params['wpa_key_mgmt'] = "FT-EAP"
1395     params["ieee8021x"] = "1"
1396     params = dict(list(radius.items()) + list(params.items()))
1397     hapd0 = hostapd.add_ap(apdev[0], params)
1398     params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
1399     params["pmk_r1_push"] = "0"
1400     params['wpa_key_mgmt'] = "FT-EAP"
1401     params["ieee8021x"] = "1"
1402     params = dict(list(radius.items()) + list(params.items()))
1403     hapd1 = hostapd.add_ap(apdev[1], params)
1404
1405     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1406               fail_test=True, eap=True)
1407
1408 def test_ap_ft_mismatching_r0kh_id_pull_eap(dev, apdev):
1409     """WPA2-EAP-FT AP over DS with mismatching R0KH-ID (pull)"""
1410     ssid = "test-ft"
1411     passphrase = "12345678"
1412
1413     radius = hostapd.radius_params()
1414     params = ft_params1(ssid=ssid, passphrase=passphrase)
1415     params["pmk_r1_push"] = "0"
1416     params["nas_identifier"] = "nas0.w1.fi"
1417     params['wpa_key_mgmt'] = "FT-EAP"
1418     params["ieee8021x"] = "1"
1419     params = dict(list(radius.items()) + list(params.items()))
1420     hostapd.add_ap(apdev[0], params)
1421     dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
1422                    eap="GPSK", identity="gpsk user",
1423                    password="abcdefghijklmnop0123456789abcdef",
1424                    scan_freq="2412")
1425
1426     params = ft_params2(ssid=ssid, passphrase=passphrase)
1427     params["pmk_r1_push"] = "0"
1428     params['wpa_key_mgmt'] = "FT-EAP"
1429     params["ieee8021x"] = "1"
1430     params = dict(list(radius.items()) + list(params.items()))
1431     hostapd.add_ap(apdev[1], params)
1432
1433     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1434     dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
1435
1436 def test_ap_ft_mismatching_rrb_r0kh_push_eap(dev, apdev):
1437     """WPA2-EAP-FT AP over DS with mismatching R0KH key (push)"""
1438     ssid = "test-ft"
1439     passphrase = "12345678"
1440
1441     radius = hostapd.radius_params()
1442     params = ft_params1(ssid=ssid, passphrase=passphrase)
1443     params["ieee80211w"] = "2"
1444     params['wpa_key_mgmt'] = "FT-EAP"
1445     params["ieee8021x"] = "1"
1446     params = dict(list(radius.items()) + list(params.items()))
1447     hapd0 = hostapd.add_ap(apdev[0], params)
1448     params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
1449     params["ieee80211w"] = "2"
1450     params['wpa_key_mgmt'] = "FT-EAP"
1451     params["ieee8021x"] = "1"
1452     params = dict(list(radius.items()) + list(params.items()))
1453     hapd1 = hostapd.add_ap(apdev[1], params)
1454
1455     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1456               fail_test=True, eap=True)
1457
1458 def test_ap_ft_mismatching_rrb_r0kh_pull_eap(dev, apdev):
1459     """WPA2-EAP-FT AP over DS with mismatching R0KH key (pull)"""
1460     ssid = "test-ft"
1461     passphrase = "12345678"
1462
1463     radius = hostapd.radius_params()
1464     params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
1465     params["pmk_r1_push"] = "0"
1466     params['wpa_key_mgmt'] = "FT-EAP"
1467     params["ieee8021x"] = "1"
1468     params = dict(list(radius.items()) + list(params.items()))
1469     hapd0 = hostapd.add_ap(apdev[0], params)
1470     params = ft_params2(ssid=ssid, passphrase=passphrase)
1471     params["pmk_r1_push"] = "0"
1472     params['wpa_key_mgmt'] = "FT-EAP"
1473     params["ieee8021x"] = "1"
1474     params = dict(list(radius.items()) + list(params.items()))
1475     hapd1 = hostapd.add_ap(apdev[1], params)
1476
1477     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1478               fail_test=True, eap=True)
1479
1480 def test_ap_ft_gtk_rekey(dev, apdev):
1481     """WPA2-PSK-FT AP and GTK rekey"""
1482     ssid = "test-ft"
1483     passphrase = "12345678"
1484
1485     params = ft_params1(ssid=ssid, passphrase=passphrase)
1486     params['wpa_group_rekey'] = '1'
1487     hapd = hostapd.add_ap(apdev[0], params)
1488
1489     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1490                    ieee80211w="1", scan_freq="2412")
1491
1492     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
1493     if ev is None:
1494         raise Exception("GTK rekey timed out after initial association")
1495     hwsim_utils.test_connectivity(dev[0], hapd)
1496
1497     params = ft_params2(ssid=ssid, passphrase=passphrase)
1498     params['wpa_group_rekey'] = '1'
1499     hapd1 = hostapd.add_ap(apdev[1], params)
1500
1501     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1502     dev[0].roam(apdev[1]['bssid'])
1503     if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
1504         raise Exception("Did not connect to correct AP")
1505     hwsim_utils.test_connectivity(dev[0], hapd1)
1506
1507     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
1508     if ev is None:
1509         raise Exception("GTK rekey timed out after FT protocol")
1510     hwsim_utils.test_connectivity(dev[0], hapd1)
1511
1512 def test_ft_psk_key_lifetime_in_memory(dev, apdev, params):
1513     """WPA2-PSK-FT and key lifetime in memory"""
1514     ssid = "test-ft"
1515     passphrase = "04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0"
1516     psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d'
1517     pmk = binascii.unhexlify(psk)
1518     p = ft_params1(ssid=ssid, passphrase=passphrase)
1519     hapd0 = hostapd.add_ap(apdev[0], p)
1520     p = ft_params2(ssid=ssid, passphrase=passphrase)
1521     hapd1 = hostapd.add_ap(apdev[1], p)
1522
1523     pid = find_wpas_process(dev[0])
1524
1525     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1526                    scan_freq="2412")
1527     # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
1528     # event has been delivered, so verify that wpa_supplicant has returned to
1529     # eloop before reading process memory.
1530     time.sleep(1)
1531     dev[0].ping()
1532
1533     buf = read_process_memory(pid, pmk)
1534
1535     dev[0].request("DISCONNECT")
1536     dev[0].wait_disconnected()
1537
1538     dev[0].relog()
1539     pmkr0 = None
1540     pmkr1 = None
1541     ptk = None
1542     gtk = None
1543     with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
1544         for l in f.readlines():
1545             if "FT: PMK-R0 - hexdump" in l:
1546                 val = l.strip().split(':')[3].replace(' ', '')
1547                 pmkr0 = binascii.unhexlify(val)
1548             if "FT: PMK-R1 - hexdump" in l:
1549                 val = l.strip().split(':')[3].replace(' ', '')
1550                 pmkr1 = binascii.unhexlify(val)
1551             if "FT: KCK - hexdump" in l:
1552                 val = l.strip().split(':')[3].replace(' ', '')
1553                 kck = binascii.unhexlify(val)
1554             if "FT: KEK - hexdump" in l:
1555                 val = l.strip().split(':')[3].replace(' ', '')
1556                 kek = binascii.unhexlify(val)
1557             if "FT: TK - hexdump" in l:
1558                 val = l.strip().split(':')[3].replace(' ', '')
1559                 tk = binascii.unhexlify(val)
1560             if "WPA: Group Key - hexdump" in l:
1561                 val = l.strip().split(':')[3].replace(' ', '')
1562                 gtk = binascii.unhexlify(val)
1563     if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk:
1564         raise Exception("Could not find keys from debug log")
1565     if len(gtk) != 16:
1566         raise Exception("Unexpected GTK length")
1567
1568     logger.info("Checking keys in memory while associated")
1569     get_key_locations(buf, pmk, "PMK")
1570     get_key_locations(buf, pmkr0, "PMK-R0")
1571     get_key_locations(buf, pmkr1, "PMK-R1")
1572     if pmk not in buf:
1573         raise HwsimSkip("PMK not found while associated")
1574     if pmkr0 not in buf:
1575         raise HwsimSkip("PMK-R0 not found while associated")
1576     if pmkr1 not in buf:
1577         raise HwsimSkip("PMK-R1 not found while associated")
1578     if kck not in buf:
1579         raise Exception("KCK not found while associated")
1580     if kek not in buf:
1581         raise Exception("KEK not found while associated")
1582     #if tk in buf:
1583     #    raise Exception("TK found from memory")
1584
1585     logger.info("Checking keys in memory after disassociation")
1586     buf = read_process_memory(pid, pmk)
1587     get_key_locations(buf, pmk, "PMK")
1588     get_key_locations(buf, pmkr0, "PMK-R0")
1589     get_key_locations(buf, pmkr1, "PMK-R1")
1590
1591     # Note: PMK/PSK is still present in network configuration
1592
1593     fname = os.path.join(params['logdir'],
1594                          'ft_psk_key_lifetime_in_memory.memctx-')
1595     verify_not_present(buf, pmkr0, fname, "PMK-R0")
1596     verify_not_present(buf, pmkr1, fname, "PMK-R1")
1597     verify_not_present(buf, kck, fname, "KCK")
1598     verify_not_present(buf, kek, fname, "KEK")
1599     verify_not_present(buf, tk, fname, "TK")
1600     if gtk in buf:
1601         get_key_locations(buf, gtk, "GTK")
1602     verify_not_present(buf, gtk, fname, "GTK")
1603
1604     dev[0].request("REMOVE_NETWORK all")
1605
1606     logger.info("Checking keys in memory after network profile removal")
1607     buf = read_process_memory(pid, pmk)
1608     get_key_locations(buf, pmk, "PMK")
1609     get_key_locations(buf, pmkr0, "PMK-R0")
1610     get_key_locations(buf, pmkr1, "PMK-R1")
1611
1612     verify_not_present(buf, pmk, fname, "PMK")
1613     verify_not_present(buf, pmkr0, fname, "PMK-R0")
1614     verify_not_present(buf, pmkr1, fname, "PMK-R1")
1615     verify_not_present(buf, kck, fname, "KCK")
1616     verify_not_present(buf, kek, fname, "KEK")
1617     verify_not_present(buf, tk, fname, "TK")
1618     verify_not_present(buf, gtk, fname, "GTK")
1619
1620 @remote_compatible
1621 def test_ap_ft_invalid_resp(dev, apdev):
1622     """WPA2-PSK-FT AP and invalid response IEs"""
1623     ssid = "test-ft"
1624     passphrase = "12345678"
1625
1626     params = ft_params1(ssid=ssid, passphrase=passphrase)
1627     hapd0 = hostapd.add_ap(apdev[0], params)
1628     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1629                    scan_freq="2412")
1630
1631     params = ft_params2(ssid=ssid, passphrase=passphrase)
1632     hapd1 = hostapd.add_ap(apdev[1], params)
1633
1634     tests = [
1635         # Various IEs for test coverage. The last one is FTIE with invalid
1636         # R1KH-ID subelement.
1637         "020002000000" + "3800" + "38051122334455" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010100",
1638         # FTIE with invalid R0KH-ID subelement (len=0).
1639         "020002000000" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010300",
1640         # FTIE with invalid R0KH-ID subelement (len=49).
1641         "020002000000" + "378500010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001033101020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849",
1642         # Invalid RSNE.
1643         "020002000000" + "3000",
1644         # Required IEs missing from protected IE count.
1645         "020002000000" + "3603a1b201" + "375200010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
1646         # RIC missing from protected IE count.
1647         "020002000000" + "3603a1b201" + "375200020203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
1648         # Protected IE missing.
1649         "020002000000" + "3603a1b201" + "375200ff0203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900" + "0000"]
1650     for t in tests:
1651         dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1652         hapd1.set("ext_mgmt_frame_handling", "1")
1653         hapd1.dump_monitor()
1654         if "OK" not in dev[0].request("ROAM " + apdev[1]['bssid']):
1655             raise Exception("ROAM failed")
1656         auth = None
1657         for i in range(20):
1658             msg = hapd1.mgmt_rx()
1659             if msg['subtype'] == 11:
1660                 auth = msg
1661                 break
1662         if not auth:
1663             raise Exception("Authentication frame not seen")
1664
1665         resp = {}
1666         resp['fc'] = auth['fc']
1667         resp['da'] = auth['sa']
1668         resp['sa'] = auth['da']
1669         resp['bssid'] = auth['bssid']
1670         resp['payload'] = binascii.unhexlify(t)
1671         hapd1.mgmt_tx(resp)
1672         hapd1.set("ext_mgmt_frame_handling", "0")
1673         dev[0].wait_disconnected()
1674
1675         dev[0].request("RECONNECT")
1676         dev[0].wait_connected()
1677
1678 def test_ap_ft_gcmp_256(dev, apdev):
1679     """WPA2-PSK-FT AP with GCMP-256 cipher"""
1680     if "GCMP-256" not in dev[0].get_capability("pairwise"):
1681         raise HwsimSkip("Cipher GCMP-256 not supported")
1682     ssid = "test-ft"
1683     passphrase = "12345678"
1684
1685     params = ft_params1(ssid=ssid, passphrase=passphrase)
1686     params['rsn_pairwise'] = "GCMP-256"
1687     hapd0 = hostapd.add_ap(apdev[0], params)
1688     params = ft_params2(ssid=ssid, passphrase=passphrase)
1689     params['rsn_pairwise'] = "GCMP-256"
1690     hapd1 = hostapd.add_ap(apdev[1], params)
1691
1692     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
1693               pairwise_cipher="GCMP-256", group_cipher="GCMP-256")
1694
1695 def setup_ap_ft_oom(dev, apdev):
1696     skip_with_fips(dev[0])
1697     ssid = "test-ft"
1698     passphrase = "12345678"
1699
1700     params = ft_params1(ssid=ssid, passphrase=passphrase)
1701     hapd0 = hostapd.add_ap(apdev[0], params)
1702     params = ft_params2(ssid=ssid, passphrase=passphrase)
1703     hapd1 = hostapd.add_ap(apdev[1], params)
1704
1705     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1706                    scan_freq="2412")
1707     if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
1708         dst = apdev[1]['bssid']
1709     else:
1710         dst = apdev[0]['bssid']
1711
1712     dev[0].scan_for_bss(dst, freq="2412")
1713
1714     return dst
1715
1716 def test_ap_ft_oom(dev, apdev):
1717     """WPA2-PSK-FT and OOM"""
1718     dst = setup_ap_ft_oom(dev, apdev)
1719     with alloc_fail(dev[0], 1, "wpa_ft_gen_req_ies"):
1720         dev[0].roam(dst)
1721
1722 def test_ap_ft_oom2(dev, apdev):
1723     """WPA2-PSK-FT and OOM (2)"""
1724     dst = setup_ap_ft_oom(dev, apdev)
1725     with fail_test(dev[0], 1, "wpa_ft_mic"):
1726         dev[0].roam(dst, fail_test=True, assoc_reject_ok=True)
1727
1728 def test_ap_ft_oom3(dev, apdev):
1729     """WPA2-PSK-FT and OOM (3)"""
1730     dst = setup_ap_ft_oom(dev, apdev)
1731     with fail_test(dev[0], 1, "os_get_random;wpa_ft_prepare_auth_request"):
1732         dev[0].roam(dst)
1733
1734 def test_ap_ft_oom4(dev, apdev):
1735     """WPA2-PSK-FT and OOM (4)"""
1736     ssid = "test-ft"
1737     passphrase = "12345678"
1738     dst = setup_ap_ft_oom(dev, apdev)
1739     dev[0].request("REMOVE_NETWORK all")
1740     with alloc_fail(dev[0], 1, "=sme_update_ft_ies"):
1741         dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1742                        scan_freq="2412")
1743
1744 def test_ap_ft_ap_oom(dev, apdev):
1745     """WPA2-PSK-FT and AP OOM"""
1746     ssid = "test-ft"
1747     passphrase = "12345678"
1748
1749     params = ft_params1(ssid=ssid, passphrase=passphrase)
1750     hapd0 = hostapd.add_ap(apdev[0], params)
1751     bssid0 = hapd0.own_addr()
1752
1753     dev[0].scan_for_bss(bssid0, freq="2412")
1754     with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r0"):
1755         dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1756                        scan_freq="2412")
1757
1758     params = ft_params2(ssid=ssid, passphrase=passphrase)
1759     hapd1 = hostapd.add_ap(apdev[1], params)
1760     bssid1 = hapd1.own_addr()
1761     dev[0].scan_for_bss(bssid1, freq="2412")
1762     # This roam will fail due to missing PMK-R0 (OOM prevented storing it)
1763     dev[0].roam(bssid1)
1764
1765 def test_ap_ft_ap_oom2(dev, apdev):
1766     """WPA2-PSK-FT and AP OOM 2"""
1767     ssid = "test-ft"
1768     passphrase = "12345678"
1769
1770     params = ft_params1(ssid=ssid, passphrase=passphrase)
1771     hapd0 = hostapd.add_ap(apdev[0], params)
1772     bssid0 = hapd0.own_addr()
1773
1774     dev[0].scan_for_bss(bssid0, freq="2412")
1775     with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r1"):
1776         dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1777                        scan_freq="2412")
1778
1779     params = ft_params2(ssid=ssid, passphrase=passphrase)
1780     hapd1 = hostapd.add_ap(apdev[1], params)
1781     bssid1 = hapd1.own_addr()
1782     dev[0].scan_for_bss(bssid1, freq="2412")
1783     dev[0].roam(bssid1)
1784     if dev[0].get_status_field('bssid') != bssid1:
1785         raise Exception("Did not roam to AP1")
1786     # This roam will fail due to missing PMK-R1 (OOM prevented storing it)
1787     dev[0].roam(bssid0)
1788
1789 def test_ap_ft_ap_oom3(dev, apdev):
1790     """WPA2-PSK-FT and AP OOM 3"""
1791     ssid = "test-ft"
1792     passphrase = "12345678"
1793
1794     params = ft_params1(ssid=ssid, passphrase=passphrase)
1795     hapd0 = hostapd.add_ap(apdev[0], params)
1796     bssid0 = hapd0.own_addr()
1797
1798     dev[0].scan_for_bss(bssid0, freq="2412")
1799     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1800                    scan_freq="2412")
1801
1802     params = ft_params2(ssid=ssid, passphrase=passphrase)
1803     hapd1 = hostapd.add_ap(apdev[1], params)
1804     bssid1 = hapd1.own_addr()
1805     dev[0].scan_for_bss(bssid1, freq="2412")
1806     with alloc_fail(hapd1, 1, "wpa_ft_pull_pmk_r1"):
1807         # This will fail due to not being able to send out PMK-R1 pull request
1808         dev[0].roam(bssid1)
1809
1810     with fail_test(hapd1, 2, "os_get_random;wpa_ft_pull_pmk_r1"):
1811         # This will fail due to not being able to send out PMK-R1 pull request
1812         dev[0].roam(bssid1)
1813
1814     with fail_test(hapd1, 2, "aes_siv_encrypt;wpa_ft_pull_pmk_r1"):
1815         # This will fail due to not being able to send out PMK-R1 pull request
1816         dev[0].roam(bssid1)
1817
1818 def test_ap_ft_ap_oom3b(dev, apdev):
1819     """WPA2-PSK-FT and AP OOM 3b"""
1820     ssid = "test-ft"
1821     passphrase = "12345678"
1822
1823     params = ft_params1(ssid=ssid, passphrase=passphrase)
1824     hapd0 = hostapd.add_ap(apdev[0], params)
1825     bssid0 = hapd0.own_addr()
1826
1827     dev[0].scan_for_bss(bssid0, freq="2412")
1828     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1829                    scan_freq="2412")
1830
1831     params = ft_params2(ssid=ssid, passphrase=passphrase)
1832     hapd1 = hostapd.add_ap(apdev[1], params)
1833     bssid1 = hapd1.own_addr()
1834     dev[0].scan_for_bss(bssid1, freq="2412")
1835     with fail_test(hapd1, 1, "os_get_random;wpa_ft_pull_pmk_r1"):
1836         # This will fail due to not being able to send out PMK-R1 pull request
1837         dev[0].roam(bssid1)
1838
1839 def test_ap_ft_ap_oom4(dev, apdev):
1840     """WPA2-PSK-FT and AP OOM 4"""
1841     ssid = "test-ft"
1842     passphrase = "12345678"
1843
1844     params = ft_params1(ssid=ssid, passphrase=passphrase)
1845     hapd0 = hostapd.add_ap(apdev[0], params)
1846     bssid0 = hapd0.own_addr()
1847
1848     dev[0].scan_for_bss(bssid0, freq="2412")
1849     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1850                    scan_freq="2412")
1851
1852     params = ft_params2(ssid=ssid, passphrase=passphrase)
1853     hapd1 = hostapd.add_ap(apdev[1], params)
1854     bssid1 = hapd1.own_addr()
1855     dev[0].scan_for_bss(bssid1, freq="2412")
1856     with alloc_fail(hapd1, 1, "wpa_ft_gtk_subelem"):
1857         dev[0].roam(bssid1)
1858         if dev[0].get_status_field('bssid') != bssid1:
1859             raise Exception("Did not roam to AP1")
1860
1861     with fail_test(hapd0, 1, "wpa_auth_get_seqnum;wpa_ft_gtk_subelem"):
1862         dev[0].roam(bssid0)
1863         if dev[0].get_status_field('bssid') != bssid0:
1864             raise Exception("Did not roam to AP0")
1865
1866     with fail_test(hapd0, 1, "aes_wrap;wpa_ft_gtk_subelem"):
1867         dev[0].roam(bssid1)
1868         if dev[0].get_status_field('bssid') != bssid1:
1869             raise Exception("Did not roam to AP1")
1870
1871 def test_ap_ft_ap_oom5(dev, apdev):
1872     """WPA2-PSK-FT and AP OOM 5"""
1873     ssid = "test-ft"
1874     passphrase = "12345678"
1875
1876     params = ft_params1(ssid=ssid, passphrase=passphrase)
1877     hapd0 = hostapd.add_ap(apdev[0], params)
1878     bssid0 = hapd0.own_addr()
1879
1880     dev[0].scan_for_bss(bssid0, freq="2412")
1881     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1882                    scan_freq="2412")
1883
1884     params = ft_params2(ssid=ssid, passphrase=passphrase)
1885     hapd1 = hostapd.add_ap(apdev[1], params)
1886     bssid1 = hapd1.own_addr()
1887     dev[0].scan_for_bss(bssid1, freq="2412")
1888     with alloc_fail(hapd1, 1, "=wpa_ft_process_auth_req"):
1889         # This will fail to roam
1890         dev[0].roam(bssid1)
1891
1892     with fail_test(hapd1, 1, "os_get_random;wpa_ft_process_auth_req"):
1893         # This will fail to roam
1894         dev[0].roam(bssid1)
1895
1896     with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
1897         # This will fail to roam
1898         dev[0].roam(bssid1)
1899
1900     with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
1901         # This will fail to roam
1902         dev[0].roam(bssid1)
1903
1904     with fail_test(hapd1, 1, "wpa_derive_pmk_r1_name;wpa_ft_process_auth_req"):
1905         # This will fail to roam
1906         dev[0].roam(bssid1)
1907
1908 def test_ap_ft_ap_oom6(dev, apdev):
1909     """WPA2-PSK-FT and AP OOM 6"""
1910     ssid = "test-ft"
1911     passphrase = "12345678"
1912
1913     params = ft_params1(ssid=ssid, passphrase=passphrase)
1914     hapd0 = hostapd.add_ap(apdev[0], params)
1915     bssid0 = hapd0.own_addr()
1916
1917     dev[0].scan_for_bss(bssid0, freq="2412")
1918     with fail_test(hapd0, 1, "wpa_derive_pmk_r0;wpa_auth_derive_ptk_ft"):
1919         dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1920                        scan_freq="2412")
1921     dev[0].request("REMOVE_NETWORK all")
1922     dev[0].wait_disconnected()
1923     with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_auth_derive_ptk_ft"):
1924         dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1925                        scan_freq="2412")
1926     dev[0].request("REMOVE_NETWORK all")
1927     dev[0].wait_disconnected()
1928     with fail_test(hapd0, 1, "wpa_pmk_r1_to_ptk;wpa_auth_derive_ptk_ft"):
1929         dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1930                        scan_freq="2412")
1931
1932 def test_ap_ft_ap_oom7a(dev, apdev):
1933     """WPA2-PSK-FT and AP OOM 7a"""
1934     ssid = "test-ft"
1935     passphrase = "12345678"
1936
1937     params = ft_params1(ssid=ssid, passphrase=passphrase)
1938     params["ieee80211w"] = "2"
1939     hapd0 = hostapd.add_ap(apdev[0], params)
1940     bssid0 = hapd0.own_addr()
1941
1942     dev[0].scan_for_bss(bssid0, freq="2412")
1943     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1944                    ieee80211w="2", scan_freq="2412")
1945
1946     params = ft_params2(ssid=ssid, passphrase=passphrase)
1947     params["ieee80211w"] = "2"
1948     hapd1 = hostapd.add_ap(apdev[1], params)
1949     bssid1 = hapd1.own_addr()
1950     dev[0].scan_for_bss(bssid1, freq="2412")
1951     with alloc_fail(hapd1, 1, "wpa_ft_igtk_subelem"):
1952         # This will fail to roam
1953         dev[0].roam(bssid1)
1954
1955 def test_ap_ft_ap_oom7b(dev, apdev):
1956     """WPA2-PSK-FT and AP OOM 7b"""
1957     ssid = "test-ft"
1958     passphrase = "12345678"
1959
1960     params = ft_params1(ssid=ssid, passphrase=passphrase)
1961     params["ieee80211w"] = "2"
1962     hapd0 = hostapd.add_ap(apdev[0], params)
1963     bssid0 = hapd0.own_addr()
1964
1965     dev[0].scan_for_bss(bssid0, freq="2412")
1966     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1967                    ieee80211w="2", scan_freq="2412")
1968
1969     params = ft_params2(ssid=ssid, passphrase=passphrase)
1970     params["ieee80211w"] = "2"
1971     hapd1 = hostapd.add_ap(apdev[1], params)
1972     bssid1 = hapd1.own_addr()
1973     dev[0].scan_for_bss(bssid1, freq="2412")
1974     with fail_test(hapd1, 1, "aes_wrap;wpa_ft_igtk_subelem"):
1975         # This will fail to roam
1976         dev[0].roam(bssid1)
1977
1978 def test_ap_ft_ap_oom7c(dev, apdev):
1979     """WPA2-PSK-FT and AP OOM 7c"""
1980     ssid = "test-ft"
1981     passphrase = "12345678"
1982
1983     params = ft_params1(ssid=ssid, passphrase=passphrase)
1984     params["ieee80211w"] = "2"
1985     hapd0 = hostapd.add_ap(apdev[0], params)
1986     bssid0 = hapd0.own_addr()
1987
1988     dev[0].scan_for_bss(bssid0, freq="2412")
1989     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1990                    ieee80211w="2", scan_freq="2412")
1991
1992     params = ft_params2(ssid=ssid, passphrase=passphrase)
1993     params["ieee80211w"] = "2"
1994     hapd1 = hostapd.add_ap(apdev[1], params)
1995     bssid1 = hapd1.own_addr()
1996     dev[0].scan_for_bss(bssid1, freq="2412")
1997     with alloc_fail(hapd1, 1, "=wpa_sm_write_assoc_resp_ies"):
1998         # This will fail to roam
1999         dev[0].roam(bssid1)
2000
2001 def test_ap_ft_ap_oom7d(dev, apdev):
2002     """WPA2-PSK-FT and AP OOM 7d"""
2003     ssid = "test-ft"
2004     passphrase = "12345678"
2005
2006     params = ft_params1(ssid=ssid, passphrase=passphrase)
2007     params["ieee80211w"] = "2"
2008     hapd0 = hostapd.add_ap(apdev[0], params)
2009     bssid0 = hapd0.own_addr()
2010
2011     dev[0].scan_for_bss(bssid0, freq="2412")
2012     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2013                    ieee80211w="2", scan_freq="2412")
2014
2015     params = ft_params2(ssid=ssid, passphrase=passphrase)
2016     params["ieee80211w"] = "2"
2017     hapd1 = hostapd.add_ap(apdev[1], params)
2018     bssid1 = hapd1.own_addr()
2019     dev[0].scan_for_bss(bssid1, freq="2412")
2020     with fail_test(hapd1, 1, "wpa_ft_mic;wpa_sm_write_assoc_resp_ies"):
2021         # This will fail to roam
2022         dev[0].roam(bssid1)
2023
2024 def test_ap_ft_ap_oom8(dev, apdev):
2025     """WPA2-PSK-FT and AP OOM 8"""
2026     ssid = "test-ft"
2027     passphrase = "12345678"
2028
2029     params = ft_params1(ssid=ssid, passphrase=passphrase)
2030     params['ft_psk_generate_local'] = "1"
2031     hapd0 = hostapd.add_ap(apdev[0], params)
2032     bssid0 = hapd0.own_addr()
2033
2034     dev[0].scan_for_bss(bssid0, freq="2412")
2035     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2036                    scan_freq="2412")
2037
2038     params = ft_params2(ssid=ssid, passphrase=passphrase)
2039     params['ft_psk_generate_local'] = "1"
2040     hapd1 = hostapd.add_ap(apdev[1], params)
2041     bssid1 = hapd1.own_addr()
2042     dev[0].scan_for_bss(bssid1, freq="2412")
2043     with fail_test(hapd1, 1, "wpa_derive_pmk_r0;wpa_ft_psk_pmk_r1"):
2044         # This will fail to roam
2045         dev[0].roam(bssid1)
2046     with fail_test(hapd1, 1, "wpa_derive_pmk_r1;wpa_ft_psk_pmk_r1"):
2047         # This will fail to roam
2048         dev[0].roam(bssid1)
2049
2050 def test_ap_ft_ap_oom9(dev, apdev):
2051     """WPA2-PSK-FT and AP OOM 9"""
2052     ssid = "test-ft"
2053     passphrase = "12345678"
2054
2055     params = ft_params1(ssid=ssid, passphrase=passphrase)
2056     hapd0 = hostapd.add_ap(apdev[0], params)
2057     bssid0 = hapd0.own_addr()
2058
2059     dev[0].scan_for_bss(bssid0, freq="2412")
2060     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2061                    scan_freq="2412")
2062
2063     params = ft_params2(ssid=ssid, passphrase=passphrase)
2064     hapd1 = hostapd.add_ap(apdev[1], params)
2065     bssid1 = hapd1.own_addr()
2066     dev[0].scan_for_bss(bssid1, freq="2412")
2067
2068     with alloc_fail(hapd0, 1, "wpa_ft_action_rx"):
2069         # This will fail to roam
2070         if "OK" not in dev[0].request("FT_DS " + bssid1):
2071             raise Exception("FT_DS failed")
2072         wait_fail_trigger(hapd0, "GET_ALLOC_FAIL")
2073
2074     with alloc_fail(hapd1, 1, "wpa_ft_rrb_rx_request"):
2075         # This will fail to roam
2076         if "OK" not in dev[0].request("FT_DS " + bssid1):
2077             raise Exception("FT_DS failed")
2078         wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
2079
2080     with alloc_fail(hapd1, 1, "wpa_ft_send_rrb_auth_resp"):
2081         # This will fail to roam
2082         if "OK" not in dev[0].request("FT_DS " + bssid1):
2083             raise Exception("FT_DS failed")
2084         wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
2085
2086 def test_ap_ft_ap_oom10(dev, apdev):
2087     """WPA2-PSK-FT and AP OOM 10"""
2088     ssid = "test-ft"
2089     passphrase = "12345678"
2090
2091     params = ft_params1(ssid=ssid, passphrase=passphrase)
2092     hapd0 = hostapd.add_ap(apdev[0], params)
2093     bssid0 = hapd0.own_addr()
2094
2095     dev[0].scan_for_bss(bssid0, freq="2412")
2096     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2097                    scan_freq="2412")
2098
2099     params = ft_params2(ssid=ssid, passphrase=passphrase)
2100     hapd1 = hostapd.add_ap(apdev[1], params)
2101     bssid1 = hapd1.own_addr()
2102     dev[0].scan_for_bss(bssid1, freq="2412")
2103
2104     with fail_test(hapd0, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_pull"):
2105         # This will fail to roam
2106         if "OK" not in dev[0].request("FT_DS " + bssid1):
2107             raise Exception("FT_DS failed")
2108         wait_fail_trigger(hapd0, "GET_FAIL")
2109
2110     with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_rrb_rx_pull"):
2111         # This will fail to roam
2112         if "OK" not in dev[0].request("FT_DS " + bssid1):
2113             raise Exception("FT_DS failed")
2114         wait_fail_trigger(hapd0, "GET_FAIL")
2115
2116     with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_rrb_rx_pull"):
2117         # This will fail to roam
2118         if "OK" not in dev[0].request("FT_DS " + bssid1):
2119             raise Exception("FT_DS failed")
2120         wait_fail_trigger(hapd0, "GET_FAIL")
2121
2122     with fail_test(hapd1, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_resp"):
2123         # This will fail to roam
2124         if "OK" not in dev[0].request("FT_DS " + bssid1):
2125             raise Exception("FT_DS failed")
2126         wait_fail_trigger(hapd1, "GET_FAIL")
2127
2128 def test_ap_ft_ap_oom11(dev, apdev):
2129     """WPA2-PSK-FT and AP OOM 11"""
2130     ssid = "test-ft"
2131     passphrase = "12345678"
2132
2133     params = ft_params1(ssid=ssid, passphrase=passphrase)
2134     hapd0 = hostapd.add_ap(apdev[0], params)
2135     bssid0 = hapd0.own_addr()
2136
2137     dev[0].scan_for_bss(bssid0, freq="2412")
2138     with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_generate_pmk_r1"):
2139         dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2140                        scan_freq="2412")
2141         wait_fail_trigger(hapd0, "GET_FAIL")
2142
2143     dev[1].scan_for_bss(bssid0, freq="2412")
2144     with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_generate_pmk_r1"):
2145         dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2146                        scan_freq="2412")
2147         wait_fail_trigger(hapd0, "GET_FAIL")
2148
2149 def test_ap_ft_over_ds_proto_ap(dev, apdev):
2150     """WPA2-PSK-FT AP over DS protocol testing for AP processing"""
2151     ssid = "test-ft"
2152     passphrase = "12345678"
2153
2154     params = ft_params1(ssid=ssid, passphrase=passphrase)
2155     hapd0 = hostapd.add_ap(apdev[0], params)
2156     bssid0 = hapd0.own_addr()
2157     _bssid0 = bssid0.replace(':', '')
2158     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2159                    scan_freq="2412")
2160     addr = dev[0].own_addr()
2161     _addr = addr.replace(':', '')
2162
2163     params = ft_params2(ssid=ssid, passphrase=passphrase)
2164     hapd1 = hostapd.add_ap(apdev[1], params)
2165     bssid1 = hapd1.own_addr()
2166     _bssid1 = bssid1.replace(':', '')
2167
2168     hapd0.set("ext_mgmt_frame_handling", "1")
2169     hdr = "d0003a01" + _bssid0 + _addr + _bssid0 + "1000"
2170     valid = "0601" + _addr + _bssid1
2171     tests = ["0601",
2172              "0601" + _addr,
2173              "0601" + _addr + _bssid0,
2174              "0601" + _addr + "ffffffffffff",
2175              "0601" + _bssid0 + _bssid0,
2176              valid,
2177              valid + "01",
2178              valid + "3700",
2179              valid + "3600",
2180              valid + "3603ffffff",
2181              valid + "3603a1b2ff",
2182              valid + "3603a1b2ff" + "3700",
2183              valid + "3603a1b2ff" + "37520000" + 16*"00" + 32*"00" + 32*"00",
2184              valid + "3603a1b2ff" + "37520001" + 16*"00" + 32*"00" + 32*"00",
2185              valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa",
2186              valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "3000",
2187              valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000facff00000100a225368fe0983b5828a37a0acb37f253",
2188              valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac030100000fac0400000100a225368fe0983b5828a37a0acb37f253",
2189              valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000fac0400000100a225368fe0983b5828a37a0acb37f253",
2190              valid + "0001"]
2191     for t in tests:
2192         hapd0.dump_monitor()
2193         if "OK" not in hapd0.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
2194             raise Exception("MGMT_RX_PROCESS failed")
2195
2196     hapd0.set("ext_mgmt_frame_handling", "0")
2197
2198 def test_ap_ft_over_ds_proto(dev, apdev):
2199     """WPA2-PSK-FT AP over DS protocol testing"""
2200     ssid = "test-ft"
2201     passphrase = "12345678"
2202
2203     params = ft_params1(ssid=ssid, passphrase=passphrase)
2204     hapd0 = hostapd.add_ap(apdev[0], params)
2205     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2206                    scan_freq="2412")
2207
2208     # FT Action Response while no FT-over-DS in progress
2209     msg = {}
2210     msg['fc'] = 13 << 4
2211     msg['da'] = dev[0].own_addr()
2212     msg['sa'] = apdev[0]['bssid']
2213     msg['bssid'] = apdev[0]['bssid']
2214     msg['payload'] = binascii.unhexlify("06020200000000000200000004000000")
2215     hapd0.mgmt_tx(msg)
2216
2217     params = ft_params2(ssid=ssid, passphrase=passphrase)
2218     hapd1 = hostapd.add_ap(apdev[1], params)
2219     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
2220     hapd0.set("ext_mgmt_frame_handling", "1")
2221     hapd0.dump_monitor()
2222     dev[0].request("FT_DS " + apdev[1]['bssid'])
2223     for i in range(0, 10):
2224         req = hapd0.mgmt_rx()
2225         if req is None:
2226             raise Exception("MGMT RX wait timed out")
2227         if req['subtype'] == 13:
2228             break
2229         req = None
2230     if not req:
2231         raise Exception("FT Action frame not received")
2232
2233     # FT Action Response for unexpected Target AP
2234     msg['payload'] = binascii.unhexlify("0602020000000000" + "f20000000400" + "0000")
2235     hapd0.mgmt_tx(msg)
2236
2237     # FT Action Response without MDIE
2238     msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000")
2239     hapd0.mgmt_tx(msg)
2240
2241     # FT Action Response without FTIE
2242     msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201")
2243     hapd0.mgmt_tx(msg)
2244
2245     # FT Action Response with FTIE SNonce mismatch
2246     msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201" + "3766000000000000000000000000000000000000c4e67ac1999bebd00ff4ae4d5dcaf87896bb060b469f7c78d49623fb395c3455ffffff6b693fe6f8d8c5dfac0a22344750775bd09437f98b238c9f87b97f790c0106000102030406030a6e6173312e77312e6669")
2247     hapd0.mgmt_tx(msg)
2248
2249 @remote_compatible
2250 def test_ap_ft_rrb(dev, apdev):
2251     """WPA2-PSK-FT RRB protocol testing"""
2252     ssid = "test-ft"
2253     passphrase = "12345678"
2254
2255     params = ft_params1(ssid=ssid, passphrase=passphrase)
2256     hapd0 = hostapd.add_ap(apdev[0], params)
2257
2258     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2259                    scan_freq="2412")
2260
2261     _dst_ll = binascii.unhexlify(apdev[0]['bssid'].replace(':', ''))
2262     _src_ll = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
2263     proto = b'\x89\x0d'
2264     ehdr = _dst_ll + _src_ll + proto
2265
2266     # Too short RRB frame
2267     pkt = ehdr + b'\x01'
2268     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2269         raise Exception("DATA_TEST_FRAME failed")
2270
2271     # RRB discarded frame wikth unrecognized type
2272     pkt = ehdr + b'\x02' + b'\x02' + b'\x01\x00' + _src_ll
2273     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2274         raise Exception("DATA_TEST_FRAME failed")
2275
2276     # RRB frame too short for action frame
2277     pkt = ehdr + b'\x01' + b'\x02' + b'\x01\x00' + _src_ll
2278     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2279         raise Exception("DATA_TEST_FRAME failed")
2280
2281     # Too short RRB frame (not enough room for Action Frame body)
2282     pkt = ehdr + b'\x01' + b'\x02' + b'\x00\x00' + _src_ll
2283     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2284         raise Exception("DATA_TEST_FRAME failed")
2285
2286     # Unexpected Action frame category
2287     pkt = ehdr + b'\x01' + b'\x02' + b'\x0e\x00' + _src_ll + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2288     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2289         raise Exception("DATA_TEST_FRAME failed")
2290
2291     # Unexpected Action in RRB Request
2292     pkt = ehdr + b'\x01' + b'\x00' + b'\x0e\x00' + _src_ll + b'\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2293     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2294         raise Exception("DATA_TEST_FRAME failed")
2295
2296     # Target AP address in RRB Request does not match with own address
2297     pkt = ehdr + b'\x01' + b'\x00' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2298     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2299         raise Exception("DATA_TEST_FRAME failed")
2300
2301     # Not enough room for status code in RRB Response
2302     pkt = ehdr + b'\x01' + b'\x01' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2303     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2304         raise Exception("DATA_TEST_FRAME failed")
2305
2306     # RRB discarded frame with unknown packet_type
2307     pkt = ehdr + b'\x01' + b'\x02' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2308     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2309         raise Exception("DATA_TEST_FRAME failed")
2310
2311     # RRB Response with non-zero status code; no STA match
2312     pkt = ehdr + b'\x01' + b'\x01' + b'\x10\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\xff\xff'
2313     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2314         raise Exception("DATA_TEST_FRAME failed")
2315
2316     # RRB Response with zero status code and extra data; STA match
2317     pkt = ehdr + b'\x01' + b'\x01' + b'\x11\x00' + _src_ll + b'\x06\x01' + _src_ll + b'\x00\x00\x00\x00\x00\x00' + b'\x00\x00' + b'\x00'
2318     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2319         raise Exception("DATA_TEST_FRAME failed")
2320
2321     # Too short PMK-R1 pull
2322     pkt = ehdr + b'\x01' + b'\xc8' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2323     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2324         raise Exception("DATA_TEST_FRAME failed")
2325
2326     # Too short PMK-R1 resp
2327     pkt = ehdr + b'\x01' + b'\xc9' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2328     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2329         raise Exception("DATA_TEST_FRAME failed")
2330
2331     # Too short PMK-R1 push
2332     pkt = ehdr + b'\x01' + b'\xca' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2333     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2334         raise Exception("DATA_TEST_FRAME failed")
2335
2336     # No matching R0KH address found for PMK-R0 pull response
2337     pkt = ehdr + b'\x01' + b'\xc9' + b'\x5a\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + 76 * b'\00'
2338     if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
2339         raise Exception("DATA_TEST_FRAME failed")
2340
2341 @remote_compatible
2342 def test_rsn_ie_proto_ft_psk_sta(dev, apdev):
2343     """RSN element protocol testing for FT-PSK + PMF cases on STA side"""
2344     bssid = apdev[0]['bssid']
2345     ssid = "test-ft"
2346     passphrase = "12345678"
2347
2348     params = ft_params1(ssid=ssid, passphrase=passphrase)
2349     params["ieee80211w"] = "1"
2350     # This is the RSN element used normally by hostapd
2351     params['own_ie_override'] = '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'
2352     hapd = hostapd.add_ap(apdev[0], params)
2353     id = dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2354                         ieee80211w="1", scan_freq="2412",
2355                         pairwise="CCMP", group="CCMP")
2356
2357     tests = [('PMKIDCount field included',
2358               '30160100000fac040100000fac040100000fac048c000000' + '3603a1b201'),
2359              ('Extra IE before RSNE',
2360               'dd0400000000' + '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'),
2361              ('PMKIDCount and Group Management Cipher suite fields included',
2362               '301a0100000fac040100000fac040100000fac048c000000000fac06' + '3603a1b201'),
2363              ('Extra octet after defined fields (future extensibility)',
2364               '301b0100000fac040100000fac040100000fac048c000000000fac0600' + '3603a1b201'),
2365              ('No RSN Capabilities field (PMF disabled in practice)',
2366               '30120100000fac040100000fac040100000fac04' + '3603a1b201')]
2367     for txt, ie in tests:
2368         dev[0].request("DISCONNECT")
2369         dev[0].wait_disconnected()
2370         logger.info(txt)
2371         hapd.disable()
2372         hapd.set('own_ie_override', ie)
2373         hapd.enable()
2374         dev[0].request("BSS_FLUSH 0")
2375         dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
2376         dev[0].select_network(id, freq=2412)
2377         dev[0].wait_connected()
2378
2379     dev[0].request("DISCONNECT")
2380     dev[0].wait_disconnected()
2381
2382     logger.info('Invalid RSNE causing internal hostapd error')
2383     hapd.disable()
2384     hapd.set('own_ie_override', '30130100000fac040100000fac040100000fac048c' + '3603a1b201')
2385     hapd.enable()
2386     dev[0].request("BSS_FLUSH 0")
2387     dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
2388     dev[0].select_network(id, freq=2412)
2389     # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
2390     # complete.
2391     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
2392     if ev is not None:
2393         raise Exception("Unexpected connection")
2394     dev[0].request("DISCONNECT")
2395
2396     logger.info('Unexpected PMKID causing internal hostapd error')
2397     hapd.disable()
2398     hapd.set('own_ie_override', '30260100000fac040100000fac040100000fac048c000100ffffffffffffffffffffffffffffffff' + '3603a1b201')
2399     hapd.enable()
2400     dev[0].request("BSS_FLUSH 0")
2401     dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
2402     dev[0].select_network(id, freq=2412)
2403     # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
2404     # complete.
2405     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
2406     if ev is not None:
2407         raise Exception("Unexpected connection")
2408     dev[0].request("DISCONNECT")
2409
2410 def start_ft(apdev, wpa_ptk_rekey=None):
2411     ssid = "test-ft"
2412     passphrase = "12345678"
2413
2414     params = ft_params1(ssid=ssid, passphrase=passphrase)
2415     if wpa_ptk_rekey:
2416         params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
2417     hapd0 = hostapd.add_ap(apdev[0], params)
2418     params = ft_params2(ssid=ssid, passphrase=passphrase)
2419     if wpa_ptk_rekey:
2420         params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
2421     hapd1 = hostapd.add_ap(apdev[1], params)
2422
2423     return hapd0, hapd1
2424
2425 def check_ptk_rekey(dev, hapd0=None, hapd1=None):
2426     ev = dev.wait_event(["CTRL-EVENT-DISCONNECTED",
2427                          "WPA: Key negotiation completed"], timeout=5)
2428     if ev is None:
2429         raise Exception("No event received after roam")
2430     if "CTRL-EVENT-DISCONNECTED" in ev:
2431         raise Exception("Unexpected disconnection after roam")
2432
2433     if not hapd0 or not hapd1:
2434         return
2435     if dev.get_status_field('bssid') == hapd0.own_addr():
2436         hapd = hapd0
2437     else:
2438         hapd = hapd1
2439     time.sleep(0.1)
2440     hwsim_utils.test_connectivity(dev, hapd)
2441
2442 def test_ap_ft_ptk_rekey(dev, apdev):
2443     """WPA2-PSK-FT PTK rekeying triggered by station after roam"""
2444     hapd0, hapd1 = start_ft(apdev)
2445     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", ptk_rekey="1")
2446     check_ptk_rekey(dev[0], hapd0, hapd1)
2447
2448 def test_ap_ft_ptk_rekey2(dev, apdev):
2449     """WPA2-PSK-FT PTK rekeying triggered by station after one roam"""
2450     hapd0, hapd1 = start_ft(apdev)
2451     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", ptk_rekey="1",
2452               only_one_way=True)
2453     check_ptk_rekey(dev[0], hapd0, hapd1)
2454
2455 def test_ap_ft_ptk_rekey_ap(dev, apdev):
2456     """WPA2-PSK-FT PTK rekeying triggered by AP after roam"""
2457     hapd0, hapd1 = start_ft(apdev, wpa_ptk_rekey=2)
2458     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678")
2459     check_ptk_rekey(dev[0], hapd0, hapd1)
2460
2461 def test_ap_ft_ptk_rekey_ap2(dev, apdev):
2462     """WPA2-PSK-FT PTK rekeying triggered by AP after one roam"""
2463     hapd0, hapd1 = start_ft(apdev, wpa_ptk_rekey=2)
2464     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678",
2465               only_one_way=True)
2466     check_ptk_rekey(dev[0], hapd0, hapd1)
2467
2468 def test_ap_ft_eap_ptk_rekey_ap(dev, apdev):
2469     """WPA2-EAP-FT PTK rekeying triggered by AP"""
2470     generic_ap_ft_eap(dev, apdev, only_one_way=True, wpa_ptk_rekey=2)
2471     check_ptk_rekey(dev[0])
2472
2473 def test_ap_ft_internal_rrb_check(dev, apdev):
2474     """RRB internal delivery only to WPA enabled BSS"""
2475     ssid = "test-ft"
2476     passphrase = "12345678"
2477
2478     radius = hostapd.radius_params()
2479     params = ft_params1(ssid=ssid, passphrase=passphrase)
2480     params['wpa_key_mgmt'] = "FT-EAP"
2481     params["ieee8021x"] = "1"
2482     params = dict(list(radius.items()) + list(params.items()))
2483     hapd = hostapd.add_ap(apdev[0], params)
2484     key_mgmt = hapd.get_config()['key_mgmt']
2485     if key_mgmt.split(' ')[0] != "FT-EAP":
2486         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
2487
2488     hapd1 = hostapd.add_ap(apdev[1], {"ssid": ssid})
2489
2490     # Connect to WPA enabled AP
2491     dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
2492                    eap="GPSK", identity="gpsk user",
2493                    password="abcdefghijklmnop0123456789abcdef",
2494                    scan_freq="2412")
2495
2496     # Try over_ds roaming to non-WPA-enabled AP.
2497     # If hostapd does not check hapd->wpa_auth internally, it will crash now.
2498     dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
2499
2500 def test_ap_ft_extra_ie(dev, apdev):
2501     """WPA2-PSK-FT AP with WPA2-PSK enabled and unexpected MDE"""
2502     ssid = "test-ft"
2503     passphrase = "12345678"
2504
2505     params = ft_params1(ssid=ssid, passphrase=passphrase)
2506     params["wpa_key_mgmt"] = "WPA-PSK FT-PSK"
2507     hapd0 = hostapd.add_ap(apdev[0], params)
2508     dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2509                    scan_freq="2412")
2510     dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
2511                    scan_freq="2412")
2512     try:
2513         # Add Mobility Domain element to test AP validation code.
2514         dev[0].request("VENDOR_ELEM_ADD 13 3603a1b201")
2515         dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
2516                        scan_freq="2412", wait_connect=False)
2517         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2518                                 "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
2519         if ev is None:
2520             raise Exception("No connection result")
2521         if "CTRL-EVENT-CONNECTED" in ev:
2522             raise Exception("Non-FT association accepted with MDE")
2523         if "status_code=43" not in ev:
2524             raise Exception("Unexpected status code: " + ev)
2525         dev[0].request("DISCONNECT")
2526     finally:
2527         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
2528
2529 def test_ap_ft_ric(dev, apdev):
2530     """WPA2-PSK-FT AP and RIC"""
2531     ssid = "test-ft"
2532     passphrase = "12345678"
2533
2534     params = ft_params1(ssid=ssid, passphrase=passphrase)
2535     hapd0 = hostapd.add_ap(apdev[0], params)
2536     params = ft_params2(ssid=ssid, passphrase=passphrase)
2537     hapd1 = hostapd.add_ap(apdev[1], params)
2538
2539     dev[0].set("ric_ies", "")
2540     dev[0].set("ric_ies", '""')
2541     if "FAIL" not in dev[0].request("SET ric_ies q"):
2542         raise Exception("Invalid ric_ies value accepted")
2543
2544     tests = ["3900",
2545              "3900ff04eeeeeeee",
2546              "390400000000",
2547              "390400000000" + "390400000000",
2548              "390400000000" + "dd050050f20202",
2549              "390400000000" + "dd3d0050f2020201" + 55*"00",
2550              "390400000000" + "dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000",
2551              "390401010000" + "dd3d0050f2020201aa3000dc050000000000000000000000000000000000000000000000000000dc050000000000000000000000000000808d5b0028230000"]
2552     for t in tests:
2553         dev[0].set("ric_ies", t)
2554         run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
2555                   test_connectivity=False)
2556         dev[0].request("REMOVE_NETWORK all")
2557         dev[0].wait_disconnected()
2558         dev[0].dump_monitor()
2559
2560 def ie_hex(ies, id):
2561     return binascii.hexlify(struct.pack('BB', id, len(ies[id])) + ies[id]).decode()
2562
2563 def test_ap_ft_reassoc_proto(dev, apdev):
2564     """WPA2-PSK-FT AP Reassociation Request frame parsing"""
2565     ssid = "test-ft"
2566     passphrase = "12345678"
2567
2568     params = ft_params1(ssid=ssid, passphrase=passphrase)
2569     hapd0 = hostapd.add_ap(apdev[0], params)
2570     params = ft_params2(ssid=ssid, passphrase=passphrase)
2571     hapd1 = hostapd.add_ap(apdev[1], params)
2572
2573     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2574                    ieee80211w="1", scan_freq="2412")
2575     if dev[0].get_status_field('bssid') == hapd0.own_addr():
2576         hapd1ap = hapd0
2577         hapd2ap = hapd1
2578     else:
2579         hapd1ap = hapd1
2580         hapd2ap = hapd0
2581
2582     dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
2583     hapd2ap.set("ext_mgmt_frame_handling", "1")
2584     dev[0].request("ROAM " + hapd2ap.own_addr())
2585
2586     while True:
2587         req = hapd2ap.mgmt_rx()
2588         hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2589         if req['subtype'] == 11:
2590             break
2591
2592     while True:
2593         req = hapd2ap.mgmt_rx()
2594         if req['subtype'] == 2:
2595             break
2596         hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2597
2598     # IEEE 802.11 header + fixed fields before IEs
2599     hdr = binascii.hexlify(req['frame'][0:34]).decode()
2600     ies = parse_ie(binascii.hexlify(req['frame'][34:]))
2601     # First elements: SSID, Supported Rates, Extended Supported Rates
2602     ies1 = ie_hex(ies, 0) + ie_hex(ies, 1) + ie_hex(ies, 50)
2603
2604     rsne = ie_hex(ies, 48)
2605     mde = ie_hex(ies, 54)
2606     fte = ie_hex(ies, 55)
2607     tests = []
2608     # RSN: Trying to use FT, but MDIE not included
2609     tests += [rsne]
2610     # RSN: Attempted to use unknown MDIE
2611     tests += [rsne + "3603000000"]
2612     # Invalid RSN pairwise cipher
2613     tests += ["30260100000fac040100000fac030100000fac040000010029208a42cd25c85aa571567dce10dae3"]
2614     # FT: No PMKID in RSNIE
2615     tests += ["30160100000fac040100000fac040100000fac0400000000" + ie_hex(ies, 54)]
2616     # FT: Invalid FTIE
2617     tests += [rsne + mde]
2618     # FT: RIC IE(s) in the frame, but not included in protected IE count
2619     # FT: Failed to parse FT IEs
2620     tests += [rsne + mde + fte + "3900"]
2621     # FT: SNonce mismatch in FTIE
2622     tests += [rsne + mde + "37520000" + 16*"00" + 32*"00" + 32*"00"]
2623     # FT: ANonce mismatch in FTIE
2624     tests += [rsne + mde + fte[0:40] + 32*"00" + fte[104:]]
2625     # FT: No R0KH-ID subelem in FTIE
2626     tests += [rsne + mde + "3752" + fte[4:168]]
2627     # FT: R0KH-ID in FTIE did not match with the current R0KH-ID
2628     tests += [rsne + mde + "3755" + fte[4:168] + "0301ff"]
2629     # FT: No R1KH-ID subelem in FTIE
2630     tests += [rsne + mde + "375e" + fte[4:168] + "030a" + binascii.hexlify(b"nas1.w1.fi").decode()]
2631     # FT: Unknown R1KH-ID used in ReassocReq
2632     tests += [rsne + mde + "3766" + fte[4:168] + "030a" + binascii.hexlify(b"nas1.w1.fi").decode() + "0106000000000000"]
2633     # FT: PMKID in Reassoc Req did not match with the PMKR1Name derived from auth request
2634     tests += [rsne[:-32] + 16*"00" + mde + fte]
2635     # Invalid MIC in FTIE
2636     tests += [rsne + mde + fte[0:8] + 16*"00" + fte[40:]]
2637     for t in tests:
2638         hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + ies1 + t)
2639
2640 def test_ap_ft_reassoc_local_fail(dev, apdev):
2641     """WPA2-PSK-FT AP Reassociation Request frame and local failure"""
2642     ssid = "test-ft"
2643     passphrase = "12345678"
2644
2645     params = ft_params1(ssid=ssid, passphrase=passphrase)
2646     hapd0 = hostapd.add_ap(apdev[0], params)
2647     params = ft_params2(ssid=ssid, passphrase=passphrase)
2648     hapd1 = hostapd.add_ap(apdev[1], params)
2649
2650     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2651                    ieee80211w="1", scan_freq="2412")
2652     if dev[0].get_status_field('bssid') == hapd0.own_addr():
2653         hapd1ap = hapd0
2654         hapd2ap = hapd1
2655     else:
2656         hapd1ap = hapd1
2657         hapd2ap = hapd0
2658
2659     dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
2660     # FT: Failed to calculate MIC
2661     with fail_test(hapd2ap, 1, "wpa_ft_validate_reassoc"):
2662         dev[0].request("ROAM " + hapd2ap.own_addr())
2663         ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
2664         dev[0].request("DISCONNECT")
2665         if ev is None:
2666             raise Exception("Association reject not seen")
2667
2668 def test_ap_ft_reassoc_replay(dev, apdev, params):
2669     """WPA2-PSK-FT AP and replayed Reassociation Request frame"""
2670     capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
2671     ssid = "test-ft"
2672     passphrase = "12345678"
2673
2674     params = ft_params1(ssid=ssid, passphrase=passphrase)
2675     hapd0 = hostapd.add_ap(apdev[0], params)
2676     params = ft_params2(ssid=ssid, passphrase=passphrase)
2677     hapd1 = hostapd.add_ap(apdev[1], params)
2678
2679     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2680                    scan_freq="2412")
2681     if dev[0].get_status_field('bssid') == hapd0.own_addr():
2682         hapd1ap = hapd0
2683         hapd2ap = hapd1
2684     else:
2685         hapd1ap = hapd1
2686         hapd2ap = hapd0
2687
2688     dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
2689     hapd2ap.set("ext_mgmt_frame_handling", "1")
2690     dev[0].dump_monitor()
2691     if "OK" not in dev[0].request("ROAM " + hapd2ap.own_addr()):
2692         raise Exception("ROAM failed")
2693
2694     reassocreq = None
2695     count = 0
2696     while count < 100:
2697         req = hapd2ap.mgmt_rx()
2698         count += 1
2699         hapd2ap.dump_monitor()
2700         hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2701         if req['subtype'] == 2:
2702             reassocreq = req
2703             ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
2704             if ev is None:
2705                 raise Exception("No TX status seen")
2706             cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
2707             if "OK" not in hapd2ap.request(cmd):
2708                 raise Exception("MGMT_TX_STATUS_PROCESS failed")
2709             break
2710     hapd2ap.set("ext_mgmt_frame_handling", "0")
2711     if reassocreq is None:
2712         raise Exception("No Reassociation Request frame seen")
2713     dev[0].wait_connected()
2714     dev[0].dump_monitor()
2715     hapd2ap.dump_monitor()
2716
2717     hwsim_utils.test_connectivity(dev[0], hapd2ap)
2718
2719     logger.info("Replay the last Reassociation Request frame")
2720     hapd2ap.dump_monitor()
2721     hapd2ap.set("ext_mgmt_frame_handling", "1")
2722     hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2723     ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
2724     if ev is None:
2725         raise Exception("No TX status seen")
2726     cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
2727     if "OK" not in hapd2ap.request(cmd):
2728         raise Exception("MGMT_TX_STATUS_PROCESS failed")
2729     hapd2ap.set("ext_mgmt_frame_handling", "0")
2730
2731     try:
2732         hwsim_utils.test_connectivity(dev[0], hapd2ap)
2733         ok = True
2734     except:
2735         ok = False
2736
2737     ap = hapd2ap.own_addr()
2738     sta = dev[0].own_addr()
2739     filt = "wlan.fc.type == 2 && " + \
2740            "wlan.da == " + sta + " && " + \
2741            "wlan.sa == " + ap
2742     fields = ["wlan.ccmp.extiv"]
2743     res = run_tshark(capfile, filt, fields)
2744     vals = res.splitlines()
2745     logger.info("CCMP PN: " + str(vals))
2746     if len(vals) < 2:
2747         raise Exception("Could not find all CCMP protected frames from capture")
2748     if len(set(vals)) < len(vals):
2749         raise Exception("Duplicate CCMP PN used")
2750
2751     if not ok:
2752         raise Exception("The second hwsim connectivity test failed")
2753
2754 def test_ap_ft_psk_file(dev, apdev):
2755     """WPA2-PSK-FT AP with PSK from a file"""
2756     ssid = "test-ft"
2757     passphrase = "12345678"
2758
2759     params = ft_params1a(ssid=ssid, passphrase=passphrase)
2760     params['wpa_psk_file'] = 'hostapd.wpa_psk'
2761     hapd = hostapd.add_ap(apdev[0], params)
2762
2763     dev[1].connect(ssid, psk="very secret",
2764                    key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
2765                    scan_freq="2412", wait_connect=False)
2766     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2767                    ieee80211w="1", scan_freq="2412")
2768     dev[0].request("REMOVE_NETWORK all")
2769     dev[0].wait_disconnected()
2770     dev[0].connect(ssid, psk="very secret", key_mgmt="FT-PSK", proto="WPA2",
2771                    ieee80211w="1", scan_freq="2412")
2772     dev[0].request("REMOVE_NETWORK all")
2773     dev[0].wait_disconnected()
2774     dev[0].connect(ssid, psk="secret passphrase",
2775                    key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
2776                    scan_freq="2412")
2777     dev[2].connect(ssid, psk="another passphrase for all STAs",
2778                    key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
2779                    scan_freq="2412")
2780     ev = dev[1].wait_event(["WPA: 4-Way Handshake failed"], timeout=10)
2781     if ev is None:
2782         raise Exception("Timed out while waiting for failure report")
2783     dev[1].request("REMOVE_NETWORK all")
2784
2785 def test_ap_ft_eap_ap_config_change(dev, apdev):
2786     """WPA2-EAP-FT AP changing from 802.1X-only to FT-only"""
2787     ssid = "test-ft"
2788     passphrase = "12345678"
2789     bssid = apdev[0]['bssid']
2790
2791     radius = hostapd.radius_params()
2792     params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
2793     params['wpa_key_mgmt'] = "WPA-EAP"
2794     params["ieee8021x"] = "1"
2795     params["pmk_r1_push"] = "0"
2796     params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
2797     params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
2798     params["eap_server"] = "0"
2799     params = dict(list(radius.items()) + list(params.items()))
2800     hapd = hostapd.add_ap(apdev[0], params)
2801
2802     dev[0].connect(ssid, key_mgmt="FT-EAP WPA-EAP", proto="WPA2",
2803                    eap="GPSK", identity="gpsk user",
2804                    password="abcdefghijklmnop0123456789abcdef",
2805                    scan_freq="2412")
2806     dev[0].request("DISCONNECT")
2807     dev[0].wait_disconnected()
2808     dev[0].dump_monitor()
2809
2810     hapd.disable()
2811     hapd.set('wpa_key_mgmt', "FT-EAP")
2812     hapd.enable()
2813
2814     dev[0].request("BSS_FLUSH 0")
2815     dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
2816
2817     dev[0].request("RECONNECT")
2818     dev[0].wait_connected()
2819
2820 def test_ap_ft_eap_sha384(dev, apdev):
2821     """WPA2-EAP-FT with SHA384"""
2822     ssid = "test-ft"
2823     passphrase = "12345678"
2824
2825     radius = hostapd.radius_params()
2826     params = ft_params1(ssid=ssid, passphrase=passphrase)
2827     params["ieee80211w"] = "2"
2828     params['wpa_key_mgmt'] = "FT-EAP-SHA384"
2829     params["ieee8021x"] = "1"
2830     params = dict(list(radius.items()) + list(params.items()))
2831     hapd0 = hostapd.add_ap(apdev[0], params)
2832     params = ft_params2(ssid=ssid, passphrase=passphrase)
2833     params["ieee80211w"] = "2"
2834     params['wpa_key_mgmt'] = "FT-EAP-SHA384"
2835     params["ieee8021x"] = "1"
2836     params = dict(list(radius.items()) + list(params.items()))
2837     hapd1 = hostapd.add_ap(apdev[1], params)
2838
2839     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
2840               sha384=True)
2841
2842 def test_ap_ft_eap_sha384_reassoc(dev, apdev):
2843     """WPA2-EAP-FT with SHA384 using REASSOCIATE"""
2844     check_suite_b_192_capa(dev)
2845     ssid = "test-ft"
2846     passphrase = "12345678"
2847
2848     radius = hostapd.radius_params()
2849     params = ft_params1(ssid=ssid, passphrase=passphrase)
2850     params["ieee80211w"] = "2"
2851     params['wpa_key_mgmt'] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384"
2852     params["ieee8021x"] = "1"
2853     params = dict(list(radius.items()) + list(params.items()))
2854     hapd0 = hostapd.add_ap(apdev[0], params)
2855     params = ft_params2(ssid=ssid, passphrase=passphrase)
2856     params["ieee80211w"] = "2"
2857     params['wpa_key_mgmt'] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384"
2858     params["ieee8021x"] = "1"
2859     params = dict(list(radius.items()) + list(params.items()))
2860     hapd1 = hostapd.add_ap(apdev[1], params)
2861
2862     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
2863               sha384=True, also_non_ft=True, roam_with_reassoc=True)
2864
2865 def test_ap_ft_eap_sha384_over_ds(dev, apdev):
2866     """WPA2-EAP-FT with SHA384 over DS"""
2867     ssid = "test-ft"
2868     passphrase = "12345678"
2869
2870     radius = hostapd.radius_params()
2871     params = ft_params1(ssid=ssid, passphrase=passphrase)
2872     params["ieee80211w"] = "2"
2873     params['wpa_key_mgmt'] = "FT-EAP-SHA384"
2874     params["ieee8021x"] = "1"
2875     params = dict(list(radius.items()) + list(params.items()))
2876     hapd0 = hostapd.add_ap(apdev[0], params)
2877     params = ft_params2(ssid=ssid, passphrase=passphrase)
2878     params["ieee80211w"] = "2"
2879     params['wpa_key_mgmt'] = "FT-EAP-SHA384"
2880     params["ieee8021x"] = "1"
2881     params = dict(list(radius.items()) + list(params.items()))
2882     hapd1 = hostapd.add_ap(apdev[1], params)
2883
2884     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
2885               eap=True, sha384=True)
2886
2887 def test_ap_ft_roam_rrm(dev, apdev):
2888     """WPA2-PSK-FT AP and radio measurement request"""
2889     ssid = "test-ft"
2890     passphrase = "12345678"
2891
2892     params = ft_params1(ssid=ssid, passphrase=passphrase)
2893     params["rrm_beacon_report"] = "1"
2894     hapd0 = hostapd.add_ap(apdev[0], params)
2895     bssid0 = hapd0.own_addr()
2896
2897     addr = dev[0].own_addr()
2898     dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2899                    scan_freq="2412")
2900     check_beacon_req(hapd0, addr, 1)
2901
2902     params = ft_params2(ssid=ssid, passphrase=passphrase)
2903     params["rrm_beacon_report"] = "1"
2904     hapd1 = hostapd.add_ap(apdev[1], params)
2905     bssid1 = hapd1.own_addr()
2906
2907     dev[0].scan_for_bss(bssid1, freq=2412)
2908     dev[0].roam(bssid1)
2909     check_beacon_req(hapd1, addr, 2)
2910
2911     dev[0].scan_for_bss(bssid0, freq=2412)
2912     dev[0].roam(bssid0)
2913     check_beacon_req(hapd0, addr, 3)
2914
2915 def test_ap_ft_pmksa_caching(dev, apdev):
2916     """FT-EAP and PMKSA caching for initial mobility domain association"""
2917     ssid = "test-ft"
2918     identity = "gpsk user"
2919
2920     radius = hostapd.radius_params()
2921     params = ft_params1(ssid=ssid)
2922     params['wpa_key_mgmt'] = "FT-EAP"
2923     params["ieee8021x"] = "1"
2924     params["mobility_domain"] = "c3d4"
2925     params = dict(list(radius.items()) + list(params.items()))
2926     hapd = hostapd.add_ap(apdev[0], params)
2927
2928     params = ft_params2(ssid=ssid)
2929     params['wpa_key_mgmt'] = "FT-EAP"
2930     params["ieee8021x"] = "1"
2931     params["mobility_domain"] = "c3d4"
2932     params = dict(list(radius.items()) + list(params.items()))
2933     hapd1 = hostapd.add_ap(apdev[1], params)
2934
2935     run_roams(dev[0], apdev, hapd, hapd1, ssid, None, eap=True,
2936               eap_identity=identity, pmksa_caching=True)
2937
2938 def test_ap_ft_pmksa_caching_sha384(dev, apdev):
2939     """FT-EAP-SHA384 and PMKSA caching for initial mobility domain association"""
2940     ssid = "test-ft"
2941     identity = "gpsk user"
2942
2943     radius = hostapd.radius_params()
2944     params = ft_params1(ssid=ssid)
2945     params['wpa_key_mgmt'] = "FT-EAP-SHA384"
2946     params["ieee8021x"] = "1"
2947     params["mobility_domain"] = "c3d4"
2948     params = dict(list(radius.items()) + list(params.items()))
2949     hapd = hostapd.add_ap(apdev[0], params)
2950
2951     params = ft_params2(ssid=ssid)
2952     params['wpa_key_mgmt'] = "FT-EAP-SHA384"
2953     params["ieee8021x"] = "1"
2954     params["mobility_domain"] = "c3d4"
2955     params = dict(list(radius.items()) + list(params.items()))
2956     hapd1 = hostapd.add_ap(apdev[1], params)
2957
2958     run_roams(dev[0], apdev, hapd, hapd1, ssid, None, eap=True,
2959               eap_identity=identity, pmksa_caching=True, sha384=True)
2960
2961 def test_ap_ft_r1_key_expiration(dev, apdev):
2962     """WPA2-PSK-FT and PMK-R1 expiration"""
2963     ssid = "test-ft"
2964     passphrase = "12345678"
2965
2966     params = ft_params1(ssid=ssid, passphrase=passphrase)
2967     params['r1_max_key_lifetime'] = "2"
2968     hapd0 = hostapd.add_ap(apdev[0], params)
2969     params = ft_params2(ssid=ssid, passphrase=passphrase)
2970     params['r1_max_key_lifetime'] = "2"
2971     hapd1 = hostapd.add_ap(apdev[1], params)
2972
2973     # This succeeds, but results in having to run another PMK-R1 pull before the
2974     # second AP can complete FT protocol.
2975     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, wait_before_roam=4)
2976
2977 def test_ap_ft_r0_key_expiration(dev, apdev):
2978     """WPA2-PSK-FT and PMK-R0 expiration"""
2979     ssid = "test-ft"
2980     passphrase = "12345678"
2981
2982     params = ft_params1(ssid=ssid, passphrase=passphrase)
2983     params['ft_r0_key_lifetime'] = "2"
2984     hapd0 = hostapd.add_ap(apdev[0], params)
2985     params = ft_params2(ssid=ssid, passphrase=passphrase)
2986     params['ft_r0_key_lifetime'] = "2"
2987     hapd1 = hostapd.add_ap(apdev[1], params)
2988
2989     bssid2 = run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
2990                        return_after_initial=True)
2991     time.sleep(4)
2992     dev[0].scan_for_bss(bssid2, freq="2412")
2993     if "OK" not in dev[0].request("ROAM " + bssid2):
2994         raise Exception("ROAM failed")
2995     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2996                             "CTRL-EVENT-AUTH-REJECT",
2997                             "CTRL-EVENT-ASSOC-REJECT"], timeout=5)
2998     dev[0].request("DISCONNECT")
2999     if ev is None or "CTRL-EVENT-AUTH-REJECT" not in ev:
3000         raise Exception("FT protocol failure not reported")
3001     if "status_code=53" not in ev:
3002         raise Exception("Unexpected status in FT protocol failure: " + ev)
3003
3004     # Generate a new PMK-R0
3005     dev[0].dump_monitor()
3006     dev[0].request("RECONNECT")
3007     dev[0].wait_connected()