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