diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2015-11-15 01:43:22 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2015-11-15 01:43:22 +0000 |
commit | 846719835bc5b8f76b6aa04c5833fa297fb42c15 (patch) | |
tree | 9c16edb3022cc60d9daa301dd02e58f19b09e425 /sys/net80211 | |
parent | 2fde2f7e9ee4be054f5a8fcc1121309f8daaac31 (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.c | 15 |
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; } |