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
24static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
25static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
26static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
27static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
28
29static 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 */
38int 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
65static 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
86static 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
122void 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
209static 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
281static 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
299static 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
310static 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
397int 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);
483fail:
484	return -1;
485}
486
487
488int 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
517void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
518{
519	/* TODO: Stop listen operation on non-operating channel */
520}
521
522
523static 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
609static 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
680static 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 */
731fail:
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	}
757fail2:
758#endif /* CONFIG_DPP2 */
759	dpp_auth_deinit(hapd->dpp_auth);
760	hapd->dpp_auth = NULL;
761}
762
763
764static 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
802static 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
824static 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
877static 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
908static 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
925static 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
963static 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
992skip_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
1009skip_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
1041skip_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
1055static 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
1146static void
1147hostapd_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
1201static void
1202hostapd_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
1237static void
1238hostapd_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
1285static void
1286hostapd_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
1328void 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
1426struct wpabuf *
1427hostapd_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
1459void 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
1494int 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
1520int 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
1596int 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
1626void 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
1637static 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
1656static 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
1668static 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
1691int 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
1699void 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