def run_wpas_ap_lifetime_in_memory(dev, apdev, params, raw): ssid = "test-wpa2-psk" passphrase = 'qwertyuiop' psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6' pmk = binascii.unhexlify(psk) pid = find_wpas_process(dev[0]) id = dev[0].add_network() dev[0].set_network(id, "mode", "2") dev[0].set_network_quoted(id, "ssid", ssid) dev[0].set_network(id, "proto", "WPA2") dev[0].set_network(id, "pairwise", "CCMP") dev[0].set_network(id, "group", "CCMP") if raw: dev[0].set_network(id, "psk", psk) else: dev[0].set_network_quoted(id, "psk", passphrase) dev[0].set_network(id, "frequency", "2412") dev[0].set_network(id, "scan_freq", "2412") logger.info("Checking keys in memory after network profile configuration") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") dev[0].select_network(id) wait_ap_ready(dev[0]) logger.info("Checking keys in memory after AP start") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") dev[1].connect(ssid, psk=passphrase, scan_freq="2412") buf = read_process_memory(pid, pmk) dev[1].request("DISCONNECT") dev[1].wait_disconnected() buf2 = read_process_memory(pid, pmk) dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() buf3 = read_process_memory(pid, pmk) dev[1].relog() ptk = None gtk = None with open(os.path.join(params['logdir'], 'log1'), 'r') as f: for l in f.readlines(): if "WPA: PTK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') ptk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not pmk or not ptk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") kck = ptk[0:16] kek = ptk[16:32] tk = ptk[32:48] logger.info("Checking keys in memory while associated") get_key_locations(buf, pmk, "PMK") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") #if tk in buf: # raise Exception("TK found from memory") logger.info("Checking keys in memory after disassociation") get_key_locations(buf2, pmk, "PMK") # Note: PMK/PSK is still present in network configuration and GTK is still # in use. fname = params['prefix'] + '.memctx-' verify_not_present(buf2, kck, fname, "KCK") verify_not_present(buf2, kek, fname, "KEK") verify_not_present(buf2, tk, fname, "TK") get_key_locations(buf2, gtk, "GTK") logger.info("Checking keys in memory after network profile removal") get_key_locations(buf3, pmk, "PMK") verify_not_present(buf3, pmk, fname, "PMK") verify_not_present(buf3, kck, fname, "KCK") verify_not_present(buf3, kek, fname, "KEK") verify_not_present(buf3, tk, fname, "TK") get_key_locations(buf3, gtk, "GTK") verify_not_present(buf3, gtk, fname, "GTK")
def test_sae_key_lifetime_in_memory(dev, apdev, params): """SAE and key lifetime in memory""" if "SAE" not in dev[0].get_capability("auth_alg"): raise HwsimSkip("SAE not supported") password = "******" p = hostapd.wpa2_params(ssid="test-sae", passphrase=password) p['wpa_key_mgmt'] = 'SAE' hapd = hostapd.add_ap(apdev[0], p) pid = find_wpas_process(dev[0]) dev[0].request("SET sae_groups ") id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE", scan_freq="2412") # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED # event has been delivered, so verify that wpa_supplicant has returned to # eloop before reading process memory. time.sleep(1) dev[0].ping() buf = read_process_memory(pid, password) dev[0].request("DISCONNECT") dev[0].wait_disconnected() dev[0].relog() sae_k = None sae_keyseed = None sae_kck = None pmk = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "SAE: k - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') sae_k = binascii.unhexlify(val) if "SAE: keyseed - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') sae_keyseed = binascii.unhexlify(val) if "SAE: KCK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') sae_kck = binascii.unhexlify(val) if "SAE: PMK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmk = binascii.unhexlify(val) if "WPA: PTK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') ptk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") kck = ptk[0:16] kek = ptk[16:32] tk = ptk[32:48] fname = os.path.join(params['logdir'], 'sae_key_lifetime_in_memory.memctx-') logger.info("Checking keys in memory while associated") get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") if password not in buf: raise HwsimSkip("Password not found while associated") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") if tk in buf: raise Exception("TK found from memory") if gtk in buf: get_key_locations(buf, gtk, "GTK") raise Exception("GTK found from memory") verify_not_present(buf, sae_k, fname, "SAE(k)") verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") verify_not_present(buf, sae_kck, fname, "SAE(KCK)") logger.info("Checking keys in memory after disassociation") buf = read_process_memory(pid, password) # Note: Password is still present in network configuration # Note: PMK is in PMKSA cache get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") verify_not_present(buf, sae_k, fname, "SAE(k)") verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") verify_not_present(buf, sae_kck, fname, "SAE(KCK)") dev[0].request("PMKSA_FLUSH") logger.info("Checking keys in memory after PMKSA cache flush") buf = read_process_memory(pid, password) get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") verify_not_present(buf, pmk, fname, "PMK") dev[0].request("REMOVE_NETWORK all") logger.info("Checking keys in memory after network profile removal") buf = read_process_memory(pid, password) get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") verify_not_present(buf, password, fname, "password") verify_not_present(buf, pmk, fname, "PMK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") verify_not_present(buf, sae_k, fname, "SAE(k)") verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
def test_erp_key_lifetime_in_memory(dev, apdev, params): """ERP and key lifetime in memory""" check_erp_capa(dev[0]) p = int_eap_server_params() p['erp_send_reauth_start'] = '1' p['erp_domain'] = 'example.com' p['eap_server_erp'] = '1' p['disable_pmksa_caching'] = '1' hapd = hostapd.add_ap(apdev[0], p) password = "******" pid = find_wpas_process(dev[0]) dev[0].request("ERP_FLUSH") dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="*****@*****.**", password=password, ca_cert="auth_serv/ca.pem", phase2="auth=PAP", erp="1", scan_freq="2412") # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED # event has been delivered, so verify that wpa_supplicant has returned to # eloop before reading process memory. time.sleep(1) dev[0].ping() password = password.encode() buf = read_process_memory(pid, password) dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=15) dev[0].relog() msk = None emsk = None rRK = None rIK = None pmk = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "EAP-TTLS: Derived key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') msk = binascii.unhexlify(val) if "EAP-TTLS: Derived EMSK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') emsk = binascii.unhexlify(val) if "EAP: ERP rRK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') rRK = binascii.unhexlify(val) if "EAP: ERP rIK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') rIK = binascii.unhexlify(val) if "WPA: PMK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmk = binascii.unhexlify(val) if "WPA: PTK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') ptk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not msk or not emsk or not rIK or not rRK or not pmk or not ptk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") kck = ptk[0:16] kek = ptk[16:32] tk = ptk[32:48] fname = os.path.join(params['logdir'], 'erp_key_lifetime_in_memory.memctx-') logger.info("Checking keys in memory while associated") get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") if password not in buf: raise HwsimSkip("Password not found while associated") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") #if tk in buf: # raise Exception("TK found from memory") logger.info("Checking keys in memory after disassociation") buf = read_process_memory(pid, password) # Note: Password is still present in network configuration # Note: PMK is in EAP fast re-auth data get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") if gtk in buf: get_key_locations(buf, gtk, "GTK") verify_not_present(buf, gtk, fname, "GTK") dev[0].request("RECONNECT") ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) if ev is None: raise Exception("EAP success timed out") if "EAP re-authentication completed successfully" not in ev: raise Exception("Did not use ERP") dev[0].wait_connected(timeout=15, error="Reconnection timed out") dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=15) dev[0].relog() pmk = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "WPA: PMK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmk = binascii.unhexlify(val) if "WPA: PTK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') ptk = binascii.unhexlify(val) if "WPA: GTK in EAPOL-Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not pmk or not ptk or not gtk: raise Exception("Could not find keys from debug log") kck = ptk[0:16] kek = ptk[16:32] tk = ptk[32:48] logger.info("Checking keys in memory after ERP and disassociation") buf = read_process_memory(pid, password) # Note: Password is still present in network configuration get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") dev[0].request("REMOVE_NETWORK all") logger.info("Checking keys in memory after network profile removal") buf = read_process_memory(pid, password) # Note: rRK and rIK are still in memory get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, password, fname, "password") verify_not_present(buf, pmk, fname, "PMK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") verify_not_present(buf, msk, fname, "MSK") verify_not_present(buf, emsk, fname, "EMSK") dev[0].request("ERP_FLUSH") logger.info("Checking keys in memory after ERP_FLUSH") buf = read_process_memory(pid, password) get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, rRK, fname, "rRK") verify_not_present(buf, rIK, fname, "rIK")
def test_ft_psk_key_lifetime_in_memory(dev, apdev, params): """WPA2-PSK-FT and key lifetime in memory""" ssid = "test-ft" passphrase = "04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0" psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d' pmk = binascii.unhexlify(psk) p = ft_params1(ssid=ssid, passphrase=passphrase) hapd0 = hostapd.add_ap(apdev[0], p) p = ft_params2(ssid=ssid, passphrase=passphrase) hapd1 = hostapd.add_ap(apdev[1], p) pid = find_wpas_process(dev[0]) dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2", scan_freq="2412") # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED # event has been delivered, so verify that wpa_supplicant has returned to # eloop before reading process memory. time.sleep(1) dev[0].ping() buf = read_process_memory(pid, pmk) dev[0].request("DISCONNECT") dev[0].wait_disconnected() dev[0].relog() pmkr0 = None pmkr1 = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "FT: PMK-R0 - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmkr0 = binascii.unhexlify(val) if "FT: PMK-R1 - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmkr1 = binascii.unhexlify(val) if "FT: KCK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') kck = binascii.unhexlify(val) if "FT: KEK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') kek = binascii.unhexlify(val) if "FT: TK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') tk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") logger.info("Checking keys in memory while associated") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if pmkr0 not in buf: raise HwsimSkip("PMK-R0 not found while associated") if pmkr1 not in buf: raise HwsimSkip("PMK-R1 not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") if tk in buf: raise Exception("TK found from memory") if gtk in buf: get_key_locations(buf, gtk, "GTK") raise Exception("GTK found from memory") logger.info("Checking keys in memory after disassociation") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") # Note: PMK/PSK is still present in network configuration fname = os.path.join(params['logdir'], 'ft_psk_key_lifetime_in_memory.memctx-') verify_not_present(buf, pmkr0, fname, "PMK-R0") verify_not_present(buf, pmkr1, fname, "PMK-R1") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") dev[0].request("REMOVE_NETWORK all") logger.info("Checking keys in memory after network profile removal") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") verify_not_present(buf, pmk, fname, "PMK") verify_not_present(buf, pmkr0, fname, "PMK-R0") verify_not_present(buf, pmkr1, fname, "PMK-R1") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK")
def test_erp_key_lifetime_in_memory(dev, apdev, params): """ERP and key lifetime in memory""" check_erp_capa(dev[0]) p = int_eap_server_params() p['erp_send_reauth_start'] = '1' p['erp_domain'] = 'example.com' p['eap_server_erp'] = '1' p['disable_pmksa_caching'] = '1' hapd = hostapd.add_ap(apdev[0]['ifname'], p) password = "******" pid = find_wpas_process(dev[0]) dev[0].request("ERP_FLUSH") dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="*****@*****.**", password=password, ca_cert="auth_serv/ca.pem", phase2="auth=PAP", erp="1", scan_freq="2412") # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED # event has been delivered, so verify that wpa_supplicant has returned to # eloop before reading process memory. time.sleep(1) dev[0].ping() buf = read_process_memory(pid, password) dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=15) dev[0].relog() msk = None emsk = None rRK = None rIK = None pmk = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "EAP-TTLS: Derived key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') msk = binascii.unhexlify(val) if "EAP-TTLS: Derived EMSK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') emsk = binascii.unhexlify(val) if "EAP: ERP rRK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') rRK = binascii.unhexlify(val) if "EAP: ERP rIK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') rIK = binascii.unhexlify(val) if "WPA: PMK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmk = binascii.unhexlify(val) if "WPA: PTK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') ptk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not msk or not emsk or not rIK or not rRK or not pmk or not ptk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") kck = ptk[0:16] kek = ptk[16:32] tk = ptk[32:48] fname = os.path.join(params['logdir'], 'erp_key_lifetime_in_memory.memctx-') logger.info("Checking keys in memory while associated") get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") if password not in buf: raise HwsimSkip("Password not found while associated") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") if tk in buf: raise Exception("TK found from memory") if gtk in buf: get_key_locations(buf, gtk, "GTK") raise Exception("GTK found from memory") logger.info("Checking keys in memory after disassociation") buf = read_process_memory(pid, password) # Note: Password is still present in network configuration # Note: PMK is in EAP fast re-auth data get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") dev[0].request("RECONNECT") ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) if ev is None: raise Exception("EAP success timed out") if "EAP re-authentication completed successfully" not in ev: raise Exception("Did not use ERP") dev[0].wait_connected(timeout=15, error="Reconnection timed out") dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=15) dev[0].relog() pmk = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "WPA: PMK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmk = binascii.unhexlify(val) if "WPA: PTK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') ptk = binascii.unhexlify(val) if "WPA: GTK in EAPOL-Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not pmk or not ptk or not gtk: raise Exception("Could not find keys from debug log") kck = ptk[0:16] kek = ptk[16:32] tk = ptk[32:48] logger.info("Checking keys in memory after ERP and disassociation") buf = read_process_memory(pid, password) # Note: Password is still present in network configuration get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") dev[0].request("REMOVE_NETWORK all") logger.info("Checking keys in memory after network profile removal") buf = read_process_memory(pid, password) # Note: rRK and rIK are still in memory get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, msk, "MSK") get_key_locations(buf, emsk, "EMSK") get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, password, fname, "password") verify_not_present(buf, pmk, fname, "PMK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") verify_not_present(buf, msk, fname, "MSK") verify_not_present(buf, emsk, fname, "EMSK") dev[0].request("ERP_FLUSH") logger.info("Checking keys in memory after ERP_FLUSH") buf = read_process_memory(pid, password) get_key_locations(buf, rRK, "rRK") get_key_locations(buf, rIK, "rIK") verify_not_present(buf, rRK, fname, "rRK") verify_not_present(buf, rIK, fname, "rIK")
def test_ft_psk_key_lifetime_in_memory(dev, apdev, params): """WPA2-PSK-FT and key lifetime in memory""" ssid = "test-ft" passphrase="04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0" psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d' pmk = binascii.unhexlify(psk) p = ft_params1(ssid=ssid, passphrase=passphrase) hapd0 = hostapd.add_ap(apdev[0], p) p = ft_params2(ssid=ssid, passphrase=passphrase) hapd1 = hostapd.add_ap(apdev[1], p) pid = find_wpas_process(dev[0]) dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2", scan_freq="2412") # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED # event has been delivered, so verify that wpa_supplicant has returned to # eloop before reading process memory. time.sleep(1) dev[0].ping() buf = read_process_memory(pid, pmk) dev[0].request("DISCONNECT") dev[0].wait_disconnected() dev[0].relog() pmkr0 = None pmkr1 = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "FT: PMK-R0 - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmkr0 = binascii.unhexlify(val) if "FT: PMK-R1 - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmkr1 = binascii.unhexlify(val) if "FT: KCK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') kck = binascii.unhexlify(val) if "FT: KEK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') kek = binascii.unhexlify(val) if "FT: TK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') tk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") logger.info("Checking keys in memory while associated") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if pmkr0 not in buf: raise HwsimSkip("PMK-R0 not found while associated") if pmkr1 not in buf: raise HwsimSkip("PMK-R1 not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") if tk in buf: raise Exception("TK found from memory") if gtk in buf: get_key_locations(buf, gtk, "GTK") raise Exception("GTK found from memory") logger.info("Checking keys in memory after disassociation") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") # Note: PMK/PSK is still present in network configuration fname = os.path.join(params['logdir'], 'ft_psk_key_lifetime_in_memory.memctx-') verify_not_present(buf, pmkr0, fname, "PMK-R0") verify_not_present(buf, pmkr1, fname, "PMK-R1") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") dev[0].request("REMOVE_NETWORK all") logger.info("Checking keys in memory after network profile removal") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") verify_not_present(buf, pmk, fname, "PMK") verify_not_present(buf, pmkr0, fname, "PMK-R0") verify_not_present(buf, pmkr1, fname, "PMK-R1") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK")