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