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