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