blob: c86f01ba76843468ebe21d97fd5f4da56c6b2326 [file] [log] [blame]
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001/*
2 * hostapd / DPP integration
3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
Hai Shalomfdcde762020-04-02 11:19:20 -07004 * Copyright (c) 2018-2020, The Linux Foundation
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07005 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10#include "utils/includes.h"
11
12#include "utils/common.h"
13#include "utils/eloop.h"
14#include "common/dpp.h"
15#include "common/gas.h"
16#include "common/wpa_ctrl.h"
17#include "hostapd.h"
18#include "ap_drv_ops.h"
19#include "gas_query_ap.h"
Hai Shalom81f62d82019-07-22 12:10:00 -070020#include "gas_serv.h"
Dmitry Shmidtd2986c22017-10-23 14:22:09 -070021#include "wpa_auth.h"
22#include "dpp_hostapd.h"
23
24
Roshan Pius3a1667e2018-07-03 15:17:14 -070025static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -070026static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
Roshan Pius3a1667e2018-07-03 15:17:14 -070027static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
28static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -070029
30static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
31
32
Dmitry Shmidtd2986c22017-10-23 14:22:09 -070033/**
34 * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
35 * @hapd: Pointer to hostapd_data
36 * @cmd: DPP URI read from a QR Code
37 * Returns: Identifier of the stored info or -1 on failure
38 */
39int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
40{
41 struct dpp_bootstrap_info *bi;
42 struct dpp_authentication *auth = hapd->dpp_auth;
43
Hai Shalom021b0b52019-04-10 11:17:58 -070044 bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -070045 if (!bi)
46 return -1;
47
Dmitry Shmidtd2986c22017-10-23 14:22:09 -070048 if (auth && auth->response_pending &&
49 dpp_notify_new_qr_code(auth, bi) == 1) {
50 wpa_printf(MSG_DEBUG,
51 "DPP: Sending out pending authentication response");
Roshan Pius3a1667e2018-07-03 15:17:14 -070052 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
53 " freq=%u type=%d",
54 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
55 DPP_PA_AUTHENTICATION_RESP);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -070056 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
57 auth->peer_mac_addr,
58 wpabuf_head(hapd->dpp_auth->resp_msg),
59 wpabuf_len(hapd->dpp_auth->resp_msg));
60 }
61
62 return bi->id;
63}
64
65
Ahmed ElArabawy0ff61c52019-12-26 12:38:39 -080066/**
67 * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
68 * @hapd: Pointer to hostapd_data
69 * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
70 * Returns: Identifier of the stored info or -1 on failure
71 */
72int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
73{
74 struct dpp_bootstrap_info *bi;
75
76 bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
77 if (!bi)
78 return -1;
79
80 return bi->id;
81}
82
83
Hai Shalomfdcde762020-04-02 11:19:20 -070084int hostapd_dpp_nfc_handover_req(struct hostapd_data *hapd, const char *cmd)
85{
86 const char *pos;
87 struct dpp_bootstrap_info *peer_bi, *own_bi;
88
89 pos = os_strstr(cmd, " own=");
90 if (!pos)
91 return -1;
92 pos += 5;
93 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
94 if (!own_bi)
95 return -1;
96
97 pos = os_strstr(cmd, " uri=");
98 if (!pos)
99 return -1;
100 pos += 5;
101 peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
102 if (!peer_bi) {
103 wpa_printf(MSG_INFO,
104 "DPP: Failed to parse URI from NFC Handover Request");
105 return -1;
106 }
107
108 if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
109 return -1;
110
111 return peer_bi->id;
112}
113
114
115int hostapd_dpp_nfc_handover_sel(struct hostapd_data *hapd, const char *cmd)
116{
117 const char *pos;
118 struct dpp_bootstrap_info *peer_bi, *own_bi;
119
120 pos = os_strstr(cmd, " own=");
121 if (!pos)
122 return -1;
123 pos += 5;
124 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
125 if (!own_bi)
126 return -1;
127
128 pos = os_strstr(cmd, " uri=");
129 if (!pos)
130 return -1;
131 pos += 5;
132 peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
133 if (!peer_bi) {
134 wpa_printf(MSG_INFO,
135 "DPP: Failed to parse URI from NFC Handover Select");
136 return -1;
137 }
138
139 if (peer_bi->curve != own_bi->curve) {
140 wpa_printf(MSG_INFO,
141 "DPP: Peer (NFC Handover Selector) used different curve");
142 return -1;
143 }
144
145 return peer_bi->id;
146}
147
148
Roshan Pius3a1667e2018-07-03 15:17:14 -0700149static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
150 void *timeout_ctx)
151{
152 struct hostapd_data *hapd = eloop_ctx;
153 struct dpp_authentication *auth = hapd->dpp_auth;
154
155 if (!auth || !auth->resp_msg)
156 return;
157
158 wpa_printf(MSG_DEBUG,
159 "DPP: Retry Authentication Response after timeout");
160 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
161 " freq=%u type=%d",
162 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
163 DPP_PA_AUTHENTICATION_RESP);
164 hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
165 wpabuf_head(auth->resp_msg),
166 wpabuf_len(auth->resp_msg));
167}
168
169
170static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
171{
172 struct dpp_authentication *auth = hapd->dpp_auth;
173 unsigned int wait_time, max_tries;
174
175 if (!auth || !auth->resp_msg)
176 return;
177
178 if (hapd->dpp_resp_max_tries)
179 max_tries = hapd->dpp_resp_max_tries;
180 else
181 max_tries = 5;
182 auth->auth_resp_tries++;
183 if (auth->auth_resp_tries >= max_tries) {
184 wpa_printf(MSG_INFO,
185 "DPP: No confirm received from initiator - stopping exchange");
186 hostapd_drv_send_action_cancel_wait(hapd);
187 dpp_auth_deinit(hapd->dpp_auth);
188 hapd->dpp_auth = NULL;
189 return;
190 }
191
192 if (hapd->dpp_resp_retry_time)
193 wait_time = hapd->dpp_resp_retry_time;
194 else
195 wait_time = 1000;
196 wpa_printf(MSG_DEBUG,
197 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
198 wait_time);
199 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
200 eloop_register_timeout(wait_time / 1000,
201 (wait_time % 1000) * 1000,
202 hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
203}
204
205
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700206void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
207 const u8 *data, size_t data_len, int ok)
208{
Roshan Pius3a1667e2018-07-03 15:17:14 -0700209 struct dpp_authentication *auth = hapd->dpp_auth;
210
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700211 wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
212 MAC2STR(dst), ok);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700213 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
214 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700215
216 if (!hapd->dpp_auth) {
217 wpa_printf(MSG_DEBUG,
218 "DPP: Ignore TX status since there is no ongoing authentication exchange");
219 return;
220 }
221
Hai Shalom021b0b52019-04-10 11:17:58 -0700222#ifdef CONFIG_DPP2
223 if (auth->connect_on_tx_status) {
224 wpa_printf(MSG_DEBUG,
225 "DPP: Complete exchange on configuration result");
226 dpp_auth_deinit(hapd->dpp_auth);
227 hapd->dpp_auth = NULL;
228 return;
229 }
230#endif /* CONFIG_DPP2 */
231
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700232 if (hapd->dpp_auth->remove_on_tx_status) {
233 wpa_printf(MSG_DEBUG,
234 "DPP: Terminate authentication exchange due to an earlier error");
Roshan Pius3a1667e2018-07-03 15:17:14 -0700235 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
236 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
237 hapd, NULL);
238 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
239 NULL);
240 hostapd_drv_send_action_cancel_wait(hapd);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700241 dpp_auth_deinit(hapd->dpp_auth);
242 hapd->dpp_auth = NULL;
243 return;
244 }
245
246 if (hapd->dpp_auth_ok_on_ack)
247 hostapd_dpp_auth_success(hapd, 1);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700248
249 if (!is_broadcast_ether_addr(dst) && !ok) {
250 wpa_printf(MSG_DEBUG,
251 "DPP: Unicast DPP Action frame was not ACKed");
252 if (auth->waiting_auth_resp) {
253 /* In case of DPP Authentication Request frame, move to
254 * the next channel immediately. */
255 hostapd_drv_send_action_cancel_wait(hapd);
256 hostapd_dpp_auth_init_next(hapd);
257 return;
258 }
259 if (auth->waiting_auth_conf) {
260 hostapd_dpp_auth_resp_retry(hapd);
261 return;
262 }
263 }
264
265 if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
266 /* Allow timeout handling to stop iteration if no response is
267 * received from a peer that has ACKed a request. */
268 auth->auth_req_ack = 1;
269 }
270
271 if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
272 hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
273 wpa_printf(MSG_DEBUG,
274 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
275 hapd->dpp_auth->curr_freq,
276 hapd->dpp_auth->neg_freq);
277 hostapd_drv_send_action_cancel_wait(hapd);
278
279 if (hapd->dpp_auth->neg_freq !=
280 (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
281 /* TODO: Listen operation on non-operating channel */
282 wpa_printf(MSG_INFO,
283 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
284 hapd->dpp_auth->neg_freq, hapd->iface->freq);
285 }
286 }
287
288 if (hapd->dpp_auth_ok_on_ack)
289 hapd->dpp_auth_ok_on_ack = 0;
290}
291
292
293static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
294{
295 struct hostapd_data *hapd = eloop_ctx;
296 struct dpp_authentication *auth = hapd->dpp_auth;
297 unsigned int freq;
298 struct os_reltime now, diff;
299 unsigned int wait_time, diff_ms;
300
301 if (!auth || !auth->waiting_auth_resp)
302 return;
303
304 wait_time = hapd->dpp_resp_wait_time ?
305 hapd->dpp_resp_wait_time : 2000;
306 os_get_reltime(&now);
307 os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
308 diff_ms = diff.sec * 1000 + diff.usec / 1000;
309 wpa_printf(MSG_DEBUG,
310 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
311 wait_time, diff_ms);
312
313 if (auth->auth_req_ack && diff_ms >= wait_time) {
314 /* Peer ACK'ed Authentication Request frame, but did not reply
315 * with Authentication Response frame within two seconds. */
316 wpa_printf(MSG_INFO,
317 "DPP: No response received from responder - stopping initiation attempt");
318 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
319 hostapd_drv_send_action_cancel_wait(hapd);
320 hostapd_dpp_listen_stop(hapd);
321 dpp_auth_deinit(auth);
322 hapd->dpp_auth = NULL;
323 return;
324 }
325
326 if (diff_ms >= wait_time) {
327 /* Authentication Request frame was not ACK'ed and no reply
328 * was receiving within two seconds. */
329 wpa_printf(MSG_DEBUG,
330 "DPP: Continue Initiator channel iteration");
331 hostapd_drv_send_action_cancel_wait(hapd);
332 hostapd_dpp_listen_stop(hapd);
333 hostapd_dpp_auth_init_next(hapd);
334 return;
335 }
336
337 /* Driver did not support 2000 ms long wait_time with TX command, so
338 * schedule listen operation to continue waiting for the response.
339 *
340 * DPP listen operations continue until stopped, so simply schedule a
341 * new call to this function at the point when the two second reply
342 * wait has expired. */
343 wait_time -= diff_ms;
344
345 freq = auth->curr_freq;
346 if (auth->neg_freq > 0)
347 freq = auth->neg_freq;
348 wpa_printf(MSG_DEBUG,
349 "DPP: Continue reply wait on channel %u MHz for %u ms",
350 freq, wait_time);
351 hapd->dpp_in_response_listen = 1;
352
353 if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
354 /* TODO: Listen operation on non-operating channel */
355 wpa_printf(MSG_INFO,
356 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
357 freq, hapd->iface->freq);
358 }
359
360 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
361 hostapd_dpp_reply_wait_timeout, hapd, NULL);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700362}
363
364
365static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
366 struct dpp_authentication *auth)
367{
368#ifdef CONFIG_TESTING_OPTIONS
369 if (hapd->dpp_config_obj_override)
370 auth->config_obj_override =
371 os_strdup(hapd->dpp_config_obj_override);
372 if (hapd->dpp_discovery_override)
373 auth->discovery_override =
374 os_strdup(hapd->dpp_discovery_override);
375 if (hapd->dpp_groups_override)
376 auth->groups_override = os_strdup(hapd->dpp_groups_override);
377 auth->ignore_netaccesskey_mismatch =
378 hapd->dpp_ignore_netaccesskey_mismatch;
379#endif /* CONFIG_TESTING_OPTIONS */
380}
381
382
Roshan Pius3a1667e2018-07-03 15:17:14 -0700383static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
384{
385 struct hostapd_data *hapd = eloop_ctx;
386
387 if (!hapd->dpp_auth)
388 return;
389 wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
390 hostapd_dpp_auth_init_next(hapd);
391}
392
393
394static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
395{
396 struct dpp_authentication *auth = hapd->dpp_auth;
397 const u8 *dst;
398 unsigned int wait_time, max_wait_time, freq, max_tries, used;
399 struct os_reltime now, diff;
400
401 if (!auth)
402 return -1;
403
404 if (auth->freq_idx == 0)
405 os_get_reltime(&hapd->dpp_init_iter_start);
406
407 if (auth->freq_idx >= auth->num_freq) {
408 auth->num_freq_iters++;
409 if (hapd->dpp_init_max_tries)
410 max_tries = hapd->dpp_init_max_tries;
411 else
412 max_tries = 5;
413 if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
414 wpa_printf(MSG_INFO,
415 "DPP: No response received from responder - stopping initiation attempt");
416 wpa_msg(hapd->msg_ctx, MSG_INFO,
417 DPP_EVENT_AUTH_INIT_FAILED);
418 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
419 hapd, NULL);
420 hostapd_drv_send_action_cancel_wait(hapd);
421 dpp_auth_deinit(hapd->dpp_auth);
422 hapd->dpp_auth = NULL;
423 return -1;
424 }
425 auth->freq_idx = 0;
426 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
427 if (hapd->dpp_init_retry_time)
428 wait_time = hapd->dpp_init_retry_time;
429 else
430 wait_time = 10000;
431 os_get_reltime(&now);
432 os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
433 used = diff.sec * 1000 + diff.usec / 1000;
434 if (used > wait_time)
435 wait_time = 0;
436 else
437 wait_time -= used;
438 wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
439 wait_time);
440 eloop_register_timeout(wait_time / 1000,
441 (wait_time % 1000) * 1000,
442 hostapd_dpp_init_timeout, hapd,
443 NULL);
444 return 0;
445 }
446 freq = auth->freq[auth->freq_idx++];
447 auth->curr_freq = freq;
448
449 if (is_zero_ether_addr(auth->peer_bi->mac_addr))
450 dst = broadcast;
451 else
452 dst = auth->peer_bi->mac_addr;
453 hapd->dpp_auth_ok_on_ack = 0;
454 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
455 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
456 max_wait_time = hapd->dpp_resp_wait_time ?
457 hapd->dpp_resp_wait_time : 2000;
458 if (wait_time > max_wait_time)
459 wait_time = max_wait_time;
460 wait_time += 10; /* give the driver some extra time to complete */
461 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
462 hostapd_dpp_reply_wait_timeout, hapd, NULL);
463 wait_time -= 10;
464 if (auth->neg_freq > 0 && freq != auth->neg_freq) {
465 wpa_printf(MSG_DEBUG,
466 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
467 freq, auth->neg_freq);
468 }
469 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
470 " freq=%u type=%d",
471 MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
472 auth->auth_req_ack = 0;
473 os_get_reltime(&hapd->dpp_last_init);
474 return hostapd_drv_send_action(hapd, freq, wait_time,
475 dst,
476 wpabuf_head(hapd->dpp_auth->req_msg),
477 wpabuf_len(hapd->dpp_auth->req_msg));
478}
479
480
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700481int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
482{
483 const char *pos;
484 struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
Roshan Pius3a1667e2018-07-03 15:17:14 -0700485 u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
486 unsigned int neg_freq = 0;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700487
488 pos = os_strstr(cmd, " peer=");
489 if (!pos)
490 return -1;
491 pos += 6;
Hai Shalom021b0b52019-04-10 11:17:58 -0700492 peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700493 if (!peer_bi) {
494 wpa_printf(MSG_INFO,
495 "DPP: Could not find bootstrapping info for the identified peer");
496 return -1;
497 }
498
499 pos = os_strstr(cmd, " own=");
500 if (pos) {
501 pos += 5;
Hai Shalom021b0b52019-04-10 11:17:58 -0700502 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
503 atoi(pos));
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700504 if (!own_bi) {
505 wpa_printf(MSG_INFO,
506 "DPP: Could not find bootstrapping info for the identified local entry");
507 return -1;
508 }
509
510 if (peer_bi->curve != own_bi->curve) {
511 wpa_printf(MSG_INFO,
512 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
513 peer_bi->curve->name, own_bi->curve->name);
514 return -1;
515 }
516 }
517
518 pos = os_strstr(cmd, " role=");
519 if (pos) {
520 pos += 6;
521 if (os_strncmp(pos, "configurator", 12) == 0)
Roshan Pius3a1667e2018-07-03 15:17:14 -0700522 allowed_roles = DPP_CAPAB_CONFIGURATOR;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700523 else if (os_strncmp(pos, "enrollee", 8) == 0)
Roshan Pius3a1667e2018-07-03 15:17:14 -0700524 allowed_roles = DPP_CAPAB_ENROLLEE;
525 else if (os_strncmp(pos, "either", 6) == 0)
526 allowed_roles = DPP_CAPAB_CONFIGURATOR |
527 DPP_CAPAB_ENROLLEE;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700528 else
529 goto fail;
530 }
531
Roshan Pius3a1667e2018-07-03 15:17:14 -0700532 pos = os_strstr(cmd, " neg_freq=");
533 if (pos)
534 neg_freq = atoi(pos + 10);
535
536 if (hapd->dpp_auth) {
537 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
538 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
539 hapd, NULL);
540 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
541 NULL);
542 hostapd_drv_send_action_cancel_wait(hapd);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700543 dpp_auth_deinit(hapd->dpp_auth);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700544 }
545
Hai Shalomfdcde762020-04-02 11:19:20 -0700546 hapd->dpp_auth = dpp_auth_init(hapd->iface->interfaces->dpp,
547 hapd->msg_ctx, peer_bi, own_bi,
Roshan Pius3a1667e2018-07-03 15:17:14 -0700548 allowed_roles, neg_freq,
549 hapd->iface->hw_features,
550 hapd->iface->num_hw_features);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700551 if (!hapd->dpp_auth)
552 goto fail;
553 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
Hai Shalomfdcde762020-04-02 11:19:20 -0700554 if (dpp_set_configurator(hapd->dpp_auth, cmd) < 0) {
Hai Shalom74f70d42019-02-11 14:42:39 -0800555 dpp_auth_deinit(hapd->dpp_auth);
556 hapd->dpp_auth = NULL;
557 goto fail;
558 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700559
Roshan Pius3a1667e2018-07-03 15:17:14 -0700560 hapd->dpp_auth->neg_freq = neg_freq;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700561
Roshan Pius3a1667e2018-07-03 15:17:14 -0700562 if (!is_zero_ether_addr(peer_bi->mac_addr))
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700563 os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
564 ETH_ALEN);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700565
Roshan Pius3a1667e2018-07-03 15:17:14 -0700566 return hostapd_dpp_auth_init_next(hapd);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700567fail:
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700568 return -1;
569}
570
571
Roshan Pius3a1667e2018-07-03 15:17:14 -0700572int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
573{
574 int freq;
575
576 freq = atoi(cmd);
577 if (freq <= 0)
578 return -1;
579
580 if (os_strstr(cmd, " role=configurator"))
581 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
582 else if (os_strstr(cmd, " role=enrollee"))
583 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
584 else
585 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
586 DPP_CAPAB_ENROLLEE;
587 hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
588
589 if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
590 /* TODO: Listen operation on non-operating channel */
591 wpa_printf(MSG_INFO,
592 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
593 freq, hapd->iface->freq);
594 return -1;
595 }
596
597 return 0;
598}
599
600
601void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
602{
603 /* TODO: Stop listen operation on non-operating channel */
604}
605
606
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700607static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
608 const u8 *hdr, const u8 *buf, size_t len,
609 unsigned int freq)
610{
Roshan Pius3a1667e2018-07-03 15:17:14 -0700611 const u8 *r_bootstrap, *i_bootstrap;
612 u16 r_bootstrap_len, i_bootstrap_len;
Hai Shalom021b0b52019-04-10 11:17:58 -0700613 struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
614
615 if (!hapd->iface->interfaces->dpp)
616 return;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700617
618 wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
619 MAC2STR(src));
620
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700621 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
622 &r_bootstrap_len);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700623 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
624 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
625 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700626 return;
627 }
628 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
629 r_bootstrap, r_bootstrap_len);
630
631 i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
632 &i_bootstrap_len);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700633 if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
634 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
635 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700636 return;
637 }
638 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
639 i_bootstrap, i_bootstrap_len);
640
641 /* Try to find own and peer bootstrapping key matches based on the
642 * received hash values */
Hai Shalom021b0b52019-04-10 11:17:58 -0700643 dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
644 r_bootstrap, &own_bi, &peer_bi);
Hai Shalom81f62d82019-07-22 12:10:00 -0700645#ifdef CONFIG_DPP2
646 if (!own_bi) {
647 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
648 src, hdr, buf, len, freq, i_bootstrap,
649 r_bootstrap) == 0)
650 return;
651 }
652#endif /* CONFIG_DPP2 */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700653 if (!own_bi) {
Roshan Pius3a1667e2018-07-03 15:17:14 -0700654 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
655 "No matching own bootstrapping key found - ignore message");
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700656 return;
657 }
658
659 if (hapd->dpp_auth) {
Roshan Pius3a1667e2018-07-03 15:17:14 -0700660 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
661 "Already in DPP authentication exchange - ignore new one");
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700662 return;
663 }
664
665 hapd->dpp_auth_ok_on_ack = 0;
Hai Shalomfdcde762020-04-02 11:19:20 -0700666 hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
667 hapd->msg_ctx, hapd->dpp_allowed_roles,
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700668 hapd->dpp_qr_mutual,
Roshan Pius3a1667e2018-07-03 15:17:14 -0700669 peer_bi, own_bi, freq, hdr, buf, len);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700670 if (!hapd->dpp_auth) {
671 wpa_printf(MSG_DEBUG, "DPP: No response generated");
672 return;
673 }
674 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
Hai Shalomfdcde762020-04-02 11:19:20 -0700675 if (dpp_set_configurator(hapd->dpp_auth,
Hai Shalom021b0b52019-04-10 11:17:58 -0700676 hapd->dpp_configurator_params) < 0) {
Hai Shalom74f70d42019-02-11 14:42:39 -0800677 dpp_auth_deinit(hapd->dpp_auth);
678 hapd->dpp_auth = NULL;
679 return;
680 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700681 os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
682
Roshan Pius3a1667e2018-07-03 15:17:14 -0700683 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
684 " freq=%u type=%d",
685 MAC2STR(src), hapd->dpp_auth->curr_freq,
686 DPP_PA_AUTHENTICATION_RESP);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700687 hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
688 src, wpabuf_head(hapd->dpp_auth->resp_msg),
689 wpabuf_len(hapd->dpp_auth->resp_msg));
690}
691
692
Roshan Pius3a1667e2018-07-03 15:17:14 -0700693static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
Hai Shalomc3565922019-10-28 11:58:20 -0700694 struct dpp_authentication *auth,
695 struct dpp_config_obj *conf)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700696{
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700697 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700698 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
Hai Shalomc3565922019-10-28 11:58:20 -0700699 dpp_akm_str(conf->akm));
700 if (conf->ssid_len)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700701 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
Hai Shalomc3565922019-10-28 11:58:20 -0700702 wpa_ssid_txt(conf->ssid, conf->ssid_len));
703 if (conf->connector) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700704 /* TODO: Save the Connector and consider using a command
705 * to fetch the value instead of sending an event with
706 * it. The Connector could end up being larger than what
707 * most clients are ready to receive as an event
708 * message. */
709 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
Hai Shalomc3565922019-10-28 11:58:20 -0700710 conf->connector);
Hai Shalomfdcde762020-04-02 11:19:20 -0700711 }
712 if (conf->passphrase[0]) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700713 char hex[64 * 2 + 1];
714
715 wpa_snprintf_hex(hex, sizeof(hex),
Hai Shalomc3565922019-10-28 11:58:20 -0700716 (const u8 *) conf->passphrase,
717 os_strlen(conf->passphrase));
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700718 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
719 hex);
Hai Shalomc3565922019-10-28 11:58:20 -0700720 } else if (conf->psk_set) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700721 char hex[PMK_LEN * 2 + 1];
722
Hai Shalomc3565922019-10-28 11:58:20 -0700723 wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700724 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
725 hex);
726 }
Hai Shalomc3565922019-10-28 11:58:20 -0700727 if (conf->c_sign_key) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700728 char *hex;
729 size_t hexlen;
730
Hai Shalomc3565922019-10-28 11:58:20 -0700731 hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700732 hex = os_malloc(hexlen);
733 if (hex) {
734 wpa_snprintf_hex(hex, hexlen,
Hai Shalomc3565922019-10-28 11:58:20 -0700735 wpabuf_head(conf->c_sign_key),
736 wpabuf_len(conf->c_sign_key));
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700737 wpa_msg(hapd->msg_ctx, MSG_INFO,
738 DPP_EVENT_C_SIGN_KEY "%s", hex);
739 os_free(hex);
740 }
741 }
742 if (auth->net_access_key) {
743 char *hex;
744 size_t hexlen;
745
746 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
747 hex = os_malloc(hexlen);
748 if (hex) {
749 wpa_snprintf_hex(hex, hexlen,
750 wpabuf_head(auth->net_access_key),
751 wpabuf_len(auth->net_access_key));
752 if (auth->net_access_key_expiry)
753 wpa_msg(hapd->msg_ctx, MSG_INFO,
754 DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
755 (unsigned long)
756 auth->net_access_key_expiry);
757 else
758 wpa_msg(hapd->msg_ctx, MSG_INFO,
759 DPP_EVENT_NET_ACCESS_KEY "%s", hex);
760 os_free(hex);
761 }
762 }
Roshan Pius3a1667e2018-07-03 15:17:14 -0700763}
764
765
Hai Shalomfdcde762020-04-02 11:19:20 -0700766static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
767 struct dpp_asymmetric_key *key)
768{
769#ifdef CONFIG_DPP2
770 int res;
771
772 if (!key)
773 return 0;
774
775 wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
776 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
777
778 while (key) {
779 res = dpp_configurator_from_backup(
780 hapd->iface->interfaces->dpp, key);
781 if (res < 0)
782 return -1;
783 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
784 res);
785 key = key->next;
786 }
787#endif /* CONFIG_DPP2 */
788
789 return 0;
790}
791
792
Roshan Pius3a1667e2018-07-03 15:17:14 -0700793static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
794 enum gas_query_ap_result result,
795 const struct wpabuf *adv_proto,
796 const struct wpabuf *resp, u16 status_code)
797{
798 struct hostapd_data *hapd = ctx;
799 const u8 *pos;
800 struct dpp_authentication *auth = hapd->dpp_auth;
Hai Shalom021b0b52019-04-10 11:17:58 -0700801 enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
Roshan Pius3a1667e2018-07-03 15:17:14 -0700802
803 if (!auth || !auth->auth_success) {
804 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
805 return;
806 }
807 if (!resp || status_code != WLAN_STATUS_SUCCESS) {
808 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
809 goto fail;
810 }
811
812 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
813 adv_proto);
814 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
815 resp);
816
817 if (wpabuf_len(adv_proto) != 10 ||
818 !(pos = wpabuf_head(adv_proto)) ||
819 pos[0] != WLAN_EID_ADV_PROTO ||
820 pos[1] != 8 ||
821 pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
822 pos[4] != 5 ||
823 WPA_GET_BE24(&pos[5]) != OUI_WFA ||
824 pos[8] != 0x1a ||
825 pos[9] != 1) {
826 wpa_printf(MSG_DEBUG,
827 "DPP: Not a DPP Advertisement Protocol ID");
828 goto fail;
829 }
830
831 if (dpp_conf_resp_rx(auth, resp) < 0) {
832 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
833 goto fail;
834 }
835
Hai Shalomc3565922019-10-28 11:58:20 -0700836 hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
Hai Shalomfdcde762020-04-02 11:19:20 -0700837 if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
838 goto fail;
839
Hai Shalom021b0b52019-04-10 11:17:58 -0700840 status = DPP_STATUS_OK;
841#ifdef CONFIG_TESTING_OPTIONS
842 if (dpp_test == DPP_TEST_REJECT_CONFIG) {
843 wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
844 status = DPP_STATUS_CONFIG_REJECTED;
845 }
846#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700847fail:
Hai Shalom021b0b52019-04-10 11:17:58 -0700848 if (status != DPP_STATUS_OK)
849 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
850#ifdef CONFIG_DPP2
851 if (auth->peer_version >= 2 &&
852 auth->conf_resp_status == DPP_STATUS_OK) {
853 struct wpabuf *msg;
854
855 wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
856 msg = dpp_build_conf_result(auth, status);
857 if (!msg)
858 goto fail2;
859
860 wpa_msg(hapd->msg_ctx, MSG_INFO,
861 DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
862 MAC2STR(addr), auth->curr_freq,
863 DPP_PA_CONFIGURATION_RESULT);
864 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
865 addr, wpabuf_head(msg),
866 wpabuf_len(msg));
867 wpabuf_free(msg);
868
869 /* This exchange will be terminated in the TX status handler */
870 auth->connect_on_tx_status = 1;
871 return;
872 }
873fail2:
874#endif /* CONFIG_DPP2 */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700875 dpp_auth_deinit(hapd->dpp_auth);
876 hapd->dpp_auth = NULL;
877}
878
879
880static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
881{
882 struct dpp_authentication *auth = hapd->dpp_auth;
Hai Shalom021b0b52019-04-10 11:17:58 -0700883 struct wpabuf *buf;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700884 int res;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700885
Ahmed ElArabawy0ff61c52019-12-26 12:38:39 -0800886 buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
887 DPP_NETROLE_AP,
Hai Shalomc3565922019-10-28 11:58:20 -0700888 hapd->conf->dpp_mud_url, NULL);
Hai Shalom021b0b52019-04-10 11:17:58 -0700889 if (!buf) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700890 wpa_printf(MSG_DEBUG,
891 "DPP: No configuration request data available");
892 return;
893 }
894
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700895 wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
896 MAC2STR(auth->peer_mac_addr), auth->curr_freq);
897
898 res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
899 buf, hostapd_dpp_gas_resp_cb, hapd);
900 if (res < 0) {
901 wpa_msg(hapd->msg_ctx, MSG_DEBUG,
902 "GAS: Failed to send Query Request");
903 wpabuf_free(buf);
904 } else {
905 wpa_printf(MSG_DEBUG,
906 "DPP: GAS query started with dialog token %u", res);
907 }
908}
909
910
911static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
912{
913 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
914 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
915 initiator);
Roshan Pius3a1667e2018-07-03 15:17:14 -0700916#ifdef CONFIG_TESTING_OPTIONS
917 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
918 wpa_printf(MSG_INFO,
919 "DPP: TESTING - stop at Authentication Confirm");
920 if (hapd->dpp_auth->configurator) {
921 /* Prevent GAS response */
922 hapd->dpp_auth->auth_success = 0;
923 }
924 return;
925 }
926#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700927
928 if (!hapd->dpp_auth->configurator)
929 hostapd_dpp_start_gas_client(hapd);
930}
931
932
933static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
Roshan Pius3a1667e2018-07-03 15:17:14 -0700934 const u8 *hdr, const u8 *buf, size_t len,
935 unsigned int freq)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700936{
937 struct dpp_authentication *auth = hapd->dpp_auth;
938 struct wpabuf *msg;
939
940 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
941 MAC2STR(src));
942
943 if (!auth) {
944 wpa_printf(MSG_DEBUG,
945 "DPP: No DPP Authentication in progress - drop");
946 return;
947 }
948
949 if (!is_zero_ether_addr(auth->peer_mac_addr) &&
950 os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
951 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
952 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
953 return;
954 }
955
Roshan Pius3a1667e2018-07-03 15:17:14 -0700956 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
957
958 if (auth->curr_freq != freq && auth->neg_freq == freq) {
959 wpa_printf(MSG_DEBUG,
960 "DPP: Responder accepted request for different negotiation channel");
961 auth->curr_freq = freq;
962 }
963
964 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700965 msg = dpp_auth_resp_rx(auth, hdr, buf, len);
966 if (!msg) {
967 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
968 wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
969 return;
970 }
971 wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
972 return;
973 }
974 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
975
Roshan Pius3a1667e2018-07-03 15:17:14 -0700976 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
977 " freq=%u type=%d", MAC2STR(src), auth->curr_freq,
978 DPP_PA_AUTHENTICATION_CONF);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700979 hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
980 wpabuf_head(msg), wpabuf_len(msg));
981 wpabuf_free(msg);
982 hapd->dpp_auth_ok_on_ack = 1;
983}
984
985
986static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
987 const u8 *hdr, const u8 *buf, size_t len)
988{
989 struct dpp_authentication *auth = hapd->dpp_auth;
990
991 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
992 MAC2STR(src));
993
994 if (!auth) {
995 wpa_printf(MSG_DEBUG,
996 "DPP: No DPP Authentication in progress - drop");
997 return;
998 }
999
1000 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1001 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1002 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1003 return;
1004 }
1005
1006 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1007 wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1008 return;
1009 }
1010
1011 hostapd_dpp_auth_success(hapd, 0);
1012}
1013
1014
Hai Shalom021b0b52019-04-10 11:17:58 -07001015#ifdef CONFIG_DPP2
1016
1017static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1018 void *timeout_ctx)
1019{
1020 struct hostapd_data *hapd = eloop_ctx;
1021 struct dpp_authentication *auth = hapd->dpp_auth;
1022
1023 if (!auth || !auth->waiting_conf_result)
1024 return;
1025
1026 wpa_printf(MSG_DEBUG,
1027 "DPP: Timeout while waiting for Configuration Result");
1028 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1029 dpp_auth_deinit(auth);
1030 hapd->dpp_auth = NULL;
1031}
1032
1033
Hai Shalomc3565922019-10-28 11:58:20 -07001034static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1035 void *timeout_ctx)
1036{
1037 struct hostapd_data *hapd = eloop_ctx;
1038 struct dpp_authentication *auth = hapd->dpp_auth;
1039
1040 if (!auth || !auth->waiting_conf_result)
1041 return;
1042
1043 wpa_printf(MSG_DEBUG,
1044 "DPP: Timeout while waiting for Connection Status Result");
1045 wpa_msg(hapd->msg_ctx, MSG_INFO,
1046 DPP_EVENT_CONN_STATUS_RESULT "timeout");
1047 dpp_auth_deinit(auth);
1048 hapd->dpp_auth = NULL;
1049}
1050
1051
Hai Shalom021b0b52019-04-10 11:17:58 -07001052static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1053 const u8 *hdr, const u8 *buf, size_t len)
1054{
1055 struct dpp_authentication *auth = hapd->dpp_auth;
1056 enum dpp_status_error status;
1057
1058 wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
1059 MAC2STR(src));
1060
1061 if (!auth || !auth->waiting_conf_result) {
1062 wpa_printf(MSG_DEBUG,
1063 "DPP: No DPP Configuration waiting for result - drop");
1064 return;
1065 }
1066
1067 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1068 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1069 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1070 return;
1071 }
1072
1073 status = dpp_conf_result_rx(auth, hdr, buf, len);
1074
Hai Shalomc3565922019-10-28 11:58:20 -07001075 if (status == DPP_STATUS_OK && auth->send_conn_status) {
1076 wpa_msg(hapd->msg_ctx, MSG_INFO,
1077 DPP_EVENT_CONF_SENT "wait_conn_status=1");
1078 wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1079 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1080 hapd, NULL);
1081 eloop_cancel_timeout(
1082 hostapd_dpp_conn_status_result_wait_timeout,
1083 hapd, NULL);
1084 eloop_register_timeout(
1085 16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1086 hapd, NULL);
1087 return;
1088 }
Hai Shalom021b0b52019-04-10 11:17:58 -07001089 hostapd_drv_send_action_cancel_wait(hapd);
1090 hostapd_dpp_listen_stop(hapd);
1091 if (status == DPP_STATUS_OK)
1092 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1093 else
1094 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1095 dpp_auth_deinit(auth);
1096 hapd->dpp_auth = NULL;
1097 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1098 NULL);
1099}
1100
Hai Shalomc3565922019-10-28 11:58:20 -07001101
1102static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1103 const u8 *src, const u8 *hdr,
1104 const u8 *buf, size_t len)
1105{
1106 struct dpp_authentication *auth = hapd->dpp_auth;
1107 enum dpp_status_error status;
1108 u8 ssid[SSID_MAX_LEN];
1109 size_t ssid_len = 0;
1110 char *channel_list = NULL;
1111
1112 wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1113
1114 if (!auth || !auth->waiting_conn_status_result) {
1115 wpa_printf(MSG_DEBUG,
1116 "DPP: No DPP Configuration waiting for connection status result - drop");
1117 return;
1118 }
1119
1120 status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1121 ssid, &ssid_len, &channel_list);
1122 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1123 "result=%d ssid=%s channel_list=%s",
1124 status, wpa_ssid_txt(ssid, ssid_len),
1125 channel_list ? channel_list : "N/A");
1126 os_free(channel_list);
1127 hostapd_drv_send_action_cancel_wait(hapd);
1128 hostapd_dpp_listen_stop(hapd);
1129 dpp_auth_deinit(auth);
1130 hapd->dpp_auth = NULL;
1131 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1132 hapd, NULL);
1133}
1134
1135
Hai Shalomfdcde762020-04-02 11:19:20 -07001136static void
1137hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1138 const u8 *hdr, const u8 *buf, size_t len,
1139 unsigned int freq)
1140{
1141 const u8 *r_bootstrap;
1142 u16 r_bootstrap_len;
1143 struct dpp_bootstrap_info *peer_bi;
1144 struct dpp_authentication *auth;
1145
1146 wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
1147 MAC2STR(src));
1148
1149 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1150 &r_bootstrap_len);
1151 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1152 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1153 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1154 return;
1155 }
1156 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1157 r_bootstrap, r_bootstrap_len);
1158 peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1159 r_bootstrap);
1160 if (!peer_bi) {
1161 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1162 src, hdr, buf, len, freq, NULL,
1163 r_bootstrap) == 0)
1164 return;
1165 wpa_printf(MSG_DEBUG,
1166 "DPP: No matching bootstrapping information found");
1167 return;
1168 }
1169
1170 if (hapd->dpp_auth) {
1171 wpa_printf(MSG_DEBUG,
1172 "DPP: Ignore Presence Announcement during ongoing Authentication");
1173 return;
1174 }
1175
1176 auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1177 peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1178 0);
1179 if (!auth)
1180 return;
1181 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
1182 if (dpp_set_configurator(hapd->dpp_auth,
1183 hapd->dpp_configurator_params) < 0) {
1184 dpp_auth_deinit(auth);
1185 return;
1186 }
1187
1188 auth->neg_freq = freq;
1189
1190 if (!is_zero_ether_addr(peer_bi->mac_addr))
1191 os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
1192
1193 hapd->dpp_auth = auth;
1194 if (hostapd_dpp_auth_init_next(hapd) < 0) {
1195 dpp_auth_deinit(hapd->dpp_auth);
1196 hapd->dpp_auth = NULL;
1197 }
1198}
1199
Hai Shalom021b0b52019-04-10 11:17:58 -07001200#endif /* CONFIG_DPP2 */
1201
1202
Roshan Pius3a1667e2018-07-03 15:17:14 -07001203static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1204 const u8 *src, unsigned int freq,
1205 u8 trans_id,
1206 enum dpp_status_error status)
1207{
1208 struct wpabuf *msg;
1209
1210 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP,
1211 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector));
1212 if (!msg)
1213 return;
1214
1215#ifdef CONFIG_TESTING_OPTIONS
1216 if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1217 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1218 goto skip_trans_id;
1219 }
1220 if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1221 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1222 trans_id ^= 0x01;
1223 }
1224#endif /* CONFIG_TESTING_OPTIONS */
1225
1226 /* Transaction ID */
1227 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1228 wpabuf_put_le16(msg, 1);
1229 wpabuf_put_u8(msg, trans_id);
1230
1231#ifdef CONFIG_TESTING_OPTIONS
1232skip_trans_id:
1233 if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1234 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1235 goto skip_status;
1236 }
1237 if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1238 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1239 status = 254;
1240 }
1241#endif /* CONFIG_TESTING_OPTIONS */
1242
1243 /* DPP Status */
1244 wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1245 wpabuf_put_le16(msg, 1);
1246 wpabuf_put_u8(msg, status);
1247
1248#ifdef CONFIG_TESTING_OPTIONS
1249skip_status:
1250 if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1251 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1252 goto skip_connector;
1253 }
1254 if (status == DPP_STATUS_OK &&
1255 dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1256 char *connector;
1257
1258 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1259 connector = dpp_corrupt_connector_signature(
1260 hapd->conf->dpp_connector);
1261 if (!connector) {
1262 wpabuf_free(msg);
1263 return;
1264 }
1265 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1266 wpabuf_put_le16(msg, os_strlen(connector));
1267 wpabuf_put_str(msg, connector);
1268 os_free(connector);
1269 goto skip_connector;
1270 }
1271#endif /* CONFIG_TESTING_OPTIONS */
1272
1273 /* DPP Connector */
1274 if (status == DPP_STATUS_OK) {
1275 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1276 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1277 wpabuf_put_str(msg, hapd->conf->dpp_connector);
1278 }
1279
1280#ifdef CONFIG_TESTING_OPTIONS
1281skip_connector:
1282#endif /* CONFIG_TESTING_OPTIONS */
1283
1284 wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
1285 " status=%d", MAC2STR(src), status);
1286 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1287 " freq=%u type=%d status=%d", MAC2STR(src), freq,
1288 DPP_PA_PEER_DISCOVERY_RESP, status);
1289 hostapd_drv_send_action(hapd, freq, 0, src,
1290 wpabuf_head(msg), wpabuf_len(msg));
1291 wpabuf_free(msg);
1292}
1293
1294
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001295static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
1296 const u8 *src,
1297 const u8 *buf, size_t len,
1298 unsigned int freq)
1299{
1300 const u8 *connector, *trans_id;
1301 u16 connector_len, trans_id_len;
1302 struct os_time now;
1303 struct dpp_introduction intro;
1304 os_time_t expire;
1305 int expiration;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001306 enum dpp_status_error res;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001307
1308 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
1309 MAC2STR(src));
1310 if (!hapd->wpa_auth ||
1311 !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
1312 !(hapd->conf->wpa & WPA_PROTO_RSN)) {
1313 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
1314 return;
1315 }
1316
1317 if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
1318 !hapd->conf->dpp_csign) {
1319 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
1320 return;
1321 }
1322
1323 os_get_time(&now);
1324
1325 if (hapd->conf->dpp_netaccesskey_expiry &&
Roshan Pius3a1667e2018-07-03 15:17:14 -07001326 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001327 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
1328 return;
1329 }
1330
1331 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
1332 &trans_id_len);
1333 if (!trans_id || trans_id_len != 1) {
1334 wpa_printf(MSG_DEBUG,
1335 "DPP: Peer did not include Transaction ID");
1336 return;
1337 }
1338
1339 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
1340 if (!connector) {
1341 wpa_printf(MSG_DEBUG,
1342 "DPP: Peer did not include its Connector");
1343 return;
1344 }
1345
Roshan Pius3a1667e2018-07-03 15:17:14 -07001346 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
1347 wpabuf_head(hapd->conf->dpp_netaccesskey),
1348 wpabuf_len(hapd->conf->dpp_netaccesskey),
1349 wpabuf_head(hapd->conf->dpp_csign),
1350 wpabuf_len(hapd->conf->dpp_csign),
1351 connector, connector_len, &expire);
1352 if (res == 255) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001353 wpa_printf(MSG_INFO,
Roshan Pius3a1667e2018-07-03 15:17:14 -07001354 "DPP: Network Introduction protocol resulted in internal failure (peer "
1355 MACSTR ")", MAC2STR(src));
1356 return;
1357 }
1358 if (res != DPP_STATUS_OK) {
1359 wpa_printf(MSG_INFO,
1360 "DPP: Network Introduction protocol resulted in failure (peer "
1361 MACSTR " status %d)", MAC2STR(src), res);
1362 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1363 res);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001364 return;
1365 }
1366
Roshan Pius3a1667e2018-07-03 15:17:14 -07001367 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001368 expire = hapd->conf->dpp_netaccesskey_expiry;
1369 if (expire)
1370 expiration = expire - now.sec;
1371 else
1372 expiration = 0;
1373
1374 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
1375 intro.pmkid, expiration,
1376 WPA_KEY_MGMT_DPP) < 0) {
1377 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
1378 return;
1379 }
1380
Roshan Pius3a1667e2018-07-03 15:17:14 -07001381 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1382 DPP_STATUS_OK);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001383}
1384
1385
1386static void
1387hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
1388 const u8 *buf, size_t len,
1389 unsigned int freq)
1390{
1391 struct wpabuf *msg;
1392
1393 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
1394 MAC2STR(src));
1395
1396 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1397 * values here */
1398
1399 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
1400 wpa_printf(MSG_DEBUG,
1401 "DPP: No PKEX code configured - ignore request");
1402 return;
1403 }
1404
1405 if (hapd->dpp_pkex) {
1406 /* TODO: Support parallel operations */
1407 wpa_printf(MSG_DEBUG,
1408 "DPP: Already in PKEX session - ignore new request");
1409 return;
1410 }
1411
Roshan Pius3a1667e2018-07-03 15:17:14 -07001412 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
1413 hapd->dpp_pkex_bi,
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001414 hapd->own_addr, src,
1415 hapd->dpp_pkex_identifier,
1416 hapd->dpp_pkex_code,
1417 buf, len);
1418 if (!hapd->dpp_pkex) {
1419 wpa_printf(MSG_DEBUG,
1420 "DPP: Failed to process the request - ignore it");
1421 return;
1422 }
1423
1424 msg = hapd->dpp_pkex->exchange_resp;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001425 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1426 " freq=%u type=%d", MAC2STR(src), freq,
1427 DPP_PA_PKEX_EXCHANGE_RESP);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001428 hostapd_drv_send_action(hapd, freq, 0, src,
1429 wpabuf_head(msg), wpabuf_len(msg));
Roshan Pius3a1667e2018-07-03 15:17:14 -07001430 if (hapd->dpp_pkex->failed) {
1431 wpa_printf(MSG_DEBUG,
1432 "DPP: Terminate PKEX exchange due to an earlier error");
1433 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1434 hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
1435 dpp_pkex_free(hapd->dpp_pkex);
1436 hapd->dpp_pkex = NULL;
1437 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001438}
1439
1440
1441static void
1442hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
1443 const u8 *buf, size_t len, unsigned int freq)
1444{
1445 struct wpabuf *msg;
1446
1447 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
1448 MAC2STR(src));
1449
1450 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1451 * values here */
1452
1453 if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
1454 hapd->dpp_pkex->exchange_done) {
1455 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1456 return;
1457 }
1458
Roshan Pius3a1667e2018-07-03 15:17:14 -07001459 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001460 if (!msg) {
1461 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1462 return;
1463 }
1464
1465 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
1466 MAC2STR(src));
1467
Roshan Pius3a1667e2018-07-03 15:17:14 -07001468 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1469 " freq=%u type=%d", MAC2STR(src), freq,
1470 DPP_PA_PKEX_COMMIT_REVEAL_REQ);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001471 hostapd_drv_send_action(hapd, freq, 0, src,
1472 wpabuf_head(msg), wpabuf_len(msg));
1473 wpabuf_free(msg);
1474}
1475
1476
1477static void
1478hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
1479 const u8 *hdr, const u8 *buf, size_t len,
1480 unsigned int freq)
1481{
1482 struct wpabuf *msg;
1483 struct dpp_pkex *pkex = hapd->dpp_pkex;
1484 struct dpp_bootstrap_info *bi;
1485
1486 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
1487 MAC2STR(src));
1488
1489 if (!pkex || pkex->initiator || !pkex->exchange_done) {
1490 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1491 return;
1492 }
1493
1494 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1495 if (!msg) {
1496 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
Roshan Pius3a1667e2018-07-03 15:17:14 -07001497 if (hapd->dpp_pkex->failed) {
1498 wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
1499 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1500 hapd->dpp_pkex->own_bi->pkex_t =
1501 hapd->dpp_pkex->t;
1502 dpp_pkex_free(hapd->dpp_pkex);
1503 hapd->dpp_pkex = NULL;
1504 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001505 return;
1506 }
1507
1508 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
1509 MACSTR, MAC2STR(src));
1510
Roshan Pius3a1667e2018-07-03 15:17:14 -07001511 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1512 " freq=%u type=%d", MAC2STR(src), freq,
1513 DPP_PA_PKEX_COMMIT_REVEAL_RESP);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001514 hostapd_drv_send_action(hapd, freq, 0, src,
1515 wpabuf_head(msg), wpabuf_len(msg));
1516 wpabuf_free(msg);
1517
Hai Shalom021b0b52019-04-10 11:17:58 -07001518 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001519 if (!bi)
1520 return;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001521 hapd->dpp_pkex = NULL;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001522}
1523
1524
1525static void
1526hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
1527 const u8 *hdr, const u8 *buf, size_t len,
1528 unsigned int freq)
1529{
1530 int res;
Hai Shalom021b0b52019-04-10 11:17:58 -07001531 struct dpp_bootstrap_info *bi;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001532 struct dpp_pkex *pkex = hapd->dpp_pkex;
1533 char cmd[500];
1534
1535 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
1536 MAC2STR(src));
1537
1538 if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1539 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1540 return;
1541 }
1542
1543 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1544 if (res < 0) {
1545 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1546 return;
1547 }
1548
Hai Shalom021b0b52019-04-10 11:17:58 -07001549 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001550 if (!bi)
1551 return;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001552 hapd->dpp_pkex = NULL;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001553
1554 os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
1555 bi->id,
1556 hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
1557 wpa_printf(MSG_DEBUG,
1558 "DPP: Start authentication after PKEX with parameters: %s",
1559 cmd);
1560 if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
1561 wpa_printf(MSG_DEBUG,
1562 "DPP: Authentication initialization failed");
1563 return;
1564 }
1565}
1566
1567
1568void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
1569 const u8 *buf, size_t len, unsigned int freq)
1570{
1571 u8 crypto_suite;
1572 enum dpp_public_action_frame_type type;
1573 const u8 *hdr;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001574 unsigned int pkex_t;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001575
1576 if (len < DPP_HDR_LEN)
1577 return;
1578 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
1579 return;
1580 hdr = buf;
1581 buf += 4;
1582 len -= 4;
1583 crypto_suite = *buf++;
1584 type = *buf++;
1585 len -= 2;
1586
1587 wpa_printf(MSG_DEBUG,
1588 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1589 MACSTR " freq=%u",
1590 crypto_suite, type, MAC2STR(src), freq);
1591 if (crypto_suite != 1) {
1592 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
1593 crypto_suite);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001594 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1595 " freq=%u type=%d ignore=unsupported-crypto-suite",
1596 MAC2STR(src), freq, type);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001597 return;
1598 }
1599 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001600 if (dpp_check_attrs(buf, len) < 0) {
1601 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1602 " freq=%u type=%d ignore=invalid-attributes",
1603 MAC2STR(src), freq, type);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001604 return;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001605 }
1606 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1607 " freq=%u type=%d", MAC2STR(src), freq, type);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001608
Hai Shalom81f62d82019-07-22 12:10:00 -07001609#ifdef CONFIG_DPP2
1610 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1611 src, hdr, buf, len, freq, NULL, NULL) == 0)
1612 return;
1613#endif /* CONFIG_DPP2 */
1614
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001615 switch (type) {
1616 case DPP_PA_AUTHENTICATION_REQ:
1617 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
1618 break;
1619 case DPP_PA_AUTHENTICATION_RESP:
Roshan Pius3a1667e2018-07-03 15:17:14 -07001620 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001621 break;
1622 case DPP_PA_AUTHENTICATION_CONF:
1623 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
1624 break;
1625 case DPP_PA_PEER_DISCOVERY_REQ:
1626 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
1627 break;
1628 case DPP_PA_PKEX_EXCHANGE_REQ:
1629 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq);
1630 break;
1631 case DPP_PA_PKEX_EXCHANGE_RESP:
1632 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
1633 break;
1634 case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1635 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
1636 freq);
1637 break;
1638 case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1639 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
1640 freq);
1641 break;
Hai Shalom021b0b52019-04-10 11:17:58 -07001642#ifdef CONFIG_DPP2
1643 case DPP_PA_CONFIGURATION_RESULT:
1644 hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
1645 break;
Hai Shalomc3565922019-10-28 11:58:20 -07001646 case DPP_PA_CONNECTION_STATUS_RESULT:
1647 hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
1648 break;
Hai Shalomfdcde762020-04-02 11:19:20 -07001649 case DPP_PA_PRESENCE_ANNOUNCEMENT:
1650 hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
1651 freq);
1652 break;
Hai Shalom021b0b52019-04-10 11:17:58 -07001653#endif /* CONFIG_DPP2 */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001654 default:
1655 wpa_printf(MSG_DEBUG,
1656 "DPP: Ignored unsupported frame subtype %d", type);
1657 break;
1658 }
Roshan Pius3a1667e2018-07-03 15:17:14 -07001659
1660 if (hapd->dpp_pkex)
1661 pkex_t = hapd->dpp_pkex->t;
1662 else if (hapd->dpp_pkex_bi)
1663 pkex_t = hapd->dpp_pkex_bi->pkex_t;
1664 else
1665 pkex_t = 0;
1666 if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
1667 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
1668 hostapd_dpp_pkex_remove(hapd, "*");
1669 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001670}
1671
1672
1673struct wpabuf *
1674hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
Hai Shalom81f62d82019-07-22 12:10:00 -07001675 const u8 *query, size_t query_len,
1676 const u8 *data, size_t data_len)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001677{
1678 struct dpp_authentication *auth = hapd->dpp_auth;
1679 struct wpabuf *resp;
1680
1681 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
1682 if (!auth || !auth->auth_success ||
1683 os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
Hai Shalom81f62d82019-07-22 12:10:00 -07001684#ifdef CONFIG_DPP2
1685 if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
1686 data_len) == 0) {
1687 /* Response will be forwarded once received over TCP */
1688 return NULL;
1689 }
1690#endif /* CONFIG_DPP2 */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001691 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1692 return NULL;
1693 }
1694 wpa_hexdump(MSG_DEBUG,
1695 "DPP: Received Configuration Request (GAS Query Request)",
1696 query, query_len);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001697 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
1698 MAC2STR(sa));
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001699 resp = dpp_conf_req_rx(auth, query, query_len);
1700 if (!resp)
1701 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1702 return resp;
1703}
1704
1705
Roshan Pius3a1667e2018-07-03 15:17:14 -07001706void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
1707{
Hai Shalom021b0b52019-04-10 11:17:58 -07001708 struct dpp_authentication *auth = hapd->dpp_auth;
1709
1710 if (!auth)
Roshan Pius3a1667e2018-07-03 15:17:14 -07001711 return;
1712
Hai Shalom021b0b52019-04-10 11:17:58 -07001713 wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
1714 ok);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001715 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1716 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
Hai Shalom021b0b52019-04-10 11:17:58 -07001717#ifdef CONFIG_DPP2
1718 if (ok && auth->peer_version >= 2 &&
1719 auth->conf_resp_status == DPP_STATUS_OK) {
1720 wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
1721 auth->waiting_conf_result = 1;
1722 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1723 hapd, NULL);
1724 eloop_register_timeout(2, 0,
1725 hostapd_dpp_config_result_wait_timeout,
1726 hapd, NULL);
1727 return;
1728 }
1729#endif /* CONFIG_DPP2 */
Roshan Pius3a1667e2018-07-03 15:17:14 -07001730 hostapd_drv_send_action_cancel_wait(hapd);
1731
1732 if (ok)
1733 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1734 else
1735 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1736 dpp_auth_deinit(hapd->dpp_auth);
1737 hapd->dpp_auth = NULL;
1738}
1739
1740
Roshan Pius3a1667e2018-07-03 15:17:14 -07001741int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
1742{
1743 struct dpp_authentication *auth;
1744 int ret = -1;
1745 char *curve = NULL;
1746
Hai Shalomfdcde762020-04-02 11:19:20 -07001747 auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001748 if (!auth)
1749 return -1;
1750
1751 curve = get_param(cmd, " curve=");
Hai Shalom74f70d42019-02-11 14:42:39 -08001752 hostapd_dpp_set_testing_options(hapd, auth);
Hai Shalomfdcde762020-04-02 11:19:20 -07001753 if (dpp_set_configurator(auth, cmd) == 0 &&
Hai Shalom74f70d42019-02-11 14:42:39 -08001754 dpp_configurator_own_config(auth, curve, 1) == 0) {
Hai Shalomc3565922019-10-28 11:58:20 -07001755 hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001756 ret = 0;
1757 }
1758
1759 dpp_auth_deinit(auth);
1760 os_free(curve);
1761
1762 return ret;
1763}
1764
1765
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001766int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
1767{
1768 struct dpp_bootstrap_info *own_bi;
1769 const char *pos, *end;
1770
1771 pos = os_strstr(cmd, " own=");
1772 if (!pos)
1773 return -1;
1774 pos += 5;
Hai Shalom021b0b52019-04-10 11:17:58 -07001775 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001776 if (!own_bi) {
1777 wpa_printf(MSG_DEBUG,
1778 "DPP: Identified bootstrap info not found");
1779 return -1;
1780 }
1781 if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
1782 wpa_printf(MSG_DEBUG,
1783 "DPP: Identified bootstrap info not for PKEX");
1784 return -1;
1785 }
1786 hapd->dpp_pkex_bi = own_bi;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001787 own_bi->pkex_t = 0; /* clear pending errors on new code */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001788
1789 os_free(hapd->dpp_pkex_identifier);
1790 hapd->dpp_pkex_identifier = NULL;
1791 pos = os_strstr(cmd, " identifier=");
1792 if (pos) {
1793 pos += 12;
1794 end = os_strchr(pos, ' ');
1795 if (!end)
1796 return -1;
1797 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
1798 if (!hapd->dpp_pkex_identifier)
1799 return -1;
1800 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
1801 hapd->dpp_pkex_identifier[end - pos] = '\0';
1802 }
1803
1804 pos = os_strstr(cmd, " code=");
1805 if (!pos)
1806 return -1;
1807 os_free(hapd->dpp_pkex_code);
1808 hapd->dpp_pkex_code = os_strdup(pos + 6);
1809 if (!hapd->dpp_pkex_code)
1810 return -1;
1811
1812 if (os_strstr(cmd, " init=1")) {
1813 struct wpabuf *msg;
1814
1815 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
1816 dpp_pkex_free(hapd->dpp_pkex);
Roshan Pius3a1667e2018-07-03 15:17:14 -07001817 hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
1818 hapd->own_addr,
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001819 hapd->dpp_pkex_identifier,
1820 hapd->dpp_pkex_code);
1821 if (!hapd->dpp_pkex)
1822 return -1;
1823
1824 msg = hapd->dpp_pkex->exchange_req;
1825 /* TODO: Which channel to use? */
Roshan Pius3a1667e2018-07-03 15:17:14 -07001826 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1827 " freq=%u type=%d", MAC2STR(broadcast), 2437,
1828 DPP_PA_PKEX_EXCHANGE_REQ);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001829 hostapd_drv_send_action(hapd, 2437, 0, broadcast,
1830 wpabuf_head(msg), wpabuf_len(msg));
1831 }
1832
1833 /* TODO: Support multiple PKEX info entries */
1834
1835 os_free(hapd->dpp_pkex_auth_cmd);
1836 hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
1837
1838 return 1;
1839}
1840
1841
1842int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
1843{
1844 unsigned int id_val;
1845
1846 if (os_strcmp(id, "*") == 0) {
1847 id_val = 0;
1848 } else {
1849 id_val = atoi(id);
1850 if (id_val == 0)
1851 return -1;
1852 }
1853
1854 if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
1855 return -1;
1856
1857 /* TODO: Support multiple PKEX entries */
1858 os_free(hapd->dpp_pkex_code);
1859 hapd->dpp_pkex_code = NULL;
1860 os_free(hapd->dpp_pkex_identifier);
1861 hapd->dpp_pkex_identifier = NULL;
1862 os_free(hapd->dpp_pkex_auth_cmd);
1863 hapd->dpp_pkex_auth_cmd = NULL;
1864 hapd->dpp_pkex_bi = NULL;
1865 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
1866 dpp_pkex_free(hapd->dpp_pkex);
1867 hapd->dpp_pkex = NULL;
1868 return 0;
1869}
1870
1871
Roshan Pius3a1667e2018-07-03 15:17:14 -07001872void hostapd_dpp_stop(struct hostapd_data *hapd)
1873{
1874 dpp_auth_deinit(hapd->dpp_auth);
1875 hapd->dpp_auth = NULL;
1876 dpp_pkex_free(hapd->dpp_pkex);
1877 hapd->dpp_pkex = NULL;
1878}
1879
1880
Hai Shalom81f62d82019-07-22 12:10:00 -07001881#ifdef CONFIG_DPP2
1882
1883static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
1884 const u8 *msg, size_t len)
1885{
1886 struct hostapd_data *hapd = ctx;
1887 u8 *buf;
1888
1889 wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
1890 MAC2STR(addr), freq);
1891 buf = os_malloc(2 + len);
1892 if (!buf)
1893 return;
1894 buf[0] = WLAN_ACTION_PUBLIC;
1895 buf[1] = WLAN_PA_VENDOR_SPECIFIC;
1896 os_memcpy(buf + 2, msg, len);
1897 hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
1898 os_free(buf);
1899}
1900
1901
1902static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
1903 u8 dialog_token, int prot,
1904 struct wpabuf *buf)
1905{
1906 struct hostapd_data *hapd = ctx;
1907
1908 gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf);
1909}
1910
1911#endif /* CONFIG_DPP2 */
1912
1913
1914static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
1915{
1916#ifdef CONFIG_DPP2
1917 struct dpp_controller_conf *ctrl;
1918 struct dpp_relay_config config;
1919
1920 os_memset(&config, 0, sizeof(config));
1921 config.cb_ctx = hapd;
1922 config.tx = hostapd_dpp_relay_tx;
1923 config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
1924 for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
1925 config.ipaddr = &ctrl->ipaddr;
1926 config.pkhash = ctrl->pkhash;
1927 if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
1928 &config) < 0)
1929 return -1;
1930 }
1931#endif /* CONFIG_DPP2 */
1932
1933 return 0;
1934}
1935
1936
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001937int hostapd_dpp_init(struct hostapd_data *hapd)
1938{
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001939 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
1940 hapd->dpp_init_done = 1;
Hai Shalom81f62d82019-07-22 12:10:00 -07001941 return hostapd_dpp_add_controllers(hapd);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001942}
1943
1944
1945void hostapd_dpp_deinit(struct hostapd_data *hapd)
1946{
1947#ifdef CONFIG_TESTING_OPTIONS
1948 os_free(hapd->dpp_config_obj_override);
1949 hapd->dpp_config_obj_override = NULL;
1950 os_free(hapd->dpp_discovery_override);
1951 hapd->dpp_discovery_override = NULL;
1952 os_free(hapd->dpp_groups_override);
1953 hapd->dpp_groups_override = NULL;
1954 hapd->dpp_ignore_netaccesskey_mismatch = 0;
1955#endif /* CONFIG_TESTING_OPTIONS */
1956 if (!hapd->dpp_init_done)
1957 return;
Roshan Pius3a1667e2018-07-03 15:17:14 -07001958 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1959 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1960 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
Hai Shalom021b0b52019-04-10 11:17:58 -07001961#ifdef CONFIG_DPP2
1962 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1963 NULL);
Hai Shalomc3565922019-10-28 11:58:20 -07001964 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
1965 NULL);
Hai Shalom021b0b52019-04-10 11:17:58 -07001966#endif /* CONFIG_DPP2 */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001967 dpp_auth_deinit(hapd->dpp_auth);
1968 hapd->dpp_auth = NULL;
1969 hostapd_dpp_pkex_remove(hapd, "*");
1970 hapd->dpp_pkex = NULL;
1971 os_free(hapd->dpp_configurator_params);
1972 hapd->dpp_configurator_params = NULL;
1973}