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