[PATCHv2] EAP-TEAP: like EAP-FAST, reverse the order of the MS-MPPE keys

Alexander Clouter alex+hostapd at coremem.com
Tue Jul 5 01:18:37 PDT 2022


This gets us working with FreeRADIUS (which works for Win11).

Changes since v1:
 * comment fix from over-eager cut'n'pasting from src/eap_server/eap_server_fast.c (s/ISK/IMSK/)
 * whitespace

Signed-off-by: Alexander Clouter <alex at coremem.com>
---
 src/eap_common/eap_teap_common.c | 25 +++++++++++++++++++------
 src/eap_common/eap_teap_common.h |  1 +
 src/eap_peer/eap_teap.c          |  1 +
 src/eap_server/eap_server_teap.c |  1 +
 4 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/src/eap_common/eap_teap_common.c b/src/eap_common/eap_teap_common.c
index ffb9a6234..50fab73d7 100644
--- a/src/eap_common/eap_teap_common.c
+++ b/src/eap_common/eap_teap_common.c
@@ -143,6 +143,7 @@ int eap_teap_derive_cmk_basic_pw_auth(u16 tls_cs, const u8 *s_imck_msk, u8 *cmk)
 
 
 int eap_teap_derive_imck(u16 tls_cs,
+			 const int phase2_vendor, const u32 phase2_method,
 			 const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk,
 			 const u8 *msk, size_t msk_len,
 			 const u8 *emsk, size_t emsk_len,
@@ -204,12 +205,24 @@ int eap_teap_derive_imck(u16 tls_cs,
 	}
 
 	if (msk && msk_len > 0) {
-		size_t copy_len = msk_len;
-
-		os_memset(imsk, 0, 32); /* zero pad, if needed */
-		if (copy_len > 32)
-			copy_len = 32;
-		os_memcpy(imsk, msk, copy_len);
+		if (msk_len == 32 &&
+		    phase2_vendor == EAP_VENDOR_IETF &&
+		    phase2_method == EAP_TYPE_MSCHAPV2) {
+			/*
+			 * EAP-TEAP uses reverse order for MS-MPPE keys when deriving
+			 * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
+			 * IMSK for EAP-TEAP cryptobinding.
+			 */
+			os_memcpy(imsk, msk + 16, 16);
+			os_memcpy(imsk + 16, msk, 16);
+		} else {
+			size_t copy_len = msk_len;
+
+			os_memset(imsk, 0, 32); /* zero pad, if needed */
+			if (copy_len > 32)
+				copy_len = 32;
+			os_memcpy(imsk, msk, copy_len);
+		}
 		wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: IMSK from MSK", imsk, 32);
 	} else {
 		os_memset(imsk, 0, 32);
diff --git a/src/eap_common/eap_teap_common.h b/src/eap_common/eap_teap_common.h
index 3a2587949..382044e7a 100644
--- a/src/eap_common/eap_teap_common.h
+++ b/src/eap_common/eap_teap_common.h
@@ -208,6 +208,7 @@ int eap_teap_derive_eap_emsk(u16 tls_cs, const u8 *simck, u8 *emsk);
 int eap_teap_derive_cmk_basic_pw_auth(u16 tls_cs, const u8 *s_imck_msk,
 				      u8 *cmk);
 int eap_teap_derive_imck(u16 tls_cs,
+			 const int phase2_vendor, const u32 phase2_method,
 			 const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk,
 			 const u8 *msk, size_t msk_len,
 			 const u8 *emsk, size_t emsk_len,
diff --git a/src/eap_peer/eap_teap.c b/src/eap_peer/eap_teap.c
index bc7f6f4f5..42769eb64 100644
--- a/src/eap_peer/eap_teap.c
+++ b/src/eap_peer/eap_teap.c
@@ -767,6 +767,7 @@ static int eap_teap_get_cmk(struct eap_sm *sm, struct eap_teap_data *data,
 	}
 
 	res = eap_teap_derive_imck(data->tls_cs,
+				   data->phase2_method->vendor, data->phase2_method->method,
 				   data->simck_msk, data->simck_emsk,
 				   msk, msk_len, emsk, emsk_len,
 				   data->simck_msk, cmk_msk,
diff --git a/src/eap_server/eap_server_teap.c b/src/eap_server/eap_server_teap.c
index 691b44a8d..1ef4054f7 100644
--- a/src/eap_server/eap_server_teap.c
+++ b/src/eap_server/eap_server_teap.c
@@ -340,6 +340,7 @@ static int eap_teap_update_icmk(struct eap_sm *sm, struct eap_teap_data *data)
 	}
 
 	res = eap_teap_derive_imck(data->tls_cs,
+				   data->phase2_method->vendor, data->phase2_method->method,
 				   data->simck_msk, data->simck_emsk,
 				   msk, msk_len, emsk, emsk_len,
 				   data->simck_msk, data->cmk_msk,
-- 
2.35.1



More information about the Hostap mailing list