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

📄 wpa.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
		 * 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;	}#ifdef CONFIG_IEEE80211R	if (wpa_key_mgmt_ft(sm->key_mgmt)) {		/* Prepare for the next transition */		wpa_ft_prepare_auth_request(sm);	}#endif /* CONFIG_IEEE80211R */}static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx){	struct wpa_sm *sm = eloop_ctx;	wpa_printf(MSG_DEBUG, "WPA: Request PTK rekeying");	wpa_sm_key_request(sm, 0, 1);}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;	}	if (sm->wpa_ptk_rekey) {		eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);		eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,				       sm, NULL);	}	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 len=%d).", gd->keyidx, gd->tx,		   gd->gtk_len);	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 */		os_memcpy(gtk_buf, gd->gtk, 16);		os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);		os_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, size_t gtk_len,				       int key_info){#ifndef CONFIG_NO_WPA2	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	 */	os_memset(&gd, 0, sizeof(gd));	wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",			gtk, gtk_len);	if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))		return -1;	gd.keyidx = gtk[0] & 0x3;	gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,						     !!(gtk[0] & BIT(2)));	gtk += 2;	gtk_len -= 2;	os_memcpy(gd.gtk, gtk, gtk_len);	gd.gtk_len = gtk_len;	if (wpa_supplicant_check_group_cipher(sm->group_cipher,					      gtk_len, gtk_len,					      &gd.key_rsc_len, &gd.alg) ||	    wpa_supplicant_install_gtk(sm, &gd, key->key_rsc)) {		wpa_printf(MSG_DEBUG, "RSN: Failed to install GTK");		return -1;	}	wpa_supplicant_key_neg_complete(sm, sm->bssid,					key_info & WPA_KEY_INFO_SECURE);	return 0;#else /* CONFIG_NO_WPA2 */	return -1;#endif /* CONFIG_NO_WPA2 */}static int ieee80211w_set_keys(struct wpa_sm *sm,			       struct wpa_eapol_ie_parse *ie){#ifdef CONFIG_IEEE80211W	if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)		return 0;	if (ie->igtk) {		const struct wpa_igtk_kde *igtk;		u16 keyidx;		if (ie->igtk_len != sizeof(*igtk))			return -1;		igtk = (const struct wpa_igtk_kde *) ie->igtk;		keyidx = WPA_GET_LE16(igtk->keyid);		wpa_printf(MSG_DEBUG, "WPA: IGTK keyid %d "			   "pn %02x%02x%02x%02x%02x%02x",			   keyidx, MAC2STR(igtk->pn));		wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",				igtk->igtk, WPA_IGTK_LEN);		if (keyidx > 4095) {			wpa_printf(MSG_WARNING, "WPA: Invalid IGTK KeyID %d",				   keyidx);			return -1;		}		if (wpa_sm_set_key(sm, WPA_ALG_IGTK,				   (u8 *) "\xff\xff\xff\xff\xff\xff",				   keyidx, 0, igtk->pn, sizeof(igtk->pn),				   igtk->igtk, WPA_IGTK_LEN) < 0) {			wpa_printf(MSG_WARNING, "WPA: Failed to configure IGTK"				   " to the driver");			return -1;		}	}	return 0;#else /* CONFIG_IEEE80211W */	return 0;#endif /* CONFIG_IEEE80211W */}static void wpa_report_ie_mismatch(struct wpa_sm *sm,				   const char *reason, const u8 *src_addr,				   const u8 *wpa_ie, size_t wpa_ie_len,				   const u8 *rsn_ie, size_t rsn_ie_len){	wpa_msg(sm->ctx->ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",		reason, MAC2STR(src_addr));	if (sm->ap_wpa_ie) {		wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",			    sm->ap_wpa_ie, sm->ap_wpa_ie_len);	}	if (wpa_ie) {		if (!sm->ap_wpa_ie) {			wpa_printf(MSG_INFO, "WPA: No WPA IE in "				   "Beacon/ProbeResp");		}		wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",			    wpa_ie, wpa_ie_len);	}	if (sm->ap_rsn_ie) {		wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",			    sm->ap_rsn_ie, sm->ap_rsn_ie_len);	}	if (rsn_ie) {		if (!sm->ap_rsn_ie) {			wpa_printf(MSG_INFO, "WPA: No RSN IE in "				   "Beacon/ProbeResp");		}		wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",			    rsn_ie, rsn_ie_len);	}	wpa_sm_disassociate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);}static int wpa_supplicant_validate_ie(struct wpa_sm *sm,				      const unsigned char *src_addr,				      struct wpa_eapol_ie_parse *ie){	if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {		wpa_printf(MSG_DEBUG, "WPA: No WPA/RSN IE for this AP known. "			   "Trying to get from scan results");		if (wpa_sm_get_beacon_ie(sm) < 0) {			wpa_printf(MSG_WARNING, "WPA: Could not find AP from "				   "the scan results");		} else {			wpa_printf(MSG_DEBUG, "WPA: Found the current AP from "				   "updated scan results");		}	}	if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&	    (sm->ap_wpa_ie || sm->ap_rsn_ie)) {		wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "				       "with IE in Beacon/ProbeResp (no IE?)",				       src_addr, ie->wpa_ie, ie->wpa_ie_len,				       ie->rsn_ie, ie->rsn_ie_len);		return -1;	}	if ((ie->wpa_ie && sm->ap_wpa_ie &&	     (ie->wpa_ie_len != sm->ap_wpa_ie_len ||	      os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||	    (ie->rsn_ie && sm->ap_rsn_ie &&	     (ie->rsn_ie_len != sm->ap_rsn_ie_len ||	      os_memcmp(ie->rsn_ie, sm->ap_rsn_ie, ie->rsn_ie_len) != 0))) {		wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "				       "with IE in Beacon/ProbeResp",				       src_addr, ie->wpa_ie, ie->wpa_ie_len,				       ie->rsn_ie, ie->rsn_ie_len);		return -1;	}	if (sm->proto == WPA_PROTO_WPA &&	    ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {		wpa_report_ie_mismatch(sm, "Possible downgrade attack "				       "detected - RSN was enabled and RSN IE "				       "was in msg 3/4, but not in "				       "Beacon/ProbeResp",				       src_addr, ie->wpa_ie, ie->wpa_ie_len,				       ie->rsn_ie, ie->rsn_ie_len);		return -1;	}#ifdef CONFIG_IEEE80211R	if (wpa_key_mgmt_ft(sm->key_mgmt)) {		struct rsn_mdie *mdie;		/* TODO: verify that full MDIE matches with the one from scan		 * results, not only mobility domain */		mdie = (struct rsn_mdie *) (ie->mdie + 2);		if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||		    os_memcmp(mdie->mobility_domain, sm->mobility_domain,			      MOBILITY_DOMAIN_ID_LEN) != 0) {			wpa_printf(MSG_DEBUG, "FT: MDIE in msg 3/4 did not "				   "match with the current mobility domain");			return -1;		}	}#endif /* CONFIG_IEEE80211R */	return 0;}/** * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake * @sm: Pointer to WPA state machine data from wpa_sm_init() * @dst: Destination address for the frame * @key: Pointer to the EAPOL-Key frame header * @ver: Version bits from EAPOL-Key Key Info * @key_info: Key Info * @kde: KDEs to include the EAPOL-Key frame * @kde_len: Length of KDEs * @ptk: PTK to use for keyed hash and encryption * Returns: 0 on success, -1 on failure */int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,			       const struct wpa_eapol_key *key,			       u16 ver, u16 key_info,			       const u8 *kde, size_t kde_len,			       struct wpa_ptk *ptk){	size_t rlen;	struct wpa_eapol_key *reply;	u8 *rbuf;	if (kde)		wpa_hexdump(MSG_DEBUG, "WPA: KDE for msg 4/4", kde, kde_len);	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,				  sizeof(*reply) + kde_len,				  &rlen, (void *) &reply);	if (rbuf == NULL)		return -1;	reply->type = sm->proto == WPA_PROTO_RSN ?		EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;	key_info &= WPA_KEY_INFO_SECURE;	key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC;	WPA_PUT_BE16(reply->key_info, key_info);	if (sm->proto == WPA_PROTO_RSN)		WPA_PUT_BE16(reply->key_length, 0);	else		os_memcpy(reply->key_length, key->key_length, 2);	os_memcpy(reply->replay_counter, key->replay_counter,		  WPA_REPLAY_COUNTER_LEN);	WPA_PUT_BE16(reply->key_data_length, kde_len);	if (kde)		os_memcpy(reply + 1, kde, kde_len);	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 4/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_3_of_4(struct wpa_sm *sm,					  const struct wpa_eapol_key *key,					  u16 ver){	u16 key_info, keylen, len;	const u8 *pos;	struct wpa_eapol_ie_parse ie;	wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);	wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from "

⌨️ 快捷键说明

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