Root/package/mac80211/patches/420-mac80211_ignore_invalid_ccmp_rx_pn.patch

1--- a/net/mac80211/key.h
2+++ b/net/mac80211/key.h
3@@ -86,6 +86,7 @@ struct ieee80211_key {
4              * Management frames.
5              */
6             u8 rx_pn[NUM_RX_DATA_QUEUES + 1][6];
7+ u8 rx_invalid_pn[NUM_RX_DATA_QUEUES + 1];
8             struct crypto_cipher *tfm;
9             u32 replays; /* dot11RSNAStatsCCMPReplays */
10             /* scratch buffers for virt_to_page() (crypto API) */
11--- a/net/mac80211/wpa.c
12+++ b/net/mac80211/wpa.c
13@@ -441,6 +441,13 @@ ieee80211_crypto_ccmp_encrypt(struct iee
14     return TX_CONTINUE;
15 }
16 
17+static inline u64 pn_to_u64(u8 *data)
18+{
19+ u64 pn = get_unaligned_be32(data + 2);
20+ pn |= ((u64) get_unaligned_be16(data)) << 32;
21+ return pn;
22+}
23+
24 
25 ieee80211_rx_result
26 ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
27@@ -453,6 +460,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
28     u8 pn[CCMP_PN_LEN];
29     int data_len;
30     int queue;
31+ u64 diff;
32 
33     hdrlen = ieee80211_hdrlen(hdr->frame_control);
34 
35@@ -486,6 +494,11 @@ ieee80211_crypto_ccmp_decrypt(struct iee
36             return RX_DROP_UNUSABLE;
37     }
38 
39+ diff = pn_to_u64(pn) - pn_to_u64(key->u.ccmp.rx_pn[queue]);
40+ if (diff > 1000 && key->u.ccmp.rx_invalid_pn[queue]++ < 10)
41+ return RX_DROP_UNUSABLE;
42+
43+ key->u.ccmp.rx_invalid_pn[queue] = 0;
44     memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN);
45 
46     /* Remove CCMP header and MIC */
47

Archive Download this file



interactive