]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_sae.py
d54f0ec95e0f554bbcce7ceff85abc97443dfcd9
[thirdparty/hostap.git] / tests / hwsim / test_sae.py
1 # Test cases for SAE
2 # Copyright (c) 2013-2020, 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 import socket
14 import struct
15 import subprocess
16
17 import hwsim_utils
18 import hostapd
19 from wpasupplicant import WpaSupplicant
20 from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger, start_monitor, stop_monitor, radiotap_build
21 from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations
22
23 def check_sae_capab(dev):
24 if "SAE" not in dev.get_capability("auth_alg"):
25 raise HwsimSkip("SAE not supported")
26
27 @remote_compatible
28 def test_sae(dev, apdev):
29 """SAE with default group"""
30 check_sae_capab(dev[0])
31 params = hostapd.wpa2_params(ssid="test-sae",
32 passphrase="12345678")
33 params['wpa_key_mgmt'] = 'SAE'
34 hapd = hostapd.add_ap(apdev[0], params)
35 key_mgmt = hapd.get_config()['key_mgmt']
36 if key_mgmt.split(' ')[0] != "SAE":
37 raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
38
39 dev[0].request("SET sae_groups ")
40 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
41 scan_freq="2412")
42 hapd.wait_sta()
43 if dev[0].get_status_field('sae_group') != '19':
44 raise Exception("Expected default SAE group not used")
45 bss = dev[0].get_bss(apdev[0]['bssid'])
46 if 'flags' not in bss:
47 raise Exception("Could not get BSS flags from BSS table")
48 if "[WPA2-SAE-CCMP]" not in bss['flags']:
49 raise Exception("Unexpected BSS flags: " + bss['flags'])
50
51 res = hapd.request("STA-FIRST")
52 if "sae_group=19" not in res.splitlines():
53 raise Exception("hostapd STA output did not specify SAE group")
54
55 pmk_h = hapd.request("GET_PMK " + dev[0].own_addr())
56 pmk_w = dev[0].get_pmk(id)
57 if pmk_h != pmk_w:
58 raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w))
59
60 @remote_compatible
61 def test_sae_password_ecc(dev, apdev):
62 """SAE with number of different passwords (ECC)"""
63 check_sae_capab(dev[0])
64 params = hostapd.wpa2_params(ssid="test-sae",
65 passphrase="12345678")
66 params['wpa_key_mgmt'] = 'SAE'
67 hapd = hostapd.add_ap(apdev[0], params)
68
69 dev[0].request("SET sae_groups 19")
70
71 for i in range(10):
72 password = "12345678-" + str(i)
73 hapd.set("wpa_passphrase", password)
74 dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
75 scan_freq="2412")
76 dev[0].request("REMOVE_NETWORK all")
77 dev[0].wait_disconnected()
78
79 @remote_compatible
80 def test_sae_password_ffc(dev, apdev):
81 """SAE with number of different passwords (FFC)"""
82 check_sae_capab(dev[0])
83 params = hostapd.wpa2_params(ssid="test-sae",
84 passphrase="12345678")
85 params['wpa_key_mgmt'] = 'SAE'
86 params['sae_groups'] = '15'
87 hapd = hostapd.add_ap(apdev[0], params)
88
89 dev[0].request("SET sae_groups 15")
90
91 for i in range(10):
92 password = "12345678-" + str(i)
93 hapd.set("wpa_passphrase", password)
94 dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
95 scan_freq="2412")
96 dev[0].request("REMOVE_NETWORK all")
97 dev[0].wait_disconnected()
98
99 @remote_compatible
100 def test_sae_pmksa_caching(dev, apdev):
101 """SAE and PMKSA caching"""
102 run_sae_pmksa_caching(dev, apdev)
103
104 @remote_compatible
105 def test_sae_pmksa_caching_pmkid(dev, apdev):
106 """SAE and PMKSA caching (PMKID in AssocReq after SAE)"""
107 try:
108 dev[0].set("sae_pmkid_in_assoc", "1")
109 run_sae_pmksa_caching(dev, apdev)
110 finally:
111 dev[0].set("sae_pmkid_in_assoc", "0")
112
113 def run_sae_pmksa_caching(dev, apdev):
114 check_sae_capab(dev[0])
115 params = hostapd.wpa2_params(ssid="test-sae",
116 passphrase="12345678")
117 params['wpa_key_mgmt'] = 'SAE'
118 hapd = hostapd.add_ap(apdev[0], params)
119
120 dev[0].request("SET sae_groups ")
121 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
122 scan_freq="2412")
123 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
124 if ev is None:
125 raise Exception("No connection event received from hostapd")
126 sta0 = hapd.get_sta(dev[0].own_addr())
127 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-8':
128 raise Exception("SAE STA(0) AKM suite selector reported incorrectly")
129 dev[0].request("DISCONNECT")
130 dev[0].wait_disconnected()
131 dev[0].request("RECONNECT")
132 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
133 if dev[0].get_status_field('sae_group') is not None:
134 raise Exception("SAE group claimed to have been used")
135 sta0 = hapd.get_sta(dev[0].own_addr())
136 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-8':
137 raise Exception("SAE STA(0) AKM suite selector reported incorrectly after PMKSA caching")
138
139 @remote_compatible
140 def test_sae_pmksa_caching_disabled(dev, apdev):
141 """SAE and PMKSA caching disabled"""
142 check_sae_capab(dev[0])
143 params = hostapd.wpa2_params(ssid="test-sae",
144 passphrase="12345678")
145 params['wpa_key_mgmt'] = 'SAE'
146 params['disable_pmksa_caching'] = '1'
147 hapd = hostapd.add_ap(apdev[0], params)
148
149 dev[0].request("SET sae_groups ")
150 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
151 scan_freq="2412")
152 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
153 if ev is None:
154 raise Exception("No connection event received from hostapd")
155 dev[0].request("DISCONNECT")
156 dev[0].wait_disconnected()
157 dev[0].request("RECONNECT")
158 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
159 if dev[0].get_status_field('sae_group') != '19':
160 raise Exception("Expected default SAE group not used")
161
162 def test_sae_groups(dev, apdev):
163 """SAE with all supported groups"""
164 check_sae_capab(dev[0])
165 # This is the full list of supported groups, but groups 14-16 (2048-4096 bit
166 # MODP) and group 21 (521-bit random ECP group) are a bit too slow on some
167 # VMs and can result in hitting the mac80211 authentication timeout, so
168 # allow them to fail and just report such failures in the debug log.
169 sae_groups = [19, 25, 26, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24]
170 tls = dev[0].request("GET tls_library")
171 if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls:
172 logger.info("Add Brainpool EC groups since OpenSSL is new enough")
173 sae_groups += [27, 28, 29, 30]
174 heavy_groups = [14, 15, 16]
175 suitable_groups = [15, 16, 17, 18, 19, 20, 21]
176 groups = [str(g) for g in sae_groups]
177 params = hostapd.wpa2_params(ssid="test-sae-groups",
178 passphrase="12345678")
179 params['wpa_key_mgmt'] = 'SAE'
180 params['sae_groups'] = ' '.join(groups)
181 hapd = hostapd.add_ap(apdev[0], params)
182
183 for g in groups:
184 logger.info("Testing SAE group " + g)
185 dev[0].request("SET sae_groups " + g)
186 id = dev[0].connect("test-sae-groups", psk="12345678", key_mgmt="SAE",
187 scan_freq="2412", wait_connect=False)
188 if int(g) in heavy_groups:
189 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5)
190 if ev is None:
191 logger.info("No connection with heavy SAE group %s did not connect - likely hitting timeout in mac80211" % g)
192 dev[0].remove_network(id)
193 time.sleep(0.1)
194 dev[0].dump_monitor()
195 continue
196 logger.info("Connection with heavy SAE group " + g)
197 else:
198 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
199 if ev is None:
200 if "BoringSSL" in tls and int(g) in [25]:
201 logger.info("Ignore connection failure with group " + g + " with BoringSSL")
202 dev[0].remove_network(id)
203 dev[0].dump_monitor()
204 continue
205 if int(g) not in suitable_groups:
206 logger.info("Ignore connection failure with unsuitable group " + g)
207 dev[0].remove_network(id)
208 dev[0].dump_monitor()
209 continue
210 raise Exception("Connection timed out with group " + g)
211 if dev[0].get_status_field('sae_group') != g:
212 raise Exception("Expected SAE group not used")
213 pmksa = dev[0].get_pmksa(hapd.own_addr())
214 if not pmksa:
215 raise Exception("No PMKSA cache entry added")
216 if pmksa['pmkid'] == '00000000000000000000000000000000':
217 raise Exception("All zeros PMKID derived for group %s" % g)
218 dev[0].remove_network(id)
219 dev[0].wait_disconnected()
220 dev[0].dump_monitor()
221
222 @remote_compatible
223 def test_sae_group_nego(dev, apdev):
224 """SAE group negotiation"""
225 check_sae_capab(dev[0])
226 params = hostapd.wpa2_params(ssid="test-sae-group-nego",
227 passphrase="12345678")
228 params['wpa_key_mgmt'] = 'SAE'
229 params['sae_groups'] = '19'
230 hostapd.add_ap(apdev[0], params)
231
232 dev[0].request("SET sae_groups 25 26 20 19")
233 dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE",
234 scan_freq="2412")
235 if dev[0].get_status_field('sae_group') != '19':
236 raise Exception("Expected SAE group not used")
237
238 def test_sae_group_nego_no_match(dev, apdev):
239 """SAE group negotiation (no match)"""
240 check_sae_capab(dev[0])
241 params = hostapd.wpa2_params(ssid="test-sae-group-nego",
242 passphrase="12345678")
243 params['wpa_key_mgmt'] = 'SAE'
244 # None-existing SAE group to force all attempts to be rejected
245 params['sae_groups'] = '0'
246 hostapd.add_ap(apdev[0], params)
247
248 dev[0].request("SET sae_groups ")
249 dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE",
250 scan_freq="2412", wait_connect=False)
251 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
252 dev[0].request("REMOVE_NETWORK all")
253 if ev is None:
254 raise Exception("Network profile disabling not reported")
255
256 @remote_compatible
257 def test_sae_anti_clogging(dev, apdev):
258 """SAE anti clogging"""
259 check_sae_capab(dev[0])
260 check_sae_capab(dev[1])
261 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
262 params['wpa_key_mgmt'] = 'SAE'
263 params['sae_anti_clogging_threshold'] = '1'
264 hostapd.add_ap(apdev[0], params)
265
266 dev[0].request("SET sae_groups ")
267 dev[1].request("SET sae_groups ")
268 id = {}
269 for i in range(0, 2):
270 dev[i].scan(freq="2412")
271 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
272 scan_freq="2412", only_add_network=True)
273 for i in range(0, 2):
274 dev[i].select_network(id[i])
275 for i in range(0, 2):
276 dev[i].wait_connected(timeout=10)
277
278 def test_sae_forced_anti_clogging(dev, apdev):
279 """SAE anti clogging (forced)"""
280 check_sae_capab(dev[0])
281 check_sae_capab(dev[1])
282 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
283 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
284 params['sae_anti_clogging_threshold'] = '0'
285 hostapd.add_ap(apdev[0], params)
286 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
287 for i in range(0, 2):
288 dev[i].request("SET sae_groups ")
289 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
290 scan_freq="2412")
291
292 def test_sae_mixed(dev, apdev):
293 """Mixed SAE and non-SAE network"""
294 check_sae_capab(dev[0])
295 check_sae_capab(dev[1])
296 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
297 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
298 params['sae_anti_clogging_threshold'] = '0'
299 hapd = hostapd.add_ap(apdev[0], params)
300
301 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
302 for i in range(0, 2):
303 dev[i].request("SET sae_groups ")
304 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
305 scan_freq="2412")
306 sta0 = hapd.get_sta(dev[0].own_addr())
307 sta2 = hapd.get_sta(dev[2].own_addr())
308 if sta0['wpa'] != '2' or sta0['AKMSuiteSelector'] != '00-0f-ac-8':
309 raise Exception("SAE STA(0) AKM suite selector reported incorrectly")
310 if sta2['wpa'] != '2' or sta2['AKMSuiteSelector'] != '00-0f-ac-2':
311 raise Exception("PSK STA(2) AKM suite selector reported incorrectly")
312
313 def test_sae_and_psk(dev, apdev):
314 """SAE and PSK enabled in network profile"""
315 check_sae_capab(dev[0])
316 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
317 params['wpa_key_mgmt'] = 'SAE'
318 hostapd.add_ap(apdev[0], params)
319
320 dev[0].request("SET sae_groups ")
321 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE WPA-PSK",
322 scan_freq="2412")
323
324 def test_sae_and_psk2(dev, apdev):
325 """SAE and PSK enabled in network profile (use PSK)"""
326 check_sae_capab(dev[0])
327 params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678")
328 hostapd.add_ap(apdev[0], params)
329
330 dev[0].request("SET sae_groups ")
331 dev[0].connect("test-psk", psk="12345678", key_mgmt="SAE WPA-PSK",
332 scan_freq="2412")
333
334 def test_sae_mixed_mfp(dev, apdev):
335 """Mixed SAE and non-SAE network and MFP required with SAE"""
336 check_sae_capab(dev[0])
337 check_sae_capab(dev[1])
338 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
339 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
340 params["ieee80211w"] = "1"
341 params['sae_require_mfp'] = '1'
342 hostapd.add_ap(apdev[0], params)
343
344 dev[0].request("SET sae_groups ")
345 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2",
346 scan_freq="2412")
347 dev[0].dump_monitor()
348
349 dev[1].request("SET sae_groups ")
350 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="0",
351 scan_freq="2412", wait_connect=False)
352 ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED",
353 "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
354 if ev is None:
355 raise Exception("No connection result reported")
356 if "CTRL-EVENT-ASSOC-REJECT" not in ev:
357 raise Exception("SAE connection without MFP was not rejected")
358 if "status_code=31" not in ev:
359 raise Exception("Unexpected status code in rejection: " + ev)
360 dev[1].request("DISCONNECT")
361 dev[1].dump_monitor()
362
363 dev[2].connect("test-sae", psk="12345678", ieee80211w="0", scan_freq="2412")
364 dev[2].dump_monitor()
365
366 def test_sae_mfp(dev, apdev):
367 """SAE and MFP enabled without sae_require_mfp"""
368 check_sae_capab(dev[0])
369 check_sae_capab(dev[1])
370 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
371 params['wpa_key_mgmt'] = 'SAE'
372 params["ieee80211w"] = "1"
373 hostapd.add_ap(apdev[0], params)
374
375 dev[0].request("SET sae_groups ")
376 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2",
377 scan_freq="2412")
378
379 dev[1].request("SET sae_groups ")
380 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="0",
381 scan_freq="2412")
382
383 @remote_compatible
384 def test_sae_missing_password(dev, apdev):
385 """SAE and missing password"""
386 check_sae_capab(dev[0])
387 params = hostapd.wpa2_params(ssid="test-sae",
388 passphrase="12345678")
389 params['wpa_key_mgmt'] = 'SAE'
390 hapd = hostapd.add_ap(apdev[0], params)
391
392 dev[0].request("SET sae_groups ")
393 id = dev[0].connect("test-sae",
394 raw_psk="46b4a73b8a951ad53ebd2e0afdb9c5483257edd4c21d12b7710759da70945858",
395 key_mgmt="SAE", scan_freq="2412", wait_connect=False)
396 ev = dev[0].wait_event(['CTRL-EVENT-SSID-TEMP-DISABLED'], timeout=10)
397 if ev is None:
398 raise Exception("Invalid network not temporarily disabled")
399
400
401 def test_sae_key_lifetime_in_memory(dev, apdev, params):
402 """SAE and key lifetime in memory"""
403 check_sae_capab(dev[0])
404 password = "5ad144a7c1f5a5503baa6fa01dabc15b1843e8c01662d78d16b70b5cd23cf8b"
405 p = hostapd.wpa2_params(ssid="test-sae", passphrase=password)
406 p['wpa_key_mgmt'] = 'SAE'
407 hapd = hostapd.add_ap(apdev[0], p)
408
409 pid = find_wpas_process(dev[0])
410
411 dev[0].request("SET sae_groups ")
412 id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
413 scan_freq="2412")
414
415 # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
416 # event has been delivered, so verify that wpa_supplicant has returned to
417 # eloop before reading process memory.
418 time.sleep(1)
419 dev[0].ping()
420 password = password.encode()
421 buf = read_process_memory(pid, password)
422
423 dev[0].request("DISCONNECT")
424 dev[0].wait_disconnected()
425
426 dev[0].relog()
427 sae_k = None
428 sae_keyseed = None
429 sae_kck = None
430 pmk = None
431 ptk = None
432 gtk = None
433 with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
434 for l in f.readlines():
435 if "SAE: k - hexdump" in l:
436 val = l.strip().split(':')[3].replace(' ', '')
437 sae_k = binascii.unhexlify(val)
438 if "SAE: keyseed - hexdump" in l:
439 val = l.strip().split(':')[3].replace(' ', '')
440 sae_keyseed = binascii.unhexlify(val)
441 if "SAE: KCK - hexdump" in l:
442 val = l.strip().split(':')[3].replace(' ', '')
443 sae_kck = binascii.unhexlify(val)
444 if "SAE: PMK - hexdump" in l:
445 val = l.strip().split(':')[3].replace(' ', '')
446 pmk = binascii.unhexlify(val)
447 if "WPA: PTK - hexdump" in l:
448 val = l.strip().split(':')[3].replace(' ', '')
449 ptk = binascii.unhexlify(val)
450 if "WPA: Group Key - hexdump" in l:
451 val = l.strip().split(':')[3].replace(' ', '')
452 gtk = binascii.unhexlify(val)
453 if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk:
454 raise Exception("Could not find keys from debug log")
455 if len(gtk) != 16:
456 raise Exception("Unexpected GTK length")
457
458 kck = ptk[0:16]
459 kek = ptk[16:32]
460 tk = ptk[32:48]
461
462 fname = os.path.join(params['logdir'],
463 'sae_key_lifetime_in_memory.memctx-')
464
465 logger.info("Checking keys in memory while associated")
466 get_key_locations(buf, password, "Password")
467 get_key_locations(buf, pmk, "PMK")
468 if password not in buf:
469 raise HwsimSkip("Password not found while associated")
470 if pmk not in buf:
471 raise HwsimSkip("PMK not found while associated")
472 if kck not in buf:
473 raise Exception("KCK not found while associated")
474 if kek not in buf:
475 raise Exception("KEK not found while associated")
476 #if tk in buf:
477 # raise Exception("TK found from memory")
478 verify_not_present(buf, sae_k, fname, "SAE(k)")
479 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
480 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
481
482 logger.info("Checking keys in memory after disassociation")
483 buf = read_process_memory(pid, password)
484
485 # Note: Password is still present in network configuration
486 # Note: PMK is in PMKSA cache
487
488 get_key_locations(buf, password, "Password")
489 get_key_locations(buf, pmk, "PMK")
490 verify_not_present(buf, kck, fname, "KCK")
491 verify_not_present(buf, kek, fname, "KEK")
492 verify_not_present(buf, tk, fname, "TK")
493 if gtk in buf:
494 get_key_locations(buf, gtk, "GTK")
495 verify_not_present(buf, gtk, fname, "GTK")
496 verify_not_present(buf, sae_k, fname, "SAE(k)")
497 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
498 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
499
500 dev[0].request("PMKSA_FLUSH")
501 logger.info("Checking keys in memory after PMKSA cache flush")
502 buf = read_process_memory(pid, password)
503 get_key_locations(buf, password, "Password")
504 get_key_locations(buf, pmk, "PMK")
505 verify_not_present(buf, pmk, fname, "PMK")
506
507 dev[0].request("REMOVE_NETWORK all")
508
509 logger.info("Checking keys in memory after network profile removal")
510 buf = read_process_memory(pid, password)
511
512 get_key_locations(buf, password, "Password")
513 get_key_locations(buf, pmk, "PMK")
514 verify_not_present(buf, password, fname, "password")
515 verify_not_present(buf, pmk, fname, "PMK")
516 verify_not_present(buf, kck, fname, "KCK")
517 verify_not_present(buf, kek, fname, "KEK")
518 verify_not_present(buf, tk, fname, "TK")
519 verify_not_present(buf, gtk, fname, "GTK")
520 verify_not_present(buf, sae_k, fname, "SAE(k)")
521 verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
522 verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
523
524 @remote_compatible
525 def test_sae_oom_wpas(dev, apdev):
526 """SAE and OOM in wpa_supplicant"""
527 check_sae_capab(dev[0])
528 params = hostapd.wpa2_params(ssid="test-sae",
529 passphrase="12345678")
530 params['wpa_key_mgmt'] = 'SAE'
531 params['sae_groups'] = '19 25 26 20'
532 hapd = hostapd.add_ap(apdev[0], params)
533
534 dev[0].request("SET sae_groups 20")
535 with alloc_fail(dev[0], 1, "sae_set_group"):
536 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
537 scan_freq="2412")
538 dev[0].request("REMOVE_NETWORK all")
539
540 dev[0].request("SET sae_groups ")
541 with alloc_fail(dev[0], 2, "sae_set_group"):
542 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
543 scan_freq="2412")
544 dev[0].request("REMOVE_NETWORK all")
545
546 with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_commit"):
547 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
548 scan_freq="2412")
549 dev[0].request("REMOVE_NETWORK all")
550
551 with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_confirm"):
552 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
553 scan_freq="2412", wait_connect=False)
554 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
555 dev[0].request("REMOVE_NETWORK all")
556
557 with alloc_fail(dev[0], 1, "=sme_authenticate"):
558 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
559 scan_freq="2412", wait_connect=False)
560 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
561 dev[0].request("REMOVE_NETWORK all")
562
563 with alloc_fail(dev[0], 1, "radio_add_work;sme_authenticate"):
564 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
565 scan_freq="2412", wait_connect=False)
566 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
567 dev[0].request("REMOVE_NETWORK all")
568
569 @remote_compatible
570 def test_sae_proto_ecc(dev, apdev):
571 """SAE protocol testing (ECC)"""
572 check_sae_capab(dev[0])
573 params = hostapd.wpa2_params(ssid="test-sae",
574 passphrase="12345678")
575 params['wpa_key_mgmt'] = 'SAE'
576 hapd = hostapd.add_ap(apdev[0], params)
577 bssid = apdev[0]['bssid']
578
579 dev[0].request("SET sae_groups 19")
580
581 tests = [("Confirm mismatch",
582 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
583 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc4240"),
584 ("Commit without even full cyclic group field",
585 "13",
586 None),
587 ("Too short commit",
588 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02",
589 None),
590 ("Invalid commit scalar (0)",
591 "1300" + "0000000000000000000000000000000000000000000000000000000000000000" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
592 None),
593 ("Invalid commit scalar (1)",
594 "1300" + "0000000000000000000000000000000000000000000000000000000000000001" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
595 None),
596 ("Invalid commit scalar (> r)",
597 "1300" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
598 None),
599 ("Commit element not on curve",
600 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728d0000000000000000000000000000000000000000000000000000000000000000",
601 None),
602 ("Invalid commit element (y coordinate > P)",
603 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
604 None),
605 ("Invalid commit element (x coordinate > P)",
606 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
607 None),
608 ("Different group in commit",
609 "1400" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
610 None),
611 ("Too short confirm",
612 "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
613 "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc42")]
614 for (note, commit, confirm) in tests:
615 logger.info(note)
616 dev[0].scan_for_bss(bssid, freq=2412)
617 hapd.set("ext_mgmt_frame_handling", "1")
618 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
619 scan_freq="2412", wait_connect=False)
620
621 logger.info("Commit")
622 for i in range(0, 10):
623 req = hapd.mgmt_rx()
624 if req is None:
625 raise Exception("MGMT RX wait timed out (commit)")
626 if req['subtype'] == 11:
627 break
628 req = None
629 if not req:
630 raise Exception("Authentication frame (commit) not received")
631
632 hapd.dump_monitor()
633 resp = {}
634 resp['fc'] = req['fc']
635 resp['da'] = req['sa']
636 resp['sa'] = req['da']
637 resp['bssid'] = req['bssid']
638 resp['payload'] = binascii.unhexlify("030001000000" + commit)
639 hapd.mgmt_tx(resp)
640
641 if confirm:
642 logger.info("Confirm")
643 for i in range(0, 10):
644 req = hapd.mgmt_rx()
645 if req is None:
646 raise Exception("MGMT RX wait timed out (confirm)")
647 if req['subtype'] == 11:
648 break
649 req = None
650 if not req:
651 raise Exception("Authentication frame (confirm) not received")
652
653 hapd.dump_monitor()
654 resp = {}
655 resp['fc'] = req['fc']
656 resp['da'] = req['sa']
657 resp['sa'] = req['da']
658 resp['bssid'] = req['bssid']
659 resp['payload'] = binascii.unhexlify("030002000000" + confirm)
660 hapd.mgmt_tx(resp)
661
662 time.sleep(0.1)
663 dev[0].request("REMOVE_NETWORK all")
664 hapd.set("ext_mgmt_frame_handling", "0")
665 hapd.dump_monitor()
666
667 @remote_compatible
668 def test_sae_proto_ffc(dev, apdev):
669 """SAE protocol testing (FFC)"""
670 check_sae_capab(dev[0])
671 params = hostapd.wpa2_params(ssid="test-sae",
672 passphrase="12345678")
673 params['wpa_key_mgmt'] = 'SAE'
674 hapd = hostapd.add_ap(apdev[0], params)
675 bssid = apdev[0]['bssid']
676
677 dev[0].request("SET sae_groups 2")
678
679 tests = [("Confirm mismatch",
680 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a17486",
681 "0000f3116a9731f1259622e3eb55d4b3b50ba16f8c5f5565b28e609b180c51460251"),
682 ("Too short commit",
683 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a174",
684 None),
685 ("Invalid element (0) in commit",
686 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
687 None),
688 ("Invalid element (1) in commit",
689 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
690 None),
691 ("Invalid element (> P) in commit",
692 "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
693 None)]
694 for (note, commit, confirm) in tests:
695 logger.info(note)
696 dev[0].scan_for_bss(bssid, freq=2412)
697 hapd.set("ext_mgmt_frame_handling", "1")
698 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
699 scan_freq="2412", wait_connect=False)
700
701 logger.info("Commit")
702 for i in range(0, 10):
703 req = hapd.mgmt_rx()
704 if req is None:
705 raise Exception("MGMT RX wait timed out (commit)")
706 if req['subtype'] == 11:
707 break
708 req = None
709 if not req:
710 raise Exception("Authentication frame (commit) not received")
711
712 hapd.dump_monitor()
713 resp = {}
714 resp['fc'] = req['fc']
715 resp['da'] = req['sa']
716 resp['sa'] = req['da']
717 resp['bssid'] = req['bssid']
718 resp['payload'] = binascii.unhexlify("030001000000" + commit)
719 hapd.mgmt_tx(resp)
720
721 if confirm:
722 logger.info("Confirm")
723 for i in range(0, 10):
724 req = hapd.mgmt_rx()
725 if req is None:
726 raise Exception("MGMT RX wait timed out (confirm)")
727 if req['subtype'] == 11:
728 break
729 req = None
730 if not req:
731 raise Exception("Authentication frame (confirm) not received")
732
733 hapd.dump_monitor()
734 resp = {}
735 resp['fc'] = req['fc']
736 resp['da'] = req['sa']
737 resp['sa'] = req['da']
738 resp['bssid'] = req['bssid']
739 resp['payload'] = binascii.unhexlify("030002000000" + confirm)
740 hapd.mgmt_tx(resp)
741
742 time.sleep(0.1)
743 dev[0].request("REMOVE_NETWORK all")
744 hapd.set("ext_mgmt_frame_handling", "0")
745 hapd.dump_monitor()
746
747
748 def test_sae_proto_commit_delayed(dev, apdev):
749 """SAE protocol testing - Commit delayed"""
750 check_sae_capab(dev[0])
751 params = hostapd.wpa2_params(ssid="test-sae",
752 passphrase="12345678")
753 params['wpa_key_mgmt'] = 'SAE'
754 hapd = hostapd.add_ap(apdev[0], params)
755 bssid = apdev[0]['bssid']
756
757 dev[0].request("SET sae_groups 19")
758
759 dev[0].scan_for_bss(bssid, freq=2412)
760 hapd.set("ext_mgmt_frame_handling", "1")
761 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
762 scan_freq="2412", wait_connect=False)
763
764 logger.info("Commit")
765 for i in range(0, 10):
766 req = hapd.mgmt_rx()
767 if req is None:
768 raise Exception("MGMT RX wait timed out (commit)")
769 if req['subtype'] == 11:
770 break
771 req = None
772 if not req:
773 raise Exception("Authentication frame (commit) not received")
774
775 hapd.dump_monitor()
776 time.sleep(2.5)
777 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
778
779 logger.info("Commit/Confirm")
780 for i in range(0, 10):
781 req = hapd.mgmt_rx()
782 if req is None:
783 raise Exception("MGMT RX wait timed out (confirm)")
784 if req['subtype'] == 11:
785 trans, = struct.unpack('<H', req['payload'][2:4])
786 if trans == 1:
787 logger.info("Extra Commit")
788 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
789 continue
790 break
791 req = None
792 if not req:
793 raise Exception("Authentication frame (confirm) not received")
794
795 hapd.dump_monitor()
796 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
797
798 logger.info("Association Request")
799 for i in range(0, 10):
800 req = hapd.mgmt_rx()
801 if req is None:
802 raise Exception("MGMT RX wait timed out (AssocReq)")
803 if req['subtype'] == 0:
804 break
805 req = None
806 if not req:
807 raise Exception("Association Request frame not received")
808
809 hapd.dump_monitor()
810 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
811 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
812 if ev is None:
813 raise Exception("Management frame TX status not reported (1)")
814 if "stype=1 ok=1" not in ev:
815 raise Exception("Unexpected management frame TX status (1): " + ev)
816 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
817 if "OK" not in hapd.request(cmd):
818 raise Exception("MGMT_TX_STATUS_PROCESS failed")
819
820 hapd.set("ext_mgmt_frame_handling", "0")
821
822 dev[0].wait_connected()
823
824 def test_sae_proto_commit_replay(dev, apdev):
825 """SAE protocol testing - Commit replay"""
826 check_sae_capab(dev[0])
827 params = hostapd.wpa2_params(ssid="test-sae",
828 passphrase="12345678")
829 params['wpa_key_mgmt'] = 'SAE'
830 hapd = hostapd.add_ap(apdev[0], params)
831 bssid = apdev[0]['bssid']
832
833 dev[0].request("SET sae_groups 19")
834
835 dev[0].scan_for_bss(bssid, freq=2412)
836 hapd.set("ext_mgmt_frame_handling", "1")
837 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
838 scan_freq="2412", wait_connect=False)
839
840 logger.info("Commit")
841 for i in range(0, 10):
842 req = hapd.mgmt_rx()
843 if req is None:
844 raise Exception("MGMT RX wait timed out (commit)")
845 if req['subtype'] == 11:
846 break
847 req = None
848 if not req:
849 raise Exception("Authentication frame (commit) not received")
850
851 hapd.dump_monitor()
852 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
853 logger.info("Replay Commit")
854 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
855
856 logger.info("Confirm")
857 for i in range(0, 10):
858 req = hapd.mgmt_rx()
859 if req is None:
860 raise Exception("MGMT RX wait timed out (confirm)")
861 if req['subtype'] == 11:
862 trans, = struct.unpack('<H', req['payload'][2:4])
863 if trans == 1:
864 logger.info("Extra Commit")
865 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
866 continue
867 break
868 req = None
869 if not req:
870 raise Exception("Authentication frame (confirm) not received")
871
872 hapd.dump_monitor()
873 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
874
875 logger.info("Association Request")
876 for i in range(0, 10):
877 req = hapd.mgmt_rx()
878 if req is None:
879 raise Exception("MGMT RX wait timed out (AssocReq)")
880 if req['subtype'] == 0:
881 break
882 req = None
883 if not req:
884 raise Exception("Association Request frame not received")
885
886 hapd.dump_monitor()
887 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
888 for i in range(0, 10):
889 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
890 if ev is None:
891 raise Exception("Management frame TX status not reported (1)")
892 if "stype=11 ok=1" in ev:
893 continue
894 if "stype=12 ok=1" in ev:
895 continue
896 if "stype=1 ok=1" not in ev:
897 raise Exception("Unexpected management frame TX status (1): " + ev)
898 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
899 if "OK" not in hapd.request(cmd):
900 raise Exception("MGMT_TX_STATUS_PROCESS failed")
901 break
902
903 hapd.set("ext_mgmt_frame_handling", "0")
904
905 dev[0].wait_connected()
906
907 def test_sae_proto_confirm_replay(dev, apdev):
908 """SAE protocol testing - Confirm replay"""
909 check_sae_capab(dev[0])
910 params = hostapd.wpa2_params(ssid="test-sae",
911 passphrase="12345678")
912 params['wpa_key_mgmt'] = 'SAE'
913 hapd = hostapd.add_ap(apdev[0], params)
914 bssid = apdev[0]['bssid']
915
916 dev[0].request("SET sae_groups 19")
917
918 dev[0].scan_for_bss(bssid, freq=2412)
919 hapd.set("ext_mgmt_frame_handling", "1")
920 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
921 scan_freq="2412", wait_connect=False)
922
923 logger.info("Commit")
924 for i in range(0, 10):
925 req = hapd.mgmt_rx()
926 if req is None:
927 raise Exception("MGMT RX wait timed out (commit)")
928 if req['subtype'] == 11:
929 break
930 req = None
931 if not req:
932 raise Exception("Authentication frame (commit) not received")
933
934 hapd.dump_monitor()
935 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
936
937 logger.info("Confirm")
938 for i in range(0, 10):
939 req = hapd.mgmt_rx()
940 if req is None:
941 raise Exception("MGMT RX wait timed out (confirm)")
942 if req['subtype'] == 11:
943 break
944 req = None
945 if not req:
946 raise Exception("Authentication frame (confirm) not received")
947
948 hapd.dump_monitor()
949 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
950
951 logger.info("Replay Confirm")
952 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
953
954 logger.info("Association Request")
955 for i in range(0, 10):
956 req = hapd.mgmt_rx()
957 if req is None:
958 raise Exception("MGMT RX wait timed out (AssocReq)")
959 if req['subtype'] == 0:
960 break
961 req = None
962 if not req:
963 raise Exception("Association Request frame not received")
964
965 hapd.dump_monitor()
966 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
967 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
968 if ev is None:
969 raise Exception("Management frame TX status not reported (1)")
970 if "stype=1 ok=1" not in ev:
971 raise Exception("Unexpected management frame TX status (1): " + ev)
972 cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
973 if "OK" not in hapd.request(cmd):
974 raise Exception("MGMT_TX_STATUS_PROCESS failed")
975
976 hapd.set("ext_mgmt_frame_handling", "0")
977
978 dev[0].wait_connected()
979
980 def test_sae_proto_hostapd(dev, apdev):
981 """SAE protocol testing with hostapd"""
982 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
983 params['wpa_key_mgmt'] = 'SAE'
984 params['sae_groups'] = "19 65535"
985 hapd = hostapd.add_ap(apdev[0], params)
986 hapd.set("ext_mgmt_frame_handling", "1")
987 bssid = hapd.own_addr().replace(':', '')
988 addr = "020000000000"
989 addr2 = "020000000001"
990 hdr = "b0003a01" + bssid + addr + bssid + "1000"
991 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000"
992 group = "1300"
993 scalar = "f7df19f4a7fef1d3b895ea1de150b7c5a7a705c8ebb31a52b623e0057908bd93"
994 element_x = "21931572027f2e953e2a49fab3d992944102cc95aa19515fc068b394fb25ae3c"
995 element_y = "cb4eeb94d7b0b789abfdb73a67ab9d6d5efa94dd553e0e724a6289821cbce530"
996 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y)
997 # "SAE: Not enough data for scalar"
998 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar[:-2])
999 # "SAE: Do not allow group to be changed"
1000 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + "ffff" + scalar[:-2])
1001 # "SAE: Unsupported Finite Cyclic Group 65535"
1002 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr2 + "030001000000" + "ffff" + scalar[:-2])
1003
1004 def test_sae_proto_hostapd_ecc(dev, apdev):
1005 """SAE protocol testing with hostapd (ECC)"""
1006 params = hostapd.wpa2_params(ssid="test-sae", passphrase="foofoofoo")
1007 params['wpa_key_mgmt'] = 'SAE'
1008 params['sae_groups'] = "19"
1009 hapd = hostapd.add_ap(apdev[0], params)
1010 hapd.set("ext_mgmt_frame_handling", "1")
1011 bssid = hapd.own_addr().replace(':', '')
1012 addr = "020000000000"
1013 addr2 = "020000000001"
1014 hdr = "b0003a01" + bssid + addr + bssid + "1000"
1015 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000"
1016 group = "1300"
1017 scalar = "9e9a959bf2dda875a4a29ce9b2afef46f2d83060930124cd9e39ddce798cd69a"
1018 element_x = "dfc55fd8622b91d362f4d1fc9646474d7fba0ff7cce6ca58b8e96a931e070220"
1019 element_y = "dac8a4e80724f167c1349cc9e1f9dd82a7c77b29d49789b63b72b4c849301a28"
1020 # sae_parse_commit_element_ecc() failure to parse peer element
1021 # (depending on crypto library, either crypto_ec_point_from_bin() failure
1022 # or crypto_ec_point_is_on_curve() returning 0)
1023 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y)
1024 # Unexpected continuation of the connection attempt with confirm
1025 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030002000000" + "0000" + "fd7b081ff4e8676f03612a4140eedcd3c179ab3a13b93863c6f7ca451340b9ae")
1026
1027 def test_sae_proto_hostapd_ffc(dev, apdev):
1028 """SAE protocol testing with hostapd (FFC)"""
1029 params = hostapd.wpa2_params(ssid="test-sae", passphrase="foofoofoo")
1030 params['wpa_key_mgmt'] = 'SAE'
1031 params['sae_groups'] = "22"
1032 hapd = hostapd.add_ap(apdev[0], params)
1033 hapd.set("ext_mgmt_frame_handling", "1")
1034 bssid = hapd.own_addr().replace(':', '')
1035 addr = "020000000000"
1036 addr2 = "020000000001"
1037 hdr = "b0003a01" + bssid + addr + bssid + "1000"
1038 hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000"
1039 group = "1600"
1040 scalar = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044cc46a73c07ef479dc66ec1f5e8ccf25131fa40"
1041 element = "0f1d67025e12fc874cf718c35b19d1ab2db858215623f1ce661cbd1d7b1d7a09ceda7dba46866cf37044259b5cac4db15e7feb778edc8098854b93a84347c1850c02ee4d7dac46db79c477c731085d5b39f56803cda1eeac4a2fbbccb9a546379e258c00ebe93dfdd0a34cf8ce5c55cf905a89564a590b7e159fb89198e9d5cd"
1042 # sae_parse_commit_element_ffc() failure to parse peer element
1043 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element)
1044 # Unexpected continuation of the connection attempt with confirm
1045 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030002000000" + "0000" + "fd7b081ff4e8676f03612a4140eedcd3c179ab3a13b93863c6f7ca451340b9ae")
1046
1047 @remote_compatible
1048 def test_sae_no_ffc_by_default(dev, apdev):
1049 """SAE and default groups rejecting FFC"""
1050 check_sae_capab(dev[0])
1051 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1052 params['wpa_key_mgmt'] = 'SAE'
1053 hapd = hostapd.add_ap(apdev[0], params)
1054
1055 dev[0].request("SET sae_groups 15")
1056 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412",
1057 wait_connect=False)
1058 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
1059 if ev is None:
1060 raise Exception("Did not try to authenticate")
1061 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
1062 if ev is None:
1063 raise Exception("Did not try to authenticate (2)")
1064 dev[0].request("REMOVE_NETWORK all")
1065
1066 def sae_reflection_attack(apdev, dev, group):
1067 check_sae_capab(dev)
1068 params = hostapd.wpa2_params(ssid="test-sae",
1069 passphrase="no-knowledge-of-passphrase")
1070 params['wpa_key_mgmt'] = 'SAE'
1071 hapd = hostapd.add_ap(apdev, params)
1072 bssid = apdev['bssid']
1073
1074 dev.scan_for_bss(bssid, freq=2412)
1075 hapd.set("ext_mgmt_frame_handling", "1")
1076
1077 dev.request("SET sae_groups %d" % group)
1078 dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
1079 scan_freq="2412", wait_connect=False)
1080
1081 # Commit
1082 for i in range(0, 10):
1083 req = hapd.mgmt_rx()
1084 if req is None:
1085 raise Exception("MGMT RX wait timed out")
1086 if req['subtype'] == 11:
1087 break
1088 req = None
1089 if not req:
1090 raise Exception("Authentication frame not received")
1091
1092 resp = {}
1093 resp['fc'] = req['fc']
1094 resp['da'] = req['sa']
1095 resp['sa'] = req['da']
1096 resp['bssid'] = req['bssid']
1097 resp['payload'] = req['payload']
1098 hapd.mgmt_tx(resp)
1099
1100 # Confirm
1101 req = hapd.mgmt_rx(timeout=0.5)
1102 if req is not None:
1103 if req['subtype'] == 11:
1104 raise Exception("Unexpected Authentication frame seen")
1105
1106 @remote_compatible
1107 def test_sae_reflection_attack_ecc(dev, apdev):
1108 """SAE reflection attack (ECC)"""
1109 sae_reflection_attack(apdev[0], dev[0], 19)
1110
1111 @remote_compatible
1112 def test_sae_reflection_attack_ffc(dev, apdev):
1113 """SAE reflection attack (FFC)"""
1114 sae_reflection_attack(apdev[0], dev[0], 15)
1115
1116 def sae_reflection_attack_internal(apdev, dev, group):
1117 check_sae_capab(dev)
1118 params = hostapd.wpa2_params(ssid="test-sae",
1119 passphrase="no-knowledge-of-passphrase")
1120 params['wpa_key_mgmt'] = 'SAE'
1121 params['sae_reflection_attack'] = '1'
1122 hapd = hostapd.add_ap(apdev, params)
1123 bssid = apdev['bssid']
1124
1125 dev.scan_for_bss(bssid, freq=2412)
1126 dev.request("SET sae_groups %d" % group)
1127 dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
1128 scan_freq="2412", wait_connect=False)
1129 ev = dev.wait_event(["SME: Trying to authenticate"], timeout=10)
1130 if ev is None:
1131 raise Exception("No authentication attempt seen")
1132 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1133 if ev is not None:
1134 raise Exception("Unexpected connection")
1135
1136 @remote_compatible
1137 def test_sae_reflection_attack_ecc_internal(dev, apdev):
1138 """SAE reflection attack (ECC) - internal"""
1139 sae_reflection_attack_internal(apdev[0], dev[0], 19)
1140
1141 @remote_compatible
1142 def test_sae_reflection_attack_ffc_internal(dev, apdev):
1143 """SAE reflection attack (FFC) - internal"""
1144 sae_reflection_attack_internal(apdev[0], dev[0], 15)
1145
1146 @remote_compatible
1147 def test_sae_commit_override(dev, apdev):
1148 """SAE commit override (hostapd)"""
1149 check_sae_capab(dev[0])
1150 params = hostapd.wpa2_params(ssid="test-sae",
1151 passphrase="12345678")
1152 params['wpa_key_mgmt'] = 'SAE'
1153 params['sae_commit_override'] = '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514'
1154 hapd = hostapd.add_ap(apdev[0], params)
1155 dev[0].request("SET sae_groups ")
1156 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
1157 scan_freq="2412", wait_connect=False)
1158 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1159 if ev is not None:
1160 raise Exception("Unexpected connection")
1161
1162 @remote_compatible
1163 def test_sae_commit_override2(dev, apdev):
1164 """SAE commit override (wpa_supplicant)"""
1165 check_sae_capab(dev[0])
1166 params = hostapd.wpa2_params(ssid="test-sae",
1167 passphrase="12345678")
1168 params['wpa_key_mgmt'] = 'SAE'
1169 hapd = hostapd.add_ap(apdev[0], params)
1170 dev[0].request("SET sae_groups ")
1171 dev[0].set('sae_commit_override', '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514')
1172 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
1173 scan_freq="2412", wait_connect=False)
1174 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1175 if ev is not None:
1176 raise Exception("Unexpected connection")
1177
1178 def test_sae_commit_invalid_scalar_element_ap(dev, apdev):
1179 """SAE commit invalid scalar/element from AP"""
1180 check_sae_capab(dev[0])
1181 params = hostapd.wpa2_params(ssid="test-sae",
1182 passphrase="12345678")
1183 params['wpa_key_mgmt'] = 'SAE'
1184 params['sae_commit_override'] = '1300' + 96*'00'
1185 hapd = hostapd.add_ap(apdev[0], params)
1186 dev[0].request("SET sae_groups ")
1187 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
1188 scan_freq="2412", wait_connect=False)
1189 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1190 if ev is not None:
1191 raise Exception("Unexpected connection")
1192
1193 def test_sae_commit_invalid_element_ap(dev, apdev):
1194 """SAE commit invalid element from AP"""
1195 check_sae_capab(dev[0])
1196 params = hostapd.wpa2_params(ssid="test-sae",
1197 passphrase="12345678")
1198 params['wpa_key_mgmt'] = 'SAE'
1199 params['sae_commit_override'] = '1300' + 31*'00' + '02' + 64*'00'
1200 hapd = hostapd.add_ap(apdev[0], params)
1201 dev[0].request("SET sae_groups ")
1202 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
1203 scan_freq="2412", wait_connect=False)
1204 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1205 if ev is not None:
1206 raise Exception("Unexpected connection")
1207
1208 def test_sae_commit_invalid_scalar_element_sta(dev, apdev):
1209 """SAE commit invalid scalar/element from STA"""
1210 check_sae_capab(dev[0])
1211 params = hostapd.wpa2_params(ssid="test-sae",
1212 passphrase="12345678")
1213 params['wpa_key_mgmt'] = 'SAE'
1214 hapd = hostapd.add_ap(apdev[0], params)
1215 dev[0].request("SET sae_groups ")
1216 dev[0].set('sae_commit_override', '1300' + 96*'00')
1217 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
1218 scan_freq="2412", wait_connect=False)
1219 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1220 if ev is not None:
1221 raise Exception("Unexpected connection")
1222
1223 def test_sae_commit_invalid_element_sta(dev, apdev):
1224 """SAE commit invalid element from STA"""
1225 check_sae_capab(dev[0])
1226 params = hostapd.wpa2_params(ssid="test-sae",
1227 passphrase="12345678")
1228 params['wpa_key_mgmt'] = 'SAE'
1229 hapd = hostapd.add_ap(apdev[0], params)
1230 dev[0].request("SET sae_groups ")
1231 dev[0].set('sae_commit_override', '1300' + 31*'00' + '02' + 64*'00')
1232 dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
1233 scan_freq="2412", wait_connect=False)
1234 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1235 if ev is not None:
1236 raise Exception("Unexpected connection")
1237
1238 @remote_compatible
1239 def test_sae_anti_clogging_proto(dev, apdev):
1240 """SAE anti clogging protocol testing"""
1241 check_sae_capab(dev[0])
1242 params = hostapd.wpa2_params(ssid="test-sae",
1243 passphrase="no-knowledge-of-passphrase")
1244 params['wpa_key_mgmt'] = 'SAE'
1245 hapd = hostapd.add_ap(apdev[0], params)
1246 bssid = apdev[0]['bssid']
1247
1248 dev[0].scan_for_bss(bssid, freq=2412)
1249 hapd.set("ext_mgmt_frame_handling", "1")
1250
1251 dev[0].request("SET sae_groups ")
1252 dev[0].connect("test-sae", psk="anti-cloggign", key_mgmt="SAE",
1253 scan_freq="2412", wait_connect=False)
1254
1255 # Commit
1256 for i in range(0, 10):
1257 req = hapd.mgmt_rx()
1258 if req is None:
1259 raise Exception("MGMT RX wait timed out")
1260 if req['subtype'] == 11:
1261 break
1262 req = None
1263 if not req:
1264 raise Exception("Authentication frame not received")
1265
1266 resp = {}
1267 resp['fc'] = req['fc']
1268 resp['da'] = req['sa']
1269 resp['sa'] = req['da']
1270 resp['bssid'] = req['bssid']
1271 resp['payload'] = binascii.unhexlify("030001004c00" + "ffff00")
1272 hapd.mgmt_tx(resp)
1273
1274 # Confirm (not received due to DH group being rejected)
1275 req = hapd.mgmt_rx(timeout=0.5)
1276 if req is not None:
1277 if req['subtype'] == 11:
1278 raise Exception("Unexpected Authentication frame seen")
1279
1280 @remote_compatible
1281 def test_sae_no_random(dev, apdev):
1282 """SAE and no random numbers available"""
1283 check_sae_capab(dev[0])
1284 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1285 params['wpa_key_mgmt'] = 'SAE'
1286 hapd = hostapd.add_ap(apdev[0], params)
1287
1288 dev[0].request("SET sae_groups ")
1289 tests = [(1, "os_get_random;sae_derive_pwe_ecc")]
1290 for count, func in tests:
1291 with fail_test(dev[0], count, func):
1292 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1293 scan_freq="2412")
1294 dev[0].request("REMOVE_NETWORK all")
1295 dev[0].wait_disconnected()
1296
1297 @remote_compatible
1298 def test_sae_pwe_failure(dev, apdev):
1299 """SAE and pwe failure"""
1300 check_sae_capab(dev[0])
1301 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1302 params['wpa_key_mgmt'] = 'SAE'
1303 params['sae_groups'] = '19 15'
1304 hapd = hostapd.add_ap(apdev[0], params)
1305
1306 dev[0].request("SET sae_groups 19")
1307 with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ecc"):
1308 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1309 scan_freq="2412")
1310 dev[0].request("REMOVE_NETWORK all")
1311 dev[0].wait_disconnected()
1312 with fail_test(dev[0], 1, "sae_test_pwd_seed_ecc"):
1313 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1314 scan_freq="2412")
1315 dev[0].request("REMOVE_NETWORK all")
1316 dev[0].wait_disconnected()
1317
1318 dev[0].request("SET sae_groups 15")
1319 with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ffc"):
1320 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1321 scan_freq="2412")
1322 dev[0].request("REMOVE_NETWORK all")
1323 dev[0].wait_disconnected()
1324
1325 dev[0].request("SET sae_groups 15")
1326 with fail_test(dev[0], 1, "sae_test_pwd_seed_ffc"):
1327 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1328 scan_freq="2412")
1329 dev[0].request("REMOVE_NETWORK all")
1330 dev[0].wait_disconnected()
1331 with fail_test(dev[0], 2, "sae_test_pwd_seed_ffc"):
1332 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1333 scan_freq="2412")
1334 dev[0].request("REMOVE_NETWORK all")
1335 dev[0].wait_disconnected()
1336
1337 @remote_compatible
1338 def test_sae_bignum_failure(dev, apdev):
1339 """SAE and bignum failure"""
1340 check_sae_capab(dev[0])
1341 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1342 params['wpa_key_mgmt'] = 'SAE'
1343 params['sae_groups'] = '19 15 22'
1344 hapd = hostapd.add_ap(apdev[0], params)
1345
1346 dev[0].request("SET sae_groups 19")
1347 tests = [(1, "crypto_bignum_init_set;dragonfly_get_rand_1_to_p_1"),
1348 (1, "crypto_bignum_init;dragonfly_is_quadratic_residue_blind"),
1349 (1, "crypto_bignum_mulmod;dragonfly_is_quadratic_residue_blind"),
1350 (2, "crypto_bignum_mulmod;dragonfly_is_quadratic_residue_blind"),
1351 (3, "crypto_bignum_mulmod;dragonfly_is_quadratic_residue_blind"),
1352 (1, "crypto_bignum_legendre;dragonfly_is_quadratic_residue_blind"),
1353 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ecc"),
1354 (1, "crypto_ec_point_compute_y_sqr;sae_test_pwd_seed_ecc"),
1355 (1, "crypto_bignum_to_bin;sae_derive_pwe_ecc"),
1356 (1, "crypto_ec_point_init;sae_derive_pwe_ecc"),
1357 (1, "crypto_ec_point_solve_y_coord;sae_derive_pwe_ecc"),
1358 (1, "crypto_ec_point_init;sae_derive_commit_element_ecc"),
1359 (1, "crypto_ec_point_mul;sae_derive_commit_element_ecc"),
1360 (1, "crypto_ec_point_invert;sae_derive_commit_element_ecc"),
1361 (1, "crypto_bignum_init;=sae_derive_commit"),
1362 (1, "crypto_ec_point_init;sae_derive_k_ecc"),
1363 (1, "crypto_ec_point_mul;sae_derive_k_ecc"),
1364 (1, "crypto_ec_point_add;sae_derive_k_ecc"),
1365 (2, "crypto_ec_point_mul;sae_derive_k_ecc"),
1366 (1, "crypto_ec_point_to_bin;sae_derive_k_ecc"),
1367 (1, "crypto_bignum_legendre;dragonfly_get_random_qr_qnr"),
1368 (1, "sha256_prf;sae_derive_keys"),
1369 (1, "crypto_bignum_init;sae_derive_keys"),
1370 (1, "crypto_bignum_init_set;sae_parse_commit_scalar"),
1371 (1, "crypto_bignum_to_bin;sae_parse_commit_element_ecc"),
1372 (1, "crypto_ec_point_from_bin;sae_parse_commit_element_ecc")]
1373 for count, func in tests:
1374 with fail_test(dev[0], count, func):
1375 hapd.request("NOTE STA failure testing %d:%s" % (count, func))
1376 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1377 scan_freq="2412", wait_connect=False)
1378 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1)
1379 dev[0].request("REMOVE_NETWORK all")
1380 dev[0].dump_monitor()
1381 hapd.dump_monitor()
1382
1383 dev[0].request("SET sae_groups 15")
1384 tests = [(1, "crypto_bignum_init_set;sae_set_group"),
1385 (2, "crypto_bignum_init_set;sae_set_group"),
1386 (1, "crypto_bignum_init;sae_derive_commit"),
1387 (2, "crypto_bignum_init;sae_derive_commit"),
1388 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
1389 (1, "crypto_bignum_exptmod;sae_test_pwd_seed_ffc"),
1390 (1, "crypto_bignum_init;sae_derive_pwe_ffc"),
1391 (1, "crypto_bignum_init;sae_derive_commit_element_ffc"),
1392 (1, "crypto_bignum_exptmod;sae_derive_commit_element_ffc"),
1393 (1, "crypto_bignum_inverse;sae_derive_commit_element_ffc"),
1394 (1, "crypto_bignum_init;sae_derive_k_ffc"),
1395 (1, "crypto_bignum_exptmod;sae_derive_k_ffc"),
1396 (1, "crypto_bignum_mulmod;sae_derive_k_ffc"),
1397 (2, "crypto_bignum_exptmod;sae_derive_k_ffc"),
1398 (1, "crypto_bignum_to_bin;sae_derive_k_ffc"),
1399 (1, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
1400 (1, "crypto_bignum_init;sae_parse_commit_element_ffc"),
1401 (2, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
1402 (1, "crypto_bignum_exptmod;sae_parse_commit_element_ffc")]
1403 for count, func in tests:
1404 with fail_test(dev[0], count, func):
1405 hapd.request("NOTE STA failure testing %d:%s" % (count, func))
1406 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1407 scan_freq="2412", wait_connect=False)
1408 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1)
1409 dev[0].request("REMOVE_NETWORK all")
1410 dev[0].dump_monitor()
1411 hapd.dump_monitor()
1412
1413 def test_sae_bignum_failure_unsafe_group(dev, apdev):
1414 """SAE and bignum failure unsafe group"""
1415 check_sae_capab(dev[0])
1416 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1417 params['wpa_key_mgmt'] = 'SAE'
1418 params['sae_groups'] = '22'
1419 hapd = hostapd.add_ap(apdev[0], params)
1420
1421 dev[0].request("SET sae_groups 22")
1422 tests = [(1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
1423 (1, "crypto_bignum_sub;sae_test_pwd_seed_ffc"),
1424 (1, "crypto_bignum_div;sae_test_pwd_seed_ffc")]
1425 for count, func in tests:
1426 with fail_test(dev[0], count, func):
1427 hapd.request("NOTE STA failure testing %d:%s" % (count, func))
1428 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1429 scan_freq="2412", wait_connect=False)
1430 wait_fail_trigger(dev[0], "GET_FAIL")
1431 dev[0].request("REMOVE_NETWORK all")
1432 dev[0].dump_monitor()
1433 hapd.dump_monitor()
1434
1435 def test_sae_invalid_anti_clogging_token_req(dev, apdev):
1436 """SAE and invalid anti-clogging token request"""
1437 check_sae_capab(dev[0])
1438 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1439 params['wpa_key_mgmt'] = 'SAE'
1440 # Beacon more frequently since Probe Request frames are practically ignored
1441 # in this test setup (ext_mgmt_frame_handled=1 on hostapd side) and
1442 # wpa_supplicant scans may end up getting ignored if no new results are
1443 # available due to the missing Probe Response frames.
1444 params['beacon_int'] = '20'
1445 hapd = hostapd.add_ap(apdev[0], params)
1446 bssid = apdev[0]['bssid']
1447
1448 dev[0].request("SET sae_groups 19")
1449 dev[0].scan_for_bss(bssid, freq=2412)
1450 hapd.set("ext_mgmt_frame_handling", "1")
1451 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1452 scan_freq="2412", wait_connect=False)
1453 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1454 if ev is None:
1455 raise Exception("No authentication attempt seen (1)")
1456 dev[0].dump_monitor()
1457
1458 for i in range(0, 10):
1459 req = hapd.mgmt_rx()
1460 if req is None:
1461 raise Exception("MGMT RX wait timed out (commit)")
1462 if req['subtype'] == 11:
1463 break
1464 req = None
1465 if not req:
1466 raise Exception("Authentication frame (commit) not received")
1467
1468 hapd.dump_monitor()
1469 resp = {}
1470 resp['fc'] = req['fc']
1471 resp['da'] = req['sa']
1472 resp['sa'] = req['da']
1473 resp['bssid'] = req['bssid']
1474 resp['payload'] = binascii.unhexlify("030001004c0013")
1475 hapd.mgmt_tx(resp)
1476 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
1477 if ev is None:
1478 raise Exception("Management frame TX status not reported (1)")
1479 if "stype=11 ok=1" not in ev:
1480 raise Exception("Unexpected management frame TX status (1): " + ev)
1481
1482 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1483 if ev is None:
1484 raise Exception("No authentication attempt seen (2)")
1485 dev[0].dump_monitor()
1486
1487 for i in range(0, 10):
1488 req = hapd.mgmt_rx()
1489 if req is None:
1490 raise Exception("MGMT RX wait timed out (commit) (2)")
1491 if req['subtype'] == 11:
1492 break
1493 req = None
1494 if not req:
1495 raise Exception("Authentication frame (commit) not received (2)")
1496
1497 hapd.dump_monitor()
1498 resp = {}
1499 resp['fc'] = req['fc']
1500 resp['da'] = req['sa']
1501 resp['sa'] = req['da']
1502 resp['bssid'] = req['bssid']
1503 resp['payload'] = binascii.unhexlify("030001000100")
1504 hapd.mgmt_tx(resp)
1505 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
1506 if ev is None:
1507 raise Exception("Management frame TX status not reported (1)")
1508 if "stype=11 ok=1" not in ev:
1509 raise Exception("Unexpected management frame TX status (1): " + ev)
1510
1511 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1512 if ev is None:
1513 raise Exception("No authentication attempt seen (3)")
1514 dev[0].dump_monitor()
1515
1516 dev[0].request("DISCONNECT")
1517
1518 def test_sae_password(dev, apdev):
1519 """SAE and sae_password in hostapd configuration"""
1520 check_sae_capab(dev[0])
1521 params = hostapd.wpa2_params(ssid="test-sae",
1522 passphrase="12345678")
1523 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
1524 params['sae_password'] = "sae-password"
1525 hapd = hostapd.add_ap(apdev[0], params)
1526
1527 dev[0].request("SET sae_groups ")
1528 dev[0].connect("test-sae", psk="sae-password", key_mgmt="SAE",
1529 scan_freq="2412")
1530 dev[1].connect("test-sae", psk="12345678", scan_freq="2412")
1531 dev[2].request("SET sae_groups ")
1532 dev[2].connect("test-sae", sae_password="sae-password", key_mgmt="SAE",
1533 scan_freq="2412")
1534
1535 def test_sae_password_short(dev, apdev):
1536 """SAE and short password"""
1537 check_sae_capab(dev[0])
1538 params = hostapd.wpa2_params(ssid="test-sae")
1539 params['wpa_key_mgmt'] = 'SAE'
1540 params['sae_password'] = "secret"
1541 hapd = hostapd.add_ap(apdev[0], params)
1542
1543 dev[0].request("SET sae_groups ")
1544 dev[0].connect("test-sae", sae_password="secret", key_mgmt="SAE",
1545 scan_freq="2412")
1546
1547 def test_sae_password_long(dev, apdev):
1548 """SAE and long password"""
1549 check_sae_capab(dev[0])
1550 params = hostapd.wpa2_params(ssid="test-sae")
1551 params['wpa_key_mgmt'] = 'SAE'
1552 params['sae_password'] = 100*"A"
1553 hapd = hostapd.add_ap(apdev[0], params)
1554
1555 dev[0].request("SET sae_groups ")
1556 dev[0].connect("test-sae", sae_password=100*"A", key_mgmt="SAE",
1557 scan_freq="2412")
1558
1559 def test_sae_connect_cmd(dev, apdev):
1560 """SAE with connect command"""
1561 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1562 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1563 check_sae_capab(wpas)
1564 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1565 params['wpa_key_mgmt'] = 'SAE'
1566 hapd = hostapd.add_ap(apdev[0], params)
1567
1568 wpas.request("SET sae_groups ")
1569 wpas.connect("test-sae", psk="12345678", key_mgmt="SAE",
1570 scan_freq="2412", wait_connect=False)
1571 # mac80211_hwsim does not support SAE offload, so accept both a successful
1572 # connection and association rejection.
1573 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-ASSOC-REJECT",
1574 "Association request to the driver failed"],
1575 timeout=15)
1576 if ev is None:
1577 raise Exception("No connection result reported")
1578
1579 def run_sae_password_id(dev, apdev, groups=None):
1580 check_sae_capab(dev[0])
1581 params = hostapd.wpa2_params(ssid="test-sae")
1582 params['wpa_key_mgmt'] = 'SAE'
1583 if groups:
1584 params['sae_groups'] = groups
1585 else:
1586 groups = ""
1587 params['sae_password'] = ['secret|mac=ff:ff:ff:ff:ff:ff|id=pw id',
1588 'foo|mac=02:02:02:02:02:02',
1589 'another secret|mac=ff:ff:ff:ff:ff:ff|id=' + 29*'A']
1590 hapd = hostapd.add_ap(apdev[0], params)
1591
1592 dev[0].request("SET sae_groups " + groups)
1593 dev[0].connect("test-sae", sae_password="secret", sae_password_id="pw id",
1594 key_mgmt="SAE", scan_freq="2412")
1595 dev[0].request("REMOVE_NETWORK all")
1596 dev[0].wait_disconnected()
1597
1598 # SAE Password Identifier element with the exact same length as the
1599 # optional Anti-Clogging Token field
1600 dev[0].connect("test-sae", sae_password="another secret",
1601 sae_password_id=29*'A',
1602 key_mgmt="SAE", scan_freq="2412")
1603 dev[0].request("REMOVE_NETWORK all")
1604 dev[0].wait_disconnected()
1605
1606 dev[0].connect("test-sae", sae_password="secret", sae_password_id="unknown",
1607 key_mgmt="SAE", scan_freq="2412", wait_connect=False)
1608
1609 ev = dev[0].wait_event(["CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER"],
1610 timeout=10)
1611 if ev is None:
1612 raise Exception("Unknown password identifier not reported")
1613 dev[0].request("REMOVE_NETWORK all")
1614
1615 def test_sae_password_id(dev, apdev):
1616 """SAE and password identifier"""
1617 run_sae_password_id(dev, apdev, "")
1618
1619 def test_sae_password_id_ecc(dev, apdev):
1620 """SAE and password identifier (ECC)"""
1621 run_sae_password_id(dev, apdev, "19")
1622
1623 def test_sae_password_id_ffc(dev, apdev):
1624 """SAE and password identifier (FFC)"""
1625 run_sae_password_id(dev, apdev, "15")
1626
1627 def test_sae_password_id_only(dev, apdev):
1628 """SAE and password identifier (exclusively)"""
1629 check_sae_capab(dev[0])
1630 params = hostapd.wpa2_params(ssid="test-sae")
1631 params['wpa_key_mgmt'] = 'SAE'
1632 params['sae_password'] = 'secret|id=pw id'
1633 hapd = hostapd.add_ap(apdev[0], params)
1634
1635 dev[0].request("SET sae_groups ")
1636 dev[0].connect("test-sae", sae_password="secret", sae_password_id="pw id",
1637 key_mgmt="SAE", scan_freq="2412")
1638
1639 def test_sae_forced_anti_clogging_pw_id(dev, apdev):
1640 """SAE anti clogging (forced and Password Identifier)"""
1641 check_sae_capab(dev[0])
1642 params = hostapd.wpa2_params(ssid="test-sae")
1643 params['wpa_key_mgmt'] = 'SAE'
1644 params['sae_anti_clogging_threshold'] = '0'
1645 params['sae_password'] = 'secret|id=' + 29*'A'
1646 hostapd.add_ap(apdev[0], params)
1647 for i in range(0, 2):
1648 dev[i].request("SET sae_groups ")
1649 dev[i].connect("test-sae", sae_password="secret",
1650 sae_password_id=29*'A', key_mgmt="SAE", scan_freq="2412")
1651
1652 def test_sae_reauth(dev, apdev):
1653 """SAE reauthentication"""
1654 check_sae_capab(dev[0])
1655 params = hostapd.wpa2_params(ssid="test-sae",
1656 passphrase="12345678")
1657 params['wpa_key_mgmt'] = 'SAE'
1658 params["ieee80211w"] = "2"
1659 hapd = hostapd.add_ap(apdev[0], params)
1660
1661 dev[0].request("SET sae_groups ")
1662 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1663 ieee80211w="2", scan_freq="2412")
1664
1665 hapd.set("ext_mgmt_frame_handling", "1")
1666 dev[0].request("DISCONNECT")
1667 dev[0].wait_disconnected(timeout=10)
1668 hapd.set("ext_mgmt_frame_handling", "0")
1669 dev[0].request("PMKSA_FLUSH")
1670 dev[0].request("REASSOCIATE")
1671 dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
1672
1673 def test_sae_anti_clogging_during_attack(dev, apdev):
1674 """SAE anti clogging during an attack"""
1675 try:
1676 run_sae_anti_clogging_during_attack(dev, apdev)
1677 finally:
1678 stop_monitor(apdev[1]["ifname"])
1679
1680 def build_sae_commit(bssid, addr, group=21, token=None):
1681 if group == 19:
1682 scalar = binascii.unhexlify("7332d3ebff24804005ccd8c56141e3ed8d84f40638aa31cd2fac11d4d2e89e7b")
1683 element = binascii.unhexlify("954d0f4457066bff3168376a1d7174f4e66620d1792406f613055b98513a7f03a538c13dfbaf2029e2adc6aa96aa0ddcf08ac44887b02f004b7f29b9dbf4b7d9")
1684 elif group == 21:
1685 scalar = binascii.unhexlify("001eec673111b902f5c8a61c8cb4c1c4793031aeea8c8c319410903bc64bcbaea134ab01c4e016d51436f5b5426f7e2af635759a3033fb4031ea79f89a62a3e2f828")
1686 element = binascii.unhexlify("00580eb4b448ea600ea277d5e66e4ed37db82bb04ac90442e9c3727489f366ba4b82f0a472d02caf4cdd142e96baea5915d71374660ee23acbaca38cf3fe8c5fb94b01abbc5278121635d7c06911c5dad8f18d516e1fbe296c179b7c87a1dddfab393337d3d215ed333dd396da6d8f20f798c60d054f1093c24d9c2d98e15c030cc375f0")
1687 pass
1688 frame = binascii.unhexlify("b0003a01")
1689 frame += bssid + addr + bssid
1690 frame += binascii.unhexlify("1000")
1691 auth_alg = 3
1692 transact = 1
1693 status = 0
1694 frame += struct.pack("<HHHH", auth_alg, transact, status, group)
1695 if token:
1696 frame += token
1697 frame += scalar + element
1698 return frame
1699
1700 def sae_rx_commit_token_req(sock, radiotap, send_two=False):
1701 msg = sock.recv(1500)
1702 ver, pad, len, present = struct.unpack('<BBHL', msg[0:8])
1703 frame = msg[len:]
1704 fc, duration = struct.unpack('<HH', frame[0:4])
1705 if fc != 0xb0:
1706 return False
1707 frame = frame[4:]
1708 da = frame[0:6]
1709 if da[0] != 0xf2:
1710 return False
1711 sa = frame[6:12]
1712 bssid = frame[12:18]
1713 body = frame[20:]
1714
1715 alg, seq, status, group = struct.unpack('<HHHH', body[0:8])
1716 if alg != 3 or seq != 1 or status != 76:
1717 return False
1718 token = body[8:]
1719
1720 frame = build_sae_commit(bssid, da, token=token)
1721 sock.send(radiotap + frame)
1722 if send_two:
1723 sock.send(radiotap + frame)
1724 return True
1725
1726 def run_sae_anti_clogging_during_attack(dev, apdev):
1727 check_sae_capab(dev[0])
1728 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1729 params['wpa_key_mgmt'] = 'SAE'
1730 params['sae_groups'] = '21'
1731 hapd = hostapd.add_ap(apdev[0], params)
1732
1733 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1734 dev[0].request("SET sae_groups 21")
1735 dev[1].scan_for_bss(hapd.own_addr(), freq=2412)
1736 dev[1].request("SET sae_groups 21")
1737
1738 sock = start_monitor(apdev[1]["ifname"])
1739 radiotap = radiotap_build()
1740
1741 bssid = binascii.unhexlify(hapd.own_addr().replace(':', ''))
1742 for i in range(16):
1743 addr = binascii.unhexlify("f2%010x" % i)
1744 frame = build_sae_commit(bssid, addr)
1745 sock.send(radiotap + frame)
1746 sock.send(radiotap + frame)
1747
1748 count = 0
1749 for i in range(150):
1750 if sae_rx_commit_token_req(sock, radiotap, send_two=True):
1751 count += 1
1752 logger.info("Number of token responses sent: %d" % count)
1753 if count < 10:
1754 raise Exception("Too few token responses seen: %d" % count)
1755
1756 for i in range(16):
1757 addr = binascii.unhexlify("f201%08x" % i)
1758 frame = build_sae_commit(bssid, addr)
1759 sock.send(radiotap + frame)
1760
1761 count = 0
1762 for i in range(150):
1763 if sae_rx_commit_token_req(sock, radiotap):
1764 count += 1
1765 if count == 10:
1766 break
1767 if count < 5:
1768 raise Exception("Too few token responses in second round: %d" % count)
1769
1770 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1771 scan_freq="2412", wait_connect=False)
1772 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE",
1773 scan_freq="2412", wait_connect=False)
1774
1775 count = 0
1776 connected0 = False
1777 connected1 = False
1778 for i in range(1000):
1779 if sae_rx_commit_token_req(sock, radiotap):
1780 count += 1
1781 addr = binascii.unhexlify("f202%08x" % i)
1782 frame = build_sae_commit(bssid, addr)
1783 sock.send(radiotap + frame)
1784 while dev[0].mon.pending():
1785 ev = dev[0].mon.recv()
1786 logger.debug("EV0: " + ev)
1787 if "CTRL-EVENT-CONNECTED" in ev:
1788 connected0 = True
1789 while dev[1].mon.pending():
1790 ev = dev[1].mon.recv()
1791 logger.debug("EV1: " + ev)
1792 if "CTRL-EVENT-CONNECTED" in ev:
1793 connected1 = True
1794 if connected0 and connected1:
1795 break
1796 time.sleep(0.00000001)
1797 if not connected0:
1798 raise Exception("Real station(0) did not get connected")
1799 if not connected1:
1800 raise Exception("Real station(1) did not get connected")
1801 if count < 1:
1802 raise Exception("Too few token responses in third round: %d" % count)
1803
1804 def test_sae_sync(dev, apdev):
1805 """SAE dot11RSNASAESync"""
1806 check_sae_capab(dev[0])
1807 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1808 params['wpa_key_mgmt'] = 'SAE'
1809 params['sae_sync'] = '1'
1810 hostapd.add_ap(apdev[0], params)
1811
1812 # TODO: More complete dot11RSNASAESync testing. For now, this is really only
1813 # checking that sae_sync config parameter is accepted.
1814 dev[0].request("SET sae_groups ")
1815 dev[1].request("SET sae_groups ")
1816 id = {}
1817 for i in range(0, 2):
1818 dev[i].scan(freq="2412")
1819 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
1820 scan_freq="2412", only_add_network=True)
1821 for i in range(0, 2):
1822 dev[i].select_network(id[i])
1823 for i in range(0, 2):
1824 dev[i].wait_connected(timeout=10)
1825
1826 def test_sae_confirm_immediate(dev, apdev):
1827 """SAE and AP sending Confirm message without waiting STA"""
1828 check_sae_capab(dev[0])
1829 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1830 params['wpa_key_mgmt'] = 'SAE'
1831 params['sae_confirm_immediate'] = '1'
1832 hapd = hostapd.add_ap(apdev[0], params)
1833
1834 dev[0].request("SET sae_groups ")
1835 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412")
1836
1837 def test_sae_confirm_immediate2(dev, apdev):
1838 """SAE and AP sending Confirm message without waiting STA (2)"""
1839 check_sae_capab(dev[0])
1840 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1841 params['wpa_key_mgmt'] = 'SAE'
1842 params['sae_confirm_immediate'] = '2'
1843 hapd = hostapd.add_ap(apdev[0], params)
1844
1845 dev[0].request("SET sae_groups ")
1846 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412")
1847
1848 def test_sae_pwe_group_19(dev, apdev):
1849 """SAE PWE derivation options with group 19"""
1850 run_sae_pwe_group(dev, apdev, 19)
1851
1852 def test_sae_pwe_group_20(dev, apdev):
1853 """SAE PWE derivation options with group 20"""
1854 run_sae_pwe_group(dev, apdev, 20)
1855
1856 def test_sae_pwe_group_21(dev, apdev):
1857 """SAE PWE derivation options with group 21"""
1858 run_sae_pwe_group(dev, apdev, 21)
1859
1860 def test_sae_pwe_group_25(dev, apdev):
1861 """SAE PWE derivation options with group 25"""
1862 run_sae_pwe_group(dev, apdev, 25)
1863
1864 def test_sae_pwe_group_28(dev, apdev):
1865 """SAE PWE derivation options with group 28"""
1866 run_sae_pwe_group(dev, apdev, 28)
1867
1868 def test_sae_pwe_group_29(dev, apdev):
1869 """SAE PWE derivation options with group 29"""
1870 run_sae_pwe_group(dev, apdev, 29)
1871
1872 def test_sae_pwe_group_30(dev, apdev):
1873 """SAE PWE derivation options with group 30"""
1874 run_sae_pwe_group(dev, apdev, 30)
1875
1876 def test_sae_pwe_group_1(dev, apdev):
1877 """SAE PWE derivation options with group 1"""
1878 run_sae_pwe_group(dev, apdev, 1)
1879
1880 def test_sae_pwe_group_2(dev, apdev):
1881 """SAE PWE derivation options with group 2"""
1882 run_sae_pwe_group(dev, apdev, 2)
1883
1884 def test_sae_pwe_group_5(dev, apdev):
1885 """SAE PWE derivation options with group 5"""
1886 run_sae_pwe_group(dev, apdev, 5)
1887
1888 def test_sae_pwe_group_14(dev, apdev):
1889 """SAE PWE derivation options with group 14"""
1890 run_sae_pwe_group(dev, apdev, 14)
1891
1892 def test_sae_pwe_group_15(dev, apdev):
1893 """SAE PWE derivation options with group 15"""
1894 run_sae_pwe_group(dev, apdev, 15)
1895
1896 def test_sae_pwe_group_16(dev, apdev):
1897 """SAE PWE derivation options with group 16"""
1898 run_sae_pwe_group(dev, apdev, 16)
1899
1900 def test_sae_pwe_group_22(dev, apdev):
1901 """SAE PWE derivation options with group 22"""
1902 run_sae_pwe_group(dev, apdev, 22)
1903
1904 def test_sae_pwe_group_23(dev, apdev):
1905 """SAE PWE derivation options with group 23"""
1906 run_sae_pwe_group(dev, apdev, 23)
1907
1908 def test_sae_pwe_group_24(dev, apdev):
1909 """SAE PWE derivation options with group 24"""
1910 run_sae_pwe_group(dev, apdev, 24)
1911
1912 def start_sae_pwe_ap(apdev, group, sae_pwe):
1913 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
1914 params['wpa_key_mgmt'] = 'SAE'
1915 params['sae_groups'] = str(group)
1916 params['sae_pwe'] = str(sae_pwe)
1917 return hostapd.add_ap(apdev, params)
1918
1919 def run_sae_pwe_group(dev, apdev, group):
1920 check_sae_capab(dev[0])
1921 tls = dev[0].request("GET tls_library")
1922 if group in [27, 28, 29, 30]:
1923 if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls:
1924 logger.info("Add Brainpool EC groups since OpenSSL is new enough")
1925 else:
1926 raise HwsimSkip("Brainpool curve not supported")
1927 start_sae_pwe_ap(apdev[0], group, 2)
1928 try:
1929 check_sae_pwe_group(dev[0], group, 0)
1930 check_sae_pwe_group(dev[0], group, 1)
1931 check_sae_pwe_group(dev[0], group, 2)
1932 finally:
1933 dev[0].set("sae_groups", "")
1934 dev[0].set("sae_pwe", "0")
1935
1936 def check_sae_pwe_group(dev, group, sae_pwe):
1937 dev.set("sae_groups", str(group))
1938 dev.set("sae_pwe", str(sae_pwe))
1939 dev.connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412")
1940 dev.request("REMOVE_NETWORK all")
1941 dev.wait_disconnected()
1942 dev.dump_monitor()
1943
1944 def test_sae_pwe_h2e_only_ap(dev, apdev):
1945 """SAE PWE derivation with H2E-only AP"""
1946 check_sae_capab(dev[0])
1947 start_sae_pwe_ap(apdev[0], 19, 1)
1948 try:
1949 check_sae_pwe_group(dev[0], 19, 1)
1950 check_sae_pwe_group(dev[0], 19, 2)
1951 finally:
1952 dev[0].set("sae_groups", "")
1953 dev[0].set("sae_pwe", "0")
1954
1955 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412",
1956 wait_connect=False)
1957 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
1958 if ev is None:
1959 raise Exception("No indication of mismatching network seen")
1960
1961 def test_sae_pwe_h2e_only_ap_sta_forcing_loop(dev, apdev):
1962 """SAE PWE derivation with H2E-only AP and STA forcing loop"""
1963 check_sae_capab(dev[0])
1964 start_sae_pwe_ap(apdev[0], 19, 1)
1965 dev[0].set("ignore_sae_h2e_only", "1")
1966 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412",
1967 wait_connect=False)
1968 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
1969 dev[0].request("DISCONNECT")
1970 if ev is None:
1971 raise Exception("No indication of temporary disabled network seen")
1972
1973 def test_sae_pwe_loop_only_ap(dev, apdev):
1974 """SAE PWE derivation with loop-only AP"""
1975 check_sae_capab(dev[0])
1976 start_sae_pwe_ap(apdev[0], 19, 0)
1977 try:
1978 check_sae_pwe_group(dev[0], 19, 0)
1979 check_sae_pwe_group(dev[0], 19, 2)
1980 dev[0].set("sae_pwe", "1")
1981 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
1982 scan_freq="2412", wait_connect=False)
1983 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
1984 if ev is None:
1985 raise Exception("No indication of mismatching network seen")
1986 finally:
1987 dev[0].set("sae_groups", "")
1988 dev[0].set("sae_pwe", "0")
1989
1990 def test_sae_h2e_rejected_groups(dev, apdev):
1991 """SAE H2E and rejected groups indication"""
1992 check_sae_capab(dev[0])
1993 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
1994 params['wpa_key_mgmt'] = 'SAE'
1995 params['sae_groups'] = "19"
1996 params['sae_pwe'] = "1"
1997 hapd = hostapd.add_ap(apdev[0], params)
1998 try:
1999 dev[0].set("sae_groups", "21 20 19")
2000 dev[0].set("sae_pwe", "1")
2001 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2002 scan_freq="2412")
2003 addr = dev[0].own_addr()
2004 hapd.wait_sta(addr)
2005 sta = hapd.get_sta(addr)
2006 if 'sae_rejected_groups' not in sta:
2007 raise Exception("No sae_rejected_groups")
2008 val = sta['sae_rejected_groups']
2009 if val != "21 20":
2010 raise Exception("Unexpected sae_rejected_groups value: " + val)
2011 finally:
2012 dev[0].set("sae_groups", "")
2013 dev[0].set("sae_pwe", "0")
2014
2015 def test_sae_h2e_rejected_groups_unexpected(dev, apdev):
2016 """SAE H2E and rejected groups indication (unexpected group)"""
2017 check_sae_capab(dev[0])
2018 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2019 params['wpa_key_mgmt'] = 'SAE'
2020 params['sae_groups'] = "19 20"
2021 params['sae_pwe'] = "1"
2022 hapd = hostapd.add_ap(apdev[0], params)
2023 try:
2024 dev[0].set("sae_groups", "21 19")
2025 dev[0].set("extra_sae_rejected_groups", "19")
2026 dev[0].set("sae_pwe", "1")
2027 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2028 scan_freq="2412", wait_connect=False)
2029 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2030 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
2031 dev[0].request("DISCONNECT")
2032 if ev is None:
2033 raise Exception("No indication of temporary disabled network seen")
2034 if "CTRL-EVENT-CONNECTED" in ev:
2035 raise Exception("Unexpected connection")
2036 finally:
2037 dev[0].set("sae_groups", "")
2038 dev[0].set("sae_pwe", "0")
2039
2040 def test_sae_h2e_password_id(dev, apdev):
2041 """SAE H2E and password identifier"""
2042 check_sae_capab(dev[0])
2043 params = hostapd.wpa2_params(ssid="test-sae")
2044 params['wpa_key_mgmt'] = 'SAE'
2045 params['sae_pwe'] = '1'
2046 params['sae_password'] = 'secret|id=pw id'
2047 hapd = hostapd.add_ap(apdev[0], params)
2048
2049 try:
2050 dev[0].request("SET sae_groups ")
2051 dev[0].set("sae_pwe", "1")
2052 dev[0].connect("test-sae", sae_password="secret",
2053 sae_password_id="pw id",
2054 key_mgmt="SAE", scan_freq="2412")
2055 finally:
2056 dev[0].set("sae_groups", "")
2057 dev[0].set("sae_pwe", "0")
2058
2059 def test_sae_pwe_in_psk_ap(dev, apdev):
2060 """sae_pwe parameter in PSK-only-AP"""
2061 params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678")
2062 params['sae_pwe'] = '1'
2063 hapd = hostapd.add_ap(apdev[0], params)
2064
2065 dev[0].connect("test-psk", psk="12345678", scan_freq="2412")
2066
2067 def test_sae_auth_restart(dev, apdev):
2068 """SAE and authentication restarts with H2E/looping"""
2069 check_sae_capab(dev[0])
2070 params = hostapd.wpa2_params(ssid="test-sae")
2071 params['wpa_key_mgmt'] = 'SAE'
2072 params['sae_pwe'] = '2'
2073 params['sae_password'] = 'secret|id=pw id'
2074 hapd = hostapd.add_ap(apdev[0], params)
2075
2076 try:
2077 dev[0].request("SET sae_groups ")
2078 for pwe in [1, 0, 1]:
2079 dev[0].set("sae_pwe", str(pwe))
2080 dev[0].connect("test-sae", sae_password="secret",
2081 sae_password_id="pw id",
2082 key_mgmt="SAE", scan_freq="2412")
2083 # Disconnect without hostapd removing the STA entry so that the
2084 # following SAE authentication instance starts with an existing
2085 # STA entry that has maintained some SAE state.
2086 hapd.set("ext_mgmt_frame_handling", "1")
2087 dev[0].request("REMOVE_NETWORK all")
2088 req = hapd.mgmt_rx()
2089 dev[0].wait_disconnected()
2090 dev[0].dump_monitor()
2091 hapd.set("ext_mgmt_frame_handling", "0")
2092 finally:
2093 dev[0].set("sae_groups", "")
2094 dev[0].set("sae_pwe", "0")
2095
2096 def test_sae_h2e_rsnxe_mismatch(dev, apdev):
2097 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4"""
2098 check_sae_capab(dev[0])
2099 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2100 params['wpa_key_mgmt'] = 'SAE'
2101 params['sae_pwe'] = "1"
2102 hapd = hostapd.add_ap(apdev[0], params)
2103 try:
2104 dev[0].set("sae_groups", "19")
2105 dev[0].set("sae_pwe", "1")
2106 for rsnxe in ["F40100", "F400", ""]:
2107 dev[0].set("rsnxe_override_eapol", rsnxe)
2108 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2109 scan_freq="2412", wait_connect=False)
2110 ev = dev[0].wait_event(["Associated with"], timeout=10)
2111 if ev is None:
2112 raise Exception("No indication of association seen")
2113 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2114 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2115 dev[0].request("REMOVE_NETWORK all")
2116 if ev is None:
2117 raise Exception("No disconnection seen")
2118 if "CTRL-EVENT-DISCONNECTED" not in ev:
2119 raise Exception("Unexpected connection")
2120 dev[0].dump_monitor()
2121 finally:
2122 dev[0].set("sae_groups", "")
2123 dev[0].set("sae_pwe", "0")
2124
2125 def test_sae_h2e_rsnxe_mismatch_retries(dev, apdev):
2126 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 retries"""
2127 check_sae_capab(dev[0])
2128 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2129 params['wpa_key_mgmt'] = 'SAE'
2130 params['sae_pwe'] = "1"
2131 hapd = hostapd.add_ap(apdev[0], params)
2132 try:
2133 dev[0].set("sae_groups", "19")
2134 dev[0].set("sae_pwe", "1")
2135 rsnxe = "F40100"
2136 dev[0].set("rsnxe_override_eapol", rsnxe)
2137 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2138 scan_freq="2412", wait_connect=False)
2139 ev = dev[0].wait_event(["Associated with"], timeout=10)
2140 if ev is None:
2141 raise Exception("No indication of association seen")
2142 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2143 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2144 if ev is None:
2145 raise Exception("No disconnection seen")
2146 if "CTRL-EVENT-DISCONNECTED" not in ev:
2147 raise Exception("Unexpected connection")
2148
2149 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2150 "CTRL-EVENT-DISCONNECTED"], timeout=10)
2151 if ev is None:
2152 raise Exception("No disconnection seen (2)")
2153 if "CTRL-EVENT-DISCONNECTED" not in ev:
2154 raise Exception("Unexpected connection (2)")
2155
2156 dev[0].dump_monitor()
2157 finally:
2158 dev[0].set("sae_groups", "")
2159 dev[0].set("sae_pwe", "0")
2160
2161 def test_sae_h2e_rsnxe_mismatch_assoc(dev, apdev):
2162 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 (assoc)"""
2163 check_sae_capab(dev[0])
2164 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2165 params['wpa_key_mgmt'] = 'SAE'
2166 params['sae_pwe'] = "1"
2167 hapd = hostapd.add_ap(apdev[0], params)
2168 try:
2169 dev[0].set("sae_groups", "19")
2170 dev[0].set("sae_pwe", "1")
2171 for rsnxe in ["F40100", "F400", ""]:
2172 dev[0].set("rsnxe_override_assoc", rsnxe)
2173 dev[0].set("rsnxe_override_eapol", "F40120")
2174 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2175 scan_freq="2412", wait_connect=False)
2176 ev = dev[0].wait_event(["Associated with"], timeout=10)
2177 if ev is None:
2178 raise Exception("No indication of association seen")
2179 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2180 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2181 dev[0].request("REMOVE_NETWORK all")
2182 if ev is None:
2183 raise Exception("No disconnection seen")
2184 if "CTRL-EVENT-DISCONNECTED" not in ev:
2185 raise Exception("Unexpected connection")
2186 dev[0].dump_monitor()
2187 finally:
2188 dev[0].set("sae_groups", "")
2189 dev[0].set("sae_pwe", "0")
2190
2191 def test_sae_h2e_rsnxe_mismatch_ap(dev, apdev):
2192 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
2193 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F40100")
2194
2195 def test_sae_h2e_rsnxe_mismatch_ap2(dev, apdev):
2196 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
2197 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F400")
2198
2199 def run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, rsnxe):
2200 check_sae_capab(dev[0])
2201 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2202 params['wpa_key_mgmt'] = 'SAE'
2203 params['sae_pwe'] = "1"
2204 params['rsnxe_override_eapol'] = rsnxe
2205 hapd = hostapd.add_ap(apdev[0], params)
2206 try:
2207 dev[0].set("sae_groups", "19")
2208 dev[0].set("sae_pwe", "1")
2209 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2210 scan_freq="2412", wait_connect=False)
2211 ev = dev[0].wait_event(["Associated with"], timeout=10)
2212 if ev is None:
2213 raise Exception("No indication of association seen")
2214 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2215 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2216 dev[0].request("REMOVE_NETWORK all")
2217 if ev is None:
2218 raise Exception("No disconnection seen")
2219 if "CTRL-EVENT-DISCONNECTED" not in ev:
2220 raise Exception("Unexpected connection")
2221 finally:
2222 dev[0].set("sae_groups", "")
2223 dev[0].set("sae_pwe", "0")
2224
2225 def test_sae_forced_anti_clogging_h2e(dev, apdev):
2226 """SAE anti clogging (forced, H2E)"""
2227 check_sae_capab(dev[0])
2228 check_sae_capab(dev[1])
2229 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
2230 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
2231 params['sae_pwe'] = "1"
2232 params['sae_anti_clogging_threshold'] = '0'
2233 hostapd.add_ap(apdev[0], params)
2234 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
2235 try:
2236 for i in range(2):
2237 dev[i].request("SET sae_groups ")
2238 dev[i].set("sae_pwe", "1")
2239 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
2240 scan_freq="2412")
2241 finally:
2242 for i in range(2):
2243 dev[i].set("sae_pwe", "0")
2244
2245 def test_sae_forced_anti_clogging_h2e_loop(dev, apdev):
2246 """SAE anti clogging (forced, H2E + loop)"""
2247 check_sae_capab(dev[0])
2248 check_sae_capab(dev[1])
2249 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
2250 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
2251 params['sae_pwe'] = "2"
2252 params['sae_anti_clogging_threshold'] = '0'
2253 hostapd.add_ap(apdev[0], params)
2254 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
2255 try:
2256 for i in range(2):
2257 dev[i].request("SET sae_groups ")
2258 dev[i].set("sae_pwe", "2")
2259 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
2260 scan_freq="2412")
2261 finally:
2262 for i in range(2):
2263 dev[i].set("sae_pwe", "0")