summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0001.patch254
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0002.patch139
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0003.patch196
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0004.patch941
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0005.patch144
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.10.bb5
6 files changed, 1679 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0001.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0001.patch
new file mode 100644
index 0000000000..e7d3a967fa
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0001.patch
@@ -0,0 +1,254 @@
1From 9d3f347a2b14652e767d51142600206a32676b62 Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <quic_jouni@quicinc.com>
3Date: Mon, 24 Jan 2022 20:57:19 +0200
4Subject: [PATCH] DPP3: Add PKEX initiator retries and fallback from v2 to v1
5 for hostapd
6
7This extends hostapd with the design used in wpa_supplicant for PKEX
8initiator retries and automatic version fallback from v2 to v1 (the
9latter is enabled only with CONFIG_DPP3=y).
10
11Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
12
13CVE: CVE-2022-37660
14
15Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?id=9d3f347a2b14652e767d51142600206a32676b62]
16
17Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
18---
19 src/ap/dpp_hostapd.c | 188 +++++++++++++++++++++++++++++++++++++++----
20 1 file changed, 171 insertions(+), 17 deletions(-)
21
22diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
23index 13e1fc5..6c30ba3 100644
24--- a/src/ap/dpp_hostapd.c
25+++ b/src/ap/dpp_hostapd.c
26@@ -216,6 +216,163 @@ static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
27 }
28
29
30+static int hostapd_dpp_allow_ir(struct hostapd_data *hapd, unsigned int freq)
31+{
32+ int i, j;
33+
34+ if (!hapd->iface->hw_features)
35+ return -1;
36+
37+ for (i = 0; i < hapd->iface->num_hw_features; i++) {
38+ struct hostapd_hw_modes *mode = &hapd->iface->hw_features[i];
39+
40+ for (j = 0; j < mode->num_channels; j++) {
41+ struct hostapd_channel_data *chan = &mode->channels[j];
42+
43+ if (chan->freq != (int) freq)
44+ continue;
45+
46+ if (chan->flag & (HOSTAPD_CHAN_DISABLED |
47+ HOSTAPD_CHAN_NO_IR |
48+ HOSTAPD_CHAN_RADAR))
49+ continue;
50+
51+ return 1;
52+ }
53+ }
54+
55+ wpa_printf(MSG_DEBUG,
56+ "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
57+ freq);
58+
59+ return 0;
60+}
61+
62+
63+static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
64+ struct dpp_pkex *pkex)
65+{
66+ if (pkex->freq == 2437)
67+ pkex->freq = 5745;
68+ else if (pkex->freq == 5745)
69+ pkex->freq = 5220;
70+ else if (pkex->freq == 5220)
71+ pkex->freq = 60480;
72+ else
73+ return -1; /* no more channels to try */
74+
75+ if (hostapd_dpp_allow_ir(hapd, pkex->freq) == 1) {
76+ wpa_printf(MSG_DEBUG, "DPP: Try to initiate on %u MHz",
77+ pkex->freq);
78+ return 0;
79+ }
80+
81+ /* Could not use this channel - try the next one */
82+ return hostapd_dpp_pkex_next_channel(hapd, pkex);
83+}
84+
85+
86+static int hostapd_dpp_pkex_init(struct hostapd_data *hapd, bool v2)
87+{
88+ struct dpp_pkex *pkex;
89+ struct wpabuf *msg;
90+ unsigned int wait_time;
91+
92+ wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
93+ dpp_pkex_free(hapd->dpp_pkex);
94+ hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi,
95+ hapd->own_addr,
96+ hapd->dpp_pkex_identifier,
97+ hapd->dpp_pkex_code, v2);
98+ pkex = hapd->dpp_pkex;
99+ if (!pkex)
100+ return -1;
101+
102+ msg = hapd->dpp_pkex->exchange_req;
103+ wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
104+ pkex->freq = 2437;
105+ wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
106+ " freq=%u type=%d", MAC2STR(broadcast), pkex->freq,
107+ v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
108+ DPP_PA_PKEX_V1_EXCHANGE_REQ);
109+ hostapd_drv_send_action(hapd, pkex->freq, 0, broadcast,
110+ wpabuf_head(msg), wpabuf_len(msg));
111+ pkex->exch_req_wait_time = wait_time;
112+ pkex->exch_req_tries = 1;
113+
114+ return 0;
115+}
116+
117+
118+static void hostapd_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
119+{
120+ struct hostapd_data *hapd = eloop_ctx;
121+ struct dpp_pkex *pkex = hapd->dpp_pkex;
122+
123+ if (!pkex || !pkex->exchange_req)
124+ return;
125+ if (pkex->exch_req_tries >= 5) {
126+ if (hostapd_dpp_pkex_next_channel(hapd, pkex) < 0) {
127+#ifdef CONFIG_DPP3
128+ if (pkex->v2) {
129+ wpa_printf(MSG_DEBUG,
130+ "DPP: Fall back to PKEXv1");
131+ hostapd_dpp_pkex_init(hapd, false);
132+ return;
133+ }
134+#endif /* CONFIG_DPP3 */
135+ wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
136+ "No response from PKEX peer");
137+ dpp_pkex_free(pkex);
138+ hapd->dpp_pkex = NULL;
139+ return;
140+ }
141+ pkex->exch_req_tries = 0;
142+ }
143+
144+ pkex->exch_req_tries++;
145+ wpa_printf(MSG_DEBUG, "DPP: Retransmit PKEX Exchange Request (try %u)",
146+ pkex->exch_req_tries);
147+ wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
148+ " freq=%u type=%d",
149+ MAC2STR(broadcast), pkex->freq,
150+ pkex->v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
151+ DPP_PA_PKEX_V1_EXCHANGE_REQ);
152+ hostapd_drv_send_action(hapd, pkex->freq, pkex->exch_req_wait_time,
153+ broadcast,
154+ wpabuf_head(pkex->exchange_req),
155+ wpabuf_len(pkex->exchange_req));
156+}
157+
158+
159+static void hostapd_dpp_pkex_tx_status(struct hostapd_data *hapd, const u8 *dst,
160+ const u8 *data, size_t data_len, int ok)
161+{
162+ struct dpp_pkex *pkex = hapd->dpp_pkex;
163+
164+ if (pkex->failed) {
165+ wpa_printf(MSG_DEBUG,
166+ "DPP: Terminate PKEX exchange due to an earlier error");
167+ if (pkex->t > pkex->own_bi->pkex_t)
168+ pkex->own_bi->pkex_t = pkex->t;
169+ dpp_pkex_free(pkex);
170+ hapd->dpp_pkex = NULL;
171+ return;
172+ }
173+
174+ if (pkex->exch_req_wait_time && pkex->exchange_req) {
175+ /* Wait for PKEX Exchange Response frame and retry request if
176+ * no response is seen. */
177+ eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd,
178+ NULL);
179+ eloop_register_timeout(pkex->exch_req_wait_time / 1000,
180+ (pkex->exch_req_wait_time % 1000) * 1000,
181+ hostapd_dpp_pkex_retry_timeout, hapd,
182+ NULL);
183+ }
184+}
185+
186+
187 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
188 const u8 *data, size_t data_len, int ok)
189 {
190@@ -227,6 +384,11 @@ void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
191 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
192
193 if (!hapd->dpp_auth) {
194+ if (hapd->dpp_pkex) {
195+ hostapd_dpp_pkex_tx_status(hapd, dst, data, data_len,
196+ ok);
197+ return;
198+ }
199 wpa_printf(MSG_DEBUG,
200 "DPP: Ignore TX status since there is no ongoing authentication exchange");
201 return;
202@@ -1783,6 +1945,9 @@ hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
203 return;
204 }
205
206+ eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
207+ hapd->dpp_pkex->exch_req_wait_time = 0;
208+
209 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
210 if (!msg) {
211 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
212@@ -2172,26 +2337,14 @@ int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
213 return -1;
214
215 if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
216- struct wpabuf *msg;
217+#ifdef CONFIG_DPP3
218+ bool v2 = true;
219+#else /* CONFIG_DPP3 */
220 bool v2 = os_strstr(cmd, " init=2") != NULL;
221+#endif /* CONFIG_DPP3 */
222
223- wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
224- dpp_pkex_free(hapd->dpp_pkex);
225- hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
226- hapd->own_addr,
227- hapd->dpp_pkex_identifier,
228- hapd->dpp_pkex_code, v2);
229- if (!hapd->dpp_pkex)
230+ if (hostapd_dpp_pkex_init(hapd, v2) < 0)
231 return -1;
232-
233- msg = hapd->dpp_pkex->exchange_req;
234- /* TODO: Which channel to use? */
235- wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
236- " freq=%u type=%d", MAC2STR(broadcast), 2437,
237- v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
238- DPP_PA_PKEX_V1_EXCHANGE_REQ);
239- hostapd_drv_send_action(hapd, 2437, 0, broadcast,
240- wpabuf_head(msg), wpabuf_len(msg));
241 }
242
243 /* TODO: Support multiple PKEX info entries */
244@@ -2319,6 +2472,7 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
245 #endif /* CONFIG_TESTING_OPTIONS */
246 if (!hapd->dpp_init_done)
247 return;
248+ eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
249 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
250 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
251 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
252--
2532.40.0
254
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0002.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0002.patch
new file mode 100644
index 0000000000..9d39f18f43
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0002.patch
@@ -0,0 +1,139 @@
1From 80213629981a21825e4688fde1b590e4c4d4bcea Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <quic_jouni@quicinc.com>
3Date: Mon, 24 Jan 2022 20:21:24 +0200
4Subject: [PATCH] DPP3: Start with PKEXv2 and fall back to v1
5
6Use automatic PKEX version negotiation as the initiator by starting with
7PKEXv2 and if no response is received, trying again with PKEXv1. For
8now, this is enabled only in wpa_supplicant CONFIG_DPP3=y builds.
9
10Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
11
12CVE: CVE-2022-37660
13
14Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?id=80213629981a21825e4688fde1b590e4c4d4bcea]
15
16Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
17---
18 wpa_supplicant/dpp_supplicant.c | 81 +++++++++++++++++++++------------
19 1 file changed, 52 insertions(+), 29 deletions(-)
20
21diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
22index 584654a..43c85d3 100644
23--- a/wpa_supplicant/dpp_supplicant.c
24+++ b/wpa_supplicant/dpp_supplicant.c
25@@ -2557,6 +2557,45 @@ static int wpas_dpp_pkex_next_channel(struct wpa_supplicant *wpa_s,
26 }
27
28
29+static int wpas_dpp_pkex_init(struct wpa_supplicant *wpa_s, bool v2)
30+{
31+ struct dpp_pkex *pkex;
32+ struct wpabuf *msg;
33+ unsigned int wait_time;
34+
35+ wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
36+ dpp_pkex_free(wpa_s->dpp_pkex);
37+ wpa_s->dpp_pkex = dpp_pkex_init(wpa_s, wpa_s->dpp_pkex_bi,
38+ wpa_s->own_addr,
39+ wpa_s->dpp_pkex_identifier,
40+ wpa_s->dpp_pkex_code, v2);
41+ pkex = wpa_s->dpp_pkex;
42+ if (!pkex)
43+ return -1;
44+
45+ msg = pkex->exchange_req;
46+ wait_time = wpa_s->max_remain_on_chan;
47+ if (wait_time > 2000)
48+ wait_time = 2000;
49+ pkex->freq = 2437;
50+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
51+ " freq=%u type=%d",
52+ MAC2STR(broadcast), pkex->freq,
53+ v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
54+ DPP_PA_PKEX_V1_EXCHANGE_REQ);
55+ offchannel_send_action(wpa_s, pkex->freq, broadcast,
56+ wpa_s->own_addr, broadcast,
57+ wpabuf_head(msg), wpabuf_len(msg),
58+ wait_time, wpas_dpp_tx_pkex_status, 0);
59+ if (wait_time == 0)
60+ wait_time = 2000;
61+ pkex->exch_req_wait_time = wait_time;
62+ pkex->exch_req_tries = 1;
63+
64+ return 0;
65+}
66+
67+
68 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
69 {
70 struct wpa_supplicant *wpa_s = eloop_ctx;
71@@ -2566,6 +2605,14 @@ static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
72 return;
73 if (pkex->exch_req_tries >= 5) {
74 if (wpas_dpp_pkex_next_channel(wpa_s, pkex) < 0) {
75+#ifdef CONFIG_DPP3
76+ if (pkex->v2) {
77+ wpa_printf(MSG_DEBUG,
78+ "DPP: Fall back to PKEXv1");
79+ wpas_dpp_pkex_init(wpa_s, false);
80+ return;
81+ }
82+#endif /* CONFIG_DPP3 */
83 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
84 "No response from PKEX peer");
85 dpp_pkex_free(pkex);
86@@ -3271,7 +3318,6 @@ int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
87 {
88 struct dpp_bootstrap_info *own_bi;
89 const char *pos, *end;
90- unsigned int wait_time;
91
92 pos = os_strstr(cmd, " own=");
93 if (!pos)
94@@ -3315,37 +3361,14 @@ int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
95 return -1;
96
97 if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
98- struct dpp_pkex *pkex;
99- struct wpabuf *msg;
100+#ifdef CONFIG_DPP3
101+ bool v2 = true;
102+#else /* CONFIG_DPP3 */
103 bool v2 = os_strstr(cmd, " init=2") != NULL;
104+#endif /* CONFIG_DPP3 */
105
106- wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
107- dpp_pkex_free(wpa_s->dpp_pkex);
108- wpa_s->dpp_pkex = dpp_pkex_init(wpa_s, own_bi, wpa_s->own_addr,
109- wpa_s->dpp_pkex_identifier,
110- wpa_s->dpp_pkex_code, v2);
111- pkex = wpa_s->dpp_pkex;
112- if (!pkex)
113+ if (wpas_dpp_pkex_init(wpa_s, v2) < 0)
114 return -1;
115-
116- msg = pkex->exchange_req;
117- wait_time = wpa_s->max_remain_on_chan;
118- if (wait_time > 2000)
119- wait_time = 2000;
120- pkex->freq = 2437;
121- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
122- " freq=%u type=%d",
123- MAC2STR(broadcast), pkex->freq,
124- v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
125- DPP_PA_PKEX_V1_EXCHANGE_REQ);
126- offchannel_send_action(wpa_s, pkex->freq, broadcast,
127- wpa_s->own_addr, broadcast,
128- wpabuf_head(msg), wpabuf_len(msg),
129- wait_time, wpas_dpp_tx_pkex_status, 0);
130- if (wait_time == 0)
131- wait_time = 2000;
132- pkex->exch_req_wait_time = wait_time;
133- pkex->exch_req_tries = 1;
134 }
135
136 /* TODO: Support multiple PKEX info entries */
137--
1382.40.0
139
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0003.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0003.patch
new file mode 100644
index 0000000000..7334720dfb
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0003.patch
@@ -0,0 +1,196 @@
1From bdcccbc2755dd1a75731496782e02b5435fb9534 Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <quic_jouni@quicinc.com>
3Date: Tue, 25 Jan 2022 20:06:49 +0200
4Subject: [PATCH] DPP: Change PKEX version configuration design
5
6Use a separate ver=<1|2> parameter to DPP_PKEX_ADD instead of
7overloading init=1 with version indication. This allows additional
8options for forcing v1-only and v2-only in addition to automatic mode
9(start with v2 and fall back to v1, if needed).
10
11Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
12
13CVE: CVE-2022-37660
14
15Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?id=bdcccbc2755dd1a75731496782e02b5435fb9534]
16
17Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
18---
19 src/ap/dpp_hostapd.c | 37 ++++++++++++++++++++++++++-------
20 src/common/dpp.h | 1 +
21 wpa_supplicant/dpp_supplicant.c | 37 ++++++++++++++++++++++++++-------
22 3 files changed, 61 insertions(+), 14 deletions(-)
23
24diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
25index 6c30ba3..fdfdcf9 100644
26--- a/src/ap/dpp_hostapd.c
27+++ b/src/ap/dpp_hostapd.c
28@@ -272,11 +272,19 @@ static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
29 }
30
31
32-static int hostapd_dpp_pkex_init(struct hostapd_data *hapd, bool v2)
33+enum hostapd_dpp_pkex_ver {
34+ PKEX_VER_AUTO,
35+ PKEX_VER_ONLY_1,
36+ PKEX_VER_ONLY_2,
37+};
38+
39+static int hostapd_dpp_pkex_init(struct hostapd_data *hapd,
40+ enum hostapd_dpp_pkex_ver ver)
41 {
42 struct dpp_pkex *pkex;
43 struct wpabuf *msg;
44 unsigned int wait_time;
45+ bool v2 = ver != PKEX_VER_ONLY_1;
46
47 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
48 dpp_pkex_free(hapd->dpp_pkex);
49@@ -287,6 +295,7 @@ static int hostapd_dpp_pkex_init(struct hostapd_data *hapd, bool v2)
50 pkex = hapd->dpp_pkex;
51 if (!pkex)
52 return -1;
53+ pkex->forced_ver = ver != PKEX_VER_AUTO;
54
55 msg = hapd->dpp_pkex->exchange_req;
56 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
57@@ -314,10 +323,10 @@ static void hostapd_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
58 if (pkex->exch_req_tries >= 5) {
59 if (hostapd_dpp_pkex_next_channel(hapd, pkex) < 0) {
60 #ifdef CONFIG_DPP3
61- if (pkex->v2) {
62+ if (pkex->v2 && !pkex->forced_ver) {
63 wpa_printf(MSG_DEBUG,
64 "DPP: Fall back to PKEXv1");
65- hostapd_dpp_pkex_init(hapd, false);
66+ hostapd_dpp_pkex_init(hapd, PKEX_VER_ONLY_1);
67 return;
68 }
69 #endif /* CONFIG_DPP3 */
70@@ -2336,14 +2345,28 @@ int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
71 if (!hapd->dpp_pkex_code)
72 return -1;
73
74- if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
75+ if (os_strstr(cmd, " init=1")) {
76 #ifdef CONFIG_DPP3
77- bool v2 = true;
78+ enum hostapd_dpp_pkex_ver ver = PKEX_VER_AUTO;
79 #else /* CONFIG_DPP3 */
80- bool v2 = os_strstr(cmd, " init=2") != NULL;
81+ enum hostapd_dpp_pkex_ver ver = PKEX_VER_ONLY_1;
82 #endif /* CONFIG_DPP3 */
83
84- if (hostapd_dpp_pkex_init(hapd, v2) < 0)
85+ pos = os_strstr(cmd, " ver=");
86+ if (pos) {
87+ int v;
88+
89+ pos += 5;
90+ v = atoi(pos);
91+ if (v == 1)
92+ ver = PKEX_VER_ONLY_1;
93+ else if (v == 2)
94+ ver = PKEX_VER_ONLY_2;
95+ else
96+ return -1;
97+ }
98+
99+ if (hostapd_dpp_pkex_init(hapd, ver) < 0)
100 return -1;
101 }
102
103diff --git a/src/common/dpp.h b/src/common/dpp.h
104index 8d62a0e..bfea446 100644
105--- a/src/common/dpp.h
106+++ b/src/common/dpp.h
107@@ -177,6 +177,7 @@ struct dpp_pkex {
108 unsigned int exchange_done:1;
109 unsigned int failed:1;
110 unsigned int v2:1;
111+ unsigned int forced_ver:1;
112 struct dpp_bootstrap_info *own_bi;
113 u8 own_mac[ETH_ALEN];
114 u8 peer_mac[ETH_ALEN];
115diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
116index 43c85d3..61b300f 100644
117--- a/wpa_supplicant/dpp_supplicant.c
118+++ b/wpa_supplicant/dpp_supplicant.c
119@@ -2557,11 +2557,19 @@ static int wpas_dpp_pkex_next_channel(struct wpa_supplicant *wpa_s,
120 }
121
122
123-static int wpas_dpp_pkex_init(struct wpa_supplicant *wpa_s, bool v2)
124+enum wpas_dpp_pkex_ver {
125+ PKEX_VER_AUTO,
126+ PKEX_VER_ONLY_1,
127+ PKEX_VER_ONLY_2,
128+};
129+
130+static int wpas_dpp_pkex_init(struct wpa_supplicant *wpa_s,
131+ enum wpas_dpp_pkex_ver ver)
132 {
133 struct dpp_pkex *pkex;
134 struct wpabuf *msg;
135 unsigned int wait_time;
136+ bool v2 = ver != PKEX_VER_ONLY_1;
137
138 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
139 dpp_pkex_free(wpa_s->dpp_pkex);
140@@ -2572,6 +2580,7 @@ static int wpas_dpp_pkex_init(struct wpa_supplicant *wpa_s, bool v2)
141 pkex = wpa_s->dpp_pkex;
142 if (!pkex)
143 return -1;
144+ pkex->forced_ver = ver != PKEX_VER_AUTO;
145
146 msg = pkex->exchange_req;
147 wait_time = wpa_s->max_remain_on_chan;
148@@ -2606,10 +2615,10 @@ static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
149 if (pkex->exch_req_tries >= 5) {
150 if (wpas_dpp_pkex_next_channel(wpa_s, pkex) < 0) {
151 #ifdef CONFIG_DPP3
152- if (pkex->v2) {
153+ if (pkex->v2 && !pkex->forced_ver) {
154 wpa_printf(MSG_DEBUG,
155 "DPP: Fall back to PKEXv1");
156- wpas_dpp_pkex_init(wpa_s, false);
157+ wpas_dpp_pkex_init(wpa_s, PKEX_VER_ONLY_1);
158 return;
159 }
160 #endif /* CONFIG_DPP3 */
161@@ -3360,14 +3369,28 @@ int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
162 if (!wpa_s->dpp_pkex_code)
163 return -1;
164
165- if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
166+ if (os_strstr(cmd, " init=1")) {
167 #ifdef CONFIG_DPP3
168- bool v2 = true;
169+ enum wpas_dpp_pkex_ver ver = PKEX_VER_AUTO;
170 #else /* CONFIG_DPP3 */
171- bool v2 = os_strstr(cmd, " init=2") != NULL;
172+ enum wpas_dpp_pkex_ver ver = PKEX_VER_ONLY_1;
173 #endif /* CONFIG_DPP3 */
174
175- if (wpas_dpp_pkex_init(wpa_s, v2) < 0)
176+ pos = os_strstr(cmd, " ver=");
177+ if (pos) {
178+ int v;
179+
180+ pos += 5;
181+ v = atoi(pos);
182+ if (v == 1)
183+ ver = PKEX_VER_ONLY_1;
184+ else if (v == 2)
185+ ver = PKEX_VER_ONLY_2;
186+ else
187+ return -1;
188+ }
189+
190+ if (wpas_dpp_pkex_init(wpa_s, ver) < 0)
191 return -1;
192 }
193
194--
1952.40.0
196
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0004.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0004.patch
new file mode 100644
index 0000000000..0077bb5aa3
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0004.patch
@@ -0,0 +1,941 @@
1From d7be749335f2585658cf98c4f0e7d6cd5ac06865 Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <jouni@qca.qualcomm.com>
3Date: Tue, 25 Jan 2022 00:35:36 +0200
4Subject: [PATCH] DPP3: PKEX over TCP
5
6Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
7
8CVE: CVE-2022-37660
9
10Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?id=d7be749335f2585658cf98c4f0e7d6cd5ac06865]
11
12Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
13---
14 src/ap/dpp_hostapd.c | 155 ++++++++++++++--
15 src/common/dpp.h | 13 ++
16 src/common/dpp_pkex.c | 18 +-
17 src/common/dpp_tcp.c | 308 +++++++++++++++++++++++++++++++-
18 wpa_supplicant/dpp_supplicant.c | 122 ++++++++++++-
19 5 files changed, 580 insertions(+), 36 deletions(-)
20
21diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
22index fdfdcf9..d956be9 100644
23--- a/src/ap/dpp_hostapd.c
24+++ b/src/ap/dpp_hostapd.c
25@@ -28,12 +28,16 @@ static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
26 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
27 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
28 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
29+static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
30+ struct dpp_authentication *auth);
31 #ifdef CONFIG_DPP2
32 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
33 void *timeout_ctx);
34 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
35 struct dpp_authentication *auth,
36 struct dpp_config_obj *conf);
37+static int hostapd_dpp_process_conf_obj(void *ctx,
38+ struct dpp_authentication *auth);
39 #endif /* CONFIG_DPP2 */
40
41 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
42@@ -272,6 +276,75 @@ static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
43 }
44
45
46+#ifdef CONFIG_DPP2
47+static int hostapd_dpp_pkex_done(void *ctx, void *conn,
48+ struct dpp_bootstrap_info *peer_bi)
49+{
50+ struct hostapd_data *hapd = ctx;
51+ const char *cmd = hapd->dpp_pkex_auth_cmd;
52+ const char *pos;
53+ u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
54+ struct dpp_bootstrap_info *own_bi = NULL;
55+ struct dpp_authentication *auth;
56+
57+ if (!cmd)
58+ cmd = "";
59+ wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
60+ cmd);
61+
62+ pos = os_strstr(cmd, " own=");
63+ if (pos) {
64+ pos += 5;
65+ own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
66+ atoi(pos));
67+ if (!own_bi) {
68+ wpa_printf(MSG_INFO,
69+ "DPP: Could not find bootstrapping info for the identified local entry");
70+ return -1;
71+ }
72+
73+ if (peer_bi->curve != own_bi->curve) {
74+ wpa_printf(MSG_INFO,
75+ "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
76+ peer_bi->curve->name, own_bi->curve->name);
77+ return -1;
78+ }
79+ }
80+
81+ pos = os_strstr(cmd, " role=");
82+ if (pos) {
83+ pos += 6;
84+ if (os_strncmp(pos, "configurator", 12) == 0)
85+ allowed_roles = DPP_CAPAB_CONFIGURATOR;
86+ else if (os_strncmp(pos, "enrollee", 8) == 0)
87+ allowed_roles = DPP_CAPAB_ENROLLEE;
88+ else if (os_strncmp(pos, "either", 6) == 0)
89+ allowed_roles = DPP_CAPAB_CONFIGURATOR |
90+ DPP_CAPAB_ENROLLEE;
91+ else
92+ return -1;
93+ }
94+
95+ auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
96+ peer_bi, own_bi, allowed_roles, 0,
97+ hapd->iface->hw_features,
98+ hapd->iface->num_hw_features);
99+ if (!auth)
100+ return -1;
101+
102+ hostapd_dpp_set_testing_options(hapd, auth);
103+ if (dpp_set_configurator(auth, cmd) < 0) {
104+ dpp_auth_deinit(auth);
105+ return -1;
106+ }
107+
108+ return dpp_tcp_auth(hapd->iface->interfaces->dpp, conn, auth,
109+ hapd->conf->dpp_name, DPP_NETROLE_AP,
110+ hostapd_dpp_process_conf_obj);
111+}
112+#endif /* CONFIG_DPP2 */
113+
114+
115 enum hostapd_dpp_pkex_ver {
116 PKEX_VER_AUTO,
117 PKEX_VER_ONLY_1,
118@@ -279,7 +352,9 @@ enum hostapd_dpp_pkex_ver {
119 };
120
121 static int hostapd_dpp_pkex_init(struct hostapd_data *hapd,
122- enum hostapd_dpp_pkex_ver ver)
123+ enum hostapd_dpp_pkex_ver ver,
124+ const struct hostapd_ip_addr *ipaddr,
125+ int tcp_port)
126 {
127 struct dpp_pkex *pkex;
128 struct wpabuf *msg;
129@@ -288,15 +363,26 @@ static int hostapd_dpp_pkex_init(struct hostapd_data *hapd,
130
131 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
132 dpp_pkex_free(hapd->dpp_pkex);
133- hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi,
134- hapd->own_addr,
135- hapd->dpp_pkex_identifier,
136- hapd->dpp_pkex_code, v2);
137- pkex = hapd->dpp_pkex;
138+ hapd->dpp_pkex = NULL;
139+ pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
140+ hapd->dpp_pkex_identifier,
141+ hapd->dpp_pkex_code, v2);
142 if (!pkex)
143 return -1;
144 pkex->forced_ver = ver != PKEX_VER_AUTO;
145
146+ if (ipaddr) {
147+#ifdef CONFIG_DPP2
148+ return dpp_tcp_pkex_init(hapd->iface->interfaces->dpp, pkex,
149+ ipaddr, tcp_port,
150+ hapd->msg_ctx, hapd,
151+ hostapd_dpp_pkex_done);
152+#else /* CONFIG_DPP2 */
153+ return -1;
154+#endif /* CONFIG_DPP2 */
155+ }
156+
157+ hapd->dpp_pkex = pkex;
158 msg = hapd->dpp_pkex->exchange_req;
159 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
160 pkex->freq = 2437;
161@@ -326,7 +412,8 @@ static void hostapd_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
162 if (pkex->v2 && !pkex->forced_ver) {
163 wpa_printf(MSG_DEBUG,
164 "DPP: Fall back to PKEXv1");
165- hostapd_dpp_pkex_init(hapd, PKEX_VER_ONLY_1);
166+ hostapd_dpp_pkex_init(hapd, PKEX_VER_ONLY_1,
167+ NULL, 0);
168 return;
169 }
170 #endif /* CONFIG_DPP3 */
171@@ -1883,7 +1970,7 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
172
173 static void
174 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
175- const u8 *buf, size_t len,
176+ const u8 *hdr, const u8 *buf, size_t len,
177 unsigned int freq, bool v2)
178 {
179 struct wpabuf *msg;
180@@ -1897,14 +1984,14 @@ hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
181 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
182 wpa_printf(MSG_DEBUG,
183 "DPP: No PKEX code configured - ignore request");
184- return;
185+ goto try_relay;
186 }
187
188 if (hapd->dpp_pkex) {
189 /* TODO: Support parallel operations */
190 wpa_printf(MSG_DEBUG,
191 "DPP: Already in PKEX session - ignore new request");
192- return;
193+ goto try_relay;
194 }
195
196 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
197@@ -1916,7 +2003,7 @@ hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
198 if (!hapd->dpp_pkex) {
199 wpa_printf(MSG_DEBUG,
200 "DPP: Failed to process the request - ignore it");
201- return;
202+ goto try_relay;
203 }
204
205 msg = hapd->dpp_pkex->exchange_resp;
206@@ -1933,6 +2020,17 @@ hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
207 dpp_pkex_free(hapd->dpp_pkex);
208 hapd->dpp_pkex = NULL;
209 }
210+
211+ return;
212+
213+try_relay:
214+#ifdef CONFIG_DPP2
215+ if (v2)
216+ dpp_relay_rx_action(hapd->iface->interfaces->dpp,
217+ src, hdr, buf, len, freq, NULL, NULL, hapd);
218+#else /* CONFIG_DPP2 */
219+ wpa_printf(MSG_DEBUG, "DPP: No relay functionality included - skip");
220+#endif /* CONFIG_DPP2 */
221 }
222
223
224@@ -2132,12 +2230,12 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
225 /* This is for PKEXv2, but for now, process only with
226 * CONFIG_DPP3 to avoid issues with a capability that has not
227 * been tested with other implementations. */
228- hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
229+ hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
230 true);
231 break;
232 #endif /* CONFIG_DPP3 */
233 case DPP_PA_PKEX_V1_EXCHANGE_REQ:
234- hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
235+ hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
236 false);
237 break;
238 case DPP_PA_PKEX_EXCHANGE_RESP:
239@@ -2303,6 +2401,29 @@ int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
240 {
241 struct dpp_bootstrap_info *own_bi;
242 const char *pos, *end;
243+ int tcp_port = DPP_TCP_PORT;
244+ struct hostapd_ip_addr *ipaddr = NULL;
245+#ifdef CONFIG_DPP2
246+ struct hostapd_ip_addr ipaddr_buf;
247+ char *addr;
248+
249+ pos = os_strstr(cmd, " tcp_port=");
250+ if (pos) {
251+ pos += 10;
252+ tcp_port = atoi(pos);
253+ }
254+
255+ addr = get_param(cmd, " tcp_addr=");
256+ if (addr) {
257+ int res;
258+
259+ res = hostapd_parse_ip_addr(addr, &ipaddr_buf);
260+ os_free(addr);
261+ if (res)
262+ return -1;
263+ ipaddr = &ipaddr_buf;
264+ }
265+#endif /* CONFIG_DPP2 */
266
267 pos = os_strstr(cmd, " own=");
268 if (!pos)
269@@ -2366,8 +2487,14 @@ int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
270 return -1;
271 }
272
273- if (hostapd_dpp_pkex_init(hapd, ver) < 0)
274+ if (hostapd_dpp_pkex_init(hapd, ver, ipaddr, tcp_port) < 0)
275 return -1;
276+ } else {
277+#ifdef CONFIG_DPP2
278+ dpp_controller_pkex_add(hapd->iface->interfaces->dpp, own_bi,
279+ hapd->dpp_pkex_code,
280+ hapd->dpp_pkex_identifier);
281+#endif /* CONFIG_DPP2 */
282 }
283
284 /* TODO: Support multiple PKEX info entries */
285diff --git a/src/common/dpp.h b/src/common/dpp.h
286index bfea446..ca33fe3 100644
287--- a/src/common/dpp.h
288+++ b/src/common/dpp.h
289@@ -550,6 +550,9 @@ int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
290 const u8 *attr_start, size_t attr_len);
291 int dpp_notify_new_qr_code(struct dpp_authentication *auth,
292 struct dpp_bootstrap_info *peer_bi);
293+void dpp_controller_pkex_add(struct dpp_global *dpp,
294+ struct dpp_bootstrap_info *bi,
295+ const char *code, const char *identifier);
296 struct dpp_configuration * dpp_configuration_alloc(const char *type);
297 int dpp_akm_psk(enum dpp_akm akm);
298 int dpp_akm_sae(enum dpp_akm akm);
299@@ -688,12 +691,22 @@ struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp,
300 unsigned int id);
301 void dpp_controller_new_qr_code(struct dpp_global *dpp,
302 struct dpp_bootstrap_info *bi);
303+int dpp_tcp_pkex_init(struct dpp_global *dpp, struct dpp_pkex *pkex,
304+ const struct hostapd_ip_addr *addr, int port,
305+ void *msg_ctx, void *cb_ctx,
306+ int (*pkex_done)(void *ctx, void *conn,
307+ struct dpp_bootstrap_info *bi));
308 int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
309 const struct hostapd_ip_addr *addr, int port,
310 const char *name, enum dpp_netrole netrole, void *msg_ctx,
311 void *cb_ctx,
312 int (*process_conf_obj)(void *ctx,
313 struct dpp_authentication *auth));
314+int dpp_tcp_auth(struct dpp_global *dpp, void *_conn,
315+ struct dpp_authentication *auth, const char *name,
316+ enum dpp_netrole netrole,
317+ int (*process_conf_obj)(void *ctx,
318+ struct dpp_authentication *auth));
319
320 struct wpabuf * dpp_build_presence_announcement(struct dpp_bootstrap_info *bi);
321 void dpp_notify_chirp_received(void *msg_ctx, int id, const u8 *src,
322diff --git a/src/common/dpp_pkex.c b/src/common/dpp_pkex.c
323index 38349fa..72084d9 100644
324--- a/src/common/dpp_pkex.c
325+++ b/src/common/dpp_pkex.c
326@@ -469,8 +469,10 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
327 pkex->t = bi->pkex_t;
328 pkex->msg_ctx = msg_ctx;
329 pkex->own_bi = bi;
330- os_memcpy(pkex->own_mac, own_mac, ETH_ALEN);
331- os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
332+ if (own_mac)
333+ os_memcpy(pkex->own_mac, own_mac, ETH_ALEN);
334+ if (peer_mac)
335+ os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
336 if (identifier) {
337 pkex->identifier = os_strdup(identifier);
338 if (!pkex->identifier)
339@@ -742,7 +744,8 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
340 }
341 #endif /* CONFIG_DPP2 */
342
343- os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
344+ if (peer_mac)
345+ os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
346
347 attr_status = dpp_get_attr(buf, buflen, DPP_ATTR_STATUS,
348 &attr_status_len);
349@@ -1341,9 +1344,12 @@ dpp_pkex_finish(struct dpp_global *dpp, struct dpp_pkex *pkex, const u8 *peer,
350 return NULL;
351 bi->id = dpp_next_id(dpp);
352 bi->type = DPP_BOOTSTRAP_PKEX;
353- os_memcpy(bi->mac_addr, peer, ETH_ALEN);
354- bi->num_freq = 1;
355- bi->freq[0] = freq;
356+ if (peer)
357+ os_memcpy(bi->mac_addr, peer, ETH_ALEN);
358+ if (freq) {
359+ bi->num_freq = 1;
360+ bi->freq[0] = freq;
361+ }
362 bi->curve = pkex->own_bi->curve;
363 bi->pubkey = pkex->peer_bootstrap_key;
364 pkex->peer_bootstrap_key = NULL;
365diff --git a/src/common/dpp_tcp.c b/src/common/dpp_tcp.c
366index fb8ef1c..1a8a7c7 100644
367--- a/src/common/dpp_tcp.c
368+++ b/src/common/dpp_tcp.c
369@@ -24,10 +24,12 @@ struct dpp_connection {
370 struct dpp_controller *ctrl;
371 struct dpp_relay_controller *relay;
372 struct dpp_global *global;
373+ struct dpp_pkex *pkex;
374 struct dpp_authentication *auth;
375 void *msg_ctx;
376 void *cb_ctx;
377 int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
378+ int (*pkex_done)(void *ctx, void *conn, struct dpp_bootstrap_info *bi);
379 int sock;
380 u8 mac_addr[ETH_ALEN];
381 unsigned int freq;
382@@ -71,6 +73,9 @@ struct dpp_controller {
383 struct dl_list conn; /* struct dpp_connection */
384 char *configurator_params;
385 enum dpp_netrole netrole;
386+ struct dpp_bootstrap_info *pkex_bi;
387+ char *pkex_code;
388+ char *pkex_identifier;
389 void *msg_ctx;
390 void *cb_ctx;
391 int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
392@@ -102,6 +107,7 @@ static void dpp_connection_free(struct dpp_connection *conn)
393 wpabuf_free(conn->msg);
394 wpabuf_free(conn->msg_out);
395 dpp_auth_deinit(conn->auth);
396+ dpp_pkex_free(conn->pkex);
397 os_free(conn->name);
398 os_free(conn);
399 }
400@@ -525,6 +531,8 @@ int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
401 /* TODO: Could send this to all configured Controllers. For now,
402 * only the first Controller is supported. */
403 ctrl = dpp_relay_controller_get_ctx(dpp, cb_ctx);
404+ } else if (type == DPP_PA_PKEX_EXCHANGE_REQ) {
405+ ctrl = dpp_relay_controller_get_ctx(dpp, cb_ctx);
406 } else {
407 if (!r_bootstrap)
408 return -1;
409@@ -609,6 +617,8 @@ static void dpp_controller_free(struct dpp_controller *ctrl)
410 eloop_unregister_sock(ctrl->sock, EVENT_TYPE_READ);
411 }
412 os_free(ctrl->configurator_params);
413+ os_free(ctrl->pkex_code);
414+ os_free(ctrl->pkex_identifier);
415 os_free(ctrl);
416 }
417
418@@ -955,6 +965,143 @@ static int dpp_controller_rx_reconfig_auth_resp(struct dpp_connection *conn,
419 }
420
421
422+static int dpp_controller_rx_pkex_exchange_req(struct dpp_connection *conn,
423+ const u8 *hdr, const u8 *buf,
424+ size_t len)
425+{
426+ struct dpp_controller *ctrl = conn->ctrl;
427+
428+ if (!ctrl)
429+ return 0;
430+
431+ wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request");
432+
433+ /* TODO: Support multiple PKEX codes by iterating over all the enabled
434+ * values here */
435+
436+ if (!ctrl->pkex_code || !ctrl->pkex_bi) {
437+ wpa_printf(MSG_DEBUG,
438+ "DPP: No PKEX code configured - ignore request");
439+ return 0;
440+ }
441+
442+ if (conn->pkex || conn->auth) {
443+ wpa_printf(MSG_DEBUG,
444+ "DPP: Already in PKEX/Authentication session - ignore new PKEX request");
445+ return 0;
446+ }
447+
448+ conn->pkex = dpp_pkex_rx_exchange_req(conn->ctrl->global, ctrl->pkex_bi,
449+ NULL, NULL,
450+ ctrl->pkex_identifier,
451+ ctrl->pkex_code,
452+ buf, len, true);
453+ if (!conn->pkex) {
454+ wpa_printf(MSG_DEBUG,
455+ "DPP: Failed to process the request");
456+ return -1;
457+ }
458+
459+ return dpp_tcp_send_msg(conn, conn->pkex->exchange_resp);
460+}
461+
462+
463+static int dpp_controller_rx_pkex_exchange_resp(struct dpp_connection *conn,
464+ const u8 *hdr, const u8 *buf,
465+ size_t len)
466+{
467+ struct dpp_pkex *pkex = conn->pkex;
468+ struct wpabuf *msg;
469+ int res;
470+
471+ wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response");
472+
473+ if (!pkex || !pkex->initiator || pkex->exchange_done) {
474+ wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
475+ return 0;
476+ }
477+
478+ msg = dpp_pkex_rx_exchange_resp(pkex, NULL, buf, len);
479+ if (!msg) {
480+ wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
481+ return -1;
482+ }
483+
484+ wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request");
485+ res = dpp_tcp_send_msg(conn, msg);
486+ wpabuf_free(msg);
487+ return res;
488+}
489+
490+
491+static int dpp_controller_rx_pkex_commit_reveal_req(struct dpp_connection *conn,
492+ const u8 *hdr,
493+ const u8 *buf, size_t len)
494+{
495+ struct dpp_pkex *pkex = conn->pkex;
496+ struct wpabuf *msg;
497+ int res;
498+ struct dpp_bootstrap_info *bi;
499+
500+ wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request");
501+
502+ if (!pkex || pkex->initiator || !pkex->exchange_done) {
503+ wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
504+ return 0;
505+ }
506+
507+ msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
508+ if (!msg) {
509+ wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
510+ return -1;
511+ }
512+
513+ wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response");
514+ res = dpp_tcp_send_msg(conn, msg);
515+ wpabuf_free(msg);
516+ if (res < 0)
517+ return res;
518+ bi = dpp_pkex_finish(conn->global, pkex, NULL, 0);
519+ if (!bi)
520+ return -1;
521+ conn->pkex = NULL;
522+ return 0;
523+}
524+
525+
526+static int
527+dpp_controller_rx_pkex_commit_reveal_resp(struct dpp_connection *conn,
528+ const u8 *hdr,
529+ const u8 *buf, size_t len)
530+{
531+ struct dpp_pkex *pkex = conn->pkex;
532+ int res;
533+ struct dpp_bootstrap_info *bi;
534+
535+ wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response");
536+
537+ if (!pkex || !pkex->initiator || !pkex->exchange_done) {
538+ wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
539+ return 0;
540+ }
541+
542+ res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
543+ if (res < 0) {
544+ wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
545+ return res;
546+ }
547+
548+ bi = dpp_pkex_finish(conn->global, pkex, NULL, 0);
549+ if (!bi)
550+ return -1;
551+ conn->pkex = NULL;
552+
553+ if (!conn->pkex_done)
554+ return -1;
555+ return conn->pkex_done(conn->cb_ctx, conn, bi);
556+}
557+
558+
559 static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
560 size_t len)
561 {
562@@ -1014,6 +1161,22 @@ static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
563 case DPP_PA_RECONFIG_AUTH_RESP:
564 return dpp_controller_rx_reconfig_auth_resp(conn, msg, pos,
565 end - pos);
566+ case DPP_PA_PKEX_V1_EXCHANGE_REQ:
567+ wpa_printf(MSG_DEBUG,
568+ "DPP: Ignore PKEXv1 Exchange Request - not supported over TCP");
569+ return -1;
570+ case DPP_PA_PKEX_EXCHANGE_REQ:
571+ return dpp_controller_rx_pkex_exchange_req(conn, msg, pos,
572+ end - pos);
573+ case DPP_PA_PKEX_EXCHANGE_RESP:
574+ return dpp_controller_rx_pkex_exchange_resp(conn, msg, pos,
575+ end - pos);
576+ case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
577+ return dpp_controller_rx_pkex_commit_reveal_req(conn, msg, pos,
578+ end - pos);
579+ case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
580+ return dpp_controller_rx_pkex_commit_reveal_resp(conn, msg, pos,
581+ end - pos);
582 default:
583 /* TODO: missing messages types */
584 wpa_printf(MSG_DEBUG,
585@@ -1559,6 +1722,101 @@ fail:
586 }
587
588
589+int dpp_tcp_pkex_init(struct dpp_global *dpp, struct dpp_pkex *pkex,
590+ const struct hostapd_ip_addr *addr, int port,
591+ void *msg_ctx, void *cb_ctx,
592+ int (*pkex_done)(void *ctx, void *conn,
593+ struct dpp_bootstrap_info *bi))
594+{
595+ struct dpp_connection *conn;
596+ struct sockaddr_storage saddr;
597+ socklen_t addrlen;
598+ const u8 *hdr, *pos, *end;
599+ char txt[100];
600+
601+ wpa_printf(MSG_DEBUG, "DPP: Initialize TCP connection to %s port %d",
602+ hostapd_ip_txt(addr, txt, sizeof(txt)), port);
603+ if (dpp_ipaddr_to_sockaddr((struct sockaddr *) &saddr, &addrlen,
604+ addr, port) < 0) {
605+ dpp_pkex_free(pkex);
606+ return -1;
607+ }
608+
609+ conn = os_zalloc(sizeof(*conn));
610+ if (!conn) {
611+ dpp_pkex_free(pkex);
612+ return -1;
613+ }
614+
615+ conn->msg_ctx = msg_ctx;
616+ conn->cb_ctx = cb_ctx;
617+ conn->pkex_done = pkex_done;
618+ conn->global = dpp;
619+ conn->pkex = pkex;
620+ conn->sock = socket(AF_INET, SOCK_STREAM, 0);
621+ if (conn->sock < 0)
622+ goto fail;
623+
624+ if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
625+ wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
626+ strerror(errno));
627+ goto fail;
628+ }
629+
630+ if (connect(conn->sock, (struct sockaddr *) &saddr, addrlen) < 0) {
631+ if (errno != EINPROGRESS) {
632+ wpa_printf(MSG_DEBUG, "DPP: Failed to connect: %s",
633+ strerror(errno));
634+ goto fail;
635+ }
636+
637+ /*
638+ * Continue connecting in the background; eloop will call us
639+ * once the connection is ready (or failed).
640+ */
641+ }
642+
643+ if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
644+ dpp_conn_tx_ready, conn, NULL) < 0)
645+ goto fail;
646+ conn->write_eloop = 1;
647+
648+ hdr = wpabuf_head(pkex->exchange_req);
649+ end = hdr + wpabuf_len(pkex->exchange_req);
650+ hdr += 2; /* skip Category and Actiom */
651+ pos = hdr + DPP_HDR_LEN;
652+ conn->msg_out = dpp_tcp_encaps(hdr, pos, end - pos);
653+ if (!conn->msg_out)
654+ goto fail;
655+ /* Message will be sent in dpp_conn_tx_ready() */
656+
657+ /* TODO: eloop timeout to clear a connection if it does not complete
658+ * properly */
659+ dl_list_add(&dpp->tcp_init, &conn->list);
660+ return 0;
661+fail:
662+ dpp_connection_free(conn);
663+ return -1;
664+}
665+
666+
667+static int dpp_tcp_auth_start(struct dpp_connection *conn,
668+ struct dpp_authentication *auth)
669+{
670+ const u8 *hdr, *pos, *end;
671+
672+ hdr = wpabuf_head(auth->req_msg);
673+ end = hdr + wpabuf_len(auth->req_msg);
674+ hdr += 2; /* skip Category and Actiom */
675+ pos = hdr + DPP_HDR_LEN;
676+ conn->msg_out = dpp_tcp_encaps(hdr, pos, end - pos);
677+ if (!conn->msg_out)
678+ return -1;
679+ /* Message will be sent in dpp_conn_tx_ready() */
680+ return 0;
681+}
682+
683+
684 int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
685 const struct hostapd_ip_addr *addr, int port, const char *name,
686 enum dpp_netrole netrole, void *msg_ctx, void *cb_ctx,
687@@ -1568,7 +1826,6 @@ int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
688 struct dpp_connection *conn;
689 struct sockaddr_storage saddr;
690 socklen_t addrlen;
691- const u8 *hdr, *pos, *end;
692 char txt[100];
693
694 wpa_printf(MSG_DEBUG, "DPP: Initialize TCP connection to %s port %d",
695@@ -1620,14 +1877,8 @@ int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
696 goto fail;
697 conn->write_eloop = 1;
698
699- hdr = wpabuf_head(auth->req_msg);
700- end = hdr + wpabuf_len(auth->req_msg);
701- hdr += 2; /* skip Category and Actiom */
702- pos = hdr + DPP_HDR_LEN;
703- conn->msg_out = dpp_tcp_encaps(hdr, pos, end - pos);
704- if (!conn->msg_out)
705+ if (dpp_tcp_auth_start(conn, auth) < 0)
706 goto fail;
707- /* Message will be sent in dpp_conn_tx_ready() */
708
709 /* TODO: eloop timeout to clear a connection if it does not complete
710 * properly */
711@@ -1639,6 +1890,30 @@ fail:
712 }
713
714
715+int dpp_tcp_auth(struct dpp_global *dpp, void *_conn,
716+ struct dpp_authentication *auth, const char *name,
717+ enum dpp_netrole netrole,
718+ int (*process_conf_obj)(void *ctx,
719+ struct dpp_authentication *auth))
720+{
721+ struct dpp_connection *conn = _conn;
722+
723+ /* Continue with Authentication exchange on an existing TCP connection.
724+ */
725+ conn->process_conf_obj = process_conf_obj;
726+ os_free(conn->name);
727+ conn->name = os_strdup(name ? name : "Test");
728+ conn->netrole = netrole;
729+ conn->auth = auth;
730+
731+ if (dpp_tcp_auth_start(conn, auth) < 0)
732+ return -1;
733+
734+ dpp_conn_tx_ready(conn->sock, conn, NULL);
735+ return 0;
736+}
737+
738+
739 int dpp_controller_start(struct dpp_global *dpp,
740 struct dpp_controller_config *config)
741 {
742@@ -1789,6 +2064,23 @@ void dpp_controller_new_qr_code(struct dpp_global *dpp,
743 }
744
745
746+void dpp_controller_pkex_add(struct dpp_global *dpp,
747+ struct dpp_bootstrap_info *bi,
748+ const char *code, const char *identifier)
749+{
750+ struct dpp_controller *ctrl = dpp->controller;
751+
752+ if (!ctrl)
753+ return;
754+
755+ ctrl->pkex_bi = bi;
756+ os_free(ctrl->pkex_code);
757+ ctrl->pkex_code = code ? os_strdup(code) : NULL;
758+ os_free(ctrl->pkex_identifier);
759+ ctrl->pkex_identifier = identifier ? os_strdup(identifier) : NULL;
760+}
761+
762+
763 void dpp_tcp_init_flush(struct dpp_global *dpp)
764 {
765 struct dpp_connection *conn, *tmp;
766diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
767index 61b300f..aab94cb 100644
768--- a/wpa_supplicant/dpp_supplicant.c
769+++ b/wpa_supplicant/dpp_supplicant.c
770@@ -2557,6 +2557,71 @@ static int wpas_dpp_pkex_next_channel(struct wpa_supplicant *wpa_s,
771 }
772
773
774+#ifdef CONFIG_DPP2
775+static int wpas_dpp_pkex_done(void *ctx, void *conn,
776+ struct dpp_bootstrap_info *peer_bi)
777+{
778+ struct wpa_supplicant *wpa_s = ctx;
779+ const char *cmd = wpa_s->dpp_pkex_auth_cmd;
780+ const char *pos;
781+ u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
782+ struct dpp_bootstrap_info *own_bi = NULL;
783+ struct dpp_authentication *auth;
784+
785+ if (!cmd)
786+ cmd = "";
787+ wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
788+ cmd);
789+
790+ pos = os_strstr(cmd, " own=");
791+ if (pos) {
792+ pos += 5;
793+ own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
794+ if (!own_bi) {
795+ wpa_printf(MSG_INFO,
796+ "DPP: Could not find bootstrapping info for the identified local entry");
797+ return -1;
798+ }
799+
800+ if (peer_bi->curve != own_bi->curve) {
801+ wpa_printf(MSG_INFO,
802+ "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
803+ peer_bi->curve->name, own_bi->curve->name);
804+ return -1;
805+ }
806+ }
807+
808+ pos = os_strstr(cmd, " role=");
809+ if (pos) {
810+ pos += 6;
811+ if (os_strncmp(pos, "configurator", 12) == 0)
812+ allowed_roles = DPP_CAPAB_CONFIGURATOR;
813+ else if (os_strncmp(pos, "enrollee", 8) == 0)
814+ allowed_roles = DPP_CAPAB_ENROLLEE;
815+ else if (os_strncmp(pos, "either", 6) == 0)
816+ allowed_roles = DPP_CAPAB_CONFIGURATOR |
817+ DPP_CAPAB_ENROLLEE;
818+ else
819+ return -1;
820+ }
821+
822+ auth = dpp_auth_init(wpa_s->dpp, wpa_s, peer_bi, own_bi, allowed_roles,
823+ 0, wpa_s->hw.modes, wpa_s->hw.num_modes);
824+ if (!auth)
825+ return -1;
826+
827+ wpas_dpp_set_testing_options(wpa_s, auth);
828+ if (dpp_set_configurator(auth, cmd) < 0) {
829+ dpp_auth_deinit(auth);
830+ return -1;
831+ }
832+
833+ return dpp_tcp_auth(wpa_s->dpp, conn, auth, wpa_s->conf->dpp_name,
834+ DPP_NETROLE_STA, wpas_dpp_process_conf_obj);
835+}
836+#endif /* CONFIG_DPP2 */
837+
838+
839 enum wpas_dpp_pkex_ver {
840 PKEX_VER_AUTO,
841 PKEX_VER_ONLY_1,
842@@ -2564,7 +2629,9 @@ enum wpas_dpp_pkex_ver {
843 };
844
845 static int wpas_dpp_pkex_init(struct wpa_supplicant *wpa_s,
846- enum wpas_dpp_pkex_ver ver)
847+ enum wpas_dpp_pkex_ver ver,
848+ const struct hostapd_ip_addr *ipaddr,
849+ int tcp_port)
850 {
851 struct dpp_pkex *pkex;
852 struct wpabuf *msg;
853@@ -2573,15 +2640,24 @@ static int wpas_dpp_pkex_init(struct wpa_supplicant *wpa_s,
854
855 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
856 dpp_pkex_free(wpa_s->dpp_pkex);
857- wpa_s->dpp_pkex = dpp_pkex_init(wpa_s, wpa_s->dpp_pkex_bi,
858- wpa_s->own_addr,
859- wpa_s->dpp_pkex_identifier,
860- wpa_s->dpp_pkex_code, v2);
861- pkex = wpa_s->dpp_pkex;
862+ wpa_s->dpp_pkex = NULL;
863+ pkex = dpp_pkex_init(wpa_s, wpa_s->dpp_pkex_bi, wpa_s->own_addr,
864+ wpa_s->dpp_pkex_identifier,
865+ wpa_s->dpp_pkex_code, v2);
866 if (!pkex)
867 return -1;
868 pkex->forced_ver = ver != PKEX_VER_AUTO;
869
870+ if (ipaddr) {
871+#ifdef CONFIG_DPP2
872+ return dpp_tcp_pkex_init(wpa_s->dpp, pkex, ipaddr, tcp_port,
873+ wpa_s, wpa_s, wpas_dpp_pkex_done);
874+#else /* CONFIG_DPP2 */
875+ return -1;
876+#endif /* CONFIG_DPP2 */
877+ }
878+
879+ wpa_s->dpp_pkex = pkex;
880 msg = pkex->exchange_req;
881 wait_time = wpa_s->max_remain_on_chan;
882 if (wait_time > 2000)
883@@ -2618,7 +2694,8 @@ static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
884 if (pkex->v2 && !pkex->forced_ver) {
885 wpa_printf(MSG_DEBUG,
886 "DPP: Fall back to PKEXv1");
887- wpas_dpp_pkex_init(wpa_s, PKEX_VER_ONLY_1);
888+ wpas_dpp_pkex_init(wpa_s, PKEX_VER_ONLY_1,
889+ NULL, 0);
890 return;
891 }
892 #endif /* CONFIG_DPP3 */
893@@ -3327,6 +3404,29 @@ int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
894 {
895 struct dpp_bootstrap_info *own_bi;
896 const char *pos, *end;
897+ int tcp_port = DPP_TCP_PORT;
898+ struct hostapd_ip_addr *ipaddr = NULL;
899+#ifdef CONFIG_DPP2
900+ struct hostapd_ip_addr ipaddr_buf;
901+ char *addr;
902+
903+ pos = os_strstr(cmd, " tcp_port=");
904+ if (pos) {
905+ pos += 10;
906+ tcp_port = atoi(pos);
907+ }
908+
909+ addr = get_param(cmd, " tcp_addr=");
910+ if (addr) {
911+ int res;
912+
913+ res = hostapd_parse_ip_addr(addr, &ipaddr_buf);
914+ os_free(addr);
915+ if (res)
916+ return -1;
917+ ipaddr = &ipaddr_buf;
918+ }
919+#endif /* CONFIG_DPP2 */
920
921 pos = os_strstr(cmd, " own=");
922 if (!pos)
923@@ -3390,8 +3490,14 @@ int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
924 return -1;
925 }
926
927- if (wpas_dpp_pkex_init(wpa_s, ver) < 0)
928+ if (wpas_dpp_pkex_init(wpa_s, ver, ipaddr, tcp_port) < 0)
929 return -1;
930+ } else {
931+#ifdef CONFIG_DPP2
932+ dpp_controller_pkex_add(wpa_s->dpp, own_bi,
933+ wpa_s->dpp_pkex_code,
934+ wpa_s->dpp_pkex_identifier);
935+#endif /* CONFIG_DPP2 */
936 }
937
938 /* TODO: Support multiple PKEX info entries */
939--
9402.40.0
941
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0005.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0005.patch
new file mode 100644
index 0000000000..92828fbbbb
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-37660-0005.patch
@@ -0,0 +1,144 @@
1From 15af83cf1846870873a011ed4d714732f01cd2e4 Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <quic_jouni@quicinc.com>
3Date: Tue, 19 Jul 2022 21:23:04 +0300
4Subject: [PATCH] DPP: Delete PKEX code and identifier on success completion of
5 PKEX
6
7We are not supposed to reuse these without being explicitly requested to
8perform PKEX again. There is not a strong use case for being able to
9provision an Enrollee multiple times with PKEX, so this should have no
10issues on the Enrollee. For a Configurator, there might be some use
11cases that would benefit from being able to use the same code with
12multiple Enrollee devices, e.g., for guess access with a laptop and a
13smart phone. That case will now require a new DPP_PKEX_ADD command on
14the Configurator after each completion of the provisioning exchange.
15
16Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
17
18CVE: CVE-2022-37660
19
20Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?id=15af83cf1846870873a011ed4d714732f01cd2e4]
21
22Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
23---
24 src/ap/dpp_hostapd.c | 22 +++++++++++++++++++++-
25 wpa_supplicant/dpp_supplicant.c | 21 ++++++++++++++++++++-
26 2 files changed, 41 insertions(+), 2 deletions(-)
27
28diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
29index d956be9..73b09ba 100644
30--- a/src/ap/dpp_hostapd.c
31+++ b/src/ap/dpp_hostapd.c
32@@ -276,6 +276,22 @@ static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
33 }
34
35
36+static void hostapd_dpp_pkex_clear_code(struct hostapd_data *hapd)
37+{
38+ if (!hapd->dpp_pkex_code && !hapd->dpp_pkex_identifier)
39+ return;
40+
41+ /* Delete PKEX code and identifier on successful completion of
42+ * PKEX. We are not supposed to reuse these without being
43+ * explicitly requested to perform PKEX again. */
44+ wpa_printf(MSG_DEBUG, "DPP: Delete PKEX code/identifier");
45+ os_free(hapd->dpp_pkex_code);
46+ hapd->dpp_pkex_code = NULL;
47+ os_free(hapd->dpp_pkex_identifier);
48+ hapd->dpp_pkex_identifier = NULL;
49+}
50+
51+
52 #ifdef CONFIG_DPP2
53 static int hostapd_dpp_pkex_done(void *ctx, void *conn,
54 struct dpp_bootstrap_info *peer_bi)
55@@ -287,6 +303,8 @@ static int hostapd_dpp_pkex_done(void *ctx, void *conn,
56 struct dpp_bootstrap_info *own_bi = NULL;
57 struct dpp_authentication *auth;
58
59+ hostapd_dpp_pkex_clear_code(hapd);
60+
61 if (!cmd)
62 cmd = "";
63 wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
64@@ -2114,6 +2132,7 @@ hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
65 wpabuf_head(msg), wpabuf_len(msg));
66 wpabuf_free(msg);
67
68+ hostapd_dpp_pkex_clear_code(hapd);
69 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
70 if (!bi)
71 return;
72@@ -2145,6 +2164,7 @@ hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
73 return;
74 }
75
76+ hostapd_dpp_pkex_clear_code(hapd);
77 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
78 if (!bi)
79 return;
80@@ -2518,7 +2538,7 @@ int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
81 return -1;
82 }
83
84- if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
85+ if ((id_val != 0 && id_val != 1))
86 return -1;
87
88 /* TODO: Support multiple PKEX entries */
89diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
90index aab94cb..015ae66 100644
91--- a/wpa_supplicant/dpp_supplicant.c
92+++ b/wpa_supplicant/dpp_supplicant.c
93@@ -2557,6 +2557,22 @@ static int wpas_dpp_pkex_next_channel(struct wpa_supplicant *wpa_s,
94 }
95
96
97+static void wpas_dpp_pkex_clear_code(struct wpa_supplicant *wpa_s)
98+{
99+ if (!wpa_s->dpp_pkex_code && !wpa_s->dpp_pkex_identifier)
100+ return;
101+
102+ /* Delete PKEX code and identifier on successful completion of
103+ * PKEX. We are not supposed to reuse these without being
104+ * explicitly requested to perform PKEX again. */
105+ os_free(wpa_s->dpp_pkex_code);
106+ wpa_s->dpp_pkex_code = NULL;
107+ os_free(wpa_s->dpp_pkex_identifier);
108+ wpa_s->dpp_pkex_identifier = NULL;
109+
110+}
111+
112+
113 #ifdef CONFIG_DPP2
114 static int wpas_dpp_pkex_done(void *ctx, void *conn,
115 struct dpp_bootstrap_info *peer_bi)
116@@ -2568,6 +2584,8 @@ static int wpas_dpp_pkex_done(void *ctx, void *conn,
117 struct dpp_bootstrap_info *own_bi = NULL;
118 struct dpp_authentication *auth;
119
120+ wpas_dpp_pkex_clear_code(wpa_s);
121+
122 if (!cmd)
123 cmd = "";
124 wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
125@@ -2872,6 +2890,7 @@ wpas_dpp_pkex_finish(struct wpa_supplicant *wpa_s, const u8 *peer,
126 {
127 struct dpp_bootstrap_info *bi;
128
129+ wpas_dpp_pkex_clear_code(wpa_s);
130 bi = dpp_pkex_finish(wpa_s->dpp, wpa_s->dpp_pkex, peer, freq);
131 if (!bi)
132 return NULL;
133@@ -3521,7 +3540,7 @@ int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id)
134 return -1;
135 }
136
137- if ((id_val != 0 && id_val != 1) || !wpa_s->dpp_pkex_code)
138+ if ((id_val != 0 && id_val != 1))
139 return -1;
140
141 /* TODO: Support multiple PKEX entries */
142--
1432.40.0
144
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.10.bb b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.10.bb
index 459039d01e..fbbbebc450 100644
--- a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.10.bb
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.10.bb
@@ -38,6 +38,11 @@ SRC_URI = "http://w1.fi/releases/wpa_supplicant-${PV}.tar.gz \
38 file://0001-SAE-Check-for-invalid-Rejected-Groups-element-length.patch \ 38 file://0001-SAE-Check-for-invalid-Rejected-Groups-element-length.patch \
39 file://0002-SAE-Check-for-invalid-Rejected-Groups-element-length.patch \ 39 file://0002-SAE-Check-for-invalid-Rejected-Groups-element-length.patch \
40 file://0003-SAE-Reject-invalid-Rejected-Groups-element-in-the-pa.patch \ 40 file://0003-SAE-Reject-invalid-Rejected-Groups-element-in-the-pa.patch \
41 file://CVE-2022-37660-0001.patch \
42 file://CVE-2022-37660-0002.patch \
43 file://CVE-2022-37660-0003.patch \
44 file://CVE-2022-37660-0004.patch \
45 file://CVE-2022-37660-0005.patch \
41 " 46 "
42SRC_URI[sha256sum] = "20df7ae5154b3830355f8ab4269123a87affdea59fe74fe9292a91d0d7e17b2f" 47SRC_URI[sha256sum] = "20df7ae5154b3830355f8ab4269123a87affdea59fe74fe9292a91d0d7e17b2f"
43 48