diff --git a/src/eap_server/eap_server_sim.c b/src/eap_server/eap_server_sim.c index d67457bbf..c64b664f4 100644 --- a/src/eap_server/eap_server_sim.c +++ b/src/eap_server/eap_server_sim.c @@ -118,6 +118,13 @@ static struct wpabuf * eap_sim_build_start(struct eap_sm *sm, } else if (data->start_round > 3) { /* Cannot use more than three rounds of Start messages */ return NULL; + } else if (data->start_round == 0) { + /* + * This is a special case that is used to recover from + * AT_COUNTER_TOO_SMALL during re-authentication. Since we + * already know the identity of the peer, there is no need to + * request any identity in this case. + */ } else if (sm->identity && sm->identity_len > 0 && sm->identity[0] == EAP_SIM_REAUTH_ID_PREFIX) { /* Reauth id may have expired - try fullauth */ @@ -410,6 +417,14 @@ static void eap_sim_process_start(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "EAP-SIM: Receive start response"); + if (data->start_round == 0) { + /* + * Special case for AT_COUNTER_TOO_SMALL recovery - no identity + * was requested since we already know it. + */ + goto skip_id_update; + } + /* * We always request identity in SIM/Start, so the peer is required to * have replied with one. @@ -488,6 +503,7 @@ static void eap_sim_process_start(struct eap_sm *sm, return; } +skip_id_update: /* Full authentication */ if (attr->nonce_mt == NULL || attr->selected_version < 0) { @@ -624,6 +640,16 @@ static void eap_sim_process_reauth(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "EAP-SIM: Re-authentication response includes " "the correct AT_MAC"); + + if (eattr.counter_too_small) { + wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response " + "included AT_COUNTER_TOO_SMALL - starting full " + "authentication"); + data->start_round = -1; + eap_sim_state(data, START); + return; + } + if (sm->eap_sim_aka_result_ind && attr->result_ind) { data->use_result_ind = 1; data->notification = EAP_SIM_SUCCESS;