mac80211: backport latest version from trunk as of r27395
[openwrt-10.03/.git] / 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 */