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