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

📄 peerkey.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	size_t kde_len;	u16 key_info, ver;	be32 lifetime;	kde_len = peerkey->rsnie_i_len +		2 + RSN_SELECTOR_LEN + sizeof(lifetime);	mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,				  sizeof(*msg) + kde_len, &mlen,				  (void *) &msg);	if (mbuf == NULL)		return;	msg->type = EAPOL_KEY_TYPE_RSN;	if (peerkey->cipher == WPA_CIPHER_CCMP)		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;	else		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;	key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK |		WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;	WPA_PUT_BE16(msg->key_info, key_info);	if (peerkey->cipher == WPA_CIPHER_CCMP)		WPA_PUT_BE16(msg->key_length, 16);	else		WPA_PUT_BE16(msg->key_length, 32);	os_memcpy(msg->replay_counter, peerkey->replay_counter,		  WPA_REPLAY_COUNTER_LEN);	inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);	WPA_PUT_BE16(msg->key_data_length, kde_len);	pos = (u8 *) (msg + 1);	pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);	lifetime = host_to_be32(peerkey->lifetime);	wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,		    (u8 *) &lifetime, sizeof(lifetime));	os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);	wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,		   MAC2STR(peerkey->addr));	wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,			   ETH_P_EAPOL, mbuf, mlen, msg->key_mic);}static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey,					 struct wpa_eapol_ie_parse *kde){	wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")",		   MAC2STR(kde->mac_addr));	if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0)	{		wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not "			   "match with the one used in SMK M3");		return -1;	}	if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {		wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not "			   "match with the one received in SMK M2");		return -1;	}	return 0;}static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm,					 const unsigned char *src_addr,					 const struct wpa_eapol_key *key,					 int ver,					 struct wpa_peerkey *peerkey,					 struct wpa_eapol_ie_parse *kde){	int cipher;	struct wpa_ie_data ie;	wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")",		   MAC2STR(kde->mac_addr));	if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN ||	    wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) {		wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5");		/* TODO: abort negotiation */		return -1;	}	if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {		wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does "			   "not match with INonce used in SMK M1");		return -1;	}	if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0)	{		wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not "			   "match with the one used in SMK M1");		return -1;	}	os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len);	peerkey->rsnie_p_len = kde->rsn_ie_len;	os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);	cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;	if (cipher & WPA_CIPHER_CCMP) {		wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");		peerkey->cipher = WPA_CIPHER_CCMP;	} else if (cipher & WPA_CIPHER_TKIP) {		wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");		peerkey->cipher = WPA_CIPHER_TKIP;	} else {		wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "			   "unacceptable cipher", MAC2STR(kde->mac_addr));		wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,					      STK_MUI_SMK, STK_ERR_CPHR_NS,					      ver);		/* TODO: abort negotiation */		return -1;	}	return 0;}static int wpa_supplicant_process_smk_m45(	struct wpa_sm *sm, const unsigned char *src_addr,	const struct wpa_eapol_key *key, size_t extra_len, int ver){	struct wpa_peerkey *peerkey;	struct wpa_eapol_ie_parse kde;	u32 lifetime;	struct os_time now;	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {		wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "			   "the current network");		return -1;	}	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <	    0) {		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5");		return -1;	}	if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||	    kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN ||	    kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN ||	    kde.lifetime == NULL || kde.lifetime_len < 4) {		wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or "			   "Lifetime KDE in SMK M4/M5");		return -1;	}	for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {		if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 &&		    os_memcmp(peerkey->initiator ? peerkey->inonce :			   peerkey->pnonce,			   key->key_nonce, WPA_NONCE_LEN) == 0)			break;	}	if (peerkey == NULL) {		wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found "			   "for SMK M4/M5: peer " MACSTR,			   MAC2STR(kde.mac_addr));		return -1;	}	if (peerkey->initiator) {		if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver,						  peerkey, &kde) < 0)			return -1;	} else {		if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0)			return -1;	}	os_memcpy(peerkey->smk, kde.smk, PMK_LEN);	peerkey->smk_complete = 1;	wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN);	lifetime = WPA_GET_BE32(kde.lifetime);	wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime);	if (lifetime > 1000000000)		lifetime = 1000000000; /* avoid overflowing expiration time */	peerkey->lifetime = lifetime;	os_get_time(&now);	peerkey->expiration = now.sec + lifetime;	eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,			       sm, peerkey);	if (peerkey->initiator) {		rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,			  peerkey->inonce, sm->own_addr, peerkey->smkid,			  peerkey->use_sha256);		wpa_supplicant_send_stk_1_of_4(sm, peerkey);	} else {		rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,			  peerkey->inonce, peerkey->addr, peerkey->smkid,			  peerkey->use_sha256);	}	wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);	return 0;}static int wpa_supplicant_process_smk_error(	struct wpa_sm *sm, const unsigned char *src_addr,	const struct wpa_eapol_key *key, size_t extra_len){	struct wpa_eapol_ie_parse kde;	struct rsn_error_kde error;	u8 peer[ETH_ALEN];	u16 error_type;	wpa_printf(MSG_DEBUG, "RSN: Received SMK Error");	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {		wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "			   "the current network");		return -1;	}	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <	    0) {		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");		return -1;	}	if (kde.error == NULL || kde.error_len < sizeof(error)) {		wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error");		return -1;	}	if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN)		os_memcpy(peer, kde.mac_addr, ETH_ALEN);	os_memcpy(&error, kde.error, sizeof(error));	error_type = be_to_host16(error.error_type);	wpa_msg(sm->ctx->ctx, MSG_INFO,		"RSN: SMK Error KDE received: MUI %d error_type %d peer "		MACSTR,		be_to_host16(error.mui), error_type,		MAC2STR(peer));	if (kde.mac_addr &&	    (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN ||	     error_type == STK_ERR_CPHR_NS)) {		struct wpa_peerkey *peerkey;		for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {			if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) ==			    0)				break;		}		if (peerkey == NULL) {			wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake "				   "found for SMK Error");			return -1;		}		/* TODO: abort SMK/STK handshake and remove all related keys */	}	return 0;}static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,					      struct wpa_peerkey *peerkey,					      const struct wpa_eapol_key *key,					      u16 ver){	struct wpa_eapol_ie_parse ie;	const u8 *kde;	size_t len, kde_buf_len;	struct wpa_ptk *stk;	u8 buf[8], *kde_buf, *pos;	be32 lifetime;	wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from "		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);	os_memset(&ie, 0, sizeof(ie));	/* RSN: msg 1/4 should contain SMKID for the selected SMK */	kde = (const u8 *) (key + 1);	len = WPA_GET_BE16(key->key_data_length);	wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);	if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {		wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");		return;	}	if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {		wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",			    ie.pmkid, PMKID_LEN);		return;	}	if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) {		wpa_msg(sm->ctx->ctx, MSG_WARNING,			"RSN: Failed to get random data for PNonce");		return;	}	wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce",		    peerkey->pnonce, WPA_NONCE_LEN);	/* Calculate STK which will be stored as a temporary STK until it has	 * been verified when processing message 3/4. */	stk = &peerkey->tstk;	wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",		       sm->own_addr, peerkey->addr,		       peerkey->pnonce, key->key_nonce,		       (u8 *) stk, sizeof(*stk),		       peerkey->use_sha256);	/* Supplicant: swap tx/rx Mic keys */	os_memcpy(buf, stk->u.auth.tx_mic_key, 8);	os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8);	os_memcpy(stk->u.auth.rx_mic_key, buf, 8);	peerkey->tstk_set = 1;	kde_buf_len = peerkey->rsnie_p_len +		2 + RSN_SELECTOR_LEN + sizeof(lifetime) +		2 + RSN_SELECTOR_LEN + PMKID_LEN;	kde_buf = os_malloc(kde_buf_len);	if (kde_buf == NULL)		return;	pos = kde_buf;	pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);	lifetime = host_to_be32(peerkey->lifetime);	pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,			  (u8 *) &lifetime, sizeof(lifetime));	wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN);	if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver,				       peerkey->pnonce, kde_buf, kde_buf_len,				       stk)) {		os_free(kde_buf);		return;	}	os_free(kde_buf);	os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);}static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,					       struct wpa_peerkey *peerkey,					       struct wpa_eapol_ie_parse *kde){	u32 lifetime;	struct os_time now;	if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))		return;	lifetime = WPA_GET_BE32(kde->lifetime);	if (lifetime >= peerkey->lifetime) {		wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "			   "which is larger than or equal to own value %u "			   "seconds - ignored", lifetime, peerkey->lifetime);		return;	}	wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "		   "(own was %u seconds) - updated",		   lifetime, peerkey->lifetime);	peerkey->lifetime = lifetime;	os_get_time(&now);	peerkey->expiration = now.sec + lifetime;	eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);	eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,			       sm, peerkey);}static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,					      struct wpa_peerkey *peerkey,					      const struct wpa_eapol_key *key,					      u16 ver){	struct wpa_eapol_ie_parse kde;	const u8 *keydata;	size_t len;	wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);	os_memset(&kde, 0, sizeof(kde));

⌨️ 快捷键说明

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