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