diff options
Diffstat (limited to 'src/eap_peer/eap_aka.c')
-rw-r--r-- | src/eap_peer/eap_aka.c | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c index a4441413f0dd..d50bc6186d91 100644 --- a/src/eap_peer/eap_aka.c +++ b/src/eap_peer/eap_aka.c @@ -31,6 +31,7 @@ struct eap_aka_data { u8 emsk[EAP_EMSK_LEN]; u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN]; u8 auts[EAP_AKA_AUTS_LEN]; + u8 reauth_mac[EAP_SIM_MAC_LEN]; int num_id_req, num_notification; u8 *pseudonym; @@ -622,15 +623,22 @@ static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm, identity_len = data->reauth_id_len; data->reauth = 1; } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) && - data->pseudonym) { + data->pseudonym && + !eap_sim_anonymous_username(data->pseudonym, + data->pseudonym_len)) { identity = data->pseudonym; identity_len = data->pseudonym_len; eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID); } else if (id_req != NO_ID_REQ) { identity = eap_get_config_identity(sm, &identity_len); if (identity) { - eap_aka_clear_identities(sm, data, CLEAR_PSEUDONYM | - CLEAR_REAUTH_ID); + int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID; + + if (data->pseudonym && + eap_sim_anonymous_username(data->pseudonym, + data->pseudonym_len)) + ids &= ~CLEAR_PSEUDONYM; + eap_aka_clear_identities(sm, data, ids); } } if (id_req != NO_ID_REQ) @@ -924,8 +932,13 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm, attr->checkcode_len)) { wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " "message"); +#ifdef TEST_FUZZ + wpa_printf(MSG_INFO, + "TEST: Ignore AT_CHECKCODE mismatch for fuzz testing"); +#else /* TEST_FUZZ */ return eap_aka_client_error(data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET); +#endif /* TEST_FUZZ */ } #ifdef EAP_AKA_PRIME @@ -1026,7 +1039,9 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm, if (data->last_eap_identity) { identity = data->last_eap_identity; identity_len = data->last_eap_identity_len; - } else if (data->pseudonym) { + } else if (data->pseudonym && + !eap_sim_anonymous_username(data->pseudonym, + data->pseudonym_len)) { identity = data->pseudonym; identity_len = data->pseudonym_len; } else { @@ -1055,8 +1070,13 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm, if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " "used invalid AT_MAC"); +#ifdef TEST_FUZZ + wpa_printf(MSG_INFO, + "TEST: Ignore AT_MAC mismatch for fuzz testing"); +#else /* TEST_FUZZ */ return eap_aka_client_error(data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET); +#endif /* TEST_FUZZ */ } /* Old reauthentication identity must not be used anymore. In @@ -1205,8 +1225,13 @@ static struct wpabuf * eap_aka_process_reauthentication( if (attr->checkcode && eap_aka_verify_checkcode(data, attr->checkcode, attr->checkcode_len)) { +#ifdef TEST_FUZZ + wpa_printf(MSG_INFO, + "TEST: Ignore AT_CHECKCODE mismatch for fuzz testing"); +#else /* TEST_FUZZ */ wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " "message"); +#endif /* TEST_FUZZ */ return eap_aka_client_error(data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET); } @@ -1226,6 +1251,14 @@ static struct wpabuf * eap_aka_process_reauthentication( EAP_AKA_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-AKA: Server MAC", + data->reauth_mac, EAP_SIM_MAC_LEN); + if (attr->encr_data == NULL || attr->iv == NULL) { wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " "message did not include encrypted data"); @@ -1497,14 +1530,24 @@ static u8 * eap_aka_get_session_id(struct eap_sm *sm, void *priv, size_t *len) if (data->state != SUCCESS) return NULL; - *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN; + if (!data->reauth) + *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN; + else + *len = 1 + EAP_SIM_NONCE_S_LEN + EAP_SIM_MAC_LEN; id = os_malloc(*len); if (id == NULL) return NULL; id[0] = data->eap_method; - os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN); - os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, EAP_AKA_AUTN_LEN); + if (!data->reauth) { + os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN); + os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, + EAP_AKA_AUTN_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-AKA: Derived Session-Id", id, *len); return id; |