]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_ft.py
tests: Use rfkill python module
[thirdparty/hostap.git] / tests / hwsim / test_ap_ft.py
CommitLineData
cd7f1b9a 1# Fast BSS Transition tests
ae14a2e2 2# Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
cd7f1b9a
JM
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
5b3c40a6
JM
7import binascii
8import os
cd7f1b9a
JM
9import time
10import subprocess
11import logging
c9aa4308 12logger = logging.getLogger()
cd7f1b9a
JM
13
14import hwsim_utils
15import hostapd
16from wlantest import Wlantest
5b3c40a6 17from test_ap_psk import check_mib, find_wpas_process, read_process_memory, verify_not_present, get_key_locations
cd7f1b9a
JM
18
19def ft_base_rsn():
20 params = { "wpa": "2",
21 "wpa_key_mgmt": "FT-PSK",
22 "rsn_pairwise": "CCMP" }
23 return params
24
25def ft_base_mixed():
26 params = { "wpa": "3",
27 "wpa_key_mgmt": "WPA-PSK FT-PSK",
28 "wpa_pairwise": "TKIP",
29 "rsn_pairwise": "CCMP" }
30 return params
31
32def ft_params(rsn=True, ssid=None, passphrase=None):
33 if rsn:
34 params = ft_base_rsn()
35 else:
36 params = ft_base_mixed()
37 if ssid:
38 params["ssid"] = ssid
39 if passphrase:
40 params["wpa_passphrase"] = passphrase
41
42 params["mobility_domain"] = "a1b2"
43 params["r0_key_lifetime"] = "10000"
44 params["pmk_r1_push"] = "1"
45 params["reassociation_deadline"] = "1000"
46 return params
47
48def ft_params1(rsn=True, ssid=None, passphrase=None):
49 params = ft_params(rsn, ssid, passphrase)
50 params['nas_identifier'] = "nas1.w1.fi"
51 params['r1_key_holder'] = "000102030405"
52 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
53 "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
54 params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
55 return params
56
57def ft_params2(rsn=True, ssid=None, passphrase=None):
58 params = ft_params(rsn, ssid, passphrase)
59 params['nas_identifier'] = "nas2.w1.fi"
60 params['r1_key_holder'] = "000102030406"
61 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
62 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
63 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
64 return params
65
3b808945
JM
66def ft_params1_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
67 params = ft_params(rsn, ssid, passphrase)
68 params['nas_identifier'] = "nas1.w1.fi"
69 params['r1_key_holder'] = "000102030405"
70 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
71 "12:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
72 params['r1kh'] = "12:00:00:00:04:00 10:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
73 return params
74
75def ft_params2_incorrect_rrb_key(rsn=True, ssid=None, passphrase=None):
76 params = ft_params(rsn, ssid, passphrase)
77 params['nas_identifier'] = "nas2.w1.fi"
78 params['r1_key_holder'] = "000102030406"
79 params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0ef1",
80 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0ef2" ]
81 params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0ef3"
82 return params
83
84def ft_params2_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
85 params = ft_params(rsn, ssid, passphrase)
86 params['nas_identifier'] = "nas2.w1.fi"
87 params['r1_key_holder'] = "000102030406"
88 params['r0kh'] = [ "12:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
89 "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
90 params['r1kh'] = "12:00:00:00:03:00 10:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
91 return params
92
a8375c94 93def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False, sae=False, eap=False, fail_test=False, roams=1):
cd7f1b9a 94 logger.info("Connect to first AP")
6f62809b
JM
95 if eap:
96 dev.connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
2f816c21
JM
97 eap="GPSK", identity="gpsk user",
98 password="abcdefghijklmnop0123456789abcdef",
99 scan_freq="2412")
6e658cc4 100 else:
6f62809b
JM
101 if sae:
102 key_mgmt="FT-SAE"
103 else:
104 key_mgmt="FT-PSK"
105 dev.connect(ssid, psk=passphrase, key_mgmt=key_mgmt, proto="WPA2",
2f816c21 106 ieee80211w="1", scan_freq="2412")
cd7f1b9a
JM
107 if dev.get_status_field('bssid') == apdev[0]['bssid']:
108 ap1 = apdev[0]
109 ap2 = apdev[1]
a8375c94
JM
110 hapd1ap = hapd0
111 hapd2ap = hapd1
cd7f1b9a
JM
112 else:
113 ap1 = apdev[1]
114 ap2 = apdev[0]
a8375c94
JM
115 hapd1ap = hapd1
116 hapd2ap = hapd0
117 hwsim_utils.test_connectivity(dev, hapd1ap)
cd7f1b9a 118
655bc8bf 119 dev.scan_for_bss(ap2['bssid'], freq="2412")
40602101
JM
120
121 for i in range(0, roams):
122 logger.info("Roam to the second AP")
123 if over_ds:
124 dev.roam_over_ds(ap2['bssid'], fail_test=fail_test)
125 else:
126 dev.roam(ap2['bssid'], fail_test=fail_test)
127 if fail_test:
128 return
129 if dev.get_status_field('bssid') != ap2['bssid']:
130 raise Exception("Did not connect to correct AP")
131 if i == 0 or i == roams - 1:
a8375c94 132 hwsim_utils.test_connectivity(dev, hapd2ap)
40602101
JM
133
134 logger.info("Roam back to the first AP")
135 if over_ds:
136 dev.roam_over_ds(ap1['bssid'])
137 else:
138 dev.roam(ap1['bssid'])
139 if dev.get_status_field('bssid') != ap1['bssid']:
140 raise Exception("Did not connect to correct AP")
141 if i == 0 or i == roams - 1:
a8375c94 142 hwsim_utils.test_connectivity(dev, hapd1ap)
cd7f1b9a
JM
143
144def test_ap_ft(dev, apdev):
145 """WPA2-PSK-FT AP"""
146 ssid = "test-ft"
147 passphrase="12345678"
148
149 params = ft_params1(ssid=ssid, passphrase=passphrase)
a8375c94 150 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
cd7f1b9a 151 params = ft_params2(ssid=ssid, passphrase=passphrase)
a8375c94 152 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
cd7f1b9a 153
a8375c94 154 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
91bc6c36
JM
155 if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
156 raise Exception("Scan results missing RSN element info")
cd7f1b9a 157
40602101
JM
158def test_ap_ft_many(dev, apdev):
159 """WPA2-PSK-FT AP multiple times"""
160 ssid = "test-ft"
161 passphrase="12345678"
162
163 params = ft_params1(ssid=ssid, passphrase=passphrase)
a8375c94 164 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
40602101 165 params = ft_params2(ssid=ssid, passphrase=passphrase)
a8375c94 166 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
40602101 167
a8375c94 168 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50)
40602101 169
cd7f1b9a
JM
170def test_ap_ft_mixed(dev, apdev):
171 """WPA2-PSK-FT mixed-mode AP"""
172 ssid = "test-ft-mixed"
173 passphrase="12345678"
174
175 params = ft_params1(rsn=False, ssid=ssid, passphrase=passphrase)
65038313
JM
176 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
177 key_mgmt = hapd.get_config()['key_mgmt']
178 vals = key_mgmt.split(' ')
179 if vals[0] != "WPA-PSK" or vals[1] != "FT-PSK":
180 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
cd7f1b9a 181 params = ft_params2(rsn=False, ssid=ssid, passphrase=passphrase)
a8375c94 182 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
cd7f1b9a 183
a8375c94 184 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase)
cd7f1b9a
JM
185
186def test_ap_ft_pmf(dev, apdev):
187 """WPA2-PSK-FT AP with PMF"""
188 ssid = "test-ft"
189 passphrase="12345678"
190
191 params = ft_params1(ssid=ssid, passphrase=passphrase)
192 params["ieee80211w"] = "2";
a8375c94 193 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
cd7f1b9a
JM
194 params = ft_params2(ssid=ssid, passphrase=passphrase)
195 params["ieee80211w"] = "2";
a8375c94 196 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
cd7f1b9a 197
a8375c94 198 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
b553eab1
JM
199
200def test_ap_ft_over_ds(dev, apdev):
201 """WPA2-PSK-FT AP over DS"""
202 ssid = "test-ft"
203 passphrase="12345678"
204
205 params = ft_params1(ssid=ssid, passphrase=passphrase)
a8375c94 206 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
b553eab1 207 params = ft_params2(ssid=ssid, passphrase=passphrase)
a8375c94 208 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
b553eab1 209
a8375c94 210 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
eaf3f9b1
JM
211 check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
212 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4") ])
b553eab1 213
40602101
JM
214def test_ap_ft_over_ds_many(dev, apdev):
215 """WPA2-PSK-FT AP over DS multiple times"""
216 ssid = "test-ft"
217 passphrase="12345678"
218
219 params = ft_params1(ssid=ssid, passphrase=passphrase)
a8375c94 220 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
40602101 221 params = ft_params2(ssid=ssid, passphrase=passphrase)
a8375c94 222 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
40602101 223
a8375c94
JM
224 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
225 roams=50)
40602101 226
c337d07a
JM
227def test_ap_ft_over_ds_unknown_target(dev, apdev):
228 """WPA2-PSK-FT AP"""
229 ssid = "test-ft"
230 passphrase="12345678"
231
232 params = ft_params1(ssid=ssid, passphrase=passphrase)
233 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
234
235 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
236 scan_freq="2412")
237 dev[0].roam_over_ds("02:11:22:33:44:55", fail_test=True)
238
b553eab1
JM
239def test_ap_ft_pmf_over_ds(dev, apdev):
240 """WPA2-PSK-FT AP over DS with PMF"""
241 ssid = "test-ft"
242 passphrase="12345678"
243
244 params = ft_params1(ssid=ssid, passphrase=passphrase)
245 params["ieee80211w"] = "2";
a8375c94 246 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
b553eab1
JM
247 params = ft_params2(ssid=ssid, passphrase=passphrase)
248 params["ieee80211w"] = "2";
a8375c94 249 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
b553eab1 250
a8375c94 251 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
6e658cc4 252
aaba98d3
JM
253def test_ap_ft_over_ds_pull(dev, apdev):
254 """WPA2-PSK-FT AP over DS (pull PMK)"""
255 ssid = "test-ft"
256 passphrase="12345678"
257
258 params = ft_params1(ssid=ssid, passphrase=passphrase)
259 params["pmk_r1_push"] = "0"
a8375c94 260 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
aaba98d3
JM
261 params = ft_params2(ssid=ssid, passphrase=passphrase)
262 params["pmk_r1_push"] = "0"
a8375c94 263 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
aaba98d3 264
a8375c94 265 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
aaba98d3 266
6e658cc4
JM
267def test_ap_ft_sae(dev, apdev):
268 """WPA2-PSK-FT-SAE AP"""
269 ssid = "test-ft"
270 passphrase="12345678"
271
272 params = ft_params1(ssid=ssid, passphrase=passphrase)
273 params['wpa_key_mgmt'] = "FT-SAE"
a8375c94 274 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
6e658cc4
JM
275 params = ft_params2(ssid=ssid, passphrase=passphrase)
276 params['wpa_key_mgmt'] = "FT-SAE"
65038313
JM
277 hapd = hostapd.add_ap(apdev[1]['ifname'], params)
278 key_mgmt = hapd.get_config()['key_mgmt']
279 if key_mgmt.split(' ')[0] != "FT-SAE":
280 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
6e658cc4 281
17ffdf39 282 dev[0].request("SET sae_groups ")
a8375c94 283 run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True)
6e658cc4
JM
284
285def test_ap_ft_sae_over_ds(dev, apdev):
286 """WPA2-PSK-FT-SAE AP over DS"""
287 ssid = "test-ft"
288 passphrase="12345678"
289
290 params = ft_params1(ssid=ssid, passphrase=passphrase)
291 params['wpa_key_mgmt'] = "FT-SAE"
a8375c94 292 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
6e658cc4
JM
293 params = ft_params2(ssid=ssid, passphrase=passphrase)
294 params['wpa_key_mgmt'] = "FT-SAE"
a8375c94 295 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
6e658cc4 296
17ffdf39 297 dev[0].request("SET sae_groups ")
a8375c94
JM
298 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, sae=True,
299 over_ds=True)
6f62809b
JM
300
301def test_ap_ft_eap(dev, apdev):
302 """WPA2-EAP-FT AP"""
303 ssid = "test-ft"
304 passphrase="12345678"
305
306 radius = hostapd.radius_params()
307 params = ft_params1(ssid=ssid, passphrase=passphrase)
308 params['wpa_key_mgmt'] = "FT-EAP"
309 params["ieee8021x"] = "1"
310 params = dict(radius.items() + params.items())
65038313
JM
311 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
312 key_mgmt = hapd.get_config()['key_mgmt']
313 if key_mgmt.split(' ')[0] != "FT-EAP":
314 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
6f62809b
JM
315 params = ft_params2(ssid=ssid, passphrase=passphrase)
316 params['wpa_key_mgmt'] = "FT-EAP"
317 params["ieee8021x"] = "1"
318 params = dict(radius.items() + params.items())
a8375c94 319 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
6f62809b 320
a8375c94 321 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
91bc6c36
JM
322 if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"):
323 raise Exception("Scan results missing RSN element info")
eaf3f9b1
JM
324 check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"),
325 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3") ])
aaba98d3
JM
326
327def test_ap_ft_eap_pull(dev, apdev):
328 """WPA2-EAP-FT AP (pull PMK)"""
329 ssid = "test-ft"
330 passphrase="12345678"
331
332 radius = hostapd.radius_params()
333 params = ft_params1(ssid=ssid, passphrase=passphrase)
334 params['wpa_key_mgmt'] = "FT-EAP"
335 params["ieee8021x"] = "1"
336 params["pmk_r1_push"] = "0"
337 params = dict(radius.items() + params.items())
338 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
339 key_mgmt = hapd.get_config()['key_mgmt']
340 if key_mgmt.split(' ')[0] != "FT-EAP":
341 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
342 params = ft_params2(ssid=ssid, passphrase=passphrase)
343 params['wpa_key_mgmt'] = "FT-EAP"
344 params["ieee8021x"] = "1"
345 params["pmk_r1_push"] = "0"
346 params = dict(radius.items() + params.items())
a8375c94 347 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
aaba98d3 348
a8375c94 349 run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
3b808945
JM
350
351def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
352 """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
353 ssid = "test-ft"
354 passphrase="12345678"
355
356 params = ft_params1(ssid=ssid, passphrase=passphrase)
357 params["ieee80211w"] = "2";
a8375c94 358 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
3b808945
JM
359 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
360 params["ieee80211w"] = "2";
a8375c94 361 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
3b808945 362
a8375c94
JM
363 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
364 fail_test=True)
3b808945
JM
365
366def test_ap_ft_mismatching_rrb_key_pull(dev, apdev):
367 """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
368 ssid = "test-ft"
369 passphrase="12345678"
370
371 params = ft_params1(ssid=ssid, passphrase=passphrase)
372 params["pmk_r1_push"] = "0"
a8375c94 373 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
3b808945
JM
374 params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
375 params["pmk_r1_push"] = "0"
a8375c94 376 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
3b808945 377
a8375c94
JM
378 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
379 fail_test=True)
3b808945 380
ae14a2e2
JM
381def test_ap_ft_mismatching_r0kh_id_pull(dev, apdev):
382 """WPA2-PSK-FT AP over DS with mismatching R0KH-ID (pull)"""
383 ssid = "test-ft"
384 passphrase="12345678"
385
386 params = ft_params1(ssid=ssid, passphrase=passphrase)
387 params["pmk_r1_push"] = "0"
388 params["nas_identifier"] = "nas0.w1.fi"
389 hostapd.add_ap(apdev[0]['ifname'], params)
2f816c21
JM
390 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
391 scan_freq="2412")
ae14a2e2
JM
392
393 params = ft_params2(ssid=ssid, passphrase=passphrase)
394 params["pmk_r1_push"] = "0"
395 hostapd.add_ap(apdev[1]['ifname'], params)
396
397 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
398 dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
399
3b808945
JM
400def test_ap_ft_mismatching_rrb_r0kh_push(dev, apdev):
401 """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
402 ssid = "test-ft"
403 passphrase="12345678"
404
405 params = ft_params1(ssid=ssid, passphrase=passphrase)
406 params["ieee80211w"] = "2";
a8375c94 407 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
3b808945
JM
408 params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
409 params["ieee80211w"] = "2";
a8375c94 410 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
3b808945 411
a8375c94
JM
412 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
413 fail_test=True)
3b808945
JM
414
415def test_ap_ft_mismatching_rrb_r0kh_pull(dev, apdev):
416 """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
417 ssid = "test-ft"
418 passphrase="12345678"
419
420 params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
421 params["pmk_r1_push"] = "0"
a8375c94 422 hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
3b808945
JM
423 params = ft_params2(ssid=ssid, passphrase=passphrase)
424 params["pmk_r1_push"] = "0"
a8375c94 425 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
3b808945 426
a8375c94
JM
427 run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
428 fail_test=True)
c6b6e105
JM
429
430def test_ap_ft_gtk_rekey(dev, apdev):
431 """WPA2-PSK-FT AP and GTK rekey"""
432 ssid = "test-ft"
433 passphrase="12345678"
434
435 params = ft_params1(ssid=ssid, passphrase=passphrase)
436 params['wpa_group_rekey'] = '1'
a8375c94 437 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
c6b6e105
JM
438
439 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
2f816c21 440 ieee80211w="1", scan_freq="2412")
c6b6e105
JM
441
442 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
443 if ev is None:
444 raise Exception("GTK rekey timed out after initial association")
a8375c94 445 hwsim_utils.test_connectivity(dev[0], hapd)
c6b6e105
JM
446
447 params = ft_params2(ssid=ssid, passphrase=passphrase)
448 params['wpa_group_rekey'] = '1'
a8375c94 449 hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
c6b6e105
JM
450
451 dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
452 dev[0].roam(apdev[1]['bssid'])
453 if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
454 raise Exception("Did not connect to correct AP")
a8375c94 455 hwsim_utils.test_connectivity(dev[0], hapd1)
c6b6e105
JM
456
457 ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
458 if ev is None:
459 raise Exception("GTK rekey timed out after FT protocol")
a8375c94 460 hwsim_utils.test_connectivity(dev[0], hapd1)
5b3c40a6
JM
461
462def test_ft_psk_key_lifetime_in_memory(dev, apdev, params):
463 """WPA2-PSK-FT and key lifetime in memory"""
464 ssid = "test-ft"
465 passphrase="04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0"
466 psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d'
467 pmk = binascii.unhexlify(psk)
468 p = ft_params1(ssid=ssid, passphrase=passphrase)
469 hapd0 = hostapd.add_ap(apdev[0]['ifname'], p)
470 p = ft_params2(ssid=ssid, passphrase=passphrase)
471 hapd1 = hostapd.add_ap(apdev[1]['ifname'], p)
472
473 pid = find_wpas_process(dev[0])
474
475 dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
476 scan_freq="2412")
477 time.sleep(0.1)
478
479 buf = read_process_memory(pid, pmk)
480
481 dev[0].request("DISCONNECT")
482 dev[0].wait_disconnected()
483
484 dev[0].relog()
485 pmkr0 = None
486 pmkr1 = None
487 ptk = None
488 gtk = None
489 with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
490 for l in f.readlines():
491 if "FT: PMK-R0 - hexdump" in l:
492 val = l.strip().split(':')[3].replace(' ', '')
493 pmkr0 = binascii.unhexlify(val)
494 if "FT: PMK-R1 - hexdump" in l:
495 val = l.strip().split(':')[3].replace(' ', '')
496 pmkr1 = binascii.unhexlify(val)
497 if "FT: PTK - hexdump" in l:
498 val = l.strip().split(':')[3].replace(' ', '')
499 ptk = binascii.unhexlify(val)
500 if "WPA: Group Key - hexdump" in l:
501 val = l.strip().split(':')[3].replace(' ', '')
502 gtk = binascii.unhexlify(val)
503 if not pmkr0 or not pmkr1 or not ptk or not gtk:
504 raise Exception("Could not find keys from debug log")
505 if len(gtk) != 16:
506 raise Exception("Unexpected GTK length")
507
508 kck = ptk[0:16]
509 kek = ptk[16:32]
510 tk = ptk[32:48]
511
512 logger.info("Checking keys in memory while associated")
513 get_key_locations(buf, pmk, "PMK")
514 get_key_locations(buf, pmkr0, "PMK-R0")
515 get_key_locations(buf, pmkr1, "PMK-R1")
516 if pmk not in buf:
517 print("PMK not found while associated")
518 return "skip"
519 if pmkr0 not in buf:
520 print("PMK-R0 not found while associated")
521 return "skip"
522 if pmkr1 not in buf:
523 print("PMK-R1 not found while associated")
524 return "skip"
525 if kck not in buf:
526 raise Exception("KCK not found while associated")
527 if kek not in buf:
528 raise Exception("KEK not found while associated")
529 if tk in buf:
530 raise Exception("TK found from memory")
531 if gtk in buf:
532 raise Exception("GTK found from memory")
533
534 logger.info("Checking keys in memory after disassociation")
535 buf = read_process_memory(pid, pmk)
536 get_key_locations(buf, pmk, "PMK")
537 get_key_locations(buf, pmkr0, "PMK-R0")
538 get_key_locations(buf, pmkr1, "PMK-R1")
539
540 # Note: PMK/PSK is still present in network configuration
541
542 fname = os.path.join(params['logdir'],
543 'ft_psk_key_lifetime_in_memory.memctx-')
544 verify_not_present(buf, pmkr0, fname, "PMK-R0")
545 verify_not_present(buf, pmkr1, fname, "PMK-R1")
546 verify_not_present(buf, kck, fname, "KCK")
547 verify_not_present(buf, kek, fname, "KEK")
548 verify_not_present(buf, tk, fname, "TK")
549 verify_not_present(buf, gtk, fname, "GTK")
550
551 dev[0].request("REMOVE_NETWORK all")
552
553 logger.info("Checking keys in memory after network profile removal")
554 buf = read_process_memory(pid, pmk)
555 get_key_locations(buf, pmk, "PMK")
556 get_key_locations(buf, pmkr0, "PMK-R0")
557 get_key_locations(buf, pmkr1, "PMK-R1")
558
559 verify_not_present(buf, pmk, fname, "PMK")
560 verify_not_present(buf, pmkr0, fname, "PMK-R0")
561 verify_not_present(buf, pmkr1, fname, "PMK-R1")
562 verify_not_present(buf, kck, fname, "KCK")
563 verify_not_present(buf, kek, fname, "KEK")
564 verify_not_present(buf, tk, fname, "TK")
565 verify_not_present(buf, gtk, fname, "GTK")