aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/b43/xmit.c3
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-tx.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c3
-rw-r--r--include/net/mac80211.h48
-rw-r--r--net/mac80211/key.c1
-rw-r--r--net/mac80211/key.h10
-rw-r--r--net/mac80211/tkip.c111
-rw-r--r--net/mac80211/tkip.h8
-rw-r--r--net/mac80211/wpa.c9
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 */
974enum 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 *
2579ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 2564ieee80211_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 */
2577void 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 */
2594void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, 2591void 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
54struct tkip_ctx { 54struct 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
106static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, 107static 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). */
143u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) 144u8 *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
151void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, 154static 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
173void 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 189EXPORT_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); 191void 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}
196EXPORT_SYMBOL(ieee80211_get_tkip_key); 209EXPORT_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 */
205int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, 218int 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
16u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); 16u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key);
17 17
18int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, 18int 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
21enum { 23enum {
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