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