]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_ft.py
tests: WPA2-PSK-FT AP Reassociation Request frame processing
[thirdparty/hostap.git] / tests / hwsim / test_ap_ft.py
1 # Fast BSS Transition tests
2 # Copyright (c) 2013-2017, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 from remotehost import remote_compatible
8 import binascii
9 import os
10 import time
11 import logging
12 logger = logging.getLogger()
13 import struct
14
15 import hwsim_utils
16 import hostapd
17 from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger, skip_with_fips, parse_ie
18 from wlantest import Wlantest
19 from test_ap_psk import check_mib, find_wpas_process, read_process_memory, verify_not_present, get_key_locations
20
21 def ft_base_rsn():
22 params = { "wpa": "2",
23 "wpa_key_mgmt": "FT-PSK",
24 "rsn_pairwise": "CCMP" }
25 return params
26
27 def ft_base_mixed():
28 params = { "wpa": "3",
29 "wpa_key_mgmt": "WPA-PSK FT-PSK",
30 "wpa_pairwise": "TKIP",
31 "rsn_pairwise": "CCMP" }
32 return params
33
34 def ft_params(rsn=True, ssid=None, passphrase=None):
35 if rsn:
36 params = ft_base_rsn()
37 else:
38 params = ft_base_mixed()
39 if ssid:
40 params["ssid"] = ssid
41 if passphrase:
42 params["wpa_passphrase"] = passphrase
43
44 params["mobility_domain"] = "a1b2"
45 params["r0_key_lifetime"] = "10000"
46 params["pmk_r1_push"] = "1"
47 params["reassociation_deadline"] = "1000"
48 return params
49
50 def ft_params1a(rsn=True, ssid=None, passphrase=None):
51 params = ft_params(rsn, ssid, passphrase)
52 params['nas_identifier'] = "nas1.w1.fi"
53 params['r1_key_holder'] = "000102030405"
54 return params
55
56 def ft_params1(rsn=True, ssid=None, passphrase=None):
57 params = ft_params1a(rsn, ssid, passphrase)
58 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
59 "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
60 params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
61 return params
62
63 def ft_params2a(rsn=True, ssid=None, passphrase=None):
64 params = ft_params(rsn, ssid, passphrase)
65 params['nas_identifier'] = "nas2.w1.fi"
66 params['r1_key_holder'] = "000102030406"
67 return params
68
69 def ft_params2(rsn=True, ssid=None, passphrase=None):
70 params = ft_params2a(rsn, ssid, passphrase)
71 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
72 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
73 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
74 return params
75
76 def ft_params1_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
77 params = ft_params(rsn, ssid, passphrase)
78 params['nas_identifier'] = "nas1.w1.fi"
79 params['r1_key_holder'] = "000102030405"
80 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
81 "12:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
82 params['r1kh'] = "12:00:00:00:04:00 10:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
83 return params
84
85 def ft_params2_incorrect_rrb_key(rsn=True, ssid=None, passphrase=None):
86 params = ft_params(rsn, ssid, passphrase)
87 params['nas_identifier'] = "nas2.w1.fi"
88 params['r1_key_holder'] = "000102030406"
89 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0ef1",
90 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0ef2" ]
91 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0ef3"
92 return params
93
94 def ft_params2_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
95 params = ft_params(rsn, ssid, passphrase)
96 params['nas_identifier'] = "nas2.w1.fi"
97 params['r1_key_holder'] = "000102030406"
98 params['r0kh'] = [ "12:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
99 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
100 params['r1kh'] = "12:00:00:00:03:00 10:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
101 return params
102
103 def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False,
104 sae=False, eap=False, fail_test=False, roams=1,
105 pairwise_cipher="CCMP", group_cipher="TKIP CCMP", ptk_rekey="0",
106 test_connectivity=True):
107 logger.info("Connect to first AP")
108 if eap:
109 dev.connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
110 eap="GPSK", identity="gpsk user",
111 password="abcdefghijklmnop0123456789abcdef",
112 scan_freq="2412",
113 pairwise=pairwise_cipher, group=group_cipher,
114 wpa_ptk_rekey=ptk_rekey)
115 else:
116 if sae:
117 key_mgmt="FT-SAE"
118 else:
119 key_mgmt="FT-PSK"
120 dev.connect(ssid, psk=passphrase, key_mgmt=key_mgmt, proto="WPA2",
121 ieee80211w="1", scan_freq="2412",
122 pairwise=pairwise_cipher, group=group_cipher,
123 wpa_ptk_rekey=ptk_rekey)
124 if dev.get_status_field('bssid') == apdev[0]['bssid']:
125 ap1 = apdev[0]
126 ap2 = apdev[1]
127 hapd1ap = hapd0
128 hapd2ap = hapd1
129 else:
130 ap1 = apdev[1]
131 ap2 = apdev[0]
132 hapd1ap = hapd1
133 hapd2ap = hapd0
134 if test_connectivity:
135 hwsim_utils.test_connectivity(dev, hapd1ap)
136
137 dev.scan_for_bss(ap2['bssid'], freq="2412")
138
139 for i in range(0, roams):
140 logger.info("Roam to the second AP")
141 if over_ds:
142 dev.roam_over_ds(ap2['bssid'], fail_test=fail_test)
143 else:
144 dev.roam(ap2['bssid'], fail_test=fail_test)
145 if fail_test:
146 return
147 if dev.get_status_field('bssid') != ap2['bssid']:
148 raise Exception("Did not connect to correct AP")
149 if (i == 0 or i == roams - 1) and test_connectivity:
150 hwsim_utils.test_connectivity(dev, hapd2ap)
151
152 logger.info("Roam back to the first AP")
153 if over_ds:
154 dev.roam_over_ds(ap1['bssid'])
155 else:
156 dev.roam(ap1['bssid'])
157 if dev.get_status_field('bssid') != ap1['bssid']:
158 raise Exception("Did not connect to correct AP")
159 if (i == 0 or i == roams - 1) and test_connectivity:
160 hwsim_utils.test_connectivity(dev, hapd1ap)
161
162 def test_ap_ft(dev, apdev):
163 """WPA2-PSK-FT AP"""
164 ssid = "test-ft"
165 passphrase="12345678"
166
167 params = ft_params1(ssid=ssid, passphrase=passphrase)
168 hapd0 = hostapd.add_ap(apdev[0], params)
169 params = ft_params2(ssid=ssid, passphrase=passphrase)
170 hapd1 = hostapd.add_ap(apdev[1], params)
171
172 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
173 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
174 raise Exception("Scan results missing RSN element info")
175
176 def test_ap_ft_local_key_gen(dev, apdev):
177 """WPA2-PSK-FT AP with local key generation (without pull/push)"""
178 ssid = "test-ft"
179 passphrase="12345678"
180
181 params = ft_params1a(ssid=ssid, passphrase=passphrase)
182 params['ft_psk_generate_local'] = "1";
183 del params['pmk_r1_push']
184 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
185 params = ft_params2a(ssid=ssid, passphrase=passphrase)
186 params['ft_psk_generate_local'] = "1";
187 del params['pmk_r1_push']
188 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
189
190 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
191 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
192 raise Exception("Scan results missing RSN element info")
193
194 def test_ap_ft_many(dev, apdev):
195 """WPA2-PSK-FT AP multiple times"""
196 ssid = "test-ft"
197 passphrase="12345678"
198
199 params = ft_params1(ssid=ssid, passphrase=passphrase)
200 hapd0 = hostapd.add_ap(apdev[0], params)
201 params = ft_params2(ssid=ssid, passphrase=passphrase)
202 hapd1 = hostapd.add_ap(apdev[1], params)
203
204 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50)
205
206 def test_ap_ft_mixed(dev, apdev):
207 """WPA2-PSK-FT mixed-mode AP"""
208 ssid = "test-ft-mixed"
209 passphrase="12345678"
210
211 params = ft_params1(rsn=False, ssid=ssid, passphrase=passphrase)
212 hapd = hostapd.add_ap(apdev[0], params)
213 key_mgmt = hapd.get_config()['key_mgmt']
214 vals = key_mgmt.split(' ')
215 if vals[0] != "WPA-PSK" or vals[1] != "FT-PSK":
216 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
217 params = ft_params2(rsn=False, ssid=ssid, passphrase=passphrase)
218 hapd1 = hostapd.add_ap(apdev[1], params)
219
220 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase)
221
222 def test_ap_ft_pmf(dev, apdev):
223 """WPA2-PSK-FT AP with PMF"""
224 ssid = "test-ft"
225 passphrase="12345678"
226
227 params = ft_params1(ssid=ssid, passphrase=passphrase)
228 params["ieee80211w"] = "2"
229 hapd0 = hostapd.add_ap(apdev[0], params)
230 params = ft_params2(ssid=ssid, passphrase=passphrase)
231 params["ieee80211w"] = "2"
232 hapd1 = hostapd.add_ap(apdev[1], params)
233
234 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
235
236 def test_ap_ft_over_ds(dev, apdev):
237 """WPA2-PSK-FT AP over DS"""
238 ssid = "test-ft"
239 passphrase="12345678"
240
241 params = ft_params1(ssid=ssid, passphrase=passphrase)
242 hapd0 = hostapd.add_ap(apdev[0], params)
243 params = ft_params2(ssid=ssid, passphrase=passphrase)
244 hapd1 = hostapd.add_ap(apdev[1], params)
245
246 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
247 check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
248 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4") ])
249
250 def test_ap_ft_over_ds_disabled(dev, apdev):
251 """WPA2-PSK-FT AP over DS disabled"""
252 ssid = "test-ft"
253 passphrase="12345678"
254
255 params = ft_params1(ssid=ssid, passphrase=passphrase)
256 params['ft_over_ds'] = '0'
257 hapd0 = hostapd.add_ap(apdev[0], params)
258 params = ft_params2(ssid=ssid, passphrase=passphrase)
259 params['ft_over_ds'] = '0'
260 hapd1 = hostapd.add_ap(apdev[1], params)
261
262 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
263 fail_test=True)
264
265 def test_ap_ft_over_ds_many(dev, apdev):
266 """WPA2-PSK-FT AP over DS multiple times"""
267 ssid = "test-ft"
268 passphrase="12345678"
269
270 params = ft_params1(ssid=ssid, passphrase=passphrase)
271 hapd0 = hostapd.add_ap(apdev[0], params)
272 params = ft_params2(ssid=ssid, passphrase=passphrase)
273 hapd1 = hostapd.add_ap(apdev[1], params)
274
275 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
276 roams=50)
277
278 @remote_compatible
279 def test_ap_ft_over_ds_unknown_target(dev, apdev):
280 """WPA2-PSK-FT AP"""
281 ssid = "test-ft"
282 passphrase="12345678"
283
284 params = ft_params1(ssid=ssid, passphrase=passphrase)
285 hapd0 = hostapd.add_ap(apdev[0], params)
286
287 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
288 scan_freq="2412")
289 dev[0].roam_over_ds("02:11:22:33:44:55", fail_test=True)
290
291 @remote_compatible
292 def test_ap_ft_over_ds_unexpected(dev, apdev):
293 """WPA2-PSK-FT AP over DS and unexpected response"""
294 ssid = "test-ft"
295 passphrase="12345678"
296
297 params = ft_params1(ssid=ssid, passphrase=passphrase)
298 hapd0 = hostapd.add_ap(apdev[0], params)
299 params = ft_params2(ssid=ssid, passphrase=passphrase)
300 hapd1 = hostapd.add_ap(apdev[1], params)
301
302 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
303 scan_freq="2412")
304 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
305 ap1 = apdev[0]
306 ap2 = apdev[1]
307 hapd1ap = hapd0
308 hapd2ap = hapd1
309 else:
310 ap1 = apdev[1]
311 ap2 = apdev[0]
312 hapd1ap = hapd1
313 hapd2ap = hapd0
314
315 addr = dev[0].own_addr()
316 hapd1ap.set("ext_mgmt_frame_handling", "1")
317 logger.info("Foreign STA address")
318 msg = {}
319 msg['fc'] = 13 << 4
320 msg['da'] = addr
321 msg['sa'] = ap1['bssid']
322 msg['bssid'] = ap1['bssid']
323 msg['payload'] = binascii.unhexlify("06021122334455660102030405060000")
324 hapd1ap.mgmt_tx(msg)
325
326 logger.info("No over-the-DS in progress")
327 msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
328 hapd1ap.mgmt_tx(msg)
329
330 logger.info("Non-zero status code")
331 msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060100")
332 hapd1ap.mgmt_tx(msg)
333
334 hapd1ap.dump_monitor()
335
336 dev[0].scan_for_bss(ap2['bssid'], freq="2412")
337 if "OK" not in dev[0].request("FT_DS " + ap2['bssid']):
338 raise Exception("FT_DS failed")
339
340 req = hapd1ap.mgmt_rx()
341
342 logger.info("Foreign Target AP")
343 msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
344 hapd1ap.mgmt_tx(msg)
345
346 addrs = addr.replace(':', '') + ap2['bssid'].replace(':', '')
347
348 logger.info("No IEs")
349 msg['payload'] = binascii.unhexlify("0602" + addrs + "0000")
350 hapd1ap.mgmt_tx(msg)
351
352 logger.info("Invalid IEs (trigger parsing failure)")
353 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003700")
354 hapd1ap.mgmt_tx(msg)
355
356 logger.info("Too short MDIE")
357 msg['payload'] = binascii.unhexlify("0602" + addrs + "000036021122")
358 hapd1ap.mgmt_tx(msg)
359
360 logger.info("Mobility domain mismatch")
361 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603112201")
362 hapd1ap.mgmt_tx(msg)
363
364 logger.info("No FTIE")
365 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201")
366 hapd1ap.mgmt_tx(msg)
367
368 logger.info("FTIE SNonce mismatch")
369 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "1000000000000000000000000000000000000000000000000000000000000001" + "030a6e6173322e77312e6669")
370 hapd1ap.mgmt_tx(msg)
371
372 logger.info("No R0KH-ID subelem in FTIE")
373 snonce = binascii.hexlify(req['payload'][111:111+32])
374 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137520000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce)
375 hapd1ap.mgmt_tx(msg)
376
377 logger.info("No R0KH-ID subelem mismatch in FTIE")
378 snonce = binascii.hexlify(req['payload'][111:111+32])
379 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a11223344556677889900")
380 hapd1ap.mgmt_tx(msg)
381
382 logger.info("No R1KH-ID subelem in FTIE")
383 r0khid = binascii.hexlify(req['payload'][145:145+10])
384 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid)
385 hapd1ap.mgmt_tx(msg)
386
387 logger.info("No RSNE")
388 r0khid = binascii.hexlify(req['payload'][145:145+10])
389 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137660000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid + "0106000102030405")
390 hapd1ap.mgmt_tx(msg)
391
392 def test_ap_ft_pmf_over_ds(dev, apdev):
393 """WPA2-PSK-FT AP over DS with PMF"""
394 ssid = "test-ft"
395 passphrase="12345678"
396
397 params = ft_params1(ssid=ssid, passphrase=passphrase)
398 params["ieee80211w"] = "2"
399 hapd0 = hostapd.add_ap(apdev[0], params)
400 params = ft_params2(ssid=ssid, passphrase=passphrase)
401 params["ieee80211w"] = "2"
402 hapd1 = hostapd.add_ap(apdev[1], params)
403
404 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
405
406 def test_ap_ft_over_ds_pull(dev, apdev):
407 """WPA2-PSK-FT AP over DS (pull PMK)"""
408 ssid = "test-ft"
409 passphrase="12345678"
410
411 params = ft_params1(ssid=ssid, passphrase=passphrase)
412 params["pmk_r1_push"] = "0"
413 hapd0 = hostapd.add_ap(apdev[0], params)
414 params = ft_params2(ssid=ssid, passphrase=passphrase)
415 params["pmk_r1_push"] = "0"
416 hapd1 = hostapd.add_ap(apdev[1], params)
417
418 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
419
420 def test_ap_ft_sae(dev, apdev):
421 """WPA2-PSK-FT-SAE AP"""
422 if "SAE" not in dev[0].get_capability("auth_alg"):
423 raise HwsimSkip("SAE not supported")
424 ssid = "test-ft"
425 passphrase="12345678"
426
427 params = ft_params1(ssid=ssid, passphrase=passphrase)
428 params['wpa_key_mgmt'] = "FT-SAE"
429 hapd0 = hostapd.add_ap(apdev[0], params)
430 params = ft_params2(ssid=ssid, passphrase=passphrase)
431 params['wpa_key_mgmt'] = "FT-SAE"
432 hapd = hostapd.add_ap(apdev[1], params)
433 key_mgmt = hapd.get_config()['key_mgmt']
434 if key_mgmt.split(' ')[0] != "FT-SAE":
435 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
436
437 dev[0].request("SET sae_groups ")
438 run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True)
439
440 def test_ap_ft_sae_over_ds(dev, apdev):
441 """WPA2-PSK-FT-SAE AP over DS"""
442 if "SAE" not in dev[0].get_capability("auth_alg"):
443 raise HwsimSkip("SAE not supported")
444 ssid = "test-ft"
445 passphrase="12345678"
446
447 params = ft_params1(ssid=ssid, passphrase=passphrase)
448 params['wpa_key_mgmt'] = "FT-SAE"
449 hapd0 = hostapd.add_ap(apdev[0], params)
450 params = ft_params2(ssid=ssid, passphrase=passphrase)
451 params['wpa_key_mgmt'] = "FT-SAE"
452 hapd1 = hostapd.add_ap(apdev[1], params)
453
454 dev[0].request("SET sae_groups ")
455 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, sae=True,
456 over_ds=True)
457
458 def test_ap_ft_eap(dev, apdev):
459 """WPA2-EAP-FT AP"""
460 ssid = "test-ft"
461 passphrase="12345678"
462
463 radius = hostapd.radius_params()
464 params = ft_params1(ssid=ssid, passphrase=passphrase)
465 params['wpa_key_mgmt'] = "FT-EAP"
466 params["ieee8021x"] = "1"
467 params = dict(radius.items() + params.items())
468 hapd = hostapd.add_ap(apdev[0], params)
469 key_mgmt = hapd.get_config()['key_mgmt']
470 if key_mgmt.split(' ')[0] != "FT-EAP":
471 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
472 params = ft_params2(ssid=ssid, passphrase=passphrase)
473 params['wpa_key_mgmt'] = "FT-EAP"
474 params["ieee8021x"] = "1"
475 params = dict(radius.items() + params.items())
476 hapd1 = hostapd.add_ap(apdev[1], params)
477
478 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
479 if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"):
480 raise Exception("Scan results missing RSN element info")
481 check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"),
482 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3") ])
483
484 # Verify EAPOL reauthentication after FT protocol
485 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
486 ap = hapd
487 else:
488 ap = hapd1
489 ap.request("EAPOL_REAUTH " + dev[0].own_addr())
490 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
491 if ev is None:
492 raise Exception("EAP authentication did not start")
493 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
494 if ev is None:
495 raise Exception("EAP authentication did not succeed")
496 time.sleep(0.1)
497 hwsim_utils.test_connectivity(dev[0], ap)
498
499 def test_ap_ft_eap_pull(dev, apdev):
500 """WPA2-EAP-FT AP (pull PMK)"""
501 ssid = "test-ft"
502 passphrase="12345678"
503
504 radius = hostapd.radius_params()
505 params = ft_params1(ssid=ssid, passphrase=passphrase)
506 params['wpa_key_mgmt'] = "FT-EAP"
507 params["ieee8021x"] = "1"
508 params["pmk_r1_push"] = "0"
509 params = dict(radius.items() + params.items())
510 hapd = hostapd.add_ap(apdev[0], params)
511 key_mgmt = hapd.get_config()['key_mgmt']
512 if key_mgmt.split(' ')[0] != "FT-EAP":
513 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
514 params = ft_params2(ssid=ssid, passphrase=passphrase)
515 params['wpa_key_mgmt'] = "FT-EAP"
516 params["ieee8021x"] = "1"
517 params["pmk_r1_push"] = "0"
518 params = dict(radius.items() + params.items())
519 hapd1 = hostapd.add_ap(apdev[1], params)
520
521 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
522
523 @remote_compatible
524 def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
525 """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
526 ssid = "test-ft"
527 passphrase="12345678"
528
529 params = ft_params1(ssid=ssid, passphrase=passphrase)
530 params["ieee80211w"] = "2"
531 hapd0 = hostapd.add_ap(apdev[0], params)
532 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
533 params["ieee80211w"] = "2"
534 hapd1 = hostapd.add_ap(apdev[1], params)
535
536 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
537 fail_test=True)
538
539 @remote_compatible
540 def test_ap_ft_mismatching_rrb_key_pull(dev, apdev):
541 """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
542 ssid = "test-ft"
543 passphrase="12345678"
544
545 params = ft_params1(ssid=ssid, passphrase=passphrase)
546 params["pmk_r1_push"] = "0"
547 hapd0 = hostapd.add_ap(apdev[0], params)
548 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
549 params["pmk_r1_push"] = "0"
550 hapd1 = hostapd.add_ap(apdev[1], params)
551
552 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
553 fail_test=True)
554
555 @remote_compatible
556 def test_ap_ft_mismatching_r0kh_id_pull(dev, apdev):
557 """WPA2-PSK-FT AP over DS with mismatching R0KH-ID (pull)"""
558 ssid = "test-ft"
559 passphrase="12345678"
560
561 params = ft_params1(ssid=ssid, passphrase=passphrase)
562 params["pmk_r1_push"] = "0"
563 params["nas_identifier"] = "nas0.w1.fi"
564 hostapd.add_ap(apdev[0], params)
565 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
566 scan_freq="2412")
567
568 params = ft_params2(ssid=ssid, passphrase=passphrase)
569 params["pmk_r1_push"] = "0"
570 hostapd.add_ap(apdev[1], params)
571
572 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
573 dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
574
575 @remote_compatible
576 def test_ap_ft_mismatching_rrb_r0kh_push(dev, apdev):
577 """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
578 ssid = "test-ft"
579 passphrase="12345678"
580
581 params = ft_params1(ssid=ssid, passphrase=passphrase)
582 params["ieee80211w"] = "2"
583 hapd0 = hostapd.add_ap(apdev[0], params)
584 params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
585 params["ieee80211w"] = "2"
586 hapd1 = hostapd.add_ap(apdev[1], params)
587
588 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
589 fail_test=True)
590
591 @remote_compatible
592 def test_ap_ft_mismatching_rrb_r0kh_pull(dev, apdev):
593 """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
594 ssid = "test-ft"
595 passphrase="12345678"
596
597 params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
598 params["pmk_r1_push"] = "0"
599 hapd0 = hostapd.add_ap(apdev[0], params)
600 params = ft_params2(ssid=ssid, passphrase=passphrase)
601 params["pmk_r1_push"] = "0"
602 hapd1 = hostapd.add_ap(apdev[1], params)
603
604 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
605 fail_test=True)
606
607 def test_ap_ft_mismatching_rrb_key_push_eap(dev, apdev):
608 """WPA2-EAP-FT AP over DS with mismatching RRB key (push)"""
609 ssid = "test-ft"
610 passphrase="12345678"
611
612 radius = hostapd.radius_params()
613 params = ft_params1(ssid=ssid, passphrase=passphrase)
614 params["ieee80211w"] = "2";
615 params['wpa_key_mgmt'] = "FT-EAP"
616 params["ieee8021x"] = "1"
617 params = dict(radius.items() + params.items())
618 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
619 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
620 params["ieee80211w"] = "2";
621 params['wpa_key_mgmt'] = "FT-EAP"
622 params["ieee8021x"] = "1"
623 params = dict(radius.items() + params.items())
624 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
625
626 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
627 fail_test=True, eap=True)
628
629 def test_ap_ft_mismatching_rrb_key_pull_eap(dev, apdev):
630 """WPA2-EAP-FT AP over DS with mismatching RRB key (pull)"""
631 ssid = "test-ft"
632 passphrase="12345678"
633
634 radius = hostapd.radius_params()
635 params = ft_params1(ssid=ssid, passphrase=passphrase)
636 params["pmk_r1_push"] = "0"
637 params['wpa_key_mgmt'] = "FT-EAP"
638 params["ieee8021x"] = "1"
639 params = dict(radius.items() + params.items())
640 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
641 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
642 params["pmk_r1_push"] = "0"
643 params['wpa_key_mgmt'] = "FT-EAP"
644 params["ieee8021x"] = "1"
645 params = dict(radius.items() + params.items())
646 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
647
648 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
649 fail_test=True, eap=True)
650
651 def test_ap_ft_mismatching_r0kh_id_pull_eap(dev, apdev):
652 """WPA2-EAP-FT AP over DS with mismatching R0KH-ID (pull)"""
653 ssid = "test-ft"
654 passphrase="12345678"
655
656 radius = hostapd.radius_params()
657 params = ft_params1(ssid=ssid, passphrase=passphrase)
658 params["pmk_r1_push"] = "0"
659 params["nas_identifier"] = "nas0.w1.fi"
660 params['wpa_key_mgmt'] = "FT-EAP"
661 params["ieee8021x"] = "1"
662 params = dict(radius.items() + params.items())
663 hostapd.add_ap(apdev[0]['ifname'], params)
664 dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
665 eap="GPSK", identity="gpsk user",
666 password="abcdefghijklmnop0123456789abcdef",
667 scan_freq="2412")
668
669 params = ft_params2(ssid=ssid, passphrase=passphrase)
670 params["pmk_r1_push"] = "0"
671 params['wpa_key_mgmt'] = "FT-EAP"
672 params["ieee8021x"] = "1"
673 params = dict(radius.items() + params.items())
674 hostapd.add_ap(apdev[1]['ifname'], params)
675
676 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
677 dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
678
679 def test_ap_ft_mismatching_rrb_r0kh_push_eap(dev, apdev):
680 """WPA2-EAP-FT AP over DS with mismatching R0KH key (push)"""
681 ssid = "test-ft"
682 passphrase="12345678"
683
684 radius = hostapd.radius_params()
685 params = ft_params1(ssid=ssid, passphrase=passphrase)
686 params["ieee80211w"] = "2";
687 params['wpa_key_mgmt'] = "FT-EAP"
688 params["ieee8021x"] = "1"
689 params = dict(radius.items() + params.items())
690 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
691 params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
692 params["ieee80211w"] = "2";
693 params['wpa_key_mgmt'] = "FT-EAP"
694 params["ieee8021x"] = "1"
695 params = dict(radius.items() + params.items())
696 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
697
698 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
699 fail_test=True, eap=True)
700
701 def test_ap_ft_mismatching_rrb_r0kh_pull_eap(dev, apdev):
702 """WPA2-EAP-FT AP over DS with mismatching R0KH key (pull)"""
703 ssid = "test-ft"
704 passphrase="12345678"
705
706 radius = hostapd.radius_params()
707 params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
708 params["pmk_r1_push"] = "0"
709 params['wpa_key_mgmt'] = "FT-EAP"
710 params["ieee8021x"] = "1"
711 params = dict(radius.items() + params.items())
712 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
713 params = ft_params2(ssid=ssid, passphrase=passphrase)
714 params["pmk_r1_push"] = "0"
715 params['wpa_key_mgmt'] = "FT-EAP"
716 params["ieee8021x"] = "1"
717 params = dict(radius.items() + params.items())
718 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
719
720 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
721 fail_test=True, eap=True)
722
723 def test_ap_ft_gtk_rekey(dev, apdev):
724 """WPA2-PSK-FT AP and GTK rekey"""
725 ssid = "test-ft"
726 passphrase="12345678"
727
728 params = ft_params1(ssid=ssid, passphrase=passphrase)
729 params['wpa_group_rekey'] = '1'
730 hapd = hostapd.add_ap(apdev[0], params)
731
732 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
733 ieee80211w="1", scan_freq="2412")
734
735 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
736 if ev is None:
737 raise Exception("GTK rekey timed out after initial association")
738 hwsim_utils.test_connectivity(dev[0], hapd)
739
740 params = ft_params2(ssid=ssid, passphrase=passphrase)
741 params['wpa_group_rekey'] = '1'
742 hapd1 = hostapd.add_ap(apdev[1], params)
743
744 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
745 dev[0].roam(apdev[1]['bssid'])
746 if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
747 raise Exception("Did not connect to correct AP")
748 hwsim_utils.test_connectivity(dev[0], hapd1)
749
750 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
751 if ev is None:
752 raise Exception("GTK rekey timed out after FT protocol")
753 hwsim_utils.test_connectivity(dev[0], hapd1)
754
755 def test_ft_psk_key_lifetime_in_memory(dev, apdev, params):
756 """WPA2-PSK-FT and key lifetime in memory"""
757 ssid = "test-ft"
758 passphrase="04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0"
759 psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d'
760 pmk = binascii.unhexlify(psk)
761 p = ft_params1(ssid=ssid, passphrase=passphrase)
762 hapd0 = hostapd.add_ap(apdev[0], p)
763 p = ft_params2(ssid=ssid, passphrase=passphrase)
764 hapd1 = hostapd.add_ap(apdev[1], p)
765
766 pid = find_wpas_process(dev[0])
767
768 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
769 scan_freq="2412")
770 # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
771 # event has been delivered, so verify that wpa_supplicant has returned to
772 # eloop before reading process memory.
773 time.sleep(1)
774 dev[0].ping()
775
776 buf = read_process_memory(pid, pmk)
777
778 dev[0].request("DISCONNECT")
779 dev[0].wait_disconnected()
780
781 dev[0].relog()
782 pmkr0 = None
783 pmkr1 = None
784 ptk = None
785 gtk = None
786 with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
787 for l in f.readlines():
788 if "FT: PMK-R0 - hexdump" in l:
789 val = l.strip().split(':')[3].replace(' ', '')
790 pmkr0 = binascii.unhexlify(val)
791 if "FT: PMK-R1 - hexdump" in l:
792 val = l.strip().split(':')[3].replace(' ', '')
793 pmkr1 = binascii.unhexlify(val)
794 if "FT: KCK - hexdump" in l:
795 val = l.strip().split(':')[3].replace(' ', '')
796 kck = binascii.unhexlify(val)
797 if "FT: KEK - hexdump" in l:
798 val = l.strip().split(':')[3].replace(' ', '')
799 kek = binascii.unhexlify(val)
800 if "FT: TK - hexdump" in l:
801 val = l.strip().split(':')[3].replace(' ', '')
802 tk = binascii.unhexlify(val)
803 if "WPA: Group Key - hexdump" in l:
804 val = l.strip().split(':')[3].replace(' ', '')
805 gtk = binascii.unhexlify(val)
806 if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk:
807 raise Exception("Could not find keys from debug log")
808 if len(gtk) != 16:
809 raise Exception("Unexpected GTK length")
810
811 logger.info("Checking keys in memory while associated")
812 get_key_locations(buf, pmk, "PMK")
813 get_key_locations(buf, pmkr0, "PMK-R0")
814 get_key_locations(buf, pmkr1, "PMK-R1")
815 if pmk not in buf:
816 raise HwsimSkip("PMK not found while associated")
817 if pmkr0 not in buf:
818 raise HwsimSkip("PMK-R0 not found while associated")
819 if pmkr1 not in buf:
820 raise HwsimSkip("PMK-R1 not found while associated")
821 if kck not in buf:
822 raise Exception("KCK not found while associated")
823 if kek not in buf:
824 raise Exception("KEK not found while associated")
825 if tk in buf:
826 raise Exception("TK found from memory")
827 if gtk in buf:
828 get_key_locations(buf, gtk, "GTK")
829 raise Exception("GTK found from memory")
830
831 logger.info("Checking keys in memory after disassociation")
832 buf = read_process_memory(pid, pmk)
833 get_key_locations(buf, pmk, "PMK")
834 get_key_locations(buf, pmkr0, "PMK-R0")
835 get_key_locations(buf, pmkr1, "PMK-R1")
836
837 # Note: PMK/PSK is still present in network configuration
838
839 fname = os.path.join(params['logdir'],
840 'ft_psk_key_lifetime_in_memory.memctx-')
841 verify_not_present(buf, pmkr0, fname, "PMK-R0")
842 verify_not_present(buf, pmkr1, fname, "PMK-R1")
843 verify_not_present(buf, kck, fname, "KCK")
844 verify_not_present(buf, kek, fname, "KEK")
845 verify_not_present(buf, tk, fname, "TK")
846 verify_not_present(buf, gtk, fname, "GTK")
847
848 dev[0].request("REMOVE_NETWORK all")
849
850 logger.info("Checking keys in memory after network profile removal")
851 buf = read_process_memory(pid, pmk)
852 get_key_locations(buf, pmk, "PMK")
853 get_key_locations(buf, pmkr0, "PMK-R0")
854 get_key_locations(buf, pmkr1, "PMK-R1")
855
856 verify_not_present(buf, pmk, fname, "PMK")
857 verify_not_present(buf, pmkr0, fname, "PMK-R0")
858 verify_not_present(buf, pmkr1, fname, "PMK-R1")
859 verify_not_present(buf, kck, fname, "KCK")
860 verify_not_present(buf, kek, fname, "KEK")
861 verify_not_present(buf, tk, fname, "TK")
862 verify_not_present(buf, gtk, fname, "GTK")
863
864 @remote_compatible
865 def test_ap_ft_invalid_resp(dev, apdev):
866 """WPA2-PSK-FT AP and invalid response IEs"""
867 ssid = "test-ft"
868 passphrase="12345678"
869
870 params = ft_params1(ssid=ssid, passphrase=passphrase)
871 hapd0 = hostapd.add_ap(apdev[0], params)
872 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
873 scan_freq="2412")
874
875 params = ft_params2(ssid=ssid, passphrase=passphrase)
876 hapd1 = hostapd.add_ap(apdev[1], params)
877
878 tests = [
879 # Various IEs for test coverage. The last one is FTIE with invalid
880 # R1KH-ID subelement.
881 "020002000000" + "3800" + "38051122334455" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010100",
882 # FTIE with invalid R0KH-ID subelement (len=0).
883 "020002000000" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010300",
884 # FTIE with invalid R0KH-ID subelement (len=49).
885 "020002000000" + "378500010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001033101020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849",
886 # Invalid RSNE.
887 "020002000000" + "3000",
888 # Required IEs missing from protected IE count.
889 "020002000000" + "3603a1b201" + "375200010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
890 # RIC missing from protected IE count.
891 "020002000000" + "3603a1b201" + "375200020203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
892 # Protected IE missing.
893 "020002000000" + "3603a1b201" + "375200ff0203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900" + "0000" ]
894 for t in tests:
895 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
896 hapd1.set("ext_mgmt_frame_handling", "1")
897 hapd1.dump_monitor()
898 if "OK" not in dev[0].request("ROAM " + apdev[1]['bssid']):
899 raise Exception("ROAM failed")
900 auth = None
901 for i in range(20):
902 msg = hapd1.mgmt_rx()
903 if msg['subtype'] == 11:
904 auth = msg
905 break
906 if not auth:
907 raise Exception("Authentication frame not seen")
908
909 resp = {}
910 resp['fc'] = auth['fc']
911 resp['da'] = auth['sa']
912 resp['sa'] = auth['da']
913 resp['bssid'] = auth['bssid']
914 resp['payload'] = binascii.unhexlify(t)
915 hapd1.mgmt_tx(resp)
916 hapd1.set("ext_mgmt_frame_handling", "0")
917 dev[0].wait_disconnected()
918
919 dev[0].request("RECONNECT")
920 dev[0].wait_connected()
921
922 def test_ap_ft_gcmp_256(dev, apdev):
923 """WPA2-PSK-FT AP with GCMP-256 cipher"""
924 if "GCMP-256" not in dev[0].get_capability("pairwise"):
925 raise HwsimSkip("Cipher GCMP-256 not supported")
926 ssid = "test-ft"
927 passphrase="12345678"
928
929 params = ft_params1(ssid=ssid, passphrase=passphrase)
930 params['rsn_pairwise'] = "GCMP-256"
931 hapd0 = hostapd.add_ap(apdev[0], params)
932 params = ft_params2(ssid=ssid, passphrase=passphrase)
933 params['rsn_pairwise'] = "GCMP-256"
934 hapd1 = hostapd.add_ap(apdev[1], params)
935
936 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
937 pairwise_cipher="GCMP-256", group_cipher="GCMP-256")
938
939 def test_ap_ft_oom(dev, apdev):
940 """WPA2-PSK-FT and OOM"""
941 skip_with_fips(dev[0])
942 ssid = "test-ft"
943 passphrase="12345678"
944
945 params = ft_params1(ssid=ssid, passphrase=passphrase)
946 hapd0 = hostapd.add_ap(apdev[0], params)
947 params = ft_params2(ssid=ssid, passphrase=passphrase)
948 hapd1 = hostapd.add_ap(apdev[1], params)
949
950 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
951 scan_freq="2412")
952 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
953 dst = apdev[1]['bssid']
954 else:
955 dst = apdev[0]['bssid']
956
957 dev[0].scan_for_bss(dst, freq="2412")
958 with alloc_fail(dev[0], 1, "wpa_ft_gen_req_ies"):
959 dev[0].roam(dst)
960 with fail_test(dev[0], 1, "wpa_ft_mic"):
961 dev[0].roam(dst, fail_test=True)
962 with fail_test(dev[0], 1, "os_get_random;wpa_ft_prepare_auth_request"):
963 dev[0].roam(dst, fail_test=True)
964
965 dev[0].request("REMOVE_NETWORK all")
966 with alloc_fail(dev[0], 1, "=sme_update_ft_ies"):
967 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
968 scan_freq="2412")
969
970 def test_ap_ft_ap_oom(dev, apdev):
971 """WPA2-PSK-FT and AP OOM"""
972 ssid = "test-ft"
973 passphrase="12345678"
974
975 params = ft_params1(ssid=ssid, passphrase=passphrase)
976 hapd0 = hostapd.add_ap(apdev[0], params)
977 bssid0 = hapd0.own_addr()
978
979 dev[0].scan_for_bss(bssid0, freq="2412")
980 with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r0"):
981 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
982 scan_freq="2412")
983
984 params = ft_params2(ssid=ssid, passphrase=passphrase)
985 hapd1 = hostapd.add_ap(apdev[1], params)
986 bssid1 = hapd1.own_addr()
987 dev[0].scan_for_bss(bssid1, freq="2412")
988 # This roam will fail due to missing PMK-R0 (OOM prevented storing it)
989 dev[0].roam(bssid1)
990
991 def test_ap_ft_ap_oom2(dev, apdev):
992 """WPA2-PSK-FT and AP OOM 2"""
993 ssid = "test-ft"
994 passphrase="12345678"
995
996 params = ft_params1(ssid=ssid, passphrase=passphrase)
997 hapd0 = hostapd.add_ap(apdev[0], params)
998 bssid0 = hapd0.own_addr()
999
1000 dev[0].scan_for_bss(bssid0, freq="2412")
1001 with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r1"):
1002 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1003 scan_freq="2412")
1004
1005 params = ft_params2(ssid=ssid, passphrase=passphrase)
1006 hapd1 = hostapd.add_ap(apdev[1], params)
1007 bssid1 = hapd1.own_addr()
1008 dev[0].scan_for_bss(bssid1, freq="2412")
1009 dev[0].roam(bssid1)
1010 if dev[0].get_status_field('bssid') != bssid1:
1011 raise Exception("Did not roam to AP1")
1012 # This roam will fail due to missing PMK-R1 (OOM prevented storing it)
1013 dev[0].roam(bssid0)
1014
1015 def test_ap_ft_ap_oom3(dev, apdev):
1016 """WPA2-PSK-FT and AP OOM 3"""
1017 ssid = "test-ft"
1018 passphrase="12345678"
1019
1020 params = ft_params1(ssid=ssid, passphrase=passphrase)
1021 hapd0 = hostapd.add_ap(apdev[0], params)
1022 bssid0 = hapd0.own_addr()
1023
1024 dev[0].scan_for_bss(bssid0, freq="2412")
1025 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1026 scan_freq="2412")
1027
1028 params = ft_params2(ssid=ssid, passphrase=passphrase)
1029 hapd1 = hostapd.add_ap(apdev[1], params)
1030 bssid1 = hapd1.own_addr()
1031 dev[0].scan_for_bss(bssid1, freq="2412")
1032 with alloc_fail(hapd1, 1, "wpa_ft_pull_pmk_r1"):
1033 # This will fail due to not being able to send out PMK-R1 pull request
1034 dev[0].roam(bssid1)
1035
1036 with fail_test(hapd1, 1, "os_get_random;wpa_ft_pull_pmk_r1"):
1037 # This will fail due to not being able to send out PMK-R1 pull request
1038 dev[0].roam(bssid1)
1039
1040 with fail_test(hapd1, 1, "aes_wrap;wpa_ft_pull_pmk_r1"):
1041 # This will fail due to not being able to send out PMK-R1 pull request
1042 dev[0].roam(bssid1)
1043
1044 def test_ap_ft_ap_oom4(dev, apdev):
1045 """WPA2-PSK-FT and AP OOM 4"""
1046 ssid = "test-ft"
1047 passphrase="12345678"
1048
1049 params = ft_params1(ssid=ssid, passphrase=passphrase)
1050 hapd0 = hostapd.add_ap(apdev[0], params)
1051 bssid0 = hapd0.own_addr()
1052
1053 dev[0].scan_for_bss(bssid0, freq="2412")
1054 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1055 scan_freq="2412")
1056
1057 params = ft_params2(ssid=ssid, passphrase=passphrase)
1058 hapd1 = hostapd.add_ap(apdev[1], params)
1059 bssid1 = hapd1.own_addr()
1060 dev[0].scan_for_bss(bssid1, freq="2412")
1061 with alloc_fail(hapd1, 1, "wpa_ft_gtk_subelem"):
1062 dev[0].roam(bssid1)
1063 if dev[0].get_status_field('bssid') != bssid1:
1064 raise Exception("Did not roam to AP1")
1065
1066 with fail_test(hapd0, 1, "wpa_auth_get_seqnum;wpa_ft_gtk_subelem"):
1067 dev[0].roam(bssid0)
1068 if dev[0].get_status_field('bssid') != bssid0:
1069 raise Exception("Did not roam to AP0")
1070
1071 with fail_test(hapd0, 1, "aes_wrap;wpa_ft_gtk_subelem"):
1072 dev[0].roam(bssid1)
1073 if dev[0].get_status_field('bssid') != bssid1:
1074 raise Exception("Did not roam to AP1")
1075
1076 def test_ap_ft_ap_oom5(dev, apdev):
1077 """WPA2-PSK-FT and AP OOM 5"""
1078 ssid = "test-ft"
1079 passphrase="12345678"
1080
1081 params = ft_params1(ssid=ssid, passphrase=passphrase)
1082 hapd0 = hostapd.add_ap(apdev[0], params)
1083 bssid0 = hapd0.own_addr()
1084
1085 dev[0].scan_for_bss(bssid0, freq="2412")
1086 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1087 scan_freq="2412")
1088
1089 params = ft_params2(ssid=ssid, passphrase=passphrase)
1090 hapd1 = hostapd.add_ap(apdev[1], params)
1091 bssid1 = hapd1.own_addr()
1092 dev[0].scan_for_bss(bssid1, freq="2412")
1093 with alloc_fail(hapd1, 1, "=wpa_ft_process_auth_req"):
1094 # This will fail to roam
1095 dev[0].roam(bssid1)
1096
1097 with fail_test(hapd1, 1, "os_get_random;wpa_ft_process_auth_req"):
1098 # This will fail to roam
1099 dev[0].roam(bssid1)
1100
1101 with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
1102 # This will fail to roam
1103 dev[0].roam(bssid1)
1104
1105 with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
1106 # This will fail to roam
1107 dev[0].roam(bssid1)
1108
1109 with fail_test(hapd1, 1, "wpa_derive_pmk_r1_name;wpa_ft_process_auth_req"):
1110 # This will fail to roam
1111 dev[0].roam(bssid1)
1112
1113 def test_ap_ft_ap_oom6(dev, apdev):
1114 """WPA2-PSK-FT and AP OOM 6"""
1115 ssid = "test-ft"
1116 passphrase="12345678"
1117
1118 params = ft_params1(ssid=ssid, passphrase=passphrase)
1119 hapd0 = hostapd.add_ap(apdev[0], params)
1120 bssid0 = hapd0.own_addr()
1121
1122 dev[0].scan_for_bss(bssid0, freq="2412")
1123 with fail_test(hapd0, 1, "wpa_derive_pmk_r0;wpa_auth_derive_ptk_ft"):
1124 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1125 scan_freq="2412")
1126 dev[0].request("REMOVE_NETWORK all")
1127 dev[0].wait_disconnected()
1128 with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_auth_derive_ptk_ft"):
1129 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1130 scan_freq="2412")
1131 dev[0].request("REMOVE_NETWORK all")
1132 dev[0].wait_disconnected()
1133 with fail_test(hapd0, 1, "wpa_pmk_r1_to_ptk;wpa_auth_derive_ptk_ft"):
1134 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1135 scan_freq="2412")
1136
1137 def test_ap_ft_ap_oom7(dev, apdev):
1138 """WPA2-PSK-FT and AP OOM 7"""
1139 ssid = "test-ft"
1140 passphrase="12345678"
1141
1142 params = ft_params1(ssid=ssid, passphrase=passphrase)
1143 params["ieee80211w"] = "2"
1144 hapd0 = hostapd.add_ap(apdev[0], params)
1145 bssid0 = hapd0.own_addr()
1146
1147 dev[0].scan_for_bss(bssid0, freq="2412")
1148 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1149 ieee80211w="2", scan_freq="2412")
1150
1151 params = ft_params2(ssid=ssid, passphrase=passphrase)
1152 params["ieee80211w"] = "2"
1153 hapd1 = hostapd.add_ap(apdev[1], params)
1154 bssid1 = hapd1.own_addr()
1155 dev[0].scan_for_bss(bssid1, freq="2412")
1156 with alloc_fail(hapd1, 1, "wpa_ft_igtk_subelem"):
1157 # This will fail to roam
1158 dev[0].roam(bssid1)
1159 with fail_test(hapd1, 1, "aes_wrap;wpa_ft_igtk_subelem"):
1160 # This will fail to roam
1161 dev[0].roam(bssid1)
1162 with alloc_fail(hapd1, 1, "=wpa_sm_write_assoc_resp_ies"):
1163 # This will fail to roam
1164 dev[0].roam(bssid1)
1165 with fail_test(hapd1, 1, "wpa_ft_mic;wpa_sm_write_assoc_resp_ies"):
1166 # This will fail to roam
1167 dev[0].roam(bssid1)
1168
1169 def test_ap_ft_ap_oom8(dev, apdev):
1170 """WPA2-PSK-FT and AP OOM 8"""
1171 ssid = "test-ft"
1172 passphrase="12345678"
1173
1174 params = ft_params1(ssid=ssid, passphrase=passphrase)
1175 params['ft_psk_generate_local'] = "1";
1176 hapd0 = hostapd.add_ap(apdev[0], params)
1177 bssid0 = hapd0.own_addr()
1178
1179 dev[0].scan_for_bss(bssid0, freq="2412")
1180 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1181 scan_freq="2412")
1182
1183 params = ft_params2(ssid=ssid, passphrase=passphrase)
1184 params['ft_psk_generate_local'] = "1";
1185 hapd1 = hostapd.add_ap(apdev[1], params)
1186 bssid1 = hapd1.own_addr()
1187 dev[0].scan_for_bss(bssid1, freq="2412")
1188 with fail_test(hapd1, 1, "wpa_derive_pmk_r0;wpa_ft_psk_pmk_r1"):
1189 # This will fail to roam
1190 dev[0].roam(bssid1)
1191 with fail_test(hapd1, 1, "wpa_derive_pmk_r1;wpa_ft_psk_pmk_r1"):
1192 # This will fail to roam
1193 dev[0].roam(bssid1)
1194
1195 def test_ap_ft_ap_oom9(dev, apdev):
1196 """WPA2-PSK-FT and AP OOM 9"""
1197 ssid = "test-ft"
1198 passphrase="12345678"
1199
1200 params = ft_params1(ssid=ssid, passphrase=passphrase)
1201 hapd0 = hostapd.add_ap(apdev[0], params)
1202 bssid0 = hapd0.own_addr()
1203
1204 dev[0].scan_for_bss(bssid0, freq="2412")
1205 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1206 scan_freq="2412")
1207
1208 params = ft_params2(ssid=ssid, passphrase=passphrase)
1209 hapd1 = hostapd.add_ap(apdev[1], params)
1210 bssid1 = hapd1.own_addr()
1211 dev[0].scan_for_bss(bssid1, freq="2412")
1212
1213 with alloc_fail(hapd0, 1, "wpa_ft_action_rx"):
1214 # This will fail to roam
1215 if "OK" not in dev[0].request("FT_DS " + bssid1):
1216 raise Exception("FT_DS failed")
1217 wait_fail_trigger(hapd0, "GET_ALLOC_FAIL")
1218
1219 with alloc_fail(hapd1, 1, "wpa_ft_rrb_rx_request"):
1220 # This will fail to roam
1221 if "OK" not in dev[0].request("FT_DS " + bssid1):
1222 raise Exception("FT_DS failed")
1223 wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
1224
1225 with alloc_fail(hapd1, 1, "wpa_ft_send_rrb_auth_resp"):
1226 # This will fail to roam
1227 if "OK" not in dev[0].request("FT_DS " + bssid1):
1228 raise Exception("FT_DS failed")
1229 wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
1230
1231 def test_ap_ft_ap_oom10(dev, apdev):
1232 """WPA2-PSK-FT and AP OOM 10"""
1233 ssid = "test-ft"
1234 passphrase="12345678"
1235
1236 params = ft_params1(ssid=ssid, passphrase=passphrase)
1237 hapd0 = hostapd.add_ap(apdev[0], params)
1238 bssid0 = hapd0.own_addr()
1239
1240 dev[0].scan_for_bss(bssid0, freq="2412")
1241 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1242 scan_freq="2412")
1243
1244 params = ft_params2(ssid=ssid, passphrase=passphrase)
1245 hapd1 = hostapd.add_ap(apdev[1], params)
1246 bssid1 = hapd1.own_addr()
1247 dev[0].scan_for_bss(bssid1, freq="2412")
1248
1249 with fail_test(hapd0, 1, "aes_unwrap;wpa_ft_rrb_rx_pull"):
1250 # This will fail to roam
1251 if "OK" not in dev[0].request("FT_DS " + bssid1):
1252 raise Exception("FT_DS failed")
1253 wait_fail_trigger(hapd0, "GET_FAIL")
1254
1255 with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_rrb_rx_pull"):
1256 # This will fail to roam
1257 if "OK" not in dev[0].request("FT_DS " + bssid1):
1258 raise Exception("FT_DS failed")
1259 wait_fail_trigger(hapd0, "GET_FAIL")
1260
1261 with fail_test(hapd0, 1, "aes_wrap;wpa_ft_rrb_rx_pull"):
1262 # This will fail to roam
1263 if "OK" not in dev[0].request("FT_DS " + bssid1):
1264 raise Exception("FT_DS failed")
1265 wait_fail_trigger(hapd0, "GET_FAIL")
1266
1267 with fail_test(hapd1, 1, "aes_unwrap;wpa_ft_rrb_rx_resp"):
1268 # This will fail to roam
1269 if "OK" not in dev[0].request("FT_DS " + bssid1):
1270 raise Exception("FT_DS failed")
1271 wait_fail_trigger(hapd1, "GET_FAIL")
1272
1273 def test_ap_ft_ap_oom11(dev, apdev):
1274 """WPA2-PSK-FT and AP OOM 11"""
1275 ssid = "test-ft"
1276 passphrase="12345678"
1277
1278 params = ft_params1(ssid=ssid, passphrase=passphrase)
1279 hapd0 = hostapd.add_ap(apdev[0], params)
1280 bssid0 = hapd0.own_addr()
1281
1282 dev[0].scan_for_bss(bssid0, freq="2412")
1283 with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_generate_pmk_r1"):
1284 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1285 scan_freq="2412")
1286 wait_fail_trigger(hapd0, "GET_FAIL")
1287
1288 dev[1].scan_for_bss(bssid0, freq="2412")
1289 with fail_test(hapd0, 1, "aes_wrap;wpa_ft_generate_pmk_r1"):
1290 dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1291 scan_freq="2412")
1292 wait_fail_trigger(hapd0, "GET_FAIL")
1293
1294 def test_ap_ft_over_ds_proto_ap(dev, apdev):
1295 """WPA2-PSK-FT AP over DS protocol testing for AP processing"""
1296 ssid = "test-ft"
1297 passphrase="12345678"
1298
1299 params = ft_params1(ssid=ssid, passphrase=passphrase)
1300 hapd0 = hostapd.add_ap(apdev[0], params)
1301 bssid0 = hapd0.own_addr()
1302 _bssid0 = bssid0.replace(':', '')
1303 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1304 scan_freq="2412")
1305 addr = dev[0].own_addr()
1306 _addr = addr.replace(':', '')
1307
1308 params = ft_params2(ssid=ssid, passphrase=passphrase)
1309 hapd1 = hostapd.add_ap(apdev[1], params)
1310 bssid1 = hapd1.own_addr()
1311 _bssid1 = bssid1.replace(':', '')
1312
1313 hapd0.set("ext_mgmt_frame_handling", "1")
1314 hdr = "d0003a01" + _bssid0 + _addr + _bssid0 + "1000"
1315 valid = "0601" + _addr + _bssid1
1316 tests = [ "0601",
1317 "0601" + _addr,
1318 "0601" + _addr + _bssid0,
1319 "0601" + _addr + "ffffffffffff",
1320 "0601" + _bssid0 + _bssid0,
1321 valid,
1322 valid + "01",
1323 valid + "3700",
1324 valid + "3600",
1325 valid + "3603ffffff",
1326 valid + "3603a1b2ff",
1327 valid + "3603a1b2ff" + "3700",
1328 valid + "3603a1b2ff" + "37520000" + 16*"00" + 32*"00" + 32*"00",
1329 valid + "3603a1b2ff" + "37520001" + 16*"00" + 32*"00" + 32*"00",
1330 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa",
1331 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "3000",
1332 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000facff00000100a225368fe0983b5828a37a0acb37f253",
1333 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac030100000fac0400000100a225368fe0983b5828a37a0acb37f253",
1334 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000fac0400000100a225368fe0983b5828a37a0acb37f253",
1335 valid + "0001" ]
1336 for t in tests:
1337 hapd0.dump_monitor()
1338 if "OK" not in hapd0.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
1339 raise Exception("MGMT_RX_PROCESS failed")
1340
1341 hapd0.set("ext_mgmt_frame_handling", "0")
1342
1343 def test_ap_ft_over_ds_proto(dev, apdev):
1344 """WPA2-PSK-FT AP over DS protocol testing"""
1345 ssid = "test-ft"
1346 passphrase="12345678"
1347
1348 params = ft_params1(ssid=ssid, passphrase=passphrase)
1349 hapd0 = hostapd.add_ap(apdev[0], params)
1350 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1351 scan_freq="2412")
1352
1353 # FT Action Response while no FT-over-DS in progress
1354 msg = {}
1355 msg['fc'] = 13 << 4
1356 msg['da'] = dev[0].own_addr()
1357 msg['sa'] = apdev[0]['bssid']
1358 msg['bssid'] = apdev[0]['bssid']
1359 msg['payload'] = binascii.unhexlify("06020200000000000200000004000000")
1360 hapd0.mgmt_tx(msg)
1361
1362 params = ft_params2(ssid=ssid, passphrase=passphrase)
1363 hapd1 = hostapd.add_ap(apdev[1], params)
1364 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1365 hapd0.set("ext_mgmt_frame_handling", "1")
1366 hapd0.dump_monitor()
1367 dev[0].request("FT_DS " + apdev[1]['bssid'])
1368 for i in range(0, 10):
1369 req = hapd0.mgmt_rx()
1370 if req is None:
1371 raise Exception("MGMT RX wait timed out")
1372 if req['subtype'] == 13:
1373 break
1374 req = None
1375 if not req:
1376 raise Exception("FT Action frame not received")
1377
1378 # FT Action Response for unexpected Target AP
1379 msg['payload'] = binascii.unhexlify("0602020000000000" + "f20000000400" + "0000")
1380 hapd0.mgmt_tx(msg)
1381
1382 # FT Action Response without MDIE
1383 msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000")
1384 hapd0.mgmt_tx(msg)
1385
1386 # FT Action Response without FTIE
1387 msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201")
1388 hapd0.mgmt_tx(msg)
1389
1390 # FT Action Response with FTIE SNonce mismatch
1391 msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201" + "3766000000000000000000000000000000000000c4e67ac1999bebd00ff4ae4d5dcaf87896bb060b469f7c78d49623fb395c3455ffffff6b693fe6f8d8c5dfac0a22344750775bd09437f98b238c9f87b97f790c0106000102030406030a6e6173312e77312e6669")
1392 hapd0.mgmt_tx(msg)
1393
1394 @remote_compatible
1395 def test_ap_ft_rrb(dev, apdev):
1396 """WPA2-PSK-FT RRB protocol testing"""
1397 ssid = "test-ft"
1398 passphrase="12345678"
1399
1400 params = ft_params1(ssid=ssid, passphrase=passphrase)
1401 hapd0 = hostapd.add_ap(apdev[0], params)
1402
1403 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1404 scan_freq="2412")
1405
1406 _dst_ll = binascii.unhexlify(apdev[0]['bssid'].replace(':',''))
1407 _src_ll = binascii.unhexlify(dev[0].own_addr().replace(':',''))
1408 proto = '\x89\x0d'
1409 ehdr = _dst_ll + _src_ll + proto
1410
1411 # Too short RRB frame
1412 pkt = ehdr + '\x01'
1413 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1414 raise Exception("DATA_TEST_FRAME failed")
1415
1416 # RRB discarded frame wikth unrecognized type
1417 pkt = ehdr + '\x02' + '\x02' + '\x01\x00' + _src_ll
1418 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1419 raise Exception("DATA_TEST_FRAME failed")
1420
1421 # RRB frame too short for action frame
1422 pkt = ehdr + '\x01' + '\x02' + '\x01\x00' + _src_ll
1423 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1424 raise Exception("DATA_TEST_FRAME failed")
1425
1426 # Too short RRB frame (not enough room for Action Frame body)
1427 pkt = ehdr + '\x01' + '\x02' + '\x00\x00' + _src_ll
1428 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1429 raise Exception("DATA_TEST_FRAME failed")
1430
1431 # Unexpected Action frame category
1432 pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1433 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1434 raise Exception("DATA_TEST_FRAME failed")
1435
1436 # Unexpected Action in RRB Request
1437 pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1438 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1439 raise Exception("DATA_TEST_FRAME failed")
1440
1441 # Target AP address in RRB Request does not match with own address
1442 pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1443 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1444 raise Exception("DATA_TEST_FRAME failed")
1445
1446 # Not enough room for status code in RRB Response
1447 pkt = ehdr + '\x01' + '\x01' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1448 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1449 raise Exception("DATA_TEST_FRAME failed")
1450
1451 # RRB discarded frame with unknown packet_type
1452 pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1453 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1454 raise Exception("DATA_TEST_FRAME failed")
1455
1456 # RRB Response with non-zero status code; no STA match
1457 pkt = ehdr + '\x01' + '\x01' + '\x10\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + '\xff\xff'
1458 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1459 raise Exception("DATA_TEST_FRAME failed")
1460
1461 # RRB Response with zero status code and extra data; STA match
1462 pkt = ehdr + '\x01' + '\x01' + '\x11\x00' + _src_ll + '\x06\x01' + _src_ll + '\x00\x00\x00\x00\x00\x00' + '\x00\x00' + '\x00'
1463 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1464 raise Exception("DATA_TEST_FRAME failed")
1465
1466 # Too short PMK-R1 pull
1467 pkt = ehdr + '\x01' + '\xc8' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1468 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1469 raise Exception("DATA_TEST_FRAME failed")
1470
1471 # Too short PMK-R1 resp
1472 pkt = ehdr + '\x01' + '\xc9' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1473 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1474 raise Exception("DATA_TEST_FRAME failed")
1475
1476 # Too short PMK-R1 push
1477 pkt = ehdr + '\x01' + '\xca' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1478 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1479 raise Exception("DATA_TEST_FRAME failed")
1480
1481 # No matching R0KH address found for PMK-R0 pull response
1482 pkt = ehdr + '\x01' + '\xc9' + '\x5a\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + 76*'\00'
1483 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
1484 raise Exception("DATA_TEST_FRAME failed")
1485
1486 @remote_compatible
1487 def test_rsn_ie_proto_ft_psk_sta(dev, apdev):
1488 """RSN element protocol testing for FT-PSK + PMF cases on STA side"""
1489 bssid = apdev[0]['bssid']
1490 ssid = "test-ft"
1491 passphrase="12345678"
1492
1493 params = ft_params1(ssid=ssid, passphrase=passphrase)
1494 params["ieee80211w"] = "1"
1495 # This is the RSN element used normally by hostapd
1496 params['own_ie_override'] = '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'
1497 hapd = hostapd.add_ap(apdev[0], params)
1498 id = dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1499 ieee80211w="1", scan_freq="2412",
1500 pairwise="CCMP", group="CCMP")
1501
1502 tests = [ ('PMKIDCount field included',
1503 '30160100000fac040100000fac040100000fac048c000000' + '3603a1b201'),
1504 ('Extra IE before RSNE',
1505 'dd0400000000' + '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'),
1506 ('PMKIDCount and Group Management Cipher suite fields included',
1507 '301a0100000fac040100000fac040100000fac048c000000000fac06' + '3603a1b201'),
1508 ('Extra octet after defined fields (future extensibility)',
1509 '301b0100000fac040100000fac040100000fac048c000000000fac0600' + '3603a1b201'),
1510 ('No RSN Capabilities field (PMF disabled in practice)',
1511 '30120100000fac040100000fac040100000fac04' + '3603a1b201') ]
1512 for txt,ie in tests:
1513 dev[0].request("DISCONNECT")
1514 dev[0].wait_disconnected()
1515 logger.info(txt)
1516 hapd.disable()
1517 hapd.set('own_ie_override', ie)
1518 hapd.enable()
1519 dev[0].request("BSS_FLUSH 0")
1520 dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
1521 dev[0].select_network(id, freq=2412)
1522 dev[0].wait_connected()
1523
1524 dev[0].request("DISCONNECT")
1525 dev[0].wait_disconnected()
1526
1527 logger.info('Invalid RSNE causing internal hostapd error')
1528 hapd.disable()
1529 hapd.set('own_ie_override', '30130100000fac040100000fac040100000fac048c' + '3603a1b201')
1530 hapd.enable()
1531 dev[0].request("BSS_FLUSH 0")
1532 dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
1533 dev[0].select_network(id, freq=2412)
1534 # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
1535 # complete.
1536 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1537 if ev is not None:
1538 raise Exception("Unexpected connection")
1539 dev[0].request("DISCONNECT")
1540
1541 logger.info('Unexpected PMKID causing internal hostapd error')
1542 hapd.disable()
1543 hapd.set('own_ie_override', '30260100000fac040100000fac040100000fac048c000100ffffffffffffffffffffffffffffffff' + '3603a1b201')
1544 hapd.enable()
1545 dev[0].request("BSS_FLUSH 0")
1546 dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
1547 dev[0].select_network(id, freq=2412)
1548 # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
1549 # complete.
1550 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1551 if ev is not None:
1552 raise Exception("Unexpected connection")
1553 dev[0].request("DISCONNECT")
1554
1555 def test_ap_ft_ptk_rekey(dev, apdev):
1556 """WPA2-PSK-FT PTK rekeying triggered by station after roam"""
1557 ssid = "test-ft"
1558 passphrase="12345678"
1559
1560 params = ft_params1(ssid=ssid, passphrase=passphrase)
1561 hapd0 = hostapd.add_ap(apdev[0], params)
1562 params = ft_params2(ssid=ssid, passphrase=passphrase)
1563 hapd1 = hostapd.add_ap(apdev[1], params)
1564
1565 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ptk_rekey="1")
1566
1567 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
1568 "WPA: Key negotiation completed"], timeout=5)
1569 if ev is None:
1570 raise Exception("No event received after roam")
1571 if "CTRL-EVENT-DISCONNECTED" in ev:
1572 raise Exception("Unexpected disconnection after roam")
1573
1574 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
1575 hapd = hapd0
1576 else:
1577 hapd = hapd1
1578 hwsim_utils.test_connectivity(dev[0], hapd)
1579
1580 def test_ap_ft_ptk_rekey_ap(dev, apdev):
1581 """WPA2-PSK-FT PTK rekeying triggered by AP after roam"""
1582 ssid = "test-ft"
1583 passphrase="12345678"
1584
1585 params = ft_params1(ssid=ssid, passphrase=passphrase)
1586 params['wpa_ptk_rekey'] = '2'
1587 hapd0 = hostapd.add_ap(apdev[0], params)
1588 params = ft_params2(ssid=ssid, passphrase=passphrase)
1589 params['wpa_ptk_rekey'] = '2'
1590 hapd1 = hostapd.add_ap(apdev[1], params)
1591
1592 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
1593
1594 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
1595 "WPA: Key negotiation completed"], timeout=5)
1596 if ev is None:
1597 raise Exception("No event received after roam")
1598 if "CTRL-EVENT-DISCONNECTED" in ev:
1599 raise Exception("Unexpected disconnection after roam")
1600
1601 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
1602 hapd = hapd0
1603 else:
1604 hapd = hapd1
1605 hwsim_utils.test_connectivity(dev[0], hapd)
1606
1607 def test_ap_ft_internal_rrb_check(dev, apdev):
1608 """RRB internal delivery only to WPA enabled BSS"""
1609 ssid = "test-ft"
1610 passphrase="12345678"
1611
1612 radius = hostapd.radius_params()
1613 params = ft_params1(ssid=ssid, passphrase=passphrase)
1614 params['wpa_key_mgmt'] = "FT-EAP"
1615 params["ieee8021x"] = "1"
1616 params = dict(radius.items() + params.items())
1617 hapd = hostapd.add_ap(apdev[0], params)
1618 key_mgmt = hapd.get_config()['key_mgmt']
1619 if key_mgmt.split(' ')[0] != "FT-EAP":
1620 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1621
1622 hapd1 = hostapd.add_ap(apdev[1], { "ssid" : ssid })
1623
1624 # Connect to WPA enabled AP
1625 dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
1626 eap="GPSK", identity="gpsk user",
1627 password="abcdefghijklmnop0123456789abcdef",
1628 scan_freq="2412")
1629
1630 # Try over_ds roaming to non-WPA-enabled AP.
1631 # If hostapd does not check hapd->wpa_auth internally, it will crash now.
1632 dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
1633
1634 def test_ap_ft_extra_ie(dev, apdev):
1635 """WPA2-PSK-FT AP with WPA2-PSK enabled and unexpected MDE"""
1636 ssid = "test-ft"
1637 passphrase="12345678"
1638
1639 params = ft_params1(ssid=ssid, passphrase=passphrase)
1640 params["wpa_key_mgmt"] = "WPA-PSK FT-PSK"
1641 hapd0 = hostapd.add_ap(apdev[0], params)
1642 dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1643 scan_freq="2412")
1644 dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
1645 scan_freq="2412")
1646 try:
1647 # Add Mobility Domain element to test AP validation code.
1648 dev[0].request("VENDOR_ELEM_ADD 13 3603a1b201")
1649 dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
1650 scan_freq="2412", wait_connect=False)
1651 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1652 "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
1653 if ev is None:
1654 raise Exception("No connection result")
1655 if "CTRL-EVENT-CONNECTED" in ev:
1656 raise Exception("Non-FT association accepted with MDE")
1657 if "status_code=43" not in ev:
1658 raise Exception("Unexpected status code: " + ev)
1659 dev[0].request("DISCONNECT")
1660 finally:
1661 dev[0].request("VENDOR_ELEM_REMOVE 13 *")
1662
1663 def test_ap_ft_ric(dev, apdev):
1664 """WPA2-PSK-FT AP and RIC"""
1665 ssid = "test-ft"
1666 passphrase="12345678"
1667
1668 params = ft_params1(ssid=ssid, passphrase=passphrase)
1669 hapd0 = hostapd.add_ap(apdev[0], params)
1670 params = ft_params2(ssid=ssid, passphrase=passphrase)
1671 hapd1 = hostapd.add_ap(apdev[1], params)
1672
1673 dev[0].set("ric_ies", "")
1674 dev[0].set("ric_ies", '""')
1675 if "FAIL" not in dev[0].request("SET ric_ies q"):
1676 raise Exception("Invalid ric_ies value accepted")
1677
1678 tests = [ "3900",
1679 "3900ff04eeeeeeee",
1680 "390400000000",
1681 "390400000000" + "390400000000",
1682 "390400000000" + "dd050050f20202",
1683 "390400000000" + "dd3d0050f2020201" + 55*"00",
1684 "390400000000" + "dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000",
1685 "390401010000" + "dd3d0050f2020201aa3000dc050000000000000000000000000000000000000000000000000000dc050000000000000000000000000000808d5b0028230000" ]
1686 for t in tests:
1687 dev[0].set("ric_ies", t)
1688 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
1689 test_connectivity=False)
1690 dev[0].request("REMOVE_NETWORK all")
1691 dev[0].wait_disconnected()
1692 dev[0].dump_monitor()
1693
1694 def ie_hex(ies, id):
1695 return binascii.hexlify(struct.pack('BB', id, len(ies[id])) + ies[id])
1696
1697 def test_ap_ft_reassoc_proto(dev, apdev):
1698 """WPA2-PSK-FT AP Reassociation Request frame parsing"""
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 params = ft_params2(ssid=ssid, passphrase=passphrase)
1705 hapd1 = hostapd.add_ap(apdev[1], params)
1706
1707 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1708 ieee80211w="1", scan_freq="2412")
1709 if dev[0].get_status_field('bssid') == hapd0.own_addr():
1710 hapd1ap = hapd0
1711 hapd2ap = hapd1
1712 else:
1713 hapd1ap = hapd1
1714 hapd2ap = hapd0
1715
1716 dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
1717 hapd2ap.set("ext_mgmt_frame_handling", "1")
1718 dev[0].request("ROAM " + hapd2ap.own_addr())
1719
1720 while True:
1721 req = hapd2ap.mgmt_rx()
1722 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
1723 if req['subtype'] == 11:
1724 break
1725
1726 while True:
1727 req = hapd2ap.mgmt_rx()
1728 if req['subtype'] == 2:
1729 break
1730 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
1731
1732 # IEEE 802.11 header + fixed fields before IEs
1733 hdr = binascii.hexlify(req['frame'][0:34])
1734 ies = parse_ie(binascii.hexlify(req['frame'][34:]))
1735 # First elements: SSID, Supported Rates, Extended Supported Rates
1736 ies1 = ie_hex(ies, 0) + ie_hex(ies, 1) + ie_hex(ies, 50)
1737
1738 rsne = ie_hex(ies, 48)
1739 mde = ie_hex(ies, 54)
1740 fte = ie_hex(ies, 55)
1741 tests = [ ]
1742 # RSN: Trying to use FT, but MDIE not included
1743 tests += [ rsne ]
1744 # RSN: Attempted to use unknown MDIE
1745 tests += [ rsne + "3603000000" ]
1746 # Invalid RSN pairwise cipher
1747 tests += [ "30260100000fac040100000fac030100000fac040000010029208a42cd25c85aa571567dce10dae3" ]
1748 # FT: No PMKID in RSNIE
1749 tests += [ "30160100000fac040100000fac040100000fac0400000000" + ie_hex(ies, 54) ]
1750 # FT: Invalid FTIE
1751 tests += [ rsne + mde ]
1752 # FT: RIC IE(s) in the frame, but not included in protected IE count
1753 # FT: Failed to parse FT IEs
1754 tests += [ rsne + mde + fte + "3900" ]
1755 # FT: SNonce mismatch in FTIE
1756 tests += [ rsne + mde + "37520000" + 16*"00" + 32*"00" + 32*"00" ]
1757 # FT: ANonce mismatch in FTIE
1758 tests += [ rsne + mde + fte[0:40] + 32*"00" + fte[104:] ]
1759 # FT: No R0KH-ID subelem in FTIE
1760 tests += [ rsne + mde + "3752" + fte[4:168] ]
1761 # FT: R0KH-ID in FTIE did not match with the current R0KH-ID
1762 tests += [ rsne + mde + "3755" + fte[4:168] + "0301ff" ]
1763 # FT: No R1KH-ID subelem in FTIE
1764 tests += [ rsne + mde + "375e" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") ]
1765 # FT: Unknown R1KH-ID used in ReassocReq
1766 tests += [ rsne + mde + "3766" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") + "0106000000000000" ]
1767 # FT: PMKID in Reassoc Req did not match with the PMKR1Name derived from auth request
1768 tests += [ rsne[:-32] + 16*"00" + mde + fte ]
1769 # Invalid MIC in FTIE
1770 tests += [ rsne + mde + fte[0:8] + 16*"00" + fte[40:] ]
1771 for t in tests:
1772 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + ies1 + t)
1773
1774 def test_ap_ft_reassoc_local_fail(dev, apdev):
1775 """WPA2-PSK-FT AP Reassociation Request frame and local failure"""
1776 ssid = "test-ft"
1777 passphrase="12345678"
1778
1779 params = ft_params1(ssid=ssid, passphrase=passphrase)
1780 hapd0 = hostapd.add_ap(apdev[0], params)
1781 params = ft_params2(ssid=ssid, passphrase=passphrase)
1782 hapd1 = hostapd.add_ap(apdev[1], params)
1783
1784 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1785 ieee80211w="1", scan_freq="2412")
1786 if dev[0].get_status_field('bssid') == hapd0.own_addr():
1787 hapd1ap = hapd0
1788 hapd2ap = hapd1
1789 else:
1790 hapd1ap = hapd1
1791 hapd2ap = hapd0
1792
1793 dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
1794 # FT: Failed to calculate MIC
1795 with fail_test(hapd2ap, 1, "wpa_ft_validate_reassoc"):
1796 dev[0].request("ROAM " + hapd2ap.own_addr())
1797 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
1798 dev[0].request("DISCONNECT")
1799 if ev is None:
1800 raise Exception("Association reject not seen")