]> Pileus Git - ~andy/linux/blobdiff - net/mac80211/wpa.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[~andy/linux] / net / mac80211 / wpa.c
index 360d11e9de153b09104c460e3ce28812a2b45fcc..6f04311cf0a07922727ace9373291ce5f04b9270 100644 (file)
@@ -175,6 +175,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
        /* remove Michael MIC from payload */
        skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
 
+       /* update IV in key information to be able to detect replays */
+       rx->key->u.tkip.iv32_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv32;
+       rx->key->u.tkip.iv16_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv16;
+
        return TXRX_CONTINUE;
 }
 
@@ -239,19 +243,11 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
 
 
 ieee80211_txrx_result
-ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-       u16 fc;
-       struct ieee80211_key *key = tx->key;
        struct sk_buff *skb = tx->skb;
        int wpa_test = 0, test = 0;
 
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (!key || key->conf.alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc))
-               return TXRX_CONTINUE;
-
        tx->u.tx.control->icv_len = TKIP_ICV_LEN;
        tx->u.tx.control->iv_len = TKIP_IV_LEN;
        ieee80211_tx_set_iswep(tx);
@@ -281,7 +277,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
 
 
 ieee80211_txrx_result
-ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
+ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
        u16 fc;
@@ -293,9 +289,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
        fc = le16_to_cpu(hdr->frame_control);
        hdrlen = ieee80211_get_hdrlen(fc);
 
-       if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
-           !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
-           (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
+       if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
                return TXRX_CONTINUE;
 
        if (!rx->sta || skb->len - hdrlen < 12)
@@ -318,11 +312,16 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
        res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
                                          key, skb->data + hdrlen,
                                          skb->len - hdrlen, rx->sta->addr,
-                                         hwaccel, rx->u.rx.queue);
+                                         hwaccel, rx->u.rx.queue,
+                                         &rx->u.rx.tkip_iv32,
+                                         &rx->u.rx.tkip_iv16);
        if (res != TKIP_DECRYPT_OK || wpa_test) {
-               printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from "
-                      "%s (res=%d)\n",
-                      rx->dev->name, print_mac(mac, rx->sta->addr), res);
+#ifdef CONFIG_MAC80211_DEBUG
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "%s: TKIP decrypt failed for RX "
+                              "frame from %s (res=%d)\n", rx->dev->name,
+                              print_mac(mac, rx->sta->addr), res);
+#endif /* CONFIG_MAC80211_DEBUG */
                return TXRX_DROP;
        }
 
@@ -493,19 +492,11 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
 
 
 ieee80211_txrx_result
-ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-       struct ieee80211_key *key = tx->key;
-       u16 fc;
        struct sk_buff *skb = tx->skb;
        int test = 0;
 
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (!key || key->conf.alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc))
-               return TXRX_CONTINUE;
-
        tx->u.tx.control->icv_len = CCMP_MIC_LEN;
        tx->u.tx.control->iv_len = CCMP_HDR_LEN;
        ieee80211_tx_set_iswep(tx);
@@ -535,7 +526,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
 
 
 ieee80211_txrx_result
-ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
+ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
        u16 fc;
@@ -549,9 +540,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
        fc = le16_to_cpu(hdr->frame_control);
        hdrlen = ieee80211_get_hdrlen(fc);
 
-       if (!key || key->conf.alg != ALG_CCMP ||
-           !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
-           (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
+       if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
                return TXRX_CONTINUE;
 
        data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
@@ -594,9 +583,12 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
                            skb->data + hdrlen + CCMP_HDR_LEN, data_len,
                            skb->data + skb->len - CCMP_MIC_LEN,
                            skb->data + hdrlen + CCMP_HDR_LEN)) {
-                       printk(KERN_DEBUG "%s: CCMP decrypt failed for RX "
-                              "frame from %s\n", rx->dev->name,
-                              print_mac(mac, rx->sta->addr));
+#ifdef CONFIG_MAC80211_DEBUG
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "%s: CCMP decrypt failed "
+                                      "for RX frame from %s\n", rx->dev->name,
+                                      print_mac(mac, rx->sta->addr));
+#endif /* CONFIG_MAC80211_DEBUG */
                        return TXRX_DROP;
                }
        }