summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/rtl8187_dev.c3
-rw-r--r--include/net/mac80211.h49
-rw-r--r--net/mac80211/rx.c24
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/wpa.c43
5 files changed, 42 insertions, 82 deletions
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 9db9ece31b49..7dbf11e30db3 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -605,8 +605,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
priv->modes[1].channels = priv->channels;
priv->mode = IEEE80211_IF_TYPE_MGMT;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_WEP_INCLUDE_IV;
+ IEEE80211_HW_RX_INCLUDES_FCS;
dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
dev->queues = 1;
dev->max_rssi = 65;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index fcb7e3f9c669..9137579c12a4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -240,6 +240,8 @@ struct ieee80211_rx_status {
#define RX_FLAG_MMIC_ERROR (1<<0)
#define RX_FLAG_DECRYPTED (1<<1)
#define RX_FLAG_RADIOTAP (1<<2)
+#define RX_FLAG_MMIC_STRIPPED (1<<3)
+#define RX_FLAG_IV_STRIPPED (1<<4)
int flag;
};
@@ -402,6 +404,16 @@ typedef enum {
* that situation it should reject that key.
*/
#define IEEE80211_KEY_FLAG_WMM_STA (1<<0)
+/*
+ * This flag should be set by the driver if it requires
+ * IV generation in software for this key.
+ */
+#define IEEE80211_KEY_FLAG_GENERATE_IV (1<<1)
+/*
+ * This flag should be set by the driver if it requires
+ * MMIC generation in software for this key.
+ */
+#define IEEE80211_KEY_FLAG_GENERATE_MMIC (1<<2)
struct ieee80211_key_conf {
/*
@@ -465,17 +477,7 @@ struct ieee80211_hw {
*/
#define IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE (1<<1)
- /*
- * Some devices handle decryption internally and do not
- * indicate whether the frame was encrypted (unencrypted frames
- * will be dropped by the hardware, unless specifically allowed
- * through.)
- * It is permissible to not handle all encrypted frames and fall
- * back to software encryption; however, if this flag is set
- * unencrypted frames must be dropped unless the driver is told
- * otherwise via the set_ieee8021x() callback.
- */
-#define IEEE80211_HW_DEVICE_HIDES_WEP (1<<2)
+/* hole at 2 */
/* Whether RX frames passed to ieee80211_rx() include FCS in the end */
#define IEEE80211_HW_RX_INCLUDES_FCS (1<<3)
@@ -488,32 +490,13 @@ struct ieee80211_hw {
* can fetch them with ieee80211_get_buffered_bc(). */
#define IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING (1<<4)
- /*
- * This flag is only relevant if hardware encryption is used.
- * If set, it has two meanings:
- * 1) the IV and ICV are present in received frames that have
- * been decrypted (unless IEEE80211_HW_DEVICE_HIDES_WEP is
- * also set)
- * 2) on transmission, the IV should be generated in software.
- *
- * Please let us know if you *don't* use this flag, the stack would
- * really like to be able to get the IV to keep key statistics
- * accurate.
- */
-#define IEEE80211_HW_WEP_INCLUDE_IV (1<<5)
+/* hole at 5 */
/* hole at 6 */
/* hole at 7 */
- /*
- * Some devices handle Michael MIC internally and do not include MIC in
- * the received packets passed up. This flag must be set for such
- * devices. The 'encryption' frame control bit is expected to be still
- * set in the IEEE 802.11 header with this option unlike with the
- * IEEE80211_HW_DEVICE_HIDES_WEP flag.
- */
-#define IEEE80211_HW_DEVICE_STRIPS_MIC (1<<8)
+/* hole at 8 */
/* Device is capable of performing full monitor mode even during
* normal operation. */
@@ -527,8 +510,6 @@ struct ieee80211_hw {
* specified in the device's EEPROM */
#define IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED (1<<11)
- /* calculate Michael MIC for an MSDU when doing hwcrypto */
-#define IEEE80211_HW_TKIP_INCLUDE_MMIC (1<<12)
/* Do TKIP phase1 key mixing in stack to support cards only do
* phase2 key mixing when doing hwcrypto */
#define IEEE80211_HW_TKIP_REQ_PHASE1_KEY (1<<13)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8c6e29089216..28b8b6af4c42 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -363,7 +363,8 @@ ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx)
* we somehow allow the driver to tell us which key
* the hardware used if this flag is set?
*/
- if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV))
+ if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
+ (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED))
return TXRX_CONTINUE;
hdrlen = ieee80211_get_hdrlen(rx->fc);
@@ -534,8 +535,8 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
return TXRX_CONTINUE;
/* Check for weak IVs, if hwaccel did not remove IV from the frame */
- if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) ||
- !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+ if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) ||
+ !(rx->u.rx.status->flag & RX_FLAG_DECRYPTED))
if (ieee80211_wep_is_weak_iv(rx->skb, rx->key))
rx->sta->wep_weak_iv_count++;
@@ -559,15 +560,14 @@ ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
return TXRX_DROP;
}
- if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) ||
- !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
+ if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
"failed\n", rx->dev->name);
return TXRX_DROP;
}
- } else if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
+ } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
/* remove ICV */
skb_trim(rx->skb, rx->skb->len - 4);
@@ -898,13 +898,10 @@ static ieee80211_txrx_result
ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
{
/*
- * Pass through unencrypted frames if the hardware might have
- * decrypted them already without telling us, but that can only
- * be true if we either didn't find a key or the found key is
- * uploaded to the hardware.
+ * Pass through unencrypted frames if the hardware has
+ * decrypted them already.
*/
- if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) &&
- (!rx->key || (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)))
+ if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED)
return TXRX_CONTINUE;
/* Drop unencrypted frames if key is set. */
@@ -1212,8 +1209,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
goto ignore;
}
- if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
- rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) {
+ if (rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) {
/* AP with Pairwise keys support should never receive Michael
* MIC errors for non-zero keyidx because these are reserved
* for group keys and only the AP is sending real multicast
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 08d221674bc0..e2ae1e1fcc7b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -545,9 +545,8 @@ static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
return -1;
} else {
tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
- if (tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
- if (ieee80211_wep_add_iv(tx->local, skb, tx->key) ==
- NULL)
+ if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
+ if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
return -1;
}
}
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 775f89e42a43..a23531cef5b0 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -91,7 +91,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!(tx->flags & IEEE80211_TXRXD_FRAGMENTED) &&
- !(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) &&
+ !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
!wpa_test) {
/* hwaccel - with no need for preallocated room for Michael MIC
*/
@@ -138,26 +138,13 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
/*
* No way to verify the MIC if the hardware stripped it
*/
- if (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC)
+ if (rx->u.rx.status->flag & RX_FLAG_MMIC_STRIPPED)
return TXRX_CONTINUE;
if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
!(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc))
return TXRX_CONTINUE;
- if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
- if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
- if (skb->len < MICHAEL_MIC_LEN)
- return TXRX_DROP;
- }
- /* Need to verify Michael MIC sometimes in software even when
- * hwaccel is used. Atheros ar5212: fragmented frames and QoS
- * frames. */
- if (!(rx->flags & IEEE80211_TXRXD_FRAGMENTED) && !wpa_test)
- goto remove_mic;
- }
-
if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)
|| data_len < MICHAEL_MIC_LEN)
return TXRX_DROP;
@@ -184,7 +171,6 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
return TXRX_DROP;
}
- remove_mic:
/* remove Michael MIC from payload */
skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
@@ -287,7 +273,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
ieee80211_tx_set_iswep(tx);
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
- !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
+ !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
!wpa_test) {
/* hwaccel - with no need for preallocated room for IV/ICV */
tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
@@ -330,11 +316,13 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
if (!rx->sta || skb->len - hdrlen < 12)
return TXRX_DROP;
- if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
- if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
- /* Hardware takes care of all processing, including
- * replay protection, so no need to continue here. */
+ if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) {
+ if (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) {
+ /*
+ * Hardware took care of all processing, including
+ * replay protection, and stripped the ICV/IV so
+ * we cannot do any checks here.
+ */
return TXRX_CONTINUE;
}
@@ -538,7 +526,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
ieee80211_tx_set_iswep(tx);
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
- !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
+ !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
/* hwaccel - with no need for preallocated room for CCMP "
* header or MIC fields */
tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
@@ -585,8 +573,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
return TXRX_DROP;
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
- !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV))
+ (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED))
return TXRX_CONTINUE;
(void) ccmp_hdr2pn(pn, skb->data + hdrlen);
@@ -605,10 +592,8 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
return TXRX_DROP;
}
- if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
- /* hwaccel has already decrypted frame and verified MIC */
- } else {
+ if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
+ /* hardware didn't decrypt/verify MIC */
u8 *scratch, *b_0, *aad;
scratch = key->u.ccmp.rx_crypto_buf;