aboutsummaryrefslogtreecommitdiffstats
path: root/wlantest/rx_data.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-11-10 23:29:30 (GMT)
committerJouni Malinen <j@w1.fi>2010-11-10 23:29:30 (GMT)
commitd318c534da6eb07a45b636e00b3d90e0af4e7436 (patch)
tree3c3c2c26ea8e0582696f203778289ecc5c1d7fea /wlantest/rx_data.c
parentdd149bbf44781bd033fdae631afa80e8a8a56116 (diff)
downloadhostap-d318c534da6eb07a45b636e00b3d90e0af4e7436.zip
hostap-d318c534da6eb07a45b636e00b3d90e0af4e7436.tar.gz
hostap-d318c534da6eb07a45b636e00b3d90e0af4e7436.tar.bz2
wlantest: Add support for decrypting CCMP protected unicast Data frames
Diffstat (limited to 'wlantest/rx_data.c')
-rw-r--r--wlantest/rx_data.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/wlantest/rx_data.c b/wlantest/rx_data.c
index ac24c25..34679ed 100644
--- a/wlantest/rx_data.c
+++ b/wlantest/rx_data.c
@@ -691,13 +691,86 @@ static void rx_data_process(struct wlantest *wt, const u8 *dst, const u8 *src,
}
+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;
+
+ bss = bss_get(wt, hdr->addr2);
+ if (bss == NULL)
+ return;
+ if (len < 4) {
+ wpa_printf(MSG_INFO, "Too short group addressed data frame");
+ return;
+ }
+
+ keyid = data[3] >> 6;
+ if (bss->gtk_len[keyid] == 0) {
+ wpa_printf(MSG_MSGDUMP, "No GTK known to decrypt the frame "
+ "(A2=" MACSTR " KeyID=%d)",
+ MAC2STR(hdr->addr2), keyid);
+ return;
+ }
+
+ /* TODO: try to decrypt */
+}
+
+
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)
{
- /* TODO: Try to decrypt and if success, call rx_data_process() with
- * prot = 1 */
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+ int keyid;
+ u16 fc = le_to_host16(hdr->frame_control);
+ u8 *decrypted;
+ size_t dlen;
+
+ 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);
+ } else {
+ bss = bss_get(wt, hdr->addr2);
+ if (bss == NULL)
+ return;
+ sta = sta_get(bss, hdr->addr1);
+ }
+ if (sta == NULL || !sta->ptk_set) {
+ wpa_printf(MSG_MSGDUMP, "No PTK known to decrypt the frame");
+ return;
+ }
+
+ if (len < 4) {
+ wpa_printf(MSG_INFO, "Too short encrypted data frame");
+ return;
+ }
+
+ keyid = data[3] >> 6;
+ if (keyid != 0) {
+ wpa_printf(MSG_INFO, "Unexpected non-zero KeyID %d in "
+ "individually addressed Data frame from " MACSTR,
+ keyid, MAC2STR(hdr->addr2));
+ }
+
+ /* TODO: check PN for replay */
+ /* TODO: TKIP */
+
+ decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
+ if (decrypted)
+ rx_data_process(wt, dst, src, decrypted, dlen, 1);
+ os_free(decrypted);
}