1# EAP Re-authentication Protocol (ERP) tests
2# Copyright (c) 2014-2019, Jouni Malinen <j@w1.fi>
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7import binascii
8import logging
9logger = logging.getLogger()
10import os
11import time
12
13import hostapd
14from utils import *
15from test_ap_eap import int_eap_server_params, check_tls13_support
16from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations
17
18def test_erp_initiate_reauth_start(dev, apdev):
19    """Authenticator sending EAP-Initiate/Re-auth-Start, but ERP disabled on peer"""
20    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
21    params['erp_send_reauth_start'] = '1'
22    params['erp_domain'] = 'example.com'
23    hapd = hostapd.add_ap(apdev[0], params)
24
25    dev[0].request("ERP_FLUSH")
26    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
27                   eap="PAX", identity="pax.user@example.com",
28                   password_hex="0123456789abcdef0123456789abcdef",
29                   scan_freq="2412")
30
31def test_erp_enabled_on_server(dev, apdev):
32    """ERP enabled on internal EAP server, but disabled on peer"""
33    params = int_eap_server_params()
34    params['erp_send_reauth_start'] = '1'
35    params['erp_domain'] = 'example.com'
36    params['eap_server_erp'] = '1'
37    hapd = hostapd.add_ap(apdev[0], params)
38
39    dev[0].request("ERP_FLUSH")
40    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
41                   eap="PAX", identity="pax.user@example.com",
42                   password_hex="0123456789abcdef0123456789abcdef",
43                   scan_freq="2412")
44
45def test_erp(dev, apdev):
46    """ERP enabled on server and peer"""
47    check_erp_capa(dev[0])
48    params = int_eap_server_params()
49    params['erp_send_reauth_start'] = '1'
50    params['erp_domain'] = 'example.com'
51    params['eap_server_erp'] = '1'
52    params['disable_pmksa_caching'] = '1'
53    hapd = hostapd.add_ap(apdev[0], params)
54
55    dev[0].request("ERP_FLUSH")
56    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
57                   eap="PSK", identity="psk.user@example.com",
58                   password_hex="0123456789abcdef0123456789abcdef",
59                   erp="1", scan_freq="2412")
60    for i in range(3):
61        dev[0].request("DISCONNECT")
62        dev[0].wait_disconnected(timeout=15)
63        dev[0].request("RECONNECT")
64        ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
65        if ev is None:
66            raise Exception("EAP success timed out")
67        if "EAP re-authentication completed successfully" not in ev:
68            raise Exception("Did not use ERP")
69        dev[0].wait_connected(timeout=15, error="Reconnection timed out")
70
71def test_erp_server_no_match(dev, apdev):
72    """ERP enabled on server and peer, but server has no key match"""
73    check_erp_capa(dev[0])
74    params = int_eap_server_params()
75    params['erp_send_reauth_start'] = '1'
76    params['erp_domain'] = 'example.com'
77    params['eap_server_erp'] = '1'
78    params['disable_pmksa_caching'] = '1'
79    hapd = hostapd.add_ap(apdev[0], params)
80
81    dev[0].request("ERP_FLUSH")
82    id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
83                        eap="PSK", identity="psk.user@example.com",
84                        password_hex="0123456789abcdef0123456789abcdef",
85                        erp="1", scan_freq="2412")
86    dev[0].request("DISCONNECT")
87    dev[0].wait_disconnected(timeout=15)
88    hapd.request("ERP_FLUSH")
89    dev[0].request("RECONNECT")
90    ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS",
91                            "CTRL-EVENT-EAP-FAILURE"], timeout=15)
92    if ev is None:
93        raise Exception("EAP result timed out")
94    if "CTRL-EVENT-EAP-SUCCESS" in ev:
95        raise Exception("Unexpected EAP success")
96    dev[0].request("DISCONNECT")
97    dev[0].select_network(id)
98    ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
99    if ev is None:
100        raise Exception("EAP success timed out")
101    if "EAP re-authentication completed successfully" in ev:
102        raise Exception("Unexpected use of ERP")
103    dev[0].wait_connected(timeout=15, error="Reconnection timed out")
104
105def start_erp_as(erp_domain="example.com", msk_dump=None, tls13=False,
106                 eap_user_file="auth_serv/eap_user.conf"):
107    params = {"driver": "none",
108              "interface": "as-erp",
109              "radius_server_clients": "auth_serv/radius_clients.conf",
110              "radius_server_auth_port": '18128',
111              "eap_server": "1",
112              "eap_user_file": eap_user_file,
113              "ca_cert": "auth_serv/ca.pem",
114              "server_cert": "auth_serv/server.pem",
115              "private_key": "auth_serv/server.key",
116              "eap_sim_db": "unix:/tmp/hlr_auc_gw.sock",
117              "dh_file": "auth_serv/dh.conf",
118              "pac_opaque_encr_key": "000102030405060708090a0b0c0d0e0f",
119              "eap_fast_a_id": "101112131415161718191a1b1c1d1e1f",
120              "eap_fast_a_id_info": "test server",
121              "eap_server_erp": "1",
122              "erp_domain": erp_domain}
123    if msk_dump:
124        params["dump_msk_file"] = msk_dump
125    if tls13:
126        params["tls_flags"] = "[ENABLE-TLSv1.3]"
127    apdev = {'ifname': 'as-erp'}
128    return hostapd.add_ap(apdev, params, driver="none")
129
130def test_erp_radius(dev, apdev):
131    """ERP enabled on RADIUS server and peer"""
132    check_erp_capa(dev[0])
133    start_erp_as()
134    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
135    params['auth_server_port'] = "18128"
136    params['erp_send_reauth_start'] = '1'
137    params['erp_domain'] = 'example.com'
138    params['disable_pmksa_caching'] = '1'
139    hapd = hostapd.add_ap(apdev[0], params)
140
141    dev[0].request("ERP_FLUSH")
142    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
143                   eap="PSK", identity="psk.user@example.com",
144                   password_hex="0123456789abcdef0123456789abcdef",
145                   erp="1", scan_freq="2412")
146    for i in range(3):
147        dev[0].request("DISCONNECT")
148        dev[0].wait_disconnected(timeout=15)
149        dev[0].request("RECONNECT")
150        ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
151        if ev is None:
152            raise Exception("EAP success timed out")
153        if "EAP re-authentication completed successfully" not in ev:
154            raise Exception("Did not use ERP")
155        dev[0].wait_connected(timeout=15, error="Reconnection timed out")
156
157def test_erp_radius_no_wildcard_user(dev, apdev, params):
158    """ERP enabled on RADIUS server and peer and no wildcard user"""
159    check_erp_capa(dev[0])
160    user_file = os.path.join(params['logdir'],
161                             'erp_radius_no_wildcard_user.eap_users')
162    with open(user_file, 'w') as f:
163        f.write('"user@example.com" PSK 0123456789abcdef0123456789abcdef\n')
164    start_erp_as(eap_user_file=user_file)
165    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
166    params['auth_server_port'] = "18128"
167    params['erp_send_reauth_start'] = '1'
168    params['erp_domain'] = 'example.com'
169    params['disable_pmksa_caching'] = '1'
170    hapd = hostapd.add_ap(apdev[0], params)
171
172    dev[0].request("ERP_FLUSH")
173    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
174                   eap="PSK", identity="user@example.com",
175                   password_hex="0123456789abcdef0123456789abcdef",
176                   erp="1", scan_freq="2412")
177    for i in range(3):
178        dev[0].request("DISCONNECT")
179        dev[0].wait_disconnected(timeout=15)
180        dev[0].request("RECONNECT")
181        ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
182        if ev is None:
183            raise Exception("EAP success timed out")
184        if "EAP re-authentication completed successfully" not in ev:
185            raise Exception("Did not use ERP")
186        dev[0].wait_connected(timeout=15, error="Reconnection timed out")
187
188def test_erp_radius_ext(dev, apdev):
189    """ERP enabled on a separate RADIUS server and peer"""
190    as_hapd = hostapd.Hostapd("as")
191    try:
192        as_hapd.disable()
193        as_hapd.set("eap_server_erp", "1")
194        as_hapd.set("erp_domain", "erp.example.com")
195        as_hapd.enable()
196        run_erp_radius_ext(dev, apdev)
197    finally:
198        as_hapd.disable()
199        as_hapd.set("eap_server_erp", "0")
200        as_hapd.set("erp_domain", "")
201        as_hapd.enable()
202
203def run_erp_radius_ext(dev, apdev):
204    check_erp_capa(dev[0])
205    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
206    params['erp_send_reauth_start'] = '1'
207    params['erp_domain'] = 'erp.example.com'
208    params['disable_pmksa_caching'] = '1'
209    hapd = hostapd.add_ap(apdev[0], params)
210
211    dev[0].request("ERP_FLUSH")
212    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
213                   eap="PSK", identity="psk@erp.example.com",
214                   password_hex="0123456789abcdef0123456789abcdef",
215                   erp="1", scan_freq="2412")
216    for i in range(3):
217        dev[0].request("DISCONNECT")
218        dev[0].wait_disconnected(timeout=15)
219        dev[0].request("RECONNECT")
220        ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
221        if ev is None:
222            raise Exception("EAP success timed out")
223        if "EAP re-authentication completed successfully" not in ev:
224            raise Exception("Did not use ERP")
225        dev[0].wait_connected(timeout=15, error="Reconnection timed out")
226
227def erp_test(dev, hapd, reauth=False, **kwargs):
228    res = dev.get_capability("eap")
229    if kwargs['eap'] not in res:
230        logger.info("Skip ERP test with %s due to missing support" % kwargs['eap'])
231        return
232    hapd.dump_monitor()
233    dev.dump_monitor()
234    dev.request("ERP_FLUSH")
235    id = dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", erp="1",
236                     scan_freq="2412", **kwargs)
237    dev.request("DISCONNECT")
238    dev.wait_disconnected(timeout=15)
239    dev.dump_monitor()
240    hapd.dump_monitor()
241
242    if reauth:
243        dev.request("ERP_FLUSH")
244        dev.request("RECONNECT")
245        ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
246        if ev is None:
247            raise Exception("EAP success timed out")
248        if "EAP re-authentication completed successfully" in ev:
249            raise Exception("Used ERP unexpectedly")
250        dev.wait_connected(timeout=15, error="Reconnection timed out")
251        dev.request("DISCONNECT")
252        dev.wait_disconnected(timeout=15)
253        dev.dump_monitor()
254        hapd.dump_monitor()
255
256    dev.request("RECONNECT")
257    ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
258    if ev is None:
259        raise Exception("EAP success timed out")
260    if "EAP re-authentication completed successfully" not in ev:
261        raise Exception("Did not use ERP")
262    dev.wait_connected(timeout=15, error="Reconnection timed out")
263    ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
264    if ev is None:
265        raise Exception("No connection event received from hostapd")
266    dev.request("DISCONNECT")
267
268def test_erp_radius_eap_methods(dev, apdev):
269    """ERP enabled on RADIUS server and peer"""
270    check_erp_capa(dev[0])
271    eap_methods = dev[0].get_capability("eap")
272    start_erp_as()
273    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
274    params['auth_server_port'] = "18128"
275    params['erp_send_reauth_start'] = '1'
276    params['erp_domain'] = 'example.com'
277    params['disable_pmksa_caching'] = '1'
278    hapd = hostapd.add_ap(apdev[0], params)
279
280    erp_test(dev[0], hapd, eap="AKA", identity="0232010000000000@example.com",
281             password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
282    erp_test(dev[0], hapd, reauth=True,
283             eap="AKA", identity="0232010000000000@example.com",
284             password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
285    erp_test(dev[0], hapd, eap="AKA'", identity="6555444333222111@example.com",
286             password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
287    erp_test(dev[0], hapd, reauth=True,
288             eap="AKA'", identity="6555444333222111@example.com",
289             password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
290    erp_test(dev[0], hapd, eap="EKE", identity="erp-eke@example.com",
291             password="hello")
292    if "FAST" in eap_methods:
293        erp_test(dev[0], hapd, eap="FAST", identity="erp-fast@example.com",
294                 password="password", ca_cert="auth_serv/ca.pem",
295                 phase2="auth=GTC",
296                 phase1="fast_provisioning=2",
297                 pac_file="blob://fast_pac_auth_erp")
298    erp_test(dev[0], hapd, eap="GPSK", identity="erp-gpsk@example.com",
299             password="abcdefghijklmnop0123456789abcdef")
300    erp_test(dev[0], hapd, eap="IKEV2", identity="erp-ikev2@example.com",
301             password="password")
302    erp_test(dev[0], hapd, eap="PAX", identity="erp-pax@example.com",
303             password_hex="0123456789abcdef0123456789abcdef")
304    if "MSCHAPV2" in eap_methods:
305        erp_test(dev[0], hapd, eap="PEAP", identity="erp-peap@example.com",
306                 password="password", ca_cert="auth_serv/ca.pem",
307                 phase2="auth=MSCHAPV2")
308        erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com",
309                 password="password", ca_cert="auth_serv/ca.pem",
310                 phase2="auth=MSCHAPV2", pac_file="blob://teap_pac")
311    erp_test(dev[0], hapd, eap="PSK", identity="erp-psk@example.com",
312             password_hex="0123456789abcdef0123456789abcdef")
313    if "PWD" in eap_methods:
314        erp_test(dev[0], hapd, eap="PWD", identity="erp-pwd@example.com",
315                 password="secret password")
316    erp_test(dev[0], hapd, eap="SAKE", identity="erp-sake@example.com",
317             password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
318    erp_test(dev[0], hapd, eap="SIM", identity="1232010000000000@example.com",
319             password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
320    erp_test(dev[0], hapd, reauth=True,
321             eap="SIM", identity="1232010000000000@example.com",
322             password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
323    erp_test(dev[0], hapd, eap="TLS", identity="erp-tls@example.com",
324             ca_cert="auth_serv/ca.pem", client_cert="auth_serv/user.pem",
325             private_key="auth_serv/user.key")
326    erp_test(dev[0], hapd, eap="TTLS", identity="erp-ttls@example.com",
327             password="password", ca_cert="auth_serv/ca.pem", phase2="auth=PAP")
328
329def test_erp_radius_eap_tls_v13(dev, apdev):
330    """ERP enabled on RADIUS server and peer using EAP-TLS v1.3"""
331    check_erp_capa(dev[0])
332    check_tls13_support(dev[0])
333
334    eap_methods = dev[0].get_capability("eap")
335    start_erp_as(tls13=True)
336    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
337    params['auth_server_port'] = "18128"
338    params['erp_send_reauth_start'] = '1'
339    params['erp_domain'] = 'example.com'
340    params['disable_pmksa_caching'] = '1'
341    hapd = hostapd.add_ap(apdev[0], params)
342
343    erp_test(dev[0], hapd, eap="TLS", identity="erp-tls@example.com",
344             ca_cert="auth_serv/ca.pem", client_cert="auth_serv/user.pem",
345             private_key="auth_serv/user.key",
346             phase1="tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0")
347
348def test_erp_key_lifetime_in_memory(dev, apdev, params):
349    """ERP and key lifetime in memory"""
350    check_erp_capa(dev[0])
351    p = int_eap_server_params()
352    p['erp_send_reauth_start'] = '1'
353    p['erp_domain'] = 'example.com'
354    p['eap_server_erp'] = '1'
355    p['disable_pmksa_caching'] = '1'
356    hapd = hostapd.add_ap(apdev[0], p)
357    password = "63d2d21ac3c09ed567ee004a34490f1d16e7fa5835edf17ddba70a63f1a90a25"
358
359    pid = find_wpas_process(dev[0])
360
361    dev[0].request("ERP_FLUSH")
362    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
363                   identity="pap-secret@example.com", password=password,
364                   ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
365                   erp="1", scan_freq="2412")
366
367    # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
368    # event has been delivered, so verify that wpa_supplicant has returned to
369    # eloop before reading process memory.
370    time.sleep(1)
371    dev[0].ping()
372    password = password.encode()
373    buf = read_process_memory(pid, password)
374
375    dev[0].request("DISCONNECT")
376    dev[0].wait_disconnected(timeout=15)
377
378    dev[0].relog()
379    msk = None
380    emsk = None
381    rRK = None
382    rIK = None
383    pmk = None
384    ptk = None
385    gtk = None
386    with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
387        for l in f.readlines():
388            if "EAP-TTLS: Derived key - hexdump" in l:
389                val = l.strip().split(':')[3].replace(' ', '')
390                msk = binascii.unhexlify(val)
391            if "EAP-TTLS: Derived EMSK - hexdump" in l:
392                val = l.strip().split(':')[3].replace(' ', '')
393                emsk = binascii.unhexlify(val)
394            if "EAP: ERP rRK - hexdump" in l:
395                val = l.strip().split(':')[3].replace(' ', '')
396                rRK = binascii.unhexlify(val)
397            if "EAP: ERP rIK - hexdump" in l:
398                val = l.strip().split(':')[3].replace(' ', '')
399                rIK = binascii.unhexlify(val)
400            if "WPA: PMK - hexdump" in l:
401                val = l.strip().split(':')[3].replace(' ', '')
402                pmk = binascii.unhexlify(val)
403            if "WPA: PTK - hexdump" in l:
404                val = l.strip().split(':')[3].replace(' ', '')
405                ptk = binascii.unhexlify(val)
406            if "WPA: Group Key - hexdump" in l:
407                val = l.strip().split(':')[3].replace(' ', '')
408                gtk = binascii.unhexlify(val)
409    if not msk or not emsk or not rIK or not rRK or not pmk or not ptk or not gtk:
410        raise Exception("Could not find keys from debug log")
411    if len(gtk) != 16:
412        raise Exception("Unexpected GTK length")
413
414    kck = ptk[0:16]
415    kek = ptk[16:32]
416    tk = ptk[32:48]
417
418    fname = os.path.join(params['logdir'],
419                         'erp_key_lifetime_in_memory.memctx-')
420
421    logger.info("Checking keys in memory while associated")
422    get_key_locations(buf, password, "Password")
423    get_key_locations(buf, pmk, "PMK")
424    get_key_locations(buf, msk, "MSK")
425    get_key_locations(buf, emsk, "EMSK")
426    get_key_locations(buf, rRK, "rRK")
427    get_key_locations(buf, rIK, "rIK")
428    if password not in buf:
429        raise HwsimSkip("Password not found while associated")
430    if pmk not in buf:
431        raise HwsimSkip("PMK not found while associated")
432    if kck not in buf:
433        raise Exception("KCK not found while associated")
434    if kek not in buf:
435        raise Exception("KEK not found while associated")
436    #if tk in buf:
437    #    raise Exception("TK found from memory")
438
439    logger.info("Checking keys in memory after disassociation")
440    buf = read_process_memory(pid, password)
441
442    # Note: Password is still present in network configuration
443    # Note: PMK is in EAP fast re-auth data
444
445    get_key_locations(buf, password, "Password")
446    get_key_locations(buf, pmk, "PMK")
447    get_key_locations(buf, msk, "MSK")
448    get_key_locations(buf, emsk, "EMSK")
449    get_key_locations(buf, rRK, "rRK")
450    get_key_locations(buf, rIK, "rIK")
451    verify_not_present(buf, kck, fname, "KCK")
452    verify_not_present(buf, kek, fname, "KEK")
453    verify_not_present(buf, tk, fname, "TK")
454    if gtk in buf:
455        get_key_locations(buf, gtk, "GTK")
456    verify_not_present(buf, gtk, fname, "GTK")
457
458    dev[0].request("RECONNECT")
459    ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
460    if ev is None:
461        raise Exception("EAP success timed out")
462    if "EAP re-authentication completed successfully" not in ev:
463        raise Exception("Did not use ERP")
464    dev[0].wait_connected(timeout=15, error="Reconnection timed out")
465
466    dev[0].request("DISCONNECT")
467    dev[0].wait_disconnected(timeout=15)
468
469    dev[0].relog()
470    pmk = None
471    ptk = None
472    gtk = None
473    with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
474        for l in f.readlines():
475            if "WPA: PMK - hexdump" in l:
476                val = l.strip().split(':')[3].replace(' ', '')
477                pmk = binascii.unhexlify(val)
478            if "WPA: PTK - hexdump" in l:
479                val = l.strip().split(':')[3].replace(' ', '')
480                ptk = binascii.unhexlify(val)
481            if "WPA: GTK in EAPOL-Key - hexdump" in l:
482                val = l.strip().split(':')[3].replace(' ', '')
483                gtk = binascii.unhexlify(val)
484    if not pmk or not ptk or not gtk:
485        raise Exception("Could not find keys from debug log")
486
487    kck = ptk[0:16]
488    kek = ptk[16:32]
489    tk = ptk[32:48]
490
491    logger.info("Checking keys in memory after ERP and disassociation")
492    buf = read_process_memory(pid, password)
493
494    # Note: Password is still present in network configuration
495
496    get_key_locations(buf, password, "Password")
497    get_key_locations(buf, pmk, "PMK")
498    get_key_locations(buf, msk, "MSK")
499    get_key_locations(buf, emsk, "EMSK")
500    get_key_locations(buf, rRK, "rRK")
501    get_key_locations(buf, rIK, "rIK")
502    verify_not_present(buf, kck, fname, "KCK")
503    verify_not_present(buf, kek, fname, "KEK")
504    verify_not_present(buf, tk, fname, "TK")
505    verify_not_present(buf, gtk, fname, "GTK")
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    # Note: rRK and rIK are still in memory
513
514    get_key_locations(buf, password, "Password")
515    get_key_locations(buf, pmk, "PMK")
516    get_key_locations(buf, msk, "MSK")
517    get_key_locations(buf, emsk, "EMSK")
518    get_key_locations(buf, rRK, "rRK")
519    get_key_locations(buf, rIK, "rIK")
520    verify_not_present(buf, password, fname, "password")
521    verify_not_present(buf, pmk, fname, "PMK")
522    verify_not_present(buf, kck, fname, "KCK")
523    verify_not_present(buf, kek, fname, "KEK")
524    verify_not_present(buf, tk, fname, "TK")
525    verify_not_present(buf, gtk, fname, "GTK")
526    verify_not_present(buf, msk, fname, "MSK")
527    verify_not_present(buf, emsk, fname, "EMSK")
528
529    dev[0].request("ERP_FLUSH")
530    logger.info("Checking keys in memory after ERP_FLUSH")
531    buf = read_process_memory(pid, password)
532    get_key_locations(buf, rRK, "rRK")
533    get_key_locations(buf, rIK, "rIK")
534    verify_not_present(buf, rRK, fname, "rRK")
535    verify_not_present(buf, rIK, fname, "rIK")
536
537def test_erp_anonymous_identity(dev, apdev):
538    """ERP and anonymous identity"""
539    check_erp_capa(dev[0])
540    params = int_eap_server_params()
541    params['erp_send_reauth_start'] = '1'
542    params['erp_domain'] = 'example.com'
543    params['eap_server_erp'] = '1'
544    params['disable_pmksa_caching'] = '1'
545    hapd = hostapd.add_ap(apdev[0], params)
546
547    dev[0].request("ERP_FLUSH")
548    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
549                   identity="erp-ttls",
550                   anonymous_identity="anonymous@example.com",
551                   password="password",
552                   ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
553                   erp="1", scan_freq="2412")
554    for i in range(3):
555        dev[0].request("DISCONNECT")
556        dev[0].wait_disconnected(timeout=15)
557        dev[0].request("RECONNECT")
558        ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
559        if ev is None:
560            raise Exception("EAP success timed out")
561        if "EAP re-authentication completed successfully" not in ev:
562            raise Exception("Did not use ERP")
563        dev[0].wait_connected(timeout=15, error="Reconnection timed out")
564
565def test_erp_home_realm_oom(dev, apdev):
566    """ERP and home realm OOM"""
567    check_erp_capa(dev[0])
568    params = int_eap_server_params()
569    params['erp_send_reauth_start'] = '1'
570    params['erp_domain'] = 'example.com'
571    params['eap_server_erp'] = '1'
572    params['disable_pmksa_caching'] = '1'
573    hapd = hostapd.add_ap(apdev[0], params)
574
575    for count in range(1, 3):
576        with alloc_fail(dev[0], count, "eap_get_realm"):
577            dev[0].request("ERP_FLUSH")
578            dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
579                           identity="erp-ttls@example.com",
580                           anonymous_identity="anonymous@example.com",
581                           password="password",
582                           ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
583                           erp="1", scan_freq="2412", wait_connect=False)
584            dev[0].wait_connected(timeout=10)
585            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
586            dev[0].request("REMOVE_NETWORK all")
587            dev[0].wait_disconnected()
588
589    for count in range(1, 3):
590        with alloc_fail(dev[0], count, "eap_get_realm"):
591            dev[0].request("ERP_FLUSH")
592            dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
593                           identity="erp-ttls",
594                           anonymous_identity="anonymous@example.com",
595                           password="password",
596                           ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
597                           erp="1", scan_freq="2412", wait_connect=False)
598            dev[0].wait_connected(timeout=10)
599            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
600            dev[0].request("REMOVE_NETWORK all")
601            dev[0].wait_disconnected()
602
603    for count in range(1, 3):
604        dev[0].request("ERP_FLUSH")
605        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
606                       identity="erp-ttls@example.com",
607                       anonymous_identity="anonymous@example.com",
608                       password="password",
609                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
610                       erp="1", scan_freq="2412", wait_connect=False)
611        dev[0].wait_connected(timeout=10)
612        if count > 1:
613            continue
614        with alloc_fail(dev[0], count, "eap_get_realm"):
615            dev[0].request("DISCONNECT")
616            dev[0].wait_disconnected(timeout=15)
617            dev[0].request("RECONNECT")
618            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
619            dev[0].request("REMOVE_NETWORK all")
620            dev[0].wait_disconnected()
621
622def test_erp_local_errors(dev, apdev):
623    """ERP and local error cases"""
624    check_erp_capa(dev[0])
625    params = int_eap_server_params()
626    params['erp_send_reauth_start'] = '1'
627    params['erp_domain'] = 'example.com'
628    params['eap_server_erp'] = '1'
629    params['disable_pmksa_caching'] = '1'
630    hapd = hostapd.add_ap(apdev[0], params)
631
632    dev[0].request("ERP_FLUSH")
633    with alloc_fail(dev[0], 1, "eap_peer_erp_init"):
634        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
635                       identity="erp-ttls@example.com",
636                       anonymous_identity="anonymous@example.com",
637                       password="password",
638                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
639                       erp="1", scan_freq="2412")
640        dev[0].request("REMOVE_NETWORK all")
641        dev[0].wait_disconnected()
642
643    for count in range(1, 6):
644        dev[0].request("ERP_FLUSH")
645        with fail_test(dev[0], count, "hmac_sha256_kdf;eap_peer_erp_init"):
646            dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
647                           identity="erp-ttls@example.com",
648                           anonymous_identity="anonymous@example.com",
649                           password="password",
650                           ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
651                           erp="1", scan_freq="2412")
652            dev[0].request("REMOVE_NETWORK all")
653            dev[0].wait_disconnected()
654
655    dev[0].request("ERP_FLUSH")
656    with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_peer_erp_reauth_start"):
657        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
658                       identity="erp-ttls@example.com",
659                       anonymous_identity="anonymous@example.com",
660                       password="password",
661                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
662                       erp="1", scan_freq="2412")
663        dev[0].request("DISCONNECT")
664        dev[0].wait_disconnected(timeout=15)
665        dev[0].request("RECONNECT")
666        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
667        dev[0].request("REMOVE_NETWORK all")
668        dev[0].wait_disconnected()
669
670    dev[0].request("ERP_FLUSH")
671    with fail_test(dev[0], 1, "hmac_sha256;eap_peer_erp_reauth_start"):
672        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
673                       identity="erp-ttls@example.com",
674                       anonymous_identity="anonymous@example.com",
675                       password="password",
676                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
677                       erp="1", scan_freq="2412")
678        dev[0].request("DISCONNECT")
679        dev[0].wait_disconnected(timeout=15)
680        dev[0].request("RECONNECT")
681        wait_fail_trigger(dev[0], "GET_FAIL")
682        dev[0].request("REMOVE_NETWORK all")
683        dev[0].wait_disconnected()
684
685    dev[0].request("ERP_FLUSH")
686    with fail_test(dev[0], 1, "hmac_sha256;eap_peer_finish"):
687        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
688                       identity="erp-ttls@example.com",
689                       anonymous_identity="anonymous@example.com",
690                       password="password",
691                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
692                       erp="1", scan_freq="2412")
693        dev[0].request("DISCONNECT")
694        dev[0].wait_disconnected(timeout=15)
695        dev[0].request("RECONNECT")
696        wait_fail_trigger(dev[0], "GET_FAIL")
697        dev[0].request("REMOVE_NETWORK all")
698        dev[0].wait_disconnected()
699
700    dev[0].request("ERP_FLUSH")
701    with alloc_fail(dev[0], 1, "eap_peer_erp_init"):
702        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
703                       identity="erp-ttls@example.com",
704                       anonymous_identity="anonymous@example.com",
705                       password="password",
706                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
707                       erp="1", scan_freq="2412")
708        dev[0].request("DISCONNECT")
709        dev[0].wait_disconnected(timeout=15)
710
711    dev[0].request("ERP_FLUSH")
712    with alloc_fail(dev[0], 1, "eap_peer_finish"):
713        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
714                       identity="erp-ttls@example.com",
715                       anonymous_identity="anonymous@example.com",
716                       password="password",
717                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
718                       erp="1", scan_freq="2412")
719        dev[0].request("DISCONNECT")
720        dev[0].wait_disconnected(timeout=15)
721        dev[0].request("RECONNECT")
722        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
723        dev[0].request("REMOVE_NETWORK all")
724        dev[0].wait_disconnected()
725
726    dev[0].request("ERP_FLUSH")
727    with fail_test(dev[0], 1, "hmac_sha256_kdf;eap_peer_finish"):
728        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
729                       identity="erp-ttls@example.com",
730                       anonymous_identity="anonymous@example.com",
731                       password="password",
732                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
733                       erp="1", scan_freq="2412")
734        dev[0].request("DISCONNECT")
735        dev[0].wait_disconnected(timeout=15)
736        dev[0].request("RECONNECT")
737        wait_fail_trigger(dev[0], "GET_FAIL")
738        dev[0].request("REMOVE_NETWORK all")
739        dev[0].wait_disconnected()
740