[PATCH 1/2] EAP-PEAP: Fix TLS 1.3 cryptobinding key derivation

github at singe.za.net github at singe.za.net
Mon Oct 5 08:35:35 PDT 2026


From: Dominic White <singe-github at singe.za.net>

The authenticator derived 64 bytes for the PEAP tunnel key while the peer
derives EAP_TLS_KEY_LEN + EAP_EMSK_LEN bytes. TLS 1.3 exporter output depends
on the requested length, so these values differ and cryptobinding fails. Derive
the same amount of key material as the peer.

Extend the PEAP TLS 1.3 hwsim test to require cryptobinding.

Signed-off-by: Dominic White <singe-github at singe.za.net>
---
 src/eap_server/eap_server_peap.c | 12 +++++++-----
 tests/hwsim/test_ap_eap.py       |  2 +-
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c
index 66882c3e2..a4d4e4331 100644
--- a/src/eap_server/eap_server_peap.c
+++ b/src/eap_server/eap_server_peap.c
@@ -345,11 +345,13 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
 
 	/*
 	 * Tunnel key (TK) is the first 60 octets of the key generated by
-	 * phase 1 of PEAP (based on TLS).
+	 * phase 1 of PEAP (based on TLS). Derive the same amount of key
+	 * material as the peer; the TLS 1.3 exporter output depends on the
+	 * requested length.
 	 */
 	tk = eap_server_tls_derive_key(sm, &data->ssl, label,
 				       context, context_len,
-				       EAP_TLS_KEY_LEN);
+				       EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 	if (tk == NULL)
 		return -1;
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
@@ -362,7 +364,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
 		os_memcpy(data->cmk, tk + 40, 20);
 		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK from TK",
 				data->cmk, 20);
-		os_free(tk);
+		bin_clear_free(tk, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 		return 0;
 	}
 
@@ -382,13 +384,13 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
 			   isk, sizeof(isk), imck, sizeof(imck));
 	forced_memzero(isk, sizeof(isk));
 	if (res < 0) {
-		os_free(tk);
+		bin_clear_free(tk, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 		return -1;
 	}
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)",
 			imck, sizeof(imck));
 
-	os_free(tk);
+	bin_clear_free(tk, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 
 	os_memcpy(data->ipmk, imck, 40);
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK (S-IPMKj)", data->ipmk, 40);
diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py
index 399968678..29c702ff7 100644
--- a/tests/hwsim/test_ap_eap.py
+++ b/tests/hwsim/test_ap_eap.py
@@ -6345,7 +6345,7 @@ def test_ap_wpa2_eap_peap_13(dev, apdev):
     id = eap_connect(dev[0], hapd, "PEAP", "user",
                      anonymous_identity="peap", password="password",
                      ca_cert="auth_serv/ca.pem",
-                     phase1="tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0",
+                     phase1="tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0 crypto_binding=2",
                      phase2="auth=MSCHAPV2")
     ver = dev[0].get_status_field("eap_tls_version")
     if ver != "TLSv1.3":
-- 
2.54.0 (Apple Git-157)




More information about the Hostap mailing list