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