3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
4 * Copyright (c) 2018-2019, The Linux Foundation
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
10 #include "utils/includes.h"
12 #include "utils/common.h"
13 #include "utils/eloop.h"
14 #include "utils/ip_addr.h"
15 #include "common/dpp.h"
16 #include "common/gas.h"
17 #include "common/gas_server.h"
18 #include "rsn_supp/wpa.h"
19 #include "rsn_supp/pmksa_cache.h"
20 #include "wpa_supplicant_i.h"
23 #include "offchannel.h"
24 #include "gas_query.h"
28 #include "dpp_supplicant.h"
31 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
33 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
);
34 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
);
35 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
36 unsigned int freq
, const u8
*dst
,
37 const u8
*src
, const u8
*bssid
,
38 const u8
*data
, size_t data_len
,
39 enum offchannel_send_action_result result
);
40 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
);
41 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
);
43 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
44 unsigned int freq
, const u8
*dst
,
45 const u8
*src
, const u8
*bssid
,
46 const u8
*data
, size_t data_len
,
47 enum offchannel_send_action_result result
);
49 static const u8 broadcast
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
51 /* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only
52 * a single transaction in progress at any point in time. */
53 static const u8 TRANSACTION_ID
= 1;
57 * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
58 * @wpa_s: Pointer to wpa_supplicant data
59 * @cmd: DPP URI read from a QR Code
60 * Returns: Identifier of the stored info or -1 on failure
62 int wpas_dpp_qr_code(struct wpa_supplicant
*wpa_s
, const char *cmd
)
64 struct dpp_bootstrap_info
*bi
;
65 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
67 bi
= dpp_add_qr_code(wpa_s
->dpp
, cmd
);
71 if (auth
&& auth
->response_pending
&&
72 dpp_notify_new_qr_code(auth
, bi
) == 1) {
74 "DPP: Sending out pending authentication response");
75 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
77 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
78 DPP_PA_AUTHENTICATION_RESP
);
79 offchannel_send_action(wpa_s
, auth
->curr_freq
,
80 auth
->peer_mac_addr
, wpa_s
->own_addr
,
82 wpabuf_head(auth
->resp_msg
),
83 wpabuf_len(auth
->resp_msg
),
84 500, wpas_dpp_tx_status
, 0);
91 static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
93 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
94 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
96 if (!auth
|| !auth
->resp_msg
)
100 "DPP: Retry Authentication Response after timeout");
101 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
103 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
104 DPP_PA_AUTHENTICATION_RESP
);
105 offchannel_send_action(wpa_s
, auth
->curr_freq
, auth
->peer_mac_addr
,
106 wpa_s
->own_addr
, broadcast
,
107 wpabuf_head(auth
->resp_msg
),
108 wpabuf_len(auth
->resp_msg
),
109 500, wpas_dpp_tx_status
, 0);
113 static void wpas_dpp_auth_resp_retry(struct wpa_supplicant
*wpa_s
)
115 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
116 unsigned int wait_time
, max_tries
;
118 if (!auth
|| !auth
->resp_msg
)
121 if (wpa_s
->dpp_resp_max_tries
)
122 max_tries
= wpa_s
->dpp_resp_max_tries
;
125 auth
->auth_resp_tries
++;
126 if (auth
->auth_resp_tries
>= max_tries
) {
127 wpa_printf(MSG_INFO
, "DPP: No confirm received from initiator - stopping exchange");
128 offchannel_send_action_done(wpa_s
);
129 dpp_auth_deinit(wpa_s
->dpp_auth
);
130 wpa_s
->dpp_auth
= NULL
;
134 if (wpa_s
->dpp_resp_retry_time
)
135 wait_time
= wpa_s
->dpp_resp_retry_time
;
138 wpa_printf(MSG_DEBUG
,
139 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
141 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
142 eloop_register_timeout(wait_time
/ 1000,
143 (wait_time
% 1000) * 1000,
144 wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
148 static void wpas_dpp_try_to_connect(struct wpa_supplicant
*wpa_s
)
150 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
151 wpa_s
->suitable_network
= 0;
152 wpa_s
->no_suitable_network
= 0;
153 wpa_s
->disconnected
= 0;
154 wpa_s
->reassociate
= 1;
155 wpa_s
->scan_runs
= 0;
156 wpa_s
->normal_scans
= 0;
157 wpa_supplicant_cancel_sched_scan(wpa_s
);
158 wpa_supplicant_req_scan(wpa_s
, 0, 0);
164 static void wpas_dpp_conn_status_result_timeout(void *eloop_ctx
,
167 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
168 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
169 enum dpp_status_error result
;
171 if (!auth
|| !auth
->conn_status_requested
)
174 wpa_printf(MSG_DEBUG
,
175 "DPP: Connection timeout - report Connection Status Result");
176 if (wpa_s
->suitable_network
)
177 result
= DPP_STATUS_AUTH_FAILURE
;
178 else if (wpa_s
->no_suitable_network
)
179 result
= DPP_STATUS_NO_AP
;
181 result
= 255; /* What to report here for unexpected state? */
182 wpas_dpp_send_conn_status_result(wpa_s
, result
);
186 static char * wpas_dpp_scan_channel_list(struct wpa_supplicant
*wpa_s
)
188 char *str
, *end
, *pos
;
191 u8 last_op_class
= 0;
194 if (!wpa_s
->last_scan_freqs
|| !wpa_s
->num_last_scan_freqs
)
197 len
= wpa_s
->num_last_scan_freqs
* 8;
198 str
= os_zalloc(len
);
204 for (i
= 0; i
< wpa_s
->num_last_scan_freqs
; i
++) {
205 enum hostapd_hw_mode mode
;
206 u8 op_class
, channel
;
208 mode
= ieee80211_freq_to_channel_ext(wpa_s
->last_scan_freqs
[i
],
209 0, 0, &op_class
, &channel
);
210 if (mode
== NUM_HOSTAPD_MODES
)
212 if (op_class
== last_op_class
)
213 res
= os_snprintf(pos
, end
- pos
, ",%d", channel
);
215 res
= os_snprintf(pos
, end
- pos
, "%s%d/%d",
216 pos
== str
? "" : ",",
218 if (os_snprintf_error(end
- pos
, res
)) {
223 last_op_class
= op_class
;
234 void wpas_dpp_send_conn_status_result(struct wpa_supplicant
*wpa_s
,
235 enum dpp_status_error result
)
238 const char *channel_list
= NULL
;
239 char *channel_list_buf
= NULL
;
240 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
241 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
243 eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout
, wpa_s
, NULL
);
245 if (!auth
|| !auth
->conn_status_requested
)
247 auth
->conn_status_requested
= 0;
248 wpa_printf(MSG_DEBUG
, "DPP: Report connection status result %d",
251 if (result
== DPP_STATUS_NO_AP
) {
252 channel_list_buf
= wpas_dpp_scan_channel_list(wpa_s
);
253 channel_list
= channel_list_buf
;
256 msg
= dpp_build_conn_status_result(auth
, result
,
258 wpa_s
->dpp_last_ssid
,
259 ssid
? ssid
->ssid_len
:
260 wpa_s
->dpp_last_ssid_len
,
262 os_free(channel_list_buf
);
264 dpp_auth_deinit(wpa_s
->dpp_auth
);
265 wpa_s
->dpp_auth
= NULL
;
269 wpa_msg(wpa_s
, MSG_INFO
,
270 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
271 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
272 DPP_PA_CONNECTION_STATUS_RESULT
);
273 offchannel_send_action(wpa_s
, auth
->curr_freq
,
274 auth
->peer_mac_addr
, wpa_s
->own_addr
, broadcast
,
275 wpabuf_head(msg
), wpabuf_len(msg
),
276 500, wpas_dpp_tx_status
, 0);
279 /* This exchange will be terminated in the TX status handler */
280 auth
->remove_on_tx_status
= 1;
286 void wpas_dpp_connected(struct wpa_supplicant
*wpa_s
)
288 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
290 if (auth
&& auth
->conn_status_requested
)
291 wpas_dpp_send_conn_status_result(wpa_s
, DPP_STATUS_OK
);
294 #endif /* CONFIG_DPP2 */
297 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
298 unsigned int freq
, const u8
*dst
,
299 const u8
*src
, const u8
*bssid
,
300 const u8
*data
, size_t data_len
,
301 enum offchannel_send_action_result result
)
304 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
306 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
307 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
309 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
310 " result=%s", freq
, MAC2STR(dst
), res_txt
);
311 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
312 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
314 if (!wpa_s
->dpp_auth
) {
315 wpa_printf(MSG_DEBUG
,
316 "DPP: Ignore TX status since there is no ongoing authentication exchange");
321 if (auth
->connect_on_tx_status
) {
322 auth
->connect_on_tx_status
= 0;
323 wpa_printf(MSG_DEBUG
,
324 "DPP: Try to connect after completed configuration result");
325 wpas_dpp_try_to_connect(wpa_s
);
326 if (auth
->conn_status_requested
) {
327 wpa_printf(MSG_DEBUG
,
328 "DPP: Start 15 second timeout for reporting connection status result");
329 eloop_cancel_timeout(
330 wpas_dpp_conn_status_result_timeout
,
332 eloop_register_timeout(
333 15, 0, wpas_dpp_conn_status_result_timeout
,
336 dpp_auth_deinit(wpa_s
->dpp_auth
);
337 wpa_s
->dpp_auth
= NULL
;
341 #endif /* CONFIG_DPP2 */
343 if (wpa_s
->dpp_auth
->remove_on_tx_status
) {
344 wpa_printf(MSG_DEBUG
,
345 "DPP: Terminate authentication exchange due to a request to do so on TX status");
346 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
347 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
348 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
350 offchannel_send_action_done(wpa_s
);
351 dpp_auth_deinit(wpa_s
->dpp_auth
);
352 wpa_s
->dpp_auth
= NULL
;
356 if (wpa_s
->dpp_auth_ok_on_ack
)
357 wpas_dpp_auth_success(wpa_s
, 1);
359 if (!is_broadcast_ether_addr(dst
) &&
360 result
!= OFFCHANNEL_SEND_ACTION_SUCCESS
) {
361 wpa_printf(MSG_DEBUG
,
362 "DPP: Unicast DPP Action frame was not ACKed");
363 if (auth
->waiting_auth_resp
) {
364 /* In case of DPP Authentication Request frame, move to
365 * the next channel immediately. */
366 offchannel_send_action_done(wpa_s
);
367 wpas_dpp_auth_init_next(wpa_s
);
370 if (auth
->waiting_auth_conf
) {
371 wpas_dpp_auth_resp_retry(wpa_s
);
376 if (!is_broadcast_ether_addr(dst
) && auth
->waiting_auth_resp
&&
377 result
== OFFCHANNEL_SEND_ACTION_SUCCESS
) {
378 /* Allow timeout handling to stop iteration if no response is
379 * received from a peer that has ACKed a request. */
380 auth
->auth_req_ack
= 1;
383 if (!wpa_s
->dpp_auth_ok_on_ack
&& wpa_s
->dpp_auth
->neg_freq
> 0 &&
384 wpa_s
->dpp_auth
->curr_freq
!= wpa_s
->dpp_auth
->neg_freq
) {
385 wpa_printf(MSG_DEBUG
,
386 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
387 wpa_s
->dpp_auth
->curr_freq
,
388 wpa_s
->dpp_auth
->neg_freq
);
389 offchannel_send_action_done(wpa_s
);
390 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->neg_freq
);
393 if (wpa_s
->dpp_auth_ok_on_ack
)
394 wpa_s
->dpp_auth_ok_on_ack
= 0;
398 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
400 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
401 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
403 struct os_reltime now
, diff
;
404 unsigned int wait_time
, diff_ms
;
406 if (!auth
|| !auth
->waiting_auth_resp
)
409 wait_time
= wpa_s
->dpp_resp_wait_time
?
410 wpa_s
->dpp_resp_wait_time
: 2000;
411 os_get_reltime(&now
);
412 os_reltime_sub(&now
, &wpa_s
->dpp_last_init
, &diff
);
413 diff_ms
= diff
.sec
* 1000 + diff
.usec
/ 1000;
414 wpa_printf(MSG_DEBUG
,
415 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
418 if (auth
->auth_req_ack
&& diff_ms
>= wait_time
) {
419 /* Peer ACK'ed Authentication Request frame, but did not reply
420 * with Authentication Response frame within two seconds. */
422 "DPP: No response received from responder - stopping initiation attempt");
423 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
424 offchannel_send_action_done(wpa_s
);
425 wpas_dpp_listen_stop(wpa_s
);
426 dpp_auth_deinit(auth
);
427 wpa_s
->dpp_auth
= NULL
;
431 if (diff_ms
>= wait_time
) {
432 /* Authentication Request frame was not ACK'ed and no reply
433 * was receiving within two seconds. */
434 wpa_printf(MSG_DEBUG
,
435 "DPP: Continue Initiator channel iteration");
436 offchannel_send_action_done(wpa_s
);
437 wpas_dpp_listen_stop(wpa_s
);
438 wpas_dpp_auth_init_next(wpa_s
);
442 /* Driver did not support 2000 ms long wait_time with TX command, so
443 * schedule listen operation to continue waiting for the response.
445 * DPP listen operations continue until stopped, so simply schedule a
446 * new call to this function at the point when the two second reply
447 * wait has expired. */
448 wait_time
-= diff_ms
;
450 freq
= auth
->curr_freq
;
451 if (auth
->neg_freq
> 0)
452 freq
= auth
->neg_freq
;
453 wpa_printf(MSG_DEBUG
,
454 "DPP: Continue reply wait on channel %u MHz for %u ms",
456 wpa_s
->dpp_in_response_listen
= 1;
457 wpas_dpp_listen_start(wpa_s
, freq
);
459 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
460 wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
464 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
465 struct dpp_authentication
*auth
)
467 #ifdef CONFIG_TESTING_OPTIONS
468 if (wpa_s
->dpp_config_obj_override
)
469 auth
->config_obj_override
=
470 os_strdup(wpa_s
->dpp_config_obj_override
);
471 if (wpa_s
->dpp_discovery_override
)
472 auth
->discovery_override
=
473 os_strdup(wpa_s
->dpp_discovery_override
);
474 if (wpa_s
->dpp_groups_override
)
475 auth
->groups_override
=
476 os_strdup(wpa_s
->dpp_groups_override
);
477 auth
->ignore_netaccesskey_mismatch
=
478 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
479 #endif /* CONFIG_TESTING_OPTIONS */
483 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
485 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
487 if (!wpa_s
->dpp_auth
)
489 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
490 wpas_dpp_auth_init_next(wpa_s
);
494 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
496 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
498 unsigned int wait_time
, max_wait_time
, freq
, max_tries
, used
;
499 struct os_reltime now
, diff
;
501 wpa_s
->dpp_in_response_listen
= 0;
505 if (auth
->freq_idx
== 0)
506 os_get_reltime(&wpa_s
->dpp_init_iter_start
);
508 if (auth
->freq_idx
>= auth
->num_freq
) {
509 auth
->num_freq_iters
++;
510 if (wpa_s
->dpp_init_max_tries
)
511 max_tries
= wpa_s
->dpp_init_max_tries
;
514 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
516 "DPP: No response received from responder - stopping initiation attempt");
517 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
518 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
520 offchannel_send_action_done(wpa_s
);
521 dpp_auth_deinit(wpa_s
->dpp_auth
);
522 wpa_s
->dpp_auth
= NULL
;
526 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
527 if (wpa_s
->dpp_init_retry_time
)
528 wait_time
= wpa_s
->dpp_init_retry_time
;
531 os_get_reltime(&now
);
532 os_reltime_sub(&now
, &wpa_s
->dpp_init_iter_start
, &diff
);
533 used
= diff
.sec
* 1000 + diff
.usec
/ 1000;
534 if (used
> wait_time
)
538 wpa_printf(MSG_DEBUG
, "DPP: Next init attempt in %u ms",
540 eloop_register_timeout(wait_time
/ 1000,
541 (wait_time
% 1000) * 1000,
542 wpas_dpp_init_timeout
, wpa_s
,
546 freq
= auth
->freq
[auth
->freq_idx
++];
547 auth
->curr_freq
= freq
;
549 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
552 dst
= auth
->peer_bi
->mac_addr
;
553 wpa_s
->dpp_auth_ok_on_ack
= 0;
554 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
555 wait_time
= wpa_s
->max_remain_on_chan
;
556 max_wait_time
= wpa_s
->dpp_resp_wait_time
?
557 wpa_s
->dpp_resp_wait_time
: 2000;
558 if (wait_time
> max_wait_time
)
559 wait_time
= max_wait_time
;
560 wait_time
+= 10; /* give the driver some extra time to complete */
561 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
562 wpas_dpp_reply_wait_timeout
,
565 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
566 wpa_printf(MSG_DEBUG
,
567 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
568 freq
, auth
->neg_freq
);
570 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
571 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
572 auth
->auth_req_ack
= 0;
573 os_get_reltime(&wpa_s
->dpp_last_init
);
574 return offchannel_send_action(wpa_s
, freq
, dst
,
575 wpa_s
->own_addr
, broadcast
,
576 wpabuf_head(auth
->req_msg
),
577 wpabuf_len(auth
->req_msg
),
578 wait_time
, wpas_dpp_tx_status
, 0);
582 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
585 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
586 struct dpp_authentication
*auth
;
587 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
588 unsigned int neg_freq
= 0;
591 int tcp_port
= DPP_TCP_PORT
;
592 struct hostapd_ip_addr ipaddr
;
594 #endif /* CONFIG_DPP2 */
596 wpa_s
->dpp_gas_client
= 0;
598 pos
= os_strstr(cmd
, " peer=");
602 peer_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
605 "DPP: Could not find bootstrapping info for the identified peer");
610 pos
= os_strstr(cmd
, " tcp_port=");
613 tcp_port
= atoi(pos
);
616 addr
= get_param(cmd
, " tcp_addr=");
620 res
= hostapd_parse_ip_addr(addr
, &ipaddr
);
626 #endif /* CONFIG_DPP2 */
628 pos
= os_strstr(cmd
, " own=");
631 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
634 "DPP: Could not find bootstrapping info for the identified local entry");
638 if (peer_bi
->curve
!= own_bi
->curve
) {
640 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
641 peer_bi
->curve
->name
, own_bi
->curve
->name
);
646 pos
= os_strstr(cmd
, " role=");
649 if (os_strncmp(pos
, "configurator", 12) == 0)
650 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
651 else if (os_strncmp(pos
, "enrollee", 8) == 0)
652 allowed_roles
= DPP_CAPAB_ENROLLEE
;
653 else if (os_strncmp(pos
, "either", 6) == 0)
654 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
660 pos
= os_strstr(cmd
, " netrole=");
663 wpa_s
->dpp_netrole_ap
= os_strncmp(pos
, "ap", 2) == 0;
666 pos
= os_strstr(cmd
, " neg_freq=");
668 neg_freq
= atoi(pos
+ 10);
670 if (!tcp
&& wpa_s
->dpp_auth
) {
671 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
672 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
673 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
675 offchannel_send_action_done(wpa_s
);
676 dpp_auth_deinit(wpa_s
->dpp_auth
);
677 wpa_s
->dpp_auth
= NULL
;
680 auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
, neg_freq
,
681 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
684 wpas_dpp_set_testing_options(wpa_s
, auth
);
685 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, auth
, cmd
) < 0) {
686 dpp_auth_deinit(auth
);
690 auth
->neg_freq
= neg_freq
;
692 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
693 os_memcpy(auth
->peer_mac_addr
, peer_bi
->mac_addr
, ETH_ALEN
);
697 return dpp_tcp_init(wpa_s
->dpp
, auth
, &ipaddr
, tcp_port
);
698 #endif /* CONFIG_DPP2 */
700 wpa_s
->dpp_auth
= auth
;
701 return wpas_dpp_auth_init_next(wpa_s
);
707 struct wpas_dpp_listen_work
{
709 unsigned int duration
;
710 struct wpabuf
*probe_resp_ie
;
714 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
722 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
724 struct wpas_dpp_listen_work
*lwork
;
726 if (!wpa_s
->dpp_listen_work
)
729 lwork
= wpa_s
->dpp_listen_work
->ctx
;
730 wpas_dpp_listen_work_free(lwork
);
731 radio_work_done(wpa_s
->dpp_listen_work
);
732 wpa_s
->dpp_listen_work
= NULL
;
736 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
738 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
739 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
743 wpa_s
->dpp_listen_work
= NULL
;
744 wpas_dpp_listen_stop(wpa_s
);
746 wpas_dpp_listen_work_free(lwork
);
750 wpa_s
->dpp_listen_work
= work
;
752 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
754 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
755 wpa_s
->max_remain_on_chan
) < 0) {
756 wpa_printf(MSG_DEBUG
,
757 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
759 wpa_s
->dpp_listen_freq
= 0;
760 wpas_dpp_listen_work_done(wpa_s
);
761 wpa_s
->dpp_pending_listen_freq
= 0;
764 wpa_s
->off_channel_freq
= 0;
765 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
769 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
772 struct wpas_dpp_listen_work
*lwork
;
774 if (wpa_s
->dpp_listen_work
) {
775 wpa_printf(MSG_DEBUG
,
776 "DPP: Reject start_listen since dpp_listen_work already exists");
780 if (wpa_s
->dpp_listen_freq
)
781 wpas_dpp_listen_stop(wpa_s
);
782 wpa_s
->dpp_listen_freq
= freq
;
784 lwork
= os_zalloc(sizeof(*lwork
));
789 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
791 wpas_dpp_listen_work_free(lwork
);
799 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
807 if (os_strstr(cmd
, " role=configurator"))
808 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
809 else if (os_strstr(cmd
, " role=enrollee"))
810 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
812 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
814 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
815 wpa_s
->dpp_netrole_ap
= os_strstr(cmd
, " netrole=ap") != NULL
;
816 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
817 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
822 return wpas_dpp_listen_start(wpa_s
, freq
);
826 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
828 wpa_s
->dpp_in_response_listen
= 0;
829 if (!wpa_s
->dpp_listen_freq
)
832 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
833 wpa_s
->dpp_listen_freq
);
834 wpa_drv_cancel_remain_on_channel(wpa_s
);
835 wpa_s
->dpp_listen_freq
= 0;
836 wpas_dpp_listen_work_done(wpa_s
);
840 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
843 wpas_dpp_listen_work_done(wpa_s
);
845 if (wpa_s
->dpp_auth
&& wpa_s
->dpp_in_response_listen
) {
846 unsigned int new_freq
;
848 /* Continue listen with a new remain-on-channel */
849 if (wpa_s
->dpp_auth
->neg_freq
> 0)
850 new_freq
= wpa_s
->dpp_auth
->neg_freq
;
852 new_freq
= wpa_s
->dpp_auth
->curr_freq
;
853 wpa_printf(MSG_DEBUG
,
854 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
856 wpas_dpp_listen_start(wpa_s
, new_freq
);
860 if (wpa_s
->dpp_listen_freq
) {
861 /* Continue listen with a new remain-on-channel */
862 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
867 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
868 const u8
*hdr
, const u8
*buf
, size_t len
,
871 const u8
*r_bootstrap
, *i_bootstrap
;
872 u16 r_bootstrap_len
, i_bootstrap_len
;
873 struct dpp_bootstrap_info
*own_bi
= NULL
, *peer_bi
= NULL
;
878 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
881 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
883 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
884 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
885 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
888 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
889 r_bootstrap
, r_bootstrap_len
);
891 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
893 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
894 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
895 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
898 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
899 i_bootstrap
, i_bootstrap_len
);
901 /* Try to find own and peer bootstrapping key matches based on the
902 * received hash values */
903 dpp_bootstrap_find_pair(wpa_s
->dpp
, i_bootstrap
, r_bootstrap
,
906 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
907 "No matching own bootstrapping key found - ignore message");
911 if (wpa_s
->dpp_auth
) {
912 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
913 "Already in DPP authentication exchange - ignore new one");
917 wpa_s
->dpp_gas_client
= 0;
918 wpa_s
->dpp_auth_ok_on_ack
= 0;
919 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
920 wpa_s
->dpp_qr_mutual
,
921 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
922 if (!wpa_s
->dpp_auth
) {
923 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
926 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
927 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, wpa_s
->dpp_auth
,
928 wpa_s
->dpp_configurator_params
) < 0) {
929 dpp_auth_deinit(wpa_s
->dpp_auth
);
930 wpa_s
->dpp_auth
= NULL
;
933 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
935 if (wpa_s
->dpp_listen_freq
&&
936 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
937 wpa_printf(MSG_DEBUG
,
938 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
939 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
940 wpas_dpp_listen_stop(wpa_s
);
943 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
944 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
945 DPP_PA_AUTHENTICATION_RESP
);
946 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
947 src
, wpa_s
->own_addr
, broadcast
,
948 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
949 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
950 500, wpas_dpp_tx_status
, 0);
954 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
956 /* TODO: stop wait and start ROC */
960 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
961 struct dpp_authentication
*auth
)
963 struct wpa_ssid
*ssid
;
966 if (auth
->akm
== DPP_AKM_SAE
) {
968 struct wpa_driver_capa capa
;
971 res
= wpa_drv_get_capa(wpa_s
, &capa
);
973 !(capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_SAE
) &&
974 !(wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_SAE
)) {
975 wpa_printf(MSG_DEBUG
,
976 "DPP: SAE not supported by the driver");
979 #else /* CONFIG_SAE */
980 wpa_printf(MSG_DEBUG
, "DPP: SAE not supported in the build");
982 #endif /* CONFIG_SAE */
984 #endif /* CONFIG_DPP2 */
986 ssid
= wpa_config_add_network(wpa_s
->conf
);
989 wpas_notify_network_added(wpa_s
, ssid
);
990 wpa_config_set_network_defaults(ssid
);
993 ssid
->ssid
= os_malloc(auth
->ssid_len
);
996 os_memcpy(ssid
->ssid
, auth
->ssid
, auth
->ssid_len
);
997 ssid
->ssid_len
= auth
->ssid_len
;
999 if (auth
->connector
) {
1000 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
1001 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_REQUIRED
;
1002 ssid
->dpp_connector
= os_strdup(auth
->connector
);
1003 if (!ssid
->dpp_connector
)
1007 if (auth
->c_sign_key
) {
1008 ssid
->dpp_csign
= os_malloc(wpabuf_len(auth
->c_sign_key
));
1009 if (!ssid
->dpp_csign
)
1011 os_memcpy(ssid
->dpp_csign
, wpabuf_head(auth
->c_sign_key
),
1012 wpabuf_len(auth
->c_sign_key
));
1013 ssid
->dpp_csign_len
= wpabuf_len(auth
->c_sign_key
);
1016 if (auth
->net_access_key
) {
1017 ssid
->dpp_netaccesskey
=
1018 os_malloc(wpabuf_len(auth
->net_access_key
));
1019 if (!ssid
->dpp_netaccesskey
)
1021 os_memcpy(ssid
->dpp_netaccesskey
,
1022 wpabuf_head(auth
->net_access_key
),
1023 wpabuf_len(auth
->net_access_key
));
1024 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
1025 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
1028 if (!auth
->connector
|| dpp_akm_psk(auth
->akm
) ||
1029 dpp_akm_sae(auth
->akm
)) {
1030 if (!auth
->connector
)
1032 if (dpp_akm_psk(auth
->akm
))
1033 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
1034 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
1035 if (dpp_akm_sae(auth
->akm
))
1036 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
1037 WPA_KEY_MGMT_FT_SAE
;
1038 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_OPTIONAL
;
1039 if (auth
->passphrase
[0]) {
1040 if (wpa_config_set_quoted(ssid
, "psk",
1041 auth
->passphrase
) < 0)
1043 wpa_config_update_psk(ssid
);
1044 ssid
->export_keys
= 1;
1046 ssid
->psk_set
= auth
->psk_set
;
1047 os_memcpy(ssid
->psk
, auth
->psk
, PMK_LEN
);
1051 os_memcpy(wpa_s
->dpp_last_ssid
, auth
->ssid
, auth
->ssid_len
);
1052 wpa_s
->dpp_last_ssid_len
= auth
->ssid_len
;
1056 wpas_notify_network_removed(wpa_s
, ssid
);
1057 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1062 static int wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
1063 struct dpp_authentication
*auth
)
1065 struct wpa_ssid
*ssid
;
1067 if (wpa_s
->conf
->dpp_config_processing
< 1)
1070 ssid
= wpas_dpp_add_network(wpa_s
, auth
);
1074 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1075 if (wpa_s
->conf
->dpp_config_processing
== 2)
1078 #ifndef CONFIG_NO_CONFIG_WRITE
1079 if (wpa_s
->conf
->update_config
&&
1080 wpa_config_write(wpa_s
->confname
, wpa_s
->conf
))
1081 wpa_printf(MSG_DEBUG
, "DPP: Failed to update configuration");
1082 #endif /* CONFIG_NO_CONFIG_WRITE */
1084 if (wpa_s
->conf
->dpp_config_processing
< 2)
1088 if (auth
->peer_version
>= 2) {
1089 wpa_printf(MSG_DEBUG
,
1090 "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
1091 auth
->connect_on_tx_status
= 1;
1094 #endif /* CONFIG_DPP2 */
1096 wpas_dpp_try_to_connect(wpa_s
);
1101 static int wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1102 struct dpp_authentication
*auth
)
1104 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1106 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1107 wpa_ssid_txt(auth
->ssid
, auth
->ssid_len
));
1108 if (auth
->connector
) {
1109 /* TODO: Save the Connector and consider using a command
1110 * to fetch the value instead of sending an event with
1111 * it. The Connector could end up being larger than what
1112 * most clients are ready to receive as an event
1114 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1117 if (auth
->c_sign_key
) {
1121 hexlen
= 2 * wpabuf_len(auth
->c_sign_key
) + 1;
1122 hex
= os_malloc(hexlen
);
1124 wpa_snprintf_hex(hex
, hexlen
,
1125 wpabuf_head(auth
->c_sign_key
),
1126 wpabuf_len(auth
->c_sign_key
));
1127 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1132 if (auth
->net_access_key
) {
1136 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1137 hex
= os_malloc(hexlen
);
1139 wpa_snprintf_hex(hex
, hexlen
,
1140 wpabuf_head(auth
->net_access_key
),
1141 wpabuf_len(auth
->net_access_key
));
1142 if (auth
->net_access_key_expiry
)
1143 wpa_msg(wpa_s
, MSG_INFO
,
1144 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1146 auth
->net_access_key_expiry
);
1148 wpa_msg(wpa_s
, MSG_INFO
,
1149 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1154 return wpas_dpp_process_config(wpa_s
, auth
);
1158 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1159 enum gas_query_result result
,
1160 const struct wpabuf
*adv_proto
,
1161 const struct wpabuf
*resp
, u16 status_code
)
1163 struct wpa_supplicant
*wpa_s
= ctx
;
1165 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1167 enum dpp_status_error status
= DPP_STATUS_CONFIG_REJECTED
;
1169 wpa_s
->dpp_gas_dialog_token
= -1;
1171 if (!auth
|| !auth
->auth_success
) {
1172 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1175 if (result
!= GAS_QUERY_SUCCESS
||
1176 !resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1177 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1181 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1183 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1186 if (wpabuf_len(adv_proto
) != 10 ||
1187 !(pos
= wpabuf_head(adv_proto
)) ||
1188 pos
[0] != WLAN_EID_ADV_PROTO
||
1190 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1192 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1195 wpa_printf(MSG_DEBUG
,
1196 "DPP: Not a DPP Advertisement Protocol ID");
1200 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1201 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1205 res
= wpas_dpp_handle_config_obj(wpa_s
, auth
);
1209 status
= DPP_STATUS_OK
;
1210 #ifdef CONFIG_TESTING_OPTIONS
1211 if (dpp_test
== DPP_TEST_REJECT_CONFIG
) {
1212 wpa_printf(MSG_INFO
, "DPP: TESTING - Reject Config Object");
1213 status
= DPP_STATUS_CONFIG_REJECTED
;
1215 #endif /* CONFIG_TESTING_OPTIONS */
1217 if (status
!= DPP_STATUS_OK
)
1218 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1220 if (auth
->peer_version
>= 2 &&
1221 auth
->conf_resp_status
== DPP_STATUS_OK
) {
1224 wpa_printf(MSG_DEBUG
, "DPP: Send DPP Configuration Result");
1225 msg
= dpp_build_conf_result(auth
, status
);
1229 wpa_msg(wpa_s
, MSG_INFO
,
1230 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1231 MAC2STR(addr
), auth
->curr_freq
,
1232 DPP_PA_CONFIGURATION_RESULT
);
1233 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1234 addr
, wpa_s
->own_addr
, broadcast
,
1237 500, wpas_dpp_tx_status
, 0);
1240 /* This exchange will be terminated in the TX status handler */
1244 #endif /* CONFIG_DPP2 */
1245 dpp_auth_deinit(wpa_s
->dpp_auth
);
1246 wpa_s
->dpp_auth
= NULL
;
1250 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1252 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1255 int *supp_op_classes
;
1257 wpa_s
->dpp_gas_client
= 1;
1258 offchannel_send_action_done(wpa_s
);
1259 wpas_dpp_listen_stop(wpa_s
);
1261 supp_op_classes
= wpas_supp_op_classes(wpa_s
);
1262 buf
= dpp_build_conf_req_helper(auth
, wpa_s
->conf
->dpp_name
,
1263 wpa_s
->dpp_netrole_ap
,
1264 wpa_s
->conf
->dpp_mud_url
,
1266 os_free(supp_op_classes
);
1268 wpa_printf(MSG_DEBUG
,
1269 "DPP: No configuration request data available");
1273 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1274 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1276 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1277 1, buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1279 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1282 wpa_printf(MSG_DEBUG
,
1283 "DPP: GAS query started with dialog token %u", res
);
1284 wpa_s
->dpp_gas_dialog_token
= res
;
1289 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1291 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1292 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1293 #ifdef CONFIG_TESTING_OPTIONS
1294 if (dpp_test
== DPP_TEST_STOP_AT_AUTH_CONF
) {
1295 wpa_printf(MSG_INFO
,
1296 "DPP: TESTING - stop at Authentication Confirm");
1297 if (wpa_s
->dpp_auth
->configurator
) {
1298 /* Prevent GAS response */
1299 wpa_s
->dpp_auth
->auth_success
= 0;
1303 #endif /* CONFIG_TESTING_OPTIONS */
1305 if (wpa_s
->dpp_auth
->configurator
)
1306 wpas_dpp_start_gas_server(wpa_s
);
1308 wpas_dpp_start_gas_client(wpa_s
);
1312 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1313 const u8
*hdr
, const u8
*buf
, size_t len
,
1316 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1319 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1320 " (freq %u MHz)", MAC2STR(src
), freq
);
1323 wpa_printf(MSG_DEBUG
,
1324 "DPP: No DPP Authentication in progress - drop");
1328 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1329 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1330 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1331 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1335 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1337 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1338 wpa_printf(MSG_DEBUG
,
1339 "DPP: Responder accepted request for different negotiation channel");
1340 auth
->curr_freq
= freq
;
1343 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1344 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1346 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1347 wpa_printf(MSG_DEBUG
,
1348 "DPP: Start wait for full response");
1349 offchannel_send_action_done(wpa_s
);
1350 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1353 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1356 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1358 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1359 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1360 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1361 src
, wpa_s
->own_addr
, broadcast
,
1362 wpabuf_head(msg
), wpabuf_len(msg
),
1363 500, wpas_dpp_tx_status
, 0);
1365 wpa_s
->dpp_auth_ok_on_ack
= 1;
1369 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1370 const u8
*hdr
, const u8
*buf
, size_t len
)
1372 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1374 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1378 wpa_printf(MSG_DEBUG
,
1379 "DPP: No DPP Authentication in progress - drop");
1383 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1384 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1385 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1389 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1390 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1394 wpas_dpp_auth_success(wpa_s
, 0);
1400 static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx
,
1403 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1404 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1406 if (!auth
|| !auth
->waiting_conf_result
)
1409 wpa_printf(MSG_DEBUG
,
1410 "DPP: Timeout while waiting for Configuration Result");
1411 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1412 dpp_auth_deinit(auth
);
1413 wpa_s
->dpp_auth
= NULL
;
1417 static void wpas_dpp_conn_status_result_wait_timeout(void *eloop_ctx
,
1420 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1421 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1423 if (!auth
|| !auth
->waiting_conn_status_result
)
1426 wpa_printf(MSG_DEBUG
,
1427 "DPP: Timeout while waiting for Connection Status Result");
1428 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONN_STATUS_RESULT
"timeout");
1429 wpas_dpp_listen_stop(wpa_s
);
1430 dpp_auth_deinit(auth
);
1431 wpa_s
->dpp_auth
= NULL
;
1435 static void wpas_dpp_rx_conf_result(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1436 const u8
*hdr
, const u8
*buf
, size_t len
)
1438 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1439 enum dpp_status_error status
;
1441 wpa_printf(MSG_DEBUG
, "DPP: Configuration Result from " MACSTR
,
1444 if (!auth
|| !auth
->waiting_conf_result
) {
1445 wpa_printf(MSG_DEBUG
,
1446 "DPP: No DPP Configuration waiting for result - drop");
1450 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1451 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1452 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1456 status
= dpp_conf_result_rx(auth
, hdr
, buf
, len
);
1458 if (status
== DPP_STATUS_OK
&& auth
->send_conn_status
) {
1459 wpa_msg(wpa_s
, MSG_INFO
,
1460 DPP_EVENT_CONF_SENT
"wait_conn_status=1");
1461 wpa_printf(MSG_DEBUG
, "DPP: Wait for Connection Status Result");
1462 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
1464 auth
->waiting_conn_status_result
= 1;
1465 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
1467 eloop_register_timeout(16, 0,
1468 wpas_dpp_conn_status_result_wait_timeout
,
1470 offchannel_send_action_done(wpa_s
);
1471 wpas_dpp_listen_start(wpa_s
, auth
->neg_freq
? auth
->neg_freq
:
1475 offchannel_send_action_done(wpa_s
);
1476 wpas_dpp_listen_stop(wpa_s
);
1477 if (status
== DPP_STATUS_OK
)
1478 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
1480 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1481 dpp_auth_deinit(auth
);
1482 wpa_s
->dpp_auth
= NULL
;
1483 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
1487 static void wpas_dpp_rx_conn_status_result(struct wpa_supplicant
*wpa_s
,
1488 const u8
*src
, const u8
*hdr
,
1489 const u8
*buf
, size_t len
)
1491 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1492 enum dpp_status_error status
;
1493 u8 ssid
[SSID_MAX_LEN
];
1494 size_t ssid_len
= 0;
1495 char *channel_list
= NULL
;
1497 wpa_printf(MSG_DEBUG
, "DPP: Connection Status Result");
1499 if (!auth
|| !auth
->waiting_conn_status_result
) {
1500 wpa_printf(MSG_DEBUG
,
1501 "DPP: No DPP Configuration waiting for connection status result - drop");
1505 status
= dpp_conn_status_result_rx(auth
, hdr
, buf
, len
,
1506 ssid
, &ssid_len
, &channel_list
);
1507 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONN_STATUS_RESULT
1508 "result=%d ssid=%s channel_list=%s",
1509 status
, wpa_ssid_txt(ssid
, ssid_len
),
1510 channel_list
? channel_list
: "N/A");
1511 os_free(channel_list
);
1512 offchannel_send_action_done(wpa_s
);
1513 wpas_dpp_listen_stop(wpa_s
);
1514 dpp_auth_deinit(auth
);
1515 wpa_s
->dpp_auth
= NULL
;
1516 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
1521 static int wpas_dpp_process_conf_obj(void *ctx
,
1522 struct dpp_authentication
*auth
)
1524 struct wpa_supplicant
*wpa_s
= ctx
;
1526 return wpas_dpp_handle_config_obj(wpa_s
, auth
);
1529 #endif /* CONFIG_DPP2 */
1532 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1534 const u8
*buf
, size_t len
)
1536 struct wpa_ssid
*ssid
;
1537 const u8
*connector
, *trans_id
, *status
;
1538 u16 connector_len
, trans_id_len
, status_len
;
1539 struct dpp_introduction intro
;
1540 struct rsn_pmksa_cache_entry
*entry
;
1542 struct os_reltime rnow
;
1544 unsigned int seconds
;
1545 enum dpp_status_error res
;
1547 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1549 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1550 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1551 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1552 MACSTR
" - drop", MAC2STR(src
));
1555 offchannel_send_action_done(wpa_s
);
1557 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1558 if (ssid
== wpa_s
->dpp_intro_network
)
1561 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1563 wpa_printf(MSG_DEBUG
,
1564 "DPP: Profile not found for network introduction");
1568 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1570 if (!trans_id
|| trans_id_len
!= 1) {
1571 wpa_printf(MSG_DEBUG
,
1572 "DPP: Peer did not include Transaction ID");
1573 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1574 " fail=missing_transaction_id", MAC2STR(src
));
1577 if (trans_id
[0] != TRANSACTION_ID
) {
1578 wpa_printf(MSG_DEBUG
,
1579 "DPP: Ignore frame with unexpected Transaction ID %u",
1581 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1582 " fail=transaction_id_mismatch", MAC2STR(src
));
1586 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1587 if (!status
|| status_len
!= 1) {
1588 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1589 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1590 " fail=missing_status", MAC2STR(src
));
1593 if (status
[0] != DPP_STATUS_OK
) {
1594 wpa_printf(MSG_DEBUG
,
1595 "DPP: Peer rejected network introduction: Status %u",
1597 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1598 " status=%u", MAC2STR(src
), status
[0]);
1600 wpas_dpp_send_conn_status_result(wpa_s
, status
[0]);
1601 #endif /* CONFIG_DPP2 */
1605 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1607 wpa_printf(MSG_DEBUG
,
1608 "DPP: Peer did not include its Connector");
1609 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1610 " fail=missing_connector", MAC2STR(src
));
1614 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1615 ssid
->dpp_netaccesskey
,
1616 ssid
->dpp_netaccesskey_len
,
1618 ssid
->dpp_csign_len
,
1619 connector
, connector_len
, &expiry
);
1620 if (res
!= DPP_STATUS_OK
) {
1621 wpa_printf(MSG_INFO
,
1622 "DPP: Network Introduction protocol resulted in failure");
1623 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1624 " fail=peer_connector_validation_failed", MAC2STR(src
));
1626 wpas_dpp_send_conn_status_result(wpa_s
, res
);
1627 #endif /* CONFIG_DPP2 */
1631 entry
= os_zalloc(sizeof(*entry
));
1634 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1635 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1636 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1637 entry
->pmk_len
= intro
.pmk_len
;
1638 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1641 seconds
= expiry
- now
.sec
;
1643 seconds
= 86400 * 7;
1645 os_get_reltime(&rnow
);
1646 entry
->expiration
= rnow
.sec
+ seconds
;
1647 entry
->reauth_time
= rnow
.sec
+ seconds
;
1648 entry
->network_ctx
= ssid
;
1649 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1651 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1652 " status=%u", MAC2STR(src
), status
[0]);
1654 wpa_printf(MSG_DEBUG
,
1655 "DPP: Try connection again after successful network introduction");
1656 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1657 wpa_supplicant_cancel_sched_scan(wpa_s
);
1658 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1661 os_memset(&intro
, 0, sizeof(intro
));
1665 static int wpas_dpp_allow_ir(struct wpa_supplicant
*wpa_s
, unsigned int freq
)
1669 if (!wpa_s
->hw
.modes
)
1672 for (i
= 0; i
< wpa_s
->hw
.num_modes
; i
++) {
1673 struct hostapd_hw_modes
*mode
= &wpa_s
->hw
.modes
[i
];
1675 for (j
= 0; j
< mode
->num_channels
; j
++) {
1676 struct hostapd_channel_data
*chan
= &mode
->channels
[j
];
1678 if (chan
->freq
!= (int) freq
)
1681 if (chan
->flag
& (HOSTAPD_CHAN_DISABLED
|
1682 HOSTAPD_CHAN_NO_IR
|
1683 HOSTAPD_CHAN_RADAR
))
1690 wpa_printf(MSG_DEBUG
,
1691 "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
1698 static int wpas_dpp_pkex_next_channel(struct wpa_supplicant
*wpa_s
,
1699 struct dpp_pkex
*pkex
)
1701 if (pkex
->freq
== 2437)
1703 else if (pkex
->freq
== 5745)
1705 else if (pkex
->freq
== 5220)
1708 return -1; /* no more channels to try */
1710 if (wpas_dpp_allow_ir(wpa_s
, pkex
->freq
) == 1) {
1711 wpa_printf(MSG_DEBUG
, "DPP: Try to initiate on %u MHz",
1716 /* Could not use this channel - try the next one */
1717 return wpas_dpp_pkex_next_channel(wpa_s
, pkex
);
1721 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1723 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1724 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1726 if (!pkex
|| !pkex
->exchange_req
)
1728 if (pkex
->exch_req_tries
>= 5) {
1729 if (wpas_dpp_pkex_next_channel(wpa_s
, pkex
) < 0) {
1730 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1731 "No response from PKEX peer");
1732 dpp_pkex_free(pkex
);
1733 wpa_s
->dpp_pkex
= NULL
;
1736 pkex
->exch_req_tries
= 0;
1739 pkex
->exch_req_tries
++;
1740 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1741 pkex
->exch_req_tries
);
1742 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1743 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1744 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1745 wpa_s
->own_addr
, broadcast
,
1746 wpabuf_head(pkex
->exchange_req
),
1747 wpabuf_len(pkex
->exchange_req
),
1748 pkex
->exch_req_wait_time
,
1749 wpas_dpp_tx_pkex_status
, 0);
1754 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1755 unsigned int freq
, const u8
*dst
,
1756 const u8
*src
, const u8
*bssid
,
1757 const u8
*data
, size_t data_len
,
1758 enum offchannel_send_action_result result
)
1760 const char *res_txt
;
1761 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1763 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1764 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1766 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1767 " result=%s (PKEX)",
1768 freq
, MAC2STR(dst
), res_txt
);
1769 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1770 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1773 wpa_printf(MSG_DEBUG
,
1774 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1779 wpa_printf(MSG_DEBUG
,
1780 "DPP: Terminate PKEX exchange due to an earlier error");
1781 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1782 pkex
->own_bi
->pkex_t
= pkex
->t
;
1783 dpp_pkex_free(pkex
);
1784 wpa_s
->dpp_pkex
= NULL
;
1788 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1789 /* Wait for PKEX Exchange Response frame and retry request if
1790 * no response is seen. */
1791 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1792 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1793 (pkex
->exch_req_wait_time
% 1000) * 1000,
1794 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1801 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1802 const u8
*buf
, size_t len
, unsigned int freq
)
1805 unsigned int wait_time
;
1807 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1810 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1813 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1814 wpa_printf(MSG_DEBUG
,
1815 "DPP: No PKEX code configured - ignore request");
1819 if (wpa_s
->dpp_pkex
) {
1820 /* TODO: Support parallel operations */
1821 wpa_printf(MSG_DEBUG
,
1822 "DPP: Already in PKEX session - ignore new request");
1826 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1827 wpa_s
->own_addr
, src
,
1828 wpa_s
->dpp_pkex_identifier
,
1829 wpa_s
->dpp_pkex_code
,
1831 if (!wpa_s
->dpp_pkex
) {
1832 wpa_printf(MSG_DEBUG
,
1833 "DPP: Failed to process the request - ignore it");
1837 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1838 wait_time
= wpa_s
->max_remain_on_chan
;
1839 if (wait_time
> 2000)
1841 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1842 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1843 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1845 wpabuf_head(msg
), wpabuf_len(msg
),
1846 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1851 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1852 const u8
*buf
, size_t len
, unsigned int freq
)
1855 unsigned int wait_time
;
1857 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1860 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1863 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1864 wpa_s
->dpp_pkex
->exchange_done
) {
1865 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1869 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1870 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
1872 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, src
, buf
, len
);
1874 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1878 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1881 wait_time
= wpa_s
->max_remain_on_chan
;
1882 if (wait_time
> 2000)
1884 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1885 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1886 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1888 wpabuf_head(msg
), wpabuf_len(msg
),
1889 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1894 static struct dpp_bootstrap_info
*
1895 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
1898 struct dpp_bootstrap_info
*bi
;
1900 bi
= dpp_pkex_finish(wpa_s
->dpp
, wpa_s
->dpp_pkex
, peer
, freq
);
1903 wpa_s
->dpp_pkex
= NULL
;
1909 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1910 const u8
*hdr
, const u8
*buf
, size_t len
,
1914 unsigned int wait_time
;
1915 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1917 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1920 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1921 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1925 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1927 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1929 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
1930 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1931 pkex
->own_bi
->pkex_t
= pkex
->t
;
1932 dpp_pkex_free(wpa_s
->dpp_pkex
);
1933 wpa_s
->dpp_pkex
= NULL
;
1938 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1939 MACSTR
, MAC2STR(src
));
1941 wait_time
= wpa_s
->max_remain_on_chan
;
1942 if (wait_time
> 2000)
1944 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1945 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
1946 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1948 wpabuf_head(msg
), wpabuf_len(msg
),
1949 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1952 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1957 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1958 const u8
*hdr
, const u8
*buf
, size_t len
,
1962 struct dpp_bootstrap_info
*bi
;
1963 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1966 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
1969 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
1970 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1974 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
1976 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1980 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1984 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
1986 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
1987 wpa_printf(MSG_DEBUG
,
1988 "DPP: Start authentication after PKEX with parameters: %s",
1990 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
1991 wpa_printf(MSG_DEBUG
,
1992 "DPP: Authentication initialization failed");
1998 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1999 const u8
*buf
, size_t len
, unsigned int freq
)
2002 enum dpp_public_action_frame_type type
;
2004 unsigned int pkex_t
;
2006 if (len
< DPP_HDR_LEN
)
2008 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
2013 crypto_suite
= *buf
++;
2017 wpa_printf(MSG_DEBUG
,
2018 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2020 crypto_suite
, type
, MAC2STR(src
), freq
);
2021 if (crypto_suite
!= 1) {
2022 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
2024 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2025 " freq=%u type=%d ignore=unsupported-crypto-suite",
2026 MAC2STR(src
), freq
, type
);
2029 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
2030 if (dpp_check_attrs(buf
, len
) < 0) {
2031 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2032 " freq=%u type=%d ignore=invalid-attributes",
2033 MAC2STR(src
), freq
, type
);
2036 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
2037 MAC2STR(src
), freq
, type
);
2040 case DPP_PA_AUTHENTICATION_REQ
:
2041 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
2043 case DPP_PA_AUTHENTICATION_RESP
:
2044 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
2046 case DPP_PA_AUTHENTICATION_CONF
:
2047 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
2049 case DPP_PA_PEER_DISCOVERY_RESP
:
2050 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
2052 case DPP_PA_PKEX_EXCHANGE_REQ
:
2053 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
2055 case DPP_PA_PKEX_EXCHANGE_RESP
:
2056 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
2058 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
2059 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
2062 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
2063 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
2067 case DPP_PA_CONFIGURATION_RESULT
:
2068 wpas_dpp_rx_conf_result(wpa_s
, src
, hdr
, buf
, len
);
2070 case DPP_PA_CONNECTION_STATUS_RESULT
:
2071 wpas_dpp_rx_conn_status_result(wpa_s
, src
, hdr
, buf
, len
);
2073 #endif /* CONFIG_DPP2 */
2075 wpa_printf(MSG_DEBUG
,
2076 "DPP: Ignored unsupported frame subtype %d", type
);
2080 if (wpa_s
->dpp_pkex
)
2081 pkex_t
= wpa_s
->dpp_pkex
->t
;
2082 else if (wpa_s
->dpp_pkex_bi
)
2083 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
2086 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
2087 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
2088 wpas_dpp_pkex_remove(wpa_s
, "*");
2093 static struct wpabuf
*
2094 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
2097 struct wpa_supplicant
*wpa_s
= ctx
;
2098 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2099 struct wpabuf
*resp
;
2101 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
2103 if (!auth
|| !auth
->auth_success
||
2104 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
2105 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
2109 if (wpa_s
->dpp_auth_ok_on_ack
&& auth
->configurator
) {
2110 wpa_printf(MSG_DEBUG
,
2111 "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
2112 /* wpas_dpp_auth_success() would normally have been called from
2113 * TX status handler, but since there was no such handler call
2114 * yet, simply send out the event message and proceed with
2116 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=1");
2117 wpa_s
->dpp_auth_ok_on_ack
= 0;
2120 wpa_hexdump(MSG_DEBUG
,
2121 "DPP: Received Configuration Request (GAS Query Request)",
2123 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_REQ_RX
"src=" MACSTR
,
2125 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
2127 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2128 auth
->conf_resp
= resp
;
2134 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
2136 struct wpa_supplicant
*wpa_s
= ctx
;
2137 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2143 if (auth
->conf_resp
!= resp
) {
2144 wpa_printf(MSG_DEBUG
,
2145 "DPP: Ignore GAS status report (ok=%d) for unknown response",
2151 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
2153 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2154 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2156 if (ok
&& auth
->peer_version
>= 2 &&
2157 auth
->conf_resp_status
== DPP_STATUS_OK
) {
2158 wpa_printf(MSG_DEBUG
, "DPP: Wait for Configuration Result");
2159 auth
->waiting_conf_result
= 1;
2160 auth
->conf_resp
= NULL
;
2162 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
2164 eloop_register_timeout(2, 0,
2165 wpas_dpp_config_result_wait_timeout
,
2169 #endif /* CONFIG_DPP2 */
2170 offchannel_send_action_done(wpa_s
);
2171 wpas_dpp_listen_stop(wpa_s
);
2173 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
2175 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2176 dpp_auth_deinit(wpa_s
->dpp_auth
);
2177 wpa_s
->dpp_auth
= NULL
;
2182 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2184 struct dpp_authentication
*auth
;
2188 auth
= os_zalloc(sizeof(*auth
));
2192 curve
= get_param(cmd
, " curve=");
2193 wpas_dpp_set_testing_options(wpa_s
, auth
);
2194 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, auth
, cmd
) == 0 &&
2195 dpp_configurator_own_config(auth
, curve
, 0) == 0)
2196 ret
= wpas_dpp_handle_config_obj(wpa_s
, auth
);
2198 dpp_auth_deinit(auth
);
2206 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
2207 unsigned int freq
, const u8
*dst
,
2208 const u8
*src
, const u8
*bssid
,
2209 const u8
*data
, size_t data_len
,
2210 enum offchannel_send_action_result result
)
2212 const char *res_txt
;
2214 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
2215 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
2217 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
2218 " result=%s (DPP Peer Discovery Request)",
2219 freq
, MAC2STR(dst
), res_txt
);
2220 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
2221 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
2222 /* TODO: Time out wait for response more quickly in error cases? */
2226 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
2227 struct wpa_bss
*bss
)
2231 unsigned int wait_time
;
2233 struct wpa_ie_data ied
;
2235 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
2236 return 0; /* Not using DPP AKM - continue */
2237 rsn
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
2238 if (rsn
&& wpa_parse_wpa_ie(rsn
, 2 + rsn
[1], &ied
) == 0 &&
2239 !(ied
.key_mgmt
& WPA_KEY_MGMT_DPP
))
2240 return 0; /* AP does not support DPP AKM - continue */
2241 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
2242 return 0; /* PMKSA exists for DPP AKM - continue */
2244 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
2246 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2248 !ssid
->dpp_connector
? "Connector" :
2249 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2256 if (ssid
->dpp_netaccesskey_expiry
&&
2257 (os_time_t
) ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2258 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2259 "netAccessKey expired");
2263 wpa_printf(MSG_DEBUG
,
2264 "DPP: Starting network introduction protocol to derive PMKSA for "
2265 MACSTR
, MAC2STR(bss
->bssid
));
2267 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2268 5 + 4 + os_strlen(ssid
->dpp_connector
));
2272 #ifdef CONFIG_TESTING_OPTIONS
2273 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2274 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2277 if (dpp_test
== DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_REQ
) {
2278 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Transaction ID");
2279 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2280 wpabuf_put_le16(msg
, 0);
2283 #endif /* CONFIG_TESTING_OPTIONS */
2285 /* Transaction ID */
2286 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2287 wpabuf_put_le16(msg
, 1);
2288 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2290 #ifdef CONFIG_TESTING_OPTIONS
2292 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2293 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2294 goto skip_connector
;
2296 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2299 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2300 connector
= dpp_corrupt_connector_signature(
2301 ssid
->dpp_connector
);
2306 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2307 wpabuf_put_le16(msg
, os_strlen(connector
));
2308 wpabuf_put_str(msg
, connector
);
2310 goto skip_connector
;
2312 #endif /* CONFIG_TESTING_OPTIONS */
2315 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2316 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2317 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2319 #ifdef CONFIG_TESTING_OPTIONS
2321 #endif /* CONFIG_TESTING_OPTIONS */
2323 /* TODO: Timeout on AP response */
2324 wait_time
= wpa_s
->max_remain_on_chan
;
2325 if (wait_time
> 2000)
2327 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2328 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2329 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2331 wpabuf_head(msg
), wpabuf_len(msg
),
2332 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2335 /* Request this connection attempt to terminate - new one will be
2336 * started when network introduction protocol completes */
2337 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2338 wpa_s
->dpp_intro_network
= ssid
;
2343 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2345 struct dpp_bootstrap_info
*own_bi
;
2346 const char *pos
, *end
;
2347 unsigned int wait_time
;
2349 pos
= os_strstr(cmd
, " own=");
2353 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
2355 wpa_printf(MSG_DEBUG
,
2356 "DPP: Identified bootstrap info not found");
2359 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2360 wpa_printf(MSG_DEBUG
,
2361 "DPP: Identified bootstrap info not for PKEX");
2364 wpa_s
->dpp_pkex_bi
= own_bi
;
2365 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2367 os_free(wpa_s
->dpp_pkex_identifier
);
2368 wpa_s
->dpp_pkex_identifier
= NULL
;
2369 pos
= os_strstr(cmd
, " identifier=");
2372 end
= os_strchr(pos
, ' ');
2375 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2376 if (!wpa_s
->dpp_pkex_identifier
)
2378 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2379 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2382 pos
= os_strstr(cmd
, " code=");
2385 os_free(wpa_s
->dpp_pkex_code
);
2386 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2387 if (!wpa_s
->dpp_pkex_code
)
2390 if (os_strstr(cmd
, " init=1")) {
2391 struct dpp_pkex
*pkex
;
2394 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2395 dpp_pkex_free(wpa_s
->dpp_pkex
);
2396 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2397 wpa_s
->dpp_pkex_identifier
,
2398 wpa_s
->dpp_pkex_code
);
2399 pkex
= wpa_s
->dpp_pkex
;
2403 msg
= pkex
->exchange_req
;
2404 wait_time
= wpa_s
->max_remain_on_chan
;
2405 if (wait_time
> 2000)
2408 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2410 MAC2STR(broadcast
), pkex
->freq
,
2411 DPP_PA_PKEX_EXCHANGE_REQ
);
2412 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2413 wpa_s
->own_addr
, broadcast
,
2414 wpabuf_head(msg
), wpabuf_len(msg
),
2415 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2418 pkex
->exch_req_wait_time
= wait_time
;
2419 pkex
->exch_req_tries
= 1;
2422 /* TODO: Support multiple PKEX info entries */
2424 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2425 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2431 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2433 unsigned int id_val
;
2435 if (os_strcmp(id
, "*") == 0) {
2443 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2446 /* TODO: Support multiple PKEX entries */
2447 os_free(wpa_s
->dpp_pkex_code
);
2448 wpa_s
->dpp_pkex_code
= NULL
;
2449 os_free(wpa_s
->dpp_pkex_identifier
);
2450 wpa_s
->dpp_pkex_identifier
= NULL
;
2451 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2452 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2453 wpa_s
->dpp_pkex_bi
= NULL
;
2454 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2455 dpp_pkex_free(wpa_s
->dpp_pkex
);
2456 wpa_s
->dpp_pkex
= NULL
;
2461 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2463 dpp_auth_deinit(wpa_s
->dpp_auth
);
2464 wpa_s
->dpp_auth
= NULL
;
2465 dpp_pkex_free(wpa_s
->dpp_pkex
);
2466 wpa_s
->dpp_pkex
= NULL
;
2467 if (wpa_s
->dpp_gas_client
&& wpa_s
->dpp_gas_dialog_token
>= 0)
2468 gas_query_stop(wpa_s
->gas
, wpa_s
->dpp_gas_dialog_token
);
2472 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2474 struct dpp_global_config config
;
2477 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2478 adv_proto_id
[1] = 5;
2479 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2480 adv_proto_id
[5] = DPP_OUI_TYPE
;
2481 adv_proto_id
[6] = 0x01;
2483 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2484 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2485 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2488 os_memset(&config
, 0, sizeof(config
));
2489 config
.msg_ctx
= wpa_s
;
2490 config
.cb_ctx
= wpa_s
;
2492 config
.process_conf_obj
= wpas_dpp_process_conf_obj
;
2493 #endif /* CONFIG_DPP2 */
2494 wpa_s
->dpp
= dpp_global_init(&config
);
2495 return wpa_s
->dpp
? 0 : -1;
2499 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2501 #ifdef CONFIG_TESTING_OPTIONS
2502 os_free(wpa_s
->dpp_config_obj_override
);
2503 wpa_s
->dpp_config_obj_override
= NULL
;
2504 os_free(wpa_s
->dpp_discovery_override
);
2505 wpa_s
->dpp_discovery_override
= NULL
;
2506 os_free(wpa_s
->dpp_groups_override
);
2507 wpa_s
->dpp_groups_override
= NULL
;
2508 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2509 #endif /* CONFIG_TESTING_OPTIONS */
2512 dpp_global_clear(wpa_s
->dpp
);
2513 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2514 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2515 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2516 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2518 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
2519 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
2521 eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout
, wpa_s
, NULL
);
2522 dpp_pfs_free(wpa_s
->dpp_pfs
);
2523 wpa_s
->dpp_pfs
= NULL
;
2524 #endif /* CONFIG_DPP2 */
2525 offchannel_send_action_done(wpa_s
);
2526 wpas_dpp_listen_stop(wpa_s
);
2527 wpas_dpp_stop(wpa_s
);
2528 wpas_dpp_pkex_remove(wpa_s
, "*");
2529 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2530 os_free(wpa_s
->dpp_configurator_params
);
2531 wpa_s
->dpp_configurator_params
= NULL
;
2536 int wpas_dpp_controller_start(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2538 struct dpp_controller_config config
;
2541 os_memset(&config
, 0, sizeof(config
));
2543 pos
= os_strstr(cmd
, " tcp_port=");
2546 config
.tcp_port
= atoi(pos
);
2549 config
.configurator_params
= wpa_s
->dpp_configurator_params
;
2550 return dpp_controller_start(wpa_s
->dpp
, &config
);
2552 #endif /* CONFIG_DPP2 */