• 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  * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "utils/includes.h"
12 
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "common/dpp.h"
16 #include "common/gas.h"
17 #include "common/wpa_ctrl.h"
18 #include "crypto/random.h"
19 #include "hostapd.h"
20 #include "ap_drv_ops.h"
21 #include "gas_query_ap.h"
22 #include "gas_serv.h"
23 #include "wpa_auth.h"
24 #include "beacon.h"
25 #include "dpp_hostapd.h"
26 
27 
28 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
29 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
30 					       void *timeout_ctx);
31 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
32 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
33 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
34 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
35 					    struct dpp_authentication *auth);
36 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd);
37 #ifdef CONFIG_DPP2
38 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
39 						    void *timeout_ctx);
40 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
41 					  struct dpp_authentication *auth,
42 					  struct dpp_config_obj *conf);
43 static int hostapd_dpp_process_conf_obj(void *ctx,
44 					struct dpp_authentication *auth);
45 #endif /* CONFIG_DPP2 */
46 
47 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
48 
49 
50 /**
51  * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
52  * @hapd: Pointer to hostapd_data
53  * @cmd: DPP URI read from a QR Code
54  * Returns: Identifier of the stored info or -1 on failure
55  */
hostapd_dpp_qr_code(struct hostapd_data * hapd,const char * cmd)56 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
57 {
58 	struct dpp_bootstrap_info *bi;
59 	struct dpp_authentication *auth = hapd->dpp_auth;
60 
61 	bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
62 	if (!bi)
63 		return -1;
64 
65 	if (auth && auth->response_pending &&
66 	    dpp_notify_new_qr_code(auth, bi) == 1) {
67 		wpa_printf(MSG_DEBUG,
68 			   "DPP: Sending out pending authentication response");
69 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
70 			" freq=%u type=%d",
71 			MAC2STR(auth->peer_mac_addr), auth->curr_freq,
72 			DPP_PA_AUTHENTICATION_RESP);
73 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
74 					auth->peer_mac_addr,
75 					wpabuf_head(hapd->dpp_auth->resp_msg),
76 					wpabuf_len(hapd->dpp_auth->resp_msg));
77 	}
78 
79 #ifdef CONFIG_DPP2
80 	dpp_controller_new_qr_code(hapd->iface->interfaces->dpp, bi);
81 #endif /* CONFIG_DPP2 */
82 
83 	return bi->id;
84 }
85 
86 
87 /**
88  * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
89  * @hapd: Pointer to hostapd_data
90  * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
91  * Returns: Identifier of the stored info or -1 on failure
92  */
hostapd_dpp_nfc_uri(struct hostapd_data * hapd,const char * cmd)93 int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
94 {
95 	struct dpp_bootstrap_info *bi;
96 
97 	bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
98 	if (!bi)
99 		return -1;
100 
101 	return bi->id;
102 }
103 
104 
hostapd_dpp_nfc_handover_req(struct hostapd_data * hapd,const char * cmd)105 int hostapd_dpp_nfc_handover_req(struct hostapd_data *hapd, const char *cmd)
106 {
107 	const char *pos;
108 	struct dpp_bootstrap_info *peer_bi, *own_bi;
109 
110 	pos = os_strstr(cmd, " own=");
111 	if (!pos)
112 		return -1;
113 	pos += 5;
114 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
115 	if (!own_bi)
116 		return -1;
117 
118 	pos = os_strstr(cmd, " uri=");
119 	if (!pos)
120 		return -1;
121 	pos += 5;
122 	peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
123 	if (!peer_bi) {
124 		wpa_printf(MSG_INFO,
125 			   "DPP: Failed to parse URI from NFC Handover Request");
126 		return -1;
127 	}
128 
129 	if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
130 		return -1;
131 
132 	return peer_bi->id;
133 }
134 
135 
hostapd_dpp_nfc_handover_sel(struct hostapd_data * hapd,const char * cmd)136 int hostapd_dpp_nfc_handover_sel(struct hostapd_data *hapd, const char *cmd)
137 {
138 	const char *pos;
139 	struct dpp_bootstrap_info *peer_bi, *own_bi;
140 
141 	pos = os_strstr(cmd, " own=");
142 	if (!pos)
143 		return -1;
144 	pos += 5;
145 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
146 	if (!own_bi)
147 		return -1;
148 
149 	pos = os_strstr(cmd, " uri=");
150 	if (!pos)
151 		return -1;
152 	pos += 5;
153 	peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
154 	if (!peer_bi) {
155 		wpa_printf(MSG_INFO,
156 			   "DPP: Failed to parse URI from NFC Handover Select");
157 		return -1;
158 	}
159 
160 	if (peer_bi->curve != own_bi->curve) {
161 		wpa_printf(MSG_INFO,
162 			   "DPP: Peer (NFC Handover Selector) used different curve");
163 		return -1;
164 	}
165 
166 	return peer_bi->id;
167 }
168 
169 
hostapd_dpp_auth_resp_retry_timeout(void * eloop_ctx,void * timeout_ctx)170 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
171 						void *timeout_ctx)
172 {
173 	struct hostapd_data *hapd = eloop_ctx;
174 	struct dpp_authentication *auth = hapd->dpp_auth;
175 
176 	if (!auth || !auth->resp_msg)
177 		return;
178 
179 	wpa_printf(MSG_DEBUG,
180 		   "DPP: Retry Authentication Response after timeout");
181 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
182 		" freq=%u type=%d",
183 		MAC2STR(auth->peer_mac_addr), auth->curr_freq,
184 		DPP_PA_AUTHENTICATION_RESP);
185 	hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
186 				wpabuf_head(auth->resp_msg),
187 				wpabuf_len(auth->resp_msg));
188 }
189 
190 
hostapd_dpp_auth_resp_retry(struct hostapd_data * hapd)191 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
192 {
193 	struct dpp_authentication *auth = hapd->dpp_auth;
194 	unsigned int wait_time, max_tries;
195 
196 	if (!auth || !auth->resp_msg)
197 		return;
198 
199 	if (hapd->dpp_resp_max_tries)
200 		max_tries = hapd->dpp_resp_max_tries;
201 	else
202 		max_tries = 5;
203 	auth->auth_resp_tries++;
204 	if (auth->auth_resp_tries >= max_tries) {
205 		wpa_printf(MSG_INFO,
206 			   "DPP: No confirm received from initiator - stopping exchange");
207 		hostapd_drv_send_action_cancel_wait(hapd);
208 		dpp_auth_deinit(hapd->dpp_auth);
209 		hapd->dpp_auth = NULL;
210 		return;
211 	}
212 
213 	if (hapd->dpp_resp_retry_time)
214 		wait_time = hapd->dpp_resp_retry_time;
215 	else
216 		wait_time = 1000;
217 	wpa_printf(MSG_DEBUG,
218 		   "DPP: Schedule retransmission of Authentication Response frame in %u ms",
219 		wait_time);
220 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
221 	eloop_register_timeout(wait_time / 1000,
222 			       (wait_time % 1000) * 1000,
223 			       hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
224 }
225 
226 
hostapd_dpp_allow_ir(struct hostapd_data * hapd,unsigned int freq)227 static int hostapd_dpp_allow_ir(struct hostapd_data *hapd, unsigned int freq)
228 {
229 	int i, j;
230 
231 	if (!hapd->iface->hw_features)
232 		return -1;
233 
234 	for (i = 0; i < hapd->iface->num_hw_features; i++) {
235 		struct hostapd_hw_modes *mode = &hapd->iface->hw_features[i];
236 
237 		for (j = 0; j < mode->num_channels; j++) {
238 			struct hostapd_channel_data *chan = &mode->channels[j];
239 
240 			if (chan->freq != (int) freq)
241 				continue;
242 
243 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
244 					  HOSTAPD_CHAN_NO_IR |
245 					  HOSTAPD_CHAN_RADAR))
246 				continue;
247 
248 			return 1;
249 		}
250 	}
251 
252 	wpa_printf(MSG_DEBUG,
253 		   "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
254 		   freq);
255 
256 	return 0;
257 }
258 
259 
hostapd_dpp_pkex_next_channel(struct hostapd_data * hapd,struct dpp_pkex * pkex)260 static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
261 					 struct dpp_pkex *pkex)
262 {
263 	if (pkex->freq == 2437)
264 		pkex->freq = 5745;
265 	else if (pkex->freq == 5745)
266 		pkex->freq = 5220;
267 	else if (pkex->freq == 5220)
268 		pkex->freq = 60480;
269 	else
270 		return -1; /* no more channels to try */
271 
272 	if (hostapd_dpp_allow_ir(hapd, pkex->freq) == 1) {
273 		wpa_printf(MSG_DEBUG, "DPP: Try to initiate on %u MHz",
274 			   pkex->freq);
275 		return 0;
276 	}
277 
278 	/* Could not use this channel - try the next one */
279 	return hostapd_dpp_pkex_next_channel(hapd, pkex);
280 }
281 
282 
hostapd_dpp_pkex_clear_code(struct hostapd_data * hapd)283 static void hostapd_dpp_pkex_clear_code(struct hostapd_data *hapd)
284 {
285 	if (!hapd->dpp_pkex_code && !hapd->dpp_pkex_identifier)
286 		return;
287 
288 	/* Delete PKEX code and identifier on successful completion of
289 	 * PKEX. We are not supposed to reuse these without being
290 	 * explicitly requested to perform PKEX again. */
291 	wpa_printf(MSG_DEBUG, "DPP: Delete PKEX code/identifier");
292 	os_free(hapd->dpp_pkex_code);
293 	hapd->dpp_pkex_code = NULL;
294 	os_free(hapd->dpp_pkex_identifier);
295 	hapd->dpp_pkex_identifier = NULL;
296 }
297 
298 
299 #ifdef CONFIG_DPP2
hostapd_dpp_pkex_done(void * ctx,void * conn,struct dpp_bootstrap_info * peer_bi)300 static int hostapd_dpp_pkex_done(void *ctx, void *conn,
301 				 struct dpp_bootstrap_info *peer_bi)
302 {
303 	struct hostapd_data *hapd = ctx;
304 	char cmd[500];
305 	const char *pos;
306 	u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
307 	struct dpp_bootstrap_info *own_bi = NULL;
308 	struct dpp_authentication *auth;
309 
310 	hostapd_dpp_pkex_clear_code(hapd);
311 
312 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s", peer_bi->id,
313 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
314 	wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
315 		   cmd);
316 
317 	pos = os_strstr(cmd, " own=");
318 	if (pos) {
319 		pos += 5;
320 		own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
321 					      atoi(pos));
322 		if (!own_bi) {
323 			wpa_printf(MSG_INFO,
324 				   "DPP: Could not find bootstrapping info for the identified local entry");
325 			return -1;
326 		}
327 
328 		if (peer_bi->curve != own_bi->curve) {
329 			wpa_printf(MSG_INFO,
330 				   "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
331 				   peer_bi->curve->name, own_bi->curve->name);
332 			return -1;
333 		}
334 	}
335 
336 	pos = os_strstr(cmd, " role=");
337 	if (pos) {
338 		pos += 6;
339 		if (os_strncmp(pos, "configurator", 12) == 0)
340 			allowed_roles = DPP_CAPAB_CONFIGURATOR;
341 		else if (os_strncmp(pos, "enrollee", 8) == 0)
342 			allowed_roles = DPP_CAPAB_ENROLLEE;
343 		else if (os_strncmp(pos, "either", 6) == 0)
344 			allowed_roles = DPP_CAPAB_CONFIGURATOR |
345 				DPP_CAPAB_ENROLLEE;
346 		else
347 			return -1;
348 	}
349 
350 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
351 			     peer_bi, own_bi, allowed_roles, 0,
352 			     hapd->iface->hw_features,
353 			     hapd->iface->num_hw_features);
354 	if (!auth)
355 		return -1;
356 
357 	hostapd_dpp_set_testing_options(hapd, auth);
358 	if (dpp_set_configurator(auth, cmd) < 0) {
359 		dpp_auth_deinit(auth);
360 		return -1;
361 	}
362 
363 	return dpp_tcp_auth(hapd->iface->interfaces->dpp, conn, auth,
364 			    hapd->conf->dpp_name, DPP_NETROLE_AP,
365 			    hapd->conf->dpp_mud_url,
366 			    hapd->conf->dpp_extra_conf_req_name,
367 			    hapd->conf->dpp_extra_conf_req_value,
368 			    hostapd_dpp_process_conf_obj, NULL);
369 }
370 #endif /* CONFIG_DPP2 */
371 
372 
hostapd_dpp_pkex_init(struct hostapd_data * hapd,enum dpp_pkex_ver ver,const struct hostapd_ip_addr * ipaddr,int tcp_port)373 static int hostapd_dpp_pkex_init(struct hostapd_data *hapd,
374 				 enum dpp_pkex_ver ver,
375 				 const struct hostapd_ip_addr *ipaddr,
376 				 int tcp_port)
377 {
378 	struct dpp_pkex *pkex;
379 	struct wpabuf *msg;
380 	unsigned int wait_time;
381 	bool v2 = ver != PKEX_VER_ONLY_1;
382 
383 	wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
384 	dpp_pkex_free(hapd->dpp_pkex);
385 	hapd->dpp_pkex = NULL;
386 	pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
387 			     hapd->dpp_pkex_identifier,
388 			     hapd->dpp_pkex_code, hapd->dpp_pkex_code_len, v2);
389 	if (!pkex)
390 		return -1;
391 	pkex->forced_ver = ver != PKEX_VER_AUTO;
392 
393 	if (ipaddr) {
394 #ifdef CONFIG_DPP2
395 		return dpp_tcp_pkex_init(hapd->iface->interfaces->dpp, pkex,
396 					 ipaddr, tcp_port,
397 					 hapd->msg_ctx, hapd,
398 					 hostapd_dpp_pkex_done);
399 #else /* CONFIG_DPP2 */
400 		return -1;
401 #endif /* CONFIG_DPP2 */
402 	}
403 
404 	hapd->dpp_pkex = pkex;
405 	msg = hapd->dpp_pkex->exchange_req;
406 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
407 	pkex->freq = 2437;
408 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
409 		" freq=%u type=%d", MAC2STR(broadcast), pkex->freq,
410 		v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
411 		DPP_PA_PKEX_V1_EXCHANGE_REQ);
412 	hostapd_drv_send_action(hapd, pkex->freq, 0, broadcast,
413 				wpabuf_head(msg), wpabuf_len(msg));
414 	pkex->exch_req_wait_time = wait_time;
415 	pkex->exch_req_tries = 1;
416 
417 	return 0;
418 }
419 
420 
hostapd_dpp_pkex_retry_timeout(void * eloop_ctx,void * timeout_ctx)421 static void hostapd_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
422 {
423 	struct hostapd_data *hapd = eloop_ctx;
424 	struct dpp_pkex *pkex = hapd->dpp_pkex;
425 
426 	if (!pkex || !pkex->exchange_req)
427 		return;
428 	if (pkex->exch_req_tries >= 5) {
429 		if (hostapd_dpp_pkex_next_channel(hapd, pkex) < 0) {
430 #ifdef CONFIG_DPP3
431 			if (pkex->v2 && !pkex->forced_ver) {
432 				wpa_printf(MSG_DEBUG,
433 					   "DPP: Fall back to PKEXv1");
434 				hostapd_dpp_pkex_init(hapd, PKEX_VER_ONLY_1,
435 						      NULL, 0);
436 				return;
437 			}
438 #endif /* CONFIG_DPP3 */
439 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
440 				"No response from PKEX peer");
441 			dpp_pkex_free(pkex);
442 			hapd->dpp_pkex = NULL;
443 			return;
444 		}
445 		pkex->exch_req_tries = 0;
446 	}
447 
448 	pkex->exch_req_tries++;
449 	wpa_printf(MSG_DEBUG, "DPP: Retransmit PKEX Exchange Request (try %u)",
450 		   pkex->exch_req_tries);
451 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
452 		" freq=%u type=%d",
453 		MAC2STR(broadcast), pkex->freq,
454 		pkex->v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
455 		DPP_PA_PKEX_V1_EXCHANGE_REQ);
456 	hostapd_drv_send_action(hapd, pkex->freq, pkex->exch_req_wait_time,
457 				broadcast,
458 				wpabuf_head(pkex->exchange_req),
459 				wpabuf_len(pkex->exchange_req));
460 }
461 
462 
hostapd_dpp_pkex_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)463 static void hostapd_dpp_pkex_tx_status(struct hostapd_data *hapd, const u8 *dst,
464 				       const u8 *data, size_t data_len, int ok)
465 {
466 	struct dpp_pkex *pkex = hapd->dpp_pkex;
467 
468 	if (pkex->failed) {
469 		wpa_printf(MSG_DEBUG,
470 			   "DPP: Terminate PKEX exchange due to an earlier error");
471 		if (pkex->t > pkex->own_bi->pkex_t)
472 			pkex->own_bi->pkex_t = pkex->t;
473 		dpp_pkex_free(pkex);
474 		hapd->dpp_pkex = NULL;
475 		return;
476 	}
477 
478 	if (pkex->exch_req_wait_time && pkex->exchange_req) {
479 		/* Wait for PKEX Exchange Response frame and retry request if
480 		 * no response is seen. */
481 		eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd,
482 				     NULL);
483 		eloop_register_timeout(pkex->exch_req_wait_time / 1000,
484 				       (pkex->exch_req_wait_time % 1000) * 1000,
485 				       hostapd_dpp_pkex_retry_timeout, hapd,
486 				       NULL);
487 	}
488 }
489 
490 
hostapd_dpp_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)491 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
492 			   const u8 *data, size_t data_len, int ok)
493 {
494 	struct dpp_authentication *auth = hapd->dpp_auth;
495 
496 	wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR_SEC " ok=%d",
497 		   MAC2STR_SEC(dst), ok);
498 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
499 		" result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
500 
501 	if (!hapd->dpp_auth) {
502 		if (hapd->dpp_pkex) {
503 			hostapd_dpp_pkex_tx_status(hapd, dst, data, data_len,
504 						   ok);
505 			return;
506 		}
507 		wpa_printf(MSG_DEBUG,
508 			   "DPP: Ignore TX status since there is no ongoing authentication exchange");
509 		return;
510 	}
511 
512 #ifdef CONFIG_DPP2
513 	if (auth->connect_on_tx_status) {
514 		wpa_printf(MSG_DEBUG,
515 			   "DPP: Complete exchange on configuration result");
516 		dpp_auth_deinit(hapd->dpp_auth);
517 		hapd->dpp_auth = NULL;
518 		return;
519 	}
520 #endif /* CONFIG_DPP2 */
521 
522 	if (hapd->dpp_auth->remove_on_tx_status) {
523 		wpa_printf(MSG_DEBUG,
524 			   "DPP: Terminate authentication exchange due to an earlier error");
525 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
526 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
527 				     hapd, NULL);
528 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
529 				     hapd, NULL);
530 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
531 				     NULL);
532 #ifdef CONFIG_DPP2
533 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
534 				     hapd, NULL);
535 #endif /* CONFIG_DPP2 */
536 		hostapd_drv_send_action_cancel_wait(hapd);
537 		dpp_auth_deinit(hapd->dpp_auth);
538 		hapd->dpp_auth = NULL;
539 		return;
540 	}
541 
542 	if (hapd->dpp_auth_ok_on_ack) {
543 		hostapd_dpp_auth_success(hapd, 1);
544 		if (!hapd->dpp_auth) {
545 			/* The authentication session could have been removed in
546 			 * some error cases, e.g., when starting GAS client and
547 			 * failing to send the initial request. */
548 			return;
549 		}
550 	}
551 
552 	if (!is_broadcast_ether_addr(dst) && !ok) {
553 		wpa_printf(MSG_DEBUG,
554 			   "DPP: Unicast DPP Action frame was not ACKed");
555 		if (auth->waiting_auth_resp) {
556 			/* In case of DPP Authentication Request frame, move to
557 			 * the next channel immediately. */
558 			hostapd_drv_send_action_cancel_wait(hapd);
559 			hostapd_dpp_auth_init_next(hapd);
560 			return;
561 		}
562 		if (auth->waiting_auth_conf) {
563 			hostapd_dpp_auth_resp_retry(hapd);
564 			return;
565 		}
566 	}
567 
568 	if (auth->waiting_auth_conf &&
569 	    auth->auth_resp_status == DPP_STATUS_OK) {
570 		/* Make sure we do not get stuck waiting for Auth Confirm
571 		 * indefinitely after successfully transmitted Auth Response to
572 		 * allow new authentication exchanges to be started. */
573 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd,
574 				     NULL);
575 		eloop_register_timeout(1, 0, hostapd_dpp_auth_conf_wait_timeout,
576 				       hapd, NULL);
577 	}
578 
579 	if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
580 		/* Allow timeout handling to stop iteration if no response is
581 		 * received from a peer that has ACKed a request. */
582 		auth->auth_req_ack = 1;
583 	}
584 
585 	if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
586 	    hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
587 		wpa_printf(MSG_DEBUG,
588 			   "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
589 			   hapd->dpp_auth->curr_freq,
590 			   hapd->dpp_auth->neg_freq);
591 		hostapd_drv_send_action_cancel_wait(hapd);
592 
593 		if (hapd->dpp_auth->neg_freq !=
594 		    (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
595 			/* TODO: Listen operation on non-operating channel */
596 			wpa_printf(MSG_INFO,
597 				   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
598 				   hapd->dpp_auth->neg_freq, hapd->iface->freq);
599 		}
600 	}
601 
602 	if (hapd->dpp_auth_ok_on_ack)
603 		hapd->dpp_auth_ok_on_ack = 0;
604 }
605 
606 
hostapd_dpp_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)607 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
608 {
609 	struct hostapd_data *hapd = eloop_ctx;
610 	struct dpp_authentication *auth = hapd->dpp_auth;
611 	unsigned int freq;
612 	struct os_reltime now, diff;
613 	unsigned int wait_time, diff_ms;
614 
615 	if (!auth || !auth->waiting_auth_resp)
616 		return;
617 
618 	wait_time = hapd->dpp_resp_wait_time ?
619 		hapd->dpp_resp_wait_time : 2000;
620 	os_get_reltime(&now);
621 	os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
622 	diff_ms = diff.sec * 1000 + diff.usec / 1000;
623 	wpa_printf(MSG_DEBUG,
624 		   "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
625 		   wait_time, diff_ms);
626 
627 	if (auth->auth_req_ack && diff_ms >= wait_time) {
628 		/* Peer ACK'ed Authentication Request frame, but did not reply
629 		 * with Authentication Response frame within two seconds. */
630 		wpa_printf(MSG_INFO,
631 			   "DPP: No response received from responder - stopping initiation attempt");
632 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
633 		hostapd_drv_send_action_cancel_wait(hapd);
634 		hostapd_dpp_listen_stop(hapd);
635 		dpp_auth_deinit(auth);
636 		hapd->dpp_auth = NULL;
637 		return;
638 	}
639 
640 	if (diff_ms >= wait_time) {
641 		/* Authentication Request frame was not ACK'ed and no reply
642 		 * was receiving within two seconds. */
643 		wpa_printf(MSG_DEBUG,
644 			   "DPP: Continue Initiator channel iteration");
645 		hostapd_drv_send_action_cancel_wait(hapd);
646 		hostapd_dpp_listen_stop(hapd);
647 		hostapd_dpp_auth_init_next(hapd);
648 		return;
649 	}
650 
651 	/* Driver did not support 2000 ms long wait_time with TX command, so
652 	 * schedule listen operation to continue waiting for the response.
653 	 *
654 	 * DPP listen operations continue until stopped, so simply schedule a
655 	 * new call to this function at the point when the two second reply
656 	 * wait has expired. */
657 	wait_time -= diff_ms;
658 
659 	freq = auth->curr_freq;
660 	if (auth->neg_freq > 0)
661 		freq = auth->neg_freq;
662 	wpa_printf(MSG_DEBUG,
663 		   "DPP: Continue reply wait on channel %u MHz for %u ms",
664 		   freq, wait_time);
665 	hapd->dpp_in_response_listen = 1;
666 
667 	if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
668 		/* TODO: Listen operation on non-operating channel */
669 		wpa_printf(MSG_INFO,
670 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
671 			   freq, hapd->iface->freq);
672 	}
673 
674 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
675 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
676 }
677 
678 
hostapd_dpp_auth_conf_wait_timeout(void * eloop_ctx,void * timeout_ctx)679 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
680 					       void *timeout_ctx)
681 {
682 	struct hostapd_data *hapd = eloop_ctx;
683 	struct dpp_authentication *auth = hapd->dpp_auth;
684 
685 	if (!auth || !auth->waiting_auth_conf)
686 		return;
687 
688 	wpa_printf(MSG_DEBUG,
689 		   "DPP: Terminate authentication exchange due to Auth Confirm timeout");
690 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
691 		"No Auth Confirm received");
692 	hostapd_drv_send_action_cancel_wait(hapd);
693 	dpp_auth_deinit(auth);
694 	hapd->dpp_auth = NULL;
695 }
696 
697 
hostapd_dpp_set_testing_options(struct hostapd_data * hapd,struct dpp_authentication * auth)698 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
699 					    struct dpp_authentication *auth)
700 {
701 #ifdef CONFIG_TESTING_OPTIONS
702 	if (hapd->dpp_config_obj_override)
703 		auth->config_obj_override =
704 			os_strdup(hapd->dpp_config_obj_override);
705 	if (hapd->dpp_discovery_override)
706 		auth->discovery_override =
707 			os_strdup(hapd->dpp_discovery_override);
708 	if (hapd->dpp_groups_override)
709 		auth->groups_override = os_strdup(hapd->dpp_groups_override);
710 	auth->ignore_netaccesskey_mismatch =
711 		hapd->dpp_ignore_netaccesskey_mismatch;
712 #endif /* CONFIG_TESTING_OPTIONS */
713 }
714 
715 
hostapd_dpp_init_timeout(void * eloop_ctx,void * timeout_ctx)716 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
717 {
718 	struct hostapd_data *hapd = eloop_ctx;
719 
720 	if (!hapd->dpp_auth)
721 		return;
722 	wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
723 	hostapd_dpp_auth_init_next(hapd);
724 }
725 
726 
hostapd_dpp_auth_init_next(struct hostapd_data * hapd)727 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
728 {
729 	struct dpp_authentication *auth = hapd->dpp_auth;
730 	const u8 *dst;
731 	unsigned int wait_time, max_wait_time, freq, max_tries, used;
732 	struct os_reltime now, diff;
733 
734 	if (!auth)
735 		return -1;
736 
737 	if (auth->freq_idx == 0)
738 		os_get_reltime(&hapd->dpp_init_iter_start);
739 
740 	if (auth->freq_idx >= auth->num_freq) {
741 		auth->num_freq_iters++;
742 		if (hapd->dpp_init_max_tries)
743 			max_tries = hapd->dpp_init_max_tries;
744 		else
745 			max_tries = 5;
746 		if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
747 			wpa_printf(MSG_INFO,
748 				   "DPP: No response received from responder - stopping initiation attempt");
749 			wpa_msg(hapd->msg_ctx, MSG_INFO,
750 				DPP_EVENT_AUTH_INIT_FAILED);
751 			eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
752 					     hapd, NULL);
753 			hostapd_drv_send_action_cancel_wait(hapd);
754 			dpp_auth_deinit(hapd->dpp_auth);
755 			hapd->dpp_auth = NULL;
756 			return -1;
757 		}
758 		auth->freq_idx = 0;
759 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
760 		if (hapd->dpp_init_retry_time)
761 			wait_time = hapd->dpp_init_retry_time;
762 		else
763 			wait_time = 10000;
764 		os_get_reltime(&now);
765 		os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
766 		used = diff.sec * 1000 + diff.usec / 1000;
767 		if (used > wait_time)
768 			wait_time = 0;
769 		else
770 			wait_time -= used;
771 		wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
772 			   wait_time);
773 		eloop_register_timeout(wait_time / 1000,
774 				       (wait_time % 1000) * 1000,
775 				       hostapd_dpp_init_timeout, hapd,
776 				       NULL);
777 		return 0;
778 	}
779 	freq = auth->freq[auth->freq_idx++];
780 	auth->curr_freq = freq;
781 
782 	if (!is_zero_ether_addr(auth->peer_mac_addr))
783 		dst = auth->peer_mac_addr;
784 	else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
785 		dst = broadcast;
786 	else
787 		dst = auth->peer_bi->mac_addr;
788 	hapd->dpp_auth_ok_on_ack = 0;
789 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
790 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
791 	max_wait_time = hapd->dpp_resp_wait_time ?
792 		hapd->dpp_resp_wait_time : 2000;
793 	if (wait_time > max_wait_time)
794 		wait_time = max_wait_time;
795 	wait_time += 10; /* give the driver some extra time to complete */
796 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
797 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
798 	wait_time -= 10;
799 	if (auth->neg_freq > 0 && freq != auth->neg_freq) {
800 		wpa_printf(MSG_DEBUG,
801 			   "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
802 			   freq, auth->neg_freq);
803 	}
804 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
805 		" freq=%u type=%d",
806 		MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
807 	auth->auth_req_ack = 0;
808 	os_get_reltime(&hapd->dpp_last_init);
809 	return hostapd_drv_send_action(hapd, freq, wait_time,
810 				       dst,
811 				       wpabuf_head(hapd->dpp_auth->req_msg),
812 				       wpabuf_len(hapd->dpp_auth->req_msg));
813 }
814 
815 
816 #ifdef CONFIG_DPP2
hostapd_dpp_process_conf_obj(void * ctx,struct dpp_authentication * auth)817 static int hostapd_dpp_process_conf_obj(void *ctx,
818 				     struct dpp_authentication *auth)
819 {
820 	struct hostapd_data *hapd = ctx;
821 	unsigned int i;
822 
823 	for (i = 0; i < auth->num_conf_obj; i++)
824 		hostapd_dpp_handle_config_obj(hapd, auth,
825 					      &auth->conf_obj[i]);
826 
827 	return 0;
828 }
829 #endif /* CONFIG_DPP2 */
830 
831 
hostapd_dpp_auth_init(struct hostapd_data * hapd,const char * cmd)832 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
833 {
834 	const char *pos;
835 	struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
836 	struct dpp_authentication *auth;
837 	u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
838 	unsigned int neg_freq = 0;
839 	int tcp = 0;
840 #ifdef CONFIG_DPP2
841 	int tcp_port = DPP_TCP_PORT;
842 	struct hostapd_ip_addr ipaddr;
843 	char *addr;
844 #endif /* CONFIG_DPP2 */
845 
846 	pos = os_strstr(cmd, " peer=");
847 	if (!pos)
848 		return -1;
849 	pos += 6;
850 	peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
851 	if (!peer_bi) {
852 		wpa_printf(MSG_INFO,
853 			   "DPP: Could not find bootstrapping info for the identified peer");
854 		return -1;
855 	}
856 
857 #ifdef CONFIG_DPP2
858 	pos = os_strstr(cmd, " tcp_port=");
859 	if (pos) {
860 		pos += 10;
861 		tcp_port = atoi(pos);
862 	}
863 
864 	addr = get_param(cmd, " tcp_addr=");
865 	if (addr && os_strcmp(addr, "from-uri") == 0) {
866 		os_free(addr);
867 		if (!peer_bi->host) {
868 			wpa_printf(MSG_INFO,
869 				   "DPP: TCP address not available in peer URI");
870 			return -1;
871 		}
872 		tcp = 1;
873 		os_memcpy(&ipaddr, peer_bi->host, sizeof(ipaddr));
874 		tcp_port = peer_bi->port;
875 	} else if (addr) {
876 		int res;
877 
878 		res = hostapd_parse_ip_addr(addr, &ipaddr);
879 		os_free(addr);
880 		if (res)
881 			return -1;
882 		tcp = 1;
883 	}
884 #endif /* CONFIG_DPP2 */
885 
886 	pos = os_strstr(cmd, " own=");
887 	if (pos) {
888 		pos += 5;
889 		own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
890 					      atoi(pos));
891 		if (!own_bi) {
892 			wpa_printf(MSG_INFO,
893 				   "DPP: Could not find bootstrapping info for the identified local entry");
894 			return -1;
895 		}
896 
897 		if (peer_bi->curve != own_bi->curve) {
898 			wpa_printf(MSG_INFO,
899 				   "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
900 				   peer_bi->curve->name, own_bi->curve->name);
901 			return -1;
902 		}
903 	}
904 
905 	pos = os_strstr(cmd, " role=");
906 	if (pos) {
907 		pos += 6;
908 		if (os_strncmp(pos, "configurator", 12) == 0)
909 			allowed_roles = DPP_CAPAB_CONFIGURATOR;
910 		else if (os_strncmp(pos, "enrollee", 8) == 0)
911 			allowed_roles = DPP_CAPAB_ENROLLEE;
912 		else if (os_strncmp(pos, "either", 6) == 0)
913 			allowed_roles = DPP_CAPAB_CONFIGURATOR |
914 				DPP_CAPAB_ENROLLEE;
915 		else
916 			goto fail;
917 	}
918 
919 	pos = os_strstr(cmd, " neg_freq=");
920 	if (pos)
921 		neg_freq = atoi(pos + 10);
922 
923 	if (!tcp && hapd->dpp_auth) {
924 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
925 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
926 				     hapd, NULL);
927 		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
928 				     hapd, NULL);
929 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
930 				     NULL);
931 #ifdef CONFIG_DPP2
932 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
933 				     hapd, NULL);
934 #endif /* CONFIG_DPP2 */
935 		hostapd_drv_send_action_cancel_wait(hapd);
936 		dpp_auth_deinit(hapd->dpp_auth);
937 	}
938 
939 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
940 			     peer_bi, own_bi, allowed_roles, neg_freq,
941 			     hapd->iface->hw_features,
942 			     hapd->iface->num_hw_features);
943 	if (!auth)
944 		goto fail;
945 	hostapd_dpp_set_testing_options(hapd, auth);
946 	if (dpp_set_configurator(auth, cmd) < 0) {
947 		dpp_auth_deinit(auth);
948 		goto fail;
949 	}
950 
951 	auth->neg_freq = neg_freq;
952 
953 	if (!is_zero_ether_addr(peer_bi->mac_addr))
954 		os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
955 
956 #ifdef CONFIG_DPP2
957 	if (tcp)
958 		return dpp_tcp_init(hapd->iface->interfaces->dpp, auth,
959 				    &ipaddr, tcp_port, hapd->conf->dpp_name,
960 				    DPP_NETROLE_AP, hapd->conf->dpp_mud_url,
961 				    hapd->conf->dpp_extra_conf_req_name,
962 				    hapd->conf->dpp_extra_conf_req_value,
963 				    hapd->msg_ctx, hapd,
964 				    hostapd_dpp_process_conf_obj, NULL);
965 #endif /* CONFIG_DPP2 */
966 
967 	hapd->dpp_auth = auth;
968 	return hostapd_dpp_auth_init_next(hapd);
969 fail:
970 	return -1;
971 }
972 
973 
hostapd_dpp_listen(struct hostapd_data * hapd,const char * cmd)974 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
975 {
976 	int freq;
977 
978 	freq = atoi(cmd);
979 	if (freq <= 0)
980 		return -1;
981 
982 	if (os_strstr(cmd, " role=configurator"))
983 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
984 	else if (os_strstr(cmd, " role=enrollee"))
985 		hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
986 	else
987 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
988 			DPP_CAPAB_ENROLLEE;
989 	hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
990 
991 	if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
992 		/* TODO: Listen operation on non-operating channel */
993 		wpa_printf(MSG_INFO,
994 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
995 			   freq, hapd->iface->freq);
996 		return -1;
997 	}
998 
999 	hostapd_drv_dpp_listen(hapd, true);
1000 	return 0;
1001 }
1002 
1003 
hostapd_dpp_listen_stop(struct hostapd_data * hapd)1004 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
1005 {
1006 	hostapd_drv_dpp_listen(hapd, false);
1007 	/* TODO: Stop listen operation on non-operating channel */
1008 }
1009 
1010 
1011 #ifdef CONFIG_DPP2
1012 static void
hostapd_dpp_relay_needs_controller(struct hostapd_data * hapd,const u8 * src,enum dpp_public_action_frame_type type)1013 hostapd_dpp_relay_needs_controller(struct hostapd_data *hapd, const u8 *src,
1014 				   enum dpp_public_action_frame_type type)
1015 {
1016 	struct os_reltime now;
1017 
1018 	if (!hapd->conf->dpp_relay_port)
1019 		return;
1020 
1021 	os_get_reltime(&now);
1022 	if (hapd->dpp_relay_last_needs_ctrl.sec &&
1023 	    !os_reltime_expired(&now, &hapd->dpp_relay_last_needs_ctrl, 60))
1024 		return;
1025 	hapd->dpp_relay_last_needs_ctrl = now;
1026 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RELAY_NEEDS_CONTROLLER
1027 		MACSTR " %u", MAC2STR(src), type);
1028 }
1029 #endif /* CONFIG_DPP2 */
1030 
1031 
hostapd_dpp_rx_auth_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1032 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
1033 				    const u8 *hdr, const u8 *buf, size_t len,
1034 				    unsigned int freq)
1035 {
1036 	const u8 *r_bootstrap, *i_bootstrap;
1037 	u16 r_bootstrap_len, i_bootstrap_len;
1038 	struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
1039 
1040 	if (!hapd->iface->interfaces->dpp)
1041 		return;
1042 
1043 	wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR_SEC,
1044 		   MAC2STR_SEC(src));
1045 
1046 #ifdef CONFIG_DPP2
1047 	hostapd_dpp_chirp_stop(hapd);
1048 #endif /* CONFIG_DPP2 */
1049 
1050 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1051 				   &r_bootstrap_len);
1052 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1053 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1054 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
1055 		return;
1056 	}
1057 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1058 		    r_bootstrap, r_bootstrap_len);
1059 
1060 	i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1061 				   &i_bootstrap_len);
1062 	if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
1063 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1064 			"Missing or invalid required Initiator Bootstrapping Key Hash attribute");
1065 		return;
1066 	}
1067 	wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
1068 		    i_bootstrap, i_bootstrap_len);
1069 
1070 	/* Try to find own and peer bootstrapping key matches based on the
1071 	 * received hash values */
1072 	dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
1073 				r_bootstrap, &own_bi, &peer_bi);
1074 #ifdef CONFIG_DPP2
1075 	if (!own_bi) {
1076 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1077 					src, hdr, buf, len, freq, i_bootstrap,
1078 					r_bootstrap, hapd) == 0)
1079 			return;
1080 		hostapd_dpp_relay_needs_controller(hapd, src,
1081 						   DPP_PA_AUTHENTICATION_REQ);
1082 	}
1083 #endif /* CONFIG_DPP2 */
1084 	if (!own_bi) {
1085 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1086 			"No matching own bootstrapping key found - ignore message");
1087 		return;
1088 	}
1089 
1090 	if (own_bi->type == DPP_BOOTSTRAP_PKEX) {
1091 		if (!peer_bi || peer_bi->type != DPP_BOOTSTRAP_PKEX) {
1092 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1093 				"No matching peer bootstrapping key found for PKEX - ignore message");
1094 			return;
1095 		}
1096 
1097 		if (os_memcmp(peer_bi->pubkey_hash, own_bi->peer_pubkey_hash,
1098 			      SHA256_MAC_LEN) != 0) {
1099 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1100 				"Mismatching peer PKEX bootstrapping key - ignore message");
1101 			return;
1102 		}
1103 	}
1104 
1105 	if (hapd->dpp_auth) {
1106 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1107 			"Already in DPP authentication exchange - ignore new one");
1108 		return;
1109 	}
1110 
1111 	hapd->dpp_auth_ok_on_ack = 0;
1112 	hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
1113 					 hapd->msg_ctx, hapd->dpp_allowed_roles,
1114 					 hapd->dpp_qr_mutual,
1115 					 peer_bi, own_bi, freq, hdr, buf, len);
1116 	if (!hapd->dpp_auth) {
1117 		wpa_printf(MSG_DEBUG, "DPP: No response generated");
1118 		return;
1119 	}
1120 	hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
1121 	if (dpp_set_configurator(hapd->dpp_auth,
1122 				 hapd->dpp_configurator_params) < 0) {
1123 		dpp_auth_deinit(hapd->dpp_auth);
1124 		hapd->dpp_auth = NULL;
1125 		return;
1126 	}
1127 	os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
1128 
1129 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1130 		" freq=%u type=%d",
1131 		MAC2STR(src), hapd->dpp_auth->curr_freq,
1132 		DPP_PA_AUTHENTICATION_RESP);
1133 	hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
1134 				src, wpabuf_head(hapd->dpp_auth->resp_msg),
1135 				wpabuf_len(hapd->dpp_auth->resp_msg));
1136 }
1137 
1138 
hostapd_dpp_handle_config_obj(struct hostapd_data * hapd,struct dpp_authentication * auth,struct dpp_config_obj * conf)1139 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
1140 					  struct dpp_authentication *auth,
1141 					  struct dpp_config_obj *conf)
1142 {
1143 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
1144 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
1145 		dpp_akm_str(conf->akm));
1146 	if (conf->ssid_len)
1147 		wpa_msg_only_for_cb(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
1148 			wpa_ssid_txt(conf->ssid, conf->ssid_len));
1149 		wpa_printf(MSG_INFO, "%s", DPP_EVENT_CONFOBJ_SSID "%s",
1150 			anonymize_ssid(wpa_ssid_txt(conf->ssid, conf->ssid_len)));
1151 	if (conf->connector) {
1152 		/* TODO: Save the Connector and consider using a command
1153 		 * to fetch the value instead of sending an event with
1154 		 * it. The Connector could end up being larger than what
1155 		 * most clients are ready to receive as an event
1156 		 * message. */
1157 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
1158 			conf->connector);
1159 	}
1160 	if (conf->passphrase[0]) {
1161 		char hex[64 * 2 + 1];
1162 
1163 		wpa_snprintf_hex(hex, sizeof(hex),
1164 				 (const u8 *) conf->passphrase,
1165 				 os_strlen(conf->passphrase));
1166 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
1167 			hex);
1168 	} else if (conf->psk_set) {
1169 		char hex[PMK_LEN * 2 + 1];
1170 
1171 		wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
1172 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
1173 			hex);
1174 	}
1175 	if (conf->c_sign_key) {
1176 		char *hex;
1177 		size_t hexlen;
1178 
1179 		hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
1180 		hex = os_malloc(hexlen);
1181 		if (hex) {
1182 			wpa_snprintf_hex(hex, hexlen,
1183 					 wpabuf_head(conf->c_sign_key),
1184 					 wpabuf_len(conf->c_sign_key));
1185 			wpa_msg(hapd->msg_ctx, MSG_INFO,
1186 				DPP_EVENT_C_SIGN_KEY "%s", hex);
1187 			os_free(hex);
1188 		}
1189 	}
1190 	if (auth->net_access_key) {
1191 		char *hex;
1192 		size_t hexlen;
1193 
1194 		hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
1195 		hex = os_malloc(hexlen);
1196 		if (hex) {
1197 			wpa_snprintf_hex(hex, hexlen,
1198 					 wpabuf_head(auth->net_access_key),
1199 					 wpabuf_len(auth->net_access_key));
1200 			if (auth->net_access_key_expiry)
1201 				wpa_msg(hapd->msg_ctx, MSG_INFO,
1202 					DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
1203 					(unsigned long)
1204 					auth->net_access_key_expiry);
1205 			else
1206 				wpa_msg(hapd->msg_ctx, MSG_INFO,
1207 					DPP_EVENT_NET_ACCESS_KEY "%s", hex);
1208 			os_free(hex);
1209 		}
1210 	}
1211 }
1212 
1213 
hostapd_dpp_handle_key_pkg(struct hostapd_data * hapd,struct dpp_asymmetric_key * key)1214 static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
1215 				      struct dpp_asymmetric_key *key)
1216 {
1217 #ifdef CONFIG_DPP2
1218 	int res;
1219 
1220 	if (!key)
1221 		return 0;
1222 
1223 	wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
1224 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
1225 
1226 	while (key) {
1227 		res = dpp_configurator_from_backup(
1228 			hapd->iface->interfaces->dpp, key);
1229 		if (res < 0)
1230 			return -1;
1231 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
1232 			res);
1233 		key = key->next;
1234 	}
1235 #endif /* CONFIG_DPP2 */
1236 
1237 	return 0;
1238 }
1239 
1240 
1241 #ifdef CONFIG_DPP3
hostapd_dpp_build_new_key(void * eloop_ctx,void * timeout_ctx)1242 static void hostapd_dpp_build_new_key(void *eloop_ctx, void *timeout_ctx)
1243 {
1244 	struct hostapd_data *hapd = eloop_ctx;
1245 	struct dpp_authentication *auth = hapd->dpp_auth;
1246 
1247 	if (!auth || !auth->waiting_new_key)
1248 		return;
1249 
1250 	wpa_printf(MSG_DEBUG, "DPP: Build config request with a new key");
1251 	hostapd_dpp_start_gas_client(hapd);
1252 }
1253 #endif /* CONFIG_DPP3 */
1254 
1255 
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)1256 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
1257 				    enum gas_query_ap_result result,
1258 				    const struct wpabuf *adv_proto,
1259 				    const struct wpabuf *resp, u16 status_code)
1260 {
1261 	struct hostapd_data *hapd = ctx;
1262 	const u8 *pos;
1263 	struct dpp_authentication *auth = hapd->dpp_auth;
1264 	enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
1265 	int res;
1266 
1267 	if (!auth || !auth->auth_success) {
1268 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1269 		return;
1270 	}
1271 	if (result != GAS_QUERY_AP_SUCCESS ||
1272 	    !resp || status_code != WLAN_STATUS_SUCCESS) {
1273 		wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
1274 		goto fail;
1275 	}
1276 
1277 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
1278 			adv_proto);
1279 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
1280 			resp);
1281 
1282 	if (wpabuf_len(adv_proto) != 10 ||
1283 	    !(pos = wpabuf_head(adv_proto)) ||
1284 	    pos[0] != WLAN_EID_ADV_PROTO ||
1285 	    pos[1] != 8 ||
1286 	    pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
1287 	    pos[4] != 5 ||
1288 	    WPA_GET_BE24(&pos[5]) != OUI_WFA ||
1289 	    pos[8] != 0x1a ||
1290 	    pos[9] != 1) {
1291 		wpa_printf(MSG_DEBUG,
1292 			   "DPP: Not a DPP Advertisement Protocol ID");
1293 		goto fail;
1294 	}
1295 
1296 	res = dpp_conf_resp_rx(auth, resp);
1297 #ifdef CONFIG_DPP3
1298 	if (res == -3) {
1299 		wpa_printf(MSG_DEBUG, "DPP: New protocol key needed");
1300 		eloop_register_timeout(0, 0, hostapd_dpp_build_new_key, hapd,
1301 				       NULL);
1302 		return;
1303 	}
1304 #endif /* CONFIG_DPP3 */
1305 	if (res < 0) {
1306 		wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
1307 		goto fail;
1308 	}
1309 
1310 	hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
1311 	if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
1312 		goto fail;
1313 
1314 	status = DPP_STATUS_OK;
1315 #ifdef CONFIG_TESTING_OPTIONS
1316 	if (dpp_test == DPP_TEST_REJECT_CONFIG) {
1317 		wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
1318 		status = DPP_STATUS_CONFIG_REJECTED;
1319 	}
1320 #endif /* CONFIG_TESTING_OPTIONS */
1321 fail:
1322 	if (status != DPP_STATUS_OK)
1323 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1324 #ifdef CONFIG_DPP2
1325 	if (auth->peer_version >= 2 &&
1326 	    auth->conf_resp_status == DPP_STATUS_OK) {
1327 		struct wpabuf *msg;
1328 
1329 		wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
1330 		msg = dpp_build_conf_result(auth, status);
1331 		if (!msg)
1332 			goto fail2;
1333 
1334 		wpa_msg(hapd->msg_ctx, MSG_INFO,
1335 			DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
1336 			MAC2STR(addr), auth->curr_freq,
1337 			DPP_PA_CONFIGURATION_RESULT);
1338 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
1339 					addr, wpabuf_head(msg),
1340 					wpabuf_len(msg));
1341 		wpabuf_free(msg);
1342 
1343 		/* This exchange will be terminated in the TX status handler */
1344 		auth->connect_on_tx_status = 1;
1345 		return;
1346 	}
1347 fail2:
1348 #endif /* CONFIG_DPP2 */
1349 	dpp_auth_deinit(hapd->dpp_auth);
1350 	hapd->dpp_auth = NULL;
1351 }
1352 
1353 
hostapd_dpp_start_gas_client(struct hostapd_data * hapd)1354 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
1355 {
1356 	struct dpp_authentication *auth = hapd->dpp_auth;
1357 	struct wpabuf *buf;
1358 	int res;
1359 
1360 	buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
1361 					DPP_NETROLE_AP,
1362 					hapd->conf->dpp_mud_url, NULL,
1363 					hapd->conf->dpp_extra_conf_req_name,
1364 					hapd->conf->dpp_extra_conf_req_value);
1365 	if (!buf) {
1366 		wpa_printf(MSG_DEBUG,
1367 			   "DPP: No configuration request data available");
1368 		return;
1369 	}
1370 
1371 	wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR_SEC " (freq %u MHz)",
1372 		   MAC2STR_SEC(auth->peer_mac_addr), auth->curr_freq);
1373 
1374 	res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
1375 			       buf, hostapd_dpp_gas_resp_cb, hapd);
1376 	if (res < 0) {
1377 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
1378 			"GAS: Failed to send Query Request");
1379 		wpabuf_free(buf);
1380 	} else {
1381 		wpa_printf(MSG_DEBUG,
1382 			   "DPP: GAS query started with dialog token %u", res);
1383 	}
1384 }
1385 
1386 
hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)1387 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
1388 {
1389 	wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
1390 	dpp_notify_auth_success(hapd->dpp_auth, initiator);
1391 #ifdef CONFIG_TESTING_OPTIONS
1392 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1393 		wpa_printf(MSG_INFO,
1394 			   "DPP: TESTING - stop at Authentication Confirm");
1395 		if (hapd->dpp_auth->configurator) {
1396 			/* Prevent GAS response */
1397 			hapd->dpp_auth->auth_success = 0;
1398 		}
1399 		return;
1400 	}
1401 #endif /* CONFIG_TESTING_OPTIONS */
1402 
1403 	if (!hapd->dpp_auth->configurator)
1404 		hostapd_dpp_start_gas_client(hapd);
1405 }
1406 
1407 
hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1408 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
1409 				     const u8 *hdr, const u8 *buf, size_t len,
1410 				     unsigned int freq)
1411 {
1412 	struct dpp_authentication *auth = hapd->dpp_auth;
1413 	struct wpabuf *msg;
1414 
1415 	wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR_SEC,
1416 		   MAC2STR_SEC(src));
1417 
1418 	if (!auth) {
1419 		wpa_printf(MSG_DEBUG,
1420 			   "DPP: No DPP Authentication in progress - drop");
1421 		return;
1422 	}
1423 
1424 	if (!is_zero_ether_addr(auth->peer_mac_addr) &&
1425 	    !ether_addr_equal(src, auth->peer_mac_addr)) {
1426 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1427 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1428 		return;
1429 	}
1430 
1431 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1432 
1433 	if (auth->curr_freq != freq && auth->neg_freq == freq) {
1434 		wpa_printf(MSG_DEBUG,
1435 			   "DPP: Responder accepted request for different negotiation channel");
1436 		auth->curr_freq = freq;
1437 	}
1438 
1439 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1440 	msg = dpp_auth_resp_rx(auth, hdr, buf, len);
1441 	if (!msg) {
1442 		if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
1443 			wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
1444 			return;
1445 		}
1446 		wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
1447 		return;
1448 	}
1449 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1450 
1451 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1452 		" freq=%u type=%d", MAC2STR(src), auth->curr_freq,
1453 		DPP_PA_AUTHENTICATION_CONF);
1454 	hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
1455 				wpabuf_head(msg), wpabuf_len(msg));
1456 	wpabuf_free(msg);
1457 	hapd->dpp_auth_ok_on_ack = 1;
1458 }
1459 
1460 
hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1461 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
1462 				     const u8 *hdr, const u8 *buf, size_t len)
1463 {
1464 	struct dpp_authentication *auth = hapd->dpp_auth;
1465 
1466 	wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR_SEC,
1467 		   MAC2STR_SEC(src));
1468 
1469 	if (!auth) {
1470 		wpa_printf(MSG_DEBUG,
1471 			   "DPP: No DPP Authentication in progress - drop");
1472 		return;
1473 	}
1474 
1475 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1476 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1477 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1478 		return;
1479 	}
1480 
1481 	if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1482 		wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1483 		return;
1484 	}
1485 
1486 	hostapd_dpp_auth_success(hapd, 0);
1487 }
1488 
1489 
1490 #ifdef CONFIG_DPP2
1491 
hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1492 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1493 						   void *timeout_ctx)
1494 {
1495 	struct hostapd_data *hapd = eloop_ctx;
1496 	struct dpp_authentication *auth = hapd->dpp_auth;
1497 
1498 	if (!auth || !auth->waiting_conf_result)
1499 		return;
1500 
1501 	wpa_printf(MSG_DEBUG,
1502 		   "DPP: Timeout while waiting for Configuration Result");
1503 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1504 	dpp_auth_deinit(auth);
1505 	hapd->dpp_auth = NULL;
1506 }
1507 
1508 
hostapd_dpp_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1509 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1510 							void *timeout_ctx)
1511 {
1512 	struct hostapd_data *hapd = eloop_ctx;
1513 	struct dpp_authentication *auth = hapd->dpp_auth;
1514 
1515 	if (!auth || !auth->waiting_conf_result)
1516 		return;
1517 
1518 	wpa_printf(MSG_DEBUG,
1519 		   "DPP: Timeout while waiting for Connection Status Result");
1520 	wpa_msg(hapd->msg_ctx, MSG_INFO,
1521 		DPP_EVENT_CONN_STATUS_RESULT "timeout");
1522 	dpp_auth_deinit(auth);
1523 	hapd->dpp_auth = NULL;
1524 }
1525 
1526 
1527 #ifdef CONFIG_DPP3
1528 
hostapd_dpp_pb_active(struct hostapd_data * hapd)1529 static bool hostapd_dpp_pb_active(struct hostapd_data *hapd)
1530 {
1531 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1532 
1533 	return ifaces && (ifaces->dpp_pb_time.sec ||
1534 			  ifaces->dpp_pb_time.usec);
1535 }
1536 
1537 
hostapd_dpp_remove_pb_hash(struct hostapd_data * hapd)1538 static void hostapd_dpp_remove_pb_hash(struct hostapd_data *hapd)
1539 {
1540 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1541 	int i;
1542 
1543 	if (!ifaces->dpp_pb_bi)
1544 		return;
1545 	for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
1546 		struct dpp_pb_info *info = &ifaces->dpp_pb[i];
1547 
1548 		if (info->rx_time.sec == 0 && info->rx_time.usec == 0)
1549 			continue;
1550 		if (os_memcmp(info->hash, ifaces->dpp_pb_resp_hash,
1551 			      SHA256_MAC_LEN) == 0) {
1552 			/* Allow a new push button session to be established
1553 			 * immediately without the successfully completed
1554 			 * session triggering session overlap. */
1555 			info->rx_time.sec = 0;
1556 			info->rx_time.usec = 0;
1557 			wpa_printf(MSG_DEBUG,
1558 				   "DPP: Removed PB hash from session overlap detection due to successfully completed provisioning");
1559 		}
1560 	}
1561 }
1562 
1563 #endif /* CONFIG_DPP3 */
1564 
1565 
hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1566 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1567 				       const u8 *hdr, const u8 *buf, size_t len)
1568 {
1569 	struct dpp_authentication *auth = hapd->dpp_auth;
1570 	enum dpp_status_error status;
1571 #ifdef CONFIG_DPP3
1572 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1573 #endif /* CONFIG_DPP3 */
1574 
1575 	wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR_SEC,
1576 		   MAC2STR_SEC(src));
1577 
1578 	if (!auth || !auth->waiting_conf_result) {
1579 		wpa_printf(MSG_DEBUG,
1580 			   "DPP: No DPP Configuration waiting for result - drop");
1581 		return;
1582 	}
1583 
1584 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1585 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1586 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1587 		return;
1588 	}
1589 
1590 	status = dpp_conf_result_rx(auth, hdr, buf, len);
1591 
1592 	if (status == DPP_STATUS_OK && auth->send_conn_status) {
1593 		wpa_msg(hapd->msg_ctx, MSG_INFO,
1594 			DPP_EVENT_CONF_SENT "wait_conn_status=1 conf_status=%d",
1595 			auth->conf_resp_status);
1596 		wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1597 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1598 				     hapd, NULL);
1599 		auth->waiting_conn_status_result = 1;
1600 		eloop_cancel_timeout(
1601 			hostapd_dpp_conn_status_result_wait_timeout,
1602 			hapd, NULL);
1603 		eloop_register_timeout(
1604 			16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1605 			hapd, NULL);
1606 		return;
1607 	}
1608 	hostapd_drv_send_action_cancel_wait(hapd);
1609 	hostapd_dpp_listen_stop(hapd);
1610 	if (status == DPP_STATUS_OK)
1611 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
1612 			"conf_status=%d", auth->conf_resp_status);
1613 	else
1614 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1615 	dpp_auth_deinit(auth);
1616 	hapd->dpp_auth = NULL;
1617 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1618 			     NULL);
1619 #ifdef CONFIG_DPP3
1620 	if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
1621 		if (status == DPP_STATUS_OK)
1622 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1623 				"success");
1624 		else
1625 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1626 				"no-configuration-available");
1627 		ifaces->dpp_pb_result_indicated = true;
1628 		if (status == DPP_STATUS_OK)
1629 			hostapd_dpp_remove_pb_hash(hapd);
1630 		hostapd_dpp_push_button_stop(hapd);
1631 	}
1632 #endif /* CONFIG_DPP3 */
1633 }
1634 
1635 
hostapd_dpp_rx_conn_status_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1636 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1637 					      const u8 *src, const u8 *hdr,
1638 					      const u8 *buf, size_t len)
1639 {
1640 	struct dpp_authentication *auth = hapd->dpp_auth;
1641 	enum dpp_status_error status;
1642 	u8 ssid[SSID_MAX_LEN];
1643 	size_t ssid_len = 0;
1644 	char *channel_list = NULL;
1645 
1646 	wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1647 
1648 	if (!auth || !auth->waiting_conn_status_result) {
1649 		wpa_printf(MSG_DEBUG,
1650 			   "DPP: No DPP Configuration waiting for connection status result - drop");
1651 		return;
1652 	}
1653 
1654 	status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1655 					   ssid, &ssid_len, &channel_list);
1656 	wpa_msg_only_for_cb(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1657 		"result=%d ssid=%s channel_list=%s",
1658 		status, wpa_ssid_txt(ssid, ssid_len),
1659 		channel_list ? channel_list : "N/A");
1660 	wpa_printf(MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1661 		"result=%d ssid=%s channel_list=%s",
1662 		status, anonymize_ssid(wpa_ssid_txt(ssid, ssid_len)),
1663 		channel_list ? channel_list : "N/A");
1664 	os_free(channel_list);
1665 	hostapd_drv_send_action_cancel_wait(hapd);
1666 	hostapd_dpp_listen_stop(hapd);
1667 	dpp_auth_deinit(auth);
1668 	hapd->dpp_auth = NULL;
1669 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1670 			     hapd, NULL);
1671 }
1672 
1673 
1674 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)1675 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1676 				     const u8 *hdr, const u8 *buf, size_t len,
1677 				     unsigned int freq)
1678 {
1679 	const u8 *r_bootstrap;
1680 	u16 r_bootstrap_len;
1681 	struct dpp_bootstrap_info *peer_bi;
1682 	struct dpp_authentication *auth;
1683 
1684 	wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR_SEC,
1685 		   MAC2STR_SEC(src));
1686 
1687 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1688 				   &r_bootstrap_len);
1689 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1690 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1691 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
1692 		return;
1693 	}
1694 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1695 		    r_bootstrap, r_bootstrap_len);
1696 	peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1697 					   r_bootstrap);
1698 	dpp_notify_chirp_received(hapd->msg_ctx,
1699 				  peer_bi ? (int) peer_bi->id : -1,
1700 				  src, freq, r_bootstrap);
1701 	if (!peer_bi) {
1702 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1703 					src, hdr, buf, len, freq, NULL,
1704 					r_bootstrap, hapd) == 0)
1705 			return;
1706 		wpa_printf(MSG_DEBUG,
1707 			   "DPP: No matching bootstrapping information found");
1708 		hostapd_dpp_relay_needs_controller(
1709 			hapd, src, DPP_PA_PRESENCE_ANNOUNCEMENT);
1710 		return;
1711 	}
1712 
1713 	if (hapd->dpp_auth) {
1714 		wpa_printf(MSG_DEBUG,
1715 			   "DPP: Ignore Presence Announcement during ongoing Authentication");
1716 		return;
1717 	}
1718 
1719 	auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1720 			     peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1721 			     0);
1722 	if (!auth)
1723 		return;
1724 	hostapd_dpp_set_testing_options(hapd, auth);
1725 	if (dpp_set_configurator(auth,
1726 				 hapd->dpp_configurator_params) < 0) {
1727 		dpp_auth_deinit(auth);
1728 		return;
1729 	}
1730 
1731 	auth->neg_freq = freq;
1732 
1733 	/* The source address of the Presence Announcement frame overrides any
1734 	 * MAC address information from the bootstrapping information. */
1735 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1736 
1737 	hapd->dpp_auth = auth;
1738 	if (hostapd_dpp_auth_init_next(hapd) < 0) {
1739 		dpp_auth_deinit(hapd->dpp_auth);
1740 		hapd->dpp_auth = NULL;
1741 	}
1742 }
1743 
1744 
hostapd_dpp_reconfig_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)1745 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
1746 						    void *timeout_ctx)
1747 {
1748 	struct hostapd_data *hapd = eloop_ctx;
1749 	struct dpp_authentication *auth = hapd->dpp_auth;
1750 
1751 	if (!auth)
1752 		return;
1753 
1754 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
1755 	hostapd_dpp_listen_stop(hapd);
1756 	dpp_auth_deinit(auth);
1757 	hapd->dpp_auth = NULL;
1758 }
1759 
1760 
1761 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)1762 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
1763 				     const u8 *hdr, const u8 *buf, size_t len,
1764 				     unsigned int freq)
1765 {
1766 	const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1767 	u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1768 	struct dpp_configurator *conf;
1769 	struct dpp_authentication *auth;
1770 	unsigned int wait_time, max_wait_time;
1771 	u16 group;
1772 
1773 	if (hapd->dpp_auth) {
1774 		wpa_printf(MSG_DEBUG,
1775 			   "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1776 		return;
1777 	}
1778 
1779 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR_SEC,
1780 		   MAC2STR_SEC(src));
1781 
1782 	csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1783 				  &csign_hash_len);
1784 	if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1785 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1786 			"Missing or invalid required Configurator C-sign key Hash attribute");
1787 		return;
1788 	}
1789 	wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1790 		    csign_hash, csign_hash_len);
1791 	conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp,
1792 					 csign_hash);
1793 	if (!conf) {
1794 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1795 					src, hdr, buf, len, freq, NULL,
1796 					NULL, hapd) == 0)
1797 			return;
1798 		wpa_printf(MSG_DEBUG,
1799 			   "DPP: No matching Configurator information found");
1800 		hostapd_dpp_relay_needs_controller(
1801 			hapd, src, DPP_PA_RECONFIG_ANNOUNCEMENT);
1802 		return;
1803 	}
1804 
1805 	fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1806 			       &fcgroup_len);
1807 	if (!fcgroup || fcgroup_len != 2) {
1808 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1809 			"Missing or invalid required Finite Cyclic Group attribute");
1810 		return;
1811 	}
1812 	group = WPA_GET_LE16(fcgroup);
1813 	wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1814 
1815 	a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1816 	e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1817 
1818 	auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1819 				 conf, freq, group, a_nonce, a_nonce_len,
1820 				 e_id, e_id_len);
1821 	if (!auth)
1822 		return;
1823 	hostapd_dpp_set_testing_options(hapd, auth);
1824 	if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
1825 		dpp_auth_deinit(auth);
1826 		return;
1827 	}
1828 
1829 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1830 	hapd->dpp_auth = auth;
1831 
1832 	hapd->dpp_in_response_listen = 0;
1833 	hapd->dpp_auth_ok_on_ack = 0;
1834 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
1835 	max_wait_time = hapd->dpp_resp_wait_time ?
1836 		hapd->dpp_resp_wait_time : 2000;
1837 	if (wait_time > max_wait_time)
1838 		wait_time = max_wait_time;
1839 	wait_time += 10; /* give the driver some extra time to complete */
1840 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
1841 			       hostapd_dpp_reconfig_reply_wait_timeout,
1842 			       hapd, NULL);
1843 	wait_time -= 10;
1844 
1845 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1846 		" freq=%u type=%d",
1847 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
1848 	if (hostapd_drv_send_action(hapd, freq, wait_time, src,
1849 				    wpabuf_head(auth->reconfig_req_msg),
1850 				    wpabuf_len(auth->reconfig_req_msg)) < 0) {
1851 		dpp_auth_deinit(hapd->dpp_auth);
1852 		hapd->dpp_auth = NULL;
1853 	}
1854 }
1855 
1856 
1857 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)1858 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src,
1859 				  const u8 *hdr, const u8 *buf, size_t len,
1860 				  unsigned int freq)
1861 {
1862 	struct dpp_authentication *auth = hapd->dpp_auth;
1863 	struct wpabuf *conf;
1864 
1865 	wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
1866 		   MACSTR_SEC, MAC2STR_SEC(src));
1867 
1868 	if (!auth || !auth->reconfig || !auth->configurator) {
1869 		wpa_printf(MSG_DEBUG,
1870 			   "DPP: No DPP Reconfig Authentication in progress - drop");
1871 		return;
1872 	}
1873 
1874 	if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1875 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1876 			   MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1877 		return;
1878 	}
1879 
1880 	conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1881 	if (!conf)
1882 		return;
1883 
1884 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1885 			     hapd, NULL);
1886 
1887 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1888 		" freq=%u type=%d",
1889 		MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
1890 	if (hostapd_drv_send_action(hapd, freq, 500, src,
1891 				    wpabuf_head(conf), wpabuf_len(conf)) < 0) {
1892 		wpabuf_free(conf);
1893 		dpp_auth_deinit(hapd->dpp_auth);
1894 		hapd->dpp_auth = NULL;
1895 		return;
1896 	}
1897 	wpabuf_free(conf);
1898 }
1899 
1900 #endif /* CONFIG_DPP2 */
1901 
1902 
hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)1903 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1904 					    const u8 *src, unsigned int freq,
1905 					    u8 trans_id,
1906 					    enum dpp_status_error status)
1907 {
1908 	struct wpabuf *msg;
1909 	size_t len;
1910 
1911 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
1912 #ifdef CONFIG_DPP2
1913 	len += 5;
1914 #endif /* CONFIG_DPP2 */
1915 	msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len);
1916 	if (!msg)
1917 		return;
1918 
1919 #ifdef CONFIG_TESTING_OPTIONS
1920 	if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1921 		wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1922 		goto skip_trans_id;
1923 	}
1924 	if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1925 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1926 		trans_id ^= 0x01;
1927 	}
1928 #endif /* CONFIG_TESTING_OPTIONS */
1929 
1930 	/* Transaction ID */
1931 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1932 	wpabuf_put_le16(msg, 1);
1933 	wpabuf_put_u8(msg, trans_id);
1934 
1935 #ifdef CONFIG_TESTING_OPTIONS
1936 skip_trans_id:
1937 	if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1938 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1939 		goto skip_status;
1940 	}
1941 	if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1942 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1943 		status = 254;
1944 	}
1945 #endif /* CONFIG_TESTING_OPTIONS */
1946 
1947 	/* DPP Status */
1948 	wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1949 	wpabuf_put_le16(msg, 1);
1950 	wpabuf_put_u8(msg, status);
1951 
1952 #ifdef CONFIG_TESTING_OPTIONS
1953 skip_status:
1954 	if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1955 		wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1956 		goto skip_connector;
1957 	}
1958 	if (status == DPP_STATUS_OK &&
1959 	    dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1960 		char *connector;
1961 
1962 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1963 		connector = dpp_corrupt_connector_signature(
1964 			hapd->conf->dpp_connector);
1965 		if (!connector) {
1966 			wpabuf_free(msg);
1967 			return;
1968 		}
1969 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1970 		wpabuf_put_le16(msg, os_strlen(connector));
1971 		wpabuf_put_str(msg, connector);
1972 		os_free(connector);
1973 		goto skip_connector;
1974 	}
1975 #endif /* CONFIG_TESTING_OPTIONS */
1976 
1977 	/* DPP Connector */
1978 	if (status == DPP_STATUS_OK) {
1979 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1980 		wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1981 		wpabuf_put_str(msg, hapd->conf->dpp_connector);
1982 	}
1983 
1984 #ifdef CONFIG_TESTING_OPTIONS
1985 skip_connector:
1986 	if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) {
1987 		wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
1988 		goto skip_proto_ver;
1989 	}
1990 #endif /* CONFIG_TESTING_OPTIONS */
1991 
1992 #ifdef CONFIG_DPP2
1993 	if (DPP_VERSION > 1) {
1994 		u8 ver = DPP_VERSION;
1995 #ifdef CONFIG_DPP3
1996 		int conn_ver;
1997 
1998 		conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
1999 		if (conn_ver > 0 && ver != conn_ver) {
2000 			wpa_printf(MSG_DEBUG,
2001 				   "DPP: Use Connector version %d instead of current protocol version %d",
2002 				   conn_ver, ver);
2003 			ver = conn_ver;
2004 		}
2005 #endif /* CONFIG_DPP3 */
2006 
2007 #ifdef CONFIG_TESTING_OPTIONS
2008 	if (dpp_test == DPP_TEST_INVALID_PROTOCOL_VERSION_PEER_DISC_RESP) {
2009 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Protocol Version");
2010 		ver = 1;
2011 	}
2012 #endif /* CONFIG_TESTING_OPTIONS */
2013 
2014 		/* Protocol Version */
2015 		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2016 		wpabuf_put_le16(msg, 1);
2017 		wpabuf_put_u8(msg, ver);
2018 	}
2019 #endif /* CONFIG_DPP2 */
2020 
2021 #ifdef CONFIG_TESTING_OPTIONS
2022 skip_proto_ver:
2023 #endif /* CONFIG_TESTING_OPTIONS */
2024 
2025 	wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR_SEC
2026 		   " status=%d", MAC2STR_SEC(src), status);
2027 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2028 		" freq=%u type=%d status=%d", MAC2STR(src), freq,
2029 		DPP_PA_PEER_DISCOVERY_RESP, status);
2030 	hostapd_drv_send_action(hapd, freq, 0, src,
2031 				wpabuf_head(msg), wpabuf_len(msg));
2032 	wpabuf_free(msg);
2033 }
2034 
2035 
hapd_dpp_connector_available(struct hostapd_data * hapd)2036 static bool hapd_dpp_connector_available(struct hostapd_data *hapd)
2037 {
2038 	if (!hapd->wpa_auth ||
2039 	    !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
2040 	    !(hapd->conf->wpa & WPA_PROTO_RSN)) {
2041 		wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
2042 		return false;
2043 	}
2044 
2045 	if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
2046 	    !hapd->conf->dpp_csign) {
2047 		wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
2048 		return false;
2049 	}
2050 
2051 	return true;
2052 }
2053 
2054 
hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2055 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
2056 					 const u8 *src,
2057 					 const u8 *buf, size_t len,
2058 					 unsigned int freq)
2059 {
2060 	const u8 *connector, *trans_id;
2061 	u16 connector_len, trans_id_len;
2062 	struct os_time now;
2063 	struct dpp_introduction intro;
2064 	os_time_t expire;
2065 	int expiration;
2066 	enum dpp_status_error res;
2067 	u8 pkhash[SHA256_MAC_LEN];
2068 
2069 	os_memset(&intro, 0, sizeof(intro));
2070 
2071 	wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR_SEC,
2072 		   MAC2STR_SEC(src));
2073 	if (!hapd_dpp_connector_available(hapd))
2074 		return;
2075 
2076 	os_get_time(&now);
2077 
2078 	if (hapd->conf->dpp_netaccesskey_expiry &&
2079 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2080 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2081 		return;
2082 	}
2083 
2084 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2085 			       &trans_id_len);
2086 	if (!trans_id || trans_id_len != 1) {
2087 		wpa_printf(MSG_DEBUG,
2088 			   "DPP: Peer did not include Transaction ID");
2089 		return;
2090 	}
2091 
2092 	connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
2093 	if (!connector) {
2094 		wpa_printf(MSG_DEBUG,
2095 			   "DPP: Peer did not include its Connector");
2096 		return;
2097 	}
2098 
2099 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2100 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
2101 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
2102 			     wpabuf_head(hapd->conf->dpp_csign),
2103 			     wpabuf_len(hapd->conf->dpp_csign),
2104 			     connector, connector_len, &expire, pkhash);
2105 	if (res == 255) {
2106 		wpa_printf(MSG_INFO,
2107 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
2108 			   MACSTR_SEC ")", MAC2STR_SEC(src));
2109 		goto done;
2110 	}
2111 	if (res != DPP_STATUS_OK) {
2112 		wpa_printf(MSG_INFO,
2113 			   "DPP: Network Introduction protocol resulted in failure (peer "
2114 			   MACSTR_SEC " status %d)", MAC2STR_SEC(src), res);
2115 		hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2116 						res);
2117 		goto done;
2118 	}
2119 
2120 #ifdef CONFIG_DPP3
2121 	if (intro.peer_version && intro.peer_version >= 2) {
2122 		const u8 *version;
2123 		u16 version_len;
2124 		u8 attr_version = 1;
2125 
2126 		version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2127 				       &version_len);
2128 		if (version && version_len >= 1)
2129 			attr_version = version[0];
2130 		if (attr_version != intro.peer_version) {
2131 			wpa_printf(MSG_INFO,
2132 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2133 				   intro.peer_version, attr_version);
2134 			hostapd_dpp_send_peer_disc_resp(hapd, src, freq,
2135 							trans_id[0],
2136 							DPP_STATUS_NO_MATCH);
2137 			goto done;
2138 		}
2139 	}
2140 #endif /* CONFIG_DPP3 */
2141 
2142 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2143 		expire = hapd->conf->dpp_netaccesskey_expiry;
2144 	if (expire)
2145 		expiration = expire - now.sec;
2146 	else
2147 		expiration = 0;
2148 
2149 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2150 				intro.pmkid, expiration,
2151 				WPA_KEY_MGMT_DPP, pkhash) < 0) {
2152 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2153 		goto done;
2154 	}
2155 
2156 	hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2157 					DPP_STATUS_OK);
2158 done:
2159 	dpp_peer_intro_deinit(&intro);
2160 }
2161 
2162 
2163 static void
hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq,bool v2)2164 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
2165 				 const u8 *hdr, const u8 *buf, size_t len,
2166 				 unsigned int freq, bool v2)
2167 {
2168 	struct wpabuf *msg;
2169 
2170 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR_SEC,
2171 		   MAC2STR_SEC(src));
2172 
2173 	if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_1 && v2) {
2174 		wpa_printf(MSG_DEBUG,
2175 			   "DPP: Ignore PKEXv2 Exchange Request when configured to be PKEX v1 only");
2176 		return;
2177 	}
2178 	if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_2 && !v2) {
2179 		wpa_printf(MSG_DEBUG,
2180 			   "DPP: Ignore PKEXv1 Exchange Request when configured to be PKEX v2 only");
2181 		return;
2182 	}
2183 
2184 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
2185 	 * values here */
2186 
2187 	if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
2188 		wpa_printf(MSG_DEBUG,
2189 			   "DPP: No PKEX code configured - ignore request");
2190 		goto try_relay;
2191 	}
2192 
2193 #ifdef CONFIG_DPP2
2194 	if (dpp_controller_is_own_pkex_req(hapd->iface->interfaces->dpp,
2195 					   buf, len)) {
2196 		wpa_printf(MSG_DEBUG,
2197 			   "DPP: PKEX Exchange Request is from local Controller - ignore request");
2198 		return;
2199 	}
2200 #endif /* CONFIG_DPP2 */
2201 
2202 	if (hapd->dpp_pkex) {
2203 		/* TODO: Support parallel operations */
2204 		wpa_printf(MSG_DEBUG,
2205 			   "DPP: Already in PKEX session - ignore new request");
2206 		goto try_relay;
2207 	}
2208 
2209 	hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
2210 						  hapd->dpp_pkex_bi,
2211 						  hapd->own_addr, src,
2212 						  hapd->dpp_pkex_identifier,
2213 						  hapd->dpp_pkex_code,
2214 						  hapd->dpp_pkex_code_len,
2215 						  buf, len, v2);
2216 	if (!hapd->dpp_pkex) {
2217 		wpa_printf(MSG_DEBUG,
2218 			   "DPP: Failed to process the request - ignore it");
2219 		goto try_relay;
2220 	}
2221 
2222 	msg = hapd->dpp_pkex->exchange_resp;
2223 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2224 		" freq=%u type=%d", MAC2STR(src), freq,
2225 		DPP_PA_PKEX_EXCHANGE_RESP);
2226 	hostapd_drv_send_action(hapd, freq, 0, src,
2227 				wpabuf_head(msg), wpabuf_len(msg));
2228 	if (hapd->dpp_pkex->failed) {
2229 		wpa_printf(MSG_DEBUG,
2230 			   "DPP: Terminate PKEX exchange due to an earlier error");
2231 		if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2232 			hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
2233 		dpp_pkex_free(hapd->dpp_pkex);
2234 		hapd->dpp_pkex = NULL;
2235 	}
2236 
2237 	return;
2238 
2239 try_relay:
2240 #ifdef CONFIG_DPP2
2241 	if (v2 && dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2242 				      src, hdr, buf, len, freq, NULL, NULL,
2243 				      hapd) != 0) {
2244 		wpa_printf(MSG_DEBUG,
2245 			   "DPP: No Relay available for the message");
2246 		hostapd_dpp_relay_needs_controller(hapd, src,
2247 						   DPP_PA_PKEX_EXCHANGE_REQ);
2248 	}
2249 #else /* CONFIG_DPP2 */
2250 	wpa_printf(MSG_DEBUG, "DPP: No relay functionality included - skip");
2251 #endif /* CONFIG_DPP2 */
2252 }
2253 
2254 
2255 static void
hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2256 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
2257 				  const u8 *buf, size_t len, unsigned int freq)
2258 {
2259 	struct wpabuf *msg;
2260 
2261 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR_SEC,
2262 		   MAC2STR_SEC(src));
2263 
2264 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
2265 	 * values here */
2266 
2267 	if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
2268 	    hapd->dpp_pkex->exchange_done) {
2269 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2270 		return;
2271 	}
2272 
2273 	eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
2274 	hapd->dpp_pkex->exch_req_wait_time = 0;
2275 
2276 	msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
2277 	if (!msg) {
2278 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2279 		return;
2280 	}
2281 
2282 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR_SEC,
2283 		   MAC2STR_SEC(src));
2284 
2285 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2286 		" freq=%u type=%d", MAC2STR(src), freq,
2287 		DPP_PA_PKEX_COMMIT_REVEAL_REQ);
2288 	hostapd_drv_send_action(hapd, freq, 0, src,
2289 				wpabuf_head(msg), wpabuf_len(msg));
2290 	wpabuf_free(msg);
2291 }
2292 
2293 
2294 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)2295 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
2296 				      const u8 *hdr, const u8 *buf, size_t len,
2297 				      unsigned int freq)
2298 {
2299 	struct wpabuf *msg;
2300 	struct dpp_pkex *pkex = hapd->dpp_pkex;
2301 	struct dpp_bootstrap_info *bi;
2302 
2303 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR_SEC,
2304 		   MAC2STR_SEC(src));
2305 
2306 	if (!pkex || pkex->initiator || !pkex->exchange_done) {
2307 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2308 		return;
2309 	}
2310 
2311 	msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
2312 	if (!msg) {
2313 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
2314 		if (hapd->dpp_pkex->failed) {
2315 			wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
2316 			if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2317 				hapd->dpp_pkex->own_bi->pkex_t =
2318 					hapd->dpp_pkex->t;
2319 			dpp_pkex_free(hapd->dpp_pkex);
2320 			hapd->dpp_pkex = NULL;
2321 		}
2322 		return;
2323 	}
2324 
2325 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
2326 		   MACSTR_SEC, MAC2STR_SEC(src));
2327 
2328 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2329 		" freq=%u type=%d", MAC2STR(src), freq,
2330 		DPP_PA_PKEX_COMMIT_REVEAL_RESP);
2331 	hostapd_drv_send_action(hapd, freq, 0, src,
2332 				wpabuf_head(msg), wpabuf_len(msg));
2333 	wpabuf_free(msg);
2334 
2335 	hostapd_dpp_pkex_clear_code(hapd);
2336 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
2337 	if (!bi)
2338 		return;
2339 	hapd->dpp_pkex = NULL;
2340 }
2341 
2342 
2343 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)2344 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
2345 				       const u8 *hdr, const u8 *buf, size_t len,
2346 				       unsigned int freq)
2347 {
2348 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2349 	int res;
2350 	struct dpp_bootstrap_info *bi;
2351 	struct dpp_pkex *pkex = hapd->dpp_pkex;
2352 	char cmd[500];
2353 
2354 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR_SEC,
2355 		   MAC2STR_SEC(src));
2356 
2357 	if (!pkex || !pkex->initiator || !pkex->exchange_done) {
2358 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2359 		return;
2360 	}
2361 
2362 	res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
2363 	if (res < 0) {
2364 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2365 		return;
2366 	}
2367 
2368 	hostapd_dpp_pkex_clear_code(hapd);
2369 	bi = dpp_pkex_finish(ifaces->dpp, pkex, src, freq);
2370 	if (!bi)
2371 		return;
2372 	hapd->dpp_pkex = NULL;
2373 
2374 #ifdef CONFIG_DPP3
2375 	if (ifaces->dpp_pb_bi &&
2376 	    os_memcmp(bi->pubkey_hash_chirp, ifaces->dpp_pb_resp_hash,
2377 		      SHA256_MAC_LEN) != 0) {
2378 		char id[20];
2379 
2380 		wpa_printf(MSG_INFO,
2381 			   "DPP: Peer bootstrap key from PKEX does not match PB announcement hash");
2382 		wpa_hexdump(MSG_DEBUG,
2383 			    "DPP: Peer provided bootstrap key hash(chirp) from PB PKEX",
2384 			    bi->pubkey_hash_chirp, SHA256_MAC_LEN);
2385 		wpa_hexdump(MSG_DEBUG,
2386 			    "DPP: Peer provided bootstrap key hash(chirp) from PB announcement",
2387 			    ifaces->dpp_pb_resp_hash, SHA256_MAC_LEN);
2388 
2389 		os_snprintf(id, sizeof(id), "%u", bi->id);
2390 		dpp_bootstrap_remove(ifaces->dpp, id);
2391 		hostapd_dpp_push_button_stop(hapd);
2392 		return;
2393 	}
2394 #endif /* CONFIG_DPP3 */
2395 
2396 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
2397 		    bi->id,
2398 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
2399 	wpa_printf(MSG_DEBUG,
2400 		   "DPP: Start authentication after PKEX with parameters: %s",
2401 		   cmd);
2402 	if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
2403 		wpa_printf(MSG_DEBUG,
2404 			   "DPP: Authentication initialization failed");
2405 		return;
2406 	}
2407 }
2408 
2409 
2410 #ifdef CONFIG_DPP3
2411 
hostapd_dpp_pb_pkex_init(struct hostapd_data * hapd,unsigned int freq,const u8 * src,const u8 * r_hash)2412 static void hostapd_dpp_pb_pkex_init(struct hostapd_data *hapd,
2413 				     unsigned int freq, const u8 *src,
2414 				     const u8 *r_hash)
2415 {
2416 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2417 	struct dpp_pkex *pkex;
2418 	struct wpabuf *msg;
2419 	char ssid_hex[2 * SSID_MAX_LEN + 1], *pass_hex = NULL;
2420 	char cmd[300];
2421 	const char *password = NULL;
2422 #ifdef CONFIG_SAE
2423 	struct sae_password_entry *e;
2424 #endif /* CONFIG_SAE */
2425 	int conf_id = -1;
2426 	bool sae = false, psk = false;
2427 	size_t len;
2428 
2429 	if (hapd->dpp_pkex) {
2430 		wpa_printf(MSG_DEBUG,
2431 			   "PDP: Sending previously generated PKEX Exchange Request to "
2432 			   MACSTR, MAC2STR(src));
2433 		msg = hapd->dpp_pkex->exchange_req;
2434 		hostapd_drv_send_action(hapd, freq, 0, src,
2435 					wpabuf_head(msg), wpabuf_len(msg));
2436 		return;
2437 	}
2438 
2439 	wpa_printf(MSG_DEBUG, "DPP: Initiate PKEX for push button with "
2440 		   MACSTR, MAC2STR(src));
2441 
2442 	hapd->dpp_pkex_bi = ifaces->dpp_pb_bi;
2443 	os_memcpy(ifaces->dpp_pb_resp_hash, r_hash, SHA256_MAC_LEN);
2444 
2445 	pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
2446 			     "PBPKEX", (const char *) ifaces->dpp_pb_c_nonce,
2447 			     ifaces->dpp_pb_bi->curve->nonce_len,
2448 			     true);
2449 	if (!pkex) {
2450 		hostapd_dpp_push_button_stop(hapd);
2451 		return;
2452 	}
2453 	pkex->freq = freq;
2454 
2455 	hapd->dpp_pkex = pkex;
2456 	msg = hapd->dpp_pkex->exchange_req;
2457 
2458 	if (ifaces->dpp_pb_cmd) {
2459 		/* Use the externally provided configuration */
2460 		os_free(hapd->dpp_pkex_auth_cmd);
2461 		len = 30 + os_strlen(ifaces->dpp_pb_cmd);
2462 		hapd->dpp_pkex_auth_cmd = os_malloc(len);
2463 		if (!hapd->dpp_pkex_auth_cmd) {
2464 			hostapd_dpp_push_button_stop(hapd);
2465 			return;
2466 		}
2467 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2468 			    hapd->dpp_pkex_bi->id, ifaces->dpp_pb_cmd);
2469 		goto send_frame;
2470 	}
2471 
2472 	/* Build config based on the current AP configuration */
2473 	wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
2474 			 (const u8 *) hapd->conf->ssid.ssid,
2475 			 hapd->conf->ssid.ssid_len);
2476 
2477 	if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
2478 		/* TODO: If a local Configurator has been enabled, allow a
2479 		 * DPP AKM credential to be provisioned by setting conf_id. */
2480 	}
2481 
2482 	if (hapd->conf->wpa & WPA_PROTO_RSN) {
2483 		psk = hapd->conf->wpa_key_mgmt & (WPA_KEY_MGMT_PSK |
2484 						  WPA_KEY_MGMT_PSK_SHA256);
2485 #ifdef CONFIG_SAE
2486 		sae = hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE;
2487 #endif /* CONFIG_SAE */
2488 	}
2489 
2490 #ifdef CONFIG_SAE
2491 	for (e = hapd->conf->sae_passwords; sae && e && !password;
2492 	     e = e->next) {
2493 		if (e->identifier || !is_broadcast_ether_addr(e->peer_addr))
2494 			continue;
2495 		password = e->password;
2496 	}
2497 #endif /* CONFIG_SAE */
2498 	if (!password && hapd->conf->ssid.wpa_passphrase_set &&
2499 	    hapd->conf->ssid.wpa_passphrase)
2500 		password = hapd->conf->ssid.wpa_passphrase;
2501 	if (password) {
2502 		len = 2 * os_strlen(password) + 1;
2503 		pass_hex = os_malloc(len);
2504 		if (!pass_hex) {
2505 			hostapd_dpp_push_button_stop(hapd);
2506 			return;
2507 		}
2508 		wpa_snprintf_hex(pass_hex, len, (const u8 *) password,
2509 				 os_strlen(password));
2510 	}
2511 
2512 	if (conf_id > 0 && sae && psk && pass_hex) {
2513 		os_snprintf(cmd, sizeof(cmd),
2514 			    "conf=sta-dpp+psk+sae configurator=%d ssid=%s pass=%s",
2515 			    conf_id, ssid_hex, pass_hex);
2516 	} else if (conf_id > 0 && sae && pass_hex) {
2517 		os_snprintf(cmd, sizeof(cmd),
2518 			    "conf=sta-dpp+sae configurator=%d ssid=%s pass=%s",
2519 			    conf_id, ssid_hex, pass_hex);
2520 	} else if (conf_id > 0) {
2521 		os_snprintf(cmd, sizeof(cmd),
2522 			    "conf=sta-dpp configurator=%d ssid=%s",
2523 			    conf_id, ssid_hex);
2524 	} if (sae && psk && pass_hex) {
2525 		os_snprintf(cmd, sizeof(cmd),
2526 			    "conf=sta-psk+sae ssid=%s pass=%s",
2527 			    ssid_hex, pass_hex);
2528 	} else if (sae && pass_hex) {
2529 		os_snprintf(cmd, sizeof(cmd),
2530 			    "conf=sta-sae ssid=%s pass=%s",
2531 			    ssid_hex, pass_hex);
2532 	} else if (psk && pass_hex) {
2533 		os_snprintf(cmd, sizeof(cmd),
2534 			    "conf=sta-psk ssid=%s pass=%s",
2535 			    ssid_hex, pass_hex);
2536 	} else {
2537 		wpa_printf(MSG_INFO,
2538 			   "DPP: Unsupported AP configuration for push button");
2539 		str_clear_free(pass_hex);
2540 		hostapd_dpp_push_button_stop(hapd);
2541 		return;
2542 	}
2543 	str_clear_free(pass_hex);
2544 
2545 	os_free(hapd->dpp_pkex_auth_cmd);
2546 	len = 30 + os_strlen(cmd);
2547 	hapd->dpp_pkex_auth_cmd = os_malloc(len);
2548 	if (hapd->dpp_pkex_auth_cmd)
2549 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2550 			    hapd->dpp_pkex_bi->id, cmd);
2551 	forced_memzero(cmd, sizeof(cmd));
2552 	if (!hapd->dpp_pkex_auth_cmd) {
2553 		hostapd_dpp_push_button_stop(hapd);
2554 		return;
2555 	}
2556 
2557 send_frame:
2558 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2559 		" freq=%u type=%d", MAC2STR(src), freq,
2560 		DPP_PA_PKEX_EXCHANGE_REQ);
2561 	hostapd_drv_send_action(hapd, pkex->freq, 0, src,
2562 				wpabuf_head(msg), wpabuf_len(msg));
2563 	pkex->exch_req_wait_time = 2000;
2564 	pkex->exch_req_tries = 1;
2565 }
2566 
2567 
2568 static void
hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2569 hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data *hapd,
2570 					const u8 *src, const u8 *hdr,
2571 					const u8 *buf, size_t len,
2572 					unsigned int freq)
2573 {
2574 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2575 	const u8 *r_hash;
2576 	u16 r_hash_len;
2577 	unsigned int i;
2578 	bool found = false;
2579 	struct dpp_pb_info *info, *tmp;
2580 	struct os_reltime now, age;
2581 	struct wpabuf *msg;
2582 
2583 	if (!ifaces)
2584 		return;
2585 
2586 	os_get_reltime(&now);
2587 	wpa_printf(MSG_DEBUG, "DPP: Push Button Presence Announcement from "
2588 		   MACSTR, MAC2STR(src));
2589 
2590 	r_hash = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
2591 			      &r_hash_len);
2592 	if (!r_hash || r_hash_len != SHA256_MAC_LEN) {
2593 		wpa_printf(MSG_DEBUG,
2594 			   "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
2595 		return;
2596 	}
2597 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
2598 		    r_hash, r_hash_len);
2599 
2600 	for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2601 		info = &ifaces->dpp_pb[i];
2602 		if ((info->rx_time.sec == 0 && info->rx_time.usec == 0) ||
2603 		    os_memcmp(r_hash, info->hash, SHA256_MAC_LEN) != 0)
2604 			continue;
2605 		wpa_printf(MSG_DEBUG,
2606 			   "DPP: Active push button Enrollee already known");
2607 		found = true;
2608 		info->rx_time = now;
2609 	}
2610 
2611 	if (!found) {
2612 		for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2613 			tmp = &ifaces->dpp_pb[i];
2614 			if (tmp->rx_time.sec == 0 && tmp->rx_time.usec == 0)
2615 				continue;
2616 
2617 			if (os_reltime_expired(&now, &tmp->rx_time, 120)) {
2618 				wpa_hexdump(MSG_DEBUG,
2619 					    "DPP: Push button Enrollee hash expired",
2620 					    tmp->hash, SHA256_MAC_LEN);
2621 				tmp->rx_time.sec = 0;
2622 				tmp->rx_time.usec = 0;
2623 				continue;
2624 			}
2625 
2626 			wpa_hexdump(MSG_DEBUG,
2627 				    "DPP: Push button session overlap with hash",
2628 				    tmp->hash, SHA256_MAC_LEN);
2629 			if (!ifaces->dpp_pb_result_indicated &&
2630 			    hostapd_dpp_pb_active(hapd)) {
2631 				wpa_msg(hapd->msg_ctx, MSG_INFO,
2632 					DPP_EVENT_PB_RESULT "session-overlap");
2633 				ifaces->dpp_pb_result_indicated = true;
2634 			}
2635 			hostapd_dpp_push_button_stop(hapd);
2636 			return;
2637 		}
2638 
2639 		/* Replace the oldest entry */
2640 		info = &ifaces->dpp_pb[0];
2641 		for (i = 1; i < DPP_PB_INFO_COUNT; i++) {
2642 			tmp = &ifaces->dpp_pb[i];
2643 			if (os_reltime_before(&tmp->rx_time, &info->rx_time))
2644 				info = tmp;
2645 		}
2646 		wpa_printf(MSG_DEBUG, "DPP: New active push button Enrollee");
2647 		os_memcpy(info->hash, r_hash, SHA256_MAC_LEN);
2648 		info->rx_time = now;
2649 	}
2650 
2651 	if (!hostapd_dpp_pb_active(hapd)) {
2652 		wpa_printf(MSG_DEBUG,
2653 			   "DPP: Discard message since own push button has not been pressed");
2654 		return;
2655 	}
2656 
2657 	if (ifaces->dpp_pb_announce_time.sec == 0 &&
2658 	    ifaces->dpp_pb_announce_time.usec == 0) {
2659 		/* Start a wait before allowing PKEX to be initiated */
2660 		ifaces->dpp_pb_announce_time = now;
2661 	}
2662 
2663 	if (!ifaces->dpp_pb_bi) {
2664 		int res;
2665 
2666 		res = dpp_bootstrap_gen(ifaces->dpp, "type=pkex");
2667 		if (res < 0)
2668 			return;
2669 		ifaces->dpp_pb_bi = dpp_bootstrap_get_id(ifaces->dpp, res);
2670 		if (!ifaces->dpp_pb_bi)
2671 			return;
2672 
2673 		if (random_get_bytes(ifaces->dpp_pb_c_nonce,
2674 				     ifaces->dpp_pb_bi->curve->nonce_len)) {
2675 			wpa_printf(MSG_ERROR,
2676 				   "DPP: Failed to generate C-nonce");
2677 			hostapd_dpp_push_button_stop(hapd);
2678 			return;
2679 		}
2680 	}
2681 
2682 	/* Skip the response if one was sent within last 50 ms since the
2683 	 * Enrollee is going to send out at least three announcement messages.
2684 	 */
2685 	os_reltime_sub(&now, &ifaces->dpp_pb_last_resp, &age);
2686 	if (age.sec == 0 && age.usec < 50000) {
2687 		wpa_printf(MSG_DEBUG,
2688 			   "DPP: Skip Push Button Presence Announcement Response frame immediately after having sent one");
2689 		return;
2690 	}
2691 
2692 	msg = dpp_build_pb_announcement_resp(
2693 		ifaces->dpp_pb_bi, r_hash, ifaces->dpp_pb_c_nonce,
2694 		ifaces->dpp_pb_bi->curve->nonce_len);
2695 	if (!msg) {
2696 		hostapd_dpp_push_button_stop(hapd);
2697 		return;
2698 	}
2699 
2700 	wpa_printf(MSG_DEBUG,
2701 		   "DPP: Send Push Button Presence Announcement Response to "
2702 		   MACSTR, MAC2STR(src));
2703 	ifaces->dpp_pb_last_resp = now;
2704 
2705 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2706 		" freq=%u type=%d", MAC2STR(src), freq,
2707 		DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP);
2708 	hostapd_drv_send_action(hapd, freq, 0, src,
2709 				wpabuf_head(msg), wpabuf_len(msg));
2710 	wpabuf_free(msg);
2711 
2712 	if (os_reltime_expired(&now, &ifaces->dpp_pb_announce_time, 15))
2713 		hostapd_dpp_pb_pkex_init(hapd, freq, src, r_hash);
2714 }
2715 
2716 
2717 static void
hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2718 hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data *hapd, const u8 *src,
2719 				     const u8 *hdr, const u8 *buf, size_t len,
2720 				     unsigned int freq)
2721 {
2722 	const u8 *trans_id, *version;
2723 	u16 trans_id_len, version_len;
2724 	struct wpabuf *msg;
2725 	u8 ver = DPP_VERSION;
2726 	int conn_ver;
2727 
2728 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Query from "
2729 		   MACSTR, MAC2STR(src));
2730 
2731 	if (!hapd_dpp_connector_available(hapd))
2732 		return;
2733 
2734 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2735 			       &trans_id_len);
2736 	if (!trans_id || trans_id_len != 1) {
2737 		wpa_printf(MSG_DEBUG,
2738 			   "DPP: Peer did not include Transaction ID");
2739 		return;
2740 	}
2741 
2742 	version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2743 			       &version_len);
2744 	if (!version || version_len != 1) {
2745 		wpa_printf(MSG_DEBUG,
2746 			   "DPP: Peer did not include Protocol Version");
2747 		return;
2748 	}
2749 
2750 	wpa_printf(MSG_DEBUG, "DPP: Transaction ID %u, Version %u",
2751 		   trans_id[0], version[0]);
2752 
2753 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
2754 	msg = dpp_alloc_msg(DPP_PA_PRIV_PEER_INTRO_NOTIFY, len);
2755 	if (!msg)
2756 		return;
2757 
2758 	/* Transaction ID */
2759 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
2760 	wpabuf_put_le16(msg, 1);
2761 	wpabuf_put_u8(msg, trans_id[0]);
2762 
2763 	/* Protocol Version */
2764 	conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
2765 	if (conn_ver > 0 && ver != conn_ver) {
2766 		wpa_printf(MSG_DEBUG,
2767 			   "DPP: Use Connector version %d instead of current protocol version %d",
2768 			   conn_ver, ver);
2769 		ver = conn_ver;
2770 	}
2771 	wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2772 	wpabuf_put_le16(msg, 1);
2773 	wpabuf_put_u8(msg, ver);
2774 
2775 	/* DPP Connector */
2776 	wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
2777 	wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
2778 	wpabuf_put_str(msg, hapd->conf->dpp_connector);
2779 
2780 	wpa_printf(MSG_DEBUG, "DPP: Send Private Peer Introduction Notify to "
2781 		   MACSTR, MAC2STR(src));
2782 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2783 		" freq=%u type=%d", MAC2STR(src), freq,
2784 		DPP_PA_PRIV_PEER_INTRO_NOTIFY);
2785 	hostapd_drv_send_action(hapd, freq, 0, src,
2786 				wpabuf_head(msg), wpabuf_len(msg));
2787 	wpabuf_free(msg);
2788 }
2789 
2790 
2791 static void
hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2792 hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data *hapd, const u8 *src,
2793 				      const u8 *hdr, const u8 *buf, size_t len,
2794 				      unsigned int freq)
2795 {
2796 	struct crypto_ec_key *own_key;
2797 	const struct dpp_curve_params *curve;
2798 	enum hpke_kem_id kem_id;
2799 	enum hpke_kdf_id kdf_id;
2800 	enum hpke_aead_id aead_id;
2801 	const u8 *aad = hdr;
2802 	size_t aad_len = DPP_HDR_LEN;
2803 	struct wpabuf *pt;
2804 	const u8 *trans_id, *wrapped, *version, *connector;
2805 	u16 trans_id_len, wrapped_len, version_len, connector_len;
2806 	struct os_time now;
2807 	struct dpp_introduction intro;
2808 	os_time_t expire;
2809 	int expiration;
2810 	enum dpp_status_error res;
2811 	u8 pkhash[SHA256_MAC_LEN];
2812 
2813 	os_memset(&intro, 0, sizeof(intro));
2814 
2815 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Update from "
2816 		   MACSTR, MAC2STR(src));
2817 
2818 	if (!hapd_dpp_connector_available(hapd))
2819 		return;
2820 
2821 	os_get_time(&now);
2822 
2823 	if (hapd->conf->dpp_netaccesskey_expiry &&
2824 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2825 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2826 		return;
2827 	}
2828 
2829 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2830 			       &trans_id_len);
2831 	if (!trans_id || trans_id_len != 1) {
2832 		wpa_printf(MSG_DEBUG,
2833 			   "DPP: Peer did not include Transaction ID");
2834 		return;
2835 	}
2836 
2837 	wrapped = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
2838 			       &wrapped_len);
2839 	if (!wrapped) {
2840 		wpa_printf(MSG_DEBUG, "DPP: Peer did not include Wrapped Data");
2841 		return;
2842 	}
2843 
2844 	own_key = dpp_set_keypair(&curve,
2845 				  wpabuf_head(hapd->conf->dpp_netaccesskey),
2846 				  wpabuf_len(hapd->conf->dpp_netaccesskey));
2847 	if (!own_key) {
2848 		wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
2849 		return;
2850 	}
2851 
2852 	if (dpp_hpke_suite(curve->ike_group, &kem_id, &kdf_id, &aead_id) < 0) {
2853 		wpa_printf(MSG_ERROR, "DPP: Unsupported curve %d",
2854 			   curve->ike_group);
2855 		crypto_ec_key_deinit(own_key);
2856 		return;
2857 	}
2858 
2859 	pt = hpke_base_open(kem_id, kdf_id, aead_id, own_key, NULL, 0,
2860 			    aad, aad_len, wrapped, wrapped_len);
2861 	crypto_ec_key_deinit(own_key);
2862 	if (!pt) {
2863 		wpa_printf(MSG_INFO, "DPP: Failed to decrypt Connector");
2864 		return;
2865 	}
2866 	wpa_hexdump_buf(MSG_MSGDUMP, "DPP: HPKE-Decrypted Wrapped Data", pt);
2867 
2868 	connector = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2869 				 DPP_ATTR_CONNECTOR, &connector_len);
2870 	if (!connector) {
2871 		wpa_printf(MSG_DEBUG,
2872 			   "DPP: Peer did not include its Connector");
2873 		goto done;
2874 	}
2875 
2876 	version = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2877 			       DPP_ATTR_PROTOCOL_VERSION, &version_len);
2878 	if (!version || version_len < 1) {
2879 		wpa_printf(MSG_DEBUG,
2880 			   "DPP: Peer did not include Protocol Version");
2881 		goto done;
2882 	}
2883 
2884 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2885 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
2886 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
2887 			     wpabuf_head(hapd->conf->dpp_csign),
2888 			     wpabuf_len(hapd->conf->dpp_csign),
2889 			     connector, connector_len, &expire, pkhash);
2890 	if (res == 255) {
2891 		wpa_printf(MSG_INFO,
2892 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
2893 			   MACSTR ")", MAC2STR(src));
2894 		goto done;
2895 	}
2896 	if (res != DPP_STATUS_OK) {
2897 		wpa_printf(MSG_INFO,
2898 			   "DPP: Network Introduction protocol resulted in failure (peer "
2899 			   MACSTR " status %d)", MAC2STR(src), res);
2900 		goto done;
2901 	}
2902 
2903 	if (intro.peer_version && intro.peer_version >= 2) {
2904 		u8 attr_version = 1;
2905 
2906 		if (version && version_len >= 1)
2907 			attr_version = version[0];
2908 		if (attr_version != intro.peer_version) {
2909 			wpa_printf(MSG_INFO,
2910 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2911 				   intro.peer_version, attr_version);
2912 			goto done;
2913 		}
2914 	}
2915 
2916 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2917 		expire = hapd->conf->dpp_netaccesskey_expiry;
2918 	if (expire)
2919 		expiration = expire - now.sec;
2920 	else
2921 		expiration = 0;
2922 
2923 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2924 				intro.pmkid, expiration,
2925 				WPA_KEY_MGMT_DPP, pkhash) < 0) {
2926 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2927 		goto done;
2928 	}
2929 
2930 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction completed with "
2931 		   MACSTR, MAC2STR(src));
2932 
2933 done:
2934 	dpp_peer_intro_deinit(&intro);
2935 	wpabuf_free(pt);
2936 }
2937 
2938 #endif /* CONFIG_DPP3 */
2939 
2940 
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2941 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
2942 			   const u8 *buf, size_t len, unsigned int freq)
2943 {
2944 	u8 crypto_suite;
2945 	enum dpp_public_action_frame_type type;
2946 	const u8 *hdr;
2947 	unsigned int pkex_t;
2948 
2949 	if (len < DPP_HDR_LEN)
2950 		return;
2951 	if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
2952 		return;
2953 	hdr = buf;
2954 	buf += 4;
2955 	len -= 4;
2956 	crypto_suite = *buf++;
2957 	type = *buf++;
2958 	len -= 2;
2959 
2960 	wpa_printf(MSG_DEBUG,
2961 		   "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2962 		   MACSTR_SEC " freq=%u",
2963 		   crypto_suite, type, MAC2STR_SEC(src), freq);
2964 	if (crypto_suite != 1) {
2965 		wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
2966 			   crypto_suite);
2967 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2968 			" freq=%u type=%d ignore=unsupported-crypto-suite",
2969 			MAC2STR(src), freq, type);
2970 		return;
2971 	}
2972 	wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
2973 	if (dpp_check_attrs(buf, len) < 0) {
2974 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2975 			" freq=%u type=%d ignore=invalid-attributes",
2976 			MAC2STR(src), freq, type);
2977 		return;
2978 	}
2979 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2980 		" freq=%u type=%d", MAC2STR(src), freq, type);
2981 
2982 #ifdef CONFIG_DPP2
2983 	if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2984 				src, hdr, buf, len, freq, NULL, NULL,
2985 				hapd) == 0)
2986 		return;
2987 #endif /* CONFIG_DPP2 */
2988 
2989 	switch (type) {
2990 	case DPP_PA_AUTHENTICATION_REQ:
2991 		hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
2992 		break;
2993 	case DPP_PA_AUTHENTICATION_RESP:
2994 		hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
2995 		break;
2996 	case DPP_PA_AUTHENTICATION_CONF:
2997 		hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
2998 		break;
2999 	case DPP_PA_PEER_DISCOVERY_REQ:
3000 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
3001 		break;
3002 #ifdef CONFIG_DPP3
3003 	case DPP_PA_PKEX_EXCHANGE_REQ:
3004 		/* This is for PKEXv2, but for now, process only with
3005 		 * CONFIG_DPP3 to avoid issues with a capability that has not
3006 		 * been tested with other implementations. */
3007 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3008 						 true);
3009 		break;
3010 #endif /* CONFIG_DPP3 */
3011 	case DPP_PA_PKEX_V1_EXCHANGE_REQ:
3012 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3013 						 false);
3014 		break;
3015 	case DPP_PA_PKEX_EXCHANGE_RESP:
3016 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
3017 		break;
3018 	case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
3019 		hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
3020 						      freq);
3021 		break;
3022 	case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
3023 		hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
3024 						       freq);
3025 		break;
3026 #ifdef CONFIG_DPP2
3027 	case DPP_PA_CONFIGURATION_RESULT:
3028 		hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
3029 		break;
3030 	case DPP_PA_CONNECTION_STATUS_RESULT:
3031 		hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
3032 		break;
3033 	case DPP_PA_PRESENCE_ANNOUNCEMENT:
3034 		hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
3035 						     freq);
3036 		break;
3037 	case DPP_PA_RECONFIG_ANNOUNCEMENT:
3038 		hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
3039 						     freq);
3040 		break;
3041 	case DPP_PA_RECONFIG_AUTH_RESP:
3042 		hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
3043 						  freq);
3044 		break;
3045 #endif /* CONFIG_DPP2 */
3046 #ifdef CONFIG_DPP3
3047 	case DPP_PA_PB_PRESENCE_ANNOUNCEMENT:
3048 		hostapd_dpp_rx_pb_presence_announcement(hapd, src, hdr,
3049 							buf, len, freq);
3050 		break;
3051 	case DPP_PA_PRIV_PEER_INTRO_QUERY:
3052 		hostapd_dpp_rx_priv_peer_intro_query(hapd, src, hdr,
3053 						     buf, len, freq);
3054 		break;
3055 	case DPP_PA_PRIV_PEER_INTRO_UPDATE:
3056 		hostapd_dpp_rx_priv_peer_intro_update(hapd, src, hdr,
3057 						      buf, len, freq);
3058 		break;
3059 #endif /* CONFIG_DPP3 */
3060 	default:
3061 		wpa_printf(MSG_DEBUG,
3062 			   "DPP: Ignored unsupported frame subtype %d", type);
3063 		break;
3064 	}
3065 
3066 	if (hapd->dpp_pkex)
3067 		pkex_t = hapd->dpp_pkex->t;
3068 	else if (hapd->dpp_pkex_bi)
3069 		pkex_t = hapd->dpp_pkex_bi->pkex_t;
3070 	else
3071 		pkex_t = 0;
3072 	if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
3073 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
3074 		hostapd_dpp_pkex_remove(hapd, "*");
3075 	}
3076 }
3077 
3078 
3079 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)3080 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
3081 			    const u8 *query, size_t query_len,
3082 			    const u8 *data, size_t data_len)
3083 {
3084 	struct dpp_authentication *auth = hapd->dpp_auth;
3085 	struct wpabuf *resp;
3086 
3087 	wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR_SEC, MAC2STR_SEC(sa));
3088 	if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
3089 	    !ether_addr_equal(sa, auth->peer_mac_addr)) {
3090 #ifdef CONFIG_DPP2
3091 		if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
3092 				     data_len) == 0) {
3093 			/* Response will be forwarded once received over TCP */
3094 			return NULL;
3095 		}
3096 #endif /* CONFIG_DPP2 */
3097 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
3098 		return NULL;
3099 	}
3100 
3101 	if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
3102 		wpa_printf(MSG_DEBUG,
3103 			   "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
3104 		/* hostapd_dpp_auth_success() would normally have been called
3105 		 * from TX status handler, but since there was no such handler
3106 		 * call yet, simply send out the event message and proceed with
3107 		 * exchange. */
3108 		dpp_notify_auth_success(hapd->dpp_auth, 1);
3109 		hapd->dpp_auth_ok_on_ack = 0;
3110 #ifdef CONFIG_TESTING_OPTIONS
3111 		if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
3112 			wpa_printf(MSG_INFO,
3113 				   "DPP: TESTING - stop at Authentication Confirm");
3114 			return NULL;
3115 		}
3116 #endif /* CONFIG_TESTING_OPTIONS */
3117 	}
3118 
3119 	wpa_hexdump(MSG_DEBUG,
3120 		    "DPP: Received Configuration Request (GAS Query Request)",
3121 		    query, query_len);
3122 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
3123 		MAC2STR(sa));
3124 	resp = dpp_conf_req_rx(auth, query, query_len);
3125 	if (!resp)
3126 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3127 	return resp;
3128 }
3129 
3130 
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)3131 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
3132 {
3133 	struct dpp_authentication *auth = hapd->dpp_auth;
3134 #ifdef CONFIG_DPP3
3135 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3136 #endif /* CONFIG_DPP3 */
3137 
3138 	if (!auth)
3139 		return;
3140 
3141 #ifdef CONFIG_DPP3
3142 	if (auth->waiting_new_key && ok) {
3143 		wpa_printf(MSG_DEBUG, "DPP: Waiting for a new key");
3144 		return;
3145 	}
3146 #endif /* CONFIG_DPP3 */
3147 
3148 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
3149 		   ok);
3150 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3151 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3152 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3153 #ifdef CONFIG_DPP2
3154 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3155 				     hapd, NULL);
3156 	if (ok && auth->peer_version >= 2 &&
3157 	    auth->conf_resp_status == DPP_STATUS_OK) {
3158 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
3159 		auth->waiting_conf_result = 1;
3160 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
3161 				     hapd, NULL);
3162 		eloop_register_timeout(2, 0,
3163 				       hostapd_dpp_config_result_wait_timeout,
3164 				       hapd, NULL);
3165 		return;
3166 	}
3167 #endif /* CONFIG_DPP2 */
3168 	hostapd_drv_send_action_cancel_wait(hapd);
3169 
3170 	if (ok)
3171 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
3172 			"conf_status=%d", auth->conf_resp_status);
3173 	else
3174 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3175 	dpp_auth_deinit(hapd->dpp_auth);
3176 	hapd->dpp_auth = NULL;
3177 #ifdef CONFIG_DPP3
3178 	if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
3179 		if (ok)
3180 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3181 				"success");
3182 		else
3183 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3184 				"could-not-connect");
3185 		ifaces->dpp_pb_result_indicated = true;
3186 		if (ok)
3187 			hostapd_dpp_remove_pb_hash(hapd);
3188 		hostapd_dpp_push_button_stop(hapd);
3189 	}
3190 #endif /* CONFIG_DPP3 */
3191 }
3192 
3193 
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)3194 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
3195 {
3196 	struct dpp_authentication *auth;
3197 	int ret = -1;
3198 	char *curve = NULL;
3199 
3200 	auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
3201 	if (!auth)
3202 		return -1;
3203 
3204 	curve = get_param(cmd, " curve=");
3205 	hostapd_dpp_set_testing_options(hapd, auth);
3206 	if (dpp_set_configurator(auth, cmd) == 0 &&
3207 	    dpp_configurator_own_config(auth, curve, 1) == 0) {
3208 		hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
3209 		ret = 0;
3210 	}
3211 
3212 	dpp_auth_deinit(auth);
3213 	os_free(curve);
3214 
3215 	return ret;
3216 }
3217 
3218 
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)3219 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
3220 {
3221 	struct dpp_bootstrap_info *own_bi;
3222 	const char *pos, *end;
3223 #ifdef CONFIG_DPP3
3224 		enum dpp_pkex_ver ver = PKEX_VER_AUTO;
3225 #else /* CONFIG_DPP3 */
3226 		enum dpp_pkex_ver ver = PKEX_VER_ONLY_1;
3227 #endif /* CONFIG_DPP3 */
3228 	int tcp_port = DPP_TCP_PORT;
3229 	struct hostapd_ip_addr *ipaddr = NULL;
3230 #ifdef CONFIG_DPP2
3231 	struct hostapd_ip_addr ipaddr_buf;
3232 	char *addr;
3233 
3234 	pos = os_strstr(cmd, " tcp_port=");
3235 	if (pos) {
3236 		pos += 10;
3237 		tcp_port = atoi(pos);
3238 	}
3239 
3240 	addr = get_param(cmd, " tcp_addr=");
3241 	if (addr) {
3242 		int res;
3243 
3244 		res = hostapd_parse_ip_addr(addr, &ipaddr_buf);
3245 		os_free(addr);
3246 		if (res)
3247 			return -1;
3248 		ipaddr = &ipaddr_buf;
3249 	}
3250 #endif /* CONFIG_DPP2 */
3251 
3252 	pos = os_strstr(cmd, " own=");
3253 	if (!pos)
3254 		return -1;
3255 	pos += 5;
3256 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3257 	if (!own_bi) {
3258 		wpa_printf(MSG_DEBUG,
3259 			   "DPP: Identified bootstrap info not found");
3260 		return -1;
3261 	}
3262 	if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
3263 		wpa_printf(MSG_DEBUG,
3264 			   "DPP: Identified bootstrap info not for PKEX");
3265 		return -1;
3266 	}
3267 	hapd->dpp_pkex_bi = own_bi;
3268 	own_bi->pkex_t = 0; /* clear pending errors on new code */
3269 
3270 	os_free(hapd->dpp_pkex_identifier);
3271 	hapd->dpp_pkex_identifier = NULL;
3272 	pos = os_strstr(cmd, " identifier=");
3273 	if (pos) {
3274 		pos += 12;
3275 		end = os_strchr(pos, ' ');
3276 		if (!end)
3277 			return -1;
3278 		hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
3279 		if (!hapd->dpp_pkex_identifier)
3280 			return -1;
3281 		os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
3282 		hapd->dpp_pkex_identifier[end - pos] = '\0';
3283 	}
3284 
3285 	pos = os_strstr(cmd, " code=");
3286 	if (!pos)
3287 		return -1;
3288 	os_free(hapd->dpp_pkex_code);
3289 	hapd->dpp_pkex_code = os_strdup(pos + 6);
3290 	if (!hapd->dpp_pkex_code)
3291 		return -1;
3292 	hapd->dpp_pkex_code_len = os_strlen(hapd->dpp_pkex_code);
3293 
3294 	pos = os_strstr(cmd, " ver=");
3295 	if (pos) {
3296 		int v;
3297 
3298 		pos += 5;
3299 		v = atoi(pos);
3300 		if (v == 1)
3301 			ver = PKEX_VER_ONLY_1;
3302 		else if (v == 2)
3303 			ver = PKEX_VER_ONLY_2;
3304 		else
3305 			return -1;
3306 	}
3307 	hapd->dpp_pkex_ver = ver;
3308 
3309 	if (os_strstr(cmd, " init=1")) {
3310 		if (hostapd_dpp_pkex_init(hapd, ver, ipaddr, tcp_port) < 0)
3311 			return -1;
3312 	} else {
3313 #ifdef CONFIG_DPP2
3314 		dpp_controller_pkex_add(hapd->iface->interfaces->dpp, own_bi,
3315 					hapd->dpp_pkex_code,
3316 					hapd->dpp_pkex_identifier);
3317 #endif /* CONFIG_DPP2 */
3318 	}
3319 
3320 	/* TODO: Support multiple PKEX info entries */
3321 
3322 	os_free(hapd->dpp_pkex_auth_cmd);
3323 	hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
3324 
3325 	return 1;
3326 }
3327 
3328 
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)3329 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
3330 {
3331 	unsigned int id_val;
3332 
3333 	if (os_strcmp(id, "*") == 0) {
3334 		id_val = 0;
3335 	} else {
3336 		id_val = atoi(id);
3337 		if (id_val == 0)
3338 			return -1;
3339 	}
3340 
3341 	if ((id_val != 0 && id_val != 1))
3342 		return -1;
3343 
3344 	/* TODO: Support multiple PKEX entries */
3345 	os_free(hapd->dpp_pkex_code);
3346 	hapd->dpp_pkex_code = NULL;
3347 	os_free(hapd->dpp_pkex_identifier);
3348 	hapd->dpp_pkex_identifier = NULL;
3349 	os_free(hapd->dpp_pkex_auth_cmd);
3350 	hapd->dpp_pkex_auth_cmd = NULL;
3351 	hapd->dpp_pkex_bi = NULL;
3352 	/* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
3353 	dpp_pkex_free(hapd->dpp_pkex);
3354 	hapd->dpp_pkex = NULL;
3355 	return 0;
3356 }
3357 
3358 
hostapd_dpp_stop(struct hostapd_data * hapd)3359 void hostapd_dpp_stop(struct hostapd_data *hapd)
3360 {
3361 	dpp_auth_deinit(hapd->dpp_auth);
3362 	hapd->dpp_auth = NULL;
3363 	dpp_pkex_free(hapd->dpp_pkex);
3364 	hapd->dpp_pkex = NULL;
3365 #ifdef CONFIG_DPP3
3366 	hostapd_dpp_push_button_stop(hapd);
3367 #endif /* CONFIG_DPP3 */
3368 }
3369 
3370 
3371 #ifdef CONFIG_DPP2
3372 
hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)3373 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
3374 				 const u8 *msg, size_t len)
3375 {
3376 	struct hostapd_data *hapd = ctx;
3377 	u8 *buf;
3378 
3379 	if (freq == 0)
3380 		freq = hapd->iface->freq;
3381 
3382 	wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR_SEC " freq=%u",
3383 		   MAC2STR_SEC(addr), freq);
3384 	buf = os_malloc(2 + len);
3385 	if (!buf)
3386 		return;
3387 	buf[0] = WLAN_ACTION_PUBLIC;
3388 	buf[1] = WLAN_PA_VENDOR_SPECIFIC;
3389 	os_memcpy(buf + 2, msg, len);
3390 	hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
3391 	os_free(buf);
3392 }
3393 
3394 
hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)3395 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
3396 					  u8 dialog_token, int prot,
3397 					  struct wpabuf *buf)
3398 {
3399 	struct hostapd_data *hapd = ctx;
3400 
3401 	gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf, 0);
3402 }
3403 
3404 #endif /* CONFIG_DPP2 */
3405 
3406 
hostapd_dpp_add_controllers(struct hostapd_data * hapd)3407 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
3408 {
3409 #ifdef CONFIG_DPP2
3410 	struct dpp_controller_conf *ctrl;
3411 	struct dpp_relay_config config;
3412 
3413 	os_memset(&config, 0, sizeof(config));
3414 	config.msg_ctx = hapd->msg_ctx;
3415 	config.cb_ctx = hapd;
3416 	config.tx = hostapd_dpp_relay_tx;
3417 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3418 	for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
3419 		config.ipaddr = &ctrl->ipaddr;
3420 		config.pkhash = ctrl->pkhash;
3421 		if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
3422 					     &config) < 0)
3423 			return -1;
3424 	}
3425 
3426 	if (hapd->conf->dpp_relay_port)
3427 		dpp_relay_listen(hapd->iface->interfaces->dpp,
3428 				 hapd->conf->dpp_relay_port,
3429 				 &config);
3430 #endif /* CONFIG_DPP2 */
3431 
3432 	return 0;
3433 }
3434 
3435 
3436 #ifdef CONFIG_DPP2
3437 
hostapd_dpp_add_controller(struct hostapd_data * hapd,const char * cmd)3438 int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd)
3439 {
3440 	struct dpp_relay_config config;
3441 	struct hostapd_ip_addr addr;
3442 	u8 pkhash[SHA256_MAC_LEN];
3443 	char *pos, *tmp;
3444 	int ret = -1;
3445 	bool prev_state, new_state;
3446 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3447 
3448 	tmp = os_strdup(cmd);
3449 	if (!tmp)
3450 		goto fail;
3451 	pos = os_strchr(tmp, ' ');
3452 	if (!pos)
3453 		goto fail;
3454 	*pos++ = '\0';
3455 	if (hostapd_parse_ip_addr(tmp, &addr) < 0 ||
3456 	    hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0)
3457 		goto fail;
3458 
3459 	os_memset(&config, 0, sizeof(config));
3460 	config.msg_ctx = hapd->msg_ctx;
3461 	config.cb_ctx = hapd;
3462 	config.tx = hostapd_dpp_relay_tx;
3463 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3464 	config.ipaddr = &addr;
3465 	config.pkhash = pkhash;
3466 	prev_state = dpp_relay_controller_available(dpp);
3467 	ret = dpp_relay_add_controller(dpp, &config);
3468 	new_state = dpp_relay_controller_available(dpp);
3469 	if (new_state != prev_state)
3470 		ieee802_11_update_beacons(hapd->iface);
3471 fail:
3472 	os_free(tmp);
3473 	return ret;
3474 }
3475 
3476 
hostapd_dpp_remove_controller(struct hostapd_data * hapd,const char * cmd)3477 void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd)
3478 {
3479 	struct hostapd_ip_addr addr;
3480 	bool prev_state, new_state;
3481 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3482 
3483 	if (hostapd_parse_ip_addr(cmd, &addr) < 0)
3484 		return;
3485 	prev_state = dpp_relay_controller_available(dpp);
3486 	dpp_relay_remove_controller(dpp, &addr);
3487 	new_state = dpp_relay_controller_available(dpp);
3488 	if (new_state != prev_state)
3489 		ieee802_11_update_beacons(hapd->iface);
3490 }
3491 
3492 #endif /* CONFIG_DPP2 */
3493 
3494 
hostapd_dpp_init(struct hostapd_data * hapd)3495 int hostapd_dpp_init(struct hostapd_data *hapd)
3496 {
3497 	hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
3498 	hapd->dpp_init_done = 1;
3499 	return hostapd_dpp_add_controllers(hapd);
3500 }
3501 
3502 
hostapd_dpp_deinit(struct hostapd_data * hapd)3503 void hostapd_dpp_deinit(struct hostapd_data *hapd)
3504 {
3505 #ifdef CONFIG_TESTING_OPTIONS
3506 	os_free(hapd->dpp_config_obj_override);
3507 	hapd->dpp_config_obj_override = NULL;
3508 	os_free(hapd->dpp_discovery_override);
3509 	hapd->dpp_discovery_override = NULL;
3510 	os_free(hapd->dpp_groups_override);
3511 	hapd->dpp_groups_override = NULL;
3512 	hapd->dpp_ignore_netaccesskey_mismatch = 0;
3513 #endif /* CONFIG_TESTING_OPTIONS */
3514 	if (!hapd->dpp_init_done)
3515 		return;
3516 	eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
3517 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3518 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3519 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
3520 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3521 #ifdef CONFIG_DPP2
3522 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3523 			     hapd, NULL);
3524 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
3525 			     NULL);
3526 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
3527 			     NULL);
3528 	hostapd_dpp_chirp_stop(hapd);
3529 	if (hapd->iface->interfaces) {
3530 		dpp_relay_stop_listen(hapd->iface->interfaces->dpp);
3531 		dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
3532 	}
3533 #endif /* CONFIG_DPP2 */
3534 #ifdef CONFIG_DPP3
3535 	eloop_cancel_timeout(hostapd_dpp_build_new_key, hapd, NULL);
3536 	hostapd_dpp_push_button_stop(hapd);
3537 #endif /* CONFIG_DPP3 */
3538 	dpp_auth_deinit(hapd->dpp_auth);
3539 	hapd->dpp_auth = NULL;
3540 	hostapd_dpp_pkex_remove(hapd, "*");
3541 	hapd->dpp_pkex = NULL;
3542 	os_free(hapd->dpp_configurator_params);
3543 	hapd->dpp_configurator_params = NULL;
3544 	os_free(hapd->dpp_pkex_auth_cmd);
3545 	hapd->dpp_pkex_auth_cmd = NULL;
3546 }
3547 
3548 
3549 #ifdef CONFIG_DPP2
3550 
hostapd_dpp_controller_start(struct hostapd_data * hapd,const char * cmd)3551 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd)
3552 {
3553 	struct dpp_controller_config config;
3554 	const char *pos;
3555 
3556 	os_memset(&config, 0, sizeof(config));
3557 	config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
3558 	config.netrole = DPP_NETROLE_AP;
3559 	config.msg_ctx = hapd->msg_ctx;
3560 	config.cb_ctx = hapd;
3561 	config.process_conf_obj = hostapd_dpp_process_conf_obj;
3562 	if (cmd) {
3563 		pos = os_strstr(cmd, " tcp_port=");
3564 		if (pos) {
3565 			pos += 10;
3566 			config.tcp_port = atoi(pos);
3567 		}
3568 
3569 		pos = os_strstr(cmd, " role=");
3570 		if (pos) {
3571 			pos += 6;
3572 			if (os_strncmp(pos, "configurator", 12) == 0)
3573 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
3574 			else if (os_strncmp(pos, "enrollee", 8) == 0)
3575 				config.allowed_roles = DPP_CAPAB_ENROLLEE;
3576 			else if (os_strncmp(pos, "either", 6) == 0)
3577 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
3578 					DPP_CAPAB_ENROLLEE;
3579 			else
3580 				return -1;
3581 		}
3582 
3583 		config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
3584 	}
3585 	config.configurator_params = hapd->dpp_configurator_params;
3586 	return dpp_controller_start(hapd->iface->interfaces->dpp, &config);
3587 }
3588 
3589 
3590 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
3591 
hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)3592 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
3593 {
3594 	struct hostapd_data *hapd = eloop_ctx;
3595 
3596 	wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
3597 	hostapd_drv_send_action_cancel_wait(hapd);
3598 	hostapd_dpp_chirp_next(hapd, NULL);
3599 }
3600 
3601 
hostapd_dpp_chirp_start(struct hostapd_data * hapd)3602 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
3603 {
3604 	struct wpabuf *msg;
3605 	int type;
3606 
3607 	msg = hapd->dpp_presence_announcement;
3608 	type = DPP_PA_PRESENCE_ANNOUNCEMENT;
3609 	wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
3610 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
3611 		" freq=%u type=%d",
3612 		MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
3613 	if (hostapd_drv_send_action(
3614 		    hapd, hapd->dpp_chirp_freq, 2000, broadcast,
3615 		    wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
3616 	    eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
3617 				   hapd, NULL) < 0)
3618 		hostapd_dpp_chirp_stop(hapd);
3619 }
3620 
3621 
3622 static struct hostapd_hw_modes *
dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)3623 dpp_get_mode(struct hostapd_data *hapd,
3624 	     enum hostapd_hw_mode mode)
3625 {
3626 	struct hostapd_hw_modes *modes = hapd->iface->hw_features;
3627 	u16 num_modes = hapd->iface->num_hw_features;
3628 	u16 i;
3629 
3630 	for (i = 0; i < num_modes; i++) {
3631 		if (modes[i].mode != mode ||
3632 		    !modes[i].num_channels || !modes[i].channels)
3633 			continue;
3634 		return &modes[i];
3635 	}
3636 
3637 	return NULL;
3638 }
3639 
3640 
3641 static void
hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)3642 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
3643 {
3644 	struct hostapd_data *hapd = iface->bss[0];
3645 	struct wpa_scan_results *scan_res;
3646 	struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
3647 	unsigned int i;
3648 	struct hostapd_hw_modes *mode;
3649 	int c;
3650 	bool chan6 = hapd->iface->hw_features == NULL;
3651 
3652 	if (!bi)
3653 		return;
3654 
3655 	hapd->dpp_chirp_scan_done = 1;
3656 
3657 	scan_res = hostapd_driver_get_scan_results(hapd);
3658 
3659 	os_free(hapd->dpp_chirp_freqs);
3660 	hapd->dpp_chirp_freqs = NULL;
3661 
3662 	/* Channels from own bootstrapping info */
3663 	if (bi) {
3664 		for (i = 0; i < bi->num_freq; i++)
3665 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3666 					     bi->freq[i]);
3667 	}
3668 
3669 	/* Preferred chirping channels */
3670 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
3671 	if (mode) {
3672 		for (c = 0; c < mode->num_channels; c++) {
3673 			struct hostapd_channel_data *chan = &mode->channels[c];
3674 
3675 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3676 					  HOSTAPD_CHAN_RADAR) ||
3677 			    chan->freq != 2437)
3678 				continue;
3679 			chan6 = true;
3680 			break;
3681 		}
3682 	}
3683 	if (chan6)
3684 		int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
3685 
3686 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
3687 	if (mode) {
3688 		int chan44 = 0, chan149 = 0;
3689 
3690 		for (c = 0; c < mode->num_channels; c++) {
3691 			struct hostapd_channel_data *chan = &mode->channels[c];
3692 
3693 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3694 					  HOSTAPD_CHAN_RADAR))
3695 				continue;
3696 			if (chan->freq == 5220)
3697 				chan44 = 1;
3698 			if (chan->freq == 5745)
3699 				chan149 = 1;
3700 		}
3701 		if (chan149)
3702 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
3703 		else if (chan44)
3704 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
3705 	}
3706 
3707 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
3708 	if (mode) {
3709 		for (c = 0; c < mode->num_channels; c++) {
3710 			struct hostapd_channel_data *chan = &mode->channels[c];
3711 
3712 			if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
3713 					   HOSTAPD_CHAN_RADAR)) ||
3714 			    chan->freq != 60480)
3715 				continue;
3716 			int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
3717 			break;
3718 		}
3719 	}
3720 
3721 	/* Add channels from scan results for APs that advertise Configurator
3722 	 * Connectivity element */
3723 	for (i = 0; scan_res && i < scan_res->num; i++) {
3724 		struct wpa_scan_res *bss = scan_res->res[i];
3725 		size_t ie_len = bss->ie_len;
3726 
3727 		if (!ie_len)
3728 			ie_len = bss->beacon_ie_len;
3729 		if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
3730 				  DPP_CC_IE_VENDOR_TYPE))
3731 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3732 					     bss->freq);
3733 	}
3734 
3735 	if (!hapd->dpp_chirp_freqs ||
3736 	    eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
3737 				   hapd, NULL) < 0)
3738 		hostapd_dpp_chirp_stop(hapd);
3739 
3740 	wpa_scan_results_free(scan_res);
3741 }
3742 
3743 
hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)3744 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
3745 {
3746 	struct hostapd_data *hapd = eloop_ctx;
3747 	int i;
3748 
3749 	if (hapd->dpp_chirp_listen)
3750 		hostapd_dpp_listen_stop(hapd);
3751 
3752 	if (hapd->dpp_chirp_freq == 0) {
3753 		if (hapd->dpp_chirp_round % 4 == 0 &&
3754 		    !hapd->dpp_chirp_scan_done) {
3755 			struct wpa_driver_scan_params params;
3756 			int ret;
3757 
3758 			wpa_printf(MSG_DEBUG,
3759 				   "DPP: Update channel list for chirping");
3760 			os_memset(&params, 0, sizeof(params));
3761 			ret = hostapd_driver_scan(hapd, &params);
3762 			if (ret < 0) {
3763 				wpa_printf(MSG_DEBUG,
3764 					   "DPP: Failed to request a scan ret=%d (%s)",
3765 					   ret, strerror(-ret));
3766 				hostapd_dpp_chirp_scan_res_handler(hapd->iface);
3767 			} else {
3768 				hapd->iface->scan_cb =
3769 					hostapd_dpp_chirp_scan_res_handler;
3770 			}
3771 			return;
3772 		}
3773 		hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
3774 		hapd->dpp_chirp_round++;
3775 		wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
3776 			   hapd->dpp_chirp_round);
3777 	} else {
3778 		for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
3779 			if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
3780 				break;
3781 		if (!hapd->dpp_chirp_freqs[i]) {
3782 			wpa_printf(MSG_DEBUG,
3783 				   "DPP: Previous chirp freq %d not found",
3784 				   hapd->dpp_chirp_freq);
3785 			return;
3786 		}
3787 		i++;
3788 		if (hapd->dpp_chirp_freqs[i]) {
3789 			hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
3790 		} else {
3791 			hapd->dpp_chirp_iter--;
3792 			if (hapd->dpp_chirp_iter <= 0) {
3793 				wpa_printf(MSG_DEBUG,
3794 					   "DPP: Chirping iterations completed");
3795 				hostapd_dpp_chirp_stop(hapd);
3796 				return;
3797 			}
3798 			hapd->dpp_chirp_freq = 0;
3799 			hapd->dpp_chirp_scan_done = 0;
3800 			if (eloop_register_timeout(30, 0,
3801 						   hostapd_dpp_chirp_next,
3802 						   hapd, NULL) < 0) {
3803 				hostapd_dpp_chirp_stop(hapd);
3804 				return;
3805 			}
3806 			if (hapd->dpp_chirp_listen) {
3807 				wpa_printf(MSG_DEBUG,
3808 					   "DPP: Listen on %d MHz during chirp 30 second wait",
3809 					hapd->dpp_chirp_listen);
3810 				/* TODO: start listen on the channel */
3811 			} else {
3812 				wpa_printf(MSG_DEBUG,
3813 					   "DPP: Wait 30 seconds before starting the next chirping round");
3814 			}
3815 			return;
3816 		}
3817 	}
3818 
3819 	hostapd_dpp_chirp_start(hapd);
3820 }
3821 
3822 
hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)3823 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
3824 {
3825 	const char *pos;
3826 	int iter = 1, listen_freq = 0;
3827 	struct dpp_bootstrap_info *bi;
3828 
3829 	pos = os_strstr(cmd, " own=");
3830 	if (!pos)
3831 		return -1;
3832 	pos += 5;
3833 	bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3834 	if (!bi) {
3835 		wpa_printf(MSG_DEBUG,
3836 			   "DPP: Identified bootstrap info not found");
3837 		return -1;
3838 	}
3839 
3840 	pos = os_strstr(cmd, " iter=");
3841 	if (pos) {
3842 		iter = atoi(pos + 6);
3843 		if (iter <= 0)
3844 			return -1;
3845 	}
3846 
3847 	pos = os_strstr(cmd, " listen=");
3848 	if (pos) {
3849 		listen_freq = atoi(pos + 8);
3850 		if (listen_freq <= 0)
3851 			return -1;
3852 	}
3853 
3854 	hostapd_dpp_chirp_stop(hapd);
3855 	hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
3856 	hapd->dpp_qr_mutual = 0;
3857 	hapd->dpp_chirp_bi = bi;
3858 	hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
3859 	if (!hapd->dpp_presence_announcement)
3860 		return -1;
3861 	hapd->dpp_chirp_iter = iter;
3862 	hapd->dpp_chirp_round = 0;
3863 	hapd->dpp_chirp_scan_done = 0;
3864 	hapd->dpp_chirp_listen = listen_freq;
3865 
3866 	return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
3867 }
3868 
3869 
hostapd_dpp_chirp_stop(struct hostapd_data * hapd)3870 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
3871 {
3872 	if (hapd->dpp_presence_announcement) {
3873 		hostapd_drv_send_action_cancel_wait(hapd);
3874 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
3875 	}
3876 	hapd->dpp_chirp_bi = NULL;
3877 	wpabuf_free(hapd->dpp_presence_announcement);
3878 	hapd->dpp_presence_announcement = NULL;
3879 	if (hapd->dpp_chirp_listen)
3880 		hostapd_dpp_listen_stop(hapd);
3881 	hapd->dpp_chirp_listen = 0;
3882 	hapd->dpp_chirp_freq = 0;
3883 	os_free(hapd->dpp_chirp_freqs);
3884 	hapd->dpp_chirp_freqs = NULL;
3885 	eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
3886 	eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
3887 	if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
3888 		/* TODO: abort ongoing scan */
3889 		hapd->iface->scan_cb = NULL;
3890 	}
3891 }
3892 
3893 
handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)3894 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
3895 {
3896 	struct dpp_bootstrap_info *bi = ctx;
3897 	size_t i;
3898 
3899 	for (i = 0; i < iface->num_bss; i++) {
3900 		struct hostapd_data *hapd = iface->bss[i];
3901 
3902 		if (bi == hapd->dpp_chirp_bi)
3903 			hostapd_dpp_chirp_stop(hapd);
3904 	}
3905 
3906 	return 0;
3907 }
3908 
3909 
hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)3910 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
3911 {
3912 	struct hapd_interfaces *interfaces = ctx;
3913 
3914 	hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
3915 }
3916 
3917 #endif /* CONFIG_DPP2 */
3918 
3919 
3920 #ifdef CONFIG_DPP3
3921 
hostapd_dpp_push_button_expire(void * eloop_ctx,void * timeout_ctx)3922 static void hostapd_dpp_push_button_expire(void *eloop_ctx, void *timeout_ctx)
3923 {
3924 	struct hostapd_data *hapd = eloop_ctx;
3925 
3926 	wpa_printf(MSG_DEBUG, "DPP: Active push button mode expired");
3927 	hostapd_dpp_push_button_stop(hapd);
3928 }
3929 
3930 
hostapd_dpp_push_button(struct hostapd_data * hapd,const char * cmd)3931 int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd)
3932 {
3933 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3934 
3935 	if (!ifaces || !ifaces->dpp)
3936 		return -1;
3937 	os_get_reltime(&ifaces->dpp_pb_time);
3938 	ifaces->dpp_pb_announce_time.sec = 0;
3939 	ifaces->dpp_pb_announce_time.usec = 0;
3940 	str_clear_free(ifaces->dpp_pb_cmd);
3941 	ifaces->dpp_pb_cmd = NULL;
3942 	if (cmd) {
3943 		ifaces->dpp_pb_cmd = os_strdup(cmd);
3944 		if (!ifaces->dpp_pb_cmd)
3945 			return -1;
3946 	}
3947 	eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
3948 			       hapd, NULL);
3949 
3950 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started");
3951 	return 0;
3952 }
3953 
3954 
hostapd_dpp_push_button_stop(struct hostapd_data * hapd)3955 void hostapd_dpp_push_button_stop(struct hostapd_data *hapd)
3956 {
3957 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3958 
3959 	if (!ifaces || !ifaces->dpp)
3960 		return;
3961 	eloop_cancel_timeout(hostapd_dpp_push_button_expire, hapd, NULL);
3962 	if (hostapd_dpp_pb_active(hapd)) {
3963 		wpa_printf(MSG_DEBUG, "DPP: Stop active push button mode");
3964 		if (!ifaces->dpp_pb_result_indicated)
3965 			wpa_msg(hapd->msg_ctx, MSG_INFO,
3966 				DPP_EVENT_PB_RESULT "failed");
3967 	}
3968 	ifaces->dpp_pb_time.sec = 0;
3969 	ifaces->dpp_pb_time.usec = 0;
3970 	dpp_pkex_free(hapd->dpp_pkex);
3971 	hapd->dpp_pkex = NULL;
3972 	hapd->dpp_pkex_bi = NULL;
3973 	os_free(hapd->dpp_pkex_auth_cmd);
3974 	hapd->dpp_pkex_auth_cmd = NULL;
3975 
3976 	if (ifaces->dpp_pb_bi) {
3977 		char id[20];
3978 		size_t i;
3979 
3980 		for (i = 0; i < ifaces->count; i++) {
3981 			struct hostapd_iface *iface = ifaces->iface[i];
3982 			size_t j;
3983 
3984 			for (j = 0; iface && j < iface->num_bss; j++) {
3985 				struct hostapd_data *h = iface->bss[j];
3986 
3987 				if (h->dpp_pkex_bi == ifaces->dpp_pb_bi)
3988 					h->dpp_pkex_bi = NULL;
3989 			}
3990 		}
3991 
3992 		os_snprintf(id, sizeof(id), "%u", ifaces->dpp_pb_bi->id);
3993 		dpp_bootstrap_remove(ifaces->dpp, id);
3994 		ifaces->dpp_pb_bi = NULL;
3995 	}
3996 
3997 	ifaces->dpp_pb_result_indicated = false;
3998 
3999 	str_clear_free(ifaces->dpp_pb_cmd);
4000 	ifaces->dpp_pb_cmd = NULL;
4001 }
4002 
4003 #endif /* CONFIG_DPP3 */
4004 
4005 
4006 #ifdef CONFIG_DPP2
hostapd_dpp_configurator_connectivity(struct hostapd_data * hapd)4007 bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd)
4008 {
4009 	return hapd->conf->dpp_configurator_connectivity ||
4010 		(hapd->iface->interfaces &&
4011 		 dpp_relay_controller_available(hapd->iface->interfaces->dpp));
4012 }
4013 #endif /* CONFIG_DPP2 */
4014