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
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    tls = dev[0].request("GET tls_library")
333    if "run=OpenSSL 1.1.1" not in tls:
334        raise HwsimSkip("No TLS v1.3 support in TLS library")
335
336    eap_methods = dev[0].get_capability("eap")
337    start_erp_as(tls13=True)
338    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
339    params['auth_server_port'] = "18128"
340    params['erp_send_reauth_start'] = '1'
341    params['erp_domain'] = 'example.com'
342    params['disable_pmksa_caching'] = '1'
343    hapd = hostapd.add_ap(apdev[0], params)
344
345    erp_test(dev[0], hapd, eap="TLS", identity="erp-tls@example.com",
346             ca_cert="auth_serv/ca.pem", client_cert="auth_serv/user.pem",
347             private_key="auth_serv/user.key",
348             phase1="tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0")
349
350def test_erp_key_lifetime_in_memory(dev, apdev, params):
351    """ERP and key lifetime in memory"""
352    check_erp_capa(dev[0])
353    p = int_eap_server_params()
354    p['erp_send_reauth_start'] = '1'
355    p['erp_domain'] = 'example.com'
356    p['eap_server_erp'] = '1'
357    p['disable_pmksa_caching'] = '1'
358    hapd = hostapd.add_ap(apdev[0], p)
359    password = "63d2d21ac3c09ed567ee004a34490f1d16e7fa5835edf17ddba70a63f1a90a25"
360
361    pid = find_wpas_process(dev[0])
362
363    dev[0].request("ERP_FLUSH")
364    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
365                   identity="pap-secret@example.com", password=password,
366                   ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
367                   erp="1", scan_freq="2412")
368
369    # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
370    # event has been delivered, so verify that wpa_supplicant has returned to
371    # eloop before reading process memory.
372    time.sleep(1)
373    dev[0].ping()
374    password = password.encode()
375    buf = read_process_memory(pid, password)
376
377    dev[0].request("DISCONNECT")
378    dev[0].wait_disconnected(timeout=15)
379
380    dev[0].relog()
381    msk = None
382    emsk = None
383    rRK = None
384    rIK = None
385    pmk = None
386    ptk = None
387    gtk = None
388    with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
389        for l in f.readlines():
390            if "EAP-TTLS: Derived key - hexdump" in l:
391                val = l.strip().split(':')[3].replace(' ', '')
392                msk = binascii.unhexlify(val)
393            if "EAP-TTLS: Derived EMSK - hexdump" in l:
394                val = l.strip().split(':')[3].replace(' ', '')
395                emsk = binascii.unhexlify(val)
396            if "EAP: ERP rRK - hexdump" in l:
397                val = l.strip().split(':')[3].replace(' ', '')
398                rRK = binascii.unhexlify(val)
399            if "EAP: ERP rIK - hexdump" in l:
400                val = l.strip().split(':')[3].replace(' ', '')
401                rIK = binascii.unhexlify(val)
402            if "WPA: PMK - hexdump" in l:
403                val = l.strip().split(':')[3].replace(' ', '')
404                pmk = binascii.unhexlify(val)
405            if "WPA: PTK - hexdump" in l:
406                val = l.strip().split(':')[3].replace(' ', '')
407                ptk = binascii.unhexlify(val)
408            if "WPA: Group Key - hexdump" in l:
409                val = l.strip().split(':')[3].replace(' ', '')
410                gtk = binascii.unhexlify(val)
411    if not msk or not emsk or not rIK or not rRK or not pmk or not ptk or not gtk:
412        raise Exception("Could not find keys from debug log")
413    if len(gtk) != 16:
414        raise Exception("Unexpected GTK length")
415
416    kck = ptk[0:16]
417    kek = ptk[16:32]
418    tk = ptk[32:48]
419
420    fname = os.path.join(params['logdir'],
421                         'erp_key_lifetime_in_memory.memctx-')
422
423    logger.info("Checking keys in memory while associated")
424    get_key_locations(buf, password, "Password")
425    get_key_locations(buf, pmk, "PMK")
426    get_key_locations(buf, msk, "MSK")
427    get_key_locations(buf, emsk, "EMSK")
428    get_key_locations(buf, rRK, "rRK")
429    get_key_locations(buf, rIK, "rIK")
430    if password not in buf:
431        raise HwsimSkip("Password not found while associated")
432    if pmk not in buf:
433        raise HwsimSkip("PMK not found while associated")
434    if kck not in buf:
435        raise Exception("KCK not found while associated")
436    if kek not in buf:
437        raise Exception("KEK not found while associated")
438    #if tk in buf:
439    #    raise Exception("TK found from memory")
440
441    logger.info("Checking keys in memory after disassociation")
442    buf = read_process_memory(pid, password)
443
444    # Note: Password is still present in network configuration
445    # Note: PMK is in EAP fast re-auth data
446
447    get_key_locations(buf, password, "Password")
448    get_key_locations(buf, pmk, "PMK")
449    get_key_locations(buf, msk, "MSK")
450    get_key_locations(buf, emsk, "EMSK")
451    get_key_locations(buf, rRK, "rRK")
452    get_key_locations(buf, rIK, "rIK")
453    verify_not_present(buf, kck, fname, "KCK")
454    verify_not_present(buf, kek, fname, "KEK")
455    verify_not_present(buf, tk, fname, "TK")
456    if gtk in buf:
457        get_key_locations(buf, gtk, "GTK")
458    verify_not_present(buf, gtk, fname, "GTK")
459
460    dev[0].request("RECONNECT")
461    ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
462    if ev is None:
463        raise Exception("EAP success timed out")
464    if "EAP re-authentication completed successfully" not in ev:
465        raise Exception("Did not use ERP")
466    dev[0].wait_connected(timeout=15, error="Reconnection timed out")
467
468    dev[0].request("DISCONNECT")
469    dev[0].wait_disconnected(timeout=15)
470
471    dev[0].relog()
472    pmk = None
473    ptk = None
474    gtk = None
475    with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
476        for l in f.readlines():
477            if "WPA: PMK - hexdump" in l:
478                val = l.strip().split(':')[3].replace(' ', '')
479                pmk = binascii.unhexlify(val)
480            if "WPA: PTK - hexdump" in l:
481                val = l.strip().split(':')[3].replace(' ', '')
482                ptk = binascii.unhexlify(val)
483            if "WPA: GTK in EAPOL-Key - hexdump" in l:
484                val = l.strip().split(':')[3].replace(' ', '')
485                gtk = binascii.unhexlify(val)
486    if not pmk or not ptk or not gtk:
487        raise Exception("Could not find keys from debug log")
488
489    kck = ptk[0:16]
490    kek = ptk[16:32]
491    tk = ptk[32:48]
492
493    logger.info("Checking keys in memory after ERP and disassociation")
494    buf = read_process_memory(pid, password)
495
496    # Note: Password is still present in network configuration
497
498    get_key_locations(buf, password, "Password")
499    get_key_locations(buf, pmk, "PMK")
500    get_key_locations(buf, msk, "MSK")
501    get_key_locations(buf, emsk, "EMSK")
502    get_key_locations(buf, rRK, "rRK")
503    get_key_locations(buf, rIK, "rIK")
504    verify_not_present(buf, kck, fname, "KCK")
505    verify_not_present(buf, kek, fname, "KEK")
506    verify_not_present(buf, tk, fname, "TK")
507    verify_not_present(buf, gtk, fname, "GTK")
508
509    dev[0].request("REMOVE_NETWORK all")
510
511    logger.info("Checking keys in memory after network profile removal")
512    buf = read_process_memory(pid, password)
513
514    # Note: rRK and rIK are still in memory
515
516    get_key_locations(buf, password, "Password")
517    get_key_locations(buf, pmk, "PMK")
518    get_key_locations(buf, msk, "MSK")
519    get_key_locations(buf, emsk, "EMSK")
520    get_key_locations(buf, rRK, "rRK")
521    get_key_locations(buf, rIK, "rIK")
522    verify_not_present(buf, password, fname, "password")
523    verify_not_present(buf, pmk, fname, "PMK")
524    verify_not_present(buf, kck, fname, "KCK")
525    verify_not_present(buf, kek, fname, "KEK")
526    verify_not_present(buf, tk, fname, "TK")
527    verify_not_present(buf, gtk, fname, "GTK")
528    verify_not_present(buf, msk, fname, "MSK")
529    verify_not_present(buf, emsk, fname, "EMSK")
530
531    dev[0].request("ERP_FLUSH")
532    logger.info("Checking keys in memory after ERP_FLUSH")
533    buf = read_process_memory(pid, password)
534    get_key_locations(buf, rRK, "rRK")
535    get_key_locations(buf, rIK, "rIK")
536    verify_not_present(buf, rRK, fname, "rRK")
537    verify_not_present(buf, rIK, fname, "rIK")
538
539def test_erp_anonymous_identity(dev, apdev):
540    """ERP and anonymous identity"""
541    check_erp_capa(dev[0])
542    params = int_eap_server_params()
543    params['erp_send_reauth_start'] = '1'
544    params['erp_domain'] = 'example.com'
545    params['eap_server_erp'] = '1'
546    params['disable_pmksa_caching'] = '1'
547    hapd = hostapd.add_ap(apdev[0], params)
548
549    dev[0].request("ERP_FLUSH")
550    dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
551                   identity="erp-ttls",
552                   anonymous_identity="anonymous@example.com",
553                   password="password",
554                   ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
555                   erp="1", scan_freq="2412")
556    for i in range(3):
557        dev[0].request("DISCONNECT")
558        dev[0].wait_disconnected(timeout=15)
559        dev[0].request("RECONNECT")
560        ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
561        if ev is None:
562            raise Exception("EAP success timed out")
563        if "EAP re-authentication completed successfully" not in ev:
564            raise Exception("Did not use ERP")
565        dev[0].wait_connected(timeout=15, error="Reconnection timed out")
566
567def test_erp_home_realm_oom(dev, apdev):
568    """ERP and home realm OOM"""
569    check_erp_capa(dev[0])
570    params = int_eap_server_params()
571    params['erp_send_reauth_start'] = '1'
572    params['erp_domain'] = 'example.com'
573    params['eap_server_erp'] = '1'
574    params['disable_pmksa_caching'] = '1'
575    hapd = hostapd.add_ap(apdev[0], params)
576
577    for count in range(1, 3):
578        with alloc_fail(dev[0], count, "eap_get_realm"):
579            dev[0].request("ERP_FLUSH")
580            dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
581                           identity="erp-ttls@example.com",
582                           anonymous_identity="anonymous@example.com",
583                           password="password",
584                           ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
585                           erp="1", scan_freq="2412", wait_connect=False)
586            dev[0].wait_connected(timeout=10)
587            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
588            dev[0].request("REMOVE_NETWORK all")
589            dev[0].wait_disconnected()
590
591    for count in range(1, 3):
592        with alloc_fail(dev[0], count, "eap_get_realm"):
593            dev[0].request("ERP_FLUSH")
594            dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
595                           identity="erp-ttls",
596                           anonymous_identity="anonymous@example.com",
597                           password="password",
598                           ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
599                           erp="1", scan_freq="2412", wait_connect=False)
600            dev[0].wait_connected(timeout=10)
601            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
602            dev[0].request("REMOVE_NETWORK all")
603            dev[0].wait_disconnected()
604
605    for count in range(1, 3):
606        dev[0].request("ERP_FLUSH")
607        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
608                       identity="erp-ttls@example.com",
609                       anonymous_identity="anonymous@example.com",
610                       password="password",
611                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
612                       erp="1", scan_freq="2412", wait_connect=False)
613        dev[0].wait_connected(timeout=10)
614        if count > 1:
615            continue
616        with alloc_fail(dev[0], count, "eap_get_realm"):
617            dev[0].request("DISCONNECT")
618            dev[0].wait_disconnected(timeout=15)
619            dev[0].request("RECONNECT")
620            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
621            dev[0].request("REMOVE_NETWORK all")
622            dev[0].wait_disconnected()
623
624def test_erp_local_errors(dev, apdev):
625    """ERP and local error cases"""
626    check_erp_capa(dev[0])
627    params = int_eap_server_params()
628    params['erp_send_reauth_start'] = '1'
629    params['erp_domain'] = 'example.com'
630    params['eap_server_erp'] = '1'
631    params['disable_pmksa_caching'] = '1'
632    hapd = hostapd.add_ap(apdev[0], params)
633
634    dev[0].request("ERP_FLUSH")
635    with alloc_fail(dev[0], 1, "eap_peer_erp_init"):
636        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
637                       identity="erp-ttls@example.com",
638                       anonymous_identity="anonymous@example.com",
639                       password="password",
640                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
641                       erp="1", scan_freq="2412")
642        dev[0].request("REMOVE_NETWORK all")
643        dev[0].wait_disconnected()
644
645    for count in range(1, 6):
646        dev[0].request("ERP_FLUSH")
647        with fail_test(dev[0], count, "hmac_sha256_kdf;eap_peer_erp_init"):
648            dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
649                           identity="erp-ttls@example.com",
650                           anonymous_identity="anonymous@example.com",
651                           password="password",
652                           ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
653                           erp="1", scan_freq="2412")
654            dev[0].request("REMOVE_NETWORK all")
655            dev[0].wait_disconnected()
656
657    dev[0].request("ERP_FLUSH")
658    with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_peer_erp_reauth_start"):
659        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
660                       identity="erp-ttls@example.com",
661                       anonymous_identity="anonymous@example.com",
662                       password="password",
663                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
664                       erp="1", scan_freq="2412")
665        dev[0].request("DISCONNECT")
666        dev[0].wait_disconnected(timeout=15)
667        dev[0].request("RECONNECT")
668        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
669        dev[0].request("REMOVE_NETWORK all")
670        dev[0].wait_disconnected()
671
672    dev[0].request("ERP_FLUSH")
673    with fail_test(dev[0], 1, "hmac_sha256;eap_peer_erp_reauth_start"):
674        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
675                       identity="erp-ttls@example.com",
676                       anonymous_identity="anonymous@example.com",
677                       password="password",
678                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
679                       erp="1", scan_freq="2412")
680        dev[0].request("DISCONNECT")
681        dev[0].wait_disconnected(timeout=15)
682        dev[0].request("RECONNECT")
683        wait_fail_trigger(dev[0], "GET_FAIL")
684        dev[0].request("REMOVE_NETWORK all")
685        dev[0].wait_disconnected()
686
687    dev[0].request("ERP_FLUSH")
688    with fail_test(dev[0], 1, "hmac_sha256;eap_peer_finish"):
689        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
690                       identity="erp-ttls@example.com",
691                       anonymous_identity="anonymous@example.com",
692                       password="password",
693                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
694                       erp="1", scan_freq="2412")
695        dev[0].request("DISCONNECT")
696        dev[0].wait_disconnected(timeout=15)
697        dev[0].request("RECONNECT")
698        wait_fail_trigger(dev[0], "GET_FAIL")
699        dev[0].request("REMOVE_NETWORK all")
700        dev[0].wait_disconnected()
701
702    dev[0].request("ERP_FLUSH")
703    with alloc_fail(dev[0], 1, "eap_peer_erp_init"):
704        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
705                       identity="erp-ttls@example.com",
706                       anonymous_identity="anonymous@example.com",
707                       password="password",
708                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
709                       erp="1", scan_freq="2412")
710        dev[0].request("DISCONNECT")
711        dev[0].wait_disconnected(timeout=15)
712
713    dev[0].request("ERP_FLUSH")
714    with alloc_fail(dev[0], 1, "eap_peer_finish"):
715        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
716                       identity="erp-ttls@example.com",
717                       anonymous_identity="anonymous@example.com",
718                       password="password",
719                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
720                       erp="1", scan_freq="2412")
721        dev[0].request("DISCONNECT")
722        dev[0].wait_disconnected(timeout=15)
723        dev[0].request("RECONNECT")
724        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
725        dev[0].request("REMOVE_NETWORK all")
726        dev[0].wait_disconnected()
727
728    dev[0].request("ERP_FLUSH")
729    with fail_test(dev[0], 1, "hmac_sha256_kdf;eap_peer_finish"):
730        dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
731                       identity="erp-ttls@example.com",
732                       anonymous_identity="anonymous@example.com",
733                       password="password",
734                       ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
735                       erp="1", scan_freq="2412")
736        dev[0].request("DISCONNECT")
737        dev[0].wait_disconnected(timeout=15)
738        dev[0].request("RECONNECT")
739        wait_fail_trigger(dev[0], "GET_FAIL")
740        dev[0].request("REMOVE_NETWORK all")
741        dev[0].wait_disconnected()
742