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