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