tests: Add more memory details on key-lifetime-in-memory
[mech_eap.git] / tests / hwsim / test_ap_psk.py
1 # WPA2-Personal tests
2 # Copyright (c) 2014, 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 from Crypto.Cipher import AES
9 import hashlib
10 import hmac
11 import logging
12 logger = logging.getLogger()
13 import os
14 import re
15 import struct
16 import subprocess
17 import time
18
19 import hostapd
20 from utils import HwsimSkip, fail_test, skip_with_fips
21 import hwsim_utils
22 from wpasupplicant import WpaSupplicant
23
24 def check_mib(dev, vals):
25     mib = dev.get_mib()
26     for v in vals:
27         if mib[v[0]] != v[1]:
28             raise Exception("Unexpected {} = {} (expected {})".format(v[0], mib[v[0]], v[1]))
29
30 def test_ap_wpa2_psk(dev, apdev):
31     """WPA2-PSK AP with PSK instead of passphrase"""
32     ssid = "test-wpa2-psk"
33     passphrase = 'qwertyuiop'
34     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
35     params = hostapd.wpa2_params(ssid=ssid)
36     params['wpa_psk'] = psk
37     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
38     key_mgmt = hapd.get_config()['key_mgmt']
39     if key_mgmt.split(' ')[0] != "WPA-PSK":
40         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
41     dev[0].connect(ssid, raw_psk=psk, scan_freq="2412")
42     dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
43
44     sig = dev[0].request("SIGNAL_POLL").splitlines()
45     pkt = dev[0].request("PKTCNT_POLL").splitlines()
46     if "FREQUENCY=2412" not in sig:
47         raise Exception("Unexpected SIGNAL_POLL value: " + str(sig))
48     if "TXBAD=0" not in pkt:
49         raise Exception("Unexpected TXBAD value: " + str(pkt))
50
51 def test_ap_wpa2_psk_file(dev, apdev):
52     """WPA2-PSK AP with PSK from a file"""
53     ssid = "test-wpa2-psk"
54     passphrase = 'qwertyuiop'
55     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
56     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
57     params['wpa_psk_file'] = 'hostapd.wpa_psk'
58     hostapd.add_ap(apdev[0]['ifname'], params)
59     dev[1].connect(ssid, psk="very secret", scan_freq="2412", wait_connect=False)
60     dev[2].connect(ssid, raw_psk=psk, scan_freq="2412")
61     dev[2].request("REMOVE_NETWORK all")
62     dev[0].connect(ssid, psk="very secret", scan_freq="2412")
63     dev[0].request("REMOVE_NETWORK all")
64     dev[2].connect(ssid, psk="another passphrase for all STAs", scan_freq="2412")
65     dev[0].connect(ssid, psk="another passphrase for all STAs", scan_freq="2412")
66     ev = dev[1].wait_event(["WPA: 4-Way Handshake failed"], timeout=10)
67     if ev is None:
68         raise Exception("Timed out while waiting for failure report")
69     dev[1].request("REMOVE_NETWORK all")
70
71 def test_ap_wpa2_psk_mem(dev, apdev):
72     """WPA2-PSK AP with passphrase only in memory"""
73     try:
74         _test_ap_wpa2_psk_mem(dev, apdev)
75     finally:
76         dev[0].request("SCAN_INTERVAL 5")
77         dev[1].request("SCAN_INTERVAL 5")
78
79 def _test_ap_wpa2_psk_mem(dev, apdev):
80     ssid = "test-wpa2-psk"
81     passphrase = 'qwertyuiop'
82     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
83     params = hostapd.wpa2_params(ssid=ssid)
84     params['wpa_psk'] = psk
85     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
86
87     dev[0].connect(ssid, mem_only_psk="1", scan_freq="2412", wait_connect=False)
88     dev[0].request("SCAN_INTERVAL 1")
89     ev = dev[0].wait_event(["CTRL-REQ-PSK_PASSPHRASE"], timeout=10)
90     if ev is None:
91         raise Exception("Request for PSK/passphrase timed out")
92     id = ev.split(':')[0].split('-')[-1]
93     dev[0].request("CTRL-RSP-PSK_PASSPHRASE-" + id + ':"' + passphrase + '"')
94     dev[0].wait_connected(timeout=10)
95
96     dev[1].connect(ssid, mem_only_psk="1", scan_freq="2412", wait_connect=False)
97     dev[1].request("SCAN_INTERVAL 1")
98     ev = dev[1].wait_event(["CTRL-REQ-PSK_PASSPHRASE"], timeout=10)
99     if ev is None:
100         raise Exception("Request for PSK/passphrase timed out(2)")
101     id = ev.split(':')[0].split('-')[-1]
102     dev[1].request("CTRL-RSP-PSK_PASSPHRASE-" + id + ':' + psk)
103     dev[1].wait_connected(timeout=10)
104
105 def test_ap_wpa2_ptk_rekey(dev, apdev):
106     """WPA2-PSK AP and PTK rekey enforced by station"""
107     ssid = "test-wpa2-psk"
108     passphrase = 'qwertyuiop'
109     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
110     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
111     dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
112     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
113     if ev is None:
114         raise Exception("PTK rekey timed out")
115     hwsim_utils.test_connectivity(dev[0], hapd)
116
117 def test_ap_wpa2_ptk_rekey_ap(dev, apdev):
118     """WPA2-PSK AP and PTK rekey enforced by AP"""
119     ssid = "test-wpa2-psk"
120     passphrase = 'qwertyuiop'
121     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
122     params['wpa_ptk_rekey'] = '2'
123     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
124     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
125     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
126     if ev is None:
127         raise Exception("PTK rekey timed out")
128     hwsim_utils.test_connectivity(dev[0], hapd)
129
130 def test_ap_wpa2_sha256_ptk_rekey(dev, apdev):
131     """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by station"""
132     ssid = "test-wpa2-psk"
133     passphrase = 'qwertyuiop'
134     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
135     params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
136     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
137     dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
138                    wpa_ptk_rekey="1", scan_freq="2412")
139     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
140     if ev is None:
141         raise Exception("PTK rekey timed out")
142     hwsim_utils.test_connectivity(dev[0], hapd)
143     check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
144                         ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
145
146 def test_ap_wpa2_sha256_ptk_rekey_ap(dev, apdev):
147     """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by AP"""
148     ssid = "test-wpa2-psk"
149     passphrase = 'qwertyuiop'
150     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
151     params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
152     params['wpa_ptk_rekey'] = '2'
153     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
154     dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
155                    scan_freq="2412")
156     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
157     if ev is None:
158         raise Exception("PTK rekey timed out")
159     hwsim_utils.test_connectivity(dev[0], hapd)
160     check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
161                         ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
162
163 def test_ap_wpa_ptk_rekey(dev, apdev):
164     """WPA-PSK/TKIP AP and PTK rekey enforced by station"""
165     skip_with_fips(dev[0])
166     ssid = "test-wpa-psk"
167     passphrase = 'qwertyuiop'
168     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
169     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
170     dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
171     if "[WPA-PSK-TKIP]" not in dev[0].request("SCAN_RESULTS"):
172         raise Exception("Scan results missing WPA element info")
173     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
174     if ev is None:
175         raise Exception("PTK rekey timed out")
176     hwsim_utils.test_connectivity(dev[0], hapd)
177
178 def test_ap_wpa_ptk_rekey_ap(dev, apdev):
179     """WPA-PSK/TKIP AP and PTK rekey enforced by AP"""
180     skip_with_fips(dev[0])
181     ssid = "test-wpa-psk"
182     passphrase = 'qwertyuiop'
183     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
184     params['wpa_ptk_rekey'] = '2'
185     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
186     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
187     ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=10)
188     if ev is None:
189         raise Exception("PTK rekey timed out")
190     hwsim_utils.test_connectivity(dev[0], hapd)
191
192 def test_ap_wpa_ccmp(dev, apdev):
193     """WPA-PSK/CCMP"""
194     ssid = "test-wpa-psk"
195     passphrase = 'qwertyuiop'
196     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
197     params['wpa_pairwise'] = "CCMP"
198     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
199     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
200     hwsim_utils.test_connectivity(dev[0], hapd)
201     check_mib(dev[0], [ ("dot11RSNAConfigGroupCipherSize", "128"),
202                         ("dot11RSNAGroupCipherRequested", "00-50-f2-4"),
203                         ("dot11RSNAPairwiseCipherRequested", "00-50-f2-4"),
204                         ("dot11RSNAAuthenticationSuiteRequested", "00-50-f2-2"),
205                         ("dot11RSNAGroupCipherSelected", "00-50-f2-4"),
206                         ("dot11RSNAPairwiseCipherSelected", "00-50-f2-4"),
207                         ("dot11RSNAAuthenticationSuiteSelected", "00-50-f2-2"),
208                         ("dot1xSuppSuppControlledPortStatus", "Authorized") ])
209
210 def test_ap_wpa2_psk_file(dev, apdev):
211     """WPA2-PSK AP with various PSK file error and success cases"""
212     addr0 = dev[0].own_addr()
213     addr1 = dev[1].own_addr()
214     addr2 = dev[2].own_addr()
215     ssid = "psk"
216     pskfile = "/tmp/ap_wpa2_psk_file_errors.psk_file"
217     try:
218         os.remove(pskfile)
219     except:
220         pass
221
222     params = { "ssid": ssid, "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
223                "rsn_pairwise": "CCMP", "wpa_psk_file": pskfile }
224
225     try:
226         # missing PSK file
227         hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
228         if "FAIL" not in hapd.request("ENABLE"):
229             raise Exception("Unexpected ENABLE success")
230         hapd.request("DISABLE")
231
232         # invalid MAC address
233         with open(pskfile, "w") as f:
234             f.write("\n")
235             f.write("foo\n")
236         if "FAIL" not in hapd.request("ENABLE"):
237             raise Exception("Unexpected ENABLE success")
238         hapd.request("DISABLE")
239
240         # no PSK on line
241         with open(pskfile, "w") as f:
242             f.write("00:11:22:33:44:55\n")
243         if "FAIL" not in hapd.request("ENABLE"):
244             raise Exception("Unexpected ENABLE success")
245         hapd.request("DISABLE")
246
247         # invalid PSK
248         with open(pskfile, "w") as f:
249             f.write("00:11:22:33:44:55 1234567\n")
250         if "FAIL" not in hapd.request("ENABLE"):
251             raise Exception("Unexpected ENABLE success")
252         hapd.request("DISABLE")
253
254         # valid PSK file
255         with open(pskfile, "w") as f:
256             f.write("00:11:22:33:44:55 12345678\n")
257             f.write(addr0 + " 123456789\n")
258             f.write(addr1 + " 123456789a\n")
259             f.write(addr2 + " 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n")
260         if "FAIL" in hapd.request("ENABLE"):
261             raise Exception("Unexpected ENABLE failure")
262
263         dev[0].connect(ssid, psk="123456789", scan_freq="2412")
264         dev[1].connect(ssid, psk="123456789a", scan_freq="2412")
265         dev[2].connect(ssid, raw_psk="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", scan_freq="2412")
266
267     finally:
268         try:
269             os.remove(pskfile)
270         except:
271             pass
272
273 def test_ap_wpa2_psk_wildcard_ssid(dev, apdev):
274     """WPA2-PSK AP and wildcard SSID configuration"""
275     ssid = "test-wpa2-psk"
276     passphrase = 'qwertyuiop'
277     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
278     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
279     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
280     dev[0].connect("", bssid=apdev[0]['bssid'], psk=passphrase,
281                    scan_freq="2412")
282     dev[1].connect("", bssid=apdev[0]['bssid'], raw_psk=psk, scan_freq="2412")
283
284 def test_ap_wpa2_gtk_rekey(dev, apdev):
285     """WPA2-PSK AP and GTK rekey enforced by AP"""
286     ssid = "test-wpa2-psk"
287     passphrase = 'qwertyuiop'
288     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
289     params['wpa_group_rekey'] = '1'
290     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
291     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
292     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
293     if ev is None:
294         raise Exception("GTK rekey timed out")
295     hwsim_utils.test_connectivity(dev[0], hapd)
296
297 def test_ap_wpa_gtk_rekey(dev, apdev):
298     """WPA-PSK/TKIP AP and GTK rekey enforced by AP"""
299     skip_with_fips(dev[0])
300     ssid = "test-wpa-psk"
301     passphrase = 'qwertyuiop'
302     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
303     params['wpa_group_rekey'] = '1'
304     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
305     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
306     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
307     if ev is None:
308         raise Exception("GTK rekey timed out")
309     hwsim_utils.test_connectivity(dev[0], hapd)
310
311 def test_ap_wpa2_gmk_rekey(dev, apdev):
312     """WPA2-PSK AP and GMK and GTK rekey enforced by AP"""
313     ssid = "test-wpa2-psk"
314     passphrase = 'qwertyuiop'
315     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
316     params['wpa_group_rekey'] = '1'
317     params['wpa_gmk_rekey'] = '2'
318     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
319     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
320     for i in range(0, 3):
321         ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
322         if ev is None:
323             raise Exception("GTK rekey timed out")
324     hwsim_utils.test_connectivity(dev[0], hapd)
325
326 def test_ap_wpa2_strict_rekey(dev, apdev):
327     """WPA2-PSK AP and strict GTK rekey enforced by AP"""
328     ssid = "test-wpa2-psk"
329     passphrase = 'qwertyuiop'
330     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
331     params['wpa_strict_rekey'] = '1'
332     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
333     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
334     dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
335     dev[1].request("DISCONNECT")
336     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
337     if ev is None:
338         raise Exception("GTK rekey timed out")
339     hwsim_utils.test_connectivity(dev[0], hapd)
340
341 def test_ap_wpa2_bridge_fdb(dev, apdev):
342     """Bridge FDB entry removal"""
343     try:
344         ssid = "test-wpa2-psk"
345         passphrase = "12345678"
346         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
347         params['bridge'] = 'ap-br0'
348         hostapd.add_ap(apdev[0]['ifname'], params)
349         subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
350         subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
351         dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
352                        bssid=apdev[0]['bssid'])
353         dev[1].connect(ssid, psk=passphrase, scan_freq="2412",
354                        bssid=apdev[0]['bssid'])
355         addr0 = dev[0].p2p_interface_addr()
356         hwsim_utils.test_connectivity_sta(dev[0], dev[1])
357         cmd = subprocess.Popen(['brctl', 'showmacs', 'ap-br0'],
358                                stdout=subprocess.PIPE)
359         macs1 = cmd.stdout.read()
360         cmd = subprocess.call(['brctl', 'setageing', 'ap-br0', '1'])
361         dev[0].request("DISCONNECT")
362         dev[1].request("DISCONNECT")
363         time.sleep(1)
364         cmd = subprocess.Popen(['brctl', 'showmacs', 'ap-br0'],
365                                stdout=subprocess.PIPE)
366         macs2 = cmd.stdout.read()
367
368         addr1 = dev[1].p2p_interface_addr()
369         if addr0 not in macs1 or addr1 not in macs1:
370             raise Exception("Bridge FDB entry missing")
371         if addr0 in macs2 or addr1 in macs2:
372             raise Exception("Bridge FDB entry was not removed")
373     finally:
374         subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
375         subprocess.call(['brctl', 'delbr', 'ap-br0'])
376
377 def test_ap_wpa2_already_in_bridge(dev, apdev):
378     """hostapd behavior with interface already in bridge"""
379     ifname = apdev[0]['ifname']
380     br_ifname = 'ext-ap-br0'
381     try:
382         ssid = "test-wpa2-psk"
383         passphrase = "12345678"
384         subprocess.call(['brctl', 'addbr', br_ifname])
385         subprocess.call(['brctl', 'setfd', br_ifname, '0'])
386         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
387         subprocess.call(['iw', ifname, 'set', 'type', '__ap'])
388         subprocess.call(['brctl', 'addif', br_ifname, ifname])
389         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
390         hapd = hostapd.add_ap(ifname, params)
391         if hapd.get_driver_status_field('brname') != br_ifname:
392             raise Exception("Bridge name not identified correctly")
393         dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
394     finally:
395         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
396         subprocess.call(['brctl', 'delif', br_ifname, ifname])
397         subprocess.call(['iw', ifname, 'set', 'type', 'station'])
398         subprocess.call(['brctl', 'delbr', br_ifname])
399
400 def test_ap_wpa2_in_different_bridge(dev, apdev):
401     """hostapd behavior with interface in different bridge"""
402     ifname = apdev[0]['ifname']
403     br_ifname = 'ext-ap-br0'
404     try:
405         ssid = "test-wpa2-psk"
406         passphrase = "12345678"
407         subprocess.call(['brctl', 'addbr', br_ifname])
408         subprocess.call(['brctl', 'setfd', br_ifname, '0'])
409         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
410         subprocess.call(['iw', ifname, 'set', 'type', '__ap'])
411         subprocess.call(['brctl', 'addif', br_ifname, ifname])
412         time.sleep(0.5)
413         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
414         params['bridge'] = 'ap-br0'
415         hapd = hostapd.add_ap(ifname, params)
416         subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
417         subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
418         brname = hapd.get_driver_status_field('brname')
419         if brname != 'ap-br0':
420             raise Exception("Incorrect bridge: " + brname)
421         dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
422         hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
423         if hapd.get_driver_status_field("added_bridge") != "1":
424             raise Exception("Unexpected added_bridge value")
425         if hapd.get_driver_status_field("added_if_into_bridge") != "1":
426             raise Exception("Unexpected added_if_into_bridge value")
427         dev[0].request("DISCONNECT")
428         hapd.disable()
429     finally:
430         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
431         subprocess.call(['brctl', 'delif', br_ifname, ifname],
432                         stderr=open('/dev/null', 'w'))
433         subprocess.call(['brctl', 'delbr', br_ifname])
434
435 def test_ap_wpa2_ext_add_to_bridge(dev, apdev):
436     """hostapd behavior with interface added to bridge externally"""
437     ifname = apdev[0]['ifname']
438     br_ifname = 'ext-ap-br0'
439     try:
440         ssid = "test-wpa2-psk"
441         passphrase = "12345678"
442         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
443         hapd = hostapd.add_ap(ifname, params)
444
445         subprocess.call(['brctl', 'addbr', br_ifname])
446         subprocess.call(['brctl', 'setfd', br_ifname, '0'])
447         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
448         subprocess.call(['brctl', 'addif', br_ifname, ifname])
449         dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
450         if hapd.get_driver_status_field('brname') != br_ifname:
451             raise Exception("Bridge name not identified correctly")
452     finally:
453         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
454         subprocess.call(['brctl', 'delif', br_ifname, ifname])
455         subprocess.call(['brctl', 'delbr', br_ifname])
456
457 def test_ap_wpa2_psk_ext(dev, apdev):
458     """WPA2-PSK AP using external EAPOL I/O"""
459     bssid = apdev[0]['bssid']
460     ssid = "test-wpa2-psk"
461     passphrase = 'qwertyuiop'
462     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
463     params = hostapd.wpa2_params(ssid=ssid)
464     params['wpa_psk'] = psk
465     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
466     hapd.request("SET ext_eapol_frame_io 1")
467     dev[0].request("SET ext_eapol_frame_io 1")
468     dev[0].connect(ssid, psk=passphrase, scan_freq="2412", wait_connect=False)
469     addr = dev[0].p2p_interface_addr()
470     while True:
471         ev = hapd.wait_event(["EAPOL-TX", "AP-STA-CONNECTED"], timeout=15)
472         if ev is None:
473             raise Exception("Timeout on EAPOL-TX from hostapd")
474         if "AP-STA-CONNECTED" in ev:
475             dev[0].wait_connected(timeout=15)
476             break
477         res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
478         if "OK" not in res:
479             raise Exception("EAPOL_RX to wpa_supplicant failed")
480         ev = dev[0].wait_event(["EAPOL-TX", "CTRL-EVENT-CONNECTED"], timeout=15)
481         if ev is None:
482             raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
483         if "CTRL-EVENT-CONNECTED" in ev:
484             break
485         res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
486         if "OK" not in res:
487             raise Exception("EAPOL_RX to hostapd failed")
488
489 def test_ap_wpa2_psk_ext_retry_msg_3(dev, apdev):
490     """WPA2-PSK AP using external EAPOL I/O and retry for EAPOL-Key msg 3/4"""
491     bssid = apdev[0]['bssid']
492     ssid = "test-wpa2-psk"
493     passphrase = 'qwertyuiop'
494     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
495     params = hostapd.wpa2_params(ssid=ssid)
496     params['wpa_psk'] = psk
497     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
498     hapd.request("SET ext_eapol_frame_io 1")
499     dev[0].request("SET ext_eapol_frame_io 1")
500     dev[0].connect(ssid, psk=passphrase, scan_freq="2412", wait_connect=False)
501     addr = dev[0].p2p_interface_addr()
502
503     # EAPOL-Key msg 1/4
504     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
505     if ev is None:
506         raise Exception("Timeout on EAPOL-TX from hostapd")
507     res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
508     if "OK" not in res:
509         raise Exception("EAPOL_RX to wpa_supplicant failed")
510
511     # EAPOL-Key msg 2/4
512     ev = dev[0].wait_event(["EAPOL-TX"], timeout=15)
513     if ev is None:
514         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
515     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
516     if "OK" not in res:
517         raise Exception("EAPOL_RX to hostapd failed")
518
519     # EAPOL-Key msg 3/4
520     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
521     if ev is None:
522         raise Exception("Timeout on EAPOL-TX from hostapd")
523     res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
524     if "OK" not in res:
525         raise Exception("EAPOL_RX to wpa_supplicant failed")
526
527     # EAPOL-Key msg 4/4
528     ev = dev[0].wait_event(["EAPOL-TX"], timeout=15)
529     if ev is None:
530         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
531     # Do not send to the AP
532     dev[0].wait_connected(timeout=15)
533
534     # EAPOL-Key msg 3/4 (retry)
535     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
536     if ev is None:
537         raise Exception("Timeout on EAPOL-TX from hostapd")
538     res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
539     if "OK" not in res:
540         raise Exception("EAPOL_RX to wpa_supplicant failed")
541
542     # EAPOL-Key msg 4/4
543     ev = dev[0].wait_event(["EAPOL-TX"], timeout=15)
544     if ev is None:
545         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
546     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
547     if "OK" not in res:
548         raise Exception("EAPOL_RX to hostapd failed")
549
550     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=15)
551     if ev is None:
552         raise Exception("Timeout on AP-STA-CONNECTED from hostapd")
553
554     hwsim_utils.test_connectivity(dev[0], hapd)
555
556 def parse_eapol(data):
557     (version, type, length) = struct.unpack('>BBH', data[0:4])
558     payload = data[4:]
559     if length > len(payload):
560         raise Exception("Invalid EAPOL length")
561     if length < len(payload):
562         payload = payload[0:length]
563     eapol = {}
564     eapol['version'] = version
565     eapol['type'] = type
566     eapol['length'] = length
567     eapol['payload'] = payload
568     if type == 3:
569         # EAPOL-Key
570         (eapol['descr_type'],) = struct.unpack('B', payload[0:1])
571         payload = payload[1:]
572         if eapol['descr_type'] == 2 or eapol['descr_type'] == 254:
573             # RSN EAPOL-Key
574             (key_info, key_len) = struct.unpack('>HH', payload[0:4])
575             eapol['rsn_key_info'] = key_info
576             eapol['rsn_key_len'] = key_len
577             eapol['rsn_replay_counter'] = payload[4:12]
578             eapol['rsn_key_nonce'] = payload[12:44]
579             eapol['rsn_key_iv'] = payload[44:60]
580             eapol['rsn_key_rsc'] = payload[60:68]
581             eapol['rsn_key_id'] = payload[68:76]
582             eapol['rsn_key_mic'] = payload[76:92]
583             payload = payload[92:]
584             (eapol['rsn_key_data_len'],) = struct.unpack('>H', payload[0:2])
585             payload = payload[2:]
586             eapol['rsn_key_data'] = payload
587     return eapol
588
589 def build_eapol(msg):
590     data = struct.pack(">BBH", msg['version'], msg['type'], msg['length'])
591     if msg['type'] == 3:
592         data += struct.pack('>BHH', msg['descr_type'], msg['rsn_key_info'],
593                             msg['rsn_key_len'])
594         data += msg['rsn_replay_counter']
595         data += msg['rsn_key_nonce']
596         data += msg['rsn_key_iv']
597         data += msg['rsn_key_rsc']
598         data += msg['rsn_key_id']
599         data += msg['rsn_key_mic']
600         data += struct.pack('>H', msg['rsn_key_data_len'])
601         data += msg['rsn_key_data']
602     else:
603         data += msg['payload']
604     return data
605
606 def sha1_prf(key, label, data, outlen):
607     res = ''
608     counter = 0
609     while outlen > 0:
610         m = hmac.new(key, label, hashlib.sha1)
611         m.update(struct.pack('B', 0))
612         m.update(data)
613         m.update(struct.pack('B', counter))
614         counter += 1
615         hash = m.digest()
616         if outlen > len(hash):
617             res += hash
618             outlen -= len(hash)
619         else:
620             res += hash[0:outlen]
621             outlen = 0
622     return res
623
624 def pmk_to_ptk(pmk, addr1, addr2, nonce1, nonce2):
625     if addr1 < addr2:
626         data = binascii.unhexlify(addr1.replace(':','')) + binascii.unhexlify(addr2.replace(':',''))
627     else:
628         data = binascii.unhexlify(addr2.replace(':','')) + binascii.unhexlify(addr1.replace(':',''))
629     if nonce1 < nonce2:
630         data += nonce1 + nonce2
631     else:
632         data += nonce2 + nonce1
633     label = "Pairwise key expansion"
634     ptk = sha1_prf(pmk, label, data, 48)
635     kck = ptk[0:16]
636     kek = ptk[16:32]
637     return (ptk, kck, kek)
638
639 def eapol_key_mic(kck, msg):
640     msg['rsn_key_mic'] = binascii.unhexlify('00000000000000000000000000000000')
641     data = build_eapol(msg)
642     m = hmac.new(kck, data, hashlib.sha1)
643     msg['rsn_key_mic'] = m.digest()[0:16]
644
645 def rsn_eapol_key_set(msg, key_info, key_len, nonce, data):
646     msg['rsn_key_info'] = key_info
647     msg['rsn_key_len'] = key_len
648     if nonce:
649         msg['rsn_key_nonce'] = nonce
650     else:
651         msg['rsn_key_nonce'] = binascii.unhexlify('0000000000000000000000000000000000000000000000000000000000000000')
652     if data:
653         msg['rsn_key_data_len'] = len(data)
654         msg['rsn_key_data'] = data
655         msg['length'] = 95 + len(data)
656     else:
657         msg['rsn_key_data_len'] = 0
658         msg['rsn_key_data'] = ''
659         msg['length'] = 95
660
661 def recv_eapol(hapd):
662     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
663     if ev is None:
664         raise Exception("Timeout on EAPOL-TX from hostapd")
665     eapol = binascii.unhexlify(ev.split(' ')[2])
666     return parse_eapol(eapol)
667
668 def send_eapol(hapd, addr, data):
669     res = hapd.request("EAPOL_RX " + addr + " " + binascii.hexlify(data))
670     if "OK" not in res:
671         raise Exception("EAPOL_RX to hostapd failed")
672
673 def reply_eapol(info, hapd, addr, msg, key_info, nonce, data, kck):
674     logger.info("Send EAPOL-Key msg " + info)
675     rsn_eapol_key_set(msg, key_info, 0, nonce, data)
676     eapol_key_mic(kck, msg)
677     send_eapol(hapd, addr, build_eapol(msg))
678
679 def hapd_connected(hapd):
680     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=15)
681     if ev is None:
682         raise Exception("Timeout on AP-STA-CONNECTED from hostapd")
683
684 def eapol_test(apdev, dev, wpa2=True):
685     bssid = apdev['bssid']
686     if wpa2:
687         ssid = "test-wpa2-psk"
688     else:
689         ssid = "test-wpa-psk"
690     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
691     pmk = binascii.unhexlify(psk)
692     if wpa2:
693         params = hostapd.wpa2_params(ssid=ssid)
694     else:
695         params = hostapd.wpa_params(ssid=ssid)
696     params['wpa_psk'] = psk
697     hapd = hostapd.add_ap(apdev['ifname'], params)
698     hapd.request("SET ext_eapol_frame_io 1")
699     dev.request("SET ext_eapol_frame_io 1")
700     dev.connect(ssid, raw_psk=psk, scan_freq="2412", wait_connect=False)
701     addr = dev.p2p_interface_addr()
702     if wpa2:
703         rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020000')
704     else:
705         rsne = binascii.unhexlify('dd160050f20101000050f20201000050f20201000050f202')
706     snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
707     return (bssid,ssid,hapd,snonce,pmk,addr,rsne)
708
709 def test_ap_wpa2_psk_ext_eapol(dev, apdev):
710     """WPA2-PSK AP using external EAPOL supplicant"""
711     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
712
713     msg = recv_eapol(hapd)
714     anonce = msg['rsn_key_nonce']
715     logger.info("Replay same data back")
716     send_eapol(hapd, addr, build_eapol(msg))
717
718     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
719
720     logger.info("Truncated Key Data in EAPOL-Key msg 2/4")
721     rsn_eapol_key_set(msg, 0x0101, 0, snonce, rsne)
722     msg['length'] = 95 + 22 - 1
723     send_eapol(hapd, addr, build_eapol(msg))
724
725     reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, rsne, kck)
726
727     msg = recv_eapol(hapd)
728     if anonce != msg['rsn_key_nonce']:
729         raise Exception("ANonce changed")
730     logger.info("Replay same data back")
731     send_eapol(hapd, addr, build_eapol(msg))
732
733     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
734     hapd_connected(hapd)
735
736 def test_ap_wpa2_psk_ext_eapol_retry1(dev, apdev):
737     """WPA2 4-way handshake with EAPOL-Key 1/4 retransmitted"""
738     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
739
740     msg1 = recv_eapol(hapd)
741     anonce = msg1['rsn_key_nonce']
742
743     msg2 = recv_eapol(hapd)
744     if anonce != msg2['rsn_key_nonce']:
745         raise Exception("ANonce changed")
746
747     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
748
749     logger.info("Send EAPOL-Key msg 2/4")
750     msg = msg2
751     rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
752     eapol_key_mic(kck, msg)
753     send_eapol(hapd, addr, build_eapol(msg))
754
755     msg = recv_eapol(hapd)
756     if anonce != msg['rsn_key_nonce']:
757         raise Exception("ANonce changed")
758
759     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
760     hapd_connected(hapd)
761
762 def test_ap_wpa2_psk_ext_eapol_retry1b(dev, apdev):
763     """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted"""
764     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
765
766     msg1 = recv_eapol(hapd)
767     anonce = msg1['rsn_key_nonce']
768     msg2 = recv_eapol(hapd)
769     if anonce != msg2['rsn_key_nonce']:
770         raise Exception("ANonce changed")
771
772     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
773     reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
774     reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce, rsne, kck)
775
776     msg = recv_eapol(hapd)
777     if anonce != msg['rsn_key_nonce']:
778         raise Exception("ANonce changed")
779
780     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
781     hapd_connected(hapd)
782
783 def test_ap_wpa2_psk_ext_eapol_retry1c(dev, apdev):
784     """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing"""
785     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
786
787     msg1 = recv_eapol(hapd)
788     anonce = msg1['rsn_key_nonce']
789
790     msg2 = recv_eapol(hapd)
791     if anonce != msg2['rsn_key_nonce']:
792         raise Exception("ANonce changed")
793     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
794     reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
795
796     snonce2 = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
797     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce2, anonce)
798     reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce2, rsne, kck)
799
800     msg = recv_eapol(hapd)
801     if anonce != msg['rsn_key_nonce']:
802         raise Exception("ANonce changed")
803     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
804     hapd_connected(hapd)
805
806 def test_ap_wpa2_psk_ext_eapol_retry1d(dev, apdev):
807     """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing and older used"""
808     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
809
810     msg1 = recv_eapol(hapd)
811     anonce = msg1['rsn_key_nonce']
812     msg2 = recv_eapol(hapd)
813     if anonce != msg2['rsn_key_nonce']:
814         raise Exception("ANonce changed")
815
816     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
817     reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
818
819     snonce2 = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
820     (ptk2, kck2, kek2) = pmk_to_ptk(pmk, addr, bssid, snonce2, anonce)
821
822     reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce2, rsne, kck2)
823     msg = recv_eapol(hapd)
824     if anonce != msg['rsn_key_nonce']:
825         raise Exception("ANonce changed")
826     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
827     hapd_connected(hapd)
828
829 def test_ap_wpa2_psk_ext_eapol_type_diff(dev, apdev):
830     """WPA2 4-way handshake using external EAPOL supplicant"""
831     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
832
833     msg = recv_eapol(hapd)
834     anonce = msg['rsn_key_nonce']
835
836     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
837
838     # Incorrect descriptor type (frame dropped)
839     msg['descr_type'] = 253
840     rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
841     eapol_key_mic(kck, msg)
842     send_eapol(hapd, addr, build_eapol(msg))
843
844     # Incorrect descriptor type, but with a workaround (frame processed)
845     msg['descr_type'] = 254
846     rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
847     eapol_key_mic(kck, msg)
848     send_eapol(hapd, addr, build_eapol(msg))
849
850     msg = recv_eapol(hapd)
851     if anonce != msg['rsn_key_nonce']:
852         raise Exception("ANonce changed")
853     logger.info("Replay same data back")
854     send_eapol(hapd, addr, build_eapol(msg))
855
856     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
857     hapd_connected(hapd)
858
859 def test_ap_wpa_psk_ext_eapol(dev, apdev):
860     """WPA2-PSK AP using external EAPOL supplicant"""
861     (bssid,ssid,hapd,snonce,pmk,addr,wpae) = eapol_test(apdev[0], dev[0],
862                                                         wpa2=False)
863
864     msg = recv_eapol(hapd)
865     anonce = msg['rsn_key_nonce']
866     logger.info("Replay same data back")
867     send_eapol(hapd, addr, build_eapol(msg))
868     logger.info("Too short data")
869     send_eapol(hapd, addr, build_eapol(msg)[0:98])
870
871     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
872     msg['descr_type'] = 2
873     reply_eapol("2/4(invalid type)", hapd, addr, msg, 0x010a, snonce, wpae, kck)
874     msg['descr_type'] = 254
875     reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, wpae, kck)
876
877     msg = recv_eapol(hapd)
878     if anonce != msg['rsn_key_nonce']:
879         raise Exception("ANonce changed")
880     logger.info("Replay same data back")
881     send_eapol(hapd, addr, build_eapol(msg))
882
883     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
884     hapd_connected(hapd)
885
886 def test_ap_wpa2_psk_ext_eapol_key_info(dev, apdev):
887     """WPA2-PSK 4-way handshake with strange key info values"""
888     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
889
890     msg = recv_eapol(hapd)
891     anonce = msg['rsn_key_nonce']
892
893     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
894     rsn_eapol_key_set(msg, 0x0000, 0, snonce, rsne)
895     send_eapol(hapd, addr, build_eapol(msg))
896     rsn_eapol_key_set(msg, 0xffff, 0, snonce, rsne)
897     send_eapol(hapd, addr, build_eapol(msg))
898     # SMK M1
899     rsn_eapol_key_set(msg, 0x2802, 0, snonce, rsne)
900     send_eapol(hapd, addr, build_eapol(msg))
901     # SMK M3
902     rsn_eapol_key_set(msg, 0x2002, 0, snonce, rsne)
903     send_eapol(hapd, addr, build_eapol(msg))
904     # Request
905     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
906     send_eapol(hapd, addr, build_eapol(msg))
907     # Request
908     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
909     tmp_kck = binascii.unhexlify('00000000000000000000000000000000')
910     eapol_key_mic(tmp_kck, msg)
911     send_eapol(hapd, addr, build_eapol(msg))
912
913     reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, rsne, kck)
914
915     msg = recv_eapol(hapd)
916     if anonce != msg['rsn_key_nonce']:
917         raise Exception("ANonce changed")
918
919     # Request (valic MIC)
920     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
921     eapol_key_mic(kck, msg)
922     send_eapol(hapd, addr, build_eapol(msg))
923     # Request (valid MIC, replayed counter)
924     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
925     eapol_key_mic(kck, msg)
926     send_eapol(hapd, addr, build_eapol(msg))
927
928     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
929     hapd_connected(hapd)
930
931 def build_eapol_key_1_4(anonce, replay_counter=1, key_data='', key_len=16):
932     msg = {}
933     msg['version'] = 2
934     msg['type'] = 3
935     msg['length'] = 95 + len(key_data)
936
937     msg['descr_type'] = 2
938     msg['rsn_key_info'] = 0x8a
939     msg['rsn_key_len'] = key_len
940     msg['rsn_replay_counter'] = struct.pack('>Q', replay_counter)
941     msg['rsn_key_nonce'] = anonce
942     msg['rsn_key_iv'] = binascii.unhexlify('00000000000000000000000000000000')
943     msg['rsn_key_rsc'] = binascii.unhexlify('0000000000000000')
944     msg['rsn_key_id'] = binascii.unhexlify('0000000000000000')
945     msg['rsn_key_mic'] = binascii.unhexlify('00000000000000000000000000000000')
946     msg['rsn_key_data_len'] = len(key_data)
947     msg['rsn_key_data'] = key_data
948     return msg
949
950 def build_eapol_key_3_4(anonce, kck, key_data, replay_counter=2,
951                         key_info=0x13ca, extra_len=0, descr_type=2, key_len=16):
952     msg = {}
953     msg['version'] = 2
954     msg['type'] = 3
955     msg['length'] = 95 + len(key_data) + extra_len
956
957     msg['descr_type'] = descr_type
958     msg['rsn_key_info'] = key_info
959     msg['rsn_key_len'] = key_len
960     msg['rsn_replay_counter'] = struct.pack('>Q', replay_counter)
961     msg['rsn_key_nonce'] = anonce
962     msg['rsn_key_iv'] = binascii.unhexlify('00000000000000000000000000000000')
963     msg['rsn_key_rsc'] = binascii.unhexlify('0000000000000000')
964     msg['rsn_key_id'] = binascii.unhexlify('0000000000000000')
965     msg['rsn_key_data_len'] = len(key_data)
966     msg['rsn_key_data'] = key_data
967     eapol_key_mic(kck, msg)
968     return msg
969
970 def aes_wrap(kek, plain):
971     n = len(plain) / 8
972     a = 0xa6a6a6a6a6a6a6a6
973     enc = AES.new(kek).encrypt
974     r = [plain[i * 8:(i + 1) * 8] for i in range(0, n)]
975     for j in range(6):
976         for i in range(1, n + 1):
977             b = enc(struct.pack('>Q', a) + r[i - 1])
978             a = struct.unpack('>Q', b[:8])[0] ^ (n * j + i)
979             r[i - 1] =b[8:]
980     return struct.pack('>Q', a) + ''.join(r)
981
982 def pad_key_data(plain):
983     pad_len = len(plain) % 8
984     if pad_len:
985         pad_len = 8 - pad_len
986         plain += '\xdd'
987         pad_len -= 1
988         plain += pad_len * '\0'
989     return plain
990
991 def test_ap_wpa2_psk_supp_proto(dev, apdev):
992     """WPA2-PSK 4-way handshake protocol testing for supplicant"""
993     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
994
995     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
996     msg = recv_eapol(hapd)
997     dev[0].dump_monitor()
998
999     # Build own EAPOL-Key msg 1/4
1000     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1001     counter = 1
1002     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1003     counter += 1
1004     send_eapol(dev[0], addr, build_eapol(msg))
1005     msg = recv_eapol(dev[0])
1006     snonce = msg['rsn_key_nonce']
1007
1008     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1009
1010     logger.debug("Invalid AES wrap data length 0")
1011     dev[0].dump_monitor()
1012     msg = build_eapol_key_3_4(anonce, kck, '', replay_counter=counter)
1013     counter += 1
1014     send_eapol(dev[0], addr, build_eapol(msg))
1015     ev = dev[0].wait_event(["WPA: Unsupported AES-WRAP len 0"])
1016     if ev is None:
1017         raise Exception("Unsupported AES-WRAP len 0 not reported")
1018
1019     logger.debug("Invalid AES wrap data length 1")
1020     dev[0].dump_monitor()
1021     msg = build_eapol_key_3_4(anonce, kck, '1', replay_counter=counter)
1022     counter += 1
1023     send_eapol(dev[0], addr, build_eapol(msg))
1024     ev = dev[0].wait_event(["WPA: Unsupported AES-WRAP len 1"])
1025     if ev is None:
1026         raise Exception("Unsupported AES-WRAP len 1 not reported")
1027
1028     logger.debug("Invalid AES wrap data length 9")
1029     dev[0].dump_monitor()
1030     msg = build_eapol_key_3_4(anonce, kck, '123456789', replay_counter=counter)
1031     counter += 1
1032     send_eapol(dev[0], addr, build_eapol(msg))
1033     ev = dev[0].wait_event(["WPA: Unsupported AES-WRAP len 9"])
1034     if ev is None:
1035         raise Exception("Unsupported AES-WRAP len 9 not reported")
1036
1037     logger.debug("Invalid AES wrap data payload")
1038     dev[0].dump_monitor()
1039     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter)
1040     # do not increment counter to test replay protection
1041     send_eapol(dev[0], addr, build_eapol(msg))
1042     ev = dev[0].wait_event(["WPA: AES unwrap failed"])
1043     if ev is None:
1044         raise Exception("AES unwrap failure not reported")
1045
1046     logger.debug("Replay Count not increasing")
1047     dev[0].dump_monitor()
1048     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter)
1049     counter += 1
1050     send_eapol(dev[0], addr, build_eapol(msg))
1051     ev = dev[0].wait_event(["WPA: EAPOL-Key Replay Counter did not increase"])
1052     if ev is None:
1053         raise Exception("Replay Counter replay not reported")
1054
1055     logger.debug("Missing Ack bit in key info")
1056     dev[0].dump_monitor()
1057     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter,
1058                               key_info=0x134a)
1059     counter += 1
1060     send_eapol(dev[0], addr, build_eapol(msg))
1061     ev = dev[0].wait_event(["WPA: No Ack bit in key_info"])
1062     if ev is None:
1063         raise Exception("Missing Ack bit not reported")
1064
1065     logger.debug("Unexpected Request bit in key info")
1066     dev[0].dump_monitor()
1067     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter,
1068                               key_info=0x1bca)
1069     counter += 1
1070     send_eapol(dev[0], addr, build_eapol(msg))
1071     ev = dev[0].wait_event(["WPA: EAPOL-Key with Request bit"])
1072     if ev is None:
1073         raise Exception("Request bit not reported")
1074
1075     logger.debug("Unsupported key descriptor version 0")
1076     dev[0].dump_monitor()
1077     msg = build_eapol_key_3_4(anonce, kck, '0123456789abcdef',
1078                               replay_counter=counter, key_info=0x13c8)
1079     counter += 1
1080     send_eapol(dev[0], addr, build_eapol(msg))
1081     ev = dev[0].wait_event(["WPA: Unsupported EAPOL-Key descriptor version 0"])
1082     if ev is None:
1083         raise Exception("Unsupported EAPOL-Key descriptor version 0 not reported")
1084
1085     logger.debug("Key descriptor version 1 not allowed with CCMP")
1086     dev[0].dump_monitor()
1087     msg = build_eapol_key_3_4(anonce, kck, '0123456789abcdef',
1088                               replay_counter=counter, key_info=0x13c9)
1089     counter += 1
1090     send_eapol(dev[0], addr, build_eapol(msg))
1091     ev = dev[0].wait_event(["WPA: CCMP is used, but EAPOL-Key descriptor version (1) is not 2"])
1092     if ev is None:
1093         raise Exception("Not allowed EAPOL-Key descriptor version not reported")
1094
1095     logger.debug("Invalid AES wrap payload with key descriptor version 2")
1096     dev[0].dump_monitor()
1097     msg = build_eapol_key_3_4(anonce, kck, '0123456789abcdef',
1098                               replay_counter=counter, key_info=0x13ca)
1099     counter += 1
1100     send_eapol(dev[0], addr, build_eapol(msg))
1101     ev = dev[0].wait_event(["WPA: AES unwrap failed"])
1102     if ev is None:
1103         raise Exception("AES unwrap failure not reported")
1104
1105     logger.debug("Key descriptor version 3 workaround")
1106     dev[0].dump_monitor()
1107     msg = build_eapol_key_3_4(anonce, kck, '0123456789abcdef',
1108                               replay_counter=counter, key_info=0x13cb)
1109     counter += 1
1110     send_eapol(dev[0], addr, build_eapol(msg))
1111     ev = dev[0].wait_event(["WPA: CCMP is used, but EAPOL-Key descriptor version (3) is not 2"])
1112     if ev is None:
1113         raise Exception("CCMP key descriptor mismatch not reported")
1114     ev = dev[0].wait_event(["WPA: Interoperability workaround"])
1115     if ev is None:
1116         raise Exception("AES-128-CMAC workaround not reported")
1117     ev = dev[0].wait_event(["WPA: Invalid EAPOL-Key MIC - dropping packet"])
1118     if ev is None:
1119         raise Exception("MIC failure with AES-128-CMAC workaround not reported")
1120
1121     logger.debug("Unsupported key descriptor version 4")
1122     dev[0].dump_monitor()
1123     msg = build_eapol_key_3_4(anonce, kck, '0123456789abcdef',
1124                               replay_counter=counter, key_info=0x13cc)
1125     counter += 1
1126     send_eapol(dev[0], addr, build_eapol(msg))
1127     ev = dev[0].wait_event(["WPA: Unsupported EAPOL-Key descriptor version 4"])
1128     if ev is None:
1129         raise Exception("Unsupported EAPOL-Key descriptor version 4 not reported")
1130
1131     logger.debug("Unsupported key descriptor version 7")
1132     dev[0].dump_monitor()
1133     msg = build_eapol_key_3_4(anonce, kck, '0123456789abcdef',
1134                               replay_counter=counter, key_info=0x13cf)
1135     counter += 1
1136     send_eapol(dev[0], addr, build_eapol(msg))
1137     ev = dev[0].wait_event(["WPA: Unsupported EAPOL-Key descriptor version 7"])
1138     if ev is None:
1139         raise Exception("Unsupported EAPOL-Key descriptor version 7 not reported")
1140
1141     logger.debug("Too short EAPOL header length")
1142     dev[0].dump_monitor()
1143     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter,
1144                               extra_len=-1)
1145     counter += 1
1146     send_eapol(dev[0], addr, build_eapol(msg))
1147     ev = dev[0].wait_event(["WPA: Invalid EAPOL-Key frame - key_data overflow (8 > 7)"])
1148     if ev is None:
1149         raise Exception("Key data overflow not reported")
1150
1151     logger.debug("Too long EAPOL header length")
1152     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter,
1153                               extra_len=1)
1154     counter += 1
1155     send_eapol(dev[0], addr, build_eapol(msg))
1156
1157     logger.debug("Unsupported descriptor type 0")
1158     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter,
1159                               descr_type=0)
1160     counter += 1
1161     send_eapol(dev[0], addr, build_eapol(msg))
1162
1163     logger.debug("WPA descriptor type 0")
1164     msg = build_eapol_key_3_4(anonce, kck, '12345678', replay_counter=counter,
1165                               descr_type=254)
1166     counter += 1
1167     send_eapol(dev[0], addr, build_eapol(msg))
1168
1169     logger.debug("Non-zero key index for pairwise key")
1170     dev[0].dump_monitor()
1171     wrapped = aes_wrap(kek, 16*'z')
1172     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter,
1173                               key_info=0x13ea)
1174     counter += 1
1175     send_eapol(dev[0], addr, build_eapol(msg))
1176     ev = dev[0].wait_event(["WPA: Ignored EAPOL-Key (Pairwise) with non-zero key index"])
1177     if ev is None:
1178         raise Exception("Non-zero key index not reported")
1179
1180     logger.debug("Invalid Key Data plaintext payload --> disconnect")
1181     dev[0].dump_monitor()
1182     wrapped = aes_wrap(kek, 16*'z')
1183     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1184     counter += 1
1185     send_eapol(dev[0], addr, build_eapol(msg))
1186     dev[0].wait_disconnected(timeout=1)
1187
1188 def test_ap_wpa2_psk_supp_proto_no_ie(dev, apdev):
1189     """WPA2-PSK supplicant protocol testing: IE not included"""
1190     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1191
1192     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1193     msg = recv_eapol(hapd)
1194     dev[0].dump_monitor()
1195
1196     # Build own EAPOL-Key msg 1/4
1197     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1198     counter = 1
1199     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1200     counter += 1
1201     send_eapol(dev[0], addr, build_eapol(msg))
1202     msg = recv_eapol(dev[0])
1203     snonce = msg['rsn_key_nonce']
1204
1205     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1206
1207     logger.debug("No IEs in msg 3/4 --> disconnect")
1208     dev[0].dump_monitor()
1209     wrapped = aes_wrap(kek, 16*'\0')
1210     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1211     counter += 1
1212     send_eapol(dev[0], addr, build_eapol(msg))
1213     dev[0].wait_disconnected(timeout=1)
1214
1215 def test_ap_wpa2_psk_supp_proto_ie_mismatch(dev, apdev):
1216     """WPA2-PSK supplicant protocol testing: IE mismatch"""
1217     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1218
1219     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1220     msg = recv_eapol(hapd)
1221     dev[0].dump_monitor()
1222
1223     # Build own EAPOL-Key msg 1/4
1224     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1225     counter = 1
1226     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1227     counter += 1
1228     send_eapol(dev[0], addr, build_eapol(msg))
1229     msg = recv_eapol(dev[0])
1230     snonce = msg['rsn_key_nonce']
1231
1232     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1233
1234     logger.debug("Msg 3/4 with mismatching IE")
1235     dev[0].dump_monitor()
1236     wrapped = aes_wrap(kek, pad_key_data(binascii.unhexlify('30060100000fac04dd16000fac010100dc11188831bf4aa4a8678d2b41498618')))
1237     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1238     counter += 1
1239     send_eapol(dev[0], addr, build_eapol(msg))
1240     dev[0].wait_disconnected(timeout=1)
1241
1242 def test_ap_wpa2_psk_supp_proto_ok(dev, apdev):
1243     """WPA2-PSK supplicant protocol testing: success"""
1244     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1245
1246     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1247     msg = recv_eapol(hapd)
1248     dev[0].dump_monitor()
1249
1250     # Build own EAPOL-Key msg 1/4
1251     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1252     counter = 1
1253     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1254     counter += 1
1255     send_eapol(dev[0], addr, build_eapol(msg))
1256     msg = recv_eapol(dev[0])
1257     snonce = msg['rsn_key_nonce']
1258
1259     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1260
1261     logger.debug("Valid EAPOL-Key msg 3/4")
1262     dev[0].dump_monitor()
1263     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010100dc11188831bf4aa4a8678d2b41498618')
1264     wrapped = aes_wrap(kek, pad_key_data(plain))
1265     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1266     counter += 1
1267     send_eapol(dev[0], addr, build_eapol(msg))
1268     dev[0].wait_connected(timeout=1)
1269
1270 def test_ap_wpa2_psk_supp_proto_no_gtk(dev, apdev):
1271     """WPA2-PSK supplicant protocol testing: no GTK"""
1272     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1273
1274     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1275     msg = recv_eapol(hapd)
1276     dev[0].dump_monitor()
1277
1278     # Build own EAPOL-Key msg 1/4
1279     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1280     counter = 1
1281     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1282     counter += 1
1283     send_eapol(dev[0], addr, build_eapol(msg))
1284     msg = recv_eapol(dev[0])
1285     snonce = msg['rsn_key_nonce']
1286
1287     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1288
1289     logger.debug("EAPOL-Key msg 3/4 without GTK KDE")
1290     dev[0].dump_monitor()
1291     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00')
1292     wrapped = aes_wrap(kek, pad_key_data(plain))
1293     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1294     counter += 1
1295     send_eapol(dev[0], addr, build_eapol(msg))
1296     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
1297     if ev is not None:
1298         raise Exception("Unexpected connection completion reported")
1299
1300 def test_ap_wpa2_psk_supp_proto_anonce_change(dev, apdev):
1301     """WPA2-PSK supplicant protocol testing: ANonce change"""
1302     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1303
1304     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1305     msg = recv_eapol(hapd)
1306     dev[0].dump_monitor()
1307
1308     # Build own EAPOL-Key msg 1/4
1309     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1310     counter = 1
1311     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1312     counter += 1
1313     send_eapol(dev[0], addr, build_eapol(msg))
1314     msg = recv_eapol(dev[0])
1315     snonce = msg['rsn_key_nonce']
1316
1317     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1318
1319     logger.debug("Valid EAPOL-Key msg 3/4")
1320     dev[0].dump_monitor()
1321     anonce2 = binascii.unhexlify('3333333333333333333333333333333333333333333333333333333333333333')
1322     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010100dc11188831bf4aa4a8678d2b41498618')
1323     wrapped = aes_wrap(kek, pad_key_data(plain))
1324     msg = build_eapol_key_3_4(anonce2, kck, wrapped, replay_counter=counter)
1325     counter += 1
1326     send_eapol(dev[0], addr, build_eapol(msg))
1327     ev = dev[0].wait_event(["WPA: ANonce from message 1 of 4-Way Handshake differs from 3 of 4-Way Handshake"])
1328     if ev is None:
1329         raise Exception("ANonce change not reported")
1330
1331 def test_ap_wpa2_psk_supp_proto_unexpected_group_msg(dev, apdev):
1332     """WPA2-PSK supplicant protocol testing: unexpected group message"""
1333     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1334
1335     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1336     msg = recv_eapol(hapd)
1337     dev[0].dump_monitor()
1338
1339     # Build own EAPOL-Key msg 1/4
1340     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1341     counter = 1
1342     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1343     counter += 1
1344     send_eapol(dev[0], addr, build_eapol(msg))
1345     msg = recv_eapol(dev[0])
1346     snonce = msg['rsn_key_nonce']
1347
1348     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1349
1350     logger.debug("Group key 1/2 instead of msg 3/4")
1351     dev[0].dump_monitor()
1352     wrapped = aes_wrap(kek, binascii.unhexlify('dd16000fac010100dc11188831bf4aa4a8678d2b41498618'))
1353     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter,
1354                               key_info=0x13c2)
1355     counter += 1
1356     send_eapol(dev[0], addr, build_eapol(msg))
1357     ev = dev[0].wait_event(["WPA: Group Key Handshake started prior to completion of 4-way handshake"])
1358     if ev is None:
1359         raise Exception("Unexpected group key message not reported")
1360     dev[0].wait_disconnected(timeout=1)
1361
1362 def test_ap_wpa2_psk_supp_proto_msg_1_invalid_kde(dev, apdev):
1363     """WPA2-PSK supplicant protocol testing: invalid KDE in msg 1/4"""
1364     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1365
1366     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1367     msg = recv_eapol(hapd)
1368     dev[0].dump_monitor()
1369
1370     # Build own EAPOL-Key msg 1/4 with invalid KDE
1371     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1372     counter = 1
1373     msg = build_eapol_key_1_4(anonce, replay_counter=counter,
1374                               key_data=binascii.unhexlify('5555'))
1375     counter += 1
1376     send_eapol(dev[0], addr, build_eapol(msg))
1377     dev[0].wait_disconnected(timeout=1)
1378
1379 def test_ap_wpa2_psk_supp_proto_wrong_pairwise_key_len(dev, apdev):
1380     """WPA2-PSK supplicant protocol testing: wrong pairwise key length"""
1381     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1382
1383     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1384     msg = recv_eapol(hapd)
1385     dev[0].dump_monitor()
1386
1387     # Build own EAPOL-Key msg 1/4
1388     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1389     counter = 1
1390     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1391     counter += 1
1392     send_eapol(dev[0], addr, build_eapol(msg))
1393     msg = recv_eapol(dev[0])
1394     snonce = msg['rsn_key_nonce']
1395
1396     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1397
1398     logger.debug("Valid EAPOL-Key msg 3/4")
1399     dev[0].dump_monitor()
1400     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010100dc11188831bf4aa4a8678d2b41498618')
1401     wrapped = aes_wrap(kek, pad_key_data(plain))
1402     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter,
1403                               key_len=15)
1404     counter += 1
1405     send_eapol(dev[0], addr, build_eapol(msg))
1406     ev = dev[0].wait_event(["WPA: Invalid CCMP key length 15"])
1407     if ev is None:
1408         raise Exception("Invalid CCMP key length not reported")
1409     dev[0].wait_disconnected(timeout=1)
1410
1411 def test_ap_wpa2_psk_supp_proto_wrong_group_key_len(dev, apdev):
1412     """WPA2-PSK supplicant protocol testing: wrong group key length"""
1413     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1414
1415     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1416     msg = recv_eapol(hapd)
1417     dev[0].dump_monitor()
1418
1419     # Build own EAPOL-Key msg 1/4
1420     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1421     counter = 1
1422     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1423     counter += 1
1424     send_eapol(dev[0], addr, build_eapol(msg))
1425     msg = recv_eapol(dev[0])
1426     snonce = msg['rsn_key_nonce']
1427
1428     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1429
1430     logger.debug("Valid EAPOL-Key msg 3/4")
1431     dev[0].dump_monitor()
1432     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd15000fac010100dc11188831bf4aa4a8678d2b414986')
1433     wrapped = aes_wrap(kek, pad_key_data(plain))
1434     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1435     counter += 1
1436     send_eapol(dev[0], addr, build_eapol(msg))
1437     ev = dev[0].wait_event(["WPA: Unsupported CCMP Group Cipher key length 15"])
1438     if ev is None:
1439         raise Exception("Invalid CCMP key length not reported")
1440     dev[0].wait_disconnected(timeout=1)
1441
1442 def test_ap_wpa2_psk_supp_proto_gtk_tx_bit_workaround(dev, apdev):
1443     """WPA2-PSK supplicant protocol testing: GTK TX bit workaround"""
1444     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1445
1446     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1447     msg = recv_eapol(hapd)
1448     dev[0].dump_monitor()
1449
1450     # Build own EAPOL-Key msg 1/4
1451     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1452     counter = 1
1453     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1454     counter += 1
1455     send_eapol(dev[0], addr, build_eapol(msg))
1456     msg = recv_eapol(dev[0])
1457     snonce = msg['rsn_key_nonce']
1458
1459     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1460
1461     logger.debug("Valid EAPOL-Key msg 3/4")
1462     dev[0].dump_monitor()
1463     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010500dc11188831bf4aa4a8678d2b41498618')
1464     wrapped = aes_wrap(kek, pad_key_data(plain))
1465     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1466     counter += 1
1467     send_eapol(dev[0], addr, build_eapol(msg))
1468     ev = dev[0].wait_event(["WPA: Tx bit set for GTK, but pairwise keys are used - ignore Tx bit"])
1469     if ev is None:
1470         raise Exception("GTK Tx bit workaround not reported")
1471     dev[0].wait_connected(timeout=1)
1472
1473 def test_ap_wpa2_psk_supp_proto_gtk_keyidx_0_and_3(dev, apdev):
1474     """WPA2-PSK supplicant protocol testing: GTK key index 0 and 3"""
1475     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1476
1477     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1478     msg = recv_eapol(hapd)
1479     dev[0].dump_monitor()
1480
1481     # Build own EAPOL-Key msg 1/4
1482     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1483     counter = 1
1484     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1485     counter += 1
1486     send_eapol(dev[0], addr, build_eapol(msg))
1487     msg = recv_eapol(dev[0])
1488     snonce = msg['rsn_key_nonce']
1489
1490     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1491
1492     logger.debug("Valid EAPOL-Key msg 3/4 (GTK keyidx 0)")
1493     dev[0].dump_monitor()
1494     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010000dc11188831bf4aa4a8678d2b41498618')
1495     wrapped = aes_wrap(kek, pad_key_data(plain))
1496     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1497     counter += 1
1498     send_eapol(dev[0], addr, build_eapol(msg))
1499     dev[0].wait_connected(timeout=1)
1500
1501     logger.debug("Valid EAPOL-Key group msg 1/2 (GTK keyidx 3)")
1502     dev[0].dump_monitor()
1503     plain = binascii.unhexlify('dd16000fac010300dc11188831bf4aa4a8678d2b41498618')
1504     wrapped = aes_wrap(kek, pad_key_data(plain))
1505     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter,
1506                               key_info=0x13c2)
1507     counter += 1
1508     send_eapol(dev[0], addr, build_eapol(msg))
1509     msg = recv_eapol(dev[0])
1510     ev = dev[0].wait_event(["WPA: Group rekeying completed"])
1511     if ev is None:
1512         raise Exception("GTK rekeing not reported")
1513
1514     logger.debug("Unencrypted GTK KDE in group msg 1/2")
1515     dev[0].dump_monitor()
1516     plain = binascii.unhexlify('dd16000fac010300dc11188831bf4aa4a8678d2b41498618')
1517     msg = build_eapol_key_3_4(anonce, kck, plain, replay_counter=counter,
1518                               key_info=0x03c2)
1519     counter += 1
1520     send_eapol(dev[0], addr, build_eapol(msg))
1521     ev = dev[0].wait_event(["WPA: GTK IE in unencrypted key data"])
1522     if ev is None:
1523         raise Exception("Unencrypted GTK KDE not reported")
1524     dev[0].wait_disconnected(timeout=1)
1525
1526 def test_ap_wpa2_psk_supp_proto_no_gtk_in_group_msg(dev, apdev):
1527     """WPA2-PSK supplicant protocol testing: GTK KDE missing from group msg"""
1528     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1529
1530     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1531     msg = recv_eapol(hapd)
1532     dev[0].dump_monitor()
1533
1534     # Build own EAPOL-Key msg 1/4
1535     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1536     counter = 1
1537     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1538     counter += 1
1539     send_eapol(dev[0], addr, build_eapol(msg))
1540     msg = recv_eapol(dev[0])
1541     snonce = msg['rsn_key_nonce']
1542
1543     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1544
1545     logger.debug("Valid EAPOL-Key msg 3/4 (GTK keyidx 0)")
1546     dev[0].dump_monitor()
1547     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010000dc11188831bf4aa4a8678d2b41498618')
1548     wrapped = aes_wrap(kek, pad_key_data(plain))
1549     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1550     counter += 1
1551     send_eapol(dev[0], addr, build_eapol(msg))
1552     dev[0].wait_connected(timeout=1)
1553
1554     logger.debug("No GTK KDE in EAPOL-Key group msg 1/2")
1555     dev[0].dump_monitor()
1556     plain = binascii.unhexlify('dd00dd00dd00dd00dd00dd00dd00dd00')
1557     wrapped = aes_wrap(kek, pad_key_data(plain))
1558     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter,
1559                               key_info=0x13c2)
1560     counter += 1
1561     send_eapol(dev[0], addr, build_eapol(msg))
1562     ev = dev[0].wait_event(["WPA: No GTK IE in Group Key msg 1/2"])
1563     if ev is None:
1564         raise Exception("Missing GTK KDE not reported")
1565     dev[0].wait_disconnected(timeout=1)
1566
1567 def test_ap_wpa2_psk_supp_proto_too_long_gtk_in_group_msg(dev, apdev):
1568     """WPA2-PSK supplicant protocol testing: too long GTK KDE in group msg"""
1569     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1570
1571     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1572     msg = recv_eapol(hapd)
1573     dev[0].dump_monitor()
1574
1575     # Build own EAPOL-Key msg 1/4
1576     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1577     counter = 1
1578     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1579     counter += 1
1580     send_eapol(dev[0], addr, build_eapol(msg))
1581     msg = recv_eapol(dev[0])
1582     snonce = msg['rsn_key_nonce']
1583
1584     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1585
1586     logger.debug("Valid EAPOL-Key msg 3/4 (GTK keyidx 0)")
1587     dev[0].dump_monitor()
1588     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010000dc11188831bf4aa4a8678d2b41498618')
1589     wrapped = aes_wrap(kek, pad_key_data(plain))
1590     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1591     counter += 1
1592     send_eapol(dev[0], addr, build_eapol(msg))
1593     dev[0].wait_connected(timeout=1)
1594
1595     logger.debug("EAPOL-Key group msg 1/2 with too long GTK KDE")
1596     dev[0].dump_monitor()
1597     plain = binascii.unhexlify('dd27000fac010100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
1598     wrapped = aes_wrap(kek, pad_key_data(plain))
1599     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter,
1600                               key_info=0x13c2)
1601     counter += 1
1602     send_eapol(dev[0], addr, build_eapol(msg))
1603     ev = dev[0].wait_event(["WPA: Unsupported CCMP Group Cipher key length 33"])
1604     if ev is None:
1605         raise Exception("Too long GTK KDE not reported")
1606     dev[0].wait_disconnected(timeout=1)
1607
1608 def test_ap_wpa2_psk_supp_proto_too_long_gtk_kde(dev, apdev):
1609     """WPA2-PSK supplicant protocol testing: too long GTK KDE"""
1610     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1611
1612     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1613     msg = recv_eapol(hapd)
1614     dev[0].dump_monitor()
1615
1616     # Build own EAPOL-Key msg 1/4
1617     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1618     counter = 1
1619     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1620     counter += 1
1621     send_eapol(dev[0], addr, build_eapol(msg))
1622     msg = recv_eapol(dev[0])
1623     snonce = msg['rsn_key_nonce']
1624
1625     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1626
1627     logger.debug("EAPOL-Key msg 3/4 with too short GTK KDE")
1628     dev[0].dump_monitor()
1629     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd27000fac010100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
1630     wrapped = aes_wrap(kek, pad_key_data(plain))
1631     msg = build_eapol_key_3_4(anonce, kck, wrapped, replay_counter=counter)
1632     counter += 1
1633     send_eapol(dev[0], addr, build_eapol(msg))
1634     dev[0].wait_disconnected(timeout=1)
1635
1636 def test_ap_wpa2_psk_supp_proto_gtk_not_encrypted(dev, apdev):
1637     """WPA2-PSK supplicant protocol testing: GTK KDE not encrypted"""
1638     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
1639
1640     # Wait for EAPOL-Key msg 1/4 from hostapd to determine when associated
1641     msg = recv_eapol(hapd)
1642     dev[0].dump_monitor()
1643
1644     # Build own EAPOL-Key msg 1/4
1645     anonce = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
1646     counter = 1
1647     msg = build_eapol_key_1_4(anonce, replay_counter=counter)
1648     counter += 1
1649     send_eapol(dev[0], addr, build_eapol(msg))
1650     msg = recv_eapol(dev[0])
1651     snonce = msg['rsn_key_nonce']
1652
1653     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
1654
1655     logger.debug("Valid EAPOL-Key msg 3/4")
1656     dev[0].dump_monitor()
1657     plain = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00dd16000fac010100dc11188831bf4aa4a8678d2b41498618')
1658     msg = build_eapol_key_3_4(anonce, kck, plain, replay_counter=counter,
1659                               key_info=0x03ca)
1660     counter += 1
1661     send_eapol(dev[0], addr, build_eapol(msg))
1662     ev = dev[0].wait_event(["WPA: GTK IE in unencrypted key data"])
1663     if ev is None:
1664         raise Exception("Unencrypted GTK KDE not reported")
1665     dev[0].wait_disconnected(timeout=1)
1666
1667 def find_wpas_process(dev):
1668     ifname = dev.ifname
1669     cmd = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE)
1670     (data,err) = cmd.communicate()
1671     for l in data.splitlines():
1672         if "wpa_supplicant" not in l:
1673             continue
1674         if "-i" + ifname not in l:
1675             continue
1676         return int(l.strip().split(' ')[0])
1677     raise Exception("Could not find wpa_supplicant process")
1678
1679 def read_process_memory(pid, key=None):
1680     buf = bytes()
1681     logger.info("Reading process memory (pid=%d)" % pid)
1682     with open('/proc/%d/maps' % pid, 'r') as maps, \
1683          open('/proc/%d/mem' % pid, 'r') as mem:
1684         for l in maps.readlines():
1685             m = re.match(r'([0-9a-f]+)-([0-9a-f]+) ([-r][-w][-x][-p])', l)
1686             if not m:
1687                 continue
1688             start = int(m.group(1), 16)
1689             end = int(m.group(2), 16)
1690             perm = m.group(3)
1691             if start > 0xffffffffffff:
1692                 continue
1693             if end < start:
1694                 continue
1695             if not perm.startswith('rw'):
1696                 continue
1697             for name in [ "[heap]", "[stack]" ]:
1698                 if name in l:
1699                     logger.info("%s 0x%x-0x%x is at %d-%d" % (name, start, end, len(buf), len(buf) + (end - start)))
1700             mem.seek(start)
1701             data = mem.read(end - start)
1702             buf += data
1703             if key and key in data:
1704                 logger.info("Key found in " + l)
1705     logger.info("Total process memory read: %d bytes" % len(buf))
1706     return buf
1707
1708 def verify_not_present(buf, key, fname, keyname):
1709     pos = buf.find(key)
1710     if pos < 0:
1711         return
1712
1713     prefix = 2048 if pos > 2048 else pos
1714     with open(fname + keyname, 'w') as f:
1715         f.write(buf[pos - prefix:pos + 2048])
1716     raise Exception(keyname + " found after disassociation")
1717
1718 def get_key_locations(buf, key, keyname):
1719     count = 0
1720     pos = 0
1721     while True:
1722         pos = buf.find(key, pos)
1723         if pos < 0:
1724             break
1725         logger.info("Found %s at %d" % (keyname, pos))
1726         context = 128;
1727         start = pos - context if pos > context else 0
1728         before = binascii.hexlify(buf[start:pos])
1729         context += len(key)
1730         end = pos + context if pos < len(buf) - context else len(buf) - context
1731         after = binascii.hexlify(buf[pos + len(key):end])
1732         logger.debug("Memory context %d-%d: %s|%s|%s" % (start, end, before, binascii.hexlify(key), after))
1733         count += 1
1734         pos += len(key)
1735     return count
1736
1737 def test_wpa2_psk_key_lifetime_in_memory(dev, apdev, params):
1738     """WPA2-PSK and PSK/PTK lifetime in memory"""
1739     ssid = "test-wpa2-psk"
1740     passphrase = 'qwertyuiop'
1741     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
1742     pmk = binascii.unhexlify(psk)
1743     p = hostapd.wpa2_params(ssid=ssid)
1744     p['wpa_psk'] = psk
1745     hapd = hostapd.add_ap(apdev[0]['ifname'], p)
1746
1747     pid = find_wpas_process(dev[0])
1748
1749     id = dev[0].connect(ssid, raw_psk=psk, scan_freq="2412",
1750                         only_add_network=True)
1751
1752     logger.info("Checking keys in memory after network profile configuration")
1753     buf = read_process_memory(pid, pmk)
1754     get_key_locations(buf, pmk, "PMK")
1755
1756     dev[0].request("REMOVE_NETWORK all")
1757     logger.info("Checking keys in memory after network profile removal")
1758     buf = read_process_memory(pid, pmk)
1759     get_key_locations(buf, pmk, "PMK")
1760
1761     id = dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
1762                         only_add_network=True)
1763
1764     logger.info("Checking keys in memory before connection")
1765     buf = read_process_memory(pid, pmk)
1766     get_key_locations(buf, pmk, "PMK")
1767
1768     dev[0].connect_network(id, timeout=20)
1769     time.sleep(1)
1770
1771     buf = read_process_memory(pid, pmk)
1772
1773     dev[0].request("DISCONNECT")
1774     dev[0].wait_disconnected()
1775
1776     dev[0].relog()
1777     ptk = None
1778     gtk = None
1779     with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
1780         for l in f.readlines():
1781             if "WPA: PTK - hexdump" in l:
1782                 val = l.strip().split(':')[3].replace(' ', '')
1783                 ptk = binascii.unhexlify(val)
1784             if "WPA: Group Key - hexdump" in l:
1785                 val = l.strip().split(':')[3].replace(' ', '')
1786                 gtk = binascii.unhexlify(val)
1787     if not pmk or not ptk or not gtk:
1788         raise Exception("Could not find keys from debug log")
1789     if len(gtk) != 16:
1790         raise Exception("Unexpected GTK length")
1791
1792     kck = ptk[0:16]
1793     kek = ptk[16:32]
1794     tk = ptk[32:48]
1795
1796     logger.info("Checking keys in memory while associated")
1797     get_key_locations(buf, pmk, "PMK")
1798     if pmk not in buf:
1799         raise HwsimSkip("PMK not found while associated")
1800     if kck not in buf:
1801         raise Exception("KCK not found while associated")
1802     if kek not in buf:
1803         raise Exception("KEK not found while associated")
1804     if tk in buf:
1805         raise Exception("TK found from memory")
1806     if gtk in buf:
1807         get_key_locations(buf, gtk, "GTK")
1808         raise Exception("GTK found from memory")
1809
1810     logger.info("Checking keys in memory after disassociation")
1811     buf = read_process_memory(pid, pmk)
1812     get_key_locations(buf, pmk, "PMK")
1813
1814     # Note: PMK/PSK is still present in network configuration
1815
1816     fname = os.path.join(params['logdir'],
1817                          'wpa2_psk_key_lifetime_in_memory.memctx-')
1818     verify_not_present(buf, kck, fname, "KCK")
1819     verify_not_present(buf, kek, fname, "KEK")
1820     verify_not_present(buf, tk, fname, "TK")
1821     verify_not_present(buf, gtk, fname, "GTK")
1822
1823     dev[0].request("REMOVE_NETWORK all")
1824
1825     logger.info("Checking keys in memory after network profile removal")
1826     buf = read_process_memory(pid, pmk)
1827     get_key_locations(buf, pmk, "PMK")
1828
1829     verify_not_present(buf, pmk, fname, "PMK")
1830     verify_not_present(buf, kck, fname, "KCK")
1831     verify_not_present(buf, kek, fname, "KEK")
1832     verify_not_present(buf, tk, fname, "TK")
1833     verify_not_present(buf, gtk, fname, "GTK")
1834
1835 def test_ap_wpa2_psk_wep(dev, apdev):
1836     """WPA2-PSK AP and WEP enabled"""
1837     ssid = "test-wpa2-psk"
1838     passphrase = 'qwertyuiop'
1839     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
1840     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1841     try:
1842         hapd.set('wep_key0', '"hello"')
1843         raise Exception("WEP key accepted to WPA2 network")
1844     except Exception:
1845         pass
1846
1847 def test_ap_wpa2_psk_wpas_in_bridge(dev, apdev):
1848     """WPA2-PSK AP and wpas interface in a bridge"""
1849     br_ifname='sta-br0'
1850     ifname='wlan5'
1851     try:
1852         _test_ap_wpa2_psk_wpas_in_bridge(dev, apdev)
1853     finally:
1854         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
1855         subprocess.call(['brctl', 'delif', br_ifname, ifname])
1856         subprocess.call(['brctl', 'delbr', br_ifname])
1857         subprocess.call(['iw', ifname, 'set', '4addr', 'off'])
1858
1859 def _test_ap_wpa2_psk_wpas_in_bridge(dev, apdev):
1860     ssid = "test-wpa2-psk"
1861     passphrase = 'qwertyuiop'
1862     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
1863     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1864
1865     br_ifname='sta-br0'
1866     ifname='wlan5'
1867     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1868     subprocess.call(['brctl', 'addbr', br_ifname])
1869     subprocess.call(['brctl', 'setfd', br_ifname, '0'])
1870     subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
1871     subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
1872     subprocess.check_call(['brctl', 'addif', br_ifname, ifname])
1873     wpas.interface_add(ifname, br_ifname=br_ifname)
1874     wpas.dump_monitor()
1875
1876     wpas.connect(ssid, psk=passphrase, scan_freq="2412")
1877     wpas.dump_monitor()
1878
1879 def test_ap_wpa2_psk_ifdown(dev, apdev):
1880     """AP with open mode and external ifconfig down"""
1881     ssid = "test-wpa2-psk"
1882     passphrase = 'qwertyuiop'
1883     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
1884     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1885     bssid = apdev[0]['bssid']
1886
1887     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
1888     subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'down'])
1889     ev = hapd.wait_event(["INTERFACE-DISABLED"], timeout=10)
1890     if ev is None:
1891         raise Exception("No INTERFACE-DISABLED event")
1892     # this wait tests beacon loss detection in mac80211
1893     dev[0].wait_disconnected()
1894     subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'up'])
1895     ev = hapd.wait_event(["INTERFACE-ENABLED"], timeout=10)
1896     if ev is None:
1897         raise Exception("No INTERFACE-ENABLED event")
1898     dev[0].wait_connected()
1899     hwsim_utils.test_connectivity(dev[0], hapd)
1900
1901 def test_ap_wpa2_psk_drop_first_msg_4(dev, apdev):
1902     """WPA2-PSK and first EAPOL-Key msg 4/4 dropped"""
1903     bssid = apdev[0]['bssid']
1904     ssid = "test-wpa2-psk"
1905     passphrase = 'qwertyuiop'
1906     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
1907     params = hostapd.wpa2_params(ssid=ssid)
1908     params['wpa_psk'] = psk
1909     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1910     hapd.request("SET ext_eapol_frame_io 1")
1911     dev[0].request("SET ext_eapol_frame_io 1")
1912     dev[0].connect(ssid, psk=passphrase, scan_freq="2412", wait_connect=False)
1913     addr = dev[0].own_addr()
1914
1915     # EAPOL-Key msg 1/4
1916     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
1917     if ev is None:
1918         raise Exception("Timeout on EAPOL-TX from hostapd")
1919     res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
1920     if "OK" not in res:
1921         raise Exception("EAPOL_RX to wpa_supplicant failed")
1922
1923     # EAPOL-Key msg 2/4
1924     ev = dev[0].wait_event(["EAPOL-TX"], timeout=15)
1925     if ev is None:
1926         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
1927     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
1928     if "OK" not in res:
1929         raise Exception("EAPOL_RX to hostapd failed")
1930
1931     # EAPOL-Key msg 3/4
1932     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
1933     if ev is None:
1934         raise Exception("Timeout on EAPOL-TX from hostapd")
1935     res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
1936     if "OK" not in res:
1937         raise Exception("EAPOL_RX to wpa_supplicant failed")
1938
1939     # EAPOL-Key msg 4/4
1940     ev = dev[0].wait_event(["EAPOL-TX"], timeout=15)
1941     if ev is None:
1942         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
1943     logger.info("Drop the first EAPOL-Key msg 4/4")
1944
1945     # wpa_supplicant believes now that 4-way handshake succeeded; hostapd
1946     # doesn't. Use normal EAPOL TX/RX to handle retries.
1947     hapd.request("SET ext_eapol_frame_io 0")
1948     dev[0].request("SET ext_eapol_frame_io 0")
1949     dev[0].wait_connected()
1950
1951     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=15)
1952     if ev is None:
1953         raise Exception("Timeout on AP-STA-CONNECTED from hostapd")
1954
1955     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.1)
1956     if ev is not None:
1957         logger.info("Disconnection detected")
1958         # The EAPOL-Key retries are supposed to allow the connection to be
1959         # established without having to reassociate. However, this does not
1960         # currently work since mac80211 ends up encrypting EAPOL-Key msg 4/4
1961         # after the pairwise key has been configured and AP will drop those and
1962         # disconnect the station after reaching retransmission limit. Connection
1963         # is then established after reassociation. Once that behavior has been
1964         # optimized to prevent EAPOL-Key frame encryption for retransmission
1965         # case, this exception can be uncommented here.
1966         #raise Exception("Unexpected disconnection")
1967
1968 def test_ap_wpa2_psk_disable_enable(dev, apdev):
1969     """WPA2-PSK AP getting disabled and re-enabled"""
1970     ssid = "test-wpa2-psk"
1971     passphrase = 'qwertyuiop'
1972     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
1973     params = hostapd.wpa2_params(ssid=ssid)
1974     params['wpa_psk'] = psk
1975     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1976     dev[0].connect(ssid, raw_psk=psk, scan_freq="2412")
1977
1978     for i in range(2):
1979         hapd.request("DISABLE")
1980         dev[0].wait_disconnected()
1981         hapd.request("ENABLE")
1982         dev[0].wait_connected()
1983         hwsim_utils.test_connectivity(dev[0], hapd)
1984
1985 def test_ap_wpa2_psk_incorrect_passphrase(dev, apdev):
1986     """WPA2-PSK AP and station using incorrect passphrase"""
1987     ssid = "test-wpa2-psk"
1988     passphrase = 'qwertyuiop'
1989     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
1990     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1991     dev[0].connect(ssid, psk="incorrect passphrase", scan_freq="2412",
1992                    wait_connect=False)
1993     ev = hapd.wait_event(["AP-STA-POSSIBLE-PSK-MISMATCH"], timeout=10)
1994     if ev is None:
1995         raise Exception("No AP-STA-POSSIBLE-PSK-MISMATCH reported")
1996     dev[0].dump_monitor()
1997
1998     hapd.disable()
1999     hapd.set("wpa_passphrase", "incorrect passphrase")
2000     hapd.enable()
2001
2002     dev[0].wait_connected(timeout=20)
2003
2004 def test_ap_wpa_ie_parsing(dev, apdev):
2005     """WPA IE parsing"""
2006     skip_with_fips(dev[0])
2007     ssid = "test-wpa-psk"
2008     passphrase = 'qwertyuiop'
2009     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
2010     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2011     id = dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
2012                         only_add_network=True)
2013
2014     tests = [ "dd040050f201",
2015               "dd050050f20101",
2016               "dd060050f2010100",
2017               "dd060050f2010001",
2018               "dd070050f201010000",
2019               "dd080050f20101000050",
2020               "dd090050f20101000050f2",
2021               "dd0a0050f20101000050f202",
2022               "dd0b0050f20101000050f20201",
2023               "dd0c0050f20101000050f2020100",
2024               "dd0c0050f20101000050f2020000",
2025               "dd0c0050f20101000050f202ffff",
2026               "dd0d0050f20101000050f202010000",
2027               "dd0e0050f20101000050f20201000050",
2028               "dd0f0050f20101000050f20201000050f2",
2029               "dd100050f20101000050f20201000050f202",
2030               "dd110050f20101000050f20201000050f20201",
2031               "dd120050f20101000050f20201000050f2020100",
2032               "dd120050f20101000050f20201000050f2020000",
2033               "dd120050f20101000050f20201000050f202ffff",
2034               "dd130050f20101000050f20201000050f202010000",
2035               "dd140050f20101000050f20201000050f20201000050",
2036               "dd150050f20101000050f20201000050f20201000050f2" ]
2037     for t in tests:
2038         try:
2039             if "OK" not in dev[0].request("VENDOR_ELEM_ADD 13 " + t):
2040                 raise Exception("VENDOR_ELEM_ADD failed")
2041             dev[0].select_network(id)
2042             ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
2043             if ev is None:
2044                 raise Exception("Association rejection not reported")
2045             dev[0].request("DISCONNECT")
2046             dev[0].dump_monitor()
2047         finally:
2048             dev[0].request("VENDOR_ELEM_REMOVE 13 *")
2049
2050     tests = [ "dd170050f20101000050f20201000050f20201000050f202ff",
2051               "dd180050f20101000050f20201000050f20201000050f202ffff",
2052               "dd190050f20101000050f20201000050f20201000050f202ffffff" ]
2053     for t in tests:
2054         try:
2055             if "OK" not in dev[0].request("VENDOR_ELEM_ADD 13 " + t):
2056                 raise Exception("VENDOR_ELEM_ADD failed")
2057             dev[0].select_network(id)
2058             dev[0].wait_connected()
2059             dev[0].request("DISCONNECT")
2060             dev[0].dump_monitor()
2061         finally:
2062             dev[0].request("VENDOR_ELEM_REMOVE 13 *")
2063
2064 def test_ap_wpa2_psk_no_random(dev, apdev):
2065     """WPA2-PSK AP and no random numbers available"""
2066     ssid = "test-wpa2-psk"
2067     passphrase = 'qwertyuiop'
2068     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
2069     params = hostapd.wpa2_params(ssid=ssid)
2070     params['wpa_psk'] = psk
2071     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2072     with fail_test(hapd, 1, "wpa_gmk_to_gtk"):
2073         id = dev[0].connect(ssid, raw_psk=psk, scan_freq="2412",
2074                             wait_connect=False)
2075         ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=15)
2076         if ev is None:
2077             raise Exception("Disconnection event not reported")
2078         dev[0].request("DISCONNECT")
2079         dev[0].select_network(id, freq=2412)
2080         dev[0].wait_connected()
2081
2082 def test_rsn_ie_proto_psk_sta(dev, apdev):
2083     """RSN element protocol testing for PSK cases on STA side"""
2084     bssid = apdev[0]['bssid']
2085     ssid = "test-wpa2-psk"
2086     passphrase = 'qwertyuiop'
2087     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
2088     # This is the RSN element used normally by hostapd
2089     params['own_ie_override'] = '30140100000fac040100000fac040100000fac020c00'
2090     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2091     if "FAIL" not in hapd.request("SET own_ie_override qwerty"):
2092         raise Exception("Invalid own_ie_override value accepted")
2093     id = dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
2094
2095     tests = [ ('No RSN Capabilities field',
2096                '30120100000fac040100000fac040100000fac02'),
2097               ('Reserved RSN Capabilities bits set',
2098                '30140100000fac040100000fac040100000fac023cff'),
2099               ('Extra pairwise cipher suite (unsupported)',
2100                '30180100000fac040200ffffffff000fac040100000fac020c00'),
2101               ('Extra AKM suite (unsupported)',
2102                '30180100000fac040100000fac040200ffffffff000fac020c00'),
2103               ('PMKIDCount field included',
2104                '30160100000fac040100000fac040100000fac020c000000'),
2105               ('Unexpected Group Management Cipher Suite with PMF disabled',
2106                '301a0100000fac040100000fac040100000fac020c000000000fac06'),
2107               ('Extra octet after defined fields (future extensibility)',
2108                '301b0100000fac040100000fac040100000fac020c000000000fac0600') ]
2109     for txt,ie in tests:
2110         dev[0].request("DISCONNECT")
2111         dev[0].wait_disconnected()
2112         logger.info(txt)
2113         hapd.disable()
2114         hapd.set('own_ie_override', ie)
2115         hapd.enable()
2116         dev[0].request("BSS_FLUSH 0")
2117         dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
2118         dev[0].select_network(id, freq=2412)
2119         dev[0].wait_connected()
2120
2121 def test_ap_cli_order(dev, apdev):
2122     ssid = "test-rsn-setup"
2123     passphrase = 'zzzzzzzz'
2124     ifname = apdev[0]['ifname']
2125
2126     hapd_global = hostapd.HostapdGlobal()
2127     hapd_global.remove(ifname)
2128     hapd_global.add(ifname)
2129
2130     hapd = hostapd.Hostapd(ifname)
2131     hapd.set_defaults()
2132     hapd.set('ssid', ssid)
2133     hapd.set('wpa_passphrase', passphrase)
2134     hapd.set('rsn_pairwise', 'CCMP')
2135     hapd.set('wpa_key_mgmt', 'WPA-PSK')
2136     hapd.set('wpa', '2')
2137     hapd.enable()
2138     cfg = hapd.get_config()
2139     if cfg['group_cipher'] != 'CCMP':
2140         raise Exception("Unexpected group_cipher: " + cfg['group_cipher'])
2141     if cfg['rsn_pairwise_cipher'] != 'CCMP':
2142         raise Exception("Unexpected rsn_pairwise_cipher: " + cfg['rsn_pairwise_cipher'])
2143
2144     ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=30)
2145     if ev is None:
2146         raise Exception("AP startup timed out")
2147     if "AP-ENABLED" not in ev:
2148         raise Exception("AP startup failed")
2149
2150     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
2151
2152 def set_test_assoc_ie(dev, ie):
2153     if "OK" not in dev.request("TEST_ASSOC_IE " + ie):
2154         raise Exception("Could not set TEST_ASSOC_IE")
2155
2156 def test_ap_wpa2_psk_assoc_rsn(dev, apdev):
2157     """WPA2-PSK AP and association request RSN IE differences"""
2158     ssid = "test-wpa2-psk"
2159     passphrase = 'qwertyuiop'
2160     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
2161     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2162
2163     tests = [ ("Normal wpa_supplicant assoc req RSN IE",
2164                "30140100000fac040100000fac040100000fac020000"),
2165               ("RSN IE without RSN Capabilities",
2166                "30120100000fac040100000fac040100000fac02") ]
2167     for title, ie in tests:
2168         logger.info(title)
2169         set_test_assoc_ie(dev[0], ie)
2170         dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
2171         dev[0].request("REMOVE_NETWORK all")
2172         dev[0].wait_disconnected()
2173
2174     tests = [ ("WPA IE instead of RSN IE and only RSN enabled on AP",
2175                "dd160050f20101000050f20201000050f20201000050f202", 40),
2176               ("Empty RSN IE", "3000", 40),
2177               ("RSN IE with truncated Version", "300101", 40),
2178               ("RSN IE with only Version", "30020100", 43) ]
2179     for title, ie, status in tests:
2180         logger.info(title)
2181         set_test_assoc_ie(dev[0], ie)
2182         dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
2183                        wait_connect=False)
2184         ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
2185         if ev is None:
2186             raise Exception("Association rejection not reported")
2187         if "status_code=" + str(status) not in ev:
2188             raise Exception("Unexpected status code: " + ev)
2189         dev[0].request("REMOVE_NETWORK all")
2190         dev[0].dump_monitor()