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

📄 wpa.c

📁 WPA在Linux下实现的原代码 WPA在Linux下实现的原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "				   "underflow (ie=%d len=%d pos=%d)",				   pos[0], pos[1], (int) (pos - buf));			wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",					buf, len);			ret = -1;			break;		}		if (*pos == RSN_INFO_ELEM) {			ie->rsn_ie = pos;			ie->rsn_ie_len = pos[1] + 2;		} else if (*pos == GENERIC_INFO_ELEM) {			ret = wpa_supplicant_parse_generic(pos, end, ie);			if (ret < 0)				break;			if (ret > 0) {				ret = 0;				break;			}		} else {			wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "				    "Key Data IE", pos, 2 + pos[1]);		}	}	return ret;}static int wpa_supplicant_get_pmk(struct wpa_sm *sm,				  const unsigned char *src_addr,				  const u8 *pmkid){	int abort_cached = 0;	if (pmkid && !sm->cur_pmksa) {		/* When using drivers that generate RSN IE, wpa_supplicant may		 * not have enough time to get the association information		 * event before receiving this 1/4 message, so try to find a		 * matching PMKSA cache entry here. */		sm->cur_pmksa = pmksa_cache_get(sm, src_addr, pmkid);		if (sm->cur_pmksa) {			wpa_printf(MSG_DEBUG, "RSN: found matching PMKID from "				   "PMKSA cache");		} else {			wpa_printf(MSG_DEBUG, "RSN: no matching PMKID found");			abort_cached = 1;		}	}	if (pmkid && sm->cur_pmksa &&	    memcmp(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {		wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);		wpa_sm_set_pmk_from_pmksa(sm);		wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",				sm->pmk, sm->pmk_len);		eapol_sm_notify_cached(sm->eapol);	} else if (sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X && sm->eapol) {		int res, pmk_len;		pmk_len = PMK_LEN;		res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);#ifdef EAP_LEAP		if (res) {			res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);			pmk_len = 16;		}#endif /* EAP_LEAP */		if (res == 0) {			wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "					"machines", sm->pmk, pmk_len);			sm->pmk_len = pmk_len;			pmksa_cache_add(sm, sm->pmk, pmk_len, src_addr,					sm->own_addr, sm->cur_ssid);			if (!sm->cur_pmksa && pmkid &&			    pmksa_cache_get(sm, src_addr, pmkid)) {				wpa_printf(MSG_DEBUG, "RSN: the new PMK "					   "matches with the PMKID");				abort_cached = 0;			}		} else {			wpa_msg(sm->ctx->ctx, MSG_WARNING,				"WPA: Failed to get master session key from "				"EAPOL state machines");			wpa_msg(sm->ctx->ctx, MSG_WARNING,				"WPA: Key handshake aborted");			if (sm->cur_pmksa) {				wpa_printf(MSG_DEBUG, "RSN: Cancelled PMKSA "					   "caching attempt");				sm->cur_pmksa = NULL;				abort_cached = 1;			} else {				return -1;			}		}	}	if (abort_cached && sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {		/* Send EAPOL-Start to trigger full EAP authentication. */		u8 *buf;		size_t buflen;		wpa_printf(MSG_DEBUG, "RSN: no PMKSA entry found - trigger "			   "full EAP authentication");		buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,					 NULL, 0, &buflen, NULL);		if (buf) {			wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,					  buf, buflen);			free(buf);		}		return -1;	}	return 0;}static int wpa_supplicant_send_2_of_4(struct wpa_sm *sm,				      const unsigned char *dst,				      const struct wpa_eapol_key *key,				      int ver){	size_t rlen;	struct wpa_eapol_key *reply;	struct wpa_ptk *ptk;	u8 buf[8], *rbuf, *wpa_ie;	int wpa_ie_len;	if (sm->assoc_wpa_ie == NULL) {		wpa_printf(MSG_WARNING, "WPA: No assoc_wpa_ie set - cannot "			   "generate msg 2/4");		return -1;	}	wpa_ie = sm->assoc_wpa_ie;	wpa_ie_len = sm->assoc_wpa_ie_len;	wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,				  NULL, sizeof(*reply) + wpa_ie_len,				  &rlen, (void *) &reply);	if (rbuf == NULL)		return -1;	reply->type = sm->proto == WPA_PROTO_RSN ?		EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;	WPA_PUT_BE16(reply->key_info,		     ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);	if (sm->proto == WPA_PROTO_RSN)		WPA_PUT_BE16(reply->key_length, 0);	else		memcpy(reply->key_length, key->key_length, 2);	memcpy(reply->replay_counter, key->replay_counter,	       WPA_REPLAY_COUNTER_LEN);	WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);	memcpy(reply + 1, wpa_ie, wpa_ie_len);	if (sm->renew_snonce) {		if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN)) {			wpa_msg(sm->ctx->ctx, MSG_WARNING,				"WPA: Failed to get random data for SNonce");			free(rbuf);			return -1;		}		sm->renew_snonce = 0;		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",			    sm->snonce, WPA_NONCE_LEN);	}	memcpy(reply->key_nonce, sm->snonce, WPA_NONCE_LEN);	/* Calculate PTK which will be stored as a temporary PTK until it has	 * been verified when processing message 3/4. */	ptk = &sm->tptk;	wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,		       sm->snonce, key->key_nonce,		       (u8 *) ptk, sizeof(*ptk));	/* Supplicant: swap tx/rx Mic keys */	memcpy(buf, ptk->u.auth.tx_mic_key, 8);	memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);	memcpy(ptk->u.auth.rx_mic_key, buf, 8);	sm->tptk_set = 1;	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");	wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,			   rbuf, rlen, reply->key_mic);	return 0;}static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,					  const unsigned char *src_addr,					  const struct wpa_eapol_key *key,					  u16 ver){	struct wpa_eapol_ie_parse ie;	if (wpa_sm_get_ssid(sm) == NULL) {		wpa_printf(MSG_WARNING, "WPA: No SSID info found (msg 1 of "			   "4).");		return;	}	wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from "		   MACSTR " (ver=%d)", MAC2STR(src_addr), ver);	memset(&ie, 0, sizeof(ie));	if (sm->proto == WPA_PROTO_RSN) {		/* RSN: msg 1/4 should contain PMKID for the selected PMK */		const u8 *buf = (const u8 *) (key + 1);		size_t len = WPA_GET_BE16(key->key_data_length);		wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", buf, len);		wpa_supplicant_parse_ies(buf, len, &ie);		if (ie.pmkid) {			wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "				    "Authenticator", ie.pmkid, PMKID_LEN);		}	}	if (wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid))		return;	if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver))		return;	memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);}static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx){	struct wpa_sm *sm = eloop_ctx;	rsn_preauth_candidate_process(sm);}static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,					    const u8 *addr, int secure){	wpa_msg(sm->ctx->ctx, MSG_INFO, "WPA: Key negotiation completed with "		MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),		wpa_cipher_txt(sm->pairwise_cipher),		wpa_cipher_txt(sm->group_cipher));	eloop_cancel_timeout(sm->ctx->scan, sm->ctx->ctx, NULL);	wpa_sm_cancel_auth_timeout(sm);	wpa_sm_set_state(sm, WPA_COMPLETED);	if (secure) {		/* MLME.SETPROTECTION.request(TA, Tx_Rx) */		eapol_sm_notify_portValid(sm->eapol, TRUE);		if (sm->key_mgmt == WPA_KEY_MGMT_PSK)			eapol_sm_notify_eap_success(sm->eapol, TRUE);		/*		 * Start preauthentication after a short wait to avoid a		 * possible race condition between the data receive and key		 * configuration after the 4-Way Handshake. This increases the		 * likelyhood of the first preauth EAPOL-Start frame getting to		 * the target AP.		 */		eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);	}	if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {		wpa_printf(MSG_DEBUG, "RSN: Authenticator accepted "			   "opportunistic PMKSA entry - marking it valid");		sm->cur_pmksa->opportunistic = 0;	}}static int wpa_supplicant_install_ptk(struct wpa_sm *sm,				      const struct wpa_eapol_key *key){	int keylen, rsclen;	wpa_alg alg;	const u8 *key_rsc;	u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };	wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.");	switch (sm->pairwise_cipher) {	case WPA_CIPHER_CCMP:		alg = WPA_ALG_CCMP;		keylen = 16;		rsclen = 6;		break;	case WPA_CIPHER_TKIP:		alg = WPA_ALG_TKIP;		keylen = 32;		rsclen = 6;		break;	case WPA_CIPHER_NONE:		wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: "			   "NONE - do not use pairwise keys");		return 0;	default:		wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise cipher %d",			   sm->pairwise_cipher);		return -1;	}	if (sm->proto == WPA_PROTO_RSN) {		key_rsc = null_rsc;	} else {		key_rsc = key->key_rsc;		wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);	}	if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,			   (u8 *) &sm->ptk.tk1, keylen) < 0) {		wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the "			   "driver.");		return -1;	}	return 0;}static int wpa_supplicant_check_group_cipher(int group_cipher,					     int keylen, int maxkeylen,					     int *key_rsc_len, wpa_alg *alg){	int ret = 0;	switch (group_cipher) {	case WPA_CIPHER_CCMP:		if (keylen != 16 || maxkeylen < 16) {			ret = -1;			break;		}		*key_rsc_len = 6;		*alg = WPA_ALG_CCMP;		break;	case WPA_CIPHER_TKIP:		if (keylen != 32 || maxkeylen < 32) {			ret = -1;			break;		}		*key_rsc_len = 6;		*alg = WPA_ALG_TKIP;		break;	case WPA_CIPHER_WEP104:		if (keylen != 13 || maxkeylen < 13) {			ret = -1;			break;		}		*key_rsc_len = 0;		*alg = WPA_ALG_WEP;		break;	case WPA_CIPHER_WEP40:		if (keylen != 5 || maxkeylen < 5) {			ret = -1;			break;		}		*key_rsc_len = 0;		*alg = WPA_ALG_WEP;		break;	default:		wpa_printf(MSG_WARNING, "WPA: Unsupported Group Cipher %d",			   group_cipher);		return -1;	}	if (ret < 0 ) {		wpa_printf(MSG_WARNING, "WPA: Unsupported %s Group Cipher key "			   "length %d (%d).",			   wpa_cipher_txt(group_cipher), keylen, maxkeylen);	}	return ret;}struct wpa_gtk_data {	wpa_alg alg;	int tx, key_rsc_len, keyidx;	u8 gtk[32];	int gtk_len;};static int wpa_supplicant_install_gtk(struct wpa_sm *sm,				      const struct wpa_gtk_data *gd,				      const u8 *key_rsc){	const u8 *_gtk = gd->gtk;	u8 gtk_buf[32];	wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);	wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "		   "(keyidx=%d tx=%d).", gd->keyidx, gd->tx);	wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);	if (sm->group_cipher == WPA_CIPHER_TKIP) {		/* Swap Tx/Rx keys for Michael MIC */		memcpy(gtk_buf, gd->gtk, 16);		memcpy(gtk_buf + 16, gd->gtk + 24, 8);		memcpy(gtk_buf + 24, gd->gtk + 16, 8);		_gtk = gtk_buf;	}	if (sm->pairwise_cipher == WPA_CIPHER_NONE) {		if (wpa_sm_set_key(sm, gd->alg,				   (u8 *) "\xff\xff\xff\xff\xff\xff",				   gd->keyidx, 1, key_rsc, gd->key_rsc_len,				   _gtk, gd->gtk_len) < 0) {			wpa_printf(MSG_WARNING, "WPA: Failed to set "				   "GTK to the driver (Group only).");			return -1;		}	} else if (wpa_sm_set_key(sm, gd->alg,				  (u8 *) "\xff\xff\xff\xff\xff\xff",				  gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,				  _gtk, gd->gtk_len) < 0) {		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "			   "the driver.");		return -1;	}	return 0;}static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,						int tx){	if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {		/* Ignore Tx bit for GTK if a pairwise key is used. One AP		 * seemed to set this bit (incorrectly, since Tx is only when		 * doing Group Key only APs) and without this workaround, the		 * data connection does not work because wpa_supplicant		 * configured non-zero keyidx to be used for unicast. */		wpa_printf(MSG_INFO, "WPA: Tx bit set for GTK, but pairwise "			   "keys are used - ignore Tx bit");		return 0;	}	return tx;}static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,				       const struct wpa_eapol_key *key,				       const u8 *gtk, int gtk_len,				       int key_info){	struct wpa_gtk_data gd;	/*	 * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x	 * GTK KDE format:	 * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]	 * Reserved [bits 0-7]	 * GTK	 */	memset(&gd, 0, sizeof(gd));	wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",

⌨️ 快捷键说明

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