]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_sae.py
tests: Mixed SAE and non-SAE network and MFP required with SAE
[thirdparty/hostap.git] / tests / hwsim / test_sae.py
1 # Test cases for SAE
2 # Copyright (c) 2013-2016, 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 from remotehost import remote_compatible
8 import binascii
9 import os
10 import time
11 import logging
12 logger = logging.getLogger()
13
14 import hwsim_utils
15 import hostapd
16 from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
17 from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations
18
19 @remote_compatible
20 def test_sae(dev, apdev):
21 """SAE with default group"""
22 if "SAE" not in dev[0].get_capability("auth_alg"):
23 raise HwsimSkip("SAE not supported")
24 params = hostapd.wpa2_params(ssid="test-sae",
25 passphrase="12345678")
26 params['wpa_key_mgmt'] = 'SAE'
27 hapd = hostapd.add_ap(apdev[0], params)
28 key_mgmt = hapd.get_config()['key_mgmt']
29 if key_mgmt.split(' ')[0] != "SAE":
30 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
31
32 dev[0].request("SET sae_groups ")
33 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
34 scan_freq="2412")
35 if dev[0].get_status_field('sae_group') != '19':
36 raise Exception("Expected default SAE group not used")
37 bss = dev[0].get_bss(apdev[0]['bssid'])
38 if 'flags' not in bss:
39 raise Exception("Could not get BSS flags from BSS table")
40 if "[WPA2-SAE-CCMP]" not in bss['flags']:
41 raise Exception("Unexpected BSS flags: " + bss['flags'])
42
43 res = hapd.request("STA-FIRST")
44 if "sae_group=19" not in res.splitlines():
45 raise Exception("hostapd STA output did not specify SAE group")
46
47 @remote_compatible
48 def test_sae_password_ecc(dev, apdev):
49 """SAE with number of different passwords (ECC)"""
50 if "SAE" not in dev[0].get_capability("auth_alg"):
51 raise HwsimSkip("SAE not supported")
52 params = hostapd.wpa2_params(ssid="test-sae",
53 passphrase="12345678")
54 params['wpa_key_mgmt'] = 'SAE'
55 hapd = hostapd.add_ap(apdev[0], params)
56
57 dev[0].request("SET sae_groups 19")
58
59 for i in range(10):
60 password = "12345678-" + str(i)
61 hapd.set("wpa_passphrase", password)
62 dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
63 scan_freq="2412")
64 dev[0].request("REMOVE_NETWORK all")
65 dev[0].wait_disconnected()
66
67 @remote_compatible
68 def test_sae_password_ffc(dev, apdev):
69 """SAE with number of different passwords (FFC)"""
70 if "SAE" not in dev[0].get_capability("auth_alg"):
71 raise HwsimSkip("SAE not supported")
72 params = hostapd.wpa2_params(ssid="test-sae",
73 passphrase="12345678")
74 params['wpa_key_mgmt'] = 'SAE'
75 params['sae_groups'] = '22'
76 hapd = hostapd.add_ap(apdev[0], params)
77
78 dev[0].request("SET sae_groups 22")
79
80 for i in range(10):
81 password = "12345678-" + str(i)
82 hapd.set("wpa_passphrase", password)
83 dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
84 scan_freq="2412")
85 dev[0].request("REMOVE_NETWORK all")
86 dev[0].wait_disconnected()
87
88 @remote_compatible
89 def test_sae_pmksa_caching(dev, apdev):
90 """SAE and PMKSA caching"""
91 if "SAE" not in dev[0].get_capability("auth_alg"):
92 raise HwsimSkip("SAE not supported")
93 params = hostapd.wpa2_params(ssid="test-sae",
94 passphrase="12345678")
95 params['wpa_key_mgmt'] = 'SAE'
96 hapd = hostapd.add_ap(apdev[0], params)
97
98 dev[0].request("SET sae_groups ")
99 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
100 scan_freq="2412")
101 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
102 if ev is None:
103 raise Exception("No connection event received from hostapd")
104 dev[0].request("DISCONNECT")
105 dev[0].wait_disconnected()
106 dev[0].request("RECONNECT")
107 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
108 if dev[0].get_status_field('sae_group') is not None:
109 raise Exception("SAE group claimed to have been used")
110
111 @remote_compatible
112 def test_sae_pmksa_caching_disabled(dev, apdev):
113 """SAE and PMKSA caching disabled"""
114 if "SAE" not in dev[0].get_capability("auth_alg"):
115 raise HwsimSkip("SAE not supported")
116 params = hostapd.wpa2_params(ssid="test-sae",
117 passphrase="12345678")
118 params['wpa_key_mgmt'] = 'SAE'
119 params['disable_pmksa_caching'] = '1'
120 hapd = hostapd.add_ap(apdev[0], params)
121
122 dev[0].request("SET sae_groups ")
123 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
124 scan_freq="2412")
125 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
126 if ev is None:
127 raise Exception("No connection event received from hostapd")
128 dev[0].request("DISCONNECT")
129 dev[0].wait_disconnected()
130 dev[0].request("RECONNECT")
131 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
132 if dev[0].get_status_field('sae_group') != '19':
133 raise Exception("Expected default SAE group not used")
134
135 def test_sae_groups(dev, apdev):
136 """SAE with all supported groups"""
137 if "SAE" not in dev[0].get_capability("auth_alg"):
138 raise HwsimSkip("SAE not supported")
139 # This is the full list of supported groups, but groups 14-16 (2048-4096 bit
140 # MODP) and group 21 (521-bit random ECP group) are a bit too slow on some
141 # VMs and can result in hitting the mac80211 authentication timeout, so
142 # allow them to fail and just report such failures in the debug log.
143 sae_groups = [ 19, 25, 26, 20, 21, 2, 5, 14, 15, 16, 22, 23, 24 ]
144 tls = dev[0].request("GET tls_library")
145 if tls.startswith("OpenSSL") and "build=OpenSSL 1.0.2" in tls and "run=OpenSSL 1.0.2" in tls:
146 logger.info("Add Brainpool EC groups since OpenSSL is new enough")
147 sae_groups += [ 27, 28, 29, 30 ]
148 heavy_groups = [ 14, 15, 16 ]
149 groups = [str(g) for g in sae_groups]
150 params = hostapd.wpa2_params(ssid="test-sae-groups",
151 passphrase="12345678")
152 params['wpa_key_mgmt'] = 'SAE'
153 params['sae_groups'] = ' '.join(groups)
154 hostapd.add_ap(apdev[0], params)
155
156 for g in groups:
157 logger.info("Testing SAE group " + g)
158 dev[0].request("SET sae_groups " + g)
159 id = dev[0].connect("test-sae-groups", psk="12345678", key_mgmt="SAE",
160 scan_freq="2412", wait_connect=False)
161 if int(g) in heavy_groups:
162 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5)
163 if ev is None:
164 logger.info("No connection with heavy SAE group %s did not connect - likely hitting timeout in mac80211" % g)
165 dev[0].remove_network(id)
166 time.sleep(0.1)
167 dev[0].dump_monitor()
168 continue
169 logger.info("Connection with heavy SAE group " + g)
170 else:
171 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
172 if ev is None:
173 if "BoringSSL" in tls and int(g) in [ 25 ]:
174 logger.info("Ignore connection failure with group " + g + " with BoringSSL")
175 dev[0].remove_network(id)
176 dev[0].dump_monitor()
177 continue
178 raise Exception("Connection timed out with group " + g)
179 if dev[0].get_status_field('sae_group') != g:
180 raise Exception("Expected SAE group not used")
181 dev[0].remove_network(id)
182 dev[0].wait_disconnected()
183 dev[0].dump_monitor()
184
185 @remote_compatible
186 def test_sae_group_nego(dev, apdev):
187 """SAE group negotiation"""
188 if "SAE" not in dev[0].get_capability("auth_alg"):
189 raise HwsimSkip("SAE not supported")
190 params = hostapd.wpa2_params(ssid="test-sae-group-nego",
191 passphrase="12345678")
192 params['wpa_key_mgmt'] = 'SAE'
193 params['sae_groups'] = '19'
194 hostapd.add_ap(apdev[0], params)
195
196 dev[0].request("SET sae_groups 25 26 20 19")
197 dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE",
198 scan_freq="2412")
199 if dev[0].get_status_field('sae_group') != '19':
200 raise Exception("Expected SAE group not used")
201
202 @remote_compatible
203 def test_sae_anti_clogging(dev, apdev):
204 """SAE anti clogging"""
205 if "SAE" not in dev[0].get_capability("auth_alg"):
206 raise HwsimSkip("SAE not supported")
207 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
208 params['wpa_key_mgmt'] = 'SAE'
209 params['sae_anti_clogging_threshold'] = '1'
210 hostapd.add_ap(apdev[0], params)
211
212 dev[0].request("SET sae_groups ")
213 dev[1].request("SET sae_groups ")
214 id = {}
215 for i in range(0, 2):
216 dev[i].scan(freq="2412")
217 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
218 scan_freq="2412", only_add_network=True)
219 for i in range(0, 2):
220 dev[i].select_network(id[i])
221 for i in range(0, 2):
222 dev[i].wait_connected(timeout=10)
223
224 def test_sae_forced_anti_clogging(dev, apdev):
225 """SAE anti clogging (forced)"""
226 if "SAE" not in dev[0].get_capability("auth_alg"):
227 raise HwsimSkip("SAE not supported")
228 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
229 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
230 params['sae_anti_clogging_threshold'] = '0'
231 hostapd.add_ap(apdev[0], params)
232 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
233 for i in range(0, 2):
234 dev[i].request("SET sae_groups ")
235 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
236 scan_freq="2412")
237
238 def test_sae_mixed(dev, apdev):
239 """Mixed SAE and non-SAE network"""
240 if "SAE" not in dev[0].get_capability("auth_alg"):
241 raise HwsimSkip("SAE not supported")
242 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
243 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
244 params['sae_anti_clogging_threshold'] = '0'
245 hostapd.add_ap(apdev[0], params)
246
247 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
248 for i in range(0, 2):
249 dev[i].request("SET sae_groups ")
250 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
251 scan_freq="2412")
252
253 def test_sae_mixed_mfp(dev, apdev):
254 """Mixed SAE and non-SAE network and MFP required with SAE"""
255 if "SAE" not in dev[0].get_capability("auth_alg"):
256 raise HwsimSkip("SAE not supported")
257 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
258 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
259 params["ieee80211w"] = "1"
260 params['sae_require_mfp'] = '1'
261 hostapd.add_ap(apdev[0], params)
262
263 dev[0].request("SET sae_groups ")
264 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2",
265 scan_freq="2412")
266 dev[0].dump_monitor()
267
268 dev[1].request("SET sae_groups ")
269 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="0",
270 scan_freq="2412", wait_connect=False)
271 ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED",
272 "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
273 if ev is None:
274 raise Exception("No connection result reported")
275 if "CTRL-EVENT-ASSOC-REJECT" not in ev:
276 raise Exception("SAE connection without MFP was not rejected")
277 if "status_code=31" not in ev:
278 raise Exception("Unexpected status code in rejection: " + ev)
279 dev[1].request("DISCONNECT")
280 dev[1].dump_monitor()
281
282 dev[2].connect("test-sae", psk="12345678", ieee80211w="0", scan_freq="2412")
283 dev[2].dump_monitor()
284
285 @remote_compatible
286 def test_sae_missing_password(dev, apdev):
287 """SAE and missing password"""
288 if "SAE" not in dev[0].get_capability("auth_alg"):
289 raise HwsimSkip("SAE not supported")
290 params = hostapd.wpa2_params(ssid="test-sae",
291 passphrase="12345678")
292 params['wpa_key_mgmt'] = 'SAE'
293 hapd = hostapd.add_ap(apdev[0], params)
294
295 dev[0].request("SET sae_groups ")
296 id = dev[0].connect("test-sae",
297 raw_psk="46b4a73b8a951ad53ebd2e0afdb9c5483257edd4c21d12b7710759da70945858",
298 key_mgmt="SAE", scan_freq="2412", wait_connect=False)
299 ev = dev[0].wait_event(['CTRL-EVENT-SSID-TEMP-DISABLED'], timeout=10)
300 if ev is None:
301 raise Exception("Invalid network not temporarily disabled")
302
303
304 def test_sae_key_lifetime_in_memory(dev, apdev, params):
305 """SAE and key lifetime in memory"""
306 if "SAE" not in dev[0].get_capability("auth_alg"):
307 raise HwsimSkip("SAE not supported")
308 password = "5ad144a7c1f5a5503baa6fa01dabc15b1843e8c01662d78d16b70b5cd23cf8b"
309 p = hostapd.wpa2_params(ssid="test-sae", passphrase=password)
310 p['wpa_key_mgmt'] = 'SAE'
311 hapd = hostapd.add_ap(apdev[0], p)
312
313 pid = find_wpas_process(dev[0])
314
315 dev[0].request("SET sae_groups ")
316 id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
317 scan_freq="2412")
318
319 # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
320 # event has been delivered, so verify that wpa_supplicant has returned to
321 # eloop before reading process memory.
322 time.sleep(1)
323 dev[0].ping()
324 buf = read_process_memory(pid, password)
325
326 dev[0].request("DISCONNECT")
327 dev[0].wait_disconnected()
328
329 dev[0].relog()
330 sae_k = None
331 sae_keyseed = None
332 sae_kck = None
333 pmk = None
334 ptk = None
335 gtk = None
336 with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
337 for l in f.readlines():
338 if "SAE: k - hexdump" in l:
339 val = l.strip().split(':')[3].replace(' ', '')
340 sae_k = binascii.unhexlify(val)
341 if "SAE: keyseed - hexdump" in l:
342 val = l.strip().split(':')[3].replace(' ', '')
343 sae_keyseed = binascii.unhexlify(val)
344 if "SAE: KCK - hexdump" in l:
345 val = l.strip().split(':')[3].replace(' ', '')
346 sae_kck = binascii.unhexlify(val)
347 if "SAE: PMK - hexdump" in l:
348 val = l.strip().split(':')[3].replace(' ', '')
349 pmk = binascii.unhexlify(val)
350 if "WPA: PTK - hexdump" in l:
351 val = l.strip().split(':')[3].replace(' ', '')
352 ptk = binascii.unhexlify(val)
353 if "WPA: Group Key - hexdump" in l:
354 val = l.strip().split(':')[3].replace(' ', '')
355 gtk = binascii.unhexlify(val)
356 if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk:
357 raise Exception("Could not find keys from debug log")
358 if len(gtk) != 16:
359 raise Exception("Unexpected GTK length")
360
361 kck = ptk[0:16]
362 kek = ptk[16:32]
363 tk = ptk[32:48]
364
365 fname = os.path.join(params['logdir'],
366 'sae_key_lifetime_in_memory.memctx-')
367
368 logger.info("Checking keys in memory while associated")
369 get_key_locations(buf, password, "Password")
370 get_key_locations(buf, pmk, "PMK")
371 if password not in buf:
372 raise HwsimSkip("Password not found while associated")
373 if pmk not in buf:
374 raise HwsimSkip("PMK not found while associated")
375 if kck not in buf:
376 raise Exception("KCK not found while associated")
377 if kek not in buf:
378 raise Exception("KEK not found while associated")
379 #if tk in buf:
380 # raise Exception("TK found from memory")
381 verify_not_present(buf, sae_k, fname, "SAE(k)")
382 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
383 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
384
385 logger.info("Checking keys in memory after disassociation")
386 buf = read_process_memory(pid, password)
387
388 # Note: Password is still present in network configuration
389 # Note: PMK is in PMKSA cache
390
391 get_key_locations(buf, password, "Password")
392 get_key_locations(buf, pmk, "PMK")
393 verify_not_present(buf, kck, fname, "KCK")
394 verify_not_present(buf, kek, fname, "KEK")
395 verify_not_present(buf, tk, fname, "TK")
396 if gtk in buf:
397 get_key_locations(buf, gtk, "GTK")
398 verify_not_present(buf, gtk, fname, "GTK")
399 verify_not_present(buf, sae_k, fname, "SAE(k)")
400 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
401 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
402
403 dev[0].request("PMKSA_FLUSH")
404 logger.info("Checking keys in memory after PMKSA cache flush")
405 buf = read_process_memory(pid, password)
406 get_key_locations(buf, password, "Password")
407 get_key_locations(buf, pmk, "PMK")
408 verify_not_present(buf, pmk, fname, "PMK")
409
410 dev[0].request("REMOVE_NETWORK all")
411
412 logger.info("Checking keys in memory after network profile removal")
413 buf = read_process_memory(pid, password)
414
415 get_key_locations(buf, password, "Password")
416 get_key_locations(buf, pmk, "PMK")
417 verify_not_present(buf, password, fname, "password")
418 verify_not_present(buf, pmk, fname, "PMK")
419 verify_not_present(buf, kck, fname, "KCK")
420 verify_not_present(buf, kek, fname, "KEK")
421 verify_not_present(buf, tk, fname, "TK")
422 verify_not_present(buf, gtk, fname, "GTK")
423 verify_not_present(buf, sae_k, fname, "SAE(k)")
424 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
425 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
426
427 @remote_compatible
428 def test_sae_oom_wpas(dev, apdev):
429 """SAE and OOM in wpa_supplicant"""
430 if "SAE" not in dev[0].get_capability("auth_alg"):
431 raise HwsimSkip("SAE not supported")
432 params = hostapd.wpa2_params(ssid="test-sae",
433 passphrase="12345678")
434 params['wpa_key_mgmt'] = 'SAE'
435 hapd = hostapd.add_ap(apdev[0], params)
436
437 dev[0].request("SET sae_groups 25")
438 tls = dev[0].request("GET tls_library")
439 if "BoringSSL" in tls:
440 dev[0].request("SET sae_groups 26")
441 with alloc_fail(dev[0], 1, "sae_set_group"):
442 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
443 scan_freq="2412")
444 dev[0].request("REMOVE_NETWORK all")
445
446 dev[0].request("SET sae_groups ")
447 with alloc_fail(dev[0], 2, "sae_set_group"):
448 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
449 scan_freq="2412")
450 dev[0].request("REMOVE_NETWORK all")
451
452 with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_commit"):
453 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
454 scan_freq="2412")
455 dev[0].request("REMOVE_NETWORK all")
456
457 with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_confirm"):
458 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
459 scan_freq="2412", wait_connect=False)
460 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
461 dev[0].request("REMOVE_NETWORK all")
462
463 with alloc_fail(dev[0], 1, "=sme_authenticate"):
464 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
465 scan_freq="2412", wait_connect=False)
466 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
467 dev[0].request("REMOVE_NETWORK all")
468
469 with alloc_fail(dev[0], 1, "radio_add_work;sme_authenticate"):
470 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
471 scan_freq="2412", wait_connect=False)
472 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
473 dev[0].request("REMOVE_NETWORK all")
474
475 @remote_compatible
476 def test_sae_proto_ecc(dev, apdev):
477 """SAE protocol testing (ECC)"""
478 if "SAE" not in dev[0].get_capability("auth_alg"):
479 raise HwsimSkip("SAE not supported")
480 params = hostapd.wpa2_params(ssid="test-sae",
481 passphrase="12345678")
482 params['wpa_key_mgmt'] = 'SAE'
483 hapd = hostapd.add_ap(apdev[0], params)
484 bssid = apdev[0]['bssid']
485
486 dev[0].request("SET sae_groups 19")
487
488 tests = [ ("Confirm mismatch",
489 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
490 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc4240"),
491 ("Commit without even full cyclic group field",
492 "13",
493 None),
494 ("Too short commit",
495 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02",
496 None),
497 ("Invalid commit scalar (0)",
498 "1300" + "0000000000000000000000000000000000000000000000000000000000000000" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
499 None),
500 ("Invalid commit scalar (1)",
501 "1300" + "0000000000000000000000000000000000000000000000000000000000000001" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
502 None),
503 ("Invalid commit scalar (> r)",
504 "1300" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
505 None),
506 ("Commit element not on curve",
507 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728d0000000000000000000000000000000000000000000000000000000000000000",
508 None),
509 ("Invalid commit element (y coordinate > P)",
510 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
511 None),
512 ("Invalid commit element (x coordinate > P)",
513 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
514 None),
515 ("Different group in commit",
516 "1400" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
517 None),
518 ("Too short confirm",
519 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
520 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc42")]
521 for (note, commit, confirm) in tests:
522 logger.info(note)
523 dev[0].scan_for_bss(bssid, freq=2412)
524 hapd.set("ext_mgmt_frame_handling", "1")
525 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
526 scan_freq="2412", wait_connect=False)
527
528 logger.info("Commit")
529 for i in range(0, 10):
530 req = hapd.mgmt_rx()
531 if req is None:
532 raise Exception("MGMT RX wait timed out (commit)")
533 if req['subtype'] == 11:
534 break
535 req = None
536 if not req:
537 raise Exception("Authentication frame (commit) not received")
538
539 hapd.dump_monitor()
540 resp = {}
541 resp['fc'] = req['fc']
542 resp['da'] = req['sa']
543 resp['sa'] = req['da']
544 resp['bssid'] = req['bssid']
545 resp['payload'] = binascii.unhexlify("030001000000" + commit)
546 hapd.mgmt_tx(resp)
547
548 if confirm:
549 logger.info("Confirm")
550 for i in range(0, 10):
551 req = hapd.mgmt_rx()
552 if req is None:
553 raise Exception("MGMT RX wait timed out (confirm)")
554 if req['subtype'] == 11:
555 break
556 req = None
557 if not req:
558 raise Exception("Authentication frame (confirm) not received")
559
560 hapd.dump_monitor()
561 resp = {}
562 resp['fc'] = req['fc']
563 resp['da'] = req['sa']
564 resp['sa'] = req['da']
565 resp['bssid'] = req['bssid']
566 resp['payload'] = binascii.unhexlify("030002000000" + confirm)
567 hapd.mgmt_tx(resp)
568
569 time.sleep(0.1)
570 dev[0].request("REMOVE_NETWORK all")
571 hapd.set("ext_mgmt_frame_handling", "0")
572 hapd.dump_monitor()
573
574 @remote_compatible
575 def test_sae_proto_ffc(dev, apdev):
576 """SAE protocol testing (FFC)"""
577 if "SAE" not in dev[0].get_capability("auth_alg"):
578 raise HwsimSkip("SAE not supported")
579 params = hostapd.wpa2_params(ssid="test-sae",
580 passphrase="12345678")
581 params['wpa_key_mgmt'] = 'SAE'
582 hapd = hostapd.add_ap(apdev[0], params)
583 bssid = apdev[0]['bssid']
584
585 dev[0].request("SET sae_groups 2")
586
587 tests = [ ("Confirm mismatch",
588 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a17486",
589 "0000f3116a9731f1259622e3eb55d4b3b50ba16f8c5f5565b28e609b180c51460251"),
590 ("Too short commit",
591 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a174",
592 None),
593 ("Invalid element (0) in commit",
594 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
595 None),
596 ("Invalid element (1) in commit",
597 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
598 None),
599 ("Invalid element (> P) in commit",
600 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
601 None) ]
602 for (note, commit, confirm) in tests:
603 logger.info(note)
604 dev[0].scan_for_bss(bssid, freq=2412)
605 hapd.set("ext_mgmt_frame_handling", "1")
606 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
607 scan_freq="2412", wait_connect=False)
608
609 logger.info("Commit")
610 for i in range(0, 10):
611 req = hapd.mgmt_rx()
612 if req is None:
613 raise Exception("MGMT RX wait timed out (commit)")
614 if req['subtype'] == 11:
615 break
616 req = None
617 if not req:
618 raise Exception("Authentication frame (commit) not received")
619
620 hapd.dump_monitor()
621 resp = {}
622 resp['fc'] = req['fc']
623 resp['da'] = req['sa']
624 resp['sa'] = req['da']
625 resp['bssid'] = req['bssid']
626 resp['payload'] = binascii.unhexlify("030001000000" + commit)
627 hapd.mgmt_tx(resp)
628
629 if confirm:
630 logger.info("Confirm")
631 for i in range(0, 10):
632 req = hapd.mgmt_rx()
633 if req is None:
634 raise Exception("MGMT RX wait timed out (confirm)")
635 if req['subtype'] == 11:
636 break
637 req = None
638 if not req:
639 raise Exception("Authentication frame (confirm) not received")
640
641 hapd.dump_monitor()
642 resp = {}
643 resp['fc'] = req['fc']
644 resp['da'] = req['sa']
645 resp['sa'] = req['da']
646 resp['bssid'] = req['bssid']
647 resp['payload'] = binascii.unhexlify("030002000000" + confirm)
648 hapd.mgmt_tx(resp)
649
650 time.sleep(0.1)
651 dev[0].request("REMOVE_NETWORK all")
652 hapd.set("ext_mgmt_frame_handling", "0")
653 hapd.dump_monitor()
654
655 def test_sae_proto_confirm_replay(dev, apdev):
656 """SAE protocol testing - Confirm replay"""
657 if "SAE" not in dev[0].get_capability("auth_alg"):
658 raise HwsimSkip("SAE not supported")
659 params = hostapd.wpa2_params(ssid="test-sae",
660 passphrase="12345678")
661 params['wpa_key_mgmt'] = 'SAE'
662 hapd = hostapd.add_ap(apdev[0], params)
663 bssid = apdev[0]['bssid']
664
665 dev[0].request("SET sae_groups 19")
666
667 dev[0].scan_for_bss(bssid, freq=2412)
668 hapd.set("ext_mgmt_frame_handling", "1")
669 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
670 scan_freq="2412", wait_connect=False)
671
672 logger.info("Commit")
673 for i in range(0, 10):
674 req = hapd.mgmt_rx()
675 if req is None:
676 raise Exception("MGMT RX wait timed out (commit)")
677 if req['subtype'] == 11:
678 break
679 req = None
680 if not req:
681 raise Exception("Authentication frame (commit) not received")
682
683 bssid = hapd.own_addr().replace(':', '')
684 addr = dev[0].own_addr().replace(':', '')
685 hdr = "b0003a01" + bssid + addr + bssid + "1000"
686
687 hapd.dump_monitor()
688 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
689
690 logger.info("Confirm")
691 for i in range(0, 10):
692 req = hapd.mgmt_rx()
693 if req is None:
694 raise Exception("MGMT RX wait timed out (confirm)")
695 if req['subtype'] == 11:
696 break
697 req = None
698 if not req:
699 raise Exception("Authentication frame (confirm) not received")
700
701 hapd.dump_monitor()
702 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
703
704 logger.info("Replay Confirm")
705 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
706
707 logger.info("Association Request")
708 for i in range(0, 10):
709 req = hapd.mgmt_rx()
710 if req is None:
711 raise Exception("MGMT RX wait timed out (AssocReq)")
712 if req['subtype'] == 0:
713 break
714 req = None
715 if not req:
716 raise Exception("Association Request frame not received")
717
718 hapd.dump_monitor()
719 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
720 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
721 if ev is None:
722 raise Exception("Management frame TX status not reported (1)")
723 if "stype=1 ok=1" not in ev:
724 raise Exception("Unexpected management frame TX status (1): " + ev)
725 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
726 if "OK" not in hapd.request(cmd):
727 raise Exception("MGMT_TX_STATUS_PROCESS failed")
728
729 hapd.set("ext_mgmt_frame_handling", "0")
730
731 dev[0].wait_connected()
732
733 def test_sae_proto_hostapd(dev, apdev):
734 """SAE protocol testing with hostapd"""
735 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
736 params['wpa_key_mgmt'] = 'SAE'
737 params['sae_groups'] = "19 65535"
738 hapd = hostapd.add_ap(apdev[0], params)
739 hapd.set("ext_mgmt_frame_handling", "1")
740 bssid = hapd.own_addr().replace(':', '')
741 addr = "020000000000"
742 addr2 = "020000000001"
743 hdr = "b0003a01" + bssid + addr + bssid + "1000"
744 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000"
745 group = "1300"
746 scalar = "f7df19f4a7fef1d3b895ea1de150b7c5a7a705c8ebb31a52b623e0057908bd93"
747 element_x = "21931572027f2e953e2a49fab3d992944102cc95aa19515fc068b394fb25ae3c"
748 element_y = "cb4eeb94d7b0b789abfdb73a67ab9d6d5efa94dd553e0e724a6289821cbce530"
749 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y)
750 # "SAE: Not enough data for scalar"
751 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar[:-2])
752 # "SAE: Do not allow group to be changed"
753 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + "ffff" + scalar[:-2])
754 # "SAE: Unsupported Finite Cyclic Group 65535"
755 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr2 + "030001000000" + "ffff" + scalar[:-2])
756
757 @remote_compatible
758 def test_sae_no_ffc_by_default(dev, apdev):
759 """SAE and default groups rejecting FFC"""
760 if "SAE" not in dev[0].get_capability("auth_alg"):
761 raise HwsimSkip("SAE not supported")
762 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
763 params['wpa_key_mgmt'] = 'SAE'
764 hapd = hostapd.add_ap(apdev[0], params)
765
766 dev[0].request("SET sae_groups 5")
767 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412",
768 wait_connect=False)
769 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
770 if ev is None:
771 raise Exception("Did not try to authenticate")
772 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
773 if ev is None:
774 raise Exception("Did not try to authenticate (2)")
775 dev[0].request("REMOVE_NETWORK all")
776
777 def sae_reflection_attack(apdev, dev, group):
778 if "SAE" not in dev.get_capability("auth_alg"):
779 raise HwsimSkip("SAE not supported")
780 params = hostapd.wpa2_params(ssid="test-sae",
781 passphrase="no-knowledge-of-passphrase")
782 params['wpa_key_mgmt'] = 'SAE'
783 hapd = hostapd.add_ap(apdev, params)
784 bssid = apdev['bssid']
785
786 dev.scan_for_bss(bssid, freq=2412)
787 hapd.set("ext_mgmt_frame_handling", "1")
788
789 dev.request("SET sae_groups %d" % group)
790 dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
791 scan_freq="2412", wait_connect=False)
792
793 # Commit
794 for i in range(0, 10):
795 req = hapd.mgmt_rx()
796 if req is None:
797 raise Exception("MGMT RX wait timed out")
798 if req['subtype'] == 11:
799 break
800 req = None
801 if not req:
802 raise Exception("Authentication frame not received")
803
804 resp = {}
805 resp['fc'] = req['fc']
806 resp['da'] = req['sa']
807 resp['sa'] = req['da']
808 resp['bssid'] = req['bssid']
809 resp['payload'] = req['payload']
810 hapd.mgmt_tx(resp)
811
812 # Confirm
813 req = hapd.mgmt_rx(timeout=0.5)
814 if req is not None:
815 if req['subtype'] == 11:
816 raise Exception("Unexpected Authentication frame seen")
817
818 @remote_compatible
819 def test_sae_reflection_attack_ecc(dev, apdev):
820 """SAE reflection attack (ECC)"""
821 sae_reflection_attack(apdev[0], dev[0], 19)
822
823 @remote_compatible
824 def test_sae_reflection_attack_ffc(dev, apdev):
825 """SAE reflection attack (FFC)"""
826 sae_reflection_attack(apdev[0], dev[0], 5)
827
828 def sae_reflection_attack_internal(apdev, dev, group):
829 if "SAE" not in dev.get_capability("auth_alg"):
830 raise HwsimSkip("SAE not supported")
831 params = hostapd.wpa2_params(ssid="test-sae",
832 passphrase="no-knowledge-of-passphrase")
833 params['wpa_key_mgmt'] = 'SAE'
834 params['sae_reflection_attack'] = '1'
835 hapd = hostapd.add_ap(apdev, params)
836 bssid = apdev['bssid']
837
838 dev.scan_for_bss(bssid, freq=2412)
839 dev.request("SET sae_groups %d" % group)
840 dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
841 scan_freq="2412", wait_connect=False)
842 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
843 if ev is not None:
844 raise Exception("Unexpected connection")
845
846 @remote_compatible
847 def test_sae_reflection_attack_ecc_internal(dev, apdev):
848 """SAE reflection attack (ECC) - internal"""
849 sae_reflection_attack_internal(apdev[0], dev[0], 19)
850
851 @remote_compatible
852 def test_sae_reflection_attack_ffc_internal(dev, apdev):
853 """SAE reflection attack (FFC) - internal"""
854 sae_reflection_attack_internal(apdev[0], dev[0], 5)
855
856 @remote_compatible
857 def test_sae_commit_override(dev, apdev):
858 """SAE commit override (hostapd)"""
859 if "SAE" not in dev[0].get_capability("auth_alg"):
860 raise HwsimSkip("SAE not supported")
861 params = hostapd.wpa2_params(ssid="test-sae",
862 passphrase="12345678")
863 params['wpa_key_mgmt'] = 'SAE'
864 params['sae_commit_override'] = '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514'
865 hapd = hostapd.add_ap(apdev[0], params)
866 dev[0].request("SET sae_groups ")
867 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
868 scan_freq="2412", wait_connect=False)
869 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
870 if ev is not None:
871 raise Exception("Unexpected connection")
872
873 @remote_compatible
874 def test_sae_commit_override2(dev, apdev):
875 """SAE commit override (wpa_supplicant)"""
876 if "SAE" not in dev[0].get_capability("auth_alg"):
877 raise HwsimSkip("SAE not supported")
878 params = hostapd.wpa2_params(ssid="test-sae",
879 passphrase="12345678")
880 params['wpa_key_mgmt'] = 'SAE'
881 hapd = hostapd.add_ap(apdev[0], params)
882 dev[0].request("SET sae_groups ")
883 dev[0].set('sae_commit_override', '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514')
884 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
885 scan_freq="2412", wait_connect=False)
886 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
887 if ev is not None:
888 raise Exception("Unexpected connection")
889
890 @remote_compatible
891 def test_sae_anti_clogging_proto(dev, apdev):
892 """SAE anti clogging protocol testing"""
893 if "SAE" not in dev[0].get_capability("auth_alg"):
894 raise HwsimSkip("SAE not supported")
895 params = hostapd.wpa2_params(ssid="test-sae",
896 passphrase="no-knowledge-of-passphrase")
897 params['wpa_key_mgmt'] = 'SAE'
898 hapd = hostapd.add_ap(apdev[0], params)
899 bssid = apdev[0]['bssid']
900
901 dev[0].scan_for_bss(bssid, freq=2412)
902 hapd.set("ext_mgmt_frame_handling", "1")
903
904 dev[0].request("SET sae_groups ")
905 dev[0].connect("test-sae", psk="anti-cloggign", key_mgmt="SAE",
906 scan_freq="2412", wait_connect=False)
907
908 # Commit
909 for i in range(0, 10):
910 req = hapd.mgmt_rx()
911 if req is None:
912 raise Exception("MGMT RX wait timed out")
913 if req['subtype'] == 11:
914 break
915 req = None
916 if not req:
917 raise Exception("Authentication frame not received")
918
919 resp = {}
920 resp['fc'] = req['fc']
921 resp['da'] = req['sa']
922 resp['sa'] = req['da']
923 resp['bssid'] = req['bssid']
924 resp['payload'] = binascii.unhexlify("030001004c00" + "ffff00")
925 hapd.mgmt_tx(resp)
926
927 # Confirm (not received due to DH group being rejected)
928 req = hapd.mgmt_rx(timeout=0.5)
929 if req is not None:
930 if req['subtype'] == 11:
931 raise Exception("Unexpected Authentication frame seen")
932
933 @remote_compatible
934 def test_sae_no_random(dev, apdev):
935 """SAE and no random numbers available"""
936 if "SAE" not in dev[0].get_capability("auth_alg"):
937 raise HwsimSkip("SAE not supported")
938 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
939 params['wpa_key_mgmt'] = 'SAE'
940 hapd = hostapd.add_ap(apdev[0], params)
941
942 dev[0].request("SET sae_groups ")
943 tests = [ (1, "os_get_random;sae_get_rand"),
944 (1, "os_get_random;get_rand_1_to_p_1"),
945 (1, "os_get_random;get_random_qr_qnr"),
946 (1, "os_get_random;sae_derive_pwe_ecc") ]
947 for count, func in tests:
948 with fail_test(dev[0], count, func):
949 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
950 scan_freq="2412")
951 dev[0].request("REMOVE_NETWORK all")
952 dev[0].wait_disconnected()
953
954 @remote_compatible
955 def test_sae_pwe_failure(dev, apdev):
956 """SAE and pwe failure"""
957 if "SAE" not in dev[0].get_capability("auth_alg"):
958 raise HwsimSkip("SAE not supported")
959 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
960 params['wpa_key_mgmt'] = 'SAE'
961 params['sae_groups'] = '19 5'
962 hapd = hostapd.add_ap(apdev[0], params)
963
964 dev[0].request("SET sae_groups 19")
965 with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ecc"):
966 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
967 scan_freq="2412")
968 dev[0].request("REMOVE_NETWORK all")
969 dev[0].wait_disconnected()
970 with fail_test(dev[0], 1, "sae_test_pwd_seed_ecc"):
971 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
972 scan_freq="2412")
973 dev[0].request("REMOVE_NETWORK all")
974 dev[0].wait_disconnected()
975
976 dev[0].request("SET sae_groups 5")
977 with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ffc"):
978 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
979 scan_freq="2412")
980 dev[0].request("REMOVE_NETWORK all")
981 dev[0].wait_disconnected()
982
983 dev[0].request("SET sae_groups 5")
984 with fail_test(dev[0], 1, "sae_test_pwd_seed_ffc"):
985 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
986 scan_freq="2412")
987 dev[0].request("REMOVE_NETWORK all")
988 dev[0].wait_disconnected()
989 with fail_test(dev[0], 2, "sae_test_pwd_seed_ffc"):
990 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
991 scan_freq="2412")
992 dev[0].request("REMOVE_NETWORK all")
993 dev[0].wait_disconnected()
994
995 @remote_compatible
996 def test_sae_bignum_failure(dev, apdev):
997 """SAE and bignum failure"""
998 if "SAE" not in dev[0].get_capability("auth_alg"):
999 raise HwsimSkip("SAE not supported")
1000 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1001 params['wpa_key_mgmt'] = 'SAE'
1002 params['sae_groups'] = '19 5 22'
1003 hapd = hostapd.add_ap(apdev[0], params)
1004
1005 dev[0].request("SET sae_groups 19")
1006 tests = [ (1, "crypto_bignum_init_set;get_rand_1_to_p_1"),
1007 (1, "crypto_bignum_init;is_quadratic_residue_blind"),
1008 (1, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
1009 (2, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
1010 (3, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
1011 (1, "crypto_bignum_legendre;is_quadratic_residue_blind"),
1012 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ecc"),
1013 (1, "crypto_ec_point_compute_y_sqr;sae_test_pwd_seed_ecc"),
1014 (1, "crypto_bignum_init_set;get_random_qr_qnr"),
1015 (1, "crypto_bignum_to_bin;sae_derive_pwe_ecc"),
1016 (1, "crypto_ec_point_init;sae_derive_pwe_ecc"),
1017 (1, "crypto_ec_point_solve_y_coord;sae_derive_pwe_ecc"),
1018 (1, "crypto_ec_point_init;sae_derive_commit_element_ecc"),
1019 (1, "crypto_ec_point_mul;sae_derive_commit_element_ecc"),
1020 (1, "crypto_ec_point_invert;sae_derive_commit_element_ecc"),
1021 (1, "crypto_bignum_init;=sae_derive_commit"),
1022 (1, "crypto_ec_point_init;sae_derive_k_ecc"),
1023 (1, "crypto_ec_point_mul;sae_derive_k_ecc"),
1024 (1, "crypto_ec_point_add;sae_derive_k_ecc"),
1025 (2, "crypto_ec_point_mul;sae_derive_k_ecc"),
1026 (1, "crypto_ec_point_to_bin;sae_derive_k_ecc"),
1027 (1, "crypto_bignum_legendre;get_random_qr_qnr"),
1028 (1, "sha256_prf;sae_derive_keys"),
1029 (1, "crypto_bignum_init;sae_derive_keys"),
1030 (1, "crypto_bignum_init_set;sae_parse_commit_scalar"),
1031 (1, "crypto_bignum_to_bin;sae_parse_commit_element_ecc"),
1032 (1, "crypto_ec_point_from_bin;sae_parse_commit_element_ecc") ]
1033 for count, func in tests:
1034 with fail_test(dev[0], count, func):
1035 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1036 scan_freq="2412", wait_connect=False)
1037 wait_fail_trigger(dev[0], "GET_FAIL")
1038 dev[0].request("REMOVE_NETWORK all")
1039
1040 dev[0].request("SET sae_groups 5")
1041 tests = [ (1, "crypto_bignum_init_set;sae_set_group"),
1042 (2, "crypto_bignum_init_set;sae_set_group"),
1043 (1, "crypto_bignum_init_set;sae_get_rand"),
1044 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
1045 (1, "crypto_bignum_exptmod;sae_test_pwd_seed_ffc"),
1046 (1, "crypto_bignum_init;sae_derive_pwe_ffc"),
1047 (1, "crypto_bignum_init;sae_derive_commit_element_ffc"),
1048 (1, "crypto_bignum_exptmod;sae_derive_commit_element_ffc"),
1049 (1, "crypto_bignum_inverse;sae_derive_commit_element_ffc"),
1050 (1, "crypto_bignum_init;sae_derive_k_ffc"),
1051 (1, "crypto_bignum_exptmod;sae_derive_k_ffc"),
1052 (1, "crypto_bignum_mulmod;sae_derive_k_ffc"),
1053 (2, "crypto_bignum_exptmod;sae_derive_k_ffc"),
1054 (1, "crypto_bignum_to_bin;sae_derive_k_ffc"),
1055 (1, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
1056 (1, "crypto_bignum_init;sae_parse_commit_element_ffc"),
1057 (2, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
1058 (1, "crypto_bignum_exptmod;sae_parse_commit_element_ffc") ]
1059 for count, func in tests:
1060 with fail_test(dev[0], count, func):
1061 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1062 scan_freq="2412", wait_connect=False)
1063 wait_fail_trigger(dev[0], "GET_FAIL")
1064 dev[0].request("REMOVE_NETWORK all")
1065
1066 dev[0].request("SET sae_groups 22")
1067 tests = [ (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
1068 (1, "crypto_bignum_sub;sae_test_pwd_seed_ffc"),
1069 (1, "crypto_bignum_div;sae_test_pwd_seed_ffc") ]
1070 for count, func in tests:
1071 with fail_test(dev[0], count, func):
1072 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1073 scan_freq="2412", wait_connect=False)
1074 wait_fail_trigger(dev[0], "GET_FAIL")
1075 dev[0].request("REMOVE_NETWORK all")
1076
1077 def test_sae_invalid_anti_clogging_token_req(dev, apdev):
1078 """SAE and invalid anti-clogging token request"""
1079 if "SAE" not in dev[0].get_capability("auth_alg"):
1080 raise HwsimSkip("SAE not supported")
1081 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1082 params['wpa_key_mgmt'] = 'SAE'
1083 # Beacon more frequently since Probe Request frames are practically ignored
1084 # in this test setup (ext_mgmt_frame_handled=1 on hostapd side) and
1085 # wpa_supplicant scans may end up getting ignored if no new results are
1086 # available due to the missing Probe Response frames.
1087 params['beacon_int'] = '20'
1088 hapd = hostapd.add_ap(apdev[0], params)
1089 bssid = apdev[0]['bssid']
1090
1091 dev[0].request("SET sae_groups 19")
1092 dev[0].scan_for_bss(bssid, freq=2412)
1093 hapd.set("ext_mgmt_frame_handling", "1")
1094 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1095 scan_freq="2412", wait_connect=False)
1096 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1097 if ev is None:
1098 raise Exception("No authentication attempt seen (1)")
1099 dev[0].dump_monitor()
1100
1101 for i in range(0, 10):
1102 req = hapd.mgmt_rx()
1103 if req is None:
1104 raise Exception("MGMT RX wait timed out (commit)")
1105 if req['subtype'] == 11:
1106 break
1107 req = None
1108 if not req:
1109 raise Exception("Authentication frame (commit) not received")
1110
1111 hapd.dump_monitor()
1112 resp = {}
1113 resp['fc'] = req['fc']
1114 resp['da'] = req['sa']
1115 resp['sa'] = req['da']
1116 resp['bssid'] = req['bssid']
1117 resp['payload'] = binascii.unhexlify("030001004c0013")
1118 hapd.mgmt_tx(resp)
1119 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
1120 if ev is None:
1121 raise Exception("Management frame TX status not reported (1)")
1122 if "stype=11 ok=1" not in ev:
1123 raise Exception("Unexpected management frame TX status (1): " + ev)
1124
1125 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1126 if ev is None:
1127 raise Exception("No authentication attempt seen (2)")
1128 dev[0].dump_monitor()
1129
1130 for i in range(0, 10):
1131 req = hapd.mgmt_rx()
1132 if req is None:
1133 raise Exception("MGMT RX wait timed out (commit) (2)")
1134 if req['subtype'] == 11:
1135 break
1136 req = None
1137 if not req:
1138 raise Exception("Authentication frame (commit) not received (2)")
1139
1140 hapd.dump_monitor()
1141 resp = {}
1142 resp['fc'] = req['fc']
1143 resp['da'] = req['sa']
1144 resp['sa'] = req['da']
1145 resp['bssid'] = req['bssid']
1146 resp['payload'] = binascii.unhexlify("030001000100")
1147 hapd.mgmt_tx(resp)
1148 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
1149 if ev is None:
1150 raise Exception("Management frame TX status not reported (1)")
1151 if "stype=11 ok=1" not in ev:
1152 raise Exception("Unexpected management frame TX status (1): " + ev)
1153
1154 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1155 if ev is None:
1156 raise Exception("No authentication attempt seen (3)")
1157 dev[0].dump_monitor()
1158
1159 dev[0].request("DISCONNECT")
1160
1161 def test_sae_password(dev, apdev):
1162 """SAE and sae_password in hostapd configuration"""
1163 if "SAE" not in dev[0].get_capability("auth_alg"):
1164 raise HwsimSkip("SAE not supported")
1165 params = hostapd.wpa2_params(ssid="test-sae",
1166 passphrase="12345678")
1167 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
1168 params['sae_password'] = "sae-password"
1169 hapd = hostapd.add_ap(apdev[0], params)
1170
1171 dev[0].request("SET sae_groups ")
1172 dev[0].connect("test-sae", psk="sae-password", key_mgmt="SAE",
1173 scan_freq="2412")
1174 dev[1].connect("test-sae", psk="12345678", scan_freq="2412")
1175 dev[2].request("SET sae_groups ")
1176 dev[2].connect("test-sae", sae_password="sae-password", key_mgmt="SAE",
1177 scan_freq="2412")
1178
1179 def test_sae_password_short(dev, apdev):
1180 """SAE and short password"""
1181 if "SAE" not in dev[0].get_capability("auth_alg"):
1182 raise HwsimSkip("SAE not supported")
1183 params = hostapd.wpa2_params(ssid="test-sae")
1184 params['wpa_key_mgmt'] = 'SAE'
1185 params['sae_password'] = "secret"
1186 hapd = hostapd.add_ap(apdev[0], params)
1187
1188 dev[0].request("SET sae_groups ")
1189 dev[0].connect("test-sae", sae_password="secret", key_mgmt="SAE",
1190 scan_freq="2412")
1191
1192 def test_sae_password_long(dev, apdev):
1193 """SAE and long password"""
1194 if "SAE" not in dev[0].get_capability("auth_alg"):
1195 raise HwsimSkip("SAE not supported")
1196 params = hostapd.wpa2_params(ssid="test-sae")
1197 params['wpa_key_mgmt'] = 'SAE'
1198 params['sae_password'] = 100*"A"
1199 hapd = hostapd.add_ap(apdev[0], params)
1200
1201 dev[0].request("SET sae_groups ")
1202 dev[0].connect("test-sae", sae_password=100*"A", key_mgmt="SAE",
1203 scan_freq="2412")