summaryrefslogtreecommitdiff
path: root/sys/net80211
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2015-11-15 01:43:22 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2015-11-15 01:43:22 +0000
commit846719835bc5b8f76b6aa04c5833fa297fb42c15 (patch)
tree9c16edb3022cc60d9daa301dd02e58f19b09e425 /sys/net80211
parent2fde2f7e9ee4be054f5a8fcc1121309f8daaac31 (diff)
Fix CCMP (WPA2) in preparation for 11n. This code didn't handle QoS
frames correctly but QoS frames are required for 11n A-MPDU aggregation and 11n STAs are required to use CCMP instead of WEP or TKIP ciphers. The QoS bit in FC0 is part of AAD (additional authentication data) but was being masked unconditionally. The FC1 order bit is masked to 0 in AAD if a data frame contains a QoS control field but this code was looking for HT control fields instead. Add an XXX comment about another bit which must be set if SPP (signaling and payload protected) A-MSDUs are supported. Neither Linux nor FreeBSD seem to set this bit, and we don't support SPP A-MSDUs yet so a comment seems good enough for now. ok deraadt mpi kettenis guenther helpful hints from mikeb
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_crypto_ccmp.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c
index b3e2f74fa53..92c6a63935a 100644
--- a/sys/net80211/ieee80211_crypto_ccmp.c
+++ b/sys/net80211/ieee80211_crypto_ccmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_crypto_ccmp.c,v 1.16 2015/07/15 22:16:42 deraadt Exp $ */
+/* $OpenBSD: ieee80211_crypto_ccmp.c,v 1.17 2015/11/15 01:43:21 stsp Exp $ */
/*-
* Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -88,17 +88,18 @@ ieee80211_ccmp_phase1(rijndael_ctx *ctx, const struct ieee80211_frame *wh,
/* construct AAD (additional authenticated data) */
aad = &auth[2]; /* skip l(a), will be filled later */
*aad = wh->i_fc[0];
- /* 11w: conditionnally mask subtype field */
+ /* 11w: conditionally mask subtype field */
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
IEEE80211_FC0_TYPE_DATA)
- *aad &= ~IEEE80211_FC0_SUBTYPE_MASK;
+ *aad &= ~IEEE80211_FC0_SUBTYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_QOS;
aad++;
/* protected bit is already set in wh */
*aad = wh->i_fc[1];
*aad &= ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
IEEE80211_FC1_MORE_DATA);
- /* 11n: conditionnally mask order bit */
- if (ieee80211_has_htc(wh))
+ /* 11n: conditionally mask order bit */
+ if (ieee80211_has_qos(wh))
*aad &= ~IEEE80211_FC1_ORDER;
aad++;
IEEE80211_ADDR_COPY(aad, wh->i_addr1); aad += IEEE80211_ADDR_LEN;
@@ -112,6 +113,10 @@ ieee80211_ccmp_phase1(rijndael_ctx *ctx, const struct ieee80211_frame *wh,
aad += IEEE80211_ADDR_LEN;
}
if (ieee80211_has_qos(wh)) {
+ /*
+ * XXX 802.11-2012 11.4.3.3.3 g says the A-MSDU present bit
+ * must be set here if both STAs are SPP A-MSDU capable.
+ */
*aad++ = tid = ieee80211_get_qos(wh) & IEEE80211_QOS_TID;
*aad++ = 0;
}