2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
12 logger = logging.getLogger()
16 from utils import HwsimSkip, alloc_fail, fail_test
17 from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations
19 def test_sae(dev, apdev):
20 """SAE with default group"""
21 if "SAE" not in dev[0].get_capability("auth_alg"):
22 raise HwsimSkip("SAE not supported")
23 params = hostapd.wpa2_params(ssid="test-sae",
24 passphrase="12345678")
25 params['wpa_key_mgmt'] = 'SAE'
26 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
27 key_mgmt = hapd.get_config()['key_mgmt']
28 if key_mgmt.split(' ')[0] != "SAE":
29 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
31 dev[0].request("SET sae_groups ")
32 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
34 if dev[0].get_status_field('sae_group') != '19':
35 raise Exception("Expected default SAE group not used")
36 bss = dev[0].get_bss(apdev[0]['bssid'])
37 if 'flags' not in bss:
38 raise Exception("Could not get BSS flags from BSS table")
39 if "[WPA2-SAE-CCMP]" not in bss['flags']:
40 raise Exception("Unexpected BSS flags: " + bss['flags'])
42 def test_sae_password_ecc(dev, apdev):
43 """SAE with number of different passwords (ECC)"""
44 if "SAE" not in dev[0].get_capability("auth_alg"):
45 raise HwsimSkip("SAE not supported")
46 params = hostapd.wpa2_params(ssid="test-sae",
47 passphrase="12345678")
48 params['wpa_key_mgmt'] = 'SAE'
49 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
51 dev[0].request("SET sae_groups 19")
54 password = "12345678-" + str(i)
55 hapd.set("wpa_passphrase", password)
56 dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
58 dev[0].request("REMOVE_NETWORK all")
59 dev[0].wait_disconnected()
61 def test_sae_password_ffc(dev, apdev):
62 """SAE with number of different passwords (FFC)"""
63 if "SAE" not in dev[0].get_capability("auth_alg"):
64 raise HwsimSkip("SAE not supported")
65 params = hostapd.wpa2_params(ssid="test-sae",
66 passphrase="12345678")
67 params['wpa_key_mgmt'] = 'SAE'
68 params['sae_groups'] = '22'
69 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
71 dev[0].request("SET sae_groups 22")
74 password = "12345678-" + str(i)
75 hapd.set("wpa_passphrase", password)
76 dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
78 dev[0].request("REMOVE_NETWORK all")
79 dev[0].wait_disconnected()
81 def test_sae_pmksa_caching(dev, apdev):
82 """SAE and PMKSA caching"""
83 if "SAE" not in dev[0].get_capability("auth_alg"):
84 raise HwsimSkip("SAE not supported")
85 params = hostapd.wpa2_params(ssid="test-sae",
86 passphrase="12345678")
87 params['wpa_key_mgmt'] = 'SAE'
88 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
90 dev[0].request("SET sae_groups ")
91 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
93 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
95 raise Exception("No connection event received from hostapd")
96 dev[0].request("DISCONNECT")
97 dev[0].wait_disconnected()
98 dev[0].request("RECONNECT")
99 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
100 if dev[0].get_status_field('sae_group') is not None:
101 raise Exception("SAE group claimed to have been used")
103 def test_sae_pmksa_caching_disabled(dev, apdev):
104 """SAE and PMKSA caching disabled"""
105 if "SAE" not in dev[0].get_capability("auth_alg"):
106 raise HwsimSkip("SAE not supported")
107 params = hostapd.wpa2_params(ssid="test-sae",
108 passphrase="12345678")
109 params['wpa_key_mgmt'] = 'SAE'
110 params['disable_pmksa_caching'] = '1'
111 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
113 dev[0].request("SET sae_groups ")
114 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
116 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
118 raise Exception("No connection event received from hostapd")
119 dev[0].request("DISCONNECT")
120 dev[0].wait_disconnected()
121 dev[0].request("RECONNECT")
122 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
123 if dev[0].get_status_field('sae_group') != '19':
124 raise Exception("Expected default SAE group not used")
126 def test_sae_groups(dev, apdev):
127 """SAE with all supported groups"""
128 if "SAE" not in dev[0].get_capability("auth_alg"):
129 raise HwsimSkip("SAE not supported")
130 # This is the full list of supported groups, but groups 14-16 (2048-4096 bit
131 # MODP) and group 21 (521-bit random ECP group) are a bit too slow on some
132 # VMs and can result in hitting the mac80211 authentication timeout, so
133 # allow them to fail and just report such failures in the debug log.
134 sae_groups = [ 19, 25, 26, 20, 21, 2, 5, 14, 15, 16, 22, 23, 24 ]
135 tls = dev[0].request("GET tls_library")
136 if tls.startswith("OpenSSL") and "build=OpenSSL 1.0.2" in tls and "run=OpenSSL 1.0.2" in tls:
137 logger.info("Add Brainpool EC groups since OpenSSL is new enough")
138 sae_groups += [ 27, 28, 29, 30 ]
139 heavy_groups = [ 14, 15, 16 ]
140 groups = [str(g) for g in sae_groups]
141 params = hostapd.wpa2_params(ssid="test-sae-groups",
142 passphrase="12345678")
143 params['wpa_key_mgmt'] = 'SAE'
144 params['sae_groups'] = ' '.join(groups)
145 hostapd.add_ap(apdev[0]['ifname'], params)
148 logger.info("Testing SAE group " + g)
149 dev[0].request("SET sae_groups " + g)
150 id = dev[0].connect("test-sae-groups", psk="12345678", key_mgmt="SAE",
151 scan_freq="2412", wait_connect=False)
152 if int(g) in heavy_groups:
153 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5)
155 logger.info("No connection with heavy SAE group %s did not connect - likely hitting timeout in mac80211" % g)
156 dev[0].remove_network(id)
158 dev[0].dump_monitor()
160 logger.info("Connection with heavy SAE group " + g)
162 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
164 if "BoringSSL" in tls and int(g) in [ 25 ]:
165 logger.info("Ignore connection failure with group " + g + " with BoringSSL")
166 dev[0].remove_network(id)
167 dev[0].dump_monitor()
169 raise Exception("Connection timed out with group " + g)
170 if dev[0].get_status_field('sae_group') != g:
171 raise Exception("Expected SAE group not used")
172 dev[0].remove_network(id)
173 dev[0].wait_disconnected()
174 dev[0].dump_monitor()
176 def test_sae_group_nego(dev, apdev):
177 """SAE group negotiation"""
178 if "SAE" not in dev[0].get_capability("auth_alg"):
179 raise HwsimSkip("SAE not supported")
180 params = hostapd.wpa2_params(ssid="test-sae-group-nego",
181 passphrase="12345678")
182 params['wpa_key_mgmt'] = 'SAE'
183 params['sae_groups'] = '19'
184 hostapd.add_ap(apdev[0]['ifname'], params)
186 dev[0].request("SET sae_groups 25 26 20 19")
187 dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE",
189 if dev[0].get_status_field('sae_group') != '19':
190 raise Exception("Expected SAE group not used")
192 def test_sae_anti_clogging(dev, apdev):
193 """SAE anti clogging"""
194 if "SAE" not in dev[0].get_capability("auth_alg"):
195 raise HwsimSkip("SAE not supported")
196 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
197 params['wpa_key_mgmt'] = 'SAE'
198 params['sae_anti_clogging_threshold'] = '1'
199 hostapd.add_ap(apdev[0]['ifname'], params)
201 dev[0].request("SET sae_groups ")
202 dev[1].request("SET sae_groups ")
204 for i in range(0, 2):
205 dev[i].scan(freq="2412")
206 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
207 scan_freq="2412", only_add_network=True)
208 for i in range(0, 2):
209 dev[i].select_network(id[i])
210 for i in range(0, 2):
211 dev[i].wait_connected(timeout=10)
213 def test_sae_forced_anti_clogging(dev, apdev):
214 """SAE anti clogging (forced)"""
215 if "SAE" not in dev[0].get_capability("auth_alg"):
216 raise HwsimSkip("SAE not supported")
217 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
218 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
219 params['sae_anti_clogging_threshold'] = '0'
220 hostapd.add_ap(apdev[0]['ifname'], params)
221 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
222 for i in range(0, 2):
223 dev[i].request("SET sae_groups ")
224 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
227 def test_sae_mixed(dev, apdev):
228 """Mixed SAE and non-SAE network"""
229 if "SAE" not in dev[0].get_capability("auth_alg"):
230 raise HwsimSkip("SAE not supported")
231 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
232 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
233 params['sae_anti_clogging_threshold'] = '0'
234 hostapd.add_ap(apdev[0]['ifname'], params)
236 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
237 for i in range(0, 2):
238 dev[i].request("SET sae_groups ")
239 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
242 def test_sae_missing_password(dev, apdev):
243 """SAE and missing password"""
244 if "SAE" not in dev[0].get_capability("auth_alg"):
245 raise HwsimSkip("SAE not supported")
246 params = hostapd.wpa2_params(ssid="test-sae",
247 passphrase="12345678")
248 params['wpa_key_mgmt'] = 'SAE'
249 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
251 dev[0].request("SET sae_groups ")
252 id = dev[0].connect("test-sae",
253 raw_psk="46b4a73b8a951ad53ebd2e0afdb9c5483257edd4c21d12b7710759da70945858",
254 key_mgmt="SAE", scan_freq="2412", wait_connect=False)
255 ev = dev[0].wait_event(['CTRL-EVENT-SSID-TEMP-DISABLED'], timeout=10)
257 raise Exception("Invalid network not temporarily disabled")
260 def test_sae_key_lifetime_in_memory(dev, apdev, params):
261 """SAE and key lifetime in memory"""
262 if "SAE" not in dev[0].get_capability("auth_alg"):
263 raise HwsimSkip("SAE not supported")
264 password = "5ad144a7c1f5a5503baa6fa01dabc15b1843e8c01662d78d16b70b5cd23cf8b"
265 p = hostapd.wpa2_params(ssid="test-sae", passphrase=password)
266 p['wpa_key_mgmt'] = 'SAE'
267 hapd = hostapd.add_ap(apdev[0]['ifname'], p)
269 pid = find_wpas_process(dev[0])
271 dev[0].request("SET sae_groups ")
272 id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
276 buf = read_process_memory(pid, password)
278 dev[0].request("DISCONNECT")
279 dev[0].wait_disconnected()
288 with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
289 for l in f.readlines():
290 if "SAE: k - hexdump" in l:
291 val = l.strip().split(':')[3].replace(' ', '')
292 sae_k = binascii.unhexlify(val)
293 if "SAE: keyseed - hexdump" in l:
294 val = l.strip().split(':')[3].replace(' ', '')
295 sae_keyseed = binascii.unhexlify(val)
296 if "SAE: KCK - hexdump" in l:
297 val = l.strip().split(':')[3].replace(' ', '')
298 sae_kck = binascii.unhexlify(val)
299 if "SAE: PMK - hexdump" in l:
300 val = l.strip().split(':')[3].replace(' ', '')
301 pmk = binascii.unhexlify(val)
302 if "WPA: PTK - hexdump" in l:
303 val = l.strip().split(':')[3].replace(' ', '')
304 ptk = binascii.unhexlify(val)
305 if "WPA: Group Key - hexdump" in l:
306 val = l.strip().split(':')[3].replace(' ', '')
307 gtk = binascii.unhexlify(val)
308 if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk:
309 raise Exception("Could not find keys from debug log")
311 raise Exception("Unexpected GTK length")
317 fname = os.path.join(params['logdir'],
318 'sae_key_lifetime_in_memory.memctx-')
320 logger.info("Checking keys in memory while associated")
321 get_key_locations(buf, password, "Password")
322 get_key_locations(buf, pmk, "PMK")
323 if password not in buf:
324 raise HwsimSkip("Password not found while associated")
326 raise HwsimSkip("PMK not found while associated")
328 raise Exception("KCK not found while associated")
330 raise Exception("KEK not found while associated")
332 raise Exception("TK found from memory")
334 raise Exception("GTK found from memory")
335 verify_not_present(buf, sae_k, fname, "SAE(k)")
336 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
337 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
339 logger.info("Checking keys in memory after disassociation")
340 buf = read_process_memory(pid, password)
342 # Note: Password is still present in network configuration
343 # Note: PMK is in PMKSA cache
345 get_key_locations(buf, password, "Password")
346 get_key_locations(buf, pmk, "PMK")
347 verify_not_present(buf, kck, fname, "KCK")
348 verify_not_present(buf, kek, fname, "KEK")
349 verify_not_present(buf, tk, fname, "TK")
350 verify_not_present(buf, gtk, fname, "GTK")
351 verify_not_present(buf, sae_k, fname, "SAE(k)")
352 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
353 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
355 dev[0].request("PMKSA_FLUSH")
356 logger.info("Checking keys in memory after PMKSA cache flush")
357 buf = read_process_memory(pid, password)
358 get_key_locations(buf, password, "Password")
359 get_key_locations(buf, pmk, "PMK")
360 verify_not_present(buf, pmk, fname, "PMK")
362 dev[0].request("REMOVE_NETWORK all")
364 logger.info("Checking keys in memory after network profile removal")
365 buf = read_process_memory(pid, password)
367 get_key_locations(buf, password, "Password")
368 get_key_locations(buf, pmk, "PMK")
369 verify_not_present(buf, password, fname, "password")
370 verify_not_present(buf, pmk, fname, "PMK")
371 verify_not_present(buf, kck, fname, "KCK")
372 verify_not_present(buf, kek, fname, "KEK")
373 verify_not_present(buf, tk, fname, "TK")
374 verify_not_present(buf, gtk, fname, "GTK")
375 verify_not_present(buf, sae_k, fname, "SAE(k)")
376 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
377 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
379 def test_sae_oom_wpas(dev, apdev):
380 """SAE and OOM in wpa_supplicant"""
381 if "SAE" not in dev[0].get_capability("auth_alg"):
382 raise HwsimSkip("SAE not supported")
383 params = hostapd.wpa2_params(ssid="test-sae",
384 passphrase="12345678")
385 params['wpa_key_mgmt'] = 'SAE'
386 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
388 dev[0].request("SET sae_groups 25")
389 tls = dev[0].request("GET tls_library")
390 if "BoringSSL" in tls:
391 dev[0].request("SET sae_groups 26")
392 with alloc_fail(dev[0], 1, "sae_set_group"):
393 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
395 dev[0].request("REMOVE_NETWORK all")
397 dev[0].request("SET sae_groups ")
398 with alloc_fail(dev[0], 2, "sae_set_group"):
399 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
401 dev[0].request("REMOVE_NETWORK all")
403 def test_sae_proto_ecc(dev, apdev):
404 """SAE protocol testing (ECC)"""
405 if "SAE" not in dev[0].get_capability("auth_alg"):
406 raise HwsimSkip("SAE not supported")
407 params = hostapd.wpa2_params(ssid="test-sae",
408 passphrase="12345678")
409 params['wpa_key_mgmt'] = 'SAE'
410 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
411 bssid = apdev[0]['bssid']
413 dev[0].request("SET sae_groups 19")
415 tests = [ ("Confirm mismatch",
416 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
417 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc4240"),
418 ("Commit without even full cyclic group field",
422 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02",
424 ("Invalid commit scalar (0)",
425 "1300" + "0000000000000000000000000000000000000000000000000000000000000000" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
427 ("Invalid commit scalar (1)",
428 "1300" + "0000000000000000000000000000000000000000000000000000000000000001" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
430 ("Invalid commit scalar (> r)",
431 "1300" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
433 ("Commit element not on curve",
434 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728d0000000000000000000000000000000000000000000000000000000000000000",
436 ("Invalid commit element (y coordinate > P)",
437 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
439 ("Invalid commit element (x coordinate > P)",
440 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
442 ("Different group in commit",
443 "1400" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
445 ("Too short confirm",
446 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
447 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc42")]
448 for (note, commit, confirm) in tests:
450 dev[0].scan_for_bss(bssid, freq=2412)
451 hapd.set("ext_mgmt_frame_handling", "1")
452 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
453 scan_freq="2412", wait_connect=False)
455 logger.info("Commit")
456 for i in range(0, 10):
459 raise Exception("MGMT RX wait timed out (commit)")
460 if req['subtype'] == 11:
464 raise Exception("Authentication frame (commit) not received")
468 resp['fc'] = req['fc']
469 resp['da'] = req['sa']
470 resp['sa'] = req['da']
471 resp['bssid'] = req['bssid']
472 resp['payload'] = binascii.unhexlify("030001000000" + commit)
476 logger.info("Confirm")
477 for i in range(0, 10):
480 raise Exception("MGMT RX wait timed out (confirm)")
481 if req['subtype'] == 11:
485 raise Exception("Authentication frame (confirm) not received")
489 resp['fc'] = req['fc']
490 resp['da'] = req['sa']
491 resp['sa'] = req['da']
492 resp['bssid'] = req['bssid']
493 resp['payload'] = binascii.unhexlify("030002000000" + confirm)
497 dev[0].request("REMOVE_NETWORK all")
498 hapd.set("ext_mgmt_frame_handling", "0")
501 def test_sae_proto_ffc(dev, apdev):
502 """SAE protocol testing (FFC)"""
503 if "SAE" not in dev[0].get_capability("auth_alg"):
504 raise HwsimSkip("SAE not supported")
505 params = hostapd.wpa2_params(ssid="test-sae",
506 passphrase="12345678")
507 params['wpa_key_mgmt'] = 'SAE'
508 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
509 bssid = apdev[0]['bssid']
511 dev[0].request("SET sae_groups 2")
513 tests = [ ("Confirm mismatch",
514 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a17486",
515 "0000f3116a9731f1259622e3eb55d4b3b50ba16f8c5f5565b28e609b180c51460251"),
517 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a174",
519 ("Invalid element (0) in commit",
520 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
522 ("Invalid element (1) in commit",
523 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
525 ("Invalid element (> P) in commit",
526 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
528 for (note, commit, confirm) in tests:
530 dev[0].scan_for_bss(bssid, freq=2412)
531 hapd.set("ext_mgmt_frame_handling", "1")
532 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
533 scan_freq="2412", wait_connect=False)
535 logger.info("Commit")
536 for i in range(0, 10):
539 raise Exception("MGMT RX wait timed out (commit)")
540 if req['subtype'] == 11:
544 raise Exception("Authentication frame (commit) not received")
548 resp['fc'] = req['fc']
549 resp['da'] = req['sa']
550 resp['sa'] = req['da']
551 resp['bssid'] = req['bssid']
552 resp['payload'] = binascii.unhexlify("030001000000" + commit)
556 logger.info("Confirm")
557 for i in range(0, 10):
560 raise Exception("MGMT RX wait timed out (confirm)")
561 if req['subtype'] == 11:
565 raise Exception("Authentication frame (confirm) not received")
569 resp['fc'] = req['fc']
570 resp['da'] = req['sa']
571 resp['sa'] = req['da']
572 resp['bssid'] = req['bssid']
573 resp['payload'] = binascii.unhexlify("030002000000" + confirm)
577 dev[0].request("REMOVE_NETWORK all")
578 hapd.set("ext_mgmt_frame_handling", "0")
581 def test_sae_no_ffc_by_default(dev, apdev):
582 """SAE and default groups rejecting FFC"""
583 if "SAE" not in dev[0].get_capability("auth_alg"):
584 raise HwsimSkip("SAE not supported")
585 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
586 params['wpa_key_mgmt'] = 'SAE'
587 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
589 dev[0].request("SET sae_groups 5")
590 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412",
592 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
594 raise Exception("Did not try to authenticate")
595 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
597 raise Exception("Did not try to authenticate (2)")
598 dev[0].request("REMOVE_NETWORK all")
600 def sae_reflection_attack(apdev, dev, group):
601 if "SAE" not in dev.get_capability("auth_alg"):
602 raise HwsimSkip("SAE not supported")
603 params = hostapd.wpa2_params(ssid="test-sae",
604 passphrase="no-knowledge-of-passphrase")
605 params['wpa_key_mgmt'] = 'SAE'
606 hapd = hostapd.add_ap(apdev['ifname'], params)
607 bssid = apdev['bssid']
609 dev.scan_for_bss(bssid, freq=2412)
610 hapd.set("ext_mgmt_frame_handling", "1")
612 dev.request("SET sae_groups %d" % group)
613 dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
614 scan_freq="2412", wait_connect=False)
617 for i in range(0, 10):
620 raise Exception("MGMT RX wait timed out")
621 if req['subtype'] == 11:
625 raise Exception("Authentication frame not received")
628 resp['fc'] = req['fc']
629 resp['da'] = req['sa']
630 resp['sa'] = req['da']
631 resp['bssid'] = req['bssid']
632 resp['payload'] = req['payload']
636 req = hapd.mgmt_rx(timeout=0.5)
638 if req['subtype'] == 11:
639 raise Exception("Unexpected Authentication frame seen")
641 def test_sae_reflection_attack_ecc(dev, apdev):
642 """SAE reflection attack (ECC)"""
643 sae_reflection_attack(apdev[0], dev[0], 19)
645 def test_sae_reflection_attack_ffc(dev, apdev):
646 """SAE reflection attack (FFC)"""
647 sae_reflection_attack(apdev[0], dev[0], 5)
649 def test_sae_anti_clogging_proto(dev, apdev):
650 """SAE anti clogging protocol testing"""
651 if "SAE" not in dev[0].get_capability("auth_alg"):
652 raise HwsimSkip("SAE not supported")
653 params = hostapd.wpa2_params(ssid="test-sae",
654 passphrase="no-knowledge-of-passphrase")
655 params['wpa_key_mgmt'] = 'SAE'
656 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
657 bssid = apdev[0]['bssid']
659 dev[0].scan_for_bss(bssid, freq=2412)
660 hapd.set("ext_mgmt_frame_handling", "1")
662 dev[0].request("SET sae_groups ")
663 dev[0].connect("test-sae", psk="anti-cloggign", key_mgmt="SAE",
664 scan_freq="2412", wait_connect=False)
667 for i in range(0, 10):
670 raise Exception("MGMT RX wait timed out")
671 if req['subtype'] == 11:
675 raise Exception("Authentication frame not received")
678 resp['fc'] = req['fc']
679 resp['da'] = req['sa']
680 resp['sa'] = req['da']
681 resp['bssid'] = req['bssid']
682 resp['payload'] = binascii.unhexlify("030001004c00" + "ffff00")
685 # Confirm (not received due to DH group being rejected)
686 req = hapd.mgmt_rx(timeout=0.5)
688 if req['subtype'] == 11:
689 raise Exception("Unexpected Authentication frame seen")
691 def test_sae_no_random(dev, apdev):
692 """SAE and no random numbers available"""
693 if "SAE" not in dev[0].get_capability("auth_alg"):
694 raise HwsimSkip("SAE not supported")
695 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
696 params['wpa_key_mgmt'] = 'SAE'
697 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
699 dev[0].request("SET sae_groups ")
700 tests = [ (1, "os_get_random;sae_get_rand"),
701 (1, "os_get_random;get_rand_1_to_p_1"),
702 (1, "os_get_random;get_random_qr_qnr"),
703 (1, "os_get_random;sae_derive_pwe_ecc") ]
704 for count, func in tests:
705 with fail_test(dev[0], count, func):
706 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
708 dev[0].request("REMOVE_NETWORK all")
709 dev[0].wait_disconnected()