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