From: Vidyullatha Kanchanapally Date: Mon, 15 May 2017 14:28:25 +0000 (+0530) Subject: eap_proxy: Add support for deriving ERP information X-Git-Tag: hostap_2_7~1295 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8696e6170264115b0066d101214bb270377ae0a1;p=thirdparty%2Fhostap.git eap_proxy: Add support for deriving ERP information This commit adds support for deriving ERP key information in EAP Proxy based EAP method implementations. Signed-off-by: Jouni Malinen --- diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 28bb0442a..359701c37 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -568,11 +568,15 @@ void eap_peer_erp_free_keys(struct eap_sm *sm) } -static void eap_peer_erp_init(struct eap_sm *sm) +void eap_peer_erp_init(struct eap_sm *sm, u8 *ext_session_id, + size_t ext_session_id_len, u8 *ext_emsk, + size_t ext_emsk_len) { #ifdef CONFIG_ERP u8 *emsk = NULL; size_t emsk_len = 0; + u8 *session_id = NULL; + size_t session_id_len = 0; u8 EMSKname[EAP_EMSK_NAME_LEN]; u8 len[2], ctx[3]; char *realm; @@ -602,7 +606,13 @@ static void eap_peer_erp_init(struct eap_sm *sm) if (erp == NULL) goto fail; - emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len); + if (ext_emsk) { + emsk = ext_emsk; + emsk_len = ext_emsk_len; + } else { + emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len); + } + if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) { wpa_printf(MSG_DEBUG, "EAP: No suitable EMSK available for ERP"); @@ -611,10 +621,23 @@ static void eap_peer_erp_init(struct eap_sm *sm) wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len); + if (ext_session_id) { + session_id = ext_session_id; + session_id_len = ext_session_id_len; + } else { + session_id = sm->eapSessionId; + session_id_len = sm->eapSessionIdLen; + } + + if (!session_id || session_id_len == 0) { + wpa_printf(MSG_DEBUG, + "EAP: No suitable session id available for ERP"); + goto fail; + } + WPA_PUT_BE16(len, EAP_EMSK_NAME_LEN); - if (hmac_sha256_kdf(sm->eapSessionId, sm->eapSessionIdLen, "EMSK", - len, sizeof(len), - EMSKname, EAP_EMSK_NAME_LEN) < 0) { + if (hmac_sha256_kdf(session_id, session_id_len, "EMSK", len, + sizeof(len), EMSKname, EAP_EMSK_NAME_LEN) < 0) { wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname"); goto fail; } @@ -651,6 +674,7 @@ static void eap_peer_erp_init(struct eap_sm *sm) erp = NULL; fail: bin_clear_free(emsk, emsk_len); + bin_clear_free(ext_session_id, ext_session_id_len); bin_clear_free(erp, sizeof(*erp)); os_free(realm); #endif /* CONFIG_ERP */ @@ -807,7 +831,7 @@ SM_STATE(EAP, METHOD) sm->eapSessionId, sm->eapSessionIdLen); } if (config->erp && sm->m->get_emsk && sm->eapSessionId) - eap_peer_erp_init(sm); + eap_peer_erp_init(sm, NULL, 0, NULL, 0); } } diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h index 883ba2423..80fbbf260 100644 --- a/src/eap_peer/eap.h +++ b/src/eap_peer/eap.h @@ -363,6 +363,9 @@ int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config, const u8 **realm, size_t *realm_len, u16 *erp_seq_num, const u8 **rrk, size_t *rrk_len); int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 seq_num); +void eap_peer_erp_init(struct eap_sm *sm, u8 *ext_session_id, + size_t ext_session_id_len, u8 *ext_emsk, + size_t ext_emsk_len); #endif /* IEEE8021X_EAPOL */ diff --git a/src/eap_peer/eap_proxy.h b/src/eap_peer/eap_proxy.h index 7205fad44..95fd71f3c 100644 --- a/src/eap_peer/eap_proxy.h +++ b/src/eap_peer/eap_proxy.h @@ -46,4 +46,10 @@ int eap_proxy_get_imsi(struct eap_proxy_sm *eap_proxy, char *imsi_buf, int eap_proxy_notify_config(struct eap_proxy_sm *sm, struct eap_peer_config *config); +u8 * eap_proxy_get_eap_session_id(struct eap_proxy_sm *sm, size_t *len); + +u8 * eap_proxy_get_emsk(struct eap_proxy_sm *sm, size_t *len); + +void eap_proxy_sm_abort(struct eap_proxy_sm *sm); + #endif /* EAP_PROXY_H */ diff --git a/src/eap_peer/eap_proxy_dummy.c b/src/eap_peer/eap_proxy_dummy.c index 08009cab2..0cf647a55 100644 --- a/src/eap_peer/eap_proxy_dummy.c +++ b/src/eap_peer/eap_proxy_dummy.c @@ -75,3 +75,20 @@ int eap_proxy_notify_config(struct eap_proxy_sm *sm, { return -1; } + + +u8 * eap_proxy_get_eap_session_id(struct eap_proxy_sm *sm, size_t *len) +{ + return NULL; +} + + +u8 * eap_proxy_get_emsk(struct eap_proxy_sm *sm, size_t *len) +{ + return NULL; +} + + +void eap_proxy_sm_abort(struct eap_proxy_sm *sm) +{ +} diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index 81761b189..ade43d8ef 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -16,6 +16,7 @@ #include "crypto/md5.h" #include "common/eapol_common.h" #include "eap_peer/eap.h" +#include "eap_peer/eap_config.h" #include "eap_peer/eap_proxy.h" #include "eapol_supp_sm.h" @@ -492,9 +493,20 @@ SM_STATE(SUPP_BE, SUCCESS) #ifdef CONFIG_EAP_PROXY if (sm->use_eap_proxy) { if (eap_proxy_key_available(sm->eap_proxy)) { + u8 *session_id, *emsk; + size_t session_id_len, emsk_len; + /* New key received - clear IEEE 802.1X EAPOL-Key replay * counter */ sm->replay_counter_valid = FALSE; + + session_id = eap_proxy_get_eap_session_id( + sm->eap_proxy, &session_id_len); + emsk = eap_proxy_get_emsk(sm->eap_proxy, &emsk_len); + if (sm->config->erp && session_id && emsk) + eap_peer_erp_init(sm->eap, session_id, + session_id_len, emsk, + emsk_len); } return; } @@ -899,6 +911,9 @@ static void eapol_sm_abortSupp(struct eapol_sm *sm) wpabuf_free(sm->eapReqData); sm->eapReqData = NULL; eap_sm_abort(sm->eap); +#ifdef CONFIG_EAP_PROXY + eap_proxy_sm_abort(sm->eap_proxy); +#endif /* CONFIG_EAP_PROXY */ }