⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eap_aka.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	size_t identity_len = 0;	struct eap_sim_msg *msg;	data->reauth = 0;	if (id_req == ANY_ID && data->reauth_id) {		identity = data->reauth_id;		identity_len = data->reauth_id_len;		data->reauth = 1;	} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&		   data->pseudonym) {		identity = data->pseudonym;		identity_len = data->pseudonym_len;		eap_aka_clear_identities(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(data, CLEAR_PSEUDONYM |						 CLEAR_REAUTH_ID);		}	}	if (id_req != NO_ID_REQ)		eap_aka_clear_identities(data, CLEAR_EAP_ID);	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id);	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,			       EAP_AKA_SUBTYPE_IDENTITY);	if (identity) {		wpa_hexdump_ascii(MSG_DEBUG, "   AT_IDENTITY",				  identity, identity_len);		eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len,				identity, identity_len);	}	return eap_sim_msg_finish(msg, NULL, NULL, 0);}static struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data,						  u8 id){	struct eap_sim_msg *msg;	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id);	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,			       EAP_AKA_SUBTYPE_CHALLENGE);	wpa_printf(MSG_DEBUG, "   AT_RES");	eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,			data->res, data->res_len);	eap_aka_add_checkcode(data, msg);	if (data->use_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, (u8 *) "", 0);}static struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data,					       u8 id, int counter_too_small,					       const u8 *nonce_s){	struct eap_sim_msg *msg;	unsigned int counter;	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)",		   id);	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,			       EAP_AKA_SUBTYPE_REAUTHENTICATION);	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);	if (counter_too_small) {		wpa_printf(MSG_DEBUG, "   *AT_COUNTER_TOO_SMALL");		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0);		counter = data->counter_too_small;	} else		counter = data->counter;	wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", counter);	eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, 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;	}	eap_aka_add_checkcode(data, msg);	if (data->use_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, nonce_s,				  EAP_SIM_NONCE_S_LEN);}static struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data,						     u8 id, u16 notification){	struct eap_sim_msg *msg;	u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id);	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,			       EAP_AKA_SUBTYPE_NOTIFICATION);	if (k_aut && 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 %d", 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;		}	}	if (k_aut) {		wpa_printf(MSG_DEBUG, "   AT_MAC");		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);	}	return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);}static struct wpabuf * eap_aka_process_identity(struct eap_sm *sm,						struct eap_aka_data *data,						u8 id,						const struct wpabuf *reqData,						struct eap_sim_attrs *attr){	int id_error;	struct wpabuf *buf;	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity");	id_error = 0;	switch (attr->id_req) {	case NO_ID_REQ:		break;	case ANY_ID:		if (data->num_id_req > 0)			id_error++;		data->num_id_req++;		break;	case FULLAUTH_ID:		if (data->num_id_req > 1)			id_error++;		data->num_id_req++;		break;	case PERMANENT_ID:		if (data->num_id_req > 2)			id_error++;		data->num_id_req++;		break;	}	if (id_error) {		wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests "			   "used within one authentication");		return eap_aka_client_error(data, id,					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);	}	buf = eap_aka_response_identity(sm, data, id, attr->id_req);	if (data->prev_id != id) {		eap_aka_add_id_msg(data, reqData);		eap_aka_add_id_msg(data, buf);		data->prev_id = id;	}	return buf;}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);}#ifdef EAP_AKA_PRIMEstatic struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data,						u8 id, u16 kdf){	struct eap_sim_msg *msg;	data->kdf_negotiation = 1;	data->kdf = kdf;	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d) (KDF "		   "select)", id);	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,			       EAP_AKA_SUBTYPE_CHALLENGE);	wpa_printf(MSG_DEBUG, "   AT_KDF");	eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0);	return eap_sim_msg_finish(msg, NULL, NULL, 0);}static struct wpabuf * eap_aka_prime_kdf_neg(struct eap_aka_data *data,					     u8 id, struct eap_sim_attrs *attr){	size_t i;	for (i = 0; i < attr->kdf_count; i++) {		if (attr->kdf[i] == EAP_AKA_PRIME_KDF)			return eap_aka_prime_kdf_select(data, id,							EAP_AKA_PRIME_KDF);	}	/* No matching KDF found - fail authentication as if AUTN had been	 * incorrect */	return eap_aka_authentication_reject(data, id);}static int eap_aka_prime_kdf_valid(struct eap_aka_data *data,				   struct eap_sim_attrs *attr){	size_t i, j;	if (attr->kdf_count == 0)		return 0;	/* The only allowed (and required) duplication of a KDF is the addition	 * of the selected KDF into the beginning of the list. */	if (data->kdf_negotiation) {		if (attr->kdf[0] != data->kdf) {			wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "				   "accept the selected KDF");			return 0;		}		for (i = 1; i < attr->kdf_count; i++) {			if (attr->kdf[i] == data->kdf)				break;		}		if (i == attr->kdf_count &&		    attr->kdf_count < EAP_AKA_PRIME_KDF_MAX) {			wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "				   "duplicate the selected KDF");			return 0;		}		/* TODO: should check that the list is identical to the one		 * used in the previous Challenge message apart from the added		 * entry in the beginning. */	}	for (i = data->kdf ? 1 : 0; i < attr->kdf_count; i++) {		for (j = i + 1; j < attr->kdf_count; j++) {			if (attr->kdf[i] == attr->kdf[j]) {				wpa_printf(MSG_WARNING, "EAP-AKA': The server "					   "included a duplicated KDF");				return 0;			}		}	}	return 1;}#endif /* EAP_AKA_PRIME */static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,						 struct eap_aka_data *data,						 u8 id,						 const struct wpabuf *reqData,						 struct eap_sim_attrs *attr){	const u8 *identity;	size_t identity_len;	int res;	struct eap_sim_attrs eattr;	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge");	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");		return eap_aka_client_error(data, id,					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);	}#ifdef EAP_AKA_PRIME	if (data->eap_method == EAP_TYPE_AKA_PRIME) {		if (!attr->kdf_input || attr->kdf_input_len == 0) {			wpa_printf(MSG_WARNING, "EAP-AKA': Challenge message "				   "did not include non-empty AT_KDF_INPUT");			/* Fail authentication as if AUTN had been incorrect */			return eap_aka_authentication_reject(data, id);		}		os_free(data->network_name);		data->network_name = os_malloc(attr->kdf_input_len);		if (data->network_name == NULL) {			wpa_printf(MSG_WARNING, "EAP-AKA': No memory for "				   "storing Network Name");			return eap_aka_authentication_reject(data, id);		}		os_memcpy(data->network_name, attr->kdf_input,			  attr->kdf_input_len);		data->network_name_len = attr->kdf_input_len;		wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': Network Name "				  "(AT_KDF_INPUT)",				  data->network_name, data->network_name_len);		/* TODO: check Network Name per 3GPP.33.402 */		if (!eap_aka_prime_kdf_valid(data, attr))			return eap_aka_authentication_reject(data, id);		if (attr->kdf[0] != EAP_AKA_PRIME_KDF)			return eap_aka_prime_kdf_neg(data, id, attr);		data->kdf = EAP_AKA_PRIME_KDF;		wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf);	}	if (data->eap_method == EAP_TYPE_AKA && attr->bidding) {		u16 flags = WPA_GET_BE16(attr->bidding);		if ((flags & EAP_AKA_BIDDING_FLAG_D) &&		    eap_allowed_method(sm, EAP_VENDOR_IETF,				       EAP_TYPE_AKA_PRIME)) {			wpa_printf(MSG_WARNING, "EAP-AKA: Bidding down from "				   "AKA' to AKA detected");			/* Fail authentication as if AUTN had been incorrect */			return eap_aka_authentication_reject(data, id);		}	}#endif /* EAP_AKA_PRIME */	data->reauth = 0;	if (!attr->mac || !attr->rand || !attr->autn) {		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "			   "did not include%s%s%s",			   !attr->mac ? " AT_MAC" : "",			   !attr->rand ? " AT_RAND" : "",			   !attr->autn ? " AT_AUTN" : "");		return eap_aka_client_error(data, id,					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);	}	os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN);	os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN);	res = eap_aka_umts_auth(sm, data);	if (res == -1) {		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "			   "failed (AUTN)");		return eap_aka_authentication_reject(data, id);	} else if (res == -2) {		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "			   "failed (AUTN seq# -> AUTS)");		return eap_aka_synchronization_failure(data, id);	} else if (res) {		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed");		return eap_aka_client_error(data, id,					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);	}#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 */		u16 amf = WPA_GET_BE16(data->autn + 6);		if (!(amf & 0x8000)) {			wpa_printf(MSG_WARNING, "EAP-AKA': AMF separation bit "				   "not set (AMF=0x%4x)", amf);			return eap_aka_authentication_reject(data, id);		}		eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik,						 data->autn,						 data->network_name,						 data->network_name_len);	}#endif /* EAP_AKA_PRIME */	if (data->last_eap_identity) {		identity = data->last_eap_identity;		identity_len = data->last_eap_identity_len;	} else if (data->pseudonym) {		identity = data->pseudonym;		identity_len = data->pseudonym_len;	} else		identity = eap_get_config_identity(sm, &identity_len);	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "			  "derivation", 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(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);	}	if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "			   "used invalid AT_MAC");		return eap_aka_client_error(data, id,					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);	}	/* Old reauthentication and pseudonym identities must not be used	 * anymore. In other words, if no new identities are received, full	 * authentication will be used on next reauthentication. */	eap_aka_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |				 CLEAR_EAP_ID);	if (attr->encr_data) {		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_aka_client_error(				data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);		}		eap_aka_learn_ids(data, &eattr);		os_free(decrypted);	}	if (data->result_ind && attr->result_ind)		data->use_result_ind = 1;	if (data->state != FAILURE && data->state != RESULT_FAILURE) {		eap_aka_state(data, data->use_result_ind ?			      RESULT_SUCCESS : SUCCESS);	}	data->num_id_req = 0;	data->num_notification = 0;	/* RFC 4187 specifies that counter is initialized to one after	 * fullauth, but initializing it to zero makes it easier to implement	 * reauth verification. */	data->counter = 0;	return eap_aka_response_challenge(data, id);}static int eap_aka_process_notification_reauth(struct eap_aka_data *data,					       struct eap_sim_attrs *attr){	struct eap_sim_attrs eattr;	u8 *decrypted;	if (attr->encr_data == NULL || attr->iv == NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -