diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c index 02d20caf4..9a0a1e540 100644 --- a/src/eap_common/eap_sim_common.c +++ b/src/eap_common/eap_sim_common.c @@ -517,6 +517,7 @@ int eap_sim_parse_attr(const u8 *start, const u8 *end, break; case EAP_SIM_AT_RES: wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RES"); + attr->res_len_bits = WPA_GET_BE16(apos); apos += 2; alen -= 2; if (!aka || alen < EAP_AKA_MIN_RES_LEN || diff --git a/src/eap_common/eap_sim_common.h b/src/eap_common/eap_sim_common.h index 49d15cf37..98b632c00 100644 --- a/src/eap_common/eap_sim_common.h +++ b/src/eap_common/eap_sim_common.h @@ -137,6 +137,7 @@ struct eap_sim_attrs { const u8 *checkcode; size_t num_chal, version_list_len, encr_data_len; size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len; + size_t res_len_bits; size_t checkcode_len; enum eap_sim_id_req id_req; int notification, counter, selected_version, client_error_code; diff --git a/src/eap_server/eap_aka.c b/src/eap_server/eap_aka.c index 2d0696571..16c747b8b 100644 --- a/src/eap_server/eap_aka.c +++ b/src/eap_server/eap_aka.c @@ -666,10 +666,19 @@ static void eap_aka_process_challenge(struct eap_sm *sm, return; } - if (attr->res == NULL || attr->res_len != data->res_len || + /* + * AT_RES is padded, so verify that there is enough room for RES and + * that the RES length in bits matches with the expected RES. + */ + if (attr->res == NULL || attr->res_len < data->res_len || + attr->res_len_bits != data->res_len * 8 || os_memcmp(attr->res, data->res, data->res_len) != 0) { wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not " - "include valid AT_RES"); + "include valid AT_RES (attr len=%lu, res len=%lu " + "bits, expected %lu bits)", + (unsigned long) attr->res_len, + (unsigned long) attr->res_len_bits, + (unsigned long) data->res_len); data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; eap_aka_state(data, NOTIFICATION); return;