1 /*
2  * hostapd / DPP integration
3  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4  * Copyright (c) 2018-2020, The Linux Foundation
5  * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "utils/includes.h"
12 
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "common/dpp.h"
16 #include "common/gas.h"
17 #include "common/wpa_ctrl.h"
18 #include "crypto/random.h"
19 #include "hostapd.h"
20 #include "ap_drv_ops.h"
21 #include "gas_query_ap.h"
22 #include "gas_serv.h"
23 #include "wpa_auth.h"
24 #include "beacon.h"
25 #include "dpp_hostapd.h"
26 
27 
28 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
29 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
30 					       void *timeout_ctx);
31 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
32 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
33 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
34 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
35 					    struct dpp_authentication *auth);
36 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd);
37 #ifdef CONFIG_DPP2
38 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
39 						    void *timeout_ctx);
40 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
41 					  struct dpp_authentication *auth,
42 					  struct dpp_config_obj *conf);
43 static int hostapd_dpp_process_conf_obj(void *ctx,
44 					struct dpp_authentication *auth);
45 #endif /* CONFIG_DPP2 */
46 
47 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
48 
49 
50 /**
51  * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
52  * @hapd: Pointer to hostapd_data
53  * @cmd: DPP URI read from a QR Code
54  * Returns: Identifier of the stored info or -1 on failure
55  */
hostapd_dpp_qr_code(struct hostapd_data * hapd,const char * cmd)56 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
57 {
58 	struct dpp_bootstrap_info *bi;
59 	struct dpp_authentication *auth = hapd->dpp_auth;
60 
61 	bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
62 	if (!bi)
63 		return -1;
64 
65 	if (auth && auth->response_pending &&
66 	    dpp_notify_new_qr_code(auth, bi) == 1) {
67 		wpa_printf(MSG_DEBUG,
68 			   "DPP: Sending out pending authentication response");
69 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
70 			" freq=%u type=%d",
71 			MAC2STR(auth->peer_mac_addr), auth->curr_freq,
72 			DPP_PA_AUTHENTICATION_RESP);
73 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
74 					auth->peer_mac_addr,
75 					wpabuf_head(hapd->dpp_auth->resp_msg),
76 					wpabuf_len(hapd->dpp_auth->resp_msg));
77 	}
78 
79 #ifdef CONFIG_DPP2
80 	dpp_controller_new_qr_code(hapd->iface->interfaces->dpp, bi);
81 #endif /* CONFIG_DPP2 */
82 
83 	return bi->id;
84 }
85 
86 
87 /**
88  * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
89  * @hapd: Pointer to hostapd_data
90  * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
91  * Returns: Identifier of the stored info or -1 on failure
92  */
hostapd_dpp_nfc_uri(struct hostapd_data * hapd,const char * cmd)93 int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
94 {
95 	struct dpp_bootstrap_info *bi;
96 
97 	bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
98 	if (!bi)
99 		return -1;
100 
101 	return bi->id;
102 }
103 
104 
hostapd_dpp_nfc_handover_req(struct hostapd_data * hapd,const char * cmd)105 int hostapd_dpp_nfc_handover_req(struct hostapd_data *hapd, const char *cmd)
106 {
107 	const char *pos;
108 	struct dpp_bootstrap_info *peer_bi, *own_bi;
109 
110 	pos = os_strstr(cmd, " own=");
111 	if (!pos)
112 		return -1;
113 	pos += 5;
114 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
115 	if (!own_bi)
116 		return -1;
117 
118 	pos = os_strstr(cmd, " uri=");
119 	if (!pos)
120 		return -1;
121 	pos += 5;
122 	peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
123 	if (!peer_bi) {
124 		wpa_printf(MSG_INFO,
125 			   "DPP: Failed to parse URI from NFC Handover Request");
126 		return -1;
127 	}
128 
129 	if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
130 		return -1;
131 
132 	return peer_bi->id;
133 }
134 
135 
hostapd_dpp_nfc_handover_sel(struct hostapd_data * hapd,const char * cmd)136 int hostapd_dpp_nfc_handover_sel(struct hostapd_data *hapd, const char *cmd)
137 {
138 	const char *pos;
139 	struct dpp_bootstrap_info *peer_bi, *own_bi;
140 
141 	pos = os_strstr(cmd, " own=");
142 	if (!pos)
143 		return -1;
144 	pos += 5;
145 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
146 	if (!own_bi)
147 		return -1;
148 
149 	pos = os_strstr(cmd, " uri=");
150 	if (!pos)
151 		return -1;
152 	pos += 5;
153 	peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
154 	if (!peer_bi) {
155 		wpa_printf(MSG_INFO,
156 			   "DPP: Failed to parse URI from NFC Handover Select");
157 		return -1;
158 	}
159 
160 	if (peer_bi->curve != own_bi->curve) {
161 		wpa_printf(MSG_INFO,
162 			   "DPP: Peer (NFC Handover Selector) used different curve");
163 		return -1;
164 	}
165 
166 	return peer_bi->id;
167 }
168 
169 
hostapd_dpp_auth_resp_retry_timeout(void * eloop_ctx,void * timeout_ctx)170 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
171 						void *timeout_ctx)
172 {
173 	struct hostapd_data *hapd = eloop_ctx;
174 	struct dpp_authentication *auth = hapd->dpp_auth;
175 
176 	if (!auth || !auth->resp_msg)
177 		return;
178 
179 	wpa_printf(MSG_DEBUG,
180 		   "DPP: Retry Authentication Response after timeout");
181 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
182 		" freq=%u type=%d",
183 		MAC2STR(auth->peer_mac_addr), auth->curr_freq,
184 		DPP_PA_AUTHENTICATION_RESP);
185 	hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
186 				wpabuf_head(auth->resp_msg),
187 				wpabuf_len(auth->resp_msg));
188 }
189 
190 
hostapd_dpp_auth_resp_retry(struct hostapd_data * hapd)191 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
192 {
193 	struct dpp_authentication *auth = hapd->dpp_auth;
194 	unsigned int wait_time, max_tries;
195 
196 	if (!auth || !auth->resp_msg)
197 		return;
198 
199 	if (hapd->dpp_resp_max_tries)
200 		max_tries = hapd->dpp_resp_max_tries;
201 	else
202 		max_tries = 5;
203 	auth->auth_resp_tries++;
204 	if (auth->auth_resp_tries >= max_tries) {
205 		wpa_printf(MSG_INFO,
206 			   "DPP: No confirm received from initiator - stopping exchange");
207 		hostapd_drv_send_action_cancel_wait(hapd);
208 		dpp_auth_deinit(hapd->dpp_auth);
209 		hapd->dpp_auth = NULL;
210 		return;
211 	}
212 
213 	if (hapd->dpp_resp_retry_time)
214 		wait_time = hapd->dpp_resp_retry_time;
215 	else
216 		wait_time = 1000;
217 	wpa_printf(MSG_DEBUG,
218 		   "DPP: Schedule retransmission of Authentication Response frame in %u ms",
219 		wait_time);
220 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
221 	eloop_register_timeout(wait_time / 1000,
222 			       (wait_time % 1000) * 1000,
223 			       hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
224 }
225 
226 
hostapd_dpp_allow_ir(struct hostapd_data * hapd,unsigned int freq)227 static int hostapd_dpp_allow_ir(struct hostapd_data *hapd, unsigned int freq)
228 {
229 	int i, j;
230 
231 	if (!hapd->iface->hw_features)
232 		return -1;
233 
234 	for (i = 0; i < hapd->iface->num_hw_features; i++) {
235 		struct hostapd_hw_modes *mode = &hapd->iface->hw_features[i];
236 
237 		for (j = 0; j < mode->num_channels; j++) {
238 			struct hostapd_channel_data *chan = &mode->channels[j];
239 
240 			if (chan->freq != (int) freq)
241 				continue;
242 
243 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
244 					  HOSTAPD_CHAN_NO_IR |
245 					  HOSTAPD_CHAN_RADAR))
246 				continue;
247 
248 			return 1;
249 		}
250 	}
251 
252 	wpa_printf(MSG_DEBUG,
253 		   "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
254 		   freq);
255 
256 	return 0;
257 }
258 
259 
hostapd_dpp_pkex_next_channel(struct hostapd_data * hapd,struct dpp_pkex * pkex)260 static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
261 					 struct dpp_pkex *pkex)
262 {
263 	if (pkex->freq == 2437)
264 		pkex->freq = 5745;
265 	else if (pkex->freq == 5745)
266 		pkex->freq = 5220;
267 	else if (pkex->freq == 5220)
268 		pkex->freq = 60480;
269 	else
270 		return -1; /* no more channels to try */
271 
272 	if (hostapd_dpp_allow_ir(hapd, pkex->freq) == 1) {
273 		wpa_printf(MSG_DEBUG, "DPP: Try to initiate on %u MHz",
274 			   pkex->freq);
275 		return 0;
276 	}
277 
278 	/* Could not use this channel - try the next one */
279 	return hostapd_dpp_pkex_next_channel(hapd, pkex);
280 }
281 
282 
hostapd_dpp_pkex_clear_code(struct hostapd_data * hapd)283 static void hostapd_dpp_pkex_clear_code(struct hostapd_data *hapd)
284 {
285 	if (!hapd->dpp_pkex_code && !hapd->dpp_pkex_identifier)
286 		return;
287 
288 	/* Delete PKEX code and identifier on successful completion of
289 	 * PKEX. We are not supposed to reuse these without being
290 	 * explicitly requested to perform PKEX again. */
291 	wpa_printf(MSG_DEBUG, "DPP: Delete PKEX code/identifier");
292 	os_free(hapd->dpp_pkex_code);
293 	hapd->dpp_pkex_code = NULL;
294 	os_free(hapd->dpp_pkex_identifier);
295 	hapd->dpp_pkex_identifier = NULL;
296 }
297 
298 
299 #ifdef CONFIG_DPP2
hostapd_dpp_pkex_done(void * ctx,void * conn,struct dpp_bootstrap_info * peer_bi)300 static int hostapd_dpp_pkex_done(void *ctx, void *conn,
301 				 struct dpp_bootstrap_info *peer_bi)
302 {
303 	struct hostapd_data *hapd = ctx;
304 	char cmd[500];
305 	const char *pos;
306 	u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
307 	struct dpp_bootstrap_info *own_bi = NULL;
308 	struct dpp_authentication *auth;
309 
310 	hostapd_dpp_pkex_clear_code(hapd);
311 
312 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s", peer_bi->id,
313 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
314 	wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
315 		   cmd);
316 
317 	pos = os_strstr(cmd, " own=");
318 	if (pos) {
319 		pos += 5;
320 		own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
321 					      atoi(pos));
322 		if (!own_bi) {
323 			wpa_printf(MSG_INFO,
324 				   "DPP: Could not find bootstrapping info for the identified local entry");
325 			return -1;
326 		}
327 
328 		if (peer_bi->curve != own_bi->curve) {
329 			wpa_printf(MSG_INFO,
330 				   "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
331 				   peer_bi->curve->name, own_bi->curve->name);
332 			return -1;
333 		}
334 	}
335 
336 	pos = os_strstr(cmd, " role=");
337 	if (pos) {
338 		pos += 6;
339 		if (os_strncmp(pos, "configurator", 12) == 0)
340 			allowed_roles = DPP_CAPAB_CONFIGURATOR;
341 		else if (os_strncmp(pos, "enrollee", 8) == 0)
342 			allowed_roles = DPP_CAPAB_ENROLLEE;
343 		else if (os_strncmp(pos, "either", 6) == 0)
344 			allowed_roles = DPP_CAPAB_CONFIGURATOR |
345 				DPP_CAPAB_ENROLLEE;
346 		else
347 			return -1;
348 	}
349 
350 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
351 			     peer_bi, own_bi, allowed_roles, 0,
352 			     hapd->iface->hw_features,
353 			     hapd->iface->num_hw_features);
354 	if (!auth)
355 		return -1;
356 
357 	hostapd_dpp_set_testing_options(hapd, auth);
358 	if (dpp_set_configurator(auth, cmd) < 0) {
359 		dpp_auth_deinit(auth);
360 		return -1;
361 	}
362 
363 	return dpp_tcp_auth(hapd->iface->interfaces->dpp, conn, auth,
364 			    hapd->conf->dpp_name, DPP_NETROLE_AP,
365 			    hapd->conf->dpp_mud_url,
366 			    hapd->conf->dpp_extra_conf_req_name,
367 			    hapd->conf->dpp_extra_conf_req_value,
368 			    hostapd_dpp_process_conf_obj, NULL);
369 }
370 #endif /* CONFIG_DPP2 */
371 
372 
hostapd_dpp_pkex_init(struct hostapd_data * hapd,enum dpp_pkex_ver ver,const struct hostapd_ip_addr * ipaddr,int tcp_port)373 static int hostapd_dpp_pkex_init(struct hostapd_data *hapd,
374 				 enum dpp_pkex_ver ver,
375 				 const struct hostapd_ip_addr *ipaddr,
376 				 int tcp_port)
377 {
378 	struct dpp_pkex *pkex;
379 	struct wpabuf *msg;
380 	unsigned int wait_time;
381 	bool v2 = ver != PKEX_VER_ONLY_1;
382 
383 	wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
384 	dpp_pkex_free(hapd->dpp_pkex);
385 	hapd->dpp_pkex = NULL;
386 	pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
387 			     hapd->dpp_pkex_identifier,
388 			     hapd->dpp_pkex_code, hapd->dpp_pkex_code_len, v2);
389 	if (!pkex)
390 		return -1;
391 	pkex->forced_ver = ver != PKEX_VER_AUTO;
392 
393 	if (ipaddr) {
394 #ifdef CONFIG_DPP2
395 		return dpp_tcp_pkex_init(hapd->iface->interfaces->dpp, pkex,
396 					 ipaddr, tcp_port,
397 					 hapd->msg_ctx, hapd,
398 					 hostapd_dpp_pkex_done);
399 #else /* CONFIG_DPP2 */
400 		return -1;
401 #endif /* CONFIG_DPP2 */
402 	}
403 
404 	hapd->dpp_pkex = pkex;
405 	msg = hapd->dpp_pkex->exchange_req;
406 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
407 	pkex->freq = 2437;
408 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
409 		" freq=%u type=%d", MAC2STR(broadcast), pkex->freq,
410 		v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
411 		DPP_PA_PKEX_V1_EXCHANGE_REQ);
412 	hostapd_drv_send_action(hapd, pkex->freq, 0, broadcast,
413 				wpabuf_head(msg), wpabuf_len(msg));
414 	pkex->exch_req_wait_time = wait_time;
415 	pkex->exch_req_tries = 1;
416 
417 	return 0;
418 }
419 
420 
hostapd_dpp_pkex_retry_timeout(void * eloop_ctx,void * timeout_ctx)421 static void hostapd_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
422 {
423 	struct hostapd_data *hapd = eloop_ctx;
424 	struct dpp_pkex *pkex = hapd->dpp_pkex;
425 
426 	if (!pkex || !pkex->exchange_req)
427 		return;
428 	if (pkex->exch_req_tries >= 5) {
429 		if (hostapd_dpp_pkex_next_channel(hapd, pkex) < 0) {
430 #ifdef CONFIG_DPP3
431 			if (pkex->v2 && !pkex->forced_ver) {
432 				wpa_printf(MSG_DEBUG,
433 					   "DPP: Fall back to PKEXv1");
434 				hostapd_dpp_pkex_init(hapd, PKEX_VER_ONLY_1,
435 						      NULL, 0);
436 				return;
437 			}
438 #endif /* CONFIG_DPP3 */
439 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
440 				"No response from PKEX peer");
441 			dpp_pkex_free(pkex);
442 			hapd->dpp_pkex = NULL;
443 			return;
444 		}
445 		pkex->exch_req_tries = 0;
446 	}
447 
448 	pkex->exch_req_tries++;
449 	wpa_printf(MSG_DEBUG, "DPP: Retransmit PKEX Exchange Request (try %u)",
450 		   pkex->exch_req_tries);
451 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
452 		" freq=%u type=%d",
453 		MAC2STR(broadcast), pkex->freq,
454 		pkex->v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
455 		DPP_PA_PKEX_V1_EXCHANGE_REQ);
456 	hostapd_drv_send_action(hapd, pkex->freq, pkex->exch_req_wait_time,
457 				broadcast,
458 				wpabuf_head(pkex->exchange_req),
459 				wpabuf_len(pkex->exchange_req));
460 }
461 
462 
hostapd_dpp_pkex_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)463 static void hostapd_dpp_pkex_tx_status(struct hostapd_data *hapd, const u8 *dst,
464 				       const u8 *data, size_t data_len, int ok)
465 {
466 	struct dpp_pkex *pkex = hapd->dpp_pkex;
467 
468 	if (pkex->failed) {
469 		wpa_printf(MSG_DEBUG,
470 			   "DPP: Terminate PKEX exchange due to an earlier error");
471 		if (pkex->t > pkex->own_bi->pkex_t)
472 			pkex->own_bi->pkex_t = pkex->t;
473 		dpp_pkex_free(pkex);
474 		hapd->dpp_pkex = NULL;
475 		return;
476 	}
477 
478 	if (pkex->exch_req_wait_time && pkex->exchange_req) {
479 		/* Wait for PKEX Exchange Response frame and retry request if
480 		 * no response is seen. */
481 		eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd,
482 				     NULL);
483 		eloop_register_timeout(pkex->exch_req_wait_time / 1000,
484 				       (pkex->exch_req_wait_time % 1000) * 1000,
485 				       hostapd_dpp_pkex_retry_timeout, hapd,
486 				       NULL);
487 	}
488 }
489 
490 
hostapd_dpp_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)491 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
492 			   const u8 *data, size_t data_len, int ok)
493 {
494 	struct dpp_authentication *auth = hapd->dpp_auth;
495 
496 	wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
497 		   MAC2STR(dst), ok);
498 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
499 		" result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
500 
501 	if (!hapd->dpp_auth) {
502 		if (hapd->dpp_pkex) {
503 			hostapd_dpp_pkex_tx_status(hapd, dst, data, data_len,
504 						   ok);
505 			return;
506 		}
507 		wpa_printf(MSG_DEBUG,
508 			   "DPP: Ignore TX status since there is no ongoing authentication exchange");
509 		return;
510 	}
511 
512 #ifdef CONFIG_DPP2
513 	if (auth->connect_on_tx_status) {
514 		wpa_printf(MSG_DEBUG,
515 			   "DPP: Complete exchange on configuration result");
516 		dpp_auth_deinit(hapd->dpp_auth);
517 		hapd->dpp_auth = NULL;
518 		return;
519 	}
520 #endif /* CONFIG_DPP2 */
521 
522 	if (hapd->dpp_auth->remove_on_tx_status) {
523 		wpa_printf(MSG_DEBUG,
524 			   "DPP: Terminate authentication exchange due to an earlier error");
525 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
526 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
527 				     hapd, NULL);
528 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
529 				     hapd, NULL);
530 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
531 				     NULL);
532 #ifdef CONFIG_DPP2
533 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
534 				     hapd, NULL);
535 #endif /* CONFIG_DPP2 */
536 		hostapd_drv_send_action_cancel_wait(hapd);
537 		dpp_auth_deinit(hapd->dpp_auth);
538 		hapd->dpp_auth = NULL;
539 		return;
540 	}
541 
542 	if (hapd->dpp_auth_ok_on_ack) {
543 		hostapd_dpp_auth_success(hapd, 1);
544 		if (!hapd->dpp_auth) {
545 			/* The authentication session could have been removed in
546 			 * some error cases, e.g., when starting GAS client and
547 			 * failing to send the initial request. */
548 			return;
549 		}
550 	}
551 
552 	if (!is_broadcast_ether_addr(dst) && !ok) {
553 		wpa_printf(MSG_DEBUG,
554 			   "DPP: Unicast DPP Action frame was not ACKed");
555 		if (auth->waiting_auth_resp) {
556 			/* In case of DPP Authentication Request frame, move to
557 			 * the next channel immediately. */
558 			hostapd_drv_send_action_cancel_wait(hapd);
559 			hostapd_dpp_auth_init_next(hapd);
560 			return;
561 		}
562 		if (auth->waiting_auth_conf) {
563 			hostapd_dpp_auth_resp_retry(hapd);
564 			return;
565 		}
566 	}
567 
568 	if (auth->waiting_auth_conf &&
569 	    auth->auth_resp_status == DPP_STATUS_OK) {
570 		/* Make sure we do not get stuck waiting for Auth Confirm
571 		 * indefinitely after successfully transmitted Auth Response to
572 		 * allow new authentication exchanges to be started. */
573 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd,
574 				     NULL);
575 		eloop_register_timeout(1, 0, hostapd_dpp_auth_conf_wait_timeout,
576 				       hapd, NULL);
577 	}
578 
579 	if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
580 		/* Allow timeout handling to stop iteration if no response is
581 		 * received from a peer that has ACKed a request. */
582 		auth->auth_req_ack = 1;
583 	}
584 
585 	if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
586 	    hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
587 		wpa_printf(MSG_DEBUG,
588 			   "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
589 			   hapd->dpp_auth->curr_freq,
590 			   hapd->dpp_auth->neg_freq);
591 		hostapd_drv_send_action_cancel_wait(hapd);
592 
593 		if (hapd->dpp_auth->neg_freq !=
594 		    (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
595 			/* TODO: Listen operation on non-operating channel */
596 			wpa_printf(MSG_INFO,
597 				   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
598 				   hapd->dpp_auth->neg_freq, hapd->iface->freq);
599 		}
600 	}
601 
602 	if (hapd->dpp_auth_ok_on_ack)
603 		hapd->dpp_auth_ok_on_ack = 0;
604 }
605 
606 
hostapd_dpp_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)607 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
608 {
609 	struct hostapd_data *hapd = eloop_ctx;
610 	struct dpp_authentication *auth = hapd->dpp_auth;
611 	unsigned int freq;
612 	struct os_reltime now, diff;
613 	unsigned int wait_time, diff_ms;
614 
615 	if (!auth || !auth->waiting_auth_resp)
616 		return;
617 
618 	wait_time = hapd->dpp_resp_wait_time ?
619 		hapd->dpp_resp_wait_time : 2000;
620 	os_get_reltime(&now);
621 	os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
622 	diff_ms = diff.sec * 1000 + diff.usec / 1000;
623 	wpa_printf(MSG_DEBUG,
624 		   "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
625 		   wait_time, diff_ms);
626 
627 	if (auth->auth_req_ack && diff_ms >= wait_time) {
628 		/* Peer ACK'ed Authentication Request frame, but did not reply
629 		 * with Authentication Response frame within two seconds. */
630 		wpa_printf(MSG_INFO,
631 			   "DPP: No response received from responder - stopping initiation attempt");
632 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
633 		hostapd_drv_send_action_cancel_wait(hapd);
634 		hostapd_dpp_listen_stop(hapd);
635 		dpp_auth_deinit(auth);
636 		hapd->dpp_auth = NULL;
637 		return;
638 	}
639 
640 	if (diff_ms >= wait_time) {
641 		/* Authentication Request frame was not ACK'ed and no reply
642 		 * was receiving within two seconds. */
643 		wpa_printf(MSG_DEBUG,
644 			   "DPP: Continue Initiator channel iteration");
645 		hostapd_drv_send_action_cancel_wait(hapd);
646 		hostapd_dpp_listen_stop(hapd);
647 		hostapd_dpp_auth_init_next(hapd);
648 		return;
649 	}
650 
651 	/* Driver did not support 2000 ms long wait_time with TX command, so
652 	 * schedule listen operation to continue waiting for the response.
653 	 *
654 	 * DPP listen operations continue until stopped, so simply schedule a
655 	 * new call to this function at the point when the two second reply
656 	 * wait has expired. */
657 	wait_time -= diff_ms;
658 
659 	freq = auth->curr_freq;
660 	if (auth->neg_freq > 0)
661 		freq = auth->neg_freq;
662 	wpa_printf(MSG_DEBUG,
663 		   "DPP: Continue reply wait on channel %u MHz for %u ms",
664 		   freq, wait_time);
665 	hapd->dpp_in_response_listen = 1;
666 
667 	if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
668 		/* TODO: Listen operation on non-operating channel */
669 		wpa_printf(MSG_INFO,
670 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
671 			   freq, hapd->iface->freq);
672 	}
673 
674 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
675 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
676 }
677 
678 
hostapd_dpp_auth_conf_wait_timeout(void * eloop_ctx,void * timeout_ctx)679 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
680 					       void *timeout_ctx)
681 {
682 	struct hostapd_data *hapd = eloop_ctx;
683 	struct dpp_authentication *auth = hapd->dpp_auth;
684 
685 	if (!auth || !auth->waiting_auth_conf)
686 		return;
687 
688 	wpa_printf(MSG_DEBUG,
689 		   "DPP: Terminate authentication exchange due to Auth Confirm timeout");
690 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
691 		"No Auth Confirm received");
692 	hostapd_drv_send_action_cancel_wait(hapd);
693 	dpp_auth_deinit(auth);
694 	hapd->dpp_auth = NULL;
695 }
696 
697 
hostapd_dpp_set_testing_options(struct hostapd_data * hapd,struct dpp_authentication * auth)698 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
699 					    struct dpp_authentication *auth)
700 {
701 #ifdef CONFIG_TESTING_OPTIONS
702 	if (hapd->dpp_config_obj_override)
703 		auth->config_obj_override =
704 			os_strdup(hapd->dpp_config_obj_override);
705 	if (hapd->dpp_discovery_override)
706 		auth->discovery_override =
707 			os_strdup(hapd->dpp_discovery_override);
708 	if (hapd->dpp_groups_override)
709 		auth->groups_override = os_strdup(hapd->dpp_groups_override);
710 	auth->ignore_netaccesskey_mismatch =
711 		hapd->dpp_ignore_netaccesskey_mismatch;
712 #endif /* CONFIG_TESTING_OPTIONS */
713 }
714 
715 
hostapd_dpp_init_timeout(void * eloop_ctx,void * timeout_ctx)716 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
717 {
718 	struct hostapd_data *hapd = eloop_ctx;
719 
720 	if (!hapd->dpp_auth)
721 		return;
722 	wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
723 	hostapd_dpp_auth_init_next(hapd);
724 }
725 
726 
hostapd_dpp_auth_init_next(struct hostapd_data * hapd)727 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
728 {
729 	struct dpp_authentication *auth = hapd->dpp_auth;
730 	const u8 *dst;
731 	unsigned int wait_time, max_wait_time, freq, max_tries, used;
732 	struct os_reltime now, diff;
733 
734 	if (!auth)
735 		return -1;
736 
737 	if (auth->freq_idx == 0)
738 		os_get_reltime(&hapd->dpp_init_iter_start);
739 
740 	if (auth->freq_idx >= auth->num_freq) {
741 		auth->num_freq_iters++;
742 		if (hapd->dpp_init_max_tries)
743 			max_tries = hapd->dpp_init_max_tries;
744 		else
745 			max_tries = 5;
746 		if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
747 			wpa_printf(MSG_INFO,
748 				   "DPP: No response received from responder - stopping initiation attempt");
749 			wpa_msg(hapd->msg_ctx, MSG_INFO,
750 				DPP_EVENT_AUTH_INIT_FAILED);
751 			eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
752 					     hapd, NULL);
753 			hostapd_drv_send_action_cancel_wait(hapd);
754 			dpp_auth_deinit(hapd->dpp_auth);
755 			hapd->dpp_auth = NULL;
756 			return -1;
757 		}
758 		auth->freq_idx = 0;
759 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
760 		if (hapd->dpp_init_retry_time)
761 			wait_time = hapd->dpp_init_retry_time;
762 		else
763 			wait_time = 10000;
764 		os_get_reltime(&now);
765 		os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
766 		used = diff.sec * 1000 + diff.usec / 1000;
767 		if (used > wait_time)
768 			wait_time = 0;
769 		else
770 			wait_time -= used;
771 		wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
772 			   wait_time);
773 		eloop_register_timeout(wait_time / 1000,
774 				       (wait_time % 1000) * 1000,
775 				       hostapd_dpp_init_timeout, hapd,
776 				       NULL);
777 		return 0;
778 	}
779 	freq = auth->freq[auth->freq_idx++];
780 	auth->curr_freq = freq;
781 
782 	if (!is_zero_ether_addr(auth->peer_mac_addr))
783 		dst = auth->peer_mac_addr;
784 	else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
785 		dst = broadcast;
786 	else
787 		dst = auth->peer_bi->mac_addr;
788 	hapd->dpp_auth_ok_on_ack = 0;
789 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
790 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
791 	max_wait_time = hapd->dpp_resp_wait_time ?
792 		hapd->dpp_resp_wait_time : 2000;
793 	if (wait_time > max_wait_time)
794 		wait_time = max_wait_time;
795 	wait_time += 10; /* give the driver some extra time to complete */
796 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
797 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
798 	wait_time -= 10;
799 	if (auth->neg_freq > 0 && freq != auth->neg_freq) {
800 		wpa_printf(MSG_DEBUG,
801 			   "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
802 			   freq, auth->neg_freq);
803 	}
804 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
805 		" freq=%u type=%d",
806 		MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
807 	auth->auth_req_ack = 0;
808 	os_get_reltime(&hapd->dpp_last_init);
809 	return hostapd_drv_send_action(hapd, freq, wait_time,
810 				       dst,
811 				       wpabuf_head(hapd->dpp_auth->req_msg),
812 				       wpabuf_len(hapd->dpp_auth->req_msg));
813 }
814 
815 
816 #ifdef CONFIG_DPP2
hostapd_dpp_process_conf_obj(void * ctx,struct dpp_authentication * auth)817 static int hostapd_dpp_process_conf_obj(void *ctx,
818 				     struct dpp_authentication *auth)
819 {
820 	struct hostapd_data *hapd = ctx;
821 	unsigned int i;
822 
823 	for (i = 0; i < auth->num_conf_obj; i++)
824 		hostapd_dpp_handle_config_obj(hapd, auth,
825 					      &auth->conf_obj[i]);
826 
827 	return 0;
828 }
829 #endif /* CONFIG_DPP2 */
830 
831 
hostapd_dpp_auth_init(struct hostapd_data * hapd,const char * cmd)832 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
833 {
834 	const char *pos;
835 	struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
836 	struct dpp_authentication *auth;
837 	u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
838 	unsigned int neg_freq = 0;
839 	int tcp = 0;
840 #ifdef CONFIG_DPP2
841 	int tcp_port = DPP_TCP_PORT;
842 	struct hostapd_ip_addr ipaddr;
843 	char *addr;
844 #endif /* CONFIG_DPP2 */
845 
846 	pos = os_strstr(cmd, " peer=");
847 	if (!pos)
848 		return -1;
849 	pos += 6;
850 	peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
851 	if (!peer_bi) {
852 		wpa_printf(MSG_INFO,
853 			   "DPP: Could not find bootstrapping info for the identified peer");
854 		return -1;
855 	}
856 
857 #ifdef CONFIG_DPP2
858 	pos = os_strstr(cmd, " tcp_port=");
859 	if (pos) {
860 		pos += 10;
861 		tcp_port = atoi(pos);
862 	}
863 
864 	addr = get_param(cmd, " tcp_addr=");
865 	if (addr && os_strcmp(addr, "from-uri") == 0) {
866 		os_free(addr);
867 		if (!peer_bi->host) {
868 			wpa_printf(MSG_INFO,
869 				   "DPP: TCP address not available in peer URI");
870 			return -1;
871 		}
872 		tcp = 1;
873 		os_memcpy(&ipaddr, peer_bi->host, sizeof(ipaddr));
874 		tcp_port = peer_bi->port;
875 	} else if (addr) {
876 		int res;
877 
878 		res = hostapd_parse_ip_addr(addr, &ipaddr);
879 		os_free(addr);
880 		if (res)
881 			return -1;
882 		tcp = 1;
883 	}
884 #endif /* CONFIG_DPP2 */
885 
886 	pos = os_strstr(cmd, " own=");
887 	if (pos) {
888 		pos += 5;
889 		own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
890 					      atoi(pos));
891 		if (!own_bi) {
892 			wpa_printf(MSG_INFO,
893 				   "DPP: Could not find bootstrapping info for the identified local entry");
894 			return -1;
895 		}
896 
897 		if (peer_bi->curve != own_bi->curve) {
898 			wpa_printf(MSG_INFO,
899 				   "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
900 				   peer_bi->curve->name, own_bi->curve->name);
901 			return -1;
902 		}
903 	}
904 
905 	pos = os_strstr(cmd, " role=");
906 	if (pos) {
907 		pos += 6;
908 		if (os_strncmp(pos, "configurator", 12) == 0)
909 			allowed_roles = DPP_CAPAB_CONFIGURATOR;
910 		else if (os_strncmp(pos, "enrollee", 8) == 0)
911 			allowed_roles = DPP_CAPAB_ENROLLEE;
912 		else if (os_strncmp(pos, "either", 6) == 0)
913 			allowed_roles = DPP_CAPAB_CONFIGURATOR |
914 				DPP_CAPAB_ENROLLEE;
915 		else
916 			goto fail;
917 	}
918 
919 	pos = os_strstr(cmd, " neg_freq=");
920 	if (pos)
921 		neg_freq = atoi(pos + 10);
922 
923 	if (!tcp && hapd->dpp_auth) {
924 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
925 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
926 				     hapd, NULL);
927 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
928 				     hapd, NULL);
929 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
930 				     NULL);
931 #ifdef CONFIG_DPP2
932 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
933 				     hapd, NULL);
934 #endif /* CONFIG_DPP2 */
935 		hostapd_drv_send_action_cancel_wait(hapd);
936 		dpp_auth_deinit(hapd->dpp_auth);
937 	}
938 
939 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
940 			     peer_bi, own_bi, allowed_roles, neg_freq,
941 			     hapd->iface->hw_features,
942 			     hapd->iface->num_hw_features);
943 	if (!auth)
944 		goto fail;
945 	hostapd_dpp_set_testing_options(hapd, auth);
946 	if (dpp_set_configurator(auth, cmd) < 0) {
947 		dpp_auth_deinit(auth);
948 		goto fail;
949 	}
950 
951 	auth->neg_freq = neg_freq;
952 
953 	if (!is_zero_ether_addr(peer_bi->mac_addr))
954 		os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
955 
956 #ifdef CONFIG_DPP2
957 	if (tcp)
958 		return dpp_tcp_init(hapd->iface->interfaces->dpp, auth,
959 				    &ipaddr, tcp_port, hapd->conf->dpp_name,
960 				    DPP_NETROLE_AP, hapd->conf->dpp_mud_url,
961 				    hapd->conf->dpp_extra_conf_req_name,
962 				    hapd->conf->dpp_extra_conf_req_value,
963 				    hapd->msg_ctx, hapd,
964 				    hostapd_dpp_process_conf_obj, NULL);
965 #endif /* CONFIG_DPP2 */
966 
967 	hapd->dpp_auth = auth;
968 	return hostapd_dpp_auth_init_next(hapd);
969 fail:
970 	return -1;
971 }
972 
973 
hostapd_dpp_listen(struct hostapd_data * hapd,const char * cmd)974 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
975 {
976 	int freq;
977 
978 	freq = atoi(cmd);
979 	if (freq <= 0)
980 		return -1;
981 
982 	if (os_strstr(cmd, " role=configurator"))
983 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
984 	else if (os_strstr(cmd, " role=enrollee"))
985 		hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
986 	else
987 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
988 			DPP_CAPAB_ENROLLEE;
989 	hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
990 
991 	if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
992 		/* TODO: Listen operation on non-operating channel */
993 		wpa_printf(MSG_INFO,
994 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
995 			   freq, hapd->iface->freq);
996 		return -1;
997 	}
998 
999 	hostapd_drv_dpp_listen(hapd, true);
1000 	return 0;
1001 }
1002 
1003 
hostapd_dpp_listen_stop(struct hostapd_data * hapd)1004 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
1005 {
1006 	hostapd_drv_dpp_listen(hapd, false);
1007 	/* TODO: Stop listen operation on non-operating channel */
1008 }
1009 
1010 
1011 #ifdef CONFIG_DPP2
1012 static void
hostapd_dpp_relay_needs_controller(struct hostapd_data * hapd,const u8 * src,enum dpp_public_action_frame_type type)1013 hostapd_dpp_relay_needs_controller(struct hostapd_data *hapd, const u8 *src,
1014 				   enum dpp_public_action_frame_type type)
1015 {
1016 	struct os_reltime now;
1017 
1018 	if (!hapd->conf->dpp_relay_port)
1019 		return;
1020 
1021 	os_get_reltime(&now);
1022 	if (hapd->dpp_relay_last_needs_ctrl.sec &&
1023 	    !os_reltime_expired(&now, &hapd->dpp_relay_last_needs_ctrl, 60))
1024 		return;
1025 	hapd->dpp_relay_last_needs_ctrl = now;
1026 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RELAY_NEEDS_CONTROLLER
1027 		MACSTR " %u", MAC2STR(src), type);
1028 }
1029 #endif /* CONFIG_DPP2 */
1030 
1031 
hostapd_dpp_rx_auth_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1032 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
1033 				    const u8 *hdr, const u8 *buf, size_t len,
1034 				    unsigned int freq)
1035 {
1036 	const u8 *r_bootstrap, *i_bootstrap;
1037 	u16 r_bootstrap_len, i_bootstrap_len;
1038 	struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
1039 
1040 	if (!hapd->iface->interfaces->dpp)
1041 		return;
1042 
1043 	wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
1044 		   MAC2STR(src));
1045 
1046 #ifdef CONFIG_DPP2
1047 	hostapd_dpp_chirp_stop(hapd);
1048 #endif /* CONFIG_DPP2 */
1049 
1050 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1051 				   &r_bootstrap_len);
1052 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1053 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1054 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
1055 		return;
1056 	}
1057 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1058 		    r_bootstrap, r_bootstrap_len);
1059 
1060 	i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1061 				   &i_bootstrap_len);
1062 	if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
1063 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1064 			"Missing or invalid required Initiator Bootstrapping Key Hash attribute");
1065 		return;
1066 	}
1067 	wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
1068 		    i_bootstrap, i_bootstrap_len);
1069 
1070 	/* Try to find own and peer bootstrapping key matches based on the
1071 	 * received hash values */
1072 	dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
1073 				r_bootstrap, &own_bi, &peer_bi);
1074 #ifdef CONFIG_DPP2
1075 	if (!own_bi) {
1076 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1077 					src, hdr, buf, len, freq, i_bootstrap,
1078 					r_bootstrap, hapd) == 0)
1079 			return;
1080 		hostapd_dpp_relay_needs_controller(hapd, src,
1081 						   DPP_PA_AUTHENTICATION_REQ);
1082 	}
1083 #endif /* CONFIG_DPP2 */
1084 	if (!own_bi) {
1085 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1086 			"No matching own bootstrapping key found - ignore message");
1087 		return;
1088 	}
1089 
1090 	if (own_bi->type == DPP_BOOTSTRAP_PKEX) {
1091 		if (!peer_bi || peer_bi->type != DPP_BOOTSTRAP_PKEX) {
1092 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1093 				"No matching peer bootstrapping key found for PKEX - ignore message");
1094 			return;
1095 		}
1096 
1097 		if (os_memcmp(peer_bi->pubkey_hash, own_bi->peer_pubkey_hash,
1098 			      SHA256_MAC_LEN) != 0) {
1099 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1100 				"Mismatching peer PKEX bootstrapping key - ignore message");
1101 			return;
1102 		}
1103 	}
1104 
1105 	if (hapd->dpp_auth) {
1106 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1107 			"Already in DPP authentication exchange - ignore new one");
1108 		return;
1109 	}
1110 
1111 	hapd->dpp_auth_ok_on_ack = 0;
1112 	hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
1113 					 hapd->msg_ctx, hapd->dpp_allowed_roles,
1114 					 hapd->dpp_qr_mutual,
1115 					 peer_bi, own_bi, freq, hdr, buf, len);
1116 	if (!hapd->dpp_auth) {
1117 		wpa_printf(MSG_DEBUG, "DPP: No response generated");
1118 		return;
1119 	}
1120 	hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
1121 	if (dpp_set_configurator(hapd->dpp_auth,
1122 				 hapd->dpp_configurator_params) < 0) {
1123 		dpp_auth_deinit(hapd->dpp_auth);
1124 		hapd->dpp_auth = NULL;
1125 		return;
1126 	}
1127 	os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
1128 
1129 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1130 		" freq=%u type=%d",
1131 		MAC2STR(src), hapd->dpp_auth->curr_freq,
1132 		DPP_PA_AUTHENTICATION_RESP);
1133 	hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
1134 				src, wpabuf_head(hapd->dpp_auth->resp_msg),
1135 				wpabuf_len(hapd->dpp_auth->resp_msg));
1136 }
1137 
1138 
hostapd_dpp_handle_config_obj(struct hostapd_data * hapd,struct dpp_authentication * auth,struct dpp_config_obj * conf)1139 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
1140 					  struct dpp_authentication *auth,
1141 					  struct dpp_config_obj *conf)
1142 {
1143 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
1144 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
1145 		dpp_akm_str(conf->akm));
1146 	if (conf->ssid_len)
1147 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
1148 			wpa_ssid_txt(conf->ssid, conf->ssid_len));
1149 	if (conf->connector) {
1150 		/* TODO: Save the Connector and consider using a command
1151 		 * to fetch the value instead of sending an event with
1152 		 * it. The Connector could end up being larger than what
1153 		 * most clients are ready to receive as an event
1154 		 * message. */
1155 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
1156 			conf->connector);
1157 	}
1158 	if (conf->passphrase[0]) {
1159 		char hex[64 * 2 + 1];
1160 
1161 		wpa_snprintf_hex(hex, sizeof(hex),
1162 				 (const u8 *) conf->passphrase,
1163 				 os_strlen(conf->passphrase));
1164 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
1165 			hex);
1166 	} else if (conf->psk_set) {
1167 		char hex[PMK_LEN * 2 + 1];
1168 
1169 		wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
1170 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
1171 			hex);
1172 	}
1173 	if (conf->c_sign_key) {
1174 		char *hex;
1175 		size_t hexlen;
1176 
1177 		hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
1178 		hex = os_malloc(hexlen);
1179 		if (hex) {
1180 			wpa_snprintf_hex(hex, hexlen,
1181 					 wpabuf_head(conf->c_sign_key),
1182 					 wpabuf_len(conf->c_sign_key));
1183 			wpa_msg(hapd->msg_ctx, MSG_INFO,
1184 				DPP_EVENT_C_SIGN_KEY "%s", hex);
1185 			os_free(hex);
1186 		}
1187 	}
1188 	if (auth->net_access_key) {
1189 		char *hex;
1190 		size_t hexlen;
1191 
1192 		hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
1193 		hex = os_malloc(hexlen);
1194 		if (hex) {
1195 			wpa_snprintf_hex(hex, hexlen,
1196 					 wpabuf_head(auth->net_access_key),
1197 					 wpabuf_len(auth->net_access_key));
1198 			if (auth->net_access_key_expiry)
1199 				wpa_msg(hapd->msg_ctx, MSG_INFO,
1200 					DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
1201 					(unsigned long)
1202 					auth->net_access_key_expiry);
1203 			else
1204 				wpa_msg(hapd->msg_ctx, MSG_INFO,
1205 					DPP_EVENT_NET_ACCESS_KEY "%s", hex);
1206 			os_free(hex);
1207 		}
1208 	}
1209 }
1210 
1211 
hostapd_dpp_handle_key_pkg(struct hostapd_data * hapd,struct dpp_asymmetric_key * key)1212 static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
1213 				      struct dpp_asymmetric_key *key)
1214 {
1215 #ifdef CONFIG_DPP2
1216 	int res;
1217 
1218 	if (!key)
1219 		return 0;
1220 
1221 	wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
1222 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
1223 
1224 	while (key) {
1225 		res = dpp_configurator_from_backup(
1226 			hapd->iface->interfaces->dpp, key);
1227 		if (res < 0)
1228 			return -1;
1229 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
1230 			res);
1231 		key = key->next;
1232 	}
1233 #endif /* CONFIG_DPP2 */
1234 
1235 	return 0;
1236 }
1237 
1238 
1239 #ifdef CONFIG_DPP3
hostapd_dpp_build_new_key(void * eloop_ctx,void * timeout_ctx)1240 static void hostapd_dpp_build_new_key(void *eloop_ctx, void *timeout_ctx)
1241 {
1242 	struct hostapd_data *hapd = eloop_ctx;
1243 	struct dpp_authentication *auth = hapd->dpp_auth;
1244 
1245 	if (!auth || !auth->waiting_new_key)
1246 		return;
1247 
1248 	wpa_printf(MSG_DEBUG, "DPP: Build config request with a new key");
1249 	hostapd_dpp_start_gas_client(hapd);
1250 }
1251 #endif /* CONFIG_DPP3 */
1252 
1253 
hostapd_dpp_gas_resp_cb(void * ctx,const u8 * addr,u8 dialog_token,enum gas_query_ap_result result,const struct wpabuf * adv_proto,const struct wpabuf * resp,u16 status_code)1254 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
1255 				    enum gas_query_ap_result result,
1256 				    const struct wpabuf *adv_proto,
1257 				    const struct wpabuf *resp, u16 status_code)
1258 {
1259 	struct hostapd_data *hapd = ctx;
1260 	const u8 *pos;
1261 	struct dpp_authentication *auth = hapd->dpp_auth;
1262 	enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
1263 	int res;
1264 
1265 	if (!auth || !auth->auth_success) {
1266 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1267 		return;
1268 	}
1269 	if (result != GAS_QUERY_AP_SUCCESS ||
1270 	    !resp || status_code != WLAN_STATUS_SUCCESS) {
1271 		wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
1272 		goto fail;
1273 	}
1274 
1275 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
1276 			adv_proto);
1277 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
1278 			resp);
1279 
1280 	if (wpabuf_len(adv_proto) != 10 ||
1281 	    !(pos = wpabuf_head(adv_proto)) ||
1282 	    pos[0] != WLAN_EID_ADV_PROTO ||
1283 	    pos[1] != 8 ||
1284 	    pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
1285 	    pos[4] != 5 ||
1286 	    WPA_GET_BE24(&pos[5]) != OUI_WFA ||
1287 	    pos[8] != 0x1a ||
1288 	    pos[9] != 1) {
1289 		wpa_printf(MSG_DEBUG,
1290 			   "DPP: Not a DPP Advertisement Protocol ID");
1291 		goto fail;
1292 	}
1293 
1294 	res = dpp_conf_resp_rx(auth, resp);
1295 #ifdef CONFIG_DPP3
1296 	if (res == -3) {
1297 		wpa_printf(MSG_DEBUG, "DPP: New protocol key needed");
1298 		eloop_register_timeout(0, 0, hostapd_dpp_build_new_key, hapd,
1299 				       NULL);
1300 		return;
1301 	}
1302 #endif /* CONFIG_DPP3 */
1303 	if (res < 0) {
1304 		wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
1305 		goto fail;
1306 	}
1307 
1308 	hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
1309 	if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
1310 		goto fail;
1311 
1312 	status = DPP_STATUS_OK;
1313 #ifdef CONFIG_TESTING_OPTIONS
1314 	if (dpp_test == DPP_TEST_REJECT_CONFIG) {
1315 		wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
1316 		status = DPP_STATUS_CONFIG_REJECTED;
1317 	}
1318 #endif /* CONFIG_TESTING_OPTIONS */
1319 fail:
1320 	if (status != DPP_STATUS_OK)
1321 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1322 #ifdef CONFIG_DPP2
1323 	if (auth->peer_version >= 2 &&
1324 	    auth->conf_resp_status == DPP_STATUS_OK) {
1325 		struct wpabuf *msg;
1326 
1327 		wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
1328 		msg = dpp_build_conf_result(auth, status);
1329 		if (!msg)
1330 			goto fail2;
1331 
1332 		wpa_msg(hapd->msg_ctx, MSG_INFO,
1333 			DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
1334 			MAC2STR(addr), auth->curr_freq,
1335 			DPP_PA_CONFIGURATION_RESULT);
1336 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
1337 					addr, wpabuf_head(msg),
1338 					wpabuf_len(msg));
1339 		wpabuf_free(msg);
1340 
1341 		/* This exchange will be terminated in the TX status handler */
1342 		auth->connect_on_tx_status = 1;
1343 		return;
1344 	}
1345 fail2:
1346 #endif /* CONFIG_DPP2 */
1347 	dpp_auth_deinit(hapd->dpp_auth);
1348 	hapd->dpp_auth = NULL;
1349 }
1350 
1351 
hostapd_dpp_start_gas_client(struct hostapd_data * hapd)1352 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
1353 {
1354 	struct dpp_authentication *auth = hapd->dpp_auth;
1355 	struct wpabuf *buf;
1356 	int res;
1357 
1358 	buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
1359 					DPP_NETROLE_AP,
1360 					hapd->conf->dpp_mud_url, NULL,
1361 					hapd->conf->dpp_extra_conf_req_name,
1362 					hapd->conf->dpp_extra_conf_req_value);
1363 	if (!buf) {
1364 		wpa_printf(MSG_DEBUG,
1365 			   "DPP: No configuration request data available");
1366 		return;
1367 	}
1368 
1369 	wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
1370 		   MAC2STR(auth->peer_mac_addr), auth->curr_freq);
1371 
1372 	res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
1373 			       buf, hostapd_dpp_gas_resp_cb, hapd);
1374 	if (res < 0) {
1375 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
1376 			"GAS: Failed to send Query Request");
1377 		wpabuf_free(buf);
1378 	} else {
1379 		wpa_printf(MSG_DEBUG,
1380 			   "DPP: GAS query started with dialog token %u", res);
1381 	}
1382 }
1383 
1384 
hostapd_gas_req_wait(void * eloop_ctx,void * timeout_ctx)1385 static void hostapd_gas_req_wait(void *eloop_ctx, void *timeout_ctx)
1386 {
1387 	struct hostapd_data *hapd = eloop_ctx;
1388 	struct dpp_authentication *auth = hapd->dpp_auth;
1389 
1390 	if (!auth)
1391 		return;
1392 
1393 	wpa_printf(MSG_DEBUG, "DPP: Timeout while waiting for Config Request");
1394 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1395 	dpp_auth_deinit(auth);
1396 	hapd->dpp_auth = NULL;
1397 }
1398 
1399 
hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)1400 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
1401 {
1402 	wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
1403 	dpp_notify_auth_success(hapd->dpp_auth, initiator);
1404 #ifdef CONFIG_TESTING_OPTIONS
1405 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1406 		wpa_printf(MSG_INFO,
1407 			   "DPP: TESTING - stop at Authentication Confirm");
1408 		if (hapd->dpp_auth->configurator) {
1409 			/* Prevent GAS response */
1410 			hapd->dpp_auth->auth_success = 0;
1411 		}
1412 		return;
1413 	}
1414 #endif /* CONFIG_TESTING_OPTIONS */
1415 
1416 	if (!hapd->dpp_auth->configurator)
1417 		hostapd_dpp_start_gas_client(hapd);
1418 	else
1419 		eloop_register_timeout(10, 0, hostapd_gas_req_wait,
1420 				       hapd, NULL);
1421 }
1422 
1423 
hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1424 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
1425 				     const u8 *hdr, const u8 *buf, size_t len,
1426 				     unsigned int freq)
1427 {
1428 	struct dpp_authentication *auth = hapd->dpp_auth;
1429 	struct wpabuf *msg;
1430 
1431 	wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
1432 		   MAC2STR(src));
1433 
1434 	if (!auth) {
1435 		wpa_printf(MSG_DEBUG,
1436 			   "DPP: No DPP Authentication in progress - drop");
1437 		return;
1438 	}
1439 
1440 	if (!is_zero_ether_addr(auth->peer_mac_addr) &&
1441 	    !ether_addr_equal(src, auth->peer_mac_addr)) {
1442 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1443 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1444 		return;
1445 	}
1446 
1447 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1448 
1449 	if (auth->curr_freq != freq && auth->neg_freq == freq) {
1450 		wpa_printf(MSG_DEBUG,
1451 			   "DPP: Responder accepted request for different negotiation channel");
1452 		auth->curr_freq = freq;
1453 	}
1454 
1455 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1456 	msg = dpp_auth_resp_rx(auth, hdr, buf, len);
1457 	if (!msg) {
1458 		if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
1459 			wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
1460 			return;
1461 		}
1462 		wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
1463 		return;
1464 	}
1465 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1466 
1467 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1468 		" freq=%u type=%d", MAC2STR(src), auth->curr_freq,
1469 		DPP_PA_AUTHENTICATION_CONF);
1470 	hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
1471 				wpabuf_head(msg), wpabuf_len(msg));
1472 	wpabuf_free(msg);
1473 	hapd->dpp_auth_ok_on_ack = 1;
1474 }
1475 
1476 
hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1477 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
1478 				     const u8 *hdr, const u8 *buf, size_t len)
1479 {
1480 	struct dpp_authentication *auth = hapd->dpp_auth;
1481 
1482 	wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
1483 		   MAC2STR(src));
1484 
1485 	if (!auth) {
1486 		wpa_printf(MSG_DEBUG,
1487 			   "DPP: No DPP Authentication in progress - drop");
1488 		return;
1489 	}
1490 
1491 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1492 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1493 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1494 		return;
1495 	}
1496 
1497 	if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1498 		wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1499 		return;
1500 	}
1501 
1502 	hostapd_dpp_auth_success(hapd, 0);
1503 }
1504 
1505 
1506 #ifdef CONFIG_DPP2
1507 
hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1508 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1509 						   void *timeout_ctx)
1510 {
1511 	struct hostapd_data *hapd = eloop_ctx;
1512 	struct dpp_authentication *auth = hapd->dpp_auth;
1513 
1514 	if (!auth || !auth->waiting_conf_result)
1515 		return;
1516 
1517 	wpa_printf(MSG_DEBUG,
1518 		   "DPP: Timeout while waiting for Configuration Result");
1519 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1520 	dpp_auth_deinit(auth);
1521 	hapd->dpp_auth = NULL;
1522 }
1523 
1524 
hostapd_dpp_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1525 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1526 							void *timeout_ctx)
1527 {
1528 	struct hostapd_data *hapd = eloop_ctx;
1529 	struct dpp_authentication *auth = hapd->dpp_auth;
1530 
1531 	if (!auth || !auth->waiting_conf_result)
1532 		return;
1533 
1534 	wpa_printf(MSG_DEBUG,
1535 		   "DPP: Timeout while waiting for Connection Status Result");
1536 	wpa_msg(hapd->msg_ctx, MSG_INFO,
1537 		DPP_EVENT_CONN_STATUS_RESULT "timeout");
1538 	dpp_auth_deinit(auth);
1539 	hapd->dpp_auth = NULL;
1540 }
1541 
1542 
1543 #ifdef CONFIG_DPP3
1544 
hostapd_dpp_pb_active(struct hostapd_data * hapd)1545 static bool hostapd_dpp_pb_active(struct hostapd_data *hapd)
1546 {
1547 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1548 
1549 	return ifaces && (ifaces->dpp_pb_time.sec ||
1550 			  ifaces->dpp_pb_time.usec);
1551 }
1552 
1553 
hostapd_dpp_remove_pb_hash(struct hostapd_data * hapd)1554 static void hostapd_dpp_remove_pb_hash(struct hostapd_data *hapd)
1555 {
1556 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1557 	int i;
1558 
1559 	if (!ifaces->dpp_pb_bi)
1560 		return;
1561 	for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
1562 		struct dpp_pb_info *info = &ifaces->dpp_pb[i];
1563 
1564 		if (info->rx_time.sec == 0 && info->rx_time.usec == 0)
1565 			continue;
1566 		if (os_memcmp(info->hash, ifaces->dpp_pb_resp_hash,
1567 			      SHA256_MAC_LEN) == 0) {
1568 			/* Allow a new push button session to be established
1569 			 * immediately without the successfully completed
1570 			 * session triggering session overlap. */
1571 			info->rx_time.sec = 0;
1572 			info->rx_time.usec = 0;
1573 			wpa_printf(MSG_DEBUG,
1574 				   "DPP: Removed PB hash from session overlap detection due to successfully completed provisioning");
1575 		}
1576 	}
1577 }
1578 
1579 #endif /* CONFIG_DPP3 */
1580 
1581 
hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1582 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1583 				       const u8 *hdr, const u8 *buf, size_t len)
1584 {
1585 	struct dpp_authentication *auth = hapd->dpp_auth;
1586 	enum dpp_status_error status;
1587 #ifdef CONFIG_DPP3
1588 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1589 #endif /* CONFIG_DPP3 */
1590 
1591 	wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
1592 		   MAC2STR(src));
1593 
1594 	if (!auth || !auth->waiting_conf_result) {
1595 		wpa_printf(MSG_DEBUG,
1596 			   "DPP: No DPP Configuration waiting for result - drop");
1597 		return;
1598 	}
1599 
1600 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1601 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1602 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1603 		return;
1604 	}
1605 
1606 	status = dpp_conf_result_rx(auth, hdr, buf, len);
1607 
1608 	if (status == DPP_STATUS_OK && auth->send_conn_status) {
1609 		wpa_msg(hapd->msg_ctx, MSG_INFO,
1610 			DPP_EVENT_CONF_SENT "wait_conn_status=1 conf_status=%d",
1611 			auth->conf_resp_status);
1612 		wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1613 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1614 				     hapd, NULL);
1615 		auth->waiting_conn_status_result = 1;
1616 		eloop_cancel_timeout(
1617 			hostapd_dpp_conn_status_result_wait_timeout,
1618 			hapd, NULL);
1619 		eloop_register_timeout(
1620 			16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1621 			hapd, NULL);
1622 		return;
1623 	}
1624 	hostapd_drv_send_action_cancel_wait(hapd);
1625 	hostapd_dpp_listen_stop(hapd);
1626 	if (status == DPP_STATUS_OK)
1627 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
1628 			"conf_status=%d", auth->conf_resp_status);
1629 	else
1630 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1631 	dpp_auth_deinit(auth);
1632 	hapd->dpp_auth = NULL;
1633 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1634 			     NULL);
1635 #ifdef CONFIG_DPP3
1636 	if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
1637 		if (status == DPP_STATUS_OK)
1638 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1639 				"success");
1640 		else
1641 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1642 				"no-configuration-available");
1643 		ifaces->dpp_pb_result_indicated = true;
1644 		if (status == DPP_STATUS_OK)
1645 			hostapd_dpp_remove_pb_hash(hapd);
1646 		hostapd_dpp_push_button_stop(hapd);
1647 	}
1648 #endif /* CONFIG_DPP3 */
1649 }
1650 
1651 
hostapd_dpp_rx_conn_status_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1652 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1653 					      const u8 *src, const u8 *hdr,
1654 					      const u8 *buf, size_t len)
1655 {
1656 	struct dpp_authentication *auth = hapd->dpp_auth;
1657 	enum dpp_status_error status;
1658 	u8 ssid[SSID_MAX_LEN];
1659 	size_t ssid_len = 0;
1660 	char *channel_list = NULL;
1661 
1662 	wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1663 
1664 	if (!auth || !auth->waiting_conn_status_result) {
1665 		wpa_printf(MSG_DEBUG,
1666 			   "DPP: No DPP Configuration waiting for connection status result - drop");
1667 		return;
1668 	}
1669 
1670 	status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1671 					   ssid, &ssid_len, &channel_list);
1672 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1673 		"result=%d ssid=%s channel_list=%s",
1674 		status, wpa_ssid_txt(ssid, ssid_len),
1675 		channel_list ? channel_list : "N/A");
1676 	os_free(channel_list);
1677 	hostapd_drv_send_action_cancel_wait(hapd);
1678 	hostapd_dpp_listen_stop(hapd);
1679 	dpp_auth_deinit(auth);
1680 	hapd->dpp_auth = NULL;
1681 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1682 			     hapd, NULL);
1683 }
1684 
1685 
1686 static void
hostapd_dpp_rx_presence_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1687 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1688 				     const u8 *hdr, const u8 *buf, size_t len,
1689 				     unsigned int freq)
1690 {
1691 	const u8 *r_bootstrap;
1692 	u16 r_bootstrap_len;
1693 	struct dpp_bootstrap_info *peer_bi;
1694 	struct dpp_authentication *auth;
1695 
1696 	wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
1697 		   MAC2STR(src));
1698 
1699 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1700 				   &r_bootstrap_len);
1701 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1702 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1703 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
1704 		return;
1705 	}
1706 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1707 		    r_bootstrap, r_bootstrap_len);
1708 	peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1709 					   r_bootstrap);
1710 	dpp_notify_chirp_received(hapd->msg_ctx,
1711 				  peer_bi ? (int) peer_bi->id : -1,
1712 				  src, freq, r_bootstrap);
1713 	if (!peer_bi) {
1714 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1715 					src, hdr, buf, len, freq, NULL,
1716 					r_bootstrap, hapd) == 0)
1717 			return;
1718 		wpa_printf(MSG_DEBUG,
1719 			   "DPP: No matching bootstrapping information found");
1720 		hostapd_dpp_relay_needs_controller(
1721 			hapd, src, DPP_PA_PRESENCE_ANNOUNCEMENT);
1722 		return;
1723 	}
1724 
1725 	if (hapd->dpp_auth) {
1726 		wpa_printf(MSG_DEBUG,
1727 			   "DPP: Ignore Presence Announcement during ongoing Authentication");
1728 		return;
1729 	}
1730 
1731 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1732 			     peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1733 			     0);
1734 	if (!auth)
1735 		return;
1736 	hostapd_dpp_set_testing_options(hapd, auth);
1737 	if (dpp_set_configurator(auth,
1738 				 hapd->dpp_configurator_params) < 0) {
1739 		dpp_auth_deinit(auth);
1740 		return;
1741 	}
1742 
1743 	auth->neg_freq = freq;
1744 
1745 	/* The source address of the Presence Announcement frame overrides any
1746 	 * MAC address information from the bootstrapping information. */
1747 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1748 
1749 	hapd->dpp_auth = auth;
1750 	if (hostapd_dpp_auth_init_next(hapd) < 0) {
1751 		dpp_auth_deinit(hapd->dpp_auth);
1752 		hapd->dpp_auth = NULL;
1753 	}
1754 }
1755 
1756 
hostapd_dpp_reconfig_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)1757 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
1758 						    void *timeout_ctx)
1759 {
1760 	struct hostapd_data *hapd = eloop_ctx;
1761 	struct dpp_authentication *auth = hapd->dpp_auth;
1762 
1763 	if (!auth)
1764 		return;
1765 
1766 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
1767 	hostapd_dpp_listen_stop(hapd);
1768 	dpp_auth_deinit(auth);
1769 	hapd->dpp_auth = NULL;
1770 }
1771 
1772 
1773 static void
hostapd_dpp_rx_reconfig_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1774 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
1775 				     const u8 *hdr, const u8 *buf, size_t len,
1776 				     unsigned int freq)
1777 {
1778 	const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1779 	u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1780 	struct dpp_configurator *conf;
1781 	struct dpp_authentication *auth;
1782 	unsigned int wait_time, max_wait_time;
1783 	u16 group;
1784 
1785 	if (hapd->dpp_auth) {
1786 		wpa_printf(MSG_DEBUG,
1787 			   "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1788 		return;
1789 	}
1790 
1791 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR,
1792 		   MAC2STR(src));
1793 
1794 	csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1795 				  &csign_hash_len);
1796 	if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1797 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1798 			"Missing or invalid required Configurator C-sign key Hash attribute");
1799 		return;
1800 	}
1801 	wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1802 		    csign_hash, csign_hash_len);
1803 	conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp,
1804 					 csign_hash);
1805 	if (!conf) {
1806 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1807 					src, hdr, buf, len, freq, NULL,
1808 					NULL, hapd) == 0)
1809 			return;
1810 		wpa_printf(MSG_DEBUG,
1811 			   "DPP: No matching Configurator information found");
1812 		hostapd_dpp_relay_needs_controller(
1813 			hapd, src, DPP_PA_RECONFIG_ANNOUNCEMENT);
1814 		return;
1815 	}
1816 
1817 	fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1818 			       &fcgroup_len);
1819 	if (!fcgroup || fcgroup_len != 2) {
1820 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1821 			"Missing or invalid required Finite Cyclic Group attribute");
1822 		return;
1823 	}
1824 	group = WPA_GET_LE16(fcgroup);
1825 	wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1826 
1827 	a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1828 	e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1829 
1830 	auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1831 				 conf, freq, group, a_nonce, a_nonce_len,
1832 				 e_id, e_id_len);
1833 	if (!auth)
1834 		return;
1835 	hostapd_dpp_set_testing_options(hapd, auth);
1836 	if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
1837 		dpp_auth_deinit(auth);
1838 		return;
1839 	}
1840 
1841 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1842 	hapd->dpp_auth = auth;
1843 
1844 	hapd->dpp_in_response_listen = 0;
1845 	hapd->dpp_auth_ok_on_ack = 0;
1846 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
1847 	max_wait_time = hapd->dpp_resp_wait_time ?
1848 		hapd->dpp_resp_wait_time : 2000;
1849 	if (wait_time > max_wait_time)
1850 		wait_time = max_wait_time;
1851 	wait_time += 10; /* give the driver some extra time to complete */
1852 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
1853 			       hostapd_dpp_reconfig_reply_wait_timeout,
1854 			       hapd, NULL);
1855 	wait_time -= 10;
1856 
1857 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1858 		" freq=%u type=%d",
1859 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
1860 	if (hostapd_drv_send_action(hapd, freq, wait_time, src,
1861 				    wpabuf_head(auth->reconfig_req_msg),
1862 				    wpabuf_len(auth->reconfig_req_msg)) < 0) {
1863 		dpp_auth_deinit(hapd->dpp_auth);
1864 		hapd->dpp_auth = NULL;
1865 	}
1866 }
1867 
1868 
1869 static void
hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1870 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src,
1871 				  const u8 *hdr, const u8 *buf, size_t len,
1872 				  unsigned int freq)
1873 {
1874 	struct dpp_authentication *auth = hapd->dpp_auth;
1875 	struct wpabuf *conf;
1876 
1877 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
1878 		   MACSTR, MAC2STR(src));
1879 
1880 	if (!auth || !auth->reconfig || !auth->configurator) {
1881 		wpa_printf(MSG_DEBUG,
1882 			   "DPP: No DPP Reconfig Authentication in progress - drop");
1883 		return;
1884 	}
1885 
1886 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1887 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1888 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1889 		return;
1890 	}
1891 
1892 	conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1893 	if (!conf)
1894 		return;
1895 
1896 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1897 			     hapd, NULL);
1898 
1899 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1900 		" freq=%u type=%d",
1901 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
1902 	if (hostapd_drv_send_action(hapd, freq, 500, src,
1903 				    wpabuf_head(conf), wpabuf_len(conf)) < 0) {
1904 		wpabuf_free(conf);
1905 		dpp_auth_deinit(hapd->dpp_auth);
1906 		hapd->dpp_auth = NULL;
1907 		return;
1908 	}
1909 	wpabuf_free(conf);
1910 }
1911 
1912 #endif /* CONFIG_DPP2 */
1913 
1914 
hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)1915 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1916 					    const u8 *src, unsigned int freq,
1917 					    u8 trans_id,
1918 					    enum dpp_status_error status)
1919 {
1920 	struct wpabuf *msg;
1921 	size_t len;
1922 
1923 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
1924 #ifdef CONFIG_DPP2
1925 	len += 5;
1926 #endif /* CONFIG_DPP2 */
1927 	msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len);
1928 	if (!msg)
1929 		return;
1930 
1931 #ifdef CONFIG_TESTING_OPTIONS
1932 	if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1933 		wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1934 		goto skip_trans_id;
1935 	}
1936 	if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1937 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1938 		trans_id ^= 0x01;
1939 	}
1940 #endif /* CONFIG_TESTING_OPTIONS */
1941 
1942 	/* Transaction ID */
1943 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1944 	wpabuf_put_le16(msg, 1);
1945 	wpabuf_put_u8(msg, trans_id);
1946 
1947 #ifdef CONFIG_TESTING_OPTIONS
1948 skip_trans_id:
1949 	if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1950 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1951 		goto skip_status;
1952 	}
1953 	if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1954 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1955 		status = 254;
1956 	}
1957 #endif /* CONFIG_TESTING_OPTIONS */
1958 
1959 	/* DPP Status */
1960 	wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1961 	wpabuf_put_le16(msg, 1);
1962 	wpabuf_put_u8(msg, status);
1963 
1964 #ifdef CONFIG_TESTING_OPTIONS
1965 skip_status:
1966 	if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1967 		wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1968 		goto skip_connector;
1969 	}
1970 	if (status == DPP_STATUS_OK &&
1971 	    dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1972 		char *connector;
1973 
1974 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1975 		connector = dpp_corrupt_connector_signature(
1976 			hapd->conf->dpp_connector);
1977 		if (!connector) {
1978 			wpabuf_free(msg);
1979 			return;
1980 		}
1981 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1982 		wpabuf_put_le16(msg, os_strlen(connector));
1983 		wpabuf_put_str(msg, connector);
1984 		os_free(connector);
1985 		goto skip_connector;
1986 	}
1987 #endif /* CONFIG_TESTING_OPTIONS */
1988 
1989 	/* DPP Connector */
1990 	if (status == DPP_STATUS_OK) {
1991 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1992 		wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1993 		wpabuf_put_str(msg, hapd->conf->dpp_connector);
1994 	}
1995 
1996 #ifdef CONFIG_TESTING_OPTIONS
1997 skip_connector:
1998 	if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) {
1999 		wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
2000 		goto skip_proto_ver;
2001 	}
2002 #endif /* CONFIG_TESTING_OPTIONS */
2003 
2004 #ifdef CONFIG_DPP2
2005 	if (DPP_VERSION > 1) {
2006 		u8 ver = DPP_VERSION;
2007 #ifdef CONFIG_DPP3
2008 		int conn_ver;
2009 
2010 		conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
2011 		if (conn_ver > 0 && ver != conn_ver) {
2012 			wpa_printf(MSG_DEBUG,
2013 				   "DPP: Use Connector version %d instead of current protocol version %d",
2014 				   conn_ver, ver);
2015 			ver = conn_ver;
2016 		}
2017 #endif /* CONFIG_DPP3 */
2018 
2019 #ifdef CONFIG_TESTING_OPTIONS
2020 	if (dpp_test == DPP_TEST_INVALID_PROTOCOL_VERSION_PEER_DISC_RESP) {
2021 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Protocol Version");
2022 		ver = 1;
2023 	}
2024 #endif /* CONFIG_TESTING_OPTIONS */
2025 
2026 		/* Protocol Version */
2027 		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2028 		wpabuf_put_le16(msg, 1);
2029 		wpabuf_put_u8(msg, ver);
2030 	}
2031 #endif /* CONFIG_DPP2 */
2032 
2033 #ifdef CONFIG_TESTING_OPTIONS
2034 skip_proto_ver:
2035 #endif /* CONFIG_TESTING_OPTIONS */
2036 
2037 	wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
2038 		   " status=%d", MAC2STR(src), status);
2039 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2040 		" freq=%u type=%d status=%d", MAC2STR(src), freq,
2041 		DPP_PA_PEER_DISCOVERY_RESP, status);
2042 	hostapd_drv_send_action(hapd, freq, 0, src,
2043 				wpabuf_head(msg), wpabuf_len(msg));
2044 	wpabuf_free(msg);
2045 }
2046 
2047 
hapd_dpp_connector_available(struct hostapd_data * hapd)2048 static bool hapd_dpp_connector_available(struct hostapd_data *hapd)
2049 {
2050 	if (!hapd->wpa_auth ||
2051 	    !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
2052 	    !(hapd->conf->wpa & WPA_PROTO_RSN)) {
2053 		wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
2054 		return false;
2055 	}
2056 
2057 	if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
2058 	    !hapd->conf->dpp_csign) {
2059 		wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
2060 		return false;
2061 	}
2062 
2063 	return true;
2064 }
2065 
2066 
hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2067 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
2068 					 const u8 *src,
2069 					 const u8 *buf, size_t len,
2070 					 unsigned int freq)
2071 {
2072 	const u8 *connector, *trans_id;
2073 	u16 connector_len, trans_id_len;
2074 	struct os_time now;
2075 	struct dpp_introduction intro;
2076 	os_time_t expire;
2077 	int expiration;
2078 	enum dpp_status_error res;
2079 	u8 pkhash[SHA256_MAC_LEN];
2080 
2081 	os_memset(&intro, 0, sizeof(intro));
2082 
2083 	wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
2084 		   MAC2STR(src));
2085 	if (!hapd_dpp_connector_available(hapd))
2086 		return;
2087 
2088 	os_get_time(&now);
2089 
2090 	if (hapd->conf->dpp_netaccesskey_expiry &&
2091 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2092 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2093 		return;
2094 	}
2095 
2096 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2097 			       &trans_id_len);
2098 	if (!trans_id || trans_id_len != 1) {
2099 		wpa_printf(MSG_DEBUG,
2100 			   "DPP: Peer did not include Transaction ID");
2101 		return;
2102 	}
2103 
2104 	connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
2105 	if (!connector) {
2106 		wpa_printf(MSG_DEBUG,
2107 			   "DPP: Peer did not include its Connector");
2108 		return;
2109 	}
2110 
2111 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2112 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
2113 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
2114 			     wpabuf_head(hapd->conf->dpp_csign),
2115 			     wpabuf_len(hapd->conf->dpp_csign),
2116 			     connector, connector_len, &expire, pkhash);
2117 	if (res == 255) {
2118 		wpa_printf(MSG_INFO,
2119 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
2120 			   MACSTR ")", MAC2STR(src));
2121 		goto done;
2122 	}
2123 	if (res != DPP_STATUS_OK) {
2124 		wpa_printf(MSG_INFO,
2125 			   "DPP: Network Introduction protocol resulted in failure (peer "
2126 			   MACSTR " status %d)", MAC2STR(src), res);
2127 		hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2128 						res);
2129 		goto done;
2130 	}
2131 
2132 #ifdef CONFIG_DPP3
2133 	if (intro.peer_version && intro.peer_version >= 2) {
2134 		const u8 *version;
2135 		u16 version_len;
2136 		u8 attr_version = 1;
2137 
2138 		version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2139 				       &version_len);
2140 		if (version && version_len >= 1)
2141 			attr_version = version[0];
2142 		if (attr_version != intro.peer_version) {
2143 			wpa_printf(MSG_INFO,
2144 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2145 				   intro.peer_version, attr_version);
2146 			hostapd_dpp_send_peer_disc_resp(hapd, src, freq,
2147 							trans_id[0],
2148 							DPP_STATUS_NO_MATCH);
2149 			goto done;
2150 		}
2151 	}
2152 #endif /* CONFIG_DPP3 */
2153 
2154 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2155 		expire = hapd->conf->dpp_netaccesskey_expiry;
2156 	if (expire)
2157 		expiration = expire - now.sec;
2158 	else
2159 		expiration = 0;
2160 
2161 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2162 				intro.pmkid, expiration,
2163 				WPA_KEY_MGMT_DPP, pkhash, false) < 0) {
2164 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2165 		goto done;
2166 	}
2167 
2168 #ifdef CONFIG_IEEE80211BE
2169 	if (hapd->conf->mld_ap &&
2170 	    wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2171 				intro.pmkid, expiration,
2172 				WPA_KEY_MGMT_DPP, pkhash, true) < 0) {
2173 		wpa_printf(MSG_ERROR,
2174 			   "DPP: Failed to add PMKSA cache entry (MLD)");
2175 		goto done;
2176 	}
2177 #endif /* CONFIG_IEEE80211BE */
2178 
2179 	hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2180 					DPP_STATUS_OK);
2181 done:
2182 	dpp_peer_intro_deinit(&intro);
2183 }
2184 
2185 
2186 static void
hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq,bool v2)2187 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
2188 				 const u8 *hdr, const u8 *buf, size_t len,
2189 				 unsigned int freq, bool v2)
2190 {
2191 	struct wpabuf *msg;
2192 
2193 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
2194 		   MAC2STR(src));
2195 
2196 	if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_1 && v2) {
2197 		wpa_printf(MSG_DEBUG,
2198 			   "DPP: Ignore PKEXv2 Exchange Request when configured to be PKEX v1 only");
2199 		return;
2200 	}
2201 	if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_2 && !v2) {
2202 		wpa_printf(MSG_DEBUG,
2203 			   "DPP: Ignore PKEXv1 Exchange Request when configured to be PKEX v2 only");
2204 		return;
2205 	}
2206 
2207 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
2208 	 * values here */
2209 
2210 	if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
2211 		wpa_printf(MSG_DEBUG,
2212 			   "DPP: No PKEX code configured - ignore request");
2213 		goto try_relay;
2214 	}
2215 
2216 #ifdef CONFIG_DPP2
2217 	if (dpp_controller_is_own_pkex_req(hapd->iface->interfaces->dpp,
2218 					   buf, len)) {
2219 		wpa_printf(MSG_DEBUG,
2220 			   "DPP: PKEX Exchange Request is from local Controller - ignore request");
2221 		return;
2222 	}
2223 #endif /* CONFIG_DPP2 */
2224 
2225 	if (hapd->dpp_pkex) {
2226 		/* TODO: Support parallel operations */
2227 		wpa_printf(MSG_DEBUG,
2228 			   "DPP: Already in PKEX session - ignore new request");
2229 		goto try_relay;
2230 	}
2231 
2232 	hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
2233 						  hapd->dpp_pkex_bi,
2234 						  hapd->own_addr, src,
2235 						  hapd->dpp_pkex_identifier,
2236 						  hapd->dpp_pkex_code,
2237 						  hapd->dpp_pkex_code_len,
2238 						  buf, len, v2);
2239 	if (!hapd->dpp_pkex) {
2240 		wpa_printf(MSG_DEBUG,
2241 			   "DPP: Failed to process the request - ignore it");
2242 		goto try_relay;
2243 	}
2244 
2245 	msg = hapd->dpp_pkex->exchange_resp;
2246 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2247 		" freq=%u type=%d", MAC2STR(src), freq,
2248 		DPP_PA_PKEX_EXCHANGE_RESP);
2249 	hostapd_drv_send_action(hapd, freq, 0, src,
2250 				wpabuf_head(msg), wpabuf_len(msg));
2251 	if (hapd->dpp_pkex->failed) {
2252 		wpa_printf(MSG_DEBUG,
2253 			   "DPP: Terminate PKEX exchange due to an earlier error");
2254 		if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2255 			hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
2256 		dpp_pkex_free(hapd->dpp_pkex);
2257 		hapd->dpp_pkex = NULL;
2258 	}
2259 
2260 	return;
2261 
2262 try_relay:
2263 #ifdef CONFIG_DPP2
2264 	if (v2 && dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2265 				      src, hdr, buf, len, freq, NULL, NULL,
2266 				      hapd) != 0) {
2267 		wpa_printf(MSG_DEBUG,
2268 			   "DPP: No Relay available for the message");
2269 		hostapd_dpp_relay_needs_controller(hapd, src,
2270 						   DPP_PA_PKEX_EXCHANGE_REQ);
2271 	}
2272 #else /* CONFIG_DPP2 */
2273 	wpa_printf(MSG_DEBUG, "DPP: No relay functionality included - skip");
2274 #endif /* CONFIG_DPP2 */
2275 }
2276 
2277 
2278 static void
hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2279 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
2280 				  const u8 *buf, size_t len, unsigned int freq)
2281 {
2282 	struct wpabuf *msg;
2283 
2284 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
2285 		   MAC2STR(src));
2286 
2287 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
2288 	 * values here */
2289 
2290 	if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
2291 	    hapd->dpp_pkex->exchange_done) {
2292 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2293 		return;
2294 	}
2295 
2296 	eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
2297 	hapd->dpp_pkex->exch_req_wait_time = 0;
2298 
2299 	msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
2300 	if (!msg) {
2301 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2302 		return;
2303 	}
2304 
2305 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
2306 		   MAC2STR(src));
2307 
2308 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2309 		" freq=%u type=%d", MAC2STR(src), freq,
2310 		DPP_PA_PKEX_COMMIT_REVEAL_REQ);
2311 	hostapd_drv_send_action(hapd, freq, 0, src,
2312 				wpabuf_head(msg), wpabuf_len(msg));
2313 	wpabuf_free(msg);
2314 }
2315 
2316 
2317 static void
hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2318 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
2319 				      const u8 *hdr, const u8 *buf, size_t len,
2320 				      unsigned int freq)
2321 {
2322 	struct wpabuf *msg;
2323 	struct dpp_pkex *pkex = hapd->dpp_pkex;
2324 	struct dpp_bootstrap_info *bi;
2325 
2326 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
2327 		   MAC2STR(src));
2328 
2329 	if (!pkex || pkex->initiator || !pkex->exchange_done) {
2330 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2331 		return;
2332 	}
2333 
2334 	msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
2335 	if (!msg) {
2336 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
2337 		if (hapd->dpp_pkex->failed) {
2338 			wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
2339 			if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2340 				hapd->dpp_pkex->own_bi->pkex_t =
2341 					hapd->dpp_pkex->t;
2342 			dpp_pkex_free(hapd->dpp_pkex);
2343 			hapd->dpp_pkex = NULL;
2344 		}
2345 		return;
2346 	}
2347 
2348 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
2349 		   MACSTR, MAC2STR(src));
2350 
2351 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2352 		" freq=%u type=%d", MAC2STR(src), freq,
2353 		DPP_PA_PKEX_COMMIT_REVEAL_RESP);
2354 	hostapd_drv_send_action(hapd, freq, 0, src,
2355 				wpabuf_head(msg), wpabuf_len(msg));
2356 	wpabuf_free(msg);
2357 
2358 	hostapd_dpp_pkex_clear_code(hapd);
2359 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
2360 	if (!bi)
2361 		return;
2362 	hapd->dpp_pkex = NULL;
2363 }
2364 
2365 
2366 static void
hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2367 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
2368 				       const u8 *hdr, const u8 *buf, size_t len,
2369 				       unsigned int freq)
2370 {
2371 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2372 	int res;
2373 	struct dpp_bootstrap_info *bi;
2374 	struct dpp_pkex *pkex = hapd->dpp_pkex;
2375 	char cmd[500];
2376 
2377 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
2378 		   MAC2STR(src));
2379 
2380 	if (!pkex || !pkex->initiator || !pkex->exchange_done) {
2381 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2382 		return;
2383 	}
2384 
2385 	res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
2386 	if (res < 0) {
2387 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2388 		return;
2389 	}
2390 
2391 	hostapd_dpp_pkex_clear_code(hapd);
2392 	bi = dpp_pkex_finish(ifaces->dpp, pkex, src, freq);
2393 	if (!bi)
2394 		return;
2395 	hapd->dpp_pkex = NULL;
2396 
2397 #ifdef CONFIG_DPP3
2398 	if (ifaces->dpp_pb_bi &&
2399 	    os_memcmp(bi->pubkey_hash_chirp, ifaces->dpp_pb_resp_hash,
2400 		      SHA256_MAC_LEN) != 0) {
2401 		char id[20];
2402 
2403 		wpa_printf(MSG_INFO,
2404 			   "DPP: Peer bootstrap key from PKEX does not match PB announcement hash");
2405 		wpa_hexdump(MSG_DEBUG,
2406 			    "DPP: Peer provided bootstrap key hash(chirp) from PB PKEX",
2407 			    bi->pubkey_hash_chirp, SHA256_MAC_LEN);
2408 		wpa_hexdump(MSG_DEBUG,
2409 			    "DPP: Peer provided bootstrap key hash(chirp) from PB announcement",
2410 			    ifaces->dpp_pb_resp_hash, SHA256_MAC_LEN);
2411 
2412 		os_snprintf(id, sizeof(id), "%u", bi->id);
2413 		dpp_bootstrap_remove(ifaces->dpp, id);
2414 		hostapd_dpp_push_button_stop(hapd);
2415 		return;
2416 	}
2417 #endif /* CONFIG_DPP3 */
2418 
2419 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
2420 		    bi->id,
2421 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
2422 	wpa_printf(MSG_DEBUG,
2423 		   "DPP: Start authentication after PKEX with parameters: %s",
2424 		   cmd);
2425 	if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
2426 		wpa_printf(MSG_DEBUG,
2427 			   "DPP: Authentication initialization failed");
2428 		return;
2429 	}
2430 }
2431 
2432 
2433 #ifdef CONFIG_DPP3
2434 
hostapd_dpp_pb_pkex_init(struct hostapd_data * hapd,unsigned int freq,const u8 * src,const u8 * r_hash)2435 static void hostapd_dpp_pb_pkex_init(struct hostapd_data *hapd,
2436 				     unsigned int freq, const u8 *src,
2437 				     const u8 *r_hash)
2438 {
2439 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2440 	struct dpp_pkex *pkex;
2441 	struct wpabuf *msg;
2442 	char ssid_hex[2 * SSID_MAX_LEN + 1], *pass_hex = NULL;
2443 	char cmd[300];
2444 	const char *password = NULL;
2445 #ifdef CONFIG_SAE
2446 	struct sae_password_entry *e;
2447 #endif /* CONFIG_SAE */
2448 	int conf_id = -1;
2449 	bool sae = false, psk = false;
2450 	size_t len;
2451 
2452 	if (hapd->dpp_pkex) {
2453 		wpa_printf(MSG_DEBUG,
2454 			   "PDP: Sending previously generated PKEX Exchange Request to "
2455 			   MACSTR, MAC2STR(src));
2456 		msg = hapd->dpp_pkex->exchange_req;
2457 		hostapd_drv_send_action(hapd, freq, 0, src,
2458 					wpabuf_head(msg), wpabuf_len(msg));
2459 		return;
2460 	}
2461 
2462 	wpa_printf(MSG_DEBUG, "DPP: Initiate PKEX for push button with "
2463 		   MACSTR, MAC2STR(src));
2464 
2465 	hapd->dpp_pkex_bi = ifaces->dpp_pb_bi;
2466 	os_memcpy(ifaces->dpp_pb_resp_hash, r_hash, SHA256_MAC_LEN);
2467 
2468 	pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
2469 			     "PBPKEX", (const char *) ifaces->dpp_pb_c_nonce,
2470 			     ifaces->dpp_pb_bi->curve->nonce_len,
2471 			     true);
2472 	if (!pkex) {
2473 		hostapd_dpp_push_button_stop(hapd);
2474 		return;
2475 	}
2476 	pkex->freq = freq;
2477 
2478 	hapd->dpp_pkex = pkex;
2479 	msg = hapd->dpp_pkex->exchange_req;
2480 
2481 	if (ifaces->dpp_pb_cmd) {
2482 		/* Use the externally provided configuration */
2483 		os_free(hapd->dpp_pkex_auth_cmd);
2484 		len = 30 + os_strlen(ifaces->dpp_pb_cmd);
2485 		hapd->dpp_pkex_auth_cmd = os_malloc(len);
2486 		if (!hapd->dpp_pkex_auth_cmd) {
2487 			hostapd_dpp_push_button_stop(hapd);
2488 			return;
2489 		}
2490 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2491 			    hapd->dpp_pkex_bi->id, ifaces->dpp_pb_cmd);
2492 		goto send_frame;
2493 	}
2494 
2495 	/* Build config based on the current AP configuration */
2496 	wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
2497 			 (const u8 *) hapd->conf->ssid.ssid,
2498 			 hapd->conf->ssid.ssid_len);
2499 
2500 	if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
2501 		/* TODO: If a local Configurator has been enabled, allow a
2502 		 * DPP AKM credential to be provisioned by setting conf_id. */
2503 	}
2504 
2505 	if (hapd->conf->wpa & WPA_PROTO_RSN) {
2506 		psk = hapd->conf->wpa_key_mgmt & (WPA_KEY_MGMT_PSK |
2507 						  WPA_KEY_MGMT_PSK_SHA256);
2508 #ifdef CONFIG_SAE
2509 		sae = hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE;
2510 #endif /* CONFIG_SAE */
2511 	}
2512 
2513 #ifdef CONFIG_SAE
2514 	for (e = hapd->conf->sae_passwords; sae && e && !password;
2515 	     e = e->next) {
2516 		if (e->identifier || !is_broadcast_ether_addr(e->peer_addr))
2517 			continue;
2518 		password = e->password;
2519 	}
2520 #endif /* CONFIG_SAE */
2521 	if (!password && hapd->conf->ssid.wpa_passphrase_set &&
2522 	    hapd->conf->ssid.wpa_passphrase)
2523 		password = hapd->conf->ssid.wpa_passphrase;
2524 	if (password) {
2525 		len = 2 * os_strlen(password) + 1;
2526 		pass_hex = os_malloc(len);
2527 		if (!pass_hex) {
2528 			hostapd_dpp_push_button_stop(hapd);
2529 			return;
2530 		}
2531 		wpa_snprintf_hex(pass_hex, len, (const u8 *) password,
2532 				 os_strlen(password));
2533 	}
2534 
2535 	if (conf_id > 0 && sae && psk && pass_hex) {
2536 		os_snprintf(cmd, sizeof(cmd),
2537 			    "conf=sta-dpp+psk+sae configurator=%d ssid=%s pass=%s",
2538 			    conf_id, ssid_hex, pass_hex);
2539 	} else if (conf_id > 0 && sae && pass_hex) {
2540 		os_snprintf(cmd, sizeof(cmd),
2541 			    "conf=sta-dpp+sae configurator=%d ssid=%s pass=%s",
2542 			    conf_id, ssid_hex, pass_hex);
2543 	} else if (conf_id > 0) {
2544 		os_snprintf(cmd, sizeof(cmd),
2545 			    "conf=sta-dpp configurator=%d ssid=%s",
2546 			    conf_id, ssid_hex);
2547 	} if (sae && psk && pass_hex) {
2548 		os_snprintf(cmd, sizeof(cmd),
2549 			    "conf=sta-psk+sae ssid=%s pass=%s",
2550 			    ssid_hex, pass_hex);
2551 	} else if (sae && pass_hex) {
2552 		os_snprintf(cmd, sizeof(cmd),
2553 			    "conf=sta-sae ssid=%s pass=%s",
2554 			    ssid_hex, pass_hex);
2555 	} else if (psk && pass_hex) {
2556 		os_snprintf(cmd, sizeof(cmd),
2557 			    "conf=sta-psk ssid=%s pass=%s",
2558 			    ssid_hex, pass_hex);
2559 	} else {
2560 		wpa_printf(MSG_INFO,
2561 			   "DPP: Unsupported AP configuration for push button");
2562 		str_clear_free(pass_hex);
2563 		hostapd_dpp_push_button_stop(hapd);
2564 		return;
2565 	}
2566 	str_clear_free(pass_hex);
2567 
2568 	os_free(hapd->dpp_pkex_auth_cmd);
2569 	len = 30 + os_strlen(cmd);
2570 	hapd->dpp_pkex_auth_cmd = os_malloc(len);
2571 	if (hapd->dpp_pkex_auth_cmd)
2572 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2573 			    hapd->dpp_pkex_bi->id, cmd);
2574 	forced_memzero(cmd, sizeof(cmd));
2575 	if (!hapd->dpp_pkex_auth_cmd) {
2576 		hostapd_dpp_push_button_stop(hapd);
2577 		return;
2578 	}
2579 
2580 send_frame:
2581 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2582 		" freq=%u type=%d", MAC2STR(src), freq,
2583 		DPP_PA_PKEX_EXCHANGE_REQ);
2584 	hostapd_drv_send_action(hapd, pkex->freq, 0, src,
2585 				wpabuf_head(msg), wpabuf_len(msg));
2586 	pkex->exch_req_wait_time = 2000;
2587 	pkex->exch_req_tries = 1;
2588 }
2589 
2590 
2591 static void
hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2592 hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data *hapd,
2593 					const u8 *src, const u8 *hdr,
2594 					const u8 *buf, size_t len,
2595 					unsigned int freq)
2596 {
2597 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2598 	const u8 *r_hash;
2599 	u16 r_hash_len;
2600 	unsigned int i;
2601 	bool found = false;
2602 	struct dpp_pb_info *info, *tmp;
2603 	struct os_reltime now, age;
2604 	struct wpabuf *msg;
2605 
2606 	if (!ifaces)
2607 		return;
2608 
2609 	os_get_reltime(&now);
2610 	wpa_printf(MSG_DEBUG, "DPP: Push Button Presence Announcement from "
2611 		   MACSTR, MAC2STR(src));
2612 
2613 	r_hash = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
2614 			      &r_hash_len);
2615 	if (!r_hash || r_hash_len != SHA256_MAC_LEN) {
2616 		wpa_printf(MSG_DEBUG,
2617 			   "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
2618 		return;
2619 	}
2620 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
2621 		    r_hash, r_hash_len);
2622 
2623 	for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2624 		info = &ifaces->dpp_pb[i];
2625 		if ((info->rx_time.sec == 0 && info->rx_time.usec == 0) ||
2626 		    os_memcmp(r_hash, info->hash, SHA256_MAC_LEN) != 0)
2627 			continue;
2628 		wpa_printf(MSG_DEBUG,
2629 			   "DPP: Active push button Enrollee already known");
2630 		found = true;
2631 		info->rx_time = now;
2632 	}
2633 
2634 	if (!found) {
2635 		for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2636 			tmp = &ifaces->dpp_pb[i];
2637 			if (tmp->rx_time.sec == 0 && tmp->rx_time.usec == 0)
2638 				continue;
2639 
2640 			if (os_reltime_expired(&now, &tmp->rx_time, 120)) {
2641 				wpa_hexdump(MSG_DEBUG,
2642 					    "DPP: Push button Enrollee hash expired",
2643 					    tmp->hash, SHA256_MAC_LEN);
2644 				tmp->rx_time.sec = 0;
2645 				tmp->rx_time.usec = 0;
2646 				continue;
2647 			}
2648 
2649 			wpa_hexdump(MSG_DEBUG,
2650 				    "DPP: Push button session overlap with hash",
2651 				    tmp->hash, SHA256_MAC_LEN);
2652 			if (!ifaces->dpp_pb_result_indicated &&
2653 			    hostapd_dpp_pb_active(hapd)) {
2654 				wpa_msg(hapd->msg_ctx, MSG_INFO,
2655 					DPP_EVENT_PB_RESULT "session-overlap");
2656 				ifaces->dpp_pb_result_indicated = true;
2657 			}
2658 			hostapd_dpp_push_button_stop(hapd);
2659 			return;
2660 		}
2661 
2662 		/* Replace the oldest entry */
2663 		info = &ifaces->dpp_pb[0];
2664 		for (i = 1; i < DPP_PB_INFO_COUNT; i++) {
2665 			tmp = &ifaces->dpp_pb[i];
2666 			if (os_reltime_before(&tmp->rx_time, &info->rx_time))
2667 				info = tmp;
2668 		}
2669 		wpa_printf(MSG_DEBUG, "DPP: New active push button Enrollee");
2670 		os_memcpy(info->hash, r_hash, SHA256_MAC_LEN);
2671 		info->rx_time = now;
2672 	}
2673 
2674 	if (!hostapd_dpp_pb_active(hapd)) {
2675 		wpa_printf(MSG_DEBUG,
2676 			   "DPP: Discard message since own push button has not been pressed");
2677 		return;
2678 	}
2679 
2680 	if (ifaces->dpp_pb_announce_time.sec == 0 &&
2681 	    ifaces->dpp_pb_announce_time.usec == 0) {
2682 		/* Start a wait before allowing PKEX to be initiated */
2683 		ifaces->dpp_pb_announce_time = now;
2684 	}
2685 
2686 	if (!ifaces->dpp_pb_bi) {
2687 		int res;
2688 
2689 		res = dpp_bootstrap_gen(ifaces->dpp, "type=pkex");
2690 		if (res < 0)
2691 			return;
2692 		ifaces->dpp_pb_bi = dpp_bootstrap_get_id(ifaces->dpp, res);
2693 		if (!ifaces->dpp_pb_bi)
2694 			return;
2695 
2696 		if (random_get_bytes(ifaces->dpp_pb_c_nonce,
2697 				     ifaces->dpp_pb_bi->curve->nonce_len)) {
2698 			wpa_printf(MSG_ERROR,
2699 				   "DPP: Failed to generate C-nonce");
2700 			hostapd_dpp_push_button_stop(hapd);
2701 			return;
2702 		}
2703 	}
2704 
2705 	/* Skip the response if one was sent within last 50 ms since the
2706 	 * Enrollee is going to send out at least three announcement messages.
2707 	 */
2708 	os_reltime_sub(&now, &ifaces->dpp_pb_last_resp, &age);
2709 	if (age.sec == 0 && age.usec < 50000) {
2710 		wpa_printf(MSG_DEBUG,
2711 			   "DPP: Skip Push Button Presence Announcement Response frame immediately after having sent one");
2712 		return;
2713 	}
2714 
2715 	msg = dpp_build_pb_announcement_resp(
2716 		ifaces->dpp_pb_bi, r_hash, ifaces->dpp_pb_c_nonce,
2717 		ifaces->dpp_pb_bi->curve->nonce_len);
2718 	if (!msg) {
2719 		hostapd_dpp_push_button_stop(hapd);
2720 		return;
2721 	}
2722 
2723 	wpa_printf(MSG_DEBUG,
2724 		   "DPP: Send Push Button Presence Announcement Response to "
2725 		   MACSTR, MAC2STR(src));
2726 	ifaces->dpp_pb_last_resp = now;
2727 
2728 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2729 		" freq=%u type=%d", MAC2STR(src), freq,
2730 		DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP);
2731 	hostapd_drv_send_action(hapd, freq, 0, src,
2732 				wpabuf_head(msg), wpabuf_len(msg));
2733 	wpabuf_free(msg);
2734 
2735 	if (os_reltime_expired(&now, &ifaces->dpp_pb_announce_time, 15))
2736 		hostapd_dpp_pb_pkex_init(hapd, freq, src, r_hash);
2737 }
2738 
2739 
2740 static void
hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2741 hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data *hapd, const u8 *src,
2742 				     const u8 *hdr, const u8 *buf, size_t len,
2743 				     unsigned int freq)
2744 {
2745 	const u8 *trans_id, *version;
2746 	u16 trans_id_len, version_len;
2747 	struct wpabuf *msg;
2748 	u8 ver = DPP_VERSION;
2749 	int conn_ver;
2750 
2751 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Query from "
2752 		   MACSTR, MAC2STR(src));
2753 
2754 	if (!hapd_dpp_connector_available(hapd))
2755 		return;
2756 
2757 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2758 			       &trans_id_len);
2759 	if (!trans_id || trans_id_len != 1) {
2760 		wpa_printf(MSG_DEBUG,
2761 			   "DPP: Peer did not include Transaction ID");
2762 		return;
2763 	}
2764 
2765 	version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2766 			       &version_len);
2767 	if (!version || version_len != 1) {
2768 		wpa_printf(MSG_DEBUG,
2769 			   "DPP: Peer did not include Protocol Version");
2770 		return;
2771 	}
2772 
2773 	wpa_printf(MSG_DEBUG, "DPP: Transaction ID %u, Version %u",
2774 		   trans_id[0], version[0]);
2775 
2776 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
2777 	msg = dpp_alloc_msg(DPP_PA_PRIV_PEER_INTRO_NOTIFY, len);
2778 	if (!msg)
2779 		return;
2780 
2781 	/* Transaction ID */
2782 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
2783 	wpabuf_put_le16(msg, 1);
2784 	wpabuf_put_u8(msg, trans_id[0]);
2785 
2786 	/* Protocol Version */
2787 	conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
2788 	if (conn_ver > 0 && ver != conn_ver) {
2789 		wpa_printf(MSG_DEBUG,
2790 			   "DPP: Use Connector version %d instead of current protocol version %d",
2791 			   conn_ver, ver);
2792 		ver = conn_ver;
2793 	}
2794 	wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2795 	wpabuf_put_le16(msg, 1);
2796 	wpabuf_put_u8(msg, ver);
2797 
2798 	/* DPP Connector */
2799 	wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
2800 	wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
2801 	wpabuf_put_str(msg, hapd->conf->dpp_connector);
2802 
2803 	wpa_printf(MSG_DEBUG, "DPP: Send Private Peer Introduction Notify to "
2804 		   MACSTR, MAC2STR(src));
2805 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2806 		" freq=%u type=%d", MAC2STR(src), freq,
2807 		DPP_PA_PRIV_PEER_INTRO_NOTIFY);
2808 	hostapd_drv_send_action(hapd, freq, 0, src,
2809 				wpabuf_head(msg), wpabuf_len(msg));
2810 	wpabuf_free(msg);
2811 }
2812 
2813 
2814 static void
hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2815 hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data *hapd, const u8 *src,
2816 				      const u8 *hdr, const u8 *buf, size_t len,
2817 				      unsigned int freq)
2818 {
2819 	struct crypto_ec_key *own_key;
2820 	const struct dpp_curve_params *curve;
2821 	enum hpke_kem_id kem_id;
2822 	enum hpke_kdf_id kdf_id;
2823 	enum hpke_aead_id aead_id;
2824 	const u8 *aad = hdr;
2825 	size_t aad_len = DPP_HDR_LEN;
2826 	struct wpabuf *pt;
2827 	const u8 *trans_id, *wrapped, *version, *connector;
2828 	u16 trans_id_len, wrapped_len, version_len, connector_len;
2829 	struct os_time now;
2830 	struct dpp_introduction intro;
2831 	os_time_t expire;
2832 	int expiration;
2833 	enum dpp_status_error res;
2834 	u8 pkhash[SHA256_MAC_LEN];
2835 
2836 	os_memset(&intro, 0, sizeof(intro));
2837 
2838 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Update from "
2839 		   MACSTR, MAC2STR(src));
2840 
2841 	if (!hapd_dpp_connector_available(hapd))
2842 		return;
2843 
2844 	os_get_time(&now);
2845 
2846 	if (hapd->conf->dpp_netaccesskey_expiry &&
2847 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2848 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2849 		return;
2850 	}
2851 
2852 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2853 			       &trans_id_len);
2854 	if (!trans_id || trans_id_len != 1) {
2855 		wpa_printf(MSG_DEBUG,
2856 			   "DPP: Peer did not include Transaction ID");
2857 		return;
2858 	}
2859 
2860 	wrapped = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
2861 			       &wrapped_len);
2862 	if (!wrapped) {
2863 		wpa_printf(MSG_DEBUG, "DPP: Peer did not include Wrapped Data");
2864 		return;
2865 	}
2866 
2867 	own_key = dpp_set_keypair(&curve,
2868 				  wpabuf_head(hapd->conf->dpp_netaccesskey),
2869 				  wpabuf_len(hapd->conf->dpp_netaccesskey));
2870 	if (!own_key) {
2871 		wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
2872 		return;
2873 	}
2874 
2875 	if (dpp_hpke_suite(curve->ike_group, &kem_id, &kdf_id, &aead_id) < 0) {
2876 		wpa_printf(MSG_ERROR, "DPP: Unsupported curve %d",
2877 			   curve->ike_group);
2878 		crypto_ec_key_deinit(own_key);
2879 		return;
2880 	}
2881 
2882 	pt = hpke_base_open(kem_id, kdf_id, aead_id, own_key, NULL, 0,
2883 			    aad, aad_len, wrapped, wrapped_len);
2884 	crypto_ec_key_deinit(own_key);
2885 	if (!pt) {
2886 		wpa_printf(MSG_INFO, "DPP: Failed to decrypt Connector");
2887 		return;
2888 	}
2889 	wpa_hexdump_buf(MSG_MSGDUMP, "DPP: HPKE-Decrypted Wrapped Data", pt);
2890 
2891 	connector = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2892 				 DPP_ATTR_CONNECTOR, &connector_len);
2893 	if (!connector) {
2894 		wpa_printf(MSG_DEBUG,
2895 			   "DPP: Peer did not include its Connector");
2896 		goto done;
2897 	}
2898 
2899 	version = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2900 			       DPP_ATTR_PROTOCOL_VERSION, &version_len);
2901 	if (!version || version_len < 1) {
2902 		wpa_printf(MSG_DEBUG,
2903 			   "DPP: Peer did not include Protocol Version");
2904 		goto done;
2905 	}
2906 
2907 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2908 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
2909 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
2910 			     wpabuf_head(hapd->conf->dpp_csign),
2911 			     wpabuf_len(hapd->conf->dpp_csign),
2912 			     connector, connector_len, &expire, pkhash);
2913 	if (res == 255) {
2914 		wpa_printf(MSG_INFO,
2915 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
2916 			   MACSTR ")", MAC2STR(src));
2917 		goto done;
2918 	}
2919 	if (res != DPP_STATUS_OK) {
2920 		wpa_printf(MSG_INFO,
2921 			   "DPP: Network Introduction protocol resulted in failure (peer "
2922 			   MACSTR " status %d)", MAC2STR(src), res);
2923 		goto done;
2924 	}
2925 
2926 	if (intro.peer_version && intro.peer_version >= 2) {
2927 		u8 attr_version = 1;
2928 
2929 		if (version && version_len >= 1)
2930 			attr_version = version[0];
2931 		if (attr_version != intro.peer_version) {
2932 			wpa_printf(MSG_INFO,
2933 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2934 				   intro.peer_version, attr_version);
2935 			goto done;
2936 		}
2937 	}
2938 
2939 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2940 		expire = hapd->conf->dpp_netaccesskey_expiry;
2941 	if (expire)
2942 		expiration = expire - now.sec;
2943 	else
2944 		expiration = 0;
2945 
2946 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2947 				intro.pmkid, expiration,
2948 				WPA_KEY_MGMT_DPP, pkhash, false) < 0) {
2949 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2950 		goto done;
2951 	}
2952 
2953 #ifdef CONFIG_IEEE80211BE
2954 	if (hapd->conf->mld_ap &&
2955 	    wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2956 				intro.pmkid, expiration,
2957 				WPA_KEY_MGMT_DPP, pkhash, true) < 0) {
2958 		wpa_printf(MSG_ERROR,
2959 			   "DPP: Failed to add PMKSA cache entry (MLD)");
2960 		goto done;
2961 	}
2962 #endif /* CONFIG_IEEE80211BE */
2963 
2964 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction completed with "
2965 		   MACSTR, MAC2STR(src));
2966 
2967 done:
2968 	dpp_peer_intro_deinit(&intro);
2969 	wpabuf_free(pt);
2970 }
2971 
2972 #endif /* CONFIG_DPP3 */
2973 
2974 
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2975 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
2976 			   const u8 *buf, size_t len, unsigned int freq)
2977 {
2978 	u8 crypto_suite;
2979 	enum dpp_public_action_frame_type type;
2980 	const u8 *hdr;
2981 	unsigned int pkex_t;
2982 
2983 	/* Discard DPP Action frames if there is no global DPP context */
2984 	if (!hapd->iface->interfaces || !hapd->iface->interfaces->dpp)
2985 		return;
2986 
2987 	if (len < DPP_HDR_LEN)
2988 		return;
2989 	if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
2990 		return;
2991 	hdr = buf;
2992 	buf += 4;
2993 	len -= 4;
2994 	crypto_suite = *buf++;
2995 	type = *buf++;
2996 	len -= 2;
2997 
2998 	wpa_printf(MSG_DEBUG,
2999 		   "DPP: Received DPP Public Action frame crypto suite %u type %d from "
3000 		   MACSTR " freq=%u",
3001 		   crypto_suite, type, MAC2STR(src), freq);
3002 	if (crypto_suite != 1) {
3003 		wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
3004 			   crypto_suite);
3005 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
3006 			" freq=%u type=%d ignore=unsupported-crypto-suite",
3007 			MAC2STR(src), freq, type);
3008 		return;
3009 	}
3010 	wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
3011 	if (dpp_check_attrs(buf, len) < 0) {
3012 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
3013 			" freq=%u type=%d ignore=invalid-attributes",
3014 			MAC2STR(src), freq, type);
3015 		return;
3016 	}
3017 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
3018 		" freq=%u type=%d", MAC2STR(src), freq, type);
3019 
3020 #ifdef CONFIG_DPP2
3021 	if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
3022 				src, hdr, buf, len, freq, NULL, NULL,
3023 				hapd) == 0)
3024 		return;
3025 #endif /* CONFIG_DPP2 */
3026 
3027 	switch (type) {
3028 	case DPP_PA_AUTHENTICATION_REQ:
3029 		hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
3030 		break;
3031 	case DPP_PA_AUTHENTICATION_RESP:
3032 		hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
3033 		break;
3034 	case DPP_PA_AUTHENTICATION_CONF:
3035 		hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
3036 		break;
3037 	case DPP_PA_PEER_DISCOVERY_REQ:
3038 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
3039 		break;
3040 #ifdef CONFIG_DPP3
3041 	case DPP_PA_PKEX_EXCHANGE_REQ:
3042 		/* This is for PKEXv2, but for now, process only with
3043 		 * CONFIG_DPP3 to avoid issues with a capability that has not
3044 		 * been tested with other implementations. */
3045 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3046 						 true);
3047 		break;
3048 #endif /* CONFIG_DPP3 */
3049 	case DPP_PA_PKEX_V1_EXCHANGE_REQ:
3050 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3051 						 false);
3052 		break;
3053 	case DPP_PA_PKEX_EXCHANGE_RESP:
3054 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
3055 		break;
3056 	case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
3057 		hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
3058 						      freq);
3059 		break;
3060 	case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
3061 		hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
3062 						       freq);
3063 		break;
3064 #ifdef CONFIG_DPP2
3065 	case DPP_PA_CONFIGURATION_RESULT:
3066 		hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
3067 		break;
3068 	case DPP_PA_CONNECTION_STATUS_RESULT:
3069 		hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
3070 		break;
3071 	case DPP_PA_PRESENCE_ANNOUNCEMENT:
3072 		hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
3073 						     freq);
3074 		break;
3075 	case DPP_PA_RECONFIG_ANNOUNCEMENT:
3076 		hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
3077 						     freq);
3078 		break;
3079 	case DPP_PA_RECONFIG_AUTH_RESP:
3080 		hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
3081 						  freq);
3082 		break;
3083 #endif /* CONFIG_DPP2 */
3084 #ifdef CONFIG_DPP3
3085 	case DPP_PA_PB_PRESENCE_ANNOUNCEMENT:
3086 		hostapd_dpp_rx_pb_presence_announcement(hapd, src, hdr,
3087 							buf, len, freq);
3088 		break;
3089 	case DPP_PA_PRIV_PEER_INTRO_QUERY:
3090 		hostapd_dpp_rx_priv_peer_intro_query(hapd, src, hdr,
3091 						     buf, len, freq);
3092 		break;
3093 	case DPP_PA_PRIV_PEER_INTRO_UPDATE:
3094 		hostapd_dpp_rx_priv_peer_intro_update(hapd, src, hdr,
3095 						      buf, len, freq);
3096 		break;
3097 #endif /* CONFIG_DPP3 */
3098 	default:
3099 		wpa_printf(MSG_DEBUG,
3100 			   "DPP: Ignored unsupported frame subtype %d", type);
3101 		break;
3102 	}
3103 
3104 	if (hapd->dpp_pkex)
3105 		pkex_t = hapd->dpp_pkex->t;
3106 	else if (hapd->dpp_pkex_bi)
3107 		pkex_t = hapd->dpp_pkex_bi->pkex_t;
3108 	else
3109 		pkex_t = 0;
3110 	if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
3111 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
3112 		hostapd_dpp_pkex_remove(hapd, "*");
3113 	}
3114 }
3115 
3116 
3117 struct wpabuf *
hostapd_dpp_gas_req_handler(struct hostapd_data * hapd,const u8 * sa,const u8 * query,size_t query_len,const u8 * data,size_t data_len)3118 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
3119 			    const u8 *query, size_t query_len,
3120 			    const u8 *data, size_t data_len)
3121 {
3122 	struct dpp_authentication *auth = hapd->dpp_auth;
3123 	struct wpabuf *resp;
3124 
3125 	wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
3126 	eloop_cancel_timeout(hostapd_gas_req_wait, hapd, NULL);
3127 	if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
3128 	    !ether_addr_equal(sa, auth->peer_mac_addr)) {
3129 #ifdef CONFIG_DPP2
3130 		if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
3131 				     data_len) == 0) {
3132 			/* Response will be forwarded once received over TCP */
3133 			return NULL;
3134 		}
3135 #endif /* CONFIG_DPP2 */
3136 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
3137 		return NULL;
3138 	}
3139 
3140 	if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
3141 		wpa_printf(MSG_DEBUG,
3142 			   "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
3143 		/* hostapd_dpp_auth_success() would normally have been called
3144 		 * from TX status handler, but since there was no such handler
3145 		 * call yet, simply send out the event message and proceed with
3146 		 * exchange. */
3147 		dpp_notify_auth_success(hapd->dpp_auth, 1);
3148 		hapd->dpp_auth_ok_on_ack = 0;
3149 #ifdef CONFIG_TESTING_OPTIONS
3150 		if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
3151 			wpa_printf(MSG_INFO,
3152 				   "DPP: TESTING - stop at Authentication Confirm");
3153 			return NULL;
3154 		}
3155 #endif /* CONFIG_TESTING_OPTIONS */
3156 	}
3157 
3158 	wpa_hexdump(MSG_DEBUG,
3159 		    "DPP: Received Configuration Request (GAS Query Request)",
3160 		    query, query_len);
3161 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
3162 		MAC2STR(sa));
3163 	resp = dpp_conf_req_rx(auth, query, query_len);
3164 	if (!resp)
3165 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3166 	return resp;
3167 }
3168 
3169 
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)3170 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
3171 {
3172 	struct dpp_authentication *auth = hapd->dpp_auth;
3173 #ifdef CONFIG_DPP3
3174 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3175 #endif /* CONFIG_DPP3 */
3176 
3177 	if (!auth)
3178 		return;
3179 
3180 #ifdef CONFIG_DPP3
3181 	if (auth->waiting_new_key && ok) {
3182 		wpa_printf(MSG_DEBUG, "DPP: Waiting for a new key");
3183 		return;
3184 	}
3185 #endif /* CONFIG_DPP3 */
3186 
3187 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
3188 		   ok);
3189 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3190 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3191 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3192 #ifdef CONFIG_DPP2
3193 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3194 				     hapd, NULL);
3195 	if (ok && auth->peer_version >= 2 &&
3196 	    auth->conf_resp_status == DPP_STATUS_OK) {
3197 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
3198 		auth->waiting_conf_result = 1;
3199 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
3200 				     hapd, NULL);
3201 		eloop_register_timeout(2, 0,
3202 				       hostapd_dpp_config_result_wait_timeout,
3203 				       hapd, NULL);
3204 		return;
3205 	}
3206 #endif /* CONFIG_DPP2 */
3207 	hostapd_drv_send_action_cancel_wait(hapd);
3208 
3209 	if (ok)
3210 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
3211 			"conf_status=%d", auth->conf_resp_status);
3212 	else
3213 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3214 	dpp_auth_deinit(hapd->dpp_auth);
3215 	hapd->dpp_auth = NULL;
3216 #ifdef CONFIG_DPP3
3217 	if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
3218 		if (ok)
3219 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3220 				"success");
3221 		else
3222 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3223 				"could-not-connect");
3224 		ifaces->dpp_pb_result_indicated = true;
3225 		if (ok)
3226 			hostapd_dpp_remove_pb_hash(hapd);
3227 		hostapd_dpp_push_button_stop(hapd);
3228 	}
3229 #endif /* CONFIG_DPP3 */
3230 }
3231 
3232 
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)3233 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
3234 {
3235 	struct dpp_authentication *auth;
3236 	int ret = -1;
3237 	char *curve = NULL;
3238 
3239 	auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
3240 	if (!auth)
3241 		return -1;
3242 
3243 	curve = get_param(cmd, " curve=");
3244 	hostapd_dpp_set_testing_options(hapd, auth);
3245 	if (dpp_set_configurator(auth, cmd) == 0 &&
3246 	    dpp_configurator_own_config(auth, curve, 1) == 0) {
3247 		hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
3248 		ret = 0;
3249 	}
3250 
3251 	dpp_auth_deinit(auth);
3252 	os_free(curve);
3253 
3254 	return ret;
3255 }
3256 
3257 
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)3258 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
3259 {
3260 	struct dpp_bootstrap_info *own_bi;
3261 	const char *pos, *end;
3262 #ifdef CONFIG_DPP3
3263 		enum dpp_pkex_ver ver = PKEX_VER_AUTO;
3264 #else /* CONFIG_DPP3 */
3265 		enum dpp_pkex_ver ver = PKEX_VER_ONLY_1;
3266 #endif /* CONFIG_DPP3 */
3267 	int tcp_port = DPP_TCP_PORT;
3268 	struct hostapd_ip_addr *ipaddr = NULL;
3269 #ifdef CONFIG_DPP2
3270 	struct hostapd_ip_addr ipaddr_buf;
3271 	char *addr;
3272 
3273 	pos = os_strstr(cmd, " tcp_port=");
3274 	if (pos) {
3275 		pos += 10;
3276 		tcp_port = atoi(pos);
3277 	}
3278 
3279 	addr = get_param(cmd, " tcp_addr=");
3280 	if (addr) {
3281 		int res;
3282 
3283 		res = hostapd_parse_ip_addr(addr, &ipaddr_buf);
3284 		os_free(addr);
3285 		if (res)
3286 			return -1;
3287 		ipaddr = &ipaddr_buf;
3288 	}
3289 #endif /* CONFIG_DPP2 */
3290 
3291 	pos = os_strstr(cmd, " own=");
3292 	if (!pos)
3293 		return -1;
3294 	pos += 5;
3295 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3296 	if (!own_bi) {
3297 		wpa_printf(MSG_DEBUG,
3298 			   "DPP: Identified bootstrap info not found");
3299 		return -1;
3300 	}
3301 	if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
3302 		wpa_printf(MSG_DEBUG,
3303 			   "DPP: Identified bootstrap info not for PKEX");
3304 		return -1;
3305 	}
3306 	hapd->dpp_pkex_bi = own_bi;
3307 	own_bi->pkex_t = 0; /* clear pending errors on new code */
3308 
3309 	os_free(hapd->dpp_pkex_identifier);
3310 	hapd->dpp_pkex_identifier = NULL;
3311 	pos = os_strstr(cmd, " identifier=");
3312 	if (pos) {
3313 		pos += 12;
3314 		end = os_strchr(pos, ' ');
3315 		if (!end)
3316 			return -1;
3317 		hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
3318 		if (!hapd->dpp_pkex_identifier)
3319 			return -1;
3320 		os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
3321 		hapd->dpp_pkex_identifier[end - pos] = '\0';
3322 	}
3323 
3324 	pos = os_strstr(cmd, " code=");
3325 	if (!pos)
3326 		return -1;
3327 	os_free(hapd->dpp_pkex_code);
3328 	hapd->dpp_pkex_code = os_strdup(pos + 6);
3329 	if (!hapd->dpp_pkex_code)
3330 		return -1;
3331 	hapd->dpp_pkex_code_len = os_strlen(hapd->dpp_pkex_code);
3332 
3333 	pos = os_strstr(cmd, " ver=");
3334 	if (pos) {
3335 		int v;
3336 
3337 		pos += 5;
3338 		v = atoi(pos);
3339 		if (v == 1)
3340 			ver = PKEX_VER_ONLY_1;
3341 		else if (v == 2)
3342 			ver = PKEX_VER_ONLY_2;
3343 		else
3344 			return -1;
3345 	}
3346 	hapd->dpp_pkex_ver = ver;
3347 
3348 	if (os_strstr(cmd, " init=1")) {
3349 		if (hostapd_dpp_pkex_init(hapd, ver, ipaddr, tcp_port) < 0)
3350 			return -1;
3351 	} else {
3352 #ifdef CONFIG_DPP2
3353 		dpp_controller_pkex_add(hapd->iface->interfaces->dpp, own_bi,
3354 					hapd->dpp_pkex_code,
3355 					hapd->dpp_pkex_identifier);
3356 #endif /* CONFIG_DPP2 */
3357 	}
3358 
3359 	/* TODO: Support multiple PKEX info entries */
3360 
3361 	os_free(hapd->dpp_pkex_auth_cmd);
3362 	hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
3363 
3364 	return 1;
3365 }
3366 
3367 
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)3368 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
3369 {
3370 	unsigned int id_val;
3371 
3372 	if (os_strcmp(id, "*") == 0) {
3373 		id_val = 0;
3374 	} else {
3375 		id_val = atoi(id);
3376 		if (id_val == 0)
3377 			return -1;
3378 	}
3379 
3380 	if ((id_val != 0 && id_val != 1))
3381 		return -1;
3382 
3383 	/* TODO: Support multiple PKEX entries */
3384 	os_free(hapd->dpp_pkex_code);
3385 	hapd->dpp_pkex_code = NULL;
3386 	os_free(hapd->dpp_pkex_identifier);
3387 	hapd->dpp_pkex_identifier = NULL;
3388 	os_free(hapd->dpp_pkex_auth_cmd);
3389 	hapd->dpp_pkex_auth_cmd = NULL;
3390 	hapd->dpp_pkex_bi = NULL;
3391 	/* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
3392 	dpp_pkex_free(hapd->dpp_pkex);
3393 	hapd->dpp_pkex = NULL;
3394 	return 0;
3395 }
3396 
3397 
hostapd_dpp_stop(struct hostapd_data * hapd)3398 void hostapd_dpp_stop(struct hostapd_data *hapd)
3399 {
3400 	dpp_auth_deinit(hapd->dpp_auth);
3401 	hapd->dpp_auth = NULL;
3402 	dpp_pkex_free(hapd->dpp_pkex);
3403 	hapd->dpp_pkex = NULL;
3404 #ifdef CONFIG_DPP3
3405 	hostapd_dpp_push_button_stop(hapd);
3406 #endif /* CONFIG_DPP3 */
3407 	eloop_cancel_timeout(hostapd_gas_req_wait, hapd, NULL);
3408 }
3409 
3410 
3411 #ifdef CONFIG_DPP2
3412 
hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)3413 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
3414 				 const u8 *msg, size_t len)
3415 {
3416 	struct hostapd_data *hapd = ctx;
3417 	u8 *buf;
3418 
3419 	if (freq == 0)
3420 		freq = hapd->iface->freq;
3421 
3422 	wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
3423 		   MAC2STR(addr), freq);
3424 	buf = os_malloc(2 + len);
3425 	if (!buf)
3426 		return;
3427 	buf[0] = WLAN_ACTION_PUBLIC;
3428 	buf[1] = WLAN_PA_VENDOR_SPECIFIC;
3429 	os_memcpy(buf + 2, msg, len);
3430 	hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
3431 	os_free(buf);
3432 }
3433 
3434 
hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)3435 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
3436 					  u8 dialog_token, int prot,
3437 					  struct wpabuf *buf)
3438 {
3439 	struct hostapd_data *hapd = ctx;
3440 
3441 	gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf, 0);
3442 }
3443 
3444 #endif /* CONFIG_DPP2 */
3445 
3446 
hostapd_dpp_add_controllers(struct hostapd_data * hapd)3447 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
3448 {
3449 #ifdef CONFIG_DPP2
3450 	struct dpp_controller_conf *ctrl;
3451 	struct dpp_relay_config config;
3452 
3453 	os_memset(&config, 0, sizeof(config));
3454 	config.msg_ctx = hapd->msg_ctx;
3455 	config.cb_ctx = hapd;
3456 	config.tx = hostapd_dpp_relay_tx;
3457 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3458 	for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
3459 		config.ipaddr = &ctrl->ipaddr;
3460 		config.pkhash = ctrl->pkhash;
3461 		if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
3462 					     &config) < 0)
3463 			return -1;
3464 	}
3465 
3466 	if (hapd->conf->dpp_relay_port)
3467 		dpp_relay_listen(hapd->iface->interfaces->dpp,
3468 				 hapd->conf->dpp_relay_port,
3469 				 &config);
3470 #endif /* CONFIG_DPP2 */
3471 
3472 	return 0;
3473 }
3474 
3475 
3476 #ifdef CONFIG_DPP2
3477 
hostapd_dpp_add_controller(struct hostapd_data * hapd,const char * cmd)3478 int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd)
3479 {
3480 	struct dpp_relay_config config;
3481 	struct hostapd_ip_addr addr;
3482 	u8 pkhash[SHA256_MAC_LEN];
3483 	char *pos, *tmp;
3484 	int ret = -1;
3485 	bool prev_state, new_state;
3486 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3487 
3488 	tmp = os_strdup(cmd);
3489 	if (!tmp)
3490 		goto fail;
3491 	pos = os_strchr(tmp, ' ');
3492 	if (!pos)
3493 		goto fail;
3494 	*pos++ = '\0';
3495 	if (hostapd_parse_ip_addr(tmp, &addr) < 0 ||
3496 	    hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0)
3497 		goto fail;
3498 
3499 	os_memset(&config, 0, sizeof(config));
3500 	config.msg_ctx = hapd->msg_ctx;
3501 	config.cb_ctx = hapd;
3502 	config.tx = hostapd_dpp_relay_tx;
3503 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3504 	config.ipaddr = &addr;
3505 	config.pkhash = pkhash;
3506 	prev_state = dpp_relay_controller_available(dpp);
3507 	ret = dpp_relay_add_controller(dpp, &config);
3508 	new_state = dpp_relay_controller_available(dpp);
3509 	if (new_state != prev_state)
3510 		ieee802_11_update_beacons(hapd->iface);
3511 fail:
3512 	os_free(tmp);
3513 	return ret;
3514 }
3515 
3516 
hostapd_dpp_remove_controller(struct hostapd_data * hapd,const char * cmd)3517 void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd)
3518 {
3519 	struct hostapd_ip_addr addr;
3520 	bool prev_state, new_state;
3521 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3522 
3523 	if (hostapd_parse_ip_addr(cmd, &addr) < 0)
3524 		return;
3525 	prev_state = dpp_relay_controller_available(dpp);
3526 	dpp_relay_remove_controller(dpp, &addr);
3527 	new_state = dpp_relay_controller_available(dpp);
3528 	if (new_state != prev_state)
3529 		ieee802_11_update_beacons(hapd->iface);
3530 }
3531 
3532 #endif /* CONFIG_DPP2 */
3533 
3534 
hostapd_dpp_init(struct hostapd_data * hapd)3535 int hostapd_dpp_init(struct hostapd_data *hapd)
3536 {
3537 	hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
3538 	hapd->dpp_init_done = 1;
3539 	return hostapd_dpp_add_controllers(hapd);
3540 }
3541 
3542 
hostapd_dpp_deinit(struct hostapd_data * hapd)3543 void hostapd_dpp_deinit(struct hostapd_data *hapd)
3544 {
3545 #ifdef CONFIG_TESTING_OPTIONS
3546 	os_free(hapd->dpp_config_obj_override);
3547 	hapd->dpp_config_obj_override = NULL;
3548 	os_free(hapd->dpp_discovery_override);
3549 	hapd->dpp_discovery_override = NULL;
3550 	os_free(hapd->dpp_groups_override);
3551 	hapd->dpp_groups_override = NULL;
3552 	hapd->dpp_ignore_netaccesskey_mismatch = 0;
3553 #endif /* CONFIG_TESTING_OPTIONS */
3554 	if (!hapd->dpp_init_done)
3555 		return;
3556 	eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
3557 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3558 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3559 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
3560 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3561 	eloop_cancel_timeout(hostapd_gas_req_wait, hapd, NULL);
3562 #ifdef CONFIG_DPP2
3563 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3564 			     hapd, NULL);
3565 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
3566 			     NULL);
3567 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
3568 			     NULL);
3569 	hostapd_dpp_chirp_stop(hapd);
3570 	if (hapd->iface->interfaces) {
3571 		dpp_relay_stop_listen(hapd->iface->interfaces->dpp);
3572 		dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
3573 	}
3574 #endif /* CONFIG_DPP2 */
3575 #ifdef CONFIG_DPP3
3576 	eloop_cancel_timeout(hostapd_dpp_build_new_key, hapd, NULL);
3577 	hostapd_dpp_push_button_stop(hapd);
3578 #endif /* CONFIG_DPP3 */
3579 	dpp_auth_deinit(hapd->dpp_auth);
3580 	hapd->dpp_auth = NULL;
3581 	hostapd_dpp_pkex_remove(hapd, "*");
3582 	hapd->dpp_pkex = NULL;
3583 	os_free(hapd->dpp_configurator_params);
3584 	hapd->dpp_configurator_params = NULL;
3585 	os_free(hapd->dpp_pkex_auth_cmd);
3586 	hapd->dpp_pkex_auth_cmd = NULL;
3587 }
3588 
3589 
3590 #ifdef CONFIG_DPP2
3591 
hostapd_dpp_controller_start(struct hostapd_data * hapd,const char * cmd)3592 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd)
3593 {
3594 	struct dpp_controller_config config;
3595 	const char *pos;
3596 
3597 	os_memset(&config, 0, sizeof(config));
3598 	config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
3599 	config.netrole = DPP_NETROLE_AP;
3600 	config.msg_ctx = hapd->msg_ctx;
3601 	config.cb_ctx = hapd;
3602 	config.process_conf_obj = hostapd_dpp_process_conf_obj;
3603 	if (cmd) {
3604 		pos = os_strstr(cmd, " tcp_port=");
3605 		if (pos) {
3606 			pos += 10;
3607 			config.tcp_port = atoi(pos);
3608 		}
3609 
3610 		pos = os_strstr(cmd, " role=");
3611 		if (pos) {
3612 			pos += 6;
3613 			if (os_strncmp(pos, "configurator", 12) == 0)
3614 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
3615 			else if (os_strncmp(pos, "enrollee", 8) == 0)
3616 				config.allowed_roles = DPP_CAPAB_ENROLLEE;
3617 			else if (os_strncmp(pos, "either", 6) == 0)
3618 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
3619 					DPP_CAPAB_ENROLLEE;
3620 			else
3621 				return -1;
3622 		}
3623 
3624 		config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
3625 	}
3626 	config.configurator_params = hapd->dpp_configurator_params;
3627 	return dpp_controller_start(hapd->iface->interfaces->dpp, &config);
3628 }
3629 
3630 
3631 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
3632 
hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)3633 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
3634 {
3635 	struct hostapd_data *hapd = eloop_ctx;
3636 
3637 	wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
3638 	hostapd_drv_send_action_cancel_wait(hapd);
3639 	hostapd_dpp_chirp_next(hapd, NULL);
3640 }
3641 
3642 
hostapd_dpp_chirp_start(struct hostapd_data * hapd)3643 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
3644 {
3645 	struct wpabuf *msg;
3646 	int type;
3647 
3648 	msg = hapd->dpp_presence_announcement;
3649 	type = DPP_PA_PRESENCE_ANNOUNCEMENT;
3650 	wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
3651 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
3652 		" freq=%u type=%d",
3653 		MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
3654 	if (hostapd_drv_send_action(
3655 		    hapd, hapd->dpp_chirp_freq, 2000, broadcast,
3656 		    wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
3657 	    eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
3658 				   hapd, NULL) < 0)
3659 		hostapd_dpp_chirp_stop(hapd);
3660 }
3661 
3662 
3663 static struct hostapd_hw_modes *
dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)3664 dpp_get_mode(struct hostapd_data *hapd,
3665 	     enum hostapd_hw_mode mode)
3666 {
3667 	struct hostapd_hw_modes *modes = hapd->iface->hw_features;
3668 	u16 num_modes = hapd->iface->num_hw_features;
3669 	u16 i;
3670 
3671 	for (i = 0; i < num_modes; i++) {
3672 		if (modes[i].mode != mode ||
3673 		    !modes[i].num_channels || !modes[i].channels)
3674 			continue;
3675 		return &modes[i];
3676 	}
3677 
3678 	return NULL;
3679 }
3680 
3681 
3682 static void
hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)3683 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
3684 {
3685 	struct hostapd_data *hapd = iface->bss[0];
3686 	struct wpa_scan_results *scan_res;
3687 	struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
3688 	unsigned int i;
3689 	struct hostapd_hw_modes *mode;
3690 	int c;
3691 	bool chan6 = hapd->iface->hw_features == NULL;
3692 
3693 	if (!bi)
3694 		return;
3695 
3696 	hapd->dpp_chirp_scan_done = 1;
3697 
3698 	scan_res = hostapd_driver_get_scan_results(hapd);
3699 
3700 	os_free(hapd->dpp_chirp_freqs);
3701 	hapd->dpp_chirp_freqs = NULL;
3702 
3703 	/* Channels from own bootstrapping info */
3704 	if (bi) {
3705 		for (i = 0; i < bi->num_freq; i++)
3706 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3707 					     bi->freq[i]);
3708 	}
3709 
3710 	/* Preferred chirping channels */
3711 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
3712 	if (mode) {
3713 		for (c = 0; c < mode->num_channels; c++) {
3714 			struct hostapd_channel_data *chan = &mode->channels[c];
3715 
3716 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3717 					  HOSTAPD_CHAN_RADAR) ||
3718 			    chan->freq != 2437)
3719 				continue;
3720 			chan6 = true;
3721 			break;
3722 		}
3723 	}
3724 	if (chan6)
3725 		int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
3726 
3727 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
3728 	if (mode) {
3729 		int chan44 = 0, chan149 = 0;
3730 
3731 		for (c = 0; c < mode->num_channels; c++) {
3732 			struct hostapd_channel_data *chan = &mode->channels[c];
3733 
3734 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3735 					  HOSTAPD_CHAN_RADAR))
3736 				continue;
3737 			if (chan->freq == 5220)
3738 				chan44 = 1;
3739 			if (chan->freq == 5745)
3740 				chan149 = 1;
3741 		}
3742 		if (chan149)
3743 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
3744 		else if (chan44)
3745 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
3746 	}
3747 
3748 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
3749 	if (mode) {
3750 		for (c = 0; c < mode->num_channels; c++) {
3751 			struct hostapd_channel_data *chan = &mode->channels[c];
3752 
3753 			if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
3754 					   HOSTAPD_CHAN_RADAR)) ||
3755 			    chan->freq != 60480)
3756 				continue;
3757 			int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
3758 			break;
3759 		}
3760 	}
3761 
3762 	/* Add channels from scan results for APs that advertise Configurator
3763 	 * Connectivity element */
3764 	for (i = 0; scan_res && i < scan_res->num; i++) {
3765 		struct wpa_scan_res *bss = scan_res->res[i];
3766 		size_t ie_len = bss->ie_len;
3767 
3768 		if (!ie_len)
3769 			ie_len = bss->beacon_ie_len;
3770 		if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
3771 				  DPP_CC_IE_VENDOR_TYPE))
3772 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3773 					     bss->freq);
3774 	}
3775 
3776 	if (!hapd->dpp_chirp_freqs ||
3777 	    eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
3778 				   hapd, NULL) < 0)
3779 		hostapd_dpp_chirp_stop(hapd);
3780 
3781 	wpa_scan_results_free(scan_res);
3782 }
3783 
3784 
hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)3785 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
3786 {
3787 	struct hostapd_data *hapd = eloop_ctx;
3788 	int i;
3789 
3790 	if (hapd->dpp_chirp_listen)
3791 		hostapd_dpp_listen_stop(hapd);
3792 
3793 	if (hapd->dpp_chirp_freq == 0) {
3794 		if (hapd->dpp_chirp_round % 4 == 0 &&
3795 		    !hapd->dpp_chirp_scan_done) {
3796 			struct wpa_driver_scan_params params;
3797 			int ret;
3798 
3799 			wpa_printf(MSG_DEBUG,
3800 				   "DPP: Update channel list for chirping");
3801 			os_memset(&params, 0, sizeof(params));
3802 			ret = hostapd_driver_scan(hapd, &params);
3803 			if (ret < 0) {
3804 				wpa_printf(MSG_DEBUG,
3805 					   "DPP: Failed to request a scan ret=%d (%s)",
3806 					   ret, strerror(-ret));
3807 				hostapd_dpp_chirp_scan_res_handler(hapd->iface);
3808 			} else {
3809 				hapd->iface->scan_cb =
3810 					hostapd_dpp_chirp_scan_res_handler;
3811 			}
3812 			return;
3813 		}
3814 		hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
3815 		hapd->dpp_chirp_round++;
3816 		wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
3817 			   hapd->dpp_chirp_round);
3818 	} else {
3819 		for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
3820 			if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
3821 				break;
3822 		if (!hapd->dpp_chirp_freqs[i]) {
3823 			wpa_printf(MSG_DEBUG,
3824 				   "DPP: Previous chirp freq %d not found",
3825 				   hapd->dpp_chirp_freq);
3826 			return;
3827 		}
3828 		i++;
3829 		if (hapd->dpp_chirp_freqs[i]) {
3830 			hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
3831 		} else {
3832 			hapd->dpp_chirp_iter--;
3833 			if (hapd->dpp_chirp_iter <= 0) {
3834 				wpa_printf(MSG_DEBUG,
3835 					   "DPP: Chirping iterations completed");
3836 				hostapd_dpp_chirp_stop(hapd);
3837 				return;
3838 			}
3839 			hapd->dpp_chirp_freq = 0;
3840 			hapd->dpp_chirp_scan_done = 0;
3841 			if (eloop_register_timeout(30, 0,
3842 						   hostapd_dpp_chirp_next,
3843 						   hapd, NULL) < 0) {
3844 				hostapd_dpp_chirp_stop(hapd);
3845 				return;
3846 			}
3847 			if (hapd->dpp_chirp_listen) {
3848 				wpa_printf(MSG_DEBUG,
3849 					   "DPP: Listen on %d MHz during chirp 30 second wait",
3850 					hapd->dpp_chirp_listen);
3851 				/* TODO: start listen on the channel */
3852 			} else {
3853 				wpa_printf(MSG_DEBUG,
3854 					   "DPP: Wait 30 seconds before starting the next chirping round");
3855 			}
3856 			return;
3857 		}
3858 	}
3859 
3860 	hostapd_dpp_chirp_start(hapd);
3861 }
3862 
3863 
hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)3864 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
3865 {
3866 	const char *pos;
3867 	int iter = 1, listen_freq = 0;
3868 	struct dpp_bootstrap_info *bi;
3869 
3870 	pos = os_strstr(cmd, " own=");
3871 	if (!pos)
3872 		return -1;
3873 	pos += 5;
3874 	bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3875 	if (!bi) {
3876 		wpa_printf(MSG_DEBUG,
3877 			   "DPP: Identified bootstrap info not found");
3878 		return -1;
3879 	}
3880 
3881 	pos = os_strstr(cmd, " iter=");
3882 	if (pos) {
3883 		iter = atoi(pos + 6);
3884 		if (iter <= 0)
3885 			return -1;
3886 	}
3887 
3888 	pos = os_strstr(cmd, " listen=");
3889 	if (pos) {
3890 		listen_freq = atoi(pos + 8);
3891 		if (listen_freq <= 0)
3892 			return -1;
3893 	}
3894 
3895 	hostapd_dpp_chirp_stop(hapd);
3896 	hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
3897 	hapd->dpp_qr_mutual = 0;
3898 	hapd->dpp_chirp_bi = bi;
3899 	hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
3900 	if (!hapd->dpp_presence_announcement)
3901 		return -1;
3902 	hapd->dpp_chirp_iter = iter;
3903 	hapd->dpp_chirp_round = 0;
3904 	hapd->dpp_chirp_scan_done = 0;
3905 	hapd->dpp_chirp_listen = listen_freq;
3906 
3907 	return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
3908 }
3909 
3910 
hostapd_dpp_chirp_stop(struct hostapd_data * hapd)3911 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
3912 {
3913 	if (hapd->dpp_presence_announcement) {
3914 		hostapd_drv_send_action_cancel_wait(hapd);
3915 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
3916 	}
3917 	hapd->dpp_chirp_bi = NULL;
3918 	wpabuf_free(hapd->dpp_presence_announcement);
3919 	hapd->dpp_presence_announcement = NULL;
3920 	if (hapd->dpp_chirp_listen)
3921 		hostapd_dpp_listen_stop(hapd);
3922 	hapd->dpp_chirp_listen = 0;
3923 	hapd->dpp_chirp_freq = 0;
3924 	os_free(hapd->dpp_chirp_freqs);
3925 	hapd->dpp_chirp_freqs = NULL;
3926 	eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
3927 	eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
3928 	if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
3929 		/* TODO: abort ongoing scan */
3930 		hapd->iface->scan_cb = NULL;
3931 	}
3932 }
3933 
3934 
handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)3935 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
3936 {
3937 	struct dpp_bootstrap_info *bi = ctx;
3938 	size_t i;
3939 
3940 	for (i = 0; i < iface->num_bss; i++) {
3941 		struct hostapd_data *hapd = iface->bss[i];
3942 
3943 		if (bi == hapd->dpp_chirp_bi)
3944 			hostapd_dpp_chirp_stop(hapd);
3945 	}
3946 
3947 	return 0;
3948 }
3949 
3950 
hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)3951 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
3952 {
3953 	struct hapd_interfaces *interfaces = ctx;
3954 
3955 	hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
3956 }
3957 
3958 #endif /* CONFIG_DPP2 */
3959 
3960 
3961 #ifdef CONFIG_DPP3
3962 
hostapd_dpp_push_button_expire(void * eloop_ctx,void * timeout_ctx)3963 static void hostapd_dpp_push_button_expire(void *eloop_ctx, void *timeout_ctx)
3964 {
3965 	struct hostapd_data *hapd = eloop_ctx;
3966 
3967 	wpa_printf(MSG_DEBUG, "DPP: Active push button mode expired");
3968 	hostapd_dpp_push_button_stop(hapd);
3969 }
3970 
3971 
hostapd_dpp_push_button(struct hostapd_data * hapd,const char * cmd)3972 int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd)
3973 {
3974 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3975 
3976 	if (!ifaces || !ifaces->dpp)
3977 		return -1;
3978 	os_get_reltime(&ifaces->dpp_pb_time);
3979 	ifaces->dpp_pb_announce_time.sec = 0;
3980 	ifaces->dpp_pb_announce_time.usec = 0;
3981 	str_clear_free(ifaces->dpp_pb_cmd);
3982 	ifaces->dpp_pb_cmd = NULL;
3983 	if (cmd) {
3984 		ifaces->dpp_pb_cmd = os_strdup(cmd);
3985 		if (!ifaces->dpp_pb_cmd)
3986 			return -1;
3987 	}
3988 	eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
3989 			       hapd, NULL);
3990 
3991 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started");
3992 	return 0;
3993 }
3994 
3995 
hostapd_dpp_push_button_stop(struct hostapd_data * hapd)3996 void hostapd_dpp_push_button_stop(struct hostapd_data *hapd)
3997 {
3998 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3999 
4000 	if (!ifaces || !ifaces->dpp)
4001 		return;
4002 	eloop_cancel_timeout(hostapd_dpp_push_button_expire, hapd, NULL);
4003 	if (hostapd_dpp_pb_active(hapd)) {
4004 		wpa_printf(MSG_DEBUG, "DPP: Stop active push button mode");
4005 		if (!ifaces->dpp_pb_result_indicated)
4006 			wpa_msg(hapd->msg_ctx, MSG_INFO,
4007 				DPP_EVENT_PB_RESULT "failed");
4008 	}
4009 	ifaces->dpp_pb_time.sec = 0;
4010 	ifaces->dpp_pb_time.usec = 0;
4011 	dpp_pkex_free(hapd->dpp_pkex);
4012 	hapd->dpp_pkex = NULL;
4013 	hapd->dpp_pkex_bi = NULL;
4014 	os_free(hapd->dpp_pkex_auth_cmd);
4015 	hapd->dpp_pkex_auth_cmd = NULL;
4016 
4017 	if (ifaces->dpp_pb_bi) {
4018 		char id[20];
4019 		size_t i;
4020 
4021 		for (i = 0; i < ifaces->count; i++) {
4022 			struct hostapd_iface *iface = ifaces->iface[i];
4023 			size_t j;
4024 
4025 			for (j = 0; iface && j < iface->num_bss; j++) {
4026 				struct hostapd_data *h = iface->bss[j];
4027 
4028 				if (h->dpp_pkex_bi == ifaces->dpp_pb_bi)
4029 					h->dpp_pkex_bi = NULL;
4030 			}
4031 		}
4032 
4033 		os_snprintf(id, sizeof(id), "%u", ifaces->dpp_pb_bi->id);
4034 		dpp_bootstrap_remove(ifaces->dpp, id);
4035 		ifaces->dpp_pb_bi = NULL;
4036 	}
4037 
4038 	ifaces->dpp_pb_result_indicated = false;
4039 
4040 	str_clear_free(ifaces->dpp_pb_cmd);
4041 	ifaces->dpp_pb_cmd = NULL;
4042 }
4043 
4044 #endif /* CONFIG_DPP3 */
4045 
4046 
4047 #ifdef CONFIG_DPP2
hostapd_dpp_configurator_connectivity(struct hostapd_data * hapd)4048 bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd)
4049 {
4050 	return hapd->conf->dpp_configurator_connectivity ||
4051 		(hapd->iface->interfaces &&
4052 		 dpp_relay_controller_available(hapd->iface->interfaces->dpp));
4053 }
4054 #endif /* CONFIG_DPP2 */
4055