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

📄 wpa.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
		   MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);	key_info = WPA_GET_BE16(key->key_info);	pos = (const u8 *) (key + 1);	len = WPA_GET_BE16(key->key_data_length);	wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", pos, len);	wpa_supplicant_parse_ies(pos, len, &ie);	if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {		wpa_printf(MSG_WARNING, "WPA: GTK IE in unencrypted key data");		return;	}#ifdef CONFIG_IEEE80211W	if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {		wpa_printf(MSG_WARNING, "WPA: IGTK KDE in unencrypted key "			   "data");		return;	}	if (ie.igtk && ie.igtk_len != sizeof(struct wpa_igtk_kde)) {		wpa_printf(MSG_WARNING, "WPA: Invalid IGTK KDE length %lu",			   (unsigned long) ie.igtk_len);		return;	}#endif /* CONFIG_IEEE80211W */	if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)		return;	if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {		wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way "			   "Handshake differs from 3 of 4-Way Handshake - drop"			   " packet (src=" MACSTR ")", MAC2STR(sm->bssid));		return;	}	keylen = WPA_GET_BE16(key->key_length);	switch (sm->pairwise_cipher) {	case WPA_CIPHER_CCMP:		if (keylen != 16) {			wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "				   "%d (src=" MACSTR ")",				   keylen, MAC2STR(sm->bssid));			return;		}		break;	case WPA_CIPHER_TKIP:		if (keylen != 32) {			wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length "				   "%d (src=" MACSTR ")",				   keylen, MAC2STR(sm->bssid));			return;		}		break;	}	if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,				       NULL, 0, &sm->ptk))		return;	/* SNonce was successfully used in msg 3/4, so mark it to be renewed	 * for the next 4-Way Handshake. If msg 3 is received again, the old	 * SNonce will still be used to avoid changing PTK. */	sm->renew_snonce = 1;	if (key_info & WPA_KEY_INFO_INSTALL) {		wpa_supplicant_install_ptk(sm, key);	}	if (key_info & WPA_KEY_INFO_SECURE) {		wpa_sm_mlme_setprotection(			sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,			MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);		eapol_sm_notify_portValid(sm->eapol, TRUE);	}	wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);	if (ie.gtk &&	    wpa_supplicant_pairwise_gtk(sm, key,					ie.gtk, ie.gtk_len, key_info) < 0) {		wpa_printf(MSG_INFO, "RSN: Failed to configure GTK");	}	if (ieee80211w_set_keys(sm, &ie) < 0)		wpa_printf(MSG_INFO, "RSN: Failed to configure IGTK");}static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,					     const u8 *keydata,					     size_t keydatalen,					     u16 key_info,					     struct wpa_gtk_data *gd){	int maxkeylen;	struct wpa_eapol_ie_parse ie;	wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);	wpa_supplicant_parse_ies(keydata, keydatalen, &ie);	if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {		wpa_printf(MSG_WARNING, "WPA: GTK IE in unencrypted key data");		return -1;	}	if (ie.gtk == NULL) {		wpa_printf(MSG_INFO, "WPA: No GTK IE in Group Key msg 1/2");		return -1;	}	maxkeylen = gd->gtk_len = ie.gtk_len - 2;	if (wpa_supplicant_check_group_cipher(sm->group_cipher,					      gd->gtk_len, maxkeylen,					      &gd->key_rsc_len, &gd->alg))		return -1;	wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake",		    ie.gtk, ie.gtk_len);	gd->keyidx = ie.gtk[0] & 0x3;	gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,						      !!(ie.gtk[0] & BIT(2)));	if (ie.gtk_len - 2 > sizeof(gd->gtk)) {		wpa_printf(MSG_INFO, "RSN: Too long GTK in GTK IE "			   "(len=%lu)", (unsigned long) ie.gtk_len - 2);		return -1;	}	os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);	if (ieee80211w_set_keys(sm, &ie) < 0)		wpa_printf(MSG_INFO, "RSN: Failed to configure IGTK");	return 0;}static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,					     const struct wpa_eapol_key *key,					     size_t keydatalen, int key_info,					     size_t extra_len, u16 ver,					     struct wpa_gtk_data *gd){	size_t maxkeylen;	u8 ek[32];	gd->gtk_len = WPA_GET_BE16(key->key_length);	maxkeylen = keydatalen;	if (keydatalen > extra_len) {		wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"			   " key_data_length=%lu > extra_len=%lu",			   (unsigned long) keydatalen,			   (unsigned long) extra_len);		return -1;	}	if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {		if (maxkeylen < 8) {			wpa_printf(MSG_INFO, "WPA: Too short maxkeylen (%lu)",				   (unsigned long) maxkeylen);			return -1;		}		maxkeylen -= 8;	}	if (wpa_supplicant_check_group_cipher(sm->group_cipher,					      gd->gtk_len, maxkeylen,					      &gd->key_rsc_len, &gd->alg))		return -1;	gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>		WPA_KEY_INFO_KEY_INDEX_SHIFT;	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {		os_memcpy(ek, key->key_iv, 16);		os_memcpy(ek + 16, sm->ptk.kek, 16);		if (keydatalen > sizeof(gd->gtk)) {			wpa_printf(MSG_WARNING, "WPA: RC4 key data "				   "too long (%lu)",				   (unsigned long) keydatalen);			return -1;		}		os_memcpy(gd->gtk, key + 1, keydatalen);		rc4_skip(ek, 32, 256, gd->gtk, keydatalen);	} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {		if (keydatalen % 8) {			wpa_printf(MSG_WARNING, "WPA: Unsupported AES-WRAP "				   "len %lu", (unsigned long) keydatalen);			return -1;		}		if (maxkeylen > sizeof(gd->gtk)) {			wpa_printf(MSG_WARNING, "WPA: AES-WRAP key data "				   "too long (keydatalen=%lu maxkeylen=%lu)",				   (unsigned long) keydatalen,				   (unsigned long) maxkeylen);			return -1;		}		if (aes_unwrap(sm->ptk.kek, maxkeylen / 8,			       (const u8 *) (key + 1), gd->gtk)) {			wpa_printf(MSG_WARNING, "WPA: AES unwrap "				   "failed - could not decrypt GTK");			return -1;		}	} else {		wpa_printf(MSG_WARNING, "WPA: Unsupported key_info type %d",			   ver);		return -1;	}	gd->tx = wpa_supplicant_gtk_tx_bit_workaround(		sm, !!(key_info & WPA_KEY_INFO_TXRX));	return 0;}static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,				      const struct wpa_eapol_key *key,				      int ver, u16 key_info){	size_t rlen;	struct wpa_eapol_key *reply;	u8 *rbuf;	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,				  sizeof(*reply), &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_KEY_INDEX_MASK;	key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;	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, 0);	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");	wpa_eapol_key_send(sm, sm->ptk.kck, ver, sm->bssid, ETH_P_EAPOL,			   rbuf, rlen, reply->key_mic);	return 0;}static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,					  const unsigned char *src_addr,					  const struct wpa_eapol_key *key,					  int extra_len, u16 ver){	u16 key_info, keydatalen;	int rekey, ret;	struct wpa_gtk_data gd;	os_memset(&gd, 0, sizeof(gd));	rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of Group Key Handshake from "		   MACSTR " (ver=%d)", MAC2STR(src_addr), ver);	key_info = WPA_GET_BE16(key->key_info);	keydatalen = WPA_GET_BE16(key->key_data_length);	if (sm->proto == WPA_PROTO_RSN) {		ret = wpa_supplicant_process_1_of_2_rsn(sm,							(const u8 *) (key + 1),							keydatalen, key_info,							&gd);	} else {		ret = wpa_supplicant_process_1_of_2_wpa(sm, key, keydatalen,							key_info, extra_len,							ver, &gd);	}	wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);	if (ret)		return;	if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) ||	    wpa_supplicant_send_2_of_2(sm, key, ver, key_info))		return;	if (rekey) {		wpa_msg(sm->ctx->ctx, MSG_INFO, "WPA: Group rekeying "			"completed with " MACSTR " [GTK=%s]",			MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));		wpa_sm_cancel_auth_timeout(sm);		wpa_sm_set_state(sm, WPA_COMPLETED);	} else {		wpa_supplicant_key_neg_complete(sm, sm->bssid,						key_info &						WPA_KEY_INFO_SECURE);	}}static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,					       struct wpa_eapol_key *key,					       u16 ver,					       const u8 *buf, size_t len){	u8 mic[16];	int ok = 0;	os_memcpy(mic, key->key_mic, 16);	if (sm->tptk_set) {		os_memset(key->key_mic, 0, 16);		wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len,				  key->key_mic);		if (os_memcmp(mic, key->key_mic, 16) != 0) {			wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "				   "when using TPTK - ignoring TPTK");		} else {			ok = 1;			sm->tptk_set = 0;			sm->ptk_set = 1;			os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));		}	}	if (!ok && sm->ptk_set) {		os_memset(key->key_mic, 0, 16);		wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len,				  key->key_mic);		if (os_memcmp(mic, key->key_mic, 16) != 0) {			wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "				   "- dropping packet");			return -1;		}		ok = 1;	}	if (!ok) {		wpa_printf(MSG_WARNING, "WPA: Could not verify EAPOL-Key MIC "			   "- dropping packet");		return -1;	}	os_memcpy(sm->rx_replay_counter, key->replay_counter,		  WPA_REPLAY_COUNTER_LEN);	sm->rx_replay_counter_set = 1;	return 0;}/* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,					   struct wpa_eapol_key *key, u16 ver){	u16 keydatalen = WPA_GET_BE16(key->key_data_length);	wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",		    (u8 *) (key + 1), keydatalen);	if (!sm->ptk_set) {		wpa_printf(MSG_WARNING, "WPA: PTK not available, "			   "cannot decrypt EAPOL-Key key data.");		return -1;	}	/* Decrypt key data here so that this operation does not need	 * to be implemented separately for each message type. */	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {		u8 ek[32];		os_memcpy(ek, key->key_iv, 16);		os_memcpy(ek + 16, sm->ptk.kek, 16);		rc4_skip(ek, 32, 256, (u8 *) (key + 1), keydatalen);	} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||		   ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {		u8 *buf;		if (keydatalen % 8) {			wpa_printf(MSG_WARNING, "WPA: Unsupported "				   "AES-WRAP len %d", keydatalen);			return -1;		}		keydatalen -= 8; /* AES-WRAP adds 8 bytes */		buf = os_malloc(keydatalen);		if (buf == NULL) {			wpa_printf(MSG_WARNING, "WPA: No memory for "				   "AES-UNWRAP buffer");			return -1;		}		if (aes_unwrap(sm->ptk.kek, keydatalen / 8,			       (u8 *) (key + 1), buf)) {			os_free(buf);			wpa_printf(MSG_WARNING, "WPA: AES unwrap failed - "				   "could not decrypt EAPOL-Key key data");			return -1;		}		os_memcpy(key + 1, buf, keydatalen);		os_free(buf);		WPA_PUT_BE16(key->key_data_length, keydatalen);	} else {		wpa_printf(MSG_WARNING, "WPA: Unsupported key_info type %d",			   ver);		return -1;	}	wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",			(u8 *) (key + 1), keydatalen);	return 0;}/** * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted * @sm: Pointer to WPA state machine data from wpa_sm_init() */void wpa_sm_aborted_cached(struct wpa_sm *sm){	if (sm && sm->cur_pmksa) {		wpa_printf(MSG_DEBUG, "RSN: Cancelling PMKSA caching attempt");		sm->cur_pmksa = NULL;	}}static void wpa_eapol_key_dump(const struct wpa_eapol_key *key){#ifndef CONFIG_NO_STDOUT_DEBUG	u16 key_info = WPA_GET_BE16(key->key_info);	wpa_printf(MSG_DEBUG, "  EAPOL-Key type=%d", key->type);	wpa_printf(MSG_DEBUG, "  key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s"		   "%s%s%s%s%s%s%s)",		   key_info, key_info & WPA_KEY_INFO_TYPE_MASK,		   (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>		   WPA_KEY_INFO_KEY_INDEX_SHIFT,		   (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,		   key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",		   key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",		   key_info & WPA_KEY_INFO_ACK ? " Ack" : "",		   key_info & WPA_KEY_INFO_MIC ? " MIC" : "",		   key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",		   key_info & WPA_KEY_INFO_ERROR ? " Error" : "",		   key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",		   key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");	wpa_printf(MSG_DEBUG, "  key_length=%u key_data_length=%u",		   WPA_GET_BE16(key->key_length),		   WPA_GET_BE16(key->key_data_length));	wpa_hexdump(MSG_DEBUG, "  replay_counter",		    key->replay_counter, WPA_REPLAY_COUNTER_LEN);	wpa_hexdump(MSG_DEBUG, "  key_nonce", key->key_nonce, WPA_NONCE_LEN);	wpa_hexdump(MSG_DEBUG, "  key_iv", key->key_iv, 16);	wpa_hexdump(MSG_DEBUG, "  key_rsc", key->key_rsc, 8);	wpa_hexdump(MSG_DEBUG, "  key_id (reserved)", key->key_id, 8);	wpa_hexdump(MSG_DEBUG, "  key_mic", key->key_mic, 16);#endif /* CONFIG_NO_STDOUT_DEBUG */}/** * wpa_sm_rx_eapol - Process received WPA EAPOL frames * @sm: Pointer to WPA state machine data from wpa_sm_init() * @src_addr: Source MAC address of the EAPOL packet * @buf: Pointer to the beginning of the EAPOL data (EAPOL header) * @len: Length of the EAPOL frame * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure * * This function is called for each received EAPOL frame. Other than EAPOL-Key * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is * only processing WPA and WPA2 EAPOL-Key frames. * * The received EAPOL-Key packets are validated and valid packets are replied * to. In addition, key material (PTK, GTK) is configured at the end of a * successful key handshake. */int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,		    const u8 *buf, size_t len){	size_t plen, data_len, extra_len;

⌨️ 快捷键说明

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