Exemple #1
0
static u8 * try_all_ptk(struct wlantest *wt, int pairwise_cipher,
			const struct ieee80211_hdr *hdr,
			const u8 *data, size_t data_len, size_t *decrypted_len)
{
	struct wlantest_ptk *ptk;
	u8 *decrypted;
	int prev_level = wpa_debug_level;

	wpa_debug_level = MSG_WARNING;
	dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
		decrypted = NULL;
		if ((pairwise_cipher == WPA_CIPHER_CCMP ||
		     pairwise_cipher == 0) && ptk->ptk_len == 48) {
			decrypted = ccmp_decrypt(ptk->ptk.tk1, hdr, data,
						 data_len, decrypted_len);
		}
		if ((pairwise_cipher == WPA_CIPHER_TKIP ||
		     pairwise_cipher == 0) && ptk->ptk_len == 64) {
			decrypted = tkip_decrypt(ptk->ptk.tk1, hdr, data,
						 data_len, decrypted_len);
		}
		if (decrypted) {
			wpa_debug_level = prev_level;
			add_note(wt, MSG_DEBUG, "Found PTK match from list of all known PTKs");
			return decrypted;
		}
	}
	wpa_debug_level = prev_level;

	return NULL;
}
static void test_vector_ccmp(void)
{
	u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
		    0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f };
	u8 pn[] = { 0xB5, 0x03, 0x97, 0x76, 0xE7, 0x0C };
	u8 frame[] = {
		0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
		0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
		0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
		0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
		0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
		0x7e, 0x78, 0xa0, 0x50
	};
	u8 *enc, *plain;
	size_t enc_len, plain_len;
	u8 fcs[4];

	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.6.4 CCMP test "
		   "vector\n");

	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);

	enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
	if (enc == NULL) {
		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
		return;
	}

	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
	WPA_PUT_LE32(fcs, crc32(enc, enc_len));
	wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));

	wpa_debug_level = MSG_INFO;
	plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
			     enc + 24, enc_len - 24, &plain_len);
	wpa_debug_level = MSG_EXCESSIVE;
	os_free(enc);

	if (plain == NULL) {
		wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
		return;
	}

	if (plain_len != sizeof(frame) - 24 ||
	    os_memcmp(plain, frame + 24, plain_len) != 0) {
		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
			    plain, plain_len);
	}

	os_free(plain);
}
static void test_vector_ccmp_mgmt(void)
{
	u8 tk[] = { 0x66, 0xed, 0x21, 0x04, 0x2f, 0x9f, 0x26, 0xd7,
		    0x11, 0x57, 0x06, 0xe4, 0x04, 0x14, 0xcf, 0x2e };
	u8 pn[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
	u8 frame[] = {
		0xc0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
		0x02, 0x00
	};
	u8 *enc, *plain;
	size_t enc_len, plain_len;

	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.9.2 CCMP with unicast "
		   "Deauthentication frame\n");

	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);

	enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
	if (enc == NULL) {
		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
		return;
	}

	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);

	wpa_debug_level = MSG_INFO;
	plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
			     enc + 24, enc_len - 24, &plain_len);
	wpa_debug_level = MSG_EXCESSIVE;
	os_free(enc);

	if (plain == NULL) {
		wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
		return;
	}

	if (plain_len != sizeof(frame) - 24 ||
	    os_memcmp(plain, frame + 24, plain_len) != 0) {
		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
			    plain, plain_len);
	}

	os_free(plain);
}
Exemple #4
0
static void rx_data_bss_prot(struct wlantest *wt,
			     const struct ieee80211_hdr *hdr, const u8 *qos,
			     const u8 *dst, const u8 *src, const u8 *data,
			     size_t len)
{
	struct wlantest_bss *bss;
	struct wlantest_sta *sta, *sta2;
	int keyid;
	u16 fc = le_to_host16(hdr->frame_control);
	u8 *decrypted;
	size_t dlen;
	int tid;
	u8 pn[6], *rsc;
	struct wlantest_tdls *tdls = NULL, *found;
	const u8 *tk = NULL;
	int ptk_iter_done = 0;
	int try_ptk_iter = 0;

	if (hdr->addr1[0] & 0x01) {
		rx_data_bss_prot_group(wt, hdr, qos, dst, src, data, len);
		return;
	}

	if (fc & WLAN_FC_TODS) {
		bss = bss_get(wt, hdr->addr1);
		if (bss == NULL)
			return;
		sta = sta_get(bss, hdr->addr2);
		if (sta)
			sta->counters[WLANTEST_STA_COUNTER_PROT_DATA_TX]++;
	} else if (fc & WLAN_FC_FROMDS) {
		bss = bss_get(wt, hdr->addr2);
		if (bss == NULL)
			return;
		sta = sta_get(bss, hdr->addr1);
	} else {
		bss = bss_get(wt, hdr->addr3);
		if (bss == NULL)
			return;
		sta = sta_find(bss, hdr->addr2);
		sta2 = sta_find(bss, hdr->addr1);
		if (sta == NULL || sta2 == NULL)
			return;
		found = NULL;
		dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list)
		{
			if ((tdls->init == sta && tdls->resp == sta2) ||
			    (tdls->init == sta2 && tdls->resp == sta)) {
				found = tdls;
				if (tdls->link_up)
					break;
			}
		}
		if (found) {
			if (!found->link_up)
				add_note(wt, MSG_DEBUG,
					 "TDLS: Link not up, but Data "
					 "frame seen");
			tk = found->tpk.tk;
			tdls = found;
		}
	}
	if ((sta == NULL ||
	     (!sta->ptk_set && sta->pairwise_cipher != WPA_CIPHER_WEP40)) &&
	    tk == NULL) {
		add_note(wt, MSG_MSGDUMP, "No PTK known to decrypt the frame");
		if (dl_list_empty(&wt->ptk))
			return;
		try_ptk_iter = 1;
	}

	if (len < 4) {
		add_note(wt, MSG_INFO, "Too short encrypted data frame");
		return;
	}

	if (sta == NULL)
		return;
	if (sta->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
	    !(data[3] & 0x20)) {
		add_note(wt, MSG_INFO, "Expected TKIP/CCMP frame from "
			 MACSTR " did not have ExtIV bit set to 1",
			 MAC2STR(src));
		return;
	}

	if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP) {
		if (data[3] & 0x1f) {
			add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
				 " used non-zero reserved bit",
				 MAC2STR(hdr->addr2));
		}
		if (data[1] != ((data[0] | 0x20) & 0x7f)) {
			add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
				 " used incorrect WEPSeed[1] (was 0x%x, "
				 "expected 0x%x)",
				 MAC2STR(hdr->addr2), data[1],
				 (data[0] | 0x20) & 0x7f);
		}
	} else if (tk || sta->pairwise_cipher == WPA_CIPHER_CCMP) {
		if (data[2] != 0 || (data[3] & 0x1f) != 0) {
			add_note(wt, MSG_INFO, "CCMP frame from " MACSTR
				 " used non-zero reserved bit",
				 MAC2STR(hdr->addr2));
		}
	}

	keyid = data[3] >> 6;
	if (keyid != 0) {
		add_note(wt, MSG_INFO, "Unexpected non-zero KeyID %d in "
			 "individually addressed Data frame from " MACSTR,
			 keyid, MAC2STR(hdr->addr2));
	}

	if (qos) {
		tid = qos[0] & 0x0f;
		if (fc & WLAN_FC_TODS)
			sta->tx_tid[tid]++;
		else
			sta->rx_tid[tid]++;
	} else {
		tid = 0;
		if (fc & WLAN_FC_TODS)
			sta->tx_tid[16]++;
		else
			sta->rx_tid[16]++;
	}
	if (tk) {
		if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0)
			rsc = tdls->rsc_init[tid];
		else
			rsc = tdls->rsc_resp[tid];
	} else if (fc & WLAN_FC_TODS)
		rsc = sta->rsc_tods[tid];
	else
		rsc = sta->rsc_fromds[tid];


	if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP)
		tkip_get_pn(pn, data);
	else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
		goto skip_replay_det;
	else
		ccmp_get_pn(pn, data);
	if (os_memcmp(pn, rsc, 6) <= 0) {
		u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
		add_note(wt, MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
			 " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
			 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
			 MAC2STR(hdr->addr3),
			 WLAN_GET_SEQ_SEQ(seq_ctrl),
			 WLAN_GET_SEQ_FRAG(seq_ctrl));
		wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
		wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
	}

