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 "common/dpp.h"
15 #include "common/gas.h"
16 #include "common/gas_server.h"
17 #include "rsn_supp/wpa.h"
18 #include "rsn_supp/pmksa_cache.h"
19 #include "wpa_supplicant_i.h"
22 #include "offchannel.h"
23 #include "gas_query.h"
27 #include "dpp_supplicant.h"
30 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
32 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
);
33 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
);
34 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
35 unsigned int freq
, const u8
*dst
,
36 const u8
*src
, const u8
*bssid
,
37 const u8
*data
, size_t data_len
,
38 enum offchannel_send_action_result result
);
39 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
);
40 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
);
42 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
43 unsigned int freq
, const u8
*dst
,
44 const u8
*src
, const u8
*bssid
,
45 const u8
*data
, size_t data_len
,
46 enum offchannel_send_action_result result
);
48 static const u8 broadcast
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
50 /* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only
51 * a single transaction in progress at any point in time. */
52 static const u8 TRANSACTION_ID
= 1;
56 * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
57 * @wpa_s: Pointer to wpa_supplicant data
58 * @cmd: DPP URI read from a QR Code
59 * Returns: Identifier of the stored info or -1 on failure
61 int wpas_dpp_qr_code(struct wpa_supplicant
*wpa_s
, const char *cmd
)
63 struct dpp_bootstrap_info
*bi
;
64 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
66 bi
= dpp_add_qr_code(wpa_s
->dpp
, cmd
);
70 if (auth
&& auth
->response_pending
&&
71 dpp_notify_new_qr_code(auth
, bi
) == 1) {
73 "DPP: Sending out pending authentication response");
74 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
76 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
77 DPP_PA_AUTHENTICATION_RESP
);
78 offchannel_send_action(wpa_s
, auth
->curr_freq
,
79 auth
->peer_mac_addr
, wpa_s
->own_addr
,
81 wpabuf_head(auth
->resp_msg
),
82 wpabuf_len(auth
->resp_msg
),
83 500, wpas_dpp_tx_status
, 0);
90 static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
92 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
93 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
95 if (!auth
|| !auth
->resp_msg
)
99 "DPP: Retry Authentication Response after timeout");
100 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
102 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
103 DPP_PA_AUTHENTICATION_RESP
);
104 offchannel_send_action(wpa_s
, auth
->curr_freq
, auth
->peer_mac_addr
,
105 wpa_s
->own_addr
, broadcast
,
106 wpabuf_head(auth
->resp_msg
),
107 wpabuf_len(auth
->resp_msg
),
108 500, wpas_dpp_tx_status
, 0);
112 static void wpas_dpp_auth_resp_retry(struct wpa_supplicant
*wpa_s
)
114 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
115 unsigned int wait_time
, max_tries
;
117 if (!auth
|| !auth
->resp_msg
)
120 if (wpa_s
->dpp_resp_max_tries
)
121 max_tries
= wpa_s
->dpp_resp_max_tries
;
124 auth
->auth_resp_tries
++;
125 if (auth
->auth_resp_tries
>= max_tries
) {
126 wpa_printf(MSG_INFO
, "DPP: No confirm received from initiator - stopping exchange");
127 offchannel_send_action_done(wpa_s
);
128 dpp_auth_deinit(wpa_s
->dpp_auth
);
129 wpa_s
->dpp_auth
= NULL
;
133 if (wpa_s
->dpp_resp_retry_time
)
134 wait_time
= wpa_s
->dpp_resp_retry_time
;
137 wpa_printf(MSG_DEBUG
,
138 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
140 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
141 eloop_register_timeout(wait_time
/ 1000,
142 (wait_time
% 1000) * 1000,
143 wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
147 static void wpas_dpp_try_to_connect(struct wpa_supplicant
*wpa_s
)
149 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
150 wpa_s
->disconnected
= 0;
151 wpa_s
->reassociate
= 1;
152 wpa_s
->scan_runs
= 0;
153 wpa_s
->normal_scans
= 0;
154 wpa_supplicant_cancel_sched_scan(wpa_s
);
155 wpa_supplicant_req_scan(wpa_s
, 0, 0);
159 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
160 unsigned int freq
, const u8
*dst
,
161 const u8
*src
, const u8
*bssid
,
162 const u8
*data
, size_t data_len
,
163 enum offchannel_send_action_result result
)
166 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
168 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
169 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
171 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
172 " result=%s", freq
, MAC2STR(dst
), res_txt
);
173 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
174 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
176 if (!wpa_s
->dpp_auth
) {
177 wpa_printf(MSG_DEBUG
,
178 "DPP: Ignore TX status since there is no ongoing authentication exchange");
183 if (auth
->connect_on_tx_status
) {
184 wpa_printf(MSG_DEBUG
,
185 "DPP: Try to connect after completed configuration result");
186 wpas_dpp_try_to_connect(wpa_s
);
187 dpp_auth_deinit(wpa_s
->dpp_auth
);
188 wpa_s
->dpp_auth
= NULL
;
191 #endif /* CONFIG_DPP2 */
193 if (wpa_s
->dpp_auth
->remove_on_tx_status
) {
194 wpa_printf(MSG_DEBUG
,
195 "DPP: Terminate authentication exchange due to an earlier error");
196 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
197 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
198 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
200 offchannel_send_action_done(wpa_s
);
201 dpp_auth_deinit(wpa_s
->dpp_auth
);
202 wpa_s
->dpp_auth
= NULL
;
206 if (wpa_s
->dpp_auth_ok_on_ack
)
207 wpas_dpp_auth_success(wpa_s
, 1);
209 if (!is_broadcast_ether_addr(dst
) &&
210 result
!= OFFCHANNEL_SEND_ACTION_SUCCESS
) {
211 wpa_printf(MSG_DEBUG
,
212 "DPP: Unicast DPP Action frame was not ACKed");
213 if (auth
->waiting_auth_resp
) {
214 /* In case of DPP Authentication Request frame, move to
215 * the next channel immediately. */
216 offchannel_send_action_done(wpa_s
);
217 wpas_dpp_auth_init_next(wpa_s
);
220 if (auth
->waiting_auth_conf
) {
221 wpas_dpp_auth_resp_retry(wpa_s
);
226 if (!is_broadcast_ether_addr(dst
) && auth
->waiting_auth_resp
&&
227 result
== OFFCHANNEL_SEND_ACTION_SUCCESS
) {
228 /* Allow timeout handling to stop iteration if no response is
229 * received from a peer that has ACKed a request. */
230 auth
->auth_req_ack
= 1;
233 if (!wpa_s
->dpp_auth_ok_on_ack
&& wpa_s
->dpp_auth
->neg_freq
> 0 &&
234 wpa_s
->dpp_auth
->curr_freq
!= wpa_s
->dpp_auth
->neg_freq
) {
235 wpa_printf(MSG_DEBUG
,
236 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
237 wpa_s
->dpp_auth
->curr_freq
,
238 wpa_s
->dpp_auth
->neg_freq
);
239 offchannel_send_action_done(wpa_s
);
240 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->neg_freq
);
243 if (wpa_s
->dpp_auth_ok_on_ack
)
244 wpa_s
->dpp_auth_ok_on_ack
= 0;
248 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
250 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
251 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
253 struct os_reltime now
, diff
;
254 unsigned int wait_time
, diff_ms
;
256 if (!auth
|| !auth
->waiting_auth_resp
)
259 wait_time
= wpa_s
->dpp_resp_wait_time
?
260 wpa_s
->dpp_resp_wait_time
: 2000;
261 os_get_reltime(&now
);
262 os_reltime_sub(&now
, &wpa_s
->dpp_last_init
, &diff
);
263 diff_ms
= diff
.sec
* 1000 + diff
.usec
/ 1000;
264 wpa_printf(MSG_DEBUG
,
265 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
268 if (auth
->auth_req_ack
&& diff_ms
>= wait_time
) {
269 /* Peer ACK'ed Authentication Request frame, but did not reply
270 * with Authentication Response frame within two seconds. */
272 "DPP: No response received from responder - stopping initiation attempt");
273 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
274 offchannel_send_action_done(wpa_s
);
275 wpas_dpp_listen_stop(wpa_s
);
276 dpp_auth_deinit(auth
);
277 wpa_s
->dpp_auth
= NULL
;
281 if (diff_ms
>= wait_time
) {
282 /* Authentication Request frame was not ACK'ed and no reply
283 * was receiving within two seconds. */
284 wpa_printf(MSG_DEBUG
,
285 "DPP: Continue Initiator channel iteration");
286 offchannel_send_action_done(wpa_s
);
287 wpas_dpp_listen_stop(wpa_s
);
288 wpas_dpp_auth_init_next(wpa_s
);
292 /* Driver did not support 2000 ms long wait_time with TX command, so
293 * schedule listen operation to continue waiting for the response.
295 * DPP listen operations continue until stopped, so simply schedule a
296 * new call to this function at the point when the two second reply
297 * wait has expired. */
298 wait_time
-= diff_ms
;
300 freq
= auth
->curr_freq
;
301 if (auth
->neg_freq
> 0)
302 freq
= auth
->neg_freq
;
303 wpa_printf(MSG_DEBUG
,
304 "DPP: Continue reply wait on channel %u MHz for %u ms",
306 wpa_s
->dpp_in_response_listen
= 1;
307 wpas_dpp_listen_start(wpa_s
, freq
);
309 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
310 wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
314 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
315 struct dpp_authentication
*auth
)
317 #ifdef CONFIG_TESTING_OPTIONS
318 if (wpa_s
->dpp_config_obj_override
)
319 auth
->config_obj_override
=
320 os_strdup(wpa_s
->dpp_config_obj_override
);
321 if (wpa_s
->dpp_discovery_override
)
322 auth
->discovery_override
=
323 os_strdup(wpa_s
->dpp_discovery_override
);
324 if (wpa_s
->dpp_groups_override
)
325 auth
->groups_override
=
326 os_strdup(wpa_s
->dpp_groups_override
);
327 auth
->ignore_netaccesskey_mismatch
=
328 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
329 #endif /* CONFIG_TESTING_OPTIONS */
333 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
335 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
337 if (!wpa_s
->dpp_auth
)
339 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
340 wpas_dpp_auth_init_next(wpa_s
);
344 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
346 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
348 unsigned int wait_time
, max_wait_time
, freq
, max_tries
, used
;
349 struct os_reltime now
, diff
;
351 wpa_s
->dpp_in_response_listen
= 0;
355 if (auth
->freq_idx
== 0)
356 os_get_reltime(&wpa_s
->dpp_init_iter_start
);
358 if (auth
->freq_idx
>= auth
->num_freq
) {
359 auth
->num_freq_iters
++;
360 if (wpa_s
->dpp_init_max_tries
)
361 max_tries
= wpa_s
->dpp_init_max_tries
;
364 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
366 "DPP: No response received from responder - stopping initiation attempt");
367 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
368 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
370 offchannel_send_action_done(wpa_s
);
371 dpp_auth_deinit(wpa_s
->dpp_auth
);
372 wpa_s
->dpp_auth
= NULL
;
376 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
377 if (wpa_s
->dpp_init_retry_time
)
378 wait_time
= wpa_s
->dpp_init_retry_time
;
381 os_get_reltime(&now
);
382 os_reltime_sub(&now
, &wpa_s
->dpp_init_iter_start
, &diff
);
383 used
= diff
.sec
* 1000 + diff
.usec
/ 1000;
384 if (used
> wait_time
)
388 wpa_printf(MSG_DEBUG
, "DPP: Next init attempt in %u ms",
390 eloop_register_timeout(wait_time
/ 1000,
391 (wait_time
% 1000) * 1000,
392 wpas_dpp_init_timeout
, wpa_s
,
396 freq
= auth
->freq
[auth
->freq_idx
++];
397 auth
->curr_freq
= freq
;
399 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
402 dst
= auth
->peer_bi
->mac_addr
;
403 wpa_s
->dpp_auth_ok_on_ack
= 0;
404 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
405 wait_time
= wpa_s
->max_remain_on_chan
;
406 max_wait_time
= wpa_s
->dpp_resp_wait_time
?
407 wpa_s
->dpp_resp_wait_time
: 2000;
408 if (wait_time
> max_wait_time
)
409 wait_time
= max_wait_time
;
410 wait_time
+= 10; /* give the driver some extra time to complete */
411 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
412 wpas_dpp_reply_wait_timeout
,
415 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
416 wpa_printf(MSG_DEBUG
,
417 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
418 freq
, auth
->neg_freq
);
420 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
421 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
422 auth
->auth_req_ack
= 0;
423 os_get_reltime(&wpa_s
->dpp_last_init
);
424 return offchannel_send_action(wpa_s
, freq
, dst
,
425 wpa_s
->own_addr
, broadcast
,
426 wpabuf_head(auth
->req_msg
),
427 wpabuf_len(auth
->req_msg
),
428 wait_time
, wpas_dpp_tx_status
, 0);
432 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
435 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
436 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
437 unsigned int neg_freq
= 0;
439 wpa_s
->dpp_gas_client
= 0;
441 pos
= os_strstr(cmd
, " peer=");
445 peer_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
448 "DPP: Could not find bootstrapping info for the identified peer");
452 pos
= os_strstr(cmd
, " own=");
455 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
458 "DPP: Could not find bootstrapping info for the identified local entry");
462 if (peer_bi
->curve
!= own_bi
->curve
) {
464 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
465 peer_bi
->curve
->name
, own_bi
->curve
->name
);
470 pos
= os_strstr(cmd
, " role=");
473 if (os_strncmp(pos
, "configurator", 12) == 0)
474 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
475 else if (os_strncmp(pos
, "enrollee", 8) == 0)
476 allowed_roles
= DPP_CAPAB_ENROLLEE
;
477 else if (os_strncmp(pos
, "either", 6) == 0)
478 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
484 pos
= os_strstr(cmd
, " netrole=");
487 wpa_s
->dpp_netrole_ap
= os_strncmp(pos
, "ap", 2) == 0;
490 pos
= os_strstr(cmd
, " neg_freq=");
492 neg_freq
= atoi(pos
+ 10);
494 if (wpa_s
->dpp_auth
) {
495 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
496 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
497 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
499 offchannel_send_action_done(wpa_s
);
500 dpp_auth_deinit(wpa_s
->dpp_auth
);
502 wpa_s
->dpp_auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
,
504 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
505 if (!wpa_s
->dpp_auth
)
507 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
508 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, wpa_s
->dpp_auth
, cmd
) < 0) {
509 dpp_auth_deinit(wpa_s
->dpp_auth
);
510 wpa_s
->dpp_auth
= NULL
;
514 wpa_s
->dpp_auth
->neg_freq
= neg_freq
;
516 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
517 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, peer_bi
->mac_addr
,
520 return wpas_dpp_auth_init_next(wpa_s
);
526 struct wpas_dpp_listen_work
{
528 unsigned int duration
;
529 struct wpabuf
*probe_resp_ie
;
533 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
541 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
543 struct wpas_dpp_listen_work
*lwork
;
545 if (!wpa_s
->dpp_listen_work
)
548 lwork
= wpa_s
->dpp_listen_work
->ctx
;
549 wpas_dpp_listen_work_free(lwork
);
550 radio_work_done(wpa_s
->dpp_listen_work
);
551 wpa_s
->dpp_listen_work
= NULL
;
555 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
557 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
558 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
562 wpa_s
->dpp_listen_work
= NULL
;
563 wpas_dpp_listen_stop(wpa_s
);
565 wpas_dpp_listen_work_free(lwork
);
569 wpa_s
->dpp_listen_work
= work
;
571 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
573 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
574 wpa_s
->max_remain_on_chan
) < 0) {
575 wpa_printf(MSG_DEBUG
,
576 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
578 wpa_s
->dpp_listen_freq
= 0;
579 wpas_dpp_listen_work_done(wpa_s
);
580 wpa_s
->dpp_pending_listen_freq
= 0;
583 wpa_s
->off_channel_freq
= 0;
584 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
588 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
591 struct wpas_dpp_listen_work
*lwork
;
593 if (wpa_s
->dpp_listen_work
) {
594 wpa_printf(MSG_DEBUG
,
595 "DPP: Reject start_listen since dpp_listen_work already exists");
599 if (wpa_s
->dpp_listen_freq
)
600 wpas_dpp_listen_stop(wpa_s
);
601 wpa_s
->dpp_listen_freq
= freq
;
603 lwork
= os_zalloc(sizeof(*lwork
));
608 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
610 wpas_dpp_listen_work_free(lwork
);
618 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
626 if (os_strstr(cmd
, " role=configurator"))
627 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
628 else if (os_strstr(cmd
, " role=enrollee"))
629 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
631 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
633 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
634 wpa_s
->dpp_netrole_ap
= os_strstr(cmd
, " netrole=ap") != NULL
;
635 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
636 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
641 return wpas_dpp_listen_start(wpa_s
, freq
);
645 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
647 wpa_s
->dpp_in_response_listen
= 0;
648 if (!wpa_s
->dpp_listen_freq
)
651 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
652 wpa_s
->dpp_listen_freq
);
653 wpa_drv_cancel_remain_on_channel(wpa_s
);
654 wpa_s
->dpp_listen_freq
= 0;
655 wpas_dpp_listen_work_done(wpa_s
);
659 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
662 wpas_dpp_listen_work_done(wpa_s
);
664 if (wpa_s
->dpp_auth
&& wpa_s
->dpp_in_response_listen
) {
665 unsigned int new_freq
;
667 /* Continue listen with a new remain-on-channel */
668 if (wpa_s
->dpp_auth
->neg_freq
> 0)
669 new_freq
= wpa_s
->dpp_auth
->neg_freq
;
671 new_freq
= wpa_s
->dpp_auth
->curr_freq
;
672 wpa_printf(MSG_DEBUG
,
673 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
675 wpas_dpp_listen_start(wpa_s
, new_freq
);
679 if (wpa_s
->dpp_listen_freq
) {
680 /* Continue listen with a new remain-on-channel */
681 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
686 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
687 const u8
*hdr
, const u8
*buf
, size_t len
,
690 const u8
*r_bootstrap
, *i_bootstrap
;
691 u16 r_bootstrap_len
, i_bootstrap_len
;
692 struct dpp_bootstrap_info
*own_bi
= NULL
, *peer_bi
= NULL
;
697 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
700 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
702 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
703 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
704 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
707 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
708 r_bootstrap
, r_bootstrap_len
);
710 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
712 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
713 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
714 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
717 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
718 i_bootstrap
, i_bootstrap_len
);
720 /* Try to find own and peer bootstrapping key matches based on the
721 * received hash values */
722 dpp_bootstrap_find_pair(wpa_s
->dpp
, i_bootstrap
, r_bootstrap
,
725 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
726 "No matching own bootstrapping key found - ignore message");
730 if (wpa_s
->dpp_auth
) {
731 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
732 "Already in DPP authentication exchange - ignore new one");
736 wpa_s
->dpp_gas_client
= 0;
737 wpa_s
->dpp_auth_ok_on_ack
= 0;
738 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
739 wpa_s
->dpp_qr_mutual
,
740 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
741 if (!wpa_s
->dpp_auth
) {
742 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
745 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
746 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, wpa_s
->dpp_auth
,
747 wpa_s
->dpp_configurator_params
) < 0) {
748 dpp_auth_deinit(wpa_s
->dpp_auth
);
749 wpa_s
->dpp_auth
= NULL
;
752 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
754 if (wpa_s
->dpp_listen_freq
&&
755 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
756 wpa_printf(MSG_DEBUG
,
757 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
758 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
759 wpas_dpp_listen_stop(wpa_s
);
762 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
763 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
764 DPP_PA_AUTHENTICATION_RESP
);
765 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
766 src
, wpa_s
->own_addr
, broadcast
,
767 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
768 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
769 500, wpas_dpp_tx_status
, 0);
773 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
775 /* TODO: stop wait and start ROC */
779 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
780 struct dpp_authentication
*auth
)
782 struct wpa_ssid
*ssid
;
785 if (auth
->akm
== DPP_AKM_SAE
) {
787 struct wpa_driver_capa capa
;
790 res
= wpa_drv_get_capa(wpa_s
, &capa
);
792 !(capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_SAE
) &&
793 !(wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_SAE
)) {
794 wpa_printf(MSG_DEBUG
,
795 "DPP: SAE not supported by the driver");
798 #else /* CONFIG_SAE */
799 wpa_printf(MSG_DEBUG
, "DPP: SAE not supported in the build");
801 #endif /* CONFIG_SAE */
803 #endif /* CONFIG_DPP2 */
805 ssid
= wpa_config_add_network(wpa_s
->conf
);
808 wpas_notify_network_added(wpa_s
, ssid
);
809 wpa_config_set_network_defaults(ssid
);
812 ssid
->ssid
= os_malloc(auth
->ssid_len
);
815 os_memcpy(ssid
->ssid
, auth
->ssid
, auth
->ssid_len
);
816 ssid
->ssid_len
= auth
->ssid_len
;
818 if (auth
->connector
) {
819 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
820 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_REQUIRED
;
821 ssid
->dpp_connector
= os_strdup(auth
->connector
);
822 if (!ssid
->dpp_connector
)
826 if (auth
->c_sign_key
) {
827 ssid
->dpp_csign
= os_malloc(wpabuf_len(auth
->c_sign_key
));
828 if (!ssid
->dpp_csign
)
830 os_memcpy(ssid
->dpp_csign
, wpabuf_head(auth
->c_sign_key
),
831 wpabuf_len(auth
->c_sign_key
));
832 ssid
->dpp_csign_len
= wpabuf_len(auth
->c_sign_key
);
835 if (auth
->net_access_key
) {
836 ssid
->dpp_netaccesskey
=
837 os_malloc(wpabuf_len(auth
->net_access_key
));
838 if (!ssid
->dpp_netaccesskey
)
840 os_memcpy(ssid
->dpp_netaccesskey
,
841 wpabuf_head(auth
->net_access_key
),
842 wpabuf_len(auth
->net_access_key
));
843 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
844 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
847 if (!auth
->connector
|| dpp_akm_psk(auth
->akm
) ||
848 dpp_akm_sae(auth
->akm
)) {
849 if (!auth
->connector
)
851 if (dpp_akm_psk(auth
->akm
))
852 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
853 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
854 if (dpp_akm_sae(auth
->akm
))
855 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
857 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_OPTIONAL
;
858 if (auth
->passphrase
[0]) {
859 if (wpa_config_set_quoted(ssid
, "psk",
860 auth
->passphrase
) < 0)
862 wpa_config_update_psk(ssid
);
863 ssid
->export_keys
= 1;
865 ssid
->psk_set
= auth
->psk_set
;
866 os_memcpy(ssid
->psk
, auth
->psk
, PMK_LEN
);
872 wpas_notify_network_removed(wpa_s
, ssid
);
873 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
878 static int wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
879 struct dpp_authentication
*auth
)
881 struct wpa_ssid
*ssid
;
883 if (wpa_s
->conf
->dpp_config_processing
< 1)
886 ssid
= wpas_dpp_add_network(wpa_s
, auth
);
890 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
891 if (wpa_s
->conf
->dpp_config_processing
== 2)
894 #ifndef CONFIG_NO_CONFIG_WRITE
895 if (wpa_s
->conf
->update_config
&&
896 wpa_config_write(wpa_s
->confname
, wpa_s
->conf
))
897 wpa_printf(MSG_DEBUG
, "DPP: Failed to update configuration");
898 #endif /* CONFIG_NO_CONFIG_WRITE */
900 if (wpa_s
->conf
->dpp_config_processing
< 2)
904 if (auth
->peer_version
>= 2) {
905 wpa_printf(MSG_DEBUG
,
906 "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
907 auth
->connect_on_tx_status
= 1;
910 #endif /* CONFIG_DPP2 */
912 wpas_dpp_try_to_connect(wpa_s
);
917 static int wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
918 struct dpp_authentication
*auth
)
920 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
922 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
923 wpa_ssid_txt(auth
->ssid
, auth
->ssid_len
));
924 if (auth
->connector
) {
925 /* TODO: Save the Connector and consider using a command
926 * to fetch the value instead of sending an event with
927 * it. The Connector could end up being larger than what
928 * most clients are ready to receive as an event
930 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
933 if (auth
->c_sign_key
) {
937 hexlen
= 2 * wpabuf_len(auth
->c_sign_key
) + 1;
938 hex
= os_malloc(hexlen
);
940 wpa_snprintf_hex(hex
, hexlen
,
941 wpabuf_head(auth
->c_sign_key
),
942 wpabuf_len(auth
->c_sign_key
));
943 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
948 if (auth
->net_access_key
) {
952 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
953 hex
= os_malloc(hexlen
);
955 wpa_snprintf_hex(hex
, hexlen
,
956 wpabuf_head(auth
->net_access_key
),
957 wpabuf_len(auth
->net_access_key
));
958 if (auth
->net_access_key_expiry
)
959 wpa_msg(wpa_s
, MSG_INFO
,
960 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
962 auth
->net_access_key_expiry
);
964 wpa_msg(wpa_s
, MSG_INFO
,
965 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
970 return wpas_dpp_process_config(wpa_s
, auth
);
974 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
975 enum gas_query_result result
,
976 const struct wpabuf
*adv_proto
,
977 const struct wpabuf
*resp
, u16 status_code
)
979 struct wpa_supplicant
*wpa_s
= ctx
;
981 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
983 enum dpp_status_error status
= DPP_STATUS_CONFIG_REJECTED
;
985 wpa_s
->dpp_gas_dialog_token
= -1;
987 if (!auth
|| !auth
->auth_success
) {
988 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
991 if (result
!= GAS_QUERY_SUCCESS
||
992 !resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
993 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
997 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
999 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1002 if (wpabuf_len(adv_proto
) != 10 ||
1003 !(pos
= wpabuf_head(adv_proto
)) ||
1004 pos
[0] != WLAN_EID_ADV_PROTO
||
1006 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1008 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1011 wpa_printf(MSG_DEBUG
,
1012 "DPP: Not a DPP Advertisement Protocol ID");
1016 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1017 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1021 res
= wpas_dpp_handle_config_obj(wpa_s
, auth
);
1025 status
= DPP_STATUS_OK
;
1026 #ifdef CONFIG_TESTING_OPTIONS
1027 if (dpp_test
== DPP_TEST_REJECT_CONFIG
) {
1028 wpa_printf(MSG_INFO
, "DPP: TESTING - Reject Config Object");
1029 status
= DPP_STATUS_CONFIG_REJECTED
;
1031 #endif /* CONFIG_TESTING_OPTIONS */
1033 if (status
!= DPP_STATUS_OK
)
1034 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1036 if (auth
->peer_version
>= 2 &&
1037 auth
->conf_resp_status
== DPP_STATUS_OK
) {
1040 wpa_printf(MSG_DEBUG
, "DPP: Send DPP Configuration Result");
1041 msg
= dpp_build_conf_result(auth
, status
);
1045 wpa_msg(wpa_s
, MSG_INFO
,
1046 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1047 MAC2STR(addr
), auth
->curr_freq
,
1048 DPP_PA_CONFIGURATION_RESULT
);
1049 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1050 addr
, wpa_s
->own_addr
, broadcast
,
1053 500, wpas_dpp_tx_status
, 0);
1056 /* This exchange will be terminated in the TX status handler */
1060 #endif /* CONFIG_DPP2 */
1061 dpp_auth_deinit(wpa_s
->dpp_auth
);
1062 wpa_s
->dpp_auth
= NULL
;
1066 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1068 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1069 struct wpabuf
*buf
, *conf_req
;
1073 wpa_s
->dpp_gas_client
= 1;
1074 os_snprintf(json
, sizeof(json
),
1075 "{\"name\":\"Test\","
1076 "\"wi-fi_tech\":\"infra\","
1077 "\"netRole\":\"%s\"}",
1078 wpa_s
->dpp_netrole_ap
? "ap" : "sta");
1079 #ifdef CONFIG_TESTING_OPTIONS
1080 if (dpp_test
== DPP_TEST_INVALID_CONFIG_ATTR_OBJ_CONF_REQ
) {
1081 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Config Attr");
1082 json
[29] = 'k'; /* replace "infra" with "knfra" */
1084 #endif /* CONFIG_TESTING_OPTIONS */
1085 wpa_printf(MSG_DEBUG
, "DPP: GAS Config Attributes: %s", json
);
1087 offchannel_send_action_done(wpa_s
);
1088 wpas_dpp_listen_stop(wpa_s
);
1090 conf_req
= dpp_build_conf_req(auth
, json
);
1092 wpa_printf(MSG_DEBUG
,
1093 "DPP: No configuration request data available");
1097 buf
= gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req
));
1099 wpabuf_free(conf_req
);
1103 /* Advertisement Protocol IE */
1104 wpabuf_put_u8(buf
, WLAN_EID_ADV_PROTO
);
1105 wpabuf_put_u8(buf
, 8); /* Length */
1106 wpabuf_put_u8(buf
, 0x7f);
1107 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
1108 wpabuf_put_u8(buf
, 5);
1109 wpabuf_put_be24(buf
, OUI_WFA
);
1110 wpabuf_put_u8(buf
, DPP_OUI_TYPE
);
1111 wpabuf_put_u8(buf
, 0x01);
1114 wpabuf_put_le16(buf
, wpabuf_len(conf_req
));
1115 wpabuf_put_buf(buf
, conf_req
);
1116 wpabuf_free(conf_req
);
1118 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1119 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1121 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1122 1, buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1124 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1127 wpa_printf(MSG_DEBUG
,
1128 "DPP: GAS query started with dialog token %u", res
);
1129 wpa_s
->dpp_gas_dialog_token
= res
;
1134 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1136 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1137 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1138 #ifdef CONFIG_TESTING_OPTIONS
1139 if (dpp_test
== DPP_TEST_STOP_AT_AUTH_CONF
) {
1140 wpa_printf(MSG_INFO
,
1141 "DPP: TESTING - stop at Authentication Confirm");
1142 if (wpa_s
->dpp_auth
->configurator
) {
1143 /* Prevent GAS response */
1144 wpa_s
->dpp_auth
->auth_success
= 0;
1148 #endif /* CONFIG_TESTING_OPTIONS */
1150 if (wpa_s
->dpp_auth
->configurator
)
1151 wpas_dpp_start_gas_server(wpa_s
);
1153 wpas_dpp_start_gas_client(wpa_s
);
1157 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1158 const u8
*hdr
, const u8
*buf
, size_t len
,
1161 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1164 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1165 " (freq %u MHz)", MAC2STR(src
), freq
);
1168 wpa_printf(MSG_DEBUG
,
1169 "DPP: No DPP Authentication in progress - drop");
1173 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1174 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1175 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1176 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1180 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1182 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1183 wpa_printf(MSG_DEBUG
,
1184 "DPP: Responder accepted request for different negotiation channel");
1185 auth
->curr_freq
= freq
;
1188 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1189 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1191 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1192 wpa_printf(MSG_DEBUG
,
1193 "DPP: Start wait for full response");
1194 offchannel_send_action_done(wpa_s
);
1195 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1198 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1201 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1203 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1204 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1205 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1206 src
, wpa_s
->own_addr
, broadcast
,
1207 wpabuf_head(msg
), wpabuf_len(msg
),
1208 500, wpas_dpp_tx_status
, 0);
1210 wpa_s
->dpp_auth_ok_on_ack
= 1;
1214 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1215 const u8
*hdr
, const u8
*buf
, size_t len
)
1217 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1219 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1223 wpa_printf(MSG_DEBUG
,
1224 "DPP: No DPP Authentication in progress - drop");
1228 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1229 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1230 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1234 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1235 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1239 wpas_dpp_auth_success(wpa_s
, 0);
1245 static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx
,
1248 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1249 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1251 if (!auth
|| !auth
->waiting_conf_result
)
1254 wpa_printf(MSG_DEBUG
,
1255 "DPP: Timeout while waiting for Configuration Result");
1256 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1257 dpp_auth_deinit(auth
);
1258 wpa_s
->dpp_auth
= NULL
;
1262 static void wpas_dpp_rx_conf_result(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1263 const u8
*hdr
, const u8
*buf
, size_t len
)
1265 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1266 enum dpp_status_error status
;
1268 wpa_printf(MSG_DEBUG
, "DPP: Configuration Result from " MACSTR
,
1271 if (!auth
|| !auth
->waiting_conf_result
) {
1272 wpa_printf(MSG_DEBUG
,
1273 "DPP: No DPP Configuration waiting for result - drop");
1277 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1278 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1279 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1283 status
= dpp_conf_result_rx(auth
, hdr
, buf
, len
);
1285 offchannel_send_action_done(wpa_s
);
1286 wpas_dpp_listen_stop(wpa_s
);
1287 if (status
== DPP_STATUS_OK
)
1288 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
1290 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1291 dpp_auth_deinit(auth
);
1292 wpa_s
->dpp_auth
= NULL
;
1293 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
1296 #endif /* CONFIG_DPP2 */
1299 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1301 const u8
*buf
, size_t len
)
1303 struct wpa_ssid
*ssid
;
1304 const u8
*connector
, *trans_id
, *status
;
1305 u16 connector_len
, trans_id_len
, status_len
;
1306 struct dpp_introduction intro
;
1307 struct rsn_pmksa_cache_entry
*entry
;
1309 struct os_reltime rnow
;
1311 unsigned int seconds
;
1312 enum dpp_status_error res
;
1314 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1316 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1317 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1318 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1319 MACSTR
" - drop", MAC2STR(src
));
1322 offchannel_send_action_done(wpa_s
);
1324 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1325 if (ssid
== wpa_s
->dpp_intro_network
)
1328 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1330 wpa_printf(MSG_DEBUG
,
1331 "DPP: Profile not found for network introduction");
1335 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1337 if (!trans_id
|| trans_id_len
!= 1) {
1338 wpa_printf(MSG_DEBUG
,
1339 "DPP: Peer did not include Transaction ID");
1340 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1341 " fail=missing_transaction_id", MAC2STR(src
));
1344 if (trans_id
[0] != TRANSACTION_ID
) {
1345 wpa_printf(MSG_DEBUG
,
1346 "DPP: Ignore frame with unexpected Transaction ID %u",
1348 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1349 " fail=transaction_id_mismatch", MAC2STR(src
));
1353 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1354 if (!status
|| status_len
!= 1) {
1355 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1356 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1357 " fail=missing_status", MAC2STR(src
));
1360 if (status
[0] != DPP_STATUS_OK
) {
1361 wpa_printf(MSG_DEBUG
,
1362 "DPP: Peer rejected network introduction: Status %u",
1364 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1365 " status=%u", MAC2STR(src
), status
[0]);
1369 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1371 wpa_printf(MSG_DEBUG
,
1372 "DPP: Peer did not include its Connector");
1373 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1374 " fail=missing_connector", MAC2STR(src
));
1378 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1379 ssid
->dpp_netaccesskey
,
1380 ssid
->dpp_netaccesskey_len
,
1382 ssid
->dpp_csign_len
,
1383 connector
, connector_len
, &expiry
);
1384 if (res
!= DPP_STATUS_OK
) {
1385 wpa_printf(MSG_INFO
,
1386 "DPP: Network Introduction protocol resulted in failure");
1387 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1388 " fail=peer_connector_validation_failed", MAC2STR(src
));
1392 entry
= os_zalloc(sizeof(*entry
));
1395 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1396 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1397 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1398 entry
->pmk_len
= intro
.pmk_len
;
1399 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1402 seconds
= expiry
- now
.sec
;
1404 seconds
= 86400 * 7;
1406 os_get_reltime(&rnow
);
1407 entry
->expiration
= rnow
.sec
+ seconds
;
1408 entry
->reauth_time
= rnow
.sec
+ seconds
;
1409 entry
->network_ctx
= ssid
;
1410 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1412 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1413 " status=%u", MAC2STR(src
), status
[0]);
1415 wpa_printf(MSG_DEBUG
,
1416 "DPP: Try connection again after successful network introduction");
1417 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1418 wpa_supplicant_cancel_sched_scan(wpa_s
);
1419 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1422 os_memset(&intro
, 0, sizeof(intro
));
1426 static int wpas_dpp_allow_ir(struct wpa_supplicant
*wpa_s
, unsigned int freq
)
1430 if (!wpa_s
->hw
.modes
)
1433 for (i
= 0; i
< wpa_s
->hw
.num_modes
; i
++) {
1434 struct hostapd_hw_modes
*mode
= &wpa_s
->hw
.modes
[i
];
1436 for (j
= 0; j
< mode
->num_channels
; j
++) {
1437 struct hostapd_channel_data
*chan
= &mode
->channels
[j
];
1439 if (chan
->freq
!= (int) freq
)
1442 if (chan
->flag
& (HOSTAPD_CHAN_DISABLED
|
1443 HOSTAPD_CHAN_NO_IR
|
1444 HOSTAPD_CHAN_RADAR
))
1451 wpa_printf(MSG_DEBUG
,
1452 "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
1459 static int wpas_dpp_pkex_next_channel(struct wpa_supplicant
*wpa_s
,
1460 struct dpp_pkex
*pkex
)
1462 if (pkex
->freq
== 2437)
1464 else if (pkex
->freq
== 5745)
1466 else if (pkex
->freq
== 5220)
1469 return -1; /* no more channels to try */
1471 if (wpas_dpp_allow_ir(wpa_s
, pkex
->freq
) == 1) {
1472 wpa_printf(MSG_DEBUG
, "DPP: Try to initiate on %u MHz",
1477 /* Could not use this channel - try the next one */
1478 return wpas_dpp_pkex_next_channel(wpa_s
, pkex
);
1482 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1484 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1485 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1487 if (!pkex
|| !pkex
->exchange_req
)
1489 if (pkex
->exch_req_tries
>= 5) {
1490 if (wpas_dpp_pkex_next_channel(wpa_s
, pkex
) < 0) {
1491 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1492 "No response from PKEX peer");
1493 dpp_pkex_free(pkex
);
1494 wpa_s
->dpp_pkex
= NULL
;
1497 pkex
->exch_req_tries
= 0;
1500 pkex
->exch_req_tries
++;
1501 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1502 pkex
->exch_req_tries
);
1503 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1504 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1505 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1506 wpa_s
->own_addr
, broadcast
,
1507 wpabuf_head(pkex
->exchange_req
),
1508 wpabuf_len(pkex
->exchange_req
),
1509 pkex
->exch_req_wait_time
,
1510 wpas_dpp_tx_pkex_status
, 0);
1515 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1516 unsigned int freq
, const u8
*dst
,
1517 const u8
*src
, const u8
*bssid
,
1518 const u8
*data
, size_t data_len
,
1519 enum offchannel_send_action_result result
)
1521 const char *res_txt
;
1522 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1524 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1525 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1527 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1528 " result=%s (PKEX)",
1529 freq
, MAC2STR(dst
), res_txt
);
1530 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1531 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1534 wpa_printf(MSG_DEBUG
,
1535 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1540 wpa_printf(MSG_DEBUG
,
1541 "DPP: Terminate PKEX exchange due to an earlier error");
1542 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1543 pkex
->own_bi
->pkex_t
= pkex
->t
;
1544 dpp_pkex_free(pkex
);
1545 wpa_s
->dpp_pkex
= NULL
;
1549 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1550 /* Wait for PKEX Exchange Response frame and retry request if
1551 * no response is seen. */
1552 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1553 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1554 (pkex
->exch_req_wait_time
% 1000) * 1000,
1555 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1562 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1563 const u8
*buf
, size_t len
, unsigned int freq
)
1566 unsigned int wait_time
;
1568 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1571 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1574 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1575 wpa_printf(MSG_DEBUG
,
1576 "DPP: No PKEX code configured - ignore request");
1580 if (wpa_s
->dpp_pkex
) {
1581 /* TODO: Support parallel operations */
1582 wpa_printf(MSG_DEBUG
,
1583 "DPP: Already in PKEX session - ignore new request");
1587 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1588 wpa_s
->own_addr
, src
,
1589 wpa_s
->dpp_pkex_identifier
,
1590 wpa_s
->dpp_pkex_code
,
1592 if (!wpa_s
->dpp_pkex
) {
1593 wpa_printf(MSG_DEBUG
,
1594 "DPP: Failed to process the request - ignore it");
1598 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1599 wait_time
= wpa_s
->max_remain_on_chan
;
1600 if (wait_time
> 2000)
1602 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1603 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1604 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1606 wpabuf_head(msg
), wpabuf_len(msg
),
1607 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1612 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1613 const u8
*buf
, size_t len
, unsigned int freq
)
1616 unsigned int wait_time
;
1618 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1621 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1624 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1625 wpa_s
->dpp_pkex
->exchange_done
) {
1626 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1630 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1631 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
1633 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, src
, buf
, len
);
1635 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1639 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1642 wait_time
= wpa_s
->max_remain_on_chan
;
1643 if (wait_time
> 2000)
1645 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1646 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1647 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1649 wpabuf_head(msg
), wpabuf_len(msg
),
1650 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1655 static struct dpp_bootstrap_info
*
1656 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
1659 struct dpp_bootstrap_info
*bi
;
1661 bi
= dpp_pkex_finish(wpa_s
->dpp
, wpa_s
->dpp_pkex
, peer
, freq
);
1664 wpa_s
->dpp_pkex
= NULL
;
1670 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1671 const u8
*hdr
, const u8
*buf
, size_t len
,
1675 unsigned int wait_time
;
1676 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1678 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1681 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1682 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1686 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1688 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1690 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
1691 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1692 pkex
->own_bi
->pkex_t
= pkex
->t
;
1693 dpp_pkex_free(wpa_s
->dpp_pkex
);
1694 wpa_s
->dpp_pkex
= NULL
;
1699 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1700 MACSTR
, MAC2STR(src
));
1702 wait_time
= wpa_s
->max_remain_on_chan
;
1703 if (wait_time
> 2000)
1705 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1706 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
1707 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1709 wpabuf_head(msg
), wpabuf_len(msg
),
1710 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1713 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1718 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1719 const u8
*hdr
, const u8
*buf
, size_t len
,
1723 struct dpp_bootstrap_info
*bi
;
1724 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1727 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
1730 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
1731 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1735 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
1737 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1741 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1745 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
1747 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
1748 wpa_printf(MSG_DEBUG
,
1749 "DPP: Start authentication after PKEX with parameters: %s",
1751 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
1752 wpa_printf(MSG_DEBUG
,
1753 "DPP: Authentication initialization failed");
1759 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1760 const u8
*buf
, size_t len
, unsigned int freq
)
1763 enum dpp_public_action_frame_type type
;
1765 unsigned int pkex_t
;
1767 if (len
< DPP_HDR_LEN
)
1769 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
1774 crypto_suite
= *buf
++;
1778 wpa_printf(MSG_DEBUG
,
1779 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1781 crypto_suite
, type
, MAC2STR(src
), freq
);
1782 if (crypto_suite
!= 1) {
1783 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
1785 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1786 " freq=%u type=%d ignore=unsupported-crypto-suite",
1787 MAC2STR(src
), freq
, type
);
1790 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
1791 if (dpp_check_attrs(buf
, len
) < 0) {
1792 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1793 " freq=%u type=%d ignore=invalid-attributes",
1794 MAC2STR(src
), freq
, type
);
1797 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
1798 MAC2STR(src
), freq
, type
);
1801 case DPP_PA_AUTHENTICATION_REQ
:
1802 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
1804 case DPP_PA_AUTHENTICATION_RESP
:
1805 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
1807 case DPP_PA_AUTHENTICATION_CONF
:
1808 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
1810 case DPP_PA_PEER_DISCOVERY_RESP
:
1811 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
1813 case DPP_PA_PKEX_EXCHANGE_REQ
:
1814 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
1816 case DPP_PA_PKEX_EXCHANGE_RESP
:
1817 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
1819 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
1820 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
1823 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
1824 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
1828 case DPP_PA_CONFIGURATION_RESULT
:
1829 wpas_dpp_rx_conf_result(wpa_s
, src
, hdr
, buf
, len
);
1831 #endif /* CONFIG_DPP2 */
1833 wpa_printf(MSG_DEBUG
,
1834 "DPP: Ignored unsupported frame subtype %d", type
);
1838 if (wpa_s
->dpp_pkex
)
1839 pkex_t
= wpa_s
->dpp_pkex
->t
;
1840 else if (wpa_s
->dpp_pkex_bi
)
1841 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
1844 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
1845 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
1846 wpas_dpp_pkex_remove(wpa_s
, "*");
1851 static struct wpabuf
*
1852 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
1855 struct wpa_supplicant
*wpa_s
= ctx
;
1856 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1857 struct wpabuf
*resp
;
1859 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
1861 if (!auth
|| !auth
->auth_success
||
1862 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1863 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1866 wpa_hexdump(MSG_DEBUG
,
1867 "DPP: Received Configuration Request (GAS Query Request)",
1869 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_REQ_RX
"src=" MACSTR
,
1871 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
1873 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1874 auth
->conf_resp
= resp
;
1880 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
1882 struct wpa_supplicant
*wpa_s
= ctx
;
1883 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1889 if (auth
->conf_resp
!= resp
) {
1890 wpa_printf(MSG_DEBUG
,
1891 "DPP: Ignore GAS status report (ok=%d) for unknown response",
1897 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
1899 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1900 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
1902 if (ok
&& auth
->peer_version
>= 2 &&
1903 auth
->conf_resp_status
== DPP_STATUS_OK
) {
1904 wpa_printf(MSG_DEBUG
, "DPP: Wait for Configuration Result");
1905 auth
->waiting_conf_result
= 1;
1906 auth
->conf_resp
= NULL
;
1908 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
1910 eloop_register_timeout(2, 0,
1911 wpas_dpp_config_result_wait_timeout
,
1915 #endif /* CONFIG_DPP2 */
1916 offchannel_send_action_done(wpa_s
);
1917 wpas_dpp_listen_stop(wpa_s
);
1919 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
1921 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1922 dpp_auth_deinit(wpa_s
->dpp_auth
);
1923 wpa_s
->dpp_auth
= NULL
;
1928 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
1930 struct dpp_authentication
*auth
;
1934 auth
= os_zalloc(sizeof(*auth
));
1938 curve
= get_param(cmd
, " curve=");
1939 wpas_dpp_set_testing_options(wpa_s
, auth
);
1940 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, auth
, cmd
) == 0 &&
1941 dpp_configurator_own_config(auth
, curve
, 0) == 0)
1942 ret
= wpas_dpp_handle_config_obj(wpa_s
, auth
);
1944 dpp_auth_deinit(auth
);
1952 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
1953 unsigned int freq
, const u8
*dst
,
1954 const u8
*src
, const u8
*bssid
,
1955 const u8
*data
, size_t data_len
,
1956 enum offchannel_send_action_result result
)
1958 const char *res_txt
;
1960 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1961 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1963 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1964 " result=%s (DPP Peer Discovery Request)",
1965 freq
, MAC2STR(dst
), res_txt
);
1966 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1967 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1968 /* TODO: Time out wait for response more quickly in error cases? */
1972 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
1973 struct wpa_bss
*bss
)
1977 unsigned int wait_time
;
1979 struct wpa_ie_data ied
;
1981 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
1982 return 0; /* Not using DPP AKM - continue */
1983 rsn
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
1984 if (rsn
&& wpa_parse_wpa_ie(rsn
, 2 + rsn
[1], &ied
) == 0 &&
1985 !(ied
.key_mgmt
& WPA_KEY_MGMT_DPP
))
1986 return 0; /* AP does not support DPP AKM - continue */
1987 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
1988 return 0; /* PMKSA exists for DPP AKM - continue */
1990 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1992 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
1994 !ssid
->dpp_connector
? "Connector" :
1995 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2002 if (ssid
->dpp_netaccesskey_expiry
&&
2003 (os_time_t
) ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2004 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2005 "netAccessKey expired");
2009 wpa_printf(MSG_DEBUG
,
2010 "DPP: Starting network introduction protocol to derive PMKSA for "
2011 MACSTR
, MAC2STR(bss
->bssid
));
2013 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2014 5 + 4 + os_strlen(ssid
->dpp_connector
));
2018 #ifdef CONFIG_TESTING_OPTIONS
2019 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2020 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2023 if (dpp_test
== DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_REQ
) {
2024 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Transaction ID");
2025 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2026 wpabuf_put_le16(msg
, 0);
2029 #endif /* CONFIG_TESTING_OPTIONS */
2031 /* Transaction ID */
2032 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2033 wpabuf_put_le16(msg
, 1);
2034 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2036 #ifdef CONFIG_TESTING_OPTIONS
2038 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2039 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2040 goto skip_connector
;
2042 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2045 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2046 connector
= dpp_corrupt_connector_signature(
2047 ssid
->dpp_connector
);
2052 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2053 wpabuf_put_le16(msg
, os_strlen(connector
));
2054 wpabuf_put_str(msg
, connector
);
2056 goto skip_connector
;
2058 #endif /* CONFIG_TESTING_OPTIONS */
2061 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2062 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2063 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2065 #ifdef CONFIG_TESTING_OPTIONS
2067 #endif /* CONFIG_TESTING_OPTIONS */
2069 /* TODO: Timeout on AP response */
2070 wait_time
= wpa_s
->max_remain_on_chan
;
2071 if (wait_time
> 2000)
2073 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2074 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2075 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2077 wpabuf_head(msg
), wpabuf_len(msg
),
2078 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2081 /* Request this connection attempt to terminate - new one will be
2082 * started when network introduction protocol completes */
2083 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2084 wpa_s
->dpp_intro_network
= ssid
;
2089 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2091 struct dpp_bootstrap_info
*own_bi
;
2092 const char *pos
, *end
;
2093 unsigned int wait_time
;
2095 pos
= os_strstr(cmd
, " own=");
2099 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
2101 wpa_printf(MSG_DEBUG
,
2102 "DPP: Identified bootstrap info not found");
2105 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2106 wpa_printf(MSG_DEBUG
,
2107 "DPP: Identified bootstrap info not for PKEX");
2110 wpa_s
->dpp_pkex_bi
= own_bi
;
2111 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2113 os_free(wpa_s
->dpp_pkex_identifier
);
2114 wpa_s
->dpp_pkex_identifier
= NULL
;
2115 pos
= os_strstr(cmd
, " identifier=");
2118 end
= os_strchr(pos
, ' ');
2121 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2122 if (!wpa_s
->dpp_pkex_identifier
)
2124 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2125 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2128 pos
= os_strstr(cmd
, " code=");
2131 os_free(wpa_s
->dpp_pkex_code
);
2132 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2133 if (!wpa_s
->dpp_pkex_code
)
2136 if (os_strstr(cmd
, " init=1")) {
2137 struct dpp_pkex
*pkex
;
2140 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2141 dpp_pkex_free(wpa_s
->dpp_pkex
);
2142 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2143 wpa_s
->dpp_pkex_identifier
,
2144 wpa_s
->dpp_pkex_code
);
2145 pkex
= wpa_s
->dpp_pkex
;
2149 msg
= pkex
->exchange_req
;
2150 wait_time
= wpa_s
->max_remain_on_chan
;
2151 if (wait_time
> 2000)
2154 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2156 MAC2STR(broadcast
), pkex
->freq
,
2157 DPP_PA_PKEX_EXCHANGE_REQ
);
2158 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2159 wpa_s
->own_addr
, broadcast
,
2160 wpabuf_head(msg
), wpabuf_len(msg
),
2161 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2164 pkex
->exch_req_wait_time
= wait_time
;
2165 pkex
->exch_req_tries
= 1;
2168 /* TODO: Support multiple PKEX info entries */
2170 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2171 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2177 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2179 unsigned int id_val
;
2181 if (os_strcmp(id
, "*") == 0) {
2189 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2192 /* TODO: Support multiple PKEX entries */
2193 os_free(wpa_s
->dpp_pkex_code
);
2194 wpa_s
->dpp_pkex_code
= NULL
;
2195 os_free(wpa_s
->dpp_pkex_identifier
);
2196 wpa_s
->dpp_pkex_identifier
= NULL
;
2197 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2198 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2199 wpa_s
->dpp_pkex_bi
= NULL
;
2200 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2201 dpp_pkex_free(wpa_s
->dpp_pkex
);
2202 wpa_s
->dpp_pkex
= NULL
;
2207 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2209 dpp_auth_deinit(wpa_s
->dpp_auth
);
2210 wpa_s
->dpp_auth
= NULL
;
2211 dpp_pkex_free(wpa_s
->dpp_pkex
);
2212 wpa_s
->dpp_pkex
= NULL
;
2213 if (wpa_s
->dpp_gas_client
&& wpa_s
->dpp_gas_dialog_token
>= 0)
2214 gas_query_stop(wpa_s
->gas
, wpa_s
->dpp_gas_dialog_token
);
2218 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2222 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2223 adv_proto_id
[1] = 5;
2224 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2225 adv_proto_id
[5] = DPP_OUI_TYPE
;
2226 adv_proto_id
[6] = 0x01;
2228 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2229 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2230 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2232 wpa_s
->dpp
= dpp_global_init();
2233 return wpa_s
->dpp
? 0 : -1;
2237 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2239 #ifdef CONFIG_TESTING_OPTIONS
2240 os_free(wpa_s
->dpp_config_obj_override
);
2241 wpa_s
->dpp_config_obj_override
= NULL
;
2242 os_free(wpa_s
->dpp_discovery_override
);
2243 wpa_s
->dpp_discovery_override
= NULL
;
2244 os_free(wpa_s
->dpp_groups_override
);
2245 wpa_s
->dpp_groups_override
= NULL
;
2246 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2247 #endif /* CONFIG_TESTING_OPTIONS */
2250 dpp_global_clear(wpa_s
->dpp
);
2251 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2252 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2253 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2254 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2256 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
2257 dpp_pfs_free(wpa_s
->dpp_pfs
);
2258 wpa_s
->dpp_pfs
= NULL
;
2259 #endif /* CONFIG_DPP2 */
2260 offchannel_send_action_done(wpa_s
);
2261 wpas_dpp_listen_stop(wpa_s
);
2262 wpas_dpp_stop(wpa_s
);
2263 wpas_dpp_pkex_remove(wpa_s
, "*");
2264 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2265 os_free(wpa_s
->dpp_configurator_params
);
2266 wpa_s
->dpp_configurator_params
= NULL
;