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
);
441 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
443 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
444 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
446 struct os_reltime now
;
451 if (auth
->waiting_auth_resp
&& auth
->auth_req_ack
) {
453 "DPP: No response received from responder - stopping initiation attempt");
454 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
455 offchannel_send_action_done(wpa_s
);
456 dpp_auth_deinit(auth
);
457 wpa_s
->dpp_auth
= NULL
;
461 if (auth
->waiting_auth_resp
) {
462 unsigned int wait_time
;
464 wait_time
= wpa_s
->dpp_resp_wait_time
?
465 wpa_s
->dpp_resp_wait_time
: 2;
466 os_get_reltime(&now
);
467 if (os_reltime_expired(&now
, &wpa_s
->dpp_last_init
,
469 offchannel_send_action_done(wpa_s
);
470 wpas_dpp_auth_init_next(wpa_s
);
475 freq
= auth
->curr_freq
;
476 if (auth
->neg_freq
> 0)
477 freq
= auth
->neg_freq
;
478 wpa_printf(MSG_DEBUG
, "DPP: Continue reply wait on channel %u MHz",
480 wpas_dpp_listen_start(wpa_s
, freq
);
484 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
485 struct dpp_authentication
*auth
)
487 #ifdef CONFIG_TESTING_OPTIONS
488 if (wpa_s
->dpp_config_obj_override
)
489 auth
->config_obj_override
=
490 os_strdup(wpa_s
->dpp_config_obj_override
);
491 if (wpa_s
->dpp_discovery_override
)
492 auth
->discovery_override
=
493 os_strdup(wpa_s
->dpp_discovery_override
);
494 if (wpa_s
->dpp_groups_override
)
495 auth
->groups_override
=
496 os_strdup(wpa_s
->dpp_groups_override
);
497 auth
->ignore_netaccesskey_mismatch
=
498 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
499 #endif /* CONFIG_TESTING_OPTIONS */
503 static void wpas_dpp_set_configurator(struct wpa_supplicant
*wpa_s
,
504 struct dpp_authentication
*auth
,
507 const char *pos
, *end
;
508 struct dpp_configuration
*conf_sta
= NULL
, *conf_ap
= NULL
;
509 struct dpp_configurator
*conf
= NULL
;
510 u8 ssid
[32] = { "test" };
520 wpa_printf(MSG_DEBUG
, "DPP: Set configurator parameters: %s", cmd
);
521 pos
= os_strstr(cmd
, " ssid=");
524 end
= os_strchr(pos
, ' ');
525 ssid_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
527 if (ssid_len
> sizeof(ssid
) ||
528 hexstr2bin(pos
, ssid
, ssid_len
) < 0)
532 pos
= os_strstr(cmd
, " pass=");
535 end
= os_strchr(pos
, ' ');
536 pass_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
538 if (pass_len
> sizeof(pass
) - 1 || pass_len
< 8 ||
539 hexstr2bin(pos
, (u8
*) pass
, pass_len
) < 0)
543 pos
= os_strstr(cmd
, " psk=");
546 if (hexstr2bin(pos
, psk
, PMK_LEN
) < 0)
551 if (os_strstr(cmd
, " conf=sta-")) {
552 conf_sta
= os_zalloc(sizeof(struct dpp_configuration
));
555 os_memcpy(conf_sta
->ssid
, ssid
, ssid_len
);
556 conf_sta
->ssid_len
= ssid_len
;
557 if (os_strstr(cmd
, " conf=sta-psk") ||
558 os_strstr(cmd
, " conf=sta-sae") ||
559 os_strstr(cmd
, " conf=sta-psk-sae")) {
560 if (os_strstr(cmd
, " conf=sta-psk-sae"))
561 conf_sta
->akm
= DPP_AKM_PSK_SAE
;
562 else if (os_strstr(cmd
, " conf=sta-sae"))
563 conf_sta
->akm
= DPP_AKM_SAE
;
565 conf_sta
->akm
= DPP_AKM_PSK
;
567 os_memcpy(conf_sta
->psk
, psk
, PMK_LEN
);
569 conf_sta
->passphrase
= os_strdup(pass
);
570 if (!conf_sta
->passphrase
)
573 } else if (os_strstr(cmd
, " conf=sta-dpp")) {
574 conf_sta
->akm
= DPP_AKM_DPP
;
580 if (os_strstr(cmd
, " conf=ap-")) {
581 conf_ap
= os_zalloc(sizeof(struct dpp_configuration
));
584 os_memcpy(conf_ap
->ssid
, ssid
, ssid_len
);
585 conf_ap
->ssid_len
= ssid_len
;
586 if (os_strstr(cmd
, " conf=ap-psk") ||
587 os_strstr(cmd
, " conf=ap-sae") ||
588 os_strstr(cmd
, " conf=ap-psk-sae")) {
589 if (os_strstr(cmd
, " conf=ap-psk-sae"))
590 conf_ap
->akm
= DPP_AKM_PSK_SAE
;
591 else if (os_strstr(cmd
, " conf=ap-sae"))
592 conf_ap
->akm
= DPP_AKM_SAE
;
594 conf_ap
->akm
= DPP_AKM_PSK
;
596 os_memcpy(conf_ap
->psk
, psk
, PMK_LEN
);
598 conf_ap
->passphrase
= os_strdup(pass
);
599 if (!conf_ap
->passphrase
)
602 } else if (os_strstr(cmd
, " conf=ap-dpp")) {
603 conf_ap
->akm
= DPP_AKM_DPP
;
609 pos
= os_strstr(cmd
, " expiry=");
614 val
= strtol(pos
, NULL
, 0);
618 conf_sta
->netaccesskey_expiry
= val
;
620 conf_ap
->netaccesskey_expiry
= val
;
623 pos
= os_strstr(cmd
, " configurator=");
626 conf
= dpp_configurator_get_id(wpa_s
, atoi(pos
));
629 "DPP: Could not find the specified configurator");
633 auth
->conf_sta
= conf_sta
;
634 auth
->conf_ap
= conf_ap
;
639 wpa_printf(MSG_DEBUG
, "DPP: Failed to set configurator parameters");
640 dpp_configuration_free(conf_sta
);
641 dpp_configuration_free(conf_ap
);
645 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
647 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
649 if (!wpa_s
->dpp_auth
)
651 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
652 wpas_dpp_auth_init_next(wpa_s
);
656 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
658 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
660 unsigned int wait_time
, freq
, max_tries
;
664 if (auth
->freq_idx
>= auth
->num_freq
) {
665 auth
->num_freq_iters
++;
666 if (wpa_s
->dpp_init_max_tries
)
667 max_tries
= wpa_s
->dpp_init_max_tries
;
670 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
672 "DPP: No response received from responder - stopping initiation attempt");
673 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
674 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
676 offchannel_send_action_done(wpa_s
);
677 dpp_auth_deinit(wpa_s
->dpp_auth
);
678 wpa_s
->dpp_auth
= NULL
;
682 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
683 if (wpa_s
->dpp_init_retry_time
)
684 wait_time
= wpa_s
->dpp_init_retry_time
;
687 eloop_register_timeout(wait_time
/ 1000,
688 (wait_time
% 1000) * 1000,
689 wpas_dpp_init_timeout
, wpa_s
,
693 freq
= auth
->freq
[auth
->freq_idx
++];
694 auth
->curr_freq
= freq
;
696 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
699 dst
= auth
->peer_bi
->mac_addr
;
700 wpa_s
->dpp_auth_ok_on_ack
= 0;
701 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
702 wait_time
= wpa_s
->max_remain_on_chan
;
703 if (wait_time
> 2000)
705 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
706 wpas_dpp_reply_wait_timeout
,
708 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
709 wpa_printf(MSG_DEBUG
,
710 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
711 freq
, auth
->neg_freq
);
713 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
714 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
715 auth
->auth_req_ack
= 0;
716 os_get_reltime(&wpa_s
->dpp_last_init
);
717 return offchannel_send_action(wpa_s
, freq
, dst
,
718 wpa_s
->own_addr
, broadcast
,
719 wpabuf_head(auth
->req_msg
),
720 wpabuf_len(auth
->req_msg
),
721 wait_time
, wpas_dpp_tx_status
, 0);
725 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
728 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
729 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
730 unsigned int neg_freq
= 0;
732 wpa_s
->dpp_gas_client
= 0;
734 pos
= os_strstr(cmd
, " peer=");
738 peer_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
741 "DPP: Could not find bootstrapping info for the identified peer");
745 pos
= os_strstr(cmd
, " own=");
748 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
751 "DPP: Could not find bootstrapping info for the identified local entry");
755 if (peer_bi
->curve
!= own_bi
->curve
) {
757 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
758 peer_bi
->curve
->name
, own_bi
->curve
->name
);
763 pos
= os_strstr(cmd
, " role=");
766 if (os_strncmp(pos
, "configurator", 12) == 0)
767 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
768 else if (os_strncmp(pos
, "enrollee", 8) == 0)
769 allowed_roles
= DPP_CAPAB_ENROLLEE
;
770 else if (os_strncmp(pos
, "either", 6) == 0)
771 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
777 pos
= os_strstr(cmd
, " netrole=");
780 wpa_s
->dpp_netrole_ap
= os_strncmp(pos
, "ap", 2) == 0;
783 pos
= os_strstr(cmd
, " neg_freq=");
785 neg_freq
= atoi(pos
+ 10);
787 if (wpa_s
->dpp_auth
) {
788 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
789 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
790 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
792 offchannel_send_action_done(wpa_s
);
793 dpp_auth_deinit(wpa_s
->dpp_auth
);
795 wpa_s
->dpp_auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
,
797 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
798 if (!wpa_s
->dpp_auth
)
800 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
801 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
, cmd
);
803 wpa_s
->dpp_auth
->neg_freq
= neg_freq
;
805 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
806 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, peer_bi
->mac_addr
,
809 return wpas_dpp_auth_init_next(wpa_s
);
815 struct wpas_dpp_listen_work
{
817 unsigned int duration
;
818 struct wpabuf
*probe_resp_ie
;
822 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
830 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
832 struct wpas_dpp_listen_work
*lwork
;
834 if (!wpa_s
->dpp_listen_work
)
837 lwork
= wpa_s
->dpp_listen_work
->ctx
;
838 wpas_dpp_listen_work_free(lwork
);
839 radio_work_done(wpa_s
->dpp_listen_work
);
840 wpa_s
->dpp_listen_work
= NULL
;
844 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
846 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
847 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
851 wpa_s
->dpp_listen_work
= NULL
;
852 wpas_dpp_listen_stop(wpa_s
);
854 wpas_dpp_listen_work_free(lwork
);
858 wpa_s
->dpp_listen_work
= work
;
860 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
862 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
863 wpa_s
->max_remain_on_chan
) < 0) {
864 wpa_printf(MSG_DEBUG
,
865 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
867 wpas_dpp_listen_work_done(wpa_s
);
868 wpa_s
->dpp_pending_listen_freq
= 0;
871 wpa_s
->off_channel_freq
= 0;
872 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
876 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
879 struct wpas_dpp_listen_work
*lwork
;
881 if (wpa_s
->dpp_listen_work
) {
882 wpa_printf(MSG_DEBUG
,
883 "DPP: Reject start_listen since dpp_listen_work already exists");
887 if (wpa_s
->dpp_listen_freq
)
888 wpas_dpp_listen_stop(wpa_s
);
889 wpa_s
->dpp_listen_freq
= freq
;
891 lwork
= os_zalloc(sizeof(*lwork
));
896 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
898 wpas_dpp_listen_work_free(lwork
);
906 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
914 if (os_strstr(cmd
, " role=configurator"))
915 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
916 else if (os_strstr(cmd
, " role=enrollee"))
917 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
919 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
921 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
922 wpa_s
->dpp_netrole_ap
= os_strstr(cmd
, " netrole=ap") != NULL
;
923 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
924 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
929 return wpas_dpp_listen_start(wpa_s
, freq
);
933 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
935 if (!wpa_s
->dpp_listen_freq
)
938 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
939 wpa_s
->dpp_listen_freq
);
940 wpa_drv_cancel_remain_on_channel(wpa_s
);
941 wpa_s
->dpp_listen_freq
= 0;
942 wpas_dpp_listen_work_done(wpa_s
);
946 void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
949 if (!wpa_s
->dpp_listen_freq
&& !wpa_s
->dpp_pending_listen_freq
)
952 wpa_printf(MSG_DEBUG
,
953 "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)",
954 wpa_s
->off_channel_freq
, wpa_s
->dpp_pending_listen_freq
,
955 wpa_s
->roc_waiting_drv_freq
, freq
);
956 if (wpa_s
->off_channel_freq
&&
957 wpa_s
->off_channel_freq
== wpa_s
->dpp_pending_listen_freq
) {
958 wpa_printf(MSG_DEBUG
, "DPP: Listen on %u MHz started", freq
);
959 wpa_s
->dpp_pending_listen_freq
= 0;
961 wpa_printf(MSG_DEBUG
,
962 "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)",
963 wpa_s
->off_channel_freq
,
964 wpa_s
->dpp_pending_listen_freq
, freq
);
969 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
972 wpas_dpp_listen_work_done(wpa_s
);
974 if (wpa_s
->dpp_auth
&& !wpa_s
->dpp_gas_client
) {
975 /* Continue listen with a new remain-on-channel */
976 wpa_printf(MSG_DEBUG
,
977 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
978 wpa_s
->dpp_auth
->curr_freq
);
979 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->curr_freq
);
983 if (wpa_s
->dpp_listen_freq
) {
984 /* Continue listen with a new remain-on-channel */
985 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
990 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
991 const u8
*hdr
, const u8
*buf
, size_t len
,
994 const u8
*r_bootstrap
, *i_bootstrap
;
995 u16 r_bootstrap_len
, i_bootstrap_len
;
996 struct dpp_bootstrap_info
*bi
, *own_bi
= NULL
, *peer_bi
= NULL
;
998 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
1001 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
1003 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
1004 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1005 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1008 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
1009 r_bootstrap
, r_bootstrap_len
);
1011 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
1013 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
1014 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1015 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
1018 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
1019 i_bootstrap
, i_bootstrap_len
);
1021 /* Try to find own and peer bootstrapping key matches based on the
1022 * received hash values */
1023 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
1025 if (!own_bi
&& bi
->own
&&
1026 os_memcmp(bi
->pubkey_hash
, r_bootstrap
,
1027 SHA256_MAC_LEN
) == 0) {
1028 wpa_printf(MSG_DEBUG
,
1029 "DPP: Found matching own bootstrapping information");
1033 if (!peer_bi
&& !bi
->own
&&
1034 os_memcmp(bi
->pubkey_hash
, i_bootstrap
,
1035 SHA256_MAC_LEN
) == 0) {
1036 wpa_printf(MSG_DEBUG
,
1037 "DPP: Found matching peer bootstrapping information");
1041 if (own_bi
&& peer_bi
)
1046 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1047 "No matching own bootstrapping key found - ignore message");
1051 if (wpa_s
->dpp_auth
) {
1052 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1053 "Already in DPP authentication exchange - ignore new one");
1057 wpa_s
->dpp_gas_client
= 0;
1058 wpa_s
->dpp_auth_ok_on_ack
= 0;
1059 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
1060 wpa_s
->dpp_qr_mutual
,
1061 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
1062 if (!wpa_s
->dpp_auth
) {
1063 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
1066 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
1067 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
,
1068 wpa_s
->dpp_configurator_params
);
1069 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
1071 if (wpa_s
->dpp_listen_freq
&&
1072 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
1073 wpa_printf(MSG_DEBUG
,
1074 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
1075 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
1076 wpas_dpp_listen_stop(wpa_s
);
1079 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1080 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
1081 DPP_PA_AUTHENTICATION_RESP
);
1082 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
1083 src
, wpa_s
->own_addr
, broadcast
,
1084 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
1085 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
1086 500, wpas_dpp_tx_status
, 0);
1090 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
1092 /* TODO: stop wait and start ROC */
1096 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
1097 struct dpp_authentication
*auth
)
1099 struct wpa_ssid
*ssid
;
1101 ssid
= wpa_config_add_network(wpa_s
->conf
);
1104 wpas_notify_network_added(wpa_s
, ssid
);
1105 wpa_config_set_network_defaults(ssid
);
1108 ssid
->ssid
= os_malloc(auth
->ssid_len
);
1111 os_memcpy(ssid
->ssid
, auth
->ssid
, auth
->ssid_len
);
1112 ssid
->ssid_len
= auth
->ssid_len
;
1114 if (auth
->connector
) {
1115 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
1116 ssid
->ieee80211w
= 1;
1117 ssid
->dpp_connector
= os_strdup(auth
->connector
);
1118 if (!ssid
->dpp_connector
)
1122 if (auth
->c_sign_key
) {
1123 ssid
->dpp_csign
= os_malloc(wpabuf_len(auth
->c_sign_key
));
1124 if (!ssid
->dpp_csign
)
1126 os_memcpy(ssid
->dpp_csign
, wpabuf_head(auth
->c_sign_key
),
1127 wpabuf_len(auth
->c_sign_key
));
1128 ssid
->dpp_csign_len
= wpabuf_len(auth
->c_sign_key
);
1131 if (auth
->net_access_key
) {
1132 ssid
->dpp_netaccesskey
=
1133 os_malloc(wpabuf_len(auth
->net_access_key
));
1134 if (!ssid
->dpp_netaccesskey
)
1136 os_memcpy(ssid
->dpp_netaccesskey
,
1137 wpabuf_head(auth
->net_access_key
),
1138 wpabuf_len(auth
->net_access_key
));
1139 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
1140 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
1143 if (!auth
->connector
) {
1145 if (auth
->akm
== DPP_AKM_PSK
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1146 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
1147 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
1148 if (auth
->akm
== DPP_AKM_SAE
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1149 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
1150 WPA_KEY_MGMT_FT_SAE
;
1151 ssid
->ieee80211w
= 1;
1152 if (auth
->passphrase
[0]) {
1153 if (wpa_config_set_quoted(ssid
, "psk",
1154 auth
->passphrase
) < 0)
1156 wpa_config_update_psk(ssid
);
1157 ssid
->export_keys
= 1;
1159 ssid
->psk_set
= auth
->psk_set
;
1160 os_memcpy(ssid
->psk
, auth
->psk
, PMK_LEN
);
1166 wpas_notify_network_removed(wpa_s
, ssid
);
1167 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1172 static void wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
1173 struct dpp_authentication
*auth
)
1175 struct wpa_ssid
*ssid
;
1177 if (wpa_s
->conf
->dpp_config_processing
< 1)
1180 ssid
= wpas_dpp_add_network(wpa_s
, auth
);
1184 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1185 if (wpa_s
->conf
->dpp_config_processing
< 2)
1188 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
1190 wpa_s
->disconnected
= 0;
1191 wpa_s
->reassociate
= 1;
1192 wpa_s
->scan_runs
= 0;
1193 wpa_s
->normal_scans
= 0;
1194 wpa_supplicant_cancel_sched_scan(wpa_s
);
1195 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1199 static void wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1200 struct dpp_authentication
*auth
)
1202 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1204 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1205 wpa_ssid_txt(auth
->ssid
, auth
->ssid_len
));
1206 if (auth
->connector
) {
1207 /* TODO: Save the Connector and consider using a command
1208 * to fetch the value instead of sending an event with
1209 * it. The Connector could end up being larger than what
1210 * most clients are ready to receive as an event
1212 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1215 if (auth
->c_sign_key
) {
1219 hexlen
= 2 * wpabuf_len(auth
->c_sign_key
) + 1;
1220 hex
= os_malloc(hexlen
);
1222 wpa_snprintf_hex(hex
, hexlen
,
1223 wpabuf_head(auth
->c_sign_key
),
1224 wpabuf_len(auth
->c_sign_key
));
1225 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1230 if (auth
->net_access_key
) {
1234 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1235 hex
= os_malloc(hexlen
);
1237 wpa_snprintf_hex(hex
, hexlen
,
1238 wpabuf_head(auth
->net_access_key
),
1239 wpabuf_len(auth
->net_access_key
));
1240 if (auth
->net_access_key_expiry
)
1241 wpa_msg(wpa_s
, MSG_INFO
,
1242 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1244 auth
->net_access_key_expiry
);
1246 wpa_msg(wpa_s
, MSG_INFO
,
1247 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1252 wpas_dpp_process_config(wpa_s
, auth
);
1256 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1257 enum gas_query_result result
,
1258 const struct wpabuf
*adv_proto
,
1259 const struct wpabuf
*resp
, u16 status_code
)
1261 struct wpa_supplicant
*wpa_s
= ctx
;
1263 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1265 if (!auth
|| !auth
->auth_success
) {
1266 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1269 if (!resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1270 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1274 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1276 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1279 if (wpabuf_len(adv_proto
) != 10 ||
1280 !(pos
= wpabuf_head(adv_proto
)) ||
1281 pos
[0] != WLAN_EID_ADV_PROTO
||
1283 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1285 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1288 wpa_printf(MSG_DEBUG
,
1289 "DPP: Not a DPP Advertisement Protocol ID");
1293 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1294 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1298 wpas_dpp_handle_config_obj(wpa_s
, auth
);
1299 dpp_auth_deinit(wpa_s
->dpp_auth
);
1300 wpa_s
->dpp_auth
= NULL
;
1304 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1305 dpp_auth_deinit(wpa_s
->dpp_auth
);
1306 wpa_s
->dpp_auth
= NULL
;
1310 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1312 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1313 struct wpabuf
*buf
, *conf_req
;
1317 wpa_s
->dpp_gas_client
= 1;
1318 os_snprintf(json
, sizeof(json
),
1319 "{\"name\":\"Test\","
1320 "\"wi-fi_tech\":\"infra\","
1321 "\"netRole\":\"%s\"}",
1322 wpa_s
->dpp_netrole_ap
? "ap" : "sta");
1323 #ifdef CONFIG_TESTING_OPTIONS
1324 if (dpp_test
== DPP_TEST_INVALID_CONFIG_ATTR_OBJ_CONF_REQ
) {
1325 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Config Attr");
1326 json
[29] = 'k'; /* replace "infra" with "knfra" */
1328 #endif /* CONFIG_TESTING_OPTIONS */
1329 wpa_printf(MSG_DEBUG
, "DPP: GAS Config Attributes: %s", json
);
1331 offchannel_send_action_done(wpa_s
);
1332 wpas_dpp_listen_stop(wpa_s
);
1334 conf_req
= dpp_build_conf_req(auth
, json
);
1336 wpa_printf(MSG_DEBUG
,
1337 "DPP: No configuration request data available");
1341 buf
= gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req
));
1343 wpabuf_free(conf_req
);
1347 /* Advertisement Protocol IE */
1348 wpabuf_put_u8(buf
, WLAN_EID_ADV_PROTO
);
1349 wpabuf_put_u8(buf
, 8); /* Length */
1350 wpabuf_put_u8(buf
, 0x7f);
1351 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
1352 wpabuf_put_u8(buf
, 5);
1353 wpabuf_put_be24(buf
, OUI_WFA
);
1354 wpabuf_put_u8(buf
, DPP_OUI_TYPE
);
1355 wpabuf_put_u8(buf
, 0x01);
1358 wpabuf_put_le16(buf
, wpabuf_len(conf_req
));
1359 wpabuf_put_buf(buf
, conf_req
);
1360 wpabuf_free(conf_req
);
1362 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1363 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1365 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1366 buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1368 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1371 wpa_printf(MSG_DEBUG
,
1372 "DPP: GAS query started with dialog token %u", res
);
1377 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1379 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1380 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1382 if (wpa_s
->dpp_auth
->configurator
)
1383 wpas_dpp_start_gas_server(wpa_s
);
1385 wpas_dpp_start_gas_client(wpa_s
);
1389 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1390 const u8
*hdr
, const u8
*buf
, size_t len
,
1393 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1396 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1397 " (freq %u MHz)", MAC2STR(src
), freq
);
1400 wpa_printf(MSG_DEBUG
,
1401 "DPP: No DPP Authentication in progress - drop");
1405 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1406 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1407 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1408 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1412 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1414 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1415 wpa_printf(MSG_DEBUG
,
1416 "DPP: Responder accepted request for different negotiation channel");
1417 auth
->curr_freq
= freq
;
1420 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1421 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1423 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1424 wpa_printf(MSG_DEBUG
,
1425 "DPP: Start wait for full response");
1426 offchannel_send_action_done(wpa_s
);
1427 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1430 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1433 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1435 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1436 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1437 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1438 src
, wpa_s
->own_addr
, broadcast
,
1439 wpabuf_head(msg
), wpabuf_len(msg
),
1440 500, wpas_dpp_tx_status
, 0);
1442 wpa_s
->dpp_auth_ok_on_ack
= 1;
1446 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1447 const u8
*hdr
, const u8
*buf
, size_t len
)
1449 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1451 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1455 wpa_printf(MSG_DEBUG
,
1456 "DPP: No DPP Authentication in progress - drop");
1460 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1461 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1462 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1466 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1467 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1471 wpas_dpp_auth_success(wpa_s
, 0);
1475 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1477 const u8
*buf
, size_t len
)
1479 struct wpa_ssid
*ssid
;
1480 const u8
*connector
, *trans_id
, *status
;
1481 u16 connector_len
, trans_id_len
, status_len
;
1482 struct dpp_introduction intro
;
1483 struct rsn_pmksa_cache_entry
*entry
;
1485 struct os_reltime rnow
;
1487 unsigned int seconds
;
1488 enum dpp_status_error res
;
1490 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1492 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1493 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1494 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1495 MACSTR
" - drop", MAC2STR(src
));
1498 offchannel_send_action_done(wpa_s
);
1500 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1501 if (ssid
== wpa_s
->dpp_intro_network
)
1504 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1506 wpa_printf(MSG_DEBUG
,
1507 "DPP: Profile not found for network introduction");
1511 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1513 if (!trans_id
|| trans_id_len
!= 1) {
1514 wpa_printf(MSG_DEBUG
,
1515 "DPP: Peer did not include Transaction ID");
1516 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1517 " fail=missing_transaction_id", MAC2STR(src
));
1520 if (trans_id
[0] != TRANSACTION_ID
) {
1521 wpa_printf(MSG_DEBUG
,
1522 "DPP: Ignore frame with unexpected Transaction ID %u",
1524 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1525 " fail=transaction_id_mismatch", MAC2STR(src
));
1529 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1530 if (!status
|| status_len
!= 1) {
1531 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1532 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1533 " fail=missing_status", MAC2STR(src
));
1536 if (status
[0] != DPP_STATUS_OK
) {
1537 wpa_printf(MSG_DEBUG
,
1538 "DPP: Peer rejected network introduction: Status %u",
1540 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1541 " status=%u", MAC2STR(src
), status
[0]);
1545 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1547 wpa_printf(MSG_DEBUG
,
1548 "DPP: Peer did not include its Connector");
1549 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1550 " fail=missing_connector", MAC2STR(src
));
1554 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1555 ssid
->dpp_netaccesskey
,
1556 ssid
->dpp_netaccesskey_len
,
1558 ssid
->dpp_csign_len
,
1559 connector
, connector_len
, &expiry
);
1560 if (res
!= DPP_STATUS_OK
) {
1561 wpa_printf(MSG_INFO
,
1562 "DPP: Network Introduction protocol resulted in failure");
1563 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1564 " fail=peer_connector_validation_failed", MAC2STR(src
));
1568 entry
= os_zalloc(sizeof(*entry
));
1571 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1572 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1573 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1574 entry
->pmk_len
= intro
.pmk_len
;
1575 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1578 seconds
= expiry
- now
.sec
;
1580 seconds
= 86400 * 7;
1582 os_get_reltime(&rnow
);
1583 entry
->expiration
= rnow
.sec
+ seconds
;
1584 entry
->reauth_time
= rnow
.sec
+ seconds
;
1585 entry
->network_ctx
= ssid
;
1586 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1588 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1589 " status=%u", MAC2STR(src
), status
[0]);
1591 wpa_printf(MSG_DEBUG
,
1592 "DPP: Try connection again after successful network introduction");
1593 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1594 wpa_supplicant_cancel_sched_scan(wpa_s
);
1595 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1598 os_memset(&intro
, 0, sizeof(intro
));
1602 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1604 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1605 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1607 if (!pkex
|| !pkex
->exchange_req
)
1609 if (pkex
->exch_req_tries
>= 5) {
1610 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1611 "No response from PKEX peer");
1612 dpp_pkex_free(pkex
);
1613 wpa_s
->dpp_pkex
= NULL
;
1617 pkex
->exch_req_tries
++;
1618 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1619 pkex
->exch_req_tries
);
1620 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1621 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1622 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1623 wpa_s
->own_addr
, broadcast
,
1624 wpabuf_head(pkex
->exchange_req
),
1625 wpabuf_len(pkex
->exchange_req
),
1626 pkex
->exch_req_wait_time
,
1627 wpas_dpp_tx_pkex_status
, 0);
1632 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1633 unsigned int freq
, const u8
*dst
,
1634 const u8
*src
, const u8
*bssid
,
1635 const u8
*data
, size_t data_len
,
1636 enum offchannel_send_action_result result
)
1638 const char *res_txt
;
1639 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1641 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1642 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1644 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1645 " result=%s (PKEX)",
1646 freq
, MAC2STR(dst
), res_txt
);
1647 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1648 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1651 wpa_printf(MSG_DEBUG
,
1652 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1657 wpa_printf(MSG_DEBUG
,
1658 "DPP: Terminate PKEX exchange due to an earlier error");
1659 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1660 pkex
->own_bi
->pkex_t
= pkex
->t
;
1661 dpp_pkex_free(pkex
);
1662 wpa_s
->dpp_pkex
= NULL
;
1666 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1667 /* Wait for PKEX Exchange Response frame and retry request if
1668 * no response is seen. */
1669 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1670 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1671 (pkex
->exch_req_wait_time
% 1000) * 1000,
1672 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1679 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1680 const u8
*buf
, size_t len
, unsigned int freq
)
1683 unsigned int wait_time
;
1685 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1688 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1691 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1692 wpa_printf(MSG_DEBUG
,
1693 "DPP: No PKEX code configured - ignore request");
1697 if (wpa_s
->dpp_pkex
) {
1698 /* TODO: Support parallel operations */
1699 wpa_printf(MSG_DEBUG
,
1700 "DPP: Already in PKEX session - ignore new request");
1704 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1705 wpa_s
->own_addr
, src
,
1706 wpa_s
->dpp_pkex_identifier
,
1707 wpa_s
->dpp_pkex_code
,
1709 if (!wpa_s
->dpp_pkex
) {
1710 wpa_printf(MSG_DEBUG
,
1711 "DPP: Failed to process the request - ignore it");
1715 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1716 wait_time
= wpa_s
->max_remain_on_chan
;
1717 if (wait_time
> 2000)
1719 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1720 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1721 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1723 wpabuf_head(msg
), wpabuf_len(msg
),
1724 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1729 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1730 const u8
*buf
, size_t len
, unsigned int freq
)
1733 unsigned int wait_time
;
1735 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1738 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1741 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1742 wpa_s
->dpp_pkex
->exchange_done
) {
1743 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1747 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1748 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
1750 os_memcpy(wpa_s
->dpp_pkex
->peer_mac
, src
, ETH_ALEN
);
1751 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, buf
, len
);
1753 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1757 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1760 wait_time
= wpa_s
->max_remain_on_chan
;
1761 if (wait_time
> 2000)
1763 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1764 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1765 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1767 wpabuf_head(msg
), wpabuf_len(msg
),
1768 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1773 static struct dpp_bootstrap_info
*
1774 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
1777 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1778 struct dpp_bootstrap_info
*bi
;
1780 bi
= os_zalloc(sizeof(*bi
));
1783 bi
->id
= wpas_dpp_next_id(wpa_s
);
1784 bi
->type
= DPP_BOOTSTRAP_PKEX
;
1785 os_memcpy(bi
->mac_addr
, peer
, ETH_ALEN
);
1788 bi
->curve
= pkex
->own_bi
->curve
;
1789 bi
->pubkey
= pkex
->peer_bootstrap_key
;
1790 pkex
->peer_bootstrap_key
= NULL
;
1791 dpp_pkex_free(pkex
);
1792 wpa_s
->dpp_pkex
= NULL
;
1793 if (dpp_bootstrap_key_hash(bi
) < 0) {
1794 dpp_bootstrap_info_free(bi
);
1797 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
1803 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1804 const u8
*hdr
, const u8
*buf
, size_t len
,
1808 unsigned int wait_time
;
1809 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1811 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1814 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1815 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1819 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1821 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1823 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
1824 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1825 pkex
->own_bi
->pkex_t
= pkex
->t
;
1826 dpp_pkex_free(wpa_s
->dpp_pkex
);
1827 wpa_s
->dpp_pkex
= NULL
;
1832 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1833 MACSTR
, MAC2STR(src
));
1835 wait_time
= wpa_s
->max_remain_on_chan
;
1836 if (wait_time
> 2000)
1838 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1839 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
1840 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1842 wpabuf_head(msg
), wpabuf_len(msg
),
1843 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1846 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1851 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1852 const u8
*hdr
, const u8
*buf
, size_t len
,
1856 struct dpp_bootstrap_info
*bi
;
1857 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1860 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
1863 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
1864 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1868 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
1870 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1874 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1878 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
1880 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
1881 wpa_printf(MSG_DEBUG
,
1882 "DPP: Start authentication after PKEX with parameters: %s",
1884 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
1885 wpa_printf(MSG_DEBUG
,
1886 "DPP: Authentication initialization failed");
1892 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1893 const u8
*buf
, size_t len
, unsigned int freq
)
1896 enum dpp_public_action_frame_type type
;
1898 unsigned int pkex_t
;
1900 if (len
< DPP_HDR_LEN
)
1902 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
1907 crypto_suite
= *buf
++;
1911 wpa_printf(MSG_DEBUG
,
1912 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1914 crypto_suite
, type
, MAC2STR(src
), freq
);
1915 if (crypto_suite
!= 1) {
1916 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
1918 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1919 " freq=%u type=%d ignore=unsupported-crypto-suite",
1920 MAC2STR(src
), freq
, type
);
1923 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
1924 if (dpp_check_attrs(buf
, len
) < 0) {
1925 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1926 " freq=%u type=%d ignore=invalid-attributes",
1927 MAC2STR(src
), freq
, type
);
1930 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
1931 MAC2STR(src
), freq
, type
);
1934 case DPP_PA_AUTHENTICATION_REQ
:
1935 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
1937 case DPP_PA_AUTHENTICATION_RESP
:
1938 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
1940 case DPP_PA_AUTHENTICATION_CONF
:
1941 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
1943 case DPP_PA_PEER_DISCOVERY_RESP
:
1944 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
1946 case DPP_PA_PKEX_EXCHANGE_REQ
:
1947 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
1949 case DPP_PA_PKEX_EXCHANGE_RESP
:
1950 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
1952 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
1953 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
1956 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
1957 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
1961 wpa_printf(MSG_DEBUG
,
1962 "DPP: Ignored unsupported frame subtype %d", type
);
1966 if (wpa_s
->dpp_pkex
)
1967 pkex_t
= wpa_s
->dpp_pkex
->t
;
1968 else if (wpa_s
->dpp_pkex_bi
)
1969 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
1972 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
1973 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
1974 wpas_dpp_pkex_remove(wpa_s
, "*");
1979 static struct wpabuf
*
1980 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
1983 struct wpa_supplicant
*wpa_s
= ctx
;
1984 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1985 struct wpabuf
*resp
;
1987 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
1989 if (!auth
|| !auth
->auth_success
||
1990 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1991 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1994 wpa_hexdump(MSG_DEBUG
,
1995 "DPP: Received Configuration Request (GAS Query Request)",
1997 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
1999 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2005 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
2007 struct wpa_supplicant
*wpa_s
= ctx
;
2008 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2015 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
2017 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2018 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2019 offchannel_send_action_done(wpa_s
);
2020 wpas_dpp_listen_stop(wpa_s
);
2022 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
2024 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2025 dpp_auth_deinit(wpa_s
->dpp_auth
);
2026 wpa_s
->dpp_auth
= NULL
;
2031 static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant
*wpa_s
)
2033 struct dpp_configurator
*conf
;
2034 unsigned int max_id
= 0;
2036 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
2037 struct dpp_configurator
, list
) {
2038 if (conf
->id
> max_id
)
2045 int wpas_dpp_configurator_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2050 size_t privkey_len
= 0;
2052 struct dpp_configurator
*conf
= NULL
;
2054 curve
= get_param(cmd
, " curve=");
2055 key
= get_param(cmd
, " key=");
2058 privkey_len
= os_strlen(key
) / 2;
2059 privkey
= os_malloc(privkey_len
);
2061 hexstr2bin(key
, privkey
, privkey_len
) < 0)
2065 conf
= dpp_keygen_configurator(curve
, privkey
, privkey_len
);
2069 conf
->id
= wpas_dpp_next_configurator_id(wpa_s
);
2070 dl_list_add(&wpa_s
->dpp_configurator
, &conf
->list
);
2075 str_clear_free(key
);
2076 bin_clear_free(privkey
, privkey_len
);
2077 dpp_configurator_free(conf
);
2082 static int dpp_configurator_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
2084 struct dpp_configurator
*conf
, *tmp
;
2087 dl_list_for_each_safe(conf
, tmp
, &wpa_s
->dpp_configurator
,
2088 struct dpp_configurator
, list
) {
2089 if (id
&& conf
->id
!= id
)
2092 dl_list_del(&conf
->list
);
2093 dpp_configurator_free(conf
);
2097 return 0; /* flush succeeds regardless of entries found */
2098 return found
? 0 : -1;
2102 int wpas_dpp_configurator_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2104 unsigned int id_val
;
2106 if (os_strcmp(id
, "*") == 0) {
2114 return dpp_configurator_del(wpa_s
, id_val
);
2118 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2120 struct dpp_authentication
*auth
;
2124 auth
= os_zalloc(sizeof(*auth
));
2128 curve
= get_param(cmd
, " curve=");
2129 wpas_dpp_set_configurator(wpa_s
, auth
, cmd
);
2131 if (dpp_configurator_own_config(auth
, curve
) == 0) {
2132 wpas_dpp_handle_config_obj(wpa_s
, auth
);
2136 dpp_auth_deinit(auth
);
2144 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
2145 unsigned int freq
, const u8
*dst
,
2146 const u8
*src
, const u8
*bssid
,
2147 const u8
*data
, size_t data_len
,
2148 enum offchannel_send_action_result result
)
2150 const char *res_txt
;
2152 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
2153 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
2155 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
2156 " result=%s (DPP Peer Discovery Request)",
2157 freq
, MAC2STR(dst
), res_txt
);
2158 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
2159 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
2160 /* TODO: Time out wait for response more quickly in error cases? */
2164 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
2165 struct wpa_bss
*bss
)
2169 unsigned int wait_time
;
2171 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
2172 return 0; /* Not using DPP AKM - continue */
2173 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
2174 return 0; /* PMKSA exists for DPP AKM - continue */
2176 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
2178 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2180 !ssid
->dpp_connector
? "Connector" :
2181 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2188 if (ssid
->dpp_netaccesskey_expiry
&&
2189 ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2190 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2191 "netAccessKey expired");
2195 wpa_printf(MSG_DEBUG
,
2196 "DPP: Starting network introduction protocol to derive PMKSA for "
2197 MACSTR
, MAC2STR(bss
->bssid
));
2199 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2200 5 + 4 + os_strlen(ssid
->dpp_connector
));
2204 #ifdef CONFIG_TESTING_OPTIONS
2205 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2206 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2209 #endif /* CONFIG_TESTING_OPTIONS */
2211 /* Transaction ID */
2212 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2213 wpabuf_put_le16(msg
, 1);
2214 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2216 #ifdef CONFIG_TESTING_OPTIONS
2218 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2219 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2220 goto skip_connector
;
2222 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2225 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2226 connector
= dpp_corrupt_connector_signature(
2227 ssid
->dpp_connector
);
2232 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2233 wpabuf_put_le16(msg
, os_strlen(connector
));
2234 wpabuf_put_str(msg
, connector
);
2236 goto skip_connector
;
2238 #endif /* CONFIG_TESTING_OPTIONS */
2241 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2242 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2243 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2245 #ifdef CONFIG_TESTING_OPTIONS
2247 #endif /* CONFIG_TESTING_OPTIONS */
2249 /* TODO: Timeout on AP response */
2250 wait_time
= wpa_s
->max_remain_on_chan
;
2251 if (wait_time
> 2000)
2253 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2254 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2255 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2257 wpabuf_head(msg
), wpabuf_len(msg
),
2258 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2261 /* Request this connection attempt to terminate - new one will be
2262 * started when network introduction protocol completes */
2263 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2264 wpa_s
->dpp_intro_network
= ssid
;
2269 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2271 struct dpp_bootstrap_info
*own_bi
;
2272 const char *pos
, *end
;
2273 unsigned int wait_time
;
2275 pos
= os_strstr(cmd
, " own=");
2279 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
2281 wpa_printf(MSG_DEBUG
,
2282 "DPP: Identified bootstrap info not found");
2285 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2286 wpa_printf(MSG_DEBUG
,
2287 "DPP: Identified bootstrap info not for PKEX");
2290 wpa_s
->dpp_pkex_bi
= own_bi
;
2291 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2293 os_free(wpa_s
->dpp_pkex_identifier
);
2294 wpa_s
->dpp_pkex_identifier
= NULL
;
2295 pos
= os_strstr(cmd
, " identifier=");
2298 end
= os_strchr(pos
, ' ');
2301 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2302 if (!wpa_s
->dpp_pkex_identifier
)
2304 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2305 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2308 pos
= os_strstr(cmd
, " code=");
2311 os_free(wpa_s
->dpp_pkex_code
);
2312 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2313 if (!wpa_s
->dpp_pkex_code
)
2316 if (os_strstr(cmd
, " init=1")) {
2317 struct dpp_pkex
*pkex
;
2320 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2321 dpp_pkex_free(wpa_s
->dpp_pkex
);
2322 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2323 wpa_s
->dpp_pkex_identifier
,
2324 wpa_s
->dpp_pkex_code
);
2325 pkex
= wpa_s
->dpp_pkex
;
2329 msg
= pkex
->exchange_req
;
2330 wait_time
= wpa_s
->max_remain_on_chan
;
2331 if (wait_time
> 2000)
2333 /* TODO: Support for 5 GHz channels */
2335 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2337 MAC2STR(broadcast
), pkex
->freq
,
2338 DPP_PA_PKEX_EXCHANGE_REQ
);
2339 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2340 wpa_s
->own_addr
, broadcast
,
2341 wpabuf_head(msg
), wpabuf_len(msg
),
2342 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2345 pkex
->exch_req_wait_time
= wait_time
;
2346 pkex
->exch_req_tries
= 1;
2349 /* TODO: Support multiple PKEX info entries */
2351 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2352 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2358 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2360 unsigned int id_val
;
2362 if (os_strcmp(id
, "*") == 0) {
2370 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2373 /* TODO: Support multiple PKEX entries */
2374 os_free(wpa_s
->dpp_pkex_code
);
2375 wpa_s
->dpp_pkex_code
= NULL
;
2376 os_free(wpa_s
->dpp_pkex_identifier
);
2377 wpa_s
->dpp_pkex_identifier
= NULL
;
2378 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2379 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2380 wpa_s
->dpp_pkex_bi
= NULL
;
2381 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2382 dpp_pkex_free(wpa_s
->dpp_pkex
);
2383 wpa_s
->dpp_pkex
= NULL
;
2388 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2390 dpp_auth_deinit(wpa_s
->dpp_auth
);
2391 wpa_s
->dpp_auth
= NULL
;
2395 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2399 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2400 adv_proto_id
[1] = 5;
2401 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2402 adv_proto_id
[5] = DPP_OUI_TYPE
;
2403 adv_proto_id
[6] = 0x01;
2405 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2406 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2407 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2409 dl_list_init(&wpa_s
->dpp_bootstrap
);
2410 dl_list_init(&wpa_s
->dpp_configurator
);
2411 wpa_s
->dpp_init_done
= 1;
2416 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2418 #ifdef CONFIG_TESTING_OPTIONS
2419 os_free(wpa_s
->dpp_config_obj_override
);
2420 wpa_s
->dpp_config_obj_override
= NULL
;
2421 os_free(wpa_s
->dpp_discovery_override
);
2422 wpa_s
->dpp_discovery_override
= NULL
;
2423 os_free(wpa_s
->dpp_groups_override
);
2424 wpa_s
->dpp_groups_override
= NULL
;
2425 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2426 #endif /* CONFIG_TESTING_OPTIONS */
2427 if (!wpa_s
->dpp_init_done
)
2429 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2430 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2431 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2432 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2433 offchannel_send_action_done(wpa_s
);
2434 wpas_dpp_listen_stop(wpa_s
);
2435 dpp_bootstrap_del(wpa_s
, 0);
2436 dpp_configurator_del(wpa_s
, 0);
2437 dpp_auth_deinit(wpa_s
->dpp_auth
);
2438 wpa_s
->dpp_auth
= NULL
;
2439 wpas_dpp_pkex_remove(wpa_s
, "*");
2440 wpa_s
->dpp_pkex
= NULL
;
2441 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2442 os_free(wpa_s
->dpp_configurator_params
);
2443 wpa_s
->dpp_configurator_params
= NULL
;