From 4e1cd3468e5003210b7ca13fafbc64486e5145f0 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 1 Feb 2019 23:52:28 +0200 Subject: [PATCH] EAP-PEAP: Derive EMSK and use 128-octet derivation for MSK Derive EMSK when using EAP-PEAP to enable ERP. In addition, change the MSK derivation for EAP-PEAP to always derive 128 octets of key material instead of the 64 octets to cover just the MSK. This is needed with the PRF used in TLS 1.3 since the output length is mixed into the PRF context. Signed-off-by: Jouni Malinen --- src/eap_peer/eap_peap.c | 36 ++++++++++++++++++++++++--- src/eap_server/eap_server_peap.c | 42 +++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c index 34075b1d9..9b87b6b94 100644 --- a/src/eap_peer/eap_peap.c +++ b/src/eap_peer/eap_peap.c @@ -1,6 +1,6 @@ /* * EAP peer method: EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt) - * Copyright (c) 2004-2015, Jouni Malinen + * Copyright (c) 2004-2019, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -169,7 +169,7 @@ static void * eap_peap_init(struct eap_sm *sm) static void eap_peap_free_key(struct eap_peap_data *data) { if (data->key_data) { - bin_clear_free(data->key_data, EAP_TLS_KEY_LEN); + bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); data->key_data = NULL; } } @@ -1081,12 +1081,18 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, "key derivation", label); data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, label, - EAP_TLS_KEY_LEN); + EAP_TLS_KEY_LEN + + EAP_EMSK_LEN); if (data->key_data) { wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Derived key", data->key_data, EAP_TLS_KEY_LEN); + wpa_hexdump_key(MSG_DEBUG, + "EAP-PEAP: Derived EMSK", + data->key_data + + EAP_TLS_KEY_LEN, + EAP_EMSK_LEN); } else { wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to " "derive key"); @@ -1264,6 +1270,29 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len) } +static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len) +{ + struct eap_peap_data *data = priv; + u8 *key; + + if (!data->key_data || !data->phase2_success) + return NULL; + + if (data->crypto_binding_used) { + /* [MS-PEAP] does not define EMSK derivation */ + return NULL; + } + + key = os_memdup(data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN); + if (!key) + return NULL; + + *len = EAP_EMSK_LEN; + + return key; +} + + static u8 * eap_peap_get_session_id(struct eap_sm *sm, void *priv, size_t *len) { struct eap_peap_data *data = priv; @@ -1296,6 +1325,7 @@ int eap_peer_peap_register(void) eap->process = eap_peap_process; eap->isKeyAvailable = eap_peap_isKeyAvailable; eap->getKey = eap_peap_getKey; + eap->get_emsk = eap_peap_get_emsk; eap->get_status = eap_peap_get_status; eap->has_reauth_data = eap_peap_has_reauth_data; eap->deinit_for_reauth = eap_peap_deinit_for_reauth; diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c index 18d31b527..97dba41c8 100644 --- a/src/eap_server/eap_server_peap.c +++ b/src/eap_server/eap_server_peap.c @@ -1,6 +1,6 @@ /* * hostapd / EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt) - * Copyright (c) 2004-2008, Jouni Malinen + * Copyright (c) 2004-2019, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -756,7 +756,7 @@ static void eap_peap_process_phase2_tlv(struct eap_sm *sm, } else { eap_peap_state(data, FAILURE); } - + } else if (status == EAP_TLV_RESULT_FAILURE) { wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Failure " "- requested %s", requested); @@ -1328,8 +1328,9 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len) /* TODO: PEAPv1 - different label in some cases */ eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, "client EAP encryption", - EAP_TLS_KEY_LEN); + EAP_TLS_KEY_LEN + EAP_EMSK_LEN); if (eapKeyData) { + os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN); *len = EAP_TLS_KEY_LEN; wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key", eapKeyData, EAP_TLS_KEY_LEN); @@ -1341,6 +1342,40 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len) } +static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len) +{ + struct eap_peap_data *data = priv; + u8 *eapKeyData, *emsk; + + if (data->state != SUCCESS) + return NULL; + + if (data->crypto_binding_used) { + /* [MS-PEAP] does not define EMSK derivation */ + return NULL; + } + + /* TODO: PEAPv1 - different label in some cases */ + eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, + "client EAP encryption", + EAP_TLS_KEY_LEN + EAP_EMSK_LEN); + if (eapKeyData) { + emsk = os_memdup(eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN); + bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); + if (!emsk) + return NULL; + *len = EAP_EMSK_LEN; + wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived EMSK", + emsk, EAP_EMSK_LEN); + } else { + wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive EMSK"); + emsk = NULL; + } + + return emsk; +} + + static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv) { struct eap_peap_data *data = priv; @@ -1376,6 +1411,7 @@ int eap_server_peap_register(void) eap->process = eap_peap_process; eap->isDone = eap_peap_isDone; eap->getKey = eap_peap_getKey; + eap->get_emsk = eap_peap_get_emsk; eap->isSuccess = eap_peap_isSuccess; eap->getSessionId = eap_peap_get_session_id;