]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_fils.py
tests: Remove tabs
[thirdparty/hostap.git] / tests / hwsim / test_fils.py
1 # Test cases for FILS
2 # Copyright (c) 2015-2017, Qualcomm Atheros, Inc.
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import binascii
8 import hashlib
9 import logging
10 logger = logging.getLogger()
11 import os
12 import socket
13 import struct
14 import time
15
16 import hostapd
17 from tshark import run_tshark
18 from wpasupplicant import WpaSupplicant
19 import hwsim_utils
20 from utils import HwsimSkip, alloc_fail
21 from test_erp import check_erp_capa, start_erp_as
22 from test_ap_hs20 import ip_checksum
23
24 def check_fils_capa(dev):
25 capa = dev.get_capability("fils")
26 if capa is None or "FILS" not in capa:
27 raise HwsimSkip("FILS not supported")
28
29 def check_fils_sk_pfs_capa(dev):
30 capa = dev.get_capability("fils")
31 if capa is None or "FILS-SK-PFS" not in capa:
32 raise HwsimSkip("FILS-SK-PFS not supported")
33
34 def test_fils_sk_full_auth(dev, apdev, params):
35 """FILS SK full authentication"""
36 check_fils_capa(dev[0])
37 check_erp_capa(dev[0])
38
39 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
40
41 bssid = apdev[0]['bssid']
42 params = hostapd.wpa2_eap_params(ssid="fils")
43 params['wpa_key_mgmt'] = "FILS-SHA256"
44 params['auth_server_port'] = "18128"
45 params['erp_send_reauth_start'] = '1'
46 params['erp_domain'] = 'example.com'
47 params['fils_realm'] = 'example.com'
48 params['wpa_group_rekey'] = '1'
49 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
50
51 dev[0].scan_for_bss(bssid, freq=2412)
52 bss = dev[0].get_bss(bssid)
53 logger.debug("BSS: " + str(bss))
54 if "[FILS]" not in bss['flags']:
55 raise Exception("[FILS] flag not indicated")
56 if "[WPA2-FILS-SHA256-CCMP]" not in bss['flags']:
57 raise Exception("[WPA2-FILS-SHA256-CCMP] flag not indicated")
58
59 res = dev[0].request("SCAN_RESULTS")
60 logger.debug("SCAN_RESULTS: " + res)
61 if "[FILS]" not in res:
62 raise Exception("[FILS] flag not indicated")
63 if "[WPA2-FILS-SHA256-CCMP]" not in res:
64 raise Exception("[WPA2-FILS-SHA256-CCMP] flag not indicated")
65
66 dev[0].request("ERP_FLUSH")
67 dev[0].connect("fils", key_mgmt="FILS-SHA256",
68 eap="PSK", identity="psk.user@example.com",
69 password_hex="0123456789abcdef0123456789abcdef",
70 erp="1", scan_freq="2412")
71 hwsim_utils.test_connectivity(dev[0], hapd)
72
73 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
74 if ev is None:
75 raise Exception("GTK rekey timed out")
76 hwsim_utils.test_connectivity(dev[0], hapd)
77
78 conf = hapd.get_config()
79 if conf['key_mgmt'] != 'FILS-SHA256':
80 raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
81
82 def test_fils_sk_sha384_full_auth(dev, apdev, params):
83 """FILS SK full authentication (SHA384)"""
84 check_fils_capa(dev[0])
85 check_erp_capa(dev[0])
86
87 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
88
89 bssid = apdev[0]['bssid']
90 params = hostapd.wpa2_eap_params(ssid="fils")
91 params['wpa_key_mgmt'] = "FILS-SHA384"
92 params['auth_server_port'] = "18128"
93 params['erp_send_reauth_start'] = '1'
94 params['erp_domain'] = 'example.com'
95 params['fils_realm'] = 'example.com'
96 params['wpa_group_rekey'] = '1'
97 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
98
99 dev[0].scan_for_bss(bssid, freq=2412)
100 bss = dev[0].get_bss(bssid)
101 logger.debug("BSS: " + str(bss))
102 if "[FILS]" not in bss['flags']:
103 raise Exception("[FILS] flag not indicated")
104 if "[WPA2-FILS-SHA384-CCMP]" not in bss['flags']:
105 raise Exception("[WPA2-FILS-SHA384-CCMP] flag not indicated")
106
107 res = dev[0].request("SCAN_RESULTS")
108 logger.debug("SCAN_RESULTS: " + res)
109 if "[FILS]" not in res:
110 raise Exception("[FILS] flag not indicated")
111 if "[WPA2-FILS-SHA384-CCMP]" not in res:
112 raise Exception("[WPA2-FILS-SHA384-CCMP] flag not indicated")
113
114 dev[0].request("ERP_FLUSH")
115 dev[0].connect("fils", key_mgmt="FILS-SHA384",
116 eap="PSK", identity="psk.user@example.com",
117 password_hex="0123456789abcdef0123456789abcdef",
118 erp="1", scan_freq="2412")
119 hwsim_utils.test_connectivity(dev[0], hapd)
120
121 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
122 if ev is None:
123 raise Exception("GTK rekey timed out")
124 hwsim_utils.test_connectivity(dev[0], hapd)
125
126 conf = hapd.get_config()
127 if conf['key_mgmt'] != 'FILS-SHA384':
128 raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
129
130 def test_fils_sk_pmksa_caching(dev, apdev, params):
131 """FILS SK and PMKSA caching"""
132 check_fils_capa(dev[0])
133 check_erp_capa(dev[0])
134
135 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
136
137 bssid = apdev[0]['bssid']
138 params = hostapd.wpa2_eap_params(ssid="fils")
139 params['wpa_key_mgmt'] = "FILS-SHA256"
140 params['auth_server_port'] = "18128"
141 params['erp_domain'] = 'example.com'
142 params['fils_realm'] = 'example.com'
143 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
144
145 dev[0].scan_for_bss(bssid, freq=2412)
146 dev[0].request("ERP_FLUSH")
147 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
148 eap="PSK", identity="psk.user@example.com",
149 password_hex="0123456789abcdef0123456789abcdef",
150 erp="1", scan_freq="2412")
151 pmksa = dev[0].get_pmksa(bssid)
152 if pmksa is None:
153 raise Exception("No PMKSA cache entry created")
154
155 dev[0].request("DISCONNECT")
156 dev[0].wait_disconnected()
157
158 dev[0].dump_monitor()
159 dev[0].select_network(id, freq=2412)
160 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
161 "CTRL-EVENT-CONNECTED"], timeout=10)
162 if ev is None:
163 raise Exception("Connection using PMKSA caching timed out")
164 if "CTRL-EVENT-EAP-STARTED" in ev:
165 raise Exception("Unexpected EAP exchange")
166 hwsim_utils.test_connectivity(dev[0], hapd)
167 pmksa2 = dev[0].get_pmksa(bssid)
168 if pmksa2 is None:
169 raise Exception("No PMKSA cache entry found")
170 if pmksa['pmkid'] != pmksa2['pmkid']:
171 raise Exception("Unexpected PMKID change")
172
173 # Verify EAPOL reauthentication after FILS authentication
174 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
175 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
176 if ev is None:
177 raise Exception("EAP authentication did not start")
178 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
179 if ev is None:
180 raise Exception("EAP authentication did not succeed")
181 time.sleep(0.1)
182 hwsim_utils.test_connectivity(dev[0], hapd)
183
184 def test_fils_sk_pmksa_caching_ocv(dev, apdev, params):
185 """FILS SK and PMKSA caching with OCV"""
186 check_fils_capa(dev[0])
187 check_erp_capa(dev[0])
188
189 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
190
191 bssid = apdev[0]['bssid']
192 params = hostapd.wpa2_eap_params(ssid="fils")
193 params['wpa_key_mgmt'] = "FILS-SHA256"
194 params['auth_server_port'] = "18128"
195 params['erp_domain'] = 'example.com'
196 params['fils_realm'] = 'example.com'
197 params['ieee80211w'] = '1'
198 params['ocv'] = '1'
199 try:
200 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
201 except Exception as e:
202 if "Failed to set hostapd parameter ocv" in str(e):
203 raise HwsimSkip("OCV not supported")
204 raise
205
206 dev[0].scan_for_bss(bssid, freq=2412)
207 dev[0].request("ERP_FLUSH")
208 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
209 eap="PSK", identity="psk.user@example.com",
210 password_hex="0123456789abcdef0123456789abcdef",
211 erp="1", scan_freq="2412", ieee80211w="1", ocv="1")
212 pmksa = dev[0].get_pmksa(bssid)
213 if pmksa is None:
214 raise Exception("No PMKSA cache entry created")
215
216 dev[0].request("DISCONNECT")
217 dev[0].wait_disconnected()
218
219 dev[0].dump_monitor()
220 dev[0].select_network(id, freq=2412)
221 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
222 "CTRL-EVENT-CONNECTED"], timeout=10)
223 if ev is None:
224 raise Exception("Connection using PMKSA caching timed out")
225 if "CTRL-EVENT-EAP-STARTED" in ev:
226 raise Exception("Unexpected EAP exchange")
227 hwsim_utils.test_connectivity(dev[0], hapd)
228 pmksa2 = dev[0].get_pmksa(bssid)
229 if pmksa2 is None:
230 raise Exception("No PMKSA cache entry found")
231 if pmksa['pmkid'] != pmksa2['pmkid']:
232 raise Exception("Unexpected PMKID change")
233
234 # Verify EAPOL reauthentication after FILS authentication
235 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
236 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
237 if ev is None:
238 raise Exception("EAP authentication did not start")
239 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
240 if ev is None:
241 raise Exception("EAP authentication did not succeed")
242 time.sleep(0.1)
243 hwsim_utils.test_connectivity(dev[0], hapd)
244
245 def test_fils_sk_pmksa_caching_and_cache_id(dev, apdev):
246 """FILS SK and PMKSA caching with Cache Identifier"""
247 check_fils_capa(dev[0])
248 check_erp_capa(dev[0])
249
250 bssid = apdev[0]['bssid']
251 params = hostapd.wpa2_eap_params(ssid="fils")
252 params['wpa_key_mgmt'] = "FILS-SHA256"
253 params['auth_server_port'] = "18128"
254 params['erp_domain'] = 'example.com'
255 params['fils_realm'] = 'example.com'
256 params['fils_cache_id'] = "abcd"
257 params["radius_server_clients"] = "auth_serv/radius_clients.conf"
258 params["radius_server_auth_port"] = '18128'
259 params["eap_server"] = "1"
260 params["eap_user_file"] = "auth_serv/eap_user.conf"
261 params["ca_cert"] = "auth_serv/ca.pem"
262 params["server_cert"] = "auth_serv/server.pem"
263 params["private_key"] = "auth_serv/server.key"
264 params["eap_sim_db"] = "unix:/tmp/hlr_auc_gw.sock"
265 params["dh_file"] = "auth_serv/dh.conf"
266 params["pac_opaque_encr_key"] = "000102030405060708090a0b0c0d0e0f"
267 params["eap_fast_a_id"] = "101112131415161718191a1b1c1d1e1f"
268 params["eap_fast_a_id_info"] = "test server"
269 params["eap_server_erp"] = "1"
270 params["erp_domain"] = "example.com"
271 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
272
273 dev[0].scan_for_bss(bssid, freq=2412)
274 dev[0].request("ERP_FLUSH")
275 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
276 eap="PSK", identity="psk.user@example.com",
277 password_hex="0123456789abcdef0123456789abcdef",
278 erp="1", scan_freq="2412")
279 res = dev[0].request("PMKSA")
280 if "FILS Cache Identifier" not in res:
281 raise Exception("PMKSA list does not include FILS Cache Identifier")
282 pmksa = dev[0].get_pmksa(bssid)
283 if pmksa is None:
284 raise Exception("No PMKSA cache entry created")
285 if "cache_id" not in pmksa:
286 raise Exception("No FILS Cache Identifier listed")
287 if pmksa["cache_id"] != "abcd":
288 raise Exception("The configured FILS Cache Identifier not seen in PMKSA")
289
290 bssid2 = apdev[1]['bssid']
291 params = hostapd.wpa2_eap_params(ssid="fils")
292 params['wpa_key_mgmt'] = "FILS-SHA256"
293 params['auth_server_port'] = "18128"
294 params['erp_domain'] = 'example.com'
295 params['fils_realm'] = 'example.com'
296 params['fils_cache_id'] = "abcd"
297 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
298
299 dev[0].scan_for_bss(bssid2, freq=2412)
300
301 dev[0].dump_monitor()
302 if "OK" not in dev[0].request("ROAM " + bssid2):
303 raise Exception("ROAM failed")
304
305 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
306 "CTRL-EVENT-CONNECTED"], timeout=10)
307 if ev is None:
308 raise Exception("Connection using PMKSA caching timed out")
309 if "CTRL-EVENT-EAP-STARTED" in ev:
310 raise Exception("Unexpected EAP exchange")
311 if bssid2 not in ev:
312 raise Exception("Failed to connect to the second AP")
313
314 hwsim_utils.test_connectivity(dev[0], hapd2)
315 pmksa2 = dev[0].get_pmksa(bssid2)
316 if pmksa2:
317 raise Exception("Unexpected extra PMKSA cache added")
318 pmksa2 = dev[0].get_pmksa(bssid)
319 if not pmksa2:
320 raise Exception("Original PMKSA cache entry removed")
321 if pmksa['pmkid'] != pmksa2['pmkid']:
322 raise Exception("Unexpected PMKID change")
323
324 def test_fils_sk_pmksa_caching_ctrl_ext(dev, apdev, params):
325 """FILS SK and PMKSA caching with Cache Identifier and external management"""
326 check_fils_capa(dev[0])
327 check_erp_capa(dev[0])
328
329 hapd_as = start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
330
331 bssid = apdev[0]['bssid']
332 params = hostapd.wpa2_eap_params(ssid="fils")
333 params['wpa_key_mgmt'] = "FILS-SHA384"
334 params['auth_server_port'] = "18128"
335 params['erp_send_reauth_start'] = '1'
336 params['erp_domain'] = 'example.com'
337 params['fils_realm'] = 'example.com'
338 params['fils_cache_id'] = "ffee"
339 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
340
341 dev[0].scan_for_bss(bssid, freq=2412)
342 dev[0].request("ERP_FLUSH")
343 id = dev[0].connect("fils", key_mgmt="FILS-SHA384",
344 eap="PSK", identity="psk.user@example.com",
345 password_hex="0123456789abcdef0123456789abcdef",
346 erp="1", scan_freq="2412")
347
348 res1 = dev[0].request("PMKSA_GET %d" % id)
349 logger.info("PMKSA_GET: " + res1)
350 if "UNKNOWN COMMAND" in res1:
351 raise HwsimSkip("PMKSA_GET not supported in the build")
352 if bssid not in res1:
353 raise Exception("PMKSA cache entry missing")
354 if "ffee" not in res1:
355 raise Exception("FILS Cache Identifier not seen in PMKSA cache entry")
356
357 dev[0].request("DISCONNECT")
358 dev[0].wait_disconnected()
359 hapd_as.disable()
360
361 dev[0].scan_for_bss(bssid, freq=2412)
362 dev[0].request("PMKSA_FLUSH")
363 dev[0].request("ERP_FLUSH")
364 for entry in res1.splitlines():
365 if "OK" not in dev[0].request("PMKSA_ADD %d %s" % (id, entry)):
366 raise Exception("Failed to add PMKSA entry")
367
368 bssid2 = apdev[1]['bssid']
369 params = hostapd.wpa2_eap_params(ssid="fils")
370 params['wpa_key_mgmt'] = "FILS-SHA384"
371 params['auth_server_port'] = "18128"
372 params['erp_send_reauth_start'] = '1'
373 params['erp_domain'] = 'example.com'
374 params['fils_realm'] = 'example.com'
375 params['fils_cache_id'] = "ffee"
376 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
377
378 dev[0].scan_for_bss(bssid2, freq=2412)
379 dev[0].set_network(id, "bssid", bssid2)
380 dev[0].select_network(id, freq=2412)
381 ev = dev[0].wait_connected()
382 if bssid2 not in ev:
383 raise Exception("Unexpected BSS selected")
384
385 def test_fils_sk_erp(dev, apdev, params):
386 """FILS SK using ERP"""
387 run_fils_sk_erp(dev, apdev, "FILS-SHA256", params)
388
389 def test_fils_sk_erp_sha384(dev, apdev, params):
390 """FILS SK using ERP and SHA384"""
391 run_fils_sk_erp(dev, apdev, "FILS-SHA384", params)
392
393 def run_fils_sk_erp(dev, apdev, key_mgmt, params):
394 check_fils_capa(dev[0])
395 check_erp_capa(dev[0])
396
397 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
398
399 bssid = apdev[0]['bssid']
400 params = hostapd.wpa2_eap_params(ssid="fils")
401 params['wpa_key_mgmt'] = key_mgmt
402 params['auth_server_port'] = "18128"
403 params['erp_domain'] = 'example.com'
404 params['fils_realm'] = 'example.com'
405 params['disable_pmksa_caching'] = '1'
406 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
407
408 dev[0].scan_for_bss(bssid, freq=2412)
409 dev[0].request("ERP_FLUSH")
410 id = dev[0].connect("fils", key_mgmt=key_mgmt,
411 eap="PSK", identity="psk.user@example.com",
412 password_hex="0123456789abcdef0123456789abcdef",
413 erp="1", scan_freq="2412")
414
415 dev[0].request("DISCONNECT")
416 dev[0].wait_disconnected()
417
418 dev[0].dump_monitor()
419 dev[0].select_network(id, freq=2412)
420 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
421 "EVENT-ASSOC-REJECT",
422 "CTRL-EVENT-CONNECTED"], timeout=10)
423 if ev is None:
424 raise Exception("Connection using FILS/ERP timed out")
425 if "CTRL-EVENT-EAP-STARTED" in ev:
426 raise Exception("Unexpected EAP exchange")
427 if "EVENT-ASSOC-REJECT" in ev:
428 raise Exception("Association failed")
429 hwsim_utils.test_connectivity(dev[0], hapd)
430
431 def test_fils_sk_erp_followed_by_pmksa_caching(dev, apdev, params):
432 """FILS SK ERP following by PMKSA caching"""
433 check_fils_capa(dev[0])
434 check_erp_capa(dev[0])
435
436 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
437
438 bssid = apdev[0]['bssid']
439 params = hostapd.wpa2_eap_params(ssid="fils")
440 params['wpa_key_mgmt'] = "FILS-SHA256"
441 params['auth_server_port'] = "18128"
442 params['erp_domain'] = 'example.com'
443 params['fils_realm'] = 'example.com'
444 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
445
446 dev[0].scan_for_bss(bssid, freq=2412)
447 dev[0].request("ERP_FLUSH")
448 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
449 eap="PSK", identity="psk.user@example.com",
450 password_hex="0123456789abcdef0123456789abcdef",
451 erp="1", scan_freq="2412")
452
453 dev[0].request("DISCONNECT")
454 dev[0].wait_disconnected()
455
456 # Force the second connection to use ERP by deleting the PMKSA entry.
457 dev[0].request("PMKSA_FLUSH")
458
459 dev[0].dump_monitor()
460 dev[0].select_network(id, freq=2412)
461 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
462 "EVENT-ASSOC-REJECT",
463 "CTRL-EVENT-CONNECTED"], timeout=10)
464 if ev is None:
465 raise Exception("Connection using FILS/ERP timed out")
466 if "CTRL-EVENT-EAP-STARTED" in ev:
467 raise Exception("Unexpected EAP exchange")
468 if "EVENT-ASSOC-REJECT" in ev:
469 raise Exception("Association failed")
470 hwsim_utils.test_connectivity(dev[0], hapd)
471
472 pmksa = dev[0].get_pmksa(bssid)
473 if pmksa is None:
474 raise Exception("No PMKSA cache entry created")
475
476 dev[0].request("DISCONNECT")
477 dev[0].wait_disconnected()
478
479 # The third connection is expected to use PMKSA caching for FILS
480 # authentication.
481 dev[0].dump_monitor()
482 dev[0].select_network(id, freq=2412)
483 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
484 "EVENT-ASSOC-REJECT",
485 "CTRL-EVENT-CONNECTED"], timeout=10)
486 if ev is None:
487 raise Exception("Connection using PMKSA caching timed out")
488 if "CTRL-EVENT-EAP-STARTED" in ev:
489 raise Exception("Unexpected EAP exchange")
490 if "EVENT-ASSOC-REJECT" in ev:
491 raise Exception("Association failed")
492 hwsim_utils.test_connectivity(dev[0], hapd)
493
494 pmksa2 = dev[0].get_pmksa(bssid)
495 if pmksa2 is None:
496 raise Exception("No PMKSA cache entry found")
497 if pmksa['pmkid'] != pmksa2['pmkid']:
498 raise Exception("Unexpected PMKID change")
499
500 def test_fils_sk_erp_another_ssid(dev, apdev, params):
501 """FILS SK using ERP and roam to another SSID"""
502 check_fils_capa(dev[0])
503 check_erp_capa(dev[0])
504
505 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
506
507 bssid = apdev[0]['bssid']
508 params = hostapd.wpa2_eap_params(ssid="fils")
509 params['wpa_key_mgmt'] = "FILS-SHA256"
510 params['auth_server_port'] = "18128"
511 params['erp_domain'] = 'example.com'
512 params['fils_realm'] = 'example.com'
513 params['disable_pmksa_caching'] = '1'
514 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
515
516 dev[0].scan_for_bss(bssid, freq=2412)
517 dev[0].request("ERP_FLUSH")
518 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
519 eap="PSK", identity="psk.user@example.com",
520 password_hex="0123456789abcdef0123456789abcdef",
521 erp="1", scan_freq="2412")
522
523 dev[0].request("DISCONNECT")
524 dev[0].wait_disconnected()
525 hapd.disable()
526 dev[0].flush_scan_cache()
527 if "FAIL" in dev[0].request("PMKSA_FLUSH"):
528 raise Exception("PMKSA_FLUSH failed")
529
530 params = hostapd.wpa2_eap_params(ssid="fils2")
531 params['wpa_key_mgmt'] = "FILS-SHA256"
532 params['auth_server_port'] = "18128"
533 params['erp_domain'] = 'example.com'
534 params['fils_realm'] = 'example.com'
535 params['disable_pmksa_caching'] = '1'
536 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
537
538 dev[0].scan_for_bss(bssid, freq=2412)
539 dev[0].dump_monitor()
540 id = dev[0].connect("fils2", key_mgmt="FILS-SHA256",
541 eap="PSK", identity="psk.user@example.com",
542 password_hex="0123456789abcdef0123456789abcdef",
543 erp="1", scan_freq="2412", wait_connect=False)
544
545 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
546 "EVENT-ASSOC-REJECT",
547 "CTRL-EVENT-CONNECTED"], timeout=10)
548 if ev is None:
549 raise Exception("Connection using FILS/ERP timed out")
550 if "CTRL-EVENT-EAP-STARTED" in ev:
551 raise Exception("Unexpected EAP exchange")
552 if "EVENT-ASSOC-REJECT" in ev:
553 raise Exception("Association failed")
554 hwsim_utils.test_connectivity(dev[0], hapd)
555
556 def test_fils_sk_multiple_realms(dev, apdev, params):
557 """FILS SK and multiple realms"""
558 check_fils_capa(dev[0])
559 check_erp_capa(dev[0])
560
561 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
562
563 bssid = apdev[0]['bssid']
564 params = hostapd.wpa2_eap_params(ssid="fils")
565 params['wpa_key_mgmt'] = "FILS-SHA256"
566 params['auth_server_port'] = "18128"
567 params['erp_domain'] = 'example.com'
568 fils_realms = ['r1.example.org', 'r2.EXAMPLE.org', 'r3.example.org',
569 'r4.example.org', 'r5.example.org', 'r6.example.org',
570 'r7.example.org', 'r8.example.org',
571 'example.com',
572 'r9.example.org', 'r10.example.org', 'r11.example.org',
573 'r12.example.org', 'r13.example.org', 'r14.example.org',
574 'r15.example.org', 'r16.example.org']
575 params['fils_realm'] = fils_realms
576 params['fils_cache_id'] = "1234"
577 params['hessid'] = bssid
578 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
579
580 dev[0].scan_for_bss(bssid, freq=2412)
581
582 if "OK" not in dev[0].request("ANQP_GET " + bssid + " 275"):
583 raise Exception("ANQP_GET command failed")
584 ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10)
585 if ev is None:
586 raise Exception("GAS query timed out")
587 bss = dev[0].get_bss(bssid)
588
589 if 'fils_info' not in bss:
590 raise Exception("FILS Indication element information missing")
591 if bss['fils_info'] != '02b8':
592 raise Exception("Unexpected FILS Information: " + bss['fils_info'])
593
594 if 'fils_cache_id' not in bss:
595 raise Exception("FILS Cache Identifier missing")
596 if bss['fils_cache_id'] != '1234':
597 raise Exception("Unexpected FILS Cache Identifier: " + bss['fils_cache_id'])
598
599 if 'fils_realms' not in bss:
600 raise Exception("FILS Realm Identifiers missing")
601 expected = ''
602 count = 0
603 for realm in fils_realms:
604 hash = hashlib.sha256(realm.lower().encode()).digest()
605 expected += binascii.hexlify(hash[0:2]).decode()
606 count += 1
607 if count == 7:
608 break
609 if bss['fils_realms'] != expected:
610 raise Exception("Unexpected FILS Realm Identifiers: " + bss['fils_realms'])
611
612 if 'anqp_fils_realm_info' not in bss:
613 raise Exception("FILS Realm Information ANQP-element not seen")
614 info = bss['anqp_fils_realm_info']
615 expected = ''
616 for realm in fils_realms:
617 hash = hashlib.sha256(realm.lower().encode()).digest()
618 expected += binascii.hexlify(hash[0:2]).decode()
619 if info != expected:
620 raise Exception("Unexpected FILS Realm Info ANQP-element: " + info)
621
622 dev[0].request("ERP_FLUSH")
623 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
624 eap="PSK", identity="psk.user@example.com",
625 password_hex="0123456789abcdef0123456789abcdef",
626 erp="1", scan_freq="2412")
627
628 dev[0].request("DISCONNECT")
629 dev[0].wait_disconnected()
630
631 dev[0].dump_monitor()
632 dev[0].select_network(id, freq=2412)
633 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
634 "EVENT-ASSOC-REJECT",
635 "CTRL-EVENT-CONNECTED"], timeout=10)
636 if ev is None:
637 raise Exception("Connection using FILS/ERP timed out")
638 if "CTRL-EVENT-EAP-STARTED" in ev:
639 raise Exception("Unexpected EAP exchange")
640 if "EVENT-ASSOC-REJECT" in ev:
641 raise Exception("Association failed")
642 hwsim_utils.test_connectivity(dev[0], hapd)
643
644 # DHCP message op codes
645 BOOTREQUEST = 1
646 BOOTREPLY = 2
647
648 OPT_PAD = 0
649 OPT_DHCP_MESSAGE_TYPE = 53
650 OPT_RAPID_COMMIT = 80
651 OPT_END = 255
652
653 DHCPDISCOVER = 1
654 DHCPOFFER = 2
655 DHCPREQUEST = 3
656 DHCPDECLINE = 4
657 DHCPACK = 5
658 DHCPNAK = 6
659 DHCPRELEASE = 7
660 DHCPINFORM = 8
661
662 def build_dhcp(req, dhcp_msg, chaddr, giaddr="0.0.0.0",
663 ip_src="0.0.0.0", ip_dst="255.255.255.255",
664 rapid_commit=True, override_op=None, magic_override=None,
665 opt_end=True, extra_op=None):
666 proto = b'\x08\x00' # IPv4
667 _ip_src = socket.inet_pton(socket.AF_INET, ip_src)
668 _ip_dst = socket.inet_pton(socket.AF_INET, ip_dst)
669
670 _ciaddr = b'\x00\x00\x00\x00'
671 _yiaddr = b'\x00\x00\x00\x00'
672 _siaddr = b'\x00\x00\x00\x00'
673 _giaddr = socket.inet_pton(socket.AF_INET, giaddr)
674 _chaddr = binascii.unhexlify(chaddr.replace(':', '')) + 10 * b'\x00'
675 htype = 1 # Hardware address type; 1 = Ethernet
676 hlen = 6 # Hardware address length
677 hops = 0
678 xid = 123456
679 secs = 0
680 flags = 0
681 if req:
682 op = BOOTREQUEST
683 src_port = 68
684 dst_port = 67
685 else:
686 op = BOOTREPLY
687 src_port = 67
688 dst_port = 68
689 if override_op is not None:
690 op = override_op
691 payload = struct.pack('>BBBBLHH', op, htype, hlen, hops, xid, secs, flags)
692 sname = 64*b'\x00'
693 file = 128*b'\x00'
694 payload += _ciaddr + _yiaddr + _siaddr + _giaddr + _chaddr + sname + file
695 # magic - DHCP
696 if magic_override is not None:
697 payload += magic_override
698 else:
699 payload += b'\x63\x82\x53\x63'
700 # Option: DHCP Message Type
701 if dhcp_msg is not None:
702 payload += struct.pack('BBB', OPT_DHCP_MESSAGE_TYPE, 1, dhcp_msg)
703 if rapid_commit:
704 # Option: Rapid Commit
705 payload += struct.pack('BB', OPT_RAPID_COMMIT, 0)
706 if extra_op:
707 payload += extra_op
708 # End Option
709 if opt_end:
710 payload += struct.pack('B', OPT_END)
711
712 udp = struct.pack('>HHHH', src_port, dst_port,
713 8 + len(payload), 0) + payload
714
715 tot_len = 20 + len(udp)
716 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
717 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
718 csum = ip_checksum(ipv4)
719 ipv4 = start + csum + _ip_src + _ip_dst
720
721 return proto + ipv4 + udp
722
723 def fils_hlp_config(fils_hlp_wait_time=10000):
724 params = hostapd.wpa2_eap_params(ssid="fils")
725 params['wpa_key_mgmt'] = "FILS-SHA256"
726 params['auth_server_port'] = "18128"
727 params['erp_domain'] = 'example.com'
728 params['fils_realm'] = 'example.com'
729 params['disable_pmksa_caching'] = '1'
730 params['own_ip_addr'] = '127.0.0.3'
731 params['dhcp_server'] = '127.0.0.2'
732 params['fils_hlp_wait_time'] = str(fils_hlp_wait_time)
733 return params
734
735 def test_fils_sk_hlp(dev, apdev, params):
736 """FILS SK HLP (rapid commit server)"""
737 run_fils_sk_hlp(dev, apdev, True, params)
738
739 def test_fils_sk_hlp_no_rapid_commit(dev, apdev, params):
740 """FILS SK HLP (no rapid commit server)"""
741 run_fils_sk_hlp(dev, apdev, False, params)
742
743 def run_fils_sk_hlp(dev, apdev, rapid_commit_server, params):
744 check_fils_capa(dev[0])
745 check_erp_capa(dev[0])
746
747 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
748
749 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
750 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
751 sock.settimeout(5)
752 sock.bind(("127.0.0.2", 67))
753
754 bssid = apdev[0]['bssid']
755 params = fils_hlp_config()
756 params['fils_hlp_wait_time'] = '10000'
757 if not rapid_commit_server:
758 params['dhcp_rapid_commit_proxy'] = '1'
759 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
760
761 dev[0].scan_for_bss(bssid, freq=2412)
762 dev[0].request("ERP_FLUSH")
763 if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
764 raise Exception("Failed to flush pending FILS HLP requests")
765 tests = ["",
766 "q",
767 "ff:ff:ff:ff:ff:ff",
768 "ff:ff:ff:ff:ff:ff q"]
769 for t in tests:
770 if "FAIL" not in dev[0].request("FILS_HLP_REQ_ADD " + t):
771 raise Exception("Invalid FILS_HLP_REQ_ADD accepted: " + t)
772 dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
773 chaddr=dev[0].own_addr())
774 tests = ["ff:ff:ff:ff:ff:ff aabb",
775 "ff:ff:ff:ff:ff:ff " + 255*'cc',
776 hapd.own_addr() + " ddee010203040506070809",
777 "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc).decode()]
778 for t in tests:
779 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + t):
780 raise Exception("FILS_HLP_REQ_ADD failed: " + t)
781 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
782 eap="PSK", identity="psk.user@example.com",
783 password_hex="0123456789abcdef0123456789abcdef",
784 erp="1", scan_freq="2412")
785
786 dev[0].request("DISCONNECT")
787 dev[0].wait_disconnected()
788
789 dev[0].dump_monitor()
790 dev[0].select_network(id, freq=2412)
791
792 (msg, addr) = sock.recvfrom(1000)
793 logger.debug("Received DHCP message from %s" % str(addr))
794 if rapid_commit_server:
795 # TODO: Proper rapid commit response
796 dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
797 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
798 sock.sendto(dhcpdisc[2+20+8:], addr)
799 else:
800 dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
801 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
802 sock.sendto(dhcpdisc[2+20+8:], addr)
803 (msg, addr) = sock.recvfrom(1000)
804 logger.debug("Received DHCP message from %s" % str(addr))
805 dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK, rapid_commit=False,
806 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
807 sock.sendto(dhcpdisc[2+20+8:], addr)
808 ev = dev[0].wait_event(["FILS-HLP-RX"], timeout=10)
809 if ev is None:
810 raise Exception("FILS HLP response not reported")
811 vals = ev.split(' ')
812 frame = binascii.unhexlify(vals[3].split('=')[1])
813 proto, = struct.unpack('>H', frame[0:2])
814 if proto != 0x0800:
815 raise Exception("Unexpected ethertype in HLP response: %d" % proto)
816 frame = frame[2:]
817 ip = frame[0:20]
818 if ip_checksum(ip) != b'\x00\x00':
819 raise Exception("IP header checksum mismatch in HLP response")
820 frame = frame[20:]
821 udp = frame[0:8]
822 frame = frame[8:]
823 sport, dport, ulen, ucheck = struct.unpack('>HHHH', udp)
824 if sport != 67 or dport != 68:
825 raise Exception("Unexpected UDP port in HLP response")
826 dhcp = frame[0:28]
827 frame = frame[28:]
828 op, htype, hlen, hops, xid, secs, flags, ciaddr, yiaddr, siaddr, giaddr = struct.unpack('>4BL2H4L', dhcp)
829 chaddr = frame[0:16]
830 frame = frame[16:]
831 sname = frame[0:64]
832 frame = frame[64:]
833 file = frame[0:128]
834 frame = frame[128:]
835 options = frame
836 if options[0:4] != b'\x63\x82\x53\x63':
837 raise Exception("No DHCP magic seen in HLP response")
838 options = options[4:]
839 # TODO: fully parse and validate DHCPACK options
840 if struct.pack('BBB', OPT_DHCP_MESSAGE_TYPE, 1, DHCPACK) not in options:
841 raise Exception("DHCPACK not in HLP response")
842
843 dev[0].wait_connected()
844
845 dev[0].request("FILS_HLP_REQ_FLUSH")
846
847 def test_fils_sk_hlp_timeout(dev, apdev, params):
848 """FILS SK HLP (rapid commit server timeout)"""
849 check_fils_capa(dev[0])
850 check_erp_capa(dev[0])
851
852 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
853
854 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
855 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
856 sock.settimeout(5)
857 sock.bind(("127.0.0.2", 67))
858
859 bssid = apdev[0]['bssid']
860 params = fils_hlp_config(fils_hlp_wait_time=30)
861 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
862
863 dev[0].scan_for_bss(bssid, freq=2412)
864 dev[0].request("ERP_FLUSH")
865 if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
866 raise Exception("Failed to flush pending FILS HLP requests")
867 dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
868 chaddr=dev[0].own_addr())
869 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc).decode()):
870 raise Exception("FILS_HLP_REQ_ADD failed")
871 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
872 eap="PSK", identity="psk.user@example.com",
873 password_hex="0123456789abcdef0123456789abcdef",
874 erp="1", scan_freq="2412")
875
876 dev[0].request("DISCONNECT")
877 dev[0].wait_disconnected()
878
879 dev[0].dump_monitor()
880 dev[0].select_network(id, freq=2412)
881
882 (msg, addr) = sock.recvfrom(1000)
883 logger.debug("Received DHCP message from %s" % str(addr))
884 # Wait for HLP wait timeout to hit
885 # FILS: HLP response timeout - continue with association response
886 dev[0].wait_connected()
887
888 dev[0].request("FILS_HLP_REQ_FLUSH")
889
890 def test_fils_sk_hlp_oom(dev, apdev, params):
891 """FILS SK HLP and hostapd OOM"""
892 check_fils_capa(dev[0])
893 check_erp_capa(dev[0])
894
895 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
896
897 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
898 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
899 sock.settimeout(5)
900 sock.bind(("127.0.0.2", 67))
901
902 bssid = apdev[0]['bssid']
903 params = fils_hlp_config(fils_hlp_wait_time=500)
904 params['dhcp_rapid_commit_proxy'] = '1'
905 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
906
907 dev[0].scan_for_bss(bssid, freq=2412)
908 dev[0].request("ERP_FLUSH")
909 if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
910 raise Exception("Failed to flush pending FILS HLP requests")
911 dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
912 chaddr=dev[0].own_addr())
913 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc).decode()):
914 raise Exception("FILS_HLP_REQ_ADD failed")
915 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
916 eap="PSK", identity="psk.user@example.com",
917 password_hex="0123456789abcdef0123456789abcdef",
918 erp="1", scan_freq="2412")
919
920 dev[0].request("DISCONNECT")
921 dev[0].wait_disconnected()
922
923 dev[0].dump_monitor()
924 with alloc_fail(hapd, 1, "fils_process_hlp"):
925 dev[0].select_network(id, freq=2412)
926 dev[0].wait_connected()
927 dev[0].request("DISCONNECT")
928 dev[0].wait_disconnected()
929
930 dev[0].dump_monitor()
931 with alloc_fail(hapd, 1, "fils_process_hlp_dhcp"):
932 dev[0].select_network(id, freq=2412)
933 dev[0].wait_connected()
934 dev[0].request("DISCONNECT")
935 dev[0].wait_disconnected()
936
937 dev[0].dump_monitor()
938 with alloc_fail(hapd, 1, "wpabuf_alloc;fils_process_hlp_dhcp"):
939 dev[0].select_network(id, freq=2412)
940 dev[0].wait_connected()
941 dev[0].request("DISCONNECT")
942 dev[0].wait_disconnected()
943
944 dev[0].dump_monitor()
945 with alloc_fail(hapd, 1, "wpabuf_alloc;fils_dhcp_handler"):
946 dev[0].select_network(id, freq=2412)
947 (msg, addr) = sock.recvfrom(1000)
948 logger.debug("Received DHCP message from %s" % str(addr))
949 dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
950 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
951 sock.sendto(dhcpdisc[2+20+8:], addr)
952 dev[0].wait_connected()
953 dev[0].request("DISCONNECT")
954 dev[0].wait_disconnected()
955
956 dev[0].dump_monitor()
957 with alloc_fail(hapd, 1, "wpabuf_resize;fils_dhcp_handler"):
958 dev[0].select_network(id, freq=2412)
959 (msg, addr) = sock.recvfrom(1000)
960 logger.debug("Received DHCP message from %s" % str(addr))
961 dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
962 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
963 sock.sendto(dhcpdisc[2+20+8:], addr)
964 dev[0].wait_connected()
965 dev[0].request("DISCONNECT")
966 dev[0].wait_disconnected()
967
968 dev[0].dump_monitor()
969 dev[0].select_network(id, freq=2412)
970 (msg, addr) = sock.recvfrom(1000)
971 logger.debug("Received DHCP message from %s" % str(addr))
972 dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
973 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
974 with alloc_fail(hapd, 1, "wpabuf_resize;fils_dhcp_request"):
975 sock.sendto(dhcpoffer[2+20+8:], addr)
976 dev[0].wait_connected()
977 dev[0].request("DISCONNECT")
978 dev[0].wait_disconnected()
979
980 dev[0].request("FILS_HLP_REQ_FLUSH")
981
982 def test_fils_sk_hlp_req_parsing(dev, apdev, params):
983 """FILS SK HLP request parsing"""
984 check_fils_capa(dev[0])
985 check_erp_capa(dev[0])
986
987 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
988
989 bssid = apdev[0]['bssid']
990 params = fils_hlp_config(fils_hlp_wait_time=30)
991 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
992
993 dev[0].scan_for_bss(bssid, freq=2412)
994 dev[0].request("ERP_FLUSH")
995 if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
996 raise Exception("Failed to flush pending FILS HLP requests")
997
998 tot_len = 20 + 1
999 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
1000 _ip_src = b'\x00\x00\x00\x00'
1001 _ip_dst = b'\x00\x00\x00\x00'
1002 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
1003 csum = ip_checksum(ipv4)
1004 ipv4_overflow = start + csum + _ip_src + _ip_dst
1005
1006 tot_len = 20
1007 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 123)
1008 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
1009 csum = ip_checksum(ipv4)
1010 ipv4_unknown_proto = start + csum + _ip_src + _ip_dst
1011
1012 tot_len = 20
1013 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
1014 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
1015 csum = ip_checksum(ipv4)
1016 ipv4_missing_udp_hdr = start + csum + _ip_src + _ip_dst
1017
1018 src_port = 68
1019 dst_port = 67
1020 udp = struct.pack('>HHHH', src_port, dst_port, 8 + 1, 0)
1021 tot_len = 20 + len(udp)
1022 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
1023 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
1024 csum = ip_checksum(ipv4)
1025 udp_overflow = start + csum + _ip_src + _ip_dst + udp
1026
1027 udp = struct.pack('>HHHH', src_port, dst_port, 7, 0)
1028 tot_len = 20 + len(udp)
1029 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
1030 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
1031 csum = ip_checksum(ipv4)
1032 udp_underflow = start + csum + _ip_src + _ip_dst + udp
1033
1034 src_port = 123
1035 dst_port = 456
1036 udp = struct.pack('>HHHH', src_port, dst_port, 8, 0)
1037 tot_len = 20 + len(udp)
1038 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
1039 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
1040 csum = ip_checksum(ipv4)
1041 udp_unknown_port = start + csum + _ip_src + _ip_dst + udp
1042
1043 src_port = 68
1044 dst_port = 67
1045 udp = struct.pack('>HHHH', src_port, dst_port, 8, 0)
1046 tot_len = 20 + len(udp)
1047 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
1048 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst
1049 csum = ip_checksum(ipv4)
1050 dhcp_missing_data = start + csum + _ip_src + _ip_dst + udp
1051
1052 dhcp_not_req = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
1053 chaddr=dev[0].own_addr(), override_op=BOOTREPLY)
1054 dhcp_no_magic = build_dhcp(req=True, dhcp_msg=None,
1055 chaddr=dev[0].own_addr(), magic_override=b'',
1056 rapid_commit=False, opt_end=False)
1057 dhcp_unknown_magic = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
1058 chaddr=dev[0].own_addr(),
1059 magic_override=b'\x00\x00\x00\x00')
1060 dhcp_opts = build_dhcp(req=True, dhcp_msg=DHCPNAK,
1061 chaddr=dev[0].own_addr(),
1062 extra_op=b'\x00\x11', opt_end=False)
1063 dhcp_opts2 = build_dhcp(req=True, dhcp_msg=DHCPNAK,
1064 chaddr=dev[0].own_addr(),
1065 extra_op=b'\x11\x01', opt_end=False)
1066 dhcp_valid = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
1067 chaddr=dev[0].own_addr())
1068
1069 tests = ["ff",
1070 "0800",
1071 "0800" + 20*"00",
1072 "0800" + binascii.hexlify(ipv4_overflow).decode(),
1073 "0800" + binascii.hexlify(ipv4_unknown_proto).decode(),
1074 "0800" + binascii.hexlify(ipv4_missing_udp_hdr).decode(),
1075 "0800" + binascii.hexlify(udp_overflow).decode(),
1076 "0800" + binascii.hexlify(udp_underflow).decode(),
1077 "0800" + binascii.hexlify(udp_unknown_port).decode(),
1078 "0800" + binascii.hexlify(dhcp_missing_data).decode(),
1079 binascii.hexlify(dhcp_not_req).decode(),
1080 binascii.hexlify(dhcp_no_magic).decode(),
1081 binascii.hexlify(dhcp_unknown_magic).decode()]
1082 for t in tests:
1083 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + t):
1084 raise Exception("FILS_HLP_REQ_ADD failed: " + t)
1085 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1086 eap="PSK", identity="psk.user@example.com",
1087 password_hex="0123456789abcdef0123456789abcdef",
1088 erp="1", scan_freq="2412")
1089
1090 dev[0].request("DISCONNECT")
1091 dev[0].wait_disconnected()
1092
1093 dev[0].dump_monitor()
1094 dev[0].select_network(id, freq=2412)
1095 dev[0].wait_connected()
1096 dev[0].request("DISCONNECT")
1097 dev[0].wait_disconnected()
1098
1099 dev[0].request("FILS_HLP_REQ_FLUSH")
1100 tests = [binascii.hexlify(dhcp_opts).decode(),
1101 binascii.hexlify(dhcp_opts2).decode()]
1102 for t in tests:
1103 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + t):
1104 raise Exception("FILS_HLP_REQ_ADD failed: " + t)
1105
1106 dev[0].dump_monitor()
1107 dev[0].select_network(id, freq=2412)
1108 dev[0].wait_connected()
1109 dev[0].request("DISCONNECT")
1110 dev[0].wait_disconnected()
1111
1112 dev[0].request("FILS_HLP_REQ_FLUSH")
1113 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcp_valid).decode()):
1114 raise Exception("FILS_HLP_REQ_ADD failed")
1115 hapd.set("own_ip_addr", "0.0.0.0")
1116 dev[0].select_network(id, freq=2412)
1117 dev[0].wait_connected()
1118 dev[0].request("DISCONNECT")
1119 dev[0].wait_disconnected()
1120
1121 hapd.set("dhcp_server", "0.0.0.0")
1122 dev[0].select_network(id, freq=2412)
1123 dev[0].wait_connected()
1124 dev[0].request("DISCONNECT")
1125 dev[0].wait_disconnected()
1126
1127 # FILS: Failed to bind DHCP socket: Address already in use
1128 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1129 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1130 sock.settimeout(5)
1131 sock.bind(("127.0.0.2", 67))
1132 hapd.set("own_ip_addr", "127.0.0.2")
1133 hapd.set("dhcp_server", "127.0.0.2")
1134 dev[0].select_network(id, freq=2412)
1135 dev[0].wait_connected()
1136 dev[0].request("DISCONNECT")
1137 dev[0].wait_disconnected()
1138
1139 # FILS: DHCP sendto failed: Invalid argument
1140 hapd.set("own_ip_addr", "127.0.0.3")
1141 hapd.set("dhcp_server", "127.0.0.2")
1142 hapd.set("dhcp_relay_port", "0")
1143 hapd.set("dhcp_server_port", "0")
1144 dev[0].select_network(id, freq=2412)
1145 dev[0].wait_connected()
1146 dev[0].request("DISCONNECT")
1147 dev[0].wait_disconnected()
1148
1149 dev[0].request("FILS_HLP_REQ_FLUSH")
1150
1151 def test_fils_sk_hlp_dhcp_parsing(dev, apdev, params):
1152 """FILS SK HLP and DHCP response parsing"""
1153 check_fils_capa(dev[0])
1154 check_erp_capa(dev[0])
1155
1156 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1157
1158 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1159 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1160 sock.settimeout(5)
1161 sock.bind(("127.0.0.2", 67))
1162
1163 bssid = apdev[0]['bssid']
1164 params = fils_hlp_config(fils_hlp_wait_time=30)
1165 params['dhcp_rapid_commit_proxy'] = '1'
1166 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1167
1168 dev[0].scan_for_bss(bssid, freq=2412)
1169 dev[0].request("ERP_FLUSH")
1170 if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
1171 raise Exception("Failed to flush pending FILS HLP requests")
1172 dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
1173 chaddr=dev[0].own_addr())
1174 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc).decode()):
1175 raise Exception("FILS_HLP_REQ_ADD failed")
1176 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1177 eap="PSK", identity="psk.user@example.com",
1178 password_hex="0123456789abcdef0123456789abcdef",
1179 erp="1", scan_freq="2412")
1180
1181 dev[0].request("DISCONNECT")
1182 dev[0].wait_disconnected()
1183
1184 dev[0].dump_monitor()
1185 with alloc_fail(hapd, 1, "fils_process_hlp"):
1186 dev[0].select_network(id, freq=2412)
1187 dev[0].wait_connected()
1188 dev[0].request("DISCONNECT")
1189 dev[0].wait_disconnected()
1190
1191 dev[0].dump_monitor()
1192 dev[0].select_network(id, freq=2412)
1193 (msg, addr) = sock.recvfrom(1000)
1194 logger.debug("Received DHCP message from %s" % str(addr))
1195 dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
1196 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
1197 #sock.sendto(dhcpdisc[2+20+8:], addr)
1198 chaddr = binascii.unhexlify(dev[0].own_addr().replace(':', '')) + 10*b'\x00'
1199 tests = [b"\x00",
1200 b"\x02" + 500 * b"\x00",
1201 b"\x02\x00\x00\x00" + 20*b"\x00" + b"\x7f\x00\x00\x03" + 500*b"\x00",
1202 b"\x02\x00\x00\x00" + 20*b"\x00" + b"\x7f\x00\x00\x03" + 16*b"\x00" + 64*b"\x00" + 128*b"\x00" + b"\x63\x82\x53\x63",
1203 b"\x02\x00\x00\x00" + 20*b"\x00" + b"\x7f\x00\x00\x03" + 16*b"\x00" + 64*b"\x00" + 128*b"\x00" + b"\x63\x82\x53\x63" + b"\x00\x11",
1204 b"\x02\x00\x00\x00" + 20*b"\x00" + b"\x7f\x00\x00\x03" + 16*b"\x00" + 64*b"\x00" + 128*b"\x00" + b"\x63\x82\x53\x63" + b"\x11\x01",
1205 b"\x02\x00\x00\x00" + 20*b"\x00" + b"\x7f\x00\x00\x03" + chaddr + 64*b"\x00" + 128*b"\x00" + b"\x63\x82\x53\x63" + b"\x35\x00\xff",
1206 b"\x02\x00\x00\x00" + 20*b"\x00" + b"\x7f\x00\x00\x03" + chaddr + 64*b"\x00" + 128*b"\x00" + b"\x63\x82\x53\x63" + b"\x35\x01\x00\xff",
1207 1501 * b"\x00"]
1208 for t in tests:
1209 sock.sendto(t, addr)
1210 dev[0].wait_connected()
1211 dev[0].request("DISCONNECT")
1212 dev[0].wait_disconnected()
1213
1214 # FILS: DHCP sendto failed: Invalid argument for second DHCP TX in proxy
1215 dev[0].dump_monitor()
1216 dev[0].select_network(id, freq=2412)
1217 (msg, addr) = sock.recvfrom(1000)
1218 logger.debug("Received DHCP message from %s" % str(addr))
1219 hapd.set("dhcp_server_port", "0")
1220 dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
1221 chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
1222 sock.sendto(dhcpoffer[2+20+8:], addr)
1223 dev[0].wait_connected()
1224 dev[0].request("DISCONNECT")
1225 dev[0].wait_disconnected()
1226 hapd.set("dhcp_server_port", "67")
1227
1228 # Options in DHCPOFFER
1229 dev[0].dump_monitor()
1230 dev[0].select_network(id, freq=2412)
1231 (msg, addr) = sock.recvfrom(1000)
1232 logger.debug("Received DHCP message from %s" % str(addr))
1233 dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
1234 chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
1235 extra_op=b"\x00\x11", opt_end=False)
1236 sock.sendto(dhcpoffer[2+20+8:], addr)
1237 (msg, addr) = sock.recvfrom(1000)
1238 logger.debug("Received DHCP message from %s" % str(addr))
1239 dev[0].wait_connected()
1240 dev[0].request("DISCONNECT")
1241 dev[0].wait_disconnected()
1242
1243 # Options in DHCPOFFER (2)
1244 dev[0].dump_monitor()
1245 dev[0].select_network(id, freq=2412)
1246 (msg, addr) = sock.recvfrom(1000)
1247 logger.debug("Received DHCP message from %s" % str(addr))
1248 dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
1249 chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
1250 extra_op=b"\x11\x01", opt_end=False)
1251 sock.sendto(dhcpoffer[2+20+8:], addr)
1252 (msg, addr) = sock.recvfrom(1000)
1253 logger.debug("Received DHCP message from %s" % str(addr))
1254 dev[0].wait_connected()
1255 dev[0].request("DISCONNECT")
1256 dev[0].wait_disconnected()
1257
1258 # Server ID in DHCPOFFER
1259 dev[0].dump_monitor()
1260 dev[0].select_network(id, freq=2412)
1261 (msg, addr) = sock.recvfrom(1000)
1262 logger.debug("Received DHCP message from %s" % str(addr))
1263 dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
1264 chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
1265 extra_op=b"\x36\x01\x30")
1266 sock.sendto(dhcpoffer[2+20+8:], addr)
1267 (msg, addr) = sock.recvfrom(1000)
1268 logger.debug("Received DHCP message from %s" % str(addr))
1269 dev[0].wait_connected()
1270 dev[0].request("DISCONNECT")
1271 dev[0].wait_disconnected()
1272
1273 # FILS: Could not update DHCPDISCOVER
1274 dev[0].request("FILS_HLP_REQ_FLUSH")
1275 dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
1276 chaddr=dev[0].own_addr(),
1277 extra_op=b"\x00\x11", opt_end=False)
1278 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc).decode()):
1279 raise Exception("FILS_HLP_REQ_ADD failed")
1280 dev[0].dump_monitor()
1281 dev[0].select_network(id, freq=2412)
1282 (msg, addr) = sock.recvfrom(1000)
1283 logger.debug("Received DHCP message from %s" % str(addr))
1284 dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
1285 chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
1286 extra_op=b"\x36\x01\x30")
1287 sock.sendto(dhcpoffer[2+20+8:], addr)
1288 dev[0].wait_connected()
1289 dev[0].request("DISCONNECT")
1290 dev[0].wait_disconnected()
1291
1292 # FILS: Could not update DHCPDISCOVER (2)
1293 dev[0].request("FILS_HLP_REQ_FLUSH")
1294 dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
1295 chaddr=dev[0].own_addr(),
1296 extra_op=b"\x11\x01", opt_end=False)
1297 if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc).decode()):
1298 raise Exception("FILS_HLP_REQ_ADD failed")
1299 dev[0].dump_monitor()
1300 dev[0].select_network(id, freq=2412)
1301 (msg, addr) = sock.recvfrom(1000)
1302 logger.debug("Received DHCP message from %s" % str(addr))
1303 dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
1304 chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
1305 extra_op=b"\x36\x01\x30")
1306 sock.sendto(dhcpoffer[2+20+8:], addr)
1307 dev[0].wait_connected()
1308 dev[0].request("DISCONNECT")
1309 dev[0].wait_disconnected()
1310
1311 dev[0].request("FILS_HLP_REQ_FLUSH")
1312
1313 def test_fils_sk_erp_and_reauth(dev, apdev, params):
1314 """FILS SK using ERP and AP going away"""
1315 check_fils_capa(dev[0])
1316 check_erp_capa(dev[0])
1317
1318 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1319
1320 bssid = apdev[0]['bssid']
1321 params = hostapd.wpa2_eap_params(ssid="fils")
1322 params['wpa_key_mgmt'] = "FILS-SHA256"
1323 params['auth_server_port'] = "18128"
1324 params['erp_domain'] = 'example.com'
1325 params['fils_realm'] = 'example.com'
1326 params['disable_pmksa_caching'] = '1'
1327 params['broadcast_deauth'] = '0'
1328 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1329
1330 dev[0].scan_for_bss(bssid, freq=2412)
1331 dev[0].request("ERP_FLUSH")
1332 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1333 eap="PSK", identity="psk.user@example.com",
1334 password_hex="0123456789abcdef0123456789abcdef",
1335 erp="1", scan_freq="2412")
1336
1337 hapd.disable()
1338 dev[0].wait_disconnected()
1339 dev[0].dump_monitor()
1340 hapd.enable()
1341
1342 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1343 "EVENT-ASSOC-REJECT",
1344 "CTRL-EVENT-CONNECTED"], timeout=10)
1345 if ev is None:
1346 raise Exception("Reconnection using FILS/ERP timed out")
1347 if "CTRL-EVENT-EAP-STARTED" in ev:
1348 raise Exception("Unexpected EAP exchange")
1349 if "EVENT-ASSOC-REJECT" in ev:
1350 raise Exception("Association failed")
1351
1352 def test_fils_sk_erp_sim(dev, apdev, params):
1353 """FILS SK using ERP with SIM"""
1354 check_fils_capa(dev[0])
1355 check_erp_capa(dev[0])
1356
1357 realm = 'wlan.mnc001.mcc232.3gppnetwork.org'
1358 start_erp_as(erp_domain=realm,
1359 msk_dump=os.path.join(params['logdir'], "msk.lst"))
1360
1361 bssid = apdev[0]['bssid']
1362 params = hostapd.wpa2_eap_params(ssid="fils")
1363 params['wpa_key_mgmt'] = "FILS-SHA256"
1364 params['auth_server_port'] = "18128"
1365 params['fils_realm'] = realm
1366 params['disable_pmksa_caching'] = '1'
1367 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1368
1369 dev[0].scan_for_bss(bssid, freq=2412)
1370 dev[0].request("ERP_FLUSH")
1371 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1372 eap="SIM", identity="1232010000000000@" + realm,
1373 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
1374 erp="1", scan_freq="2412")
1375
1376 hapd.disable()
1377 dev[0].wait_disconnected()
1378 dev[0].dump_monitor()
1379 hapd.enable()
1380
1381 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1382 "EVENT-ASSOC-REJECT",
1383 "CTRL-EVENT-CONNECTED"], timeout=10)
1384 if ev is None:
1385 raise Exception("Reconnection using FILS/ERP timed out")
1386 if "CTRL-EVENT-EAP-STARTED" in ev:
1387 raise Exception("Unexpected EAP exchange")
1388 if "EVENT-ASSOC-REJECT" in ev:
1389 raise Exception("Association failed")
1390
1391 def test_fils_sk_pfs_19(dev, apdev, params):
1392 """FILS SK with PFS (DH group 19)"""
1393 run_fils_sk_pfs(dev, apdev, "19", params)
1394
1395 def test_fils_sk_pfs_20(dev, apdev, params):
1396 """FILS SK with PFS (DH group 20)"""
1397 run_fils_sk_pfs(dev, apdev, "20", params)
1398
1399 def test_fils_sk_pfs_21(dev, apdev, params):
1400 """FILS SK with PFS (DH group 21)"""
1401 run_fils_sk_pfs(dev, apdev, "21", params)
1402
1403 def test_fils_sk_pfs_25(dev, apdev, params):
1404 """FILS SK with PFS (DH group 25)"""
1405 run_fils_sk_pfs(dev, apdev, "25", params)
1406
1407 def test_fils_sk_pfs_26(dev, apdev, params):
1408 """FILS SK with PFS (DH group 26)"""
1409 run_fils_sk_pfs(dev, apdev, "26", params)
1410
1411 def test_fils_sk_pfs_27(dev, apdev, params):
1412 """FILS SK with PFS (DH group 27)"""
1413 run_fils_sk_pfs(dev, apdev, "27", params)
1414
1415 def test_fils_sk_pfs_28(dev, apdev, params):
1416 """FILS SK with PFS (DH group 28)"""
1417 run_fils_sk_pfs(dev, apdev, "28", params)
1418
1419 def test_fils_sk_pfs_29(dev, apdev, params):
1420 """FILS SK with PFS (DH group 29)"""
1421 run_fils_sk_pfs(dev, apdev, "29", params)
1422
1423 def test_fils_sk_pfs_30(dev, apdev, params):
1424 """FILS SK with PFS (DH group 30)"""
1425 run_fils_sk_pfs(dev, apdev, "30", params)
1426
1427 def run_fils_sk_pfs(dev, apdev, group, params):
1428 check_fils_sk_pfs_capa(dev[0])
1429 check_erp_capa(dev[0])
1430
1431 tls = dev[0].request("GET tls_library")
1432 if int(group) in [25]:
1433 if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)):
1434 raise HwsimSkip("EC group not supported")
1435 if int(group) in [27, 28, 29, 30]:
1436 if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)):
1437 raise HwsimSkip("Brainpool EC group not supported")
1438
1439 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1440
1441 bssid = apdev[0]['bssid']
1442 params = hostapd.wpa2_eap_params(ssid="fils")
1443 params['wpa_key_mgmt'] = "FILS-SHA256"
1444 params['auth_server_port'] = "18128"
1445 params['erp_domain'] = 'example.com'
1446 params['fils_realm'] = 'example.com'
1447 params['disable_pmksa_caching'] = '1'
1448 params['fils_dh_group'] = group
1449 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1450
1451 dev[0].scan_for_bss(bssid, freq=2412)
1452 dev[0].request("ERP_FLUSH")
1453 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1454 eap="PSK", identity="psk.user@example.com",
1455 password_hex="0123456789abcdef0123456789abcdef",
1456 erp="1", fils_dh_group=group, scan_freq="2412")
1457
1458 dev[0].request("DISCONNECT")
1459 dev[0].wait_disconnected()
1460
1461 dev[0].dump_monitor()
1462 dev[0].select_network(id, freq=2412)
1463 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1464 "EVENT-ASSOC-REJECT",
1465 "CTRL-EVENT-CONNECTED"], timeout=10)
1466 if ev is None:
1467 raise Exception("Connection using FILS/ERP timed out")
1468 if "CTRL-EVENT-EAP-STARTED" in ev:
1469 raise Exception("Unexpected EAP exchange")
1470 if "EVENT-ASSOC-REJECT" in ev:
1471 raise Exception("Association failed")
1472 hwsim_utils.test_connectivity(dev[0], hapd)
1473
1474 def test_fils_sk_pfs_group_mismatch(dev, apdev, params):
1475 """FILS SK PFS DH group mismatch"""
1476 check_fils_sk_pfs_capa(dev[0])
1477 check_erp_capa(dev[0])
1478
1479 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1480
1481 bssid = apdev[0]['bssid']
1482 params = hostapd.wpa2_eap_params(ssid="fils")
1483 params['wpa_key_mgmt'] = "FILS-SHA256"
1484 params['auth_server_port'] = "18128"
1485 params['erp_domain'] = 'example.com'
1486 params['fils_realm'] = 'example.com'
1487 params['disable_pmksa_caching'] = '1'
1488 params['fils_dh_group'] = "20"
1489 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1490
1491 dev[0].scan_for_bss(bssid, freq=2412)
1492 dev[0].request("ERP_FLUSH")
1493 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1494 eap="PSK", identity="psk.user@example.com",
1495 password_hex="0123456789abcdef0123456789abcdef",
1496 erp="1", fils_dh_group="19", scan_freq="2412")
1497
1498 dev[0].request("DISCONNECT")
1499 dev[0].wait_disconnected()
1500
1501 dev[0].dump_monitor()
1502 dev[0].select_network(id, freq=2412)
1503 ev = dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10)
1504 dev[0].request("DISCONNECT")
1505 if ev is None:
1506 raise Exception("Authentication rejection not seen")
1507 if "auth_type=5 auth_transaction=2 status_code=77" not in ev:
1508 raise Exception("Unexpected auth reject value: " + ev)
1509
1510 def test_fils_sk_pfs_pmksa_caching(dev, apdev, params):
1511 """FILS SK with PFS and PMKSA caching"""
1512 check_fils_sk_pfs_capa(dev[0])
1513 check_erp_capa(dev[0])
1514
1515 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1516
1517 bssid = apdev[0]['bssid']
1518 params = hostapd.wpa2_eap_params(ssid="fils")
1519 params['wpa_key_mgmt'] = "FILS-SHA256"
1520 params['auth_server_port'] = "18128"
1521 params['erp_domain'] = 'example.com'
1522 params['fils_realm'] = 'example.com'
1523 params['fils_dh_group'] = "19"
1524 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1525
1526 dev[0].scan_for_bss(bssid, freq=2412)
1527 dev[0].request("ERP_FLUSH")
1528 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1529 eap="PSK", identity="psk.user@example.com",
1530 password_hex="0123456789abcdef0123456789abcdef",
1531 erp="1", fils_dh_group="19", scan_freq="2412")
1532 pmksa = dev[0].get_pmksa(bssid)
1533 if pmksa is None:
1534 raise Exception("No PMKSA cache entry created")
1535
1536 dev[0].request("DISCONNECT")
1537 dev[0].wait_disconnected()
1538
1539 # FILS authentication with PMKSA caching and PFS
1540 dev[0].dump_monitor()
1541 dev[0].select_network(id, freq=2412)
1542 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1543 "CTRL-EVENT-CONNECTED"], timeout=10)
1544 if ev is None:
1545 raise Exception("Connection using PMKSA caching timed out")
1546 if "CTRL-EVENT-EAP-STARTED" in ev:
1547 raise Exception("Unexpected EAP exchange")
1548 hwsim_utils.test_connectivity(dev[0], hapd)
1549 pmksa2 = dev[0].get_pmksa(bssid)
1550 if pmksa2 is None:
1551 raise Exception("No PMKSA cache entry found")
1552 if pmksa['pmkid'] != pmksa2['pmkid']:
1553 raise Exception("Unexpected PMKID change")
1554
1555 # Verify EAPOL reauthentication after FILS authentication
1556 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
1557 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
1558 if ev is None:
1559 raise Exception("EAP authentication did not start")
1560 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
1561 if ev is None:
1562 raise Exception("EAP authentication did not succeed")
1563 time.sleep(0.1)
1564 hwsim_utils.test_connectivity(dev[0], hapd)
1565
1566 dev[0].request("DISCONNECT")
1567 dev[0].wait_disconnected()
1568
1569 # FILS authentication with ERP and PFS
1570 dev[0].request("PMKSA_FLUSH")
1571 dev[0].dump_monitor()
1572 dev[0].select_network(id, freq=2412)
1573 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1574 "CTRL-EVENT-EAP-SUCCESS",
1575 "CTRL-EVENT-CONNECTED"], timeout=10)
1576 if ev is None:
1577 raise Exception("Connection using ERP and PFS timed out")
1578 if "CTRL-EVENT-EAP-STARTED" in ev:
1579 raise Exception("Unexpected EAP exchange")
1580 if "CTRL-EVENT-EAP-SUCCESS" not in ev:
1581 raise Exception("ERP success not reported")
1582 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1583 "SME: Trying to authenticate",
1584 "CTRL-EVENT-CONNECTED"], timeout=10)
1585 if ev is None:
1586 raise Exception("Connection using ERP and PFS timed out")
1587 if "CTRL-EVENT-EAP-STARTED" in ev:
1588 raise Exception("Unexpected EAP exchange")
1589 if "SME: Trying to authenticate" in ev:
1590 raise Exception("Unexpected extra authentication round with ERP and PFS")
1591 hwsim_utils.test_connectivity(dev[0], hapd)
1592 pmksa3 = dev[0].get_pmksa(bssid)
1593 if pmksa3 is None:
1594 raise Exception("No PMKSA cache entry found")
1595 if pmksa2['pmkid'] == pmksa3['pmkid']:
1596 raise Exception("PMKID did not change")
1597
1598 dev[0].request("DISCONNECT")
1599 dev[0].wait_disconnected()
1600
1601 # FILS authentication with PMKSA caching and PFS
1602 dev[0].dump_monitor()
1603 dev[0].select_network(id, freq=2412)
1604 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1605 "CTRL-EVENT-CONNECTED"], timeout=10)
1606 if ev is None:
1607 raise Exception("Connection using PMKSA caching timed out")
1608 if "CTRL-EVENT-EAP-STARTED" in ev:
1609 raise Exception("Unexpected EAP exchange")
1610 hwsim_utils.test_connectivity(dev[0], hapd)
1611 pmksa4 = dev[0].get_pmksa(bssid)
1612 if pmksa4 is None:
1613 raise Exception("No PMKSA cache entry found")
1614 if pmksa3['pmkid'] != pmksa4['pmkid']:
1615 raise Exception("Unexpected PMKID change (2)")
1616
1617 def test_fils_sk_auth_mismatch(dev, apdev, params):
1618 """FILS SK authentication type mismatch (PFS not supported)"""
1619 check_fils_sk_pfs_capa(dev[0])
1620 check_erp_capa(dev[0])
1621
1622 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1623
1624 bssid = apdev[0]['bssid']
1625 params = hostapd.wpa2_eap_params(ssid="fils")
1626 params['wpa_key_mgmt'] = "FILS-SHA256"
1627 params['auth_server_port'] = "18128"
1628 params['erp_domain'] = 'example.com'
1629 params['fils_realm'] = 'example.com'
1630 params['disable_pmksa_caching'] = '1'
1631 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1632
1633 dev[0].scan_for_bss(bssid, freq=2412)
1634 dev[0].request("ERP_FLUSH")
1635 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1636 eap="PSK", identity="psk.user@example.com",
1637 password_hex="0123456789abcdef0123456789abcdef",
1638 erp="1", fils_dh_group="19", scan_freq="2412")
1639
1640 dev[0].request("DISCONNECT")
1641 dev[0].wait_disconnected()
1642
1643 hapd.dump_monitor()
1644 dev[0].dump_monitor()
1645 dev[0].select_network(id, freq=2412)
1646 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1647 "EVENT-ASSOC-REJECT",
1648 "CTRL-EVENT-CONNECTED"], timeout=10)
1649 if ev is None:
1650 raise Exception("Connection using FILS/ERP timed out")
1651 if "CTRL-EVENT-EAP-STARTED" not in ev:
1652 raise Exception("No EAP exchange seen")
1653 dev[0].wait_connected()
1654 hapd.wait_sta()
1655 hwsim_utils.test_connectivity(dev[0], hapd)
1656
1657 def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0,
1658 pmksa_caching=True):
1659 check_fils_capa(dev[0])
1660 check_erp_capa(dev[0])
1661
1662 start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1663
1664 bssid = apdev[0]['bssid']
1665 params = hostapd.wpa2_eap_params(ssid="fils")
1666 params['wpa_key_mgmt'] = "FILS-SHA256"
1667 params['auth_server_port'] = "18128"
1668 params['erp_domain'] = 'example.com'
1669 params['fils_realm'] = 'example.com'
1670 if wpa_ptk_rekey:
1671 params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
1672 if wpa_group_rekey:
1673 params['wpa_group_rekey'] = str(wpa_group_rekey)
1674 if not pmksa_caching:
1675 params['disable_pmksa_caching'] = '1'
1676 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1677
1678 dev[0].scan_for_bss(bssid, freq=2412)
1679 dev[0].request("ERP_FLUSH")
1680 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1681 eap="PSK", identity="psk.user@example.com",
1682 password_hex="0123456789abcdef0123456789abcdef",
1683 erp="1", scan_freq="2412")
1684
1685 dev[0].request("DISCONNECT")
1686 dev[0].wait_disconnected()
1687
1688 dev[0].dump_monitor()
1689 dev[0].select_network(id, freq=2412)
1690 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1691 "CTRL-EVENT-CONNECTED"], timeout=10)
1692 if ev is None:
1693 raise Exception("Connection using ERP or PMKSA caching timed out")
1694 if "CTRL-EVENT-EAP-STARTED" in ev:
1695 raise Exception("Unexpected EAP exchange")
1696 dev[0].dump_monitor()
1697
1698 hwsim_utils.test_connectivity(dev[0], hapd)
1699 return hapd
1700
1701 def test_fils_auth_gtk_rekey(dev, apdev, params):
1702 """GTK rekeying after FILS authentication"""
1703 hapd = setup_fils_rekey(dev, apdev, params, wpa_group_rekey=1)
1704 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
1705 if ev is None:
1706 raise Exception("GTK rekey timed out")
1707 hwsim_utils.test_connectivity(dev[0], hapd)
1708
1709 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
1710 if ev is not None:
1711 raise Exception("Rekeying failed - disconnected")
1712 hwsim_utils.test_connectivity(dev[0], hapd)
1713
1714 def test_fils_auth_ptk_rekey_ap(dev, apdev, params):
1715 """PTK rekeying after FILS authentication triggered by AP"""
1716 hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2)
1717 ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3)
1718 if ev is None:
1719 raise Exception("PTK rekey timed out")
1720 hwsim_utils.test_connectivity(dev[0], hapd)
1721
1722 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
1723 if ev is not None:
1724 raise Exception("Rekeying failed - disconnected")
1725 hwsim_utils.test_connectivity(dev[0], hapd)
1726
1727 def test_fils_auth_ptk_rekey_ap_erp(dev, apdev, params):
1728 """PTK rekeying after FILS authentication triggered by AP (ERP)"""
1729 hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2,
1730 pmksa_caching=False)
1731 ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3)
1732 if ev is None:
1733 raise Exception("PTK rekey timed out")
1734 hwsim_utils.test_connectivity(dev[0], hapd)
1735
1736 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
1737 if ev is not None:
1738 raise Exception("Rekeying failed - disconnected")
1739 hwsim_utils.test_connectivity(dev[0], hapd)
1740
1741 def test_fils_and_ft(dev, apdev, params):
1742 """FILS SK using ERP and FT initial mobility domain association"""
1743 check_fils_capa(dev[0])
1744 check_erp_capa(dev[0])
1745
1746 er = start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1747
1748 bssid = apdev[0]['bssid']
1749 params = hostapd.wpa2_eap_params(ssid="fils")
1750 params['wpa_key_mgmt'] = "FILS-SHA256"
1751 params['auth_server_port'] = "18128"
1752 params['erp_domain'] = 'example.com'
1753 params['fils_realm'] = 'example.com'
1754 params['disable_pmksa_caching'] = '1'
1755 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1756
1757 dev[0].scan_for_bss(bssid, freq=2412)
1758 dev[0].request("ERP_FLUSH")
1759 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1760 eap="PSK", identity="psk.user@example.com",
1761 password_hex="0123456789abcdef0123456789abcdef",
1762 erp="1", scan_freq="2412")
1763
1764 dev[0].request("DISCONNECT")
1765 dev[0].wait_disconnected()
1766 hapd.disable()
1767 dev[0].flush_scan_cache()
1768 if "FAIL" in dev[0].request("PMKSA_FLUSH"):
1769 raise Exception("PMKSA_FLUSH failed")
1770
1771 params = hostapd.wpa2_eap_params(ssid="fils-ft")
1772 params['wpa_key_mgmt'] = "FILS-SHA256 FT-FILS-SHA256 FT-EAP"
1773 params['auth_server_port'] = "18128"
1774 params['erp_domain'] = 'example.com'
1775 params['fils_realm'] = 'example.com'
1776 params['disable_pmksa_caching'] = '1'
1777 params["mobility_domain"] = "a1b2"
1778 params["r0_key_lifetime"] = "10000"
1779 params["pmk_r1_push"] = "1"
1780 params["reassociation_deadline"] = "1000"
1781 params['nas_identifier'] = "nas1.w1.fi"
1782 params['r1_key_holder'] = "000102030405"
1783 params['r0kh'] = ["02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"]
1784 params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
1785 params['ieee80211w'] = "1"
1786 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1787
1788 dev[0].scan_for_bss(bssid, freq=2412)
1789 dev[0].dump_monitor()
1790 id = dev[0].connect("fils-ft", key_mgmt="FILS-SHA256 FT-FILS-SHA256 FT-EAP",
1791 ieee80211w="1",
1792 eap="PSK", identity="psk.user@example.com",
1793 password_hex="0123456789abcdef0123456789abcdef",
1794 erp="1", scan_freq="2412", wait_connect=False)
1795
1796 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1797 "CTRL-EVENT-AUTH-REJECT",
1798 "EVENT-ASSOC-REJECT",
1799 "CTRL-EVENT-CONNECTED"], timeout=10)
1800 if ev is None:
1801 raise Exception("Connection using FILS/ERP timed out")
1802 if "CTRL-EVENT-EAP-STARTED" in ev:
1803 raise Exception("Unexpected EAP exchange")
1804 if "CTRL-EVENT-AUTH-REJECT" in ev:
1805 raise Exception("Authentication failed")
1806 if "EVENT-ASSOC-REJECT" in ev:
1807 raise Exception("Association failed")
1808 hwsim_utils.test_connectivity(dev[0], hapd)
1809
1810 er.disable()
1811
1812 # FIX: FT-FILS-SHA256 does not currently work for FT protocol due to not
1813 # fully defined FT Reassociation Request/Response frame MIC use in FTE.
1814 # FT-EAP can be used to work around that in this test case to confirm the
1815 # FT key hierarchy was properly formed in the previous step.
1816 #params['wpa_key_mgmt'] = "FILS-SHA256 FT-FILS-SHA256"
1817 params['wpa_key_mgmt'] = "FT-EAP"
1818 params['nas_identifier'] = "nas2.w1.fi"
1819 params['r1_key_holder'] = "000102030406"
1820 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f"]
1821 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
1822 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
1823
1824 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True)
1825 # FIX: Cannot use FT-over-DS without the FTE MIC issue addressed
1826 #dev[0].roam_over_ds(apdev[1]['bssid'])
1827 dev[0].roam(apdev[1]['bssid'])
1828
1829 def test_fils_and_ft_over_air(dev, apdev, params):
1830 """FILS SK using ERP and FT-over-air (SHA256)"""
1831 run_fils_and_ft_over_air(dev, apdev, params, "FT-FILS-SHA256")
1832
1833 def test_fils_and_ft_over_air_sha384(dev, apdev, params):
1834 """FILS SK using ERP and FT-over-air (SHA384)"""
1835 run_fils_and_ft_over_air(dev, apdev, params, "FT-FILS-SHA384")
1836
1837 def run_fils_and_ft_over_air(dev, apdev, params, key_mgmt):
1838 hapd, hapd2 = run_fils_and_ft_setup(dev, apdev, params, key_mgmt)
1839
1840 logger.info("FT protocol using FT key hierarchy established during FILS authentication")
1841 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True)
1842 hapd.request("NOTE FT protocol to AP2 using FT keys established during FILS FILS authentication")
1843 dev[0].roam(apdev[1]['bssid'])
1844 hwsim_utils.test_connectivity(dev[0], hapd2)
1845
1846 logger.info("FT protocol using the previously established FT key hierarchy from FILS authentication")
1847 hapd.request("NOTE FT protocol back to AP1 using FT keys established during FILS FILS authentication")
1848 dev[0].roam(apdev[0]['bssid'])
1849 hwsim_utils.test_connectivity(dev[0], hapd)
1850
1851 hapd.request("NOTE FT protocol back to AP2 using FT keys established during FILS FILS authentication")
1852 dev[0].roam(apdev[1]['bssid'])
1853 hwsim_utils.test_connectivity(dev[0], hapd2)
1854
1855 hapd.request("NOTE FT protocol back to AP1 using FT keys established during FILS FILS authentication (2)")
1856 dev[0].roam(apdev[0]['bssid'])
1857 hwsim_utils.test_connectivity(dev[0], hapd)
1858
1859 def test_fils_and_ft_over_ds(dev, apdev, params):
1860 """FILS SK using ERP and FT-over-DS (SHA256)"""
1861 run_fils_and_ft_over_ds(dev, apdev, params, "FT-FILS-SHA256")
1862
1863 def test_fils_and_ft_over_ds_sha384(dev, apdev, params):
1864 """FILS SK using ERP and FT-over-DS (SHA384)"""
1865 run_fils_and_ft_over_ds(dev, apdev, params, "FT-FILS-SHA384")
1866
1867 def run_fils_and_ft_over_ds(dev, apdev, params, key_mgmt):
1868 hapd, hapd2 = run_fils_and_ft_setup(dev, apdev, params, key_mgmt)
1869
1870 logger.info("FT protocol using FT key hierarchy established during FILS authentication")
1871 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True)
1872 hapd.request("NOTE FT protocol to AP2 using FT keys established during FILS FILS authentication")
1873 dev[0].roam_over_ds(apdev[1]['bssid'])
1874
1875 logger.info("FT protocol using the previously established FT key hierarchy from FILS authentication")
1876 hapd.request("NOTE FT protocol back to AP1 using FT keys established during FILS FILS authentication")
1877 dev[0].roam_over_ds(apdev[0]['bssid'])
1878
1879 hapd.request("NOTE FT protocol back to AP2 using FT keys established during FILS FILS authentication")
1880 dev[0].roam_over_ds(apdev[1]['bssid'])
1881
1882 hapd.request("NOTE FT protocol back to AP1 using FT keys established during FILS FILS authentication (2)")
1883 dev[0].roam_over_ds(apdev[0]['bssid'])
1884
1885 def run_fils_and_ft_setup(dev, apdev, params, key_mgmt):
1886 check_fils_capa(dev[0])
1887 check_erp_capa(dev[0])
1888
1889 er = start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
1890
1891 logger.info("Set up ERP key hierarchy without FILS/FT authentication")
1892 bssid = apdev[0]['bssid']
1893 params = hostapd.wpa2_eap_params(ssid="fils")
1894 params['wpa_key_mgmt'] = key_mgmt
1895 params['auth_server_port'] = "18128"
1896 params['erp_domain'] = 'example.com'
1897 params['fils_realm'] = 'example.com'
1898 params['disable_pmksa_caching'] = '1'
1899 params['ieee80211w'] = "2"
1900 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1901
1902 dev[0].scan_for_bss(bssid, freq=2412)
1903 dev[0].request("ERP_FLUSH")
1904 hapd.request("NOTE Initial association to establish ERP keys")
1905 id = dev[0].connect("fils", key_mgmt=key_mgmt, ieee80211w="2",
1906 eap="PSK", identity="psk.user@example.com",
1907 password_hex="0123456789abcdef0123456789abcdef",
1908 erp="1", scan_freq="2412")
1909 hapd.wait_sta()
1910 hwsim_utils.test_connectivity(dev[0], hapd)
1911
1912 dev[0].request("DISCONNECT")
1913 dev[0].wait_disconnected()
1914 hapd.disable()
1915 dev[0].flush_scan_cache()
1916 if "FAIL" in dev[0].request("PMKSA_FLUSH"):
1917 raise Exception("PMKSA_FLUSH failed")
1918
1919 logger.info("Initial mobility domain association using FILS authentication")
1920 params = hostapd.wpa2_eap_params(ssid="fils-ft")
1921 params['wpa_key_mgmt'] = key_mgmt
1922 params['auth_server_port'] = "18128"
1923 params['erp_domain'] = 'example.com'
1924 params['fils_realm'] = 'example.com'
1925 params['disable_pmksa_caching'] = '1'
1926 params["mobility_domain"] = "a1b2"
1927 params["r0_key_lifetime"] = "10000"
1928 params["pmk_r1_push"] = "1"
1929 params["reassociation_deadline"] = "1000"
1930 params['nas_identifier'] = "nas1.w1.fi"
1931 params['r1_key_holder'] = "000102030405"
1932 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f",
1933 "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"]
1934 params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
1935 params['ieee80211w'] = "2"
1936 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1937
1938 dev[0].scan_for_bss(bssid, freq=2412)
1939 dev[0].dump_monitor()
1940 hapd.request("NOTE Initial FT mobility domain association using FILS authentication")
1941 dev[0].set_network_quoted(id, "ssid", "fils-ft")
1942 dev[0].select_network(id, freq=2412)
1943
1944 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
1945 "CTRL-EVENT-AUTH-REJECT",
1946 "EVENT-ASSOC-REJECT",
1947 "CTRL-EVENT-CONNECTED"], timeout=10)
1948 if ev is None:
1949 raise Exception("Connection using FILS/ERP timed out")
1950 if "CTRL-EVENT-EAP-STARTED" in ev:
1951 raise Exception("Unexpected EAP exchange")
1952 if "CTRL-EVENT-AUTH-REJECT" in ev:
1953 raise Exception("Authentication failed")
1954 if "EVENT-ASSOC-REJECT" in ev:
1955 raise Exception("Association failed")
1956 hapd.wait_sta()
1957 hwsim_utils.test_connectivity(dev[0], hapd)
1958
1959 er.disable()
1960
1961 params['wpa_key_mgmt'] = key_mgmt
1962 params['nas_identifier'] = "nas2.w1.fi"
1963 params['r1_key_holder'] = "000102030406"
1964 params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
1965 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"]
1966 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
1967 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
1968
1969 return hapd, hapd2
1970
1971 def test_fils_assoc_replay(dev, apdev, params):
1972 """FILS AP and replayed Association Request frame"""
1973 capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
1974 check_fils_capa(dev[0])
1975 check_erp_capa(dev[0])
1976
1977 start_erp_as()
1978
1979 bssid = apdev[0]['bssid']
1980 params = hostapd.wpa2_eap_params(ssid="fils")
1981 params['wpa_key_mgmt'] = "FILS-SHA256"
1982 params['auth_server_port'] = "18128"
1983 params['erp_domain'] = 'example.com'
1984 params['fils_realm'] = 'example.com'
1985 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1986
1987 dev[0].scan_for_bss(bssid, freq=2412)
1988 dev[0].request("ERP_FLUSH")
1989 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
1990 eap="PSK", identity="psk.user@example.com",
1991 password_hex="0123456789abcdef0123456789abcdef",
1992 erp="1", scan_freq="2412")
1993
1994 dev[0].request("DISCONNECT")
1995 dev[0].wait_disconnected()
1996
1997 hapd.set("ext_mgmt_frame_handling", "1")
1998 dev[0].dump_monitor()
1999 dev[0].select_network(id, freq=2412)
2000
2001 assocreq = None
2002 count = 0
2003 while count < 100:
2004 req = hapd.mgmt_rx()
2005 count += 1
2006 hapd.dump_monitor()
2007 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2008 if req['subtype'] == 0:
2009 assocreq = req
2010 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
2011 if ev is None:
2012 raise Exception("No TX status seen")
2013 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
2014 if "OK" not in hapd.request(cmd):
2015 raise Exception("MGMT_TX_STATUS_PROCESS failed")
2016 break
2017 hapd.set("ext_mgmt_frame_handling", "0")
2018 if assocreq is None:
2019 raise Exception("No Association Request frame seen")
2020 dev[0].wait_connected()
2021 dev[0].dump_monitor()
2022 hapd.dump_monitor()
2023
2024 hwsim_utils.test_connectivity(dev[0], hapd)
2025
2026 logger.info("Replay the last Association Request frame")
2027 hapd.dump_monitor()
2028 hapd.set("ext_mgmt_frame_handling", "1")
2029 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2030 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
2031 if ev is None:
2032 raise Exception("No TX status seen")
2033 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
2034 if "OK" not in hapd.request(cmd):
2035 raise Exception("MGMT_TX_STATUS_PROCESS failed")
2036 hapd.set("ext_mgmt_frame_handling", "0")
2037
2038 try:
2039 hwsim_utils.test_connectivity(dev[0], hapd)
2040 ok = True
2041 except:
2042 ok = False
2043
2044 ap = hapd.own_addr()
2045 sta = dev[0].own_addr()
2046 filt = "wlan.fc.type == 2 && " + \
2047 "wlan.da == " + sta + " && " + \
2048 "wlan.sa == " + ap + " && wlan.ccmp.extiv"
2049 fields = ["wlan.ccmp.extiv"]
2050 res = run_tshark(capfile, filt, fields)
2051 vals = res.splitlines()
2052 logger.info("CCMP PN: " + str(vals))
2053 if len(vals) < 2:
2054 raise Exception("Could not find all CCMP protected frames from capture")
2055 if len(set(vals)) < len(vals):
2056 raise Exception("Duplicate CCMP PN used")
2057
2058 if not ok:
2059 raise Exception("The second hwsim connectivity test failed")
2060
2061 def test_fils_sk_erp_server_flush(dev, apdev, params):
2062 """FILS SK ERP and ERP flush on server, but not on peer"""
2063 check_fils_capa(dev[0])
2064 check_erp_capa(dev[0])
2065
2066 hapd_as = start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
2067
2068 bssid = apdev[0]['bssid']
2069 params = hostapd.wpa2_eap_params(ssid="fils")
2070 params['wpa_key_mgmt'] = "FILS-SHA256"
2071 params['auth_server_port'] = "18128"
2072 params['erp_domain'] = 'example.com'
2073 params['fils_realm'] = 'example.com'
2074 params['disable_pmksa_caching'] = '1'
2075 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2076
2077 dev[0].scan_for_bss(bssid, freq=2412)
2078 dev[0].request("ERP_FLUSH")
2079 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
2080 eap="PSK", identity="psk.user@example.com",
2081 password_hex="0123456789abcdef0123456789abcdef",
2082 erp="1", scan_freq="2412")
2083
2084 dev[0].request("DISCONNECT")
2085 dev[0].wait_disconnected()
2086
2087 dev[0].dump_monitor()
2088 dev[0].select_network(id, freq=2412)
2089 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
2090 "EVENT-ASSOC-REJECT",
2091 "CTRL-EVENT-CONNECTED"], timeout=10)
2092 if ev is None:
2093 raise Exception("Connection using FILS/ERP timed out")
2094 if "CTRL-EVENT-EAP-STARTED" in ev:
2095 raise Exception("Unexpected EAP exchange")
2096 if "EVENT-ASSOC-REJECT" in ev:
2097 raise Exception("Association failed")
2098
2099 dev[0].request("DISCONNECT")
2100 dev[0].wait_disconnected()
2101
2102 hapd_as.request("ERP_FLUSH")
2103 dev[0].dump_monitor()
2104 dev[0].select_network(id, freq=2412)
2105 ev = dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10)
2106 if ev is None:
2107 raise Exception("No authentication rejection seen after ERP flush on server")
2108
2109 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
2110 "CTRL-EVENT-AUTH-REJECT",
2111 "EVENT-ASSOC-REJECT",
2112 "CTRL-EVENT-CONNECTED"], timeout=10)
2113 if ev is None:
2114 raise Exception("Connection attempt using FILS/ERP timed out")
2115 if "CTRL-EVENT-AUTH-REJECT" in ev:
2116 raise Exception("Failed to recover from ERP flush on server")
2117 if "EVENT-ASSOC-REJECT" in ev:
2118 raise Exception("Association failed")
2119 if "CTRL-EVENT-EAP-STARTED" not in ev:
2120 raise Exception("New EAP exchange not seen")
2121 dev[0].wait_connected(error="Connection timeout after ERP flush")
2122
2123 dev[0].request("DISCONNECT")
2124 dev[0].wait_disconnected()
2125 dev[0].dump_monitor()
2126 dev[0].select_network(id, freq=2412)
2127 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
2128 "CTRL-EVENT-AUTH-REJECT",
2129 "EVENT-ASSOC-REJECT",
2130 "CTRL-EVENT-CONNECTED"], timeout=10)
2131 if ev is None:
2132 raise Exception("Connection attempt using FILS with new ERP keys timed out")
2133 if "CTRL-EVENT-AUTH-REJECT" in ev:
2134 raise Exception("Authentication failed with new ERP keys")
2135 if "EVENT-ASSOC-REJECT" in ev:
2136 raise Exception("Association failed with new ERP keys")
2137 if "CTRL-EVENT-EAP-STARTED" in ev:
2138 raise Exception("Unexpected EAP exchange")
2139
2140 def test_fils_sk_erp_radius_ext(dev, apdev, params):
2141 """FILS SK using ERP and external RADIUS server"""
2142 as_hapd = hostapd.Hostapd("as")
2143 try:
2144 as_hapd.disable()
2145 as_hapd.set("eap_server_erp", "1")
2146 as_hapd.set("erp_domain", "erp.example.com")
2147 as_hapd.enable()
2148 run_fils_sk_erp_radius_ext(dev, apdev, params)
2149 finally:
2150 as_hapd.disable()
2151 as_hapd.set("eap_server_erp", "0")
2152 as_hapd.set("erp_domain", "")
2153 as_hapd.enable()
2154
2155 def run_fils_sk_erp_radius_ext(dev, apdev, params):
2156 check_fils_capa(dev[0])
2157 check_erp_capa(dev[0])
2158
2159 bssid = apdev[0]['bssid']
2160 params = hostapd.wpa2_eap_params(ssid="fils")
2161 params['wpa_key_mgmt'] = "FILS-SHA256"
2162 params['erp_domain'] = 'erp.example.com'
2163 params['fils_realm'] = 'erp.example.com'
2164 params['disable_pmksa_caching'] = '1'
2165 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2166
2167 dev[0].scan_for_bss(bssid, freq=2412)
2168 dev[0].request("ERP_FLUSH")
2169 id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
2170 eap="PWD", identity="pwd@erp.example.com",
2171 password="secret password",
2172 erp="1", scan_freq="2412")
2173
2174 dev[0].request("DISCONNECT")
2175 dev[0].wait_disconnected()
2176
2177 dev[0].dump_monitor()
2178 dev[0].select_network(id, freq=2412)
2179 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
2180 "EVENT-ASSOC-REJECT",
2181 "CTRL-EVENT-CONNECTED"], timeout=10)
2182 if ev is None:
2183 raise Exception("Connection using FILS/ERP timed out")
2184 if "CTRL-EVENT-EAP-STARTED" in ev:
2185 raise Exception("Unexpected EAP exchange")
2186 if "EVENT-ASSOC-REJECT" in ev:
2187 raise Exception("Association failed")
2188 hwsim_utils.test_connectivity(dev[0], hapd)
2189
2190 def test_fils_sk_erp_radius_roam(dev, apdev):
2191 """FILS SK/ERP and roaming with different AKM"""
2192 as_hapd = hostapd.Hostapd("as")
2193 try:
2194 as_hapd.disable()
2195 as_hapd.set("eap_server_erp", "1")
2196 as_hapd.set("erp_domain", "example.com")
2197 as_hapd.enable()
2198 run_fils_sk_erp_radius_roam(dev, apdev)
2199 finally:
2200 as_hapd.disable()
2201 as_hapd.set("eap_server_erp", "0")
2202 as_hapd.set("erp_domain", "")
2203 as_hapd.enable()
2204
2205 def run_fils_sk_erp_radius_roam(dev, apdev):
2206 check_fils_capa(dev[0])
2207 check_erp_capa(dev[0])
2208
2209 bssid = apdev[0]['bssid']
2210 params = hostapd.wpa2_eap_params(ssid="fils")
2211 params['wpa_key_mgmt'] = "FILS-SHA256"
2212 params['erp_domain'] = 'example.com'
2213 params['fils_realm'] = 'example.com'
2214 params['disable_pmksa_caching'] = '1'
2215 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2216
2217 dev[0].scan_for_bss(bssid, freq=2412)
2218 dev[0].request("ERP_FLUSH")
2219 id = dev[0].connect("fils", key_mgmt="FILS-SHA256 FILS-SHA384",
2220 eap="PWD", identity="erp-pwd@example.com",
2221 password="secret password",
2222 erp="1", scan_freq="2412")
2223
2224 bssid2 = apdev[1]['bssid']
2225 params = hostapd.wpa2_eap_params(ssid="fils")
2226 params['wpa_key_mgmt'] = "FILS-SHA384"
2227 params['erp_domain'] = 'example.com'
2228 params['fils_realm'] = 'example.com'
2229 params['disable_pmksa_caching'] = '1'
2230 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
2231
2232 dev[0].scan_for_bss(bssid2, freq=2412)
2233
2234 dev[0].dump_monitor()
2235 if "OK" not in dev[0].request("ROAM " + bssid2):
2236 raise Exception("ROAM failed")
2237
2238 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
2239 "CTRL-EVENT-CONNECTED"], timeout=10)
2240 if ev is None:
2241 raise Exception("Connection using PMKSA caching timed out")
2242 if "CTRL-EVENT-EAP-STARTED" in ev:
2243 raise Exception("Unexpected EAP exchange")
2244 if bssid2 not in ev:
2245 raise Exception("Failed to connect to the second AP")
2246
2247 hapd2.wait_sta()
2248 hwsim_utils.test_connectivity(dev[0], hapd2)
2249
2250 def test_fils_sk_erp_roam_diff_akm(dev, apdev, params):
2251 """FILS SK using ERP and SHA256/SHA384 change in roam"""
2252 check_fils_capa(dev[0])
2253 check_erp_capa(dev[0])
2254
2255 start_erp_as()
2256
2257 bssid = apdev[0]['bssid']
2258 params = hostapd.wpa2_eap_params(ssid="fils")
2259 params['wpa_key_mgmt'] = "FILS-SHA256"
2260 params['auth_server_port'] = "18128"
2261 params['erp_domain'] = 'example.com'
2262 params['fils_realm'] = 'example.com'
2263 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2264
2265 dev[0].scan_for_bss(bssid, freq=2412)
2266 dev[0].request("ERP_FLUSH")
2267 id = dev[0].connect("fils", key_mgmt="FILS-SHA256 FILS-SHA384",
2268 eap="PSK", identity="psk.user@example.com",
2269 password_hex="0123456789abcdef0123456789abcdef",
2270 erp="1", scan_freq="2412")
2271 dev[0].request("DISCONNECT")
2272 dev[0].wait_disconnected()
2273 dev[0].request("RECONNECT")
2274 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
2275 "CTRL-EVENT-CONNECTED"], timeout=10)
2276 if ev is None:
2277 raise Exception("Connection using FILS timed out")
2278 if "CTRL-EVENT-EAP-STARTED" in ev:
2279 raise Exception("Unexpected EAP exchange")
2280
2281 bssid2 = apdev[1]['bssid']
2282 params = hostapd.wpa2_eap_params(ssid="fils")
2283 params['wpa_key_mgmt'] = "FILS-SHA256 FILS-SHA384"
2284 params['auth_server_port'] = "18128"
2285 params['erp_domain'] = 'example.com'
2286 params['fils_realm'] = 'example.com'
2287 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
2288
2289 dev[0].scan_for_bss(bssid2, freq=2412)
2290
2291 dev[0].dump_monitor()
2292 if "OK" not in dev[0].request("ROAM " + bssid2):
2293 raise Exception("ROAM failed")
2294
2295 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
2296 "CTRL-EVENT-CONNECTED"], timeout=10)
2297 if ev is None:
2298 raise Exception("Roaming using FILS timed out")
2299 if "CTRL-EVENT-EAP-STARTED" in ev:
2300 raise Exception("Unexpected EAP exchange")
2301 if bssid2 not in ev:
2302 raise Exception("Failed to connect to the second AP")
2303
2304 hwsim_utils.test_connectivity(dev[0], hapd2)