Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 41463
b: refs/heads/master
c: c9308b0
h: refs/heads/master
i:
  41461: 75e06f2
  41459: 930c4b8
  41455: 72e4e11
v: v3
  • Loading branch information
Daniel Drake authored and Jeff Garzik committed Dec 2, 2006
1 parent 97a8e3f commit 105f707
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f2423723d70298e04179f934ff17346c3e06f408
refs/heads/master: c9308b06c049a107edfbd4e5271771564eb6024d
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,7 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
bcm->ieee->host_encrypt = !!on;
bcm->ieee->host_decrypt = !!on;
bcm->ieee->host_build_iv = !on;
bcm->ieee->host_strip_iv_icv = !on;
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);

Expand Down
19 changes: 0 additions & 19 deletions trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,25 +543,6 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
break;
}

frame_ctl = le16_to_cpu(wlhdr->frame_ctl);
if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) {
frame_ctl &= ~IEEE80211_FCTL_PROTECTED;
wlhdr->frame_ctl = cpu_to_le16(frame_ctl);
/* trim IV and ICV */
/* FIXME: this must be done only for WEP encrypted packets */
if (skb->len < 32) {
dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag "
"set and length < 32)\n");
return -EINVAL;
} else {
memmove(skb->data + 4, skb->data, 24);
skb_pull(skb, 4);
skb_trim(skb, skb->len - 4);
stats.len -= 8;
}
wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
}

switch (WLAN_FC_GET_TYPE(frame_ctl)) {
case IEEE80211_FTYPE_MGMT:
ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/net/ieee80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,10 @@ struct ieee80211_device {
/* host performs multicast decryption */
int host_mc_decrypt;

/* host should strip IV and ICV from protected frames */
/* meaningful only when hardware decryption is being used */
int host_strip_iv_icv;

int host_open_frag;
int host_build_iv;
int ieee802_1x; /* is IEEE 802.1X used */
Expand Down
56 changes: 50 additions & 6 deletions trunk/net/ieee80211/ieee80211_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,17 +415,16 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee->host_mc_decrypt : ieee->host_decrypt;

if (can_be_decrypted) {
int idx = 0;
if (skb->len >= hdrlen + 3) {
/* Top two-bits of byte 3 are the key index */
idx = skb->data[hdrlen + 3] >> 6;
keyidx = skb->data[hdrlen + 3] >> 6;
}

/* ieee->crypt[] is WEP_KEY (4) in length. Given that idx
* is only allowed 2-bits of storage, no value of idx can
* be provided via above code that would result in idx
/* ieee->crypt[] is WEP_KEY (4) in length. Given that keyidx
* is only allowed 2-bits of storage, no value of keyidx can
* be provided via above code that would result in keyidx
* being out of range */
crypt = ieee->crypt[idx];
crypt = ieee->crypt[keyidx];

#ifdef NOT_YET
sta = NULL;
Expand Down Expand Up @@ -655,6 +654,51 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
goto rx_dropped;
}

/* If the frame was decrypted in hardware, we may need to strip off
* any security data (IV, ICV, etc) that was left behind */
if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
ieee->host_strip_iv_icv) {
int trimlen = 0;

/* Top two-bits of byte 3 are the key index */
if (skb->len >= hdrlen + 3)
keyidx = skb->data[hdrlen + 3] >> 6;

/* To strip off any security data which appears before the
* payload, we simply increase hdrlen (as the header gets
* chopped off immediately below). For the security data which
* appears after the payload, we use skb_trim. */

switch (ieee->sec.encode_alg[keyidx]) {
case SEC_ALG_WEP:
/* 4 byte IV */
hdrlen += 4;
/* 4 byte ICV */
trimlen = 4;
break;
case SEC_ALG_TKIP:
/* 4 byte IV, 4 byte ExtIV */
hdrlen += 8;
/* 8 byte MIC, 4 byte ICV */
trimlen = 12;
break;
case SEC_ALG_CCMP:
/* 8 byte CCMP header */
hdrlen += 8;
/* 8 byte MIC */
trimlen = 8;
break;
}

if (skb->len < trimlen)
goto rx_dropped;

__skb_trim(skb, skb->len - trimlen);

if (skb->len < hdrlen)
goto rx_dropped;
}

/* skb: hdr + (possible reassembled) full plaintext payload */

payload = skb->data + hdrlen;
Expand Down

0 comments on commit 105f707

Please sign in to comment.