]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_psk.py
2 # Copyright (c) 2014, Qualcomm Atheros, Inc.
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
11 logger
= logging
.getLogger()
21 def check_mib(dev
, vals
):
25 raise Exception("Unexpected {} = {} (expected {})".format(v
[0], mib
[v
[0]], v
[1]))
27 def test_ap_wpa2_psk(dev
, apdev
):
28 """WPA2-PSK AP with PSK instead of passphrase"""
29 ssid
= "test-wpa2-psk"
30 passphrase
= 'qwertyuiop'
31 psk
= '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
32 params
= hostapd
.wpa2_params(ssid
=ssid
)
33 params
['wpa_psk'] = psk
34 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
35 key_mgmt
= hapd
.get_config()['key_mgmt']
36 if key_mgmt
.split(' ')[0] != "WPA-PSK":
37 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt
)
38 dev
[0].connect(ssid
, raw_psk
=psk
, scan_freq
="2412")
39 dev
[1].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
41 sig
= dev
[0].request("SIGNAL_POLL").splitlines()
42 pkt
= dev
[0].request("PKTCNT_POLL").splitlines()
43 if "FREQUENCY=2412" not in sig
:
44 raise Exception("Unexpected SIGNAL_POLL value: " + str(sig
))
45 if "TXBAD=0" not in pkt
:
46 raise Exception("Unexpected TXBAD value: " + str(pkt
))
48 def test_ap_wpa2_psk_file(dev
, apdev
):
49 """WPA2-PSK AP with PSK from a file"""
50 ssid
= "test-wpa2-psk"
51 passphrase
= 'qwertyuiop'
52 psk
= '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
53 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
54 params
['wpa_psk_file'] = 'hostapd.wpa_psk'
55 hostapd
.add_ap(apdev
[0]['ifname'], params
)
56 dev
[1].connect(ssid
, psk
="very secret", scan_freq
="2412", wait_connect
=False)
57 dev
[2].connect(ssid
, raw_psk
=psk
, scan_freq
="2412")
58 dev
[2].request("REMOVE_NETWORK all")
59 dev
[0].connect(ssid
, psk
="very secret", scan_freq
="2412")
60 dev
[0].request("REMOVE_NETWORK all")
61 dev
[2].connect(ssid
, psk
="another passphrase for all STAs", scan_freq
="2412")
62 dev
[0].connect(ssid
, psk
="another passphrase for all STAs", scan_freq
="2412")
63 ev
= dev
[1].wait_event(["WPA: 4-Way Handshake failed"], timeout
=10)
65 raise Exception("Timed out while waiting for failure report")
66 dev
[1].request("REMOVE_NETWORK all")
68 def test_ap_wpa2_ptk_rekey(dev
, apdev
):
69 """WPA2-PSK AP and PTK rekey enforced by station"""
70 ssid
= "test-wpa2-psk"
71 passphrase
= 'qwertyuiop'
72 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
73 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
74 dev
[0].connect(ssid
, psk
=passphrase
, wpa_ptk_rekey
="1", scan_freq
="2412")
75 ev
= dev
[0].wait_event(["WPA: Key negotiation completed"])
77 raise Exception("PTK rekey timed out")
78 hwsim_utils
.test_connectivity(dev
[0], hapd
)
80 def test_ap_wpa2_ptk_rekey_ap(dev
, apdev
):
81 """WPA2-PSK AP and PTK rekey enforced by AP"""
82 ssid
= "test-wpa2-psk"
83 passphrase
= 'qwertyuiop'
84 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
85 params
['wpa_ptk_rekey'] = '2'
86 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
87 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
88 ev
= dev
[0].wait_event(["WPA: Key negotiation completed"])
90 raise Exception("PTK rekey timed out")
91 hwsim_utils
.test_connectivity(dev
[0], hapd
)
93 def test_ap_wpa2_sha256_ptk_rekey(dev
, apdev
):
94 """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by station"""
95 ssid
= "test-wpa2-psk"
96 passphrase
= 'qwertyuiop'
97 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
98 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
99 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
100 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="WPA-PSK-SHA256",
101 wpa_ptk_rekey
="1", scan_freq
="2412")
102 ev
= dev
[0].wait_event(["WPA: Key negotiation completed"])
104 raise Exception("PTK rekey timed out")
105 hwsim_utils
.test_connectivity(dev
[0], hapd
)
106 check_mib(dev
[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
107 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
109 def test_ap_wpa2_sha256_ptk_rekey_ap(dev
, apdev
):
110 """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by AP"""
111 ssid
= "test-wpa2-psk"
112 passphrase
= 'qwertyuiop'
113 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
114 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
115 params
['wpa_ptk_rekey'] = '2'
116 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
117 dev
[0].connect(ssid
, psk
=passphrase
, key_mgmt
="WPA-PSK-SHA256",
119 ev
= dev
[0].wait_event(["WPA: Key negotiation completed"])
121 raise Exception("PTK rekey timed out")
122 hwsim_utils
.test_connectivity(dev
[0], hapd
)
123 check_mib(dev
[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
124 ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
126 def test_ap_wpa_ptk_rekey(dev
, apdev
):
127 """WPA-PSK/TKIP AP and PTK rekey enforced by station"""
128 ssid
= "test-wpa-psk"
129 passphrase
= 'qwertyuiop'
130 params
= hostapd
.wpa_params(ssid
=ssid
, passphrase
=passphrase
)
131 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
132 dev
[0].connect(ssid
, psk
=passphrase
, wpa_ptk_rekey
="1", scan_freq
="2412")
133 if "[WPA-PSK-TKIP]" not in dev
[0].request("SCAN_RESULTS"):
134 raise Exception("Scan results missing WPA element info")
135 ev
= dev
[0].wait_event(["WPA: Key negotiation completed"])
137 raise Exception("PTK rekey timed out")
138 hwsim_utils
.test_connectivity(dev
[0], hapd
)
140 def test_ap_wpa_ptk_rekey_ap(dev
, apdev
):
141 """WPA-PSK/TKIP AP and PTK rekey enforced by AP"""
142 ssid
= "test-wpa-psk"
143 passphrase
= 'qwertyuiop'
144 params
= hostapd
.wpa_params(ssid
=ssid
, passphrase
=passphrase
)
145 params
['wpa_ptk_rekey'] = '2'
146 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
147 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
148 ev
= dev
[0].wait_event(["WPA: Key negotiation completed"], timeout
=10)
150 raise Exception("PTK rekey timed out")
151 hwsim_utils
.test_connectivity(dev
[0], hapd
)
153 def test_ap_wpa_ccmp(dev
, apdev
):
155 ssid
= "test-wpa-psk"
156 passphrase
= 'qwertyuiop'
157 params
= hostapd
.wpa_params(ssid
=ssid
, passphrase
=passphrase
)
158 params
['wpa_pairwise'] = "CCMP"
159 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
160 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
161 hwsim_utils
.test_connectivity(dev
[0], hapd
)
162 check_mib(dev
[0], [ ("dot11RSNAConfigGroupCipherSize", "128"),
163 ("dot11RSNAGroupCipherRequested", "00-50-f2-4"),
164 ("dot11RSNAPairwiseCipherRequested", "00-50-f2-4"),
165 ("dot11RSNAAuthenticationSuiteRequested", "00-50-f2-2"),
166 ("dot11RSNAGroupCipherSelected", "00-50-f2-4"),
167 ("dot11RSNAPairwiseCipherSelected", "00-50-f2-4"),
168 ("dot11RSNAAuthenticationSuiteSelected", "00-50-f2-2"),
169 ("dot1xSuppSuppControlledPortStatus", "Authorized") ])
171 def test_ap_wpa2_psk_file(dev
, apdev
):
172 """WPA2-PSK AP with various PSK file error and success cases"""
173 addr0
= dev
[0].p2p_dev_addr()
174 addr1
= dev
[1].p2p_dev_addr()
175 addr2
= dev
[2].p2p_dev_addr()
177 pskfile
= "/tmp/ap_wpa2_psk_file_errors.psk_file"
183 params
= { "ssid": ssid
, "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
184 "rsn_pairwise": "CCMP", "wpa_psk_file": pskfile
}
188 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
189 if "FAIL" not in hapd
.request("ENABLE"):
190 raise Exception("Unexpected ENABLE success")
191 hapd
.request("DISABLE")
193 # invalid MAC address
194 with
open(pskfile
, "w") as f
:
197 if "FAIL" not in hapd
.request("ENABLE"):
198 raise Exception("Unexpected ENABLE success")
199 hapd
.request("DISABLE")
202 with
open(pskfile
, "w") as f
:
203 f
.write("00:11:22:33:44:55\n")
204 if "FAIL" not in hapd
.request("ENABLE"):
205 raise Exception("Unexpected ENABLE success")
206 hapd
.request("DISABLE")
209 with
open(pskfile
, "w") as f
:
210 f
.write("00:11:22:33:44:55 1234567\n")
211 if "FAIL" not in hapd
.request("ENABLE"):
212 raise Exception("Unexpected ENABLE success")
213 hapd
.request("DISABLE")
216 with
open(pskfile
, "w") as f
:
217 f
.write("00:11:22:33:44:55 12345678\n")
218 f
.write(addr0
+ " 123456789\n")
219 f
.write(addr1
+ " 123456789a\n")
220 f
.write(addr2
+ " 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n")
221 if "FAIL" in hapd
.request("ENABLE"):
222 raise Exception("Unexpected ENABLE failure")
224 dev
[0].connect(ssid
, psk
="123456789", scan_freq
="2412")
225 dev
[1].connect(ssid
, psk
="123456789a", scan_freq
="2412")
226 dev
[2].connect(ssid
, raw_psk
="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", scan_freq
="2412")
234 def test_ap_wpa2_psk_wildcard_ssid(dev
, apdev
):
235 """WPA2-PSK AP and wildcard SSID configuration"""
236 ssid
= "test-wpa2-psk"
237 passphrase
= 'qwertyuiop'
238 psk
= '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
239 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
240 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
241 dev
[0].connect("", bssid
=apdev
[0]['bssid'], psk
=passphrase
,
243 dev
[1].connect("", bssid
=apdev
[0]['bssid'], raw_psk
=psk
, scan_freq
="2412")
245 def test_ap_wpa2_gtk_rekey(dev
, apdev
):
246 """WPA2-PSK AP and GTK rekey enforced by AP"""
247 ssid
= "test-wpa2-psk"
248 passphrase
= 'qwertyuiop'
249 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
250 params
['wpa_group_rekey'] = '1'
251 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
252 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
253 ev
= dev
[0].wait_event(["WPA: Group rekeying completed"], timeout
=2)
255 raise Exception("GTK rekey timed out")
256 hwsim_utils
.test_connectivity(dev
[0], hapd
)
258 def test_ap_wpa_gtk_rekey(dev
, apdev
):
259 """WPA-PSK/TKIP AP and GTK rekey enforced by AP"""
260 ssid
= "test-wpa-psk"
261 passphrase
= 'qwertyuiop'
262 params
= hostapd
.wpa_params(ssid
=ssid
, passphrase
=passphrase
)
263 params
['wpa_group_rekey'] = '1'
264 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
265 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
266 ev
= dev
[0].wait_event(["WPA: Group rekeying completed"], timeout
=2)
268 raise Exception("GTK rekey timed out")
269 hwsim_utils
.test_connectivity(dev
[0], hapd
)
271 def test_ap_wpa2_gmk_rekey(dev
, apdev
):
272 """WPA2-PSK AP and GMK and GTK rekey enforced by AP"""
273 ssid
= "test-wpa2-psk"
274 passphrase
= 'qwertyuiop'
275 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
276 params
['wpa_group_rekey'] = '1'
277 params
['wpa_gmk_rekey'] = '2'
278 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
279 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
280 for i
in range(0, 3):
281 ev
= dev
[0].wait_event(["WPA: Group rekeying completed"], timeout
=2)
283 raise Exception("GTK rekey timed out")
284 hwsim_utils
.test_connectivity(dev
[0], hapd
)
286 def test_ap_wpa2_strict_rekey(dev
, apdev
):
287 """WPA2-PSK AP and strict GTK rekey enforced by AP"""
288 ssid
= "test-wpa2-psk"
289 passphrase
= 'qwertyuiop'
290 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
291 params
['wpa_strict_rekey'] = '1'
292 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
293 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
294 dev
[1].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
295 dev
[1].request("DISCONNECT")
296 ev
= dev
[0].wait_event(["WPA: Group rekeying completed"], timeout
=2)
298 raise Exception("GTK rekey timed out")
299 hwsim_utils
.test_connectivity(dev
[0], hapd
)
301 def test_ap_wpa2_bridge_fdb(dev
, apdev
):
302 """Bridge FDB entry removal"""
304 ssid
= "test-wpa2-psk"
305 passphrase
= "12345678"
306 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
307 params
['bridge'] = 'ap-br0'
308 hostapd
.add_ap(apdev
[0]['ifname'], params
)
309 subprocess
.call(['sudo', 'brctl', 'setfd', 'ap-br0', '0'])
310 subprocess
.call(['sudo', 'ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
311 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412",
312 bssid
=apdev
[0]['bssid'])
313 dev
[1].connect(ssid
, psk
=passphrase
, scan_freq
="2412",
314 bssid
=apdev
[0]['bssid'])
315 addr0
= dev
[0].p2p_interface_addr()
316 hwsim_utils
.test_connectivity_sta(dev
[0], dev
[1])
317 cmd
= subprocess
.Popen(['brctl', 'showmacs', 'ap-br0'],
318 stdout
=subprocess
.PIPE
)
319 macs1
= cmd
.stdout
.read()
320 dev
[0].request("DISCONNECT")
321 dev
[1].request("DISCONNECT")
323 cmd
= subprocess
.Popen(['brctl', 'showmacs', 'ap-br0'],
324 stdout
=subprocess
.PIPE
)
325 macs2
= cmd
.stdout
.read()
327 addr1
= dev
[1].p2p_interface_addr()
328 if addr0
not in macs1
or addr1
not in macs1
:
329 raise Exception("Bridge FDB entry missing")
330 if addr0
in macs2
or addr1
in macs2
:
331 raise Exception("Bridge FDB entry was not removed")
333 subprocess
.call(['sudo', 'ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
334 subprocess
.call(['sudo', 'brctl', 'delbr', 'ap-br0'])
336 def test_ap_wpa2_already_in_bridge(dev
, apdev
):
337 """hostapd behavior with interface already in bridge"""
338 ifname
= apdev
[0]['ifname']
339 br_ifname
= 'ext-ap-br0'
341 ssid
= "test-wpa2-psk"
342 passphrase
= "12345678"
343 subprocess
.call(['brctl', 'addbr', br_ifname
])
344 subprocess
.call(['brctl', 'setfd', br_ifname
, '0'])
345 subprocess
.call(['ip', 'link', 'set', 'dev', br_ifname
, 'up'])
346 subprocess
.call(['iw', ifname
, 'set', 'type', '__ap'])
347 subprocess
.call(['brctl', 'addif', br_ifname
, ifname
])
348 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
349 hapd
= hostapd
.add_ap(ifname
, params
)
350 if hapd
.get_driver_status_field('brname') != br_ifname
:
351 raise Exception("Bridge name not identified correctly")
352 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
354 subprocess
.call(['ip', 'link', 'set', 'dev', br_ifname
, 'down'])
355 subprocess
.call(['brctl', 'delif', br_ifname
, ifname
])
356 subprocess
.call(['iw', ifname
, 'set', 'type', 'station'])
357 subprocess
.call(['brctl', 'delbr', br_ifname
])
359 def test_ap_wpa2_in_different_bridge(dev
, apdev
):
360 """hostapd behavior with interface in different bridge"""
361 ifname
= apdev
[0]['ifname']
362 br_ifname
= 'ext-ap-br0'
364 ssid
= "test-wpa2-psk"
365 passphrase
= "12345678"
366 subprocess
.call(['brctl', 'addbr', br_ifname
])
367 subprocess
.call(['brctl', 'setfd', br_ifname
, '0'])
368 subprocess
.call(['ip', 'link', 'set', 'dev', br_ifname
, 'up'])
369 subprocess
.call(['iw', ifname
, 'set', 'type', '__ap'])
370 subprocess
.call(['brctl', 'addif', br_ifname
, ifname
])
372 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
373 params
['bridge'] = 'ap-br0'
374 hapd
= hostapd
.add_ap(ifname
, params
)
375 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
376 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
377 brname
= hapd
.get_driver_status_field('brname')
378 if brname
!= 'ap-br0':
379 raise Exception("Incorrect bridge: " + brname
)
380 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
381 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
382 if hapd
.get_driver_status_field("added_bridge") != "1":
383 raise Exception("Unexpected added_bridge value")
384 if hapd
.get_driver_status_field("added_if_into_bridge") != "1":
385 raise Exception("Unexpected added_if_into_bridge value")
386 dev
[0].request("DISCONNECT")
389 subprocess
.call(['ip', 'link', 'set', 'dev', br_ifname
, 'down'])
390 subprocess
.call(['brctl', 'delif', br_ifname
, ifname
],
391 stderr
=open('/dev/null', 'w'))
392 subprocess
.call(['brctl', 'delbr', br_ifname
])
394 def test_ap_wpa2_ext_add_to_bridge(dev
, apdev
):
395 """hostapd behavior with interface added to bridge externally"""
396 ifname
= apdev
[0]['ifname']
397 br_ifname
= 'ext-ap-br0'
399 ssid
= "test-wpa2-psk"
400 passphrase
= "12345678"
401 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
=passphrase
)
402 hapd
= hostapd
.add_ap(ifname
, params
)
404 subprocess
.call(['brctl', 'addbr', br_ifname
])
405 subprocess
.call(['brctl', 'setfd', br_ifname
, '0'])
406 subprocess
.call(['ip', 'link', 'set', 'dev', br_ifname
, 'up'])
407 subprocess
.call(['brctl', 'addif', br_ifname
, ifname
])
408 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412")
409 if hapd
.get_driver_status_field('brname') != br_ifname
:
410 raise Exception("Bridge name not identified correctly")
412 subprocess
.call(['ip', 'link', 'set', 'dev', br_ifname
, 'down'])
413 subprocess
.call(['brctl', 'delif', br_ifname
, ifname
])
414 subprocess
.call(['brctl', 'delbr', br_ifname
])
416 def test_ap_wpa2_psk_ext(dev
, apdev
):
417 """WPA2-PSK AP using external EAPOL I/O"""
418 bssid
= apdev
[0]['bssid']
419 ssid
= "test-wpa2-psk"
420 passphrase
= 'qwertyuiop'
421 psk
= '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
422 params
= hostapd
.wpa2_params(ssid
=ssid
)
423 params
['wpa_psk'] = psk
424 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
425 hapd
.request("SET ext_eapol_frame_io 1")
426 dev
[0].request("SET ext_eapol_frame_io 1")
427 dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412", wait_connect
=False)
428 addr
= dev
[0].p2p_interface_addr()
430 ev
= hapd
.wait_event(["EAPOL-TX", "AP-STA-CONNECTED"], timeout
=15)
432 raise Exception("Timeout on EAPOL-TX from hostapd")
433 if "AP-STA-CONNECTED" in ev
:
434 dev
[0].wait_connected(timeout
=15)
436 res
= dev
[0].request("EAPOL_RX " + bssid
+ " " + ev
.split(' ')[2])
438 raise Exception("EAPOL_RX to wpa_supplicant failed")
439 ev
= dev
[0].wait_event(["EAPOL-TX", "CTRL-EVENT-CONNECTED"], timeout
=15)
441 raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
442 if "CTRL-EVENT-CONNECTED" in ev
:
444 res
= hapd
.request("EAPOL_RX " + addr
+ " " + ev
.split(' ')[2])
446 raise Exception("EAPOL_RX to hostapd failed")
448 def parse_eapol(data
):
449 (version
, type, length
) = struct
.unpack('>BBH', data
[0:4])
451 if length
> len(payload
):
452 raise Exception("Invalid EAPOL length")
453 if length
< len(payload
):
454 payload
= payload
[0:length
]
456 eapol
['version'] = version
458 eapol
['length'] = length
459 eapol
['payload'] = payload
462 (eapol
['descr_type'],) = struct
.unpack('B', payload
[0:1])
463 payload
= payload
[1:]
464 if eapol
['descr_type'] == 2 or eapol
['descr_type'] == 254:
466 (key_info
, key_len
) = struct
.unpack('>HH', payload
[0:4])
467 eapol
['rsn_key_info'] = key_info
468 eapol
['rsn_key_len'] = key_len
469 eapol
['rsn_replay_counter'] = payload
[4:12]
470 eapol
['rsn_key_nonce'] = payload
[12:44]
471 eapol
['rsn_key_iv'] = payload
[44:60]
472 eapol
['rsn_key_rsc'] = payload
[60:68]
473 eapol
['rsn_key_id'] = payload
[68:76]
474 eapol
['rsn_key_mic'] = payload
[76:92]
475 payload
= payload
[92:]
476 (eapol
['rsn_key_data_len'],) = struct
.unpack('>H', payload
[0:2])
477 payload
= payload
[2:]
478 eapol
['rsn_key_data'] = payload
481 def build_eapol(msg
):
482 data
= struct
.pack(">BBH", msg
['version'], msg
['type'], msg
['length'])
484 data
+= struct
.pack('>BHH', msg
['descr_type'], msg
['rsn_key_info'],
486 data
+= msg
['rsn_replay_counter']
487 data
+= msg
['rsn_key_nonce']
488 data
+= msg
['rsn_key_iv']
489 data
+= msg
['rsn_key_rsc']
490 data
+= msg
['rsn_key_id']
491 data
+= msg
['rsn_key_mic']
492 data
+= struct
.pack('>H', msg
['rsn_key_data_len'])
493 data
+= msg
['rsn_key_data']
495 data
+= msg
['payload']
498 def sha1_prf(key
, label
, data
, outlen
):
502 m
= hmac
.new(key
, label
, hashlib
.sha1
)
503 m
.update(struct
.pack('B', 0))
505 m
.update(struct
.pack('B', counter
))
508 if outlen
> len(hash):
512 res
+= hash[0:outlen
]
516 def pmk_to_ptk(pmk
, addr1
, addr2
, nonce1
, nonce2
):
518 data
= binascii
.unhexlify(addr1
.replace(':','')) + binascii
.unhexlify(addr2
.replace(':',''))
520 data
= binascii
.unhexlify(addr2
.replace(':','')) + binascii
.unhexlify(addr1
.replace(':',''))
522 data
+= nonce1
+ nonce2
524 data
+= nonce2
+ nonce1
525 label
= "Pairwise key expansion"
526 ptk
= sha1_prf(pmk
, label
, data
, 48)
529 return (ptk
, kck
, kek
)
531 def eapol_key_mic(kck
, msg
):
532 msg
['rsn_key_mic'] = binascii
.unhexlify('00000000000000000000000000000000')
533 data
= build_eapol(msg
)
534 m
= hmac
.new(kck
, data
, hashlib
.sha1
)
535 msg
['rsn_key_mic'] = m
.digest()[0:16]
537 def rsn_eapol_key_set(msg
, key_info
, key_len
, nonce
, data
):
538 msg
['rsn_key_info'] = key_info
539 msg
['rsn_key_len'] = key_len
541 msg
['rsn_key_nonce'] = nonce
543 msg
['rsn_key_nonce'] = binascii
.unhexlify('0000000000000000000000000000000000000000000000000000000000000000')
545 msg
['rsn_key_data_len'] = len(data
)
546 msg
['rsn_key_data'] = data
547 msg
['length'] = 95 + len(data
)
549 msg
['rsn_key_data_len'] = 0
550 msg
['rsn_key_data'] = ''
553 def recv_eapol(hapd
):
554 ev
= hapd
.wait_event(["EAPOL-TX"], timeout
=15)
556 raise Exception("Timeout on EAPOL-TX from hostapd")
557 eapol
= binascii
.unhexlify(ev
.split(' ')[2])
558 return parse_eapol(eapol
)
560 def send_eapol(hapd
, addr
, data
):
561 res
= hapd
.request("EAPOL_RX " + addr
+ " " + binascii
.hexlify(data
))
563 raise Exception("EAPOL_RX to hostapd failed")
565 def reply_eapol(info
, hapd
, addr
, msg
, key_info
, nonce
, data
, kck
):
566 logger
.info("Send EAPOL-Key msg " + info
)
567 rsn_eapol_key_set(msg
, key_info
, 0, nonce
, data
)
568 eapol_key_mic(kck
, msg
)
569 send_eapol(hapd
, addr
, build_eapol(msg
))
571 def hapd_connected(hapd
):
572 ev
= hapd
.wait_event(["AP-STA-CONNECTED"], timeout
=15)
574 raise Exception("Timeout on AP-STA-CONNECTED from hostapd")
576 def eapol_test(apdev
, dev
, wpa2
=True):
577 bssid
= apdev
['bssid']
579 ssid
= "test-wpa2-psk"
581 ssid
= "test-wpa-psk"
582 psk
= '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
583 pmk
= binascii
.unhexlify(psk
)
585 params
= hostapd
.wpa2_params(ssid
=ssid
)
587 params
= hostapd
.wpa_params(ssid
=ssid
)
588 params
['wpa_psk'] = psk
589 hapd
= hostapd
.add_ap(apdev
['ifname'], params
)
590 hapd
.request("SET ext_eapol_frame_io 1")
591 dev
.request("SET ext_eapol_frame_io 1")
592 dev
.connect(ssid
, psk
="not used", scan_freq
="2412", wait_connect
=False)
593 addr
= dev
.p2p_interface_addr()
595 rsne
= binascii
.unhexlify('30140100000fac040100000fac040100000fac020000')
597 rsne
= binascii
.unhexlify('dd160050f20101000050f20201000050f20201000050f202')
598 snonce
= binascii
.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
599 return (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
)
601 def test_ap_wpa2_psk_ext_eapol(dev
, apdev
):
602 """WPA2-PSK AP using external EAPOL supplicant"""
603 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
) = eapol_test(apdev
[0], dev
[0])
605 msg
= recv_eapol(hapd
)
606 anonce
= msg
['rsn_key_nonce']
607 logger
.info("Replay same data back")
608 send_eapol(hapd
, addr
, build_eapol(msg
))
610 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
612 logger
.info("Truncated Key Data in EAPOL-Key msg 2/4")
613 rsn_eapol_key_set(msg
, 0x0101, 0, snonce
, rsne
)
614 msg
['length'] = 95 + 22 - 1
615 send_eapol(hapd
, addr
, build_eapol(msg
))
617 reply_eapol("2/4", hapd
, addr
, msg
, 0x010a, snonce
, rsne
, kck
)
619 msg
= recv_eapol(hapd
)
620 if anonce
!= msg
['rsn_key_nonce']:
621 raise Exception("ANonce changed")
622 logger
.info("Replay same data back")
623 send_eapol(hapd
, addr
, build_eapol(msg
))
625 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
628 def test_ap_wpa2_psk_ext_eapol_retry1(dev
, apdev
):
629 """WPA2 4-way handshake with EAPOL-Key 1/4 retransmitted"""
630 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
) = eapol_test(apdev
[0], dev
[0])
632 msg1
= recv_eapol(hapd
)
633 anonce
= msg1
['rsn_key_nonce']
635 msg2
= recv_eapol(hapd
)
636 if anonce
!= msg2
['rsn_key_nonce']:
637 raise Exception("ANonce changed")
639 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
641 logger
.info("Send EAPOL-Key msg 2/4")
643 rsn_eapol_key_set(msg
, 0x010a, 0, snonce
, rsne
)
644 eapol_key_mic(kck
, msg
)
645 send_eapol(hapd
, addr
, build_eapol(msg
))
647 msg
= recv_eapol(hapd
)
648 if anonce
!= msg
['rsn_key_nonce']:
649 raise Exception("ANonce changed")
651 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
654 def test_ap_wpa2_psk_ext_eapol_retry1b(dev
, apdev
):
655 """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted"""
656 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
) = eapol_test(apdev
[0], dev
[0])
658 msg1
= recv_eapol(hapd
)
659 anonce
= msg1
['rsn_key_nonce']
660 msg2
= recv_eapol(hapd
)
661 if anonce
!= msg2
['rsn_key_nonce']:
662 raise Exception("ANonce changed")
664 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
665 reply_eapol("2/4 (a)", hapd
, addr
, msg1
, 0x010a, snonce
, rsne
, kck
)
666 reply_eapol("2/4 (b)", hapd
, addr
, msg2
, 0x010a, snonce
, rsne
, kck
)
668 msg
= recv_eapol(hapd
)
669 if anonce
!= msg
['rsn_key_nonce']:
670 raise Exception("ANonce changed")
672 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
675 def test_ap_wpa2_psk_ext_eapol_retry1c(dev
, apdev
):
676 """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing"""
677 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
) = eapol_test(apdev
[0], dev
[0])
679 msg1
= recv_eapol(hapd
)
680 anonce
= msg1
['rsn_key_nonce']
682 msg2
= recv_eapol(hapd
)
683 if anonce
!= msg2
['rsn_key_nonce']:
684 raise Exception("ANonce changed")
685 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
686 reply_eapol("2/4 (a)", hapd
, addr
, msg1
, 0x010a, snonce
, rsne
, kck
)
688 snonce2
= binascii
.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
689 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce2
, anonce
)
690 reply_eapol("2/4 (b)", hapd
, addr
, msg2
, 0x010a, snonce2
, rsne
, kck
)
692 msg
= recv_eapol(hapd
)
693 if anonce
!= msg
['rsn_key_nonce']:
694 raise Exception("ANonce changed")
695 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
698 def test_ap_wpa2_psk_ext_eapol_retry1d(dev
, apdev
):
699 """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing and older used"""
700 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
) = eapol_test(apdev
[0], dev
[0])
702 msg1
= recv_eapol(hapd
)
703 anonce
= msg1
['rsn_key_nonce']
704 msg2
= recv_eapol(hapd
)
705 if anonce
!= msg2
['rsn_key_nonce']:
706 raise Exception("ANonce changed")
708 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
709 reply_eapol("2/4 (a)", hapd
, addr
, msg1
, 0x010a, snonce
, rsne
, kck
)
711 snonce2
= binascii
.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
712 (ptk2
, kck2
, kek2
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce2
, anonce
)
714 reply_eapol("2/4 (b)", hapd
, addr
, msg2
, 0x010a, snonce2
, rsne
, kck2
)
715 msg
= recv_eapol(hapd
)
716 if anonce
!= msg
['rsn_key_nonce']:
717 raise Exception("ANonce changed")
718 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
721 def test_ap_wpa2_psk_ext_eapol_type_diff(dev
, apdev
):
722 """WPA2 4-way handshake using external EAPOL supplicant"""
723 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
) = eapol_test(apdev
[0], dev
[0])
725 msg
= recv_eapol(hapd
)
726 anonce
= msg
['rsn_key_nonce']
728 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
730 # Incorrect descriptor type (frame dropped)
731 msg
['descr_type'] = 253
732 rsn_eapol_key_set(msg
, 0x010a, 0, snonce
, rsne
)
733 eapol_key_mic(kck
, msg
)
734 send_eapol(hapd
, addr
, build_eapol(msg
))
736 # Incorrect descriptor type, but with a workaround (frame processed)
737 msg
['descr_type'] = 254
738 rsn_eapol_key_set(msg
, 0x010a, 0, snonce
, rsne
)
739 eapol_key_mic(kck
, msg
)
740 send_eapol(hapd
, addr
, build_eapol(msg
))
742 msg
= recv_eapol(hapd
)
743 if anonce
!= msg
['rsn_key_nonce']:
744 raise Exception("ANonce changed")
745 logger
.info("Replay same data back")
746 send_eapol(hapd
, addr
, build_eapol(msg
))
748 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
751 def test_ap_wpa_psk_ext_eapol(dev
, apdev
):
752 """WPA2-PSK AP using external EAPOL supplicant"""
753 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,wpae
) = eapol_test(apdev
[0], dev
[0],
756 msg
= recv_eapol(hapd
)
757 anonce
= msg
['rsn_key_nonce']
758 logger
.info("Replay same data back")
759 send_eapol(hapd
, addr
, build_eapol(msg
))
760 logger
.info("Too short data")
761 send_eapol(hapd
, addr
, build_eapol(msg
)[0:98])
763 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
764 msg
['descr_type'] = 2
765 reply_eapol("2/4(invalid type)", hapd
, addr
, msg
, 0x010a, snonce
, wpae
, kck
)
766 msg
['descr_type'] = 254
767 reply_eapol("2/4", hapd
, addr
, msg
, 0x010a, snonce
, wpae
, kck
)
769 msg
= recv_eapol(hapd
)
770 if anonce
!= msg
['rsn_key_nonce']:
771 raise Exception("ANonce changed")
772 logger
.info("Replay same data back")
773 send_eapol(hapd
, addr
, build_eapol(msg
))
775 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
778 def test_ap_wpa2_psk_ext_eapol_key_info(dev
, apdev
):
779 """WPA2-PSK 4-way handshake with strange key info values"""
780 (bssid
,ssid
,hapd
,snonce
,pmk
,addr
,rsne
) = eapol_test(apdev
[0], dev
[0])
782 msg
= recv_eapol(hapd
)
783 anonce
= msg
['rsn_key_nonce']
785 (ptk
, kck
, kek
) = pmk_to_ptk(pmk
, addr
, bssid
, snonce
, anonce
)
786 rsn_eapol_key_set(msg
, 0x0000, 0, snonce
, rsne
)
787 send_eapol(hapd
, addr
, build_eapol(msg
))
788 rsn_eapol_key_set(msg
, 0xffff, 0, snonce
, rsne
)
789 send_eapol(hapd
, addr
, build_eapol(msg
))
791 rsn_eapol_key_set(msg
, 0x2802, 0, snonce
, rsne
)
792 send_eapol(hapd
, addr
, build_eapol(msg
))
794 rsn_eapol_key_set(msg
, 0x2002, 0, snonce
, rsne
)
795 send_eapol(hapd
, addr
, build_eapol(msg
))
797 rsn_eapol_key_set(msg
, 0x0902, 0, snonce
, rsne
)
798 send_eapol(hapd
, addr
, build_eapol(msg
))
800 rsn_eapol_key_set(msg
, 0x0902, 0, snonce
, rsne
)
801 tmp_kck
= binascii
.unhexlify('00000000000000000000000000000000')
802 eapol_key_mic(tmp_kck
, msg
)
803 send_eapol(hapd
, addr
, build_eapol(msg
))
805 reply_eapol("2/4", hapd
, addr
, msg
, 0x010a, snonce
, rsne
, kck
)
807 msg
= recv_eapol(hapd
)
808 if anonce
!= msg
['rsn_key_nonce']:
809 raise Exception("ANonce changed")
811 # Request (valic MIC)
812 rsn_eapol_key_set(msg
, 0x0902, 0, snonce
, rsne
)
813 eapol_key_mic(kck
, msg
)
814 send_eapol(hapd
, addr
, build_eapol(msg
))
815 # Request (valid MIC, replayed counter)
816 rsn_eapol_key_set(msg
, 0x0902, 0, snonce
, rsne
)
817 eapol_key_mic(kck
, msg
)
818 send_eapol(hapd
, addr
, build_eapol(msg
))
820 reply_eapol("4/4", hapd
, addr
, msg
, 0x030a, None, None, kck
)
823 def find_wpas_process(dev
):
825 cmd
= subprocess
.Popen(['ps', 'ax'], stdout
=subprocess
.PIPE
)
826 (data
,err
) = cmd
.communicate()
827 for l
in data
.splitlines():
828 if "wpa_supplicant" not in l
:
830 if "-i" + ifname
not in l
:
832 return int(l
.strip().split(' ')[0])
833 raise Exception("Could not find wpa_supplicant process")
835 def read_process_memory(pid
, key
=None):
837 with
open('/proc/%d/maps' % pid
, 'r') as maps
, \
838 open('/proc/%d/mem' % pid
, 'r') as mem
:
839 for l
in maps
.readlines():
840 m
= re
.match(r
'([0-9a-f]+)-([0-9a-f]+) ([-r][-w][-x][-p])', l
)
843 start
= int(m
.group(1), 16)
844 end
= int(m
.group(2), 16)
846 if start
> 0xffffffffffff:
850 if not perm
.startswith('rw'):
853 data
= mem
.read(end
- start
)
855 if key
and key
in data
:
856 logger
.info("Key found in " + l
)
859 def verify_not_present(buf
, key
, fname
, keyname
):
864 prefix
= 2048 if pos
> 2048 else pos
865 with
open(fname
+ keyname
, 'w') as f
:
866 f
.write(buf
[pos
- prefix
:pos
+ 2048])
867 raise Exception(keyname
+ " found after disassociation")
869 def get_key_locations(buf
, key
, keyname
):
873 pos
= buf
.find(key
, pos
)
876 logger
.info("Found %s at %d" % (keyname
, pos
))
881 def test_wpa2_psk_key_lifetime_in_memory(dev
, apdev
, params
):
882 """WPA2-PSK and PSK/PTK lifetime in memory"""
883 ssid
= "test-wpa2-psk"
884 passphrase
= 'qwertyuiop'
885 psk
= '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
886 pmk
= binascii
.unhexlify(psk
)
887 p
= hostapd
.wpa2_params(ssid
=ssid
)
889 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], p
)
891 pid
= find_wpas_process(dev
[0])
893 id = dev
[0].connect(ssid
, raw_psk
=psk
, scan_freq
="2412",
894 only_add_network
=True)
896 logger
.info("Checking keys in memory after network profile configuration")
897 buf
= read_process_memory(pid
, pmk
)
898 get_key_locations(buf
, pmk
, "PMK")
900 dev
[0].request("REMOVE_NETWORK all")
901 logger
.info("Checking keys in memory after network profile removal")
902 buf
= read_process_memory(pid
, pmk
)
903 get_key_locations(buf
, pmk
, "PMK")
905 id = dev
[0].connect(ssid
, psk
=passphrase
, scan_freq
="2412",
906 only_add_network
=True)
908 logger
.info("Checking keys in memory before connection")
909 buf
= read_process_memory(pid
, pmk
)
910 get_key_locations(buf
, pmk
, "PMK")
912 dev
[0].connect_network(id, timeout
=20)
915 buf
= read_process_memory(pid
, pmk
)
917 dev
[0].request("DISCONNECT")
918 dev
[0].wait_disconnected()
923 with
open(os
.path
.join(params
['logdir'], 'log0'), 'r') as f
:
924 for l
in f
.readlines():
925 if "WPA: PTK - hexdump" in l
:
926 val
= l
.strip().split(':')[3].replace(' ', '')
927 ptk
= binascii
.unhexlify(val
)
928 if "WPA: Group Key - hexdump" in l
:
929 val
= l
.strip().split(':')[3].replace(' ', '')
930 gtk
= binascii
.unhexlify(val
)
931 if not pmk
or not ptk
or not gtk
:
932 raise Exception("Could not find keys from debug log")
934 raise Exception("Unexpected GTK length")
940 logger
.info("Checking keys in memory while associated")
941 get_key_locations(buf
, pmk
, "PMK")
943 print("PMK not found while associated")
946 raise Exception("KCK not found while associated")
948 raise Exception("KEK not found while associated")
950 raise Exception("TK found from memory")
952 raise Exception("GTK found from memory")
954 logger
.info("Checking keys in memory after disassociation")
955 buf
= read_process_memory(pid
, pmk
)
956 get_key_locations(buf
, pmk
, "PMK")
958 # Note: PMK/PSK is still present in network configuration
960 fname
= os
.path
.join(params
['logdir'],
961 'wpa2_psk_key_lifetime_in_memory.memctx-')
962 verify_not_present(buf
, kck
, fname
, "KCK")
963 verify_not_present(buf
, kek
, fname
, "KEK")
964 verify_not_present(buf
, tk
, fname
, "TK")
965 verify_not_present(buf
, gtk
, fname
, "GTK")
967 dev
[0].request("REMOVE_NETWORK all")
969 logger
.info("Checking keys in memory after network profile removal")
970 buf
= read_process_memory(pid
, pmk
)
971 get_key_locations(buf
, pmk
, "PMK")
973 verify_not_present(buf
, pmk
, fname
, "PMK")
974 verify_not_present(buf
, kck
, fname
, "KCK")
975 verify_not_present(buf
, kek
, fname
, "KEK")
976 verify_not_present(buf
, tk
, fname
, "TK")
977 verify_not_present(buf
, gtk
, fname
, "GTK")