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