10 #include <linux/netdevice.h>
11 #include <linux/types.h>
13 #include <linux/compiler.h>
16 #include <asm/unaligned.h>
18 #include <crypto/aes.h>
44 if (skb->
len < hdrlen)
57 tx->
local->ops->set_frag_threshold) &&
67 if (
WARN_ON(skb_tailroom(skb) < tail ||
142 if (skb_linearize(rx->
skb))
144 hdr = (
void *)skb->
data;
146 data = skb->
data + hdrlen;
170 rx->
key ? rx->
key->conf.keyidx : -1,
186 if (
info->control.hw_key &&
196 if (
info->control.hw_key)
201 if (
WARN_ON(skb_tailroom(skb) < tail ||
207 skb_set_network_header(skb, skb_network_offset(skb) +
TKIP_IV_LEN);
211 if (
info->control.hw_key &&
217 key->u.tkip.tx.iv16++;
218 if (
key->u.tkip.tx.iv16 == 0)
219 key->u.tkip.tx.iv32++;
221 spin_unlock_irqrestore(&
key->u.tkip.txlock, flags);
224 if (
info->control.hw_key)
242 skb_queue_walk(&tx->
skbs, skb) {
243 if (tkip_encrypt_skb(tx, skb) < 0)
255 int hdrlen,
res, hwaccel = 0;
265 if (!rx->
sta || skb->
len - hdrlen < 12)
269 if (skb_linearize(rx->
skb))
271 hdr = (
void *)skb->
data;
283 skb->
len - hdrlen, rx->
sta->sta.addr,
305 int a4_included,
mgmt;
347 b_0[1] = qos_tid | (mgmt << 4);
351 put_unaligned_be16(data_len, &b_0[14]);
355 put_unaligned_be16(len_a, &aad[0]);
374 static inline void ccmp_pn2hdr(
u8 *hdr,
u8 *pn,
int key_id)
379 hdr[3] = 0x20 | (key_id << 6);
387 static inline void ccmp_hdr2pn(
u8 *pn,
u8 *hdr)
409 if (
info->control.hw_key &&
422 if (
info->control.hw_key)
427 if (
WARN_ON(skb_tailroom(skb) < tail ||
428 skb_headroom(skb) < CCMP_HDR_LEN))
432 memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
433 skb_set_network_header(skb, skb_network_offset(skb) + CCMP_HDR_LEN);
436 if (
info->control.hw_key &&
452 ccmp_pn2hdr(pos, pn,
key->conf.keyidx);
455 if (
info->control.hw_key)
459 ccmp_special_blocks(skb, pn, scratch, 0);
474 skb_queue_walk(&tx->
skbs, skb) {
475 if (ccmp_encrypt_skb(tx, skb) < 0)
498 !ieee80211_is_robust_mgmt_frame(hdr))
502 if (!rx->
sta || data_len < 0)
506 if (!pskb_may_pull(rx->
skb, hdrlen + CCMP_HDR_LEN))
509 if (skb_linearize(rx->
skb))
513 ccmp_hdr2pn(pn, skb->
data + hdrlen);
518 key->u.ccmp.replays++;
525 ccmp_special_blocks(skb, pn, scratch, 1);
528 key->u.ccmp.tfm, scratch,
529 skb->
data + hdrlen + CCMP_HDR_LEN, data_len,
530 skb->
data + skb->
len - CCMP_MIC_LEN,
531 skb->
data + hdrlen + CCMP_HDR_LEN))
538 if (pskb_trim(skb, skb->
len - CCMP_MIC_LEN))
547 static void bip_aad(
struct sk_buff *skb,
u8 *aad)
565 static inline void bip_ipn_set64(
u8 *
d,
u64 pn)
575 static inline void bip_ipn_swap(
u8 *
d,
const u8 *
s)
599 skb = skb_peek(&tx->
skbs);
601 info = IEEE80211_SKB_CB(skb);
606 if (
WARN_ON(skb_tailroom(skb) <
sizeof(*mmie)))
611 mmie->
length =
sizeof(*mmie) - 2;
638 u8 aad[20],
mic[8], ipn[6];
646 if (skb->
len < 24 +
sizeof(*mmie))
650 (skb->
data + skb->
len -
sizeof(*mmie));
652 mmie->
length !=
sizeof(*mmie) - 2)
666 skb->
data + 24, skb->
len - 24, mic);
687 skb_queue_walk(&tx->
skbs, skb) {
688 info = IEEE80211_SKB_CB(skb);