skip_replay_det:
	if (tk)
		decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen);
	else if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
		decrypted = tkip_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
	else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
		decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
	else if (sta->ptk_set)
		decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
	else {
		decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data,
					len, &dlen);
		ptk_iter_done = 1;
	}
	if (!decrypted && !ptk_iter_done) {
		decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data,
					len, &dlen);
		if (decrypted) {
			add_note(wt, MSG_DEBUG, "Current PTK did not work, but found a match from all known PTKs");
		}
	}
	if (decrypted) {
		u16 fc = le_to_host16(hdr->frame_control);
		const u8 *peer_addr = NULL;
		if (!(fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)))
			peer_addr = hdr->addr1;
		os_memcpy(rsc, pn, 6);
		rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
				dlen, 1, peer_addr);
		write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
				     decrypted, dlen);
	} else if (!try_ptk_iter)
		add_note(wt, MSG_DEBUG, "Failed to decrypt frame");
	os_free(decrypted);
}
Exemple #5
0
static void rx_data_bss_prot_group(struct wlantest *wt,
				   const struct ieee80211_hdr *hdr,
				   const u8 *qos, const u8 *dst, const u8 *src,
				   const u8 *data, size_t len)
{
	struct wlantest_bss *bss;
	int keyid;
	u8 *decrypted;
	size_t dlen;
	u8 pn[6];

	bss = bss_get(wt, hdr->addr2);
	if (bss == NULL)
		return;
	if (len < 4) {
		add_note(wt, MSG_INFO, "Too short group addressed data frame");
		return;
	}

	if (bss->group_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
	    !(data[3] & 0x20)) {
		add_note(wt, MSG_INFO, "Expected TKIP/CCMP frame from "
			 MACSTR " did not have ExtIV bit set to 1",
			 MAC2STR(bss->bssid));
		return;
	}

	if (bss->group_cipher == WPA_CIPHER_TKIP) {
		if (data[3] & 0x1f) {
			add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
				 " used non-zero reserved bit",
				 MAC2STR(bss->bssid));
		}
		if (data[1] != ((data[0] | 0x20) & 0x7f)) {
			add_note(wt, MSG_INFO, "TKIP frame from " MACSTR
				 " used incorrect WEPSeed[1] (was 0x%x, "
				 "expected 0x%x)",
				 MAC2STR(bss->bssid), data[1],
				 (data[0] | 0x20) & 0x7f);
		}
	} else if (bss->group_cipher == WPA_CIPHER_CCMP) {
		if (data[2] != 0 || (data[3] & 0x1f) != 0) {
			add_note(wt, MSG_INFO, "CCMP frame from " MACSTR
				 " used non-zero reserved bit",
				 MAC2STR(bss->bssid));
		}
	}

	keyid = data[3] >> 6;
	if (bss->gtk_len[keyid] == 0 && bss->group_cipher != WPA_CIPHER_WEP40)
	{
		add_note(wt, MSG_MSGDUMP, "No GTK known to decrypt the frame "
			 "(A2=" MACSTR " KeyID=%d)",
			 MAC2STR(hdr->addr2), keyid);
		return;
	}

	if (bss->group_cipher == WPA_CIPHER_TKIP)
		tkip_get_pn(pn, data);
	else if (bss->group_cipher == WPA_CIPHER_WEP40)
		goto skip_replay_det;
	else
		ccmp_get_pn(pn, data);
	if (os_memcmp(pn, bss->rsc[keyid], 6) <= 0) {
		u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
		add_note(wt, MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
			 " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
			 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
			 MAC2STR(hdr->addr3),
			 WLAN_GET_SEQ_SEQ(seq_ctrl),
			 WLAN_GET_SEQ_FRAG(seq_ctrl));
		wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
		wpa_hexdump(MSG_INFO, "RSC", bss->rsc[keyid], 6);
	}

skip_replay_det:
	if (bss->group_cipher == WPA_CIPHER_TKIP)
		decrypted = tkip_decrypt(bss->gtk[keyid], hdr, data, len,
					 &dlen);
	else if (bss->group_cipher == WPA_CIPHER_WEP40)
		decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
	else
		decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len,
					 &dlen);
	if (decrypted) {
		rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
				dlen, 1, NULL);
		os_memcpy(bss->rsc[keyid], pn, 6);
		write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
				     decrypted, dlen);
	} else
		add_note(wt, MSG_DEBUG, "Failed to decrypt frame");
	os_free(decrypted);
}