]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_ft.py
1 # Fast BSS Transition tests
2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
12 logger
= logging
.getLogger()
16 from utils
import HwsimSkip
, alloc_fail
, fail_test
17 from wlantest
import Wlantest
18 from test_ap_psk
import check_mib
, find_wpas_process
, read_process_memory
, verify_not_present
, get_key_locations
21 params
= { "wpa": "2",
22 "wpa_key_mgmt": "FT-PSK",
23 "rsn_pairwise": "CCMP" }
27 params
= { "wpa": "3",
28 "wpa_key_mgmt": "WPA-PSK FT-PSK",
29 "wpa_pairwise": "TKIP",
30 "rsn_pairwise": "CCMP" }
33 def ft_params(rsn
=True, ssid
=None, passphrase
=None):
35 params
= ft_base_rsn()
37 params
= ft_base_mixed()
41 params
["wpa_passphrase"] = passphrase
43 params
["mobility_domain"] = "a1b2"
44 params
["r0_key_lifetime"] = "10000"
45 params
["pmk_r1_push"] = "1"
46 params
["reassociation_deadline"] = "1000"
49 def ft_params1(rsn
=True, ssid
=None, passphrase
=None):
50 params
= ft_params(rsn
, ssid
, passphrase
)
51 params
['nas_identifier'] = "nas1.w1.fi"
52 params
['r1_key_holder'] = "000102030405"
53 params
['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
54 "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
55 params
['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
58 def ft_params2(rsn
=True, ssid
=None, passphrase
=None):
59 params
= ft_params(rsn
, ssid
, passphrase
)
60 params
['nas_identifier'] = "nas2.w1.fi"
61 params
['r1_key_holder'] = "000102030406"
62 params
['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
63 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
64 params
['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
67 def ft_params1_r0kh_mismatch(rsn
=True, ssid
=None, passphrase
=None):
68 params
= ft_params(rsn
, ssid
, passphrase
)
69 params
['nas_identifier'] = "nas1.w1.fi"
70 params
['r1_key_holder'] = "000102030405"
71 params
['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
72 "12:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
73 params
['r1kh'] = "12:00:00:00:04:00 10:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
76 def ft_params2_incorrect_rrb_key(rsn
=True, ssid
=None, passphrase
=None):
77 params
= ft_params(rsn
, ssid
, passphrase
)
78 params
['nas_identifier'] = "nas2.w1.fi"
79 params
['r1_key_holder'] = "000102030406"
80 params
['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0ef1",
81 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0ef2" ]
82 params
['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0ef3"
85 def ft_params2_r0kh_mismatch(rsn
=True, ssid
=None, passphrase
=None):
86 params
= ft_params(rsn
, ssid
, passphrase
)
87 params
['nas_identifier'] = "nas2.w1.fi"
88 params
['r1_key_holder'] = "000102030406"
89 params
['r0kh'] = [ "12:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
90 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
91 params
['r1kh'] = "12:00:00:00:03:00 10:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
94 def run_roams(dev
, apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=False,
95 sae
=False, eap
=False, fail_test
=False, roams
=1,
96 pairwise_cipher
="CCMP", group_cipher
="TKIP CCMP"):
97 logger
.info("Connect to first AP")
99 dev
.connect(ssid
, key_mgmt
="FT-EAP", proto
="WPA2", ieee80211w
="1",
100 eap
="GPSK", identity
="gpsk user",
101 password
="abcdefghijklmnop0123456789abcdef",
103 pairwise
=pairwise_cipher
, group
=group_cipher
)
109 dev
.connect(ssid
, psk
=passphrase
, key_mgmt
=key_mgmt
, proto
="WPA2",
110 ieee80211w
="1", scan_freq
="2412",
111 pairwise
=pairwise_cipher
, group
=group_cipher
)
112 if dev
.get_status_field('bssid') == apdev
[0]['bssid']:
122 hwsim_utils
.test_connectivity(dev
, hapd1ap
)
124 dev
.scan_for_bss(ap2
['bssid'], freq
="2412")
126 for i
in range(0, roams
):
127 logger
.info("Roam to the second AP")
129 dev
.roam_over_ds(ap2
['bssid'], fail_test
=fail_test
)
131 dev
.roam(ap2
['bssid'], fail_test
=fail_test
)
134 if dev
.get_status_field('bssid') != ap2
['bssid']:
135 raise Exception("Did not connect to correct AP")
136 if i
== 0 or i
== roams
- 1:
137 hwsim_utils
.test_connectivity(dev
, hapd2ap
)
139 logger
.info("Roam back to the first AP")
141 dev
.roam_over_ds(ap1
['bssid'])
143 dev
.roam(ap1
['bssid'])
144 if dev
.get_status_field('bssid') != ap1
['bssid']:
145 raise Exception("Did not connect to correct AP")
146 if i
== 0 or i
== roams
- 1:
147 hwsim_utils
.test_connectivity(dev
, hapd1ap
)
149 def test_ap_ft(dev
, apdev
):
152 passphrase
="12345678"
154 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
155 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
156 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
157 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
159 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
)
160 if "[WPA2-FT/PSK-CCMP]" not in dev
[0].request("SCAN_RESULTS"):
161 raise Exception("Scan results missing RSN element info")
163 def test_ap_ft_many(dev
, apdev
):
164 """WPA2-PSK-FT AP multiple times"""
166 passphrase
="12345678"
168 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
169 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
170 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
171 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
173 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, roams
=50)
175 def test_ap_ft_mixed(dev
, apdev
):
176 """WPA2-PSK-FT mixed-mode AP"""
177 ssid
= "test-ft-mixed"
178 passphrase
="12345678"
180 params
= ft_params1(rsn
=False, ssid
=ssid
, passphrase
=passphrase
)
181 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
182 key_mgmt
= hapd
.get_config()['key_mgmt']
183 vals
= key_mgmt
.split(' ')
184 if vals
[0] != "WPA-PSK" or vals
[1] != "FT-PSK":
185 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt
)
186 params
= ft_params2(rsn
=False, ssid
=ssid
, passphrase
=passphrase
)
187 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
189 run_roams(dev
[0], apdev
, hapd
, hapd1
, ssid
, passphrase
)
191 def test_ap_ft_pmf(dev
, apdev
):
192 """WPA2-PSK-FT AP with PMF"""
194 passphrase
="12345678"
196 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
197 params
["ieee80211w"] = "2";
198 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
199 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
200 params
["ieee80211w"] = "2";
201 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
203 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
)
205 def test_ap_ft_over_ds(dev
, apdev
):
206 """WPA2-PSK-FT AP over DS"""
208 passphrase
="12345678"
210 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
211 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
212 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
213 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
215 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True)
216 check_mib(dev
[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
217 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4") ])
219 def test_ap_ft_over_ds_many(dev
, apdev
):
220 """WPA2-PSK-FT AP over DS multiple times"""
222 passphrase
="12345678"
224 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
225 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
226 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
227 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
229 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True,
232 def test_ap_ft_over_ds_unknown_target(dev
, apdev
):
235 passphrase
="12345678"
237 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
238 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
240 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
242 dev
[0].roam_over_ds("02:11:22:33:44:55", fail_test
=True)
244 def test_ap_ft_over_ds_unexpected(dev
, apdev
):
245 """WPA2-PSK-FT AP over DS and unexpected response"""
247 passphrase
="12345678"
249 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
250 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
251 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
252 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
254 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
256 if dev
[0].get_status_field('bssid') == apdev
[0]['bssid']:
267 addr
= dev
[0].own_addr()
268 hapd1ap
.set("ext_mgmt_frame_handling", "1")
269 logger
.info("Foreign STA address")
273 msg
['sa'] = ap1
['bssid']
274 msg
['bssid'] = ap1
['bssid']
275 msg
['payload'] = binascii
.unhexlify("06021122334455660102030405060000")
278 logger
.info("No over-the-DS in progress")
279 msg
['payload'] = binascii
.unhexlify("0602" + addr
.replace(':', '') + "0102030405060000")
282 logger
.info("Non-zero status code")
283 msg
['payload'] = binascii
.unhexlify("0602" + addr
.replace(':', '') + "0102030405060100")
286 hapd1ap
.dump_monitor()
288 dev
[0].scan_for_bss(ap2
['bssid'], freq
="2412")
289 if "OK" not in dev
[0].request("FT_DS " + ap2
['bssid']):
290 raise Exception("FT_DS failed")
292 req
= hapd1ap
.mgmt_rx()
294 logger
.info("Foreign Target AP")
295 msg
['payload'] = binascii
.unhexlify("0602" + addr
.replace(':', '') + "0102030405060000")
298 addrs
= addr
.replace(':', '') + ap2
['bssid'].replace(':', '')
300 logger
.info("No IEs")
301 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "0000")
304 logger
.info("Invalid IEs (trigger parsing failure)")
305 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003700")
308 logger
.info("Too short MDIE")
309 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "000036021122")
312 logger
.info("Mobility domain mismatch")
313 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003603112201")
316 logger
.info("No FTIE")
317 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003603a1b201")
320 logger
.info("FTIE SNonce mismatch")
321 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "1000000000000000000000000000000000000000000000000000000000000001" + "030a6e6173322e77312e6669")
324 logger
.info("No R0KH-ID subelem in FTIE")
325 snonce
= binascii
.hexlify(req
['payload'][111:111+32])
326 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003603a1b20137520000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce
)
329 logger
.info("No R0KH-ID subelem mismatch in FTIE")
330 snonce
= binascii
.hexlify(req
['payload'][111:111+32])
331 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce
+ "030a11223344556677889900")
334 logger
.info("No R1KH-ID subelem in FTIE")
335 r0khid
= binascii
.hexlify(req
['payload'][145:145+10])
336 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce
+ "030a" + r0khid
)
339 logger
.info("No RSNE")
340 r0khid
= binascii
.hexlify(req
['payload'][145:145+10])
341 msg
['payload'] = binascii
.unhexlify("0602" + addrs
+ "00003603a1b20137660000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce
+ "030a" + r0khid
+ "0106000102030405")
344 def test_ap_ft_pmf_over_ds(dev
, apdev
):
345 """WPA2-PSK-FT AP over DS with PMF"""
347 passphrase
="12345678"
349 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
350 params
["ieee80211w"] = "2";
351 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
352 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
353 params
["ieee80211w"] = "2";
354 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
356 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True)
358 def test_ap_ft_over_ds_pull(dev
, apdev
):
359 """WPA2-PSK-FT AP over DS (pull PMK)"""
361 passphrase
="12345678"
363 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
364 params
["pmk_r1_push"] = "0"
365 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
366 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
367 params
["pmk_r1_push"] = "0"
368 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
370 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True)
372 def test_ap_ft_sae(dev
, apdev
):
373 """WPA2-PSK-FT-SAE AP"""
374 if "SAE" not in dev
[0].get_capability("auth_alg"):
375 raise HwsimSkip("SAE not supported")
377 passphrase
="12345678"
379 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
380 params
['wpa_key_mgmt'] = "FT-SAE"
381 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
382 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
383 params
['wpa_key_mgmt'] = "FT-SAE"
384 hapd
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
385 key_mgmt
= hapd
.get_config()['key_mgmt']
386 if key_mgmt
.split(' ')[0] != "FT-SAE":
387 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt
)
389 dev
[0].request("SET sae_groups ")
390 run_roams(dev
[0], apdev
, hapd0
, hapd
, ssid
, passphrase
, sae
=True)
392 def test_ap_ft_sae_over_ds(dev
, apdev
):
393 """WPA2-PSK-FT-SAE AP over DS"""
394 if "SAE" not in dev
[0].get_capability("auth_alg"):
395 raise HwsimSkip("SAE not supported")
397 passphrase
="12345678"
399 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
400 params
['wpa_key_mgmt'] = "FT-SAE"
401 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
402 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
403 params
['wpa_key_mgmt'] = "FT-SAE"
404 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
406 dev
[0].request("SET sae_groups ")
407 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, sae
=True,
410 def test_ap_ft_eap(dev
, apdev
):
413 passphrase
="12345678"
415 radius
= hostapd
.radius_params()
416 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
417 params
['wpa_key_mgmt'] = "FT-EAP"
418 params
["ieee8021x"] = "1"
419 params
= dict(radius
.items() + params
.items())
420 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
421 key_mgmt
= hapd
.get_config()['key_mgmt']
422 if key_mgmt
.split(' ')[0] != "FT-EAP":
423 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt
)
424 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
425 params
['wpa_key_mgmt'] = "FT-EAP"
426 params
["ieee8021x"] = "1"
427 params
= dict(radius
.items() + params
.items())
428 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
430 run_roams(dev
[0], apdev
, hapd
, hapd1
, ssid
, passphrase
, eap
=True)
431 if "[WPA2-FT/EAP-CCMP]" not in dev
[0].request("SCAN_RESULTS"):
432 raise Exception("Scan results missing RSN element info")
433 check_mib(dev
[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"),
434 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3") ])
436 def test_ap_ft_eap_pull(dev
, apdev
):
437 """WPA2-EAP-FT AP (pull PMK)"""
439 passphrase
="12345678"
441 radius
= hostapd
.radius_params()
442 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
443 params
['wpa_key_mgmt'] = "FT-EAP"
444 params
["ieee8021x"] = "1"
445 params
["pmk_r1_push"] = "0"
446 params
= dict(radius
.items() + params
.items())
447 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
448 key_mgmt
= hapd
.get_config()['key_mgmt']
449 if key_mgmt
.split(' ')[0] != "FT-EAP":
450 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt
)
451 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
452 params
['wpa_key_mgmt'] = "FT-EAP"
453 params
["ieee8021x"] = "1"
454 params
["pmk_r1_push"] = "0"
455 params
= dict(radius
.items() + params
.items())
456 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
458 run_roams(dev
[0], apdev
, hapd
, hapd1
, ssid
, passphrase
, eap
=True)
460 def test_ap_ft_mismatching_rrb_key_push(dev
, apdev
):
461 """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
463 passphrase
="12345678"
465 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
466 params
["ieee80211w"] = "2";
467 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
468 params
= ft_params2_incorrect_rrb_key(ssid
=ssid
, passphrase
=passphrase
)
469 params
["ieee80211w"] = "2";
470 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
472 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True,
475 def test_ap_ft_mismatching_rrb_key_pull(dev
, apdev
):
476 """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
478 passphrase
="12345678"
480 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
481 params
["pmk_r1_push"] = "0"
482 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
483 params
= ft_params2_incorrect_rrb_key(ssid
=ssid
, passphrase
=passphrase
)
484 params
["pmk_r1_push"] = "0"
485 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
487 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True,
490 def test_ap_ft_mismatching_r0kh_id_pull(dev
, apdev
):
491 """WPA2-PSK-FT AP over DS with mismatching R0KH-ID (pull)"""
493 passphrase
="12345678"
495 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
496 params
["pmk_r1_push"] = "0"
497 params
["nas_identifier"] = "nas0.w1.fi"
498 hostapd
.add_ap(apdev
[0]['ifname'], params
)
499 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
502 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
503 params
["pmk_r1_push"] = "0"
504 hostapd
.add_ap(apdev
[1]['ifname'], params
)
506 dev
[0].scan_for_bss(apdev
[1]['bssid'], freq
="2412")
507 dev
[0].roam_over_ds(apdev
[1]['bssid'], fail_test
=True)
509 def test_ap_ft_mismatching_rrb_r0kh_push(dev
, apdev
):
510 """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
512 passphrase
="12345678"
514 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
515 params
["ieee80211w"] = "2";
516 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
517 params
= ft_params2_r0kh_mismatch(ssid
=ssid
, passphrase
=passphrase
)
518 params
["ieee80211w"] = "2";
519 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
521 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True,
524 def test_ap_ft_mismatching_rrb_r0kh_pull(dev
, apdev
):
525 """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
527 passphrase
="12345678"
529 params
= ft_params1_r0kh_mismatch(ssid
=ssid
, passphrase
=passphrase
)
530 params
["pmk_r1_push"] = "0"
531 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
532 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
533 params
["pmk_r1_push"] = "0"
534 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
536 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
, over_ds
=True,
539 def test_ap_ft_gtk_rekey(dev
, apdev
):
540 """WPA2-PSK-FT AP and GTK rekey"""
542 passphrase
="12345678"
544 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
545 params
['wpa_group_rekey'] = '1'
546 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
548 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
549 ieee80211w
="1", scan_freq
="2412")
551 ev
= dev
[0].wait_event(["WPA: Group rekeying completed"], timeout
=2)
553 raise Exception("GTK rekey timed out after initial association")
554 hwsim_utils
.test_connectivity(dev
[0], hapd
)
556 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
557 params
['wpa_group_rekey'] = '1'
558 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
560 dev
[0].scan_for_bss(apdev
[1]['bssid'], freq
="2412")
561 dev
[0].roam(apdev
[1]['bssid'])
562 if dev
[0].get_status_field('bssid') != apdev
[1]['bssid']:
563 raise Exception("Did not connect to correct AP")
564 hwsim_utils
.test_connectivity(dev
[0], hapd1
)
566 ev
= dev
[0].wait_event(["WPA: Group rekeying completed"], timeout
=2)
568 raise Exception("GTK rekey timed out after FT protocol")
569 hwsim_utils
.test_connectivity(dev
[0], hapd1
)
571 def test_ft_psk_key_lifetime_in_memory(dev
, apdev
, params
):
572 """WPA2-PSK-FT and key lifetime in memory"""
574 passphrase
="04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0"
575 psk
= '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d'
576 pmk
= binascii
.unhexlify(psk
)
577 p
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
578 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], p
)
579 p
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
580 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], p
)
582 pid
= find_wpas_process(dev
[0])
584 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
588 buf
= read_process_memory(pid
, pmk
)
590 dev
[0].request("DISCONNECT")
591 dev
[0].wait_disconnected()
598 with
open(os
.path
.join(params
['logdir'], 'log0'), 'r') as f
:
599 for l
in f
.readlines():
600 if "FT: PMK-R0 - hexdump" in l
:
601 val
= l
.strip().split(':')[3].replace(' ', '')
602 pmkr0
= binascii
.unhexlify(val
)
603 if "FT: PMK-R1 - hexdump" in l
:
604 val
= l
.strip().split(':')[3].replace(' ', '')
605 pmkr1
= binascii
.unhexlify(val
)
606 if "FT: KCK - hexdump" in l
:
607 val
= l
.strip().split(':')[3].replace(' ', '')
608 kck
= binascii
.unhexlify(val
)
609 if "FT: KEK - hexdump" in l
:
610 val
= l
.strip().split(':')[3].replace(' ', '')
611 kek
= binascii
.unhexlify(val
)
612 if "FT: TK - hexdump" in l
:
613 val
= l
.strip().split(':')[3].replace(' ', '')
614 tk
= binascii
.unhexlify(val
)
615 if "WPA: Group Key - hexdump" in l
:
616 val
= l
.strip().split(':')[3].replace(' ', '')
617 gtk
= binascii
.unhexlify(val
)
618 if not pmkr0
or not pmkr1
or not kck
or not kek
or not tk
or not gtk
:
619 raise Exception("Could not find keys from debug log")
621 raise Exception("Unexpected GTK length")
623 logger
.info("Checking keys in memory while associated")
624 get_key_locations(buf
, pmk
, "PMK")
625 get_key_locations(buf
, pmkr0
, "PMK-R0")
626 get_key_locations(buf
, pmkr1
, "PMK-R1")
628 raise HwsimSkip("PMK not found while associated")
630 raise HwsimSkip("PMK-R0 not found while associated")
632 raise HwsimSkip("PMK-R1 not found while associated")
634 raise Exception("KCK not found while associated")
636 raise Exception("KEK not found while associated")
638 raise Exception("TK found from memory")
640 raise Exception("GTK found from memory")
642 logger
.info("Checking keys in memory after disassociation")
643 buf
= read_process_memory(pid
, pmk
)
644 get_key_locations(buf
, pmk
, "PMK")
645 get_key_locations(buf
, pmkr0
, "PMK-R0")
646 get_key_locations(buf
, pmkr1
, "PMK-R1")
648 # Note: PMK/PSK is still present in network configuration
650 fname
= os
.path
.join(params
['logdir'],
651 'ft_psk_key_lifetime_in_memory.memctx-')
652 verify_not_present(buf
, pmkr0
, fname
, "PMK-R0")
653 verify_not_present(buf
, pmkr1
, fname
, "PMK-R1")
654 verify_not_present(buf
, kck
, fname
, "KCK")
655 verify_not_present(buf
, kek
, fname
, "KEK")
656 verify_not_present(buf
, tk
, fname
, "TK")
657 verify_not_present(buf
, gtk
, fname
, "GTK")
659 dev
[0].request("REMOVE_NETWORK all")
661 logger
.info("Checking keys in memory after network profile removal")
662 buf
= read_process_memory(pid
, pmk
)
663 get_key_locations(buf
, pmk
, "PMK")
664 get_key_locations(buf
, pmkr0
, "PMK-R0")
665 get_key_locations(buf
, pmkr1
, "PMK-R1")
667 verify_not_present(buf
, pmk
, fname
, "PMK")
668 verify_not_present(buf
, pmkr0
, fname
, "PMK-R0")
669 verify_not_present(buf
, pmkr1
, fname
, "PMK-R1")
670 verify_not_present(buf
, kck
, fname
, "KCK")
671 verify_not_present(buf
, kek
, fname
, "KEK")
672 verify_not_present(buf
, tk
, fname
, "TK")
673 verify_not_present(buf
, gtk
, fname
, "GTK")
675 def test_ap_ft_invalid_resp(dev
, apdev
):
676 """WPA2-PSK-FT AP and invalid response IEs"""
678 passphrase
="12345678"
680 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
681 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
682 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
685 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
686 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
689 # Various IEs for test coverage. The last one is FTIE with invalid
690 # R1KH-ID subelement.
691 "020002000000" + "3800" + "38051122334455" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010100",
692 # FTIE with invalid R0KH-ID subelement (len=0).
693 "020002000000" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010300",
694 # FTIE with invalid R0KH-ID subelement (len=49).
695 "020002000000" + "378500010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001033101020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849",
697 "020002000000" + "3000",
698 # Required IEs missing from protected IE count.
699 "020002000000" + "3603a1b201" + "375200010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
700 # RIC missing from protected IE count.
701 "020002000000" + "3603a1b201" + "375200020203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
702 # Protected IE missing.
703 "020002000000" + "3603a1b201" + "375200ff0203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900" + "0000" ]
705 dev
[0].scan_for_bss(apdev
[1]['bssid'], freq
="2412")
706 hapd1
.set("ext_mgmt_frame_handling", "1")
708 if "OK" not in dev
[0].request("ROAM " + apdev
[1]['bssid']):
709 raise Exception("ROAM failed")
712 msg
= hapd1
.mgmt_rx()
713 if msg
['subtype'] == 11:
717 raise Exception("Authentication frame not seen")
720 resp
['fc'] = auth
['fc']
721 resp
['da'] = auth
['sa']
722 resp
['sa'] = auth
['da']
723 resp
['bssid'] = auth
['bssid']
724 resp
['payload'] = binascii
.unhexlify(t
)
726 hapd1
.set("ext_mgmt_frame_handling", "0")
727 dev
[0].wait_disconnected()
729 dev
[0].request("RECONNECT")
730 dev
[0].wait_connected()
732 def test_ap_ft_gcmp_256(dev
, apdev
):
733 """WPA2-PSK-FT AP with GCMP-256 cipher"""
734 if "GCMP-256" not in dev
[0].get_capability("pairwise"):
735 raise HwsimSkip("Cipher GCMP-256 not supported")
737 passphrase
="12345678"
739 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
740 params
['rsn_pairwise'] = "GCMP-256"
741 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
742 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
743 params
['rsn_pairwise'] = "GCMP-256"
744 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
746 run_roams(dev
[0], apdev
, hapd0
, hapd1
, ssid
, passphrase
,
747 pairwise_cipher
="GCMP-256", group_cipher
="GCMP-256")
749 def test_ap_ft_oom(dev
, apdev
):
750 """WPA2-PSK-FT and OOM"""
752 passphrase
="12345678"
754 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
755 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
756 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
757 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
759 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
761 if dev
[0].get_status_field('bssid') == apdev
[0]['bssid']:
762 dst
= apdev
[1]['bssid']
764 dst
= apdev
[0]['bssid']
766 dev
[0].scan_for_bss(dst
, freq
="2412")
767 with
alloc_fail(dev
[0], 1, "wpa_ft_gen_req_ies"):
769 with
alloc_fail(dev
[0], 1, "wpa_ft_mic"):
770 dev
[0].roam(dst
, fail_test
=True)
771 with
fail_test(dev
[0], 1, "os_get_random;wpa_ft_prepare_auth_request"):
772 dev
[0].roam(dst
, fail_test
=True)
774 def test_ap_ft_over_ds_proto(dev
, apdev
):
775 """WPA2-PSK-FT AP over DS protocol testing"""
777 passphrase
="12345678"
779 params
= ft_params1(ssid
=ssid
, passphrase
=passphrase
)
780 hapd0
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
781 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="FT-PSK", proto
="WPA2",
784 # FT Action Response while no FT-over-DS in progress
787 msg
['da'] = dev
[0].own_addr()
788 msg
['sa'] = apdev
[0]['bssid']
789 msg
['bssid'] = apdev
[0]['bssid']
790 msg
['payload'] = binascii
.unhexlify("06020200000000000200000004000000")
793 params
= ft_params2(ssid
=ssid
, passphrase
=passphrase
)
794 hapd1
= hostapd
.add_ap(apdev
[1]['ifname'], params
)
795 dev
[0].scan_for_bss(apdev
[1]['bssid'], freq
="2412")
796 hapd0
.set("ext_mgmt_frame_handling", "1")
798 dev
[0].request("FT_DS " + apdev
[1]['bssid'])
799 for i
in range(0, 10):
800 req
= hapd0
.mgmt_rx()
802 raise Exception("MGMT RX wait timed out")
803 if req
['subtype'] == 13:
807 raise Exception("FT Action frame not received")
809 # FT Action Response for unexpected Target AP
810 msg
['payload'] = binascii
.unhexlify("0602020000000000" + "f20000000400" + "0000")
813 # FT Action Response without MDIE
814 msg
['payload'] = binascii
.unhexlify("0602020000000000" + "020000000400" + "0000")
817 # FT Action Response without FTIE
818 msg
['payload'] = binascii
.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201")
821 # FT Action Response with FTIE SNonce mismatch
822 msg
['payload'] = binascii
.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201" + "3766000000000000000000000000000000000000c4e67ac1999bebd00ff4ae4d5dcaf87896bb060b469f7c78d49623fb395c3455ffffff6b693fe6f8d8c5dfac0a22344750775bd09437f98b238c9f87b97f790c0106000102030406030a6e6173312e77312e6669")