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