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