diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-03-12 08:49:14 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-13 14:54:17 -0400 |
commit | a8286911881948c7a2ecc63ee4224c258cce2da3 (patch) | |
tree | a35566503b81c654db55857f42fe9664d0aab3af /net/mac80211/wpa.c | |
parent | 617bbde878604adfcd557fc2a8952f77ab4ebd95 (diff) |
mac80211: linearize SKBs as needed for crypto
Not linearizing every SKB will help actually pass
non-linear SKBs all the way up when on an encrypted
connection. For now, linearize TKIP completely as
it is lower performance and I don't quite grok all
the details.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index b758350919ff..0ae23c60968c 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -138,6 +138,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
138 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) | 138 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) |
139 | return RX_DROP_UNUSABLE; | 139 | return RX_DROP_UNUSABLE; |
140 | 140 | ||
141 | if (skb_linearize(rx->skb)) | ||
142 | return RX_DROP_UNUSABLE; | ||
143 | hdr = (void *)skb->data; | ||
144 | |||
141 | data = skb->data + hdrlen; | 145 | data = skb->data + hdrlen; |
142 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | 146 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; |
143 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; | 147 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; |
@@ -253,6 +257,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
253 | if (!rx->sta || skb->len - hdrlen < 12) | 257 | if (!rx->sta || skb->len - hdrlen < 12) |
254 | return RX_DROP_UNUSABLE; | 258 | return RX_DROP_UNUSABLE; |
255 | 259 | ||
260 | /* it may be possible to optimize this a bit more */ | ||
261 | if (skb_linearize(rx->skb)) | ||
262 | return RX_DROP_UNUSABLE; | ||
263 | hdr = (void *)skb->data; | ||
264 | |||
256 | /* | 265 | /* |
257 | * Let TKIP code verify IV, but skip decryption. | 266 | * Let TKIP code verify IV, but skip decryption. |
258 | * In the case where hardware checks the IV as well, | 267 | * In the case where hardware checks the IV as well, |
@@ -484,6 +493,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
484 | if (!rx->sta || data_len < 0) | 493 | if (!rx->sta || data_len < 0) |
485 | return RX_DROP_UNUSABLE; | 494 | return RX_DROP_UNUSABLE; |
486 | 495 | ||
496 | if (status->flag & RX_FLAG_DECRYPTED) { | ||
497 | if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN)) | ||
498 | return RX_DROP_UNUSABLE; | ||
499 | } else { | ||
500 | if (skb_linearize(rx->skb)) | ||
501 | return RX_DROP_UNUSABLE; | ||
502 | } | ||
503 | |||
487 | ccmp_hdr2pn(pn, skb->data + hdrlen); | 504 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
488 | 505 | ||
489 | queue = rx->security_idx; | 506 | queue = rx->security_idx; |
@@ -509,7 +526,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
509 | memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); | 526 | memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); |
510 | 527 | ||
511 | /* Remove CCMP header and MIC */ | 528 | /* Remove CCMP header and MIC */ |
512 | skb_trim(skb, skb->len - CCMP_MIC_LEN); | 529 | if (pskb_trim(skb, skb->len - CCMP_MIC_LEN)) |
530 | return RX_DROP_UNUSABLE; | ||
513 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); | 531 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); |
514 | skb_pull(skb, CCMP_HDR_LEN); | 532 | skb_pull(skb, CCMP_HDR_LEN); |
515 | 533 | ||
@@ -609,6 +627,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
609 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 627 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
610 | return RX_CONTINUE; | 628 | return RX_CONTINUE; |
611 | 629 | ||
630 | /* management frames are already linear */ | ||
631 | |||
612 | if (skb->len < 24 + sizeof(*mmie)) | 632 | if (skb->len < 24 + sizeof(*mmie)) |
613 | return RX_DROP_UNUSABLE; | 633 | return RX_DROP_UNUSABLE; |
614 | 634 | ||