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

📄 wpa.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct ieee802_1x_hdr *hdr;	struct wpa_eapol_key *key;	u16 key_info, ver;	u8 *tmp;	int ret = -1;	struct wpa_peerkey *peerkey = NULL;#ifdef CONFIG_IEEE80211R	sm->ft_completed = 0;#endif /* CONFIG_IEEE80211R */	if (len < sizeof(*hdr) + sizeof(*key)) {		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short to be a WPA "			   "EAPOL-Key (len %lu, expecting at least %lu)",			   (unsigned long) len,			   (unsigned long) sizeof(*hdr) + sizeof(*key));		return 0;	}	tmp = os_malloc(len);	if (tmp == NULL)		return -1;	os_memcpy(tmp, buf, len);	hdr = (struct ieee802_1x_hdr *) tmp;	key = (struct wpa_eapol_key *) (hdr + 1);	plen = be_to_host16(hdr->length);	data_len = plen + sizeof(*hdr);	wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%lu",		   hdr->version, hdr->type, (unsigned long) plen);	if (hdr->version < EAPOL_VERSION) {		/* TODO: backwards compatibility */	}	if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame (type %u) discarded, "			"not a Key frame", hdr->type);		ret = 0;		goto out;	}	if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) {		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %lu "			   "invalid (frame size %lu)",			   (unsigned long) plen, (unsigned long) len);		ret = 0;		goto out;	}	if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)	{		wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key type (%d) unknown, "			   "discarded", key->type);		ret = 0;		goto out;	}	wpa_eapol_key_dump(key);	eapol_sm_notify_lower_layer_success(sm->eapol, 0);	wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", tmp, len);	if (data_len < len) {		wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE "			   "802.1X data", (unsigned long) len - data_len);	}	key_info = WPA_GET_BE16(key->key_info);	ver = key_info & WPA_KEY_INFO_TYPE_MASK;	if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)	    ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */	    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {		wpa_printf(MSG_INFO, "WPA: Unsupported EAPOL-Key descriptor "			   "version %d.", ver);		goto out;	}#ifdef CONFIG_IEEE80211R	if (wpa_key_mgmt_ft(sm->key_mgmt)) {		/* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */		if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {			wpa_printf(MSG_INFO, "FT: AP did not use "				   "AES-128-CMAC.");			goto out;		}	} else#endif /* CONFIG_IEEE80211R */#ifdef CONFIG_IEEE80211W	if (wpa_key_mgmt_sha256(sm->key_mgmt)) {		if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {			wpa_printf(MSG_INFO, "WPA: AP did not use the "				   "negotiated AES-128-CMAC.");			goto out;		}	} else#endif /* CONFIG_IEEE80211W */	if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&	    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {		wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key "			   "descriptor version (%d) is not 2.", ver);		if (sm->group_cipher != WPA_CIPHER_CCMP &&		    !(key_info & WPA_KEY_INFO_KEY_TYPE)) {			/* Earlier versions of IEEE 802.11i did not explicitly			 * require version 2 descriptor for all EAPOL-Key			 * packets, so allow group keys to use version 1 if			 * CCMP is not used for them. */			wpa_printf(MSG_INFO, "WPA: Backwards compatibility: "				   "allow invalid version for non-CCMP group "				   "keys");		} else			goto out;	}#ifdef CONFIG_PEERKEY	for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {		if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)			break;	}	if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {		if (!peerkey->initiator && peerkey->replay_counter_set &&		    os_memcmp(key->replay_counter, peerkey->replay_counter,			      WPA_REPLAY_COUNTER_LEN) <= 0) {			wpa_printf(MSG_WARNING, "RSN: EAPOL-Key Replay "				   "Counter did not increase (STK) - dropping "				   "packet");			goto out;		} else if (peerkey->initiator) {			u8 _tmp[WPA_REPLAY_COUNTER_LEN];			os_memcpy(_tmp, key->replay_counter,				  WPA_REPLAY_COUNTER_LEN);			inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);			if (os_memcmp(_tmp, peerkey->replay_counter,				      WPA_REPLAY_COUNTER_LEN) != 0) {				wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key Replay "					   "Counter did not match (STK) - "					   "dropping packet");				goto out;			}		}	}	if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {		wpa_printf(MSG_INFO, "RSN: Ack bit in key_info from STK peer");		goto out;	}#endif /* CONFIG_PEERKEY */	if (!peerkey && sm->rx_replay_counter_set &&	    os_memcmp(key->replay_counter, sm->rx_replay_counter,		      WPA_REPLAY_COUNTER_LEN) <= 0) {		wpa_printf(MSG_WARNING, "WPA: EAPOL-Key Replay Counter did not"			   " increase - dropping packet");		goto out;	}	if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))#ifdef CONFIG_PEERKEY	    && (peerkey == NULL || !peerkey->initiator)#endif /* CONFIG_PEERKEY */		) {		wpa_printf(MSG_INFO, "WPA: No Ack bit in key_info");		goto out;	}	if (key_info & WPA_KEY_INFO_REQUEST) {		wpa_printf(MSG_INFO, "WPA: EAPOL-Key with Request bit - "			   "dropped");		goto out;	}	if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&	    wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))		goto out;#ifdef CONFIG_PEERKEY	if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&	    peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp, data_len))		goto out;#endif /* CONFIG_PEERKEY */	extra_len = data_len - sizeof(*hdr) - sizeof(*key);	if (WPA_GET_BE16(key->key_data_length) > extra_len) {		wpa_msg(sm->ctx->ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "			"frame - key_data overflow (%d > %lu)",			WPA_GET_BE16(key->key_data_length),			(unsigned long) extra_len);		goto out;	}	extra_len = WPA_GET_BE16(key->key_data_length);	if (sm->proto == WPA_PROTO_RSN &&	    (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {		if (wpa_supplicant_decrypt_key_data(sm, key, ver))			goto out;		extra_len = WPA_GET_BE16(key->key_data_length);	}	if (key_info & WPA_KEY_INFO_KEY_TYPE) {		if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {			wpa_printf(MSG_WARNING, "WPA: Ignored EAPOL-Key "				   "(Pairwise) with non-zero key index");			goto out;		}		if (peerkey) {			/* PeerKey 4-Way Handshake */			peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver);		} else if (key_info & WPA_KEY_INFO_MIC) {			/* 3/4 4-Way Handshake */			wpa_supplicant_process_3_of_4(sm, key, ver);		} else {			/* 1/4 4-Way Handshake */			wpa_supplicant_process_1_of_4(sm, src_addr, key,						      ver);		}	} else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {		/* PeerKey SMK Handshake */		peerkey_rx_eapol_smk(sm, src_addr, key, extra_len, key_info,				     ver);	} else {		if (key_info & WPA_KEY_INFO_MIC) {			/* 1/2 Group Key Handshake */			wpa_supplicant_process_1_of_2(sm, src_addr, key,						      extra_len, ver);		} else {			wpa_printf(MSG_WARNING, "WPA: EAPOL-Key (Group) "				   "without Mic bit - dropped");		}	}	ret = 1;out:	os_free(tmp);	return ret;}#ifdef CONFIG_CTRL_IFACEstatic int wpa_cipher_bits(int cipher){	switch (cipher) {	case WPA_CIPHER_CCMP:		return 128;	case WPA_CIPHER_TKIP:		return 256;	case WPA_CIPHER_WEP104:		return 104;	case WPA_CIPHER_WEP40:		return 40;	default:		return 0;	}}static u32 wpa_key_mgmt_suite(struct wpa_sm *sm){	switch (sm->key_mgmt) {	case WPA_KEY_MGMT_IEEE8021X:		return (sm->proto == WPA_PROTO_RSN ?			RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :			WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);	case WPA_KEY_MGMT_PSK:		return (sm->proto == WPA_PROTO_RSN ?			RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :			WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);#ifdef CONFIG_IEEE80211R	case WPA_KEY_MGMT_FT_IEEE8021X:		return RSN_AUTH_KEY_MGMT_FT_802_1X;	case WPA_KEY_MGMT_FT_PSK:		return RSN_AUTH_KEY_MGMT_FT_PSK;#endif /* CONFIG_IEEE80211R */#ifdef CONFIG_IEEE80211W	case WPA_KEY_MGMT_IEEE8021X_SHA256:		return RSN_AUTH_KEY_MGMT_802_1X_SHA256;	case WPA_KEY_MGMT_PSK_SHA256:		return RSN_AUTH_KEY_MGMT_PSK_SHA256;#endif /* CONFIG_IEEE80211W */	case WPA_KEY_MGMT_WPA_NONE:		return WPA_AUTH_KEY_MGMT_NONE;	default:		return 0;	}}static u32 wpa_cipher_suite(struct wpa_sm *sm, int cipher){	switch (cipher) {	case WPA_CIPHER_CCMP:		return (sm->proto == WPA_PROTO_RSN ?			RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);	case WPA_CIPHER_TKIP:		return (sm->proto == WPA_PROTO_RSN ?			RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);	case WPA_CIPHER_WEP104:		return (sm->proto == WPA_PROTO_RSN ?			RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);	case WPA_CIPHER_WEP40:		return (sm->proto == WPA_PROTO_RSN ?			RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);	case WPA_CIPHER_NONE:		return (sm->proto == WPA_PROTO_RSN ?			RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);	default:		return 0;	}}#define RSN_SUITE "%02x-%02x-%02x-%d"#define RSN_SUITE_ARG(s) \((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff/** * wpa_sm_get_mib - Dump text list of MIB entries * @sm: Pointer to WPA state machine data from wpa_sm_init() * @buf: Buffer for the list * @buflen: Length of the buffer * Returns: Number of bytes written to buffer * * This function is used fetch dot11 MIB variables. */int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen){	char pmkid_txt[PMKID_LEN * 2 + 1];	int rsna, ret;	size_t len;	if (sm->cur_pmksa) {		wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),				 sm->cur_pmksa->pmkid, PMKID_LEN);	} else		pmkid_txt[0] = '\0';	if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||	     wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&	    sm->proto == WPA_PROTO_RSN)		rsna = 1;	else		rsna = 0;	ret = os_snprintf(buf, buflen,			  "dot11RSNAOptionImplemented=TRUE\n"			  "dot11RSNAPreauthenticationImplemented=TRUE\n"			  "dot11RSNAEnabled=%s\n"			  "dot11RSNAPreauthenticationEnabled=%s\n"			  "dot11RSNAConfigVersion=%d\n"			  "dot11RSNAConfigPairwiseKeysSupported=5\n"			  "dot11RSNAConfigGroupCipherSize=%d\n"			  "dot11RSNAConfigPMKLifetime=%d\n"			  "dot11RSNAConfigPMKReauthThreshold=%d\n"			  "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"			  "dot11RSNAConfigSATimeout=%d\n",			  rsna ? "TRUE" : "FALSE",			  rsna ? "TRUE" : "FALSE",			  RSN_VERSION,			  wpa_cipher_bits(sm->group_cipher),			  sm->dot11RSNAConfigPMKLifetime,			  sm->dot11RSNAConfigPMKReauthThreshold,			  sm->dot11RSNAConfigSATimeout);	if (ret < 0 || (size_t) ret >= buflen)		return 0;	len = ret;	ret = os_snprintf(		buf + len, buflen - len,		"dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"		"dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"		"dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"		"dot11RSNAPMKIDUsed=%s\n"		"dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"		"dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"		"dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"		"dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"		"dot11RSNA4WayHandshakeFailures=%u\n",		RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),		RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->pairwise_cipher)),		RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->group_cipher)),		pmkid_txt,		RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),		RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->pairwise_cipher)),		RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->group_cipher)),		sm->dot11RSNA4WayHandshakeFailures);	if (ret >= 0 && (size_t) ret < buflen)		len += ret;	return (int) len;}#endif /* CONFIG_CTRL_IFACE */static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,				 void *ctx, int replace){	struct wpa_sm *sm = ctx;	if (sm->cur_pmksa == entry ||	    (sm->pmk_len == entry->pmk_len &&	     os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {		wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA entry");		sm->cur_pmksa = NULL;		if (replace) {			/* A new entry is being added, so no need to			 * deauthenticate in this case. This happens when EAP			 * authentication is completed again (reauth or failed			 * PMKSA caching attempt). */			return;		}		os_memset(sm->pmk, 0, sizeof(sm->pmk));		wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);	}}/** * wpa_sm_init - Initialize WPA state machine * @ctx: Context pointer for callbacks; this needs to be an allocated buffer * Returns: Pointer to the allocated WPA state machine data * * This function is used to allocate a new WPA state machine and the returned * value is passed to all WPA state machine calls. */struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx){	struct wpa_sm *sm;	sm = os_zalloc(sizeof(*sm));	if (sm == NULL)		return NULL;	sm->renew_snonce = 1;	sm->ctx = ctx;	sm->dot11RSNAConfigPMKLifetime = 43200;	sm->dot11RSNAConfigPMKReauthThreshold = 70;	sm->dot11RSNAConfigSATimeout = 60;	sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);	if (sm->pmksa == NULL) {		wpa_printf(MSG_ERROR, "RSN: PMKSA cache initialization "			   "failed");		os_free(sm);		return NULL;	}	return sm;}/** * wpa_sm_deinit - Deinitialize WPA state machine * @sm: Pointer to WPA state machine data from wpa_sm_init() */void wpa_sm_deinit(struct wpa_sm *sm){	if (sm == NULL)		return;	pmksa_cache_deinit(sm->pmksa);	eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);	eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);	os_free(sm->assoc_wpa_ie);	os_free(sm->ap_wpa_ie);	os_free(sm->ap_rsn_ie);	os_free(sm->ctx);	peerkey_deinit(sm);	os_free(sm);

⌨️ 快捷键说明

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