• 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 	struct sae_password_entry *e;
2410 	int conf_id = -1;
2411 	bool sae = false, psk = false;
2412 	size_t len;
2413 
2414 	if (hapd->dpp_pkex) {
2415 		wpa_printf(MSG_DEBUG,
2416 			   "PDP: Sending previously generated PKEX Exchange Request to "
2417 			   MACSTR, MAC2STR(src));
2418 		msg = hapd->dpp_pkex->exchange_req;
2419 		hostapd_drv_send_action(hapd, freq, 0, src,
2420 					wpabuf_head(msg), wpabuf_len(msg));
2421 		return;
2422 	}
2423 
2424 	wpa_printf(MSG_DEBUG, "DPP: Initiate PKEX for push button with "
2425 		   MACSTR, MAC2STR(src));
2426 
2427 	hapd->dpp_pkex_bi = ifaces->dpp_pb_bi;
2428 	os_memcpy(ifaces->dpp_pb_resp_hash, r_hash, SHA256_MAC_LEN);
2429 
2430 	pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
2431 			     "PBPKEX", (const char *) ifaces->dpp_pb_c_nonce,
2432 			     ifaces->dpp_pb_bi->curve->nonce_len,
2433 			     true);
2434 	if (!pkex) {
2435 		hostapd_dpp_push_button_stop(hapd);
2436 		return;
2437 	}
2438 	pkex->freq = freq;
2439 
2440 	hapd->dpp_pkex = pkex;
2441 	msg = hapd->dpp_pkex->exchange_req;
2442 
2443 	if (ifaces->dpp_pb_cmd) {
2444 		/* Use the externally provided configuration */
2445 		os_free(hapd->dpp_pkex_auth_cmd);
2446 		len = 30 + os_strlen(ifaces->dpp_pb_cmd);
2447 		hapd->dpp_pkex_auth_cmd = os_malloc(len);
2448 		if (!hapd->dpp_pkex_auth_cmd) {
2449 			hostapd_dpp_push_button_stop(hapd);
2450 			return;
2451 		}
2452 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2453 			    hapd->dpp_pkex_bi->id, ifaces->dpp_pb_cmd);
2454 		goto send_frame;
2455 	}
2456 
2457 	/* Build config based on the current AP configuration */
2458 	wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
2459 			 (const u8 *) hapd->conf->ssid.ssid,
2460 			 hapd->conf->ssid.ssid_len);
2461 
2462 	if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
2463 		/* TODO: If a local Configurator has been enabled, allow a
2464 		 * DPP AKM credential to be provisioned by setting conf_id. */
2465 	}
2466 
2467 	if (hapd->conf->wpa & WPA_PROTO_RSN) {
2468 		psk = hapd->conf->wpa_key_mgmt & (WPA_KEY_MGMT_PSK |
2469 						  WPA_KEY_MGMT_PSK_SHA256);
2470 #ifdef CONFIG_SAE
2471 		sae = hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE;
2472 #endif /* CONFIG_SAE */
2473 	}
2474 
2475 #ifdef CONFIG_SAE
2476 	for (e = hapd->conf->sae_passwords; sae && e && !password;
2477 	     e = e->next) {
2478 		if (e->identifier || !is_broadcast_ether_addr(e->peer_addr))
2479 			continue;
2480 		password = e->password;
2481 	}
2482 #endif /* CONFIG_SAE */
2483 	if (!password && hapd->conf->ssid.wpa_passphrase_set &&
2484 	    hapd->conf->ssid.wpa_passphrase)
2485 		password = hapd->conf->ssid.wpa_passphrase;
2486 	if (password) {
2487 		len = 2 * os_strlen(password) + 1;
2488 		pass_hex = os_malloc(len);
2489 		if (!pass_hex) {
2490 			hostapd_dpp_push_button_stop(hapd);
2491 			return;
2492 		}
2493 		wpa_snprintf_hex(pass_hex, len, (const u8 *) password,
2494 				 os_strlen(password));
2495 	}
2496 
2497 	if (conf_id > 0 && sae && psk && pass_hex) {
2498 		os_snprintf(cmd, sizeof(cmd),
2499 			    "conf=sta-dpp+psk+sae configurator=%d ssid=%s pass=%s",
2500 			    conf_id, ssid_hex, pass_hex);
2501 	} else if (conf_id > 0 && sae && pass_hex) {
2502 		os_snprintf(cmd, sizeof(cmd),
2503 			    "conf=sta-dpp+sae configurator=%d ssid=%s pass=%s",
2504 			    conf_id, ssid_hex, pass_hex);
2505 	} else if (conf_id > 0) {
2506 		os_snprintf(cmd, sizeof(cmd),
2507 			    "conf=sta-dpp configurator=%d ssid=%s",
2508 			    conf_id, ssid_hex);
2509 	} if (sae && psk && pass_hex) {
2510 		os_snprintf(cmd, sizeof(cmd),
2511 			    "conf=sta-psk+sae ssid=%s pass=%s",
2512 			    ssid_hex, pass_hex);
2513 	} else if (sae && pass_hex) {
2514 		os_snprintf(cmd, sizeof(cmd),
2515 			    "conf=sta-sae ssid=%s pass=%s",
2516 			    ssid_hex, pass_hex);
2517 	} else if (psk && pass_hex) {
2518 		os_snprintf(cmd, sizeof(cmd),
2519 			    "conf=sta-psk ssid=%s pass=%s",
2520 			    ssid_hex, pass_hex);
2521 	} else {
2522 		wpa_printf(MSG_INFO,
2523 			   "DPP: Unsupported AP configuration for push button");
2524 		str_clear_free(pass_hex);
2525 		hostapd_dpp_push_button_stop(hapd);
2526 		return;
2527 	}
2528 	str_clear_free(pass_hex);
2529 
2530 	os_free(hapd->dpp_pkex_auth_cmd);
2531 	len = 30 + os_strlen(cmd);
2532 	hapd->dpp_pkex_auth_cmd = os_malloc(len);
2533 	if (hapd->dpp_pkex_auth_cmd)
2534 		os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2535 			    hapd->dpp_pkex_bi->id, cmd);
2536 	forced_memzero(cmd, sizeof(cmd));
2537 	if (!hapd->dpp_pkex_auth_cmd) {
2538 		hostapd_dpp_push_button_stop(hapd);
2539 		return;
2540 	}
2541 
2542 send_frame:
2543 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2544 		" freq=%u type=%d", MAC2STR(src), freq,
2545 		DPP_PA_PKEX_EXCHANGE_REQ);
2546 	hostapd_drv_send_action(hapd, pkex->freq, 0, src,
2547 				wpabuf_head(msg), wpabuf_len(msg));
2548 	pkex->exch_req_wait_time = 2000;
2549 	pkex->exch_req_tries = 1;
2550 }
2551 
2552 
2553 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)2554 hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data *hapd,
2555 					const u8 *src, const u8 *hdr,
2556 					const u8 *buf, size_t len,
2557 					unsigned int freq)
2558 {
2559 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2560 	const u8 *r_hash;
2561 	u16 r_hash_len;
2562 	unsigned int i;
2563 	bool found = false;
2564 	struct dpp_pb_info *info, *tmp;
2565 	struct os_reltime now, age;
2566 	struct wpabuf *msg;
2567 
2568 	if (!ifaces)
2569 		return;
2570 
2571 	os_get_reltime(&now);
2572 	wpa_printf(MSG_DEBUG, "DPP: Push Button Presence Announcement from "
2573 		   MACSTR, MAC2STR(src));
2574 
2575 	r_hash = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
2576 			      &r_hash_len);
2577 	if (!r_hash || r_hash_len != SHA256_MAC_LEN) {
2578 		wpa_printf(MSG_DEBUG,
2579 			   "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
2580 		return;
2581 	}
2582 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
2583 		    r_hash, r_hash_len);
2584 
2585 	for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2586 		info = &ifaces->dpp_pb[i];
2587 		if ((info->rx_time.sec == 0 && info->rx_time.usec == 0) ||
2588 		    os_memcmp(r_hash, info->hash, SHA256_MAC_LEN) != 0)
2589 			continue;
2590 		wpa_printf(MSG_DEBUG,
2591 			   "DPP: Active push button Enrollee already known");
2592 		found = true;
2593 		info->rx_time = now;
2594 	}
2595 
2596 	if (!found) {
2597 		for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2598 			tmp = &ifaces->dpp_pb[i];
2599 			if (tmp->rx_time.sec == 0 && tmp->rx_time.usec == 0)
2600 				continue;
2601 
2602 			if (os_reltime_expired(&now, &tmp->rx_time, 120)) {
2603 				wpa_hexdump(MSG_DEBUG,
2604 					    "DPP: Push button Enrollee hash expired",
2605 					    tmp->hash, SHA256_MAC_LEN);
2606 				tmp->rx_time.sec = 0;
2607 				tmp->rx_time.usec = 0;
2608 				continue;
2609 			}
2610 
2611 			wpa_hexdump(MSG_DEBUG,
2612 				    "DPP: Push button session overlap with hash",
2613 				    tmp->hash, SHA256_MAC_LEN);
2614 			if (!ifaces->dpp_pb_result_indicated &&
2615 			    hostapd_dpp_pb_active(hapd)) {
2616 				wpa_msg(hapd->msg_ctx, MSG_INFO,
2617 					DPP_EVENT_PB_RESULT "session-overlap");
2618 				ifaces->dpp_pb_result_indicated = true;
2619 			}
2620 			hostapd_dpp_push_button_stop(hapd);
2621 			return;
2622 		}
2623 
2624 		/* Replace the oldest entry */
2625 		info = &ifaces->dpp_pb[0];
2626 		for (i = 1; i < DPP_PB_INFO_COUNT; i++) {
2627 			tmp = &ifaces->dpp_pb[i];
2628 			if (os_reltime_before(&tmp->rx_time, &info->rx_time))
2629 				info = tmp;
2630 		}
2631 		wpa_printf(MSG_DEBUG, "DPP: New active push button Enrollee");
2632 		os_memcpy(info->hash, r_hash, SHA256_MAC_LEN);
2633 		info->rx_time = now;
2634 	}
2635 
2636 	if (!hostapd_dpp_pb_active(hapd)) {
2637 		wpa_printf(MSG_DEBUG,
2638 			   "DPP: Discard message since own push button has not been pressed");
2639 		return;
2640 	}
2641 
2642 	if (ifaces->dpp_pb_announce_time.sec == 0 &&
2643 	    ifaces->dpp_pb_announce_time.usec == 0) {
2644 		/* Start a wait before allowing PKEX to be initiated */
2645 		ifaces->dpp_pb_announce_time = now;
2646 	}
2647 
2648 	if (!ifaces->dpp_pb_bi) {
2649 		int res;
2650 
2651 		res = dpp_bootstrap_gen(ifaces->dpp, "type=pkex");
2652 		if (res < 0)
2653 			return;
2654 		ifaces->dpp_pb_bi = dpp_bootstrap_get_id(ifaces->dpp, res);
2655 		if (!ifaces->dpp_pb_bi)
2656 			return;
2657 
2658 		if (random_get_bytes(ifaces->dpp_pb_c_nonce,
2659 				     ifaces->dpp_pb_bi->curve->nonce_len)) {
2660 			wpa_printf(MSG_ERROR,
2661 				   "DPP: Failed to generate C-nonce");
2662 			hostapd_dpp_push_button_stop(hapd);
2663 			return;
2664 		}
2665 	}
2666 
2667 	/* Skip the response if one was sent within last 50 ms since the
2668 	 * Enrollee is going to send out at least three announcement messages.
2669 	 */
2670 	os_reltime_sub(&now, &ifaces->dpp_pb_last_resp, &age);
2671 	if (age.sec == 0 && age.usec < 50000) {
2672 		wpa_printf(MSG_DEBUG,
2673 			   "DPP: Skip Push Button Presence Announcement Response frame immediately after having sent one");
2674 		return;
2675 	}
2676 
2677 	msg = dpp_build_pb_announcement_resp(
2678 		ifaces->dpp_pb_bi, r_hash, ifaces->dpp_pb_c_nonce,
2679 		ifaces->dpp_pb_bi->curve->nonce_len);
2680 	if (!msg) {
2681 		hostapd_dpp_push_button_stop(hapd);
2682 		return;
2683 	}
2684 
2685 	wpa_printf(MSG_DEBUG,
2686 		   "DPP: Send Push Button Presence Announcement Response to "
2687 		   MACSTR, MAC2STR(src));
2688 	ifaces->dpp_pb_last_resp = now;
2689 
2690 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2691 		" freq=%u type=%d", MAC2STR(src), freq,
2692 		DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP);
2693 	hostapd_drv_send_action(hapd, freq, 0, src,
2694 				wpabuf_head(msg), wpabuf_len(msg));
2695 	wpabuf_free(msg);
2696 
2697 	if (os_reltime_expired(&now, &ifaces->dpp_pb_announce_time, 15))
2698 		hostapd_dpp_pb_pkex_init(hapd, freq, src, r_hash);
2699 }
2700 
2701 
2702 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)2703 hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data *hapd, const u8 *src,
2704 				     const u8 *hdr, const u8 *buf, size_t len,
2705 				     unsigned int freq)
2706 {
2707 	const u8 *trans_id, *version;
2708 	u16 trans_id_len, version_len;
2709 	struct wpabuf *msg;
2710 	u8 ver = DPP_VERSION;
2711 	int conn_ver;
2712 
2713 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Query from "
2714 		   MACSTR, MAC2STR(src));
2715 
2716 	if (!hapd_dpp_connector_available(hapd))
2717 		return;
2718 
2719 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2720 			       &trans_id_len);
2721 	if (!trans_id || trans_id_len != 1) {
2722 		wpa_printf(MSG_DEBUG,
2723 			   "DPP: Peer did not include Transaction ID");
2724 		return;
2725 	}
2726 
2727 	version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2728 			       &version_len);
2729 	if (!version || version_len != 1) {
2730 		wpa_printf(MSG_DEBUG,
2731 			   "DPP: Peer did not include Protocol Version");
2732 		return;
2733 	}
2734 
2735 	wpa_printf(MSG_DEBUG, "DPP: Transaction ID %u, Version %u",
2736 		   trans_id[0], version[0]);
2737 
2738 	len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
2739 	msg = dpp_alloc_msg(DPP_PA_PRIV_PEER_INTRO_NOTIFY, len);
2740 	if (!msg)
2741 		return;
2742 
2743 	/* Transaction ID */
2744 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
2745 	wpabuf_put_le16(msg, 1);
2746 	wpabuf_put_u8(msg, trans_id[0]);
2747 
2748 	/* Protocol Version */
2749 	conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
2750 	if (conn_ver > 0 && ver != conn_ver) {
2751 		wpa_printf(MSG_DEBUG,
2752 			   "DPP: Use Connector version %d instead of current protocol version %d",
2753 			   conn_ver, ver);
2754 		ver = conn_ver;
2755 	}
2756 	wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2757 	wpabuf_put_le16(msg, 1);
2758 	wpabuf_put_u8(msg, ver);
2759 
2760 	/* DPP Connector */
2761 	wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
2762 	wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
2763 	wpabuf_put_str(msg, hapd->conf->dpp_connector);
2764 
2765 	wpa_printf(MSG_DEBUG, "DPP: Send Private Peer Introduction Notify to "
2766 		   MACSTR, MAC2STR(src));
2767 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2768 		" freq=%u type=%d", MAC2STR(src), freq,
2769 		DPP_PA_PRIV_PEER_INTRO_NOTIFY);
2770 	hostapd_drv_send_action(hapd, freq, 0, src,
2771 				wpabuf_head(msg), wpabuf_len(msg));
2772 	wpabuf_free(msg);
2773 }
2774 
2775 
2776 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)2777 hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data *hapd, const u8 *src,
2778 				      const u8 *hdr, const u8 *buf, size_t len,
2779 				      unsigned int freq)
2780 {
2781 	struct crypto_ec_key *own_key;
2782 	const struct dpp_curve_params *curve;
2783 	enum hpke_kem_id kem_id;
2784 	enum hpke_kdf_id kdf_id;
2785 	enum hpke_aead_id aead_id;
2786 	const u8 *aad = hdr;
2787 	size_t aad_len = DPP_HDR_LEN;
2788 	struct wpabuf *pt;
2789 	const u8 *trans_id, *wrapped, *version, *connector;
2790 	u16 trans_id_len, wrapped_len, version_len, connector_len;
2791 	struct os_time now;
2792 	struct dpp_introduction intro;
2793 	os_time_t expire;
2794 	int expiration;
2795 	enum dpp_status_error res;
2796 	u8 pkhash[SHA256_MAC_LEN];
2797 
2798 	os_memset(&intro, 0, sizeof(intro));
2799 
2800 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Update from "
2801 		   MACSTR, MAC2STR(src));
2802 
2803 	if (!hapd_dpp_connector_available(hapd))
2804 		return;
2805 
2806 	os_get_time(&now);
2807 
2808 	if (hapd->conf->dpp_netaccesskey_expiry &&
2809 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2810 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2811 		return;
2812 	}
2813 
2814 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2815 			       &trans_id_len);
2816 	if (!trans_id || trans_id_len != 1) {
2817 		wpa_printf(MSG_DEBUG,
2818 			   "DPP: Peer did not include Transaction ID");
2819 		return;
2820 	}
2821 
2822 	wrapped = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
2823 			       &wrapped_len);
2824 	if (!wrapped) {
2825 		wpa_printf(MSG_DEBUG, "DPP: Peer did not include Wrapped Data");
2826 		return;
2827 	}
2828 
2829 	own_key = dpp_set_keypair(&curve,
2830 				  wpabuf_head(hapd->conf->dpp_netaccesskey),
2831 				  wpabuf_len(hapd->conf->dpp_netaccesskey));
2832 	if (!own_key) {
2833 		wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
2834 		return;
2835 	}
2836 
2837 	if (dpp_hpke_suite(curve->ike_group, &kem_id, &kdf_id, &aead_id) < 0) {
2838 		wpa_printf(MSG_ERROR, "DPP: Unsupported curve %d",
2839 			   curve->ike_group);
2840 		crypto_ec_key_deinit(own_key);
2841 		return;
2842 	}
2843 
2844 	pt = hpke_base_open(kem_id, kdf_id, aead_id, own_key, NULL, 0,
2845 			    aad, aad_len, wrapped, wrapped_len);
2846 	crypto_ec_key_deinit(own_key);
2847 	if (!pt) {
2848 		wpa_printf(MSG_INFO, "DPP: Failed to decrypt Connector");
2849 		return;
2850 	}
2851 	wpa_hexdump_buf(MSG_MSGDUMP, "DPP: HPKE-Decrypted Wrapped Data", pt);
2852 
2853 	connector = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2854 				 DPP_ATTR_CONNECTOR, &connector_len);
2855 	if (!connector) {
2856 		wpa_printf(MSG_DEBUG,
2857 			   "DPP: Peer did not include its Connector");
2858 		goto done;
2859 	}
2860 
2861 	version = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2862 			       DPP_ATTR_PROTOCOL_VERSION, &version_len);
2863 	if (!version || version_len < 1) {
2864 		wpa_printf(MSG_DEBUG,
2865 			   "DPP: Peer did not include Protocol Version");
2866 		goto done;
2867 	}
2868 
2869 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2870 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
2871 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
2872 			     wpabuf_head(hapd->conf->dpp_csign),
2873 			     wpabuf_len(hapd->conf->dpp_csign),
2874 			     connector, connector_len, &expire, pkhash);
2875 	if (res == 255) {
2876 		wpa_printf(MSG_INFO,
2877 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
2878 			   MACSTR ")", MAC2STR(src));
2879 		goto done;
2880 	}
2881 	if (res != DPP_STATUS_OK) {
2882 		wpa_printf(MSG_INFO,
2883 			   "DPP: Network Introduction protocol resulted in failure (peer "
2884 			   MACSTR " status %d)", MAC2STR(src), res);
2885 		goto done;
2886 	}
2887 
2888 	if (intro.peer_version && intro.peer_version >= 2) {
2889 		u8 attr_version = 1;
2890 
2891 		if (version && version_len >= 1)
2892 			attr_version = version[0];
2893 		if (attr_version != intro.peer_version) {
2894 			wpa_printf(MSG_INFO,
2895 				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2896 				   intro.peer_version, attr_version);
2897 			goto done;
2898 		}
2899 	}
2900 
2901 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2902 		expire = hapd->conf->dpp_netaccesskey_expiry;
2903 	if (expire)
2904 		expiration = expire - now.sec;
2905 	else
2906 		expiration = 0;
2907 
2908 	if (wpa_auth_pmksa_add3(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2909 				intro.pmkid, expiration,
2910 				WPA_KEY_MGMT_DPP, pkhash) < 0) {
2911 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2912 		goto done;
2913 	}
2914 
2915 	wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction completed with "
2916 		   MACSTR, MAC2STR(src));
2917 
2918 done:
2919 	dpp_peer_intro_deinit(&intro);
2920 	wpabuf_free(pt);
2921 }
2922 
2923 #endif /* CONFIG_DPP3 */
2924 
2925 
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2926 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
2927 			   const u8 *buf, size_t len, unsigned int freq)
2928 {
2929 	u8 crypto_suite;
2930 	enum dpp_public_action_frame_type type;
2931 	const u8 *hdr;
2932 	unsigned int pkex_t;
2933 
2934 	if (len < DPP_HDR_LEN)
2935 		return;
2936 	if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
2937 		return;
2938 	hdr = buf;
2939 	buf += 4;
2940 	len -= 4;
2941 	crypto_suite = *buf++;
2942 	type = *buf++;
2943 	len -= 2;
2944 
2945 	wpa_printf(MSG_DEBUG,
2946 		   "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2947 		   MACSTR " freq=%u",
2948 		   crypto_suite, type, MAC2STR(src), freq);
2949 	if (crypto_suite != 1) {
2950 		wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
2951 			   crypto_suite);
2952 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2953 			" freq=%u type=%d ignore=unsupported-crypto-suite",
2954 			MAC2STR(src), freq, type);
2955 		return;
2956 	}
2957 	wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
2958 	if (dpp_check_attrs(buf, len) < 0) {
2959 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2960 			" freq=%u type=%d ignore=invalid-attributes",
2961 			MAC2STR(src), freq, type);
2962 		return;
2963 	}
2964 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2965 		" freq=%u type=%d", MAC2STR(src), freq, type);
2966 
2967 #ifdef CONFIG_DPP2
2968 	if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2969 				src, hdr, buf, len, freq, NULL, NULL,
2970 				hapd) == 0)
2971 		return;
2972 #endif /* CONFIG_DPP2 */
2973 
2974 	switch (type) {
2975 	case DPP_PA_AUTHENTICATION_REQ:
2976 		hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
2977 		break;
2978 	case DPP_PA_AUTHENTICATION_RESP:
2979 		hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
2980 		break;
2981 	case DPP_PA_AUTHENTICATION_CONF:
2982 		hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
2983 		break;
2984 	case DPP_PA_PEER_DISCOVERY_REQ:
2985 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
2986 		break;
2987 #ifdef CONFIG_DPP3
2988 	case DPP_PA_PKEX_EXCHANGE_REQ:
2989 		/* This is for PKEXv2, but for now, process only with
2990 		 * CONFIG_DPP3 to avoid issues with a capability that has not
2991 		 * been tested with other implementations. */
2992 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
2993 						 true);
2994 		break;
2995 #endif /* CONFIG_DPP3 */
2996 	case DPP_PA_PKEX_V1_EXCHANGE_REQ:
2997 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
2998 						 false);
2999 		break;
3000 	case DPP_PA_PKEX_EXCHANGE_RESP:
3001 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
3002 		break;
3003 	case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
3004 		hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
3005 						      freq);
3006 		break;
3007 	case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
3008 		hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
3009 						       freq);
3010 		break;
3011 #ifdef CONFIG_DPP2
3012 	case DPP_PA_CONFIGURATION_RESULT:
3013 		hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
3014 		break;
3015 	case DPP_PA_CONNECTION_STATUS_RESULT:
3016 		hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
3017 		break;
3018 	case DPP_PA_PRESENCE_ANNOUNCEMENT:
3019 		hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
3020 						     freq);
3021 		break;
3022 	case DPP_PA_RECONFIG_ANNOUNCEMENT:
3023 		hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
3024 						     freq);
3025 		break;
3026 	case DPP_PA_RECONFIG_AUTH_RESP:
3027 		hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
3028 						  freq);
3029 		break;
3030 #endif /* CONFIG_DPP2 */
3031 #ifdef CONFIG_DPP3
3032 	case DPP_PA_PB_PRESENCE_ANNOUNCEMENT:
3033 		hostapd_dpp_rx_pb_presence_announcement(hapd, src, hdr,
3034 							buf, len, freq);
3035 		break;
3036 	case DPP_PA_PRIV_PEER_INTRO_QUERY:
3037 		hostapd_dpp_rx_priv_peer_intro_query(hapd, src, hdr,
3038 						     buf, len, freq);
3039 		break;
3040 	case DPP_PA_PRIV_PEER_INTRO_UPDATE:
3041 		hostapd_dpp_rx_priv_peer_intro_update(hapd, src, hdr,
3042 						      buf, len, freq);
3043 		break;
3044 #endif /* CONFIG_DPP3 */
3045 	default:
3046 		wpa_printf(MSG_DEBUG,
3047 			   "DPP: Ignored unsupported frame subtype %d", type);
3048 		break;
3049 	}
3050 
3051 	if (hapd->dpp_pkex)
3052 		pkex_t = hapd->dpp_pkex->t;
3053 	else if (hapd->dpp_pkex_bi)
3054 		pkex_t = hapd->dpp_pkex_bi->pkex_t;
3055 	else
3056 		pkex_t = 0;
3057 	if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
3058 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
3059 		hostapd_dpp_pkex_remove(hapd, "*");
3060 	}
3061 }
3062 
3063 
3064 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)3065 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
3066 			    const u8 *query, size_t query_len,
3067 			    const u8 *data, size_t data_len)
3068 {
3069 	struct dpp_authentication *auth = hapd->dpp_auth;
3070 	struct wpabuf *resp;
3071 
3072 	wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
3073 	if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
3074 	    os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
3075 #ifdef CONFIG_DPP2
3076 		if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
3077 				     data_len) == 0) {
3078 			/* Response will be forwarded once received over TCP */
3079 			return NULL;
3080 		}
3081 #endif /* CONFIG_DPP2 */
3082 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
3083 		return NULL;
3084 	}
3085 
3086 	if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
3087 		wpa_printf(MSG_DEBUG,
3088 			   "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
3089 		/* hostapd_dpp_auth_success() would normally have been called
3090 		 * from TX status handler, but since there was no such handler
3091 		 * call yet, simply send out the event message and proceed with
3092 		 * exchange. */
3093 		dpp_notify_auth_success(hapd->dpp_auth, 1);
3094 		hapd->dpp_auth_ok_on_ack = 0;
3095 	}
3096 
3097 	wpa_hexdump(MSG_DEBUG,
3098 		    "DPP: Received Configuration Request (GAS Query Request)",
3099 		    query, query_len);
3100 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
3101 		MAC2STR(sa));
3102 	resp = dpp_conf_req_rx(auth, query, query_len);
3103 	if (!resp)
3104 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3105 	return resp;
3106 }
3107 
3108 
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)3109 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
3110 {
3111 	struct dpp_authentication *auth = hapd->dpp_auth;
3112 #ifdef CONFIG_DPP3
3113 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3114 #endif /* CONFIG_DPP3 */
3115 
3116 	if (!auth)
3117 		return;
3118 
3119 #ifdef CONFIG_DPP3
3120 	if (auth->waiting_new_key && ok) {
3121 		wpa_printf(MSG_DEBUG, "DPP: Waiting for a new key");
3122 		return;
3123 	}
3124 #endif /* CONFIG_DPP3 */
3125 
3126 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
3127 		   ok);
3128 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3129 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3130 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3131 #ifdef CONFIG_DPP2
3132 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3133 				     hapd, NULL);
3134 	if (ok && auth->peer_version >= 2 &&
3135 	    auth->conf_resp_status == DPP_STATUS_OK) {
3136 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
3137 		auth->waiting_conf_result = 1;
3138 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
3139 				     hapd, NULL);
3140 		eloop_register_timeout(2, 0,
3141 				       hostapd_dpp_config_result_wait_timeout,
3142 				       hapd, NULL);
3143 		return;
3144 	}
3145 #endif /* CONFIG_DPP2 */
3146 	hostapd_drv_send_action_cancel_wait(hapd);
3147 
3148 	if (ok)
3149 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
3150 			"conf_status=%d", auth->conf_resp_status);
3151 	else
3152 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3153 	dpp_auth_deinit(hapd->dpp_auth);
3154 	hapd->dpp_auth = NULL;
3155 #ifdef CONFIG_DPP3
3156 	if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
3157 		if (ok)
3158 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3159 				"success");
3160 		else
3161 			wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3162 				"could-not-connect");
3163 		ifaces->dpp_pb_result_indicated = true;
3164 		if (ok)
3165 			hostapd_dpp_remove_pb_hash(hapd);
3166 		hostapd_dpp_push_button_stop(hapd);
3167 	}
3168 #endif /* CONFIG_DPP3 */
3169 }
3170 
3171 
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)3172 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
3173 {
3174 	struct dpp_authentication *auth;
3175 	int ret = -1;
3176 	char *curve = NULL;
3177 
3178 	auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
3179 	if (!auth)
3180 		return -1;
3181 
3182 	curve = get_param(cmd, " curve=");
3183 	hostapd_dpp_set_testing_options(hapd, auth);
3184 	if (dpp_set_configurator(auth, cmd) == 0 &&
3185 	    dpp_configurator_own_config(auth, curve, 1) == 0) {
3186 		hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
3187 		ret = 0;
3188 	}
3189 
3190 	dpp_auth_deinit(auth);
3191 	os_free(curve);
3192 
3193 	return ret;
3194 }
3195 
3196 
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)3197 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
3198 {
3199 	struct dpp_bootstrap_info *own_bi;
3200 	const char *pos, *end;
3201 #ifdef CONFIG_DPP3
3202 		enum dpp_pkex_ver ver = PKEX_VER_AUTO;
3203 #else /* CONFIG_DPP3 */
3204 		enum dpp_pkex_ver ver = PKEX_VER_ONLY_1;
3205 #endif /* CONFIG_DPP3 */
3206 	int tcp_port = DPP_TCP_PORT;
3207 	struct hostapd_ip_addr *ipaddr = NULL;
3208 #ifdef CONFIG_DPP2
3209 	struct hostapd_ip_addr ipaddr_buf;
3210 	char *addr;
3211 
3212 	pos = os_strstr(cmd, " tcp_port=");
3213 	if (pos) {
3214 		pos += 10;
3215 		tcp_port = atoi(pos);
3216 	}
3217 
3218 	addr = get_param(cmd, " tcp_addr=");
3219 	if (addr) {
3220 		int res;
3221 
3222 		res = hostapd_parse_ip_addr(addr, &ipaddr_buf);
3223 		os_free(addr);
3224 		if (res)
3225 			return -1;
3226 		ipaddr = &ipaddr_buf;
3227 	}
3228 #endif /* CONFIG_DPP2 */
3229 
3230 	pos = os_strstr(cmd, " own=");
3231 	if (!pos)
3232 		return -1;
3233 	pos += 5;
3234 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3235 	if (!own_bi) {
3236 		wpa_printf(MSG_DEBUG,
3237 			   "DPP: Identified bootstrap info not found");
3238 		return -1;
3239 	}
3240 	if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
3241 		wpa_printf(MSG_DEBUG,
3242 			   "DPP: Identified bootstrap info not for PKEX");
3243 		return -1;
3244 	}
3245 	hapd->dpp_pkex_bi = own_bi;
3246 	own_bi->pkex_t = 0; /* clear pending errors on new code */
3247 
3248 	os_free(hapd->dpp_pkex_identifier);
3249 	hapd->dpp_pkex_identifier = NULL;
3250 	pos = os_strstr(cmd, " identifier=");
3251 	if (pos) {
3252 		pos += 12;
3253 		end = os_strchr(pos, ' ');
3254 		if (!end)
3255 			return -1;
3256 		hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
3257 		if (!hapd->dpp_pkex_identifier)
3258 			return -1;
3259 		os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
3260 		hapd->dpp_pkex_identifier[end - pos] = '\0';
3261 	}
3262 
3263 	pos = os_strstr(cmd, " code=");
3264 	if (!pos)
3265 		return -1;
3266 	os_free(hapd->dpp_pkex_code);
3267 	hapd->dpp_pkex_code = os_strdup(pos + 6);
3268 	if (!hapd->dpp_pkex_code)
3269 		return -1;
3270 	hapd->dpp_pkex_code_len = os_strlen(hapd->dpp_pkex_code);
3271 
3272 	pos = os_strstr(cmd, " ver=");
3273 	if (pos) {
3274 		int v;
3275 
3276 		pos += 5;
3277 		v = atoi(pos);
3278 		if (v == 1)
3279 			ver = PKEX_VER_ONLY_1;
3280 		else if (v == 2)
3281 			ver = PKEX_VER_ONLY_2;
3282 		else
3283 			return -1;
3284 	}
3285 	hapd->dpp_pkex_ver = ver;
3286 
3287 	if (os_strstr(cmd, " init=1")) {
3288 		if (hostapd_dpp_pkex_init(hapd, ver, ipaddr, tcp_port) < 0)
3289 			return -1;
3290 	} else {
3291 #ifdef CONFIG_DPP2
3292 		dpp_controller_pkex_add(hapd->iface->interfaces->dpp, own_bi,
3293 					hapd->dpp_pkex_code,
3294 					hapd->dpp_pkex_identifier);
3295 #endif /* CONFIG_DPP2 */
3296 	}
3297 
3298 	/* TODO: Support multiple PKEX info entries */
3299 
3300 	os_free(hapd->dpp_pkex_auth_cmd);
3301 	hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
3302 
3303 	return 1;
3304 }
3305 
3306 
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)3307 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
3308 {
3309 	unsigned int id_val;
3310 
3311 	if (os_strcmp(id, "*") == 0) {
3312 		id_val = 0;
3313 	} else {
3314 		id_val = atoi(id);
3315 		if (id_val == 0)
3316 			return -1;
3317 	}
3318 
3319 	if ((id_val != 0 && id_val != 1))
3320 		return -1;
3321 
3322 	/* TODO: Support multiple PKEX entries */
3323 	os_free(hapd->dpp_pkex_code);
3324 	hapd->dpp_pkex_code = NULL;
3325 	os_free(hapd->dpp_pkex_identifier);
3326 	hapd->dpp_pkex_identifier = NULL;
3327 	os_free(hapd->dpp_pkex_auth_cmd);
3328 	hapd->dpp_pkex_auth_cmd = NULL;
3329 	hapd->dpp_pkex_bi = NULL;
3330 	/* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
3331 	dpp_pkex_free(hapd->dpp_pkex);
3332 	hapd->dpp_pkex = NULL;
3333 	return 0;
3334 }
3335 
3336 
hostapd_dpp_stop(struct hostapd_data * hapd)3337 void hostapd_dpp_stop(struct hostapd_data *hapd)
3338 {
3339 	dpp_auth_deinit(hapd->dpp_auth);
3340 	hapd->dpp_auth = NULL;
3341 	dpp_pkex_free(hapd->dpp_pkex);
3342 	hapd->dpp_pkex = NULL;
3343 #ifdef CONFIG_DPP3
3344 	hostapd_dpp_push_button_stop(hapd);
3345 #endif /* CONFIG_DPP3 */
3346 }
3347 
3348 
3349 #ifdef CONFIG_DPP2
3350 
hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)3351 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
3352 				 const u8 *msg, size_t len)
3353 {
3354 	struct hostapd_data *hapd = ctx;
3355 	u8 *buf;
3356 
3357 	if (freq == 0)
3358 		freq = hapd->iface->freq;
3359 
3360 	wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
3361 		   MAC2STR(addr), freq);
3362 	buf = os_malloc(2 + len);
3363 	if (!buf)
3364 		return;
3365 	buf[0] = WLAN_ACTION_PUBLIC;
3366 	buf[1] = WLAN_PA_VENDOR_SPECIFIC;
3367 	os_memcpy(buf + 2, msg, len);
3368 	hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
3369 	os_free(buf);
3370 }
3371 
3372 
hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)3373 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
3374 					  u8 dialog_token, int prot,
3375 					  struct wpabuf *buf)
3376 {
3377 	struct hostapd_data *hapd = ctx;
3378 
3379 	gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf, 0);
3380 }
3381 
3382 #endif /* CONFIG_DPP2 */
3383 
3384 
hostapd_dpp_add_controllers(struct hostapd_data * hapd)3385 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
3386 {
3387 #ifdef CONFIG_DPP2
3388 	struct dpp_controller_conf *ctrl;
3389 	struct dpp_relay_config config;
3390 
3391 	os_memset(&config, 0, sizeof(config));
3392 	config.msg_ctx = hapd->msg_ctx;
3393 	config.cb_ctx = hapd;
3394 	config.tx = hostapd_dpp_relay_tx;
3395 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3396 	for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
3397 		config.ipaddr = &ctrl->ipaddr;
3398 		config.pkhash = ctrl->pkhash;
3399 		if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
3400 					     &config) < 0)
3401 			return -1;
3402 	}
3403 
3404 	if (hapd->conf->dpp_relay_port)
3405 		dpp_relay_listen(hapd->iface->interfaces->dpp,
3406 				 hapd->conf->dpp_relay_port,
3407 				 &config);
3408 #endif /* CONFIG_DPP2 */
3409 
3410 	return 0;
3411 }
3412 
3413 
3414 #ifdef CONFIG_DPP2
3415 
hostapd_dpp_add_controller(struct hostapd_data * hapd,const char * cmd)3416 int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd)
3417 {
3418 	struct dpp_relay_config config;
3419 	struct hostapd_ip_addr addr;
3420 	u8 pkhash[SHA256_MAC_LEN];
3421 	char *pos, *tmp;
3422 	int ret = -1;
3423 	bool prev_state, new_state;
3424 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3425 
3426 	tmp = os_strdup(cmd);
3427 	if (!tmp)
3428 		goto fail;
3429 	pos = os_strchr(tmp, ' ');
3430 	if (!pos)
3431 		goto fail;
3432 	*pos++ = '\0';
3433 	if (hostapd_parse_ip_addr(tmp, &addr) < 0 ||
3434 	    hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0)
3435 		goto fail;
3436 
3437 	os_memset(&config, 0, sizeof(config));
3438 	config.msg_ctx = hapd->msg_ctx;
3439 	config.cb_ctx = hapd;
3440 	config.tx = hostapd_dpp_relay_tx;
3441 	config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3442 	config.ipaddr = &addr;
3443 	config.pkhash = pkhash;
3444 	prev_state = dpp_relay_controller_available(dpp);
3445 	ret = dpp_relay_add_controller(dpp, &config);
3446 	new_state = dpp_relay_controller_available(dpp);
3447 	if (new_state != prev_state)
3448 		ieee802_11_update_beacons(hapd->iface);
3449 fail:
3450 	os_free(tmp);
3451 	return ret;
3452 }
3453 
3454 
hostapd_dpp_remove_controller(struct hostapd_data * hapd,const char * cmd)3455 void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd)
3456 {
3457 	struct hostapd_ip_addr addr;
3458 	bool prev_state, new_state;
3459 	struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3460 
3461 	if (hostapd_parse_ip_addr(cmd, &addr) < 0)
3462 		return;
3463 	prev_state = dpp_relay_controller_available(dpp);
3464 	dpp_relay_remove_controller(dpp, &addr);
3465 	new_state = dpp_relay_controller_available(dpp);
3466 	if (new_state != prev_state)
3467 		ieee802_11_update_beacons(hapd->iface);
3468 }
3469 
3470 #endif /* CONFIG_DPP2 */
3471 
3472 
hostapd_dpp_init(struct hostapd_data * hapd)3473 int hostapd_dpp_init(struct hostapd_data *hapd)
3474 {
3475 	hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
3476 	hapd->dpp_init_done = 1;
3477 	return hostapd_dpp_add_controllers(hapd);
3478 }
3479 
3480 
hostapd_dpp_deinit(struct hostapd_data * hapd)3481 void hostapd_dpp_deinit(struct hostapd_data *hapd)
3482 {
3483 #ifdef CONFIG_TESTING_OPTIONS
3484 	os_free(hapd->dpp_config_obj_override);
3485 	hapd->dpp_config_obj_override = NULL;
3486 	os_free(hapd->dpp_discovery_override);
3487 	hapd->dpp_discovery_override = NULL;
3488 	os_free(hapd->dpp_groups_override);
3489 	hapd->dpp_groups_override = NULL;
3490 	hapd->dpp_ignore_netaccesskey_mismatch = 0;
3491 #endif /* CONFIG_TESTING_OPTIONS */
3492 	if (!hapd->dpp_init_done)
3493 		return;
3494 	eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
3495 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3496 	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3497 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
3498 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3499 #ifdef CONFIG_DPP2
3500 	eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3501 			     hapd, NULL);
3502 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
3503 			     NULL);
3504 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
3505 			     NULL);
3506 	hostapd_dpp_chirp_stop(hapd);
3507 	if (hapd->iface->interfaces) {
3508 		dpp_relay_stop_listen(hapd->iface->interfaces->dpp);
3509 		dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
3510 	}
3511 #endif /* CONFIG_DPP2 */
3512 #ifdef CONFIG_DPP3
3513 	eloop_cancel_timeout(hostapd_dpp_build_new_key, hapd, NULL);
3514 	hostapd_dpp_push_button_stop(hapd);
3515 #endif /* CONFIG_DPP3 */
3516 	dpp_auth_deinit(hapd->dpp_auth);
3517 	hapd->dpp_auth = NULL;
3518 	hostapd_dpp_pkex_remove(hapd, "*");
3519 	hapd->dpp_pkex = NULL;
3520 	os_free(hapd->dpp_configurator_params);
3521 	hapd->dpp_configurator_params = NULL;
3522 	os_free(hapd->dpp_pkex_auth_cmd);
3523 	hapd->dpp_pkex_auth_cmd = NULL;
3524 }
3525 
3526 
3527 #ifdef CONFIG_DPP2
3528 
hostapd_dpp_controller_start(struct hostapd_data * hapd,const char * cmd)3529 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd)
3530 {
3531 	struct dpp_controller_config config;
3532 	const char *pos;
3533 
3534 	os_memset(&config, 0, sizeof(config));
3535 	config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
3536 	config.netrole = DPP_NETROLE_AP;
3537 	config.msg_ctx = hapd->msg_ctx;
3538 	config.cb_ctx = hapd;
3539 	config.process_conf_obj = hostapd_dpp_process_conf_obj;
3540 	if (cmd) {
3541 		pos = os_strstr(cmd, " tcp_port=");
3542 		if (pos) {
3543 			pos += 10;
3544 			config.tcp_port = atoi(pos);
3545 		}
3546 
3547 		pos = os_strstr(cmd, " role=");
3548 		if (pos) {
3549 			pos += 6;
3550 			if (os_strncmp(pos, "configurator", 12) == 0)
3551 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
3552 			else if (os_strncmp(pos, "enrollee", 8) == 0)
3553 				config.allowed_roles = DPP_CAPAB_ENROLLEE;
3554 			else if (os_strncmp(pos, "either", 6) == 0)
3555 				config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
3556 					DPP_CAPAB_ENROLLEE;
3557 			else
3558 				return -1;
3559 		}
3560 
3561 		config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
3562 	}
3563 	config.configurator_params = hapd->dpp_configurator_params;
3564 	return dpp_controller_start(hapd->iface->interfaces->dpp, &config);
3565 }
3566 
3567 
3568 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
3569 
hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)3570 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
3571 {
3572 	struct hostapd_data *hapd = eloop_ctx;
3573 
3574 	wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
3575 	hostapd_drv_send_action_cancel_wait(hapd);
3576 	hostapd_dpp_chirp_next(hapd, NULL);
3577 }
3578 
3579 
hostapd_dpp_chirp_start(struct hostapd_data * hapd)3580 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
3581 {
3582 	struct wpabuf *msg;
3583 	int type;
3584 
3585 	msg = hapd->dpp_presence_announcement;
3586 	type = DPP_PA_PRESENCE_ANNOUNCEMENT;
3587 	wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
3588 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
3589 		" freq=%u type=%d",
3590 		MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
3591 	if (hostapd_drv_send_action(
3592 		    hapd, hapd->dpp_chirp_freq, 2000, broadcast,
3593 		    wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
3594 	    eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
3595 				   hapd, NULL) < 0)
3596 		hostapd_dpp_chirp_stop(hapd);
3597 }
3598 
3599 
3600 static struct hostapd_hw_modes *
dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)3601 dpp_get_mode(struct hostapd_data *hapd,
3602 	     enum hostapd_hw_mode mode)
3603 {
3604 	struct hostapd_hw_modes *modes = hapd->iface->hw_features;
3605 	u16 num_modes = hapd->iface->num_hw_features;
3606 	u16 i;
3607 
3608 	for (i = 0; i < num_modes; i++) {
3609 		if (modes[i].mode != mode ||
3610 		    !modes[i].num_channels || !modes[i].channels)
3611 			continue;
3612 		return &modes[i];
3613 	}
3614 
3615 	return NULL;
3616 }
3617 
3618 
3619 static void
hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)3620 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
3621 {
3622 	struct hostapd_data *hapd = iface->bss[0];
3623 	struct wpa_scan_results *scan_res;
3624 	struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
3625 	unsigned int i;
3626 	struct hostapd_hw_modes *mode;
3627 	int c;
3628 	bool chan6 = hapd->iface->hw_features == NULL;
3629 
3630 	if (!bi)
3631 		return;
3632 
3633 	hapd->dpp_chirp_scan_done = 1;
3634 
3635 	scan_res = hostapd_driver_get_scan_results(hapd);
3636 
3637 	os_free(hapd->dpp_chirp_freqs);
3638 	hapd->dpp_chirp_freqs = NULL;
3639 
3640 	/* Channels from own bootstrapping info */
3641 	if (bi) {
3642 		for (i = 0; i < bi->num_freq; i++)
3643 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3644 					     bi->freq[i]);
3645 	}
3646 
3647 	/* Preferred chirping channels */
3648 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
3649 	if (mode) {
3650 		for (c = 0; c < mode->num_channels; c++) {
3651 			struct hostapd_channel_data *chan = &mode->channels[c];
3652 
3653 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3654 					  HOSTAPD_CHAN_RADAR) ||
3655 			    chan->freq != 2437)
3656 				continue;
3657 			chan6 = true;
3658 			break;
3659 		}
3660 	}
3661 	if (chan6)
3662 		int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
3663 
3664 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
3665 	if (mode) {
3666 		int chan44 = 0, chan149 = 0;
3667 
3668 		for (c = 0; c < mode->num_channels; c++) {
3669 			struct hostapd_channel_data *chan = &mode->channels[c];
3670 
3671 			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3672 					  HOSTAPD_CHAN_RADAR))
3673 				continue;
3674 			if (chan->freq == 5220)
3675 				chan44 = 1;
3676 			if (chan->freq == 5745)
3677 				chan149 = 1;
3678 		}
3679 		if (chan149)
3680 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
3681 		else if (chan44)
3682 			int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
3683 	}
3684 
3685 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
3686 	if (mode) {
3687 		for (c = 0; c < mode->num_channels; c++) {
3688 			struct hostapd_channel_data *chan = &mode->channels[c];
3689 
3690 			if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
3691 					   HOSTAPD_CHAN_RADAR)) ||
3692 			    chan->freq != 60480)
3693 				continue;
3694 			int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
3695 			break;
3696 		}
3697 	}
3698 
3699 	/* Add channels from scan results for APs that advertise Configurator
3700 	 * Connectivity element */
3701 	for (i = 0; scan_res && i < scan_res->num; i++) {
3702 		struct wpa_scan_res *bss = scan_res->res[i];
3703 		size_t ie_len = bss->ie_len;
3704 
3705 		if (!ie_len)
3706 			ie_len = bss->beacon_ie_len;
3707 		if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
3708 				  DPP_CC_IE_VENDOR_TYPE))
3709 			int_array_add_unique(&hapd->dpp_chirp_freqs,
3710 					     bss->freq);
3711 	}
3712 
3713 	if (!hapd->dpp_chirp_freqs ||
3714 	    eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
3715 				   hapd, NULL) < 0)
3716 		hostapd_dpp_chirp_stop(hapd);
3717 
3718 	wpa_scan_results_free(scan_res);
3719 }
3720 
3721 
hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)3722 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
3723 {
3724 	struct hostapd_data *hapd = eloop_ctx;
3725 	int i;
3726 
3727 	if (hapd->dpp_chirp_listen)
3728 		hostapd_dpp_listen_stop(hapd);
3729 
3730 	if (hapd->dpp_chirp_freq == 0) {
3731 		if (hapd->dpp_chirp_round % 4 == 0 &&
3732 		    !hapd->dpp_chirp_scan_done) {
3733 			struct wpa_driver_scan_params params;
3734 			int ret;
3735 
3736 			wpa_printf(MSG_DEBUG,
3737 				   "DPP: Update channel list for chirping");
3738 			os_memset(&params, 0, sizeof(params));
3739 			ret = hostapd_driver_scan(hapd, &params);
3740 			if (ret < 0) {
3741 				wpa_printf(MSG_DEBUG,
3742 					   "DPP: Failed to request a scan ret=%d (%s)",
3743 					   ret, strerror(-ret));
3744 				hostapd_dpp_chirp_scan_res_handler(hapd->iface);
3745 			} else {
3746 				hapd->iface->scan_cb =
3747 					hostapd_dpp_chirp_scan_res_handler;
3748 			}
3749 			return;
3750 		}
3751 		hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
3752 		hapd->dpp_chirp_round++;
3753 		wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
3754 			   hapd->dpp_chirp_round);
3755 	} else {
3756 		for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
3757 			if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
3758 				break;
3759 		if (!hapd->dpp_chirp_freqs[i]) {
3760 			wpa_printf(MSG_DEBUG,
3761 				   "DPP: Previous chirp freq %d not found",
3762 				   hapd->dpp_chirp_freq);
3763 			return;
3764 		}
3765 		i++;
3766 		if (hapd->dpp_chirp_freqs[i]) {
3767 			hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
3768 		} else {
3769 			hapd->dpp_chirp_iter--;
3770 			if (hapd->dpp_chirp_iter <= 0) {
3771 				wpa_printf(MSG_DEBUG,
3772 					   "DPP: Chirping iterations completed");
3773 				hostapd_dpp_chirp_stop(hapd);
3774 				return;
3775 			}
3776 			hapd->dpp_chirp_freq = 0;
3777 			hapd->dpp_chirp_scan_done = 0;
3778 			if (eloop_register_timeout(30, 0,
3779 						   hostapd_dpp_chirp_next,
3780 						   hapd, NULL) < 0) {
3781 				hostapd_dpp_chirp_stop(hapd);
3782 				return;
3783 			}
3784 			if (hapd->dpp_chirp_listen) {
3785 				wpa_printf(MSG_DEBUG,
3786 					   "DPP: Listen on %d MHz during chirp 30 second wait",
3787 					hapd->dpp_chirp_listen);
3788 				/* TODO: start listen on the channel */
3789 			} else {
3790 				wpa_printf(MSG_DEBUG,
3791 					   "DPP: Wait 30 seconds before starting the next chirping round");
3792 			}
3793 			return;
3794 		}
3795 	}
3796 
3797 	hostapd_dpp_chirp_start(hapd);
3798 }
3799 
3800 
hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)3801 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
3802 {
3803 	const char *pos;
3804 	int iter = 1, listen_freq = 0;
3805 	struct dpp_bootstrap_info *bi;
3806 
3807 	pos = os_strstr(cmd, " own=");
3808 	if (!pos)
3809 		return -1;
3810 	pos += 5;
3811 	bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3812 	if (!bi) {
3813 		wpa_printf(MSG_DEBUG,
3814 			   "DPP: Identified bootstrap info not found");
3815 		return -1;
3816 	}
3817 
3818 	pos = os_strstr(cmd, " iter=");
3819 	if (pos) {
3820 		iter = atoi(pos + 6);
3821 		if (iter <= 0)
3822 			return -1;
3823 	}
3824 
3825 	pos = os_strstr(cmd, " listen=");
3826 	if (pos) {
3827 		listen_freq = atoi(pos + 8);
3828 		if (listen_freq <= 0)
3829 			return -1;
3830 	}
3831 
3832 	hostapd_dpp_chirp_stop(hapd);
3833 	hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
3834 	hapd->dpp_qr_mutual = 0;
3835 	hapd->dpp_chirp_bi = bi;
3836 	hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
3837 	if (!hapd->dpp_presence_announcement)
3838 		return -1;
3839 	hapd->dpp_chirp_iter = iter;
3840 	hapd->dpp_chirp_round = 0;
3841 	hapd->dpp_chirp_scan_done = 0;
3842 	hapd->dpp_chirp_listen = listen_freq;
3843 
3844 	return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
3845 }
3846 
3847 
hostapd_dpp_chirp_stop(struct hostapd_data * hapd)3848 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
3849 {
3850 	if (hapd->dpp_presence_announcement) {
3851 		hostapd_drv_send_action_cancel_wait(hapd);
3852 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
3853 	}
3854 	hapd->dpp_chirp_bi = NULL;
3855 	wpabuf_free(hapd->dpp_presence_announcement);
3856 	hapd->dpp_presence_announcement = NULL;
3857 	if (hapd->dpp_chirp_listen)
3858 		hostapd_dpp_listen_stop(hapd);
3859 	hapd->dpp_chirp_listen = 0;
3860 	hapd->dpp_chirp_freq = 0;
3861 	os_free(hapd->dpp_chirp_freqs);
3862 	hapd->dpp_chirp_freqs = NULL;
3863 	eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
3864 	eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
3865 	if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
3866 		/* TODO: abort ongoing scan */
3867 		hapd->iface->scan_cb = NULL;
3868 	}
3869 }
3870 
3871 
handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)3872 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
3873 {
3874 	struct dpp_bootstrap_info *bi = ctx;
3875 	size_t i;
3876 
3877 	for (i = 0; i < iface->num_bss; i++) {
3878 		struct hostapd_data *hapd = iface->bss[i];
3879 
3880 		if (bi == hapd->dpp_chirp_bi)
3881 			hostapd_dpp_chirp_stop(hapd);
3882 	}
3883 
3884 	return 0;
3885 }
3886 
3887 
hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)3888 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
3889 {
3890 	struct hapd_interfaces *interfaces = ctx;
3891 
3892 	hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
3893 }
3894 
3895 #endif /* CONFIG_DPP2 */
3896 
3897 
3898 #ifdef CONFIG_DPP3
3899 
hostapd_dpp_push_button_expire(void * eloop_ctx,void * timeout_ctx)3900 static void hostapd_dpp_push_button_expire(void *eloop_ctx, void *timeout_ctx)
3901 {
3902 	struct hostapd_data *hapd = eloop_ctx;
3903 
3904 	wpa_printf(MSG_DEBUG, "DPP: Active push button mode expired");
3905 	hostapd_dpp_push_button_stop(hapd);
3906 }
3907 
3908 
hostapd_dpp_push_button(struct hostapd_data * hapd,const char * cmd)3909 int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd)
3910 {
3911 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3912 
3913 	if (!ifaces || !ifaces->dpp)
3914 		return -1;
3915 	os_get_reltime(&ifaces->dpp_pb_time);
3916 	ifaces->dpp_pb_announce_time.sec = 0;
3917 	ifaces->dpp_pb_announce_time.usec = 0;
3918 	str_clear_free(ifaces->dpp_pb_cmd);
3919 	ifaces->dpp_pb_cmd = NULL;
3920 	if (cmd) {
3921 		ifaces->dpp_pb_cmd = os_strdup(cmd);
3922 		if (!ifaces->dpp_pb_cmd)
3923 			return -1;
3924 	}
3925 	eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
3926 			       hapd, NULL);
3927 
3928 	return 0;
3929 }
3930 
3931 
hostapd_dpp_push_button_stop(struct hostapd_data * hapd)3932 void hostapd_dpp_push_button_stop(struct hostapd_data *hapd)
3933 {
3934 	struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3935 
3936 	if (!ifaces || !ifaces->dpp)
3937 		return;
3938 	eloop_cancel_timeout(hostapd_dpp_push_button_expire, hapd, NULL);
3939 	if (hostapd_dpp_pb_active(hapd)) {
3940 		wpa_printf(MSG_DEBUG, "DPP: Stop active push button mode");
3941 		if (!ifaces->dpp_pb_result_indicated)
3942 			wpa_msg(hapd->msg_ctx, MSG_INFO,
3943 				DPP_EVENT_PB_RESULT "failed");
3944 	}
3945 	ifaces->dpp_pb_time.sec = 0;
3946 	ifaces->dpp_pb_time.usec = 0;
3947 	dpp_pkex_free(hapd->dpp_pkex);
3948 	hapd->dpp_pkex = NULL;
3949 	os_free(hapd->dpp_pkex_auth_cmd);
3950 	hapd->dpp_pkex_auth_cmd = NULL;
3951 
3952 	if (ifaces->dpp_pb_bi) {
3953 		char id[20];
3954 
3955 		os_snprintf(id, sizeof(id), "%u", ifaces->dpp_pb_bi->id);
3956 		dpp_bootstrap_remove(ifaces->dpp, id);
3957 		ifaces->dpp_pb_bi = NULL;
3958 	}
3959 
3960 	ifaces->dpp_pb_result_indicated = false;
3961 
3962 	str_clear_free(ifaces->dpp_pb_cmd);
3963 	ifaces->dpp_pb_cmd = NULL;
3964 }
3965 
3966 #endif /* CONFIG_DPP3 */
3967 
3968 
3969 #ifdef CONFIG_DPP2
hostapd_dpp_configurator_connectivity(struct hostapd_data * hapd)3970 bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd)
3971 {
3972 	return hapd->conf->dpp_configurator_connectivity ||
3973 		(hapd->iface->interfaces &&
3974 		 dpp_relay_controller_available(hapd->iface->interfaces->dpp));
3975 }
3976 #endif /* CONFIG_DPP2 */
3977