1# Cipher suite tests
2# Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7from remotehost import remote_compatible
8import time
9import logging
10logger = logging.getLogger()
11import os
12import subprocess
13
14import hwsim_utils
15import hostapd
16from utils import *
17from wlantest import Wlantest
18from wpasupplicant import WpaSupplicant
19
20KT_PTK, KT_GTK, KT_IGTK, KT_BIGTK = range(4)
21
22def check_cipher(dev, ap, cipher, group_cipher=None):
23    if cipher not in dev.get_capability("pairwise"):
24        raise HwsimSkip("Cipher %s not supported" % cipher)
25    if group_cipher and group_cipher not in dev.get_capability("group"):
26        raise HwsimSkip("Cipher %s not supported" % group_cipher)
27    params = {"ssid": "test-wpa2-psk",
28              "wpa_passphrase": "12345678",
29              "wpa": "2",
30              "wpa_key_mgmt": "WPA-PSK",
31              "rsn_pairwise": cipher}
32    if group_cipher:
33        params["group_cipher"] = group_cipher
34    else:
35        group_cipher = cipher
36    hapd = hostapd.add_ap(ap, params)
37    dev.connect("test-wpa2-psk", psk="12345678",
38                pairwise=cipher, group=group_cipher, scan_freq="2412")
39    hapd.wait_sta()
40    hwsim_utils.test_connectivity(dev, hapd)
41
42def check_group_mgmt_cipher(dev, ap, cipher, sta_req_cipher=None):
43    if cipher not in dev.get_capability("group_mgmt"):
44        raise HwsimSkip("Cipher %s not supported" % cipher)
45    params = {"ssid": "test-wpa2-psk-pmf",
46              "wpa_passphrase": "12345678",
47              "wpa": "2",
48              "ieee80211w": "2",
49              "wpa_key_mgmt": "WPA-PSK-SHA256",
50              "rsn_pairwise": "CCMP",
51              "group_mgmt_cipher": cipher}
52    hapd = hostapd.add_ap(ap, params)
53
54    Wlantest.setup(hapd)
55    wt = Wlantest()
56    wt.flush()
57    wt.add_passphrase("12345678")
58
59    dev.connect("test-wpa2-psk-pmf", psk="12345678", ieee80211w="2",
60                key_mgmt="WPA-PSK-SHA256", group_mgmt=sta_req_cipher,
61                pairwise="CCMP", group="CCMP", scan_freq="2412")
62    hapd.wait_sta()
63    hwsim_utils.test_connectivity(dev, hapd)
64    hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff")
65    dev.wait_disconnected()
66    if wt.get_bss_counter('valid_bip_mmie', ap['bssid']) < 1:
67        raise Exception("No valid BIP MMIE seen")
68    if wt.get_bss_counter('bip_deauth', ap['bssid']) < 1:
69        raise Exception("No valid BIP deauth seen")
70
71    if cipher == "AES-128-CMAC":
72        group_mgmt = "BIP"
73    else:
74        group_mgmt = cipher
75    res = wt.info_bss('group_mgmt', ap['bssid']).strip()
76    if res != group_mgmt:
77        raise Exception("Unexpected group mgmt cipher: " + res)
78
79@remote_compatible
80def test_ap_cipher_tkip(dev, apdev):
81    """WPA2-PSK/TKIP connection"""
82    skip_with_fips(dev[0])
83    skip_without_tkip(dev[0])
84    check_cipher(dev[0], apdev[0], "TKIP")
85
86@remote_compatible
87def test_ap_cipher_tkip_countermeasures_ap(dev, apdev):
88    """WPA-PSK/TKIP countermeasures (detected by AP)"""
89    skip_with_fips(dev[0])
90    skip_without_tkip(dev[0])
91    testfile = "/sys/kernel/debug/ieee80211/%s/netdev:%s/tkip_mic_test" % (dev[0].get_driver_status_field("phyname"), dev[0].ifname)
92    if dev[0].cmd_execute(["ls", testfile])[0] != 0:
93        raise HwsimSkip("tkip_mic_test not supported in mac80211")
94
95    params = {"ssid": "tkip-countermeasures",
96              "wpa_passphrase": "12345678",
97              "wpa": "1",
98              "wpa_key_mgmt": "WPA-PSK",
99              "wpa_pairwise": "TKIP"}
100    hapd = hostapd.add_ap(apdev[0], params)
101
102    dev[0].connect("tkip-countermeasures", psk="12345678",
103                   pairwise="TKIP", group="TKIP", scan_freq="2412")
104
105    hapd.wait_sta()
106    time.sleep(1)
107    dev[0].dump_monitor()
108    hapd.note("Michael MIC failure to BSSID")
109    dev[0].cmd_execute(["echo", "-n", apdev[0]['bssid'], ">", testfile],
110                       shell=True)
111    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
112    if ev is not None:
113        raise Exception("Unexpected disconnection on first Michael MIC failure")
114
115    hapd.note("Michael MIC failure to broadcast")
116    dev[0].cmd_execute(["echo", "-n", "ff:ff:ff:ff:ff:ff", ">", testfile],
117                       shell=True)
118    ev = dev[0].wait_disconnected(timeout=10,
119                                  error="No disconnection after two Michael MIC failures")
120    if "reason=14" not in ev:
121        raise Exception("Unexpected disconnection reason: " + ev)
122    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
123    if ev is not None:
124        raise Exception("Unexpected connection during TKIP countermeasures")
125
126def test_ap_cipher_tkip_countermeasures_ap_mixed_mode(dev, apdev):
127    """WPA+WPA2-PSK/TKIP countermeasures (detected by mixed mode AP)"""
128    skip_with_fips(dev[0])
129    skip_without_tkip(dev[0])
130    testfile = "/sys/kernel/debug/ieee80211/%s/netdev:%s/tkip_mic_test" % (dev[0].get_driver_status_field("phyname"), dev[0].ifname)
131    if dev[0].cmd_execute(["ls", testfile])[0] != 0:
132        raise HwsimSkip("tkip_mic_test not supported in mac80211")
133
134    params = {"ssid": "tkip-countermeasures",
135              "wpa_passphrase": "12345678",
136              "wpa": "3",
137              "wpa_key_mgmt": "WPA-PSK",
138              "wpa_pairwise": "TKIP",
139              "rsn_pairwise": "CCMP"}
140    hapd = hostapd.add_ap(apdev[0], params)
141
142    dev[0].connect("tkip-countermeasures", psk="12345678",
143                   pairwise="TKIP", group="TKIP", scan_freq="2412")
144    dev[1].connect("tkip-countermeasures", psk="12345678",
145                   pairwise="CCMP", scan_freq="2412")
146
147    dev[0].dump_monitor()
148    dev[0].cmd_execute(["echo", "-n", apdev[0]['bssid'], ">", testfile],
149                       shell=True)
150    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
151    if ev is not None:
152        raise Exception("Unexpected disconnection on first Michael MIC failure")
153
154    dev[0].cmd_execute(["echo", "-n", "ff:ff:ff:ff:ff:ff", ">", testfile],
155                       shell=True)
156
157    ev = dev[0].wait_disconnected(timeout=10,
158                                  error="No disconnection after two Michael MIC failures")
159    if "reason=14" not in ev:
160        raise Exception("Unexpected disconnection reason: " + ev)
161
162    ev = dev[1].wait_disconnected(timeout=10,
163                                  error="No disconnection after two Michael MIC failures (2)")
164    if "reason=14" not in ev:
165        raise Exception("Unexpected disconnection reason (2): " + ev)
166
167    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
168    if ev is not None:
169        raise Exception("Unexpected connection during TKIP countermeasures (1)")
170    ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
171    if ev is not None:
172        raise Exception("Unexpected connection during TKIP countermeasures (2)")
173
174@remote_compatible
175def test_ap_cipher_tkip_countermeasures_sta(dev, apdev):
176    """WPA-PSK/TKIP countermeasures (detected by STA)"""
177    skip_with_fips(dev[0])
178    skip_without_tkip(dev[0])
179    params = {"ssid": "tkip-countermeasures",
180              "wpa_passphrase": "12345678",
181              "wpa": "1",
182              "wpa_key_mgmt": "WPA-PSK",
183              "wpa_pairwise": "TKIP"}
184    hapd = hostapd.add_ap(apdev[0], params)
185
186    testfile = "/sys/kernel/debug/ieee80211/%s/netdev:%s/tkip_mic_test" % (hapd.get_driver_status_field("phyname"), apdev[0]['ifname'])
187    if hapd.cmd_execute(["ls", testfile])[0] != 0:
188        raise HwsimSkip("tkip_mic_test not supported in mac80211")
189
190    dev[0].connect("tkip-countermeasures", psk="12345678",
191                   pairwise="TKIP", group="TKIP", scan_freq="2412")
192
193    dev[0].dump_monitor()
194    hapd.cmd_execute(["echo", "-n", dev[0].own_addr(), ">", testfile],
195                     shell=True)
196    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
197    if ev is not None:
198        raise Exception("Unexpected disconnection on first Michael MIC failure")
199
200    hapd.cmd_execute(["echo", "-n", "ff:ff:ff:ff:ff:ff", ">", testfile],
201                     shell=True)
202    ev = dev[0].wait_disconnected(timeout=10,
203                                  error="No disconnection after two Michael MIC failures")
204    if "reason=14 locally_generated=1" not in ev:
205        raise Exception("Unexpected disconnection reason: " + ev)
206    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
207    if ev is not None:
208        raise Exception("Unexpected connection during TKIP countermeasures")
209
210@long_duration_test
211def test_ap_cipher_tkip_countermeasures_sta2(dev, apdev):
212    """WPA-PSK/TKIP countermeasures (detected by two STAs)"""
213    skip_with_fips(dev[0])
214    skip_without_tkip(dev[0])
215    params = {"ssid": "tkip-countermeasures",
216              "wpa_passphrase": "12345678",
217              "wpa": "1",
218              "wpa_key_mgmt": "WPA-PSK",
219              "wpa_pairwise": "TKIP"}
220    hapd = hostapd.add_ap(apdev[0], params)
221
222    testfile = "/sys/kernel/debug/ieee80211/%s/netdev:%s/tkip_mic_test" % (hapd.get_driver_status_field("phyname"), apdev[0]['ifname'])
223    if hapd.cmd_execute(["ls", testfile])[0] != 0:
224        raise HwsimSkip("tkip_mic_test not supported in mac80211")
225
226    dev[0].connect("tkip-countermeasures", psk="12345678",
227                   pairwise="TKIP", group="TKIP", scan_freq="2412")
228    dev[0].dump_monitor()
229    hapd.wait_sta()
230    id = dev[1].connect("tkip-countermeasures", psk="12345678",
231                        pairwise="TKIP", group="TKIP", scan_freq="2412")
232    dev[1].dump_monitor()
233    hapd.wait_sta()
234
235    hapd.cmd_execute(["echo", "-n", "ff:ff:ff:ff:ff:ff", ">", testfile],
236                     shell=True)
237    ev0 = dev[0].wait_disconnected(timeout=10,
238                                   error="No disconnection after two Michael MIC failure")
239    ev1 = dev[1].wait_disconnected(timeout=5,
240                                   error="No disconnection after two Michael MIC failure")
241    # There is a race condition here between EAPOL-Key Request frame initiated
242    # 4-way handshake from one of the STAs being able to start before the AP
243    # has received the Michael MIC error report from the other STA. If the new
244    # 4-way handshake has been started, it is possible for the that 4-way
245    # handshake to fail due to being unable to send an EAPOL-Key frame if the
246    # AP deauthenticates the STA in the middle of that exchange. That ends up
247    # showing a different disconnection reason, so we need to accept both the
248    # normal reason code 14 for Michael MIC failures and the locally generated
249    # disconnection.
250    if "reason=14" not in ev0:
251        if "reason=1 locally_generated=1" not in ev0:
252            raise Exception("Unexpected disconnection reason (dev0): " + ev0)
253    if "reason=14" not in ev1:
254        if "reason=1 locally_generated=1" not in ev1:
255            raise Exception("Unexpected disconnection reason (dev1): " + ev1)
256
257    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
258    if ev is not None:
259        raise Exception("Unexpected connection during TKIP countermeasures")
260    ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
261    if ev is not None:
262        raise Exception("Unexpected connection during TKIP countermeasures")
263
264    dev[0].request("REMOVE_NETWORK all")
265    logger.info("Waiting for TKIP countermeasures to end")
266    connected = False
267    start = os.times()[4]
268    while True:
269        now = os.times()[4]
270        if start + 70 < now:
271            break
272        dev[0].connect("tkip-countermeasures", psk="12345678",
273                       pairwise="TKIP", group="TKIP", scan_freq="2412",
274                       wait_connect=False)
275        ev = dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT",
276                                "CTRL-EVENT-CONNECTED"], timeout=10)
277        if ev is None:
278            raise Exception("No connection result")
279        if "CTRL-EVENT-CONNECTED" in ev:
280            connected = True
281            break
282        if "status_code=1" not in ev:
283            raise Exception("Unexpected connection failure reason during TKIP countermeasures: " + ev)
284        dev[0].request("REMOVE_NETWORK all")
285        time.sleep(1)
286        dev[0].dump_monitor()
287        dev[1].dump_monitor()
288    if not connected:
289        raise Exception("No connection after TKIP countermeasures terminated")
290
291    ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
292    if ev is None:
293        dev[1].request("DISCONNECT")
294        dev[1].select_network(id)
295        dev[1].wait_connected()
296
297@remote_compatible
298def test_ap_cipher_ccmp(dev, apdev):
299    """WPA2-PSK/CCMP connection"""
300    check_cipher(dev[0], apdev[0], "CCMP")
301
302def test_ap_cipher_gcmp(dev, apdev):
303    """WPA2-PSK/GCMP connection"""
304    check_cipher(dev[0], apdev[0], "GCMP")
305
306def test_ap_cipher_ccmp_256(dev, apdev):
307    """WPA2-PSK/CCMP-256 connection"""
308    check_cipher(dev[0], apdev[0], "CCMP-256")
309
310def test_ap_cipher_gcmp_256(dev, apdev):
311    """WPA2-PSK/GCMP-256 connection"""
312    check_cipher(dev[0], apdev[0], "GCMP-256")
313
314def test_ap_cipher_gcmp_256_group_gcmp_256(dev, apdev):
315    """WPA2-PSK/GCMP-256 connection with group cipher override GCMP-256"""
316    check_cipher(dev[0], apdev[0], "GCMP-256", "GCMP-256")
317
318def test_ap_cipher_gcmp_256_group_gcmp(dev, apdev):
319    """WPA2-PSK/GCMP-256 connection with group cipher override GCMP"""
320    check_cipher(dev[0], apdev[0], "GCMP-256", "GCMP")
321
322def test_ap_cipher_gcmp_256_group_ccmp_256(dev, apdev):
323    """WPA2-PSK/GCMP-256 connection with group cipher override CCMP-256"""
324    check_cipher(dev[0], apdev[0], "GCMP-256", "CCMP-256")
325
326def test_ap_cipher_gcmp_256_group_ccmp(dev, apdev):
327    """WPA2-PSK/GCMP-256 connection with group cipher override CCMP"""
328    check_cipher(dev[0], apdev[0], "GCMP-256", "CCMP")
329
330def test_ap_cipher_gcmp_ccmp(dev, apdev, params):
331    """WPA2-PSK/GCMP/CCMP ciphers"""
332    config = os.path.join(params['logdir'], 'ap_cipher_gcmp_ccmp.conf')
333
334    for cipher in ["CCMP", "GCMP", "CCMP-256", "GCMP-256"]:
335        if cipher not in dev[0].get_capability("pairwise"):
336            raise HwsimSkip("Cipher %s not supported" % cipher)
337        if cipher not in dev[0].get_capability("group"):
338            raise HwsimSkip("Group cipher %s not supported" % cipher)
339
340    params = {"ssid": "test-wpa2-psk",
341              "wpa_passphrase": "12345678",
342              "wpa": "2",
343              "wpa_key_mgmt": "WPA-PSK",
344              "rsn_pairwise": "CCMP GCMP CCMP-256 GCMP-256"}
345    hapd = hostapd.add_ap(apdev[0], params)
346
347
348    for cipher in ["CCMP", "GCMP", "CCMP-256", "GCMP-256"]:
349        dev[0].connect("test-wpa2-psk", psk="12345678",
350                       pairwise=cipher, group="CCMP", scan_freq="2412")
351        if dev[0].get_status_field("group_cipher") != "CCMP":
352            raise Exception("Unexpected group_cipher")
353        if dev[0].get_status_field("pairwise_cipher") != cipher:
354            raise Exception("Unexpected pairwise_cipher")
355        dev[0].request("REMOVE_NETWORK all")
356        dev[0].wait_disconnected()
357
358    dev[0].connect("test-wpa2-psk", psk="12345678",
359                   pairwise="CCMP CCMP-256 GCMP GCMP-256",
360                   group="CCMP CCMP-256 GCMP GCMP-256", scan_freq="2412")
361    if dev[0].get_status_field("group_cipher") != "CCMP":
362        raise Exception("Unexpected group_cipher")
363    res = dev[0].get_status_field("pairwise_cipher")
364    if res != "CCMP-256" and res != "GCMP-256":
365        raise Exception("Unexpected pairwise_cipher")
366
367    try:
368        with open(config, "w") as f:
369            f.write("network={\n" +
370                    "\tssid=\"test-wpa2-psk\"\n" +
371                    "\tkey_mgmt=WPA-PSK\n" +
372                    "\tpsk=\"12345678\"\n" +
373                    "\tpairwise=GCMP\n" +
374                    "\tgroup=CCMP\n" +
375                    "\tscan_freq=2412\n" +
376                    "}\n")
377
378        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
379        wpas.interface_add("wlan5", config=config)
380        wpas.wait_connected()
381        if wpas.get_status_field("group_cipher") != "CCMP":
382            raise Exception("Unexpected group_cipher")
383        if wpas.get_status_field("pairwise_cipher") != "GCMP":
384            raise Exception("Unexpected pairwise_cipher")
385    finally:
386        os.remove(config)
387
388@remote_compatible
389def test_ap_cipher_mixed_wpa_wpa2(dev, apdev):
390    """WPA2-PSK/CCMP/ and WPA-PSK/TKIP mixed configuration"""
391    skip_with_fips(dev[0])
392    skip_without_tkip(dev[0])
393    ssid = "test-wpa-wpa2-psk"
394    passphrase = "12345678"
395    params = {"ssid": ssid,
396              "wpa_passphrase": passphrase,
397              "wpa": "3",
398              "wpa_key_mgmt": "WPA-PSK",
399              "rsn_pairwise": "CCMP",
400              "wpa_pairwise": "TKIP"}
401    hapd = hostapd.add_ap(apdev[0], params)
402    dev[0].flush_scan_cache()
403    dev[0].connect(ssid, psk=passphrase, proto="WPA2",
404                   pairwise="CCMP", group="TKIP", scan_freq="2412")
405    status = dev[0].get_status()
406    if status['key_mgmt'] != 'WPA2-PSK':
407        raise Exception("Incorrect key_mgmt reported")
408    if status['pairwise_cipher'] != 'CCMP':
409        raise Exception("Incorrect pairwise_cipher reported")
410    if status['group_cipher'] != 'TKIP':
411        raise Exception("Incorrect group_cipher reported")
412    bss = dev[0].get_bss(apdev[0]['bssid'])
413    if bss['ssid'] != ssid:
414        raise Exception("Unexpected SSID in the BSS entry")
415    if "[WPA-PSK-TKIP]" not in bss['flags']:
416        raise Exception("Missing BSS flag WPA-PSK-TKIP")
417    if "[WPA2-PSK-CCMP]" not in bss['flags']:
418        raise Exception("Missing BSS flag WPA2-PSK-CCMP")
419    hapd.wait_sta()
420    hwsim_utils.test_connectivity(dev[0], hapd)
421
422    dev[1].connect(ssid, psk=passphrase, proto="WPA",
423                   pairwise="TKIP", group="TKIP", scan_freq="2412")
424    status = dev[1].get_status()
425    if status['key_mgmt'] != 'WPA-PSK':
426        raise Exception("Incorrect key_mgmt reported")
427    if status['pairwise_cipher'] != 'TKIP':
428        raise Exception("Incorrect pairwise_cipher reported")
429    if status['group_cipher'] != 'TKIP':
430        raise Exception("Incorrect group_cipher reported")
431    hapd.wait_sta()
432    hwsim_utils.test_connectivity(dev[1], hapd)
433    hwsim_utils.test_connectivity(dev[0], dev[1])
434
435@remote_compatible
436def test_ap_cipher_wpa_sae(dev, apdev):
437    """WPA-PSK/TKIP and SAE mixed AP - WPA IE and RSNXE coexistence"""
438    skip_with_fips(dev[0])
439    skip_without_tkip(dev[0])
440    check_sae_capab(dev[0])
441    ssid = "test-wpa-sae"
442    passphrase = "12345678"
443    params = {"ssid": ssid,
444              "wpa_passphrase": passphrase,
445              "wpa": "3",
446              "wpa_key_mgmt": "WPA-PSK SAE",
447              "rsn_pairwise": "CCMP",
448              "wpa_pairwise": "TKIP",
449              "sae_pwe": "1"}
450    hapd = hostapd.add_ap(apdev[0], params)
451    dev[0].flush_scan_cache()
452
453    dev[0].connect(ssid, psk=passphrase, proto="WPA",
454                   pairwise="TKIP", group="TKIP", scan_freq="2412")
455    status = dev[0].get_status()
456    if status['key_mgmt'] != 'WPA-PSK':
457        raise Exception("Incorrect key_mgmt reported")
458    if status['pairwise_cipher'] != 'TKIP':
459        raise Exception("Incorrect pairwise_cipher reported")
460    if status['group_cipher'] != 'TKIP':
461        raise Exception("Incorrect group_cipher reported")
462    hapd.wait_sta()
463    hwsim_utils.test_connectivity(dev[0], hapd)
464
465@remote_compatible
466def test_ap_cipher_bip(dev, apdev):
467    """WPA2-PSK with BIP"""
468    check_group_mgmt_cipher(dev[0], apdev[0], "AES-128-CMAC")
469
470def test_ap_cipher_bip_req(dev, apdev):
471    """WPA2-PSK with BIP required"""
472    check_group_mgmt_cipher(dev[0], apdev[0], "AES-128-CMAC", "AES-128-CMAC")
473
474def test_ap_cipher_bip_req2(dev, apdev):
475    """WPA2-PSK with BIP required (2)"""
476    check_group_mgmt_cipher(dev[0], apdev[0], "AES-128-CMAC",
477                            "AES-128-CMAC BIP-GMAC-128 BIP-GMAC-256 BIP-CMAC-256")
478
479def test_ap_cipher_bip_gmac_128(dev, apdev):
480    """WPA2-PSK with BIP-GMAC-128"""
481    check_group_mgmt_cipher(dev[0], apdev[0], "BIP-GMAC-128")
482
483def test_ap_cipher_bip_gmac_128_req(dev, apdev):
484    """WPA2-PSK with BIP-GMAC-128 required"""
485    check_group_mgmt_cipher(dev[0], apdev[0], "BIP-GMAC-128", "BIP-GMAC-128")
486
487def test_ap_cipher_bip_gmac_256(dev, apdev):
488    """WPA2-PSK with BIP-GMAC-256"""
489    check_group_mgmt_cipher(dev[0], apdev[0], "BIP-GMAC-256")
490
491def test_ap_cipher_bip_gmac_256_req(dev, apdev):
492    """WPA2-PSK with BIP-GMAC-256 required"""
493    check_group_mgmt_cipher(dev[0], apdev[0], "BIP-GMAC-256", "BIP-GMAC-256")
494
495def test_ap_cipher_bip_cmac_256(dev, apdev):
496    """WPA2-PSK with BIP-CMAC-256"""
497    check_group_mgmt_cipher(dev[0], apdev[0], "BIP-CMAC-256")
498
499def test_ap_cipher_bip_cmac_256_req(dev, apdev):
500    """WPA2-PSK with BIP-CMAC-256 required"""
501    check_group_mgmt_cipher(dev[0], apdev[0], "BIP-CMAC-256", "BIP-CMAC-256")
502
503def test_ap_cipher_bip_req_mismatch(dev, apdev):
504    """WPA2-PSK with BIP cipher mismatch"""
505    group_mgmt = dev[0].get_capability("group_mgmt")
506    for cipher in ["AES-128-CMAC", "BIP-GMAC-256"]:
507        if cipher not in group_mgmt:
508            raise HwsimSkip("Cipher %s not supported" % cipher)
509
510    params = {"ssid": "test-wpa2-psk-pmf",
511              "wpa_passphrase": "12345678",
512              "wpa": "2",
513              "ieee80211w": "2",
514              "wpa_key_mgmt": "WPA-PSK-SHA256",
515              "rsn_pairwise": "CCMP",
516              "group_mgmt_cipher": "AES-128-CMAC"}
517    hapd = hostapd.add_ap(apdev[0], params)
518
519    dev[0].scan_for_bss(hapd.own_addr(), 2412)
520    id = dev[0].connect("test-wpa2-psk-pmf", psk="12345678", ieee80211w="2",
521                        key_mgmt="WPA-PSK-SHA256", group_mgmt="BIP-GMAC-256",
522                        pairwise="CCMP", group="CCMP", scan_freq="2412",
523                        wait_connect=False)
524    ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
525                            "CTRL-EVENT-CONNECTED"], timeout=10)
526    if ev is None:
527        raise Exception("Network selection result not indicated")
528    if "CTRL-EVENT-CONNECTED" in ev:
529        raise Exception("Unexpected connection")
530
531    dev[0].request("DISCONNECT")
532    dev[0].set_network(id, "group_mgmt", "AES-128-CMAC")
533    dev[0].select_network(id)
534    dev[0].wait_connected()
535
536def get_rx_spec(phy, keytype=KT_PTK):
537    keys = "/sys/kernel/debug/ieee80211/%s/keys" % (phy)
538    try:
539        for key in os.listdir(keys):
540            keydir = keys + "/" + key
541            with open(keydir + '/keyidx') as f:
542                keyid = int(f.read())
543            if keytype in (KT_PTK, KT_GTK) and keyid not in (0, 1, 2, 3):
544                continue
545            if keytype == KT_IGTK and keyid not in (4, 5):
546                continue
547            if keytype == KT_BIGTK and keyid not in (6, 7):
548                continue
549            files = os.listdir(keydir)
550            if keytype == KT_PTK and "station" not in files:
551                continue
552            if keytype != KT_PTK and "station" in files:
553                continue
554            with open(keydir + "/rx_spec") as f:
555                return f.read()
556    except OSError as e:
557        raise HwsimSkip("debugfs not supported in mac80211")
558    return None
559
560def get_tk_replay_counter(phy, keytype=KT_PTK):
561    keys = "/sys/kernel/debug/ieee80211/%s/keys" % (phy)
562    try:
563        for key in os.listdir(keys):
564            keydir = keys + "/" + key
565            with open(keydir + '/keyidx') as f:
566                keyid = int(f.read())
567            if keytype in (KT_PTK, KT_GTK) and keyid not in (0, 1, 2, 3):
568                continue
569            if keytype == KT_IGTK and keyid not in (4, 5):
570                continue
571            if keytype == KT_BIGTK and keyid not in (6, 7):
572                continue
573            files = os.listdir(keydir)
574            if keytype == KT_PTK and "station" not in files:
575                continue
576            if keytype != KT_PTK and "station" in files:
577                continue
578            with open(keydir + "/replays") as f:
579                return int(f.read())
580    except OSError as e:
581        raise HwsimSkip("debugfs not supported in mac80211")
582    return None
583
584def test_ap_cipher_replay_protection_ap_ccmp(dev, apdev):
585    """CCMP replay protection on AP"""
586    run_ap_cipher_replay_protection_ap(dev, apdev, "CCMP")
587
588def test_ap_cipher_replay_protection_ap_tkip(dev, apdev):
589    """TKIP replay protection on AP"""
590    skip_without_tkip(dev[0])
591    run_ap_cipher_replay_protection_ap(dev, apdev, "TKIP")
592
593def test_ap_cipher_replay_protection_ap_gcmp(dev, apdev):
594    """GCMP replay protection on AP"""
595    if "GCMP" not in dev[0].get_capability("pairwise"):
596        raise HwsimSkip("GCMP not supported")
597    run_ap_cipher_replay_protection_ap(dev, apdev, "GCMP")
598
599def run_ap_cipher_replay_protection_ap(dev, apdev, cipher):
600    params = {"ssid": "test-wpa2-psk",
601              "wpa_passphrase": "12345678",
602              "wpa": "2",
603              "wpa_key_mgmt": "WPA-PSK",
604              "rsn_pairwise": cipher}
605    hapd = hostapd.add_ap(apdev[0], params)
606    phy = hapd.get_driver_status_field("phyname")
607
608    Wlantest.setup(hapd)
609    wt = Wlantest()
610    wt.flush()
611    wt.add_passphrase("12345678")
612
613    dev[0].connect("test-wpa2-psk", psk="12345678",
614                   pairwise=cipher, group=cipher, scan_freq="2412")
615    hapd.wait_sta()
616
617    if cipher != "TKIP":
618        replays = get_tk_replay_counter(phy)
619        if replays != 0:
620            raise Exception("Unexpected replay reported (1)")
621
622    for i in range(5):
623        hwsim_utils.test_connectivity(dev[0], hapd)
624
625    if cipher != "TKIP":
626        replays = get_tk_replay_counter(phy)
627        if replays != 0:
628            raise Exception("Unexpected replay reported (2)")
629
630    if "OK" not in dev[0].request("RESET_PN"):
631        raise Exception("RESET_PN failed")
632    time.sleep(0.1)
633    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1,
634                                  success_expected=False)
635
636    if cipher != "TKIP":
637        replays = get_tk_replay_counter(phy)
638        if replays < 1:
639            raise Exception("Replays not reported")
640
641def test_ap_cipher_replay_protection_sta_ccmp(dev, apdev):
642    """CCMP replay protection on STA (TK)"""
643    run_ap_cipher_replay_protection_sta(dev, apdev, "CCMP")
644
645def test_ap_cipher_replay_protection_sta_tkip(dev, apdev):
646    """TKIP replay protection on STA (TK)"""
647    skip_without_tkip(dev[0])
648    run_ap_cipher_replay_protection_sta(dev, apdev, "TKIP")
649
650def test_ap_cipher_replay_protection_sta_gcmp(dev, apdev):
651    """GCMP replay protection on STA (TK)"""
652    if "GCMP" not in dev[0].get_capability("pairwise"):
653        raise HwsimSkip("GCMP not supported")
654    run_ap_cipher_replay_protection_sta(dev, apdev, "GCMP")
655
656def test_ap_cipher_replay_protection_sta_gtk_ccmp(dev, apdev):
657    """CCMP replay protection on STA (GTK)"""
658    run_ap_cipher_replay_protection_sta(dev, apdev, "CCMP", keytype=KT_GTK)
659
660def test_ap_cipher_replay_protection_sta_gtk_tkip(dev, apdev):
661    """TKIP replay protection on STA (GTK)"""
662    skip_without_tkip(dev[0])
663    run_ap_cipher_replay_protection_sta(dev, apdev, "TKIP", keytype=KT_GTK)
664
665def test_ap_cipher_replay_protection_sta_gtk_gcmp(dev, apdev):
666    """GCMP replay protection on STA (GTK)"""
667    if "GCMP" not in dev[0].get_capability("pairwise"):
668        raise HwsimSkip("GCMP not supported")
669    run_ap_cipher_replay_protection_sta(dev, apdev, "GCMP", keytype=KT_GTK)
670
671def test_ap_cipher_replay_protection_sta_igtk(dev, apdev):
672    """CCMP replay protection on STA (IGTK)"""
673    run_ap_cipher_replay_protection_sta(dev, apdev, "CCMP", keytype=KT_IGTK)
674
675def test_ap_cipher_replay_protection_sta_bigtk(dev, apdev):
676    """CCMP replay protection on STA (BIGTK)"""
677    run_ap_cipher_replay_protection_sta(dev, apdev, "CCMP", keytype=KT_BIGTK)
678
679def run_ap_cipher_replay_protection_sta(dev, apdev, cipher, keytype=KT_PTK):
680    params = {"ssid": "test-wpa2-psk",
681              "wpa_passphrase": "12345678",
682              "wpa": "2",
683              "wpa_key_mgmt": "WPA-PSK",
684              "rsn_pairwise": cipher}
685    if keytype == KT_IGTK or keytype == KT_BIGTK:
686        params['ieee80211w'] = '2'
687    if keytype == KT_BIGTK:
688        params['beacon_prot'] = '1'
689    hapd = hostapd.add_ap(apdev[0], params)
690
691    Wlantest.setup(hapd)
692    wt = Wlantest()
693    wt.flush()
694    wt.add_passphrase("12345678")
695
696    phy = dev[0].get_driver_status_field("phyname")
697    dev[0].connect("test-wpa2-psk", psk="12345678", ieee80211w='1',
698                   beacon_prot='1',
699                   pairwise=cipher, group=cipher, scan_freq="2412")
700    hapd.wait_sta()
701
702    if keytype == KT_BIGTK:
703        time.sleep(1)
704
705    if cipher != "TKIP":
706        replays = get_tk_replay_counter(phy, keytype)
707        if replays != 0:
708            raise Exception("Unexpected replay reported (1)")
709
710    for i in range(5):
711        hwsim_utils.test_connectivity(dev[0], hapd)
712
713    if cipher != "TKIP":
714        replays = get_tk_replay_counter(phy, keytype)
715        if replays != 0:
716            raise Exception("Unexpected replay reported (2)")
717
718    if keytype == KT_IGTK:
719        hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
720        ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
721        if ev:
722            dev[0].wait_connected()
723
724    addr = "ff:ff:ff:ff:ff:ff" if keytype != KT_PTK else dev[0].own_addr()
725    cmd = "RESET_PN " + addr
726    if keytype == KT_IGTK:
727        cmd += " IGTK"
728    if keytype == KT_BIGTK:
729        cmd += " BIGTK"
730    if "OK" not in hapd.request(cmd):
731        raise Exception("RESET_PN failed")
732    time.sleep(0.1)
733    if keytype == KT_IGTK:
734        hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
735        ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
736    elif keytype == KT_BIGTK:
737        time.sleep(1)
738    else:
739        hwsim_utils.test_connectivity(dev[0], hapd, timeout=1,
740                                      success_expected=False)
741
742    if cipher != "TKIP":
743        replays = get_tk_replay_counter(phy, keytype)
744        if replays < 1:
745            raise Exception("Replays not reported")
746
747@disable_ipv6
748def test_ap_wpa2_delayed_m3_retransmission(dev, apdev):
749    """Delayed M3 retransmission"""
750    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
751    hapd = hostapd.add_ap(apdev[0], params)
752
753    Wlantest.setup(hapd)
754    wt = Wlantest()
755    wt.flush()
756    wt.add_passphrase("12345678")
757
758    phy = dev[0].get_driver_status_field("phyname")
759    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
760    hapd.wait_sta()
761
762    for i in range(5):
763        hwsim_utils.test_connectivity(dev[0], hapd)
764
765    time.sleep(0.1)
766    before_tk = get_rx_spec(phy, keytype=KT_PTK).splitlines()
767    before_gtk = get_rx_spec(phy, keytype=KT_GTK).splitlines()
768    addr = dev[0].own_addr()
769    if "OK" not in hapd.request("RESEND_M3 " + addr):
770        raise Exception("RESEND_M3 failed")
771    time.sleep(0.1)
772    after_tk = get_rx_spec(phy, keytype=KT_PTK).splitlines()
773    after_gtk = get_rx_spec(phy, keytype=KT_GTK).splitlines()
774
775    if "OK" not in hapd.request("RESET_PN " + addr):
776        raise Exception("RESET_PN failed")
777    time.sleep(0.1)
778    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1,
779                                  success_expected=False)
780    dev[0].request("DISCONNECT")
781    dev[0].wait_disconnected()
782
783    for i in range(len(before_tk)):
784        b = int(before_tk[i], 16)
785        a = int(after_tk[i], 16)
786        if a < b:
787            raise Exception("TK RX counter decreased: idx=%d before=%d after=%d" % (i, b, a))
788
789    for i in range(len(before_gtk)):
790        b = int(before_gtk[i], 16)
791        a = int(after_gtk[i], 16)
792        if a < b:
793            raise Exception("GTK RX counter decreased: idx=%d before=%d after=%d" % (i, b, a))
794
795@disable_ipv6
796def test_ap_wpa2_delayed_m1_m3_retransmission(dev, apdev):
797    """Delayed M1+M3 retransmission"""
798    run_ap_wpa2_delayed_m1_m3_retransmission(dev, apdev, False)
799
800@disable_ipv6
801def test_ap_wpa2_delayed_m1_m3_retransmission2(dev, apdev):
802    """Delayed M1+M3 retransmission (change M1 ANonce)"""
803    run_ap_wpa2_delayed_m1_m3_retransmission(dev, apdev, True)
804
805def run_ap_wpa2_delayed_m1_m3_retransmission(dev, apdev,
806                                             change_m1_anonce=False):
807    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
808    hapd = hostapd.add_ap(apdev[0], params)
809
810    Wlantest.setup(hapd)
811    wt = Wlantest()
812    wt.flush()
813    wt.add_passphrase("12345678")
814
815    phy = dev[0].get_driver_status_field("phyname")
816    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
817    hapd.wait_sta()
818
819    for i in range(5):
820        hwsim_utils.test_connectivity(dev[0], hapd)
821
822    time.sleep(0.1)
823    before_tk = get_rx_spec(phy, keytype=KT_PTK).splitlines()
824    before_gtk = get_rx_spec(phy, keytype=KT_GTK).splitlines()
825    addr = dev[0].own_addr()
826    if change_m1_anonce:
827        if "OK" not in hapd.request("RESEND_M1 " + addr + " change-anonce"):
828            raise Exception("RESEND_M1 failed")
829    if "OK" not in hapd.request("RESEND_M1 " + addr):
830        raise Exception("RESEND_M1 failed")
831    if "OK" not in hapd.request("RESEND_M3 " + addr):
832        raise Exception("RESEND_M3 failed")
833    time.sleep(0.1)
834    after_tk = get_rx_spec(phy, keytype=KT_PTK).splitlines()
835    after_gtk = get_rx_spec(phy, keytype=KT_GTK).splitlines()
836
837    if "OK" not in hapd.request("RESET_PN " + addr):
838        raise Exception("RESET_PN failed")
839    time.sleep(0.1)
840    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1,
841                                  success_expected=False)
842    dev[0].request("DISCONNECT")
843    dev[0].wait_disconnected()
844
845    for i in range(len(before_tk)):
846        b = int(before_tk[i], 16)
847        a = int(after_tk[i], 16)
848        if a < b:
849            raise Exception("TK RX counter decreased: idx=%d before=%d after=%d" % (i, b, a))
850
851    for i in range(len(before_gtk)):
852        b = int(before_gtk[i], 16)
853        a = int(after_gtk[i], 16)
854        if a < b:
855            raise Exception("GTK RX counter decreased: idx=%d before=%d after=%d" % (i, b, a))
856
857@disable_ipv6
858def test_ap_wpa2_delayed_group_m1_retransmission(dev, apdev):
859    """Delayed group M1 retransmission"""
860    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
861    hapd = hostapd.add_ap(apdev[0], params)
862
863    Wlantest.setup(hapd)
864    wt = Wlantest()
865    wt.flush()
866    wt.add_passphrase("12345678")
867
868    phy = dev[0].get_driver_status_field("phyname")
869    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
870    hapd.wait_sta()
871
872    for i in range(5):
873        hwsim_utils.test_connectivity(dev[0], hapd)
874
875    time.sleep(0.1)
876    before = get_rx_spec(phy, keytype=KT_GTK).splitlines()
877    addr = dev[0].own_addr()
878    if "OK" not in hapd.request("RESEND_GROUP_M1 " + addr):
879        raise Exception("RESEND_GROUP_M1 failed")
880    time.sleep(0.1)
881    after = get_rx_spec(phy, keytype=KT_GTK).splitlines()
882
883    if "OK" not in hapd.request("RESET_PN ff:ff:ff:ff:ff:ff"):
884        raise Exception("RESET_PN failed")
885    time.sleep(0.1)
886    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1,
887                                  success_expected=False)
888    dev[0].request("DISCONNECT")
889    dev[0].wait_disconnected()
890
891    for i in range(len(before)):
892        b = int(before[i], 16)
893        a = int(after[i], 16)
894        if a < b:
895            raise Exception("RX counter decreased: idx=%d before=%d after=%d" % (i, b, a))
896
897@disable_ipv6
898def test_ap_wpa2_delayed_group_m1_retransmission_igtk(dev, apdev):
899    """Delayed group M1 retransmission (check IGTK protection)"""
900    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678",
901                                 ieee80211w="2")
902    hapd = hostapd.add_ap(apdev[0], params)
903
904    Wlantest.setup(hapd)
905    wt = Wlantest()
906    wt.flush()
907    wt.add_passphrase("12345678")
908
909    phy = dev[0].get_driver_status_field("phyname")
910    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412",
911                   ieee80211w="1")
912    hapd.wait_sta()
913
914    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1)
915
916    # deauth once to see that works OK
917    addr = dev[0].own_addr()
918    hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff")
919    dev[0].wait_disconnected(timeout=10)
920
921    # now to check the protection
922    dev[0].request("RECONNECT")
923    dev[0].wait_connected()
924    hapd.wait_sta()
925
926    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1)
927
928    if "OK" not in hapd.request("RESEND_GROUP_M1 " + addr):
929        raise Exception("RESEND_GROUP_M1 failed")
930    if "OK" not in hapd.request("RESET_PN ff:ff:ff:ff:ff:ff IGTK"):
931        raise Exception("RESET_PN failed")
932
933    time.sleep(0.1)
934    hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
935
936    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.1)
937    if ev is not None:
938        raise Exception("Unexpected disconnection")
939
940    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1)
941
942    dev[0].request("DISCONNECT")
943    dev[0].wait_disconnected()
944
945def test_ap_wpa2_delayed_m1_m3_zero_tk(dev, apdev):
946    """Delayed M1+M3 retransmission and zero TK"""
947    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
948    hapd = hostapd.add_ap(apdev[0], params)
949
950    Wlantest.setup(hapd)
951    wt = Wlantest()
952    wt.flush()
953    wt.add_passphrase("12345678")
954
955    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
956    hapd.wait_sta()
957
958    hwsim_utils.test_connectivity(dev[0], hapd)
959    addr = dev[0].own_addr()
960    if "OK" not in hapd.request("RESEND_M1 " + addr + " change-anonce"):
961        raise Exception("RESEND_M1 failed")
962    if "OK" not in hapd.request("RESEND_M1 " + addr):
963        raise Exception("RESEND_M1 failed")
964    if "OK" not in hapd.request("RESEND_M3 " + addr):
965        raise Exception("RESEND_M3 failed")
966
967    KEY_FLAG_RX = 0x04
968    KEY_FLAG_TX = 0x08
969    KEY_FLAG_PAIRWISE = 0x20
970    KEY_FLAG_RX_TX = KEY_FLAG_RX | KEY_FLAG_TX
971    KEY_FLAG_PAIRWISE_RX_TX = KEY_FLAG_PAIRWISE | KEY_FLAG_RX_TX
972    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s %d" % (addr, 0, 1, 6*"00", 16*"00", KEY_FLAG_PAIRWISE_RX_TX)):
973        raise Exception("SET_KEY failed")
974    time.sleep(0.1)
975    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1, broadcast=False,
976                                  success_expected=False)
977    dev[0].request("DISCONNECT")
978    dev[0].wait_disconnected()
979
980def test_ap_wpa2_plaintext_m1_m3(dev, apdev):
981    """Plaintext M1/M3 during PTK rekey"""
982    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
983    hapd = hostapd.add_ap(apdev[0], params)
984
985    Wlantest.setup(hapd)
986    wt = Wlantest()
987    wt.flush()
988    wt.add_passphrase("12345678")
989
990    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
991
992    time.sleep(0.1)
993    addr = dev[0].own_addr()
994    if "OK" not in hapd.request("RESEND_M1 " + addr + " plaintext"):
995        raise Exception("RESEND_M1 failed")
996    time.sleep(0.1)
997    if "OK" not in hapd.request("RESEND_M3 " + addr + " plaintext"):
998        raise Exception("RESEND_M3 failed")
999    time.sleep(0.1)
1000
1001def test_ap_wpa2_plaintext_m1_m3_pmf(dev, apdev):
1002    """Plaintext M1/M3 during PTK rekey (PMF)"""
1003    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
1004    params["ieee80211w"] = "2"
1005    hapd = hostapd.add_ap(apdev[0], params)
1006
1007    Wlantest.setup(hapd)
1008    wt = Wlantest()
1009    wt.flush()
1010    wt.add_passphrase("12345678")
1011
1012    dev[0].connect("test-wpa2-psk", psk="12345678", ieee80211w="2",
1013                   scan_freq="2412")
1014
1015    time.sleep(0.1)
1016    addr = dev[0].own_addr()
1017    if "OK" not in hapd.request("RESEND_M1 " + addr + " plaintext"):
1018        raise Exception("RESEND_M1 failed")
1019    time.sleep(0.1)
1020    if "OK" not in hapd.request("RESEND_M3 " + addr + " plaintext"):
1021        raise Exception("RESEND_M3 failed")
1022    time.sleep(0.1)
1023
1024def test_ap_wpa2_plaintext_m3(dev, apdev):
1025    """Plaintext M3 during PTK rekey"""
1026    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
1027    hapd = hostapd.add_ap(apdev[0], params)
1028
1029    Wlantest.setup(hapd)
1030    wt = Wlantest()
1031    wt.flush()
1032    wt.add_passphrase("12345678")
1033
1034    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
1035
1036    time.sleep(0.1)
1037    addr = dev[0].own_addr()
1038    if "OK" not in hapd.request("RESEND_M1 " + addr):
1039        raise Exception("RESEND_M1 failed")
1040    time.sleep(0.1)
1041    if "OK" not in hapd.request("RESEND_M3 " + addr + " plaintext"):
1042        raise Exception("RESEND_M3 failed")
1043    time.sleep(0.1)
1044
1045def test_ap_wpa2_plaintext_group_m1(dev, apdev):
1046    """Plaintext group M1"""
1047    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
1048    hapd = hostapd.add_ap(apdev[0], params)
1049
1050    Wlantest.setup(hapd)
1051    wt = Wlantest()
1052    wt.flush()
1053    wt.add_passphrase("12345678")
1054
1055    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
1056
1057    time.sleep(0.1)
1058    addr = dev[0].own_addr()
1059    if "OK" not in hapd.request("RESEND_GROUP_M1 " + addr + " plaintext"):
1060        raise Exception("RESEND_GROUP_M1 failed")
1061    time.sleep(0.2)
1062    if "OK" not in hapd.request("RESEND_GROUP_M1 " + addr):
1063        raise Exception("RESEND_GROUP_M1 failed")
1064    time.sleep(0.1)
1065
1066def test_ap_wpa2_plaintext_group_m1_pmf(dev, apdev):
1067    """Plaintext group M1 (PMF)"""
1068    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
1069    params["ieee80211w"] = "2"
1070    hapd = hostapd.add_ap(apdev[0], params)
1071
1072    Wlantest.setup(hapd)
1073    wt = Wlantest()
1074    wt.flush()
1075    wt.add_passphrase("12345678")
1076
1077    dev[0].connect("test-wpa2-psk", psk="12345678", ieee80211w="2",
1078                   scan_freq="2412")
1079
1080    time.sleep(0.1)
1081    addr = dev[0].own_addr()
1082    if "OK" not in hapd.request("RESEND_GROUP_M1 " + addr + " plaintext"):
1083        raise Exception("RESEND_GROUP_M1 failed")
1084    time.sleep(0.2)
1085    if "OK" not in hapd.request("RESEND_GROUP_M1 " + addr):
1086        raise Exception("RESEND_GROUP_M1 failed")
1087    time.sleep(0.1)
1088
1089def test_ap_wpa2_test_command_failures(dev, apdev):
1090    """EAPOL/key config test command failures"""
1091    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
1092    hapd = hostapd.add_ap(apdev[0], params)
1093    tests = ["RESEND_M1 foo",
1094             "RESEND_M1 22:22:22:22:22:22",
1095             "RESEND_M3 foo",
1096             "RESEND_M3 22:22:22:22:22:22",
1097             "RESEND_GROUP_M1 foo",
1098             "RESEND_GROUP_M1 22:22:22:22:22:22",
1099             "SET_KEY foo",
1100             "SET_KEY 3 foo",
1101             "SET_KEY 3 22:22:22:22:22:22",
1102             "SET_KEY 3 22:22:22:22:22:22 1",
1103             "SET_KEY 3 22:22:22:22:22:22 1 1",
1104             "SET_KEY 3 22:22:22:22:22:22 1 1 q",
1105             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566",
1106             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 1",
1107             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 12",
1108             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 12 1",
1109             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 12 1 ",
1110             "RESET_PN ff:ff:ff:ff:ff:ff BIGTK",
1111             "RESET_PN ff:ff:ff:ff:ff:ff IGTK",
1112             "RESET_PN 22:22:22:22:22:22",
1113             "RESET_PN foo"]
1114    for t in tests:
1115        if "FAIL" not in hapd.request(t):
1116            raise Exception("Invalid command accepted: " + t)
1117
1118def test_ap_wpa2_gtk_initial_rsc_tkip(dev, apdev):
1119    """Initial group cipher RSC (TKIP)"""
1120    skip_without_tkip(dev[0])
1121    run_ap_wpa2_gtk_initial_rsc(dev, apdev, "TKIP")
1122
1123def test_ap_wpa2_gtk_initial_rsc_ccmp(dev, apdev):
1124    """Initial group cipher RSC (CCMP)"""
1125    run_ap_wpa2_gtk_initial_rsc(dev, apdev, "CCMP")
1126
1127def test_ap_wpa2_gtk_initial_rsc_ccmp_256(dev, apdev):
1128    """Initial group cipher RSC (CCMP-256)"""
1129    run_ap_wpa2_gtk_initial_rsc(dev, apdev, "CCMP-256")
1130
1131def test_ap_wpa2_gtk_initial_rsc_gcmp(dev, apdev):
1132    """Initial group cipher RSC (GCMP)"""
1133    run_ap_wpa2_gtk_initial_rsc(dev, apdev, "GCMP")
1134
1135def test_ap_wpa2_gtk_initial_rsc_gcmp_256(dev, apdev):
1136    """Initial group cipher RSC (GCMP-256)"""
1137    run_ap_wpa2_gtk_initial_rsc(dev, apdev, "GCMP-256")
1138
1139def run_ap_wpa2_gtk_initial_rsc(dev, apdev, cipher):
1140    if cipher not in dev[0].get_capability("pairwise") or \
1141       cipher not in dev[0].get_capability("group"):
1142        raise HwsimSkip("Cipher %s not supported" % cipher)
1143
1144    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
1145    params["rsn_pairwise"] = cipher
1146    params["group_cipher"] = cipher
1147    params["gtk_rsc_override"] = "341200000000"
1148    hapd = hostapd.add_ap(apdev[0], params)
1149
1150    Wlantest.setup(hapd)
1151    wt = Wlantest()
1152    wt.flush()
1153    wt.add_passphrase("12345678")
1154
1155    dev[0].connect("test-wpa2-psk", psk="12345678", proto="WPA2",
1156                   pairwise=cipher, group=cipher, scan_freq="2412")
1157    hapd.wait_sta()
1158    # Verify that unicast traffic works, but broadcast traffic does not.
1159    hwsim_utils.test_connectivity(dev[0], hapd, broadcast=False)
1160    hwsim_utils.test_connectivity(dev[0], hapd, success_expected=False)
1161    hwsim_utils.test_connectivity(dev[0], hapd, success_expected=False)
1162
1163def test_ap_wpa2_igtk_initial_rsc_aes_128_cmac(dev, apdev):
1164    """Initial management group cipher RSC (AES-128-CMAC)"""
1165    run_ap_wpa2_igtk_initial_rsc(dev, apdev, "AES-128-CMAC")
1166
1167def test_ap_wpa2_igtk_initial_rsc_bip_gmac_128(dev, apdev):
1168    """Initial management group cipher RSC (BIP-GMAC-128)"""
1169    run_ap_wpa2_igtk_initial_rsc(dev, apdev, "BIP-GMAC-128")
1170
1171def test_ap_wpa2_igtk_initial_rsc_bip_gmac_256(dev, apdev):
1172    """Initial management group cipher RSC (BIP-GMAC-256)"""
1173    run_ap_wpa2_igtk_initial_rsc(dev, apdev, "BIP-GMAC-256")
1174
1175def test_ap_wpa2_igtk_initial_rsc_bip_cmac_256(dev, apdev):
1176    """Initial management group cipher RSC (BIP-CMAC-256)"""
1177    run_ap_wpa2_igtk_initial_rsc(dev, apdev, "BIP-CMAC-256")
1178
1179def run_ap_wpa2_igtk_initial_rsc(dev, apdev, cipher):
1180    if cipher not in dev[0].get_capability("group_mgmt"):
1181        raise HwsimSkip("Cipher %s not supported" % cipher)
1182
1183    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
1184    params["ieee80211w"] = "2"
1185    params["rsn_pairwise"] = "CCMP"
1186    params["group_cipher"] = "CCMP"
1187    params["group_mgmt_cipher"] = cipher
1188    params["igtk_rsc_override"] = "341200000000"
1189    hapd = hostapd.add_ap(apdev[0], params)
1190
1191    Wlantest.setup(hapd)
1192    wt = Wlantest()
1193    wt.flush()
1194    wt.add_passphrase("12345678")
1195
1196    dev[0].connect("test-wpa2-psk", psk="12345678", proto="WPA2",
1197                   ieee80211w="2", pairwise="CCMP", group="CCMP",
1198                   group_mgmt=cipher,
1199                   scan_freq="2412")
1200    hapd.wait_sta()
1201    # Verify that broadcast robust management frames are dropped.
1202    dev[0].note("Sending broadcast Deauthentication and Disassociation frames with too small IPN")
1203    hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
1204    hapd.request("DISASSOCIATE ff:ff:ff:ff:ff:ff test=1")
1205    hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
1206    hapd.request("DISASSOCIATE ff:ff:ff:ff:ff:ff test=1")
1207    dev[0].note("Done sending broadcast Deauthentication and Disassociation frames with too small IPN")
1208    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
1209    if ev is not None:
1210        raise Exception("Unexpected disconnection")
1211
1212    # Verify thar unicast robust management frames go through.
1213    hapd.request("DEAUTHENTICATE " + dev[0].own_addr() + " reason=123 test=1")
1214    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
1215    if ev is None:
1216        raise Exception("Disconnection not reported")
1217    if "reason=123" not in ev:
1218        raise Exception("Unexpected disconnection reason: " + ev)
1219