-/* $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>
{
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];
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 |
(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;
* 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;
-/* $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>
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;
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 |
(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;
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;
}
* 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;