From 1c16b257a081e810caf2ca0926ff4f9e2bb9557c Mon Sep 17 00:00:00 2001 From: Mohit Sethi Date: Fri, 17 May 2019 14:40:30 +0300 Subject: [PATCH] EAP-SIM: Add Session-Id derivation during fast-reauth The Session-Id derivation for EAP-SIM in RFC 5247 only explained how the Session-Id is derived for regular authentication. Jouni reported it as an errata with text explaining how to derive it during fast reauthentication. This patch now exports the Session-Id for EAP-SIM during fast reauthentication based on this Session-Id = 0x12 || NONCE_S || MAC construction. Signed-off-by: Mohit Sethi --- src/eap_peer/eap_sim.c | 26 ++++++++++++++++++++++---- src/eap_server/eap_server_sim.c | 31 ++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c index ba5eea9dd..59a208b1f 100644 --- a/src/eap_peer/eap_sim.c +++ b/src/eap_peer/eap_sim.c @@ -32,6 +32,7 @@ struct eap_sim_data { u8 msk[EAP_SIM_KEYING_DATA_LEN]; u8 emsk[EAP_EMSK_LEN]; u8 rand[3][GSM_RAND_LEN]; + u8 reauth_mac[EAP_SIM_MAC_LEN]; int num_id_req, num_notification; u8 *pseudonym; @@ -958,6 +959,14 @@ static struct wpabuf * eap_sim_process_reauthentication( EAP_SIM_UNABLE_TO_PROCESS_PACKET); } + /* At this stage the received MAC has been verified. Use this MAC for + * reauth Session-Id calculation if all other checks pass. + * The peer does not use the local MAC but the received MAC in deriving + * Session-Id. */ + os_memcpy(data->reauth_mac, attr->mac, EAP_SIM_MAC_LEN); + wpa_hexdump(MSG_DEBUG, "EAP-SIM: Server MAC", + data->reauth_mac, EAP_SIM_MAC_LEN); + if (attr->encr_data == NULL || attr->iv == NULL) { wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " "message did not include encrypted data"); @@ -1216,15 +1225,24 @@ static u8 * eap_sim_get_session_id(struct eap_sm *sm, void *priv, size_t *len) if (data->state != SUCCESS) return NULL; - *len = 1 + data->num_chal * GSM_RAND_LEN + EAP_SIM_NONCE_MT_LEN; + if (!data->reauth) + *len = 1 + data->num_chal * GSM_RAND_LEN + EAP_SIM_NONCE_MT_LEN; + else + *len = 1 + EAP_SIM_NONCE_S_LEN + EAP_SIM_MAC_LEN; id = os_malloc(*len); if (id == NULL) return NULL; id[0] = EAP_TYPE_SIM; - os_memcpy(id + 1, data->rand, data->num_chal * GSM_RAND_LEN); - os_memcpy(id + 1 + data->num_chal * GSM_RAND_LEN, data->nonce_mt, - EAP_SIM_NONCE_MT_LEN); + if (!data->reauth) { + os_memcpy(id + 1, data->rand, data->num_chal * GSM_RAND_LEN); + os_memcpy(id + 1 + data->num_chal * GSM_RAND_LEN, + data->nonce_mt, EAP_SIM_NONCE_MT_LEN); + } else { + os_memcpy(id + 1, data->nonce_s, EAP_SIM_NONCE_S_LEN); + os_memcpy(id + 1 + EAP_SIM_NONCE_S_LEN, data->reauth_mac, + EAP_SIM_MAC_LEN); + } wpa_hexdump(MSG_DEBUG, "EAP-SIM: Derived Session-Id", id, *len); return id; diff --git a/src/eap_server/eap_server_sim.c b/src/eap_server/eap_server_sim.c index 128782735..66a087212 100644 --- a/src/eap_server/eap_server_sim.c +++ b/src/eap_server/eap_server_sim.c @@ -26,6 +26,7 @@ struct eap_sim_data { u8 kc[EAP_SIM_MAX_CHAL][EAP_SIM_KC_LEN]; u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN]; u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN]; + u8 reauth_mac[EAP_SIM_MAC_LEN]; int num_chal; enum { START, CHALLENGE, REAUTH, NOTIFICATION, SUCCESS, FAILURE @@ -249,6 +250,7 @@ static struct wpabuf * eap_sim_build_reauth(struct eap_sm *sm, struct eap_sim_data *data, u8 id) { struct eap_sim_msg *msg; + struct wpabuf *buf; wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Re-authentication"); @@ -278,7 +280,16 @@ static struct wpabuf * eap_sim_build_reauth(struct eap_sm *sm, wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); - return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, NULL, 0); + buf = eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, NULL, 0); + + /* Remember this MAC before sending it to the peer. This MAC is used for + * Session-Id calculation after receiving response from the peer and + * after all other checks pass. */ + os_memcpy(data->reauth_mac, + wpabuf_head(buf) + wpabuf_len(buf) - EAP_SIM_MAC_LEN, + EAP_SIM_MAC_LEN); + + return buf; } @@ -829,15 +840,25 @@ static u8 * eap_sim_get_session_id(struct eap_sm *sm, void *priv, size_t *len) if (data->state != SUCCESS) return NULL; - *len = 1 + data->num_chal * GSM_RAND_LEN + EAP_SIM_NONCE_MT_LEN; + if (!data->reauth) + *len = 1 + data->num_chal * GSM_RAND_LEN + EAP_SIM_NONCE_MT_LEN; + else + *len = 1 + EAP_SIM_NONCE_S_LEN + EAP_SIM_MAC_LEN; id = os_malloc(*len); if (id == NULL) return NULL; id[0] = EAP_TYPE_SIM; - os_memcpy(id + 1, data->rand, data->num_chal * GSM_RAND_LEN); - os_memcpy(id + 1 + data->num_chal * GSM_RAND_LEN, data->nonce_mt, - EAP_SIM_NONCE_MT_LEN); + if (!data->reauth) { + os_memcpy(id + 1, data->rand, data->num_chal * GSM_RAND_LEN); + os_memcpy(id + 1 + data->num_chal * GSM_RAND_LEN, + data->nonce_mt, EAP_SIM_NONCE_MT_LEN); + } else { + os_memcpy(id + 1, data->nonce_s, EAP_SIM_NONCE_S_LEN); + os_memcpy(id + 1 + EAP_SIM_NONCE_S_LEN, data->reauth_mac, + EAP_SIM_MAC_LEN); + + } wpa_hexdump(MSG_DEBUG, "EAP-SIM: Derived Session-Id", id, *len); return id;