diff options
-rw-r--r-- | drivers/net/wireless/b43/xmit.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 3 | ||||
-rw-r--r-- | include/net/mac80211.h | 48 | ||||
-rw-r--r-- | net/mac80211/key.c | 1 | ||||
-rw-r--r-- | net/mac80211/key.h | 10 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 111 | ||||
-rw-r--r-- | net/mac80211/tkip.h | 8 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 9 |
9 files changed, 103 insertions, 93 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 488b898418a3..82bcf7595139 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
323 | /* we give the phase1key and iv16 here, the key is stored in | 323 | /* we give the phase1key and iv16 here, the key is stored in |
324 | * shm. With that the hardware can do phase 2 and encryption. | 324 | * shm. With that the hardware can do phase 2 and encryption. |
325 | */ | 325 | */ |
326 | ieee80211_get_tkip_key(info->control.hw_key, skb_frag, | 326 | ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key); |
327 | IEEE80211_TKIP_P1_KEY, (u8*)phase1key); | ||
328 | /* phase1key is in host endian. Copy to little-endian txhdr->iv. */ | 327 | /* phase1key is in host endian. Copy to little-endian txhdr->iv. */ |
329 | for (i = 0; i < 5; i++) { | 328 | for (i = 0; i < 5; i++) { |
330 | txhdr->iv[i * 2 + 0] = phase1key[i]; | 329 | txhdr->iv[i * 2 + 0] = phase1key[i]; |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c index 79ac081832fb..ac4f64de1363 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c | |||
@@ -240,8 +240,7 @@ static void iwl4965_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
240 | 240 | ||
241 | case WLAN_CIPHER_SUITE_TKIP: | 241 | case WLAN_CIPHER_SUITE_TKIP: |
242 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; | 242 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; |
243 | ieee80211_get_tkip_key(keyconf, skb_frag, | 243 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); |
244 | IEEE80211_TKIP_P2_KEY, tx_cmd->key); | ||
245 | IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); | 244 | IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); |
246 | break; | 245 | break; |
247 | 246 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c05a8d9fbd2e..a87e95728b1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -497,8 +497,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
497 | 497 | ||
498 | case WLAN_CIPHER_SUITE_TKIP: | 498 | case WLAN_CIPHER_SUITE_TKIP: |
499 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; | 499 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; |
500 | ieee80211_get_tkip_key(keyconf, skb_frag, | 500 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); |
501 | IEEE80211_TKIP_P2_KEY, tx_cmd->key); | ||
502 | IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); | 501 | IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); |
503 | break; | 502 | break; |
504 | 503 | ||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2474019f47d3..0aae7bc1eeae 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -962,21 +962,6 @@ enum sta_notify_cmd { | |||
962 | }; | 962 | }; |
963 | 963 | ||
964 | /** | 964 | /** |
965 | * enum ieee80211_tkip_key_type - get tkip key | ||
966 | * | ||
967 | * Used by drivers which need to get a tkip key for skb. Some drivers need a | ||
968 | * phase 1 key, others need a phase 2 key. A single function allows the driver | ||
969 | * to get the key, this enum indicates what type of key is required. | ||
970 | * | ||
971 | * @IEEE80211_TKIP_P1_KEY: the driver needs a phase 1 key | ||
972 | * @IEEE80211_TKIP_P2_KEY: the driver needs a phase 2 key | ||
973 | */ | ||
974 | enum ieee80211_tkip_key_type { | ||
975 | IEEE80211_TKIP_P1_KEY, | ||
976 | IEEE80211_TKIP_P2_KEY, | ||
977 | }; | ||
978 | |||
979 | /** | ||
980 | * enum ieee80211_hw_flags - hardware flags | 965 | * enum ieee80211_hw_flags - hardware flags |
981 | * | 966 | * |
982 | * These flags are used to indicate hardware capabilities to | 967 | * These flags are used to indicate hardware capabilities to |
@@ -2579,21 +2564,32 @@ struct sk_buff * | |||
2579 | ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | 2564 | ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif); |
2580 | 2565 | ||
2581 | /** | 2566 | /** |
2582 | * ieee80211_get_tkip_key - get a TKIP rc4 for skb | 2567 | * ieee80211_get_tkip_p1k - get a TKIP phase 1 key |
2568 | * | ||
2569 | * This function returns the TKIP phase 1 key for the IV32 taken | ||
2570 | * from the given packet. | ||
2571 | * | ||
2572 | * @keyconf: the parameter passed with the set key | ||
2573 | * @skb: the packet to take the IV32 value from that will be encrypted | ||
2574 | * with this P1K | ||
2575 | * @p1k: a buffer to which the key will be written, as 5 u16 values | ||
2576 | */ | ||
2577 | void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf, | ||
2578 | struct sk_buff *skb, u16 *p1k); | ||
2579 | |||
2580 | /** | ||
2581 | * ieee80211_get_tkip_p2k - get a TKIP phase 2 key | ||
2583 | * | 2582 | * |
2584 | * This function computes a TKIP rc4 key for an skb. It computes | 2583 | * This function computes the TKIP RC4 key for the IV values |
2585 | * a phase 1 key if needed (iv16 wraps around). This function is to | 2584 | * in the packet. |
2586 | * be used by drivers which can do HW encryption but need to compute | ||
2587 | * to phase 1/2 key in SW. | ||
2588 | * | 2585 | * |
2589 | * @keyconf: the parameter passed with the set key | 2586 | * @keyconf: the parameter passed with the set key |
2590 | * @skb: the skb for which the key is needed | 2587 | * @skb: the packet to take the IV32/IV16 values from that will be |
2591 | * @type: TBD | 2588 | * encrypted with this key |
2592 | * @key: a buffer to which the key will be written | 2589 | * @p2k: a buffer to which the key will be written, 16 bytes |
2593 | */ | 2590 | */ |
2594 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | 2591 | void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, |
2595 | struct sk_buff *skb, | 2592 | struct sk_buff *skb, u8 *p2k); |
2596 | enum ieee80211_tkip_key_type type, u8 *key); | ||
2597 | 2593 | ||
2598 | /** | 2594 | /** |
2599 | * ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying | 2595 | * ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1208a7878bfd..d930d4d4876d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -369,6 +369,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
369 | get_unaligned_le16(seq); | 369 | get_unaligned_le16(seq); |
370 | } | 370 | } |
371 | } | 371 | } |
372 | spin_lock_init(&key->u.tkip.txlock); | ||
372 | break; | 373 | break; |
373 | case WLAN_CIPHER_SUITE_CCMP: | 374 | case WLAN_CIPHER_SUITE_CCMP: |
374 | key->conf.iv_len = CCMP_HDR_LEN; | 375 | key->conf.iv_len = CCMP_HDR_LEN; |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index d801d5351336..1493c3e56b9f 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -52,9 +52,10 @@ enum ieee80211_internal_tkip_state { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | struct tkip_ctx { | 54 | struct tkip_ctx { |
55 | u32 iv32; | 55 | u32 iv32; /* current iv32 */ |
56 | u16 iv16; | 56 | u16 iv16; /* current iv16 */ |
57 | u16 p1k[5]; | 57 | u16 p1k[5]; /* p1k cache */ |
58 | u32 p1k_iv32; /* iv32 for which p1k computed */ | ||
58 | enum ieee80211_internal_tkip_state state; | 59 | enum ieee80211_internal_tkip_state state; |
59 | }; | 60 | }; |
60 | 61 | ||
@@ -71,6 +72,9 @@ struct ieee80211_key { | |||
71 | 72 | ||
72 | union { | 73 | union { |
73 | struct { | 74 | struct { |
75 | /* protects tx context */ | ||
76 | spinlock_t txlock; | ||
77 | |||
74 | /* last used TSC */ | 78 | /* last used TSC */ |
75 | struct tkip_ctx tx; | 79 | struct tkip_ctx tx; |
76 | 80 | ||
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 757e4eb2baf7..de570b38460f 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -101,6 +101,7 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, | |||
101 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; | 101 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
102 | } | 102 | } |
103 | ctx->state = TKIP_STATE_PHASE1_DONE; | 103 | ctx->state = TKIP_STATE_PHASE1_DONE; |
104 | ctx->p1k_iv32 = tsc_IV32; | ||
104 | } | 105 | } |
105 | 106 | ||
106 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, | 107 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, |
@@ -140,60 +141,72 @@ static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, | |||
140 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 141 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
141 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 142 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
142 | * the packet payload). */ | 143 | * the packet payload). */ |
143 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) | 144 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key) |
144 | { | 145 | { |
145 | pos = write_tkip_iv(pos, iv16); | 146 | lockdep_assert_held(&key->u.tkip.txlock); |
147 | |||
148 | pos = write_tkip_iv(pos, key->u.tkip.tx.iv16); | ||
146 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 149 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
147 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); | 150 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); |
148 | return pos + 4; | 151 | return pos + 4; |
149 | } | 152 | } |
150 | 153 | ||
151 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | 154 | static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32) |
152 | struct sk_buff *skb, enum ieee80211_tkip_key_type type, | 155 | { |
153 | u8 *outkey) | 156 | struct ieee80211_sub_if_data *sdata = key->sdata; |
157 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
158 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
159 | |||
160 | lockdep_assert_held(&key->u.tkip.txlock); | ||
161 | |||
162 | /* | ||
163 | * Update the P1K when the IV32 is different from the value it | ||
164 | * had when we last computed it (or when not initialised yet). | ||
165 | * This might flip-flop back and forth if packets are processed | ||
166 | * out-of-order due to the different ACs, but then we have to | ||
167 | * just compute the P1K more often. | ||
168 | */ | ||
169 | if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT) | ||
170 | tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32); | ||
171 | } | ||
172 | |||
173 | void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf, | ||
174 | struct sk_buff *skb, u16 *p1k) | ||
154 | { | 175 | { |
155 | struct ieee80211_key *key = (struct ieee80211_key *) | 176 | struct ieee80211_key *key = (struct ieee80211_key *) |
156 | container_of(keyconf, struct ieee80211_key, conf); | 177 | container_of(keyconf, struct ieee80211_key, conf); |
178 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
157 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 179 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
158 | u8 *data; | 180 | const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); |
159 | const u8 *tk; | 181 | u32 iv32 = get_unaligned_le32(&data[4]); |
160 | struct tkip_ctx *ctx; | 182 | unsigned long flags; |
161 | u16 iv16; | 183 | |
162 | u32 iv32; | 184 | spin_lock_irqsave(&key->u.tkip.txlock, flags); |
163 | 185 | ieee80211_compute_tkip_p1k(key, iv32); | |
164 | data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); | 186 | memcpy(p1k, ctx->p1k, sizeof(ctx->p1k)); |
165 | iv16 = data[2] | (data[0] << 8); | 187 | spin_unlock_irqrestore(&key->u.tkip.txlock, flags); |
166 | iv32 = get_unaligned_le32(&data[4]); | 188 | } |
167 | 189 | EXPORT_SYMBOL(ieee80211_get_tkip_p1k); | |
168 | tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
169 | ctx = &key->u.tkip.tx; | ||
170 | |||
171 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | ||
172 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", | ||
173 | iv16, iv32); | ||
174 | |||
175 | if (iv32 != ctx->iv32) { | ||
176 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", | ||
177 | iv32, ctx->iv32); | ||
178 | printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " | ||
179 | "fragmented packet\n"); | ||
180 | } | ||
181 | #endif | ||
182 | |||
183 | /* Update the p1k only when the iv16 in the packet wraps around, this | ||
184 | * might occur after the wrap around of iv16 in the key in case of | ||
185 | * fragmented packets. */ | ||
186 | if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) | ||
187 | tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); | ||
188 | |||
189 | if (type == IEEE80211_TKIP_P1_KEY) { | ||
190 | memcpy(outkey, ctx->p1k, sizeof(u16) * 5); | ||
191 | return; | ||
192 | } | ||
193 | 190 | ||
194 | tkip_mixing_phase2(tk, ctx, iv16, outkey); | 191 | void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, |
192 | struct sk_buff *skb, u8 *p2k) | ||
193 | { | ||
194 | struct ieee80211_key *key = (struct ieee80211_key *) | ||
195 | container_of(keyconf, struct ieee80211_key, conf); | ||
196 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
197 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
198 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
199 | const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); | ||
200 | u32 iv32 = get_unaligned_le32(&data[4]); | ||
201 | u16 iv16 = data[2] | (data[0] << 8); | ||
202 | unsigned long flags; | ||
203 | |||
204 | spin_lock_irqsave(&key->u.tkip.txlock, flags); | ||
205 | ieee80211_compute_tkip_p1k(key, iv32); | ||
206 | tkip_mixing_phase2(tk, ctx, iv16, p2k); | ||
207 | spin_unlock_irqrestore(&key->u.tkip.txlock, flags); | ||
195 | } | 208 | } |
196 | EXPORT_SYMBOL(ieee80211_get_tkip_key); | 209 | EXPORT_SYMBOL(ieee80211_get_tkip_p2k); |
197 | 210 | ||
198 | /* | 211 | /* |
199 | * Encrypt packet payload with TKIP using @key. @pos is a pointer to the | 212 | * Encrypt packet payload with TKIP using @key. @pos is a pointer to the |
@@ -204,19 +217,15 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key); | |||
204 | */ | 217 | */ |
205 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, | 218 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, |
206 | struct ieee80211_key *key, | 219 | struct ieee80211_key *key, |
207 | u8 *pos, size_t payload_len, u8 *ta) | 220 | struct sk_buff *skb, |
221 | u8 *payload, size_t payload_len) | ||
208 | { | 222 | { |
209 | u8 rc4key[16]; | 223 | u8 rc4key[16]; |
210 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
211 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
212 | |||
213 | /* Calculate per-packet key */ | ||
214 | if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) | ||
215 | tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); | ||
216 | 224 | ||
217 | tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); | 225 | ieee80211_get_tkip_p2k(&key->conf, skb, rc4key); |
218 | 226 | ||
219 | return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 227 | return ieee80211_wep_encrypt_data(tfm, rc4key, 16, |
228 | payload, payload_len); | ||
220 | } | 229 | } |
221 | 230 | ||
222 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the | 231 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the |
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index 1cab9c86978f..e3ecb659b90a 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h | |||
@@ -13,11 +13,13 @@ | |||
13 | #include <linux/crypto.h> | 13 | #include <linux/crypto.h> |
14 | #include "key.h" | 14 | #include "key.h" |
15 | 15 | ||
16 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); | 16 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key); |
17 | 17 | ||
18 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, | 18 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, |
19 | struct ieee80211_key *key, | 19 | struct ieee80211_key *key, |
20 | u8 *pos, size_t payload_len, u8 *ta); | 20 | struct sk_buff *skb, |
21 | u8 *payload, size_t payload_len); | ||
22 | |||
21 | enum { | 23 | enum { |
22 | TKIP_DECRYPT_OK = 0, | 24 | TKIP_DECRYPT_OK = 0, |
23 | TKIP_DECRYPT_NO_EXT_IV = -1, | 25 | TKIP_DECRYPT_NO_EXT_IV = -1, |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index d91c1a26630d..4ded2ae48a5f 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -171,6 +171,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
171 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 171 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
172 | struct ieee80211_key *key = tx->key; | 172 | struct ieee80211_key *key = tx->key; |
173 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 173 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
174 | unsigned long flags; | ||
174 | unsigned int hdrlen; | 175 | unsigned int hdrlen; |
175 | int len, tail; | 176 | int len, tail; |
176 | u8 *pos; | 177 | u8 *pos; |
@@ -198,11 +199,12 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
198 | pos += hdrlen; | 199 | pos += hdrlen; |
199 | 200 | ||
200 | /* Increase IV for the frame */ | 201 | /* Increase IV for the frame */ |
202 | spin_lock_irqsave(&key->u.tkip.txlock, flags); | ||
201 | key->u.tkip.tx.iv16++; | 203 | key->u.tkip.tx.iv16++; |
202 | if (key->u.tkip.tx.iv16 == 0) | 204 | if (key->u.tkip.tx.iv16 == 0) |
203 | key->u.tkip.tx.iv32++; | 205 | key->u.tkip.tx.iv32++; |
204 | 206 | pos = ieee80211_tkip_add_iv(pos, key); | |
205 | pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); | 207 | spin_unlock_irqrestore(&key->u.tkip.txlock, flags); |
206 | 208 | ||
207 | /* hwaccel - with software IV */ | 209 | /* hwaccel - with software IV */ |
208 | if (info->control.hw_key) | 210 | if (info->control.hw_key) |
@@ -211,9 +213,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
211 | /* Add room for ICV */ | 213 | /* Add room for ICV */ |
212 | skb_put(skb, TKIP_ICV_LEN); | 214 | skb_put(skb, TKIP_ICV_LEN); |
213 | 215 | ||
214 | hdr = (struct ieee80211_hdr *) skb->data; | ||
215 | return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, | 216 | return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, |
216 | key, pos, len, hdr->addr2); | 217 | key, skb, pos, len); |
217 | } | 218 | } |
218 | 219 | ||
219 | 220 | ||