aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wpa.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2010-06-11 13:27:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-15 16:00:49 -0400
commit9190252c952a33efa1ceff4ef35188f8a27b81cb (patch)
treef6c7473c919e7a3f0ff7c1b6543da44f8c338d02 /net/mac80211/wpa.c
parent05e48e8e437148298f4673e1efe81f9ead5f41d7 (diff)
mac80211: Use a separate CCMP PN receive counter for management frames
When management frame protection (IEEE 802.11w) is used, we must use a separate counter for tracking received CCMP packet number for the management frames. The previously used NUM_RX_DATA_QUEUESth queue was shared with data frames when QoS was not used and that can cause problems in detecting replays incorrectly for robust management frames. Add a new counter just for robust management frames to avoid this issue. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r--net/mac80211/wpa.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 0adbcc941ac9..a14e67707476 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -436,6 +436,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
436 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 436 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
437 u8 pn[CCMP_PN_LEN]; 437 u8 pn[CCMP_PN_LEN];
438 int data_len; 438 int data_len;
439 int queue;
439 440
440 hdrlen = ieee80211_hdrlen(hdr->frame_control); 441 hdrlen = ieee80211_hdrlen(hdr->frame_control);
441 442
@@ -453,7 +454,10 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
453 454
454 ccmp_hdr2pn(pn, skb->data + hdrlen); 455 ccmp_hdr2pn(pn, skb->data + hdrlen);
455 456
456 if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { 457 queue = ieee80211_is_mgmt(hdr->frame_control) ?
458 NUM_RX_DATA_QUEUES : rx->queue;
459
460 if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) {
457 key->u.ccmp.replays++; 461 key->u.ccmp.replays++;
458 return RX_DROP_UNUSABLE; 462 return RX_DROP_UNUSABLE;
459 } 463 }
@@ -470,7 +474,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
470 return RX_DROP_UNUSABLE; 474 return RX_DROP_UNUSABLE;
471 } 475 }
472 476
473 memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN); 477 memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN);
474 478
475 /* Remove CCMP header and MIC */ 479 /* Remove CCMP header and MIC */
476 skb_trim(skb, skb->len - CCMP_MIC_LEN); 480 skb_trim(skb, skb->len - CCMP_MIC_LEN);