]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_sae.py
tests: SAE Password Identifier with unexpected PWE derivation
[thirdparty/hostap.git] / tests / hwsim / test_sae.py
CommitLineData
1640a2e4 1# Test cases for SAE
4c0af8ad 2# Copyright (c) 2013-2020, Jouni Malinen <j@w1.fi>
1640a2e4
JM
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
9fd6804d 7from remotehost import remote_compatible
5b3c40a6
JM
8import binascii
9import os
1640a2e4 10import time
1640a2e4
JM
11import logging
12logger = logging.getLogger()
e43352ff
JM
13import socket
14import struct
15import subprocess
1640a2e4
JM
16
17import hwsim_utils
18import hostapd
33822240 19from wpasupplicant import WpaSupplicant
8030e2b5 20from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger, start_monitor, stop_monitor, radiotap_build
5b3c40a6 21from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations
1640a2e4 22
4c0af8ad
JM
23def check_sae_capab(dev):
24 if "SAE" not in dev.get_capability("auth_alg"):
25 raise HwsimSkip("SAE not supported")
26
9fd6804d 27@remote_compatible
1640a2e4
JM
28def test_sae(dev, apdev):
29 """SAE with default group"""
4c0af8ad 30 check_sae_capab(dev[0])
1640a2e4
JM
31 params = hostapd.wpa2_params(ssid="test-sae",
32 passphrase="12345678")
33 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 34 hapd = hostapd.add_ap(apdev[0], params)
65038313
JM
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)
1640a2e4
JM
38
39 dev[0].request("SET sae_groups ")
40 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
41 scan_freq="2412")
6478f437 42 hapd.wait_sta()
1640a2e4
JM
43 if dev[0].get_status_field('sae_group') != '19':
44 raise Exception("Expected default SAE group not used")
d463c556
JM
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'])
1640a2e4 50
7b28c408
JM
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
6478f437
JM
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
9fd6804d 60@remote_compatible
33dcced5
JM
61def test_sae_password_ecc(dev, apdev):
62 """SAE with number of different passwords (ECC)"""
4c0af8ad 63 check_sae_capab(dev[0])
33dcced5
JM
64 params = hostapd.wpa2_params(ssid="test-sae",
65 passphrase="12345678")
66 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 67 hapd = hostapd.add_ap(apdev[0], params)
33dcced5
JM
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
9fd6804d 79@remote_compatible
33dcced5
JM
80def test_sae_password_ffc(dev, apdev):
81 """SAE with number of different passwords (FFC)"""
4c0af8ad 82 check_sae_capab(dev[0])
33dcced5
JM
83 params = hostapd.wpa2_params(ssid="test-sae",
84 passphrase="12345678")
85 params['wpa_key_mgmt'] = 'SAE'
8e607b1b 86 params['sae_groups'] = '15'
8b8a1864 87 hapd = hostapd.add_ap(apdev[0], params)
33dcced5 88
8e607b1b 89 dev[0].request("SET sae_groups 15")
33dcced5
JM
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
9fd6804d 99@remote_compatible
19d3a6e3
JM
100def test_sae_pmksa_caching(dev, apdev):
101 """SAE and PMKSA caching"""
b6fe6e8b
JM
102 run_sae_pmksa_caching(dev, apdev)
103
104@remote_compatible
105def 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
113def run_sae_pmksa_caching(dev, apdev):
4c0af8ad 114 check_sae_capab(dev[0])
19d3a6e3
JM
115 params = hostapd.wpa2_params(ssid="test-sae",
116 passphrase="12345678")
117 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 118 hapd = hostapd.add_ap(apdev[0], params)
19d3a6e3
JM
119
120 dev[0].request("SET sae_groups ")
121 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
122 scan_freq="2412")
fab49f61 123 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
7cc9a81f
JM
124 if ev is None:
125 raise Exception("No connection event received from hostapd")
61ec2353
JM
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")
19d3a6e3 129 dev[0].request("DISCONNECT")
7cc9a81f 130 dev[0].wait_disconnected()
19d3a6e3 131 dev[0].request("RECONNECT")
5f35a5e2 132 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
19d3a6e3
JM
133 if dev[0].get_status_field('sae_group') is not None:
134 raise Exception("SAE group claimed to have been used")
61ec2353
JM
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")
19d3a6e3 138
9fd6804d 139@remote_compatible
19d3a6e3
JM
140def test_sae_pmksa_caching_disabled(dev, apdev):
141 """SAE and PMKSA caching disabled"""
4c0af8ad 142 check_sae_capab(dev[0])
19d3a6e3
JM
143 params = hostapd.wpa2_params(ssid="test-sae",
144 passphrase="12345678")
145 params['wpa_key_mgmt'] = 'SAE'
146 params['disable_pmksa_caching'] = '1'
8b8a1864 147 hapd = hostapd.add_ap(apdev[0], params)
19d3a6e3
JM
148
149 dev[0].request("SET sae_groups ")
150 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
151 scan_freq="2412")
fab49f61 152 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
7cc9a81f
JM
153 if ev is None:
154 raise Exception("No connection event received from hostapd")
19d3a6e3 155 dev[0].request("DISCONNECT")
7cc9a81f 156 dev[0].wait_disconnected()
19d3a6e3 157 dev[0].request("RECONNECT")
5f35a5e2 158 dev[0].wait_connected(timeout=15, error="Reconnect timed out")
19d3a6e3
JM
159 if dev[0].get_status_field('sae_group') != '19':
160 raise Exception("Expected default SAE group not used")
161
1640a2e4
JM
162def test_sae_groups(dev, apdev):
163 """SAE with all supported groups"""
4c0af8ad 164 check_sae_capab(dev[0])
b1f487cb
JM
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.
fab49f61 169 sae_groups = [19, 25, 26, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24]
9e286d5e 170 tls = dev[0].request("GET tls_library")
a053ab95 171 if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls:
9e286d5e 172 logger.info("Add Brainpool EC groups since OpenSSL is new enough")
fab49f61
JM
173 sae_groups += [27, 28, 29, 30]
174 heavy_groups = [14, 15, 16]
e57e3f12 175 suitable_groups = [15, 16, 17, 18, 19, 20, 21]
1640a2e4
JM
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)
48e999e9 181 hapd = hostapd.add_ap(apdev[0], params)
1640a2e4
JM
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",
b1f487cb
JM
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:
a68d1792
JM
198 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
199 if ev is None:
fab49f61 200 if "BoringSSL" in tls and int(g) in [25]:
a68d1792
JM
201 logger.info("Ignore connection failure with group " + g + " with BoringSSL")
202 dev[0].remove_network(id)
203 dev[0].dump_monitor()
204 continue
8e607b1b
JM
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
a68d1792 210 raise Exception("Connection timed out with group " + g)
1640a2e4
JM
211 if dev[0].get_status_field('sae_group') != g:
212 raise Exception("Expected SAE group not used")
48e999e9
JM
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)
1640a2e4 218 dev[0].remove_network(id)
b1f487cb
JM
219 dev[0].wait_disconnected()
220 dev[0].dump_monitor()
1640a2e4 221
9fd6804d 222@remote_compatible
1640a2e4
JM
223def test_sae_group_nego(dev, apdev):
224 """SAE group negotiation"""
4c0af8ad 225 check_sae_capab(dev[0])
1640a2e4
JM
226 params = hostapd.wpa2_params(ssid="test-sae-group-nego",
227 passphrase="12345678")
228 params['wpa_key_mgmt'] = 'SAE'
229 params['sae_groups'] = '19'
8b8a1864 230 hostapd.add_ap(apdev[0], params)
1640a2e4
JM
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")
a6cf5cd6 237
914d8eca
JM
238def test_sae_group_nego_no_match(dev, apdev):
239 """SAE group negotiation (no match)"""
4c0af8ad 240 check_sae_capab(dev[0])
914d8eca
JM
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)
fab49f61 251 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
914d8eca
JM
252 dev[0].request("REMOVE_NETWORK all")
253 if ev is None:
254 raise Exception("Network profile disabling not reported")
255
9fd6804d 256@remote_compatible
a6cf5cd6
JM
257def test_sae_anti_clogging(dev, apdev):
258 """SAE anti clogging"""
4c0af8ad
JM
259 check_sae_capab(dev[0])
260 check_sae_capab(dev[1])
a6cf5cd6
JM
261 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
262 params['wpa_key_mgmt'] = 'SAE'
263 params['sae_anti_clogging_threshold'] = '1'
8b8a1864 264 hostapd.add_ap(apdev[0], params)
a6cf5cd6
JM
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):
5f35a5e2 276 dev[i].wait_connected(timeout=10)
d05ff960
JM
277
278def test_sae_forced_anti_clogging(dev, apdev):
279 """SAE anti clogging (forced)"""
4c0af8ad
JM
280 check_sae_capab(dev[0])
281 check_sae_capab(dev[1])
d05ff960 282 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
fd4709ff 283 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
d05ff960 284 params['sae_anti_clogging_threshold'] = '0'
8b8a1864 285 hostapd.add_ap(apdev[0], params)
fd4709ff 286 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
d05ff960
JM
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
292def test_sae_mixed(dev, apdev):
293 """Mixed SAE and non-SAE network"""
4c0af8ad
JM
294 check_sae_capab(dev[0])
295 check_sae_capab(dev[1])
d05ff960
JM
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'
61ec2353 299 hapd = hostapd.add_ap(apdev[0], params)
d05ff960
JM
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")
61ec2353
JM
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")
acb63c75 312
fa617ee6
JM
313def test_sae_and_psk(dev, apdev):
314 """SAE and PSK enabled in network profile"""
4c0af8ad 315 check_sae_capab(dev[0])
fa617ee6
JM
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
324def test_sae_and_psk2(dev, apdev):
325 """SAE and PSK enabled in network profile (use PSK)"""
4c0af8ad 326 check_sae_capab(dev[0])
fa617ee6
JM
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
5c8df74f
JM
334def test_sae_mixed_mfp(dev, apdev):
335 """Mixed SAE and non-SAE network and MFP required with SAE"""
4c0af8ad
JM
336 check_sae_capab(dev[0])
337 check_sae_capab(dev[1])
5c8df74f
JM
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
c481e1cb
JM
366def test_sae_mfp(dev, apdev):
367 """SAE and MFP enabled without sae_require_mfp"""
4c0af8ad
JM
368 check_sae_capab(dev[0])
369 check_sae_capab(dev[1])
c481e1cb
JM
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
9fd6804d 383@remote_compatible
acb63c75
JM
384def test_sae_missing_password(dev, apdev):
385 """SAE and missing password"""
4c0af8ad 386 check_sae_capab(dev[0])
acb63c75
JM
387 params = hostapd.wpa2_params(ssid="test-sae",
388 passphrase="12345678")
389 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 390 hapd = hostapd.add_ap(apdev[0], params)
acb63c75
JM
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")
5b3c40a6
JM
399
400
401def test_sae_key_lifetime_in_memory(dev, apdev, params):
402 """SAE and key lifetime in memory"""
4c0af8ad 403 check_sae_capab(dev[0])
5b3c40a6
JM
404 password = "5ad144a7c1f5a5503baa6fa01dabc15b1843e8c01662d78d16b70b5cd23cf8b"
405 p = hostapd.wpa2_params(ssid="test-sae", passphrase=password)
406 p['wpa_key_mgmt'] = 'SAE'
8b8a1864 407 hapd = hostapd.add_ap(apdev[0], p)
5b3c40a6
JM
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
8e416cec
JM
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.
54f2cae2 418 time.sleep(1)
8e416cec 419 dev[0].ping()
b3361e5d 420 password = password.encode()
5b3c40a6
JM
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:
81e787b7 469 raise HwsimSkip("Password not found while associated")
5b3c40a6 470 if pmk not in buf:
81e787b7 471 raise HwsimSkip("PMK not found while associated")
5b3c40a6
JM
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")
b74f82a4
JM
476 #if tk in buf:
477 # raise Exception("TK found from memory")
5b3c40a6
JM
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")
6db556b2
JM
493 if gtk in buf:
494 get_key_locations(buf, gtk, "GTK")
5b3c40a6
JM
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)")
eb6d3532 523
9fd6804d 524@remote_compatible
eb6d3532
JM
525def test_sae_oom_wpas(dev, apdev):
526 """SAE and OOM in wpa_supplicant"""
4c0af8ad 527 check_sae_capab(dev[0])
eb6d3532
JM
528 params = hostapd.wpa2_params(ssid="test-sae",
529 passphrase="12345678")
530 params['wpa_key_mgmt'] = 'SAE'
8e607b1b 531 params['sae_groups'] = '19 25 26 20'
8b8a1864 532 hapd = hostapd.add_ap(apdev[0], params)
eb6d3532 533
8e607b1b 534 dev[0].request("SET sae_groups 20")
eb6d3532
JM
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")
5527a391 545
2fd44db7
JM
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
9fd6804d 569@remote_compatible
5527a391
JM
570def test_sae_proto_ecc(dev, apdev):
571 """SAE protocol testing (ECC)"""
4c0af8ad 572 check_sae_capab(dev[0])
5527a391
JM
573 params = hostapd.wpa2_params(ssid="test-sae",
574 passphrase="12345678")
575 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 576 hapd = hostapd.add_ap(apdev[0], params)
5527a391
JM
577 bssid = apdev[0]['bssid']
578
579 dev[0].request("SET sae_groups 19")
580
fab49f61
JM
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")]
5527a391
JM
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
9fd6804d 667@remote_compatible
5527a391
JM
668def test_sae_proto_ffc(dev, apdev):
669 """SAE protocol testing (FFC)"""
4c0af8ad 670 check_sae_capab(dev[0])
5527a391
JM
671 params = hostapd.wpa2_params(ssid="test-sae",
672 passphrase="12345678")
673 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 674 hapd = hostapd.add_ap(apdev[0], params)
5527a391
JM
675 bssid = apdev[0]['bssid']
676
677 dev[0].request("SET sae_groups 2")
678
fab49f61
JM
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)]
5527a391
JM
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
46746fc1
JM
747
748def test_sae_proto_commit_delayed(dev, apdev):
749 """SAE protocol testing - Commit delayed"""
4c0af8ad 750 check_sae_capab(dev[0])
46746fc1
JM
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
824def test_sae_proto_commit_replay(dev, apdev):
825 """SAE protocol testing - Commit replay"""
4c0af8ad 826 check_sae_capab(dev[0])
46746fc1
JM
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
2d0a04a8
JM
907def test_sae_proto_confirm_replay(dev, apdev):
908 """SAE protocol testing - Confirm replay"""
4c0af8ad 909 check_sae_capab(dev[0])
2d0a04a8
JM
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
2d0a04a8 934 hapd.dump_monitor()
54c58f29 935 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2d0a04a8
JM
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()
54c58f29 949 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2d0a04a8
JM
950
951 logger.info("Replay Confirm")
54c58f29 952 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2d0a04a8
JM
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()
54c58f29 966 hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
2d0a04a8
JM
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
7a92dbd7
JM
980def 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
2b70a82c
JM
1004def 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
1027def 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
9fd6804d 1047@remote_compatible
5527a391
JM
1048def test_sae_no_ffc_by_default(dev, apdev):
1049 """SAE and default groups rejecting FFC"""
4c0af8ad 1050 check_sae_capab(dev[0])
5527a391
JM
1051 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1052 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 1053 hapd = hostapd.add_ap(apdev[0], params)
5527a391 1054
8e607b1b 1055 dev[0].request("SET sae_groups 15")
5527a391
JM
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")
939527b5
JM
1065
1066def sae_reflection_attack(apdev, dev, group):
4c0af8ad 1067 check_sae_capab(dev)
939527b5
JM
1068 params = hostapd.wpa2_params(ssid="test-sae",
1069 passphrase="no-knowledge-of-passphrase")
1070 params['wpa_key_mgmt'] = 'SAE'
afc26df2 1071 hapd = hostapd.add_ap(apdev, params)
939527b5
JM
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
9fd6804d 1106@remote_compatible
939527b5
JM
1107def test_sae_reflection_attack_ecc(dev, apdev):
1108 """SAE reflection attack (ECC)"""
1109 sae_reflection_attack(apdev[0], dev[0], 19)
1110
9fd6804d 1111@remote_compatible
939527b5
JM
1112def test_sae_reflection_attack_ffc(dev, apdev):
1113 """SAE reflection attack (FFC)"""
8e607b1b 1114 sae_reflection_attack(apdev[0], dev[0], 15)
1965e196 1115
1342c47a 1116def sae_reflection_attack_internal(apdev, dev, group):
4c0af8ad 1117 check_sae_capab(dev)
1342c47a
JM
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)
8e607b1b
JM
1129 ev = dev.wait_event(["SME: Trying to authenticate"], timeout=10)
1130 if ev is None:
1131 raise Exception("No authentication attempt seen")
1342c47a
JM
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
1137def 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
1142def test_sae_reflection_attack_ffc_internal(dev, apdev):
1143 """SAE reflection attack (FFC) - internal"""
8e607b1b 1144 sae_reflection_attack_internal(apdev[0], dev[0], 15)
1342c47a 1145
cd06e266
JM
1146@remote_compatible
1147def test_sae_commit_override(dev, apdev):
1148 """SAE commit override (hostapd)"""
4c0af8ad 1149 check_sae_capab(dev[0])
cd06e266
JM
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
eea62048
JM
1162@remote_compatible
1163def test_sae_commit_override2(dev, apdev):
1164 """SAE commit override (wpa_supplicant)"""
4c0af8ad 1165 check_sae_capab(dev[0])
eea62048
JM
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
faddd025
JM
1178def test_sae_commit_invalid_scalar_element_ap(dev, apdev):
1179 """SAE commit invalid scalar/element from AP"""
4c0af8ad 1180 check_sae_capab(dev[0])
faddd025
JM
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
1193def test_sae_commit_invalid_element_ap(dev, apdev):
1194 """SAE commit invalid element from AP"""
4c0af8ad 1195 check_sae_capab(dev[0])
faddd025
JM
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
1208def test_sae_commit_invalid_scalar_element_sta(dev, apdev):
1209 """SAE commit invalid scalar/element from STA"""
4c0af8ad 1210 check_sae_capab(dev[0])
faddd025
JM
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
1223def test_sae_commit_invalid_element_sta(dev, apdev):
1224 """SAE commit invalid element from STA"""
4c0af8ad 1225 check_sae_capab(dev[0])
faddd025
JM
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
9fd6804d 1238@remote_compatible
1965e196
JM
1239def test_sae_anti_clogging_proto(dev, apdev):
1240 """SAE anti clogging protocol testing"""
4c0af8ad 1241 check_sae_capab(dev[0])
1965e196
JM
1242 params = hostapd.wpa2_params(ssid="test-sae",
1243 passphrase="no-knowledge-of-passphrase")
1244 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 1245 hapd = hostapd.add_ap(apdev[0], params)
1965e196
JM
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")
10ba4ae4 1279
9fd6804d 1280@remote_compatible
10ba4ae4
JM
1281def test_sae_no_random(dev, apdev):
1282 """SAE and no random numbers available"""
4c0af8ad 1283 check_sae_capab(dev[0])
10ba4ae4
JM
1284 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1285 params['wpa_key_mgmt'] = 'SAE'
8b8a1864 1286 hapd = hostapd.add_ap(apdev[0], params)
10ba4ae4
JM
1287
1288 dev[0].request("SET sae_groups ")
fbd671ac 1289 tests = [(1, "os_get_random;sae_derive_pwe_ecc")]
10ba4ae4
JM
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()
4f6985de 1296
9fd6804d 1297@remote_compatible
4f6985de
JM
1298def test_sae_pwe_failure(dev, apdev):
1299 """SAE and pwe failure"""
4c0af8ad 1300 check_sae_capab(dev[0])
4f6985de
JM
1301 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1302 params['wpa_key_mgmt'] = 'SAE'
8e607b1b 1303 params['sae_groups'] = '19 15'
8b8a1864 1304 hapd = hostapd.add_ap(apdev[0], params)
4f6985de
JM
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()
51761ba2
JM
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()
4f6985de 1317
8e607b1b 1318 dev[0].request("SET sae_groups 15")
4f6985de
JM
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
8e607b1b 1325 dev[0].request("SET sae_groups 15")
4f6985de
JM
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()
51761ba2 1336
9fd6804d 1337@remote_compatible
51761ba2
JM
1338def test_sae_bignum_failure(dev, apdev):
1339 """SAE and bignum failure"""
4c0af8ad 1340 check_sae_capab(dev[0])
51761ba2
JM
1341 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1342 params['wpa_key_mgmt'] = 'SAE'
8e607b1b 1343 params['sae_groups'] = '19 15 22'
8b8a1864 1344 hapd = hostapd.add_ap(apdev[0], params)
51761ba2
JM
1345
1346 dev[0].request("SET sae_groups 19")
a5dbddbf
JM
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"),
fab49f61
JM
1353 (1, "crypto_bignum_init_set;sae_test_pwd_seed_ecc"),
1354 (1, "crypto_ec_point_compute_y_sqr;sae_test_pwd_seed_ecc"),
fab49f61
JM
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"),
a5dbddbf 1367 (1, "crypto_bignum_legendre;dragonfly_get_random_qr_qnr"),
fab49f61
JM
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")]
51761ba2
JM
1373 for count, func in tests:
1374 with fail_test(dev[0], count, func):
e96fa197 1375 hapd.request("NOTE STA failure testing %d:%s" % (count, func))
51761ba2
JM
1376 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1377 scan_freq="2412", wait_connect=False)
7bcb6391 1378 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1)
51761ba2 1379 dev[0].request("REMOVE_NETWORK all")
e96fa197
JM
1380 dev[0].dump_monitor()
1381 hapd.dump_monitor()
51761ba2 1382
8e607b1b 1383 dev[0].request("SET sae_groups 15")
fab49f61
JM
1384 tests = [(1, "crypto_bignum_init_set;sae_set_group"),
1385 (2, "crypto_bignum_init_set;sae_set_group"),
fbd671ac
JM
1386 (1, "crypto_bignum_init;sae_derive_commit"),
1387 (2, "crypto_bignum_init;sae_derive_commit"),
fab49f61
JM
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")]
51761ba2
JM
1403 for count, func in tests:
1404 with fail_test(dev[0], count, func):
e96fa197 1405 hapd.request("NOTE STA failure testing %d:%s" % (count, func))
51761ba2
JM
1406 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1407 scan_freq="2412", wait_connect=False)
7bcb6391 1408 wait_fail_trigger(dev[0], "GET_FAIL", timeout=0.1)
51761ba2 1409 dev[0].request("REMOVE_NETWORK all")
e96fa197
JM
1410 dev[0].dump_monitor()
1411 hapd.dump_monitor()
51761ba2 1412
8e607b1b
JM
1413def test_sae_bignum_failure_unsafe_group(dev, apdev):
1414 """SAE and bignum failure unsafe group"""
4c0af8ad 1415 check_sae_capab(dev[0])
8e607b1b
JM
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
51761ba2 1421 dev[0].request("SET sae_groups 22")
fab49f61
JM
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")]
51761ba2
JM
1425 for count, func in tests:
1426 with fail_test(dev[0], count, func):
e96fa197 1427 hapd.request("NOTE STA failure testing %d:%s" % (count, func))
51761ba2
JM
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")
e96fa197
JM
1432 dev[0].dump_monitor()
1433 hapd.dump_monitor()
28be769b
JM
1434
1435def test_sae_invalid_anti_clogging_token_req(dev, apdev):
1436 """SAE and invalid anti-clogging token request"""
4c0af8ad 1437 check_sae_capab(dev[0])
28be769b
JM
1438 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1439 params['wpa_key_mgmt'] = 'SAE'
77f52098
JM
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'
28be769b
JM
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:
77f52098 1455 raise Exception("No authentication attempt seen (1)")
28be769b
JM
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)
77f52098
JM
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)
28be769b
JM
1481
1482 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1483 if ev is None:
77f52098 1484 raise Exception("No authentication attempt seen (2)")
28be769b
JM
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)
77f52098
JM
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)
28be769b
JM
1510
1511 ev = dev[0].wait_event(["SME: Trying to authenticate"])
1512 if ev is None:
77f52098 1513 raise Exception("No authentication attempt seen (3)")
28be769b
JM
1514 dev[0].dump_monitor()
1515
1516 dev[0].request("DISCONNECT")
606ef7d3
JM
1517
1518def test_sae_password(dev, apdev):
1519 """SAE and sae_password in hostapd configuration"""
4c0af8ad 1520 check_sae_capab(dev[0])
606ef7d3
JM
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
1535def test_sae_password_short(dev, apdev):
1536 """SAE and short password"""
4c0af8ad 1537 check_sae_capab(dev[0])
606ef7d3
JM
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
1547def test_sae_password_long(dev, apdev):
1548 """SAE and long password"""
4c0af8ad 1549 check_sae_capab(dev[0])
606ef7d3
JM
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")
33822240
JM
1558
1559def 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")
4c0af8ad 1563 check_sae_capab(wpas)
33822240
JM
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")
9a0ae89d 1578
be5e7a07 1579def run_sae_password_id(dev, apdev, groups=None):
4c0af8ad 1580 check_sae_capab(dev[0])
9a0ae89d
JM
1581 params = hostapd.wpa2_params(ssid="test-sae")
1582 params['wpa_key_mgmt'] = 'SAE'
be5e7a07
JM
1583 if groups:
1584 params['sae_groups'] = groups
1585 else:
1586 groups = ""
fab49f61
JM
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']
9a0ae89d
JM
1590 hapd = hostapd.add_ap(apdev[0], params)
1591
be5e7a07 1592 dev[0].request("SET sae_groups " + groups)
9a0ae89d
JM
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
be5e7a07
JM
1615def test_sae_password_id(dev, apdev):
1616 """SAE and password identifier"""
1617 run_sae_password_id(dev, apdev, "")
1618
1619def test_sae_password_id_ecc(dev, apdev):
1620 """SAE and password identifier (ECC)"""
1621 run_sae_password_id(dev, apdev, "19")
1622
1623def test_sae_password_id_ffc(dev, apdev):
1624 """SAE and password identifier (FFC)"""
8e607b1b 1625 run_sae_password_id(dev, apdev, "15")
be5e7a07 1626
6de2a809
JM
1627def test_sae_password_id_only(dev, apdev):
1628 """SAE and password identifier (exclusively)"""
4c0af8ad 1629 check_sae_capab(dev[0])
6de2a809
JM
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
c90822a5
JM
1639def test_sae_password_id_pwe_looping(dev, apdev):
1640 """SAE and password identifier with forced PWE looping)"""
1641 check_sae_capab(dev[0])
1642 params = hostapd.wpa2_params(ssid="test-sae")
1643 params['wpa_key_mgmt'] = 'SAE'
1644 params['sae_password'] = 'secret|id=pw id'
1645 params['sae_pwe'] = "3"
1646 hapd = hostapd.add_ap(apdev[0], params)
1647
1648 dev[0].request("SET sae_groups ")
1649 try:
1650 dev[0].set("sae_pwe", "3")
1651 dev[0].connect("test-sae", sae_password="secret",
1652 sae_password_id="pw id",
1653 key_mgmt="SAE", scan_freq="2412")
1654 finally:
1655 dev[0].set("sae_pwe", "0")
1656
1657def test_sae_password_id_pwe_check_ap(dev, apdev):
1658 """SAE and password identifier with STA using unexpected PWE derivation)"""
1659 check_sae_capab(dev[0])
1660 params = hostapd.wpa2_params(ssid="test-sae")
1661 params['wpa_key_mgmt'] = 'SAE'
1662 params['sae_password'] = 'secret|id=pw id'
1663 hapd = hostapd.add_ap(apdev[0], params)
1664
1665 dev[0].request("SET sae_groups ")
1666 try:
1667 dev[0].set("sae_pwe", "3")
1668 dev[0].connect("test-sae", sae_password="secret",
1669 sae_password_id="pw id",
1670 key_mgmt="SAE", scan_freq="2412", wait_connect=False)
1671 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1672 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
1673 if ev is None or "CTRL-EVENT-SSID-TEMP-DISABLED" not in ev:
1674 raise Exception("Connection failure not reported")
1675 finally:
1676 dev[0].set("sae_pwe", "0")
1677
1678def test_sae_password_id_pwe_check_sta(dev, apdev):
1679 """SAE and password identifier with AP using unexpected PWE derivation)"""
1680 check_sae_capab(dev[0])
1681 params = hostapd.wpa2_params(ssid="test-sae")
1682 params['wpa_key_mgmt'] = 'SAE'
1683 params['sae_pwe'] = "3"
1684 params['sae_password'] = 'secret|id=pw id'
1685 hapd = hostapd.add_ap(apdev[0], params)
1686
1687 dev[0].request("SET sae_groups ")
1688 dev[0].connect("test-sae", sae_password="secret",
1689 sae_password_id="pw id",
1690 key_mgmt="SAE", scan_freq="2412", wait_connect=False)
1691 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1692 "CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
1693 if ev is None or "CTRL-EVENT-NETWORK-NOT-FOUND" not in ev:
1694 raise Exception("Connection failure not reported")
1695
9a0ae89d
JM
1696def test_sae_forced_anti_clogging_pw_id(dev, apdev):
1697 """SAE anti clogging (forced and Password Identifier)"""
4c0af8ad 1698 check_sae_capab(dev[0])
9a0ae89d
JM
1699 params = hostapd.wpa2_params(ssid="test-sae")
1700 params['wpa_key_mgmt'] = 'SAE'
1701 params['sae_anti_clogging_threshold'] = '0'
1702 params['sae_password'] = 'secret|id=' + 29*'A'
1703 hostapd.add_ap(apdev[0], params)
1704 for i in range(0, 2):
1705 dev[i].request("SET sae_groups ")
1706 dev[i].connect("test-sae", sae_password="secret",
1707 sae_password_id=29*'A', key_mgmt="SAE", scan_freq="2412")
fe102801
JM
1708
1709def test_sae_reauth(dev, apdev):
1710 """SAE reauthentication"""
4c0af8ad 1711 check_sae_capab(dev[0])
fe102801
JM
1712 params = hostapd.wpa2_params(ssid="test-sae",
1713 passphrase="12345678")
1714 params['wpa_key_mgmt'] = 'SAE'
1715 params["ieee80211w"] = "2"
1716 hapd = hostapd.add_ap(apdev[0], params)
1717
1718 dev[0].request("SET sae_groups ")
1719 id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1720 ieee80211w="2", scan_freq="2412")
1721
1722 hapd.set("ext_mgmt_frame_handling", "1")
1723 dev[0].request("DISCONNECT")
1724 dev[0].wait_disconnected(timeout=10)
1725 hapd.set("ext_mgmt_frame_handling", "0")
1726 dev[0].request("PMKSA_FLUSH")
1727 dev[0].request("REASSOCIATE")
1728 dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
e43352ff
JM
1729
1730def test_sae_anti_clogging_during_attack(dev, apdev):
1731 """SAE anti clogging during an attack"""
1732 try:
1733 run_sae_anti_clogging_during_attack(dev, apdev)
1734 finally:
3507968f 1735 stop_monitor(apdev[1]["ifname"])
e43352ff
JM
1736
1737def build_sae_commit(bssid, addr, group=21, token=None):
1738 if group == 19:
1739 scalar = binascii.unhexlify("7332d3ebff24804005ccd8c56141e3ed8d84f40638aa31cd2fac11d4d2e89e7b")
1740 element = binascii.unhexlify("954d0f4457066bff3168376a1d7174f4e66620d1792406f613055b98513a7f03a538c13dfbaf2029e2adc6aa96aa0ddcf08ac44887b02f004b7f29b9dbf4b7d9")
1741 elif group == 21:
1742 scalar = binascii.unhexlify("001eec673111b902f5c8a61c8cb4c1c4793031aeea8c8c319410903bc64bcbaea134ab01c4e016d51436f5b5426f7e2af635759a3033fb4031ea79f89a62a3e2f828")
1743 element = binascii.unhexlify("00580eb4b448ea600ea277d5e66e4ed37db82bb04ac90442e9c3727489f366ba4b82f0a472d02caf4cdd142e96baea5915d71374660ee23acbaca38cf3fe8c5fb94b01abbc5278121635d7c06911c5dad8f18d516e1fbe296c179b7c87a1dddfab393337d3d215ed333dd396da6d8f20f798c60d054f1093c24d9c2d98e15c030cc375f0")
1744 pass
1745 frame = binascii.unhexlify("b0003a01")
1746 frame += bssid + addr + bssid
1747 frame += binascii.unhexlify("1000")
1748 auth_alg = 3
1749 transact = 1
1750 status = 0
1751 frame += struct.pack("<HHHH", auth_alg, transact, status, group)
1752 if token:
1753 frame += token
1754 frame += scalar + element
1755 return frame
1756
1757def sae_rx_commit_token_req(sock, radiotap, send_two=False):
1758 msg = sock.recv(1500)
fab49f61 1759 ver, pad, len, present = struct.unpack('<BBHL', msg[0:8])
e43352ff 1760 frame = msg[len:]
fab49f61 1761 fc, duration = struct.unpack('<HH', frame[0:4])
e43352ff
JM
1762 if fc != 0xb0:
1763 return False
1764 frame = frame[4:]
1765 da = frame[0:6]
1766 if da[0] != 0xf2:
1767 return False
1768 sa = frame[6:12]
1769 bssid = frame[12:18]
1770 body = frame[20:]
1771
fab49f61 1772 alg, seq, status, group = struct.unpack('<HHHH', body[0:8])
e43352ff
JM
1773 if alg != 3 or seq != 1 or status != 76:
1774 return False
1775 token = body[8:]
1776
1777 frame = build_sae_commit(bssid, da, token=token)
1778 sock.send(radiotap + frame)
1779 if send_two:
1780 sock.send(radiotap + frame)
1781 return True
1782
1783def run_sae_anti_clogging_during_attack(dev, apdev):
4c0af8ad 1784 check_sae_capab(dev[0])
e43352ff
JM
1785 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1786 params['wpa_key_mgmt'] = 'SAE'
1787 params['sae_groups'] = '21'
1788 hapd = hostapd.add_ap(apdev[0], params)
1789
1790 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1791 dev[0].request("SET sae_groups 21")
1792 dev[1].scan_for_bss(hapd.own_addr(), freq=2412)
1793 dev[1].request("SET sae_groups 21")
1794
3507968f
JM
1795 sock = start_monitor(apdev[1]["ifname"])
1796 radiotap = radiotap_build()
e43352ff
JM
1797
1798 bssid = binascii.unhexlify(hapd.own_addr().replace(':', ''))
1799 for i in range(16):
1800 addr = binascii.unhexlify("f2%010x" % i)
1801 frame = build_sae_commit(bssid, addr)
1802 sock.send(radiotap + frame)
1803 sock.send(radiotap + frame)
1804
1805 count = 0
1806 for i in range(150):
1807 if sae_rx_commit_token_req(sock, radiotap, send_two=True):
1808 count += 1
1809 logger.info("Number of token responses sent: %d" % count)
1810 if count < 10:
1811 raise Exception("Too few token responses seen: %d" % count)
1812
1813 for i in range(16):
1814 addr = binascii.unhexlify("f201%08x" % i)
1815 frame = build_sae_commit(bssid, addr)
1816 sock.send(radiotap + frame)
1817
1818 count = 0
1819 for i in range(150):
1820 if sae_rx_commit_token_req(sock, radiotap):
1821 count += 1
1822 if count == 10:
1823 break
a1983aa7 1824 if count < 5:
e43352ff
JM
1825 raise Exception("Too few token responses in second round: %d" % count)
1826
1827 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
1828 scan_freq="2412", wait_connect=False)
1829 dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE",
1830 scan_freq="2412", wait_connect=False)
1831
1832 count = 0
1833 connected0 = False
1834 connected1 = False
1835 for i in range(1000):
1836 if sae_rx_commit_token_req(sock, radiotap):
1837 count += 1
1838 addr = binascii.unhexlify("f202%08x" % i)
1839 frame = build_sae_commit(bssid, addr)
1840 sock.send(radiotap + frame)
1841 while dev[0].mon.pending():
1842 ev = dev[0].mon.recv()
1843 logger.debug("EV0: " + ev)
1844 if "CTRL-EVENT-CONNECTED" in ev:
1845 connected0 = True
1846 while dev[1].mon.pending():
1847 ev = dev[1].mon.recv()
1848 logger.debug("EV1: " + ev)
1849 if "CTRL-EVENT-CONNECTED" in ev:
1850 connected1 = True
1851 if connected0 and connected1:
1852 break
1df79115 1853 time.sleep(0.00000001)
e43352ff
JM
1854 if not connected0:
1855 raise Exception("Real station(0) did not get connected")
1856 if not connected1:
1857 raise Exception("Real station(1) did not get connected")
1858 if count < 1:
1859 raise Exception("Too few token responses in third round: %d" % count)
ed98d4d7
JM
1860
1861def test_sae_sync(dev, apdev):
1862 """SAE dot11RSNASAESync"""
4c0af8ad 1863 check_sae_capab(dev[0])
ed98d4d7
JM
1864 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1865 params['wpa_key_mgmt'] = 'SAE'
1866 params['sae_sync'] = '1'
1867 hostapd.add_ap(apdev[0], params)
1868
1869 # TODO: More complete dot11RSNASAESync testing. For now, this is really only
1870 # checking that sae_sync config parameter is accepted.
1871 dev[0].request("SET sae_groups ")
1872 dev[1].request("SET sae_groups ")
1873 id = {}
1874 for i in range(0, 2):
1875 dev[i].scan(freq="2412")
1876 id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
1877 scan_freq="2412", only_add_network=True)
1878 for i in range(0, 2):
1879 dev[i].select_network(id[i])
1880 for i in range(0, 2):
1881 dev[i].wait_connected(timeout=10)
8a9658db
JM
1882
1883def test_sae_confirm_immediate(dev, apdev):
1884 """SAE and AP sending Confirm message without waiting STA"""
4c0af8ad 1885 check_sae_capab(dev[0])
8a9658db
JM
1886 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1887 params['wpa_key_mgmt'] = 'SAE'
1888 params['sae_confirm_immediate'] = '1'
1889 hapd = hostapd.add_ap(apdev[0], params)
1890
1891 dev[0].request("SET sae_groups ")
1892 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412")
3fa701b5 1893
283be365
JM
1894def test_sae_confirm_immediate2(dev, apdev):
1895 """SAE and AP sending Confirm message without waiting STA (2)"""
4c0af8ad 1896 check_sae_capab(dev[0])
283be365
JM
1897 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
1898 params['wpa_key_mgmt'] = 'SAE'
1899 params['sae_confirm_immediate'] = '2'
1900 hapd = hostapd.add_ap(apdev[0], params)
1901
1902 dev[0].request("SET sae_groups ")
1903 dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412")
1904
3fa701b5
JM
1905def test_sae_pwe_group_19(dev, apdev):
1906 """SAE PWE derivation options with group 19"""
1907 run_sae_pwe_group(dev, apdev, 19)
1908
1909def test_sae_pwe_group_20(dev, apdev):
1910 """SAE PWE derivation options with group 20"""
1911 run_sae_pwe_group(dev, apdev, 20)
1912
1913def test_sae_pwe_group_21(dev, apdev):
1914 """SAE PWE derivation options with group 21"""
1915 run_sae_pwe_group(dev, apdev, 21)
1916
1917def test_sae_pwe_group_25(dev, apdev):
71e276f9
JM
1918 """SAE PWE derivation options with group 25"""
1919 run_sae_pwe_group(dev, apdev, 25)
3fa701b5 1920
3fa701b5 1921def test_sae_pwe_group_28(dev, apdev):
71e276f9
JM
1922 """SAE PWE derivation options with group 28"""
1923 run_sae_pwe_group(dev, apdev, 28)
3fa701b5
JM
1924
1925def test_sae_pwe_group_29(dev, apdev):
71e276f9
JM
1926 """SAE PWE derivation options with group 29"""
1927 run_sae_pwe_group(dev, apdev, 29)
3fa701b5
JM
1928
1929def test_sae_pwe_group_30(dev, apdev):
71e276f9
JM
1930 """SAE PWE derivation options with group 30"""
1931 run_sae_pwe_group(dev, apdev, 30)
3fa701b5
JM
1932
1933def test_sae_pwe_group_1(dev, apdev):
1934 """SAE PWE derivation options with group 1"""
1935 run_sae_pwe_group(dev, apdev, 1)
1936
1937def test_sae_pwe_group_2(dev, apdev):
1938 """SAE PWE derivation options with group 2"""
1939 run_sae_pwe_group(dev, apdev, 2)
1940
1941def test_sae_pwe_group_5(dev, apdev):
1942 """SAE PWE derivation options with group 5"""
1943 run_sae_pwe_group(dev, apdev, 5)
1944
1945def test_sae_pwe_group_14(dev, apdev):
1946 """SAE PWE derivation options with group 14"""
1947 run_sae_pwe_group(dev, apdev, 14)
1948
1949def test_sae_pwe_group_15(dev, apdev):
1950 """SAE PWE derivation options with group 15"""
1951 run_sae_pwe_group(dev, apdev, 15)
1952
1953def test_sae_pwe_group_16(dev, apdev):
1954 """SAE PWE derivation options with group 16"""
1955 run_sae_pwe_group(dev, apdev, 16)
1956
1957def test_sae_pwe_group_22(dev, apdev):
1958 """SAE PWE derivation options with group 22"""
1959 run_sae_pwe_group(dev, apdev, 22)
1960
1961def test_sae_pwe_group_23(dev, apdev):
1962 """SAE PWE derivation options with group 23"""
1963 run_sae_pwe_group(dev, apdev, 23)
1964
1965def test_sae_pwe_group_24(dev, apdev):
1966 """SAE PWE derivation options with group 24"""
1967 run_sae_pwe_group(dev, apdev, 24)
1968
1969def start_sae_pwe_ap(apdev, group, sae_pwe):
1970 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
1971 params['wpa_key_mgmt'] = 'SAE'
1972 params['sae_groups'] = str(group)
1973 params['sae_pwe'] = str(sae_pwe)
1974 return hostapd.add_ap(apdev, params)
1975
1976def run_sae_pwe_group(dev, apdev, group):
4c0af8ad 1977 check_sae_capab(dev[0])
3fa701b5
JM
1978 tls = dev[0].request("GET tls_library")
1979 if group in [27, 28, 29, 30]:
1980 if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls:
1981 logger.info("Add Brainpool EC groups since OpenSSL is new enough")
1982 else:
1983 raise HwsimSkip("Brainpool curve not supported")
1984 start_sae_pwe_ap(apdev[0], group, 2)
1985 try:
1986 check_sae_pwe_group(dev[0], group, 0)
1987 check_sae_pwe_group(dev[0], group, 1)
1988 check_sae_pwe_group(dev[0], group, 2)
1989 finally:
1990 dev[0].set("sae_groups", "")
1991 dev[0].set("sae_pwe", "0")
1992
1993def check_sae_pwe_group(dev, group, sae_pwe):
1994 dev.set("sae_groups", str(group))
1995 dev.set("sae_pwe", str(sae_pwe))
1996 dev.connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412")
1997 dev.request("REMOVE_NETWORK all")
1998 dev.wait_disconnected()
1999 dev.dump_monitor()
2000
2001def test_sae_pwe_h2e_only_ap(dev, apdev):
2002 """SAE PWE derivation with H2E-only AP"""
4c0af8ad 2003 check_sae_capab(dev[0])
3fa701b5
JM
2004 start_sae_pwe_ap(apdev[0], 19, 1)
2005 try:
2006 check_sae_pwe_group(dev[0], 19, 1)
2007 check_sae_pwe_group(dev[0], 19, 2)
2008 finally:
2009 dev[0].set("sae_groups", "")
2010 dev[0].set("sae_pwe", "0")
2011
2012 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412",
2013 wait_connect=False)
2014 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
2015 if ev is None:
2016 raise Exception("No indication of mismatching network seen")
2017
b1905c7d
JM
2018def test_sae_pwe_h2e_only_ap_sta_forcing_loop(dev, apdev):
2019 """SAE PWE derivation with H2E-only AP and STA forcing loop"""
4c0af8ad 2020 check_sae_capab(dev[0])
b1905c7d
JM
2021 start_sae_pwe_ap(apdev[0], 19, 1)
2022 dev[0].set("ignore_sae_h2e_only", "1")
2023 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412",
2024 wait_connect=False)
2025 ev = dev[0].wait_event(["CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
2026 dev[0].request("DISCONNECT")
2027 if ev is None:
2028 raise Exception("No indication of temporary disabled network seen")
2029
3fa701b5
JM
2030def test_sae_pwe_loop_only_ap(dev, apdev):
2031 """SAE PWE derivation with loop-only AP"""
4c0af8ad 2032 check_sae_capab(dev[0])
3fa701b5
JM
2033 start_sae_pwe_ap(apdev[0], 19, 0)
2034 try:
2035 check_sae_pwe_group(dev[0], 19, 0)
2036 check_sae_pwe_group(dev[0], 19, 2)
2037 dev[0].set("sae_pwe", "1")
2038 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2039 scan_freq="2412", wait_connect=False)
2040 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
2041 if ev is None:
2042 raise Exception("No indication of mismatching network seen")
2043 finally:
2044 dev[0].set("sae_groups", "")
2045 dev[0].set("sae_pwe", "0")
2046
2047def test_sae_h2e_rejected_groups(dev, apdev):
2048 """SAE H2E and rejected groups indication"""
4c0af8ad 2049 check_sae_capab(dev[0])
3fa701b5
JM
2050 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2051 params['wpa_key_mgmt'] = 'SAE'
2052 params['sae_groups'] = "19"
2053 params['sae_pwe'] = "1"
2054 hapd = hostapd.add_ap(apdev[0], params)
2055 try:
2056 dev[0].set("sae_groups", "21 20 19")
2057 dev[0].set("sae_pwe", "1")
2058 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2059 scan_freq="2412")
fb3ef06d
JM
2060 addr = dev[0].own_addr()
2061 hapd.wait_sta(addr)
2062 sta = hapd.get_sta(addr)
2063 if 'sae_rejected_groups' not in sta:
2064 raise Exception("No sae_rejected_groups")
2065 val = sta['sae_rejected_groups']
2066 if val != "21 20":
2067 raise Exception("Unexpected sae_rejected_groups value: " + val)
3fa701b5
JM
2068 finally:
2069 dev[0].set("sae_groups", "")
2070 dev[0].set("sae_pwe", "0")
2071
90d84bc5
JM
2072def test_sae_h2e_rejected_groups_unexpected(dev, apdev):
2073 """SAE H2E and rejected groups indication (unexpected group)"""
4c0af8ad 2074 check_sae_capab(dev[0])
90d84bc5
JM
2075 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2076 params['wpa_key_mgmt'] = 'SAE'
2077 params['sae_groups'] = "19 20"
2078 params['sae_pwe'] = "1"
2079 hapd = hostapd.add_ap(apdev[0], params)
2080 try:
2081 dev[0].set("sae_groups", "21 19")
2082 dev[0].set("extra_sae_rejected_groups", "19")
2083 dev[0].set("sae_pwe", "1")
2084 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2085 scan_freq="2412", wait_connect=False)
2086 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2087 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=10)
2088 dev[0].request("DISCONNECT")
2089 if ev is None:
2090 raise Exception("No indication of temporary disabled network seen")
2091 if "CTRL-EVENT-CONNECTED" in ev:
2092 raise Exception("Unexpected connection")
2093 finally:
2094 dev[0].set("sae_groups", "")
2095 dev[0].set("sae_pwe", "0")
2096
3fa701b5
JM
2097def test_sae_h2e_password_id(dev, apdev):
2098 """SAE H2E and password identifier"""
4c0af8ad 2099 check_sae_capab(dev[0])
3fa701b5
JM
2100 params = hostapd.wpa2_params(ssid="test-sae")
2101 params['wpa_key_mgmt'] = 'SAE'
2102 params['sae_pwe'] = '1'
2103 params['sae_password'] = 'secret|id=pw id'
2104 hapd = hostapd.add_ap(apdev[0], params)
2105
2106 try:
2107 dev[0].request("SET sae_groups ")
2108 dev[0].set("sae_pwe", "1")
2109 dev[0].connect("test-sae", sae_password="secret",
2110 sae_password_id="pw id",
2111 key_mgmt="SAE", scan_freq="2412")
2112 finally:
2113 dev[0].set("sae_groups", "")
2114 dev[0].set("sae_pwe", "0")
01b2cd64 2115
dd8eb44e
JM
2116def test_sae_pwe_in_psk_ap(dev, apdev):
2117 """sae_pwe parameter in PSK-only-AP"""
2118 params = hostapd.wpa2_params(ssid="test-psk", passphrase="12345678")
2119 params['sae_pwe'] = '1'
2120 hapd = hostapd.add_ap(apdev[0], params)
2121
2122 dev[0].connect("test-psk", psk="12345678", scan_freq="2412")
2123
01b2cd64
JM
2124def test_sae_auth_restart(dev, apdev):
2125 """SAE and authentication restarts with H2E/looping"""
4c0af8ad 2126 check_sae_capab(dev[0])
01b2cd64
JM
2127 params = hostapd.wpa2_params(ssid="test-sae")
2128 params['wpa_key_mgmt'] = 'SAE'
2129 params['sae_pwe'] = '2'
2130 params['sae_password'] = 'secret|id=pw id'
2131 hapd = hostapd.add_ap(apdev[0], params)
2132
2133 try:
2134 dev[0].request("SET sae_groups ")
2135 for pwe in [1, 0, 1]:
2136 dev[0].set("sae_pwe", str(pwe))
2137 dev[0].connect("test-sae", sae_password="secret",
2138 sae_password_id="pw id",
2139 key_mgmt="SAE", scan_freq="2412")
2140 # Disconnect without hostapd removing the STA entry so that the
2141 # following SAE authentication instance starts with an existing
2142 # STA entry that has maintained some SAE state.
2143 hapd.set("ext_mgmt_frame_handling", "1")
2144 dev[0].request("REMOVE_NETWORK all")
2145 req = hapd.mgmt_rx()
2146 dev[0].wait_disconnected()
2147 dev[0].dump_monitor()
2148 hapd.set("ext_mgmt_frame_handling", "0")
2149 finally:
2150 dev[0].set("sae_groups", "")
2151 dev[0].set("sae_pwe", "0")
250db2ab
JM
2152
2153def test_sae_h2e_rsnxe_mismatch(dev, apdev):
2154 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4"""
4c0af8ad 2155 check_sae_capab(dev[0])
250db2ab
JM
2156 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2157 params['wpa_key_mgmt'] = 'SAE'
2158 params['sae_pwe'] = "1"
2159 hapd = hostapd.add_ap(apdev[0], params)
2160 try:
2161 dev[0].set("sae_groups", "19")
2162 dev[0].set("sae_pwe", "1")
2163 for rsnxe in ["F40100", "F400", ""]:
2164 dev[0].set("rsnxe_override_eapol", rsnxe)
2165 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2166 scan_freq="2412", wait_connect=False)
2167 ev = dev[0].wait_event(["Associated with"], timeout=10)
2168 if ev is None:
2169 raise Exception("No indication of association seen")
2170 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2171 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2172 dev[0].request("REMOVE_NETWORK all")
2173 if ev is None:
2174 raise Exception("No disconnection seen")
2175 if "CTRL-EVENT-DISCONNECTED" not in ev:
2176 raise Exception("Unexpected connection")
2177 dev[0].dump_monitor()
2178 finally:
2179 dev[0].set("sae_groups", "")
2180 dev[0].set("sae_pwe", "0")
2181
06540f23
JM
2182def test_sae_h2e_rsnxe_mismatch_retries(dev, apdev):
2183 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 retries"""
4c0af8ad 2184 check_sae_capab(dev[0])
06540f23
JM
2185 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2186 params['wpa_key_mgmt'] = 'SAE'
2187 params['sae_pwe'] = "1"
2188 hapd = hostapd.add_ap(apdev[0], params)
2189 try:
2190 dev[0].set("sae_groups", "19")
2191 dev[0].set("sae_pwe", "1")
2192 rsnxe = "F40100"
2193 dev[0].set("rsnxe_override_eapol", rsnxe)
2194 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2195 scan_freq="2412", wait_connect=False)
2196 ev = dev[0].wait_event(["Associated with"], timeout=10)
2197 if ev is None:
2198 raise Exception("No indication of association seen")
2199 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2200 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2201 if ev is None:
2202 raise Exception("No disconnection seen")
2203 if "CTRL-EVENT-DISCONNECTED" not in ev:
2204 raise Exception("Unexpected connection")
2205
2206 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2207 "CTRL-EVENT-DISCONNECTED"], timeout=10)
2208 if ev is None:
2209 raise Exception("No disconnection seen (2)")
2210 if "CTRL-EVENT-DISCONNECTED" not in ev:
2211 raise Exception("Unexpected connection (2)")
2212
2213 dev[0].dump_monitor()
2214 finally:
2215 dev[0].set("sae_groups", "")
2216 dev[0].set("sae_pwe", "0")
2217
250db2ab
JM
2218def test_sae_h2e_rsnxe_mismatch_assoc(dev, apdev):
2219 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4 (assoc)"""
4c0af8ad 2220 check_sae_capab(dev[0])
250db2ab
JM
2221 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2222 params['wpa_key_mgmt'] = 'SAE'
2223 params['sae_pwe'] = "1"
2224 hapd = hostapd.add_ap(apdev[0], params)
2225 try:
2226 dev[0].set("sae_groups", "19")
2227 dev[0].set("sae_pwe", "1")
2228 for rsnxe in ["F40100", "F400", ""]:
2229 dev[0].set("rsnxe_override_assoc", rsnxe)
2230 dev[0].set("rsnxe_override_eapol", "F40120")
2231 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2232 scan_freq="2412", wait_connect=False)
2233 ev = dev[0].wait_event(["Associated with"], timeout=10)
2234 if ev is None:
2235 raise Exception("No indication of association seen")
2236 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2237 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2238 dev[0].request("REMOVE_NETWORK all")
2239 if ev is None:
2240 raise Exception("No disconnection seen")
2241 if "CTRL-EVENT-DISCONNECTED" not in ev:
2242 raise Exception("Unexpected connection")
2243 dev[0].dump_monitor()
2244 finally:
2245 dev[0].set("sae_groups", "")
2246 dev[0].set("sae_pwe", "0")
63585099
JM
2247
2248def test_sae_h2e_rsnxe_mismatch_ap(dev, apdev):
2249 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
2250 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F40100")
2251
2252def test_sae_h2e_rsnxe_mismatch_ap2(dev, apdev):
2253 """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
2254 run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F400")
2255
2256def run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, rsnxe):
4c0af8ad 2257 check_sae_capab(dev[0])
63585099
JM
2258 params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
2259 params['wpa_key_mgmt'] = 'SAE'
2260 params['sae_pwe'] = "1"
2261 params['rsnxe_override_eapol'] = rsnxe
2262 hapd = hostapd.add_ap(apdev[0], params)
2263 try:
2264 dev[0].set("sae_groups", "19")
2265 dev[0].set("sae_pwe", "1")
2266 dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
2267 scan_freq="2412", wait_connect=False)
2268 ev = dev[0].wait_event(["Associated with"], timeout=10)
2269 if ev is None:
2270 raise Exception("No indication of association seen")
2271 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2272 "CTRL-EVENT-DISCONNECTED"], timeout=5)
2273 dev[0].request("REMOVE_NETWORK all")
2274 if ev is None:
2275 raise Exception("No disconnection seen")
2276 if "CTRL-EVENT-DISCONNECTED" not in ev:
2277 raise Exception("Unexpected connection")
2278 finally:
2279 dev[0].set("sae_groups", "")
2280 dev[0].set("sae_pwe", "0")
6ce883de
JM
2281
2282def test_sae_forced_anti_clogging_h2e(dev, apdev):
2283 """SAE anti clogging (forced, H2E)"""
4c0af8ad
JM
2284 check_sae_capab(dev[0])
2285 check_sae_capab(dev[1])
6ce883de
JM
2286 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
2287 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
2288 params['sae_pwe'] = "1"
2289 params['sae_anti_clogging_threshold'] = '0'
2290 hostapd.add_ap(apdev[0], params)
2291 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
2292 try:
2293 for i in range(2):
2294 dev[i].request("SET sae_groups ")
2295 dev[i].set("sae_pwe", "1")
2296 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
2297 scan_freq="2412")
2298 finally:
2299 for i in range(2):
2300 dev[i].set("sae_pwe", "0")
3ecaddd6
JM
2301
2302def test_sae_forced_anti_clogging_h2e_loop(dev, apdev):
2303 """SAE anti clogging (forced, H2E + loop)"""
2304 check_sae_capab(dev[0])
2305 check_sae_capab(dev[1])
2306 params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
2307 params['wpa_key_mgmt'] = 'SAE WPA-PSK'
2308 params['sae_pwe'] = "2"
2309 params['sae_anti_clogging_threshold'] = '0'
2310 hostapd.add_ap(apdev[0], params)
2311 dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
2312 try:
2313 for i in range(2):
2314 dev[i].request("SET sae_groups ")
2315 dev[i].set("sae_pwe", "2")
2316 dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
2317 scan_freq="2412")
2318 finally:
2319 for i in range(2):
2320 dev[i].set("sae_pwe", "0")