1 # Protected management frames tests
2 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
10 logger = logging.getLogger()
14 from wlantest import Wlantest
15 from wpasupplicant import WpaSupplicant
17 def test_ap_pmf_required(dev, apdev):
18 """WPA2-PSK AP with PMF required"""
19 ssid = "test-pmf-required"
20 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
21 params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
22 params["ieee80211w"] = "2";
23 hapd = hostapd.add_ap(apdev[0], params)
27 wt.add_passphrase("12345678")
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",
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",
40 hwsim_utils.test_connectivity(dev[1], hapd)
41 hapd.request("SA_QUERY " + dev[0].p2p_interface_addr())
42 hapd.request("SA_QUERY " + dev[1].p2p_interface_addr())
43 wt.require_ap_pmf_mandatory(apdev[0]['bssid'])
44 wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
45 wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
47 if wt.get_sta_counter("valid_saqueryresp_tx", apdev[0]['bssid'],
48 dev[0].p2p_interface_addr()) < 1:
49 raise Exception("STA did not reply to SA Query")
50 if wt.get_sta_counter("valid_saqueryresp_tx", apdev[0]['bssid'],
51 dev[1].p2p_interface_addr()) < 1:
52 raise Exception("STA did not reply to SA Query")
54 def test_ap_pmf_optional(dev, apdev):
55 """WPA2-PSK AP with PMF optional"""
56 ssid = "test-pmf-optional"
57 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
58 params["wpa_key_mgmt"] = "WPA-PSK";
59 params["ieee80211w"] = "1";
60 hapd = hostapd.add_ap(apdev[0], params)
64 wt.add_passphrase("12345678")
65 dev[0].connect(ssid, psk="12345678", ieee80211w="1",
66 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
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",
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())
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 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
81 params["wpa_key_mgmt"] = "WPA-PSK WPA-PSK-SHA256";
82 params["ieee80211w"] = "1";
83 hapd = hostapd.add_ap(apdev[0], params)
87 wt.add_passphrase("12345678")
88 dev[0].connect(ssid, psk="12345678", ieee80211w="1",
89 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
91 hwsim_utils.test_connectivity(dev[0], hapd)
92 dev[1].connect(ssid, psk="12345678", ieee80211w="2",
93 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
95 hwsim_utils.test_connectivity(dev[1], hapd)
96 wt.require_ap_pmf_optional(apdev[0]['bssid'])
97 wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
98 wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[0].p2p_interface_addr(),
100 wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
101 wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[1].p2p_interface_addr(),
104 def test_ap_pmf_negative(dev, apdev):
105 """WPA2-PSK AP without PMF (negative test)"""
106 ssid = "test-pmf-negative"
107 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
108 hapd = hostapd.add_ap(apdev[0], params)
112 wt.add_passphrase("12345678")
113 dev[0].connect(ssid, psk="12345678", ieee80211w="1",
114 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
116 hwsim_utils.test_connectivity(dev[0], hapd)
118 dev[1].connect(ssid, psk="12345678", ieee80211w="2",
119 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
121 hwsim_utils.test_connectivity(dev[1], hapd)
122 raise Exception("PMF required STA connected to no PMF AP")
124 logger.debug("Ignore expected exception: " + str(e))
125 wt.require_ap_no_pmf(apdev[0]['bssid'])
127 def test_ap_pmf_assoc_comeback(dev, apdev):
128 """WPA2-PSK AP with PMF association comeback"""
129 ssid = "assoc-comeback"
130 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
131 params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
132 params["ieee80211w"] = "2";
133 hapd = hostapd.add_ap(apdev[0], params)
137 wt.add_passphrase("12345678")
138 dev[0].connect(ssid, psk="12345678", ieee80211w="1",
139 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
141 hapd.set("ext_mgmt_frame_handling", "1")
142 dev[0].request("DISCONNECT")
143 dev[0].wait_disconnected(timeout=10)
144 hapd.set("ext_mgmt_frame_handling", "0")
145 dev[0].request("REASSOCIATE")
146 dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
147 if wt.get_sta_counter("assocresp_comeback", apdev[0]['bssid'],
148 dev[0].p2p_interface_addr()) < 1:
149 raise Exception("AP did not use association comeback request")
151 def test_ap_pmf_assoc_comeback2(dev, apdev):
152 """WPA2-PSK AP with PMF association comeback (using DROP_SA)"""
153 ssid = "assoc-comeback"
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], params)
161 wt.add_passphrase("12345678")
162 dev[0].connect(ssid, psk="12345678", ieee80211w="2",
163 key_mgmt="WPA-PSK", proto="WPA2", scan_freq="2412")
164 if "OK" not in dev[0].request("DROP_SA"):
165 raise Exception("DROP_SA failed")
166 dev[0].request("REASSOCIATE")
167 dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
168 if wt.get_sta_counter("reassocresp_comeback", apdev[0]['bssid'],
169 dev[0].p2p_interface_addr()) < 1:
170 raise Exception("AP did not use reassociation comeback request")
172 def test_ap_pmf_sta_sa_query(dev, apdev):
173 """WPA2-PSK AP with station using SA Query"""
174 ssid = "assoc-comeback"
175 addr = dev[0].own_addr()
177 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
178 wpas.interface_add("wlan5", drv_params="use_monitor=1")
179 id = wpas.add_network()
180 wpas.set_network(id, "mode", "2")
181 wpas.set_network_quoted(id, "ssid", ssid)
182 wpas.set_network(id, "proto", "WPA2")
183 wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
184 wpas.set_network(id, "ieee80211w", "2")
185 wpas.set_network_quoted(id, "psk", "12345678")
186 wpas.set_network(id, "pairwise", "CCMP")
187 wpas.set_network(id, "group", "CCMP")
188 wpas.set_network(id, "frequency", "2412")
189 wpas.connect_network(id)
190 bssid = wpas.own_addr()
196 wt.add_passphrase("12345678")
198 dev[0].connect(ssid, psk="12345678", ieee80211w="1",
199 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
202 wpas.request("DEAUTHENTICATE " + addr + " test=0")
204 wpas.request("DISASSOCIATE " + addr + " test=0")
206 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
208 raise Exception("Unexpected disconnection")
210 wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
212 wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
214 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
216 raise Exception("Unexpected disconnection")
217 if wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr) < 1:
218 raise Exception("STA did not send SA Query")
219 if wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr) < 1:
220 raise Exception("AP did not reply to SA Query")
223 def test_ap_pmf_sta_sa_query_no_response(dev, apdev):
224 """WPA2-PSK AP with station using SA Query and getting no response"""
225 ssid = "assoc-comeback"
226 addr = dev[0].own_addr()
228 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
229 wpas.interface_add("wlan5", drv_params="use_monitor=1")
230 id = wpas.add_network()
231 wpas.set_network(id, "mode", "2")
232 wpas.set_network_quoted(id, "ssid", ssid)
233 wpas.set_network(id, "proto", "WPA2")
234 wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
235 wpas.set_network(id, "ieee80211w", "2")
236 wpas.set_network_quoted(id, "psk", "12345678")
237 wpas.set_network(id, "pairwise", "CCMP")
238 wpas.set_network(id, "group", "CCMP")
239 wpas.set_network(id, "frequency", "2412")
240 wpas.connect_network(id)
241 bssid = wpas.own_addr()
244 dev[0].connect(ssid, psk="12345678", ieee80211w="1",
245 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
248 wpas.request("DEAUTHENTICATE " + addr + " test=0")
250 wpas.request("DISASSOCIATE " + addr + " test=0")
252 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
254 raise Exception("Unexpected disconnection")
256 wpas.request("SET ext_mgmt_frame_handling 1")
257 wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
259 wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
261 dev[0].wait_disconnected()
263 wpas.request("SET ext_mgmt_frame_handling 0")
264 dev[0].wait_connected()
267 def test_ap_pmf_sta_unprot_deauth_burst(dev, apdev):
268 """WPA2-PSK AP with station receiving burst of unprotected Deauthentication frames"""
269 ssid = "deauth-attack"
270 addr = dev[0].own_addr()
272 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
273 wpas.interface_add("wlan5", drv_params="use_monitor=1")
274 id = wpas.add_network()
275 wpas.set_network(id, "mode", "2")
276 wpas.set_network_quoted(id, "ssid", ssid)
277 wpas.set_network(id, "proto", "WPA2")
278 wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
279 wpas.set_network(id, "ieee80211w", "2")
280 wpas.set_network_quoted(id, "psk", "12345678")
281 wpas.set_network(id, "pairwise", "CCMP")
282 wpas.set_network(id, "group", "CCMP")
283 wpas.set_network(id, "frequency", "2412")
284 wpas.connect_network(id)
285 bssid = wpas.own_addr()
290 wt.add_passphrase("12345678")
292 dev[0].connect(ssid, psk="12345678", ieee80211w="1",
293 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
296 for i in range(0, 10):
297 wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
298 wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
299 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
301 raise Exception("Unexpected disconnection")
302 num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
303 num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
305 raise Exception("STA did not send SA Query")
307 raise Exception("AP did not reply to SA Query")
309 raise Exception("STA initiated too many SA Query procedures (%d)" % num_req)
312 for i in range(0, 5):
313 wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
314 wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
315 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
317 raise Exception("Unexpected disconnection")
318 num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
319 num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
320 if num_req != 2 or num_resp != 2:
321 raise Exception("Unexpected number of SA Query procedures (req=%d resp=%d)" % (num_req, num_resp))
323 def test_ap_pmf_required_eap(dev, apdev):
324 """WPA2-EAP AP with PMF required"""
325 ssid = "test-pmf-required-eap"
326 params = hostapd.wpa2_eap_params(ssid=ssid)
327 params["wpa_key_mgmt"] = "WPA-EAP-SHA256";
328 params["ieee80211w"] = "2";
329 hapd = hostapd.add_ap(apdev[0], params)
330 key_mgmt = hapd.get_config()['key_mgmt']
331 if key_mgmt.split(' ')[0] != "WPA-EAP-SHA256":
332 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
333 dev[0].connect("test-pmf-required-eap", key_mgmt="WPA-EAP-SHA256",
334 ieee80211w="2", eap="PSK", identity="psk.user@example.com",
335 password_hex="0123456789abcdef0123456789abcdef",
337 dev[1].connect("test-pmf-required-eap", key_mgmt="WPA-EAP WPA-EAP-SHA256",
338 ieee80211w="1", eap="PSK", identity="psk.user@example.com",
339 password_hex="0123456789abcdef0123456789abcdef",
342 def test_ap_pmf_optional_eap(dev, apdev):
343 """WPA2EAP AP with PMF optional"""
344 params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
345 params["ieee80211w"] = "1";
346 hapd = hostapd.add_ap(apdev[0], params)
347 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
348 identity="pap user", anonymous_identity="ttls",
350 ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
351 ieee80211w="1", scan_freq="2412")
352 dev[1].connect("test-wpa2-eap", key_mgmt="WPA-EAP WPA-EAP-SHA256",
353 eap="TTLS", identity="pap user", anonymous_identity="ttls",
355 ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
356 ieee80211w="2", scan_freq="2412")
358 def test_ap_pmf_required_sha1(dev, apdev):
359 """WPA2-PSK AP with PMF required with SHA1 AKM"""
360 ssid = "test-pmf-required-sha1"
361 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
362 params["wpa_key_mgmt"] = "WPA-PSK";
363 params["ieee80211w"] = "2";
364 hapd = hostapd.add_ap(apdev[0], params)
368 wt.add_passphrase("12345678")
369 key_mgmt = hapd.get_config()['key_mgmt']
370 if key_mgmt.split(' ')[0] != "WPA-PSK":
371 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
372 dev[0].connect(ssid, psk="12345678", ieee80211w="2",
373 key_mgmt="WPA-PSK", proto="WPA2", scan_freq="2412")
374 if "[WPA2-PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
375 raise Exception("Scan results missing RSN element info")
376 hwsim_utils.test_connectivity(dev[0], hapd)
378 def test_ap_pmf_toggle(dev, apdev):
379 """WPA2-PSK AP with PMF optional and changing PMF on reassociation"""
381 _test_ap_pmf_toggle(dev, apdev)
383 dev[0].request("SET reassoc_same_bss_optim 0")
385 def _test_ap_pmf_toggle(dev, apdev):
386 ssid = "test-pmf-optional"
387 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
388 params["wpa_key_mgmt"] = "WPA-PSK";
389 params["ieee80211w"] = "1";
390 params["assoc_sa_query_max_timeout"] = "1"
391 params["assoc_sa_query_retry_timeout"] = "1"
392 hapd = hostapd.add_ap(apdev[0], params)
396 wt.add_passphrase("12345678")
397 bssid = apdev[0]['bssid']
398 addr = dev[0].own_addr()
399 dev[0].request("SET reassoc_same_bss_optim 1")
400 id = dev[0].connect(ssid, psk="12345678", ieee80211w="1",
401 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
403 wt.require_ap_pmf_optional(bssid)
404 wt.require_sta_pmf(bssid, addr)
405 sta = hapd.get_sta(addr)
406 if '[MFP]' not in sta['flags']:
407 raise Exception("MFP flag not present for STA")
409 dev[0].set_network(id, "ieee80211w", "0")
410 dev[0].request("REASSOCIATE")
411 dev[0].wait_connected()
412 wt.require_sta_no_pmf(bssid, addr)
413 sta = hapd.get_sta(addr)
414 if '[MFP]' in sta['flags']:
415 raise Exception("MFP flag unexpectedly present for STA")
416 cmd = subprocess.Popen(['iw', 'dev', apdev[0]['ifname'], 'station', 'get',
417 addr], stdout=subprocess.PIPE)
418 (data,err) = cmd.communicate()
419 if "yes" in [l for l in data.splitlines() if "MFP" in l][0]:
420 raise Exception("Kernel STA entry had MFP enabled")
422 dev[0].set_network(id, "ieee80211w", "1")
423 dev[0].request("REASSOCIATE")
424 dev[0].wait_connected()
425 wt.require_sta_pmf(bssid, addr)
426 sta = hapd.get_sta(addr)
427 if '[MFP]' not in sta['flags']:
428 raise Exception("MFP flag not present for STA")
429 cmd = subprocess.Popen(['iw', 'dev', apdev[0]['ifname'], 'station', 'get',
430 addr], stdout=subprocess.PIPE)
431 (data,err) = cmd.communicate()
432 if "yes" not in [l for l in data.splitlines() if "MFP" in l][0]:
433 raise Exception("Kernel STA entry did not have MFP enabled")
435 def test_ap_pmf_required_sta_no_pmf(dev, apdev):
436 """WPA2-PSK AP with PMF required and PMF disabled on STA"""
437 ssid = "test-pmf-required"
438 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
439 params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
440 params["ieee80211w"] = "2";
441 hapd = hostapd.add_ap(apdev[0], params)
443 # Disable PMF on the station and try to connect
444 dev[0].connect(ssid, psk="12345678", ieee80211w="0",
445 key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
446 scan_freq="2412", wait_connect=False)
447 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
448 "CTRL-EVENT-ASSOC-REJECT"], timeout=2)
450 raise Exception("No connection result")
451 if "CTRL-EVENT-ASSOC-REJECT" in ev:
452 raise Exception("Tried to connect to PMF required AP without PMF enabled")
453 dev[0].request("REMOVE_NETWORK all")