3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/dpp.h"
14 #include "common/gas.h"
15 #include "common/gas_server.h"
16 #include "rsn_supp/wpa.h"
17 #include "rsn_supp/pmksa_cache.h"
18 #include "wpa_supplicant_i.h"
21 #include "offchannel.h"
22 #include "gas_query.h"
26 #include "dpp_supplicant.h"
29 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
31 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
);
32 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
);
33 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
34 unsigned int freq
, const u8
*dst
,
35 const u8
*src
, const u8
*bssid
,
36 const u8
*data
, size_t data_len
,
37 enum offchannel_send_action_result result
);
38 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
);
39 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
);
41 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
42 unsigned int freq
, const u8
*dst
,
43 const u8
*src
, const u8
*bssid
,
44 const u8
*data
, size_t data_len
,
45 enum offchannel_send_action_result result
);
47 static const u8 broadcast
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
49 /* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only
50 * a single transaction in progress at any point in time. */
51 static const u8 TRANSACTION_ID
= 1;
54 static struct dpp_configurator
*
55 dpp_configurator_get_id(struct wpa_supplicant
*wpa_s
, unsigned int id
)
57 struct dpp_configurator
*conf
;
59 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
60 struct dpp_configurator
, list
) {
68 static unsigned int wpas_dpp_next_id(struct wpa_supplicant
*wpa_s
)
70 struct dpp_bootstrap_info
*bi
;
71 unsigned int max_id
= 0;
73 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
83 * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
84 * @wpa_s: Pointer to wpa_supplicant data
85 * @cmd: DPP URI read from a QR Code
86 * Returns: Identifier of the stored info or -1 on failure
88 int wpas_dpp_qr_code(struct wpa_supplicant
*wpa_s
, const char *cmd
)
90 struct dpp_bootstrap_info
*bi
;
91 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
93 bi
= dpp_parse_qr_code(cmd
);
97 bi
->id
= wpas_dpp_next_id(wpa_s
);
98 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
100 if (auth
&& auth
->response_pending
&&
101 dpp_notify_new_qr_code(auth
, bi
) == 1) {
102 wpa_printf(MSG_DEBUG
,
103 "DPP: Sending out pending authentication response");
104 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
106 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
107 DPP_PA_AUTHENTICATION_RESP
);
108 offchannel_send_action(wpa_s
, auth
->curr_freq
,
109 auth
->peer_mac_addr
, wpa_s
->own_addr
,
111 wpabuf_head(auth
->resp_msg
),
112 wpabuf_len(auth
->resp_msg
),
113 500, wpas_dpp_tx_status
, 0);
120 static char * get_param(const char *cmd
, const char *param
)
122 const char *pos
, *end
;
126 pos
= os_strstr(cmd
, param
);
130 pos
+= os_strlen(param
);
131 end
= os_strchr(pos
, ' ');
135 len
= os_strlen(pos
);
136 val
= os_malloc(len
+ 1);
139 os_memcpy(val
, pos
, len
);
145 int wpas_dpp_bootstrap_gen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
147 char *chan
= NULL
, *mac
= NULL
, *info
= NULL
, *pk
= NULL
, *curve
= NULL
;
150 size_t privkey_len
= 0;
153 struct dpp_bootstrap_info
*bi
;
155 bi
= os_zalloc(sizeof(*bi
));
159 if (os_strstr(cmd
, "type=qrcode"))
160 bi
->type
= DPP_BOOTSTRAP_QR_CODE
;
161 else if (os_strstr(cmd
, "type=pkex"))
162 bi
->type
= DPP_BOOTSTRAP_PKEX
;
166 chan
= get_param(cmd
, " chan=");
167 mac
= get_param(cmd
, " mac=");
168 info
= get_param(cmd
, " info=");
169 curve
= get_param(cmd
, " curve=");
170 key
= get_param(cmd
, " key=");
173 privkey_len
= os_strlen(key
) / 2;
174 privkey
= os_malloc(privkey_len
);
176 hexstr2bin(key
, privkey
, privkey_len
) < 0)
180 pk
= dpp_keygen(bi
, curve
, privkey
, privkey_len
);
184 len
= 4; /* "DPP:" */
186 if (dpp_parse_uri_chan_list(bi
, chan
) < 0)
188 len
+= 3 + os_strlen(chan
); /* C:...; */
191 if (dpp_parse_uri_mac(bi
, mac
) < 0)
193 len
+= 3 + os_strlen(mac
); /* M:...; */
196 if (dpp_parse_uri_info(bi
, info
) < 0)
198 len
+= 3 + os_strlen(info
); /* I:...; */
200 len
+= 4 + os_strlen(pk
);
201 bi
->uri
= os_malloc(len
+ 1);
204 os_snprintf(bi
->uri
, len
+ 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
205 chan
? "C:" : "", chan
? chan
: "", chan
? ";" : "",
206 mac
? "M:" : "", mac
? mac
: "", mac
? ";" : "",
207 info
? "I:" : "", info
? info
: "", info
? ";" : "",
209 bi
->id
= wpas_dpp_next_id(wpa_s
);
210 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
220 bin_clear_free(privkey
, privkey_len
);
221 dpp_bootstrap_info_free(bi
);
226 static struct dpp_bootstrap_info
*
227 dpp_bootstrap_get_id(struct wpa_supplicant
*wpa_s
, unsigned int id
)
229 struct dpp_bootstrap_info
*bi
;
231 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
240 static int dpp_bootstrap_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
242 struct dpp_bootstrap_info
*bi
, *tmp
;
245 dl_list_for_each_safe(bi
, tmp
, &wpa_s
->dpp_bootstrap
,
246 struct dpp_bootstrap_info
, list
) {
247 if (id
&& bi
->id
!= id
)
250 dl_list_del(&bi
->list
);
251 dpp_bootstrap_info_free(bi
);
255 return 0; /* flush succeeds regardless of entries found */
256 return found
? 0 : -1;
260 int wpas_dpp_bootstrap_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
264 if (os_strcmp(id
, "*") == 0) {
272 return dpp_bootstrap_del(wpa_s
, id_val
);
276 const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant
*wpa_s
,
279 struct dpp_bootstrap_info
*bi
;
281 bi
= dpp_bootstrap_get_id(wpa_s
, id
);
288 int wpas_dpp_bootstrap_info(struct wpa_supplicant
*wpa_s
, int id
,
289 char *reply
, int reply_size
)
291 struct dpp_bootstrap_info
*bi
;
293 bi
= dpp_bootstrap_get_id(wpa_s
, id
);
296 return os_snprintf(reply
, reply_size
, "type=%s\n"
297 "mac_addr=" MACSTR
"\n"
301 dpp_bootstrap_type_txt(bi
->type
),
302 MAC2STR(bi
->mac_addr
),
303 bi
->info
? bi
->info
: "",
309 static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
311 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
312 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
314 if (!auth
|| !auth
->resp_msg
)
317 wpa_printf(MSG_DEBUG
,
318 "DPP: Retry Authentication Response after timeout");
319 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
321 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
322 DPP_PA_AUTHENTICATION_RESP
);
323 offchannel_send_action(wpa_s
, auth
->curr_freq
, auth
->peer_mac_addr
,
324 wpa_s
->own_addr
, broadcast
,
325 wpabuf_head(auth
->resp_msg
),
326 wpabuf_len(auth
->resp_msg
),
327 500, wpas_dpp_tx_status
, 0);
331 static void wpas_dpp_auth_resp_retry(struct wpa_supplicant
*wpa_s
)
333 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
334 unsigned int wait_time
, max_tries
;
336 if (!auth
|| !auth
->resp_msg
)
339 if (wpa_s
->dpp_resp_max_tries
)
340 max_tries
= wpa_s
->dpp_resp_max_tries
;
343 auth
->auth_resp_tries
++;
344 if (auth
->auth_resp_tries
>= max_tries
) {
345 wpa_printf(MSG_INFO
, "DPP: No confirm received from initiator - stopping exchange");
346 offchannel_send_action_done(wpa_s
);
347 dpp_auth_deinit(wpa_s
->dpp_auth
);
348 wpa_s
->dpp_auth
= NULL
;
352 if (wpa_s
->dpp_resp_retry_time
)
353 wait_time
= wpa_s
->dpp_resp_retry_time
;
356 wpa_printf(MSG_DEBUG
,
357 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
359 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
360 eloop_register_timeout(wait_time
/ 1000,
361 (wait_time
% 1000) * 1000,
362 wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
366 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
367 unsigned int freq
, const u8
*dst
,
368 const u8
*src
, const u8
*bssid
,
369 const u8
*data
, size_t data_len
,
370 enum offchannel_send_action_result result
)
373 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
375 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
376 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
378 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
379 " result=%s", freq
, MAC2STR(dst
), res_txt
);
380 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
381 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
383 if (!wpa_s
->dpp_auth
) {
384 wpa_printf(MSG_DEBUG
,
385 "DPP: Ignore TX status since there is no ongoing authentication exchange");
389 if (wpa_s
->dpp_auth
->remove_on_tx_status
) {
390 wpa_printf(MSG_DEBUG
,
391 "DPP: Terminate authentication exchange due to an earlier error");
392 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
393 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
394 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
396 offchannel_send_action_done(wpa_s
);
397 dpp_auth_deinit(wpa_s
->dpp_auth
);
398 wpa_s
->dpp_auth
= NULL
;
402 if (wpa_s
->dpp_auth_ok_on_ack
)
403 wpas_dpp_auth_success(wpa_s
, 1);
405 if (!is_broadcast_ether_addr(dst
) &&
406 result
!= OFFCHANNEL_SEND_ACTION_SUCCESS
) {
407 wpa_printf(MSG_DEBUG
,
408 "DPP: Unicast DPP Action frame was not ACKed");
409 if (auth
->waiting_auth_resp
) {
410 /* In case of DPP Authentication Request frame, move to
411 * the next channel immediately. */
412 offchannel_send_action_done(wpa_s
);
413 wpas_dpp_auth_init_next(wpa_s
);
416 if (auth
->waiting_auth_conf
) {
417 wpas_dpp_auth_resp_retry(wpa_s
);
422 if (!is_broadcast_ether_addr(dst
) && auth
->waiting_auth_resp
&&
423 result
== OFFCHANNEL_SEND_ACTION_SUCCESS
) {
424 /* Allow timeout handling to stop iteration if no response is
425 * received from a peer that has ACKed a request. */
426 auth
->auth_req_ack
= 1;
429 if (!wpa_s
->dpp_auth_ok_on_ack
&& wpa_s
->dpp_auth
->neg_freq
> 0 &&
430 wpa_s
->dpp_auth
->curr_freq
!= wpa_s
->dpp_auth
->neg_freq
) {
431 wpa_printf(MSG_DEBUG
,
432 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
433 wpa_s
->dpp_auth
->curr_freq
,
434 wpa_s
->dpp_auth
->neg_freq
);
435 offchannel_send_action_done(wpa_s
);
436 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->neg_freq
);
439 if (wpa_s
->dpp_auth_ok_on_ack
)
440 wpa_s
->dpp_auth_ok_on_ack
= 0;
444 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
446 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
447 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
449 struct os_reltime now
, diff
;
450 unsigned int wait_time
, diff_ms
;
452 if (!auth
|| !auth
->waiting_auth_resp
)
455 wait_time
= wpa_s
->dpp_resp_wait_time
?
456 wpa_s
->dpp_resp_wait_time
: 2000;
457 os_get_reltime(&now
);
458 os_reltime_sub(&now
, &wpa_s
->dpp_last_init
, &diff
);
459 diff_ms
= diff
.sec
* 1000 + diff
.usec
/ 1000;
460 wpa_printf(MSG_DEBUG
,
461 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
464 if (auth
->auth_req_ack
&& diff_ms
>= wait_time
) {
465 /* Peer ACK'ed Authentication Request frame, but did not reply
466 * with Authentication Response frame within two seconds. */
468 "DPP: No response received from responder - stopping initiation attempt");
469 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
470 offchannel_send_action_done(wpa_s
);
471 wpas_dpp_listen_stop(wpa_s
);
472 dpp_auth_deinit(auth
);
473 wpa_s
->dpp_auth
= NULL
;
477 if (diff_ms
>= wait_time
) {
478 /* Authentication Request frame was not ACK'ed and no reply
479 * was receiving within two seconds. */
480 wpa_printf(MSG_DEBUG
,
481 "DPP: Continue Initiator channel iteration");
482 offchannel_send_action_done(wpa_s
);
483 wpas_dpp_listen_stop(wpa_s
);
484 wpas_dpp_auth_init_next(wpa_s
);
488 /* Driver did not support 2000 ms long wait_time with TX command, so
489 * schedule listen operation to continue waiting for the response.
491 * DPP listen operations continue until stopped, so simply schedule a
492 * new call to this function at the point when the two second reply
493 * wait has expired. */
494 wait_time
-= diff_ms
;
496 freq
= auth
->curr_freq
;
497 if (auth
->neg_freq
> 0)
498 freq
= auth
->neg_freq
;
499 wpa_printf(MSG_DEBUG
,
500 "DPP: Continue reply wait on channel %u MHz for %u ms",
502 wpa_s
->dpp_in_response_listen
= 1;
503 wpas_dpp_listen_start(wpa_s
, freq
);
505 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
506 wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
510 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
511 struct dpp_authentication
*auth
)
513 #ifdef CONFIG_TESTING_OPTIONS
514 if (wpa_s
->dpp_config_obj_override
)
515 auth
->config_obj_override
=
516 os_strdup(wpa_s
->dpp_config_obj_override
);
517 if (wpa_s
->dpp_discovery_override
)
518 auth
->discovery_override
=
519 os_strdup(wpa_s
->dpp_discovery_override
);
520 if (wpa_s
->dpp_groups_override
)
521 auth
->groups_override
=
522 os_strdup(wpa_s
->dpp_groups_override
);
523 auth
->ignore_netaccesskey_mismatch
=
524 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
525 #endif /* CONFIG_TESTING_OPTIONS */
529 static void wpas_dpp_set_configurator(struct wpa_supplicant
*wpa_s
,
530 struct dpp_authentication
*auth
,
533 const char *pos
, *end
;
534 struct dpp_configuration
*conf_sta
= NULL
, *conf_ap
= NULL
;
535 struct dpp_configurator
*conf
= NULL
;
536 u8 ssid
[32] = { "test" };
546 wpa_printf(MSG_DEBUG
, "DPP: Set configurator parameters: %s", cmd
);
547 pos
= os_strstr(cmd
, " ssid=");
550 end
= os_strchr(pos
, ' ');
551 ssid_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
553 if (ssid_len
> sizeof(ssid
) ||
554 hexstr2bin(pos
, ssid
, ssid_len
) < 0)
558 pos
= os_strstr(cmd
, " pass=");
561 end
= os_strchr(pos
, ' ');
562 pass_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
564 if (pass_len
> sizeof(pass
) - 1 || pass_len
< 8 ||
565 hexstr2bin(pos
, (u8
*) pass
, pass_len
) < 0)
569 pos
= os_strstr(cmd
, " psk=");
572 if (hexstr2bin(pos
, psk
, PMK_LEN
) < 0)
577 if (os_strstr(cmd
, " conf=sta-")) {
578 conf_sta
= os_zalloc(sizeof(struct dpp_configuration
));
581 os_memcpy(conf_sta
->ssid
, ssid
, ssid_len
);
582 conf_sta
->ssid_len
= ssid_len
;
583 if (os_strstr(cmd
, " conf=sta-psk") ||
584 os_strstr(cmd
, " conf=sta-sae") ||
585 os_strstr(cmd
, " conf=sta-psk-sae")) {
586 if (os_strstr(cmd
, " conf=sta-psk-sae"))
587 conf_sta
->akm
= DPP_AKM_PSK_SAE
;
588 else if (os_strstr(cmd
, " conf=sta-sae"))
589 conf_sta
->akm
= DPP_AKM_SAE
;
591 conf_sta
->akm
= DPP_AKM_PSK
;
593 os_memcpy(conf_sta
->psk
, psk
, PMK_LEN
);
595 conf_sta
->passphrase
= os_strdup(pass
);
596 if (!conf_sta
->passphrase
)
599 } else if (os_strstr(cmd
, " conf=sta-dpp")) {
600 conf_sta
->akm
= DPP_AKM_DPP
;
606 if (os_strstr(cmd
, " conf=ap-")) {
607 conf_ap
= os_zalloc(sizeof(struct dpp_configuration
));
610 os_memcpy(conf_ap
->ssid
, ssid
, ssid_len
);
611 conf_ap
->ssid_len
= ssid_len
;
612 if (os_strstr(cmd
, " conf=ap-psk") ||
613 os_strstr(cmd
, " conf=ap-sae") ||
614 os_strstr(cmd
, " conf=ap-psk-sae")) {
615 if (os_strstr(cmd
, " conf=ap-psk-sae"))
616 conf_ap
->akm
= DPP_AKM_PSK_SAE
;
617 else if (os_strstr(cmd
, " conf=ap-sae"))
618 conf_ap
->akm
= DPP_AKM_SAE
;
620 conf_ap
->akm
= DPP_AKM_PSK
;
622 os_memcpy(conf_ap
->psk
, psk
, PMK_LEN
);
624 conf_ap
->passphrase
= os_strdup(pass
);
625 if (!conf_ap
->passphrase
)
628 } else if (os_strstr(cmd
, " conf=ap-dpp")) {
629 conf_ap
->akm
= DPP_AKM_DPP
;
635 pos
= os_strstr(cmd
, " expiry=");
640 val
= strtol(pos
, NULL
, 0);
644 conf_sta
->netaccesskey_expiry
= val
;
646 conf_ap
->netaccesskey_expiry
= val
;
649 pos
= os_strstr(cmd
, " configurator=");
652 conf
= dpp_configurator_get_id(wpa_s
, atoi(pos
));
655 "DPP: Could not find the specified configurator");
659 auth
->conf_sta
= conf_sta
;
660 auth
->conf_ap
= conf_ap
;
665 wpa_printf(MSG_DEBUG
, "DPP: Failed to set configurator parameters");
666 dpp_configuration_free(conf_sta
);
667 dpp_configuration_free(conf_ap
);
671 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
673 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
675 if (!wpa_s
->dpp_auth
)
677 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
678 wpas_dpp_auth_init_next(wpa_s
);
682 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
684 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
686 unsigned int wait_time
, max_wait_time
, freq
, max_tries
, used
;
687 struct os_reltime now
, diff
;
689 wpa_s
->dpp_in_response_listen
= 0;
693 if (auth
->freq_idx
== 0)
694 os_get_reltime(&wpa_s
->dpp_init_iter_start
);
696 if (auth
->freq_idx
>= auth
->num_freq
) {
697 auth
->num_freq_iters
++;
698 if (wpa_s
->dpp_init_max_tries
)
699 max_tries
= wpa_s
->dpp_init_max_tries
;
702 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
704 "DPP: No response received from responder - stopping initiation attempt");
705 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
706 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
708 offchannel_send_action_done(wpa_s
);
709 dpp_auth_deinit(wpa_s
->dpp_auth
);
710 wpa_s
->dpp_auth
= NULL
;
714 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
715 if (wpa_s
->dpp_init_retry_time
)
716 wait_time
= wpa_s
->dpp_init_retry_time
;
719 os_get_reltime(&now
);
720 os_reltime_sub(&now
, &wpa_s
->dpp_init_iter_start
, &diff
);
721 used
= diff
.sec
* 1000 + diff
.usec
/ 1000;
722 if (used
> wait_time
)
726 wpa_printf(MSG_DEBUG
, "DPP: Next init attempt in %u ms",
728 eloop_register_timeout(wait_time
/ 1000,
729 (wait_time
% 1000) * 1000,
730 wpas_dpp_init_timeout
, wpa_s
,
734 freq
= auth
->freq
[auth
->freq_idx
++];
735 auth
->curr_freq
= freq
;
737 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
740 dst
= auth
->peer_bi
->mac_addr
;
741 wpa_s
->dpp_auth_ok_on_ack
= 0;
742 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
743 wait_time
= wpa_s
->max_remain_on_chan
;
744 max_wait_time
= wpa_s
->dpp_resp_wait_time
?
745 wpa_s
->dpp_resp_wait_time
: 2000;
746 if (wait_time
> max_wait_time
)
747 wait_time
= max_wait_time
;
748 wait_time
+= 10; /* give the driver some extra time to complete */
749 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
750 wpas_dpp_reply_wait_timeout
,
753 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
754 wpa_printf(MSG_DEBUG
,
755 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
756 freq
, auth
->neg_freq
);
758 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
759 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
760 auth
->auth_req_ack
= 0;
761 os_get_reltime(&wpa_s
->dpp_last_init
);
762 return offchannel_send_action(wpa_s
, freq
, dst
,
763 wpa_s
->own_addr
, broadcast
,
764 wpabuf_head(auth
->req_msg
),
765 wpabuf_len(auth
->req_msg
),
766 wait_time
, wpas_dpp_tx_status
, 0);
770 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
773 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
774 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
775 unsigned int neg_freq
= 0;
777 wpa_s
->dpp_gas_client
= 0;
779 pos
= os_strstr(cmd
, " peer=");
783 peer_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
786 "DPP: Could not find bootstrapping info for the identified peer");
790 pos
= os_strstr(cmd
, " own=");
793 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
796 "DPP: Could not find bootstrapping info for the identified local entry");
800 if (peer_bi
->curve
!= own_bi
->curve
) {
802 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
803 peer_bi
->curve
->name
, own_bi
->curve
->name
);
808 pos
= os_strstr(cmd
, " role=");
811 if (os_strncmp(pos
, "configurator", 12) == 0)
812 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
813 else if (os_strncmp(pos
, "enrollee", 8) == 0)
814 allowed_roles
= DPP_CAPAB_ENROLLEE
;
815 else if (os_strncmp(pos
, "either", 6) == 0)
816 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
822 pos
= os_strstr(cmd
, " netrole=");
825 wpa_s
->dpp_netrole_ap
= os_strncmp(pos
, "ap", 2) == 0;
828 pos
= os_strstr(cmd
, " neg_freq=");
830 neg_freq
= atoi(pos
+ 10);
832 if (wpa_s
->dpp_auth
) {
833 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
834 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
835 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
837 offchannel_send_action_done(wpa_s
);
838 dpp_auth_deinit(wpa_s
->dpp_auth
);
840 wpa_s
->dpp_auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
,
842 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
843 if (!wpa_s
->dpp_auth
)
845 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
846 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
, cmd
);
848 wpa_s
->dpp_auth
->neg_freq
= neg_freq
;
850 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
851 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, peer_bi
->mac_addr
,
854 return wpas_dpp_auth_init_next(wpa_s
);
860 struct wpas_dpp_listen_work
{
862 unsigned int duration
;
863 struct wpabuf
*probe_resp_ie
;
867 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
875 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
877 struct wpas_dpp_listen_work
*lwork
;
879 if (!wpa_s
->dpp_listen_work
)
882 lwork
= wpa_s
->dpp_listen_work
->ctx
;
883 wpas_dpp_listen_work_free(lwork
);
884 radio_work_done(wpa_s
->dpp_listen_work
);
885 wpa_s
->dpp_listen_work
= NULL
;
889 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
891 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
892 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
896 wpa_s
->dpp_listen_work
= NULL
;
897 wpas_dpp_listen_stop(wpa_s
);
899 wpas_dpp_listen_work_free(lwork
);
903 wpa_s
->dpp_listen_work
= work
;
905 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
907 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
908 wpa_s
->max_remain_on_chan
) < 0) {
909 wpa_printf(MSG_DEBUG
,
910 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
912 wpas_dpp_listen_work_done(wpa_s
);
913 wpa_s
->dpp_pending_listen_freq
= 0;
916 wpa_s
->off_channel_freq
= 0;
917 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
921 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
924 struct wpas_dpp_listen_work
*lwork
;
926 if (wpa_s
->dpp_listen_work
) {
927 wpa_printf(MSG_DEBUG
,
928 "DPP: Reject start_listen since dpp_listen_work already exists");
932 if (wpa_s
->dpp_listen_freq
)
933 wpas_dpp_listen_stop(wpa_s
);
934 wpa_s
->dpp_listen_freq
= freq
;
936 lwork
= os_zalloc(sizeof(*lwork
));
941 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
943 wpas_dpp_listen_work_free(lwork
);
951 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
959 if (os_strstr(cmd
, " role=configurator"))
960 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
961 else if (os_strstr(cmd
, " role=enrollee"))
962 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
964 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
966 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
967 wpa_s
->dpp_netrole_ap
= os_strstr(cmd
, " netrole=ap") != NULL
;
968 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
969 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
974 return wpas_dpp_listen_start(wpa_s
, freq
);
978 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
980 wpa_s
->dpp_in_response_listen
= 0;
981 if (!wpa_s
->dpp_listen_freq
)
984 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
985 wpa_s
->dpp_listen_freq
);
986 wpa_drv_cancel_remain_on_channel(wpa_s
);
987 wpa_s
->dpp_listen_freq
= 0;
988 wpas_dpp_listen_work_done(wpa_s
);
992 void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
995 if (!wpa_s
->dpp_listen_freq
&& !wpa_s
->dpp_pending_listen_freq
)
998 wpa_printf(MSG_DEBUG
,
999 "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)",
1000 wpa_s
->off_channel_freq
, wpa_s
->dpp_pending_listen_freq
,
1001 wpa_s
->roc_waiting_drv_freq
, freq
);
1002 if (wpa_s
->off_channel_freq
&&
1003 wpa_s
->off_channel_freq
== wpa_s
->dpp_pending_listen_freq
) {
1004 wpa_printf(MSG_DEBUG
, "DPP: Listen on %u MHz started", freq
);
1005 wpa_s
->dpp_pending_listen_freq
= 0;
1007 wpa_printf(MSG_DEBUG
,
1008 "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)",
1009 wpa_s
->off_channel_freq
,
1010 wpa_s
->dpp_pending_listen_freq
, freq
);
1015 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
1018 wpas_dpp_listen_work_done(wpa_s
);
1020 if (wpa_s
->dpp_auth
&& wpa_s
->dpp_in_response_listen
) {
1021 unsigned int new_freq
;
1023 /* Continue listen with a new remain-on-channel */
1024 if (wpa_s
->dpp_auth
->neg_freq
> 0)
1025 new_freq
= wpa_s
->dpp_auth
->neg_freq
;
1027 new_freq
= wpa_s
->dpp_auth
->curr_freq
;
1028 wpa_printf(MSG_DEBUG
,
1029 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
1031 wpas_dpp_listen_start(wpa_s
, new_freq
);
1035 if (wpa_s
->dpp_listen_freq
) {
1036 /* Continue listen with a new remain-on-channel */
1037 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
1042 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1043 const u8
*hdr
, const u8
*buf
, size_t len
,
1046 const u8
*r_bootstrap
, *i_bootstrap
;
1047 u16 r_bootstrap_len
, i_bootstrap_len
;
1048 struct dpp_bootstrap_info
*bi
, *own_bi
= NULL
, *peer_bi
= NULL
;
1050 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
1053 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
1055 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
1056 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1057 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1060 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
1061 r_bootstrap
, r_bootstrap_len
);
1063 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
1065 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
1066 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1067 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
1070 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
1071 i_bootstrap
, i_bootstrap_len
);
1073 /* Try to find own and peer bootstrapping key matches based on the
1074 * received hash values */
1075 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
1077 if (!own_bi
&& bi
->own
&&
1078 os_memcmp(bi
->pubkey_hash
, r_bootstrap
,
1079 SHA256_MAC_LEN
) == 0) {
1080 wpa_printf(MSG_DEBUG
,
1081 "DPP: Found matching own bootstrapping information");
1085 if (!peer_bi
&& !bi
->own
&&
1086 os_memcmp(bi
->pubkey_hash
, i_bootstrap
,
1087 SHA256_MAC_LEN
) == 0) {
1088 wpa_printf(MSG_DEBUG
,
1089 "DPP: Found matching peer bootstrapping information");
1093 if (own_bi
&& peer_bi
)
1098 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1099 "No matching own bootstrapping key found - ignore message");
1103 if (wpa_s
->dpp_auth
) {
1104 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1105 "Already in DPP authentication exchange - ignore new one");
1109 wpa_s
->dpp_gas_client
= 0;
1110 wpa_s
->dpp_auth_ok_on_ack
= 0;
1111 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
1112 wpa_s
->dpp_qr_mutual
,
1113 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
1114 if (!wpa_s
->dpp_auth
) {
1115 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
1118 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
1119 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
,
1120 wpa_s
->dpp_configurator_params
);
1121 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
1123 if (wpa_s
->dpp_listen_freq
&&
1124 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
1125 wpa_printf(MSG_DEBUG
,
1126 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
1127 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
1128 wpas_dpp_listen_stop(wpa_s
);
1131 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1132 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
1133 DPP_PA_AUTHENTICATION_RESP
);
1134 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
1135 src
, wpa_s
->own_addr
, broadcast
,
1136 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
1137 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
1138 500, wpas_dpp_tx_status
, 0);
1142 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
1144 /* TODO: stop wait and start ROC */
1148 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
1149 struct dpp_authentication
*auth
)
1151 struct wpa_ssid
*ssid
;
1153 ssid
= wpa_config_add_network(wpa_s
->conf
);
1156 wpas_notify_network_added(wpa_s
, ssid
);
1157 wpa_config_set_network_defaults(ssid
);
1160 ssid
->ssid
= os_malloc(auth
->ssid_len
);
1163 os_memcpy(ssid
->ssid
, auth
->ssid
, auth
->ssid_len
);
1164 ssid
->ssid_len
= auth
->ssid_len
;
1166 if (auth
->connector
) {
1167 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
1168 ssid
->ieee80211w
= 1;
1169 ssid
->dpp_connector
= os_strdup(auth
->connector
);
1170 if (!ssid
->dpp_connector
)
1174 if (auth
->c_sign_key
) {
1175 ssid
->dpp_csign
= os_malloc(wpabuf_len(auth
->c_sign_key
));
1176 if (!ssid
->dpp_csign
)
1178 os_memcpy(ssid
->dpp_csign
, wpabuf_head(auth
->c_sign_key
),
1179 wpabuf_len(auth
->c_sign_key
));
1180 ssid
->dpp_csign_len
= wpabuf_len(auth
->c_sign_key
);
1183 if (auth
->net_access_key
) {
1184 ssid
->dpp_netaccesskey
=
1185 os_malloc(wpabuf_len(auth
->net_access_key
));
1186 if (!ssid
->dpp_netaccesskey
)
1188 os_memcpy(ssid
->dpp_netaccesskey
,
1189 wpabuf_head(auth
->net_access_key
),
1190 wpabuf_len(auth
->net_access_key
));
1191 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
1192 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
1195 if (!auth
->connector
) {
1197 if (auth
->akm
== DPP_AKM_PSK
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1198 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
1199 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
1200 if (auth
->akm
== DPP_AKM_SAE
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1201 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
1202 WPA_KEY_MGMT_FT_SAE
;
1203 ssid
->ieee80211w
= 1;
1204 if (auth
->passphrase
[0]) {
1205 if (wpa_config_set_quoted(ssid
, "psk",
1206 auth
->passphrase
) < 0)
1208 wpa_config_update_psk(ssid
);
1209 ssid
->export_keys
= 1;
1211 ssid
->psk_set
= auth
->psk_set
;
1212 os_memcpy(ssid
->psk
, auth
->psk
, PMK_LEN
);
1218 wpas_notify_network_removed(wpa_s
, ssid
);
1219 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1224 static void wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
1225 struct dpp_authentication
*auth
)
1227 struct wpa_ssid
*ssid
;
1229 if (wpa_s
->conf
->dpp_config_processing
< 1)
1232 ssid
= wpas_dpp_add_network(wpa_s
, auth
);
1236 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1237 if (wpa_s
->conf
->dpp_config_processing
< 2)
1240 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
1242 wpa_s
->disconnected
= 0;
1243 wpa_s
->reassociate
= 1;
1244 wpa_s
->scan_runs
= 0;
1245 wpa_s
->normal_scans
= 0;
1246 wpa_supplicant_cancel_sched_scan(wpa_s
);
1247 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1251 static void wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1252 struct dpp_authentication
*auth
)
1254 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1256 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1257 wpa_ssid_txt(auth
->ssid
, auth
->ssid_len
));
1258 if (auth
->connector
) {
1259 /* TODO: Save the Connector and consider using a command
1260 * to fetch the value instead of sending an event with
1261 * it. The Connector could end up being larger than what
1262 * most clients are ready to receive as an event
1264 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1267 if (auth
->c_sign_key
) {
1271 hexlen
= 2 * wpabuf_len(auth
->c_sign_key
) + 1;
1272 hex
= os_malloc(hexlen
);
1274 wpa_snprintf_hex(hex
, hexlen
,
1275 wpabuf_head(auth
->c_sign_key
),
1276 wpabuf_len(auth
->c_sign_key
));
1277 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1282 if (auth
->net_access_key
) {
1286 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1287 hex
= os_malloc(hexlen
);
1289 wpa_snprintf_hex(hex
, hexlen
,
1290 wpabuf_head(auth
->net_access_key
),
1291 wpabuf_len(auth
->net_access_key
));
1292 if (auth
->net_access_key_expiry
)
1293 wpa_msg(wpa_s
, MSG_INFO
,
1294 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1296 auth
->net_access_key_expiry
);
1298 wpa_msg(wpa_s
, MSG_INFO
,
1299 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1304 wpas_dpp_process_config(wpa_s
, auth
);
1308 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1309 enum gas_query_result result
,
1310 const struct wpabuf
*adv_proto
,
1311 const struct wpabuf
*resp
, u16 status_code
)
1313 struct wpa_supplicant
*wpa_s
= ctx
;
1315 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1317 wpa_s
->dpp_gas_dialog_token
= -1;
1319 if (!auth
|| !auth
->auth_success
) {
1320 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1323 if (!resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1324 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1328 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1330 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1333 if (wpabuf_len(adv_proto
) != 10 ||
1334 !(pos
= wpabuf_head(adv_proto
)) ||
1335 pos
[0] != WLAN_EID_ADV_PROTO
||
1337 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1339 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1342 wpa_printf(MSG_DEBUG
,
1343 "DPP: Not a DPP Advertisement Protocol ID");
1347 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1348 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1352 wpas_dpp_handle_config_obj(wpa_s
, auth
);
1353 dpp_auth_deinit(wpa_s
->dpp_auth
);
1354 wpa_s
->dpp_auth
= NULL
;
1358 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1359 dpp_auth_deinit(wpa_s
->dpp_auth
);
1360 wpa_s
->dpp_auth
= NULL
;
1364 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1366 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1367 struct wpabuf
*buf
, *conf_req
;
1371 wpa_s
->dpp_gas_client
= 1;
1372 os_snprintf(json
, sizeof(json
),
1373 "{\"name\":\"Test\","
1374 "\"wi-fi_tech\":\"infra\","
1375 "\"netRole\":\"%s\"}",
1376 wpa_s
->dpp_netrole_ap
? "ap" : "sta");
1377 #ifdef CONFIG_TESTING_OPTIONS
1378 if (dpp_test
== DPP_TEST_INVALID_CONFIG_ATTR_OBJ_CONF_REQ
) {
1379 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Config Attr");
1380 json
[29] = 'k'; /* replace "infra" with "knfra" */
1382 #endif /* CONFIG_TESTING_OPTIONS */
1383 wpa_printf(MSG_DEBUG
, "DPP: GAS Config Attributes: %s", json
);
1385 offchannel_send_action_done(wpa_s
);
1386 wpas_dpp_listen_stop(wpa_s
);
1388 conf_req
= dpp_build_conf_req(auth
, json
);
1390 wpa_printf(MSG_DEBUG
,
1391 "DPP: No configuration request data available");
1395 buf
= gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req
));
1397 wpabuf_free(conf_req
);
1401 /* Advertisement Protocol IE */
1402 wpabuf_put_u8(buf
, WLAN_EID_ADV_PROTO
);
1403 wpabuf_put_u8(buf
, 8); /* Length */
1404 wpabuf_put_u8(buf
, 0x7f);
1405 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
1406 wpabuf_put_u8(buf
, 5);
1407 wpabuf_put_be24(buf
, OUI_WFA
);
1408 wpabuf_put_u8(buf
, DPP_OUI_TYPE
);
1409 wpabuf_put_u8(buf
, 0x01);
1412 wpabuf_put_le16(buf
, wpabuf_len(conf_req
));
1413 wpabuf_put_buf(buf
, conf_req
);
1414 wpabuf_free(conf_req
);
1416 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1417 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1419 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1420 buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1422 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1425 wpa_printf(MSG_DEBUG
,
1426 "DPP: GAS query started with dialog token %u", res
);
1427 wpa_s
->dpp_gas_dialog_token
= res
;
1432 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1434 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1435 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1437 if (wpa_s
->dpp_auth
->configurator
)
1438 wpas_dpp_start_gas_server(wpa_s
);
1440 wpas_dpp_start_gas_client(wpa_s
);
1444 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1445 const u8
*hdr
, const u8
*buf
, size_t len
,
1448 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1451 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1452 " (freq %u MHz)", MAC2STR(src
), freq
);
1455 wpa_printf(MSG_DEBUG
,
1456 "DPP: No DPP Authentication in progress - drop");
1460 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1461 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1462 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1463 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1467 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1469 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1470 wpa_printf(MSG_DEBUG
,
1471 "DPP: Responder accepted request for different negotiation channel");
1472 auth
->curr_freq
= freq
;
1475 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1476 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1478 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1479 wpa_printf(MSG_DEBUG
,
1480 "DPP: Start wait for full response");
1481 offchannel_send_action_done(wpa_s
);
1482 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1485 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1488 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1490 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1491 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1492 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1493 src
, wpa_s
->own_addr
, broadcast
,
1494 wpabuf_head(msg
), wpabuf_len(msg
),
1495 500, wpas_dpp_tx_status
, 0);
1497 wpa_s
->dpp_auth_ok_on_ack
= 1;
1501 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1502 const u8
*hdr
, const u8
*buf
, size_t len
)
1504 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1506 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1510 wpa_printf(MSG_DEBUG
,
1511 "DPP: No DPP Authentication in progress - drop");
1515 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1516 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1517 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1521 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1522 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1526 wpas_dpp_auth_success(wpa_s
, 0);
1530 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1532 const u8
*buf
, size_t len
)
1534 struct wpa_ssid
*ssid
;
1535 const u8
*connector
, *trans_id
, *status
;
1536 u16 connector_len
, trans_id_len
, status_len
;
1537 struct dpp_introduction intro
;
1538 struct rsn_pmksa_cache_entry
*entry
;
1540 struct os_reltime rnow
;
1542 unsigned int seconds
;
1543 enum dpp_status_error res
;
1545 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1547 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1548 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1549 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1550 MACSTR
" - drop", MAC2STR(src
));
1553 offchannel_send_action_done(wpa_s
);
1555 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1556 if (ssid
== wpa_s
->dpp_intro_network
)
1559 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1561 wpa_printf(MSG_DEBUG
,
1562 "DPP: Profile not found for network introduction");
1566 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1568 if (!trans_id
|| trans_id_len
!= 1) {
1569 wpa_printf(MSG_DEBUG
,
1570 "DPP: Peer did not include Transaction ID");
1571 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1572 " fail=missing_transaction_id", MAC2STR(src
));
1575 if (trans_id
[0] != TRANSACTION_ID
) {
1576 wpa_printf(MSG_DEBUG
,
1577 "DPP: Ignore frame with unexpected Transaction ID %u",
1579 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1580 " fail=transaction_id_mismatch", MAC2STR(src
));
1584 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1585 if (!status
|| status_len
!= 1) {
1586 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1587 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1588 " fail=missing_status", MAC2STR(src
));
1591 if (status
[0] != DPP_STATUS_OK
) {
1592 wpa_printf(MSG_DEBUG
,
1593 "DPP: Peer rejected network introduction: Status %u",
1595 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1596 " status=%u", MAC2STR(src
), status
[0]);
1600 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1602 wpa_printf(MSG_DEBUG
,
1603 "DPP: Peer did not include its Connector");
1604 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1605 " fail=missing_connector", MAC2STR(src
));
1609 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1610 ssid
->dpp_netaccesskey
,
1611 ssid
->dpp_netaccesskey_len
,
1613 ssid
->dpp_csign_len
,
1614 connector
, connector_len
, &expiry
);
1615 if (res
!= DPP_STATUS_OK
) {
1616 wpa_printf(MSG_INFO
,
1617 "DPP: Network Introduction protocol resulted in failure");
1618 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1619 " fail=peer_connector_validation_failed", MAC2STR(src
));
1623 entry
= os_zalloc(sizeof(*entry
));
1626 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1627 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1628 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1629 entry
->pmk_len
= intro
.pmk_len
;
1630 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1633 seconds
= expiry
- now
.sec
;
1635 seconds
= 86400 * 7;
1637 os_get_reltime(&rnow
);
1638 entry
->expiration
= rnow
.sec
+ seconds
;
1639 entry
->reauth_time
= rnow
.sec
+ seconds
;
1640 entry
->network_ctx
= ssid
;
1641 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1643 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1644 " status=%u", MAC2STR(src
), status
[0]);
1646 wpa_printf(MSG_DEBUG
,
1647 "DPP: Try connection again after successful network introduction");
1648 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1649 wpa_supplicant_cancel_sched_scan(wpa_s
);
1650 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1653 os_memset(&intro
, 0, sizeof(intro
));
1657 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1659 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1660 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1662 if (!pkex
|| !pkex
->exchange_req
)
1664 if (pkex
->exch_req_tries
>= 5) {
1665 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1666 "No response from PKEX peer");
1667 dpp_pkex_free(pkex
);
1668 wpa_s
->dpp_pkex
= NULL
;
1672 pkex
->exch_req_tries
++;
1673 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1674 pkex
->exch_req_tries
);
1675 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1676 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1677 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1678 wpa_s
->own_addr
, broadcast
,
1679 wpabuf_head(pkex
->exchange_req
),
1680 wpabuf_len(pkex
->exchange_req
),
1681 pkex
->exch_req_wait_time
,
1682 wpas_dpp_tx_pkex_status
, 0);
1687 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1688 unsigned int freq
, const u8
*dst
,
1689 const u8
*src
, const u8
*bssid
,
1690 const u8
*data
, size_t data_len
,
1691 enum offchannel_send_action_result result
)
1693 const char *res_txt
;
1694 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1696 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1697 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1699 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1700 " result=%s (PKEX)",
1701 freq
, MAC2STR(dst
), res_txt
);
1702 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1703 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1706 wpa_printf(MSG_DEBUG
,
1707 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1712 wpa_printf(MSG_DEBUG
,
1713 "DPP: Terminate PKEX exchange due to an earlier error");
1714 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1715 pkex
->own_bi
->pkex_t
= pkex
->t
;
1716 dpp_pkex_free(pkex
);
1717 wpa_s
->dpp_pkex
= NULL
;
1721 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1722 /* Wait for PKEX Exchange Response frame and retry request if
1723 * no response is seen. */
1724 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1725 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1726 (pkex
->exch_req_wait_time
% 1000) * 1000,
1727 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1734 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1735 const u8
*buf
, size_t len
, unsigned int freq
)
1738 unsigned int wait_time
;
1740 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1743 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1746 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1747 wpa_printf(MSG_DEBUG
,
1748 "DPP: No PKEX code configured - ignore request");
1752 if (wpa_s
->dpp_pkex
) {
1753 /* TODO: Support parallel operations */
1754 wpa_printf(MSG_DEBUG
,
1755 "DPP: Already in PKEX session - ignore new request");
1759 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1760 wpa_s
->own_addr
, src
,
1761 wpa_s
->dpp_pkex_identifier
,
1762 wpa_s
->dpp_pkex_code
,
1764 if (!wpa_s
->dpp_pkex
) {
1765 wpa_printf(MSG_DEBUG
,
1766 "DPP: Failed to process the request - ignore it");
1770 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1771 wait_time
= wpa_s
->max_remain_on_chan
;
1772 if (wait_time
> 2000)
1774 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1775 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1776 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1778 wpabuf_head(msg
), wpabuf_len(msg
),
1779 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1784 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1785 const u8
*buf
, size_t len
, unsigned int freq
)
1788 unsigned int wait_time
;
1790 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1793 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1796 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1797 wpa_s
->dpp_pkex
->exchange_done
) {
1798 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1802 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1803 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
1805 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, src
, buf
, len
);
1807 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1811 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1814 wait_time
= wpa_s
->max_remain_on_chan
;
1815 if (wait_time
> 2000)
1817 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1818 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1819 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1821 wpabuf_head(msg
), wpabuf_len(msg
),
1822 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1827 static struct dpp_bootstrap_info
*
1828 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
1831 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1832 struct dpp_bootstrap_info
*bi
;
1834 bi
= os_zalloc(sizeof(*bi
));
1837 bi
->id
= wpas_dpp_next_id(wpa_s
);
1838 bi
->type
= DPP_BOOTSTRAP_PKEX
;
1839 os_memcpy(bi
->mac_addr
, peer
, ETH_ALEN
);
1842 bi
->curve
= pkex
->own_bi
->curve
;
1843 bi
->pubkey
= pkex
->peer_bootstrap_key
;
1844 pkex
->peer_bootstrap_key
= NULL
;
1845 dpp_pkex_free(pkex
);
1846 wpa_s
->dpp_pkex
= NULL
;
1847 if (dpp_bootstrap_key_hash(bi
) < 0) {
1848 dpp_bootstrap_info_free(bi
);
1851 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
1857 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1858 const u8
*hdr
, const u8
*buf
, size_t len
,
1862 unsigned int wait_time
;
1863 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1865 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1868 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1869 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1873 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1875 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1877 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
1878 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1879 pkex
->own_bi
->pkex_t
= pkex
->t
;
1880 dpp_pkex_free(wpa_s
->dpp_pkex
);
1881 wpa_s
->dpp_pkex
= NULL
;
1886 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1887 MACSTR
, MAC2STR(src
));
1889 wait_time
= wpa_s
->max_remain_on_chan
;
1890 if (wait_time
> 2000)
1892 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1893 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
1894 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1896 wpabuf_head(msg
), wpabuf_len(msg
),
1897 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1900 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1905 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1906 const u8
*hdr
, const u8
*buf
, size_t len
,
1910 struct dpp_bootstrap_info
*bi
;
1911 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1914 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
1917 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
1918 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1922 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
1924 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1928 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1932 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
1934 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
1935 wpa_printf(MSG_DEBUG
,
1936 "DPP: Start authentication after PKEX with parameters: %s",
1938 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
1939 wpa_printf(MSG_DEBUG
,
1940 "DPP: Authentication initialization failed");
1946 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1947 const u8
*buf
, size_t len
, unsigned int freq
)
1950 enum dpp_public_action_frame_type type
;
1952 unsigned int pkex_t
;
1954 if (len
< DPP_HDR_LEN
)
1956 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
1961 crypto_suite
= *buf
++;
1965 wpa_printf(MSG_DEBUG
,
1966 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1968 crypto_suite
, type
, MAC2STR(src
), freq
);
1969 if (crypto_suite
!= 1) {
1970 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
1972 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1973 " freq=%u type=%d ignore=unsupported-crypto-suite",
1974 MAC2STR(src
), freq
, type
);
1977 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
1978 if (dpp_check_attrs(buf
, len
) < 0) {
1979 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1980 " freq=%u type=%d ignore=invalid-attributes",
1981 MAC2STR(src
), freq
, type
);
1984 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
1985 MAC2STR(src
), freq
, type
);
1988 case DPP_PA_AUTHENTICATION_REQ
:
1989 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
1991 case DPP_PA_AUTHENTICATION_RESP
:
1992 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
1994 case DPP_PA_AUTHENTICATION_CONF
:
1995 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
1997 case DPP_PA_PEER_DISCOVERY_RESP
:
1998 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
2000 case DPP_PA_PKEX_EXCHANGE_REQ
:
2001 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
2003 case DPP_PA_PKEX_EXCHANGE_RESP
:
2004 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
2006 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
2007 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
2010 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
2011 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
2015 wpa_printf(MSG_DEBUG
,
2016 "DPP: Ignored unsupported frame subtype %d", type
);
2020 if (wpa_s
->dpp_pkex
)
2021 pkex_t
= wpa_s
->dpp_pkex
->t
;
2022 else if (wpa_s
->dpp_pkex_bi
)
2023 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
2026 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
2027 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
2028 wpas_dpp_pkex_remove(wpa_s
, "*");
2033 static struct wpabuf
*
2034 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
2037 struct wpa_supplicant
*wpa_s
= ctx
;
2038 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2039 struct wpabuf
*resp
;
2041 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
2043 if (!auth
|| !auth
->auth_success
||
2044 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
2045 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
2048 wpa_hexdump(MSG_DEBUG
,
2049 "DPP: Received Configuration Request (GAS Query Request)",
2051 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
2053 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2054 auth
->conf_resp
= resp
;
2060 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
2062 struct wpa_supplicant
*wpa_s
= ctx
;
2063 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2069 if (auth
->conf_resp
!= resp
) {
2070 wpa_printf(MSG_DEBUG
,
2071 "DPP: Ignore GAS status report (ok=%d) for unknown response",
2077 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
2079 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2080 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2081 offchannel_send_action_done(wpa_s
);
2082 wpas_dpp_listen_stop(wpa_s
);
2084 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
2086 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2087 dpp_auth_deinit(wpa_s
->dpp_auth
);
2088 wpa_s
->dpp_auth
= NULL
;
2093 static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant
*wpa_s
)
2095 struct dpp_configurator
*conf
;
2096 unsigned int max_id
= 0;
2098 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
2099 struct dpp_configurator
, list
) {
2100 if (conf
->id
> max_id
)
2107 int wpas_dpp_configurator_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2112 size_t privkey_len
= 0;
2114 struct dpp_configurator
*conf
= NULL
;
2116 curve
= get_param(cmd
, " curve=");
2117 key
= get_param(cmd
, " key=");
2120 privkey_len
= os_strlen(key
) / 2;
2121 privkey
= os_malloc(privkey_len
);
2123 hexstr2bin(key
, privkey
, privkey_len
) < 0)
2127 conf
= dpp_keygen_configurator(curve
, privkey
, privkey_len
);
2131 conf
->id
= wpas_dpp_next_configurator_id(wpa_s
);
2132 dl_list_add(&wpa_s
->dpp_configurator
, &conf
->list
);
2137 str_clear_free(key
);
2138 bin_clear_free(privkey
, privkey_len
);
2139 dpp_configurator_free(conf
);
2144 static int dpp_configurator_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
2146 struct dpp_configurator
*conf
, *tmp
;
2149 dl_list_for_each_safe(conf
, tmp
, &wpa_s
->dpp_configurator
,
2150 struct dpp_configurator
, list
) {
2151 if (id
&& conf
->id
!= id
)
2154 dl_list_del(&conf
->list
);
2155 dpp_configurator_free(conf
);
2159 return 0; /* flush succeeds regardless of entries found */
2160 return found
? 0 : -1;
2164 int wpas_dpp_configurator_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2166 unsigned int id_val
;
2168 if (os_strcmp(id
, "*") == 0) {
2176 return dpp_configurator_del(wpa_s
, id_val
);
2180 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2182 struct dpp_authentication
*auth
;
2186 auth
= os_zalloc(sizeof(*auth
));
2190 curve
= get_param(cmd
, " curve=");
2191 wpas_dpp_set_configurator(wpa_s
, auth
, cmd
);
2193 if (dpp_configurator_own_config(auth
, curve
, 0) == 0) {
2194 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 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
2234 return 0; /* Not using DPP AKM - continue */
2235 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
2236 return 0; /* PMKSA exists for DPP AKM - continue */
2238 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
2240 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2242 !ssid
->dpp_connector
? "Connector" :
2243 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2250 if (ssid
->dpp_netaccesskey_expiry
&&
2251 (os_time_t
) ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2252 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2253 "netAccessKey expired");
2257 wpa_printf(MSG_DEBUG
,
2258 "DPP: Starting network introduction protocol to derive PMKSA for "
2259 MACSTR
, MAC2STR(bss
->bssid
));
2261 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2262 5 + 4 + os_strlen(ssid
->dpp_connector
));
2266 #ifdef CONFIG_TESTING_OPTIONS
2267 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2268 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2271 #endif /* CONFIG_TESTING_OPTIONS */
2273 /* Transaction ID */
2274 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2275 wpabuf_put_le16(msg
, 1);
2276 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2278 #ifdef CONFIG_TESTING_OPTIONS
2280 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2281 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2282 goto skip_connector
;
2284 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2287 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2288 connector
= dpp_corrupt_connector_signature(
2289 ssid
->dpp_connector
);
2294 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2295 wpabuf_put_le16(msg
, os_strlen(connector
));
2296 wpabuf_put_str(msg
, connector
);
2298 goto skip_connector
;
2300 #endif /* CONFIG_TESTING_OPTIONS */
2303 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2304 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2305 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2307 #ifdef CONFIG_TESTING_OPTIONS
2309 #endif /* CONFIG_TESTING_OPTIONS */
2311 /* TODO: Timeout on AP response */
2312 wait_time
= wpa_s
->max_remain_on_chan
;
2313 if (wait_time
> 2000)
2315 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2316 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2317 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2319 wpabuf_head(msg
), wpabuf_len(msg
),
2320 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2323 /* Request this connection attempt to terminate - new one will be
2324 * started when network introduction protocol completes */
2325 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2326 wpa_s
->dpp_intro_network
= ssid
;
2331 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2333 struct dpp_bootstrap_info
*own_bi
;
2334 const char *pos
, *end
;
2335 unsigned int wait_time
;
2337 pos
= os_strstr(cmd
, " own=");
2341 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
2343 wpa_printf(MSG_DEBUG
,
2344 "DPP: Identified bootstrap info not found");
2347 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2348 wpa_printf(MSG_DEBUG
,
2349 "DPP: Identified bootstrap info not for PKEX");
2352 wpa_s
->dpp_pkex_bi
= own_bi
;
2353 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2355 os_free(wpa_s
->dpp_pkex_identifier
);
2356 wpa_s
->dpp_pkex_identifier
= NULL
;
2357 pos
= os_strstr(cmd
, " identifier=");
2360 end
= os_strchr(pos
, ' ');
2363 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2364 if (!wpa_s
->dpp_pkex_identifier
)
2366 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2367 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2370 pos
= os_strstr(cmd
, " code=");
2373 os_free(wpa_s
->dpp_pkex_code
);
2374 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2375 if (!wpa_s
->dpp_pkex_code
)
2378 if (os_strstr(cmd
, " init=1")) {
2379 struct dpp_pkex
*pkex
;
2382 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2383 dpp_pkex_free(wpa_s
->dpp_pkex
);
2384 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2385 wpa_s
->dpp_pkex_identifier
,
2386 wpa_s
->dpp_pkex_code
);
2387 pkex
= wpa_s
->dpp_pkex
;
2391 msg
= pkex
->exchange_req
;
2392 wait_time
= wpa_s
->max_remain_on_chan
;
2393 if (wait_time
> 2000)
2395 /* TODO: Support for 5 GHz channels */
2397 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2399 MAC2STR(broadcast
), pkex
->freq
,
2400 DPP_PA_PKEX_EXCHANGE_REQ
);
2401 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2402 wpa_s
->own_addr
, broadcast
,
2403 wpabuf_head(msg
), wpabuf_len(msg
),
2404 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2407 pkex
->exch_req_wait_time
= wait_time
;
2408 pkex
->exch_req_tries
= 1;
2411 /* TODO: Support multiple PKEX info entries */
2413 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2414 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2420 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2422 unsigned int id_val
;
2424 if (os_strcmp(id
, "*") == 0) {
2432 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2435 /* TODO: Support multiple PKEX entries */
2436 os_free(wpa_s
->dpp_pkex_code
);
2437 wpa_s
->dpp_pkex_code
= NULL
;
2438 os_free(wpa_s
->dpp_pkex_identifier
);
2439 wpa_s
->dpp_pkex_identifier
= NULL
;
2440 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2441 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2442 wpa_s
->dpp_pkex_bi
= NULL
;
2443 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2444 dpp_pkex_free(wpa_s
->dpp_pkex
);
2445 wpa_s
->dpp_pkex
= NULL
;
2450 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2452 dpp_auth_deinit(wpa_s
->dpp_auth
);
2453 wpa_s
->dpp_auth
= NULL
;
2454 dpp_pkex_free(wpa_s
->dpp_pkex
);
2455 wpa_s
->dpp_pkex
= NULL
;
2456 if (wpa_s
->dpp_gas_client
&& wpa_s
->dpp_gas_dialog_token
>= 0)
2457 gas_query_stop(wpa_s
->gas
, wpa_s
->dpp_gas_dialog_token
);
2461 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2465 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2466 adv_proto_id
[1] = 5;
2467 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2468 adv_proto_id
[5] = DPP_OUI_TYPE
;
2469 adv_proto_id
[6] = 0x01;
2471 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2472 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2473 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2475 dl_list_init(&wpa_s
->dpp_bootstrap
);
2476 dl_list_init(&wpa_s
->dpp_configurator
);
2477 wpa_s
->dpp_init_done
= 1;
2482 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2484 #ifdef CONFIG_TESTING_OPTIONS
2485 os_free(wpa_s
->dpp_config_obj_override
);
2486 wpa_s
->dpp_config_obj_override
= NULL
;
2487 os_free(wpa_s
->dpp_discovery_override
);
2488 wpa_s
->dpp_discovery_override
= NULL
;
2489 os_free(wpa_s
->dpp_groups_override
);
2490 wpa_s
->dpp_groups_override
= NULL
;
2491 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2492 #endif /* CONFIG_TESTING_OPTIONS */
2493 if (!wpa_s
->dpp_init_done
)
2495 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2496 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2497 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2498 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2499 offchannel_send_action_done(wpa_s
);
2500 wpas_dpp_listen_stop(wpa_s
);
2501 dpp_bootstrap_del(wpa_s
, 0);
2502 dpp_configurator_del(wpa_s
, 0);
2503 dpp_auth_deinit(wpa_s
->dpp_auth
);
2504 wpa_s
->dpp_auth
= NULL
;
2505 wpas_dpp_pkex_remove(wpa_s
, "*");
2506 wpa_s
->dpp_pkex
= NULL
;
2507 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2508 os_free(wpa_s
->dpp_configurator_params
);
2509 wpa_s
->dpp_configurator_params
= NULL
;