xref: /freebsd/contrib/wpa/src/ap/dpp_hostapd.c (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1 /*
2  * hostapd / DPP integration
3  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/dpp.h"
14 #include "common/gas.h"
15 #include "common/wpa_ctrl.h"
16 #include "hostapd.h"
17 #include "ap_drv_ops.h"
18 #include "gas_query_ap.h"
19 #include "gas_serv.h"
20 #include "wpa_auth.h"
21 #include "dpp_hostapd.h"
22 
23 
24 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
25 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
26 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
27 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
28 
29 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
30 
31 
32 /**
33  * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
34  * @hapd: Pointer to hostapd_data
35  * @cmd: DPP URI read from a QR Code
36  * Returns: Identifier of the stored info or -1 on failure
37  */
38 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
39 {
40 	struct dpp_bootstrap_info *bi;
41 	struct dpp_authentication *auth = hapd->dpp_auth;
42 
43 	bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
44 	if (!bi)
45 		return -1;
46 
47 	if (auth && auth->response_pending &&
48 	    dpp_notify_new_qr_code(auth, bi) == 1) {
49 		wpa_printf(MSG_DEBUG,
50 			   "DPP: Sending out pending authentication response");
51 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
52 			" freq=%u type=%d",
53 			MAC2STR(auth->peer_mac_addr), auth->curr_freq,
54 			DPP_PA_AUTHENTICATION_RESP);
55 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
56 					auth->peer_mac_addr,
57 					wpabuf_head(hapd->dpp_auth->resp_msg),
58 					wpabuf_len(hapd->dpp_auth->resp_msg));
59 	}
60 
61 	return bi->id;
62 }
63 
64 
65 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
66 						void *timeout_ctx)
67 {
68 	struct hostapd_data *hapd = eloop_ctx;
69 	struct dpp_authentication *auth = hapd->dpp_auth;
70 
71 	if (!auth || !auth->resp_msg)
72 		return;
73 
74 	wpa_printf(MSG_DEBUG,
75 		   "DPP: Retry Authentication Response after timeout");
76 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
77 		" freq=%u type=%d",
78 		MAC2STR(auth->peer_mac_addr), auth->curr_freq,
79 		DPP_PA_AUTHENTICATION_RESP);
80 	hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
81 				wpabuf_head(auth->resp_msg),
82 				wpabuf_len(auth->resp_msg));
83 }
84 
85 
86 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
87 {
88 	struct dpp_authentication *auth = hapd->dpp_auth;
89 	unsigned int wait_time, max_tries;
90 
91 	if (!auth || !auth->resp_msg)
92 		return;
93 
94 	if (hapd->dpp_resp_max_tries)
95 		max_tries = hapd->dpp_resp_max_tries;
96 	else
97 		max_tries = 5;
98 	auth->auth_resp_tries++;
99 	if (auth->auth_resp_tries >= max_tries) {
100 		wpa_printf(MSG_INFO,
101 			   "DPP: No confirm received from initiator - stopping exchange");
102 		hostapd_drv_send_action_cancel_wait(hapd);
103 		dpp_auth_deinit(hapd->dpp_auth);
104 		hapd->dpp_auth = NULL;
105 		return;
106 	}
107 
108 	if (hapd->dpp_resp_retry_time)
109 		wait_time = hapd->dpp_resp_retry_time;
110 	else
111 		wait_time = 1000;
112 	wpa_printf(MSG_DEBUG,
113 		   "DPP: Schedule retransmission of Authentication Response frame in %u ms",
114 		wait_time);
115 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
116 	eloop_register_timeout(wait_time / 1000,
117 			       (wait_time % 1000) * 1000,
118 			       hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
119 }
120 
121 
122 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
123 			   const u8 *data, size_t data_len, int ok)
124 {
125 	struct dpp_authentication *auth = hapd->dpp_auth;
126 
127 	wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
128 		   MAC2STR(dst), ok);
129 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
130 		" result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
131 
132 	if (!hapd->dpp_auth) {
133 		wpa_printf(MSG_DEBUG,
134 			   "DPP: Ignore TX status since there is no ongoing authentication exchange");
135 		return;
136 	}
137 
138 #ifdef CONFIG_DPP2
139 	if (auth->connect_on_tx_status) {
140 		wpa_printf(MSG_DEBUG,
141 			   "DPP: Complete exchange on configuration result");
142 		dpp_auth_deinit(hapd->dpp_auth);
143 		hapd->dpp_auth = NULL;
144 		return;
145 	}
146 #endif /* CONFIG_DPP2 */
147 
148 	if (hapd->dpp_auth->remove_on_tx_status) {
149 		wpa_printf(MSG_DEBUG,
150 			   "DPP: Terminate authentication exchange due to an earlier error");
151 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
152 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
153 				     hapd, NULL);
154 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
155 				     NULL);
156 		hostapd_drv_send_action_cancel_wait(hapd);
157 		dpp_auth_deinit(hapd->dpp_auth);
158 		hapd->dpp_auth = NULL;
159 		return;
160 	}
161 
162 	if (hapd->dpp_auth_ok_on_ack)
163 		hostapd_dpp_auth_success(hapd, 1);
164 
165 	if (!is_broadcast_ether_addr(dst) && !ok) {
166 		wpa_printf(MSG_DEBUG,
167 			   "DPP: Unicast DPP Action frame was not ACKed");
168 		if (auth->waiting_auth_resp) {
169 			/* In case of DPP Authentication Request frame, move to
170 			 * the next channel immediately. */
171 			hostapd_drv_send_action_cancel_wait(hapd);
172 			hostapd_dpp_auth_init_next(hapd);
173 			return;
174 		}
175 		if (auth->waiting_auth_conf) {
176 			hostapd_dpp_auth_resp_retry(hapd);
177 			return;
178 		}
179 	}
180 
181 	if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
182 		/* Allow timeout handling to stop iteration if no response is
183 		 * received from a peer that has ACKed a request. */
184 		auth->auth_req_ack = 1;
185 	}
186 
187 	if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
188 	    hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
189 		wpa_printf(MSG_DEBUG,
190 			   "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
191 			   hapd->dpp_auth->curr_freq,
192 			   hapd->dpp_auth->neg_freq);
193 		hostapd_drv_send_action_cancel_wait(hapd);
194 
195 		if (hapd->dpp_auth->neg_freq !=
196 		    (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
197 			/* TODO: Listen operation on non-operating channel */
198 			wpa_printf(MSG_INFO,
199 				   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
200 				   hapd->dpp_auth->neg_freq, hapd->iface->freq);
201 		}
202 	}
203 
204 	if (hapd->dpp_auth_ok_on_ack)
205 		hapd->dpp_auth_ok_on_ack = 0;
206 }
207 
208 
209 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
210 {
211 	struct hostapd_data *hapd = eloop_ctx;
212 	struct dpp_authentication *auth = hapd->dpp_auth;
213 	unsigned int freq;
214 	struct os_reltime now, diff;
215 	unsigned int wait_time, diff_ms;
216 
217 	if (!auth || !auth->waiting_auth_resp)
218 		return;
219 
220 	wait_time = hapd->dpp_resp_wait_time ?
221 		hapd->dpp_resp_wait_time : 2000;
222 	os_get_reltime(&now);
223 	os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
224 	diff_ms = diff.sec * 1000 + diff.usec / 1000;
225 	wpa_printf(MSG_DEBUG,
226 		   "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
227 		   wait_time, diff_ms);
228 
229 	if (auth->auth_req_ack && diff_ms >= wait_time) {
230 		/* Peer ACK'ed Authentication Request frame, but did not reply
231 		 * with Authentication Response frame within two seconds. */
232 		wpa_printf(MSG_INFO,
233 			   "DPP: No response received from responder - stopping initiation attempt");
234 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
235 		hostapd_drv_send_action_cancel_wait(hapd);
236 		hostapd_dpp_listen_stop(hapd);
237 		dpp_auth_deinit(auth);
238 		hapd->dpp_auth = NULL;
239 		return;
240 	}
241 
242 	if (diff_ms >= wait_time) {
243 		/* Authentication Request frame was not ACK'ed and no reply
244 		 * was receiving within two seconds. */
245 		wpa_printf(MSG_DEBUG,
246 			   "DPP: Continue Initiator channel iteration");
247 		hostapd_drv_send_action_cancel_wait(hapd);
248 		hostapd_dpp_listen_stop(hapd);
249 		hostapd_dpp_auth_init_next(hapd);
250 		return;
251 	}
252 
253 	/* Driver did not support 2000 ms long wait_time with TX command, so
254 	 * schedule listen operation to continue waiting for the response.
255 	 *
256 	 * DPP listen operations continue until stopped, so simply schedule a
257 	 * new call to this function at the point when the two second reply
258 	 * wait has expired. */
259 	wait_time -= diff_ms;
260 
261 	freq = auth->curr_freq;
262 	if (auth->neg_freq > 0)
263 		freq = auth->neg_freq;
264 	wpa_printf(MSG_DEBUG,
265 		   "DPP: Continue reply wait on channel %u MHz for %u ms",
266 		   freq, wait_time);
267 	hapd->dpp_in_response_listen = 1;
268 
269 	if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
270 		/* TODO: Listen operation on non-operating channel */
271 		wpa_printf(MSG_INFO,
272 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
273 			   freq, hapd->iface->freq);
274 	}
275 
276 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
277 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
278 }
279 
280 
281 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
282 					    struct dpp_authentication *auth)
283 {
284 #ifdef CONFIG_TESTING_OPTIONS
285 	if (hapd->dpp_config_obj_override)
286 		auth->config_obj_override =
287 			os_strdup(hapd->dpp_config_obj_override);
288 	if (hapd->dpp_discovery_override)
289 		auth->discovery_override =
290 			os_strdup(hapd->dpp_discovery_override);
291 	if (hapd->dpp_groups_override)
292 		auth->groups_override = os_strdup(hapd->dpp_groups_override);
293 	auth->ignore_netaccesskey_mismatch =
294 		hapd->dpp_ignore_netaccesskey_mismatch;
295 #endif /* CONFIG_TESTING_OPTIONS */
296 }
297 
298 
299 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
300 {
301 	struct hostapd_data *hapd = eloop_ctx;
302 
303 	if (!hapd->dpp_auth)
304 		return;
305 	wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
306 	hostapd_dpp_auth_init_next(hapd);
307 }
308 
309 
310 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
311 {
312 	struct dpp_authentication *auth = hapd->dpp_auth;
313 	const u8 *dst;
314 	unsigned int wait_time, max_wait_time, freq, max_tries, used;
315 	struct os_reltime now, diff;
316 
317 	if (!auth)
318 		return -1;
319 
320 	if (auth->freq_idx == 0)
321 		os_get_reltime(&hapd->dpp_init_iter_start);
322 
323 	if (auth->freq_idx >= auth->num_freq) {
324 		auth->num_freq_iters++;
325 		if (hapd->dpp_init_max_tries)
326 			max_tries = hapd->dpp_init_max_tries;
327 		else
328 			max_tries = 5;
329 		if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
330 			wpa_printf(MSG_INFO,
331 				   "DPP: No response received from responder - stopping initiation attempt");
332 			wpa_msg(hapd->msg_ctx, MSG_INFO,
333 				DPP_EVENT_AUTH_INIT_FAILED);
334 			eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
335 					     hapd, NULL);
336 			hostapd_drv_send_action_cancel_wait(hapd);
337 			dpp_auth_deinit(hapd->dpp_auth);
338 			hapd->dpp_auth = NULL;
339 			return -1;
340 		}
341 		auth->freq_idx = 0;
342 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
343 		if (hapd->dpp_init_retry_time)
344 			wait_time = hapd->dpp_init_retry_time;
345 		else
346 			wait_time = 10000;
347 		os_get_reltime(&now);
348 		os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
349 		used = diff.sec * 1000 + diff.usec / 1000;
350 		if (used > wait_time)
351 			wait_time = 0;
352 		else
353 			wait_time -= used;
354 		wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
355 			   wait_time);
356 		eloop_register_timeout(wait_time / 1000,
357 				       (wait_time % 1000) * 1000,
358 				       hostapd_dpp_init_timeout, hapd,
359 				       NULL);
360 		return 0;
361 	}
362 	freq = auth->freq[auth->freq_idx++];
363 	auth->curr_freq = freq;
364 
365 	if (is_zero_ether_addr(auth->peer_bi->mac_addr))
366 		dst = broadcast;
367 	else
368 		dst = auth->peer_bi->mac_addr;
369 	hapd->dpp_auth_ok_on_ack = 0;
370 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
371 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
372 	max_wait_time = hapd->dpp_resp_wait_time ?
373 		hapd->dpp_resp_wait_time : 2000;
374 	if (wait_time > max_wait_time)
375 		wait_time = max_wait_time;
376 	wait_time += 10; /* give the driver some extra time to complete */
377 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
378 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
379 	wait_time -= 10;
380 	if (auth->neg_freq > 0 && freq != auth->neg_freq) {
381 		wpa_printf(MSG_DEBUG,
382 			   "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
383 			   freq, auth->neg_freq);
384 	}
385 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
386 		" freq=%u type=%d",
387 		MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
388 	auth->auth_req_ack = 0;
389 	os_get_reltime(&hapd->dpp_last_init);
390 	return hostapd_drv_send_action(hapd, freq, wait_time,
391 				       dst,
392 				       wpabuf_head(hapd->dpp_auth->req_msg),
393 				       wpabuf_len(hapd->dpp_auth->req_msg));
394 }
395 
396 
397 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
398 {
399 	const char *pos;
400 	struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
401 	u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
402 	unsigned int neg_freq = 0;
403 
404 	pos = os_strstr(cmd, " peer=");
405 	if (!pos)
406 		return -1;
407 	pos += 6;
408 	peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
409 	if (!peer_bi) {
410 		wpa_printf(MSG_INFO,
411 			   "DPP: Could not find bootstrapping info for the identified peer");
412 		return -1;
413 	}
414 
415 	pos = os_strstr(cmd, " own=");
416 	if (pos) {
417 		pos += 5;
418 		own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
419 					      atoi(pos));
420 		if (!own_bi) {
421 			wpa_printf(MSG_INFO,
422 				   "DPP: Could not find bootstrapping info for the identified local entry");
423 			return -1;
424 		}
425 
426 		if (peer_bi->curve != own_bi->curve) {
427 			wpa_printf(MSG_INFO,
428 				   "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
429 				   peer_bi->curve->name, own_bi->curve->name);
430 			return -1;
431 		}
432 	}
433 
434 	pos = os_strstr(cmd, " role=");
435 	if (pos) {
436 		pos += 6;
437 		if (os_strncmp(pos, "configurator", 12) == 0)
438 			allowed_roles = DPP_CAPAB_CONFIGURATOR;
439 		else if (os_strncmp(pos, "enrollee", 8) == 0)
440 			allowed_roles = DPP_CAPAB_ENROLLEE;
441 		else if (os_strncmp(pos, "either", 6) == 0)
442 			allowed_roles = DPP_CAPAB_CONFIGURATOR |
443 				DPP_CAPAB_ENROLLEE;
444 		else
445 			goto fail;
446 	}
447 
448 	pos = os_strstr(cmd, " neg_freq=");
449 	if (pos)
450 		neg_freq = atoi(pos + 10);
451 
452 	if (hapd->dpp_auth) {
453 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
454 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
455 				     hapd, NULL);
456 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
457 				     NULL);
458 		hostapd_drv_send_action_cancel_wait(hapd);
459 		dpp_auth_deinit(hapd->dpp_auth);
460 	}
461 
462 	hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi,
463 				       allowed_roles, neg_freq,
464 				       hapd->iface->hw_features,
465 				       hapd->iface->num_hw_features);
466 	if (!hapd->dpp_auth)
467 		goto fail;
468 	hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
469 	if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
470 				 hapd->dpp_auth, cmd) < 0) {
471 		dpp_auth_deinit(hapd->dpp_auth);
472 		hapd->dpp_auth = NULL;
473 		goto fail;
474 	}
475 
476 	hapd->dpp_auth->neg_freq = neg_freq;
477 
478 	if (!is_zero_ether_addr(peer_bi->mac_addr))
479 		os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
480 			  ETH_ALEN);
481 
482 	return hostapd_dpp_auth_init_next(hapd);
483 fail:
484 	return -1;
485 }
486 
487 
488 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
489 {
490 	int freq;
491 
492 	freq = atoi(cmd);
493 	if (freq <= 0)
494 		return -1;
495 
496 	if (os_strstr(cmd, " role=configurator"))
497 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
498 	else if (os_strstr(cmd, " role=enrollee"))
499 		hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
500 	else
501 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
502 			DPP_CAPAB_ENROLLEE;
503 	hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
504 
505 	if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
506 		/* TODO: Listen operation on non-operating channel */
507 		wpa_printf(MSG_INFO,
508 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
509 			   freq, hapd->iface->freq);
510 		return -1;
511 	}
512 
513 	return 0;
514 }
515 
516 
517 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
518 {
519 	/* TODO: Stop listen operation on non-operating channel */
520 }
521 
522 
523 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
524 				    const u8 *hdr, const u8 *buf, size_t len,
525 				    unsigned int freq)
526 {
527 	const u8 *r_bootstrap, *i_bootstrap;
528 	u16 r_bootstrap_len, i_bootstrap_len;
529 	struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
530 
531 	if (!hapd->iface->interfaces->dpp)
532 		return;
533 
534 	wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
535 		   MAC2STR(src));
536 
537 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
538 				   &r_bootstrap_len);
539 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
540 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
541 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
542 		return;
543 	}
544 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
545 		    r_bootstrap, r_bootstrap_len);
546 
547 	i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
548 				   &i_bootstrap_len);
549 	if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
550 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
551 			"Missing or invalid required Initiator Bootstrapping Key Hash attribute");
552 		return;
553 	}
554 	wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
555 		    i_bootstrap, i_bootstrap_len);
556 
557 	/* Try to find own and peer bootstrapping key matches based on the
558 	 * received hash values */
559 	dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
560 				r_bootstrap, &own_bi, &peer_bi);
561 #ifdef CONFIG_DPP2
562 	if (!own_bi) {
563 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
564 					src, hdr, buf, len, freq, i_bootstrap,
565 					r_bootstrap) == 0)
566 			return;
567 	}
568 #endif /* CONFIG_DPP2 */
569 	if (!own_bi) {
570 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
571 			"No matching own bootstrapping key found - ignore message");
572 		return;
573 	}
574 
575 	if (hapd->dpp_auth) {
576 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
577 			"Already in DPP authentication exchange - ignore new one");
578 		return;
579 	}
580 
581 	hapd->dpp_auth_ok_on_ack = 0;
582 	hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles,
583 					 hapd->dpp_qr_mutual,
584 					 peer_bi, own_bi, freq, hdr, buf, len);
585 	if (!hapd->dpp_auth) {
586 		wpa_printf(MSG_DEBUG, "DPP: No response generated");
587 		return;
588 	}
589 	hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
590 	if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
591 				 hapd->dpp_auth,
592 				 hapd->dpp_configurator_params) < 0) {
593 		dpp_auth_deinit(hapd->dpp_auth);
594 		hapd->dpp_auth = NULL;
595 		return;
596 	}
597 	os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
598 
599 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
600 		" freq=%u type=%d",
601 		MAC2STR(src), hapd->dpp_auth->curr_freq,
602 		DPP_PA_AUTHENTICATION_RESP);
603 	hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
604 				src, wpabuf_head(hapd->dpp_auth->resp_msg),
605 				wpabuf_len(hapd->dpp_auth->resp_msg));
606 }
607 
608 
609 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
610 					  struct dpp_authentication *auth)
611 {
612 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
613 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
614 		dpp_akm_str(auth->akm));
615 	if (auth->ssid_len)
616 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
617 			wpa_ssid_txt(auth->ssid, auth->ssid_len));
618 	if (auth->connector) {
619 		/* TODO: Save the Connector and consider using a command
620 		 * to fetch the value instead of sending an event with
621 		 * it. The Connector could end up being larger than what
622 		 * most clients are ready to receive as an event
623 		 * message. */
624 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
625 			auth->connector);
626 	} else if (auth->passphrase[0]) {
627 		char hex[64 * 2 + 1];
628 
629 		wpa_snprintf_hex(hex, sizeof(hex),
630 				 (const u8 *) auth->passphrase,
631 				 os_strlen(auth->passphrase));
632 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
633 			hex);
634 	} else if (auth->psk_set) {
635 		char hex[PMK_LEN * 2 + 1];
636 
637 		wpa_snprintf_hex(hex, sizeof(hex), auth->psk, PMK_LEN);
638 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
639 			hex);
640 	}
641 	if (auth->c_sign_key) {
642 		char *hex;
643 		size_t hexlen;
644 
645 		hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1;
646 		hex = os_malloc(hexlen);
647 		if (hex) {
648 			wpa_snprintf_hex(hex, hexlen,
649 					 wpabuf_head(auth->c_sign_key),
650 					 wpabuf_len(auth->c_sign_key));
651 			wpa_msg(hapd->msg_ctx, MSG_INFO,
652 				DPP_EVENT_C_SIGN_KEY "%s", hex);
653 			os_free(hex);
654 		}
655 	}
656 	if (auth->net_access_key) {
657 		char *hex;
658 		size_t hexlen;
659 
660 		hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
661 		hex = os_malloc(hexlen);
662 		if (hex) {
663 			wpa_snprintf_hex(hex, hexlen,
664 					 wpabuf_head(auth->net_access_key),
665 					 wpabuf_len(auth->net_access_key));
666 			if (auth->net_access_key_expiry)
667 				wpa_msg(hapd->msg_ctx, MSG_INFO,
668 					DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
669 					(unsigned long)
670 					auth->net_access_key_expiry);
671 			else
672 				wpa_msg(hapd->msg_ctx, MSG_INFO,
673 					DPP_EVENT_NET_ACCESS_KEY "%s", hex);
674 			os_free(hex);
675 		}
676 	}
677 }
678 
679 
680 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
681 				    enum gas_query_ap_result result,
682 				    const struct wpabuf *adv_proto,
683 				    const struct wpabuf *resp, u16 status_code)
684 {
685 	struct hostapd_data *hapd = ctx;
686 	const u8 *pos;
687 	struct dpp_authentication *auth = hapd->dpp_auth;
688 	enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
689 
690 	if (!auth || !auth->auth_success) {
691 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
692 		return;
693 	}
694 	if (!resp || status_code != WLAN_STATUS_SUCCESS) {
695 		wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
696 		goto fail;
697 	}
698 
699 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
700 			adv_proto);
701 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
702 			resp);
703 
704 	if (wpabuf_len(adv_proto) != 10 ||
705 	    !(pos = wpabuf_head(adv_proto)) ||
706 	    pos[0] != WLAN_EID_ADV_PROTO ||
707 	    pos[1] != 8 ||
708 	    pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
709 	    pos[4] != 5 ||
710 	    WPA_GET_BE24(&pos[5]) != OUI_WFA ||
711 	    pos[8] != 0x1a ||
712 	    pos[9] != 1) {
713 		wpa_printf(MSG_DEBUG,
714 			   "DPP: Not a DPP Advertisement Protocol ID");
715 		goto fail;
716 	}
717 
718 	if (dpp_conf_resp_rx(auth, resp) < 0) {
719 		wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
720 		goto fail;
721 	}
722 
723 	hostapd_dpp_handle_config_obj(hapd, auth);
724 	status = DPP_STATUS_OK;
725 #ifdef CONFIG_TESTING_OPTIONS
726 	if (dpp_test == DPP_TEST_REJECT_CONFIG) {
727 		wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
728 		status = DPP_STATUS_CONFIG_REJECTED;
729 	}
730 #endif /* CONFIG_TESTING_OPTIONS */
731 fail:
732 	if (status != DPP_STATUS_OK)
733 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
734 #ifdef CONFIG_DPP2
735 	if (auth->peer_version >= 2 &&
736 	    auth->conf_resp_status == DPP_STATUS_OK) {
737 		struct wpabuf *msg;
738 
739 		wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
740 		msg = dpp_build_conf_result(auth, status);
741 		if (!msg)
742 			goto fail2;
743 
744 		wpa_msg(hapd->msg_ctx, MSG_INFO,
745 			DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
746 			MAC2STR(addr), auth->curr_freq,
747 			DPP_PA_CONFIGURATION_RESULT);
748 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
749 					addr, wpabuf_head(msg),
750 					wpabuf_len(msg));
751 		wpabuf_free(msg);
752 
753 		/* This exchange will be terminated in the TX status handler */
754 		auth->connect_on_tx_status = 1;
755 		return;
756 	}
757 fail2:
758 #endif /* CONFIG_DPP2 */
759 	dpp_auth_deinit(hapd->dpp_auth);
760 	hapd->dpp_auth = NULL;
761 }
762 
763 
764 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
765 {
766 	struct dpp_authentication *auth = hapd->dpp_auth;
767 	struct wpabuf *buf;
768 	char json[100];
769 	int res;
770 	int netrole_ap = 1;
771 
772 	os_snprintf(json, sizeof(json),
773 		    "{\"name\":\"Test\","
774 		    "\"wi-fi_tech\":\"infra\","
775 		    "\"netRole\":\"%s\"}",
776 		    netrole_ap ? "ap" : "sta");
777 	wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json);
778 
779 	buf = dpp_build_conf_req(auth, json);
780 	if (!buf) {
781 		wpa_printf(MSG_DEBUG,
782 			   "DPP: No configuration request data available");
783 		return;
784 	}
785 
786 	wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
787 		   MAC2STR(auth->peer_mac_addr), auth->curr_freq);
788 
789 	res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
790 			       buf, hostapd_dpp_gas_resp_cb, hapd);
791 	if (res < 0) {
792 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
793 			"GAS: Failed to send Query Request");
794 		wpabuf_free(buf);
795 	} else {
796 		wpa_printf(MSG_DEBUG,
797 			   "DPP: GAS query started with dialog token %u", res);
798 	}
799 }
800 
801 
802 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
803 {
804 	wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
805 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
806 		initiator);
807 #ifdef CONFIG_TESTING_OPTIONS
808 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
809 		wpa_printf(MSG_INFO,
810 			   "DPP: TESTING - stop at Authentication Confirm");
811 		if (hapd->dpp_auth->configurator) {
812 			/* Prevent GAS response */
813 			hapd->dpp_auth->auth_success = 0;
814 		}
815 		return;
816 	}
817 #endif /* CONFIG_TESTING_OPTIONS */
818 
819 	if (!hapd->dpp_auth->configurator)
820 		hostapd_dpp_start_gas_client(hapd);
821 }
822 
823 
824 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
825 				     const u8 *hdr, const u8 *buf, size_t len,
826 				     unsigned int freq)
827 {
828 	struct dpp_authentication *auth = hapd->dpp_auth;
829 	struct wpabuf *msg;
830 
831 	wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
832 		   MAC2STR(src));
833 
834 	if (!auth) {
835 		wpa_printf(MSG_DEBUG,
836 			   "DPP: No DPP Authentication in progress - drop");
837 		return;
838 	}
839 
840 	if (!is_zero_ether_addr(auth->peer_mac_addr) &&
841 	    os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
842 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
843 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
844 		return;
845 	}
846 
847 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
848 
849 	if (auth->curr_freq != freq && auth->neg_freq == freq) {
850 		wpa_printf(MSG_DEBUG,
851 			   "DPP: Responder accepted request for different negotiation channel");
852 		auth->curr_freq = freq;
853 	}
854 
855 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
856 	msg = dpp_auth_resp_rx(auth, hdr, buf, len);
857 	if (!msg) {
858 		if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
859 			wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
860 			return;
861 		}
862 		wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
863 		return;
864 	}
865 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
866 
867 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
868 		" freq=%u type=%d", MAC2STR(src), auth->curr_freq,
869 		DPP_PA_AUTHENTICATION_CONF);
870 	hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
871 				wpabuf_head(msg), wpabuf_len(msg));
872 	wpabuf_free(msg);
873 	hapd->dpp_auth_ok_on_ack = 1;
874 }
875 
876 
877 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
878 				     const u8 *hdr, const u8 *buf, size_t len)
879 {
880 	struct dpp_authentication *auth = hapd->dpp_auth;
881 
882 	wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
883 		   MAC2STR(src));
884 
885 	if (!auth) {
886 		wpa_printf(MSG_DEBUG,
887 			   "DPP: No DPP Authentication in progress - drop");
888 		return;
889 	}
890 
891 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
892 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
893 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
894 		return;
895 	}
896 
897 	if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
898 		wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
899 		return;
900 	}
901 
902 	hostapd_dpp_auth_success(hapd, 0);
903 }
904 
905 
906 #ifdef CONFIG_DPP2
907 
908 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
909 						   void *timeout_ctx)
910 {
911 	struct hostapd_data *hapd = eloop_ctx;
912 	struct dpp_authentication *auth = hapd->dpp_auth;
913 
914 	if (!auth || !auth->waiting_conf_result)
915 		return;
916 
917 	wpa_printf(MSG_DEBUG,
918 		   "DPP: Timeout while waiting for Configuration Result");
919 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
920 	dpp_auth_deinit(auth);
921 	hapd->dpp_auth = NULL;
922 }
923 
924 
925 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
926 				       const u8 *hdr, const u8 *buf, size_t len)
927 {
928 	struct dpp_authentication *auth = hapd->dpp_auth;
929 	enum dpp_status_error status;
930 
931 	wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
932 		   MAC2STR(src));
933 
934 	if (!auth || !auth->waiting_conf_result) {
935 		wpa_printf(MSG_DEBUG,
936 			   "DPP: No DPP Configuration waiting for result - drop");
937 		return;
938 	}
939 
940 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
941 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
942 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
943 		return;
944 	}
945 
946 	status = dpp_conf_result_rx(auth, hdr, buf, len);
947 
948 	hostapd_drv_send_action_cancel_wait(hapd);
949 	hostapd_dpp_listen_stop(hapd);
950 	if (status == DPP_STATUS_OK)
951 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
952 	else
953 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
954 	dpp_auth_deinit(auth);
955 	hapd->dpp_auth = NULL;
956 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
957 			     NULL);
958 }
959 
960 #endif /* CONFIG_DPP2 */
961 
962 
963 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
964 					    const u8 *src, unsigned int freq,
965 					    u8 trans_id,
966 					    enum dpp_status_error status)
967 {
968 	struct wpabuf *msg;
969 
970 	msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP,
971 			    5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector));
972 	if (!msg)
973 		return;
974 
975 #ifdef CONFIG_TESTING_OPTIONS
976 	if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
977 		wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
978 		goto skip_trans_id;
979 	}
980 	if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
981 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
982 		trans_id ^= 0x01;
983 	}
984 #endif /* CONFIG_TESTING_OPTIONS */
985 
986 	/* Transaction ID */
987 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
988 	wpabuf_put_le16(msg, 1);
989 	wpabuf_put_u8(msg, trans_id);
990 
991 #ifdef CONFIG_TESTING_OPTIONS
992 skip_trans_id:
993 	if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
994 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
995 		goto skip_status;
996 	}
997 	if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
998 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
999 		status = 254;
1000 	}
1001 #endif /* CONFIG_TESTING_OPTIONS */
1002 
1003 	/* DPP Status */
1004 	wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1005 	wpabuf_put_le16(msg, 1);
1006 	wpabuf_put_u8(msg, status);
1007 
1008 #ifdef CONFIG_TESTING_OPTIONS
1009 skip_status:
1010 	if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1011 		wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1012 		goto skip_connector;
1013 	}
1014 	if (status == DPP_STATUS_OK &&
1015 	    dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1016 		char *connector;
1017 
1018 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1019 		connector = dpp_corrupt_connector_signature(
1020 			hapd->conf->dpp_connector);
1021 		if (!connector) {
1022 			wpabuf_free(msg);
1023 			return;
1024 		}
1025 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1026 		wpabuf_put_le16(msg, os_strlen(connector));
1027 		wpabuf_put_str(msg, connector);
1028 		os_free(connector);
1029 		goto skip_connector;
1030 	}
1031 #endif /* CONFIG_TESTING_OPTIONS */
1032 
1033 	/* DPP Connector */
1034 	if (status == DPP_STATUS_OK) {
1035 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1036 		wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1037 		wpabuf_put_str(msg, hapd->conf->dpp_connector);
1038 	}
1039 
1040 #ifdef CONFIG_TESTING_OPTIONS
1041 skip_connector:
1042 #endif /* CONFIG_TESTING_OPTIONS */
1043 
1044 	wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
1045 		   " status=%d", MAC2STR(src), status);
1046 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1047 		" freq=%u type=%d status=%d", MAC2STR(src), freq,
1048 		DPP_PA_PEER_DISCOVERY_RESP, status);
1049 	hostapd_drv_send_action(hapd, freq, 0, src,
1050 				wpabuf_head(msg), wpabuf_len(msg));
1051 	wpabuf_free(msg);
1052 }
1053 
1054 
1055 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
1056 					 const u8 *src,
1057 					 const u8 *buf, size_t len,
1058 					 unsigned int freq)
1059 {
1060 	const u8 *connector, *trans_id;
1061 	u16 connector_len, trans_id_len;
1062 	struct os_time now;
1063 	struct dpp_introduction intro;
1064 	os_time_t expire;
1065 	int expiration;
1066 	enum dpp_status_error res;
1067 
1068 	wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
1069 		   MAC2STR(src));
1070 	if (!hapd->wpa_auth ||
1071 	    !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
1072 	    !(hapd->conf->wpa & WPA_PROTO_RSN)) {
1073 		wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
1074 		return;
1075 	}
1076 
1077 	if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
1078 	    !hapd->conf->dpp_csign) {
1079 		wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
1080 		return;
1081 	}
1082 
1083 	os_get_time(&now);
1084 
1085 	if (hapd->conf->dpp_netaccesskey_expiry &&
1086 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
1087 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
1088 		return;
1089 	}
1090 
1091 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
1092 			       &trans_id_len);
1093 	if (!trans_id || trans_id_len != 1) {
1094 		wpa_printf(MSG_DEBUG,
1095 			   "DPP: Peer did not include Transaction ID");
1096 		return;
1097 	}
1098 
1099 	connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
1100 	if (!connector) {
1101 		wpa_printf(MSG_DEBUG,
1102 			   "DPP: Peer did not include its Connector");
1103 		return;
1104 	}
1105 
1106 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
1107 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
1108 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
1109 			     wpabuf_head(hapd->conf->dpp_csign),
1110 			     wpabuf_len(hapd->conf->dpp_csign),
1111 			     connector, connector_len, &expire);
1112 	if (res == 255) {
1113 		wpa_printf(MSG_INFO,
1114 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
1115 			   MACSTR ")", MAC2STR(src));
1116 		return;
1117 	}
1118 	if (res != DPP_STATUS_OK) {
1119 		wpa_printf(MSG_INFO,
1120 			   "DPP: Network Introduction protocol resulted in failure (peer "
1121 			   MACSTR " status %d)", MAC2STR(src), res);
1122 		hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1123 						res);
1124 		return;
1125 	}
1126 
1127 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
1128 		expire = hapd->conf->dpp_netaccesskey_expiry;
1129 	if (expire)
1130 		expiration = expire - now.sec;
1131 	else
1132 		expiration = 0;
1133 
1134 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
1135 				intro.pmkid, expiration,
1136 				WPA_KEY_MGMT_DPP) < 0) {
1137 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
1138 		return;
1139 	}
1140 
1141 	hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1142 					DPP_STATUS_OK);
1143 }
1144 
1145 
1146 static void
1147 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
1148 				 const u8 *buf, size_t len,
1149 				 unsigned int freq)
1150 {
1151 	struct wpabuf *msg;
1152 
1153 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
1154 		   MAC2STR(src));
1155 
1156 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
1157 	 * values here */
1158 
1159 	if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
1160 		wpa_printf(MSG_DEBUG,
1161 			   "DPP: No PKEX code configured - ignore request");
1162 		return;
1163 	}
1164 
1165 	if (hapd->dpp_pkex) {
1166 		/* TODO: Support parallel operations */
1167 		wpa_printf(MSG_DEBUG,
1168 			   "DPP: Already in PKEX session - ignore new request");
1169 		return;
1170 	}
1171 
1172 	hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
1173 						  hapd->dpp_pkex_bi,
1174 						  hapd->own_addr, src,
1175 						  hapd->dpp_pkex_identifier,
1176 						  hapd->dpp_pkex_code,
1177 						  buf, len);
1178 	if (!hapd->dpp_pkex) {
1179 		wpa_printf(MSG_DEBUG,
1180 			   "DPP: Failed to process the request - ignore it");
1181 		return;
1182 	}
1183 
1184 	msg = hapd->dpp_pkex->exchange_resp;
1185 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1186 		" freq=%u type=%d", MAC2STR(src), freq,
1187 		DPP_PA_PKEX_EXCHANGE_RESP);
1188 	hostapd_drv_send_action(hapd, freq, 0, src,
1189 				wpabuf_head(msg), wpabuf_len(msg));
1190 	if (hapd->dpp_pkex->failed) {
1191 		wpa_printf(MSG_DEBUG,
1192 			   "DPP: Terminate PKEX exchange due to an earlier error");
1193 		if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1194 			hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
1195 		dpp_pkex_free(hapd->dpp_pkex);
1196 		hapd->dpp_pkex = NULL;
1197 	}
1198 }
1199 
1200 
1201 static void
1202 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
1203 				  const u8 *buf, size_t len, unsigned int freq)
1204 {
1205 	struct wpabuf *msg;
1206 
1207 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
1208 		   MAC2STR(src));
1209 
1210 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
1211 	 * values here */
1212 
1213 	if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
1214 	    hapd->dpp_pkex->exchange_done) {
1215 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1216 		return;
1217 	}
1218 
1219 	msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
1220 	if (!msg) {
1221 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1222 		return;
1223 	}
1224 
1225 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
1226 		   MAC2STR(src));
1227 
1228 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1229 		" freq=%u type=%d", MAC2STR(src), freq,
1230 		DPP_PA_PKEX_COMMIT_REVEAL_REQ);
1231 	hostapd_drv_send_action(hapd, freq, 0, src,
1232 				wpabuf_head(msg), wpabuf_len(msg));
1233 	wpabuf_free(msg);
1234 }
1235 
1236 
1237 static void
1238 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
1239 				      const u8 *hdr, const u8 *buf, size_t len,
1240 				      unsigned int freq)
1241 {
1242 	struct wpabuf *msg;
1243 	struct dpp_pkex *pkex = hapd->dpp_pkex;
1244 	struct dpp_bootstrap_info *bi;
1245 
1246 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
1247 		   MAC2STR(src));
1248 
1249 	if (!pkex || pkex->initiator || !pkex->exchange_done) {
1250 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1251 		return;
1252 	}
1253 
1254 	msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1255 	if (!msg) {
1256 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1257 		if (hapd->dpp_pkex->failed) {
1258 			wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
1259 			if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1260 				hapd->dpp_pkex->own_bi->pkex_t =
1261 					hapd->dpp_pkex->t;
1262 			dpp_pkex_free(hapd->dpp_pkex);
1263 			hapd->dpp_pkex = NULL;
1264 		}
1265 		return;
1266 	}
1267 
1268 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
1269 		   MACSTR, MAC2STR(src));
1270 
1271 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1272 		" freq=%u type=%d", MAC2STR(src), freq,
1273 		DPP_PA_PKEX_COMMIT_REVEAL_RESP);
1274 	hostapd_drv_send_action(hapd, freq, 0, src,
1275 				wpabuf_head(msg), wpabuf_len(msg));
1276 	wpabuf_free(msg);
1277 
1278 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1279 	if (!bi)
1280 		return;
1281 	hapd->dpp_pkex = NULL;
1282 }
1283 
1284 
1285 static void
1286 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
1287 				       const u8 *hdr, const u8 *buf, size_t len,
1288 				       unsigned int freq)
1289 {
1290 	int res;
1291 	struct dpp_bootstrap_info *bi;
1292 	struct dpp_pkex *pkex = hapd->dpp_pkex;
1293 	char cmd[500];
1294 
1295 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
1296 		   MAC2STR(src));
1297 
1298 	if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1299 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1300 		return;
1301 	}
1302 
1303 	res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1304 	if (res < 0) {
1305 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1306 		return;
1307 	}
1308 
1309 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1310 	if (!bi)
1311 		return;
1312 	hapd->dpp_pkex = NULL;
1313 
1314 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
1315 		    bi->id,
1316 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
1317 	wpa_printf(MSG_DEBUG,
1318 		   "DPP: Start authentication after PKEX with parameters: %s",
1319 		   cmd);
1320 	if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
1321 		wpa_printf(MSG_DEBUG,
1322 			   "DPP: Authentication initialization failed");
1323 		return;
1324 	}
1325 }
1326 
1327 
1328 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
1329 			   const u8 *buf, size_t len, unsigned int freq)
1330 {
1331 	u8 crypto_suite;
1332 	enum dpp_public_action_frame_type type;
1333 	const u8 *hdr;
1334 	unsigned int pkex_t;
1335 
1336 	if (len < DPP_HDR_LEN)
1337 		return;
1338 	if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
1339 		return;
1340 	hdr = buf;
1341 	buf += 4;
1342 	len -= 4;
1343 	crypto_suite = *buf++;
1344 	type = *buf++;
1345 	len -= 2;
1346 
1347 	wpa_printf(MSG_DEBUG,
1348 		   "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1349 		   MACSTR " freq=%u",
1350 		   crypto_suite, type, MAC2STR(src), freq);
1351 	if (crypto_suite != 1) {
1352 		wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
1353 			   crypto_suite);
1354 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1355 			" freq=%u type=%d ignore=unsupported-crypto-suite",
1356 			MAC2STR(src), freq, type);
1357 		return;
1358 	}
1359 	wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
1360 	if (dpp_check_attrs(buf, len) < 0) {
1361 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1362 			" freq=%u type=%d ignore=invalid-attributes",
1363 			MAC2STR(src), freq, type);
1364 		return;
1365 	}
1366 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1367 		" freq=%u type=%d", MAC2STR(src), freq, type);
1368 
1369 #ifdef CONFIG_DPP2
1370 	if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1371 				src, hdr, buf, len, freq, NULL, NULL) == 0)
1372 		return;
1373 #endif /* CONFIG_DPP2 */
1374 
1375 	switch (type) {
1376 	case DPP_PA_AUTHENTICATION_REQ:
1377 		hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
1378 		break;
1379 	case DPP_PA_AUTHENTICATION_RESP:
1380 		hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
1381 		break;
1382 	case DPP_PA_AUTHENTICATION_CONF:
1383 		hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
1384 		break;
1385 	case DPP_PA_PEER_DISCOVERY_REQ:
1386 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
1387 		break;
1388 	case DPP_PA_PKEX_EXCHANGE_REQ:
1389 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq);
1390 		break;
1391 	case DPP_PA_PKEX_EXCHANGE_RESP:
1392 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
1393 		break;
1394 	case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1395 		hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
1396 						      freq);
1397 		break;
1398 	case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1399 		hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
1400 						       freq);
1401 		break;
1402 #ifdef CONFIG_DPP2
1403 	case DPP_PA_CONFIGURATION_RESULT:
1404 		hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
1405 		break;
1406 #endif /* CONFIG_DPP2 */
1407 	default:
1408 		wpa_printf(MSG_DEBUG,
1409 			   "DPP: Ignored unsupported frame subtype %d", type);
1410 		break;
1411 	}
1412 
1413 	if (hapd->dpp_pkex)
1414 		pkex_t = hapd->dpp_pkex->t;
1415 	else if (hapd->dpp_pkex_bi)
1416 		pkex_t = hapd->dpp_pkex_bi->pkex_t;
1417 	else
1418 		pkex_t = 0;
1419 	if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
1420 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
1421 		hostapd_dpp_pkex_remove(hapd, "*");
1422 	}
1423 }
1424 
1425 
1426 struct wpabuf *
1427 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
1428 			    const u8 *query, size_t query_len,
1429 			    const u8 *data, size_t data_len)
1430 {
1431 	struct dpp_authentication *auth = hapd->dpp_auth;
1432 	struct wpabuf *resp;
1433 
1434 	wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
1435 	if (!auth || !auth->auth_success ||
1436 	    os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
1437 #ifdef CONFIG_DPP2
1438 		if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
1439 				     data_len) == 0) {
1440 			/* Response will be forwarded once received over TCP */
1441 			return NULL;
1442 		}
1443 #endif /* CONFIG_DPP2 */
1444 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1445 		return NULL;
1446 	}
1447 	wpa_hexdump(MSG_DEBUG,
1448 		    "DPP: Received Configuration Request (GAS Query Request)",
1449 		    query, query_len);
1450 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
1451 		MAC2STR(sa));
1452 	resp = dpp_conf_req_rx(auth, query, query_len);
1453 	if (!resp)
1454 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1455 	return resp;
1456 }
1457 
1458 
1459 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
1460 {
1461 	struct dpp_authentication *auth = hapd->dpp_auth;
1462 
1463 	if (!auth)
1464 		return;
1465 
1466 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
1467 		   ok);
1468 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1469 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
1470 #ifdef CONFIG_DPP2
1471 	if (ok && auth->peer_version >= 2 &&
1472 	    auth->conf_resp_status == DPP_STATUS_OK) {
1473 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
1474 		auth->waiting_conf_result = 1;
1475 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1476 				     hapd, NULL);
1477 		eloop_register_timeout(2, 0,
1478 				       hostapd_dpp_config_result_wait_timeout,
1479 				       hapd, NULL);
1480 		return;
1481 	}
1482 #endif /* CONFIG_DPP2 */
1483 	hostapd_drv_send_action_cancel_wait(hapd);
1484 
1485 	if (ok)
1486 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1487 	else
1488 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1489 	dpp_auth_deinit(hapd->dpp_auth);
1490 	hapd->dpp_auth = NULL;
1491 }
1492 
1493 
1494 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
1495 {
1496 	struct dpp_authentication *auth;
1497 	int ret = -1;
1498 	char *curve = NULL;
1499 
1500 	auth = os_zalloc(sizeof(*auth));
1501 	if (!auth)
1502 		return -1;
1503 
1504 	curve = get_param(cmd, " curve=");
1505 	hostapd_dpp_set_testing_options(hapd, auth);
1506 	if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1507 				 auth, cmd) == 0 &&
1508 	    dpp_configurator_own_config(auth, curve, 1) == 0) {
1509 		hostapd_dpp_handle_config_obj(hapd, auth);
1510 		ret = 0;
1511 	}
1512 
1513 	dpp_auth_deinit(auth);
1514 	os_free(curve);
1515 
1516 	return ret;
1517 }
1518 
1519 
1520 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
1521 {
1522 	struct dpp_bootstrap_info *own_bi;
1523 	const char *pos, *end;
1524 
1525 	pos = os_strstr(cmd, " own=");
1526 	if (!pos)
1527 		return -1;
1528 	pos += 5;
1529 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
1530 	if (!own_bi) {
1531 		wpa_printf(MSG_DEBUG,
1532 			   "DPP: Identified bootstrap info not found");
1533 		return -1;
1534 	}
1535 	if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
1536 		wpa_printf(MSG_DEBUG,
1537 			   "DPP: Identified bootstrap info not for PKEX");
1538 		return -1;
1539 	}
1540 	hapd->dpp_pkex_bi = own_bi;
1541 	own_bi->pkex_t = 0; /* clear pending errors on new code */
1542 
1543 	os_free(hapd->dpp_pkex_identifier);
1544 	hapd->dpp_pkex_identifier = NULL;
1545 	pos = os_strstr(cmd, " identifier=");
1546 	if (pos) {
1547 		pos += 12;
1548 		end = os_strchr(pos, ' ');
1549 		if (!end)
1550 			return -1;
1551 		hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
1552 		if (!hapd->dpp_pkex_identifier)
1553 			return -1;
1554 		os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
1555 		hapd->dpp_pkex_identifier[end - pos] = '\0';
1556 	}
1557 
1558 	pos = os_strstr(cmd, " code=");
1559 	if (!pos)
1560 		return -1;
1561 	os_free(hapd->dpp_pkex_code);
1562 	hapd->dpp_pkex_code = os_strdup(pos + 6);
1563 	if (!hapd->dpp_pkex_code)
1564 		return -1;
1565 
1566 	if (os_strstr(cmd, " init=1")) {
1567 		struct wpabuf *msg;
1568 
1569 		wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
1570 		dpp_pkex_free(hapd->dpp_pkex);
1571 		hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
1572 					       hapd->own_addr,
1573 					       hapd->dpp_pkex_identifier,
1574 					       hapd->dpp_pkex_code);
1575 		if (!hapd->dpp_pkex)
1576 			return -1;
1577 
1578 		msg = hapd->dpp_pkex->exchange_req;
1579 		/* TODO: Which channel to use? */
1580 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1581 			" freq=%u type=%d", MAC2STR(broadcast), 2437,
1582 			DPP_PA_PKEX_EXCHANGE_REQ);
1583 		hostapd_drv_send_action(hapd, 2437, 0, broadcast,
1584 					wpabuf_head(msg), wpabuf_len(msg));
1585 	}
1586 
1587 	/* TODO: Support multiple PKEX info entries */
1588 
1589 	os_free(hapd->dpp_pkex_auth_cmd);
1590 	hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
1591 
1592 	return 1;
1593 }
1594 
1595 
1596 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
1597 {
1598 	unsigned int id_val;
1599 
1600 	if (os_strcmp(id, "*") == 0) {
1601 		id_val = 0;
1602 	} else {
1603 		id_val = atoi(id);
1604 		if (id_val == 0)
1605 			return -1;
1606 	}
1607 
1608 	if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
1609 		return -1;
1610 
1611 	/* TODO: Support multiple PKEX entries */
1612 	os_free(hapd->dpp_pkex_code);
1613 	hapd->dpp_pkex_code = NULL;
1614 	os_free(hapd->dpp_pkex_identifier);
1615 	hapd->dpp_pkex_identifier = NULL;
1616 	os_free(hapd->dpp_pkex_auth_cmd);
1617 	hapd->dpp_pkex_auth_cmd = NULL;
1618 	hapd->dpp_pkex_bi = NULL;
1619 	/* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
1620 	dpp_pkex_free(hapd->dpp_pkex);
1621 	hapd->dpp_pkex = NULL;
1622 	return 0;
1623 }
1624 
1625 
1626 void hostapd_dpp_stop(struct hostapd_data *hapd)
1627 {
1628 	dpp_auth_deinit(hapd->dpp_auth);
1629 	hapd->dpp_auth = NULL;
1630 	dpp_pkex_free(hapd->dpp_pkex);
1631 	hapd->dpp_pkex = NULL;
1632 }
1633 
1634 
1635 #ifdef CONFIG_DPP2
1636 
1637 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
1638 				 const u8 *msg, size_t len)
1639 {
1640 	struct hostapd_data *hapd = ctx;
1641 	u8 *buf;
1642 
1643 	wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
1644 		   MAC2STR(addr), freq);
1645 	buf = os_malloc(2 + len);
1646 	if (!buf)
1647 		return;
1648 	buf[0] = WLAN_ACTION_PUBLIC;
1649 	buf[1] = WLAN_PA_VENDOR_SPECIFIC;
1650 	os_memcpy(buf + 2, msg, len);
1651 	hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
1652 	os_free(buf);
1653 }
1654 
1655 
1656 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
1657 					  u8 dialog_token, int prot,
1658 					  struct wpabuf *buf)
1659 {
1660 	struct hostapd_data *hapd = ctx;
1661 
1662 	gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf);
1663 }
1664 
1665 #endif /* CONFIG_DPP2 */
1666 
1667 
1668 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
1669 {
1670 #ifdef CONFIG_DPP2
1671 	struct dpp_controller_conf *ctrl;
1672 	struct dpp_relay_config config;
1673 
1674 	os_memset(&config, 0, sizeof(config));
1675 	config.cb_ctx = hapd;
1676 	config.tx = hostapd_dpp_relay_tx;
1677 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
1678 	for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
1679 		config.ipaddr = &ctrl->ipaddr;
1680 		config.pkhash = ctrl->pkhash;
1681 		if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
1682 					     &config) < 0)
1683 			return -1;
1684 	}
1685 #endif /* CONFIG_DPP2 */
1686 
1687 	return 0;
1688 }
1689 
1690 
1691 int hostapd_dpp_init(struct hostapd_data *hapd)
1692 {
1693 	hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
1694 	hapd->dpp_init_done = 1;
1695 	return hostapd_dpp_add_controllers(hapd);
1696 }
1697 
1698 
1699 void hostapd_dpp_deinit(struct hostapd_data *hapd)
1700 {
1701 #ifdef CONFIG_TESTING_OPTIONS
1702 	os_free(hapd->dpp_config_obj_override);
1703 	hapd->dpp_config_obj_override = NULL;
1704 	os_free(hapd->dpp_discovery_override);
1705 	hapd->dpp_discovery_override = NULL;
1706 	os_free(hapd->dpp_groups_override);
1707 	hapd->dpp_groups_override = NULL;
1708 	hapd->dpp_ignore_netaccesskey_mismatch = 0;
1709 #endif /* CONFIG_TESTING_OPTIONS */
1710 	if (!hapd->dpp_init_done)
1711 		return;
1712 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1713 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1714 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
1715 #ifdef CONFIG_DPP2
1716 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1717 			     NULL);
1718 #endif /* CONFIG_DPP2 */
1719 	dpp_auth_deinit(hapd->dpp_auth);
1720 	hapd->dpp_auth = NULL;
1721 	hostapd_dpp_pkex_remove(hapd, "*");
1722 	hapd->dpp_pkex = NULL;
1723 	os_free(hapd->dpp_configurator_params);
1724 	hapd->dpp_configurator_params = NULL;
1725 }
1726