xref: /freebsd/contrib/wpa/src/ap/dpp_hostapd.c (revision db33c6f3ae9d1231087710068ee4ea5398aacca7)
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  */
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  */
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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
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 
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 
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 
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
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 
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 
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 
1385 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
1386 {
1387 	wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
1388 	dpp_notify_auth_success(hapd->dpp_auth, initiator);
1389 #ifdef CONFIG_TESTING_OPTIONS
1390 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1391 		wpa_printf(MSG_INFO,
1392 			   "DPP: TESTING - stop at Authentication Confirm");
1393 		if (hapd->dpp_auth->configurator) {
1394 			/* Prevent GAS response */
1395 			hapd->dpp_auth->auth_success = 0;
1396 		}
1397 		return;
1398 	}
1399 #endif /* CONFIG_TESTING_OPTIONS */
1400 
1401 	if (!hapd->dpp_auth->configurator)
1402 		hostapd_dpp_start_gas_client(hapd);
1403 }
1404 
1405 
1406 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
1407 				     const u8 *hdr, const u8 *buf, size_t len,
1408 				     unsigned int freq)
1409 {
1410 	struct dpp_authentication *auth = hapd->dpp_auth;
1411 	struct wpabuf *msg;
1412 
1413 	wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
1414 		   MAC2STR(src));
1415 
1416 	if (!auth) {
1417 		wpa_printf(MSG_DEBUG,
1418 			   "DPP: No DPP Authentication in progress - drop");
1419 		return;
1420 	}
1421 
1422 	if (!is_zero_ether_addr(auth->peer_mac_addr) &&
1423 	    !ether_addr_equal(src, auth->peer_mac_addr)) {
1424 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1425 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1426 		return;
1427 	}
1428 
1429 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1430 
1431 	if (auth->curr_freq != freq && auth->neg_freq == freq) {
1432 		wpa_printf(MSG_DEBUG,
1433 			   "DPP: Responder accepted request for different negotiation channel");
1434 		auth->curr_freq = freq;
1435 	}
1436 
1437 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1438 	msg = dpp_auth_resp_rx(auth, hdr, buf, len);
1439 	if (!msg) {
1440 		if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
1441 			wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
1442 			return;
1443 		}
1444 		wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
1445 		return;
1446 	}
1447 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1448 
1449 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1450 		" freq=%u type=%d", MAC2STR(src), auth->curr_freq,
1451 		DPP_PA_AUTHENTICATION_CONF);
1452 	hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
1453 				wpabuf_head(msg), wpabuf_len(msg));
1454 	wpabuf_free(msg);
1455 	hapd->dpp_auth_ok_on_ack = 1;
1456 }
1457 
1458 
1459 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
1460 				     const u8 *hdr, const u8 *buf, size_t len)
1461 {
1462 	struct dpp_authentication *auth = hapd->dpp_auth;
1463 
1464 	wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
1465 		   MAC2STR(src));
1466 
1467 	if (!auth) {
1468 		wpa_printf(MSG_DEBUG,
1469 			   "DPP: No DPP Authentication in progress - drop");
1470 		return;
1471 	}
1472 
1473 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1474 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1475 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1476 		return;
1477 	}
1478 
1479 	if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1480 		wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1481 		return;
1482 	}
1483 
1484 	hostapd_dpp_auth_success(hapd, 0);
1485 }
1486 
1487 
1488 #ifdef CONFIG_DPP2
1489 
1490 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1491 						   void *timeout_ctx)
1492 {
1493 	struct hostapd_data *hapd = eloop_ctx;
1494 	struct dpp_authentication *auth = hapd->dpp_auth;
1495 
1496 	if (!auth || !auth->waiting_conf_result)
1497 		return;
1498 
1499 	wpa_printf(MSG_DEBUG,
1500 		   "DPP: Timeout while waiting for Configuration Result");
1501 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1502 	dpp_auth_deinit(auth);
1503 	hapd->dpp_auth = NULL;
1504 }
1505 
1506 
1507 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1508 							void *timeout_ctx)
1509 {
1510 	struct hostapd_data *hapd = eloop_ctx;
1511 	struct dpp_authentication *auth = hapd->dpp_auth;
1512 
1513 	if (!auth || !auth->waiting_conf_result)
1514 		return;
1515 
1516 	wpa_printf(MSG_DEBUG,
1517 		   "DPP: Timeout while waiting for Connection Status Result");
1518 	wpa_msg(hapd->msg_ctx, MSG_INFO,
1519 		DPP_EVENT_CONN_STATUS_RESULT "timeout");
1520 	dpp_auth_deinit(auth);
1521 	hapd->dpp_auth = NULL;
1522 }
1523 
1524 
1525 #ifdef CONFIG_DPP3
1526 
1527 static bool hostapd_dpp_pb_active(struct hostapd_data *hapd)
1528 {
1529 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1530 
1531 	return ifaces && (ifaces->dpp_pb_time.sec ||
1532 			  ifaces->dpp_pb_time.usec);
1533 }
1534 
1535 
1536 static void hostapd_dpp_remove_pb_hash(struct hostapd_data *hapd)
1537 {
1538 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1539 	int i;
1540 
1541 	if (!ifaces->dpp_pb_bi)
1542 		return;
1543 	for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
1544 		struct dpp_pb_info *info = &ifaces->dpp_pb[i];
1545 
1546 		if (info->rx_time.sec == 0 && info->rx_time.usec == 0)
1547 			continue;
1548 		if (os_memcmp(info->hash, ifaces->dpp_pb_resp_hash,
1549 			      SHA256_MAC_LEN) == 0) {
1550 			/* Allow a new push button session to be established
1551 			 * immediately without the successfully completed
1552 			 * session triggering session overlap. */
1553 			info->rx_time.sec = 0;
1554 			info->rx_time.usec = 0;
1555 			wpa_printf(MSG_DEBUG,
1556 				   "DPP: Removed PB hash from session overlap detection due to successfully completed provisioning");
1557 		}
1558 	}
1559 }
1560 
1561 #endif /* CONFIG_DPP3 */
1562 
1563 
1564 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1565 				       const u8 *hdr, const u8 *buf, size_t len)
1566 {
1567 	struct dpp_authentication *auth = hapd->dpp_auth;
1568 	enum dpp_status_error status;
1569 #ifdef CONFIG_DPP3
1570 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1571 #endif /* CONFIG_DPP3 */
1572 
1573 	wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
1574 		   MAC2STR(src));
1575 
1576 	if (!auth || !auth->waiting_conf_result) {
1577 		wpa_printf(MSG_DEBUG,
1578 			   "DPP: No DPP Configuration waiting for result - drop");
1579 		return;
1580 	}
1581 
1582 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1583 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1584 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1585 		return;
1586 	}
1587 
1588 	status = dpp_conf_result_rx(auth, hdr, buf, len);
1589 
1590 	if (status == DPP_STATUS_OK && auth->send_conn_status) {
1591 		wpa_msg(hapd->msg_ctx, MSG_INFO,
1592 			DPP_EVENT_CONF_SENT "wait_conn_status=1 conf_status=%d",
1593 			auth->conf_resp_status);
1594 		wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1595 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1596 				     hapd, NULL);
1597 		auth->waiting_conn_status_result = 1;
1598 		eloop_cancel_timeout(
1599 			hostapd_dpp_conn_status_result_wait_timeout,
1600 			hapd, NULL);
1601 		eloop_register_timeout(
1602 			16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1603 			hapd, NULL);
1604 		return;
1605 	}
1606 	hostapd_drv_send_action_cancel_wait(hapd);
1607 	hostapd_dpp_listen_stop(hapd);
1608 	if (status == DPP_STATUS_OK)
1609 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
1610 			"conf_status=%d", auth->conf_resp_status);
1611 	else
1612 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1613 	dpp_auth_deinit(auth);
1614 	hapd->dpp_auth = NULL;
1615 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1616 			     NULL);
1617 #ifdef CONFIG_DPP3
1618 	if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
1619 		if (status == DPP_STATUS_OK)
1620 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1621 				"success");
1622 		else
1623 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1624 				"no-configuration-available");
1625 		ifaces->dpp_pb_result_indicated = true;
1626 		if (status == DPP_STATUS_OK)
1627 			hostapd_dpp_remove_pb_hash(hapd);
1628 		hostapd_dpp_push_button_stop(hapd);
1629 	}
1630 #endif /* CONFIG_DPP3 */
1631 }
1632 
1633 
1634 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1635 					      const u8 *src, const u8 *hdr,
1636 					      const u8 *buf, size_t len)
1637 {
1638 	struct dpp_authentication *auth = hapd->dpp_auth;
1639 	enum dpp_status_error status;
1640 	u8 ssid[SSID_MAX_LEN];
1641 	size_t ssid_len = 0;
1642 	char *channel_list = NULL;
1643 
1644 	wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1645 
1646 	if (!auth || !auth->waiting_conn_status_result) {
1647 		wpa_printf(MSG_DEBUG,
1648 			   "DPP: No DPP Configuration waiting for connection status result - drop");
1649 		return;
1650 	}
1651 
1652 	status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1653 					   ssid, &ssid_len, &channel_list);
1654 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1655 		"result=%d ssid=%s channel_list=%s",
1656 		status, wpa_ssid_txt(ssid, ssid_len),
1657 		channel_list ? channel_list : "N/A");
1658 	os_free(channel_list);
1659 	hostapd_drv_send_action_cancel_wait(hapd);
1660 	hostapd_dpp_listen_stop(hapd);
1661 	dpp_auth_deinit(auth);
1662 	hapd->dpp_auth = NULL;
1663 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1664 			     hapd, NULL);
1665 }
1666 
1667 
1668 static void
1669 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1670 				     const u8 *hdr, const u8 *buf, size_t len,
1671 				     unsigned int freq)
1672 {
1673 	const u8 *r_bootstrap;
1674 	u16 r_bootstrap_len;
1675 	struct dpp_bootstrap_info *peer_bi;
1676 	struct dpp_authentication *auth;
1677 
1678 	wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
1679 		   MAC2STR(src));
1680 
1681 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1682 				   &r_bootstrap_len);
1683 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1684 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1685 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
1686 		return;
1687 	}
1688 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1689 		    r_bootstrap, r_bootstrap_len);
1690 	peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1691 					   r_bootstrap);
1692 	dpp_notify_chirp_received(hapd->msg_ctx,
1693 				  peer_bi ? (int) peer_bi->id : -1,
1694 				  src, freq, r_bootstrap);
1695 	if (!peer_bi) {
1696 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1697 					src, hdr, buf, len, freq, NULL,
1698 					r_bootstrap, hapd) == 0)
1699 			return;
1700 		wpa_printf(MSG_DEBUG,
1701 			   "DPP: No matching bootstrapping information found");
1702 		hostapd_dpp_relay_needs_controller(
1703 			hapd, src, DPP_PA_PRESENCE_ANNOUNCEMENT);
1704 		return;
1705 	}
1706 
1707 	if (hapd->dpp_auth) {
1708 		wpa_printf(MSG_DEBUG,
1709 			   "DPP: Ignore Presence Announcement during ongoing Authentication");
1710 		return;
1711 	}
1712 
1713 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1714 			     peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1715 			     0);
1716 	if (!auth)
1717 		return;
1718 	hostapd_dpp_set_testing_options(hapd, auth);
1719 	if (dpp_set_configurator(auth,
1720 				 hapd->dpp_configurator_params) < 0) {
1721 		dpp_auth_deinit(auth);
1722 		return;
1723 	}
1724 
1725 	auth->neg_freq = freq;
1726 
1727 	/* The source address of the Presence Announcement frame overrides any
1728 	 * MAC address information from the bootstrapping information. */
1729 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1730 
1731 	hapd->dpp_auth = auth;
1732 	if (hostapd_dpp_auth_init_next(hapd) < 0) {
1733 		dpp_auth_deinit(hapd->dpp_auth);
1734 		hapd->dpp_auth = NULL;
1735 	}
1736 }
1737 
1738 
1739 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
1740 						    void *timeout_ctx)
1741 {
1742 	struct hostapd_data *hapd = eloop_ctx;
1743 	struct dpp_authentication *auth = hapd->dpp_auth;
1744 
1745 	if (!auth)
1746 		return;
1747 
1748 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
1749 	hostapd_dpp_listen_stop(hapd);
1750 	dpp_auth_deinit(auth);
1751 	hapd->dpp_auth = NULL;
1752 }
1753 
1754 
1755 static void
1756 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
1757 				     const u8 *hdr, const u8 *buf, size_t len,
1758 				     unsigned int freq)
1759 {
1760 	const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1761 	u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1762 	struct dpp_configurator *conf;
1763 	struct dpp_authentication *auth;
1764 	unsigned int wait_time, max_wait_time;
1765 	u16 group;
1766 
1767 	if (hapd->dpp_auth) {
1768 		wpa_printf(MSG_DEBUG,
1769 			   "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1770 		return;
1771 	}
1772 
1773 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR,
1774 		   MAC2STR(src));
1775 
1776 	csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1777 				  &csign_hash_len);
1778 	if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1779 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1780 			"Missing or invalid required Configurator C-sign key Hash attribute");
1781 		return;
1782 	}
1783 	wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1784 		    csign_hash, csign_hash_len);
1785 	conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp,
1786 					 csign_hash);
1787 	if (!conf) {
1788 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1789 					src, hdr, buf, len, freq, NULL,
1790 					NULL, hapd) == 0)
1791 			return;
1792 		wpa_printf(MSG_DEBUG,
1793 			   "DPP: No matching Configurator information found");
1794 		hostapd_dpp_relay_needs_controller(
1795 			hapd, src, DPP_PA_RECONFIG_ANNOUNCEMENT);
1796 		return;
1797 	}
1798 
1799 	fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1800 			       &fcgroup_len);
1801 	if (!fcgroup || fcgroup_len != 2) {
1802 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1803 			"Missing or invalid required Finite Cyclic Group attribute");
1804 		return;
1805 	}
1806 	group = WPA_GET_LE16(fcgroup);
1807 	wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1808 
1809 	a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1810 	e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1811 
1812 	auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1813 				 conf, freq, group, a_nonce, a_nonce_len,
1814 				 e_id, e_id_len);
1815 	if (!auth)
1816 		return;
1817 	hostapd_dpp_set_testing_options(hapd, auth);
1818 	if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
1819 		dpp_auth_deinit(auth);
1820 		return;
1821 	}
1822 
1823 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1824 	hapd->dpp_auth = auth;
1825 
1826 	hapd->dpp_in_response_listen = 0;
1827 	hapd->dpp_auth_ok_on_ack = 0;
1828 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
1829 	max_wait_time = hapd->dpp_resp_wait_time ?
1830 		hapd->dpp_resp_wait_time : 2000;
1831 	if (wait_time > max_wait_time)
1832 		wait_time = max_wait_time;
1833 	wait_time += 10; /* give the driver some extra time to complete */
1834 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
1835 			       hostapd_dpp_reconfig_reply_wait_timeout,
1836 			       hapd, NULL);
1837 	wait_time -= 10;
1838 
1839 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1840 		" freq=%u type=%d",
1841 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
1842 	if (hostapd_drv_send_action(hapd, freq, wait_time, src,
1843 				    wpabuf_head(auth->reconfig_req_msg),
1844 				    wpabuf_len(auth->reconfig_req_msg)) < 0) {
1845 		dpp_auth_deinit(hapd->dpp_auth);
1846 		hapd->dpp_auth = NULL;
1847 	}
1848 }
1849 
1850 
1851 static void
1852 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src,
1853 				  const u8 *hdr, const u8 *buf, size_t len,
1854 				  unsigned int freq)
1855 {
1856 	struct dpp_authentication *auth = hapd->dpp_auth;
1857 	struct wpabuf *conf;
1858 
1859 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
1860 		   MACSTR, MAC2STR(src));
1861 
1862 	if (!auth || !auth->reconfig || !auth->configurator) {
1863 		wpa_printf(MSG_DEBUG,
1864 			   "DPP: No DPP Reconfig Authentication in progress - drop");
1865 		return;
1866 	}
1867 
1868 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1869 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1870 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1871 		return;
1872 	}
1873 
1874 	conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1875 	if (!conf)
1876 		return;
1877 
1878 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1879 			     hapd, NULL);
1880 
1881 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1882 		" freq=%u type=%d",
1883 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
1884 	if (hostapd_drv_send_action(hapd, freq, 500, src,
1885 				    wpabuf_head(conf), wpabuf_len(conf)) < 0) {
1886 		wpabuf_free(conf);
1887 		dpp_auth_deinit(hapd->dpp_auth);
1888 		hapd->dpp_auth = NULL;
1889 		return;
1890 	}
1891 	wpabuf_free(conf);
1892 }
1893 
1894 #endif /* CONFIG_DPP2 */
1895 
1896 
1897 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1898 					    const u8 *src, unsigned int freq,
1899 					    u8 trans_id,
1900 					    enum dpp_status_error status)
1901 {
1902 	struct wpabuf *msg;
1903 	size_t len;
1904 
1905 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
1906 #ifdef CONFIG_DPP2
1907 	len += 5;
1908 #endif /* CONFIG_DPP2 */
1909 	msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len);
1910 	if (!msg)
1911 		return;
1912 
1913 #ifdef CONFIG_TESTING_OPTIONS
1914 	if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1915 		wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1916 		goto skip_trans_id;
1917 	}
1918 	if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1919 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1920 		trans_id ^= 0x01;
1921 	}
1922 #endif /* CONFIG_TESTING_OPTIONS */
1923 
1924 	/* Transaction ID */
1925 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1926 	wpabuf_put_le16(msg, 1);
1927 	wpabuf_put_u8(msg, trans_id);
1928 
1929 #ifdef CONFIG_TESTING_OPTIONS
1930 skip_trans_id:
1931 	if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1932 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1933 		goto skip_status;
1934 	}
1935 	if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1936 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1937 		status = 254;
1938 	}
1939 #endif /* CONFIG_TESTING_OPTIONS */
1940 
1941 	/* DPP Status */
1942 	wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1943 	wpabuf_put_le16(msg, 1);
1944 	wpabuf_put_u8(msg, status);
1945 
1946 #ifdef CONFIG_TESTING_OPTIONS
1947 skip_status:
1948 	if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1949 		wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1950 		goto skip_connector;
1951 	}
1952 	if (status == DPP_STATUS_OK &&
1953 	    dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1954 		char *connector;
1955 
1956 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1957 		connector = dpp_corrupt_connector_signature(
1958 			hapd->conf->dpp_connector);
1959 		if (!connector) {
1960 			wpabuf_free(msg);
1961 			return;
1962 		}
1963 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1964 		wpabuf_put_le16(msg, os_strlen(connector));
1965 		wpabuf_put_str(msg, connector);
1966 		os_free(connector);
1967 		goto skip_connector;
1968 	}
1969 #endif /* CONFIG_TESTING_OPTIONS */
1970 
1971 	/* DPP Connector */
1972 	if (status == DPP_STATUS_OK) {
1973 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1974 		wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1975 		wpabuf_put_str(msg, hapd->conf->dpp_connector);
1976 	}
1977 
1978 #ifdef CONFIG_TESTING_OPTIONS
1979 skip_connector:
1980 	if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) {
1981 		wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
1982 		goto skip_proto_ver;
1983 	}
1984 #endif /* CONFIG_TESTING_OPTIONS */
1985 
1986 #ifdef CONFIG_DPP2
1987 	if (DPP_VERSION > 1) {
1988 		u8 ver = DPP_VERSION;
1989 #ifdef CONFIG_DPP3
1990 		int conn_ver;
1991 
1992 		conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
1993 		if (conn_ver > 0 && ver != conn_ver) {
1994 			wpa_printf(MSG_DEBUG,
1995 				   "DPP: Use Connector version %d instead of current protocol version %d",
1996 				   conn_ver, ver);
1997 			ver = conn_ver;
1998 		}
1999 #endif /* CONFIG_DPP3 */
2000 
2001 #ifdef CONFIG_TESTING_OPTIONS
2002 	if (dpp_test == DPP_TEST_INVALID_PROTOCOL_VERSION_PEER_DISC_RESP) {
2003 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Protocol Version");
2004 		ver = 1;
2005 	}
2006 #endif /* CONFIG_TESTING_OPTIONS */
2007 
2008 		/* Protocol Version */
2009 		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2010 		wpabuf_put_le16(msg, 1);
2011 		wpabuf_put_u8(msg, ver);
2012 	}
2013 #endif /* CONFIG_DPP2 */
2014 
2015 #ifdef CONFIG_TESTING_OPTIONS
2016 skip_proto_ver:
2017 #endif /* CONFIG_TESTING_OPTIONS */
2018 
2019 	wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
2020 		   " status=%d", MAC2STR(src), status);
2021 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2022 		" freq=%u type=%d status=%d", MAC2STR(src), freq,
2023 		DPP_PA_PEER_DISCOVERY_RESP, status);
2024 	hostapd_drv_send_action(hapd, freq, 0, src,
2025 				wpabuf_head(msg), wpabuf_len(msg));
2026 	wpabuf_free(msg);
2027 }
2028 
2029 
2030 static bool hapd_dpp_connector_available(struct hostapd_data *hapd)
2031 {
2032 	if (!hapd->wpa_auth ||
2033 	    !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
2034 	    !(hapd->conf->wpa & WPA_PROTO_RSN)) {
2035 		wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
2036 		return false;
2037 	}
2038 
2039 	if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
2040 	    !hapd->conf->dpp_csign) {
2041 		wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
2042 		return false;
2043 	}
2044 
2045 	return true;
2046 }
2047 
2048 
2049 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
2050 					 const u8 *src,
2051 					 const u8 *buf, size_t len,
2052 					 unsigned int freq)
2053 {
2054 	const u8 *connector, *trans_id;
2055 	u16 connector_len, trans_id_len;
2056 	struct os_time now;
2057 	struct dpp_introduction intro;
2058 	os_time_t expire;
2059 	int expiration;
2060 	enum dpp_status_error res;
2061 	u8 pkhash[SHA256_MAC_LEN];
2062 
2063 	os_memset(&intro, 0, sizeof(intro));
2064 
2065 	wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
2066 		   MAC2STR(src));
2067 	if (!hapd_dpp_connector_available(hapd))
2068 		return;
2069 
2070 	os_get_time(&now);
2071 
2072 	if (hapd->conf->dpp_netaccesskey_expiry &&
2073 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2074 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2075 		return;
2076 	}
2077 
2078 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2079 			       &trans_id_len);
2080 	if (!trans_id || trans_id_len != 1) {
2081 		wpa_printf(MSG_DEBUG,
2082 			   "DPP: Peer did not include Transaction ID");
2083 		return;
2084 	}
2085 
2086 	connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
2087 	if (!connector) {
2088 		wpa_printf(MSG_DEBUG,
2089 			   "DPP: Peer did not include its Connector");
2090 		return;
2091 	}
2092 
2093 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2094 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
2095 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
2096 			     wpabuf_head(hapd->conf->dpp_csign),
2097 			     wpabuf_len(hapd->conf->dpp_csign),
2098 			     connector, connector_len, &expire, pkhash);
2099 	if (res == 255) {
2100 		wpa_printf(MSG_INFO,
2101 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
2102 			   MACSTR ")", MAC2STR(src));
2103 		goto done;
2104 	}
2105 	if (res != DPP_STATUS_OK) {
2106 		wpa_printf(MSG_INFO,
2107 			   "DPP: Network Introduction protocol resulted in failure (peer "
2108 			   MACSTR " status %d)", MAC2STR(src), res);
2109 		hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2110 						res);
2111 		goto done;
2112 	}
2113 
2114 #ifdef CONFIG_DPP3
2115 	if (intro.peer_version && intro.peer_version >= 2) {
2116 		const u8 *version;
2117 		u16 version_len;
2118 		u8 attr_version = 1;
2119 
2120 		version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2121 				       &version_len);
2122 		if (version && version_len >= 1)
2123 			attr_version = version[0];
2124 		if (attr_version != intro.peer_version) {
2125 			wpa_printf(MSG_INFO,
2126 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2127 				   intro.peer_version, attr_version);
2128 			hostapd_dpp_send_peer_disc_resp(hapd, src, freq,
2129 							trans_id[0],
2130 							DPP_STATUS_NO_MATCH);
2131 			goto done;
2132 		}
2133 	}
2134 #endif /* CONFIG_DPP3 */
2135 
2136 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2137 		expire = hapd->conf->dpp_netaccesskey_expiry;
2138 	if (expire)
2139 		expiration = expire - now.sec;
2140 	else
2141 		expiration = 0;
2142 
2143 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2144 				intro.pmkid, expiration,
2145 				WPA_KEY_MGMT_DPP, pkhash) < 0) {
2146 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2147 		goto done;
2148 	}
2149 
2150 	hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2151 					DPP_STATUS_OK);
2152 done:
2153 	dpp_peer_intro_deinit(&intro);
2154 }
2155 
2156 
2157 static void
2158 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
2159 				 const u8 *hdr, const u8 *buf, size_t len,
2160 				 unsigned int freq, bool v2)
2161 {
2162 	struct wpabuf *msg;
2163 
2164 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
2165 		   MAC2STR(src));
2166 
2167 	if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_1 && v2) {
2168 		wpa_printf(MSG_DEBUG,
2169 			   "DPP: Ignore PKEXv2 Exchange Request when configured to be PKEX v1 only");
2170 		return;
2171 	}
2172 	if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_2 && !v2) {
2173 		wpa_printf(MSG_DEBUG,
2174 			   "DPP: Ignore PKEXv1 Exchange Request when configured to be PKEX v2 only");
2175 		return;
2176 	}
2177 
2178 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
2179 	 * values here */
2180 
2181 	if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
2182 		wpa_printf(MSG_DEBUG,
2183 			   "DPP: No PKEX code configured - ignore request");
2184 		goto try_relay;
2185 	}
2186 
2187 #ifdef CONFIG_DPP2
2188 	if (dpp_controller_is_own_pkex_req(hapd->iface->interfaces->dpp,
2189 					   buf, len)) {
2190 		wpa_printf(MSG_DEBUG,
2191 			   "DPP: PKEX Exchange Request is from local Controller - ignore request");
2192 		return;
2193 	}
2194 #endif /* CONFIG_DPP2 */
2195 
2196 	if (hapd->dpp_pkex) {
2197 		/* TODO: Support parallel operations */
2198 		wpa_printf(MSG_DEBUG,
2199 			   "DPP: Already in PKEX session - ignore new request");
2200 		goto try_relay;
2201 	}
2202 
2203 	hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
2204 						  hapd->dpp_pkex_bi,
2205 						  hapd->own_addr, src,
2206 						  hapd->dpp_pkex_identifier,
2207 						  hapd->dpp_pkex_code,
2208 						  hapd->dpp_pkex_code_len,
2209 						  buf, len, v2);
2210 	if (!hapd->dpp_pkex) {
2211 		wpa_printf(MSG_DEBUG,
2212 			   "DPP: Failed to process the request - ignore it");
2213 		goto try_relay;
2214 	}
2215 
2216 	msg = hapd->dpp_pkex->exchange_resp;
2217 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2218 		" freq=%u type=%d", MAC2STR(src), freq,
2219 		DPP_PA_PKEX_EXCHANGE_RESP);
2220 	hostapd_drv_send_action(hapd, freq, 0, src,
2221 				wpabuf_head(msg), wpabuf_len(msg));
2222 	if (hapd->dpp_pkex->failed) {
2223 		wpa_printf(MSG_DEBUG,
2224 			   "DPP: Terminate PKEX exchange due to an earlier error");
2225 		if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2226 			hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
2227 		dpp_pkex_free(hapd->dpp_pkex);
2228 		hapd->dpp_pkex = NULL;
2229 	}
2230 
2231 	return;
2232 
2233 try_relay:
2234 #ifdef CONFIG_DPP2
2235 	if (v2 && dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2236 				      src, hdr, buf, len, freq, NULL, NULL,
2237 				      hapd) != 0) {
2238 		wpa_printf(MSG_DEBUG,
2239 			   "DPP: No Relay available for the message");
2240 		hostapd_dpp_relay_needs_controller(hapd, src,
2241 						   DPP_PA_PKEX_EXCHANGE_REQ);
2242 	}
2243 #else /* CONFIG_DPP2 */
2244 	wpa_printf(MSG_DEBUG, "DPP: No relay functionality included - skip");
2245 #endif /* CONFIG_DPP2 */
2246 }
2247 
2248 
2249 static void
2250 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
2251 				  const u8 *buf, size_t len, unsigned int freq)
2252 {
2253 	struct wpabuf *msg;
2254 
2255 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
2256 		   MAC2STR(src));
2257 
2258 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
2259 	 * values here */
2260 
2261 	if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
2262 	    hapd->dpp_pkex->exchange_done) {
2263 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2264 		return;
2265 	}
2266 
2267 	eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
2268 	hapd->dpp_pkex->exch_req_wait_time = 0;
2269 
2270 	msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
2271 	if (!msg) {
2272 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2273 		return;
2274 	}
2275 
2276 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
2277 		   MAC2STR(src));
2278 
2279 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2280 		" freq=%u type=%d", MAC2STR(src), freq,
2281 		DPP_PA_PKEX_COMMIT_REVEAL_REQ);
2282 	hostapd_drv_send_action(hapd, freq, 0, src,
2283 				wpabuf_head(msg), wpabuf_len(msg));
2284 	wpabuf_free(msg);
2285 }
2286 
2287 
2288 static void
2289 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
2290 				      const u8 *hdr, const u8 *buf, size_t len,
2291 				      unsigned int freq)
2292 {
2293 	struct wpabuf *msg;
2294 	struct dpp_pkex *pkex = hapd->dpp_pkex;
2295 	struct dpp_bootstrap_info *bi;
2296 
2297 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
2298 		   MAC2STR(src));
2299 
2300 	if (!pkex || pkex->initiator || !pkex->exchange_done) {
2301 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2302 		return;
2303 	}
2304 
2305 	msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
2306 	if (!msg) {
2307 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
2308 		if (hapd->dpp_pkex->failed) {
2309 			wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
2310 			if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2311 				hapd->dpp_pkex->own_bi->pkex_t =
2312 					hapd->dpp_pkex->t;
2313 			dpp_pkex_free(hapd->dpp_pkex);
2314 			hapd->dpp_pkex = NULL;
2315 		}
2316 		return;
2317 	}
2318 
2319 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
2320 		   MACSTR, MAC2STR(src));
2321 
2322 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2323 		" freq=%u type=%d", MAC2STR(src), freq,
2324 		DPP_PA_PKEX_COMMIT_REVEAL_RESP);
2325 	hostapd_drv_send_action(hapd, freq, 0, src,
2326 				wpabuf_head(msg), wpabuf_len(msg));
2327 	wpabuf_free(msg);
2328 
2329 	hostapd_dpp_pkex_clear_code(hapd);
2330 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
2331 	if (!bi)
2332 		return;
2333 	hapd->dpp_pkex = NULL;
2334 }
2335 
2336 
2337 static void
2338 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
2339 				       const u8 *hdr, const u8 *buf, size_t len,
2340 				       unsigned int freq)
2341 {
2342 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2343 	int res;
2344 	struct dpp_bootstrap_info *bi;
2345 	struct dpp_pkex *pkex = hapd->dpp_pkex;
2346 	char cmd[500];
2347 
2348 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
2349 		   MAC2STR(src));
2350 
2351 	if (!pkex || !pkex->initiator || !pkex->exchange_done) {
2352 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2353 		return;
2354 	}
2355 
2356 	res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
2357 	if (res < 0) {
2358 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2359 		return;
2360 	}
2361 
2362 	hostapd_dpp_pkex_clear_code(hapd);
2363 	bi = dpp_pkex_finish(ifaces->dpp, pkex, src, freq);
2364 	if (!bi)
2365 		return;
2366 	hapd->dpp_pkex = NULL;
2367 
2368 #ifdef CONFIG_DPP3
2369 	if (ifaces->dpp_pb_bi &&
2370 	    os_memcmp(bi->pubkey_hash_chirp, ifaces->dpp_pb_resp_hash,
2371 		      SHA256_MAC_LEN) != 0) {
2372 		char id[20];
2373 
2374 		wpa_printf(MSG_INFO,
2375 			   "DPP: Peer bootstrap key from PKEX does not match PB announcement hash");
2376 		wpa_hexdump(MSG_DEBUG,
2377 			    "DPP: Peer provided bootstrap key hash(chirp) from PB PKEX",
2378 			    bi->pubkey_hash_chirp, SHA256_MAC_LEN);
2379 		wpa_hexdump(MSG_DEBUG,
2380 			    "DPP: Peer provided bootstrap key hash(chirp) from PB announcement",
2381 			    ifaces->dpp_pb_resp_hash, SHA256_MAC_LEN);
2382 
2383 		os_snprintf(id, sizeof(id), "%u", bi->id);
2384 		dpp_bootstrap_remove(ifaces->dpp, id);
2385 		hostapd_dpp_push_button_stop(hapd);
2386 		return;
2387 	}
2388 #endif /* CONFIG_DPP3 */
2389 
2390 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
2391 		    bi->id,
2392 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
2393 	wpa_printf(MSG_DEBUG,
2394 		   "DPP: Start authentication after PKEX with parameters: %s",
2395 		   cmd);
2396 	if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
2397 		wpa_printf(MSG_DEBUG,
2398 			   "DPP: Authentication initialization failed");
2399 		return;
2400 	}
2401 }
2402 
2403 
2404 #ifdef CONFIG_DPP3
2405 
2406 static void hostapd_dpp_pb_pkex_init(struct hostapd_data *hapd,
2407 				     unsigned int freq, const u8 *src,
2408 				     const u8 *r_hash)
2409 {
2410 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2411 	struct dpp_pkex *pkex;
2412 	struct wpabuf *msg;
2413 	char ssid_hex[2 * SSID_MAX_LEN + 1], *pass_hex = NULL;
2414 	char cmd[300];
2415 	const char *password = NULL;
2416 #ifdef CONFIG_SAE
2417 	struct sae_password_entry *e;
2418 #endif /* CONFIG_SAE */
2419 	int conf_id = -1;
2420 	bool sae = false, psk = false;
2421 	size_t len;
2422 
2423 	if (hapd->dpp_pkex) {
2424 		wpa_printf(MSG_DEBUG,
2425 			   "PDP: Sending previously generated PKEX Exchange Request to "
2426 			   MACSTR, MAC2STR(src));
2427 		msg = hapd->dpp_pkex->exchange_req;
2428 		hostapd_drv_send_action(hapd, freq, 0, src,
2429 					wpabuf_head(msg), wpabuf_len(msg));
2430 		return;
2431 	}
2432 
2433 	wpa_printf(MSG_DEBUG, "DPP: Initiate PKEX for push button with "
2434 		   MACSTR, MAC2STR(src));
2435 
2436 	hapd->dpp_pkex_bi = ifaces->dpp_pb_bi;
2437 	os_memcpy(ifaces->dpp_pb_resp_hash, r_hash, SHA256_MAC_LEN);
2438 
2439 	pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
2440 			     "PBPKEX", (const char *) ifaces->dpp_pb_c_nonce,
2441 			     ifaces->dpp_pb_bi->curve->nonce_len,
2442 			     true);
2443 	if (!pkex) {
2444 		hostapd_dpp_push_button_stop(hapd);
2445 		return;
2446 	}
2447 	pkex->freq = freq;
2448 
2449 	hapd->dpp_pkex = pkex;
2450 	msg = hapd->dpp_pkex->exchange_req;
2451 
2452 	if (ifaces->dpp_pb_cmd) {
2453 		/* Use the externally provided configuration */
2454 		os_free(hapd->dpp_pkex_auth_cmd);
2455 		len = 30 + os_strlen(ifaces->dpp_pb_cmd);
2456 		hapd->dpp_pkex_auth_cmd = os_malloc(len);
2457 		if (!hapd->dpp_pkex_auth_cmd) {
2458 			hostapd_dpp_push_button_stop(hapd);
2459 			return;
2460 		}
2461 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2462 			    hapd->dpp_pkex_bi->id, ifaces->dpp_pb_cmd);
2463 		goto send_frame;
2464 	}
2465 
2466 	/* Build config based on the current AP configuration */
2467 	wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
2468 			 (const u8 *) hapd->conf->ssid.ssid,
2469 			 hapd->conf->ssid.ssid_len);
2470 
2471 	if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
2472 		/* TODO: If a local Configurator has been enabled, allow a
2473 		 * DPP AKM credential to be provisioned by setting conf_id. */
2474 	}
2475 
2476 	if (hapd->conf->wpa & WPA_PROTO_RSN) {
2477 		psk = hapd->conf->wpa_key_mgmt & (WPA_KEY_MGMT_PSK |
2478 						  WPA_KEY_MGMT_PSK_SHA256);
2479 #ifdef CONFIG_SAE
2480 		sae = hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE;
2481 #endif /* CONFIG_SAE */
2482 	}
2483 
2484 #ifdef CONFIG_SAE
2485 	for (e = hapd->conf->sae_passwords; sae && e && !password;
2486 	     e = e->next) {
2487 		if (e->identifier || !is_broadcast_ether_addr(e->peer_addr))
2488 			continue;
2489 		password = e->password;
2490 	}
2491 #endif /* CONFIG_SAE */
2492 	if (!password && hapd->conf->ssid.wpa_passphrase_set &&
2493 	    hapd->conf->ssid.wpa_passphrase)
2494 		password = hapd->conf->ssid.wpa_passphrase;
2495 	if (password) {
2496 		len = 2 * os_strlen(password) + 1;
2497 		pass_hex = os_malloc(len);
2498 		if (!pass_hex) {
2499 			hostapd_dpp_push_button_stop(hapd);
2500 			return;
2501 		}
2502 		wpa_snprintf_hex(pass_hex, len, (const u8 *) password,
2503 				 os_strlen(password));
2504 	}
2505 
2506 	if (conf_id > 0 && sae && psk && pass_hex) {
2507 		os_snprintf(cmd, sizeof(cmd),
2508 			    "conf=sta-dpp+psk+sae configurator=%d ssid=%s pass=%s",
2509 			    conf_id, ssid_hex, pass_hex);
2510 	} else if (conf_id > 0 && sae && pass_hex) {
2511 		os_snprintf(cmd, sizeof(cmd),
2512 			    "conf=sta-dpp+sae configurator=%d ssid=%s pass=%s",
2513 			    conf_id, ssid_hex, pass_hex);
2514 	} else if (conf_id > 0) {
2515 		os_snprintf(cmd, sizeof(cmd),
2516 			    "conf=sta-dpp configurator=%d ssid=%s",
2517 			    conf_id, ssid_hex);
2518 	} if (sae && psk && pass_hex) {
2519 		os_snprintf(cmd, sizeof(cmd),
2520 			    "conf=sta-psk+sae ssid=%s pass=%s",
2521 			    ssid_hex, pass_hex);
2522 	} else if (sae && pass_hex) {
2523 		os_snprintf(cmd, sizeof(cmd),
2524 			    "conf=sta-sae ssid=%s pass=%s",
2525 			    ssid_hex, pass_hex);
2526 	} else if (psk && pass_hex) {
2527 		os_snprintf(cmd, sizeof(cmd),
2528 			    "conf=sta-psk ssid=%s pass=%s",
2529 			    ssid_hex, pass_hex);
2530 	} else {
2531 		wpa_printf(MSG_INFO,
2532 			   "DPP: Unsupported AP configuration for push button");
2533 		str_clear_free(pass_hex);
2534 		hostapd_dpp_push_button_stop(hapd);
2535 		return;
2536 	}
2537 	str_clear_free(pass_hex);
2538 
2539 	os_free(hapd->dpp_pkex_auth_cmd);
2540 	len = 30 + os_strlen(cmd);
2541 	hapd->dpp_pkex_auth_cmd = os_malloc(len);
2542 	if (hapd->dpp_pkex_auth_cmd)
2543 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2544 			    hapd->dpp_pkex_bi->id, cmd);
2545 	forced_memzero(cmd, sizeof(cmd));
2546 	if (!hapd->dpp_pkex_auth_cmd) {
2547 		hostapd_dpp_push_button_stop(hapd);
2548 		return;
2549 	}
2550 
2551 send_frame:
2552 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2553 		" freq=%u type=%d", MAC2STR(src), freq,
2554 		DPP_PA_PKEX_EXCHANGE_REQ);
2555 	hostapd_drv_send_action(hapd, pkex->freq, 0, src,
2556 				wpabuf_head(msg), wpabuf_len(msg));
2557 	pkex->exch_req_wait_time = 2000;
2558 	pkex->exch_req_tries = 1;
2559 }
2560 
2561 
2562 static void
2563 hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data *hapd,
2564 					const u8 *src, const u8 *hdr,
2565 					const u8 *buf, size_t len,
2566 					unsigned int freq)
2567 {
2568 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2569 	const u8 *r_hash;
2570 	u16 r_hash_len;
2571 	unsigned int i;
2572 	bool found = false;
2573 	struct dpp_pb_info *info, *tmp;
2574 	struct os_reltime now, age;
2575 	struct wpabuf *msg;
2576 
2577 	if (!ifaces)
2578 		return;
2579 
2580 	os_get_reltime(&now);
2581 	wpa_printf(MSG_DEBUG, "DPP: Push Button Presence Announcement from "
2582 		   MACSTR, MAC2STR(src));
2583 
2584 	r_hash = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
2585 			      &r_hash_len);
2586 	if (!r_hash || r_hash_len != SHA256_MAC_LEN) {
2587 		wpa_printf(MSG_DEBUG,
2588 			   "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
2589 		return;
2590 	}
2591 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
2592 		    r_hash, r_hash_len);
2593 
2594 	for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2595 		info = &ifaces->dpp_pb[i];
2596 		if ((info->rx_time.sec == 0 && info->rx_time.usec == 0) ||
2597 		    os_memcmp(r_hash, info->hash, SHA256_MAC_LEN) != 0)
2598 			continue;
2599 		wpa_printf(MSG_DEBUG,
2600 			   "DPP: Active push button Enrollee already known");
2601 		found = true;
2602 		info->rx_time = now;
2603 	}
2604 
2605 	if (!found) {
2606 		for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2607 			tmp = &ifaces->dpp_pb[i];
2608 			if (tmp->rx_time.sec == 0 && tmp->rx_time.usec == 0)
2609 				continue;
2610 
2611 			if (os_reltime_expired(&now, &tmp->rx_time, 120)) {
2612 				wpa_hexdump(MSG_DEBUG,
2613 					    "DPP: Push button Enrollee hash expired",
2614 					    tmp->hash, SHA256_MAC_LEN);
2615 				tmp->rx_time.sec = 0;
2616 				tmp->rx_time.usec = 0;
2617 				continue;
2618 			}
2619 
2620 			wpa_hexdump(MSG_DEBUG,
2621 				    "DPP: Push button session overlap with hash",
2622 				    tmp->hash, SHA256_MAC_LEN);
2623 			if (!ifaces->dpp_pb_result_indicated &&
2624 			    hostapd_dpp_pb_active(hapd)) {
2625 				wpa_msg(hapd->msg_ctx, MSG_INFO,
2626 					DPP_EVENT_PB_RESULT "session-overlap");
2627 				ifaces->dpp_pb_result_indicated = true;
2628 			}
2629 			hostapd_dpp_push_button_stop(hapd);
2630 			return;
2631 		}
2632 
2633 		/* Replace the oldest entry */
2634 		info = &ifaces->dpp_pb[0];
2635 		for (i = 1; i < DPP_PB_INFO_COUNT; i++) {
2636 			tmp = &ifaces->dpp_pb[i];
2637 			if (os_reltime_before(&tmp->rx_time, &info->rx_time))
2638 				info = tmp;
2639 		}
2640 		wpa_printf(MSG_DEBUG, "DPP: New active push button Enrollee");
2641 		os_memcpy(info->hash, r_hash, SHA256_MAC_LEN);
2642 		info->rx_time = now;
2643 	}
2644 
2645 	if (!hostapd_dpp_pb_active(hapd)) {
2646 		wpa_printf(MSG_DEBUG,
2647 			   "DPP: Discard message since own push button has not been pressed");
2648 		return;
2649 	}
2650 
2651 	if (ifaces->dpp_pb_announce_time.sec == 0 &&
2652 	    ifaces->dpp_pb_announce_time.usec == 0) {
2653 		/* Start a wait before allowing PKEX to be initiated */
2654 		ifaces->dpp_pb_announce_time = now;
2655 	}
2656 
2657 	if (!ifaces->dpp_pb_bi) {
2658 		int res;
2659 
2660 		res = dpp_bootstrap_gen(ifaces->dpp, "type=pkex");
2661 		if (res < 0)
2662 			return;
2663 		ifaces->dpp_pb_bi = dpp_bootstrap_get_id(ifaces->dpp, res);
2664 		if (!ifaces->dpp_pb_bi)
2665 			return;
2666 
2667 		if (random_get_bytes(ifaces->dpp_pb_c_nonce,
2668 				     ifaces->dpp_pb_bi->curve->nonce_len)) {
2669 			wpa_printf(MSG_ERROR,
2670 				   "DPP: Failed to generate C-nonce");
2671 			hostapd_dpp_push_button_stop(hapd);
2672 			return;
2673 		}
2674 	}
2675 
2676 	/* Skip the response if one was sent within last 50 ms since the
2677 	 * Enrollee is going to send out at least three announcement messages.
2678 	 */
2679 	os_reltime_sub(&now, &ifaces->dpp_pb_last_resp, &age);
2680 	if (age.sec == 0 && age.usec < 50000) {
2681 		wpa_printf(MSG_DEBUG,
2682 			   "DPP: Skip Push Button Presence Announcement Response frame immediately after having sent one");
2683 		return;
2684 	}
2685 
2686 	msg = dpp_build_pb_announcement_resp(
2687 		ifaces->dpp_pb_bi, r_hash, ifaces->dpp_pb_c_nonce,
2688 		ifaces->dpp_pb_bi->curve->nonce_len);
2689 	if (!msg) {
2690 		hostapd_dpp_push_button_stop(hapd);
2691 		return;
2692 	}
2693 
2694 	wpa_printf(MSG_DEBUG,
2695 		   "DPP: Send Push Button Presence Announcement Response to "
2696 		   MACSTR, MAC2STR(src));
2697 	ifaces->dpp_pb_last_resp = now;
2698 
2699 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2700 		" freq=%u type=%d", MAC2STR(src), freq,
2701 		DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP);
2702 	hostapd_drv_send_action(hapd, freq, 0, src,
2703 				wpabuf_head(msg), wpabuf_len(msg));
2704 	wpabuf_free(msg);
2705 
2706 	if (os_reltime_expired(&now, &ifaces->dpp_pb_announce_time, 15))
2707 		hostapd_dpp_pb_pkex_init(hapd, freq, src, r_hash);
2708 }
2709 
2710 
2711 static void
2712 hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data *hapd, const u8 *src,
2713 				     const u8 *hdr, const u8 *buf, size_t len,
2714 				     unsigned int freq)
2715 {
2716 	const u8 *trans_id, *version;
2717 	u16 trans_id_len, version_len;
2718 	struct wpabuf *msg;
2719 	u8 ver = DPP_VERSION;
2720 	int conn_ver;
2721 
2722 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Query from "
2723 		   MACSTR, MAC2STR(src));
2724 
2725 	if (!hapd_dpp_connector_available(hapd))
2726 		return;
2727 
2728 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2729 			       &trans_id_len);
2730 	if (!trans_id || trans_id_len != 1) {
2731 		wpa_printf(MSG_DEBUG,
2732 			   "DPP: Peer did not include Transaction ID");
2733 		return;
2734 	}
2735 
2736 	version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2737 			       &version_len);
2738 	if (!version || version_len != 1) {
2739 		wpa_printf(MSG_DEBUG,
2740 			   "DPP: Peer did not include Protocol Version");
2741 		return;
2742 	}
2743 
2744 	wpa_printf(MSG_DEBUG, "DPP: Transaction ID %u, Version %u",
2745 		   trans_id[0], version[0]);
2746 
2747 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
2748 	msg = dpp_alloc_msg(DPP_PA_PRIV_PEER_INTRO_NOTIFY, len);
2749 	if (!msg)
2750 		return;
2751 
2752 	/* Transaction ID */
2753 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
2754 	wpabuf_put_le16(msg, 1);
2755 	wpabuf_put_u8(msg, trans_id[0]);
2756 
2757 	/* Protocol Version */
2758 	conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
2759 	if (conn_ver > 0 && ver != conn_ver) {
2760 		wpa_printf(MSG_DEBUG,
2761 			   "DPP: Use Connector version %d instead of current protocol version %d",
2762 			   conn_ver, ver);
2763 		ver = conn_ver;
2764 	}
2765 	wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2766 	wpabuf_put_le16(msg, 1);
2767 	wpabuf_put_u8(msg, ver);
2768 
2769 	/* DPP Connector */
2770 	wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
2771 	wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
2772 	wpabuf_put_str(msg, hapd->conf->dpp_connector);
2773 
2774 	wpa_printf(MSG_DEBUG, "DPP: Send Private Peer Introduction Notify to "
2775 		   MACSTR, MAC2STR(src));
2776 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2777 		" freq=%u type=%d", MAC2STR(src), freq,
2778 		DPP_PA_PRIV_PEER_INTRO_NOTIFY);
2779 	hostapd_drv_send_action(hapd, freq, 0, src,
2780 				wpabuf_head(msg), wpabuf_len(msg));
2781 	wpabuf_free(msg);
2782 }
2783 
2784 
2785 static void
2786 hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data *hapd, const u8 *src,
2787 				      const u8 *hdr, const u8 *buf, size_t len,
2788 				      unsigned int freq)
2789 {
2790 	struct crypto_ec_key *own_key;
2791 	const struct dpp_curve_params *curve;
2792 	enum hpke_kem_id kem_id;
2793 	enum hpke_kdf_id kdf_id;
2794 	enum hpke_aead_id aead_id;
2795 	const u8 *aad = hdr;
2796 	size_t aad_len = DPP_HDR_LEN;
2797 	struct wpabuf *pt;
2798 	const u8 *trans_id, *wrapped, *version, *connector;
2799 	u16 trans_id_len, wrapped_len, version_len, connector_len;
2800 	struct os_time now;
2801 	struct dpp_introduction intro;
2802 	os_time_t expire;
2803 	int expiration;
2804 	enum dpp_status_error res;
2805 	u8 pkhash[SHA256_MAC_LEN];
2806 
2807 	os_memset(&intro, 0, sizeof(intro));
2808 
2809 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Update from "
2810 		   MACSTR, MAC2STR(src));
2811 
2812 	if (!hapd_dpp_connector_available(hapd))
2813 		return;
2814 
2815 	os_get_time(&now);
2816 
2817 	if (hapd->conf->dpp_netaccesskey_expiry &&
2818 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2819 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2820 		return;
2821 	}
2822 
2823 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2824 			       &trans_id_len);
2825 	if (!trans_id || trans_id_len != 1) {
2826 		wpa_printf(MSG_DEBUG,
2827 			   "DPP: Peer did not include Transaction ID");
2828 		return;
2829 	}
2830 
2831 	wrapped = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
2832 			       &wrapped_len);
2833 	if (!wrapped) {
2834 		wpa_printf(MSG_DEBUG, "DPP: Peer did not include Wrapped Data");
2835 		return;
2836 	}
2837 
2838 	own_key = dpp_set_keypair(&curve,
2839 				  wpabuf_head(hapd->conf->dpp_netaccesskey),
2840 				  wpabuf_len(hapd->conf->dpp_netaccesskey));
2841 	if (!own_key) {
2842 		wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
2843 		return;
2844 	}
2845 
2846 	if (dpp_hpke_suite(curve->ike_group, &kem_id, &kdf_id, &aead_id) < 0) {
2847 		wpa_printf(MSG_ERROR, "DPP: Unsupported curve %d",
2848 			   curve->ike_group);
2849 		crypto_ec_key_deinit(own_key);
2850 		return;
2851 	}
2852 
2853 	pt = hpke_base_open(kem_id, kdf_id, aead_id, own_key, NULL, 0,
2854 			    aad, aad_len, wrapped, wrapped_len);
2855 	crypto_ec_key_deinit(own_key);
2856 	if (!pt) {
2857 		wpa_printf(MSG_INFO, "DPP: Failed to decrypt Connector");
2858 		return;
2859 	}
2860 	wpa_hexdump_buf(MSG_MSGDUMP, "DPP: HPKE-Decrypted Wrapped Data", pt);
2861 
2862 	connector = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2863 				 DPP_ATTR_CONNECTOR, &connector_len);
2864 	if (!connector) {
2865 		wpa_printf(MSG_DEBUG,
2866 			   "DPP: Peer did not include its Connector");
2867 		goto done;
2868 	}
2869 
2870 	version = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2871 			       DPP_ATTR_PROTOCOL_VERSION, &version_len);
2872 	if (!version || version_len < 1) {
2873 		wpa_printf(MSG_DEBUG,
2874 			   "DPP: Peer did not include Protocol Version");
2875 		goto done;
2876 	}
2877 
2878 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2879 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
2880 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
2881 			     wpabuf_head(hapd->conf->dpp_csign),
2882 			     wpabuf_len(hapd->conf->dpp_csign),
2883 			     connector, connector_len, &expire, pkhash);
2884 	if (res == 255) {
2885 		wpa_printf(MSG_INFO,
2886 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
2887 			   MACSTR ")", MAC2STR(src));
2888 		goto done;
2889 	}
2890 	if (res != DPP_STATUS_OK) {
2891 		wpa_printf(MSG_INFO,
2892 			   "DPP: Network Introduction protocol resulted in failure (peer "
2893 			   MACSTR " status %d)", MAC2STR(src), res);
2894 		goto done;
2895 	}
2896 
2897 	if (intro.peer_version && intro.peer_version >= 2) {
2898 		u8 attr_version = 1;
2899 
2900 		if (version && version_len >= 1)
2901 			attr_version = version[0];
2902 		if (attr_version != intro.peer_version) {
2903 			wpa_printf(MSG_INFO,
2904 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2905 				   intro.peer_version, attr_version);
2906 			goto done;
2907 		}
2908 	}
2909 
2910 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2911 		expire = hapd->conf->dpp_netaccesskey_expiry;
2912 	if (expire)
2913 		expiration = expire - now.sec;
2914 	else
2915 		expiration = 0;
2916 
2917 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2918 				intro.pmkid, expiration,
2919 				WPA_KEY_MGMT_DPP, pkhash) < 0) {
2920 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2921 		goto done;
2922 	}
2923 
2924 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction completed with "
2925 		   MACSTR, MAC2STR(src));
2926 
2927 done:
2928 	dpp_peer_intro_deinit(&intro);
2929 	wpabuf_free(pt);
2930 }
2931 
2932 #endif /* CONFIG_DPP3 */
2933 
2934 
2935 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
2936 			   const u8 *buf, size_t len, unsigned int freq)
2937 {
2938 	u8 crypto_suite;
2939 	enum dpp_public_action_frame_type type;
2940 	const u8 *hdr;
2941 	unsigned int pkex_t;
2942 
2943 	if (len < DPP_HDR_LEN)
2944 		return;
2945 	if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
2946 		return;
2947 	hdr = buf;
2948 	buf += 4;
2949 	len -= 4;
2950 	crypto_suite = *buf++;
2951 	type = *buf++;
2952 	len -= 2;
2953 
2954 	wpa_printf(MSG_DEBUG,
2955 		   "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2956 		   MACSTR " freq=%u",
2957 		   crypto_suite, type, MAC2STR(src), freq);
2958 	if (crypto_suite != 1) {
2959 		wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
2960 			   crypto_suite);
2961 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2962 			" freq=%u type=%d ignore=unsupported-crypto-suite",
2963 			MAC2STR(src), freq, type);
2964 		return;
2965 	}
2966 	wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
2967 	if (dpp_check_attrs(buf, len) < 0) {
2968 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2969 			" freq=%u type=%d ignore=invalid-attributes",
2970 			MAC2STR(src), freq, type);
2971 		return;
2972 	}
2973 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2974 		" freq=%u type=%d", MAC2STR(src), freq, type);
2975 
2976 #ifdef CONFIG_DPP2
2977 	if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2978 				src, hdr, buf, len, freq, NULL, NULL,
2979 				hapd) == 0)
2980 		return;
2981 #endif /* CONFIG_DPP2 */
2982 
2983 	switch (type) {
2984 	case DPP_PA_AUTHENTICATION_REQ:
2985 		hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
2986 		break;
2987 	case DPP_PA_AUTHENTICATION_RESP:
2988 		hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
2989 		break;
2990 	case DPP_PA_AUTHENTICATION_CONF:
2991 		hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
2992 		break;
2993 	case DPP_PA_PEER_DISCOVERY_REQ:
2994 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
2995 		break;
2996 #ifdef CONFIG_DPP3
2997 	case DPP_PA_PKEX_EXCHANGE_REQ:
2998 		/* This is for PKEXv2, but for now, process only with
2999 		 * CONFIG_DPP3 to avoid issues with a capability that has not
3000 		 * been tested with other implementations. */
3001 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3002 						 true);
3003 		break;
3004 #endif /* CONFIG_DPP3 */
3005 	case DPP_PA_PKEX_V1_EXCHANGE_REQ:
3006 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3007 						 false);
3008 		break;
3009 	case DPP_PA_PKEX_EXCHANGE_RESP:
3010 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
3011 		break;
3012 	case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
3013 		hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
3014 						      freq);
3015 		break;
3016 	case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
3017 		hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
3018 						       freq);
3019 		break;
3020 #ifdef CONFIG_DPP2
3021 	case DPP_PA_CONFIGURATION_RESULT:
3022 		hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
3023 		break;
3024 	case DPP_PA_CONNECTION_STATUS_RESULT:
3025 		hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
3026 		break;
3027 	case DPP_PA_PRESENCE_ANNOUNCEMENT:
3028 		hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
3029 						     freq);
3030 		break;
3031 	case DPP_PA_RECONFIG_ANNOUNCEMENT:
3032 		hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
3033 						     freq);
3034 		break;
3035 	case DPP_PA_RECONFIG_AUTH_RESP:
3036 		hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
3037 						  freq);
3038 		break;
3039 #endif /* CONFIG_DPP2 */
3040 #ifdef CONFIG_DPP3
3041 	case DPP_PA_PB_PRESENCE_ANNOUNCEMENT:
3042 		hostapd_dpp_rx_pb_presence_announcement(hapd, src, hdr,
3043 							buf, len, freq);
3044 		break;
3045 	case DPP_PA_PRIV_PEER_INTRO_QUERY:
3046 		hostapd_dpp_rx_priv_peer_intro_query(hapd, src, hdr,
3047 						     buf, len, freq);
3048 		break;
3049 	case DPP_PA_PRIV_PEER_INTRO_UPDATE:
3050 		hostapd_dpp_rx_priv_peer_intro_update(hapd, src, hdr,
3051 						      buf, len, freq);
3052 		break;
3053 #endif /* CONFIG_DPP3 */
3054 	default:
3055 		wpa_printf(MSG_DEBUG,
3056 			   "DPP: Ignored unsupported frame subtype %d", type);
3057 		break;
3058 	}
3059 
3060 	if (hapd->dpp_pkex)
3061 		pkex_t = hapd->dpp_pkex->t;
3062 	else if (hapd->dpp_pkex_bi)
3063 		pkex_t = hapd->dpp_pkex_bi->pkex_t;
3064 	else
3065 		pkex_t = 0;
3066 	if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
3067 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
3068 		hostapd_dpp_pkex_remove(hapd, "*");
3069 	}
3070 }
3071 
3072 
3073 struct wpabuf *
3074 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
3075 			    const u8 *query, size_t query_len,
3076 			    const u8 *data, size_t data_len)
3077 {
3078 	struct dpp_authentication *auth = hapd->dpp_auth;
3079 	struct wpabuf *resp;
3080 
3081 	wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
3082 	if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
3083 	    !ether_addr_equal(sa, auth->peer_mac_addr)) {
3084 #ifdef CONFIG_DPP2
3085 		if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
3086 				     data_len) == 0) {
3087 			/* Response will be forwarded once received over TCP */
3088 			return NULL;
3089 		}
3090 #endif /* CONFIG_DPP2 */
3091 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
3092 		return NULL;
3093 	}
3094 
3095 	if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
3096 		wpa_printf(MSG_DEBUG,
3097 			   "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
3098 		/* hostapd_dpp_auth_success() would normally have been called
3099 		 * from TX status handler, but since there was no such handler
3100 		 * call yet, simply send out the event message and proceed with
3101 		 * exchange. */
3102 		dpp_notify_auth_success(hapd->dpp_auth, 1);
3103 		hapd->dpp_auth_ok_on_ack = 0;
3104 #ifdef CONFIG_TESTING_OPTIONS
3105 		if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
3106 			wpa_printf(MSG_INFO,
3107 				   "DPP: TESTING - stop at Authentication Confirm");
3108 			return NULL;
3109 		}
3110 #endif /* CONFIG_TESTING_OPTIONS */
3111 	}
3112 
3113 	wpa_hexdump(MSG_DEBUG,
3114 		    "DPP: Received Configuration Request (GAS Query Request)",
3115 		    query, query_len);
3116 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
3117 		MAC2STR(sa));
3118 	resp = dpp_conf_req_rx(auth, query, query_len);
3119 	if (!resp)
3120 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3121 	return resp;
3122 }
3123 
3124 
3125 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
3126 {
3127 	struct dpp_authentication *auth = hapd->dpp_auth;
3128 #ifdef CONFIG_DPP3
3129 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3130 #endif /* CONFIG_DPP3 */
3131 
3132 	if (!auth)
3133 		return;
3134 
3135 #ifdef CONFIG_DPP3
3136 	if (auth->waiting_new_key && ok) {
3137 		wpa_printf(MSG_DEBUG, "DPP: Waiting for a new key");
3138 		return;
3139 	}
3140 #endif /* CONFIG_DPP3 */
3141 
3142 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
3143 		   ok);
3144 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3145 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3146 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3147 #ifdef CONFIG_DPP2
3148 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3149 				     hapd, NULL);
3150 	if (ok && auth->peer_version >= 2 &&
3151 	    auth->conf_resp_status == DPP_STATUS_OK) {
3152 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
3153 		auth->waiting_conf_result = 1;
3154 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
3155 				     hapd, NULL);
3156 		eloop_register_timeout(2, 0,
3157 				       hostapd_dpp_config_result_wait_timeout,
3158 				       hapd, NULL);
3159 		return;
3160 	}
3161 #endif /* CONFIG_DPP2 */
3162 	hostapd_drv_send_action_cancel_wait(hapd);
3163 
3164 	if (ok)
3165 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
3166 			"conf_status=%d", auth->conf_resp_status);
3167 	else
3168 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3169 	dpp_auth_deinit(hapd->dpp_auth);
3170 	hapd->dpp_auth = NULL;
3171 #ifdef CONFIG_DPP3
3172 	if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
3173 		if (ok)
3174 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3175 				"success");
3176 		else
3177 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3178 				"could-not-connect");
3179 		ifaces->dpp_pb_result_indicated = true;
3180 		if (ok)
3181 			hostapd_dpp_remove_pb_hash(hapd);
3182 		hostapd_dpp_push_button_stop(hapd);
3183 	}
3184 #endif /* CONFIG_DPP3 */
3185 }
3186 
3187 
3188 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
3189 {
3190 	struct dpp_authentication *auth;
3191 	int ret = -1;
3192 	char *curve = NULL;
3193 
3194 	auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
3195 	if (!auth)
3196 		return -1;
3197 
3198 	curve = get_param(cmd, " curve=");
3199 	hostapd_dpp_set_testing_options(hapd, auth);
3200 	if (dpp_set_configurator(auth, cmd) == 0 &&
3201 	    dpp_configurator_own_config(auth, curve, 1) == 0) {
3202 		hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
3203 		ret = 0;
3204 	}
3205 
3206 	dpp_auth_deinit(auth);
3207 	os_free(curve);
3208 
3209 	return ret;
3210 }
3211 
3212 
3213 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
3214 {
3215 	struct dpp_bootstrap_info *own_bi;
3216 	const char *pos, *end;
3217 #ifdef CONFIG_DPP3
3218 		enum dpp_pkex_ver ver = PKEX_VER_AUTO;
3219 #else /* CONFIG_DPP3 */
3220 		enum dpp_pkex_ver ver = PKEX_VER_ONLY_1;
3221 #endif /* CONFIG_DPP3 */
3222 	int tcp_port = DPP_TCP_PORT;
3223 	struct hostapd_ip_addr *ipaddr = NULL;
3224 #ifdef CONFIG_DPP2
3225 	struct hostapd_ip_addr ipaddr_buf;
3226 	char *addr;
3227 
3228 	pos = os_strstr(cmd, " tcp_port=");
3229 	if (pos) {
3230 		pos += 10;
3231 		tcp_port = atoi(pos);
3232 	}
3233 
3234 	addr = get_param(cmd, " tcp_addr=");
3235 	if (addr) {
3236 		int res;
3237 
3238 		res = hostapd_parse_ip_addr(addr, &ipaddr_buf);
3239 		os_free(addr);
3240 		if (res)
3241 			return -1;
3242 		ipaddr = &ipaddr_buf;
3243 	}
3244 #endif /* CONFIG_DPP2 */
3245 
3246 	pos = os_strstr(cmd, " own=");
3247 	if (!pos)
3248 		return -1;
3249 	pos += 5;
3250 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3251 	if (!own_bi) {
3252 		wpa_printf(MSG_DEBUG,
3253 			   "DPP: Identified bootstrap info not found");
3254 		return -1;
3255 	}
3256 	if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
3257 		wpa_printf(MSG_DEBUG,
3258 			   "DPP: Identified bootstrap info not for PKEX");
3259 		return -1;
3260 	}
3261 	hapd->dpp_pkex_bi = own_bi;
3262 	own_bi->pkex_t = 0; /* clear pending errors on new code */
3263 
3264 	os_free(hapd->dpp_pkex_identifier);
3265 	hapd->dpp_pkex_identifier = NULL;
3266 	pos = os_strstr(cmd, " identifier=");
3267 	if (pos) {
3268 		pos += 12;
3269 		end = os_strchr(pos, ' ');
3270 		if (!end)
3271 			return -1;
3272 		hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
3273 		if (!hapd->dpp_pkex_identifier)
3274 			return -1;
3275 		os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
3276 		hapd->dpp_pkex_identifier[end - pos] = '\0';
3277 	}
3278 
3279 	pos = os_strstr(cmd, " code=");
3280 	if (!pos)
3281 		return -1;
3282 	os_free(hapd->dpp_pkex_code);
3283 	hapd->dpp_pkex_code = os_strdup(pos + 6);
3284 	if (!hapd->dpp_pkex_code)
3285 		return -1;
3286 	hapd->dpp_pkex_code_len = os_strlen(hapd->dpp_pkex_code);
3287 
3288 	pos = os_strstr(cmd, " ver=");
3289 	if (pos) {
3290 		int v;
3291 
3292 		pos += 5;
3293 		v = atoi(pos);
3294 		if (v == 1)
3295 			ver = PKEX_VER_ONLY_1;
3296 		else if (v == 2)
3297 			ver = PKEX_VER_ONLY_2;
3298 		else
3299 			return -1;
3300 	}
3301 	hapd->dpp_pkex_ver = ver;
3302 
3303 	if (os_strstr(cmd, " init=1")) {
3304 		if (hostapd_dpp_pkex_init(hapd, ver, ipaddr, tcp_port) < 0)
3305 			return -1;
3306 	} else {
3307 #ifdef CONFIG_DPP2
3308 		dpp_controller_pkex_add(hapd->iface->interfaces->dpp, own_bi,
3309 					hapd->dpp_pkex_code,
3310 					hapd->dpp_pkex_identifier);
3311 #endif /* CONFIG_DPP2 */
3312 	}
3313 
3314 	/* TODO: Support multiple PKEX info entries */
3315 
3316 	os_free(hapd->dpp_pkex_auth_cmd);
3317 	hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
3318 
3319 	return 1;
3320 }
3321 
3322 
3323 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
3324 {
3325 	unsigned int id_val;
3326 
3327 	if (os_strcmp(id, "*") == 0) {
3328 		id_val = 0;
3329 	} else {
3330 		id_val = atoi(id);
3331 		if (id_val == 0)
3332 			return -1;
3333 	}
3334 
3335 	if ((id_val != 0 && id_val != 1))
3336 		return -1;
3337 
3338 	/* TODO: Support multiple PKEX entries */
3339 	os_free(hapd->dpp_pkex_code);
3340 	hapd->dpp_pkex_code = NULL;
3341 	os_free(hapd->dpp_pkex_identifier);
3342 	hapd->dpp_pkex_identifier = NULL;
3343 	os_free(hapd->dpp_pkex_auth_cmd);
3344 	hapd->dpp_pkex_auth_cmd = NULL;
3345 	hapd->dpp_pkex_bi = NULL;
3346 	/* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
3347 	dpp_pkex_free(hapd->dpp_pkex);
3348 	hapd->dpp_pkex = NULL;
3349 	return 0;
3350 }
3351 
3352 
3353 void hostapd_dpp_stop(struct hostapd_data *hapd)
3354 {
3355 	dpp_auth_deinit(hapd->dpp_auth);
3356 	hapd->dpp_auth = NULL;
3357 	dpp_pkex_free(hapd->dpp_pkex);
3358 	hapd->dpp_pkex = NULL;
3359 #ifdef CONFIG_DPP3
3360 	hostapd_dpp_push_button_stop(hapd);
3361 #endif /* CONFIG_DPP3 */
3362 }
3363 
3364 
3365 #ifdef CONFIG_DPP2
3366 
3367 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
3368 				 const u8 *msg, size_t len)
3369 {
3370 	struct hostapd_data *hapd = ctx;
3371 	u8 *buf;
3372 
3373 	if (freq == 0)
3374 		freq = hapd->iface->freq;
3375 
3376 	wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
3377 		   MAC2STR(addr), freq);
3378 	buf = os_malloc(2 + len);
3379 	if (!buf)
3380 		return;
3381 	buf[0] = WLAN_ACTION_PUBLIC;
3382 	buf[1] = WLAN_PA_VENDOR_SPECIFIC;
3383 	os_memcpy(buf + 2, msg, len);
3384 	hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
3385 	os_free(buf);
3386 }
3387 
3388 
3389 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
3390 					  u8 dialog_token, int prot,
3391 					  struct wpabuf *buf)
3392 {
3393 	struct hostapd_data *hapd = ctx;
3394 
3395 	gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf, 0);
3396 }
3397 
3398 #endif /* CONFIG_DPP2 */
3399 
3400 
3401 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
3402 {
3403 #ifdef CONFIG_DPP2
3404 	struct dpp_controller_conf *ctrl;
3405 	struct dpp_relay_config config;
3406 
3407 	os_memset(&config, 0, sizeof(config));
3408 	config.msg_ctx = hapd->msg_ctx;
3409 	config.cb_ctx = hapd;
3410 	config.tx = hostapd_dpp_relay_tx;
3411 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3412 	for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
3413 		config.ipaddr = &ctrl->ipaddr;
3414 		config.pkhash = ctrl->pkhash;
3415 		if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
3416 					     &config) < 0)
3417 			return -1;
3418 	}
3419 
3420 	if (hapd->conf->dpp_relay_port)
3421 		dpp_relay_listen(hapd->iface->interfaces->dpp,
3422 				 hapd->conf->dpp_relay_port,
3423 				 &config);
3424 #endif /* CONFIG_DPP2 */
3425 
3426 	return 0;
3427 }
3428 
3429 
3430 #ifdef CONFIG_DPP2
3431 
3432 int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd)
3433 {
3434 	struct dpp_relay_config config;
3435 	struct hostapd_ip_addr addr;
3436 	u8 pkhash[SHA256_MAC_LEN];
3437 	char *pos, *tmp;
3438 	int ret = -1;
3439 	bool prev_state, new_state;
3440 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3441 
3442 	tmp = os_strdup(cmd);
3443 	if (!tmp)
3444 		goto fail;
3445 	pos = os_strchr(tmp, ' ');
3446 	if (!pos)
3447 		goto fail;
3448 	*pos++ = '\0';
3449 	if (hostapd_parse_ip_addr(tmp, &addr) < 0 ||
3450 	    hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0)
3451 		goto fail;
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 	config.ipaddr = &addr;
3459 	config.pkhash = pkhash;
3460 	prev_state = dpp_relay_controller_available(dpp);
3461 	ret = dpp_relay_add_controller(dpp, &config);
3462 	new_state = dpp_relay_controller_available(dpp);
3463 	if (new_state != prev_state)
3464 		ieee802_11_update_beacons(hapd->iface);
3465 fail:
3466 	os_free(tmp);
3467 	return ret;
3468 }
3469 
3470 
3471 void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd)
3472 {
3473 	struct hostapd_ip_addr addr;
3474 	bool prev_state, new_state;
3475 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3476 
3477 	if (hostapd_parse_ip_addr(cmd, &addr) < 0)
3478 		return;
3479 	prev_state = dpp_relay_controller_available(dpp);
3480 	dpp_relay_remove_controller(dpp, &addr);
3481 	new_state = dpp_relay_controller_available(dpp);
3482 	if (new_state != prev_state)
3483 		ieee802_11_update_beacons(hapd->iface);
3484 }
3485 
3486 #endif /* CONFIG_DPP2 */
3487 
3488 
3489 int hostapd_dpp_init(struct hostapd_data *hapd)
3490 {
3491 	hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
3492 	hapd->dpp_init_done = 1;
3493 	return hostapd_dpp_add_controllers(hapd);
3494 }
3495 
3496 
3497 void hostapd_dpp_deinit(struct hostapd_data *hapd)
3498 {
3499 #ifdef CONFIG_TESTING_OPTIONS
3500 	os_free(hapd->dpp_config_obj_override);
3501 	hapd->dpp_config_obj_override = NULL;
3502 	os_free(hapd->dpp_discovery_override);
3503 	hapd->dpp_discovery_override = NULL;
3504 	os_free(hapd->dpp_groups_override);
3505 	hapd->dpp_groups_override = NULL;
3506 	hapd->dpp_ignore_netaccesskey_mismatch = 0;
3507 #endif /* CONFIG_TESTING_OPTIONS */
3508 	if (!hapd->dpp_init_done)
3509 		return;
3510 	eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
3511 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3512 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3513 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
3514 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3515 #ifdef CONFIG_DPP2
3516 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3517 			     hapd, NULL);
3518 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
3519 			     NULL);
3520 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
3521 			     NULL);
3522 	hostapd_dpp_chirp_stop(hapd);
3523 	if (hapd->iface->interfaces) {
3524 		dpp_relay_stop_listen(hapd->iface->interfaces->dpp);
3525 		dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
3526 	}
3527 #endif /* CONFIG_DPP2 */
3528 #ifdef CONFIG_DPP3
3529 	eloop_cancel_timeout(hostapd_dpp_build_new_key, hapd, NULL);
3530 	hostapd_dpp_push_button_stop(hapd);
3531 #endif /* CONFIG_DPP3 */
3532 	dpp_auth_deinit(hapd->dpp_auth);
3533 	hapd->dpp_auth = NULL;
3534 	hostapd_dpp_pkex_remove(hapd, "*");
3535 	hapd->dpp_pkex = NULL;
3536 	os_free(hapd->dpp_configurator_params);
3537 	hapd->dpp_configurator_params = NULL;
3538 	os_free(hapd->dpp_pkex_auth_cmd);
3539 	hapd->dpp_pkex_auth_cmd = NULL;
3540 }
3541 
3542 
3543 #ifdef CONFIG_DPP2
3544 
3545 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd)
3546 {
3547 	struct dpp_controller_config config;
3548 	const char *pos;
3549 
3550 	os_memset(&config, 0, sizeof(config));
3551 	config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
3552 	config.netrole = DPP_NETROLE_AP;
3553 	config.msg_ctx = hapd->msg_ctx;
3554 	config.cb_ctx = hapd;
3555 	config.process_conf_obj = hostapd_dpp_process_conf_obj;
3556 	if (cmd) {
3557 		pos = os_strstr(cmd, " tcp_port=");
3558 		if (pos) {
3559 			pos += 10;
3560 			config.tcp_port = atoi(pos);
3561 		}
3562 
3563 		pos = os_strstr(cmd, " role=");
3564 		if (pos) {
3565 			pos += 6;
3566 			if (os_strncmp(pos, "configurator", 12) == 0)
3567 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
3568 			else if (os_strncmp(pos, "enrollee", 8) == 0)
3569 				config.allowed_roles = DPP_CAPAB_ENROLLEE;
3570 			else if (os_strncmp(pos, "either", 6) == 0)
3571 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
3572 					DPP_CAPAB_ENROLLEE;
3573 			else
3574 				return -1;
3575 		}
3576 
3577 		config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
3578 	}
3579 	config.configurator_params = hapd->dpp_configurator_params;
3580 	return dpp_controller_start(hapd->iface->interfaces->dpp, &config);
3581 }
3582 
3583 
3584 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
3585 
3586 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
3587 {
3588 	struct hostapd_data *hapd = eloop_ctx;
3589 
3590 	wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
3591 	hostapd_drv_send_action_cancel_wait(hapd);
3592 	hostapd_dpp_chirp_next(hapd, NULL);
3593 }
3594 
3595 
3596 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
3597 {
3598 	struct wpabuf *msg;
3599 	int type;
3600 
3601 	msg = hapd->dpp_presence_announcement;
3602 	type = DPP_PA_PRESENCE_ANNOUNCEMENT;
3603 	wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
3604 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
3605 		" freq=%u type=%d",
3606 		MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
3607 	if (hostapd_drv_send_action(
3608 		    hapd, hapd->dpp_chirp_freq, 2000, broadcast,
3609 		    wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
3610 	    eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
3611 				   hapd, NULL) < 0)
3612 		hostapd_dpp_chirp_stop(hapd);
3613 }
3614 
3615 
3616 static struct hostapd_hw_modes *
3617 dpp_get_mode(struct hostapd_data *hapd,
3618 	     enum hostapd_hw_mode mode)
3619 {
3620 	struct hostapd_hw_modes *modes = hapd->iface->hw_features;
3621 	u16 num_modes = hapd->iface->num_hw_features;
3622 	u16 i;
3623 
3624 	for (i = 0; i < num_modes; i++) {
3625 		if (modes[i].mode != mode ||
3626 		    !modes[i].num_channels || !modes[i].channels)
3627 			continue;
3628 		return &modes[i];
3629 	}
3630 
3631 	return NULL;
3632 }
3633 
3634 
3635 static void
3636 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
3637 {
3638 	struct hostapd_data *hapd = iface->bss[0];
3639 	struct wpa_scan_results *scan_res;
3640 	struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
3641 	unsigned int i;
3642 	struct hostapd_hw_modes *mode;
3643 	int c;
3644 	bool chan6 = hapd->iface->hw_features == NULL;
3645 
3646 	if (!bi)
3647 		return;
3648 
3649 	hapd->dpp_chirp_scan_done = 1;
3650 
3651 	scan_res = hostapd_driver_get_scan_results(hapd);
3652 
3653 	os_free(hapd->dpp_chirp_freqs);
3654 	hapd->dpp_chirp_freqs = NULL;
3655 
3656 	/* Channels from own bootstrapping info */
3657 	if (bi) {
3658 		for (i = 0; i < bi->num_freq; i++)
3659 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3660 					     bi->freq[i]);
3661 	}
3662 
3663 	/* Preferred chirping channels */
3664 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
3665 	if (mode) {
3666 		for (c = 0; c < mode->num_channels; c++) {
3667 			struct hostapd_channel_data *chan = &mode->channels[c];
3668 
3669 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3670 					  HOSTAPD_CHAN_RADAR) ||
3671 			    chan->freq != 2437)
3672 				continue;
3673 			chan6 = true;
3674 			break;
3675 		}
3676 	}
3677 	if (chan6)
3678 		int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
3679 
3680 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
3681 	if (mode) {
3682 		int chan44 = 0, chan149 = 0;
3683 
3684 		for (c = 0; c < mode->num_channels; c++) {
3685 			struct hostapd_channel_data *chan = &mode->channels[c];
3686 
3687 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3688 					  HOSTAPD_CHAN_RADAR))
3689 				continue;
3690 			if (chan->freq == 5220)
3691 				chan44 = 1;
3692 			if (chan->freq == 5745)
3693 				chan149 = 1;
3694 		}
3695 		if (chan149)
3696 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
3697 		else if (chan44)
3698 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
3699 	}
3700 
3701 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
3702 	if (mode) {
3703 		for (c = 0; c < mode->num_channels; c++) {
3704 			struct hostapd_channel_data *chan = &mode->channels[c];
3705 
3706 			if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
3707 					   HOSTAPD_CHAN_RADAR)) ||
3708 			    chan->freq != 60480)
3709 				continue;
3710 			int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
3711 			break;
3712 		}
3713 	}
3714 
3715 	/* Add channels from scan results for APs that advertise Configurator
3716 	 * Connectivity element */
3717 	for (i = 0; scan_res && i < scan_res->num; i++) {
3718 		struct wpa_scan_res *bss = scan_res->res[i];
3719 		size_t ie_len = bss->ie_len;
3720 
3721 		if (!ie_len)
3722 			ie_len = bss->beacon_ie_len;
3723 		if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
3724 				  DPP_CC_IE_VENDOR_TYPE))
3725 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3726 					     bss->freq);
3727 	}
3728 
3729 	if (!hapd->dpp_chirp_freqs ||
3730 	    eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
3731 				   hapd, NULL) < 0)
3732 		hostapd_dpp_chirp_stop(hapd);
3733 
3734 	wpa_scan_results_free(scan_res);
3735 }
3736 
3737 
3738 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
3739 {
3740 	struct hostapd_data *hapd = eloop_ctx;
3741 	int i;
3742 
3743 	if (hapd->dpp_chirp_listen)
3744 		hostapd_dpp_listen_stop(hapd);
3745 
3746 	if (hapd->dpp_chirp_freq == 0) {
3747 		if (hapd->dpp_chirp_round % 4 == 0 &&
3748 		    !hapd->dpp_chirp_scan_done) {
3749 			struct wpa_driver_scan_params params;
3750 			int ret;
3751 
3752 			wpa_printf(MSG_DEBUG,
3753 				   "DPP: Update channel list for chirping");
3754 			os_memset(&params, 0, sizeof(params));
3755 			ret = hostapd_driver_scan(hapd, &params);
3756 			if (ret < 0) {
3757 				wpa_printf(MSG_DEBUG,
3758 					   "DPP: Failed to request a scan ret=%d (%s)",
3759 					   ret, strerror(-ret));
3760 				hostapd_dpp_chirp_scan_res_handler(hapd->iface);
3761 			} else {
3762 				hapd->iface->scan_cb =
3763 					hostapd_dpp_chirp_scan_res_handler;
3764 			}
3765 			return;
3766 		}
3767 		hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
3768 		hapd->dpp_chirp_round++;
3769 		wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
3770 			   hapd->dpp_chirp_round);
3771 	} else {
3772 		for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
3773 			if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
3774 				break;
3775 		if (!hapd->dpp_chirp_freqs[i]) {
3776 			wpa_printf(MSG_DEBUG,
3777 				   "DPP: Previous chirp freq %d not found",
3778 				   hapd->dpp_chirp_freq);
3779 			return;
3780 		}
3781 		i++;
3782 		if (hapd->dpp_chirp_freqs[i]) {
3783 			hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
3784 		} else {
3785 			hapd->dpp_chirp_iter--;
3786 			if (hapd->dpp_chirp_iter <= 0) {
3787 				wpa_printf(MSG_DEBUG,
3788 					   "DPP: Chirping iterations completed");
3789 				hostapd_dpp_chirp_stop(hapd);
3790 				return;
3791 			}
3792 			hapd->dpp_chirp_freq = 0;
3793 			hapd->dpp_chirp_scan_done = 0;
3794 			if (eloop_register_timeout(30, 0,
3795 						   hostapd_dpp_chirp_next,
3796 						   hapd, NULL) < 0) {
3797 				hostapd_dpp_chirp_stop(hapd);
3798 				return;
3799 			}
3800 			if (hapd->dpp_chirp_listen) {
3801 				wpa_printf(MSG_DEBUG,
3802 					   "DPP: Listen on %d MHz during chirp 30 second wait",
3803 					hapd->dpp_chirp_listen);
3804 				/* TODO: start listen on the channel */
3805 			} else {
3806 				wpa_printf(MSG_DEBUG,
3807 					   "DPP: Wait 30 seconds before starting the next chirping round");
3808 			}
3809 			return;
3810 		}
3811 	}
3812 
3813 	hostapd_dpp_chirp_start(hapd);
3814 }
3815 
3816 
3817 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
3818 {
3819 	const char *pos;
3820 	int iter = 1, listen_freq = 0;
3821 	struct dpp_bootstrap_info *bi;
3822 
3823 	pos = os_strstr(cmd, " own=");
3824 	if (!pos)
3825 		return -1;
3826 	pos += 5;
3827 	bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3828 	if (!bi) {
3829 		wpa_printf(MSG_DEBUG,
3830 			   "DPP: Identified bootstrap info not found");
3831 		return -1;
3832 	}
3833 
3834 	pos = os_strstr(cmd, " iter=");
3835 	if (pos) {
3836 		iter = atoi(pos + 6);
3837 		if (iter <= 0)
3838 			return -1;
3839 	}
3840 
3841 	pos = os_strstr(cmd, " listen=");
3842 	if (pos) {
3843 		listen_freq = atoi(pos + 8);
3844 		if (listen_freq <= 0)
3845 			return -1;
3846 	}
3847 
3848 	hostapd_dpp_chirp_stop(hapd);
3849 	hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
3850 	hapd->dpp_qr_mutual = 0;
3851 	hapd->dpp_chirp_bi = bi;
3852 	hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
3853 	if (!hapd->dpp_presence_announcement)
3854 		return -1;
3855 	hapd->dpp_chirp_iter = iter;
3856 	hapd->dpp_chirp_round = 0;
3857 	hapd->dpp_chirp_scan_done = 0;
3858 	hapd->dpp_chirp_listen = listen_freq;
3859 
3860 	return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
3861 }
3862 
3863 
3864 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
3865 {
3866 	if (hapd->dpp_presence_announcement) {
3867 		hostapd_drv_send_action_cancel_wait(hapd);
3868 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
3869 	}
3870 	hapd->dpp_chirp_bi = NULL;
3871 	wpabuf_free(hapd->dpp_presence_announcement);
3872 	hapd->dpp_presence_announcement = NULL;
3873 	if (hapd->dpp_chirp_listen)
3874 		hostapd_dpp_listen_stop(hapd);
3875 	hapd->dpp_chirp_listen = 0;
3876 	hapd->dpp_chirp_freq = 0;
3877 	os_free(hapd->dpp_chirp_freqs);
3878 	hapd->dpp_chirp_freqs = NULL;
3879 	eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
3880 	eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
3881 	if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
3882 		/* TODO: abort ongoing scan */
3883 		hapd->iface->scan_cb = NULL;
3884 	}
3885 }
3886 
3887 
3888 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
3889 {
3890 	struct dpp_bootstrap_info *bi = ctx;
3891 	size_t i;
3892 
3893 	for (i = 0; i < iface->num_bss; i++) {
3894 		struct hostapd_data *hapd = iface->bss[i];
3895 
3896 		if (bi == hapd->dpp_chirp_bi)
3897 			hostapd_dpp_chirp_stop(hapd);
3898 	}
3899 
3900 	return 0;
3901 }
3902 
3903 
3904 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
3905 {
3906 	struct hapd_interfaces *interfaces = ctx;
3907 
3908 	hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
3909 }
3910 
3911 #endif /* CONFIG_DPP2 */
3912 
3913 
3914 #ifdef CONFIG_DPP3
3915 
3916 static void hostapd_dpp_push_button_expire(void *eloop_ctx, void *timeout_ctx)
3917 {
3918 	struct hostapd_data *hapd = eloop_ctx;
3919 
3920 	wpa_printf(MSG_DEBUG, "DPP: Active push button mode expired");
3921 	hostapd_dpp_push_button_stop(hapd);
3922 }
3923 
3924 
3925 int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd)
3926 {
3927 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3928 
3929 	if (!ifaces || !ifaces->dpp)
3930 		return -1;
3931 	os_get_reltime(&ifaces->dpp_pb_time);
3932 	ifaces->dpp_pb_announce_time.sec = 0;
3933 	ifaces->dpp_pb_announce_time.usec = 0;
3934 	str_clear_free(ifaces->dpp_pb_cmd);
3935 	ifaces->dpp_pb_cmd = NULL;
3936 	if (cmd) {
3937 		ifaces->dpp_pb_cmd = os_strdup(cmd);
3938 		if (!ifaces->dpp_pb_cmd)
3939 			return -1;
3940 	}
3941 	eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
3942 			       hapd, NULL);
3943 
3944 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started");
3945 	return 0;
3946 }
3947 
3948 
3949 void hostapd_dpp_push_button_stop(struct hostapd_data *hapd)
3950 {
3951 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3952 
3953 	if (!ifaces || !ifaces->dpp)
3954 		return;
3955 	eloop_cancel_timeout(hostapd_dpp_push_button_expire, hapd, NULL);
3956 	if (hostapd_dpp_pb_active(hapd)) {
3957 		wpa_printf(MSG_DEBUG, "DPP: Stop active push button mode");
3958 		if (!ifaces->dpp_pb_result_indicated)
3959 			wpa_msg(hapd->msg_ctx, MSG_INFO,
3960 				DPP_EVENT_PB_RESULT "failed");
3961 	}
3962 	ifaces->dpp_pb_time.sec = 0;
3963 	ifaces->dpp_pb_time.usec = 0;
3964 	dpp_pkex_free(hapd->dpp_pkex);
3965 	hapd->dpp_pkex = NULL;
3966 	hapd->dpp_pkex_bi = NULL;
3967 	os_free(hapd->dpp_pkex_auth_cmd);
3968 	hapd->dpp_pkex_auth_cmd = NULL;
3969 
3970 	if (ifaces->dpp_pb_bi) {
3971 		char id[20];
3972 		size_t i;
3973 
3974 		for (i = 0; i < ifaces->count; i++) {
3975 			struct hostapd_iface *iface = ifaces->iface[i];
3976 			size_t j;
3977 
3978 			for (j = 0; iface && j < iface->num_bss; j++) {
3979 				struct hostapd_data *h = iface->bss[j];
3980 
3981 				if (h->dpp_pkex_bi == ifaces->dpp_pb_bi)
3982 					h->dpp_pkex_bi = NULL;
3983 			}
3984 		}
3985 
3986 		os_snprintf(id, sizeof(id), "%u", ifaces->dpp_pb_bi->id);
3987 		dpp_bootstrap_remove(ifaces->dpp, id);
3988 		ifaces->dpp_pb_bi = NULL;
3989 	}
3990 
3991 	ifaces->dpp_pb_result_indicated = false;
3992 
3993 	str_clear_free(ifaces->dpp_pb_cmd);
3994 	ifaces->dpp_pb_cmd = NULL;
3995 }
3996 
3997 #endif /* CONFIG_DPP3 */
3998 
3999 
4000 #ifdef CONFIG_DPP2
4001 bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd)
4002 {
4003 	return hapd->conf->dpp_configurator_connectivity ||
4004 		(hapd->iface->interfaces &&
4005 		 dpp_relay_controller_available(hapd->iface->interfaces->dpp));
4006 }
4007 #endif /* CONFIG_DPP2 */
4008