eap_aka.c
来自「最新的Host AP 新添加了许多pcmcia 的驱动」· C语言 代码 · 共 1,279 行 · 第 1/3 页
C
1,279 行
}#endif /* EAP_AKA_PRIME */ wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);}static struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm, struct eap_aka_data *data, u8 id){ struct eap_sim_msg *msg; wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Re-authentication"); if (os_get_random(data->nonce_s, EAP_SIM_NONCE_S_LEN)) return NULL; wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA: NONCE_S", data->nonce_s, EAP_SIM_NONCE_S_LEN); if (data->eap_method == EAP_TYPE_AKA_PRIME) { eap_aka_prime_derive_keys_reauth(data->k_re, data->counter, sm->identity, sm->identity_len, data->nonce_s, data->msk, data->emsk); } else { eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, data->emsk); eap_sim_derive_keys_reauth(data->counter, sm->identity, sm->identity_len, data->nonce_s, data->mk, data->msk, data->emsk); } msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method, EAP_AKA_SUBTYPE_REAUTHENTICATION); if (eap_aka_build_encr(sm, data, msg, data->counter, data->nonce_s)) { eap_sim_msg_free(msg); return NULL; } eap_aka_add_checkcode(data, msg); if (sm->eap_sim_aka_result_ind) { wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);}static struct wpabuf * eap_aka_build_notification(struct eap_sm *sm, struct eap_aka_data *data, u8 id){ struct eap_sim_msg *msg; wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Notification"); msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method, EAP_AKA_SUBTYPE_NOTIFICATION); wpa_printf(MSG_DEBUG, " AT_NOTIFICATION (%d)", data->notification); eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, data->notification, NULL, 0); if (data->use_result_ind) { if (data->reauth) { wpa_printf(MSG_DEBUG, " AT_IV"); wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA); wpa_printf(MSG_DEBUG, " *AT_COUNTER (%u)", data->counter); eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, NULL, 0); if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) { wpa_printf(MSG_WARNING, "EAP-AKA: Failed to " "encrypt AT_ENCR_DATA"); eap_sim_msg_free(msg); return NULL; } } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); } return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);}static struct wpabuf * eap_aka_buildReq(struct eap_sm *sm, void *priv, u8 id){ struct eap_aka_data *data = priv; data->auts_reported = 0; switch (data->state) { case IDENTITY: return eap_aka_build_identity(sm, data, id); case CHALLENGE: return eap_aka_build_challenge(sm, data, id); case REAUTH: return eap_aka_build_reauth(sm, data, id); case NOTIFICATION: return eap_aka_build_notification(sm, data, id); default: wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in " "buildReq", data->state); break; } return NULL;}static Boolean eap_aka_check(struct eap_sm *sm, void *priv, struct wpabuf *respData){ struct eap_aka_data *data = priv; const u8 *pos; size_t len; pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, respData, &len); if (pos == NULL || len < 3) { wpa_printf(MSG_INFO, "EAP-AKA: Invalid frame"); return TRUE; } return FALSE;}static Boolean eap_aka_subtype_ok(struct eap_aka_data *data, u8 subtype){ if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR || subtype == EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT) return FALSE; switch (data->state) { case IDENTITY: if (subtype != EAP_AKA_SUBTYPE_IDENTITY) { wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " "subtype %d", subtype); return TRUE; } break; case CHALLENGE: if (subtype != EAP_AKA_SUBTYPE_CHALLENGE && subtype != EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) { wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " "subtype %d", subtype); return TRUE; } break; case REAUTH: if (subtype != EAP_AKA_SUBTYPE_REAUTHENTICATION) { wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " "subtype %d", subtype); return TRUE; } break; case NOTIFICATION: if (subtype != EAP_AKA_SUBTYPE_NOTIFICATION) { wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " "subtype %d", subtype); return TRUE; } break; default: wpa_printf(MSG_INFO, "EAP-AKA: Unexpected state (%d) for " "processing a response", data->state); return TRUE; } return FALSE;}static void eap_aka_determine_identity(struct eap_sm *sm, struct eap_aka_data *data, int before_identity, int after_reauth){ const u8 *identity; size_t identity_len; int res; identity = NULL; identity_len = 0; if (after_reauth && data->reauth) { identity = data->reauth->identity; identity_len = data->reauth->identity_len; } else if (sm->identity && sm->identity_len > 0 && sm->identity[0] == EAP_AKA_PERMANENT_PREFIX) { identity = sm->identity; identity_len = sm->identity_len; } else { identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity, sm->identity_len, &identity_len); if (identity == NULL) { data->reauth = eap_sim_db_get_reauth_entry( sm->eap_sim_db_priv, sm->identity, sm->identity_len); if (data->reauth && data->reauth->aka_prime != (data->eap_method == EAP_TYPE_AKA_PRIME)) { wpa_printf(MSG_DEBUG, "EAP-AKA: Reauth data " "was for different AKA version"); data->reauth = NULL; } if (data->reauth) { wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast " "re-authentication"); identity = data->reauth->identity; identity_len = data->reauth->identity_len; data->counter = data->reauth->counter; if (data->eap_method == EAP_TYPE_AKA_PRIME) { os_memcpy(data->k_encr, data->reauth->k_encr, EAP_SIM_K_ENCR_LEN); os_memcpy(data->k_aut, data->reauth->k_aut, EAP_AKA_PRIME_K_AUT_LEN); os_memcpy(data->k_re, data->reauth->k_re, EAP_AKA_PRIME_K_RE_LEN); } else { os_memcpy(data->mk, data->reauth->mk, EAP_SIM_MK_LEN); } } } } if (identity == NULL || eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity, sm->identity_len) < 0) { if (before_identity) { wpa_printf(MSG_DEBUG, "EAP-AKA: Permanent user name " "not known - send AKA-Identity request"); eap_aka_state(data, IDENTITY); return; } else { wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown whether the " "permanent user name is known; try to use " "it"); /* eap_sim_db_get_aka_auth() will report failure, if * this identity is not known. */ } } wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity", identity, identity_len); if (!after_reauth && data->reauth) { eap_aka_state(data, REAUTH); return; } res = eap_sim_db_get_aka_auth(sm->eap_sim_db_priv, identity, identity_len, data->rand, data->autn, data->ik, data->ck, data->res, &data->res_len, sm); if (res == EAP_SIM_DB_PENDING) { wpa_printf(MSG_DEBUG, "EAP-AKA: AKA authentication data " "not yet available - pending request"); sm->method_pending = METHOD_PENDING_WAIT; return; }#ifdef EAP_AKA_PRIME if (data->eap_method == EAP_TYPE_AKA_PRIME) { /* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the * needed 6-octet SQN ^AK for CK',IK' derivation */ eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik, data->autn, data->network_name, data->network_name_len); }#endif /* EAP_AKA_PRIME */ data->reauth = NULL; data->counter = 0; /* reset re-auth counter since this is full auth */ if (res != 0) { wpa_printf(MSG_INFO, "EAP-AKA: Failed to get AKA " "authentication data for the peer"); data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; eap_aka_state(data, NOTIFICATION); return; } if (sm->method_pending == METHOD_PENDING_WAIT) { wpa_printf(MSG_DEBUG, "EAP-AKA: AKA authentication data " "available - abort pending wait"); sm->method_pending = METHOD_PENDING_NONE; } identity_len = sm->identity_len; while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') { wpa_printf(MSG_DEBUG, "EAP-AKA: Workaround - drop last null " "character from identity"); identity_len--; } wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation", sm->identity, identity_len); if (data->eap_method == EAP_TYPE_AKA_PRIME) { eap_aka_prime_derive_keys(identity, identity_len, data->ik, data->ck, data->k_encr, data->k_aut, data->k_re, data->msk, data->emsk); } else { eap_aka_derive_mk(sm->identity, identity_len, data->ik, data->ck, data->mk); eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, data->emsk); } eap_aka_state(data, CHALLENGE);}static void eap_aka_process_identity(struct eap_sm *sm, struct eap_aka_data *data, struct wpabuf *respData, struct eap_sim_attrs *attr){ wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Identity"); if (attr->mac || attr->iv || attr->encr_data) { wpa_printf(MSG_WARNING, "EAP-AKA: Unexpected attribute " "received in EAP-Response/AKA-Identity"); data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; eap_aka_state(data, NOTIFICATION); return; } if (attr->identity) { os_free(sm->identity); sm->identity = os_malloc(attr->identity_len); if (sm->identity) { os_memcpy(sm->identity, attr->identity, attr->identity_len); sm->identity_len = attr->identity_len; } } eap_aka_determine_identity(sm, data, 0, 0); if (eap_get_id(respData) == data->pending_id) { data->pending_id = -1; eap_aka_add_id_msg(data, respData); }}static int eap_aka_verify_mac(struct eap_aka_data *data, const struct wpabuf *req, const u8 *mac, const u8 *extra, size_t extra_len){ if (data->eap_method == EAP_TYPE_AKA_PRIME) return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra, extra_len); return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len);}static void eap_aka_process_challenge(struct eap_sm *sm, struct eap_aka_data *data, struct wpabuf *respData, struct eap_sim_attrs *attr){ const u8 *identity; size_t identity_len; wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Challenge");#ifdef EAP_AKA_PRIME#if 0 /* KDF negotiation; to be enabled only after more than one KDF is * supported */ if (data->eap_method == EAP_TYPE_AKA_PRIME && attr->kdf_count == 1 && attr->mac == NULL) { if (attr->kdf[0] != EAP_AKA_PRIME_KDF) { wpa_printf(MSG_WARNING, "EAP-AKA': Peer selected " "unknown KDF"); data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; eap_aka_state(data, NOTIFICATION); return; } data->kdf = attr->kdf[0]; /* Allow negotiation to continue with the selected KDF by * sending another Challenge message */ wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf); return; }#endif#endif /* EAP_AKA_PRIME */ if (attr->checkcode && eap_aka_verify_checkcode(data, attr->checkcode, attr->checkcode_len)) { wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " "message"); data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; eap_aka_state(data, NOTIFICATION); return; } if (attr->mac == NULL || eap_aka_verify_mac(data, respData, attr->mac, NULL, 0)) { wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " "did not include valid AT_MAC"); data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; eap_aka_state(data, NOTIFICATION); return; } /* * AT_RES is padded, so verify that there is enough room for RES and
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?