summaryrefslogtreecommitdiff
path: root/sys/net80211
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2008-08-12 16:21:47 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2008-08-12 16:21:47 +0000
commit32ce36c6b7f6115b9ea1139f6cfad29377702b88 (patch)
tree79b973e729372d70d6796e9cb09477ddd541db98 /sys/net80211
parent77bc72d3e8c5d32f05be63fb15cf2c4440ca62a5 (diff)
retrieve the TID from QoS frames to use with the appropriate
replay counter.
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_crypto_ccmp.c28
-rw-r--r--sys/net80211/ieee80211_crypto_tkip.c30
2 files changed, 49 insertions, 9 deletions
diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c
index 6cbc3b6df73..61be6c7168e 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.3 2008/08/12 16:14:45 henning Exp $ */
+/* $OpenBSD: ieee80211_crypto_ccmp.c,v 1.4 2008/08/12 16:21:46 damien Exp $ */
/*-
* Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -314,7 +314,7 @@ ieee80211_ccmp_decrypt(struct ieee80211com *ic, struct mbuf *m0,
{
struct ieee80211_ccmp_ctx *ctx = k->k_priv;
struct ieee80211_frame *wh;
- u_int64_t pn;
+ u_int64_t pn, *prsc;
const u_int8_t *ivp, *src;
u_int8_t *dst;
u_int8_t mic0[IEEE80211_CCMP_MICLEN];
@@ -338,6 +338,26 @@ ieee80211_ccmp_decrypt(struct ieee80211com *ic, struct mbuf *m0,
m_freem(m0);
return NULL;
}
+
+ /* retrieve last seen packet number for this frame type/TID */
+ if ((wh->i_fc[0] &
+ (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
+ (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) {
+ u_int8_t tid;
+ if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
+ IEEE80211_FC1_DIR_DSTODS) {
+ struct ieee80211_qosframe_addr4 *qwh4 =
+ (struct ieee80211_qosframe_addr4 *)wh;
+ tid = qwh4->i_qos[0] & 0x0f;
+ } else {
+ struct ieee80211_qosframe *qwh =
+ (struct ieee80211_qosframe *)wh;
+ tid = qwh->i_qos[0] & 0x0f;
+ }
+ prsc = &k->k_rsc[tid];
+ } else
+ prsc = &k->k_rsc[0];
+
/* extract the 48-bit PN from the CCMP header */
pn = (u_int64_t)ivp[0] |
(u_int64_t)ivp[1] << 8 |
@@ -345,7 +365,7 @@ ieee80211_ccmp_decrypt(struct ieee80211com *ic, struct mbuf *m0,
(u_int64_t)ivp[5] << 24 |
(u_int64_t)ivp[6] << 32 |
(u_int64_t)ivp[7] << 40;
- if (pn <= k->k_rsc[0]) {
+ if (pn <= *prsc) {
/* replayed frame, discard */
m_freem(m0);
return NULL;
@@ -453,7 +473,7 @@ ieee80211_ccmp_decrypt(struct ieee80211com *ic, struct mbuf *m0,
* Update last seen packet number (note that it must be done
* after MIC is validated.)
*/
- k->k_rsc[0] = pn;
+ *prsc = pn;
m_freem(m0);
return n0;
diff --git a/sys/net80211/ieee80211_crypto_tkip.c b/sys/net80211/ieee80211_crypto_tkip.c
index 53156bdbd68..80db449f563 100644
--- a/sys/net80211/ieee80211_crypto_tkip.c
+++ b/sys/net80211/ieee80211_crypto_tkip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_crypto_tkip.c,v 1.5 2008/08/12 16:14:45 henning Exp $ */
+/* $OpenBSD: ieee80211_crypto_tkip.c,v 1.6 2008/08/12 16:21:46 damien Exp $ */
/*-
* Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -323,7 +323,7 @@ ieee80211_tkip_decrypt(struct ieee80211com *ic, struct mbuf *m0,
u_int16_t wepseed[8]; /* needs to be 16-bit aligned for Phase2 */
u_int8_t buf[IEEE80211_TKIP_MICLEN + IEEE80211_WEP_CRCLEN];
u_int8_t mic[IEEE80211_TKIP_MICLEN];
- u_int64_t tsc;
+ u_int64_t tsc, *prsc;
u_int32_t crc, crc0;
u_int8_t *ivp, *mic0;
struct mbuf *n0, *m, *n;
@@ -343,6 +343,26 @@ ieee80211_tkip_decrypt(struct ieee80211com *ic, struct mbuf *m0,
m_freem(m0);
return NULL;
}
+
+ /* retrieve last seen packet number for this frame TID */
+ if ((wh->i_fc[0] &
+ (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
+ (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) {
+ u_int8_t tid;
+ if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
+ IEEE80211_FC1_DIR_DSTODS) {
+ struct ieee80211_qosframe_addr4 *qwh4 =
+ (struct ieee80211_qosframe_addr4 *)wh;
+ tid = qwh4->i_qos[0] & 0x0f;
+ } else {
+ struct ieee80211_qosframe *qwh =
+ (struct ieee80211_qosframe *)wh;
+ tid = qwh->i_qos[0] & 0x0f;
+ }
+ prsc = &k->k_rsc[tid];
+ } else
+ prsc = &k->k_rsc[0];
+
/* extract the 48-bit TSC from the TKIP header */
tsc = (u_int64_t)ivp[2] |
(u_int64_t)ivp[0] << 8 |
@@ -351,7 +371,7 @@ ieee80211_tkip_decrypt(struct ieee80211com *ic, struct mbuf *m0,
(u_int64_t)ivp[6] << 32 |
(u_int64_t)ivp[7] << 40;
/* NB: the keys are refreshed, we'll never overflow the 48 bits */
- if (tsc <= k->k_rsc[0]) {
+ if (tsc <= *prsc) {
/* replayed frame, discard */
m_freem(m0);
return NULL;
@@ -377,7 +397,7 @@ ieee80211_tkip_decrypt(struct ieee80211com *ic, struct mbuf *m0,
wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
/* compute WEP seed */
- if (!ctx->TTAK2ok || ((tsc >> 16) != (k->k_rsc[0] >> 16))) {
+ if (!ctx->TTAK2ok || ((tsc >> 16) != (*prsc >> 16))) {
Phase1(ctx->TTAK2, k->k_key, wh->i_addr2, tsc >> 16);
ctx->TTAK2ok = 1;
}
@@ -457,7 +477,7 @@ ieee80211_tkip_decrypt(struct ieee80211com *ic, struct mbuf *m0,
* Update last seen packet number (note that it must be done
* after MIC is validated.)
*/
- k->k_rsc[0] = tsc;
+ *prsc = tsc;
m_freem(m0);
return n0;