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