mac80211: pass vif and station to update_tkip_key
[safe/jmp/linux-2.6] / net / mac80211 / tkip.c
index 38fa111..7ef491e 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/unaligned.h>
 
 #include <net/mac80211.h>
+#include "driver-ops.h"
 #include "key.h"
 #include "tkip.h"
 #include "wep.h"
@@ -99,7 +100,7 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx,
                p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j));
                p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i;
        }
-       ctx->initialized = 1;
+       ctx->state = TKIP_STATE_PHASE1_DONE;
 }
 
 static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
@@ -182,7 +183,7 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
        /* Update the p1k only when the iv16 in the packet wraps around, this
         * might occur after the wrap around of iv16 in the key in case of
         * fragmented packets. */
-       if (iv16 == 0 || !ctx->initialized)
+       if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
                tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32);
 
        if (type == IEEE80211_TKIP_P1_KEY) {
@@ -194,11 +195,13 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
 }
 EXPORT_SYMBOL(ieee80211_get_tkip_key);
 
-/* Encrypt packet payload with TKIP using @key. @pos is a pointer to the
+/*
+ * Encrypt packet payload with TKIP using @key. @pos is a pointer to the
  * beginning of the buffer containing payload. This payload must include
- * headroom of eight octets for IV and Ext. IV and taildroom of four octets
- * for ICV. @payload_len is the length of payload (_not_ including extra
- * headroom and tailroom). @ta is the transmitter addresses. */
+ * the IV/Ext.IV and space for (taildroom) four octets for ICV.
+ * @payload_len is the length of payload (_not_ including IV/ICV length).
+ * @ta is the transmitter addresses.
+ */
 void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
                                 struct ieee80211_key *key,
                                 u8 *pos, size_t payload_len, u8 *ta)
@@ -208,12 +211,11 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
        const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
 
        /* Calculate per-packet key */
-       if (ctx->iv16 == 0 || !ctx->initialized)
+       if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
                tkip_mixing_phase1(tk, ctx, ta, ctx->iv32);
 
        tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
 
-       pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
        ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
 }
 
@@ -258,7 +260,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
        if ((keyid >> 6) != key->conf.keyidx)
                return TKIP_DECRYPT_INVALID_KEYIDX;
 
-       if (key->u.tkip.rx[queue].initialized &&
+       if (key->u.tkip.rx[queue].state != TKIP_STATE_NOT_INIT &&
            (iv32 < key->u.tkip.rx[queue].iv32 ||
             (iv32 == key->u.tkip.rx[queue].iv32 &&
              iv16 <= key->u.tkip.rx[queue].iv16))) {
@@ -274,11 +276,11 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
 
        if (only_iv) {
                res = TKIP_DECRYPT_OK;
-               key->u.tkip.rx[queue].initialized = 1;
+               key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED;
                goto done;
        }
 
-       if (!key->u.tkip.rx[queue].initialized ||
+       if (key->u.tkip.rx[queue].state == TKIP_STATE_NOT_INIT ||
            key->u.tkip.rx[queue].iv32 != iv32) {
                /* IV16 wrapped around - perform TKIP phase 1 */
                tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32);
@@ -298,19 +300,18 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
                        printk("\n");
                }
 #endif
-               if (key->local->ops->update_tkip_key &&
-                       key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
-                       u8 bcast[ETH_ALEN] =
-                               {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-                       u8 *sta_addr = key->sta->sta.addr;
-
-                       if (is_multicast_ether_addr(ra))
-                               sta_addr = bcast;
-
-                       key->local->ops->update_tkip_key(
-                               local_to_hw(key->local), &key->conf,
-                               sta_addr, iv32, key->u.tkip.rx[queue].p1k);
-               }
+       }
+       if (key->local->ops->update_tkip_key &&
+           key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
+           key->u.tkip.rx[queue].state != TKIP_STATE_PHASE1_HW_UPLOADED) {
+               struct ieee80211_sub_if_data *sdata = key->sdata;
+
+               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                       sdata = container_of(key->sdata->bss,
+                                       struct ieee80211_sub_if_data, u.ap);
+               drv_update_tkip_key(key->local, sdata, &key->conf, key->sta,
+                               iv32, key->u.tkip.rx[queue].p1k);
+               key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED;
        }
 
        tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key);