CC: hostapd: fix WPA packet number reuse with replayed messages and key reinstallation
[15.05/openwrt.git] / package / network / services / hostapd / patches / 903-v2.6-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch
1 From 8280294e74846ea342389a0cd17215050fa5afe8 Mon Sep 17 00:00:00 2001
2 From: Jouni Malinen <j@w1.fi>
3 Date: Sun, 1 Oct 2017 12:12:24 +0300
4 Subject: [PATCH 3/8] Extend protection of GTK/IGTK reinstallation of WNM-Sleep
5  Mode cases
6
7 This extends the protection to track last configured GTK/IGTK value
8 separately from EAPOL-Key frames and WNM-Sleep Mode frames to cover a
9 corner case where these two different mechanisms may get used when the
10 GTK/IGTK has changed and tracking a single value is not sufficient to
11 detect a possible key reconfiguration.
12
13 Signed-off-by: Jouni Malinen <j@w1.fi>
14 ---
15  src/rsn_supp/wpa.c   | 53 +++++++++++++++++++++++++++++++++++++---------------
16  src/rsn_supp/wpa_i.h |  2 ++
17  2 files changed, 40 insertions(+), 15 deletions(-)
18
19 diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
20 index 95bd7be..7a2c68d 100644
21 --- a/src/rsn_supp/wpa.c
22 +++ b/src/rsn_supp/wpa.c
23 @@ -709,14 +709,17 @@ struct wpa_gtk_data {
24  
25  static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
26                                       const struct wpa_gtk_data *gd,
27 -                                     const u8 *key_rsc)
28 +                                     const u8 *key_rsc, int wnm_sleep)
29  {
30         const u8 *_gtk = gd->gtk;
31         u8 gtk_buf[32];
32  
33         /* Detect possible key reinstallation */
34 -       if (sm->gtk.gtk_len == (size_t) gd->gtk_len &&
35 -           os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) {
36 +       if ((sm->gtk.gtk_len == (size_t) gd->gtk_len &&
37 +            os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) ||
38 +           (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len &&
39 +            os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk,
40 +                      sm->gtk_wnm_sleep.gtk_len) == 0)) {
41                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
42                         "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
43                         gd->keyidx, gd->tx, gd->gtk_len);
44 @@ -757,8 +760,14 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
45         }
46         os_memset(gtk_buf, 0, sizeof(gtk_buf));
47  
48 -       sm->gtk.gtk_len = gd->gtk_len;
49 -       os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
50 +       if (wnm_sleep) {
51 +               sm->gtk_wnm_sleep.gtk_len = gd->gtk_len;
52 +               os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk,
53 +                         sm->gtk_wnm_sleep.gtk_len);
54 +       } else {
55 +               sm->gtk.gtk_len = gd->gtk_len;
56 +               os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
57 +       }
58  
59         return 0;
60  }
61 @@ -852,7 +861,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
62             (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
63                                                gtk_len, gtk_len,
64                                                &gd.key_rsc_len, &gd.alg) ||
65 -            wpa_supplicant_install_gtk(sm, &gd, key_rsc))) {
66 +            wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0))) {
67                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
68                         "RSN: Failed to install GTK");
69                 os_memset(&gd, 0, sizeof(gd));
70 @@ -868,14 +877,18 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
71  
72  #ifdef CONFIG_IEEE80211W
73  static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
74 -                                      const struct wpa_igtk_kde *igtk)
75 +                                      const struct wpa_igtk_kde *igtk,
76 +                                      int wnm_sleep)
77  {
78         size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
79         u16 keyidx = WPA_GET_LE16(igtk->keyid);
80  
81         /* Detect possible key reinstallation */
82 -       if (sm->igtk.igtk_len == len &&
83 -           os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) {
84 +       if ((sm->igtk.igtk_len == len &&
85 +            os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) ||
86 +           (sm->igtk_wnm_sleep.igtk_len == len &&
87 +            os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk,
88 +                      sm->igtk_wnm_sleep.igtk_len) == 0)) {
89                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
90                         "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)",
91                         keyidx);
92 @@ -900,8 +913,14 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
93                 return -1;
94         }
95  
96 -       sm->igtk.igtk_len = len;
97 -       os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
98 +       if (wnm_sleep) {
99 +               sm->igtk_wnm_sleep.igtk_len = len;
100 +               os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk,
101 +                         sm->igtk_wnm_sleep.igtk_len);
102 +       } else {
103 +               sm->igtk.igtk_len = len;
104 +               os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
105 +       }
106  
107         return 0;
108  }
109 @@ -924,7 +943,7 @@ static int ieee80211w_set_keys(struct wpa_sm *sm,
110                         return -1;
111  
112                 igtk = (const struct wpa_igtk_kde *) ie->igtk;
113 -               if (wpa_supplicant_install_igtk(sm, igtk) < 0)
114 +               if (wpa_supplicant_install_igtk(sm, igtk, 0) < 0)
115                         return -1;
116         }
117  
118 @@ -1574,7 +1593,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
119         if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
120                 key_rsc = null_rsc;
121  
122 -       if (wpa_supplicant_install_gtk(sm, &gd, key_rsc) ||
123 +       if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0) ||
124             wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0)
125                 goto failed;
126         os_memset(&gd, 0, sizeof(gd));
127 @@ -2386,8 +2405,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
128                 sm->tptk_set = 0;
129                 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
130                 os_memset(&sm->gtk, 0, sizeof(sm->gtk));
131 +               os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
132  #ifdef CONFIG_IEEE80211W
133                 os_memset(&sm->igtk, 0, sizeof(sm->igtk));
134 +               os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
135  #endif /* CONFIG_IEEE80211W */
136         }
137  
138 @@ -2920,8 +2941,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
139         os_memset(&sm->ptk, 0, sizeof(sm->ptk));
140         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
141         os_memset(&sm->gtk, 0, sizeof(sm->gtk));
142 +       os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
143  #ifdef CONFIG_IEEE80211W
144         os_memset(&sm->igtk, 0, sizeof(sm->igtk));
145 +       os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
146  #endif /* CONFIG_IEEE80211W */
147  #ifdef CONFIG_IEEE80211R
148         os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
149 @@ -2986,7 +3009,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
150  
151                 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
152                                 gd.gtk, gd.gtk_len);
153 -               if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
154 +               if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) {
155                         os_memset(&gd, 0, sizeof(gd));
156                         wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
157                                    "WNM mode");
158 @@ -2998,7 +3021,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
159                 const struct wpa_igtk_kde *igtk;
160  
161                 igtk = (const struct wpa_igtk_kde *) (buf + 2);
162 -               if (wpa_supplicant_install_igtk(sm, igtk) < 0)
163 +               if (wpa_supplicant_install_igtk(sm, igtk, 1) < 0)
164                         return -1;
165  #endif /* CONFIG_IEEE80211W */
166         } else {
167 diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
168 index afc9e37..9a54631 100644
169 --- a/src/rsn_supp/wpa_i.h
170 +++ b/src/rsn_supp/wpa_i.h
171 @@ -32,8 +32,10 @@ struct wpa_sm {
172         int rx_replay_counter_set;
173         u8 request_counter[WPA_REPLAY_COUNTER_LEN];
174         struct wpa_gtk gtk;
175 +       struct wpa_gtk gtk_wnm_sleep;
176  #ifdef CONFIG_IEEE80211W
177         struct wpa_igtk igtk;
178 +       struct wpa_igtk igtk_wnm_sleep;
179  #endif /* CONFIG_IEEE80211W */
180  
181         struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
182 -- 
183 2.7.4
184