]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_ft.py
tests: FT roaming cases with authorized STA entry remaining
[thirdparty/hostap.git] / tests / hwsim / test_ap_ft.py
CommitLineData
cd7f1b9a 1# Fast BSS Transition tests
02a4ac0f 2# Copyright (c) 2013-2019, 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()
02a4ac0f 13import signal
c8942286 14import struct
02a4ac0f 15import subprocess
cd7f1b9a
JM
16
17import hwsim_utils
02a4ac0f 18from hwsim import HWSimRadio
cd7f1b9a 19import hostapd
d7f0bef9 20from tshark import run_tshark
681e8495 21from utils import *
cd7f1b9a 22from wlantest import Wlantest
5b3c40a6 23from test_ap_psk import check_mib, find_wpas_process, read_process_memory, verify_not_present, get_key_locations
392aba4e 24from test_rrm import check_beacon_req
e1923f5b 25from test_suite_b import check_suite_b_192_capa
cd7f1b9a
JM
26
27def ft_base_rsn():
fab49f61
JM
28 params = {"wpa": "2",
29 "wpa_key_mgmt": "FT-PSK",
30 "rsn_pairwise": "CCMP"}
cd7f1b9a
JM
31 return params
32
33def ft_base_mixed():
fab49f61
JM
34 params = {"wpa": "3",
35 "wpa_key_mgmt": "WPA-PSK FT-PSK",
36 "wpa_pairwise": "TKIP",
37 "rsn_pairwise": "CCMP"}
cd7f1b9a
JM
38 return params
39
40def ft_params(rsn=True, ssid=None, passphrase=None):
41 if rsn:
42 params = ft_base_rsn()
43 else:
44 params = ft_base_mixed()
45 if ssid:
46 params["ssid"] = ssid
47 if passphrase:
48 params["wpa_passphrase"] = passphrase
49
50 params["mobility_domain"] = "a1b2"
51 params["r0_key_lifetime"] = "10000"
52 params["pmk_r1_push"] = "1"
53 params["reassociation_deadline"] = "1000"
54 return params
55
d0175d6e 56def ft_params1a(rsn=True, ssid=None, passphrase=None):
cd7f1b9a
JM
57 params = ft_params(rsn, ssid, passphrase)
58 params['nas_identifier'] = "nas1.w1.fi"
59 params['r1_key_holder'] = "000102030405"
d0175d6e
MB
60 return params
61
942b52a8 62def ft_params1(rsn=True, ssid=None, passphrase=None, discovery=False):
d0175d6e 63 params = ft_params1a(rsn, ssid, passphrase)
942b52a8
MB
64 if discovery:
65 params['r0kh'] = "ff:ff:ff:ff:ff:ff * 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
66 params['r1kh'] = "00:00:00:00:00:00 00:00:00:00:00:00 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
67 else:
fab49f61
JM
68 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f",
69 "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"]
942b52a8 70 params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f"
cd7f1b9a
JM
71 return params
72
c95dd8e4
JM
73def ft_params1_old_key(rsn=True, ssid=None, passphrase=None):
74 params = ft_params1a(rsn, ssid, passphrase)
fab49f61
JM
75 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
76 "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"]
c95dd8e4
JM
77 params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
78 return params
79
d0175d6e 80def ft_params2a(rsn=True, ssid=None, passphrase=None):
cd7f1b9a
JM
81 params = ft_params(rsn, ssid, passphrase)
82 params['nas_identifier'] = "nas2.w1.fi"
83 params['r1_key_holder'] = "000102030406"
d0175d6e
MB
84 return params
85
942b52a8 86def ft_params2(rsn=True, ssid=None, passphrase=None, discovery=False):
d0175d6e 87 params = ft_params2a(rsn, ssid, passphrase)
942b52a8
MB
88 if discovery:
89 params['r0kh'] = "ff:ff:ff:ff:ff:ff * 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
90 params['r1kh'] = "00:00:00:00:00:00 00:00:00:00:00:00 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
91 else:
fab49f61
JM
92 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f",
93 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"]
942b52a8 94 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"
cd7f1b9a
JM
95 return params
96
c95dd8e4
JM
97def ft_params2_old_key(rsn=True, ssid=None, passphrase=None):
98 params = ft_params2a(rsn, ssid, passphrase)
fab49f61
JM
99 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
100 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f"]
c95dd8e4
JM
101 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
102 return params
103
3b808945
JM
104def ft_params1_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
105 params = ft_params(rsn, ssid, passphrase)
106 params['nas_identifier'] = "nas1.w1.fi"
107 params['r1_key_holder'] = "000102030405"
fab49f61
JM
108 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f",
109 "12:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"]
9441a227 110 params['r1kh'] = "12:00:00:00:04:00 10:01:02:03:04:06 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f"
3b808945
JM
111 return params
112
113def ft_params2_incorrect_rrb_key(rsn=True, ssid=None, passphrase=None):
114 params = ft_params(rsn, ssid, passphrase)
115 params['nas_identifier'] = "nas2.w1.fi"
116 params['r1_key_holder'] = "000102030406"
fab49f61
JM
117 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0ef1200102030405060708090a0b0c0d0ef1",
118 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0ef2000102030405060708090a0b0c0d0ef2"]
9441a227 119 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0ef3300102030405060708090a0b0c0d0ef3"
3b808945
JM
120 return params
121
122def ft_params2_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
123 params = ft_params(rsn, ssid, passphrase)
124 params['nas_identifier'] = "nas2.w1.fi"
125 params['r1_key_holder'] = "000102030406"
fab49f61
JM
126 params['r0kh'] = ["12:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f",
127 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"]
9441a227 128 params['r1kh'] = "12:00:00:00:03:00 10:01:02:03:04:05 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"
3b808945
JM
129 return params
130
7b741a53
JM
131def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False,
132 sae=False, eap=False, fail_test=False, roams=1,
fd7205fa 133 pairwise_cipher="CCMP", group_cipher="TKIP CCMP", ptk_rekey="0",
473e5176 134 test_connectivity=True, eap_identity="gpsk user", conndev=False,
ffcaca68 135 force_initial_conn_to_first_ap=False, sha384=False,
3d5b88b5 136 group_mgmt=None, ocv=None, sae_password=None,
659f7954 137 sae_password_id=None, sae_and_psk=False, pmksa_caching=False,
5916637c 138 roam_with_reassoc=False, also_non_ft=False, only_one_way=False,
30998360 139 wait_before_roam=0, return_after_initial=False, ieee80211w="1"):
cd7f1b9a 140 logger.info("Connect to first AP")
473e5176
MB
141
142 copts = {}
143 copts["proto"] = "WPA2"
30998360 144 copts["ieee80211w"] = ieee80211w
473e5176
MB
145 copts["scan_freq"] = "2412"
146 copts["pairwise"] = pairwise_cipher
fab49f61 147 copts["group"] = group_cipher
473e5176 148 copts["wpa_ptk_rekey"] = ptk_rekey
ffcaca68
JM
149 if group_mgmt:
150 copts["group_mgmt"] = group_mgmt
e63d8837
MV
151 if ocv:
152 copts["ocv"] = ocv
6f62809b 153 if eap:
9ff2b85e
JM
154 if pmksa_caching:
155 copts["ft_eap_pmksa_caching"] = "1"
659f7954
JM
156 if also_non_ft:
157 copts["key_mgmt"] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384" if sha384 else "WPA-EAP FT-EAP"
158 else:
159 copts["key_mgmt"] = "FT-EAP-SHA384" if sha384 else "FT-EAP"
473e5176
MB
160 copts["eap"] = "GPSK"
161 copts["identity"] = eap_identity
162 copts["password"] = "abcdefghijklmnop0123456789abcdef"
6e658cc4 163 else:
6f62809b 164 if sae:
cdf53910 165 copts["key_mgmt"] = "SAE FT-SAE" if sae_and_psk else "FT-SAE"
6f62809b 166 else:
473e5176 167 copts["key_mgmt"] = "FT-PSK"
3d5b88b5
JM
168 if passphrase:
169 copts["psk"] = passphrase
170 if sae_password:
171 copts["sae_password"] = sae_password
172 if sae_password_id:
173 copts["sae_password_id"] = sae_password_id
473e5176
MB
174 if force_initial_conn_to_first_ap:
175 copts["bssid"] = apdev[0]['bssid']
659f7954 176 netw = dev.connect(ssid, **copts)
1211031a 177 if pmksa_caching:
9f47fdb6
JM
178 if dev.get_status_field('bssid') == apdev[0]['bssid']:
179 hapd0.wait_sta()
180 else:
181 hapd1.wait_sta()
1211031a
JM
182 dev.request("DISCONNECT")
183 dev.wait_disconnected()
184 dev.request("RECONNECT")
9ff2b85e
JM
185 ev = dev.wait_event(["CTRL-EVENT-CONNECTED",
186 "CTRL-EVENT-DISCONNECTED",
187 "CTRL-EVENT-EAP-STARTED"],
1211031a
JM
188 timeout=15)
189 if ev is None:
190 raise Exception("Reconnect timed out")
191 if "CTRL-EVENT-DISCONNECTED" in ev:
192 raise Exception("Unexpected disconnection after RECONNECT")
9ff2b85e
JM
193 if "CTRL-EVENT-EAP-STARTED" in ev:
194 raise Exception("Unexpected EAP start after RECONNECT")
473e5176 195
cd7f1b9a
JM
196 if dev.get_status_field('bssid') == apdev[0]['bssid']:
197 ap1 = apdev[0]
198 ap2 = apdev[1]
a8375c94
JM
199 hapd1ap = hapd0
200 hapd2ap = hapd1
cd7f1b9a
JM
201 else:
202 ap1 = apdev[1]
203 ap2 = apdev[0]
a8375c94
JM
204 hapd1ap = hapd1
205 hapd2ap = hapd0
fd7205fa 206 if test_connectivity:
938c6e7b 207 hapd1ap.wait_sta()
9c50a6d3
MB
208 if conndev:
209 hwsim_utils.test_connectivity_iface(dev, hapd1ap, conndev)
210 else:
211 hwsim_utils.test_connectivity(dev, hapd1ap)
cd7f1b9a 212
5916637c
JM
213 if return_after_initial:
214 return ap2['bssid']
215
216 if wait_before_roam:
217 time.sleep(wait_before_roam)
655bc8bf 218 dev.scan_for_bss(ap2['bssid'], freq="2412")
40602101
JM
219
220 for i in range(0, roams):
e0382291
MB
221 # Roaming artificially fast can make data test fail because the key is
222 # set later.
223 time.sleep(0.01)
40602101 224 logger.info("Roam to the second AP")
659f7954
JM
225 if roam_with_reassoc:
226 dev.set_network(netw, "bssid", ap2['bssid'])
227 dev.request("REASSOCIATE")
228 dev.wait_connected()
229 elif over_ds:
40602101
JM
230 dev.roam_over_ds(ap2['bssid'], fail_test=fail_test)
231 else:
232 dev.roam(ap2['bssid'], fail_test=fail_test)
233 if fail_test:
234 return
235 if dev.get_status_field('bssid') != ap2['bssid']:
236 raise Exception("Did not connect to correct AP")
fd7205fa 237 if (i == 0 or i == roams - 1) and test_connectivity:
938c6e7b 238 hapd2ap.wait_sta()
9c50a6d3
MB
239 if conndev:
240 hwsim_utils.test_connectivity_iface(dev, hapd2ap, conndev)
241 else:
242 hwsim_utils.test_connectivity(dev, hapd2ap)
40602101 243
425e5f97
JM
244 if only_one_way:
245 return
e0382291
MB
246 # Roaming artificially fast can make data test fail because the key is
247 # set later.
248 time.sleep(0.01)
40602101 249 logger.info("Roam back to the first AP")
659f7954
JM
250 if roam_with_reassoc:
251 dev.set_network(netw, "bssid", ap1['bssid'])
252 dev.request("REASSOCIATE")
253 dev.wait_connected()
254 elif over_ds:
40602101
JM
255 dev.roam_over_ds(ap1['bssid'])
256 else:
257 dev.roam(ap1['bssid'])
258 if dev.get_status_field('bssid') != ap1['bssid']:
259 raise Exception("Did not connect to correct AP")
fd7205fa 260 if (i == 0 or i == roams - 1) and test_connectivity:
938c6e7b 261 hapd1ap.wait_sta()
9c50a6d3
MB
262 if conndev:
263 hwsim_utils.test_connectivity_iface(dev, hapd1ap, conndev)
264 else:
265 hwsim_utils.test_connectivity(dev, hapd1ap)
cd7f1b9a
JM
266
267def test_ap_ft(dev, apdev):
268 """WPA2-PSK-FT AP"""
269 ssid = "test-ft"
fab49f61 270 passphrase = "12345678"
cd7f1b9a
JM
271
272 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 273 hapd0 = hostapd.add_ap(apdev[0], params)
cd7f1b9a 274 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 275 hapd1 = hostapd.add_ap(apdev[1], params)
cd7f1b9a 276
a8375c94 277 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
91bc6c36
JM
278 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
279 raise Exception("Scan results missing RSN element info")
cd7f1b9a 280
c95dd8e4
JM
281def test_ap_ft_old_key(dev, apdev):
282 """WPA2-PSK-FT AP (old key)"""
283 ssid = "test-ft"
fab49f61 284 passphrase = "12345678"
c95dd8e4
JM
285
286 params = ft_params1_old_key(ssid=ssid, passphrase=passphrase)
287 hapd0 = hostapd.add_ap(apdev[0], params)
288 params = ft_params2_old_key(ssid=ssid, passphrase=passphrase)
289 hapd1 = hostapd.add_ap(apdev[1], params)
290
291 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
292
e4612f84
JM
293def test_ap_ft_multi_akm(dev, apdev):
294 """WPA2-PSK-FT AP with non-FT AKMs enabled"""
295 ssid = "test-ft"
fab49f61 296 passphrase = "12345678"
e4612f84
JM
297
298 params = ft_params1(ssid=ssid, passphrase=passphrase)
299 params["wpa_key_mgmt"] = "FT-PSK WPA-PSK WPA-PSK-SHA256"
300 hapd0 = hostapd.add_ap(apdev[0], params)
301 params = ft_params2(ssid=ssid, passphrase=passphrase)
302 params["wpa_key_mgmt"] = "FT-PSK WPA-PSK WPA-PSK-SHA256"
303 hapd1 = hostapd.add_ap(apdev[1], params)
304
305 Wlantest.setup(hapd0)
306 wt = Wlantest()
307 wt.flush()
308 wt.add_passphrase(passphrase)
309
310 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
311 if "[WPA2-PSK+FT/PSK+PSK-SHA256-CCMP]" not in dev[0].request("SCAN_RESULTS"):
312 raise Exception("Scan results missing RSN element info")
313 dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
314 dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
315 scan_freq="2412")
316
d0175d6e
MB
317def test_ap_ft_local_key_gen(dev, apdev):
318 """WPA2-PSK-FT AP with local key generation (without pull/push)"""
319 ssid = "test-ft"
fab49f61 320 passphrase = "12345678"
d0175d6e
MB
321
322 params = ft_params1a(ssid=ssid, passphrase=passphrase)
58be42b2 323 params['ft_psk_generate_local'] = "1"
8344ba12 324 del params['pmk_r1_push']
b098542c 325 hapd0 = hostapd.add_ap(apdev[0], params)
d0175d6e 326 params = ft_params2a(ssid=ssid, passphrase=passphrase)
58be42b2 327 params['ft_psk_generate_local'] = "1"
8344ba12 328 del params['pmk_r1_push']
b098542c 329 hapd1 = hostapd.add_ap(apdev[1], params)
d0175d6e
MB
330
331 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
332 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
333 raise Exception("Scan results missing RSN element info")
334
473e5176
MB
335def test_ap_ft_vlan(dev, apdev):
336 """WPA2-PSK-FT AP with VLAN"""
337 ssid = "test-ft"
fab49f61 338 passphrase = "12345678"
4d148384
JD
339 filename = hostapd.acl_file(dev, apdev, 'hostapd.accept')
340 hostapd.send_file(apdev[0], filename, filename)
341 hostapd.send_file(apdev[1], filename, filename)
473e5176
MB
342
343 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 344 params['dynamic_vlan'] = "1"
4d148384 345 params['accept_mac_file'] = filename
473e5176
MB
346 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
347
348 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 349 params['dynamic_vlan'] = "1"
4d148384 350 params['accept_mac_file'] = filename
473e5176
MB
351 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
352
353 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1")
354 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
355 raise Exception("Scan results missing RSN element info")
af9d8c75
JM
356 if filename.startswith('/tmp/'):
357 os.unlink(filename)
473e5176
MB
358
359def test_ap_ft_vlan_disconnected(dev, apdev):
360 """WPA2-PSK-FT AP with VLAN and local key generation"""
361 ssid = "test-ft"
fab49f61 362 passphrase = "12345678"
4d148384
JD
363 filename = hostapd.acl_file(dev, apdev, 'hostapd.accept')
364 hostapd.send_file(apdev[0], filename, filename)
365 hostapd.send_file(apdev[1], filename, filename)
473e5176
MB
366
367 params = ft_params1a(ssid=ssid, passphrase=passphrase)
58be42b2 368 params['dynamic_vlan'] = "1"
4d148384 369 params['accept_mac_file'] = filename
58be42b2 370 params['ft_psk_generate_local'] = "1"
473e5176
MB
371 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
372
373 params = ft_params2a(ssid=ssid, passphrase=passphrase)
58be42b2 374 params['dynamic_vlan'] = "1"
4d148384 375 params['accept_mac_file'] = filename
58be42b2 376 params['ft_psk_generate_local'] = "1"
473e5176
MB
377 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
378
379 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1")
380 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
381 raise Exception("Scan results missing RSN element info")
af9d8c75
JM
382 if filename.startswith('/tmp/'):
383 os.unlink(filename)
473e5176
MB
384
385def test_ap_ft_vlan_2(dev, apdev):
386 """WPA2-PSK-FT AP with VLAN and dest-AP does not have VLAN info locally"""
387 ssid = "test-ft"
fab49f61 388 passphrase = "12345678"
4d148384
JD
389 filename = hostapd.acl_file(dev, apdev, 'hostapd.accept')
390 hostapd.send_file(apdev[0], filename, filename)
473e5176
MB
391
392 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 393 params['dynamic_vlan'] = "1"
4d148384 394 params['accept_mac_file'] = filename
473e5176
MB
395 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
396
397 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 398 params['dynamic_vlan'] = "1"
473e5176
MB
399 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
400
401 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1",
e0d9f5fc 402 force_initial_conn_to_first_ap=True)
473e5176
MB
403 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
404 raise Exception("Scan results missing RSN element info")
af9d8c75
JM
405 if filename.startswith('/tmp/'):
406 os.unlink(filename)
473e5176 407
40602101
JM
408def test_ap_ft_many(dev, apdev):
409 """WPA2-PSK-FT AP multiple times"""
410 ssid = "test-ft"
fab49f61 411 passphrase = "12345678"
40602101
JM
412
413 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 414 hapd0 = hostapd.add_ap(apdev[0], params)
40602101 415 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 416 hapd1 = hostapd.add_ap(apdev[1], params)
40602101 417
a8375c94 418 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50)
40602101 419
473e5176
MB
420def test_ap_ft_many_vlan(dev, apdev):
421 """WPA2-PSK-FT AP with VLAN multiple times"""
422 ssid = "test-ft"
fab49f61 423 passphrase = "12345678"
4d148384
JD
424 filename = hostapd.acl_file(dev, apdev, 'hostapd.accept')
425 hostapd.send_file(apdev[0], filename, filename)
426 hostapd.send_file(apdev[1], filename, filename)
473e5176
MB
427
428 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 429 params['dynamic_vlan'] = "1"
4d148384 430 params['accept_mac_file'] = filename
473e5176
MB
431 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
432
433 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 434 params['dynamic_vlan'] = "1"
4d148384 435 params['accept_mac_file'] = filename
473e5176
MB
436 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
437
438 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50,
439 conndev="brvlan1")
af9d8c75
JM
440 if filename.startswith('/tmp/'):
441 os.unlink(filename)
473e5176 442
cd7f1b9a
JM
443def test_ap_ft_mixed(dev, apdev):
444 """WPA2-PSK-FT mixed-mode AP"""
445 ssid = "test-ft-mixed"
fab49f61 446 passphrase = "12345678"
cd7f1b9a
JM
447
448 params = ft_params1(rsn=False, ssid=ssid, passphrase=passphrase)
8b8a1864 449 hapd = hostapd.add_ap(apdev[0], params)
65038313
JM
450 key_mgmt = hapd.get_config()['key_mgmt']
451 vals = key_mgmt.split(' ')
452 if vals[0] != "WPA-PSK" or vals[1] != "FT-PSK":
453 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
cd7f1b9a 454 params = ft_params2(rsn=False, ssid=ssid, passphrase=passphrase)
8b8a1864 455 hapd1 = hostapd.add_ap(apdev[1], params)
cd7f1b9a 456
a8375c94 457 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase)
cd7f1b9a
JM
458
459def test_ap_ft_pmf(dev, apdev):
460 """WPA2-PSK-FT AP with PMF"""
30998360
JM
461 run_ap_ft_pmf(dev, apdev, "1")
462
463def test_ap_ft_pmf_over_ds(dev, apdev):
464 """WPA2-PSK-FT AP with PMF (over DS)"""
465 run_ap_ft_pmf(dev, apdev, "1", over_ds=True)
466
467def test_ap_ft_pmf_required(dev, apdev):
468 """WPA2-PSK-FT AP with PMF required on STA"""
469 run_ap_ft_pmf(dev, apdev, "2")
470
471def test_ap_ft_pmf_required_over_ds(dev, apdev):
472 """WPA2-PSK-FT AP with PMF required on STA (over DS)"""
473 run_ap_ft_pmf(dev, apdev, "2", over_ds=True)
474
475def run_ap_ft_pmf(dev, apdev, ieee80211w, over_ds=False):
cd7f1b9a 476 ssid = "test-ft"
fab49f61 477 passphrase = "12345678"
cd7f1b9a
JM
478
479 params = ft_params1(ssid=ssid, passphrase=passphrase)
bc6e3288 480 params["ieee80211w"] = "2"
8b8a1864 481 hapd0 = hostapd.add_ap(apdev[0], params)
cd7f1b9a 482 params = ft_params2(ssid=ssid, passphrase=passphrase)
bc6e3288 483 params["ieee80211w"] = "2"
8b8a1864 484 hapd1 = hostapd.add_ap(apdev[1], params)
cd7f1b9a 485
dbddbf16
JM
486 Wlantest.setup(hapd0)
487 wt = Wlantest()
488 wt.flush()
489 wt.add_passphrase(passphrase)
490
30998360
JM
491 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
492 ieee80211w=ieee80211w, over_ds=over_ds)
493
494def test_ap_ft_pmf_required_mismatch(dev, apdev):
495 """WPA2-PSK-FT AP with PMF required on STA but AP2 not enabling PMF"""
496 run_ap_ft_pmf_required_mismatch(dev, apdev)
497
498def test_ap_ft_pmf_required_mismatch_over_ds(dev, apdev):
499 """WPA2-PSK-FT AP with PMF required on STA but AP2 not enabling PMF (over DS)"""
500 run_ap_ft_pmf_required_mismatch(dev, apdev, over_ds=True)
501
502def run_ap_ft_pmf_required_mismatch(dev, apdev, over_ds=False):
503 ssid = "test-ft"
504 passphrase = "12345678"
505
506 params = ft_params1(ssid=ssid, passphrase=passphrase)
507 params["ieee80211w"] = "2"
508 hapd0 = hostapd.add_ap(apdev[0], params)
509 params = ft_params2(ssid=ssid, passphrase=passphrase)
510 params["ieee80211w"] = "0"
511 hapd1 = hostapd.add_ap(apdev[1], params)
512
513 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ieee80211w="2",
514 force_initial_conn_to_first_ap=True, fail_test=True,
515 over_ds=over_ds)
b553eab1 516
ffcaca68
JM
517def test_ap_ft_pmf_bip_cmac_128(dev, apdev):
518 """WPA2-PSK-FT AP with PMF/BIP-CMAC-128"""
519 run_ap_ft_pmf_bip(dev, apdev, "AES-128-CMAC")
520
521def test_ap_ft_pmf_bip_gmac_128(dev, apdev):
522 """WPA2-PSK-FT AP with PMF/BIP-GMAC-128"""
523 run_ap_ft_pmf_bip(dev, apdev, "BIP-GMAC-128")
524
525def test_ap_ft_pmf_bip_gmac_256(dev, apdev):
526 """WPA2-PSK-FT AP with PMF/BIP-GMAC-256"""
527 run_ap_ft_pmf_bip(dev, apdev, "BIP-GMAC-256")
528
529def test_ap_ft_pmf_bip_cmac_256(dev, apdev):
530 """WPA2-PSK-FT AP with PMF/BIP-CMAC-256"""
531 run_ap_ft_pmf_bip(dev, apdev, "BIP-CMAC-256")
532
533def run_ap_ft_pmf_bip(dev, apdev, cipher):
534 if cipher not in dev[0].get_capability("group_mgmt"):
535 raise HwsimSkip("Cipher %s not supported" % cipher)
536
537 ssid = "test-ft"
fab49f61 538 passphrase = "12345678"
ffcaca68
JM
539
540 params = ft_params1(ssid=ssid, passphrase=passphrase)
541 params["ieee80211w"] = "2"
542 params["group_mgmt_cipher"] = cipher
543 hapd0 = hostapd.add_ap(apdev[0], params)
544 params = ft_params2(ssid=ssid, passphrase=passphrase)
545 params["ieee80211w"] = "2"
546 params["group_mgmt_cipher"] = cipher
547 hapd1 = hostapd.add_ap(apdev[1], params)
548
549 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
550 group_mgmt=cipher)
551
e63d8837
MV
552def test_ap_ft_ocv(dev, apdev):
553 """WPA2-PSK-FT AP with OCV"""
554 ssid = "test-ft"
fab49f61 555 passphrase = "12345678"
e63d8837
MV
556
557 params = ft_params1(ssid=ssid, passphrase=passphrase)
558 params["ieee80211w"] = "2"
559 params["ocv"] = "1"
560 try:
561 hapd0 = hostapd.add_ap(apdev[0], params)
bab493b9 562 except Exception as e:
e63d8837
MV
563 if "Failed to set hostapd parameter ocv" in str(e):
564 raise HwsimSkip("OCV not supported")
565 raise
566 params = ft_params2(ssid=ssid, passphrase=passphrase)
567 params["ieee80211w"] = "2"
568 params["ocv"] = "1"
569 hapd1 = hostapd.add_ap(apdev[1], params)
570
571 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ocv="1")
572
b553eab1
JM
573def test_ap_ft_over_ds(dev, apdev):
574 """WPA2-PSK-FT AP over DS"""
575 ssid = "test-ft"
fab49f61 576 passphrase = "12345678"
b553eab1
JM
577
578 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 579 hapd0 = hostapd.add_ap(apdev[0], params)
b553eab1 580 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 581 hapd1 = hostapd.add_ap(apdev[1], params)
b553eab1 582
a8375c94 583 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
fab49f61
JM
584 check_mib(dev[0], [("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
585 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4")])
b553eab1 586
02a4ac0f
JM
587def cleanup_ap_ft_separate_hostapd():
588 subprocess.call(["brctl", "delif", "br0ft", "veth0"],
589 stderr=open('/dev/null', 'w'))
590 subprocess.call(["brctl", "delif", "br1ft", "veth1"],
591 stderr=open('/dev/null', 'w'))
592 subprocess.call(["ip", "link", "del", "veth0"],
593 stderr=open('/dev/null', 'w'))
594 subprocess.call(["ip", "link", "del", "veth1"],
595 stderr=open('/dev/null', 'w'))
fab49f61 596 for ifname in ['br0ft', 'br1ft', 'br-ft']:
02a4ac0f
JM
597 subprocess.call(['ip', 'link', 'set', 'dev', ifname, 'down'],
598 stderr=open('/dev/null', 'w'))
599 subprocess.call(['brctl', 'delbr', ifname],
600 stderr=open('/dev/null', 'w'))
601
602def test_ap_ft_separate_hostapd(dev, apdev, params):
603 """WPA2-PSK-FT AP and separate hostapd process"""
604 try:
605 run_ap_ft_separate_hostapd(dev, apdev, params, False)
606 finally:
607 cleanup_ap_ft_separate_hostapd()
608
609def test_ap_ft_over_ds_separate_hostapd(dev, apdev, params):
610 """WPA2-PSK-FT AP over DS and separate hostapd process"""
611 try:
612 run_ap_ft_separate_hostapd(dev, apdev, params, True)
613 finally:
614 cleanup_ap_ft_separate_hostapd()
615
616def run_ap_ft_separate_hostapd(dev, apdev, params, over_ds):
617 ssid = "test-ft"
fab49f61 618 passphrase = "12345678"
02a4ac0f
JM
619 logdir = params['logdir']
620 pidfile = os.path.join(logdir, 'ap_ft_over_ds_separate_hostapd.pid')
621 logfile = os.path.join(logdir, 'ap_ft_over_ds_separate_hostapd.hapd')
622 global_ctrl = '/var/run/hostapd-ft'
623 br_ifname = 'br-ft'
624
625 try:
626 subprocess.check_call(['brctl', 'addbr', br_ifname])
627 subprocess.check_call(['brctl', 'setfd', br_ifname, '0'])
628 subprocess.check_call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
629
fab49f61
JM
630 subprocess.check_call(["ip", "link", "add", "veth0", "type", "veth",
631 "peer", "name", "veth0br"])
632 subprocess.check_call(["ip", "link", "add", "veth1", "type", "veth",
633 "peer", "name", "veth1br"])
02a4ac0f
JM
634 subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth0br', 'up'])
635 subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth1br', 'up'])
636 subprocess.check_call(['brctl', 'addif', br_ifname, 'veth0br'])
637 subprocess.check_call(['brctl', 'addif', br_ifname, 'veth1br'])
638
639 subprocess.check_call(['brctl', 'addbr', 'br0ft'])
640 subprocess.check_call(['brctl', 'setfd', 'br0ft', '0'])
641 subprocess.check_call(['ip', 'link', 'set', 'dev', 'br0ft', 'up'])
642 subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth0', 'up'])
643 subprocess.check_call(['brctl', 'addif', 'br0ft', 'veth0'])
644 subprocess.check_call(['brctl', 'addbr', 'br1ft'])
645 subprocess.check_call(['brctl', 'setfd', 'br1ft', '0'])
646 subprocess.check_call(['ip', 'link', 'set', 'dev', 'br1ft', 'up'])
647 subprocess.check_call(['ip', 'link', 'set', 'dev', 'veth1', 'up'])
648 subprocess.check_call(['brctl', 'addif', 'br1ft', 'veth1'])
649 except subprocess.CalledProcessError:
650 raise HwsimSkip("Bridge or veth not supported (kernel CONFIG_VETH)")
651
652 with HWSimRadio() as (radio, iface):
653 prg = os.path.join(logdir, 'alt-hostapd/hostapd/hostapd')
654 if not os.path.exists(prg):
655 prg = '../../hostapd/hostapd'
fab49f61
JM
656 cmd = [prg, '-B', '-ddKt',
657 '-P', pidfile, '-f', logfile, '-g', global_ctrl]
02a4ac0f
JM
658 subprocess.check_call(cmd)
659
660 hglobal = hostapd.HostapdGlobal(global_ctrl_override=global_ctrl)
fab49f61
JM
661 apdev_ft = {'ifname': iface}
662 apdev2 = [apdev_ft, apdev[1]]
02a4ac0f
JM
663
664 params = ft_params1(ssid=ssid, passphrase=passphrase)
665 params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
666 params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
667 params['bridge'] = 'br0ft'
668 hapd0 = hostapd.add_ap(apdev2[0], params,
669 global_ctrl_override=global_ctrl)
670 apdev2[0]['bssid'] = hapd0.own_addr()
671 params = ft_params2(ssid=ssid, passphrase=passphrase)
672 params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
673 params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
674 params['bridge'] = 'br1ft'
675 hapd1 = hostapd.add_ap(apdev2[1], params)
676
677 run_roams(dev[0], apdev2, hapd0, hapd1, ssid, passphrase,
6f291896 678 over_ds=over_ds, test_connectivity=False, roams=2)
02a4ac0f
JM
679
680 hglobal.terminate()
681
682 if os.path.exists(pidfile):
683 with open(pidfile, 'r') as f:
684 pid = int(f.read())
685 f.close()
686 os.kill(pid, signal.SIGTERM)
687
e63d8837
MV
688def test_ap_ft_over_ds_ocv(dev, apdev):
689 """WPA2-PSK-FT AP over DS"""
690 ssid = "test-ft"
fab49f61 691 passphrase = "12345678"
e63d8837
MV
692
693 params = ft_params1(ssid=ssid, passphrase=passphrase)
694 params["ieee80211w"] = "2"
695 params["ocv"] = "1"
696 try:
697 hapd0 = hostapd.add_ap(apdev[0], params)
bab493b9 698 except Exception as e:
e63d8837
MV
699 if "Failed to set hostapd parameter ocv" in str(e):
700 raise HwsimSkip("OCV not supported")
701 raise
702 params = ft_params2(ssid=ssid, passphrase=passphrase)
703 params["ieee80211w"] = "2"
704 params["ocv"] = "1"
705 hapd1 = hostapd.add_ap(apdev[1], params)
706
707 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
708 ocv="1")
709
55139acb
JM
710def test_ap_ft_over_ds_disabled(dev, apdev):
711 """WPA2-PSK-FT AP over DS disabled"""
712 ssid = "test-ft"
fab49f61 713 passphrase = "12345678"
55139acb
JM
714
715 params = ft_params1(ssid=ssid, passphrase=passphrase)
716 params['ft_over_ds'] = '0'
717 hapd0 = hostapd.add_ap(apdev[0], params)
718 params = ft_params2(ssid=ssid, passphrase=passphrase)
719 params['ft_over_ds'] = '0'
720 hapd1 = hostapd.add_ap(apdev[1], params)
721
722 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
723 fail_test=True)
724
473e5176
MB
725def test_ap_ft_vlan_over_ds(dev, apdev):
726 """WPA2-PSK-FT AP over DS with VLAN"""
727 ssid = "test-ft"
fab49f61 728 passphrase = "12345678"
4d148384
JD
729 filename = hostapd.acl_file(dev, apdev, 'hostapd.accept')
730 hostapd.send_file(apdev[0], filename, filename)
731 hostapd.send_file(apdev[1], filename, filename)
473e5176
MB
732
733 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 734 params['dynamic_vlan'] = "1"
4d148384 735 params['accept_mac_file'] = filename
473e5176
MB
736 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
737 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 738 params['dynamic_vlan'] = "1"
4d148384 739 params['accept_mac_file'] = filename
473e5176
MB
740 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
741
742 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
743 conndev="brvlan1")
fab49f61
JM
744 check_mib(dev[0], [("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
745 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4")])
af9d8c75
JM
746 if filename.startswith('/tmp/'):
747 os.unlink(filename)
473e5176 748
40602101
JM
749def test_ap_ft_over_ds_many(dev, apdev):
750 """WPA2-PSK-FT AP over DS multiple times"""
751 ssid = "test-ft"
fab49f61 752 passphrase = "12345678"
40602101
JM
753
754 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 755 hapd0 = hostapd.add_ap(apdev[0], params)
40602101 756 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 757 hapd1 = hostapd.add_ap(apdev[1], params)
40602101 758
a8375c94
JM
759 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
760 roams=50)
40602101 761
473e5176
MB
762def test_ap_ft_vlan_over_ds_many(dev, apdev):
763 """WPA2-PSK-FT AP over DS with VLAN multiple times"""
764 ssid = "test-ft"
fab49f61 765 passphrase = "12345678"
4d148384
JD
766 filename = hostapd.acl_file(dev, apdev, 'hostapd.accept')
767 hostapd.send_file(apdev[0], filename, filename)
768 hostapd.send_file(apdev[1], filename, filename)
473e5176
MB
769
770 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 771 params['dynamic_vlan'] = "1"
4d148384 772 params['accept_mac_file'] = filename
473e5176
MB
773 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
774 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 775 params['dynamic_vlan'] = "1"
4d148384 776 params['accept_mac_file'] = filename
473e5176
MB
777 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
778
779 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
780 roams=50, conndev="brvlan1")
af9d8c75
JM
781 if filename.startswith('/tmp/'):
782 os.unlink(filename)
473e5176 783
9fd6804d 784@remote_compatible
c337d07a
JM
785def test_ap_ft_over_ds_unknown_target(dev, apdev):
786 """WPA2-PSK-FT AP"""
787 ssid = "test-ft"
fab49f61 788 passphrase = "12345678"
c337d07a
JM
789
790 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 791 hapd0 = hostapd.add_ap(apdev[0], params)
c337d07a
JM
792
793 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
794 scan_freq="2412")
795 dev[0].roam_over_ds("02:11:22:33:44:55", fail_test=True)
796
9fd6804d 797@remote_compatible
211bb7c5
JM
798def test_ap_ft_over_ds_unexpected(dev, apdev):
799 """WPA2-PSK-FT AP over DS and unexpected response"""
800 ssid = "test-ft"
fab49f61 801 passphrase = "12345678"
211bb7c5
JM
802
803 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 804 hapd0 = hostapd.add_ap(apdev[0], params)
211bb7c5 805 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 806 hapd1 = hostapd.add_ap(apdev[1], params)
211bb7c5
JM
807
808 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
809 scan_freq="2412")
810 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
811 ap1 = apdev[0]
812 ap2 = apdev[1]
813 hapd1ap = hapd0
814 hapd2ap = hapd1
815 else:
816 ap1 = apdev[1]
817 ap2 = apdev[0]
818 hapd1ap = hapd1
819 hapd2ap = hapd0
820
821 addr = dev[0].own_addr()
822 hapd1ap.set("ext_mgmt_frame_handling", "1")
823 logger.info("Foreign STA address")
824 msg = {}
825 msg['fc'] = 13 << 4
826 msg['da'] = addr
827 msg['sa'] = ap1['bssid']
828 msg['bssid'] = ap1['bssid']
829 msg['payload'] = binascii.unhexlify("06021122334455660102030405060000")
830 hapd1ap.mgmt_tx(msg)
831
832 logger.info("No over-the-DS in progress")
833 msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
834 hapd1ap.mgmt_tx(msg)
835
836 logger.info("Non-zero status code")
837 msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060100")
838 hapd1ap.mgmt_tx(msg)
839
840 hapd1ap.dump_monitor()
841
842 dev[0].scan_for_bss(ap2['bssid'], freq="2412")
843 if "OK" not in dev[0].request("FT_DS " + ap2['bssid']):
844 raise Exception("FT_DS failed")
845
846 req = hapd1ap.mgmt_rx()
847
848 logger.info("Foreign Target AP")
849 msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
850 hapd1ap.mgmt_tx(msg)
851
852 addrs = addr.replace(':', '') + ap2['bssid'].replace(':', '')
853
854 logger.info("No IEs")
855 msg['payload'] = binascii.unhexlify("0602" + addrs + "0000")
856 hapd1ap.mgmt_tx(msg)
857
858 logger.info("Invalid IEs (trigger parsing failure)")
859 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003700")
860 hapd1ap.mgmt_tx(msg)
861
862 logger.info("Too short MDIE")
863 msg['payload'] = binascii.unhexlify("0602" + addrs + "000036021122")
864 hapd1ap.mgmt_tx(msg)
865
866 logger.info("Mobility domain mismatch")
867 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603112201")
868 hapd1ap.mgmt_tx(msg)
869
870 logger.info("No FTIE")
871 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201")
872 hapd1ap.mgmt_tx(msg)
873
874 logger.info("FTIE SNonce mismatch")
875 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "1000000000000000000000000000000000000000000000000000000000000001" + "030a6e6173322e77312e6669")
876 hapd1ap.mgmt_tx(msg)
877
878 logger.info("No R0KH-ID subelem in FTIE")
7ab74770 879 snonce = binascii.hexlify(req['payload'][111:111+32]).decode()
211bb7c5
JM
880 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137520000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce)
881 hapd1ap.mgmt_tx(msg)
882
883 logger.info("No R0KH-ID subelem mismatch in FTIE")
7ab74770 884 snonce = binascii.hexlify(req['payload'][111:111+32]).decode()
211bb7c5
JM
885 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a11223344556677889900")
886 hapd1ap.mgmt_tx(msg)
887
888 logger.info("No R1KH-ID subelem in FTIE")
7ab74770 889 r0khid = binascii.hexlify(req['payload'][145:145+10]).decode()
211bb7c5
JM
890 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid)
891 hapd1ap.mgmt_tx(msg)
892
893 logger.info("No RSNE")
7ab74770 894 r0khid = binascii.hexlify(req['payload'][145:145+10]).decode()
211bb7c5
JM
895 msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137660000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid + "0106000102030405")
896 hapd1ap.mgmt_tx(msg)
897
b553eab1
JM
898def test_ap_ft_pmf_over_ds(dev, apdev):
899 """WPA2-PSK-FT AP over DS with PMF"""
0c481b78 900 run_ap_ft_pmf_bip_over_ds(dev, apdev, None)
46b8ea21 901
ffcaca68
JM
902def test_ap_ft_pmf_bip_cmac_128_over_ds(dev, apdev):
903 """WPA2-PSK-FT AP over DS with PMF/BIP-CMAC-128"""
904 run_ap_ft_pmf_bip_over_ds(dev, apdev, "AES-128-CMAC")
905
906def test_ap_ft_pmf_bip_gmac_128_over_ds(dev, apdev):
907 """WPA2-PSK-FT AP over DS with PMF/BIP-GMAC-128"""
908 run_ap_ft_pmf_bip_over_ds(dev, apdev, "BIP-GMAC-128")
909
910def test_ap_ft_pmf_bip_gmac_256_over_ds(dev, apdev):
911 """WPA2-PSK-FT AP over DS with PMF/BIP-GMAC-256"""
912 run_ap_ft_pmf_bip_over_ds(dev, apdev, "BIP-GMAC-256")
913
914def test_ap_ft_pmf_bip_cmac_256_over_ds(dev, apdev):
915 """WPA2-PSK-FT AP over DS with PMF/BIP-CMAC-256"""
916 run_ap_ft_pmf_bip_over_ds(dev, apdev, "BIP-CMAC-256")
917
918def run_ap_ft_pmf_bip_over_ds(dev, apdev, cipher):
0c481b78 919 if cipher and cipher not in dev[0].get_capability("group_mgmt"):
ffcaca68
JM
920 raise HwsimSkip("Cipher %s not supported" % cipher)
921
922 ssid = "test-ft"
fab49f61 923 passphrase = "12345678"
ffcaca68
JM
924
925 params = ft_params1(ssid=ssid, passphrase=passphrase)
926 params["ieee80211w"] = "2"
0c481b78
JM
927 if cipher:
928 params["group_mgmt_cipher"] = cipher
ffcaca68
JM
929 hapd0 = hostapd.add_ap(apdev[0], params)
930 params = ft_params2(ssid=ssid, passphrase=passphrase)
931 params["ieee80211w"] = "2"
0c481b78
JM
932 if cipher:
933 params["group_mgmt_cipher"] = cipher
ffcaca68
JM
934 hapd1 = hostapd.add_ap(apdev[1], params)
935
0defc42a
JM
936 Wlantest.setup(hapd0)
937 wt = Wlantest()
938 wt.flush()
939 wt.add_passphrase(passphrase)
940
ffcaca68
JM
941 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
942 group_mgmt=cipher)
6e658cc4 943
aaba98d3
JM
944def test_ap_ft_over_ds_pull(dev, apdev):
945 """WPA2-PSK-FT AP over DS (pull PMK)"""
946 ssid = "test-ft"
fab49f61 947 passphrase = "12345678"
aaba98d3
JM
948
949 params = ft_params1(ssid=ssid, passphrase=passphrase)
950 params["pmk_r1_push"] = "0"
8b8a1864 951 hapd0 = hostapd.add_ap(apdev[0], params)
aaba98d3
JM
952 params = ft_params2(ssid=ssid, passphrase=passphrase)
953 params["pmk_r1_push"] = "0"
8b8a1864 954 hapd1 = hostapd.add_ap(apdev[1], params)
aaba98d3 955
a8375c94 956 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
aaba98d3 957
c95dd8e4
JM
958def test_ap_ft_over_ds_pull_old_key(dev, apdev):
959 """WPA2-PSK-FT AP over DS (pull PMK; old key)"""
960 ssid = "test-ft"
fab49f61 961 passphrase = "12345678"
c95dd8e4
JM
962
963 params = ft_params1_old_key(ssid=ssid, passphrase=passphrase)
964 params["pmk_r1_push"] = "0"
965 hapd0 = hostapd.add_ap(apdev[0], params)
966 params = ft_params2_old_key(ssid=ssid, passphrase=passphrase)
967 params["pmk_r1_push"] = "0"
968 hapd1 = hostapd.add_ap(apdev[1], params)
969
970 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
971
473e5176
MB
972def test_ap_ft_over_ds_pull_vlan(dev, apdev):
973 """WPA2-PSK-FT AP over DS (pull PMK) with VLAN"""
974 ssid = "test-ft"
fab49f61 975 passphrase = "12345678"
4d148384
JD
976 filename = hostapd.acl_file(dev, apdev, 'hostapd.accept')
977 hostapd.send_file(apdev[0], filename, filename)
978 hostapd.send_file(apdev[1], filename, filename)
473e5176
MB
979
980 params = ft_params1(ssid=ssid, passphrase=passphrase)
981 params["pmk_r1_push"] = "0"
58be42b2 982 params['dynamic_vlan'] = "1"
4d148384 983 params['accept_mac_file'] = filename
473e5176
MB
984 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
985 params = ft_params2(ssid=ssid, passphrase=passphrase)
986 params["pmk_r1_push"] = "0"
58be42b2 987 params['dynamic_vlan'] = "1"
4d148384 988 params['accept_mac_file'] = filename
473e5176
MB
989 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
990
991 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
992 conndev="brvlan1")
af9d8c75
JM
993 if filename.startswith('/tmp/'):
994 os.unlink(filename)
473e5176 995
2b8f8a47 996def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None,
2af3d99c 997 rsne_override=None, rsnxe_override=None,
6f291896
JM
998 no_beacon_rsnxe2=False, ext_key_id=False,
999 skip_prune_assoc=False):
425e5f97 1000 if "SAE" not in dev.get_capability("auth_alg"):
b9749b6a 1001 raise HwsimSkip("SAE not supported")
6e658cc4 1002 ssid = "test-ft"
fab49f61 1003 passphrase = "12345678"
6e658cc4
JM
1004
1005 params = ft_params1(ssid=ssid, passphrase=passphrase)
1006 params['wpa_key_mgmt'] = "FT-SAE"
425e5f97
JM
1007 if wpa_ptk_rekey:
1008 params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
30628e0d
JM
1009 if sae_pwe is not None:
1010 params['sae_pwe'] = sae_pwe
2b8f8a47
JM
1011 if rsne_override:
1012 params['rsne_override_ft'] = rsne_override
1013 if rsnxe_override:
1014 params['rsnxe_override_ft'] = rsnxe_override
681e8495
JM
1015 if ext_key_id:
1016 params['extended_key_id'] = '1'
6f291896
JM
1017 if skip_prune_assoc:
1018 params['skip_prune_assoc'] = '1'
8b8a1864 1019 hapd0 = hostapd.add_ap(apdev[0], params)
6e658cc4
JM
1020 params = ft_params2(ssid=ssid, passphrase=passphrase)
1021 params['wpa_key_mgmt'] = "FT-SAE"
425e5f97
JM
1022 if wpa_ptk_rekey:
1023 params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
30628e0d
JM
1024 if sae_pwe is not None:
1025 params['sae_pwe'] = sae_pwe
2b8f8a47
JM
1026 if rsne_override:
1027 params['rsne_override_ft'] = rsne_override
1028 if rsnxe_override:
1029 params['rsnxe_override_ft'] = rsnxe_override
2af3d99c
JM
1030 if no_beacon_rsnxe2:
1031 params['no_beacon_rsnxe'] = "1"
681e8495
JM
1032 if ext_key_id:
1033 params['extended_key_id'] = '1'
6f291896
JM
1034 if skip_prune_assoc:
1035 params['skip_prune_assoc'] = '1'
425e5f97
JM
1036 hapd1 = hostapd.add_ap(apdev[1], params)
1037 key_mgmt = hapd1.get_config()['key_mgmt']
65038313
JM
1038 if key_mgmt.split(' ')[0] != "FT-SAE":
1039 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
6e658cc4 1040
425e5f97
JM
1041 dev.request("SET sae_groups ")
1042 return hapd0, hapd1
1043
1044def test_ap_ft_sae(dev, apdev):
1045 """WPA2-PSK-FT-SAE AP"""
1046 hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1047 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
1048
30628e0d
JM
1049def test_ap_ft_sae_h2e(dev, apdev):
1050 """WPA2-PSK-FT-SAE AP (H2E)"""
1051 try:
1052 dev[0].set("sae_pwe", "2")
1053 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2")
1054 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
1055 finally:
1056 dev[0].set("sae_pwe", "0")
1057
daf8491d
JM
1058def test_ap_ft_sae_h2e_and_loop(dev, apdev):
1059 """WPA2-PSK-FT-SAE AP (AP H2E, STA loop)"""
1060 dev[0].set("sae_pwe", "0")
1061 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2")
1062 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
1063
2af3d99c
JM
1064def test_ap_ft_sae_h2e_and_loop2(dev, apdev):
1065 """WPA2-PSK-FT-SAE AP (AP loop, STA H2E)"""
1066 try:
1067 dev[0].set("sae_pwe", "2")
1068 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="0")
1069 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
1070 finally:
1071 dev[0].set("sae_pwe", "0")
1072
1073def test_ap_ft_sae_h2e_downgrade_attack(dev, apdev):
1074 """WPA2-PSK-FT-SAE AP (H2E downgrade attack)"""
1075 try:
1076 dev[0].set("sae_pwe", "2")
1077 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
1078 no_beacon_rsnxe2=True)
1079 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1080 force_initial_conn_to_first_ap=True,
1081 return_after_initial=True)
1082 dev[0].scan_for_bss(hapd1.own_addr(), freq="2412")
1083 dev[0].request("ROAM " + hapd1.own_addr())
1084 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
1085 if ev is None:
1086 raise Exception("Association not rejected")
1087 finally:
1088 dev[0].set("sae_pwe", "0")
1089
425e5f97
JM
1090def test_ap_ft_sae_ptk_rekey0(dev, apdev):
1091 """WPA2-PSK-FT-SAE AP and PTK rekey triggered by station"""
1092 hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1093 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1094 ptk_rekey="1", roams=0)
1095 check_ptk_rekey(dev[0], hapd0, hapd1)
1096
1097def test_ap_ft_sae_ptk_rekey1(dev, apdev):
1098 """WPA2-PSK-FT-SAE AP and PTK rekey triggered by station"""
1099 hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1100 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1101 ptk_rekey="1", only_one_way=True)
1102 check_ptk_rekey(dev[0], hapd0, hapd1)
1103
1104def test_ap_ft_sae_ptk_rekey_ap(dev, apdev):
1105 """WPA2-PSK-FT-SAE AP and PTK rekey triggered by AP"""
1106 hapd0, hapd1 = start_ft_sae(dev[0], apdev, wpa_ptk_rekey=2)
1107 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1108 only_one_way=True)
1109 check_ptk_rekey(dev[0], hapd0, hapd1)
6e658cc4 1110
681e8495
JM
1111def test_ap_ft_sae_ptk_rekey_ap_ext_key_id(dev, apdev):
1112 """WPA2-PSK-FT-SAE AP and PTK rekey triggered by AP (Ext Key ID)"""
1113 check_ext_key_id_capa(dev[0])
1114 try:
1115 dev[0].set("extended_key_id", "1")
1116 hapd0, hapd1 = start_ft_sae(dev[0], apdev, wpa_ptk_rekey=2,
1117 ext_key_id=True)
1118 check_ext_key_id_capa(hapd0)
1119 check_ext_key_id_capa(hapd1)
1120 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1121 only_one_way=True)
1122 check_ptk_rekey(dev[0], hapd0, hapd1)
1123 idx = int(dev[0].request("GET last_tk_key_idx"))
1124 if idx != 1:
1125 raise Exception("Unexpected Key ID after TK rekey: %d" % idx)
1126 finally:
1127 dev[0].set("extended_key_id", "0")
1128
6e658cc4
JM
1129def test_ap_ft_sae_over_ds(dev, apdev):
1130 """WPA2-PSK-FT-SAE AP over DS"""
425e5f97
JM
1131 hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1132 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
a8375c94 1133 over_ds=True)
6f62809b 1134
425e5f97
JM
1135def test_ap_ft_sae_over_ds_ptk_rekey0(dev, apdev):
1136 """WPA2-PSK-FT-SAE AP over DS and PTK rekey triggered by station"""
1137 hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1138 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1139 over_ds=True, ptk_rekey="1", roams=0)
1140 check_ptk_rekey(dev[0], hapd0, hapd1)
1141
1142def test_ap_ft_sae_over_ds_ptk_rekey1(dev, apdev):
1143 """WPA2-PSK-FT-SAE AP over DS and PTK rekey triggered by station"""
1144 hapd0, hapd1 = start_ft_sae(dev[0], apdev)
1145 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1146 over_ds=True, ptk_rekey="1", only_one_way=True)
1147 check_ptk_rekey(dev[0], hapd0, hapd1)
1148
1149def test_ap_ft_sae_over_ds_ptk_rekey_ap(dev, apdev):
1150 """WPA2-PSK-FT-SAE AP over DS and PTK rekey triggered by AP"""
1151 hapd0, hapd1 = start_ft_sae(dev[0], apdev, wpa_ptk_rekey=2)
1152 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1153 over_ds=True, only_one_way=True)
1154 check_ptk_rekey(dev[0], hapd0, hapd1)
1155
2b8f8a47
JM
1156def test_ap_ft_sae_h2e_rsne_override(dev, apdev):
1157 """WPA2-PSK-FT-SAE AP (H2E) and RSNE override (same value)"""
1158 try:
1159 dev[0].set("sae_pwe", "2")
1160 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
1161 rsne_override="30260100000fac040100000fac040100000fac090c000100" + 16*"ff")
1162 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
1163 finally:
1164 dev[0].set("sae_pwe", "0")
1165
1166def test_ap_ft_sae_h2e_rsnxe_override(dev, apdev):
1167 """WPA2-PSK-FT-SAE AP (H2E) and RSNXE override (same value)"""
1168 try:
1169 dev[0].set("sae_pwe", "2")
1170 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
1171 rsnxe_override="F40120")
1172 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
1173 finally:
1174 dev[0].set("sae_pwe", "0")
1175
1176def test_ap_ft_sae_h2e_rsne_mismatch(dev, apdev):
1177 """WPA2-PSK-FT-SAE AP (H2E) and RSNE mismatch"""
1178 try:
1179 dev[0].set("sae_pwe", "2")
1180 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
1181 rsne_override="30260100000fac040100000fac040100000fac090c010100" + 16*"ff")
1182 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1183 fail_test=True)
1184 finally:
1185 dev[0].set("sae_pwe", "0")
1186
1187def test_ap_ft_sae_h2e_rsne_mismatch_pmkr1name(dev, apdev):
1188 """WPA2-PSK-FT-SAE AP (H2E) and RSNE mismatch in PMKR1Name"""
1189 try:
1190 dev[0].set("sae_pwe", "2")
1191 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
1192 rsne_override="30260100000fac040100000fac040100000fac090c000100" + 16*"00")
1193 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1194 fail_test=True)
1195 finally:
1196 dev[0].set("sae_pwe", "0")
1197
1198def test_ap_ft_sae_h2e_rsnxe_mismatch(dev, apdev):
1199 """WPA2-PSK-FT-SAE AP (H2E) and RSNXE mismatch"""
1200 try:
1201 dev[0].set("sae_pwe", "2")
1202 hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
1203 rsnxe_override="F40160")
1204 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
1205 fail_test=True)
1206 finally:
1207 dev[0].set("sae_pwe", "0")
1208
3d5b88b5
JM
1209def test_ap_ft_sae_pw_id(dev, apdev):
1210 """FT-SAE with Password Identifier"""
1211 if "SAE" not in dev[0].get_capability("auth_alg"):
1212 raise HwsimSkip("SAE not supported")
1213 ssid = "test-ft"
1214
1215 params = ft_params1(ssid=ssid)
1216 params["ieee80211w"] = "2"
1217 params['wpa_key_mgmt'] = "FT-SAE"
1218 params['sae_password'] = 'secret|id=pwid'
1219 hapd0 = hostapd.add_ap(apdev[0], params)
1220 params = ft_params2(ssid=ssid)
1221 params["ieee80211w"] = "2"
1222 params['wpa_key_mgmt'] = "FT-SAE"
1223 params['sae_password'] = 'secret|id=pwid'
1224 hapd = hostapd.add_ap(apdev[1], params)
1225
1226 dev[0].request("SET sae_groups ")
1227 run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase=None, sae=True,
1228 sae_password="secret", sae_password_id="pwid")
1229
cdf53910
JM
1230def test_ap_ft_sae_with_both_akms(dev, apdev):
1231 """SAE + FT-SAE configuration"""
1232 if "SAE" not in dev[0].get_capability("auth_alg"):
1233 raise HwsimSkip("SAE not supported")
1234 ssid = "test-ft"
1235 passphrase = "12345678"
1236
1237 params = ft_params1(ssid=ssid, passphrase=passphrase)
1238 params['wpa_key_mgmt'] = "FT-SAE SAE"
1239 hapd0 = hostapd.add_ap(apdev[0], params)
1240 params = ft_params2(ssid=ssid, passphrase=passphrase)
1241 params['wpa_key_mgmt'] = "FT-SAE SAE"
1242 hapd = hostapd.add_ap(apdev[1], params)
1243 key_mgmt = hapd.get_config()['key_mgmt']
1244 if key_mgmt.split(' ')[0] != "FT-SAE":
1245 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1246
1247 dev[0].request("SET sae_groups ")
1248 run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
1249 sae_and_psk=True)
1250
1211031a
JM
1251def test_ap_ft_sae_pmksa_caching(dev, apdev):
1252 """WPA2-FT-SAE AP and PMKSA caching for initial mobility domain association"""
1253 if "SAE" not in dev[0].get_capability("auth_alg"):
1254 raise HwsimSkip("SAE not supported")
1255 ssid = "test-ft"
1256 passphrase = "12345678"
1257
1258 params = ft_params1(ssid=ssid, passphrase=passphrase)
1259 params['wpa_key_mgmt'] = "FT-SAE"
1260 hapd0 = hostapd.add_ap(apdev[0], params)
1261 params = ft_params2(ssid=ssid, passphrase=passphrase)
1262 params['wpa_key_mgmt'] = "FT-SAE"
1263 hapd = hostapd.add_ap(apdev[1], params)
1264 key_mgmt = hapd.get_config()['key_mgmt']
1265 if key_mgmt.split(' ')[0] != "FT-SAE":
1266 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1267
1268 dev[0].request("SET sae_groups ")
1269 run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
1270 pmksa_caching=True)
1271
c0f3ee47
JM
1272def test_ap_ft_sae_pmksa_caching_pwe(dev, apdev):
1273 """WPA2-FT-SAE AP and PMKSA caching for initial mobility domain association (STA PWE both)"""
1274 if "SAE" not in dev[0].get_capability("auth_alg"):
1275 raise HwsimSkip("SAE not supported")
1276 ssid = "test-ft"
1277 passphrase = "12345678"
1278
1279 params = ft_params1(ssid=ssid, passphrase=passphrase)
1280 params['wpa_key_mgmt'] = "FT-SAE"
1281 hapd0 = hostapd.add_ap(apdev[0], params)
1282 params = ft_params2(ssid=ssid, passphrase=passphrase)
1283 params['wpa_key_mgmt'] = "FT-SAE"
1284 hapd = hostapd.add_ap(apdev[1], params)
1285 key_mgmt = hapd.get_config()['key_mgmt']
1286 if key_mgmt.split(' ')[0] != "FT-SAE":
1287 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1288
1289 try:
1290 dev[0].request("SET sae_groups ")
1291 dev[0].set("sae_pwe", "2")
1292 run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
1293 pmksa_caching=True)
1294 finally:
1295 dev[0].set("sae_groups", "")
1296 dev[0].set("sae_pwe", "0")
1297
1298def test_ap_ft_sae_pmksa_caching_h2e(dev, apdev):
1299 """WPA2-FT-SAE AP and PMKSA caching for initial mobility domain association (H2E)"""
1300 if "SAE" not in dev[0].get_capability("auth_alg"):
1301 raise HwsimSkip("SAE not supported")
1302 ssid = "test-ft"
1303 passphrase = "12345678"
1304
1305 params = ft_params1(ssid=ssid, passphrase=passphrase)
1306 params['wpa_key_mgmt'] = "FT-SAE"
1307 params['sae_pwe'] = "1"
1308 hapd0 = hostapd.add_ap(apdev[0], params)
1309 params = ft_params2(ssid=ssid, passphrase=passphrase)
1310 params['wpa_key_mgmt'] = "FT-SAE"
1311 params['sae_pwe'] = "1"
1312 hapd = hostapd.add_ap(apdev[1], params)
1313 key_mgmt = hapd.get_config()['key_mgmt']
1314 if key_mgmt.split(' ')[0] != "FT-SAE":
1315 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1316
1317 try:
1318 dev[0].request("SET sae_groups ")
1319 dev[0].set("sae_pwe", "1")
1320 run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True,
1321 pmksa_caching=True)
1322 finally:
1323 dev[0].set("sae_groups", "")
1324 dev[0].set("sae_pwe", "0")
1325
d269740a 1326def generic_ap_ft_eap(dev, apdev, vlan=False, cui=False, over_ds=False,
425e5f97
JM
1327 discovery=False, roams=1, wpa_ptk_rekey=0,
1328 only_one_way=False):
6f62809b 1329 ssid = "test-ft"
fab49f61 1330 passphrase = "12345678"
9c50a6d3 1331 if vlan:
fab49f61
JM
1332 identity = "gpsk-vlan1"
1333 conndev = "brvlan1"
d269740a 1334 elif cui:
fab49f61
JM
1335 identity = "gpsk-cui"
1336 conndev = False
9c50a6d3 1337 else:
fab49f61
JM
1338 identity = "gpsk user"
1339 conndev = False
6f62809b
JM
1340
1341 radius = hostapd.radius_params()
942b52a8 1342 params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=discovery)
6f62809b
JM
1343 params['wpa_key_mgmt'] = "FT-EAP"
1344 params["ieee8021x"] = "1"
9c50a6d3
MB
1345 if vlan:
1346 params["dynamic_vlan"] = "1"
35d8c254 1347 params = dict(list(radius.items()) + list(params.items()))
8b8a1864 1348 hapd = hostapd.add_ap(apdev[0], params)
65038313
JM
1349 key_mgmt = hapd.get_config()['key_mgmt']
1350 if key_mgmt.split(' ')[0] != "FT-EAP":
1351 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
942b52a8 1352 params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=discovery)
6f62809b
JM
1353 params['wpa_key_mgmt'] = "FT-EAP"
1354 params["ieee8021x"] = "1"
9c50a6d3
MB
1355 if vlan:
1356 params["dynamic_vlan"] = "1"
425e5f97
JM
1357 if wpa_ptk_rekey:
1358 params["wpa_ptk_rekey"] = str(wpa_ptk_rekey)
35d8c254 1359 params = dict(list(radius.items()) + list(params.items()))
8b8a1864 1360 hapd1 = hostapd.add_ap(apdev[1], params)
6f62809b 1361
942b52a8 1362 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True,
9c50a6d3 1363 over_ds=over_ds, roams=roams, eap_identity=identity,
425e5f97 1364 conndev=conndev, only_one_way=only_one_way)
91bc6c36
JM
1365 if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"):
1366 raise Exception("Scan results missing RSN element info")
fab49f61
JM
1367 check_mib(dev[0], [("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"),
1368 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3")])
425e5f97
JM
1369 if only_one_way:
1370 return
aaba98d3 1371
4013d688
JM
1372 # Verify EAPOL reauthentication after FT protocol
1373 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
1374 ap = hapd
1375 else:
1376 ap = hapd1
1377 ap.request("EAPOL_REAUTH " + dev[0].own_addr())
1378 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
1379 if ev is None:
1380 raise Exception("EAP authentication did not start")
1381 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
1382 if ev is None:
1383 raise Exception("EAP authentication did not succeed")
1384 time.sleep(0.1)
9c50a6d3
MB
1385 if conndev:
1386 hwsim_utils.test_connectivity_iface(dev[0], ap, conndev)
1387 else:
1388 hwsim_utils.test_connectivity(dev[0], ap)
4013d688 1389
942b52a8
MB
1390def test_ap_ft_eap(dev, apdev):
1391 """WPA2-EAP-FT AP"""
1392 generic_ap_ft_eap(dev, apdev)
1393
d269740a
MB
1394def test_ap_ft_eap_cui(dev, apdev):
1395 """WPA2-EAP-FT AP with CUI"""
1396 generic_ap_ft_eap(dev, apdev, vlan=False, cui=True)
1397
9c50a6d3
MB
1398def test_ap_ft_eap_vlan(dev, apdev):
1399 """WPA2-EAP-FT AP with VLAN"""
1400 generic_ap_ft_eap(dev, apdev, vlan=True)
1401
1402def test_ap_ft_eap_vlan_multi(dev, apdev):
1403 """WPA2-EAP-FT AP with VLAN"""
1404 generic_ap_ft_eap(dev, apdev, vlan=True, roams=50)
1405
942b52a8
MB
1406def test_ap_ft_eap_over_ds(dev, apdev):
1407 """WPA2-EAP-FT AP using over-the-DS"""
1408 generic_ap_ft_eap(dev, apdev, over_ds=True)
1409
1410def test_ap_ft_eap_dis(dev, apdev):
1411 """WPA2-EAP-FT AP with AP discovery"""
1412 generic_ap_ft_eap(dev, apdev, discovery=True)
1413
1414def test_ap_ft_eap_dis_over_ds(dev, apdev):
1415 """WPA2-EAP-FT AP with AP discovery and over-the-DS"""
1416 generic_ap_ft_eap(dev, apdev, over_ds=True, discovery=True)
1417
9c50a6d3
MB
1418def test_ap_ft_eap_vlan(dev, apdev):
1419 """WPA2-EAP-FT AP with VLAN"""
1420 generic_ap_ft_eap(dev, apdev, vlan=True)
1421
1422def test_ap_ft_eap_vlan_multi(dev, apdev):
1423 """WPA2-EAP-FT AP with VLAN"""
1424 generic_ap_ft_eap(dev, apdev, vlan=True, roams=50)
1425
1426def test_ap_ft_eap_vlan_over_ds(dev, apdev):
1427 """WPA2-EAP-FT AP with VLAN + over_ds"""
1428 generic_ap_ft_eap(dev, apdev, vlan=True, over_ds=True)
1429
1430def test_ap_ft_eap_vlan_over_ds_multi(dev, apdev):
1431 """WPA2-EAP-FT AP with VLAN + over_ds"""
1432 generic_ap_ft_eap(dev, apdev, vlan=True, over_ds=True, roams=50)
1433
1434def generic_ap_ft_eap_pull(dev, apdev, vlan=False):
aaba98d3
JM
1435 """WPA2-EAP-FT AP (pull PMK)"""
1436 ssid = "test-ft"
fab49f61 1437 passphrase = "12345678"
9c50a6d3 1438 if vlan:
fab49f61
JM
1439 identity = "gpsk-vlan1"
1440 conndev = "brvlan1"
9c50a6d3 1441 else:
fab49f61
JM
1442 identity = "gpsk user"
1443 conndev = False
aaba98d3
JM
1444
1445 radius = hostapd.radius_params()
1446 params = ft_params1(ssid=ssid, passphrase=passphrase)
1447 params['wpa_key_mgmt'] = "FT-EAP"
1448 params["ieee8021x"] = "1"
1449 params["pmk_r1_push"] = "0"
9c50a6d3
MB
1450 if vlan:
1451 params["dynamic_vlan"] = "1"
35d8c254 1452 params = dict(list(radius.items()) + list(params.items()))
8b8a1864 1453 hapd = hostapd.add_ap(apdev[0], params)
aaba98d3
JM
1454 key_mgmt = hapd.get_config()['key_mgmt']
1455 if key_mgmt.split(' ')[0] != "FT-EAP":
1456 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
1457 params = ft_params2(ssid=ssid, passphrase=passphrase)
1458 params['wpa_key_mgmt'] = "FT-EAP"
1459 params["ieee8021x"] = "1"
1460 params["pmk_r1_push"] = "0"
9c50a6d3
MB
1461 if vlan:
1462 params["dynamic_vlan"] = "1"
35d8c254 1463 params = dict(list(radius.items()) + list(params.items()))
8b8a1864 1464 hapd1 = hostapd.add_ap(apdev[1], params)
aaba98d3 1465
9c50a6d3
MB
1466 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True,
1467 eap_identity=identity, conndev=conndev)
1468
1469def test_ap_ft_eap_pull(dev, apdev):
1470 """WPA2-EAP-FT AP (pull PMK)"""
1471 generic_ap_ft_eap_pull(dev, apdev)
1472
1473def test_ap_ft_eap_pull_vlan(dev, apdev):
1474 generic_ap_ft_eap_pull(dev, apdev, vlan=True)
3b808945 1475
f81c1411
JM
1476def test_ap_ft_eap_pull_wildcard(dev, apdev):
1477 """WPA2-EAP-FT AP (pull PMK) - wildcard R0KH/R1KH"""
1478 ssid = "test-ft"
fab49f61 1479 passphrase = "12345678"
f81c1411
JM
1480
1481 radius = hostapd.radius_params()
1482 params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
1483 params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
1484 params["ieee8021x"] = "1"
1485 params["pmk_r1_push"] = "0"
1486 params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1487 params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1488 params["ft_psk_generate_local"] = "1"
1489 params["eap_server"] = "0"
c6ab7b55
JM
1490 params["rkh_pos_timeout"] = "100"
1491 params["rkh_neg_timeout"] = "50"
1492 params["rkh_pull_timeout"] = "1234"
1493 params["rkh_pull_retries"] = "10"
35d8c254 1494 params = dict(list(radius.items()) + list(params.items()))
f81c1411
JM
1495 hapd = hostapd.add_ap(apdev[0], params)
1496 params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=True)
1497 params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
1498 params["ieee8021x"] = "1"
1499 params["pmk_r1_push"] = "0"
1500 params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1501 params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1502 params["ft_psk_generate_local"] = "1"
1503 params["eap_server"] = "0"
35d8c254 1504 params = dict(list(radius.items()) + list(params.items()))
f81c1411
JM
1505 hapd1 = hostapd.add_ap(apdev[1], params)
1506
1507 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
1508
0d0baf9f
JM
1509def test_ap_ft_eap_pull_wildcard_multi_bss(dev, apdev, params):
1510 """WPA2-EAP-FT AP (pull PMK) - wildcard R0KH/R1KH with multiple BSSs"""
1511 bssconf = os.path.join(params['logdir'],
1512 'ap_ft_eap_pull_wildcard_multi_bss.bss.conf')
1513 ssid = "test-ft"
1514 passphrase = "12345678"
1515 radius = hostapd.radius_params()
1516
1517 params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
1518 params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
1519 params["ieee8021x"] = "1"
1520 params["pmk_r1_push"] = "0"
1521 params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1522 params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1523 params["eap_server"] = "0"
1524 params = dict(list(radius.items()) + list(params.items()))
1525 hapd = hostapd.add_ap(apdev[0], params)
1526 ifname2 = apdev[0]['ifname'] + "-2"
1527 bssid2 = "02:00:00:00:03:01"
1528 params['nas_identifier'] = "nas1b.w1.fi"
1529 params['r1_key_holder'] = "000102030415"
1530 with open(bssconf, 'w') as f:
1531 f.write("driver=nl80211\n")
1532 f.write("hw_mode=g\n")
1533 f.write("channel=1\n")
1534 f.write("ieee80211n=1\n")
1535 f.write("interface=%s\n" % ifname2)
1536 f.write("bssid=%s\n" % bssid2)
1537 f.write("ctrl_interface=/var/run/hostapd\n")
1538 for name, val in params.items():
1539 f.write("%s=%s\n" % (name, val))
1540 hapd2 = hostapd.add_bss(apdev[0], ifname2, bssconf)
1541
1542 params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=True)
1543 params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
1544 params["ieee8021x"] = "1"
1545 params["pmk_r1_push"] = "0"
1546 params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1547 params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
1548 params["eap_server"] = "0"
1549 params = dict(list(radius.items()) + list(params.items()))
1550 hapd1 = hostapd.add_ap(apdev[1], params)
1551
1552 # The first iteration of the roaming test will use wildcard R0KH discovery
1553 # and RRB sequence number synchronization while the second iteration shows
1554 # the clean RRB exchange where those extra steps are not needed.
1555 for i in range(2):
1556 hapd.note("Test iteration %d" % i)
1557 dev[0].note("Test iteration %d" % i)
1558
1559 id = dev[0].connect(ssid, key_mgmt="FT-EAP", eap="GPSK",
1560 identity="gpsk user",
1561 password="abcdefghijklmnop0123456789abcdef",
1562 bssid=bssid2,
1563 scan_freq="2412")
1564 res = dev[0].get_status_field("bssid")
1565 if res != bssid2:
1566 raise Exception("Unexpected BSSID after initial connection: " + res)
1567
1568 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1569 dev[0].set_network(id, "bssid", "00:00:00:00:00:00")
1570 dev[0].roam(apdev[1]['bssid'])
1571 res = dev[0].get_status_field("bssid")
1572 if res != apdev[1]['bssid']:
1573 raise Exception("Unexpected BSSID after first roam: " + res)
1574
1575 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1576 dev[0].roam(apdev[0]['bssid'])
1577 res = dev[0].get_status_field("bssid")
1578 if res != apdev[0]['bssid']:
1579 raise Exception("Unexpected BSSID after second roam: " + res)
1580
1581 dev[0].request("REMOVE_NETWORK all")
1582 dev[0].wait_disconnected()
1583 dev[0].dump_monitor()
1584 hapd.dump_monitor()
1585 hapd2.dump_monitor()
1586
9fd6804d 1587@remote_compatible
3b808945
JM
1588def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
1589 """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
1590 ssid = "test-ft"
fab49f61 1591 passphrase = "12345678"
3b808945
JM
1592
1593 params = ft_params1(ssid=ssid, passphrase=passphrase)
bc6e3288 1594 params["ieee80211w"] = "2"
8b8a1864 1595 hapd0 = hostapd.add_ap(apdev[0], params)
3b808945 1596 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
bc6e3288 1597 params["ieee80211w"] = "2"
8b8a1864 1598 hapd1 = hostapd.add_ap(apdev[1], params)
3b808945 1599
a8375c94
JM
1600 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1601 fail_test=True)
3b808945 1602
9fd6804d 1603@remote_compatible
3b808945
JM
1604def test_ap_ft_mismatching_rrb_key_pull(dev, apdev):
1605 """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
1606 ssid = "test-ft"
fab49f61 1607 passphrase = "12345678"
3b808945
JM
1608
1609 params = ft_params1(ssid=ssid, passphrase=passphrase)
1610 params["pmk_r1_push"] = "0"
8b8a1864 1611 hapd0 = hostapd.add_ap(apdev[0], params)
3b808945
JM
1612 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
1613 params["pmk_r1_push"] = "0"
8b8a1864 1614 hapd1 = hostapd.add_ap(apdev[1], params)
3b808945 1615
a8375c94
JM
1616 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1617 fail_test=True)
3b808945 1618
9fd6804d 1619@remote_compatible
ae14a2e2
JM
1620def test_ap_ft_mismatching_r0kh_id_pull(dev, apdev):
1621 """WPA2-PSK-FT AP over DS with mismatching R0KH-ID (pull)"""
1622 ssid = "test-ft"
fab49f61 1623 passphrase = "12345678"
ae14a2e2
JM
1624
1625 params = ft_params1(ssid=ssid, passphrase=passphrase)
1626 params["pmk_r1_push"] = "0"
1627 params["nas_identifier"] = "nas0.w1.fi"
8b8a1864 1628 hostapd.add_ap(apdev[0], params)
2f816c21
JM
1629 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1630 scan_freq="2412")
ae14a2e2
JM
1631
1632 params = ft_params2(ssid=ssid, passphrase=passphrase)
1633 params["pmk_r1_push"] = "0"
8b8a1864 1634 hostapd.add_ap(apdev[1], params)
ae14a2e2
JM
1635
1636 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1637 dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
1638
9fd6804d 1639@remote_compatible
3b808945
JM
1640def test_ap_ft_mismatching_rrb_r0kh_push(dev, apdev):
1641 """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
1642 ssid = "test-ft"
fab49f61 1643 passphrase = "12345678"
3b808945
JM
1644
1645 params = ft_params1(ssid=ssid, passphrase=passphrase)
bc6e3288 1646 params["ieee80211w"] = "2"
8b8a1864 1647 hapd0 = hostapd.add_ap(apdev[0], params)
3b808945 1648 params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
bc6e3288 1649 params["ieee80211w"] = "2"
8b8a1864 1650 hapd1 = hostapd.add_ap(apdev[1], params)
3b808945 1651
a8375c94
JM
1652 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1653 fail_test=True)
3b808945 1654
9fd6804d 1655@remote_compatible
3b808945
JM
1656def test_ap_ft_mismatching_rrb_r0kh_pull(dev, apdev):
1657 """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
1658 ssid = "test-ft"
fab49f61 1659 passphrase = "12345678"
3b808945
JM
1660
1661 params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
1662 params["pmk_r1_push"] = "0"
8b8a1864 1663 hapd0 = hostapd.add_ap(apdev[0], params)
3b808945
JM
1664 params = ft_params2(ssid=ssid, passphrase=passphrase)
1665 params["pmk_r1_push"] = "0"
8b8a1864 1666 hapd1 = hostapd.add_ap(apdev[1], params)
3b808945 1667
a8375c94
JM
1668 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1669 fail_test=True)
c6b6e105 1670
150948e6
MB
1671def test_ap_ft_mismatching_rrb_key_push_eap(dev, apdev):
1672 """WPA2-EAP-FT AP over DS with mismatching RRB key (push)"""
1673 ssid = "test-ft"
fab49f61 1674 passphrase = "12345678"
150948e6
MB
1675
1676 radius = hostapd.radius_params()
1677 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 1678 params["ieee80211w"] = "2"
150948e6
MB
1679 params['wpa_key_mgmt'] = "FT-EAP"
1680 params["ieee8021x"] = "1"
35d8c254 1681 params = dict(list(radius.items()) + list(params.items()))
b098542c 1682 hapd0 = hostapd.add_ap(apdev[0], params)
150948e6 1683 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
58be42b2 1684 params["ieee80211w"] = "2"
150948e6
MB
1685 params['wpa_key_mgmt'] = "FT-EAP"
1686 params["ieee8021x"] = "1"
35d8c254 1687 params = dict(list(radius.items()) + list(params.items()))
b098542c 1688 hapd1 = hostapd.add_ap(apdev[1], params)
150948e6
MB
1689
1690 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1691 fail_test=True, eap=True)
1692
1693def test_ap_ft_mismatching_rrb_key_pull_eap(dev, apdev):
1694 """WPA2-EAP-FT AP over DS with mismatching RRB key (pull)"""
1695 ssid = "test-ft"
fab49f61 1696 passphrase = "12345678"
150948e6
MB
1697
1698 radius = hostapd.radius_params()
1699 params = ft_params1(ssid=ssid, passphrase=passphrase)
1700 params["pmk_r1_push"] = "0"
1701 params['wpa_key_mgmt'] = "FT-EAP"
1702 params["ieee8021x"] = "1"
35d8c254 1703 params = dict(list(radius.items()) + list(params.items()))
b098542c 1704 hapd0 = hostapd.add_ap(apdev[0], params)
150948e6
MB
1705 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
1706 params["pmk_r1_push"] = "0"
1707 params['wpa_key_mgmt'] = "FT-EAP"
1708 params["ieee8021x"] = "1"
35d8c254 1709 params = dict(list(radius.items()) + list(params.items()))
b098542c 1710 hapd1 = hostapd.add_ap(apdev[1], params)
150948e6
MB
1711
1712 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1713 fail_test=True, eap=True)
1714
1715def test_ap_ft_mismatching_r0kh_id_pull_eap(dev, apdev):
1716 """WPA2-EAP-FT AP over DS with mismatching R0KH-ID (pull)"""
1717 ssid = "test-ft"
fab49f61 1718 passphrase = "12345678"
150948e6
MB
1719
1720 radius = hostapd.radius_params()
1721 params = ft_params1(ssid=ssid, passphrase=passphrase)
1722 params["pmk_r1_push"] = "0"
1723 params["nas_identifier"] = "nas0.w1.fi"
1724 params['wpa_key_mgmt'] = "FT-EAP"
1725 params["ieee8021x"] = "1"
35d8c254 1726 params = dict(list(radius.items()) + list(params.items()))
b098542c 1727 hostapd.add_ap(apdev[0], params)
150948e6
MB
1728 dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
1729 eap="GPSK", identity="gpsk user",
1730 password="abcdefghijklmnop0123456789abcdef",
1731 scan_freq="2412")
1732
1733 params = ft_params2(ssid=ssid, passphrase=passphrase)
1734 params["pmk_r1_push"] = "0"
1735 params['wpa_key_mgmt'] = "FT-EAP"
1736 params["ieee8021x"] = "1"
35d8c254 1737 params = dict(list(radius.items()) + list(params.items()))
b098542c 1738 hostapd.add_ap(apdev[1], params)
150948e6
MB
1739
1740 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1741 dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
1742
1743def test_ap_ft_mismatching_rrb_r0kh_push_eap(dev, apdev):
1744 """WPA2-EAP-FT AP over DS with mismatching R0KH key (push)"""
1745 ssid = "test-ft"
fab49f61 1746 passphrase = "12345678"
150948e6
MB
1747
1748 radius = hostapd.radius_params()
1749 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 1750 params["ieee80211w"] = "2"
150948e6
MB
1751 params['wpa_key_mgmt'] = "FT-EAP"
1752 params["ieee8021x"] = "1"
35d8c254 1753 params = dict(list(radius.items()) + list(params.items()))
b098542c 1754 hapd0 = hostapd.add_ap(apdev[0], params)
150948e6 1755 params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
58be42b2 1756 params["ieee80211w"] = "2"
150948e6
MB
1757 params['wpa_key_mgmt'] = "FT-EAP"
1758 params["ieee8021x"] = "1"
35d8c254 1759 params = dict(list(radius.items()) + list(params.items()))
b098542c 1760 hapd1 = hostapd.add_ap(apdev[1], params)
150948e6
MB
1761
1762 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1763 fail_test=True, eap=True)
1764
1765def test_ap_ft_mismatching_rrb_r0kh_pull_eap(dev, apdev):
1766 """WPA2-EAP-FT AP over DS with mismatching R0KH key (pull)"""
1767 ssid = "test-ft"
fab49f61 1768 passphrase = "12345678"
150948e6
MB
1769
1770 radius = hostapd.radius_params()
1771 params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
1772 params["pmk_r1_push"] = "0"
1773 params['wpa_key_mgmt'] = "FT-EAP"
1774 params["ieee8021x"] = "1"
35d8c254 1775 params = dict(list(radius.items()) + list(params.items()))
b098542c 1776 hapd0 = hostapd.add_ap(apdev[0], params)
150948e6
MB
1777 params = ft_params2(ssid=ssid, passphrase=passphrase)
1778 params["pmk_r1_push"] = "0"
1779 params['wpa_key_mgmt'] = "FT-EAP"
1780 params["ieee8021x"] = "1"
35d8c254 1781 params = dict(list(radius.items()) + list(params.items()))
b098542c 1782 hapd1 = hostapd.add_ap(apdev[1], params)
150948e6
MB
1783
1784 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
1785 fail_test=True, eap=True)
1786
c6b6e105
JM
1787def test_ap_ft_gtk_rekey(dev, apdev):
1788 """WPA2-PSK-FT AP and GTK rekey"""
1789 ssid = "test-ft"
fab49f61 1790 passphrase = "12345678"
c6b6e105
JM
1791
1792 params = ft_params1(ssid=ssid, passphrase=passphrase)
1793 params['wpa_group_rekey'] = '1'
8b8a1864 1794 hapd = hostapd.add_ap(apdev[0], params)
c6b6e105
JM
1795
1796 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2f816c21 1797 ieee80211w="1", scan_freq="2412")
c6b6e105
JM
1798
1799 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
1800 if ev is None:
1801 raise Exception("GTK rekey timed out after initial association")
a8375c94 1802 hwsim_utils.test_connectivity(dev[0], hapd)
c6b6e105
JM
1803
1804 params = ft_params2(ssid=ssid, passphrase=passphrase)
1805 params['wpa_group_rekey'] = '1'
8b8a1864 1806 hapd1 = hostapd.add_ap(apdev[1], params)
c6b6e105
JM
1807
1808 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1809 dev[0].roam(apdev[1]['bssid'])
1810 if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
1811 raise Exception("Did not connect to correct AP")
a8375c94 1812 hwsim_utils.test_connectivity(dev[0], hapd1)
c6b6e105
JM
1813
1814 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
1815 if ev is None:
1816 raise Exception("GTK rekey timed out after FT protocol")
a8375c94 1817 hwsim_utils.test_connectivity(dev[0], hapd1)
5b3c40a6
JM
1818
1819def test_ft_psk_key_lifetime_in_memory(dev, apdev, params):
1820 """WPA2-PSK-FT and key lifetime in memory"""
1821 ssid = "test-ft"
fab49f61 1822 passphrase = "04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0"
5b3c40a6
JM
1823 psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d'
1824 pmk = binascii.unhexlify(psk)
1825 p = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 1826 hapd0 = hostapd.add_ap(apdev[0], p)
5b3c40a6 1827 p = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 1828 hapd1 = hostapd.add_ap(apdev[1], p)
5b3c40a6
JM
1829
1830 pid = find_wpas_process(dev[0])
1831
1832 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1833 scan_freq="2412")
8e416cec
JM
1834 # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
1835 # event has been delivered, so verify that wpa_supplicant has returned to
1836 # eloop before reading process memory.
54f2cae2 1837 time.sleep(1)
8e416cec 1838 dev[0].ping()
5b3c40a6
JM
1839
1840 buf = read_process_memory(pid, pmk)
1841
1842 dev[0].request("DISCONNECT")
1843 dev[0].wait_disconnected()
1844
1845 dev[0].relog()
1846 pmkr0 = None
1847 pmkr1 = None
1848 ptk = None
1849 gtk = None
1850 with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
1851 for l in f.readlines():
1852 if "FT: PMK-R0 - hexdump" in l:
1853 val = l.strip().split(':')[3].replace(' ', '')
1854 pmkr0 = binascii.unhexlify(val)
1855 if "FT: PMK-R1 - hexdump" in l:
1856 val = l.strip().split(':')[3].replace(' ', '')
1857 pmkr1 = binascii.unhexlify(val)
f918b95b 1858 if "FT: KCK - hexdump" in l:
5b3c40a6 1859 val = l.strip().split(':')[3].replace(' ', '')
f918b95b
JM
1860 kck = binascii.unhexlify(val)
1861 if "FT: KEK - hexdump" in l:
1862 val = l.strip().split(':')[3].replace(' ', '')
1863 kek = binascii.unhexlify(val)
1864 if "FT: TK - hexdump" in l:
1865 val = l.strip().split(':')[3].replace(' ', '')
1866 tk = binascii.unhexlify(val)
5b3c40a6
JM
1867 if "WPA: Group Key - hexdump" in l:
1868 val = l.strip().split(':')[3].replace(' ', '')
1869 gtk = binascii.unhexlify(val)
f918b95b 1870 if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk:
5b3c40a6
JM
1871 raise Exception("Could not find keys from debug log")
1872 if len(gtk) != 16:
1873 raise Exception("Unexpected GTK length")
1874
5b3c40a6
JM
1875 logger.info("Checking keys in memory while associated")
1876 get_key_locations(buf, pmk, "PMK")
1877 get_key_locations(buf, pmkr0, "PMK-R0")
1878 get_key_locations(buf, pmkr1, "PMK-R1")
1879 if pmk not in buf:
81e787b7 1880 raise HwsimSkip("PMK not found while associated")
5b3c40a6 1881 if pmkr0 not in buf:
81e787b7 1882 raise HwsimSkip("PMK-R0 not found while associated")
5b3c40a6 1883 if pmkr1 not in buf:
81e787b7 1884 raise HwsimSkip("PMK-R1 not found while associated")
5b3c40a6
JM
1885 if kck not in buf:
1886 raise Exception("KCK not found while associated")
1887 if kek not in buf:
1888 raise Exception("KEK not found while associated")
b74f82a4
JM
1889 #if tk in buf:
1890 # raise Exception("TK found from memory")
5b3c40a6
JM
1891
1892 logger.info("Checking keys in memory after disassociation")
1893 buf = read_process_memory(pid, pmk)
1894 get_key_locations(buf, pmk, "PMK")
1895 get_key_locations(buf, pmkr0, "PMK-R0")
1896 get_key_locations(buf, pmkr1, "PMK-R1")
1897
1898 # Note: PMK/PSK is still present in network configuration
1899
1900 fname = os.path.join(params['logdir'],
1901 'ft_psk_key_lifetime_in_memory.memctx-')
1902 verify_not_present(buf, pmkr0, fname, "PMK-R0")
1903 verify_not_present(buf, pmkr1, fname, "PMK-R1")
1904 verify_not_present(buf, kck, fname, "KCK")
1905 verify_not_present(buf, kek, fname, "KEK")
1906 verify_not_present(buf, tk, fname, "TK")
6db556b2
JM
1907 if gtk in buf:
1908 get_key_locations(buf, gtk, "GTK")
5b3c40a6
JM
1909 verify_not_present(buf, gtk, fname, "GTK")
1910
1911 dev[0].request("REMOVE_NETWORK all")
1912
1913 logger.info("Checking keys in memory after network profile removal")
1914 buf = read_process_memory(pid, pmk)
1915 get_key_locations(buf, pmk, "PMK")
1916 get_key_locations(buf, pmkr0, "PMK-R0")
1917 get_key_locations(buf, pmkr1, "PMK-R1")
1918
1919 verify_not_present(buf, pmk, fname, "PMK")
1920 verify_not_present(buf, pmkr0, fname, "PMK-R0")
1921 verify_not_present(buf, pmkr1, fname, "PMK-R1")
1922 verify_not_present(buf, kck, fname, "KCK")
1923 verify_not_present(buf, kek, fname, "KEK")
1924 verify_not_present(buf, tk, fname, "TK")
1925 verify_not_present(buf, gtk, fname, "GTK")
664093b5 1926
9fd6804d 1927@remote_compatible
664093b5
JM
1928def test_ap_ft_invalid_resp(dev, apdev):
1929 """WPA2-PSK-FT AP and invalid response IEs"""
1930 ssid = "test-ft"
fab49f61 1931 passphrase = "12345678"
664093b5
JM
1932
1933 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 1934 hapd0 = hostapd.add_ap(apdev[0], params)
664093b5
JM
1935 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
1936 scan_freq="2412")
1937
1938 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 1939 hapd1 = hostapd.add_ap(apdev[1], params)
664093b5
JM
1940
1941 tests = [
1942 # Various IEs for test coverage. The last one is FTIE with invalid
1943 # R1KH-ID subelement.
1944 "020002000000" + "3800" + "38051122334455" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010100",
1945 # FTIE with invalid R0KH-ID subelement (len=0).
1946 "020002000000" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010300",
1947 # FTIE with invalid R0KH-ID subelement (len=49).
1948 "020002000000" + "378500010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001033101020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849",
1949 # Invalid RSNE.
1950 "020002000000" + "3000",
1951 # Required IEs missing from protected IE count.
1952 "020002000000" + "3603a1b201" + "375200010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
1953 # RIC missing from protected IE count.
1954 "020002000000" + "3603a1b201" + "375200020203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
1955 # Protected IE missing.
fab49f61 1956 "020002000000" + "3603a1b201" + "375200ff0203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900" + "0000"]
664093b5
JM
1957 for t in tests:
1958 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
1959 hapd1.set("ext_mgmt_frame_handling", "1")
1960 hapd1.dump_monitor()
1961 if "OK" not in dev[0].request("ROAM " + apdev[1]['bssid']):
1962 raise Exception("ROAM failed")
1963 auth = None
1964 for i in range(20):
1965 msg = hapd1.mgmt_rx()
1966 if msg['subtype'] == 11:
1967 auth = msg
1968 break
1969 if not auth:
1970 raise Exception("Authentication frame not seen")
1971
1972 resp = {}
1973 resp['fc'] = auth['fc']
1974 resp['da'] = auth['sa']
1975 resp['sa'] = auth['da']
1976 resp['bssid'] = auth['bssid']
1977 resp['payload'] = binascii.unhexlify(t)
1978 hapd1.mgmt_tx(resp)
1979 hapd1.set("ext_mgmt_frame_handling", "0")
1980 dev[0].wait_disconnected()
1981
1982 dev[0].request("RECONNECT")
1983 dev[0].wait_connected()
7b741a53
JM
1984
1985def test_ap_ft_gcmp_256(dev, apdev):
1986 """WPA2-PSK-FT AP with GCMP-256 cipher"""
1987 if "GCMP-256" not in dev[0].get_capability("pairwise"):
1988 raise HwsimSkip("Cipher GCMP-256 not supported")
1989 ssid = "test-ft"
fab49f61 1990 passphrase = "12345678"
7b741a53
JM
1991
1992 params = ft_params1(ssid=ssid, passphrase=passphrase)
1993 params['rsn_pairwise'] = "GCMP-256"
8b8a1864 1994 hapd0 = hostapd.add_ap(apdev[0], params)
7b741a53
JM
1995 params = ft_params2(ssid=ssid, passphrase=passphrase)
1996 params['rsn_pairwise'] = "GCMP-256"
8b8a1864 1997 hapd1 = hostapd.add_ap(apdev[1], params)
7b741a53
JM
1998
1999 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
2000 pairwise_cipher="GCMP-256", group_cipher="GCMP-256")
cf671d54 2001
63a7683b 2002def setup_ap_ft_oom(dev, apdev):
38934ed1 2003 skip_with_fips(dev[0])
cf671d54 2004 ssid = "test-ft"
fab49f61 2005 passphrase = "12345678"
cf671d54
JM
2006
2007 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 2008 hapd0 = hostapd.add_ap(apdev[0], params)
cf671d54 2009 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 2010 hapd1 = hostapd.add_ap(apdev[1], params)
cf671d54
JM
2011
2012 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2013 scan_freq="2412")
2014 if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
2015 dst = apdev[1]['bssid']
2016 else:
2017 dst = apdev[0]['bssid']
2018
2019 dev[0].scan_for_bss(dst, freq="2412")
63a7683b
JM
2020
2021 return dst
2022
2023def test_ap_ft_oom(dev, apdev):
2024 """WPA2-PSK-FT and OOM"""
2025 dst = setup_ap_ft_oom(dev, apdev)
cf671d54 2026 with alloc_fail(dev[0], 1, "wpa_ft_gen_req_ies"):
2b8f8a47 2027 dev[0].roam(dst, check_bssid=False, fail_test=True)
63a7683b
JM
2028
2029def test_ap_ft_oom2(dev, apdev):
2030 """WPA2-PSK-FT and OOM (2)"""
2031 dst = setup_ap_ft_oom(dev, apdev)
7cbc8e67 2032 with fail_test(dev[0], 1, "wpa_ft_mic"):
63a7683b
JM
2033 dev[0].roam(dst, fail_test=True, assoc_reject_ok=True)
2034
2035def test_ap_ft_oom3(dev, apdev):
2036 """WPA2-PSK-FT and OOM (3)"""
2037 dst = setup_ap_ft_oom(dev, apdev)
cf671d54 2038 with fail_test(dev[0], 1, "os_get_random;wpa_ft_prepare_auth_request"):
63a7683b 2039 dev[0].roam(dst)
34d3eaa8 2040
63a7683b
JM
2041def test_ap_ft_oom4(dev, apdev):
2042 """WPA2-PSK-FT and OOM (4)"""
2043 ssid = "test-ft"
fab49f61 2044 passphrase = "12345678"
63a7683b 2045 dst = setup_ap_ft_oom(dev, apdev)
dcbb5d80
JM
2046 dev[0].request("REMOVE_NETWORK all")
2047 with alloc_fail(dev[0], 1, "=sme_update_ft_ies"):
2048 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2049 scan_freq="2412")
2050
682a79f0
JM
2051def test_ap_ft_ap_oom(dev, apdev):
2052 """WPA2-PSK-FT and AP OOM"""
2053 ssid = "test-ft"
fab49f61 2054 passphrase = "12345678"
682a79f0
JM
2055
2056 params = ft_params1(ssid=ssid, passphrase=passphrase)
2057 hapd0 = hostapd.add_ap(apdev[0], params)
2058 bssid0 = hapd0.own_addr()
2059
2060 dev[0].scan_for_bss(bssid0, freq="2412")
2061 with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r0"):
2062 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2063 scan_freq="2412")
2064
2065 params = ft_params2(ssid=ssid, passphrase=passphrase)
2066 hapd1 = hostapd.add_ap(apdev[1], params)
2067 bssid1 = hapd1.own_addr()
2068 dev[0].scan_for_bss(bssid1, freq="2412")
2069 # This roam will fail due to missing PMK-R0 (OOM prevented storing it)
fd189288 2070 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2071
2072def test_ap_ft_ap_oom2(dev, apdev):
2073 """WPA2-PSK-FT and AP OOM 2"""
2074 ssid = "test-ft"
fab49f61 2075 passphrase = "12345678"
682a79f0
JM
2076
2077 params = ft_params1(ssid=ssid, passphrase=passphrase)
2078 hapd0 = hostapd.add_ap(apdev[0], params)
2079 bssid0 = hapd0.own_addr()
2080
2081 dev[0].scan_for_bss(bssid0, freq="2412")
2082 with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r1"):
2083 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2084 scan_freq="2412")
2085
2086 params = ft_params2(ssid=ssid, passphrase=passphrase)
2087 hapd1 = hostapd.add_ap(apdev[1], params)
2088 bssid1 = hapd1.own_addr()
2089 dev[0].scan_for_bss(bssid1, freq="2412")
2090 dev[0].roam(bssid1)
2091 if dev[0].get_status_field('bssid') != bssid1:
2092 raise Exception("Did not roam to AP1")
2093 # This roam will fail due to missing PMK-R1 (OOM prevented storing it)
2094 dev[0].roam(bssid0)
2095
2096def test_ap_ft_ap_oom3(dev, apdev):
2097 """WPA2-PSK-FT and AP OOM 3"""
2098 ssid = "test-ft"
fab49f61 2099 passphrase = "12345678"
682a79f0
JM
2100
2101 params = ft_params1(ssid=ssid, passphrase=passphrase)
2102 hapd0 = hostapd.add_ap(apdev[0], params)
2103 bssid0 = hapd0.own_addr()
2104
2105 dev[0].scan_for_bss(bssid0, freq="2412")
2106 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2107 scan_freq="2412")
2108
2109 params = ft_params2(ssid=ssid, passphrase=passphrase)
2110 hapd1 = hostapd.add_ap(apdev[1], params)
2111 bssid1 = hapd1.own_addr()
2112 dev[0].scan_for_bss(bssid1, freq="2412")
2113 with alloc_fail(hapd1, 1, "wpa_ft_pull_pmk_r1"):
2114 # This will fail due to not being able to send out PMK-R1 pull request
fd189288 2115 dev[0].roam(bssid1, check_bssid=False)
682a79f0 2116
ba88dd65 2117 with fail_test(hapd1, 2, "os_get_random;wpa_ft_pull_pmk_r1"):
682a79f0 2118 # This will fail due to not being able to send out PMK-R1 pull request
fd189288 2119 dev[0].roam(bssid1, check_bssid=False)
682a79f0 2120
ba88dd65
MB
2121 with fail_test(hapd1, 2, "aes_siv_encrypt;wpa_ft_pull_pmk_r1"):
2122 # This will fail due to not being able to send out PMK-R1 pull request
fd189288 2123 dev[0].roam(bssid1, check_bssid=False)
ba88dd65
MB
2124
2125def test_ap_ft_ap_oom3b(dev, apdev):
2126 """WPA2-PSK-FT and AP OOM 3b"""
2127 ssid = "test-ft"
fab49f61 2128 passphrase = "12345678"
ba88dd65
MB
2129
2130 params = ft_params1(ssid=ssid, passphrase=passphrase)
2131 hapd0 = hostapd.add_ap(apdev[0], params)
2132 bssid0 = hapd0.own_addr()
2133
2134 dev[0].scan_for_bss(bssid0, freq="2412")
2135 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2136 scan_freq="2412")
2137
2138 params = ft_params2(ssid=ssid, passphrase=passphrase)
2139 hapd1 = hostapd.add_ap(apdev[1], params)
2140 bssid1 = hapd1.own_addr()
2141 dev[0].scan_for_bss(bssid1, freq="2412")
2142 with fail_test(hapd1, 1, "os_get_random;wpa_ft_pull_pmk_r1"):
682a79f0
JM
2143 # This will fail due to not being able to send out PMK-R1 pull request
2144 dev[0].roam(bssid1)
2145
2146def test_ap_ft_ap_oom4(dev, apdev):
2147 """WPA2-PSK-FT and AP OOM 4"""
2148 ssid = "test-ft"
fab49f61 2149 passphrase = "12345678"
682a79f0
JM
2150
2151 params = ft_params1(ssid=ssid, passphrase=passphrase)
2152 hapd0 = hostapd.add_ap(apdev[0], params)
2153 bssid0 = hapd0.own_addr()
2154
2155 dev[0].scan_for_bss(bssid0, freq="2412")
2156 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2157 scan_freq="2412")
2158
2159 params = ft_params2(ssid=ssid, passphrase=passphrase)
2160 hapd1 = hostapd.add_ap(apdev[1], params)
2161 bssid1 = hapd1.own_addr()
2162 dev[0].scan_for_bss(bssid1, freq="2412")
2163 with alloc_fail(hapd1, 1, "wpa_ft_gtk_subelem"):
2164 dev[0].roam(bssid1)
2165 if dev[0].get_status_field('bssid') != bssid1:
2166 raise Exception("Did not roam to AP1")
2167
360d8d4e 2168 with fail_test(hapd0, 1, "i802_get_seqnum;wpa_ft_gtk_subelem"):
682a79f0
JM
2169 dev[0].roam(bssid0)
2170 if dev[0].get_status_field('bssid') != bssid0:
2171 raise Exception("Did not roam to AP0")
2172
2173 with fail_test(hapd0, 1, "aes_wrap;wpa_ft_gtk_subelem"):
2174 dev[0].roam(bssid1)
2175 if dev[0].get_status_field('bssid') != bssid1:
2176 raise Exception("Did not roam to AP1")
2177
2178def test_ap_ft_ap_oom5(dev, apdev):
2179 """WPA2-PSK-FT and AP OOM 5"""
2180 ssid = "test-ft"
fab49f61 2181 passphrase = "12345678"
682a79f0
JM
2182
2183 params = ft_params1(ssid=ssid, passphrase=passphrase)
2184 hapd0 = hostapd.add_ap(apdev[0], params)
2185 bssid0 = hapd0.own_addr()
2186
2187 dev[0].scan_for_bss(bssid0, freq="2412")
2188 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2189 scan_freq="2412")
2190
2191 params = ft_params2(ssid=ssid, passphrase=passphrase)
2192 hapd1 = hostapd.add_ap(apdev[1], params)
2193 bssid1 = hapd1.own_addr()
2194 dev[0].scan_for_bss(bssid1, freq="2412")
2195 with alloc_fail(hapd1, 1, "=wpa_ft_process_auth_req"):
2196 # This will fail to roam
fd189288 2197 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2198
2199 with fail_test(hapd1, 1, "os_get_random;wpa_ft_process_auth_req"):
2200 # This will fail to roam
fd189288 2201 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2202
2203 with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
2204 # This will fail to roam
fd189288 2205 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2206
2207 with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
2208 # This will fail to roam
fd189288 2209 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2210
2211 with fail_test(hapd1, 1, "wpa_derive_pmk_r1_name;wpa_ft_process_auth_req"):
2212 # This will fail to roam
fd189288 2213 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2214
2215def test_ap_ft_ap_oom6(dev, apdev):
2216 """WPA2-PSK-FT and AP OOM 6"""
2217 ssid = "test-ft"
fab49f61 2218 passphrase = "12345678"
682a79f0
JM
2219
2220 params = ft_params1(ssid=ssid, passphrase=passphrase)
2221 hapd0 = hostapd.add_ap(apdev[0], params)
2222 bssid0 = hapd0.own_addr()
2223
2224 dev[0].scan_for_bss(bssid0, freq="2412")
2225 with fail_test(hapd0, 1, "wpa_derive_pmk_r0;wpa_auth_derive_ptk_ft"):
2226 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2227 scan_freq="2412")
2228 dev[0].request("REMOVE_NETWORK all")
2229 dev[0].wait_disconnected()
2230 with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_auth_derive_ptk_ft"):
2231 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2232 scan_freq="2412")
2233 dev[0].request("REMOVE_NETWORK all")
2234 dev[0].wait_disconnected()
2235 with fail_test(hapd0, 1, "wpa_pmk_r1_to_ptk;wpa_auth_derive_ptk_ft"):
2236 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2237 scan_freq="2412")
2238
c5262648
JM
2239def test_ap_ft_ap_oom7a(dev, apdev):
2240 """WPA2-PSK-FT and AP OOM 7a"""
682a79f0 2241 ssid = "test-ft"
fab49f61 2242 passphrase = "12345678"
682a79f0
JM
2243
2244 params = ft_params1(ssid=ssid, passphrase=passphrase)
2245 params["ieee80211w"] = "2"
2246 hapd0 = hostapd.add_ap(apdev[0], params)
2247 bssid0 = hapd0.own_addr()
2248
2249 dev[0].scan_for_bss(bssid0, freq="2412")
2250 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2251 ieee80211w="2", scan_freq="2412")
2252
2253 params = ft_params2(ssid=ssid, passphrase=passphrase)
2254 params["ieee80211w"] = "2"
2255 hapd1 = hostapd.add_ap(apdev[1], params)
2256 bssid1 = hapd1.own_addr()
2257 dev[0].scan_for_bss(bssid1, freq="2412")
2258 with alloc_fail(hapd1, 1, "wpa_ft_igtk_subelem"):
2259 # This will fail to roam
2260 dev[0].roam(bssid1)
c5262648
JM
2261
2262def test_ap_ft_ap_oom7b(dev, apdev):
2263 """WPA2-PSK-FT and AP OOM 7b"""
2264 ssid = "test-ft"
fab49f61 2265 passphrase = "12345678"
c5262648
JM
2266
2267 params = ft_params1(ssid=ssid, passphrase=passphrase)
2268 params["ieee80211w"] = "2"
2269 hapd0 = hostapd.add_ap(apdev[0], params)
2270 bssid0 = hapd0.own_addr()
2271
2272 dev[0].scan_for_bss(bssid0, freq="2412")
2273 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2274 ieee80211w="2", scan_freq="2412")
2275
2276 params = ft_params2(ssid=ssid, passphrase=passphrase)
2277 params["ieee80211w"] = "2"
2278 hapd1 = hostapd.add_ap(apdev[1], params)
2279 bssid1 = hapd1.own_addr()
2280 dev[0].scan_for_bss(bssid1, freq="2412")
682a79f0
JM
2281 with fail_test(hapd1, 1, "aes_wrap;wpa_ft_igtk_subelem"):
2282 # This will fail to roam
2283 dev[0].roam(bssid1)
c5262648
JM
2284
2285def test_ap_ft_ap_oom7c(dev, apdev):
2286 """WPA2-PSK-FT and AP OOM 7c"""
2287 ssid = "test-ft"
fab49f61 2288 passphrase = "12345678"
c5262648
JM
2289
2290 params = ft_params1(ssid=ssid, passphrase=passphrase)
2291 params["ieee80211w"] = "2"
2292 hapd0 = hostapd.add_ap(apdev[0], params)
2293 bssid0 = hapd0.own_addr()
2294
2295 dev[0].scan_for_bss(bssid0, freq="2412")
2296 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2297 ieee80211w="2", scan_freq="2412")
2298
2299 params = ft_params2(ssid=ssid, passphrase=passphrase)
2300 params["ieee80211w"] = "2"
2301 hapd1 = hostapd.add_ap(apdev[1], params)
2302 bssid1 = hapd1.own_addr()
2303 dev[0].scan_for_bss(bssid1, freq="2412")
682a79f0
JM
2304 with alloc_fail(hapd1, 1, "=wpa_sm_write_assoc_resp_ies"):
2305 # This will fail to roam
2306 dev[0].roam(bssid1)
c5262648
JM
2307
2308def test_ap_ft_ap_oom7d(dev, apdev):
2309 """WPA2-PSK-FT and AP OOM 7d"""
2310 ssid = "test-ft"
fab49f61 2311 passphrase = "12345678"
c5262648
JM
2312
2313 params = ft_params1(ssid=ssid, passphrase=passphrase)
2314 params["ieee80211w"] = "2"
2315 hapd0 = hostapd.add_ap(apdev[0], params)
2316 bssid0 = hapd0.own_addr()
2317
2318 dev[0].scan_for_bss(bssid0, freq="2412")
2319 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2320 ieee80211w="2", scan_freq="2412")
2321
2322 params = ft_params2(ssid=ssid, passphrase=passphrase)
2323 params["ieee80211w"] = "2"
2324 hapd1 = hostapd.add_ap(apdev[1], params)
2325 bssid1 = hapd1.own_addr()
2326 dev[0].scan_for_bss(bssid1, freq="2412")
682a79f0
JM
2327 with fail_test(hapd1, 1, "wpa_ft_mic;wpa_sm_write_assoc_resp_ies"):
2328 # This will fail to roam
2329 dev[0].roam(bssid1)
2330
2331def test_ap_ft_ap_oom8(dev, apdev):
2332 """WPA2-PSK-FT and AP OOM 8"""
2333 ssid = "test-ft"
fab49f61 2334 passphrase = "12345678"
682a79f0
JM
2335
2336 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 2337 params['ft_psk_generate_local'] = "1"
682a79f0
JM
2338 hapd0 = hostapd.add_ap(apdev[0], params)
2339 bssid0 = hapd0.own_addr()
2340
2341 dev[0].scan_for_bss(bssid0, freq="2412")
2342 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2343 scan_freq="2412")
2344
2345 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 2346 params['ft_psk_generate_local'] = "1"
682a79f0
JM
2347 hapd1 = hostapd.add_ap(apdev[1], params)
2348 bssid1 = hapd1.own_addr()
2349 dev[0].scan_for_bss(bssid1, freq="2412")
2350 with fail_test(hapd1, 1, "wpa_derive_pmk_r0;wpa_ft_psk_pmk_r1"):
2351 # This will fail to roam
fd189288 2352 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2353 with fail_test(hapd1, 1, "wpa_derive_pmk_r1;wpa_ft_psk_pmk_r1"):
2354 # This will fail to roam
fd189288 2355 dev[0].roam(bssid1, check_bssid=False)
682a79f0
JM
2356
2357def test_ap_ft_ap_oom9(dev, apdev):
2358 """WPA2-PSK-FT and AP OOM 9"""
2359 ssid = "test-ft"
fab49f61 2360 passphrase = "12345678"
682a79f0
JM
2361
2362 params = ft_params1(ssid=ssid, passphrase=passphrase)
2363 hapd0 = hostapd.add_ap(apdev[0], params)
2364 bssid0 = hapd0.own_addr()
2365
2366 dev[0].scan_for_bss(bssid0, freq="2412")
2367 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2368 scan_freq="2412")
2369
2370 params = ft_params2(ssid=ssid, passphrase=passphrase)
2371 hapd1 = hostapd.add_ap(apdev[1], params)
2372 bssid1 = hapd1.own_addr()
2373 dev[0].scan_for_bss(bssid1, freq="2412")
2374
2375 with alloc_fail(hapd0, 1, "wpa_ft_action_rx"):
2376 # This will fail to roam
2377 if "OK" not in dev[0].request("FT_DS " + bssid1):
2378 raise Exception("FT_DS failed")
2379 wait_fail_trigger(hapd0, "GET_ALLOC_FAIL")
2380
2381 with alloc_fail(hapd1, 1, "wpa_ft_rrb_rx_request"):
2382 # This will fail to roam
2383 if "OK" not in dev[0].request("FT_DS " + bssid1):
2384 raise Exception("FT_DS failed")
2385 wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
2386
2387 with alloc_fail(hapd1, 1, "wpa_ft_send_rrb_auth_resp"):
2388 # This will fail to roam
2389 if "OK" not in dev[0].request("FT_DS " + bssid1):
2390 raise Exception("FT_DS failed")
2391 wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
2392
2393def test_ap_ft_ap_oom10(dev, apdev):
2394 """WPA2-PSK-FT and AP OOM 10"""
2395 ssid = "test-ft"
fab49f61 2396 passphrase = "12345678"
682a79f0
JM
2397
2398 params = ft_params1(ssid=ssid, passphrase=passphrase)
2399 hapd0 = hostapd.add_ap(apdev[0], params)
2400 bssid0 = hapd0.own_addr()
2401
2402 dev[0].scan_for_bss(bssid0, freq="2412")
2403 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2404 scan_freq="2412")
2405
2406 params = ft_params2(ssid=ssid, passphrase=passphrase)
2407 hapd1 = hostapd.add_ap(apdev[1], params)
2408 bssid1 = hapd1.own_addr()
2409 dev[0].scan_for_bss(bssid1, freq="2412")
2410
9441a227 2411 with fail_test(hapd0, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_pull"):
682a79f0
JM
2412 # This will fail to roam
2413 if "OK" not in dev[0].request("FT_DS " + bssid1):
2414 raise Exception("FT_DS failed")
2415 wait_fail_trigger(hapd0, "GET_FAIL")
2416
2417 with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_rrb_rx_pull"):
2418 # This will fail to roam
2419 if "OK" not in dev[0].request("FT_DS " + bssid1):
2420 raise Exception("FT_DS failed")
2421 wait_fail_trigger(hapd0, "GET_FAIL")
2422
9441a227 2423 with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_rrb_rx_pull"):
682a79f0
JM
2424 # This will fail to roam
2425 if "OK" not in dev[0].request("FT_DS " + bssid1):
2426 raise Exception("FT_DS failed")
2427 wait_fail_trigger(hapd0, "GET_FAIL")
2428
9441a227 2429 with fail_test(hapd1, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_resp"):
682a79f0
JM
2430 # This will fail to roam
2431 if "OK" not in dev[0].request("FT_DS " + bssid1):
2432 raise Exception("FT_DS failed")
2433 wait_fail_trigger(hapd1, "GET_FAIL")
2434
2435def test_ap_ft_ap_oom11(dev, apdev):
2436 """WPA2-PSK-FT and AP OOM 11"""
2437 ssid = "test-ft"
fab49f61 2438 passphrase = "12345678"
682a79f0
JM
2439
2440 params = ft_params1(ssid=ssid, passphrase=passphrase)
2441 hapd0 = hostapd.add_ap(apdev[0], params)
2442 bssid0 = hapd0.own_addr()
2443
2444 dev[0].scan_for_bss(bssid0, freq="2412")
2445 with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_generate_pmk_r1"):
2446 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2447 scan_freq="2412")
2448 wait_fail_trigger(hapd0, "GET_FAIL")
2449
2450 dev[1].scan_for_bss(bssid0, freq="2412")
9441a227 2451 with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_generate_pmk_r1"):
682a79f0
JM
2452 dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2453 scan_freq="2412")
2454 wait_fail_trigger(hapd0, "GET_FAIL")
2455
a04e6f3d
JM
2456def test_ap_ft_over_ds_proto_ap(dev, apdev):
2457 """WPA2-PSK-FT AP over DS protocol testing for AP processing"""
2458 ssid = "test-ft"
fab49f61 2459 passphrase = "12345678"
a04e6f3d
JM
2460
2461 params = ft_params1(ssid=ssid, passphrase=passphrase)
2462 hapd0 = hostapd.add_ap(apdev[0], params)
2463 bssid0 = hapd0.own_addr()
2464 _bssid0 = bssid0.replace(':', '')
2465 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2466 scan_freq="2412")
2467 addr = dev[0].own_addr()
2468 _addr = addr.replace(':', '')
2469
2470 params = ft_params2(ssid=ssid, passphrase=passphrase)
2471 hapd1 = hostapd.add_ap(apdev[1], params)
2472 bssid1 = hapd1.own_addr()
2473 _bssid1 = bssid1.replace(':', '')
2474
2475 hapd0.set("ext_mgmt_frame_handling", "1")
2476 hdr = "d0003a01" + _bssid0 + _addr + _bssid0 + "1000"
2477 valid = "0601" + _addr + _bssid1
fab49f61
JM
2478 tests = ["0601",
2479 "0601" + _addr,
2480 "0601" + _addr + _bssid0,
2481 "0601" + _addr + "ffffffffffff",
2482 "0601" + _bssid0 + _bssid0,
2483 valid,
2484 valid + "01",
2485 valid + "3700",
2486 valid + "3600",
2487 valid + "3603ffffff",
2488 valid + "3603a1b2ff",
2489 valid + "3603a1b2ff" + "3700",
2490 valid + "3603a1b2ff" + "37520000" + 16*"00" + 32*"00" + 32*"00",
2491 valid + "3603a1b2ff" + "37520001" + 16*"00" + 32*"00" + 32*"00",
2492 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa",
2493 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "3000",
2494 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000facff00000100a225368fe0983b5828a37a0acb37f253",
2495 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac030100000fac0400000100a225368fe0983b5828a37a0acb37f253",
2496 valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000fac0400000100a225368fe0983b5828a37a0acb37f253",
2497 valid + "0001"]
a04e6f3d
JM
2498 for t in tests:
2499 hapd0.dump_monitor()
2500 if "OK" not in hapd0.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
2501 raise Exception("MGMT_RX_PROCESS failed")
2502
2503 hapd0.set("ext_mgmt_frame_handling", "0")
2504
34d3eaa8
JM
2505def test_ap_ft_over_ds_proto(dev, apdev):
2506 """WPA2-PSK-FT AP over DS protocol testing"""
2507 ssid = "test-ft"
fab49f61 2508 passphrase = "12345678"
34d3eaa8
JM
2509
2510 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 2511 hapd0 = hostapd.add_ap(apdev[0], params)
34d3eaa8
JM
2512 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2513 scan_freq="2412")
2514
2515 # FT Action Response while no FT-over-DS in progress
2516 msg = {}
2517 msg['fc'] = 13 << 4
2518 msg['da'] = dev[0].own_addr()
2519 msg['sa'] = apdev[0]['bssid']
2520 msg['bssid'] = apdev[0]['bssid']
2521 msg['payload'] = binascii.unhexlify("06020200000000000200000004000000")
2522 hapd0.mgmt_tx(msg)
2523
2524 params = ft_params2(ssid=ssid, passphrase=passphrase)
8b8a1864 2525 hapd1 = hostapd.add_ap(apdev[1], params)
34d3eaa8
JM
2526 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
2527 hapd0.set("ext_mgmt_frame_handling", "1")
2528 hapd0.dump_monitor()
2529 dev[0].request("FT_DS " + apdev[1]['bssid'])
2530 for i in range(0, 10):
2531 req = hapd0.mgmt_rx()
2532 if req is None:
2533 raise Exception("MGMT RX wait timed out")
2534 if req['subtype'] == 13:
2535 break
2536 req = None
2537 if not req:
2538 raise Exception("FT Action frame not received")
2539
2540 # FT Action Response for unexpected Target AP
2541 msg['payload'] = binascii.unhexlify("0602020000000000" + "f20000000400" + "0000")
2542 hapd0.mgmt_tx(msg)
2543
2544 # FT Action Response without MDIE
2545 msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000")
2546 hapd0.mgmt_tx(msg)
2547
2548 # FT Action Response without FTIE
2549 msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201")
2550 hapd0.mgmt_tx(msg)
2551
2552 # FT Action Response with FTIE SNonce mismatch
2553 msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201" + "3766000000000000000000000000000000000000c4e67ac1999bebd00ff4ae4d5dcaf87896bb060b469f7c78d49623fb395c3455ffffff6b693fe6f8d8c5dfac0a22344750775bd09437f98b238c9f87b97f790c0106000102030406030a6e6173312e77312e6669")
2554 hapd0.mgmt_tx(msg)
6f3815c0 2555
9fd6804d 2556@remote_compatible
6f3815c0
JM
2557def test_ap_ft_rrb(dev, apdev):
2558 """WPA2-PSK-FT RRB protocol testing"""
2559 ssid = "test-ft"
fab49f61 2560 passphrase = "12345678"
6f3815c0
JM
2561
2562 params = ft_params1(ssid=ssid, passphrase=passphrase)
8b8a1864 2563 hapd0 = hostapd.add_ap(apdev[0], params)
6f3815c0
JM
2564
2565 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2566 scan_freq="2412")
2567
fab49f61
JM
2568 _dst_ll = binascii.unhexlify(apdev[0]['bssid'].replace(':', ''))
2569 _src_ll = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
15dfcb69 2570 proto = b'\x89\x0d'
6f3815c0
JM
2571 ehdr = _dst_ll + _src_ll + proto
2572
2573 # Too short RRB frame
15dfcb69 2574 pkt = ehdr + b'\x01'
7ab74770 2575 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2576 raise Exception("DATA_TEST_FRAME failed")
2577
2578 # RRB discarded frame wikth unrecognized type
15dfcb69 2579 pkt = ehdr + b'\x02' + b'\x02' + b'\x01\x00' + _src_ll
7ab74770 2580 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2581 raise Exception("DATA_TEST_FRAME failed")
2582
2583 # RRB frame too short for action frame
15dfcb69 2584 pkt = ehdr + b'\x01' + b'\x02' + b'\x01\x00' + _src_ll
7ab74770 2585 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2586 raise Exception("DATA_TEST_FRAME failed")
2587
2588 # Too short RRB frame (not enough room for Action Frame body)
15dfcb69 2589 pkt = ehdr + b'\x01' + b'\x02' + b'\x00\x00' + _src_ll
7ab74770 2590 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2591 raise Exception("DATA_TEST_FRAME failed")
2592
2593 # Unexpected Action frame category
15dfcb69 2594 pkt = ehdr + b'\x01' + b'\x02' + b'\x0e\x00' + _src_ll + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2595 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2596 raise Exception("DATA_TEST_FRAME failed")
2597
2598 # Unexpected Action in RRB Request
15dfcb69 2599 pkt = ehdr + b'\x01' + b'\x00' + b'\x0e\x00' + _src_ll + b'\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2600 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2601 raise Exception("DATA_TEST_FRAME failed")
2602
2603 # Target AP address in RRB Request does not match with own address
15dfcb69 2604 pkt = ehdr + b'\x01' + b'\x00' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2605 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2606 raise Exception("DATA_TEST_FRAME failed")
2607
2608 # Not enough room for status code in RRB Response
15dfcb69 2609 pkt = ehdr + b'\x01' + b'\x01' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2610 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2611 raise Exception("DATA_TEST_FRAME failed")
2612
2613 # RRB discarded frame with unknown packet_type
15dfcb69 2614 pkt = ehdr + b'\x01' + b'\x02' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2615 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2616 raise Exception("DATA_TEST_FRAME failed")
2617
2618 # RRB Response with non-zero status code; no STA match
15dfcb69 2619 pkt = ehdr + b'\x01' + b'\x01' + b'\x10\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\xff\xff'
7ab74770 2620 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2621 raise Exception("DATA_TEST_FRAME failed")
2622
2623 # RRB Response with zero status code and extra data; STA match
15dfcb69 2624 pkt = ehdr + b'\x01' + b'\x01' + b'\x11\x00' + _src_ll + b'\x06\x01' + _src_ll + b'\x00\x00\x00\x00\x00\x00' + b'\x00\x00' + b'\x00'
7ab74770 2625 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2626 raise Exception("DATA_TEST_FRAME failed")
2627
2628 # Too short PMK-R1 pull
15dfcb69 2629 pkt = ehdr + b'\x01' + b'\xc8' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2630 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2631 raise Exception("DATA_TEST_FRAME failed")
2632
2633 # Too short PMK-R1 resp
15dfcb69 2634 pkt = ehdr + b'\x01' + b'\xc9' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2635 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2636 raise Exception("DATA_TEST_FRAME failed")
2637
2638 # Too short PMK-R1 push
15dfcb69 2639 pkt = ehdr + b'\x01' + b'\xca' + b'\x0e\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
7ab74770 2640 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0
JM
2641 raise Exception("DATA_TEST_FRAME failed")
2642
2643 # No matching R0KH address found for PMK-R0 pull response
15dfcb69 2644 pkt = ehdr + b'\x01' + b'\xc9' + b'\x5a\x00' + _src_ll + b'\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + 76 * b'\00'
7ab74770 2645 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()):
6f3815c0 2646 raise Exception("DATA_TEST_FRAME failed")
ecafa0cf 2647
9fd6804d 2648@remote_compatible
ecafa0cf
JM
2649def test_rsn_ie_proto_ft_psk_sta(dev, apdev):
2650 """RSN element protocol testing for FT-PSK + PMF cases on STA side"""
2651 bssid = apdev[0]['bssid']
2652 ssid = "test-ft"
fab49f61 2653 passphrase = "12345678"
ecafa0cf
JM
2654
2655 params = ft_params1(ssid=ssid, passphrase=passphrase)
bc6e3288 2656 params["ieee80211w"] = "1"
ecafa0cf
JM
2657 # This is the RSN element used normally by hostapd
2658 params['own_ie_override'] = '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'
8b8a1864 2659 hapd = hostapd.add_ap(apdev[0], params)
ecafa0cf
JM
2660 id = dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2661 ieee80211w="1", scan_freq="2412",
2662 pairwise="CCMP", group="CCMP")
2663
fab49f61
JM
2664 tests = [('PMKIDCount field included',
2665 '30160100000fac040100000fac040100000fac048c000000' + '3603a1b201'),
2666 ('Extra IE before RSNE',
2667 'dd0400000000' + '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'),
2668 ('PMKIDCount and Group Management Cipher suite fields included',
2669 '301a0100000fac040100000fac040100000fac048c000000000fac06' + '3603a1b201'),
2670 ('Extra octet after defined fields (future extensibility)',
2671 '301b0100000fac040100000fac040100000fac048c000000000fac0600' + '3603a1b201'),
2672 ('No RSN Capabilities field (PMF disabled in practice)',
2673 '30120100000fac040100000fac040100000fac04' + '3603a1b201')]
2674 for txt, ie in tests:
ecafa0cf
JM
2675 dev[0].request("DISCONNECT")
2676 dev[0].wait_disconnected()
2677 logger.info(txt)
2678 hapd.disable()
2679 hapd.set('own_ie_override', ie)
2680 hapd.enable()
2681 dev[0].request("BSS_FLUSH 0")
2682 dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
2683 dev[0].select_network(id, freq=2412)
2684 dev[0].wait_connected()
2685
2686 dev[0].request("DISCONNECT")
2687 dev[0].wait_disconnected()
2688
2689 logger.info('Invalid RSNE causing internal hostapd error')
2690 hapd.disable()
2691 hapd.set('own_ie_override', '30130100000fac040100000fac040100000fac048c' + '3603a1b201')
2692 hapd.enable()
2693 dev[0].request("BSS_FLUSH 0")
2694 dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
2695 dev[0].select_network(id, freq=2412)
2696 # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
2697 # complete.
2698 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
2699 if ev is not None:
2700 raise Exception("Unexpected connection")
2701 dev[0].request("DISCONNECT")
2702
425e5f97 2703def start_ft(apdev, wpa_ptk_rekey=None):
1025603b 2704 ssid = "test-ft"
fab49f61 2705 passphrase = "12345678"
1025603b
JM
2706
2707 params = ft_params1(ssid=ssid, passphrase=passphrase)
425e5f97
JM
2708 if wpa_ptk_rekey:
2709 params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
8b8a1864 2710 hapd0 = hostapd.add_ap(apdev[0], params)
1025603b 2711 params = ft_params2(ssid=ssid, passphrase=passphrase)
425e5f97
JM
2712 if wpa_ptk_rekey:
2713 params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
8b8a1864 2714 hapd1 = hostapd.add_ap(apdev[1], params)
1025603b 2715
425e5f97 2716 return hapd0, hapd1
1025603b 2717
425e5f97
JM
2718def check_ptk_rekey(dev, hapd0=None, hapd1=None):
2719 ev = dev.wait_event(["CTRL-EVENT-DISCONNECTED",
2720 "WPA: Key negotiation completed"], timeout=5)
1025603b
JM
2721 if ev is None:
2722 raise Exception("No event received after roam")
2723 if "CTRL-EVENT-DISCONNECTED" in ev:
2724 raise Exception("Unexpected disconnection after roam")
2725
425e5f97
JM
2726 if not hapd0 or not hapd1:
2727 return
2728 if dev.get_status_field('bssid') == hapd0.own_addr():
1025603b
JM
2729 hapd = hapd0
2730 else:
2731 hapd = hapd1
d22f0902 2732 time.sleep(0.1)
425e5f97 2733 hwsim_utils.test_connectivity(dev, hapd)
1025603b 2734
425e5f97
JM
2735def test_ap_ft_ptk_rekey(dev, apdev):
2736 """WPA2-PSK-FT PTK rekeying triggered by station after roam"""
2737 hapd0, hapd1 = start_ft(apdev)
2738 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", ptk_rekey="1")
2739 check_ptk_rekey(dev[0], hapd0, hapd1)
1025603b 2740
425e5f97
JM
2741def test_ap_ft_ptk_rekey2(dev, apdev):
2742 """WPA2-PSK-FT PTK rekeying triggered by station after one roam"""
2743 hapd0, hapd1 = start_ft(apdev)
2744 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", ptk_rekey="1",
2745 only_one_way=True)
2746 check_ptk_rekey(dev[0], hapd0, hapd1)
1025603b 2747
425e5f97
JM
2748def test_ap_ft_ptk_rekey_ap(dev, apdev):
2749 """WPA2-PSK-FT PTK rekeying triggered by AP after roam"""
2750 hapd0, hapd1 = start_ft(apdev, wpa_ptk_rekey=2)
2751 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678")
2752 check_ptk_rekey(dev[0], hapd0, hapd1)
2753
2754def test_ap_ft_ptk_rekey_ap2(dev, apdev):
2755 """WPA2-PSK-FT PTK rekeying triggered by AP after one roam"""
2756 hapd0, hapd1 = start_ft(apdev, wpa_ptk_rekey=2)
2757 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678",
2758 only_one_way=True)
2759 check_ptk_rekey(dev[0], hapd0, hapd1)
2760
2761def test_ap_ft_eap_ptk_rekey_ap(dev, apdev):
2762 """WPA2-EAP-FT PTK rekeying triggered by AP"""
2763 generic_ap_ft_eap(dev, apdev, only_one_way=True, wpa_ptk_rekey=2)
2764 check_ptk_rekey(dev[0])
186ca473
MB
2765
2766def test_ap_ft_internal_rrb_check(dev, apdev):
2767 """RRB internal delivery only to WPA enabled BSS"""
2768 ssid = "test-ft"
fab49f61 2769 passphrase = "12345678"
186ca473
MB
2770
2771 radius = hostapd.radius_params()
2772 params = ft_params1(ssid=ssid, passphrase=passphrase)
2773 params['wpa_key_mgmt'] = "FT-EAP"
2774 params["ieee8021x"] = "1"
35d8c254 2775 params = dict(list(radius.items()) + list(params.items()))
8b8a1864 2776 hapd = hostapd.add_ap(apdev[0], params)
186ca473
MB
2777 key_mgmt = hapd.get_config()['key_mgmt']
2778 if key_mgmt.split(' ')[0] != "FT-EAP":
2779 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
2780
fab49f61 2781 hapd1 = hostapd.add_ap(apdev[1], {"ssid": ssid})
186ca473
MB
2782
2783 # Connect to WPA enabled AP
2784 dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
2785 eap="GPSK", identity="gpsk user",
2786 password="abcdefghijklmnop0123456789abcdef",
2787 scan_freq="2412")
2788
2789 # Try over_ds roaming to non-WPA-enabled AP.
2790 # If hostapd does not check hapd->wpa_auth internally, it will crash now.
2791 dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
c85fcff2
JM
2792
2793def test_ap_ft_extra_ie(dev, apdev):
2794 """WPA2-PSK-FT AP with WPA2-PSK enabled and unexpected MDE"""
2795 ssid = "test-ft"
fab49f61 2796 passphrase = "12345678"
c85fcff2
JM
2797
2798 params = ft_params1(ssid=ssid, passphrase=passphrase)
2799 params["wpa_key_mgmt"] = "WPA-PSK FT-PSK"
2800 hapd0 = hostapd.add_ap(apdev[0], params)
2801 dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2802 scan_freq="2412")
2803 dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
2804 scan_freq="2412")
2805 try:
2806 # Add Mobility Domain element to test AP validation code.
2807 dev[0].request("VENDOR_ELEM_ADD 13 3603a1b201")
2808 dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
2809 scan_freq="2412", wait_connect=False)
2810 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2811 "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
2812 if ev is None:
2813 raise Exception("No connection result")
2814 if "CTRL-EVENT-CONNECTED" in ev:
2815 raise Exception("Non-FT association accepted with MDE")
2816 if "status_code=43" not in ev:
2817 raise Exception("Unexpected status code: " + ev)
2818 dev[0].request("DISCONNECT")
2819 finally:
2820 dev[0].request("VENDOR_ELEM_REMOVE 13 *")
fd7205fa
JM
2821
2822def test_ap_ft_ric(dev, apdev):
2823 """WPA2-PSK-FT AP and RIC"""
2824 ssid = "test-ft"
fab49f61 2825 passphrase = "12345678"
fd7205fa
JM
2826
2827 params = ft_params1(ssid=ssid, passphrase=passphrase)
2828 hapd0 = hostapd.add_ap(apdev[0], params)
2829 params = ft_params2(ssid=ssid, passphrase=passphrase)
2830 hapd1 = hostapd.add_ap(apdev[1], params)
2831
2832 dev[0].set("ric_ies", "")
2833 dev[0].set("ric_ies", '""')
2834 if "FAIL" not in dev[0].request("SET ric_ies q"):
2835 raise Exception("Invalid ric_ies value accepted")
2836
fab49f61
JM
2837 tests = ["3900",
2838 "3900ff04eeeeeeee",
2839 "390400000000",
2840 "390400000000" + "390400000000",
2841 "390400000000" + "dd050050f20202",
2842 "390400000000" + "dd3d0050f2020201" + 55*"00",
2843 "390400000000" + "dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000",
2844 "390401010000" + "dd3d0050f2020201aa3000dc050000000000000000000000000000000000000000000000000000dc050000000000000000000000000000808d5b0028230000"]
fd7205fa
JM
2845 for t in tests:
2846 dev[0].set("ric_ies", t)
2847 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
2848 test_connectivity=False)
2849 dev[0].request("REMOVE_NETWORK all")
2850 dev[0].wait_disconnected()
2851 dev[0].dump_monitor()
c8942286
JM
2852
2853def ie_hex(ies, id):
7ab74770 2854 return binascii.hexlify(struct.pack('BB', id, len(ies[id])) + ies[id]).decode()
c8942286
JM
2855
2856def test_ap_ft_reassoc_proto(dev, apdev):
2857 """WPA2-PSK-FT AP Reassociation Request frame parsing"""
2858 ssid = "test-ft"
fab49f61 2859 passphrase = "12345678"
c8942286
JM
2860
2861 params = ft_params1(ssid=ssid, passphrase=passphrase)
2862 hapd0 = hostapd.add_ap(apdev[0], params)
2863 params = ft_params2(ssid=ssid, passphrase=passphrase)
2864 hapd1 = hostapd.add_ap(apdev[1], params)
2865
2866 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2867 ieee80211w="1", scan_freq="2412")
2868 if dev[0].get_status_field('bssid') == hapd0.own_addr():
2869 hapd1ap = hapd0
2870 hapd2ap = hapd1
2871 else:
2872 hapd1ap = hapd1
2873 hapd2ap = hapd0
2874
2875 dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
2876 hapd2ap.set("ext_mgmt_frame_handling", "1")
2877 dev[0].request("ROAM " + hapd2ap.own_addr())
2878
2879 while True:
2880 req = hapd2ap.mgmt_rx()
7ab74770 2881 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
c8942286
JM
2882 if req['subtype'] == 11:
2883 break
2884
2885 while True:
2886 req = hapd2ap.mgmt_rx()
2887 if req['subtype'] == 2:
2888 break
7ab74770 2889 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
c8942286
JM
2890
2891 # IEEE 802.11 header + fixed fields before IEs
7ab74770 2892 hdr = binascii.hexlify(req['frame'][0:34]).decode()
c8942286
JM
2893 ies = parse_ie(binascii.hexlify(req['frame'][34:]))
2894 # First elements: SSID, Supported Rates, Extended Supported Rates
2895 ies1 = ie_hex(ies, 0) + ie_hex(ies, 1) + ie_hex(ies, 50)
2896
2897 rsne = ie_hex(ies, 48)
2898 mde = ie_hex(ies, 54)
2899 fte = ie_hex(ies, 55)
fab49f61 2900 tests = []
c8942286 2901 # RSN: Trying to use FT, but MDIE not included
fab49f61 2902 tests += [rsne]
c8942286 2903 # RSN: Attempted to use unknown MDIE
fab49f61 2904 tests += [rsne + "3603000000"]
c8942286 2905 # Invalid RSN pairwise cipher
fab49f61 2906 tests += ["30260100000fac040100000fac030100000fac040000010029208a42cd25c85aa571567dce10dae3"]
c8942286 2907 # FT: No PMKID in RSNIE
fab49f61 2908 tests += ["30160100000fac040100000fac040100000fac0400000000" + ie_hex(ies, 54)]
c8942286 2909 # FT: Invalid FTIE
fab49f61 2910 tests += [rsne + mde]
c8942286
JM
2911 # FT: RIC IE(s) in the frame, but not included in protected IE count
2912 # FT: Failed to parse FT IEs
fab49f61 2913 tests += [rsne + mde + fte + "3900"]
c8942286 2914 # FT: SNonce mismatch in FTIE
fab49f61 2915 tests += [rsne + mde + "37520000" + 16*"00" + 32*"00" + 32*"00"]
c8942286 2916 # FT: ANonce mismatch in FTIE
fab49f61 2917 tests += [rsne + mde + fte[0:40] + 32*"00" + fte[104:]]
c8942286 2918 # FT: No R0KH-ID subelem in FTIE
fab49f61 2919 tests += [rsne + mde + "3752" + fte[4:168]]
c8942286 2920 # FT: R0KH-ID in FTIE did not match with the current R0KH-ID
fab49f61 2921 tests += [rsne + mde + "3755" + fte[4:168] + "0301ff"]
c8942286 2922 # FT: No R1KH-ID subelem in FTIE
fab49f61 2923 tests += [rsne + mde + "375e" + fte[4:168] + "030a" + binascii.hexlify(b"nas1.w1.fi").decode()]
c8942286 2924 # FT: Unknown R1KH-ID used in ReassocReq
fab49f61 2925 tests += [rsne + mde + "3766" + fte[4:168] + "030a" + binascii.hexlify(b"nas1.w1.fi").decode() + "0106000000000000"]
c8942286 2926 # FT: PMKID in Reassoc Req did not match with the PMKR1Name derived from auth request
fab49f61 2927 tests += [rsne[:-32] + 16*"00" + mde + fte]
c8942286 2928 # Invalid MIC in FTIE
fab49f61 2929 tests += [rsne + mde + fte[0:8] + 16*"00" + fte[40:]]
c8942286
JM
2930 for t in tests:
2931 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + ies1 + t)
2932
2933def test_ap_ft_reassoc_local_fail(dev, apdev):
2934 """WPA2-PSK-FT AP Reassociation Request frame and local failure"""
2935 ssid = "test-ft"
fab49f61 2936 passphrase = "12345678"
c8942286
JM
2937
2938 params = ft_params1(ssid=ssid, passphrase=passphrase)
2939 hapd0 = hostapd.add_ap(apdev[0], params)
2940 params = ft_params2(ssid=ssid, passphrase=passphrase)
2941 hapd1 = hostapd.add_ap(apdev[1], params)
2942
2943 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2944 ieee80211w="1", scan_freq="2412")
2945 if dev[0].get_status_field('bssid') == hapd0.own_addr():
2946 hapd1ap = hapd0
2947 hapd2ap = hapd1
2948 else:
2949 hapd1ap = hapd1
2950 hapd2ap = hapd0
2951
2952 dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
2953 # FT: Failed to calculate MIC
2954 with fail_test(hapd2ap, 1, "wpa_ft_validate_reassoc"):
2955 dev[0].request("ROAM " + hapd2ap.own_addr())
2956 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
2957 dev[0].request("DISCONNECT")
2958 if ev is None:
2959 raise Exception("Association reject not seen")
d7f0bef9
JM
2960
2961def test_ap_ft_reassoc_replay(dev, apdev, params):
2962 """WPA2-PSK-FT AP and replayed Reassociation Request frame"""
2963 capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
2964 ssid = "test-ft"
fab49f61 2965 passphrase = "12345678"
d7f0bef9
JM
2966
2967 params = ft_params1(ssid=ssid, passphrase=passphrase)
2968 hapd0 = hostapd.add_ap(apdev[0], params)
2969 params = ft_params2(ssid=ssid, passphrase=passphrase)
2970 hapd1 = hostapd.add_ap(apdev[1], params)
2971
2972 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2973 scan_freq="2412")
2974 if dev[0].get_status_field('bssid') == hapd0.own_addr():
2975 hapd1ap = hapd0
2976 hapd2ap = hapd1
2977 else:
2978 hapd1ap = hapd1
2979 hapd2ap = hapd0
2980
2981 dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
2982 hapd2ap.set("ext_mgmt_frame_handling", "1")
2983 dev[0].dump_monitor()
2984 if "OK" not in dev[0].request("ROAM " + hapd2ap.own_addr()):
2985 raise Exception("ROAM failed")
2986
2987 reassocreq = None
2988 count = 0
2989 while count < 100:
2990 req = hapd2ap.mgmt_rx()
2991 count += 1
2992 hapd2ap.dump_monitor()
7ab74770 2993 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
d7f0bef9
JM
2994 if req['subtype'] == 2:
2995 reassocreq = req
2996 ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
2997 if ev is None:
2998 raise Exception("No TX status seen")
2999 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
3000 if "OK" not in hapd2ap.request(cmd):
3001 raise Exception("MGMT_TX_STATUS_PROCESS failed")
3002 break
3003 hapd2ap.set("ext_mgmt_frame_handling", "0")
3004 if reassocreq is None:
3005 raise Exception("No Reassociation Request frame seen")
3006 dev[0].wait_connected()
3007 dev[0].dump_monitor()
3008 hapd2ap.dump_monitor()
3009
3010 hwsim_utils.test_connectivity(dev[0], hapd2ap)
3011
3012 logger.info("Replay the last Reassociation Request frame")
3013 hapd2ap.dump_monitor()
3014 hapd2ap.set("ext_mgmt_frame_handling", "1")
7ab74770 3015 hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
d7f0bef9
JM
3016 ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
3017 if ev is None:
3018 raise Exception("No TX status seen")
3019 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
3020 if "OK" not in hapd2ap.request(cmd):
3021 raise Exception("MGMT_TX_STATUS_PROCESS failed")
3022 hapd2ap.set("ext_mgmt_frame_handling", "0")
3023
3024 try:
3025 hwsim_utils.test_connectivity(dev[0], hapd2ap)
3026 ok = True
3027 except:
3028 ok = False
3029
3030 ap = hapd2ap.own_addr()
3031 sta = dev[0].own_addr()
3032 filt = "wlan.fc.type == 2 && " + \
3033 "wlan.da == " + sta + " && " + \
12de1490
JM
3034 "wlan.sa == " + ap + " && " + \
3035 "wlan.fc.protected == 1"
fab49f61 3036 fields = ["wlan.ccmp.extiv"]
d7f0bef9
JM
3037 res = run_tshark(capfile, filt, fields)
3038 vals = res.splitlines()
3039 logger.info("CCMP PN: " + str(vals))
3040 if len(vals) < 2:
3041 raise Exception("Could not find all CCMP protected frames from capture")
3042 if len(set(vals)) < len(vals):
3043 raise Exception("Duplicate CCMP PN used")
3044
3045 if not ok:
3046 raise Exception("The second hwsim connectivity test failed")
0dc3c5f2
JM
3047
3048def test_ap_ft_psk_file(dev, apdev):
3049 """WPA2-PSK-FT AP with PSK from a file"""
3050 ssid = "test-ft"
fab49f61 3051 passphrase = "12345678"
0dc3c5f2
JM
3052
3053 params = ft_params1a(ssid=ssid, passphrase=passphrase)
3054 params['wpa_psk_file'] = 'hostapd.wpa_psk'
3055 hapd = hostapd.add_ap(apdev[0], params)
3056
3057 dev[1].connect(ssid, psk="very secret",
3058 key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
3059 scan_freq="2412", wait_connect=False)
3060 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
3061 ieee80211w="1", scan_freq="2412")
3062 dev[0].request("REMOVE_NETWORK all")
3063 dev[0].wait_disconnected()
3064 dev[0].connect(ssid, psk="very secret", key_mgmt="FT-PSK", proto="WPA2",
3065 ieee80211w="1", scan_freq="2412")
3066 dev[0].request("REMOVE_NETWORK all")
3067 dev[0].wait_disconnected()
3068 dev[0].connect(ssid, psk="secret passphrase",
3069 key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
3070 scan_freq="2412")
3071 dev[2].connect(ssid, psk="another passphrase for all STAs",
3072 key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
3073 scan_freq="2412")
3074 ev = dev[1].wait_event(["WPA: 4-Way Handshake failed"], timeout=10)
3075 if ev is None:
3076 raise Exception("Timed out while waiting for failure report")
3077 dev[1].request("REMOVE_NETWORK all")
62566bc2
JM
3078
3079def test_ap_ft_eap_ap_config_change(dev, apdev):
3080 """WPA2-EAP-FT AP changing from 802.1X-only to FT-only"""
3081 ssid = "test-ft"
fab49f61 3082 passphrase = "12345678"
62566bc2
JM
3083 bssid = apdev[0]['bssid']
3084
3085 radius = hostapd.radius_params()
3086 params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
3087 params['wpa_key_mgmt'] = "WPA-EAP"
3088 params["ieee8021x"] = "1"
3089 params["pmk_r1_push"] = "0"
3090 params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
3091 params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
3092 params["eap_server"] = "0"
35d8c254 3093 params = dict(list(radius.items()) + list(params.items()))
62566bc2
JM
3094 hapd = hostapd.add_ap(apdev[0], params)
3095
3096 dev[0].connect(ssid, key_mgmt="FT-EAP WPA-EAP", proto="WPA2",
3097 eap="GPSK", identity="gpsk user",
3098 password="abcdefghijklmnop0123456789abcdef",
3099 scan_freq="2412")
3100 dev[0].request("DISCONNECT")
3101 dev[0].wait_disconnected()
3102 dev[0].dump_monitor()
3103
3104 hapd.disable()
3105 hapd.set('wpa_key_mgmt', "FT-EAP")
3106 hapd.enable()
3107
3108 dev[0].request("BSS_FLUSH 0")
3109 dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
3110
3111 dev[0].request("RECONNECT")
3112 dev[0].wait_connected()
55b3cda7
JM
3113
3114def test_ap_ft_eap_sha384(dev, apdev):
3115 """WPA2-EAP-FT with SHA384"""
3116 ssid = "test-ft"
fab49f61 3117 passphrase = "12345678"
55b3cda7
JM
3118
3119 radius = hostapd.radius_params()
3120 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 3121 params["ieee80211w"] = "2"
55b3cda7
JM
3122 params['wpa_key_mgmt'] = "FT-EAP-SHA384"
3123 params["ieee8021x"] = "1"
35d8c254 3124 params = dict(list(radius.items()) + list(params.items()))
55b3cda7
JM
3125 hapd0 = hostapd.add_ap(apdev[0], params)
3126 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 3127 params["ieee80211w"] = "2"
55b3cda7
JM
3128 params['wpa_key_mgmt'] = "FT-EAP-SHA384"
3129 params["ieee8021x"] = "1"
35d8c254 3130 params = dict(list(radius.items()) + list(params.items()))
55b3cda7
JM
3131 hapd1 = hostapd.add_ap(apdev[1], params)
3132
3133 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
3134 sha384=True)
3135
659f7954
JM
3136def test_ap_ft_eap_sha384_reassoc(dev, apdev):
3137 """WPA2-EAP-FT with SHA384 using REASSOCIATE"""
e1923f5b 3138 check_suite_b_192_capa(dev)
659f7954
JM
3139 ssid = "test-ft"
3140 passphrase = "12345678"
3141
3142 radius = hostapd.radius_params()
3143 params = ft_params1(ssid=ssid, passphrase=passphrase)
3144 params["ieee80211w"] = "2"
3145 params['wpa_key_mgmt'] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384"
3146 params["ieee8021x"] = "1"
3147 params = dict(list(radius.items()) + list(params.items()))
3148 hapd0 = hostapd.add_ap(apdev[0], params)
3149 params = ft_params2(ssid=ssid, passphrase=passphrase)
3150 params["ieee80211w"] = "2"
3151 params['wpa_key_mgmt'] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384"
3152 params["ieee8021x"] = "1"
3153 params = dict(list(radius.items()) + list(params.items()))
3154 hapd1 = hostapd.add_ap(apdev[1], params)
3155
3156 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
3157 sha384=True, also_non_ft=True, roam_with_reassoc=True)
3158
55b3cda7
JM
3159def test_ap_ft_eap_sha384_over_ds(dev, apdev):
3160 """WPA2-EAP-FT with SHA384 over DS"""
3161 ssid = "test-ft"
fab49f61 3162 passphrase = "12345678"
55b3cda7
JM
3163
3164 radius = hostapd.radius_params()
3165 params = ft_params1(ssid=ssid, passphrase=passphrase)
58be42b2 3166 params["ieee80211w"] = "2"
55b3cda7
JM
3167 params['wpa_key_mgmt'] = "FT-EAP-SHA384"
3168 params["ieee8021x"] = "1"
35d8c254 3169 params = dict(list(radius.items()) + list(params.items()))
55b3cda7
JM
3170 hapd0 = hostapd.add_ap(apdev[0], params)
3171 params = ft_params2(ssid=ssid, passphrase=passphrase)
58be42b2 3172 params["ieee80211w"] = "2"
55b3cda7
JM
3173 params['wpa_key_mgmt'] = "FT-EAP-SHA384"
3174 params["ieee8021x"] = "1"
35d8c254 3175 params = dict(list(radius.items()) + list(params.items()))
55b3cda7
JM
3176 hapd1 = hostapd.add_ap(apdev[1], params)
3177
3178 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
3179 eap=True, sha384=True)
392aba4e
JM
3180
3181def test_ap_ft_roam_rrm(dev, apdev):
3182 """WPA2-PSK-FT AP and radio measurement request"""
3183 ssid = "test-ft"
fab49f61 3184 passphrase = "12345678"
392aba4e
JM
3185
3186 params = ft_params1(ssid=ssid, passphrase=passphrase)
3187 params["rrm_beacon_report"] = "1"
3188 hapd0 = hostapd.add_ap(apdev[0], params)
3189 bssid0 = hapd0.own_addr()
3190
3191 addr = dev[0].own_addr()
3192 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
3193 scan_freq="2412")
3194 check_beacon_req(hapd0, addr, 1)
3195
3196 params = ft_params2(ssid=ssid, passphrase=passphrase)
3197 params["rrm_beacon_report"] = "1"
3198 hapd1 = hostapd.add_ap(apdev[1], params)
3199 bssid1 = hapd1.own_addr()
3200
3201 dev[0].scan_for_bss(bssid1, freq=2412)
3202 dev[0].roam(bssid1)
3203 check_beacon_req(hapd1, addr, 2)
3204
3205 dev[0].scan_for_bss(bssid0, freq=2412)
3206 dev[0].roam(bssid0)
3207 check_beacon_req(hapd0, addr, 3)
9ff2b85e
JM
3208
3209def test_ap_ft_pmksa_caching(dev, apdev):
3210 """FT-EAP and PMKSA caching for initial mobility domain association"""
3211 ssid = "test-ft"
3212 identity = "gpsk user"
3213
3214 radius = hostapd.radius_params()
3215 params = ft_params1(ssid=ssid)
3216 params['wpa_key_mgmt'] = "FT-EAP"
3217 params["ieee8021x"] = "1"
3218 params["mobility_domain"] = "c3d4"
3219 params = dict(list(radius.items()) + list(params.items()))
3220 hapd = hostapd.add_ap(apdev[0], params)
3221
3222 params = ft_params2(ssid=ssid)
3223 params['wpa_key_mgmt'] = "FT-EAP"
3224 params["ieee8021x"] = "1"
3225 params["mobility_domain"] = "c3d4"
3226 params = dict(list(radius.items()) + list(params.items()))
3227 hapd1 = hostapd.add_ap(apdev[1], params)
3228
3229 run_roams(dev[0], apdev, hapd, hapd1, ssid, None, eap=True,
3230 eap_identity=identity, pmksa_caching=True)
3231
3232def test_ap_ft_pmksa_caching_sha384(dev, apdev):
3233 """FT-EAP-SHA384 and PMKSA caching for initial mobility domain association"""
3234 ssid = "test-ft"
3235 identity = "gpsk user"
3236
3237 radius = hostapd.radius_params()
3238 params = ft_params1(ssid=ssid)
3239 params['wpa_key_mgmt'] = "FT-EAP-SHA384"
3240 params["ieee8021x"] = "1"
3241 params["mobility_domain"] = "c3d4"
3242 params = dict(list(radius.items()) + list(params.items()))
3243 hapd = hostapd.add_ap(apdev[0], params)
3244
3245 params = ft_params2(ssid=ssid)
3246 params['wpa_key_mgmt'] = "FT-EAP-SHA384"
3247 params["ieee8021x"] = "1"
3248 params["mobility_domain"] = "c3d4"
3249 params = dict(list(radius.items()) + list(params.items()))
3250 hapd1 = hostapd.add_ap(apdev[1], params)
3251
3252 run_roams(dev[0], apdev, hapd, hapd1, ssid, None, eap=True,
3253 eap_identity=identity, pmksa_caching=True, sha384=True)
5916637c
JM
3254
3255def test_ap_ft_r1_key_expiration(dev, apdev):
3256 """WPA2-PSK-FT and PMK-R1 expiration"""
3257 ssid = "test-ft"
3258 passphrase = "12345678"
3259
3260 params = ft_params1(ssid=ssid, passphrase=passphrase)
3261 params['r1_max_key_lifetime'] = "2"
3262 hapd0 = hostapd.add_ap(apdev[0], params)
3263 params = ft_params2(ssid=ssid, passphrase=passphrase)
3264 params['r1_max_key_lifetime'] = "2"
3265 hapd1 = hostapd.add_ap(apdev[1], params)
3266
3267 # This succeeds, but results in having to run another PMK-R1 pull before the
3268 # second AP can complete FT protocol.
3269 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, wait_before_roam=4)
3270
3271def test_ap_ft_r0_key_expiration(dev, apdev):
3272 """WPA2-PSK-FT and PMK-R0 expiration"""
3273 ssid = "test-ft"
3274 passphrase = "12345678"
3275
3276 params = ft_params1(ssid=ssid, passphrase=passphrase)
3277 params['ft_r0_key_lifetime'] = "2"
3278 hapd0 = hostapd.add_ap(apdev[0], params)
3279 params = ft_params2(ssid=ssid, passphrase=passphrase)
3280 params['ft_r0_key_lifetime'] = "2"
3281 hapd1 = hostapd.add_ap(apdev[1], params)
3282
3283 bssid2 = run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
3284 return_after_initial=True)
3285 time.sleep(4)
3286 dev[0].scan_for_bss(bssid2, freq="2412")
3287 if "OK" not in dev[0].request("ROAM " + bssid2):
3288 raise Exception("ROAM failed")
3289 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
3290 "CTRL-EVENT-AUTH-REJECT",
3291 "CTRL-EVENT-ASSOC-REJECT"], timeout=5)
3292 dev[0].request("DISCONNECT")
3293 if ev is None or "CTRL-EVENT-AUTH-REJECT" not in ev:
3294 raise Exception("FT protocol failure not reported")
3295 if "status_code=53" not in ev:
3296 raise Exception("Unexpected status in FT protocol failure: " + ev)
3297
3298 # Generate a new PMK-R0
3299 dev[0].dump_monitor()
3300 dev[0].request("RECONNECT")
3301 dev[0].wait_connected()
6f291896
JM
3302
3303def test_ap_ft_no_full_ap_client_state(dev, apdev):
3304 """WPA2-PSK-FT AP with full_ap_client_state=0"""
3305 run_ap_ft_skip_prune_assoc(dev, apdev, False, False)
3306
3307def test_ap_ft_skip_prune_assoc(dev, apdev):
3308 """WPA2-PSK-FT AP with skip_prune_assoc"""
3309 run_ap_ft_skip_prune_assoc(dev, apdev, True, True)
3310
3311def test_ap_ft_skip_prune_assoc2(dev, apdev):
3312 """WPA2-PSK-FT AP with skip_prune_assoc (disable full_ap_client_state)"""
3313 run_ap_ft_skip_prune_assoc(dev, apdev, True, False, test_connectivity=False)
3314
3315def run_ap_ft_skip_prune_assoc(dev, apdev, skip_prune_assoc,
3316 full_ap_client_state, test_connectivity=True):
3317 ssid = "test-ft"
3318 passphrase = "12345678"
3319
3320 params = ft_params1(ssid=ssid, passphrase=passphrase)
3321 if skip_prune_assoc:
3322 params['skip_prune_assoc'] = '1'
3323 if not full_ap_client_state:
3324 params['driver_params'] = "full_ap_client_state=0"
3325 hapd0 = hostapd.add_ap(apdev[0], params)
3326 params = ft_params2(ssid=ssid, passphrase=passphrase)
3327 if skip_prune_assoc:
3328 params['skip_prune_assoc'] = '1'
3329 if not full_ap_client_state:
3330 params['driver_params'] = "full_ap_client_state=0"
3331 hapd1 = hostapd.add_ap(apdev[1], params)
3332
3333 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
3334 test_connectivity=test_connectivity)
3335
3336def test_ap_ft_sae_skip_prune_assoc(dev, apdev):
3337 """WPA2-PSK-FT-SAE AP with skip_prune_assoc"""
3338 hapd0, hapd1 = start_ft_sae(dev[0], apdev, skip_prune_assoc=True)
3339 run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)