diff options
-rw-r--r-- | net/mac80211/debugfs_key.c | 2 | ||||
-rw-r--r-- | net/mac80211/key.c | 2 | ||||
-rw-r--r-- | net/mac80211/key.h | 8 | ||||
-rw-r--r-- | net/mac80211/rx.c | 9 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 8 |
5 files changed, 22 insertions, 7 deletions
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 97c9e46e859e..fa5e76e658ef 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -143,7 +143,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, | |||
143 | len = p - buf; | 143 | len = p - buf; |
144 | break; | 144 | break; |
145 | case ALG_CCMP: | 145 | case ALG_CCMP: |
146 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { | 146 | for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) { |
147 | rpn = key->u.ccmp.rx_pn[i]; | 147 | rpn = key->u.ccmp.rx_pn[i]; |
148 | p += scnprintf(p, sizeof(buf)+buf-p, | 148 | p += scnprintf(p, sizeof(buf)+buf-p, |
149 | "%02x%02x%02x%02x%02x%02x\n", | 149 | "%02x%02x%02x%02x%02x%02x\n", |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index d0d9001a4a6a..50d1cff23d8e 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -273,7 +273,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | |||
273 | key->conf.iv_len = CCMP_HDR_LEN; | 273 | key->conf.iv_len = CCMP_HDR_LEN; |
274 | key->conf.icv_len = CCMP_MIC_LEN; | 274 | key->conf.icv_len = CCMP_MIC_LEN; |
275 | if (seq) { | 275 | if (seq) { |
276 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 276 | for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) |
277 | for (j = 0; j < CCMP_PN_LEN; j++) | 277 | for (j = 0; j < CCMP_PN_LEN; j++) |
278 | key->u.ccmp.rx_pn[i][j] = | 278 | key->u.ccmp.rx_pn[i][j] = |
279 | seq[CCMP_PN_LEN - j - 1]; | 279 | seq[CCMP_PN_LEN - j - 1]; |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 9996e3be6e63..a3849fa3fce8 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -77,7 +77,13 @@ struct ieee80211_key { | |||
77 | } tkip; | 77 | } tkip; |
78 | struct { | 78 | struct { |
79 | u8 tx_pn[6]; | 79 | u8 tx_pn[6]; |
80 | u8 rx_pn[NUM_RX_DATA_QUEUES][6]; | 80 | /* |
81 | * Last received packet number. The first | ||
82 | * NUM_RX_DATA_QUEUES counters are used with Data | ||
83 | * frames and the last counter is used with Robust | ||
84 | * Management frames. | ||
85 | */ | ||
86 | u8 rx_pn[NUM_RX_DATA_QUEUES + 1][6]; | ||
81 | struct crypto_cipher *tfm; | 87 | struct crypto_cipher *tfm; |
82 | u32 replays; /* dot11RSNAStatsCCMPReplays */ | 88 | u32 replays; /* dot11RSNAStatsCCMPReplays */ |
83 | /* scratch buffers for virt_to_page() (crypto API) */ | 89 | /* scratch buffers for virt_to_page() (crypto API) */ |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1594ebe80a4f..1f76352caa9e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1267,11 +1267,13 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1267 | rx->queue, &(rx->skb)); | 1267 | rx->queue, &(rx->skb)); |
1268 | if (rx->key && rx->key->conf.alg == ALG_CCMP && | 1268 | if (rx->key && rx->key->conf.alg == ALG_CCMP && |
1269 | ieee80211_has_protected(fc)) { | 1269 | ieee80211_has_protected(fc)) { |
1270 | int queue = ieee80211_is_mgmt(fc) ? | ||
1271 | NUM_RX_DATA_QUEUES : rx->queue; | ||
1270 | /* Store CCMP PN so that we can verify that the next | 1272 | /* Store CCMP PN so that we can verify that the next |
1271 | * fragment has a sequential PN value. */ | 1273 | * fragment has a sequential PN value. */ |
1272 | entry->ccmp = 1; | 1274 | entry->ccmp = 1; |
1273 | memcpy(entry->last_pn, | 1275 | memcpy(entry->last_pn, |
1274 | rx->key->u.ccmp.rx_pn[rx->queue], | 1276 | rx->key->u.ccmp.rx_pn[queue], |
1275 | CCMP_PN_LEN); | 1277 | CCMP_PN_LEN); |
1276 | } | 1278 | } |
1277 | return RX_QUEUED; | 1279 | return RX_QUEUED; |
@@ -1291,6 +1293,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1291 | if (entry->ccmp) { | 1293 | if (entry->ccmp) { |
1292 | int i; | 1294 | int i; |
1293 | u8 pn[CCMP_PN_LEN], *rpn; | 1295 | u8 pn[CCMP_PN_LEN], *rpn; |
1296 | int queue; | ||
1294 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) | 1297 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) |
1295 | return RX_DROP_UNUSABLE; | 1298 | return RX_DROP_UNUSABLE; |
1296 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); | 1299 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); |
@@ -1299,7 +1302,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1299 | if (pn[i]) | 1302 | if (pn[i]) |
1300 | break; | 1303 | break; |
1301 | } | 1304 | } |
1302 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; | 1305 | queue = ieee80211_is_mgmt(fc) ? |
1306 | NUM_RX_DATA_QUEUES : rx->queue; | ||
1307 | rpn = rx->key->u.ccmp.rx_pn[queue]; | ||
1303 | if (memcmp(pn, rpn, CCMP_PN_LEN)) | 1308 | if (memcmp(pn, rpn, CCMP_PN_LEN)) |
1304 | return RX_DROP_UNUSABLE; | 1309 | return RX_DROP_UNUSABLE; |
1305 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); | 1310 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); |
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); |