aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_crypt_tkip.c
diff options
context:
space:
mode:
authorJames Ketrenos <jketreno@linux.intel.com>2005-09-21 12:58:49 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-22 15:39:41 -0400
commit31b59eaee8f8ec29d8cb6ac0c8eed086689d8030 (patch)
tree5ab119a07e98aaf623dc8ce6f04f7b3403b6b971 /net/ieee80211/ieee80211_crypt_tkip.c
parent31696160c7415b5a7efa650c7f1ca5c9623f5d8f (diff)
[PATCH] ieee80211: Added handle_deauth() callback, enhanced tkip/ccmp support of varying hw/sw offload
tree de81b55e78e85997642c651ea677078d0554a14f parent c8030da8c159f8b82712172a6748a42523aea83a author James Ketrenos <jketreno@linux.intel.com> 1127104380 -0500 committer James Ketrenos <jketreno@linux.intel.com> 1127315225 -0500 Added handle_deauth() callback. Enhanced crypt_{tkip,ccmp} to support varying splits of HW/SW offload. Changed channel freq to u32 from u16. Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'net/ieee80211/ieee80211_crypt_tkip.c')
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 21022f195bab..e0733050ae71 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -260,35 +260,27 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
260#endif 260#endif
261} 261}
262 262
263static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 263static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
264{ 264{
265 struct ieee80211_tkip_data *tkey = priv; 265 struct ieee80211_tkip_data *tkey = priv;
266 int len; 266 int len;
267 u8 rc4key[16], *pos, *icv; 267 u8 *rc4key, *pos, *icv;
268 struct ieee80211_hdr_4addr *hdr; 268 struct ieee80211_hdr_4addr *hdr;
269 u32 crc; 269 u32 crc;
270 struct scatterlist sg;
271 270
272 hdr = (struct ieee80211_hdr_4addr *)skb->data; 271 hdr = (struct ieee80211_hdr_4addr *)skb->data;
273 272
274 if (tkey->ieee->tkip_countermeasures) { 273 if (skb_headroom(skb) < 8 || skb->len < hdr_len)
275 if (net_ratelimit()) { 274 return NULL;
276 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
277 "TX packet to " MAC_FMT "\n",
278 tkey->ieee->dev->name, MAC_ARG(hdr->addr1));
279 }
280 return -1;
281 }
282
283 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
284 skb->len < hdr_len)
285 return -1;
286 275
287 if (!tkey->tx_phase1_done) { 276 if (!tkey->tx_phase1_done) {
288 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, 277 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
289 tkey->tx_iv32); 278 tkey->tx_iv32);
290 tkey->tx_phase1_done = 1; 279 tkey->tx_phase1_done = 1;
291 } 280 }
281 rc4key = kmalloc(16, GFP_ATOMIC);
282 if (!rc4key)
283 return NULL;
292 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); 284 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
293 285
294 len = skb->len - hdr_len; 286 len = skb->len - hdr_len;
@@ -297,9 +289,9 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
297 pos += hdr_len; 289 pos += hdr_len;
298 icv = skb_put(skb, 4); 290 icv = skb_put(skb, 4);
299 291
300 *pos++ = rc4key[0]; 292 *pos++ = *rc4key;
301 *pos++ = rc4key[1]; 293 *pos++ = *(rc4key + 1);
302 *pos++ = rc4key[2]; 294 *pos++ = *(rc4key + 2);
303 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ; 295 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
304 *pos++ = tkey->tx_iv32 & 0xff; 296 *pos++ = tkey->tx_iv32 & 0xff;
305 *pos++ = (tkey->tx_iv32 >> 8) & 0xff; 297 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
@@ -312,6 +304,38 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
312 icv[2] = crc >> 16; 304 icv[2] = crc >> 16;
313 icv[3] = crc >> 24; 305 icv[3] = crc >> 24;
314 306
307 return rc4key;
308}
309
310static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
311{
312 struct ieee80211_tkip_data *tkey = priv;
313 int len;
314 const u8 *rc4key;
315 u8 *pos;
316 struct scatterlist sg;
317
318 if (tkey->ieee->tkip_countermeasures) {
319 if (net_ratelimit()) {
320 struct ieee80211_hdr_4addr *hdr =
321 (struct ieee80211_hdr_4addr *)skb->data;
322 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
323 "TX packet to " MAC_FMT "\n",
324 tkey->ieee->dev->name, MAC_ARG(hdr->addr1));
325 }
326 return -1;
327 }
328
329 if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
330 return -1;
331
332 len = skb->len - hdr_len;
333 pos = skb->data + hdr_len;
334
335 rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
336 if (!rc4key)
337 return -1;
338
315 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); 339 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
316 sg.page = virt_to_page(pos); 340 sg.page = virt_to_page(pos);
317 sg.offset = offset_in_page(pos); 341 sg.offset = offset_in_page(pos);