Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / tests / hwsim / test_ap_pmf.py
1 # Protected management frames tests
2 # Copyright (c) 2013, 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
7 import time
8 import subprocess
9 import logging
10 logger = logging.getLogger()
11
12 import hwsim_utils
13 import hostapd
14 from wlantest import Wlantest
15 from wpasupplicant import WpaSupplicant
16 from test_ap_eap import eap_connect
17
18 def test_ap_pmf_required(dev, apdev):
19     """WPA2-PSK AP with PMF required"""
20     ssid = "test-pmf-required"
21     wt = Wlantest()
22     wt.flush()
23     wt.add_passphrase("12345678")
24     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
25     params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
26     params["ieee80211w"] = "2";
27     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
28     key_mgmt = hapd.get_config()['key_mgmt']
29     if key_mgmt.split(' ')[0] != "WPA-PSK-SHA256":
30         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
31     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
32                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
33                    scan_freq="2412")
34     if "[WPA2-PSK-SHA256-CCMP]" not in dev[0].request("SCAN_RESULTS"):
35         raise Exception("Scan results missing RSN element info")
36     hwsim_utils.test_connectivity(dev[0], hapd)
37     dev[1].connect(ssid, psk="12345678", ieee80211w="2",
38                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
39                    scan_freq="2412")
40     hwsim_utils.test_connectivity(dev[1], hapd)
41     hapd = hostapd.Hostapd(apdev[0]['ifname'])
42     hapd.request("SA_QUERY " + dev[0].p2p_interface_addr())
43     hapd.request("SA_QUERY " + dev[1].p2p_interface_addr())
44     wt.require_ap_pmf_mandatory(apdev[0]['bssid'])
45     wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
46     wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
47     time.sleep(0.1)
48     if wt.get_sta_counter("valid_saqueryresp_tx", apdev[0]['bssid'],
49                           dev[0].p2p_interface_addr()) < 1:
50         raise Exception("STA did not reply to SA Query")
51     if wt.get_sta_counter("valid_saqueryresp_tx", apdev[0]['bssid'],
52                           dev[1].p2p_interface_addr()) < 1:
53         raise Exception("STA did not reply to SA Query")
54
55 def test_ap_pmf_optional(dev, apdev):
56     """WPA2-PSK AP with PMF optional"""
57     ssid = "test-pmf-optional"
58     wt = Wlantest()
59     wt.flush()
60     wt.add_passphrase("12345678")
61     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
62     params["wpa_key_mgmt"] = "WPA-PSK";
63     params["ieee80211w"] = "1";
64     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
65     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
66                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
67                    scan_freq="2412")
68     hwsim_utils.test_connectivity(dev[0], hapd)
69     dev[1].connect(ssid, psk="12345678", ieee80211w="2",
70                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
71                    scan_freq="2412")
72     hwsim_utils.test_connectivity(dev[1], hapd)
73     wt.require_ap_pmf_optional(apdev[0]['bssid'])
74     wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
75     wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
76
77 def test_ap_pmf_optional_2akm(dev, apdev):
78     """WPA2-PSK AP with PMF optional (2 AKMs)"""
79     ssid = "test-pmf-optional-2akm"
80     wt = Wlantest()
81     wt.flush()
82     wt.add_passphrase("12345678")
83     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
84     params["wpa_key_mgmt"] = "WPA-PSK WPA-PSK-SHA256";
85     params["ieee80211w"] = "1";
86     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
87     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
88                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
89                    scan_freq="2412")
90     hwsim_utils.test_connectivity(dev[0], hapd)
91     dev[1].connect(ssid, psk="12345678", ieee80211w="2",
92                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
93                    scan_freq="2412")
94     hwsim_utils.test_connectivity(dev[1], hapd)
95     wt.require_ap_pmf_optional(apdev[0]['bssid'])
96     wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
97     wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[0].p2p_interface_addr(),
98                             "PSK-SHA256")
99     wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
100     wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[1].p2p_interface_addr(),
101                             "PSK-SHA256")
102
103 def test_ap_pmf_negative(dev, apdev):
104     """WPA2-PSK AP without PMF (negative test)"""
105     ssid = "test-pmf-negative"
106     wt = Wlantest()
107     wt.flush()
108     wt.add_passphrase("12345678")
109     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
110     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
111     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
112                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
113                    scan_freq="2412")
114     hwsim_utils.test_connectivity(dev[0], hapd)
115     try:
116         dev[1].connect(ssid, psk="12345678", ieee80211w="2",
117                        key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
118                        scan_freq="2412")
119         hwsim_utils.test_connectivity(dev[1], hapd)
120         raise Exception("PMF required STA connected to no PMF AP")
121     except Exception, e:
122         logger.debug("Ignore expected exception: " + str(e))
123     wt.require_ap_no_pmf(apdev[0]['bssid'])
124
125 def test_ap_pmf_assoc_comeback(dev, apdev):
126     """WPA2-PSK AP with PMF association comeback"""
127     ssid = "assoc-comeback"
128     wt = Wlantest()
129     wt.flush()
130     wt.add_passphrase("12345678")
131     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
132     params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
133     params["ieee80211w"] = "2";
134     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
135     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
136                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
137                    scan_freq="2412")
138     hapd.set("ext_mgmt_frame_handling", "1")
139     dev[0].request("DISCONNECT")
140     dev[0].wait_disconnected(timeout=10)
141     hapd.set("ext_mgmt_frame_handling", "0")
142     dev[0].request("REASSOCIATE")
143     dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
144     if wt.get_sta_counter("assocresp_comeback", apdev[0]['bssid'],
145                           dev[0].p2p_interface_addr()) < 1:
146         raise Exception("AP did not use association comeback request")
147
148 def test_ap_pmf_assoc_comeback2(dev, apdev):
149     """WPA2-PSK AP with PMF association comeback (using DROP_SA)"""
150     ssid = "assoc-comeback"
151     wt = Wlantest()
152     wt.flush()
153     wt.add_passphrase("12345678")
154     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
155     params["wpa_key_mgmt"] = "WPA-PSK";
156     params["ieee80211w"] = "1";
157     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
158     dev[0].connect(ssid, psk="12345678", ieee80211w="2",
159                    key_mgmt="WPA-PSK", proto="WPA2", scan_freq="2412")
160     if "OK" not in dev[0].request("DROP_SA"):
161         raise Exception("DROP_SA failed")
162     dev[0].request("REASSOCIATE")
163     dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
164     if wt.get_sta_counter("reassocresp_comeback", apdev[0]['bssid'],
165                           dev[0].p2p_interface_addr()) < 1:
166         raise Exception("AP did not use reassociation comeback request")
167
168 def test_ap_pmf_sta_sa_query(dev, apdev):
169     """WPA2-PSK AP with station using SA Query"""
170     ssid = "assoc-comeback"
171     addr = dev[0].own_addr()
172     wt = Wlantest()
173     wt.flush()
174     wt.add_passphrase("12345678")
175
176     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
177     wpas.interface_add("wlan5", drv_params="use_monitor=1")
178     id = wpas.add_network()
179     wpas.set_network(id, "mode", "2")
180     wpas.set_network_quoted(id, "ssid", ssid)
181     wpas.set_network(id, "proto", "WPA2")
182     wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
183     wpas.set_network(id, "ieee80211w", "2")
184     wpas.set_network_quoted(id, "psk", "12345678")
185     wpas.set_network(id, "pairwise", "CCMP")
186     wpas.set_network(id, "group", "CCMP")
187     wpas.set_network(id, "frequency", "2412")
188     wpas.connect_network(id)
189     bssid = wpas.own_addr()
190
191     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
192                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
193                    scan_freq="2412")
194     wpas.request("DEAUTHENTICATE " + addr + " test=0")
195     wpas.request("DISASSOCIATE " + addr + " test=0")
196     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
197     if ev is not None:
198         raise Exception("Unexpected disconnection")
199
200     wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
201     wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
202     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
203     if ev is not None:
204         raise Exception("Unexpected disconnection")
205     if wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr) < 1:
206         raise Exception("STA did not send SA Query")
207     if wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr) < 1:
208         raise Exception("AP did not reply to SA Query")
209
210 def test_ap_pmf_sta_sa_query_no_response(dev, apdev):
211     """WPA2-PSK AP with station using SA Query and getting no response"""
212     ssid = "assoc-comeback"
213     addr = dev[0].own_addr()
214
215     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
216     wpas.interface_add("wlan5", drv_params="use_monitor=1")
217     id = wpas.add_network()
218     wpas.set_network(id, "mode", "2")
219     wpas.set_network_quoted(id, "ssid", ssid)
220     wpas.set_network(id, "proto", "WPA2")
221     wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
222     wpas.set_network(id, "ieee80211w", "2")
223     wpas.set_network_quoted(id, "psk", "12345678")
224     wpas.set_network(id, "pairwise", "CCMP")
225     wpas.set_network(id, "group", "CCMP")
226     wpas.set_network(id, "frequency", "2412")
227     wpas.connect_network(id)
228     bssid = wpas.own_addr()
229
230     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
231                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
232                    scan_freq="2412")
233     wpas.request("DEAUTHENTICATE " + addr + " test=0")
234     wpas.request("DISASSOCIATE " + addr + " test=0")
235     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
236     if ev is not None:
237         raise Exception("Unexpected disconnection")
238
239     wpas.request("SET ext_mgmt_frame_handling 1")
240     wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
241     wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
242     dev[0].wait_disconnected()
243     wpas.request("SET ext_mgmt_frame_handling 0")
244     dev[0].wait_connected()
245
246 def test_ap_pmf_sta_unprot_deauth_burst(dev, apdev):
247     """WPA2-PSK AP with station receiving burst of unprotected Deauthentication frames"""
248     ssid = "deauth-attack"
249     addr = dev[0].own_addr()
250     wt = Wlantest()
251     wt.flush()
252     wt.add_passphrase("12345678")
253
254     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
255     wpas.interface_add("wlan5", drv_params="use_monitor=1")
256     id = wpas.add_network()
257     wpas.set_network(id, "mode", "2")
258     wpas.set_network_quoted(id, "ssid", ssid)
259     wpas.set_network(id, "proto", "WPA2")
260     wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
261     wpas.set_network(id, "ieee80211w", "2")
262     wpas.set_network_quoted(id, "psk", "12345678")
263     wpas.set_network(id, "pairwise", "CCMP")
264     wpas.set_network(id, "group", "CCMP")
265     wpas.set_network(id, "frequency", "2412")
266     wpas.connect_network(id)
267     bssid = wpas.own_addr()
268
269     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
270                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
271                    scan_freq="2412")
272
273     for i in range(0, 10):
274         wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
275         wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
276     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
277     if ev is not None:
278         raise Exception("Unexpected disconnection")
279     num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
280     num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
281     if num_req < 1:
282         raise Exception("STA did not send SA Query")
283     if num_resp < 1:
284         raise Exception("AP did not reply to SA Query")
285     if num_req > 1:
286         raise Exception("STA initiated too many SA Query procedures (%d)" % num_req)
287
288     time.sleep(10)
289     for i in range(0, 5):
290         wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
291         wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
292     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
293     if ev is not None:
294         raise Exception("Unexpected disconnection")
295     num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
296     num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
297     if num_req != 2 or num_resp != 2:
298         raise Exception("Unexpected number of SA Query procedures (req=%d resp=%d)" % (num_req, num_resp))
299
300 def test_ap_pmf_required_eap(dev, apdev):
301     """WPA2-EAP AP with PMF required"""
302     ssid = "test-pmf-required-eap"
303     params = hostapd.wpa2_eap_params(ssid=ssid)
304     params["wpa_key_mgmt"] = "WPA-EAP-SHA256";
305     params["ieee80211w"] = "2";
306     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
307     key_mgmt = hapd.get_config()['key_mgmt']
308     if key_mgmt.split(' ')[0] != "WPA-EAP-SHA256":
309         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
310     dev[0].connect("test-pmf-required-eap", key_mgmt="WPA-EAP-SHA256",
311                    ieee80211w="2", eap="PSK", identity="psk.user@example.com",
312                    password_hex="0123456789abcdef0123456789abcdef",
313                    scan_freq="2412")
314     dev[1].connect("test-pmf-required-eap", key_mgmt="WPA-EAP WPA-EAP-SHA256",
315                    ieee80211w="1", eap="PSK", identity="psk.user@example.com",
316                    password_hex="0123456789abcdef0123456789abcdef",
317                    scan_freq="2412")
318
319 def test_ap_pmf_optional_eap(dev, apdev):
320     """WPA2EAP AP with PMF optional"""
321     params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
322     params["ieee80211w"] = "1";
323     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
324     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
325                    identity="pap user", anonymous_identity="ttls",
326                    password="password",
327                    ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
328                    ieee80211w="1", scan_freq="2412")
329     dev[1].connect("test-wpa2-eap", key_mgmt="WPA-EAP WPA-EAP-SHA256",
330                    eap="TTLS", identity="pap user", anonymous_identity="ttls",
331                    password="password",
332                    ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
333                    ieee80211w="2", scan_freq="2412")
334
335 def test_ap_pmf_required_sha1(dev, apdev):
336     """WPA2-PSK AP with PMF required with SHA1 AKM"""
337     ssid = "test-pmf-required-sha1"
338     wt = Wlantest()
339     wt.flush()
340     wt.add_passphrase("12345678")
341     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
342     params["wpa_key_mgmt"] = "WPA-PSK";
343     params["ieee80211w"] = "2";
344     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
345     key_mgmt = hapd.get_config()['key_mgmt']
346     if key_mgmt.split(' ')[0] != "WPA-PSK":
347         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
348     dev[0].connect(ssid, psk="12345678", ieee80211w="2",
349                    key_mgmt="WPA-PSK", proto="WPA2", scan_freq="2412")
350     if "[WPA2-PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
351         raise Exception("Scan results missing RSN element info")
352     hwsim_utils.test_connectivity(dev[0], hapd)
353
354 def test_ap_pmf_toggle(dev, apdev):
355     """WPA2-PSK AP with PMF optional and changing PMF on reassociation"""
356     try:
357         _test_ap_pmf_toggle(dev, apdev)
358     finally:
359         dev[0].request("SET reassoc_same_bss_optim 0")
360
361 def _test_ap_pmf_toggle(dev, apdev):
362     ssid = "test-pmf-optional"
363     wt = Wlantest()
364     wt.flush()
365     wt.add_passphrase("12345678")
366     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
367     params["wpa_key_mgmt"] = "WPA-PSK";
368     params["ieee80211w"] = "1";
369     params["assoc_sa_query_max_timeout"] = "1"
370     params["assoc_sa_query_retry_timeout"] = "1"
371     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
372     bssid = apdev[0]['bssid']
373     addr = dev[0].own_addr()
374     dev[0].request("SET reassoc_same_bss_optim 1")
375     id = dev[0].connect(ssid, psk="12345678", ieee80211w="1",
376                         key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
377                         scan_freq="2412")
378     wt.require_ap_pmf_optional(bssid)
379     wt.require_sta_pmf(bssid, addr)
380     sta = hapd.get_sta(addr)
381     if '[MFP]' not in sta['flags']:
382         raise Exception("MFP flag not present for STA")
383
384     dev[0].set_network(id, "ieee80211w", "0")
385     dev[0].request("REASSOCIATE")
386     dev[0].wait_connected()
387     wt.require_sta_no_pmf(bssid, addr)
388     sta = hapd.get_sta(addr)
389     if '[MFP]' in sta['flags']:
390         raise Exception("MFP flag unexpectedly present for STA")
391     cmd = subprocess.Popen(['iw', 'dev', apdev[0]['ifname'], 'station', 'get',
392                             addr], stdout=subprocess.PIPE)
393     (data,err) = cmd.communicate()
394     if "yes" in [l for l in data.splitlines() if "MFP" in l][0]:
395         raise Exception("Kernel STA entry had MFP enabled")
396
397     dev[0].set_network(id, "ieee80211w", "1")
398     dev[0].request("REASSOCIATE")
399     dev[0].wait_connected()
400     wt.require_sta_pmf(bssid, addr)
401     sta = hapd.get_sta(addr)
402     if '[MFP]' not in sta['flags']:
403         raise Exception("MFP flag not present for STA")
404     cmd = subprocess.Popen(['iw', 'dev', apdev[0]['ifname'], 'station', 'get',
405                             addr], stdout=subprocess.PIPE)
406     (data,err) = cmd.communicate()
407     if "yes" not in [l for l in data.splitlines() if "MFP" in l][0]:
408         raise Exception("Kernel STA entry did not have MFP enabled")