1 /*
2 * hostapd / DPP integration
3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
4 * Copyright (c) 2018-2020, The Linux Foundation
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10 #include "utils/includes.h"
11
12 #include "utils/common.h"
13 #include "utils/eloop.h"
14 #include "common/dpp.h"
15 #include "common/gas.h"
16 #include "common/wpa_ctrl.h"
17 #include "hostapd.h"
18 #include "ap_drv_ops.h"
19 #include "gas_query_ap.h"
20 #include "gas_serv.h"
21 #include "wpa_auth.h"
22 #include "dpp_hostapd.h"
23
24
25 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
26 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
27 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
28 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
29 #ifdef CONFIG_DPP2
30 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
31 void *timeout_ctx);
32 #endif /* CONFIG_DPP2 */
33
34 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
35
36
37 /**
38 * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
39 * @hapd: Pointer to hostapd_data
40 * @cmd: DPP URI read from a QR Code
41 * Returns: Identifier of the stored info or -1 on failure
42 */
hostapd_dpp_qr_code(struct hostapd_data * hapd,const char * cmd)43 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
44 {
45 struct dpp_bootstrap_info *bi;
46 struct dpp_authentication *auth = hapd->dpp_auth;
47
48 bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
49 if (!bi)
50 return -1;
51
52 if (auth && auth->response_pending &&
53 dpp_notify_new_qr_code(auth, bi) == 1) {
54 wpa_printf(MSG_DEBUG,
55 "DPP: Sending out pending authentication response");
56 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
57 " freq=%u type=%d",
58 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
59 DPP_PA_AUTHENTICATION_RESP);
60 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
61 auth->peer_mac_addr,
62 wpabuf_head(hapd->dpp_auth->resp_msg),
63 wpabuf_len(hapd->dpp_auth->resp_msg));
64 }
65
66 return bi->id;
67 }
68
69
70 /**
71 * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
72 * @hapd: Pointer to hostapd_data
73 * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
74 * Returns: Identifier of the stored info or -1 on failure
75 */
hostapd_dpp_nfc_uri(struct hostapd_data * hapd,const char * cmd)76 int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
77 {
78 struct dpp_bootstrap_info *bi;
79
80 bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
81 if (!bi)
82 return -1;
83
84 return bi->id;
85 }
86
87
hostapd_dpp_nfc_handover_req(struct hostapd_data * hapd,const char * cmd)88 int hostapd_dpp_nfc_handover_req(struct hostapd_data *hapd, const char *cmd)
89 {
90 const char *pos;
91 struct dpp_bootstrap_info *peer_bi, *own_bi;
92
93 pos = os_strstr(cmd, " own=");
94 if (!pos)
95 return -1;
96 pos += 5;
97 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
98 if (!own_bi)
99 return -1;
100
101 pos = os_strstr(cmd, " uri=");
102 if (!pos)
103 return -1;
104 pos += 5;
105 peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
106 if (!peer_bi) {
107 wpa_printf(MSG_INFO,
108 "DPP: Failed to parse URI from NFC Handover Request");
109 return -1;
110 }
111
112 if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
113 return -1;
114
115 return peer_bi->id;
116 }
117
118
hostapd_dpp_nfc_handover_sel(struct hostapd_data * hapd,const char * cmd)119 int hostapd_dpp_nfc_handover_sel(struct hostapd_data *hapd, const char *cmd)
120 {
121 const char *pos;
122 struct dpp_bootstrap_info *peer_bi, *own_bi;
123
124 pos = os_strstr(cmd, " own=");
125 if (!pos)
126 return -1;
127 pos += 5;
128 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
129 if (!own_bi)
130 return -1;
131
132 pos = os_strstr(cmd, " uri=");
133 if (!pos)
134 return -1;
135 pos += 5;
136 peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
137 if (!peer_bi) {
138 wpa_printf(MSG_INFO,
139 "DPP: Failed to parse URI from NFC Handover Select");
140 return -1;
141 }
142
143 if (peer_bi->curve != own_bi->curve) {
144 wpa_printf(MSG_INFO,
145 "DPP: Peer (NFC Handover Selector) used different curve");
146 return -1;
147 }
148
149 return peer_bi->id;
150 }
151
152
hostapd_dpp_auth_resp_retry_timeout(void * eloop_ctx,void * timeout_ctx)153 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
154 void *timeout_ctx)
155 {
156 struct hostapd_data *hapd = eloop_ctx;
157 struct dpp_authentication *auth = hapd->dpp_auth;
158
159 if (!auth || !auth->resp_msg)
160 return;
161
162 wpa_printf(MSG_DEBUG,
163 "DPP: Retry Authentication Response after timeout");
164 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
165 " freq=%u type=%d",
166 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
167 DPP_PA_AUTHENTICATION_RESP);
168 hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
169 wpabuf_head(auth->resp_msg),
170 wpabuf_len(auth->resp_msg));
171 }
172
173
hostapd_dpp_auth_resp_retry(struct hostapd_data * hapd)174 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
175 {
176 struct dpp_authentication *auth = hapd->dpp_auth;
177 unsigned int wait_time, max_tries;
178
179 if (!auth || !auth->resp_msg)
180 return;
181
182 if (hapd->dpp_resp_max_tries)
183 max_tries = hapd->dpp_resp_max_tries;
184 else
185 max_tries = 5;
186 auth->auth_resp_tries++;
187 if (auth->auth_resp_tries >= max_tries) {
188 wpa_printf(MSG_INFO,
189 "DPP: No confirm received from initiator - stopping exchange");
190 hostapd_drv_send_action_cancel_wait(hapd);
191 dpp_auth_deinit(hapd->dpp_auth);
192 hapd->dpp_auth = NULL;
193 return;
194 }
195
196 if (hapd->dpp_resp_retry_time)
197 wait_time = hapd->dpp_resp_retry_time;
198 else
199 wait_time = 1000;
200 wpa_printf(MSG_DEBUG,
201 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
202 wait_time);
203 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
204 eloop_register_timeout(wait_time / 1000,
205 (wait_time % 1000) * 1000,
206 hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
207 }
208
209
hostapd_dpp_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)210 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
211 const u8 *data, size_t data_len, int ok)
212 {
213 struct dpp_authentication *auth = hapd->dpp_auth;
214
215 wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
216 MAC2STR(dst), ok);
217 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
218 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
219
220 if (!hapd->dpp_auth) {
221 wpa_printf(MSG_DEBUG,
222 "DPP: Ignore TX status since there is no ongoing authentication exchange");
223 return;
224 }
225
226 #ifdef CONFIG_DPP2
227 if (auth->connect_on_tx_status) {
228 wpa_printf(MSG_DEBUG,
229 "DPP: Complete exchange on configuration result");
230 dpp_auth_deinit(hapd->dpp_auth);
231 hapd->dpp_auth = NULL;
232 return;
233 }
234 #endif /* CONFIG_DPP2 */
235
236 if (hapd->dpp_auth->remove_on_tx_status) {
237 wpa_printf(MSG_DEBUG,
238 "DPP: Terminate authentication exchange due to an earlier error");
239 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
240 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
241 hapd, NULL);
242 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
243 NULL);
244 #ifdef CONFIG_DPP2
245 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
246 hapd, NULL);
247 #endif /* CONFIG_DPP2 */
248 hostapd_drv_send_action_cancel_wait(hapd);
249 dpp_auth_deinit(hapd->dpp_auth);
250 hapd->dpp_auth = NULL;
251 return;
252 }
253
254 if (hapd->dpp_auth_ok_on_ack)
255 hostapd_dpp_auth_success(hapd, 1);
256
257 if (!is_broadcast_ether_addr(dst) && !ok) {
258 wpa_printf(MSG_DEBUG,
259 "DPP: Unicast DPP Action frame was not ACKed");
260 if (auth->waiting_auth_resp) {
261 /* In case of DPP Authentication Request frame, move to
262 * the next channel immediately. */
263 hostapd_drv_send_action_cancel_wait(hapd);
264 hostapd_dpp_auth_init_next(hapd);
265 return;
266 }
267 if (auth->waiting_auth_conf) {
268 hostapd_dpp_auth_resp_retry(hapd);
269 return;
270 }
271 }
272
273 if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
274 /* Allow timeout handling to stop iteration if no response is
275 * received from a peer that has ACKed a request. */
276 auth->auth_req_ack = 1;
277 }
278
279 if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
280 hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
281 wpa_printf(MSG_DEBUG,
282 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
283 hapd->dpp_auth->curr_freq,
284 hapd->dpp_auth->neg_freq);
285 hostapd_drv_send_action_cancel_wait(hapd);
286
287 if (hapd->dpp_auth->neg_freq !=
288 (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
289 /* TODO: Listen operation on non-operating channel */
290 wpa_printf(MSG_INFO,
291 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
292 hapd->dpp_auth->neg_freq, hapd->iface->freq);
293 }
294 }
295
296 if (hapd->dpp_auth_ok_on_ack)
297 hapd->dpp_auth_ok_on_ack = 0;
298 }
299
300
hostapd_dpp_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)301 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
302 {
303 struct hostapd_data *hapd = eloop_ctx;
304 struct dpp_authentication *auth = hapd->dpp_auth;
305 unsigned int freq;
306 struct os_reltime now, diff;
307 unsigned int wait_time, diff_ms;
308
309 if (!auth || !auth->waiting_auth_resp)
310 return;
311
312 wait_time = hapd->dpp_resp_wait_time ?
313 hapd->dpp_resp_wait_time : 2000;
314 os_get_reltime(&now);
315 os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
316 diff_ms = diff.sec * 1000 + diff.usec / 1000;
317 wpa_printf(MSG_DEBUG,
318 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
319 wait_time, diff_ms);
320
321 if (auth->auth_req_ack && diff_ms >= wait_time) {
322 /* Peer ACK'ed Authentication Request frame, but did not reply
323 * with Authentication Response frame within two seconds. */
324 wpa_printf(MSG_INFO,
325 "DPP: No response received from responder - stopping initiation attempt");
326 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
327 hostapd_drv_send_action_cancel_wait(hapd);
328 hostapd_dpp_listen_stop(hapd);
329 dpp_auth_deinit(auth);
330 hapd->dpp_auth = NULL;
331 return;
332 }
333
334 if (diff_ms >= wait_time) {
335 /* Authentication Request frame was not ACK'ed and no reply
336 * was receiving within two seconds. */
337 wpa_printf(MSG_DEBUG,
338 "DPP: Continue Initiator channel iteration");
339 hostapd_drv_send_action_cancel_wait(hapd);
340 hostapd_dpp_listen_stop(hapd);
341 hostapd_dpp_auth_init_next(hapd);
342 return;
343 }
344
345 /* Driver did not support 2000 ms long wait_time with TX command, so
346 * schedule listen operation to continue waiting for the response.
347 *
348 * DPP listen operations continue until stopped, so simply schedule a
349 * new call to this function at the point when the two second reply
350 * wait has expired. */
351 wait_time -= diff_ms;
352
353 freq = auth->curr_freq;
354 if (auth->neg_freq > 0)
355 freq = auth->neg_freq;
356 wpa_printf(MSG_DEBUG,
357 "DPP: Continue reply wait on channel %u MHz for %u ms",
358 freq, wait_time);
359 hapd->dpp_in_response_listen = 1;
360
361 if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
362 /* TODO: Listen operation on non-operating channel */
363 wpa_printf(MSG_INFO,
364 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
365 freq, hapd->iface->freq);
366 }
367
368 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
369 hostapd_dpp_reply_wait_timeout, hapd, NULL);
370 }
371
372
hostapd_dpp_set_testing_options(struct hostapd_data * hapd,struct dpp_authentication * auth)373 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
374 struct dpp_authentication *auth)
375 {
376 #ifdef CONFIG_TESTING_OPTIONS
377 if (hapd->dpp_config_obj_override)
378 auth->config_obj_override =
379 os_strdup(hapd->dpp_config_obj_override);
380 if (hapd->dpp_discovery_override)
381 auth->discovery_override =
382 os_strdup(hapd->dpp_discovery_override);
383 if (hapd->dpp_groups_override)
384 auth->groups_override = os_strdup(hapd->dpp_groups_override);
385 auth->ignore_netaccesskey_mismatch =
386 hapd->dpp_ignore_netaccesskey_mismatch;
387 #endif /* CONFIG_TESTING_OPTIONS */
388 }
389
390
hostapd_dpp_init_timeout(void * eloop_ctx,void * timeout_ctx)391 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
392 {
393 struct hostapd_data *hapd = eloop_ctx;
394
395 if (!hapd->dpp_auth)
396 return;
397 wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
398 hostapd_dpp_auth_init_next(hapd);
399 }
400
401
hostapd_dpp_auth_init_next(struct hostapd_data * hapd)402 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
403 {
404 struct dpp_authentication *auth = hapd->dpp_auth;
405 const u8 *dst;
406 unsigned int wait_time, max_wait_time, freq, max_tries, used;
407 struct os_reltime now, diff;
408
409 if (!auth)
410 return -1;
411
412 if (auth->freq_idx == 0)
413 os_get_reltime(&hapd->dpp_init_iter_start);
414
415 if (auth->freq_idx >= auth->num_freq) {
416 auth->num_freq_iters++;
417 if (hapd->dpp_init_max_tries)
418 max_tries = hapd->dpp_init_max_tries;
419 else
420 max_tries = 5;
421 if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
422 wpa_printf(MSG_INFO,
423 "DPP: No response received from responder - stopping initiation attempt");
424 wpa_msg(hapd->msg_ctx, MSG_INFO,
425 DPP_EVENT_AUTH_INIT_FAILED);
426 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
427 hapd, NULL);
428 hostapd_drv_send_action_cancel_wait(hapd);
429 dpp_auth_deinit(hapd->dpp_auth);
430 hapd->dpp_auth = NULL;
431 return -1;
432 }
433 auth->freq_idx = 0;
434 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
435 if (hapd->dpp_init_retry_time)
436 wait_time = hapd->dpp_init_retry_time;
437 else
438 wait_time = 10000;
439 os_get_reltime(&now);
440 os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
441 used = diff.sec * 1000 + diff.usec / 1000;
442 if (used > wait_time)
443 wait_time = 0;
444 else
445 wait_time -= used;
446 wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
447 wait_time);
448 eloop_register_timeout(wait_time / 1000,
449 (wait_time % 1000) * 1000,
450 hostapd_dpp_init_timeout, hapd,
451 NULL);
452 return 0;
453 }
454 freq = auth->freq[auth->freq_idx++];
455 auth->curr_freq = freq;
456
457 if (is_zero_ether_addr(auth->peer_bi->mac_addr))
458 dst = broadcast;
459 else
460 dst = auth->peer_bi->mac_addr;
461 hapd->dpp_auth_ok_on_ack = 0;
462 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
463 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
464 max_wait_time = hapd->dpp_resp_wait_time ?
465 hapd->dpp_resp_wait_time : 2000;
466 if (wait_time > max_wait_time)
467 wait_time = max_wait_time;
468 wait_time += 10; /* give the driver some extra time to complete */
469 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
470 hostapd_dpp_reply_wait_timeout, hapd, NULL);
471 wait_time -= 10;
472 if (auth->neg_freq > 0 && freq != auth->neg_freq) {
473 wpa_printf(MSG_DEBUG,
474 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
475 freq, auth->neg_freq);
476 }
477 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
478 " freq=%u type=%d",
479 MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
480 auth->auth_req_ack = 0;
481 os_get_reltime(&hapd->dpp_last_init);
482 return hostapd_drv_send_action(hapd, freq, wait_time,
483 dst,
484 wpabuf_head(hapd->dpp_auth->req_msg),
485 wpabuf_len(hapd->dpp_auth->req_msg));
486 }
487
488
hostapd_dpp_auth_init(struct hostapd_data * hapd,const char * cmd)489 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
490 {
491 const char *pos;
492 struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
493 u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
494 unsigned int neg_freq = 0;
495
496 pos = os_strstr(cmd, " peer=");
497 if (!pos)
498 return -1;
499 pos += 6;
500 peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
501 if (!peer_bi) {
502 wpa_printf(MSG_INFO,
503 "DPP: Could not find bootstrapping info for the identified peer");
504 return -1;
505 }
506
507 pos = os_strstr(cmd, " own=");
508 if (pos) {
509 pos += 5;
510 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
511 atoi(pos));
512 if (!own_bi) {
513 wpa_printf(MSG_INFO,
514 "DPP: Could not find bootstrapping info for the identified local entry");
515 return -1;
516 }
517
518 if (peer_bi->curve != own_bi->curve) {
519 wpa_printf(MSG_INFO,
520 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
521 peer_bi->curve->name, own_bi->curve->name);
522 return -1;
523 }
524 }
525
526 pos = os_strstr(cmd, " role=");
527 if (pos) {
528 pos += 6;
529 if (os_strncmp(pos, "configurator", 12) == 0)
530 allowed_roles = DPP_CAPAB_CONFIGURATOR;
531 else if (os_strncmp(pos, "enrollee", 8) == 0)
532 allowed_roles = DPP_CAPAB_ENROLLEE;
533 else if (os_strncmp(pos, "either", 6) == 0)
534 allowed_roles = DPP_CAPAB_CONFIGURATOR |
535 DPP_CAPAB_ENROLLEE;
536 else
537 goto fail;
538 }
539
540 pos = os_strstr(cmd, " neg_freq=");
541 if (pos)
542 neg_freq = atoi(pos + 10);
543
544 if (hapd->dpp_auth) {
545 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
546 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
547 hapd, NULL);
548 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
549 NULL);
550 #ifdef CONFIG_DPP2
551 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
552 hapd, NULL);
553 #endif /* CONFIG_DPP2 */
554 hostapd_drv_send_action_cancel_wait(hapd);
555 dpp_auth_deinit(hapd->dpp_auth);
556 }
557
558 hapd->dpp_auth = dpp_auth_init(hapd->iface->interfaces->dpp,
559 hapd->msg_ctx, peer_bi, own_bi,
560 allowed_roles, neg_freq,
561 hapd->iface->hw_features,
562 hapd->iface->num_hw_features);
563 if (!hapd->dpp_auth)
564 goto fail;
565 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
566 if (dpp_set_configurator(hapd->dpp_auth, cmd) < 0) {
567 dpp_auth_deinit(hapd->dpp_auth);
568 hapd->dpp_auth = NULL;
569 goto fail;
570 }
571
572 hapd->dpp_auth->neg_freq = neg_freq;
573
574 if (!is_zero_ether_addr(peer_bi->mac_addr))
575 os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
576 ETH_ALEN);
577
578 return hostapd_dpp_auth_init_next(hapd);
579 fail:
580 return -1;
581 }
582
583
hostapd_dpp_listen(struct hostapd_data * hapd,const char * cmd)584 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
585 {
586 int freq;
587
588 freq = atoi(cmd);
589 if (freq <= 0)
590 return -1;
591
592 if (os_strstr(cmd, " role=configurator"))
593 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
594 else if (os_strstr(cmd, " role=enrollee"))
595 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
596 else
597 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
598 DPP_CAPAB_ENROLLEE;
599 hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
600
601 if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
602 /* TODO: Listen operation on non-operating channel */
603 wpa_printf(MSG_INFO,
604 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
605 freq, hapd->iface->freq);
606 return -1;
607 }
608
609 return 0;
610 }
611
612
hostapd_dpp_listen_stop(struct hostapd_data * hapd)613 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
614 {
615 /* TODO: Stop listen operation on non-operating channel */
616 }
617
618
hostapd_dpp_rx_auth_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)619 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
620 const u8 *hdr, const u8 *buf, size_t len,
621 unsigned int freq)
622 {
623 const u8 *r_bootstrap, *i_bootstrap;
624 u16 r_bootstrap_len, i_bootstrap_len;
625 struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
626
627 if (!hapd->iface->interfaces->dpp)
628 return;
629
630 wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
631 MAC2STR(src));
632
633 #ifdef CONFIG_DPP2
634 hostapd_dpp_chirp_stop(hapd);
635 #endif /* CONFIG_DPP2 */
636
637 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
638 &r_bootstrap_len);
639 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
640 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
641 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
642 return;
643 }
644 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
645 r_bootstrap, r_bootstrap_len);
646
647 i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
648 &i_bootstrap_len);
649 if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
650 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
651 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
652 return;
653 }
654 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
655 i_bootstrap, i_bootstrap_len);
656
657 /* Try to find own and peer bootstrapping key matches based on the
658 * received hash values */
659 dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
660 r_bootstrap, &own_bi, &peer_bi);
661 #ifdef CONFIG_DPP2
662 if (!own_bi) {
663 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
664 src, hdr, buf, len, freq, i_bootstrap,
665 r_bootstrap) == 0)
666 return;
667 }
668 #endif /* CONFIG_DPP2 */
669 if (!own_bi) {
670 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
671 "No matching own bootstrapping key found - ignore message");
672 return;
673 }
674
675 if (hapd->dpp_auth) {
676 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
677 "Already in DPP authentication exchange - ignore new one");
678 return;
679 }
680
681 hapd->dpp_auth_ok_on_ack = 0;
682 hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
683 hapd->msg_ctx, hapd->dpp_allowed_roles,
684 hapd->dpp_qr_mutual,
685 peer_bi, own_bi, freq, hdr, buf, len);
686 if (!hapd->dpp_auth) {
687 wpa_printf(MSG_DEBUG, "DPP: No response generated");
688 return;
689 }
690 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
691 if (dpp_set_configurator(hapd->dpp_auth,
692 hapd->dpp_configurator_params) < 0) {
693 dpp_auth_deinit(hapd->dpp_auth);
694 hapd->dpp_auth = NULL;
695 return;
696 }
697 os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
698
699 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
700 " freq=%u type=%d",
701 MAC2STR(src), hapd->dpp_auth->curr_freq,
702 DPP_PA_AUTHENTICATION_RESP);
703 hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
704 src, wpabuf_head(hapd->dpp_auth->resp_msg),
705 wpabuf_len(hapd->dpp_auth->resp_msg));
706 }
707
708
hostapd_dpp_handle_config_obj(struct hostapd_data * hapd,struct dpp_authentication * auth,struct dpp_config_obj * conf)709 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
710 struct dpp_authentication *auth,
711 struct dpp_config_obj *conf)
712 {
713 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
714 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
715 dpp_akm_str(conf->akm));
716 if (conf->ssid_len)
717 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
718 wpa_ssid_txt(conf->ssid, conf->ssid_len));
719 if (conf->connector) {
720 /* TODO: Save the Connector and consider using a command
721 * to fetch the value instead of sending an event with
722 * it. The Connector could end up being larger than what
723 * most clients are ready to receive as an event
724 * message. */
725 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
726 conf->connector);
727 }
728 if (conf->passphrase[0]) {
729 char hex[64 * 2 + 1];
730
731 wpa_snprintf_hex(hex, sizeof(hex),
732 (const u8 *) conf->passphrase,
733 os_strlen(conf->passphrase));
734 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
735 hex);
736 } else if (conf->psk_set) {
737 char hex[PMK_LEN * 2 + 1];
738
739 wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
740 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
741 hex);
742 }
743 if (conf->c_sign_key) {
744 char *hex;
745 size_t hexlen;
746
747 hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
748 hex = os_malloc(hexlen);
749 if (hex) {
750 wpa_snprintf_hex(hex, hexlen,
751 wpabuf_head(conf->c_sign_key),
752 wpabuf_len(conf->c_sign_key));
753 wpa_msg(hapd->msg_ctx, MSG_INFO,
754 DPP_EVENT_C_SIGN_KEY "%s", hex);
755 os_free(hex);
756 }
757 }
758 if (auth->net_access_key) {
759 char *hex;
760 size_t hexlen;
761
762 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
763 hex = os_malloc(hexlen);
764 if (hex) {
765 wpa_snprintf_hex(hex, hexlen,
766 wpabuf_head(auth->net_access_key),
767 wpabuf_len(auth->net_access_key));
768 if (auth->net_access_key_expiry)
769 wpa_msg(hapd->msg_ctx, MSG_INFO,
770 DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
771 (unsigned long)
772 auth->net_access_key_expiry);
773 else
774 wpa_msg(hapd->msg_ctx, MSG_INFO,
775 DPP_EVENT_NET_ACCESS_KEY "%s", hex);
776 os_free(hex);
777 }
778 }
779 }
780
781
hostapd_dpp_handle_key_pkg(struct hostapd_data * hapd,struct dpp_asymmetric_key * key)782 static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
783 struct dpp_asymmetric_key *key)
784 {
785 #ifdef CONFIG_DPP2
786 int res;
787
788 if (!key)
789 return 0;
790
791 wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
792 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
793
794 while (key) {
795 res = dpp_configurator_from_backup(
796 hapd->iface->interfaces->dpp, key);
797 if (res < 0)
798 return -1;
799 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
800 res);
801 key = key->next;
802 }
803 #endif /* CONFIG_DPP2 */
804
805 return 0;
806 }
807
808
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)809 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
810 enum gas_query_ap_result result,
811 const struct wpabuf *adv_proto,
812 const struct wpabuf *resp, u16 status_code)
813 {
814 struct hostapd_data *hapd = ctx;
815 const u8 *pos;
816 struct dpp_authentication *auth = hapd->dpp_auth;
817 enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
818
819 if (!auth || !auth->auth_success) {
820 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
821 return;
822 }
823 if (!resp || status_code != WLAN_STATUS_SUCCESS) {
824 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
825 goto fail;
826 }
827
828 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
829 adv_proto);
830 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
831 resp);
832
833 if (wpabuf_len(adv_proto) != 10 ||
834 !(pos = wpabuf_head(adv_proto)) ||
835 pos[0] != WLAN_EID_ADV_PROTO ||
836 pos[1] != 8 ||
837 pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
838 pos[4] != 5 ||
839 WPA_GET_BE24(&pos[5]) != OUI_WFA ||
840 pos[8] != 0x1a ||
841 pos[9] != 1) {
842 wpa_printf(MSG_DEBUG,
843 "DPP: Not a DPP Advertisement Protocol ID");
844 goto fail;
845 }
846
847 if (dpp_conf_resp_rx(auth, resp) < 0) {
848 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
849 goto fail;
850 }
851
852 hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
853 if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
854 goto fail;
855
856 status = DPP_STATUS_OK;
857 #ifdef CONFIG_TESTING_OPTIONS
858 if (dpp_test == DPP_TEST_REJECT_CONFIG) {
859 wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
860 status = DPP_STATUS_CONFIG_REJECTED;
861 }
862 #endif /* CONFIG_TESTING_OPTIONS */
863 fail:
864 if (status != DPP_STATUS_OK)
865 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
866 #ifdef CONFIG_DPP2
867 if (auth->peer_version >= 2 &&
868 auth->conf_resp_status == DPP_STATUS_OK) {
869 struct wpabuf *msg;
870
871 wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
872 msg = dpp_build_conf_result(auth, status);
873 if (!msg)
874 goto fail2;
875
876 wpa_msg(hapd->msg_ctx, MSG_INFO,
877 DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
878 MAC2STR(addr), auth->curr_freq,
879 DPP_PA_CONFIGURATION_RESULT);
880 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
881 addr, wpabuf_head(msg),
882 wpabuf_len(msg));
883 wpabuf_free(msg);
884
885 /* This exchange will be terminated in the TX status handler */
886 auth->connect_on_tx_status = 1;
887 return;
888 }
889 fail2:
890 #endif /* CONFIG_DPP2 */
891 dpp_auth_deinit(hapd->dpp_auth);
892 hapd->dpp_auth = NULL;
893 }
894
895
hostapd_dpp_start_gas_client(struct hostapd_data * hapd)896 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
897 {
898 struct dpp_authentication *auth = hapd->dpp_auth;
899 struct wpabuf *buf;
900 int res;
901
902 buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
903 DPP_NETROLE_AP,
904 hapd->conf->dpp_mud_url, NULL);
905 if (!buf) {
906 wpa_printf(MSG_DEBUG,
907 "DPP: No configuration request data available");
908 return;
909 }
910
911 wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
912 MAC2STR(auth->peer_mac_addr), auth->curr_freq);
913
914 res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
915 buf, hostapd_dpp_gas_resp_cb, hapd);
916 if (res < 0) {
917 wpa_msg(hapd->msg_ctx, MSG_DEBUG,
918 "GAS: Failed to send Query Request");
919 wpabuf_free(buf);
920 } else {
921 wpa_printf(MSG_DEBUG,
922 "DPP: GAS query started with dialog token %u", res);
923 }
924 }
925
926
hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)927 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
928 {
929 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
930 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
931 initiator);
932 #ifdef CONFIG_TESTING_OPTIONS
933 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
934 wpa_printf(MSG_INFO,
935 "DPP: TESTING - stop at Authentication Confirm");
936 if (hapd->dpp_auth->configurator) {
937 /* Prevent GAS response */
938 hapd->dpp_auth->auth_success = 0;
939 }
940 return;
941 }
942 #endif /* CONFIG_TESTING_OPTIONS */
943
944 if (!hapd->dpp_auth->configurator)
945 hostapd_dpp_start_gas_client(hapd);
946 }
947
948
hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)949 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
950 const u8 *hdr, const u8 *buf, size_t len,
951 unsigned int freq)
952 {
953 struct dpp_authentication *auth = hapd->dpp_auth;
954 struct wpabuf *msg;
955
956 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
957 MAC2STR(src));
958
959 if (!auth) {
960 wpa_printf(MSG_DEBUG,
961 "DPP: No DPP Authentication in progress - drop");
962 return;
963 }
964
965 if (!is_zero_ether_addr(auth->peer_mac_addr) &&
966 os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
967 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
968 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
969 return;
970 }
971
972 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
973
974 if (auth->curr_freq != freq && auth->neg_freq == freq) {
975 wpa_printf(MSG_DEBUG,
976 "DPP: Responder accepted request for different negotiation channel");
977 auth->curr_freq = freq;
978 }
979
980 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
981 msg = dpp_auth_resp_rx(auth, hdr, buf, len);
982 if (!msg) {
983 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
984 wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
985 return;
986 }
987 wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
988 return;
989 }
990 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
991
992 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
993 " freq=%u type=%d", MAC2STR(src), auth->curr_freq,
994 DPP_PA_AUTHENTICATION_CONF);
995 hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
996 wpabuf_head(msg), wpabuf_len(msg));
997 wpabuf_free(msg);
998 hapd->dpp_auth_ok_on_ack = 1;
999 }
1000
1001
hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1002 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
1003 const u8 *hdr, const u8 *buf, size_t len)
1004 {
1005 struct dpp_authentication *auth = hapd->dpp_auth;
1006
1007 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
1008 MAC2STR(src));
1009
1010 if (!auth) {
1011 wpa_printf(MSG_DEBUG,
1012 "DPP: No DPP Authentication in progress - drop");
1013 return;
1014 }
1015
1016 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1017 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1018 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1019 return;
1020 }
1021
1022 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1023 wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1024 return;
1025 }
1026
1027 hostapd_dpp_auth_success(hapd, 0);
1028 }
1029
1030
1031 #ifdef CONFIG_DPP2
1032
hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1033 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1034 void *timeout_ctx)
1035 {
1036 struct hostapd_data *hapd = eloop_ctx;
1037 struct dpp_authentication *auth = hapd->dpp_auth;
1038
1039 if (!auth || !auth->waiting_conf_result)
1040 return;
1041
1042 wpa_printf(MSG_DEBUG,
1043 "DPP: Timeout while waiting for Configuration Result");
1044 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1045 dpp_auth_deinit(auth);
1046 hapd->dpp_auth = NULL;
1047 }
1048
1049
hostapd_dpp_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1050 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1051 void *timeout_ctx)
1052 {
1053 struct hostapd_data *hapd = eloop_ctx;
1054 struct dpp_authentication *auth = hapd->dpp_auth;
1055
1056 if (!auth || !auth->waiting_conf_result)
1057 return;
1058
1059 wpa_printf(MSG_DEBUG,
1060 "DPP: Timeout while waiting for Connection Status Result");
1061 wpa_msg(hapd->msg_ctx, MSG_INFO,
1062 DPP_EVENT_CONN_STATUS_RESULT "timeout");
1063 dpp_auth_deinit(auth);
1064 hapd->dpp_auth = NULL;
1065 }
1066
1067
hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1068 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1069 const u8 *hdr, const u8 *buf, size_t len)
1070 {
1071 struct dpp_authentication *auth = hapd->dpp_auth;
1072 enum dpp_status_error status;
1073
1074 wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
1075 MAC2STR(src));
1076
1077 if (!auth || !auth->waiting_conf_result) {
1078 wpa_printf(MSG_DEBUG,
1079 "DPP: No DPP Configuration waiting for result - drop");
1080 return;
1081 }
1082
1083 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1084 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1085 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1086 return;
1087 }
1088
1089 status = dpp_conf_result_rx(auth, hdr, buf, len);
1090
1091 if (status == DPP_STATUS_OK && auth->send_conn_status) {
1092 wpa_msg(hapd->msg_ctx, MSG_INFO,
1093 DPP_EVENT_CONF_SENT "wait_conn_status=1");
1094 wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1095 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1096 hapd, NULL);
1097 eloop_cancel_timeout(
1098 hostapd_dpp_conn_status_result_wait_timeout,
1099 hapd, NULL);
1100 eloop_register_timeout(
1101 16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1102 hapd, NULL);
1103 return;
1104 }
1105 hostapd_drv_send_action_cancel_wait(hapd);
1106 hostapd_dpp_listen_stop(hapd);
1107 if (status == DPP_STATUS_OK)
1108 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1109 else
1110 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1111 dpp_auth_deinit(auth);
1112 hapd->dpp_auth = NULL;
1113 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1114 NULL);
1115 }
1116
1117
hostapd_dpp_rx_conn_status_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1118 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1119 const u8 *src, const u8 *hdr,
1120 const u8 *buf, size_t len)
1121 {
1122 struct dpp_authentication *auth = hapd->dpp_auth;
1123 enum dpp_status_error status;
1124 u8 ssid[SSID_MAX_LEN];
1125 size_t ssid_len = 0;
1126 char *channel_list = NULL;
1127
1128 wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1129
1130 if (!auth || !auth->waiting_conn_status_result) {
1131 wpa_printf(MSG_DEBUG,
1132 "DPP: No DPP Configuration waiting for connection status result - drop");
1133 return;
1134 }
1135
1136 status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1137 ssid, &ssid_len, &channel_list);
1138 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1139 "result=%d ssid=%s channel_list=%s",
1140 status, wpa_ssid_txt(ssid, ssid_len),
1141 channel_list ? channel_list : "N/A");
1142 os_free(channel_list);
1143 hostapd_drv_send_action_cancel_wait(hapd);
1144 hostapd_dpp_listen_stop(hapd);
1145 dpp_auth_deinit(auth);
1146 hapd->dpp_auth = NULL;
1147 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1148 hapd, NULL);
1149 }
1150
1151
1152 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)1153 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1154 const u8 *hdr, const u8 *buf, size_t len,
1155 unsigned int freq)
1156 {
1157 const u8 *r_bootstrap;
1158 u16 r_bootstrap_len;
1159 struct dpp_bootstrap_info *peer_bi;
1160 struct dpp_authentication *auth;
1161
1162 wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
1163 MAC2STR(src));
1164
1165 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1166 &r_bootstrap_len);
1167 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1168 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1169 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1170 return;
1171 }
1172 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1173 r_bootstrap, r_bootstrap_len);
1174 peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1175 r_bootstrap);
1176 if (!peer_bi) {
1177 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1178 src, hdr, buf, len, freq, NULL,
1179 r_bootstrap) == 0)
1180 return;
1181 wpa_printf(MSG_DEBUG,
1182 "DPP: No matching bootstrapping information found");
1183 return;
1184 }
1185
1186 if (hapd->dpp_auth) {
1187 wpa_printf(MSG_DEBUG,
1188 "DPP: Ignore Presence Announcement during ongoing Authentication");
1189 return;
1190 }
1191
1192 auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1193 peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1194 0);
1195 if (!auth)
1196 return;
1197 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
1198 if (dpp_set_configurator(hapd->dpp_auth,
1199 hapd->dpp_configurator_params) < 0) {
1200 dpp_auth_deinit(auth);
1201 return;
1202 }
1203
1204 auth->neg_freq = freq;
1205
1206 if (!is_zero_ether_addr(peer_bi->mac_addr))
1207 os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
1208
1209 hapd->dpp_auth = auth;
1210 if (hostapd_dpp_auth_init_next(hapd) < 0) {
1211 dpp_auth_deinit(hapd->dpp_auth);
1212 hapd->dpp_auth = NULL;
1213 }
1214 }
1215
1216
hostapd_dpp_reconfig_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)1217 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
1218 void *timeout_ctx)
1219 {
1220 struct hostapd_data *hapd = eloop_ctx;
1221 struct dpp_authentication *auth = hapd->dpp_auth;
1222
1223 if (!auth)
1224 return;
1225
1226 wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
1227 hostapd_dpp_listen_stop(hapd);
1228 dpp_auth_deinit(auth);
1229 hapd->dpp_auth = NULL;
1230 }
1231
1232
1233 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)1234 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
1235 const u8 *hdr, const u8 *buf, size_t len,
1236 unsigned int freq)
1237 {
1238 const u8 *csign_hash;
1239 u16 csign_hash_len;
1240 struct dpp_configurator *conf;
1241 struct dpp_authentication *auth;
1242 unsigned int wait_time, max_wait_time;
1243
1244 if (hapd->dpp_auth) {
1245 wpa_printf(MSG_DEBUG,
1246 "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1247 return;
1248 }
1249
1250 wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR,
1251 MAC2STR(src));
1252
1253 csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1254 &csign_hash_len);
1255 if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1256 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1257 "Missing or invalid required Configurator C-sign key Hash attribute");
1258 return;
1259 }
1260 wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1261 csign_hash, csign_hash_len);
1262 conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp,
1263 csign_hash);
1264 if (!conf) {
1265 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1266 src, hdr, buf, len, freq, NULL,
1267 NULL) == 0)
1268 return;
1269 wpa_printf(MSG_DEBUG,
1270 "DPP: No matching Configurator information found");
1271 return;
1272 }
1273
1274 auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1275 conf, freq);
1276 if (!auth)
1277 return;
1278 hostapd_dpp_set_testing_options(hapd, auth);
1279 if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
1280 dpp_auth_deinit(auth);
1281 return;
1282 }
1283
1284 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1285 hapd->dpp_auth = auth;
1286
1287 hapd->dpp_in_response_listen = 0;
1288 hapd->dpp_auth_ok_on_ack = 0;
1289 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
1290 max_wait_time = hapd->dpp_resp_wait_time ?
1291 hapd->dpp_resp_wait_time : 2000;
1292 if (wait_time > max_wait_time)
1293 wait_time = max_wait_time;
1294 wait_time += 10; /* give the driver some extra time to complete */
1295 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
1296 hostapd_dpp_reconfig_reply_wait_timeout,
1297 hapd, NULL);
1298 wait_time -= 10;
1299
1300 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1301 " freq=%u type=%d",
1302 MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
1303 if (hostapd_drv_send_action(hapd, freq, wait_time, src,
1304 wpabuf_head(auth->reconfig_req_msg),
1305 wpabuf_len(auth->reconfig_req_msg)) < 0) {
1306 dpp_auth_deinit(hapd->dpp_auth);
1307 hapd->dpp_auth = NULL;
1308 }
1309 }
1310
1311
1312 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)1313 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src,
1314 const u8 *hdr, const u8 *buf, size_t len,
1315 unsigned int freq)
1316 {
1317 struct dpp_authentication *auth = hapd->dpp_auth;
1318 struct wpabuf *conf;
1319
1320 wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
1321 MACSTR, MAC2STR(src));
1322
1323 if (!auth || !auth->reconfig || !auth->configurator) {
1324 wpa_printf(MSG_DEBUG,
1325 "DPP: No DPP Reconfig Authentication in progress - drop");
1326 return;
1327 }
1328
1329 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1330 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1331 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1332 return;
1333 }
1334
1335 conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1336 if (!conf)
1337 return;
1338
1339 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1340 hapd, NULL);
1341
1342 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1343 " freq=%u type=%d",
1344 MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
1345 if (hostapd_drv_send_action(hapd, freq, 500, src,
1346 wpabuf_head(conf), wpabuf_len(conf)) < 0) {
1347 wpabuf_free(conf);
1348 dpp_auth_deinit(hapd->dpp_auth);
1349 hapd->dpp_auth = NULL;
1350 return;
1351 }
1352 wpabuf_free(conf);
1353 }
1354
1355 #endif /* CONFIG_DPP2 */
1356
1357
hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)1358 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1359 const u8 *src, unsigned int freq,
1360 u8 trans_id,
1361 enum dpp_status_error status)
1362 {
1363 struct wpabuf *msg;
1364 size_t len;
1365
1366 len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
1367 #ifdef CONFIG_DPP2
1368 len += 5;
1369 #endif /* CONFIG_DPP2 */
1370 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len);
1371 if (!msg)
1372 return;
1373
1374 #ifdef CONFIG_TESTING_OPTIONS
1375 if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1376 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1377 goto skip_trans_id;
1378 }
1379 if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1380 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1381 trans_id ^= 0x01;
1382 }
1383 #endif /* CONFIG_TESTING_OPTIONS */
1384
1385 /* Transaction ID */
1386 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1387 wpabuf_put_le16(msg, 1);
1388 wpabuf_put_u8(msg, trans_id);
1389
1390 #ifdef CONFIG_TESTING_OPTIONS
1391 skip_trans_id:
1392 if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1393 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1394 goto skip_status;
1395 }
1396 if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1397 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1398 status = 254;
1399 }
1400 #endif /* CONFIG_TESTING_OPTIONS */
1401
1402 /* DPP Status */
1403 wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1404 wpabuf_put_le16(msg, 1);
1405 wpabuf_put_u8(msg, status);
1406
1407 #ifdef CONFIG_TESTING_OPTIONS
1408 skip_status:
1409 if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1410 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1411 goto skip_connector;
1412 }
1413 if (status == DPP_STATUS_OK &&
1414 dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1415 char *connector;
1416
1417 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1418 connector = dpp_corrupt_connector_signature(
1419 hapd->conf->dpp_connector);
1420 if (!connector) {
1421 wpabuf_free(msg);
1422 return;
1423 }
1424 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1425 wpabuf_put_le16(msg, os_strlen(connector));
1426 wpabuf_put_str(msg, connector);
1427 os_free(connector);
1428 goto skip_connector;
1429 }
1430 #endif /* CONFIG_TESTING_OPTIONS */
1431
1432 /* DPP Connector */
1433 if (status == DPP_STATUS_OK) {
1434 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1435 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1436 wpabuf_put_str(msg, hapd->conf->dpp_connector);
1437 }
1438
1439 #ifdef CONFIG_TESTING_OPTIONS
1440 skip_connector:
1441 #endif /* CONFIG_TESTING_OPTIONS */
1442
1443 #ifdef CONFIG_DPP2
1444 if (DPP_VERSION > 1) {
1445 /* Protocol Version */
1446 wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
1447 wpabuf_put_le16(msg, 1);
1448 wpabuf_put_u8(msg, DPP_VERSION);
1449 }
1450 #endif /* CONFIG_DPP2 */
1451
1452 wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
1453 " status=%d", MAC2STR(src), status);
1454 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1455 " freq=%u type=%d status=%d", MAC2STR(src), freq,
1456 DPP_PA_PEER_DISCOVERY_RESP, status);
1457 hostapd_drv_send_action(hapd, freq, 0, src,
1458 wpabuf_head(msg), wpabuf_len(msg));
1459 wpabuf_free(msg);
1460 }
1461
1462
hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1463 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
1464 const u8 *src,
1465 const u8 *buf, size_t len,
1466 unsigned int freq)
1467 {
1468 const u8 *connector, *trans_id;
1469 u16 connector_len, trans_id_len;
1470 struct os_time now;
1471 struct dpp_introduction intro;
1472 os_time_t expire;
1473 int expiration;
1474 enum dpp_status_error res;
1475
1476 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
1477 MAC2STR(src));
1478 if (!hapd->wpa_auth ||
1479 !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
1480 !(hapd->conf->wpa & WPA_PROTO_RSN)) {
1481 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
1482 return;
1483 }
1484
1485 if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
1486 !hapd->conf->dpp_csign) {
1487 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
1488 return;
1489 }
1490
1491 os_get_time(&now);
1492
1493 if (hapd->conf->dpp_netaccesskey_expiry &&
1494 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
1495 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
1496 return;
1497 }
1498
1499 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
1500 &trans_id_len);
1501 if (!trans_id || trans_id_len != 1) {
1502 wpa_printf(MSG_DEBUG,
1503 "DPP: Peer did not include Transaction ID");
1504 return;
1505 }
1506
1507 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
1508 if (!connector) {
1509 wpa_printf(MSG_DEBUG,
1510 "DPP: Peer did not include its Connector");
1511 return;
1512 }
1513
1514 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
1515 wpabuf_head(hapd->conf->dpp_netaccesskey),
1516 wpabuf_len(hapd->conf->dpp_netaccesskey),
1517 wpabuf_head(hapd->conf->dpp_csign),
1518 wpabuf_len(hapd->conf->dpp_csign),
1519 connector, connector_len, &expire);
1520 if (res == 255) {
1521 wpa_printf(MSG_INFO,
1522 "DPP: Network Introduction protocol resulted in internal failure (peer "
1523 MACSTR ")", MAC2STR(src));
1524 return;
1525 }
1526 if (res != DPP_STATUS_OK) {
1527 wpa_printf(MSG_INFO,
1528 "DPP: Network Introduction protocol resulted in failure (peer "
1529 MACSTR " status %d)", MAC2STR(src), res);
1530 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1531 res);
1532 return;
1533 }
1534
1535 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
1536 expire = hapd->conf->dpp_netaccesskey_expiry;
1537 if (expire)
1538 expiration = expire - now.sec;
1539 else
1540 expiration = 0;
1541
1542 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
1543 intro.pmkid, expiration,
1544 WPA_KEY_MGMT_DPP) < 0) {
1545 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
1546 return;
1547 }
1548
1549 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1550 DPP_STATUS_OK);
1551 }
1552
1553
1554 static void
hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1555 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
1556 const u8 *buf, size_t len,
1557 unsigned int freq)
1558 {
1559 struct wpabuf *msg;
1560
1561 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
1562 MAC2STR(src));
1563
1564 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1565 * values here */
1566
1567 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
1568 wpa_printf(MSG_DEBUG,
1569 "DPP: No PKEX code configured - ignore request");
1570 return;
1571 }
1572
1573 if (hapd->dpp_pkex) {
1574 /* TODO: Support parallel operations */
1575 wpa_printf(MSG_DEBUG,
1576 "DPP: Already in PKEX session - ignore new request");
1577 return;
1578 }
1579
1580 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
1581 hapd->dpp_pkex_bi,
1582 hapd->own_addr, src,
1583 hapd->dpp_pkex_identifier,
1584 hapd->dpp_pkex_code,
1585 buf, len);
1586 if (!hapd->dpp_pkex) {
1587 wpa_printf(MSG_DEBUG,
1588 "DPP: Failed to process the request - ignore it");
1589 return;
1590 }
1591
1592 msg = hapd->dpp_pkex->exchange_resp;
1593 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1594 " freq=%u type=%d", MAC2STR(src), freq,
1595 DPP_PA_PKEX_EXCHANGE_RESP);
1596 hostapd_drv_send_action(hapd, freq, 0, src,
1597 wpabuf_head(msg), wpabuf_len(msg));
1598 if (hapd->dpp_pkex->failed) {
1599 wpa_printf(MSG_DEBUG,
1600 "DPP: Terminate PKEX exchange due to an earlier error");
1601 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1602 hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
1603 dpp_pkex_free(hapd->dpp_pkex);
1604 hapd->dpp_pkex = NULL;
1605 }
1606 }
1607
1608
1609 static void
hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1610 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
1611 const u8 *buf, size_t len, unsigned int freq)
1612 {
1613 struct wpabuf *msg;
1614
1615 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
1616 MAC2STR(src));
1617
1618 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1619 * values here */
1620
1621 if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
1622 hapd->dpp_pkex->exchange_done) {
1623 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1624 return;
1625 }
1626
1627 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
1628 if (!msg) {
1629 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1630 return;
1631 }
1632
1633 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
1634 MAC2STR(src));
1635
1636 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1637 " freq=%u type=%d", MAC2STR(src), freq,
1638 DPP_PA_PKEX_COMMIT_REVEAL_REQ);
1639 hostapd_drv_send_action(hapd, freq, 0, src,
1640 wpabuf_head(msg), wpabuf_len(msg));
1641 wpabuf_free(msg);
1642 }
1643
1644
1645 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)1646 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
1647 const u8 *hdr, const u8 *buf, size_t len,
1648 unsigned int freq)
1649 {
1650 struct wpabuf *msg;
1651 struct dpp_pkex *pkex = hapd->dpp_pkex;
1652 struct dpp_bootstrap_info *bi;
1653
1654 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
1655 MAC2STR(src));
1656
1657 if (!pkex || pkex->initiator || !pkex->exchange_done) {
1658 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1659 return;
1660 }
1661
1662 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1663 if (!msg) {
1664 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1665 if (hapd->dpp_pkex->failed) {
1666 wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
1667 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1668 hapd->dpp_pkex->own_bi->pkex_t =
1669 hapd->dpp_pkex->t;
1670 dpp_pkex_free(hapd->dpp_pkex);
1671 hapd->dpp_pkex = NULL;
1672 }
1673 return;
1674 }
1675
1676 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
1677 MACSTR, MAC2STR(src));
1678
1679 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1680 " freq=%u type=%d", MAC2STR(src), freq,
1681 DPP_PA_PKEX_COMMIT_REVEAL_RESP);
1682 hostapd_drv_send_action(hapd, freq, 0, src,
1683 wpabuf_head(msg), wpabuf_len(msg));
1684 wpabuf_free(msg);
1685
1686 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1687 if (!bi)
1688 return;
1689 hapd->dpp_pkex = NULL;
1690 }
1691
1692
1693 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)1694 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
1695 const u8 *hdr, const u8 *buf, size_t len,
1696 unsigned int freq)
1697 {
1698 int res;
1699 struct dpp_bootstrap_info *bi;
1700 struct dpp_pkex *pkex = hapd->dpp_pkex;
1701 char cmd[500];
1702
1703 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
1704 MAC2STR(src));
1705
1706 if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1707 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1708 return;
1709 }
1710
1711 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1712 if (res < 0) {
1713 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1714 return;
1715 }
1716
1717 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1718 if (!bi)
1719 return;
1720 hapd->dpp_pkex = NULL;
1721
1722 os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
1723 bi->id,
1724 hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
1725 wpa_printf(MSG_DEBUG,
1726 "DPP: Start authentication after PKEX with parameters: %s",
1727 cmd);
1728 if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
1729 wpa_printf(MSG_DEBUG,
1730 "DPP: Authentication initialization failed");
1731 return;
1732 }
1733 }
1734
1735
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1736 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
1737 const u8 *buf, size_t len, unsigned int freq)
1738 {
1739 u8 crypto_suite;
1740 enum dpp_public_action_frame_type type;
1741 const u8 *hdr;
1742 unsigned int pkex_t;
1743
1744 if (len < DPP_HDR_LEN)
1745 return;
1746 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
1747 return;
1748 hdr = buf;
1749 buf += 4;
1750 len -= 4;
1751 crypto_suite = *buf++;
1752 type = *buf++;
1753 len -= 2;
1754
1755 wpa_printf(MSG_DEBUG,
1756 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1757 MACSTR " freq=%u",
1758 crypto_suite, type, MAC2STR(src), freq);
1759 if (crypto_suite != 1) {
1760 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
1761 crypto_suite);
1762 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1763 " freq=%u type=%d ignore=unsupported-crypto-suite",
1764 MAC2STR(src), freq, type);
1765 return;
1766 }
1767 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
1768 if (dpp_check_attrs(buf, len) < 0) {
1769 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1770 " freq=%u type=%d ignore=invalid-attributes",
1771 MAC2STR(src), freq, type);
1772 return;
1773 }
1774 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1775 " freq=%u type=%d", MAC2STR(src), freq, type);
1776
1777 #ifdef CONFIG_DPP2
1778 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1779 src, hdr, buf, len, freq, NULL, NULL) == 0)
1780 return;
1781 #endif /* CONFIG_DPP2 */
1782
1783 switch (type) {
1784 case DPP_PA_AUTHENTICATION_REQ:
1785 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
1786 break;
1787 case DPP_PA_AUTHENTICATION_RESP:
1788 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
1789 break;
1790 case DPP_PA_AUTHENTICATION_CONF:
1791 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
1792 break;
1793 case DPP_PA_PEER_DISCOVERY_REQ:
1794 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
1795 break;
1796 case DPP_PA_PKEX_EXCHANGE_REQ:
1797 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq);
1798 break;
1799 case DPP_PA_PKEX_EXCHANGE_RESP:
1800 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
1801 break;
1802 case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1803 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
1804 freq);
1805 break;
1806 case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1807 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
1808 freq);
1809 break;
1810 #ifdef CONFIG_DPP2
1811 case DPP_PA_CONFIGURATION_RESULT:
1812 hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
1813 break;
1814 case DPP_PA_CONNECTION_STATUS_RESULT:
1815 hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
1816 break;
1817 case DPP_PA_PRESENCE_ANNOUNCEMENT:
1818 hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
1819 freq);
1820 break;
1821 case DPP_PA_RECONFIG_ANNOUNCEMENT:
1822 hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
1823 freq);
1824 break;
1825 case DPP_PA_RECONFIG_AUTH_RESP:
1826 hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
1827 freq);
1828 break;
1829 #endif /* CONFIG_DPP2 */
1830 default:
1831 wpa_printf(MSG_DEBUG,
1832 "DPP: Ignored unsupported frame subtype %d", type);
1833 break;
1834 }
1835
1836 if (hapd->dpp_pkex)
1837 pkex_t = hapd->dpp_pkex->t;
1838 else if (hapd->dpp_pkex_bi)
1839 pkex_t = hapd->dpp_pkex_bi->pkex_t;
1840 else
1841 pkex_t = 0;
1842 if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
1843 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
1844 hostapd_dpp_pkex_remove(hapd, "*");
1845 }
1846 }
1847
1848
1849 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)1850 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
1851 const u8 *query, size_t query_len,
1852 const u8 *data, size_t data_len)
1853 {
1854 struct dpp_authentication *auth = hapd->dpp_auth;
1855 struct wpabuf *resp;
1856
1857 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
1858 if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
1859 os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
1860 #ifdef CONFIG_DPP2
1861 if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
1862 data_len) == 0) {
1863 /* Response will be forwarded once received over TCP */
1864 return NULL;
1865 }
1866 #endif /* CONFIG_DPP2 */
1867 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1868 return NULL;
1869 }
1870 wpa_hexdump(MSG_DEBUG,
1871 "DPP: Received Configuration Request (GAS Query Request)",
1872 query, query_len);
1873 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
1874 MAC2STR(sa));
1875 resp = dpp_conf_req_rx(auth, query, query_len);
1876 if (!resp)
1877 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1878 return resp;
1879 }
1880
1881
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)1882 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
1883 {
1884 struct dpp_authentication *auth = hapd->dpp_auth;
1885
1886 if (!auth)
1887 return;
1888
1889 wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
1890 ok);
1891 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1892 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
1893 #ifdef CONFIG_DPP2
1894 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1895 hapd, NULL);
1896 if (ok && auth->peer_version >= 2 &&
1897 auth->conf_resp_status == DPP_STATUS_OK) {
1898 wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
1899 auth->waiting_conf_result = 1;
1900 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1901 hapd, NULL);
1902 eloop_register_timeout(2, 0,
1903 hostapd_dpp_config_result_wait_timeout,
1904 hapd, NULL);
1905 return;
1906 }
1907 #endif /* CONFIG_DPP2 */
1908 hostapd_drv_send_action_cancel_wait(hapd);
1909
1910 if (ok)
1911 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1912 else
1913 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1914 dpp_auth_deinit(hapd->dpp_auth);
1915 hapd->dpp_auth = NULL;
1916 }
1917
1918
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)1919 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
1920 {
1921 struct dpp_authentication *auth;
1922 int ret = -1;
1923 char *curve = NULL;
1924
1925 auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
1926 if (!auth)
1927 return -1;
1928
1929 curve = get_param(cmd, " curve=");
1930 hostapd_dpp_set_testing_options(hapd, auth);
1931 if (dpp_set_configurator(auth, cmd) == 0 &&
1932 dpp_configurator_own_config(auth, curve, 1) == 0) {
1933 hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
1934 ret = 0;
1935 }
1936
1937 dpp_auth_deinit(auth);
1938 os_free(curve);
1939
1940 return ret;
1941 }
1942
1943
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)1944 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
1945 {
1946 struct dpp_bootstrap_info *own_bi;
1947 const char *pos, *end;
1948
1949 pos = os_strstr(cmd, " own=");
1950 if (!pos)
1951 return -1;
1952 pos += 5;
1953 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
1954 if (!own_bi) {
1955 wpa_printf(MSG_DEBUG,
1956 "DPP: Identified bootstrap info not found");
1957 return -1;
1958 }
1959 if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
1960 wpa_printf(MSG_DEBUG,
1961 "DPP: Identified bootstrap info not for PKEX");
1962 return -1;
1963 }
1964 hapd->dpp_pkex_bi = own_bi;
1965 own_bi->pkex_t = 0; /* clear pending errors on new code */
1966
1967 os_free(hapd->dpp_pkex_identifier);
1968 hapd->dpp_pkex_identifier = NULL;
1969 pos = os_strstr(cmd, " identifier=");
1970 if (pos) {
1971 pos += 12;
1972 end = os_strchr(pos, ' ');
1973 if (!end)
1974 return -1;
1975 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
1976 if (!hapd->dpp_pkex_identifier)
1977 return -1;
1978 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
1979 hapd->dpp_pkex_identifier[end - pos] = '\0';
1980 }
1981
1982 pos = os_strstr(cmd, " code=");
1983 if (!pos)
1984 return -1;
1985 os_free(hapd->dpp_pkex_code);
1986 hapd->dpp_pkex_code = os_strdup(pos + 6);
1987 if (!hapd->dpp_pkex_code)
1988 return -1;
1989
1990 if (os_strstr(cmd, " init=1")) {
1991 struct wpabuf *msg;
1992
1993 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
1994 dpp_pkex_free(hapd->dpp_pkex);
1995 hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
1996 hapd->own_addr,
1997 hapd->dpp_pkex_identifier,
1998 hapd->dpp_pkex_code);
1999 if (!hapd->dpp_pkex)
2000 return -1;
2001
2002 msg = hapd->dpp_pkex->exchange_req;
2003 /* TODO: Which channel to use? */
2004 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2005 " freq=%u type=%d", MAC2STR(broadcast), 2437,
2006 DPP_PA_PKEX_EXCHANGE_REQ);
2007 hostapd_drv_send_action(hapd, 2437, 0, broadcast,
2008 wpabuf_head(msg), wpabuf_len(msg));
2009 }
2010
2011 /* TODO: Support multiple PKEX info entries */
2012
2013 os_free(hapd->dpp_pkex_auth_cmd);
2014 hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
2015
2016 return 1;
2017 }
2018
2019
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)2020 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
2021 {
2022 unsigned int id_val;
2023
2024 if (os_strcmp(id, "*") == 0) {
2025 id_val = 0;
2026 } else {
2027 id_val = atoi(id);
2028 if (id_val == 0)
2029 return -1;
2030 }
2031
2032 if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
2033 return -1;
2034
2035 /* TODO: Support multiple PKEX entries */
2036 os_free(hapd->dpp_pkex_code);
2037 hapd->dpp_pkex_code = NULL;
2038 os_free(hapd->dpp_pkex_identifier);
2039 hapd->dpp_pkex_identifier = NULL;
2040 os_free(hapd->dpp_pkex_auth_cmd);
2041 hapd->dpp_pkex_auth_cmd = NULL;
2042 hapd->dpp_pkex_bi = NULL;
2043 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2044 dpp_pkex_free(hapd->dpp_pkex);
2045 hapd->dpp_pkex = NULL;
2046 return 0;
2047 }
2048
2049
hostapd_dpp_stop(struct hostapd_data * hapd)2050 void hostapd_dpp_stop(struct hostapd_data *hapd)
2051 {
2052 dpp_auth_deinit(hapd->dpp_auth);
2053 hapd->dpp_auth = NULL;
2054 dpp_pkex_free(hapd->dpp_pkex);
2055 hapd->dpp_pkex = NULL;
2056 }
2057
2058
2059 #ifdef CONFIG_DPP2
2060
hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)2061 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
2062 const u8 *msg, size_t len)
2063 {
2064 struct hostapd_data *hapd = ctx;
2065 u8 *buf;
2066
2067 wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
2068 MAC2STR(addr), freq);
2069 buf = os_malloc(2 + len);
2070 if (!buf)
2071 return;
2072 buf[0] = WLAN_ACTION_PUBLIC;
2073 buf[1] = WLAN_PA_VENDOR_SPECIFIC;
2074 os_memcpy(buf + 2, msg, len);
2075 hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
2076 os_free(buf);
2077 }
2078
2079
hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)2080 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
2081 u8 dialog_token, int prot,
2082 struct wpabuf *buf)
2083 {
2084 struct hostapd_data *hapd = ctx;
2085
2086 gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf);
2087 }
2088
2089 #endif /* CONFIG_DPP2 */
2090
2091
hostapd_dpp_add_controllers(struct hostapd_data * hapd)2092 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
2093 {
2094 #ifdef CONFIG_DPP2
2095 struct dpp_controller_conf *ctrl;
2096 struct dpp_relay_config config;
2097
2098 os_memset(&config, 0, sizeof(config));
2099 config.cb_ctx = hapd;
2100 config.tx = hostapd_dpp_relay_tx;
2101 config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
2102 for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
2103 config.ipaddr = &ctrl->ipaddr;
2104 config.pkhash = ctrl->pkhash;
2105 if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
2106 &config) < 0)
2107 return -1;
2108 }
2109 #endif /* CONFIG_DPP2 */
2110
2111 return 0;
2112 }
2113
2114
hostapd_dpp_init(struct hostapd_data * hapd)2115 int hostapd_dpp_init(struct hostapd_data *hapd)
2116 {
2117 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
2118 hapd->dpp_init_done = 1;
2119 return hostapd_dpp_add_controllers(hapd);
2120 }
2121
2122
hostapd_dpp_deinit(struct hostapd_data * hapd)2123 void hostapd_dpp_deinit(struct hostapd_data *hapd)
2124 {
2125 #ifdef CONFIG_TESTING_OPTIONS
2126 os_free(hapd->dpp_config_obj_override);
2127 hapd->dpp_config_obj_override = NULL;
2128 os_free(hapd->dpp_discovery_override);
2129 hapd->dpp_discovery_override = NULL;
2130 os_free(hapd->dpp_groups_override);
2131 hapd->dpp_groups_override = NULL;
2132 hapd->dpp_ignore_netaccesskey_mismatch = 0;
2133 #endif /* CONFIG_TESTING_OPTIONS */
2134 if (!hapd->dpp_init_done)
2135 return;
2136 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
2137 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
2138 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
2139 #ifdef CONFIG_DPP2
2140 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
2141 hapd, NULL);
2142 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
2143 NULL);
2144 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
2145 NULL);
2146 hostapd_dpp_chirp_stop(hapd);
2147 #endif /* CONFIG_DPP2 */
2148 dpp_auth_deinit(hapd->dpp_auth);
2149 hapd->dpp_auth = NULL;
2150 hostapd_dpp_pkex_remove(hapd, "*");
2151 hapd->dpp_pkex = NULL;
2152 os_free(hapd->dpp_configurator_params);
2153 hapd->dpp_configurator_params = NULL;
2154 }
2155
2156
2157 #ifdef CONFIG_DPP2
2158
2159 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
2160
hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)2161 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
2162 {
2163 struct hostapd_data *hapd = eloop_ctx;
2164
2165 wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
2166 hostapd_drv_send_action_cancel_wait(hapd);
2167 hostapd_dpp_chirp_next(hapd, NULL);
2168 }
2169
2170
hostapd_dpp_chirp_start(struct hostapd_data * hapd)2171 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
2172 {
2173 struct wpabuf *msg;
2174 int type;
2175
2176 msg = hapd->dpp_presence_announcement;
2177 type = DPP_PA_PRESENCE_ANNOUNCEMENT;
2178 wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
2179 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2180 " freq=%u type=%d",
2181 MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
2182 if (hostapd_drv_send_action(
2183 hapd, hapd->dpp_chirp_freq, 2000, broadcast,
2184 wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
2185 eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
2186 hapd, NULL) < 0)
2187 hostapd_dpp_chirp_stop(hapd);
2188 }
2189
2190
2191 static struct hostapd_hw_modes *
dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)2192 dpp_get_mode(struct hostapd_data *hapd,
2193 enum hostapd_hw_mode mode)
2194 {
2195 struct hostapd_hw_modes *modes = hapd->iface->hw_features;
2196 u16 num_modes = hapd->iface->num_hw_features;
2197 u16 i;
2198
2199 for (i = 0; i < num_modes; i++) {
2200 if (modes[i].mode != mode ||
2201 !modes[i].num_channels || !modes[i].channels)
2202 continue;
2203 return &modes[i];
2204 }
2205
2206 return NULL;
2207 }
2208
2209
2210 static void
hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)2211 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
2212 {
2213 struct hostapd_data *hapd = iface->bss[0];
2214 struct wpa_scan_results *scan_res;
2215 struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
2216 unsigned int i;
2217 struct hostapd_hw_modes *mode;
2218 int c;
2219
2220 if (!bi)
2221 return;
2222
2223 hapd->dpp_chirp_scan_done = 1;
2224
2225 scan_res = hostapd_driver_get_scan_results(hapd);
2226
2227 os_free(hapd->dpp_chirp_freqs);
2228 hapd->dpp_chirp_freqs = NULL;
2229
2230 /* Channels from own bootstrapping info */
2231 if (bi) {
2232 for (i = 0; i < bi->num_freq; i++)
2233 int_array_add_unique(&hapd->dpp_chirp_freqs,
2234 bi->freq[i]);
2235 }
2236
2237 /* Preferred chirping channels */
2238 int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
2239
2240 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
2241 if (mode) {
2242 int chan44 = 0, chan149 = 0;
2243
2244 for (c = 0; c < mode->num_channels; c++) {
2245 struct hostapd_channel_data *chan = &mode->channels[c];
2246
2247 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2248 HOSTAPD_CHAN_RADAR))
2249 continue;
2250 if (chan->freq == 5220)
2251 chan44 = 1;
2252 if (chan->freq == 5745)
2253 chan149 = 1;
2254 }
2255 if (chan149)
2256 int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
2257 else if (chan44)
2258 int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
2259 }
2260
2261 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
2262 if (mode) {
2263 for (c = 0; c < mode->num_channels; c++) {
2264 struct hostapd_channel_data *chan = &mode->channels[c];
2265
2266 if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
2267 HOSTAPD_CHAN_RADAR)) ||
2268 chan->freq != 60480)
2269 continue;
2270 int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
2271 break;
2272 }
2273 }
2274
2275 /* Add channels from scan results for APs that advertise Configurator
2276 * Connectivity element */
2277 for (i = 0; scan_res && i < scan_res->num; i++) {
2278 struct wpa_scan_res *bss = scan_res->res[i];
2279 size_t ie_len = bss->ie_len;
2280
2281 if (!ie_len)
2282 ie_len = bss->beacon_ie_len;
2283 if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
2284 DPP_CC_IE_VENDOR_TYPE))
2285 int_array_add_unique(&hapd->dpp_chirp_freqs,
2286 bss->freq);
2287 }
2288
2289 if (!hapd->dpp_chirp_freqs ||
2290 eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
2291 hapd, NULL) < 0)
2292 hostapd_dpp_chirp_stop(hapd);
2293
2294 wpa_scan_results_free(scan_res);
2295 }
2296
2297
hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)2298 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
2299 {
2300 struct hostapd_data *hapd = eloop_ctx;
2301 int i;
2302
2303 if (hapd->dpp_chirp_listen)
2304 hostapd_dpp_listen_stop(hapd);
2305
2306 if (hapd->dpp_chirp_freq == 0) {
2307 if (hapd->dpp_chirp_round % 4 == 0 &&
2308 !hapd->dpp_chirp_scan_done) {
2309 struct wpa_driver_scan_params params;
2310 int ret;
2311
2312 wpa_printf(MSG_DEBUG,
2313 "DPP: Update channel list for chirping");
2314 os_memset(¶ms, 0, sizeof(params));
2315 ret = hostapd_driver_scan(hapd, ¶ms);
2316 if (ret < 0) {
2317 wpa_printf(MSG_DEBUG,
2318 "DPP: Failed to request a scan ret=%d (%s)",
2319 ret, strerror(-ret));
2320 hostapd_dpp_chirp_scan_res_handler(hapd->iface);
2321 } else {
2322 hapd->iface->scan_cb =
2323 hostapd_dpp_chirp_scan_res_handler;
2324 }
2325 return;
2326 }
2327 hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
2328 hapd->dpp_chirp_round++;
2329 wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
2330 hapd->dpp_chirp_round);
2331 } else {
2332 for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
2333 if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
2334 break;
2335 if (!hapd->dpp_chirp_freqs[i]) {
2336 wpa_printf(MSG_DEBUG,
2337 "DPP: Previous chirp freq %d not found",
2338 hapd->dpp_chirp_freq);
2339 return;
2340 }
2341 i++;
2342 if (hapd->dpp_chirp_freqs[i]) {
2343 hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
2344 } else {
2345 hapd->dpp_chirp_iter--;
2346 if (hapd->dpp_chirp_iter <= 0) {
2347 wpa_printf(MSG_DEBUG,
2348 "DPP: Chirping iterations completed");
2349 hostapd_dpp_chirp_stop(hapd);
2350 return;
2351 }
2352 hapd->dpp_chirp_freq = 0;
2353 hapd->dpp_chirp_scan_done = 0;
2354 if (eloop_register_timeout(30, 0,
2355 hostapd_dpp_chirp_next,
2356 hapd, NULL) < 0) {
2357 hostapd_dpp_chirp_stop(hapd);
2358 return;
2359 }
2360 if (hapd->dpp_chirp_listen) {
2361 wpa_printf(MSG_DEBUG,
2362 "DPP: Listen on %d MHz during chirp 30 second wait",
2363 hapd->dpp_chirp_listen);
2364 /* TODO: start listen on the channel */
2365 } else {
2366 wpa_printf(MSG_DEBUG,
2367 "DPP: Wait 30 seconds before starting the next chirping round");
2368 }
2369 return;
2370 }
2371 }
2372
2373 hostapd_dpp_chirp_start(hapd);
2374 }
2375
2376
hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)2377 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
2378 {
2379 const char *pos;
2380 int iter = 1, listen_freq = 0;
2381 struct dpp_bootstrap_info *bi;
2382
2383 pos = os_strstr(cmd, " own=");
2384 if (!pos)
2385 return -1;
2386 pos += 5;
2387 bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
2388 if (!bi) {
2389 wpa_printf(MSG_DEBUG,
2390 "DPP: Identified bootstrap info not found");
2391 return -1;
2392 }
2393
2394 pos = os_strstr(cmd, " iter=");
2395 if (pos) {
2396 iter = atoi(pos + 6);
2397 if (iter <= 0)
2398 return -1;
2399 }
2400
2401 pos = os_strstr(cmd, " listen=");
2402 if (pos) {
2403 listen_freq = atoi(pos + 8);
2404 if (listen_freq <= 0)
2405 return -1;
2406 }
2407
2408 hostapd_dpp_chirp_stop(hapd);
2409 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
2410 hapd->dpp_qr_mutual = 0;
2411 hapd->dpp_chirp_bi = bi;
2412 hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
2413 if (!hapd->dpp_presence_announcement)
2414 return -1;
2415 hapd->dpp_chirp_iter = iter;
2416 hapd->dpp_chirp_round = 0;
2417 hapd->dpp_chirp_scan_done = 0;
2418 hapd->dpp_chirp_listen = listen_freq;
2419
2420 return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
2421 }
2422
2423
hostapd_dpp_chirp_stop(struct hostapd_data * hapd)2424 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
2425 {
2426 if (hapd->dpp_presence_announcement) {
2427 hostapd_drv_send_action_cancel_wait(hapd);
2428 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
2429 }
2430 hapd->dpp_chirp_bi = NULL;
2431 wpabuf_free(hapd->dpp_presence_announcement);
2432 hapd->dpp_presence_announcement = NULL;
2433 if (hapd->dpp_chirp_listen)
2434 hostapd_dpp_listen_stop(hapd);
2435 hapd->dpp_chirp_listen = 0;
2436 hapd->dpp_chirp_freq = 0;
2437 os_free(hapd->dpp_chirp_freqs);
2438 hapd->dpp_chirp_freqs = NULL;
2439 eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
2440 eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
2441 if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
2442 /* TODO: abort ongoing scan */
2443 hapd->iface->scan_cb = NULL;
2444 }
2445 }
2446
2447
handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)2448 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
2449 {
2450 struct dpp_bootstrap_info *bi = ctx;
2451 size_t i;
2452
2453 for (i = 0; i < iface->num_bss; i++) {
2454 struct hostapd_data *hapd = iface->bss[i];
2455
2456 if (bi == hapd->dpp_chirp_bi)
2457 hostapd_dpp_chirp_stop(hapd);
2458 }
2459
2460 return 0;
2461 }
2462
2463
hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)2464 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
2465 {
2466 struct hapd_interfaces *interfaces = ctx;
2467
2468 hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
2469 }
2470
2471 #endif /* CONFIG_DPP2 */
2472