diff options
Diffstat (limited to 'contrib/wpa_supplicant/eap_sim.c')
-rw-r--r-- | contrib/wpa_supplicant/eap_sim.c | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/contrib/wpa_supplicant/eap_sim.c b/contrib/wpa_supplicant/eap_sim.c index f7ce191..ca9d737 100644 --- a/contrib/wpa_supplicant/eap_sim.c +++ b/contrib/wpa_supplicant/eap_sim.c @@ -20,7 +20,7 @@ #include "eap_i.h" #include "wpa_supplicant.h" #include "config_ssid.h" -#include "sha1.h" +#include "crypto.h" #include "pcsc_funcs.h" #include "eap_sim_common.h" @@ -198,8 +198,7 @@ static void eap_sim_derive_mk(struct eap_sim_data *data, addr[4] = sel_ver; len[4] = 2; - sel_ver[0] = data->selected_version >> 8; - sel_ver[1] = data->selected_version & 0xff; + WPA_PUT_BE16(sel_ver, data->selected_version); /* MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */ sha1_vector(5, addr, len, data->mk); @@ -277,7 +276,7 @@ static int eap_sim_learn_ids(struct eap_sim_data *data, static u8 * eap_sim_client_error(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t *respDataLen, int err) { struct eap_sim_msg *msg; @@ -295,7 +294,7 @@ static u8 * eap_sim_client_error(struct eap_sm *sm, struct eap_sim_data *data, static u8 * eap_sim_response_start(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t *respDataLen, enum eap_sim_id_req id_req) { @@ -324,7 +323,7 @@ static u8 * eap_sim_response_start(struct eap_sm *sm, eap_sim_clear_identities(data, CLEAR_EAP_ID); wpa_printf(MSG_DEBUG, "Generating EAP-SIM Start (id=%d)", - req->identifier); + req->identifier); msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START); wpa_hexdump(MSG_DEBUG, " AT_NONCE_MT", @@ -349,13 +348,13 @@ static u8 * eap_sim_response_start(struct eap_sm *sm, static u8 * eap_sim_response_challenge(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t *respDataLen) { struct eap_sim_msg *msg; wpa_printf(MSG_DEBUG, "Generating EAP-SIM Challenge (id=%d)", - req->identifier); + req->identifier); msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE); wpa_printf(MSG_DEBUG, " AT_MAC"); @@ -368,7 +367,7 @@ static u8 * eap_sim_response_challenge(struct eap_sm *sm, static u8 * eap_sim_response_reauth(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t *respDataLen, int counter_too_small) { struct eap_sim_msg *msg; @@ -408,7 +407,7 @@ static u8 * eap_sim_response_reauth(struct eap_sm *sm, static u8 * eap_sim_response_notification(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t *respDataLen, u16 notification) { @@ -446,7 +445,7 @@ static u8 * eap_sim_response_notification(struct eap_sm *sm, static u8 * eap_sim_process_start(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, size_t reqDataLen, + const struct eap_hdr *req, size_t reqDataLen, size_t *respDataLen, struct eap_sim_attrs *attr) { @@ -524,7 +523,8 @@ static u8 * eap_sim_process_start(struct eap_sm *sm, struct eap_sim_data *data, static u8 * eap_sim_process_challenge(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, size_t reqDataLen, + const struct eap_hdr *req, + size_t reqDataLen, size_t *respDataLen, struct eap_sim_attrs *attr) { @@ -595,8 +595,9 @@ static u8 * eap_sim_process_challenge(struct eap_sm *sm, "derivation", identity, identity_len); eap_sim_derive_mk(data, identity, identity_len); eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk); - if (eap_sim_verify_mac(data->k_aut, (u8 *) req, reqDataLen, attr->mac, - data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { + if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen, + attr->mac, data->nonce_mt, + EAP_SIM_NONCE_MT_LEN)) { wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message " "used invalid AT_MAC"); return eap_sim_client_error(sm, data, req, respDataLen, @@ -610,14 +611,17 @@ static u8 * eap_sim_process_challenge(struct eap_sm *sm, CLEAR_EAP_ID); if (attr->encr_data) { - if (eap_sim_parse_encr(data->k_encr, attr->encr_data, - attr->encr_data_len, attr->iv, &eattr, - 0)) { + u8 *decrypted; + decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, + attr->encr_data_len, attr->iv, + &eattr, 0); + if (decrypted == NULL) { return eap_sim_client_error( sm, data, req, respDataLen, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } eap_sim_learn_ids(data, &eattr); + free(decrypted); } if (data->state != FAILURE) @@ -634,11 +638,12 @@ static u8 * eap_sim_process_challenge(struct eap_sm *sm, static int eap_sim_process_notification_reauth(struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t reqDataLen, struct eap_sim_attrs *attr) { struct eap_sim_attrs eattr; + u8 *decrypted; if (attr->encr_data == NULL || attr->iv == NULL) { wpa_printf(MSG_WARNING, "EAP-SIM: Notification message after " @@ -646,8 +651,10 @@ static int eap_sim_process_notification_reauth(struct eap_sim_data *data, return -1; } - if (eap_sim_parse_encr(data->k_encr, attr->encr_data, - attr->encr_data_len, attr->iv, &eattr, 0)) { + decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, + attr->encr_data_len, attr->iv, &eattr, + 0); + if (decrypted == NULL) { wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted " "data from notification message"); return -1; @@ -657,15 +664,17 @@ static int eap_sim_process_notification_reauth(struct eap_sim_data *data, wpa_printf(MSG_WARNING, "EAP-SIM: Counter in notification " "message does not match with counter in reauth " "message"); + free(decrypted); return -1; } + free(decrypted); return 0; } static int eap_sim_process_notification_auth(struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t reqDataLen, struct eap_sim_attrs *attr) { @@ -695,7 +704,7 @@ static int eap_sim_process_notification_auth(struct eap_sim_data *data, static u8 * eap_sim_process_notification(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t reqDataLen, size_t *respDataLen, struct eap_sim_attrs *attr) @@ -732,12 +741,13 @@ static u8 * eap_sim_process_notification(struct eap_sm *sm, static u8 * eap_sim_process_reauthentication(struct eap_sm *sm, struct eap_sim_data *data, - struct eap_hdr *req, + const struct eap_hdr *req, size_t reqDataLen, size_t *respDataLen, struct eap_sim_attrs *attr) { struct eap_sim_attrs eattr; + u8 *decrypted; wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Reauthentication"); @@ -749,7 +759,7 @@ static u8 * eap_sim_process_reauthentication(struct eap_sm *sm, } data->reauth = 1; - if (eap_sim_verify_mac(data->k_aut, (u8 *) req, reqDataLen, + if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen, attr->mac, (u8 *) "", 0)) { wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " "did not have valid AT_MAC"); @@ -764,8 +774,10 @@ static u8 * eap_sim_process_reauthentication(struct eap_sm *sm, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } - if (eap_sim_parse_encr(data->k_encr, attr->encr_data, - attr->encr_data_len, attr->iv, &eattr, 0)) { + decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, + attr->encr_data_len, attr->iv, &eattr, + 0); + if (decrypted == NULL) { wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted " "data from reauthentication message"); return eap_sim_client_error(sm, data, req, respDataLen, @@ -776,6 +788,7 @@ static u8 * eap_sim_process_reauthentication(struct eap_sm *sm, wpa_printf(MSG_INFO, "EAP-SIM: (encr) No%s%s in reauth packet", !eattr.nonce_s ? " AT_NONCE_S" : "", eattr.counter < 0 ? " AT_COUNTER" : ""); + free(decrypted); return eap_sim_client_error(sm, data, req, respDataLen, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } @@ -794,6 +807,7 @@ static u8 * eap_sim_process_reauthentication(struct eap_sm *sm, data->last_eap_identity_len = data->reauth_id_len; data->reauth_id = NULL; data->reauth_id_len = 0; + free(decrypted); return eap_sim_response_reauth(sm, data, req, respDataLen, 1); } data->counter = eattr.counter; @@ -818,19 +832,21 @@ static u8 * eap_sim_process_reauthentication(struct eap_sm *sm, "fast reauths performed - force fullauth"); eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); } + free(decrypted); return eap_sim_response_reauth(sm, data, req, respDataLen, 0); } static u8 * eap_sim_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, - u8 *reqData, size_t reqDataLen, + const u8 *reqData, size_t reqDataLen, size_t *respDataLen) { struct eap_sim_data *data = priv; struct wpa_ssid *config = eap_get_config(sm); - struct eap_hdr *req; - u8 *pos, subtype, *res; + const struct eap_hdr *req; + u8 subtype, *res; + const u8 *pos; struct eap_sim_attrs attr; size_t len; @@ -842,21 +858,19 @@ static u8 * eap_sim_process(struct eap_sm *sm, void *priv, return NULL; } - req = (struct eap_hdr *) reqData; - pos = (u8 *) (req + 1); - if (reqDataLen < sizeof(*req) + 4 || *pos != EAP_TYPE_SIM || - (len = be_to_host16(req->length)) > reqDataLen) { - wpa_printf(MSG_INFO, "EAP-SIM: Invalid frame"); + pos = eap_hdr_validate(EAP_TYPE_SIM, reqData, reqDataLen, &len); + if (pos == NULL || len < 1) { ret->ignore = TRUE; return NULL; } + req = (const struct eap_hdr *) reqData; + len = be_to_host16(req->length); ret->ignore = FALSE; - ret->methodState = METHOD_CONT; + ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; ret->allowNotifications = TRUE; - pos++; subtype = *pos++; wpa_printf(MSG_DEBUG, "EAP-SIM: Subtype=%d", subtype); pos += 2; /* Reserved */ @@ -901,7 +915,7 @@ done: ret->decision = DECISION_FAIL; ret->methodState = METHOD_DONE; } else if (data->state == SUCCESS) { - ret->decision = DECISION_UNCOND_SUCC; + ret->decision = DECISION_COND_SUCC; ret->methodState = METHOD_DONE; } |