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