• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hostapd / DPP integration
3  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4  * Copyright (c) 2018-2020, The Linux Foundation
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9 
10 #include "utils/includes.h"
11 
12 #include "utils/common.h"
13 #include "utils/eloop.h"
14 #include "common/dpp.h"
15 #include "common/gas.h"
16 #include "common/wpa_ctrl.h"
17 #include "hostapd.h"
18 #include "ap_drv_ops.h"
19 #include "gas_query_ap.h"
20 #include "gas_serv.h"
21 #include "wpa_auth.h"
22 #include "dpp_hostapd.h"
23 
24 
25 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
26 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
27 					       void *timeout_ctx);
28 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
29 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
30 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
31 #ifdef CONFIG_DPP2
32 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
33 						    void *timeout_ctx);
34 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
35 					  struct dpp_authentication *auth,
36 					  struct dpp_config_obj *conf);
37 #endif /* CONFIG_DPP2 */
38 
39 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
40 
41 
42 /**
43  * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
44  * @hapd: Pointer to hostapd_data
45  * @cmd: DPP URI read from a QR Code
46  * Returns: Identifier of the stored info or -1 on failure
47  */
hostapd_dpp_qr_code(struct hostapd_data * hapd,const char * cmd)48 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
49 {
50 	struct dpp_bootstrap_info *bi;
51 	struct dpp_authentication *auth = hapd->dpp_auth;
52 
53 	bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
54 	if (!bi)
55 		return -1;
56 
57 	if (auth && auth->response_pending &&
58 	    dpp_notify_new_qr_code(auth, bi) == 1) {
59 		wpa_printf(MSG_DEBUG,
60 			   "DPP: Sending out pending authentication response");
61 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
62 			" freq=%u type=%d",
63 			MAC2STR(auth->peer_mac_addr), auth->curr_freq,
64 			DPP_PA_AUTHENTICATION_RESP);
65 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
66 					auth->peer_mac_addr,
67 					wpabuf_head(hapd->dpp_auth->resp_msg),
68 					wpabuf_len(hapd->dpp_auth->resp_msg));
69 	}
70 
71 #ifdef CONFIG_DPP2
72 	dpp_controller_new_qr_code(hapd->iface->interfaces->dpp, bi);
73 #endif /* CONFIG_DPP2 */
74 
75 	return bi->id;
76 }
77 
78 
79 /**
80  * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
81  * @hapd: Pointer to hostapd_data
82  * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
83  * Returns: Identifier of the stored info or -1 on failure
84  */
hostapd_dpp_nfc_uri(struct hostapd_data * hapd,const char * cmd)85 int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
86 {
87 	struct dpp_bootstrap_info *bi;
88 
89 	bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
90 	if (!bi)
91 		return -1;
92 
93 	return bi->id;
94 }
95 
96 
hostapd_dpp_nfc_handover_req(struct hostapd_data * hapd,const char * cmd)97 int hostapd_dpp_nfc_handover_req(struct hostapd_data *hapd, const char *cmd)
98 {
99 	const char *pos;
100 	struct dpp_bootstrap_info *peer_bi, *own_bi;
101 
102 	pos = os_strstr(cmd, " own=");
103 	if (!pos)
104 		return -1;
105 	pos += 5;
106 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
107 	if (!own_bi)
108 		return -1;
109 
110 	pos = os_strstr(cmd, " uri=");
111 	if (!pos)
112 		return -1;
113 	pos += 5;
114 	peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
115 	if (!peer_bi) {
116 		wpa_printf(MSG_INFO,
117 			   "DPP: Failed to parse URI from NFC Handover Request");
118 		return -1;
119 	}
120 
121 	if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
122 		return -1;
123 
124 	return peer_bi->id;
125 }
126 
127 
hostapd_dpp_nfc_handover_sel(struct hostapd_data * hapd,const char * cmd)128 int hostapd_dpp_nfc_handover_sel(struct hostapd_data *hapd, const char *cmd)
129 {
130 	const char *pos;
131 	struct dpp_bootstrap_info *peer_bi, *own_bi;
132 
133 	pos = os_strstr(cmd, " own=");
134 	if (!pos)
135 		return -1;
136 	pos += 5;
137 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
138 	if (!own_bi)
139 		return -1;
140 
141 	pos = os_strstr(cmd, " uri=");
142 	if (!pos)
143 		return -1;
144 	pos += 5;
145 	peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
146 	if (!peer_bi) {
147 		wpa_printf(MSG_INFO,
148 			   "DPP: Failed to parse URI from NFC Handover Select");
149 		return -1;
150 	}
151 
152 	if (peer_bi->curve != own_bi->curve) {
153 		wpa_printf(MSG_INFO,
154 			   "DPP: Peer (NFC Handover Selector) used different curve");
155 		return -1;
156 	}
157 
158 	return peer_bi->id;
159 }
160 
161 
hostapd_dpp_auth_resp_retry_timeout(void * eloop_ctx,void * timeout_ctx)162 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
163 						void *timeout_ctx)
164 {
165 	struct hostapd_data *hapd = eloop_ctx;
166 	struct dpp_authentication *auth = hapd->dpp_auth;
167 
168 	if (!auth || !auth->resp_msg)
169 		return;
170 
171 	wpa_printf(MSG_DEBUG,
172 		   "DPP: Retry Authentication Response after timeout");
173 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
174 		" freq=%u type=%d",
175 		MAC2STR(auth->peer_mac_addr), auth->curr_freq,
176 		DPP_PA_AUTHENTICATION_RESP);
177 	hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
178 				wpabuf_head(auth->resp_msg),
179 				wpabuf_len(auth->resp_msg));
180 }
181 
182 
hostapd_dpp_auth_resp_retry(struct hostapd_data * hapd)183 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
184 {
185 	struct dpp_authentication *auth = hapd->dpp_auth;
186 	unsigned int wait_time, max_tries;
187 
188 	if (!auth || !auth->resp_msg)
189 		return;
190 
191 	if (hapd->dpp_resp_max_tries)
192 		max_tries = hapd->dpp_resp_max_tries;
193 	else
194 		max_tries = 5;
195 	auth->auth_resp_tries++;
196 	if (auth->auth_resp_tries >= max_tries) {
197 		wpa_printf(MSG_INFO,
198 			   "DPP: No confirm received from initiator - stopping exchange");
199 		hostapd_drv_send_action_cancel_wait(hapd);
200 		dpp_auth_deinit(hapd->dpp_auth);
201 		hapd->dpp_auth = NULL;
202 		return;
203 	}
204 
205 	if (hapd->dpp_resp_retry_time)
206 		wait_time = hapd->dpp_resp_retry_time;
207 	else
208 		wait_time = 1000;
209 	wpa_printf(MSG_DEBUG,
210 		   "DPP: Schedule retransmission of Authentication Response frame in %u ms",
211 		wait_time);
212 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
213 	eloop_register_timeout(wait_time / 1000,
214 			       (wait_time % 1000) * 1000,
215 			       hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
216 }
217 
218 
hostapd_dpp_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)219 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
220 			   const u8 *data, size_t data_len, int ok)
221 {
222 	struct dpp_authentication *auth = hapd->dpp_auth;
223 
224 	wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR_SEC " ok=%d",
225 		   MAC2STR_SEC(dst), ok);
226 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
227 		" result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
228 
229 	if (!hapd->dpp_auth) {
230 		wpa_printf(MSG_DEBUG,
231 			   "DPP: Ignore TX status since there is no ongoing authentication exchange");
232 		return;
233 	}
234 
235 #ifdef CONFIG_DPP2
236 	if (auth->connect_on_tx_status) {
237 		wpa_printf(MSG_DEBUG,
238 			   "DPP: Complete exchange on configuration result");
239 		dpp_auth_deinit(hapd->dpp_auth);
240 		hapd->dpp_auth = NULL;
241 		return;
242 	}
243 #endif /* CONFIG_DPP2 */
244 
245 	if (hapd->dpp_auth->remove_on_tx_status) {
246 		wpa_printf(MSG_DEBUG,
247 			   "DPP: Terminate authentication exchange due to an earlier error");
248 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
249 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
250 				     hapd, NULL);
251 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
252 				     hapd, NULL);
253 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
254 				     NULL);
255 #ifdef CONFIG_DPP2
256 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
257 				     hapd, NULL);
258 #endif /* CONFIG_DPP2 */
259 		hostapd_drv_send_action_cancel_wait(hapd);
260 		dpp_auth_deinit(hapd->dpp_auth);
261 		hapd->dpp_auth = NULL;
262 		return;
263 	}
264 
265 	if (hapd->dpp_auth_ok_on_ack)
266 		hostapd_dpp_auth_success(hapd, 1);
267 
268 	if (!is_broadcast_ether_addr(dst) && !ok) {
269 		wpa_printf(MSG_DEBUG,
270 			   "DPP: Unicast DPP Action frame was not ACKed");
271 		if (auth->waiting_auth_resp) {
272 			/* In case of DPP Authentication Request frame, move to
273 			 * the next channel immediately. */
274 			hostapd_drv_send_action_cancel_wait(hapd);
275 			hostapd_dpp_auth_init_next(hapd);
276 			return;
277 		}
278 		if (auth->waiting_auth_conf) {
279 			hostapd_dpp_auth_resp_retry(hapd);
280 			return;
281 		}
282 	}
283 
284 	if (auth->waiting_auth_conf &&
285 	    auth->auth_resp_status == DPP_STATUS_OK) {
286 		/* Make sure we do not get stuck waiting for Auth Confirm
287 		 * indefinitely after successfully transmitted Auth Response to
288 		 * allow new authentication exchanges to be started. */
289 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd,
290 				     NULL);
291 		eloop_register_timeout(1, 0, hostapd_dpp_auth_conf_wait_timeout,
292 				       hapd, NULL);
293 	}
294 
295 	if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
296 		/* Allow timeout handling to stop iteration if no response is
297 		 * received from a peer that has ACKed a request. */
298 		auth->auth_req_ack = 1;
299 	}
300 
301 	if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
302 	    hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
303 		wpa_printf(MSG_DEBUG,
304 			   "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
305 			   hapd->dpp_auth->curr_freq,
306 			   hapd->dpp_auth->neg_freq);
307 		hostapd_drv_send_action_cancel_wait(hapd);
308 
309 		if (hapd->dpp_auth->neg_freq !=
310 		    (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
311 			/* TODO: Listen operation on non-operating channel */
312 			wpa_printf(MSG_INFO,
313 				   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
314 				   hapd->dpp_auth->neg_freq, hapd->iface->freq);
315 		}
316 	}
317 
318 	if (hapd->dpp_auth_ok_on_ack)
319 		hapd->dpp_auth_ok_on_ack = 0;
320 }
321 
322 
hostapd_dpp_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)323 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
324 {
325 	struct hostapd_data *hapd = eloop_ctx;
326 	struct dpp_authentication *auth = hapd->dpp_auth;
327 	unsigned int freq;
328 	struct os_reltime now, diff;
329 	unsigned int wait_time, diff_ms;
330 
331 	if (!auth || !auth->waiting_auth_resp)
332 		return;
333 
334 	wait_time = hapd->dpp_resp_wait_time ?
335 		hapd->dpp_resp_wait_time : 2000;
336 	os_get_reltime(&now);
337 	os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
338 	diff_ms = diff.sec * 1000 + diff.usec / 1000;
339 	wpa_printf(MSG_DEBUG,
340 		   "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
341 		   wait_time, diff_ms);
342 
343 	if (auth->auth_req_ack && diff_ms >= wait_time) {
344 		/* Peer ACK'ed Authentication Request frame, but did not reply
345 		 * with Authentication Response frame within two seconds. */
346 		wpa_printf(MSG_INFO,
347 			   "DPP: No response received from responder - stopping initiation attempt");
348 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
349 		hostapd_drv_send_action_cancel_wait(hapd);
350 		hostapd_dpp_listen_stop(hapd);
351 		dpp_auth_deinit(auth);
352 		hapd->dpp_auth = NULL;
353 		return;
354 	}
355 
356 	if (diff_ms >= wait_time) {
357 		/* Authentication Request frame was not ACK'ed and no reply
358 		 * was receiving within two seconds. */
359 		wpa_printf(MSG_DEBUG,
360 			   "DPP: Continue Initiator channel iteration");
361 		hostapd_drv_send_action_cancel_wait(hapd);
362 		hostapd_dpp_listen_stop(hapd);
363 		hostapd_dpp_auth_init_next(hapd);
364 		return;
365 	}
366 
367 	/* Driver did not support 2000 ms long wait_time with TX command, so
368 	 * schedule listen operation to continue waiting for the response.
369 	 *
370 	 * DPP listen operations continue until stopped, so simply schedule a
371 	 * new call to this function at the point when the two second reply
372 	 * wait has expired. */
373 	wait_time -= diff_ms;
374 
375 	freq = auth->curr_freq;
376 	if (auth->neg_freq > 0)
377 		freq = auth->neg_freq;
378 	wpa_printf(MSG_DEBUG,
379 		   "DPP: Continue reply wait on channel %u MHz for %u ms",
380 		   freq, wait_time);
381 	hapd->dpp_in_response_listen = 1;
382 
383 	if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
384 		/* TODO: Listen operation on non-operating channel */
385 		wpa_printf(MSG_INFO,
386 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
387 			   freq, hapd->iface->freq);
388 	}
389 
390 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
391 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
392 }
393 
394 
hostapd_dpp_auth_conf_wait_timeout(void * eloop_ctx,void * timeout_ctx)395 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
396 					       void *timeout_ctx)
397 {
398 	struct hostapd_data *hapd = eloop_ctx;
399 	struct dpp_authentication *auth = hapd->dpp_auth;
400 
401 	if (!auth || !auth->waiting_auth_conf)
402 		return;
403 
404 	wpa_printf(MSG_DEBUG,
405 		   "DPP: Terminate authentication exchange due to Auth Confirm timeout");
406 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
407 		"No Auth Confirm received");
408 	hostapd_drv_send_action_cancel_wait(hapd);
409 	dpp_auth_deinit(auth);
410 	hapd->dpp_auth = NULL;
411 }
412 
413 
hostapd_dpp_set_testing_options(struct hostapd_data * hapd,struct dpp_authentication * auth)414 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
415 					    struct dpp_authentication *auth)
416 {
417 #ifdef CONFIG_TESTING_OPTIONS
418 	if (hapd->dpp_config_obj_override)
419 		auth->config_obj_override =
420 			os_strdup(hapd->dpp_config_obj_override);
421 	if (hapd->dpp_discovery_override)
422 		auth->discovery_override =
423 			os_strdup(hapd->dpp_discovery_override);
424 	if (hapd->dpp_groups_override)
425 		auth->groups_override = os_strdup(hapd->dpp_groups_override);
426 	auth->ignore_netaccesskey_mismatch =
427 		hapd->dpp_ignore_netaccesskey_mismatch;
428 #endif /* CONFIG_TESTING_OPTIONS */
429 }
430 
431 
hostapd_dpp_init_timeout(void * eloop_ctx,void * timeout_ctx)432 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
433 {
434 	struct hostapd_data *hapd = eloop_ctx;
435 
436 	if (!hapd->dpp_auth)
437 		return;
438 	wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
439 	hostapd_dpp_auth_init_next(hapd);
440 }
441 
442 
hostapd_dpp_auth_init_next(struct hostapd_data * hapd)443 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
444 {
445 	struct dpp_authentication *auth = hapd->dpp_auth;
446 	const u8 *dst;
447 	unsigned int wait_time, max_wait_time, freq, max_tries, used;
448 	struct os_reltime now, diff;
449 
450 	if (!auth)
451 		return -1;
452 
453 	if (auth->freq_idx == 0)
454 		os_get_reltime(&hapd->dpp_init_iter_start);
455 
456 	if (auth->freq_idx >= auth->num_freq) {
457 		auth->num_freq_iters++;
458 		if (hapd->dpp_init_max_tries)
459 			max_tries = hapd->dpp_init_max_tries;
460 		else
461 			max_tries = 5;
462 		if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
463 			wpa_printf(MSG_INFO,
464 				   "DPP: No response received from responder - stopping initiation attempt");
465 			wpa_msg(hapd->msg_ctx, MSG_INFO,
466 				DPP_EVENT_AUTH_INIT_FAILED);
467 			eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
468 					     hapd, NULL);
469 			hostapd_drv_send_action_cancel_wait(hapd);
470 			dpp_auth_deinit(hapd->dpp_auth);
471 			hapd->dpp_auth = NULL;
472 			return -1;
473 		}
474 		auth->freq_idx = 0;
475 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
476 		if (hapd->dpp_init_retry_time)
477 			wait_time = hapd->dpp_init_retry_time;
478 		else
479 			wait_time = 10000;
480 		os_get_reltime(&now);
481 		os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
482 		used = diff.sec * 1000 + diff.usec / 1000;
483 		if (used > wait_time)
484 			wait_time = 0;
485 		else
486 			wait_time -= used;
487 		wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
488 			   wait_time);
489 		eloop_register_timeout(wait_time / 1000,
490 				       (wait_time % 1000) * 1000,
491 				       hostapd_dpp_init_timeout, hapd,
492 				       NULL);
493 		return 0;
494 	}
495 	freq = auth->freq[auth->freq_idx++];
496 	auth->curr_freq = freq;
497 
498 	if (!is_zero_ether_addr(auth->peer_mac_addr))
499 		dst = auth->peer_mac_addr;
500 	else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
501 		dst = broadcast;
502 	else
503 		dst = auth->peer_bi->mac_addr;
504 	hapd->dpp_auth_ok_on_ack = 0;
505 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
506 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
507 	max_wait_time = hapd->dpp_resp_wait_time ?
508 		hapd->dpp_resp_wait_time : 2000;
509 	if (wait_time > max_wait_time)
510 		wait_time = max_wait_time;
511 	wait_time += 10; /* give the driver some extra time to complete */
512 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
513 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
514 	wait_time -= 10;
515 	if (auth->neg_freq > 0 && freq != auth->neg_freq) {
516 		wpa_printf(MSG_DEBUG,
517 			   "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
518 			   freq, auth->neg_freq);
519 	}
520 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
521 		" freq=%u type=%d",
522 		MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
523 	auth->auth_req_ack = 0;
524 	os_get_reltime(&hapd->dpp_last_init);
525 	return hostapd_drv_send_action(hapd, freq, wait_time,
526 				       dst,
527 				       wpabuf_head(hapd->dpp_auth->req_msg),
528 				       wpabuf_len(hapd->dpp_auth->req_msg));
529 }
530 
531 
532 #ifdef CONFIG_DPP2
hostapd_dpp_process_conf_obj(void * ctx,struct dpp_authentication * auth)533 static int hostapd_dpp_process_conf_obj(void *ctx,
534 				     struct dpp_authentication *auth)
535 {
536 	struct hostapd_data *hapd = ctx;
537 	unsigned int i;
538 
539 	for (i = 0; i < auth->num_conf_obj; i++)
540 		hostapd_dpp_handle_config_obj(hapd, auth,
541 					      &auth->conf_obj[i]);
542 
543 	return 0;
544 }
545 #endif /* CONFIG_DPP2 */
546 
547 
hostapd_dpp_auth_init(struct hostapd_data * hapd,const char * cmd)548 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
549 {
550 	const char *pos;
551 	struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
552 	struct dpp_authentication *auth;
553 	u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
554 	unsigned int neg_freq = 0;
555 	int tcp = 0;
556 #ifdef CONFIG_DPP2
557 	int tcp_port = DPP_TCP_PORT;
558 	struct hostapd_ip_addr ipaddr;
559 	char *addr;
560 #endif /* CONFIG_DPP2 */
561 
562 	pos = os_strstr(cmd, " peer=");
563 	if (!pos)
564 		return -1;
565 	pos += 6;
566 	peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
567 	if (!peer_bi) {
568 		wpa_printf(MSG_INFO,
569 			   "DPP: Could not find bootstrapping info for the identified peer");
570 		return -1;
571 	}
572 
573 #ifdef CONFIG_DPP2
574 	pos = os_strstr(cmd, " tcp_port=");
575 	if (pos) {
576 		pos += 10;
577 		tcp_port = atoi(pos);
578 	}
579 
580 	addr = get_param(cmd, " tcp_addr=");
581 	if (addr) {
582 		int res;
583 
584 		res = hostapd_parse_ip_addr(addr, &ipaddr);
585 		os_free(addr);
586 		if (res)
587 			return -1;
588 		tcp = 1;
589 	}
590 #endif /* CONFIG_DPP2 */
591 
592 	pos = os_strstr(cmd, " own=");
593 	if (pos) {
594 		pos += 5;
595 		own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
596 					      atoi(pos));
597 		if (!own_bi) {
598 			wpa_printf(MSG_INFO,
599 				   "DPP: Could not find bootstrapping info for the identified local entry");
600 			return -1;
601 		}
602 
603 		if (peer_bi->curve != own_bi->curve) {
604 			wpa_printf(MSG_INFO,
605 				   "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
606 				   peer_bi->curve->name, own_bi->curve->name);
607 			return -1;
608 		}
609 	}
610 
611 	pos = os_strstr(cmd, " role=");
612 	if (pos) {
613 		pos += 6;
614 		if (os_strncmp(pos, "configurator", 12) == 0)
615 			allowed_roles = DPP_CAPAB_CONFIGURATOR;
616 		else if (os_strncmp(pos, "enrollee", 8) == 0)
617 			allowed_roles = DPP_CAPAB_ENROLLEE;
618 		else if (os_strncmp(pos, "either", 6) == 0)
619 			allowed_roles = DPP_CAPAB_CONFIGURATOR |
620 				DPP_CAPAB_ENROLLEE;
621 		else
622 			goto fail;
623 	}
624 
625 	pos = os_strstr(cmd, " neg_freq=");
626 	if (pos)
627 		neg_freq = atoi(pos + 10);
628 
629 	if (!tcp && hapd->dpp_auth) {
630 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
631 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
632 				     hapd, NULL);
633 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
634 				     hapd, NULL);
635 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
636 				     NULL);
637 #ifdef CONFIG_DPP2
638 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
639 				     hapd, NULL);
640 #endif /* CONFIG_DPP2 */
641 		hostapd_drv_send_action_cancel_wait(hapd);
642 		dpp_auth_deinit(hapd->dpp_auth);
643 	}
644 
645 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
646 			     peer_bi, own_bi, allowed_roles, neg_freq,
647 			     hapd->iface->hw_features,
648 			     hapd->iface->num_hw_features);
649 	if (!auth)
650 		goto fail;
651 	hostapd_dpp_set_testing_options(hapd, auth);
652 	if (dpp_set_configurator(auth, cmd) < 0) {
653 		dpp_auth_deinit(auth);
654 		goto fail;
655 	}
656 
657 	auth->neg_freq = neg_freq;
658 
659 	if (!is_zero_ether_addr(peer_bi->mac_addr))
660 		os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
661 
662 #ifdef CONFIG_DPP2
663 	if (tcp)
664 		return dpp_tcp_init(hapd->iface->interfaces->dpp, auth,
665 				    &ipaddr, tcp_port, hapd->conf->dpp_name,
666 				    DPP_NETROLE_AP, hapd->msg_ctx, hapd,
667 				    hostapd_dpp_process_conf_obj);
668 #endif /* CONFIG_DPP2 */
669 
670 	hapd->dpp_auth = auth;
671 	return hostapd_dpp_auth_init_next(hapd);
672 fail:
673 	return -1;
674 }
675 
676 
hostapd_dpp_listen(struct hostapd_data * hapd,const char * cmd)677 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
678 {
679 	int freq;
680 
681 	freq = atoi(cmd);
682 	if (freq <= 0)
683 		return -1;
684 
685 	if (os_strstr(cmd, " role=configurator"))
686 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
687 	else if (os_strstr(cmd, " role=enrollee"))
688 		hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
689 	else
690 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
691 			DPP_CAPAB_ENROLLEE;
692 	hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
693 
694 	if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
695 		/* TODO: Listen operation on non-operating channel */
696 		wpa_printf(MSG_INFO,
697 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
698 			   freq, hapd->iface->freq);
699 		return -1;
700 	}
701 
702 	hostapd_drv_dpp_listen(hapd, true);
703 	return 0;
704 }
705 
706 
hostapd_dpp_listen_stop(struct hostapd_data * hapd)707 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
708 {
709 	hostapd_drv_dpp_listen(hapd, false);
710 	/* TODO: Stop listen operation on non-operating channel */
711 }
712 
713 
hostapd_dpp_rx_auth_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)714 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
715 				    const u8 *hdr, const u8 *buf, size_t len,
716 				    unsigned int freq)
717 {
718 	const u8 *r_bootstrap, *i_bootstrap;
719 	u16 r_bootstrap_len, i_bootstrap_len;
720 	struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
721 
722 	if (!hapd->iface->interfaces->dpp)
723 		return;
724 
725 	wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR_SEC,
726 		   MAC2STR_SEC(src));
727 
728 #ifdef CONFIG_DPP2
729 	hostapd_dpp_chirp_stop(hapd);
730 #endif /* CONFIG_DPP2 */
731 
732 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
733 				   &r_bootstrap_len);
734 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
735 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
736 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
737 		return;
738 	}
739 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
740 		    r_bootstrap, r_bootstrap_len);
741 
742 	i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
743 				   &i_bootstrap_len);
744 	if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
745 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
746 			"Missing or invalid required Initiator Bootstrapping Key Hash attribute");
747 		return;
748 	}
749 	wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
750 		    i_bootstrap, i_bootstrap_len);
751 
752 	/* Try to find own and peer bootstrapping key matches based on the
753 	 * received hash values */
754 	dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
755 				r_bootstrap, &own_bi, &peer_bi);
756 #ifdef CONFIG_DPP2
757 	if (!own_bi) {
758 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
759 					src, hdr, buf, len, freq, i_bootstrap,
760 					r_bootstrap, hapd) == 0)
761 			return;
762 	}
763 #endif /* CONFIG_DPP2 */
764 	if (!own_bi) {
765 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
766 			"No matching own bootstrapping key found - ignore message");
767 		return;
768 	}
769 
770 	if (hapd->dpp_auth) {
771 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
772 			"Already in DPP authentication exchange - ignore new one");
773 		return;
774 	}
775 
776 	hapd->dpp_auth_ok_on_ack = 0;
777 	hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
778 					 hapd->msg_ctx, hapd->dpp_allowed_roles,
779 					 hapd->dpp_qr_mutual,
780 					 peer_bi, own_bi, freq, hdr, buf, len);
781 	if (!hapd->dpp_auth) {
782 		wpa_printf(MSG_DEBUG, "DPP: No response generated");
783 		return;
784 	}
785 	hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
786 	if (dpp_set_configurator(hapd->dpp_auth,
787 				 hapd->dpp_configurator_params) < 0) {
788 		dpp_auth_deinit(hapd->dpp_auth);
789 		hapd->dpp_auth = NULL;
790 		return;
791 	}
792 	os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
793 
794 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
795 		" freq=%u type=%d",
796 		MAC2STR(src), hapd->dpp_auth->curr_freq,
797 		DPP_PA_AUTHENTICATION_RESP);
798 	hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
799 				src, wpabuf_head(hapd->dpp_auth->resp_msg),
800 				wpabuf_len(hapd->dpp_auth->resp_msg));
801 }
802 
803 
hostapd_dpp_handle_config_obj(struct hostapd_data * hapd,struct dpp_authentication * auth,struct dpp_config_obj * conf)804 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
805 					  struct dpp_authentication *auth,
806 					  struct dpp_config_obj *conf)
807 {
808 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
809 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
810 		dpp_akm_str(conf->akm));
811 	if (conf->ssid_len)
812 		wpa_msg_only_for_cb(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
813 			wpa_ssid_txt(conf->ssid, conf->ssid_len));
814 		wpa_printf(MSG_INFO, "%s", DPP_EVENT_CONFOBJ_SSID "%s",
815 			anonymize_ssid(wpa_ssid_txt(conf->ssid, conf->ssid_len)));
816 	if (conf->connector) {
817 		/* TODO: Save the Connector and consider using a command
818 		 * to fetch the value instead of sending an event with
819 		 * it. The Connector could end up being larger than what
820 		 * most clients are ready to receive as an event
821 		 * message. */
822 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
823 			conf->connector);
824 	}
825 	if (conf->passphrase[0]) {
826 		char hex[64 * 2 + 1];
827 
828 		wpa_snprintf_hex(hex, sizeof(hex),
829 				 (const u8 *) conf->passphrase,
830 				 os_strlen(conf->passphrase));
831 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
832 			hex);
833 	} else if (conf->psk_set) {
834 		char hex[PMK_LEN * 2 + 1];
835 
836 		wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
837 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
838 			hex);
839 	}
840 	if (conf->c_sign_key) {
841 		char *hex;
842 		size_t hexlen;
843 
844 		hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
845 		hex = os_malloc(hexlen);
846 		if (hex) {
847 			wpa_snprintf_hex(hex, hexlen,
848 					 wpabuf_head(conf->c_sign_key),
849 					 wpabuf_len(conf->c_sign_key));
850 			wpa_msg(hapd->msg_ctx, MSG_INFO,
851 				DPP_EVENT_C_SIGN_KEY "%s", hex);
852 			os_free(hex);
853 		}
854 	}
855 	if (auth->net_access_key) {
856 		char *hex;
857 		size_t hexlen;
858 
859 		hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
860 		hex = os_malloc(hexlen);
861 		if (hex) {
862 			wpa_snprintf_hex(hex, hexlen,
863 					 wpabuf_head(auth->net_access_key),
864 					 wpabuf_len(auth->net_access_key));
865 			if (auth->net_access_key_expiry)
866 				wpa_msg(hapd->msg_ctx, MSG_INFO,
867 					DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
868 					(unsigned long)
869 					auth->net_access_key_expiry);
870 			else
871 				wpa_msg(hapd->msg_ctx, MSG_INFO,
872 					DPP_EVENT_NET_ACCESS_KEY "%s", hex);
873 			os_free(hex);
874 		}
875 	}
876 }
877 
878 
hostapd_dpp_handle_key_pkg(struct hostapd_data * hapd,struct dpp_asymmetric_key * key)879 static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
880 				      struct dpp_asymmetric_key *key)
881 {
882 #ifdef CONFIG_DPP2
883 	int res;
884 
885 	if (!key)
886 		return 0;
887 
888 	wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
889 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
890 
891 	while (key) {
892 		res = dpp_configurator_from_backup(
893 			hapd->iface->interfaces->dpp, key);
894 		if (res < 0)
895 			return -1;
896 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
897 			res);
898 		key = key->next;
899 	}
900 #endif /* CONFIG_DPP2 */
901 
902 	return 0;
903 }
904 
905 
hostapd_dpp_gas_resp_cb(void * ctx,const u8 * addr,u8 dialog_token,enum gas_query_ap_result result,const struct wpabuf * adv_proto,const struct wpabuf * resp,u16 status_code)906 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
907 				    enum gas_query_ap_result result,
908 				    const struct wpabuf *adv_proto,
909 				    const struct wpabuf *resp, u16 status_code)
910 {
911 	struct hostapd_data *hapd = ctx;
912 	const u8 *pos;
913 	struct dpp_authentication *auth = hapd->dpp_auth;
914 	enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
915 
916 	if (!auth || !auth->auth_success) {
917 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
918 		return;
919 	}
920 	if (result != GAS_QUERY_AP_SUCCESS ||
921 	    !resp || status_code != WLAN_STATUS_SUCCESS) {
922 		wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
923 		goto fail;
924 	}
925 
926 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
927 			adv_proto);
928 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
929 			resp);
930 
931 	if (wpabuf_len(adv_proto) != 10 ||
932 	    !(pos = wpabuf_head(adv_proto)) ||
933 	    pos[0] != WLAN_EID_ADV_PROTO ||
934 	    pos[1] != 8 ||
935 	    pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
936 	    pos[4] != 5 ||
937 	    WPA_GET_BE24(&pos[5]) != OUI_WFA ||
938 	    pos[8] != 0x1a ||
939 	    pos[9] != 1) {
940 		wpa_printf(MSG_DEBUG,
941 			   "DPP: Not a DPP Advertisement Protocol ID");
942 		goto fail;
943 	}
944 
945 	if (dpp_conf_resp_rx(auth, resp) < 0) {
946 		wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
947 		goto fail;
948 	}
949 
950 	hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
951 	if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
952 		goto fail;
953 
954 	status = DPP_STATUS_OK;
955 #ifdef CONFIG_TESTING_OPTIONS
956 	if (dpp_test == DPP_TEST_REJECT_CONFIG) {
957 		wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
958 		status = DPP_STATUS_CONFIG_REJECTED;
959 	}
960 #endif /* CONFIG_TESTING_OPTIONS */
961 fail:
962 	if (status != DPP_STATUS_OK)
963 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
964 #ifdef CONFIG_DPP2
965 	if (auth->peer_version >= 2 &&
966 	    auth->conf_resp_status == DPP_STATUS_OK) {
967 		struct wpabuf *msg;
968 
969 		wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
970 		msg = dpp_build_conf_result(auth, status);
971 		if (!msg)
972 			goto fail2;
973 
974 		wpa_msg(hapd->msg_ctx, MSG_INFO,
975 			DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
976 			MAC2STR(addr), auth->curr_freq,
977 			DPP_PA_CONFIGURATION_RESULT);
978 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
979 					addr, wpabuf_head(msg),
980 					wpabuf_len(msg));
981 		wpabuf_free(msg);
982 
983 		/* This exchange will be terminated in the TX status handler */
984 		auth->connect_on_tx_status = 1;
985 		return;
986 	}
987 fail2:
988 #endif /* CONFIG_DPP2 */
989 	dpp_auth_deinit(hapd->dpp_auth);
990 	hapd->dpp_auth = NULL;
991 }
992 
993 
hostapd_dpp_start_gas_client(struct hostapd_data * hapd)994 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
995 {
996 	struct dpp_authentication *auth = hapd->dpp_auth;
997 	struct wpabuf *buf;
998 	int res;
999 
1000 	buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
1001 					DPP_NETROLE_AP,
1002 					hapd->conf->dpp_mud_url, NULL);
1003 	if (!buf) {
1004 		wpa_printf(MSG_DEBUG,
1005 			   "DPP: No configuration request data available");
1006 		return;
1007 	}
1008 
1009 	wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR_SEC " (freq %u MHz)",
1010 		   MAC2STR_SEC(auth->peer_mac_addr), auth->curr_freq);
1011 
1012 	res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
1013 			       buf, hostapd_dpp_gas_resp_cb, hapd);
1014 	if (res < 0) {
1015 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
1016 			"GAS: Failed to send Query Request");
1017 		wpabuf_free(buf);
1018 	} else {
1019 		wpa_printf(MSG_DEBUG,
1020 			   "DPP: GAS query started with dialog token %u", res);
1021 	}
1022 }
1023 
1024 
hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)1025 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
1026 {
1027 	wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
1028 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
1029 		initiator);
1030 #ifdef CONFIG_TESTING_OPTIONS
1031 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1032 		wpa_printf(MSG_INFO,
1033 			   "DPP: TESTING - stop at Authentication Confirm");
1034 		if (hapd->dpp_auth->configurator) {
1035 			/* Prevent GAS response */
1036 			hapd->dpp_auth->auth_success = 0;
1037 		}
1038 		return;
1039 	}
1040 #endif /* CONFIG_TESTING_OPTIONS */
1041 
1042 	if (!hapd->dpp_auth->configurator)
1043 		hostapd_dpp_start_gas_client(hapd);
1044 }
1045 
1046 
hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1047 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
1048 				     const u8 *hdr, const u8 *buf, size_t len,
1049 				     unsigned int freq)
1050 {
1051 	struct dpp_authentication *auth = hapd->dpp_auth;
1052 	struct wpabuf *msg;
1053 
1054 	wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR_SEC,
1055 		   MAC2STR_SEC(src));
1056 
1057 	if (!auth) {
1058 		wpa_printf(MSG_DEBUG,
1059 			   "DPP: No DPP Authentication in progress - drop");
1060 		return;
1061 	}
1062 
1063 	if (!is_zero_ether_addr(auth->peer_mac_addr) &&
1064 	    os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1065 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1066 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1067 		return;
1068 	}
1069 
1070 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1071 
1072 	if (auth->curr_freq != freq && auth->neg_freq == freq) {
1073 		wpa_printf(MSG_DEBUG,
1074 			   "DPP: Responder accepted request for different negotiation channel");
1075 		auth->curr_freq = freq;
1076 	}
1077 
1078 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1079 	msg = dpp_auth_resp_rx(auth, hdr, buf, len);
1080 	if (!msg) {
1081 		if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
1082 			wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
1083 			return;
1084 		}
1085 		wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
1086 		return;
1087 	}
1088 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1089 
1090 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1091 		" freq=%u type=%d", MAC2STR(src), auth->curr_freq,
1092 		DPP_PA_AUTHENTICATION_CONF);
1093 	hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
1094 				wpabuf_head(msg), wpabuf_len(msg));
1095 	wpabuf_free(msg);
1096 	hapd->dpp_auth_ok_on_ack = 1;
1097 }
1098 
1099 
hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1100 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
1101 				     const u8 *hdr, const u8 *buf, size_t len)
1102 {
1103 	struct dpp_authentication *auth = hapd->dpp_auth;
1104 
1105 	wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR_SEC,
1106 		   MAC2STR_SEC(src));
1107 
1108 	if (!auth) {
1109 		wpa_printf(MSG_DEBUG,
1110 			   "DPP: No DPP Authentication in progress - drop");
1111 		return;
1112 	}
1113 
1114 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1115 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1116 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1117 		return;
1118 	}
1119 
1120 	if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1121 		wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1122 		return;
1123 	}
1124 
1125 	hostapd_dpp_auth_success(hapd, 0);
1126 }
1127 
1128 
1129 #ifdef CONFIG_DPP2
1130 
hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1131 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1132 						   void *timeout_ctx)
1133 {
1134 	struct hostapd_data *hapd = eloop_ctx;
1135 	struct dpp_authentication *auth = hapd->dpp_auth;
1136 
1137 	if (!auth || !auth->waiting_conf_result)
1138 		return;
1139 
1140 	wpa_printf(MSG_DEBUG,
1141 		   "DPP: Timeout while waiting for Configuration Result");
1142 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1143 	dpp_auth_deinit(auth);
1144 	hapd->dpp_auth = NULL;
1145 }
1146 
1147 
hostapd_dpp_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1148 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1149 							void *timeout_ctx)
1150 {
1151 	struct hostapd_data *hapd = eloop_ctx;
1152 	struct dpp_authentication *auth = hapd->dpp_auth;
1153 
1154 	if (!auth || !auth->waiting_conf_result)
1155 		return;
1156 
1157 	wpa_printf(MSG_DEBUG,
1158 		   "DPP: Timeout while waiting for Connection Status Result");
1159 	wpa_msg(hapd->msg_ctx, MSG_INFO,
1160 		DPP_EVENT_CONN_STATUS_RESULT "timeout");
1161 	dpp_auth_deinit(auth);
1162 	hapd->dpp_auth = NULL;
1163 }
1164 
1165 
hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1166 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1167 				       const u8 *hdr, const u8 *buf, size_t len)
1168 {
1169 	struct dpp_authentication *auth = hapd->dpp_auth;
1170 	enum dpp_status_error status;
1171 
1172 	wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR_SEC,
1173 		   MAC2STR_SEC(src));
1174 
1175 	if (!auth || !auth->waiting_conf_result) {
1176 		wpa_printf(MSG_DEBUG,
1177 			   "DPP: No DPP Configuration waiting for result - drop");
1178 		return;
1179 	}
1180 
1181 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1182 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1183 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1184 		return;
1185 	}
1186 
1187 	status = dpp_conf_result_rx(auth, hdr, buf, len);
1188 
1189 	if (status == DPP_STATUS_OK && auth->send_conn_status) {
1190 		wpa_msg(hapd->msg_ctx, MSG_INFO,
1191 			DPP_EVENT_CONF_SENT "wait_conn_status=1");
1192 		wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1193 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1194 				     hapd, NULL);
1195 		auth->waiting_conn_status_result = 1;
1196 		eloop_cancel_timeout(
1197 			hostapd_dpp_conn_status_result_wait_timeout,
1198 			hapd, NULL);
1199 		eloop_register_timeout(
1200 			16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1201 			hapd, NULL);
1202 		return;
1203 	}
1204 	hostapd_drv_send_action_cancel_wait(hapd);
1205 	hostapd_dpp_listen_stop(hapd);
1206 	if (status == DPP_STATUS_OK)
1207 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1208 	else
1209 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1210 	dpp_auth_deinit(auth);
1211 	hapd->dpp_auth = NULL;
1212 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1213 			     NULL);
1214 }
1215 
1216 
hostapd_dpp_rx_conn_status_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1217 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1218 					      const u8 *src, const u8 *hdr,
1219 					      const u8 *buf, size_t len)
1220 {
1221 	struct dpp_authentication *auth = hapd->dpp_auth;
1222 	enum dpp_status_error status;
1223 	u8 ssid[SSID_MAX_LEN];
1224 	size_t ssid_len = 0;
1225 	char *channel_list = NULL;
1226 
1227 	wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1228 
1229 	if (!auth || !auth->waiting_conn_status_result) {
1230 		wpa_printf(MSG_DEBUG,
1231 			   "DPP: No DPP Configuration waiting for connection status result - drop");
1232 		return;
1233 	}
1234 
1235 	status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1236 					   ssid, &ssid_len, &channel_list);
1237 	wpa_msg_only_for_cb(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1238 		"result=%d ssid=%s channel_list=%s",
1239 		status, wpa_ssid_txt(ssid, ssid_len),
1240 		channel_list ? channel_list : "N/A");
1241 	wpa_printf(MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1242 		"result=%d ssid=%s channel_list=%s",
1243 		status, anonymize_ssid(wpa_ssid_txt(ssid, ssid_len)),
1244 		channel_list ? channel_list : "N/A");
1245 	os_free(channel_list);
1246 	hostapd_drv_send_action_cancel_wait(hapd);
1247 	hostapd_dpp_listen_stop(hapd);
1248 	dpp_auth_deinit(auth);
1249 	hapd->dpp_auth = NULL;
1250 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1251 			     hapd, NULL);
1252 }
1253 
1254 
1255 static void
hostapd_dpp_rx_presence_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1256 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1257 				     const u8 *hdr, const u8 *buf, size_t len,
1258 				     unsigned int freq)
1259 {
1260 	const u8 *r_bootstrap;
1261 	u16 r_bootstrap_len;
1262 	struct dpp_bootstrap_info *peer_bi;
1263 	struct dpp_authentication *auth;
1264 
1265 	wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR_SEC,
1266 		   MAC2STR_SEC(src));
1267 
1268 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1269 				   &r_bootstrap_len);
1270 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1271 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1272 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
1273 		return;
1274 	}
1275 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1276 		    r_bootstrap, r_bootstrap_len);
1277 	peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1278 					   r_bootstrap);
1279 	dpp_notify_chirp_received(hapd->msg_ctx,
1280 				  peer_bi ? (int) peer_bi->id : -1,
1281 				  src, freq, r_bootstrap);
1282 	if (!peer_bi) {
1283 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1284 					src, hdr, buf, len, freq, NULL,
1285 					r_bootstrap, hapd) == 0)
1286 			return;
1287 		wpa_printf(MSG_DEBUG,
1288 			   "DPP: No matching bootstrapping information found");
1289 		return;
1290 	}
1291 
1292 	if (hapd->dpp_auth) {
1293 		wpa_printf(MSG_DEBUG,
1294 			   "DPP: Ignore Presence Announcement during ongoing Authentication");
1295 		return;
1296 	}
1297 
1298 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1299 			     peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1300 			     0);
1301 	if (!auth)
1302 		return;
1303 	hostapd_dpp_set_testing_options(hapd, auth);
1304 	if (dpp_set_configurator(auth,
1305 				 hapd->dpp_configurator_params) < 0) {
1306 		dpp_auth_deinit(auth);
1307 		return;
1308 	}
1309 
1310 	auth->neg_freq = freq;
1311 
1312 	/* The source address of the Presence Announcement frame overrides any
1313 	 * MAC address information from the bootstrapping information. */
1314 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1315 
1316 	hapd->dpp_auth = auth;
1317 	if (hostapd_dpp_auth_init_next(hapd) < 0) {
1318 		dpp_auth_deinit(hapd->dpp_auth);
1319 		hapd->dpp_auth = NULL;
1320 	}
1321 }
1322 
1323 
hostapd_dpp_reconfig_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)1324 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
1325 						    void *timeout_ctx)
1326 {
1327 	struct hostapd_data *hapd = eloop_ctx;
1328 	struct dpp_authentication *auth = hapd->dpp_auth;
1329 
1330 	if (!auth)
1331 		return;
1332 
1333 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
1334 	hostapd_dpp_listen_stop(hapd);
1335 	dpp_auth_deinit(auth);
1336 	hapd->dpp_auth = NULL;
1337 }
1338 
1339 
1340 static void
hostapd_dpp_rx_reconfig_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1341 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
1342 				     const u8 *hdr, const u8 *buf, size_t len,
1343 				     unsigned int freq)
1344 {
1345 	const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1346 	u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1347 	struct dpp_configurator *conf;
1348 	struct dpp_authentication *auth;
1349 	unsigned int wait_time, max_wait_time;
1350 	u16 group;
1351 
1352 	if (hapd->dpp_auth) {
1353 		wpa_printf(MSG_DEBUG,
1354 			   "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1355 		return;
1356 	}
1357 
1358 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR_SEC,
1359 		   MAC2STR_SEC(src));
1360 
1361 	csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1362 				  &csign_hash_len);
1363 	if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1364 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1365 			"Missing or invalid required Configurator C-sign key Hash attribute");
1366 		return;
1367 	}
1368 	wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1369 		    csign_hash, csign_hash_len);
1370 	conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp,
1371 					 csign_hash);
1372 	if (!conf) {
1373 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1374 					src, hdr, buf, len, freq, NULL,
1375 					NULL, hapd) == 0)
1376 			return;
1377 		wpa_printf(MSG_DEBUG,
1378 			   "DPP: No matching Configurator information found");
1379 		return;
1380 	}
1381 
1382 	fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1383 			       &fcgroup_len);
1384 	if (!fcgroup || fcgroup_len != 2) {
1385 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1386 			"Missing or invalid required Finite Cyclic Group attribute");
1387 		return;
1388 	}
1389 	group = WPA_GET_LE16(fcgroup);
1390 	wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1391 
1392 	a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1393 	e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1394 
1395 	auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1396 				 conf, freq, group, a_nonce, a_nonce_len,
1397 				 e_id, e_id_len);
1398 	if (!auth)
1399 		return;
1400 	hostapd_dpp_set_testing_options(hapd, auth);
1401 	if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
1402 		dpp_auth_deinit(auth);
1403 		return;
1404 	}
1405 
1406 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1407 	hapd->dpp_auth = auth;
1408 
1409 	hapd->dpp_in_response_listen = 0;
1410 	hapd->dpp_auth_ok_on_ack = 0;
1411 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
1412 	max_wait_time = hapd->dpp_resp_wait_time ?
1413 		hapd->dpp_resp_wait_time : 2000;
1414 	if (wait_time > max_wait_time)
1415 		wait_time = max_wait_time;
1416 	wait_time += 10; /* give the driver some extra time to complete */
1417 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
1418 			       hostapd_dpp_reconfig_reply_wait_timeout,
1419 			       hapd, NULL);
1420 	wait_time -= 10;
1421 
1422 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1423 		" freq=%u type=%d",
1424 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
1425 	if (hostapd_drv_send_action(hapd, freq, wait_time, src,
1426 				    wpabuf_head(auth->reconfig_req_msg),
1427 				    wpabuf_len(auth->reconfig_req_msg)) < 0) {
1428 		dpp_auth_deinit(hapd->dpp_auth);
1429 		hapd->dpp_auth = NULL;
1430 	}
1431 }
1432 
1433 
1434 static void
hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1435 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src,
1436 				  const u8 *hdr, const u8 *buf, size_t len,
1437 				  unsigned int freq)
1438 {
1439 	struct dpp_authentication *auth = hapd->dpp_auth;
1440 	struct wpabuf *conf;
1441 
1442 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
1443 		   MACSTR_SEC, MAC2STR_SEC(src));
1444 
1445 	if (!auth || !auth->reconfig || !auth->configurator) {
1446 		wpa_printf(MSG_DEBUG,
1447 			   "DPP: No DPP Reconfig Authentication in progress - drop");
1448 		return;
1449 	}
1450 
1451 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1452 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1453 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1454 		return;
1455 	}
1456 
1457 	conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1458 	if (!conf)
1459 		return;
1460 
1461 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1462 			     hapd, NULL);
1463 
1464 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1465 		" freq=%u type=%d",
1466 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
1467 	if (hostapd_drv_send_action(hapd, freq, 500, src,
1468 				    wpabuf_head(conf), wpabuf_len(conf)) < 0) {
1469 		wpabuf_free(conf);
1470 		dpp_auth_deinit(hapd->dpp_auth);
1471 		hapd->dpp_auth = NULL;
1472 		return;
1473 	}
1474 	wpabuf_free(conf);
1475 }
1476 
1477 #endif /* CONFIG_DPP2 */
1478 
1479 
hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)1480 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1481 					    const u8 *src, unsigned int freq,
1482 					    u8 trans_id,
1483 					    enum dpp_status_error status)
1484 {
1485 	struct wpabuf *msg;
1486 	size_t len;
1487 
1488 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
1489 #ifdef CONFIG_DPP2
1490 	len += 5;
1491 #endif /* CONFIG_DPP2 */
1492 	msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len);
1493 	if (!msg)
1494 		return;
1495 
1496 #ifdef CONFIG_TESTING_OPTIONS
1497 	if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1498 		wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1499 		goto skip_trans_id;
1500 	}
1501 	if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1502 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1503 		trans_id ^= 0x01;
1504 	}
1505 #endif /* CONFIG_TESTING_OPTIONS */
1506 
1507 	/* Transaction ID */
1508 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1509 	wpabuf_put_le16(msg, 1);
1510 	wpabuf_put_u8(msg, trans_id);
1511 
1512 #ifdef CONFIG_TESTING_OPTIONS
1513 skip_trans_id:
1514 	if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1515 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1516 		goto skip_status;
1517 	}
1518 	if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1519 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1520 		status = 254;
1521 	}
1522 #endif /* CONFIG_TESTING_OPTIONS */
1523 
1524 	/* DPP Status */
1525 	wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1526 	wpabuf_put_le16(msg, 1);
1527 	wpabuf_put_u8(msg, status);
1528 
1529 #ifdef CONFIG_TESTING_OPTIONS
1530 skip_status:
1531 	if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1532 		wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1533 		goto skip_connector;
1534 	}
1535 	if (status == DPP_STATUS_OK &&
1536 	    dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1537 		char *connector;
1538 
1539 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1540 		connector = dpp_corrupt_connector_signature(
1541 			hapd->conf->dpp_connector);
1542 		if (!connector) {
1543 			wpabuf_free(msg);
1544 			return;
1545 		}
1546 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1547 		wpabuf_put_le16(msg, os_strlen(connector));
1548 		wpabuf_put_str(msg, connector);
1549 		os_free(connector);
1550 		goto skip_connector;
1551 	}
1552 #endif /* CONFIG_TESTING_OPTIONS */
1553 
1554 	/* DPP Connector */
1555 	if (status == DPP_STATUS_OK) {
1556 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1557 		wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1558 		wpabuf_put_str(msg, hapd->conf->dpp_connector);
1559 	}
1560 
1561 #ifdef CONFIG_TESTING_OPTIONS
1562 skip_connector:
1563 	if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) {
1564 		wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
1565 		goto skip_proto_ver;
1566 	}
1567 #endif /* CONFIG_TESTING_OPTIONS */
1568 
1569 #ifdef CONFIG_DPP2
1570 	if (DPP_VERSION > 1) {
1571 		u8 ver = DPP_VERSION;
1572 #ifdef CONFIG_DPP3
1573 		int conn_ver;
1574 
1575 		conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
1576 		if (conn_ver > 0 && ver != conn_ver) {
1577 			wpa_printf(MSG_DEBUG,
1578 				   "DPP: Use Connector version %d instead of current protocol version %d",
1579 				   conn_ver, ver);
1580 			ver = conn_ver;
1581 		}
1582 #endif /* CONFIG_DPP3 */
1583 
1584 		/* Protocol Version */
1585 		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
1586 		wpabuf_put_le16(msg, 1);
1587 		wpabuf_put_u8(msg, ver);
1588 	}
1589 #endif /* CONFIG_DPP2 */
1590 
1591 #ifdef CONFIG_TESTING_OPTIONS
1592 skip_proto_ver:
1593 #endif /* CONFIG_TESTING_OPTIONS */
1594 
1595 	wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
1596 		   " status=%d", MAC2STR(src), status);
1597 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1598 		" freq=%u type=%d status=%d", MAC2STR(src), freq,
1599 		DPP_PA_PEER_DISCOVERY_RESP, status);
1600 	hostapd_drv_send_action(hapd, freq, 0, src,
1601 				wpabuf_head(msg), wpabuf_len(msg));
1602 	wpabuf_free(msg);
1603 }
1604 
1605 
hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1606 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
1607 					 const u8 *src,
1608 					 const u8 *buf, size_t len,
1609 					 unsigned int freq)
1610 {
1611 	const u8 *connector, *trans_id;
1612 	u16 connector_len, trans_id_len;
1613 	struct os_time now;
1614 	struct dpp_introduction intro;
1615 	os_time_t expire;
1616 	int expiration;
1617 	enum dpp_status_error res;
1618 
1619 	wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR_SEC,
1620 		   MAC2STR_SEC(src));
1621 	if (!hapd->wpa_auth ||
1622 	    !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
1623 	    !(hapd->conf->wpa & WPA_PROTO_RSN)) {
1624 		wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
1625 		return;
1626 	}
1627 
1628 	if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
1629 	    !hapd->conf->dpp_csign) {
1630 		wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
1631 		return;
1632 	}
1633 
1634 	os_get_time(&now);
1635 
1636 	if (hapd->conf->dpp_netaccesskey_expiry &&
1637 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
1638 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
1639 		return;
1640 	}
1641 
1642 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
1643 			       &trans_id_len);
1644 	if (!trans_id || trans_id_len != 1) {
1645 		wpa_printf(MSG_DEBUG,
1646 			   "DPP: Peer did not include Transaction ID");
1647 		return;
1648 	}
1649 
1650 	connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
1651 	if (!connector) {
1652 		wpa_printf(MSG_DEBUG,
1653 			   "DPP: Peer did not include its Connector");
1654 		return;
1655 	}
1656 
1657 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
1658 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
1659 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
1660 			     wpabuf_head(hapd->conf->dpp_csign),
1661 			     wpabuf_len(hapd->conf->dpp_csign),
1662 			     connector, connector_len, &expire);
1663 	if (res == 255) {
1664 		wpa_printf(MSG_INFO,
1665 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
1666 			   MACSTR_SEC ")", MAC2STR_SEC(src));
1667 		return;
1668 	}
1669 	if (res != DPP_STATUS_OK) {
1670 		wpa_printf(MSG_INFO,
1671 			   "DPP: Network Introduction protocol resulted in failure (peer "
1672 			   MACSTR_SEC " status %d)", MAC2STR_SEC(src), res);
1673 		hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1674 						res);
1675 		return;
1676 	}
1677 
1678 #ifdef CONFIG_DPP3
1679 	if (intro.peer_version && intro.peer_version >= 2) {
1680 		const u8 *version;
1681 		u16 version_len;
1682 		u8 attr_version = 1;
1683 
1684 		version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
1685 				       &version_len);
1686 		if (version && version_len >= 1)
1687 			attr_version = version[0];
1688 		if (attr_version != intro.peer_version) {
1689 			wpa_printf(MSG_INFO,
1690 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
1691 				   intro.peer_version, attr_version);
1692 			hostapd_dpp_send_peer_disc_resp(hapd, src, freq,
1693 							trans_id[0],
1694 							DPP_STATUS_NO_MATCH);
1695 			return;
1696 		}
1697 	}
1698 #endif /* CONFIG_DPP3 */
1699 
1700 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
1701 		expire = hapd->conf->dpp_netaccesskey_expiry;
1702 	if (expire)
1703 		expiration = expire - now.sec;
1704 	else
1705 		expiration = 0;
1706 
1707 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
1708 				intro.pmkid, expiration,
1709 				WPA_KEY_MGMT_DPP) < 0) {
1710 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
1711 		return;
1712 	}
1713 
1714 	hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1715 					DPP_STATUS_OK);
1716 }
1717 
1718 
1719 static void
hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq,bool v2)1720 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
1721 				 const u8 *buf, size_t len,
1722 				 unsigned int freq, bool v2)
1723 {
1724 	struct wpabuf *msg;
1725 
1726 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR_SEC,
1727 		   MAC2STR_SEC(src));
1728 
1729 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
1730 	 * values here */
1731 
1732 	if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
1733 		wpa_printf(MSG_DEBUG,
1734 			   "DPP: No PKEX code configured - ignore request");
1735 		return;
1736 	}
1737 
1738 	if (hapd->dpp_pkex) {
1739 		/* TODO: Support parallel operations */
1740 		wpa_printf(MSG_DEBUG,
1741 			   "DPP: Already in PKEX session - ignore new request");
1742 		return;
1743 	}
1744 
1745 	hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
1746 						  hapd->dpp_pkex_bi,
1747 						  hapd->own_addr, src,
1748 						  hapd->dpp_pkex_identifier,
1749 						  hapd->dpp_pkex_code,
1750 						  buf, len, v2);
1751 	if (!hapd->dpp_pkex) {
1752 		wpa_printf(MSG_DEBUG,
1753 			   "DPP: Failed to process the request - ignore it");
1754 		return;
1755 	}
1756 
1757 	msg = hapd->dpp_pkex->exchange_resp;
1758 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1759 		" freq=%u type=%d", MAC2STR(src), freq,
1760 		DPP_PA_PKEX_EXCHANGE_RESP);
1761 	hostapd_drv_send_action(hapd, freq, 0, src,
1762 				wpabuf_head(msg), wpabuf_len(msg));
1763 	if (hapd->dpp_pkex->failed) {
1764 		wpa_printf(MSG_DEBUG,
1765 			   "DPP: Terminate PKEX exchange due to an earlier error");
1766 		if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1767 			hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
1768 		dpp_pkex_free(hapd->dpp_pkex);
1769 		hapd->dpp_pkex = NULL;
1770 	}
1771 }
1772 
1773 
1774 static void
hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1775 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
1776 				  const u8 *buf, size_t len, unsigned int freq)
1777 {
1778 	struct wpabuf *msg;
1779 
1780 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR_SEC,
1781 		   MAC2STR_SEC(src));
1782 
1783 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
1784 	 * values here */
1785 
1786 	if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
1787 	    hapd->dpp_pkex->exchange_done) {
1788 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1789 		return;
1790 	}
1791 
1792 	msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
1793 	if (!msg) {
1794 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1795 		return;
1796 	}
1797 
1798 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR_SEC,
1799 		   MAC2STR_SEC(src));
1800 
1801 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1802 		" freq=%u type=%d", MAC2STR(src), freq,
1803 		DPP_PA_PKEX_COMMIT_REVEAL_REQ);
1804 	hostapd_drv_send_action(hapd, freq, 0, src,
1805 				wpabuf_head(msg), wpabuf_len(msg));
1806 	wpabuf_free(msg);
1807 }
1808 
1809 
1810 static void
hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1811 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
1812 				      const u8 *hdr, const u8 *buf, size_t len,
1813 				      unsigned int freq)
1814 {
1815 	struct wpabuf *msg;
1816 	struct dpp_pkex *pkex = hapd->dpp_pkex;
1817 	struct dpp_bootstrap_info *bi;
1818 
1819 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR_SEC,
1820 		   MAC2STR_SEC(src));
1821 
1822 	if (!pkex || pkex->initiator || !pkex->exchange_done) {
1823 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1824 		return;
1825 	}
1826 
1827 	msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1828 	if (!msg) {
1829 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1830 		if (hapd->dpp_pkex->failed) {
1831 			wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
1832 			if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1833 				hapd->dpp_pkex->own_bi->pkex_t =
1834 					hapd->dpp_pkex->t;
1835 			dpp_pkex_free(hapd->dpp_pkex);
1836 			hapd->dpp_pkex = NULL;
1837 		}
1838 		return;
1839 	}
1840 
1841 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
1842 		   MACSTR_SEC, MAC2STR_SEC(src));
1843 
1844 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1845 		" freq=%u type=%d", MAC2STR(src), freq,
1846 		DPP_PA_PKEX_COMMIT_REVEAL_RESP);
1847 	hostapd_drv_send_action(hapd, freq, 0, src,
1848 				wpabuf_head(msg), wpabuf_len(msg));
1849 	wpabuf_free(msg);
1850 
1851 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1852 	if (!bi)
1853 		return;
1854 	hapd->dpp_pkex = NULL;
1855 }
1856 
1857 
1858 static void
hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1859 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
1860 				       const u8 *hdr, const u8 *buf, size_t len,
1861 				       unsigned int freq)
1862 {
1863 	int res;
1864 	struct dpp_bootstrap_info *bi;
1865 	struct dpp_pkex *pkex = hapd->dpp_pkex;
1866 	char cmd[500];
1867 
1868 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR_SEC,
1869 		   MAC2STR_SEC(src));
1870 
1871 	if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1872 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1873 		return;
1874 	}
1875 
1876 	res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1877 	if (res < 0) {
1878 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1879 		return;
1880 	}
1881 
1882 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1883 	if (!bi)
1884 		return;
1885 	hapd->dpp_pkex = NULL;
1886 
1887 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
1888 		    bi->id,
1889 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
1890 	wpa_printf(MSG_DEBUG,
1891 		   "DPP: Start authentication after PKEX with parameters: %s",
1892 		   cmd);
1893 	if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
1894 		wpa_printf(MSG_DEBUG,
1895 			   "DPP: Authentication initialization failed");
1896 		return;
1897 	}
1898 }
1899 
1900 
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1901 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
1902 			   const u8 *buf, size_t len, unsigned int freq)
1903 {
1904 	u8 crypto_suite;
1905 	enum dpp_public_action_frame_type type;
1906 	const u8 *hdr;
1907 	unsigned int pkex_t;
1908 
1909 	if (len < DPP_HDR_LEN)
1910 		return;
1911 	if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
1912 		return;
1913 	hdr = buf;
1914 	buf += 4;
1915 	len -= 4;
1916 	crypto_suite = *buf++;
1917 	type = *buf++;
1918 	len -= 2;
1919 
1920 	wpa_printf(MSG_DEBUG,
1921 		   "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1922 		   MACSTR_SEC " freq=%u",
1923 		   crypto_suite, type, MAC2STR_SEC(src), freq);
1924 	if (crypto_suite != 1) {
1925 		wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
1926 			   crypto_suite);
1927 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1928 			" freq=%u type=%d ignore=unsupported-crypto-suite",
1929 			MAC2STR(src), freq, type);
1930 		return;
1931 	}
1932 	wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
1933 	if (dpp_check_attrs(buf, len) < 0) {
1934 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1935 			" freq=%u type=%d ignore=invalid-attributes",
1936 			MAC2STR(src), freq, type);
1937 		return;
1938 	}
1939 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1940 		" freq=%u type=%d", MAC2STR(src), freq, type);
1941 
1942 #ifdef CONFIG_DPP2
1943 	if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1944 				src, hdr, buf, len, freq, NULL, NULL,
1945 				hapd) == 0)
1946 		return;
1947 #endif /* CONFIG_DPP2 */
1948 
1949 	switch (type) {
1950 	case DPP_PA_AUTHENTICATION_REQ:
1951 		hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
1952 		break;
1953 	case DPP_PA_AUTHENTICATION_RESP:
1954 		hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
1955 		break;
1956 	case DPP_PA_AUTHENTICATION_CONF:
1957 		hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
1958 		break;
1959 	case DPP_PA_PEER_DISCOVERY_REQ:
1960 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
1961 		break;
1962 #ifdef CONFIG_DPP3
1963 	case DPP_PA_PKEX_EXCHANGE_REQ:
1964 		/* This is for PKEXv2, but for now, process only with
1965 		 * CONFIG_DPP3 to avoid issues with a capability that has not
1966 		 * been tested with other implementations. */
1967 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
1968 						 true);
1969 		break;
1970 #endif /* CONFIG_DPP3 */
1971 	case DPP_PA_PKEX_V1_EXCHANGE_REQ:
1972 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
1973 						 false);
1974 		break;
1975 	case DPP_PA_PKEX_EXCHANGE_RESP:
1976 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
1977 		break;
1978 	case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1979 		hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
1980 						      freq);
1981 		break;
1982 	case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1983 		hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
1984 						       freq);
1985 		break;
1986 #ifdef CONFIG_DPP2
1987 	case DPP_PA_CONFIGURATION_RESULT:
1988 		hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
1989 		break;
1990 	case DPP_PA_CONNECTION_STATUS_RESULT:
1991 		hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
1992 		break;
1993 	case DPP_PA_PRESENCE_ANNOUNCEMENT:
1994 		hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
1995 						     freq);
1996 		break;
1997 	case DPP_PA_RECONFIG_ANNOUNCEMENT:
1998 		hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
1999 						     freq);
2000 		break;
2001 	case DPP_PA_RECONFIG_AUTH_RESP:
2002 		hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
2003 						  freq);
2004 		break;
2005 #endif /* CONFIG_DPP2 */
2006 	default:
2007 		wpa_printf(MSG_DEBUG,
2008 			   "DPP: Ignored unsupported frame subtype %d", type);
2009 		break;
2010 	}
2011 
2012 	if (hapd->dpp_pkex)
2013 		pkex_t = hapd->dpp_pkex->t;
2014 	else if (hapd->dpp_pkex_bi)
2015 		pkex_t = hapd->dpp_pkex_bi->pkex_t;
2016 	else
2017 		pkex_t = 0;
2018 	if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
2019 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
2020 		hostapd_dpp_pkex_remove(hapd, "*");
2021 	}
2022 }
2023 
2024 
2025 struct wpabuf *
hostapd_dpp_gas_req_handler(struct hostapd_data * hapd,const u8 * sa,const u8 * query,size_t query_len,const u8 * data,size_t data_len)2026 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
2027 			    const u8 *query, size_t query_len,
2028 			    const u8 *data, size_t data_len)
2029 {
2030 	struct dpp_authentication *auth = hapd->dpp_auth;
2031 	struct wpabuf *resp;
2032 
2033 	wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR_SEC, MAC2STR_SEC(sa));
2034 	if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
2035 	    os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
2036 #ifdef CONFIG_DPP2
2037 		if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
2038 				     data_len) == 0) {
2039 			/* Response will be forwarded once received over TCP */
2040 			return NULL;
2041 		}
2042 #endif /* CONFIG_DPP2 */
2043 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
2044 		return NULL;
2045 	}
2046 
2047 	if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
2048 		wpa_printf(MSG_DEBUG,
2049 			   "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
2050 		/* hostapd_dpp_auth_success() would normally have been called
2051 		 * from TX status handler, but since there was no such handler
2052 		 * call yet, simply send out the event message and proceed with
2053 		 * exchange. */
2054 		wpa_msg(hapd->msg_ctx, MSG_INFO,
2055 			DPP_EVENT_AUTH_SUCCESS "init=1");
2056 		hapd->dpp_auth_ok_on_ack = 0;
2057 	}
2058 
2059 	wpa_hexdump(MSG_DEBUG,
2060 		    "DPP: Received Configuration Request (GAS Query Request)",
2061 		    query, query_len);
2062 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
2063 		MAC2STR(sa));
2064 	resp = dpp_conf_req_rx(auth, query, query_len);
2065 	if (!resp)
2066 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
2067 	return resp;
2068 }
2069 
2070 
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)2071 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
2072 {
2073 	struct dpp_authentication *auth = hapd->dpp_auth;
2074 
2075 	if (!auth)
2076 		return;
2077 
2078 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
2079 		   ok);
2080 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
2081 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
2082 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
2083 #ifdef CONFIG_DPP2
2084 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
2085 				     hapd, NULL);
2086 	if (ok && auth->peer_version >= 2 &&
2087 	    auth->conf_resp_status == DPP_STATUS_OK) {
2088 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
2089 		auth->waiting_conf_result = 1;
2090 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
2091 				     hapd, NULL);
2092 		eloop_register_timeout(2, 0,
2093 				       hostapd_dpp_config_result_wait_timeout,
2094 				       hapd, NULL);
2095 		return;
2096 	}
2097 #endif /* CONFIG_DPP2 */
2098 	hostapd_drv_send_action_cancel_wait(hapd);
2099 
2100 	if (ok)
2101 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
2102 	else
2103 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
2104 	dpp_auth_deinit(hapd->dpp_auth);
2105 	hapd->dpp_auth = NULL;
2106 }
2107 
2108 
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)2109 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
2110 {
2111 	struct dpp_authentication *auth;
2112 	int ret = -1;
2113 	char *curve = NULL;
2114 
2115 	auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
2116 	if (!auth)
2117 		return -1;
2118 
2119 	curve = get_param(cmd, " curve=");
2120 	hostapd_dpp_set_testing_options(hapd, auth);
2121 	if (dpp_set_configurator(auth, cmd) == 0 &&
2122 	    dpp_configurator_own_config(auth, curve, 1) == 0) {
2123 		hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
2124 		ret = 0;
2125 	}
2126 
2127 	dpp_auth_deinit(auth);
2128 	os_free(curve);
2129 
2130 	return ret;
2131 }
2132 
2133 
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)2134 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
2135 {
2136 	struct dpp_bootstrap_info *own_bi;
2137 	const char *pos, *end;
2138 
2139 	pos = os_strstr(cmd, " own=");
2140 	if (!pos)
2141 		return -1;
2142 	pos += 5;
2143 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
2144 	if (!own_bi) {
2145 		wpa_printf(MSG_DEBUG,
2146 			   "DPP: Identified bootstrap info not found");
2147 		return -1;
2148 	}
2149 	if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
2150 		wpa_printf(MSG_DEBUG,
2151 			   "DPP: Identified bootstrap info not for PKEX");
2152 		return -1;
2153 	}
2154 	hapd->dpp_pkex_bi = own_bi;
2155 	own_bi->pkex_t = 0; /* clear pending errors on new code */
2156 
2157 	os_free(hapd->dpp_pkex_identifier);
2158 	hapd->dpp_pkex_identifier = NULL;
2159 	pos = os_strstr(cmd, " identifier=");
2160 	if (pos) {
2161 		pos += 12;
2162 		end = os_strchr(pos, ' ');
2163 		if (!end)
2164 			return -1;
2165 		hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
2166 		if (!hapd->dpp_pkex_identifier)
2167 			return -1;
2168 		os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
2169 		hapd->dpp_pkex_identifier[end - pos] = '\0';
2170 	}
2171 
2172 	pos = os_strstr(cmd, " code=");
2173 	if (!pos)
2174 		return -1;
2175 	os_free(hapd->dpp_pkex_code);
2176 	hapd->dpp_pkex_code = os_strdup(pos + 6);
2177 	if (!hapd->dpp_pkex_code)
2178 		return -1;
2179 
2180 	if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
2181 		struct wpabuf *msg;
2182 		bool v2 = os_strstr(cmd, " init=2") != NULL;
2183 
2184 		wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
2185 		dpp_pkex_free(hapd->dpp_pkex);
2186 		hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
2187 					       hapd->own_addr,
2188 					       hapd->dpp_pkex_identifier,
2189 					       hapd->dpp_pkex_code, v2);
2190 		if (!hapd->dpp_pkex)
2191 			return -1;
2192 
2193 		msg = hapd->dpp_pkex->exchange_req;
2194 		/* TODO: Which channel to use? */
2195 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2196 			" freq=%u type=%d", MAC2STR(broadcast), 2437,
2197 			v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
2198 			DPP_PA_PKEX_V1_EXCHANGE_REQ);
2199 		hostapd_drv_send_action(hapd, 2437, 0, broadcast,
2200 					wpabuf_head(msg), wpabuf_len(msg));
2201 	}
2202 
2203 	/* TODO: Support multiple PKEX info entries */
2204 
2205 	os_free(hapd->dpp_pkex_auth_cmd);
2206 	hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
2207 
2208 	return 1;
2209 }
2210 
2211 
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)2212 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
2213 {
2214 	unsigned int id_val;
2215 
2216 	if (os_strcmp(id, "*") == 0) {
2217 		id_val = 0;
2218 	} else {
2219 		id_val = atoi(id);
2220 		if (id_val == 0)
2221 			return -1;
2222 	}
2223 
2224 	if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
2225 		return -1;
2226 
2227 	/* TODO: Support multiple PKEX entries */
2228 	os_free(hapd->dpp_pkex_code);
2229 	hapd->dpp_pkex_code = NULL;
2230 	os_free(hapd->dpp_pkex_identifier);
2231 	hapd->dpp_pkex_identifier = NULL;
2232 	os_free(hapd->dpp_pkex_auth_cmd);
2233 	hapd->dpp_pkex_auth_cmd = NULL;
2234 	hapd->dpp_pkex_bi = NULL;
2235 	/* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2236 	dpp_pkex_free(hapd->dpp_pkex);
2237 	hapd->dpp_pkex = NULL;
2238 	return 0;
2239 }
2240 
2241 
hostapd_dpp_stop(struct hostapd_data * hapd)2242 void hostapd_dpp_stop(struct hostapd_data *hapd)
2243 {
2244 	dpp_auth_deinit(hapd->dpp_auth);
2245 	hapd->dpp_auth = NULL;
2246 	dpp_pkex_free(hapd->dpp_pkex);
2247 	hapd->dpp_pkex = NULL;
2248 }
2249 
2250 
2251 #ifdef CONFIG_DPP2
2252 
hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)2253 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
2254 				 const u8 *msg, size_t len)
2255 {
2256 	struct hostapd_data *hapd = ctx;
2257 	u8 *buf;
2258 
2259 	wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR_SEC " freq=%u",
2260 		   MAC2STR_SEC(addr), freq);
2261 	buf = os_malloc(2 + len);
2262 	if (!buf)
2263 		return;
2264 	buf[0] = WLAN_ACTION_PUBLIC;
2265 	buf[1] = WLAN_PA_VENDOR_SPECIFIC;
2266 	os_memcpy(buf + 2, msg, len);
2267 	hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
2268 	os_free(buf);
2269 }
2270 
2271 
hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)2272 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
2273 					  u8 dialog_token, int prot,
2274 					  struct wpabuf *buf)
2275 {
2276 	struct hostapd_data *hapd = ctx;
2277 
2278 	gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf);
2279 }
2280 
2281 #endif /* CONFIG_DPP2 */
2282 
2283 
hostapd_dpp_add_controllers(struct hostapd_data * hapd)2284 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
2285 {
2286 #ifdef CONFIG_DPP2
2287 	struct dpp_controller_conf *ctrl;
2288 	struct dpp_relay_config config;
2289 
2290 	os_memset(&config, 0, sizeof(config));
2291 	config.cb_ctx = hapd;
2292 	config.tx = hostapd_dpp_relay_tx;
2293 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
2294 	for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
2295 		config.ipaddr = &ctrl->ipaddr;
2296 		config.pkhash = ctrl->pkhash;
2297 		if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
2298 					     &config) < 0)
2299 			return -1;
2300 	}
2301 #endif /* CONFIG_DPP2 */
2302 
2303 	return 0;
2304 }
2305 
2306 
hostapd_dpp_init(struct hostapd_data * hapd)2307 int hostapd_dpp_init(struct hostapd_data *hapd)
2308 {
2309 	hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
2310 	hapd->dpp_init_done = 1;
2311 	return hostapd_dpp_add_controllers(hapd);
2312 }
2313 
2314 
hostapd_dpp_deinit(struct hostapd_data * hapd)2315 void hostapd_dpp_deinit(struct hostapd_data *hapd)
2316 {
2317 #ifdef CONFIG_TESTING_OPTIONS
2318 	os_free(hapd->dpp_config_obj_override);
2319 	hapd->dpp_config_obj_override = NULL;
2320 	os_free(hapd->dpp_discovery_override);
2321 	hapd->dpp_discovery_override = NULL;
2322 	os_free(hapd->dpp_groups_override);
2323 	hapd->dpp_groups_override = NULL;
2324 	hapd->dpp_ignore_netaccesskey_mismatch = 0;
2325 #endif /* CONFIG_TESTING_OPTIONS */
2326 	if (!hapd->dpp_init_done)
2327 		return;
2328 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
2329 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
2330 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
2331 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
2332 #ifdef CONFIG_DPP2
2333 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
2334 			     hapd, NULL);
2335 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
2336 			     NULL);
2337 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
2338 			     NULL);
2339 	hostapd_dpp_chirp_stop(hapd);
2340 	if (hapd->iface->interfaces)
2341 		dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
2342 #endif /* CONFIG_DPP2 */
2343 	dpp_auth_deinit(hapd->dpp_auth);
2344 	hapd->dpp_auth = NULL;
2345 	hostapd_dpp_pkex_remove(hapd, "*");
2346 	hapd->dpp_pkex = NULL;
2347 	os_free(hapd->dpp_configurator_params);
2348 	hapd->dpp_configurator_params = NULL;
2349 }
2350 
2351 
2352 #ifdef CONFIG_DPP2
2353 
hostapd_dpp_controller_start(struct hostapd_data * hapd,const char * cmd)2354 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd)
2355 {
2356 	struct dpp_controller_config config;
2357 	const char *pos;
2358 
2359 	os_memset(&config, 0, sizeof(config));
2360 	config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
2361 	config.netrole = DPP_NETROLE_AP;
2362 	config.msg_ctx = hapd->msg_ctx;
2363 	config.cb_ctx = hapd;
2364 	config.process_conf_obj = hostapd_dpp_process_conf_obj;
2365 	if (cmd) {
2366 		pos = os_strstr(cmd, " tcp_port=");
2367 		if (pos) {
2368 			pos += 10;
2369 			config.tcp_port = atoi(pos);
2370 		}
2371 
2372 		pos = os_strstr(cmd, " role=");
2373 		if (pos) {
2374 			pos += 6;
2375 			if (os_strncmp(pos, "configurator", 12) == 0)
2376 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
2377 			else if (os_strncmp(pos, "enrollee", 8) == 0)
2378 				config.allowed_roles = DPP_CAPAB_ENROLLEE;
2379 			else if (os_strncmp(pos, "either", 6) == 0)
2380 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
2381 					DPP_CAPAB_ENROLLEE;
2382 			else
2383 				return -1;
2384 		}
2385 
2386 		config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
2387 	}
2388 	config.configurator_params = hapd->dpp_configurator_params;
2389 	return dpp_controller_start(hapd->iface->interfaces->dpp, &config);
2390 }
2391 
2392 
2393 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
2394 
hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)2395 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
2396 {
2397 	struct hostapd_data *hapd = eloop_ctx;
2398 
2399 	wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
2400 	hostapd_drv_send_action_cancel_wait(hapd);
2401 	hostapd_dpp_chirp_next(hapd, NULL);
2402 }
2403 
2404 
hostapd_dpp_chirp_start(struct hostapd_data * hapd)2405 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
2406 {
2407 	struct wpabuf *msg;
2408 	int type;
2409 
2410 	msg = hapd->dpp_presence_announcement;
2411 	type = DPP_PA_PRESENCE_ANNOUNCEMENT;
2412 	wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
2413 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2414 		" freq=%u type=%d",
2415 		MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
2416 	if (hostapd_drv_send_action(
2417 		    hapd, hapd->dpp_chirp_freq, 2000, broadcast,
2418 		    wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
2419 	    eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
2420 				   hapd, NULL) < 0)
2421 		hostapd_dpp_chirp_stop(hapd);
2422 }
2423 
2424 
2425 static struct hostapd_hw_modes *
dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)2426 dpp_get_mode(struct hostapd_data *hapd,
2427 	     enum hostapd_hw_mode mode)
2428 {
2429 	struct hostapd_hw_modes *modes = hapd->iface->hw_features;
2430 	u16 num_modes = hapd->iface->num_hw_features;
2431 	u16 i;
2432 
2433 	for (i = 0; i < num_modes; i++) {
2434 		if (modes[i].mode != mode ||
2435 		    !modes[i].num_channels || !modes[i].channels)
2436 			continue;
2437 		return &modes[i];
2438 	}
2439 
2440 	return NULL;
2441 }
2442 
2443 
2444 static void
hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)2445 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
2446 {
2447 	struct hostapd_data *hapd = iface->bss[0];
2448 	struct wpa_scan_results *scan_res;
2449 	struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
2450 	unsigned int i;
2451 	struct hostapd_hw_modes *mode;
2452 	int c;
2453 	bool chan6 = hapd->iface->hw_features == NULL;
2454 
2455 	if (!bi)
2456 		return;
2457 
2458 	hapd->dpp_chirp_scan_done = 1;
2459 
2460 	scan_res = hostapd_driver_get_scan_results(hapd);
2461 
2462 	os_free(hapd->dpp_chirp_freqs);
2463 	hapd->dpp_chirp_freqs = NULL;
2464 
2465 	/* Channels from own bootstrapping info */
2466 	if (bi) {
2467 		for (i = 0; i < bi->num_freq; i++)
2468 			int_array_add_unique(&hapd->dpp_chirp_freqs,
2469 					     bi->freq[i]);
2470 	}
2471 
2472 	/* Preferred chirping channels */
2473 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
2474 	if (mode) {
2475 		for (c = 0; c < mode->num_channels; c++) {
2476 			struct hostapd_channel_data *chan = &mode->channels[c];
2477 
2478 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2479 					  HOSTAPD_CHAN_RADAR) ||
2480 			    chan->freq != 2437)
2481 				continue;
2482 			chan6 = true;
2483 			break;
2484 		}
2485 	}
2486 	if (chan6)
2487 		int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
2488 
2489 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
2490 	if (mode) {
2491 		int chan44 = 0, chan149 = 0;
2492 
2493 		for (c = 0; c < mode->num_channels; c++) {
2494 			struct hostapd_channel_data *chan = &mode->channels[c];
2495 
2496 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2497 					  HOSTAPD_CHAN_RADAR))
2498 				continue;
2499 			if (chan->freq == 5220)
2500 				chan44 = 1;
2501 			if (chan->freq == 5745)
2502 				chan149 = 1;
2503 		}
2504 		if (chan149)
2505 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
2506 		else if (chan44)
2507 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
2508 	}
2509 
2510 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
2511 	if (mode) {
2512 		for (c = 0; c < mode->num_channels; c++) {
2513 			struct hostapd_channel_data *chan = &mode->channels[c];
2514 
2515 			if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
2516 					   HOSTAPD_CHAN_RADAR)) ||
2517 			    chan->freq != 60480)
2518 				continue;
2519 			int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
2520 			break;
2521 		}
2522 	}
2523 
2524 	/* Add channels from scan results for APs that advertise Configurator
2525 	 * Connectivity element */
2526 	for (i = 0; scan_res && i < scan_res->num; i++) {
2527 		struct wpa_scan_res *bss = scan_res->res[i];
2528 		size_t ie_len = bss->ie_len;
2529 
2530 		if (!ie_len)
2531 			ie_len = bss->beacon_ie_len;
2532 		if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
2533 				  DPP_CC_IE_VENDOR_TYPE))
2534 			int_array_add_unique(&hapd->dpp_chirp_freqs,
2535 					     bss->freq);
2536 	}
2537 
2538 	if (!hapd->dpp_chirp_freqs ||
2539 	    eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
2540 				   hapd, NULL) < 0)
2541 		hostapd_dpp_chirp_stop(hapd);
2542 
2543 	wpa_scan_results_free(scan_res);
2544 }
2545 
2546 
hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)2547 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
2548 {
2549 	struct hostapd_data *hapd = eloop_ctx;
2550 	int i;
2551 
2552 	if (hapd->dpp_chirp_listen)
2553 		hostapd_dpp_listen_stop(hapd);
2554 
2555 	if (hapd->dpp_chirp_freq == 0) {
2556 		if (hapd->dpp_chirp_round % 4 == 0 &&
2557 		    !hapd->dpp_chirp_scan_done) {
2558 			struct wpa_driver_scan_params params;
2559 			int ret;
2560 
2561 			wpa_printf(MSG_DEBUG,
2562 				   "DPP: Update channel list for chirping");
2563 			os_memset(&params, 0, sizeof(params));
2564 			ret = hostapd_driver_scan(hapd, &params);
2565 			if (ret < 0) {
2566 				wpa_printf(MSG_DEBUG,
2567 					   "DPP: Failed to request a scan ret=%d (%s)",
2568 					   ret, strerror(-ret));
2569 				hostapd_dpp_chirp_scan_res_handler(hapd->iface);
2570 			} else {
2571 				hapd->iface->scan_cb =
2572 					hostapd_dpp_chirp_scan_res_handler;
2573 			}
2574 			return;
2575 		}
2576 		hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
2577 		hapd->dpp_chirp_round++;
2578 		wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
2579 			   hapd->dpp_chirp_round);
2580 	} else {
2581 		for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
2582 			if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
2583 				break;
2584 		if (!hapd->dpp_chirp_freqs[i]) {
2585 			wpa_printf(MSG_DEBUG,
2586 				   "DPP: Previous chirp freq %d not found",
2587 				   hapd->dpp_chirp_freq);
2588 			return;
2589 		}
2590 		i++;
2591 		if (hapd->dpp_chirp_freqs[i]) {
2592 			hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
2593 		} else {
2594 			hapd->dpp_chirp_iter--;
2595 			if (hapd->dpp_chirp_iter <= 0) {
2596 				wpa_printf(MSG_DEBUG,
2597 					   "DPP: Chirping iterations completed");
2598 				hostapd_dpp_chirp_stop(hapd);
2599 				return;
2600 			}
2601 			hapd->dpp_chirp_freq = 0;
2602 			hapd->dpp_chirp_scan_done = 0;
2603 			if (eloop_register_timeout(30, 0,
2604 						   hostapd_dpp_chirp_next,
2605 						   hapd, NULL) < 0) {
2606 				hostapd_dpp_chirp_stop(hapd);
2607 				return;
2608 			}
2609 			if (hapd->dpp_chirp_listen) {
2610 				wpa_printf(MSG_DEBUG,
2611 					   "DPP: Listen on %d MHz during chirp 30 second wait",
2612 					hapd->dpp_chirp_listen);
2613 				/* TODO: start listen on the channel */
2614 			} else {
2615 				wpa_printf(MSG_DEBUG,
2616 					   "DPP: Wait 30 seconds before starting the next chirping round");
2617 			}
2618 			return;
2619 		}
2620 	}
2621 
2622 	hostapd_dpp_chirp_start(hapd);
2623 }
2624 
2625 
hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)2626 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
2627 {
2628 	const char *pos;
2629 	int iter = 1, listen_freq = 0;
2630 	struct dpp_bootstrap_info *bi;
2631 
2632 	pos = os_strstr(cmd, " own=");
2633 	if (!pos)
2634 		return -1;
2635 	pos += 5;
2636 	bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
2637 	if (!bi) {
2638 		wpa_printf(MSG_DEBUG,
2639 			   "DPP: Identified bootstrap info not found");
2640 		return -1;
2641 	}
2642 
2643 	pos = os_strstr(cmd, " iter=");
2644 	if (pos) {
2645 		iter = atoi(pos + 6);
2646 		if (iter <= 0)
2647 			return -1;
2648 	}
2649 
2650 	pos = os_strstr(cmd, " listen=");
2651 	if (pos) {
2652 		listen_freq = atoi(pos + 8);
2653 		if (listen_freq <= 0)
2654 			return -1;
2655 	}
2656 
2657 	hostapd_dpp_chirp_stop(hapd);
2658 	hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
2659 	hapd->dpp_qr_mutual = 0;
2660 	hapd->dpp_chirp_bi = bi;
2661 	hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
2662 	if (!hapd->dpp_presence_announcement)
2663 		return -1;
2664 	hapd->dpp_chirp_iter = iter;
2665 	hapd->dpp_chirp_round = 0;
2666 	hapd->dpp_chirp_scan_done = 0;
2667 	hapd->dpp_chirp_listen = listen_freq;
2668 
2669 	return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
2670 }
2671 
2672 
hostapd_dpp_chirp_stop(struct hostapd_data * hapd)2673 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
2674 {
2675 	if (hapd->dpp_presence_announcement) {
2676 		hostapd_drv_send_action_cancel_wait(hapd);
2677 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
2678 	}
2679 	hapd->dpp_chirp_bi = NULL;
2680 	wpabuf_free(hapd->dpp_presence_announcement);
2681 	hapd->dpp_presence_announcement = NULL;
2682 	if (hapd->dpp_chirp_listen)
2683 		hostapd_dpp_listen_stop(hapd);
2684 	hapd->dpp_chirp_listen = 0;
2685 	hapd->dpp_chirp_freq = 0;
2686 	os_free(hapd->dpp_chirp_freqs);
2687 	hapd->dpp_chirp_freqs = NULL;
2688 	eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
2689 	eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
2690 	if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
2691 		/* TODO: abort ongoing scan */
2692 		hapd->iface->scan_cb = NULL;
2693 	}
2694 }
2695 
2696 
handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)2697 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
2698 {
2699 	struct dpp_bootstrap_info *bi = ctx;
2700 	size_t i;
2701 
2702 	for (i = 0; i < iface->num_bss; i++) {
2703 		struct hostapd_data *hapd = iface->bss[i];
2704 
2705 		if (bi == hapd->dpp_chirp_bi)
2706 			hostapd_dpp_chirp_stop(hapd);
2707 	}
2708 
2709 	return 0;
2710 }
2711 
2712 
hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)2713 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
2714 {
2715 	struct hapd_interfaces *interfaces = ctx;
2716 
2717 	hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
2718 }
2719 
2720 #endif /* CONFIG_DPP2 */
2721