summaryrefslogtreecommitdiff
path: root/sys/net80211/ieee80211_crypto_ccmp.c
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/ieee80211_crypto_ccmp.c
parent77bc72d3e8c5d32f05be63fb15cf2c4440ca62a5 (diff)
retrieve the TID from QoS frames to use with the appropriate
replay counter.
Diffstat (limited to 'sys/net80211/ieee80211_crypto_ccmp.c')
-rw-r--r--sys/net80211/ieee80211_crypto_ccmp.c28
1 files changed, 24 insertions, 4 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;