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
, diff
;
447 unsigned int wait_time
, diff_ms
;
449 if (!auth
|| !auth
->waiting_auth_resp
)
452 wait_time
= wpa_s
->dpp_resp_wait_time
?
453 wpa_s
->dpp_resp_wait_time
: 2000;
454 os_get_reltime(&now
);
455 os_reltime_sub(&now
, &wpa_s
->dpp_last_init
, &diff
);
456 diff_ms
= diff
.sec
* 1000 + diff
.usec
/ 1000;
457 wpa_printf(MSG_DEBUG
,
458 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
461 if (auth
->auth_req_ack
&& diff_ms
>= wait_time
) {
462 /* Peer ACK'ed Authentication Request frame, but did not reply
463 * with Authentication Response frame within two seconds. */
465 "DPP: No response received from responder - stopping initiation attempt");
466 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
467 offchannel_send_action_done(wpa_s
);
468 wpas_dpp_listen_stop(wpa_s
);
469 dpp_auth_deinit(auth
);
470 wpa_s
->dpp_auth
= NULL
;
474 if (diff_ms
>= wait_time
) {
475 /* Authentication Request frame was not ACK'ed and no reply
476 * was receiving within two seconds. */
477 wpa_printf(MSG_DEBUG
,
478 "DPP: Continue Initiator channel iteration");
479 offchannel_send_action_done(wpa_s
);
480 wpas_dpp_listen_stop(wpa_s
);
481 wpas_dpp_auth_init_next(wpa_s
);
485 /* Driver did not support 2000 ms long wait_time with TX command, so
486 * schedule listen operation to continue waiting for the response.
488 * DPP listen operations continue until stopped, so simply schedule a
489 * new call to this function at the point when the two second reply
490 * wait has expired. */
491 wait_time
-= diff_ms
;
493 freq
= auth
->curr_freq
;
494 if (auth
->neg_freq
> 0)
495 freq
= auth
->neg_freq
;
496 wpa_printf(MSG_DEBUG
,
497 "DPP: Continue reply wait on channel %u MHz for %u ms",
499 wpa_s
->dpp_in_response_listen
= 1;
500 wpas_dpp_listen_start(wpa_s
, freq
);
502 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
503 wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
507 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
508 struct dpp_authentication
*auth
)
510 #ifdef CONFIG_TESTING_OPTIONS
511 if (wpa_s
->dpp_config_obj_override
)
512 auth
->config_obj_override
=
513 os_strdup(wpa_s
->dpp_config_obj_override
);
514 if (wpa_s
->dpp_discovery_override
)
515 auth
->discovery_override
=
516 os_strdup(wpa_s
->dpp_discovery_override
);
517 if (wpa_s
->dpp_groups_override
)
518 auth
->groups_override
=
519 os_strdup(wpa_s
->dpp_groups_override
);
520 auth
->ignore_netaccesskey_mismatch
=
521 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
522 #endif /* CONFIG_TESTING_OPTIONS */
526 static void wpas_dpp_set_configurator(struct wpa_supplicant
*wpa_s
,
527 struct dpp_authentication
*auth
,
530 const char *pos
, *end
;
531 struct dpp_configuration
*conf_sta
= NULL
, *conf_ap
= NULL
;
532 struct dpp_configurator
*conf
= NULL
;
533 u8 ssid
[32] = { "test" };
543 wpa_printf(MSG_DEBUG
, "DPP: Set configurator parameters: %s", cmd
);
544 pos
= os_strstr(cmd
, " ssid=");
547 end
= os_strchr(pos
, ' ');
548 ssid_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
550 if (ssid_len
> sizeof(ssid
) ||
551 hexstr2bin(pos
, ssid
, ssid_len
) < 0)
555 pos
= os_strstr(cmd
, " pass=");
558 end
= os_strchr(pos
, ' ');
559 pass_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
561 if (pass_len
> sizeof(pass
) - 1 || pass_len
< 8 ||
562 hexstr2bin(pos
, (u8
*) pass
, pass_len
) < 0)
566 pos
= os_strstr(cmd
, " psk=");
569 if (hexstr2bin(pos
, psk
, PMK_LEN
) < 0)
574 if (os_strstr(cmd
, " conf=sta-")) {
575 conf_sta
= os_zalloc(sizeof(struct dpp_configuration
));
578 os_memcpy(conf_sta
->ssid
, ssid
, ssid_len
);
579 conf_sta
->ssid_len
= ssid_len
;
580 if (os_strstr(cmd
, " conf=sta-psk") ||
581 os_strstr(cmd
, " conf=sta-sae") ||
582 os_strstr(cmd
, " conf=sta-psk-sae")) {
583 if (os_strstr(cmd
, " conf=sta-psk-sae"))
584 conf_sta
->akm
= DPP_AKM_PSK_SAE
;
585 else if (os_strstr(cmd
, " conf=sta-sae"))
586 conf_sta
->akm
= DPP_AKM_SAE
;
588 conf_sta
->akm
= DPP_AKM_PSK
;
590 os_memcpy(conf_sta
->psk
, psk
, PMK_LEN
);
592 conf_sta
->passphrase
= os_strdup(pass
);
593 if (!conf_sta
->passphrase
)
596 } else if (os_strstr(cmd
, " conf=sta-dpp")) {
597 conf_sta
->akm
= DPP_AKM_DPP
;
603 if (os_strstr(cmd
, " conf=ap-")) {
604 conf_ap
= os_zalloc(sizeof(struct dpp_configuration
));
607 os_memcpy(conf_ap
->ssid
, ssid
, ssid_len
);
608 conf_ap
->ssid_len
= ssid_len
;
609 if (os_strstr(cmd
, " conf=ap-psk") ||
610 os_strstr(cmd
, " conf=ap-sae") ||
611 os_strstr(cmd
, " conf=ap-psk-sae")) {
612 if (os_strstr(cmd
, " conf=ap-psk-sae"))
613 conf_ap
->akm
= DPP_AKM_PSK_SAE
;
614 else if (os_strstr(cmd
, " conf=ap-sae"))
615 conf_ap
->akm
= DPP_AKM_SAE
;
617 conf_ap
->akm
= DPP_AKM_PSK
;
619 os_memcpy(conf_ap
->psk
, psk
, PMK_LEN
);
621 conf_ap
->passphrase
= os_strdup(pass
);
622 if (!conf_ap
->passphrase
)
625 } else if (os_strstr(cmd
, " conf=ap-dpp")) {
626 conf_ap
->akm
= DPP_AKM_DPP
;
632 pos
= os_strstr(cmd
, " expiry=");
637 val
= strtol(pos
, NULL
, 0);
641 conf_sta
->netaccesskey_expiry
= val
;
643 conf_ap
->netaccesskey_expiry
= val
;
646 pos
= os_strstr(cmd
, " configurator=");
649 conf
= dpp_configurator_get_id(wpa_s
, atoi(pos
));
652 "DPP: Could not find the specified configurator");
656 auth
->conf_sta
= conf_sta
;
657 auth
->conf_ap
= conf_ap
;
662 wpa_printf(MSG_DEBUG
, "DPP: Failed to set configurator parameters");
663 dpp_configuration_free(conf_sta
);
664 dpp_configuration_free(conf_ap
);
668 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
670 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
672 if (!wpa_s
->dpp_auth
)
674 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
675 wpas_dpp_auth_init_next(wpa_s
);
679 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
681 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
683 unsigned int wait_time
, max_wait_time
, freq
, max_tries
, used
;
684 struct os_reltime now
, diff
;
686 wpa_s
->dpp_in_response_listen
= 0;
690 if (auth
->freq_idx
== 0)
691 os_get_reltime(&wpa_s
->dpp_init_iter_start
);
693 if (auth
->freq_idx
>= auth
->num_freq
) {
694 auth
->num_freq_iters
++;
695 if (wpa_s
->dpp_init_max_tries
)
696 max_tries
= wpa_s
->dpp_init_max_tries
;
699 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
701 "DPP: No response received from responder - stopping initiation attempt");
702 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
703 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
705 offchannel_send_action_done(wpa_s
);
706 dpp_auth_deinit(wpa_s
->dpp_auth
);
707 wpa_s
->dpp_auth
= NULL
;
711 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
712 if (wpa_s
->dpp_init_retry_time
)
713 wait_time
= wpa_s
->dpp_init_retry_time
;
716 os_get_reltime(&now
);
717 os_reltime_sub(&now
, &wpa_s
->dpp_init_iter_start
, &diff
);
718 used
= diff
.sec
* 1000 + diff
.usec
/ 1000;
719 if (used
> wait_time
)
723 wpa_printf(MSG_DEBUG
, "DPP: Next init attempt in %u ms",
725 eloop_register_timeout(wait_time
/ 1000,
726 (wait_time
% 1000) * 1000,
727 wpas_dpp_init_timeout
, wpa_s
,
731 freq
= auth
->freq
[auth
->freq_idx
++];
732 auth
->curr_freq
= freq
;
734 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
737 dst
= auth
->peer_bi
->mac_addr
;
738 wpa_s
->dpp_auth_ok_on_ack
= 0;
739 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
740 wait_time
= wpa_s
->max_remain_on_chan
;
741 max_wait_time
= wpa_s
->dpp_resp_wait_time
?
742 wpa_s
->dpp_resp_wait_time
: 2000;
743 if (wait_time
> max_wait_time
)
744 wait_time
= max_wait_time
;
745 wait_time
+= 10; /* give the driver some extra time to complete */
746 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
747 wpas_dpp_reply_wait_timeout
,
750 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
751 wpa_printf(MSG_DEBUG
,
752 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
753 freq
, auth
->neg_freq
);
755 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
756 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
757 auth
->auth_req_ack
= 0;
758 os_get_reltime(&wpa_s
->dpp_last_init
);
759 return offchannel_send_action(wpa_s
, freq
, dst
,
760 wpa_s
->own_addr
, broadcast
,
761 wpabuf_head(auth
->req_msg
),
762 wpabuf_len(auth
->req_msg
),
763 wait_time
, wpas_dpp_tx_status
, 0);
767 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
770 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
771 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
772 unsigned int neg_freq
= 0;
774 wpa_s
->dpp_gas_client
= 0;
776 pos
= os_strstr(cmd
, " peer=");
780 peer_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
783 "DPP: Could not find bootstrapping info for the identified peer");
787 pos
= os_strstr(cmd
, " own=");
790 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
793 "DPP: Could not find bootstrapping info for the identified local entry");
797 if (peer_bi
->curve
!= own_bi
->curve
) {
799 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
800 peer_bi
->curve
->name
, own_bi
->curve
->name
);
805 pos
= os_strstr(cmd
, " role=");
808 if (os_strncmp(pos
, "configurator", 12) == 0)
809 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
810 else if (os_strncmp(pos
, "enrollee", 8) == 0)
811 allowed_roles
= DPP_CAPAB_ENROLLEE
;
812 else if (os_strncmp(pos
, "either", 6) == 0)
813 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
819 pos
= os_strstr(cmd
, " netrole=");
822 wpa_s
->dpp_netrole_ap
= os_strncmp(pos
, "ap", 2) == 0;
825 pos
= os_strstr(cmd
, " neg_freq=");
827 neg_freq
= atoi(pos
+ 10);
829 if (wpa_s
->dpp_auth
) {
830 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
831 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
832 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
834 offchannel_send_action_done(wpa_s
);
835 dpp_auth_deinit(wpa_s
->dpp_auth
);
837 wpa_s
->dpp_auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
,
839 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
840 if (!wpa_s
->dpp_auth
)
842 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
843 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
, cmd
);
845 wpa_s
->dpp_auth
->neg_freq
= neg_freq
;
847 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
848 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, peer_bi
->mac_addr
,
851 return wpas_dpp_auth_init_next(wpa_s
);
857 struct wpas_dpp_listen_work
{
859 unsigned int duration
;
860 struct wpabuf
*probe_resp_ie
;
864 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
872 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
874 struct wpas_dpp_listen_work
*lwork
;
876 if (!wpa_s
->dpp_listen_work
)
879 lwork
= wpa_s
->dpp_listen_work
->ctx
;
880 wpas_dpp_listen_work_free(lwork
);
881 radio_work_done(wpa_s
->dpp_listen_work
);
882 wpa_s
->dpp_listen_work
= NULL
;
886 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
888 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
889 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
893 wpa_s
->dpp_listen_work
= NULL
;
894 wpas_dpp_listen_stop(wpa_s
);
896 wpas_dpp_listen_work_free(lwork
);
900 wpa_s
->dpp_listen_work
= work
;
902 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
904 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
905 wpa_s
->max_remain_on_chan
) < 0) {
906 wpa_printf(MSG_DEBUG
,
907 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
909 wpas_dpp_listen_work_done(wpa_s
);
910 wpa_s
->dpp_pending_listen_freq
= 0;
913 wpa_s
->off_channel_freq
= 0;
914 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
918 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
921 struct wpas_dpp_listen_work
*lwork
;
923 if (wpa_s
->dpp_listen_work
) {
924 wpa_printf(MSG_DEBUG
,
925 "DPP: Reject start_listen since dpp_listen_work already exists");
929 if (wpa_s
->dpp_listen_freq
)
930 wpas_dpp_listen_stop(wpa_s
);
931 wpa_s
->dpp_listen_freq
= freq
;
933 lwork
= os_zalloc(sizeof(*lwork
));
938 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
940 wpas_dpp_listen_work_free(lwork
);
948 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
956 if (os_strstr(cmd
, " role=configurator"))
957 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
958 else if (os_strstr(cmd
, " role=enrollee"))
959 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
961 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
963 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
964 wpa_s
->dpp_netrole_ap
= os_strstr(cmd
, " netrole=ap") != NULL
;
965 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
966 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
971 return wpas_dpp_listen_start(wpa_s
, freq
);
975 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
977 wpa_s
->dpp_in_response_listen
= 0;
978 if (!wpa_s
->dpp_listen_freq
)
981 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
982 wpa_s
->dpp_listen_freq
);
983 wpa_drv_cancel_remain_on_channel(wpa_s
);
984 wpa_s
->dpp_listen_freq
= 0;
985 wpas_dpp_listen_work_done(wpa_s
);
989 void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
992 if (!wpa_s
->dpp_listen_freq
&& !wpa_s
->dpp_pending_listen_freq
)
995 wpa_printf(MSG_DEBUG
,
996 "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)",
997 wpa_s
->off_channel_freq
, wpa_s
->dpp_pending_listen_freq
,
998 wpa_s
->roc_waiting_drv_freq
, freq
);
999 if (wpa_s
->off_channel_freq
&&
1000 wpa_s
->off_channel_freq
== wpa_s
->dpp_pending_listen_freq
) {
1001 wpa_printf(MSG_DEBUG
, "DPP: Listen on %u MHz started", freq
);
1002 wpa_s
->dpp_pending_listen_freq
= 0;
1004 wpa_printf(MSG_DEBUG
,
1005 "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)",
1006 wpa_s
->off_channel_freq
,
1007 wpa_s
->dpp_pending_listen_freq
, freq
);
1012 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
1015 wpas_dpp_listen_work_done(wpa_s
);
1017 if (wpa_s
->dpp_auth
&& wpa_s
->dpp_in_response_listen
) {
1018 unsigned int new_freq
;
1020 /* Continue listen with a new remain-on-channel */
1021 if (wpa_s
->dpp_auth
->neg_freq
> 0)
1022 new_freq
= wpa_s
->dpp_auth
->neg_freq
;
1024 new_freq
= wpa_s
->dpp_auth
->curr_freq
;
1025 wpa_printf(MSG_DEBUG
,
1026 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
1028 wpas_dpp_listen_start(wpa_s
, new_freq
);
1032 if (wpa_s
->dpp_listen_freq
) {
1033 /* Continue listen with a new remain-on-channel */
1034 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
1039 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1040 const u8
*hdr
, const u8
*buf
, size_t len
,
1043 const u8
*r_bootstrap
, *i_bootstrap
;
1044 u16 r_bootstrap_len
, i_bootstrap_len
;
1045 struct dpp_bootstrap_info
*bi
, *own_bi
= NULL
, *peer_bi
= NULL
;
1047 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
1050 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
1052 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
1053 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1054 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1057 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
1058 r_bootstrap
, r_bootstrap_len
);
1060 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
1062 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
1063 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1064 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
1067 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
1068 i_bootstrap
, i_bootstrap_len
);
1070 /* Try to find own and peer bootstrapping key matches based on the
1071 * received hash values */
1072 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
1074 if (!own_bi
&& bi
->own
&&
1075 os_memcmp(bi
->pubkey_hash
, r_bootstrap
,
1076 SHA256_MAC_LEN
) == 0) {
1077 wpa_printf(MSG_DEBUG
,
1078 "DPP: Found matching own bootstrapping information");
1082 if (!peer_bi
&& !bi
->own
&&
1083 os_memcmp(bi
->pubkey_hash
, i_bootstrap
,
1084 SHA256_MAC_LEN
) == 0) {
1085 wpa_printf(MSG_DEBUG
,
1086 "DPP: Found matching peer bootstrapping information");
1090 if (own_bi
&& peer_bi
)
1095 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1096 "No matching own bootstrapping key found - ignore message");
1100 if (wpa_s
->dpp_auth
) {
1101 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1102 "Already in DPP authentication exchange - ignore new one");
1106 wpa_s
->dpp_gas_client
= 0;
1107 wpa_s
->dpp_auth_ok_on_ack
= 0;
1108 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
1109 wpa_s
->dpp_qr_mutual
,
1110 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
1111 if (!wpa_s
->dpp_auth
) {
1112 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
1115 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
1116 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
,
1117 wpa_s
->dpp_configurator_params
);
1118 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
1120 if (wpa_s
->dpp_listen_freq
&&
1121 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
1122 wpa_printf(MSG_DEBUG
,
1123 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
1124 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
1125 wpas_dpp_listen_stop(wpa_s
);
1128 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1129 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
1130 DPP_PA_AUTHENTICATION_RESP
);
1131 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
1132 src
, wpa_s
->own_addr
, broadcast
,
1133 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
1134 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
1135 500, wpas_dpp_tx_status
, 0);
1139 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
1141 /* TODO: stop wait and start ROC */
1145 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
1146 struct dpp_authentication
*auth
)
1148 struct wpa_ssid
*ssid
;
1150 ssid
= wpa_config_add_network(wpa_s
->conf
);
1153 wpas_notify_network_added(wpa_s
, ssid
);
1154 wpa_config_set_network_defaults(ssid
);
1157 ssid
->ssid
= os_malloc(auth
->ssid_len
);
1160 os_memcpy(ssid
->ssid
, auth
->ssid
, auth
->ssid_len
);
1161 ssid
->ssid_len
= auth
->ssid_len
;
1163 if (auth
->connector
) {
1164 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
1165 ssid
->ieee80211w
= 1;
1166 ssid
->dpp_connector
= os_strdup(auth
->connector
);
1167 if (!ssid
->dpp_connector
)
1171 if (auth
->c_sign_key
) {
1172 ssid
->dpp_csign
= os_malloc(wpabuf_len(auth
->c_sign_key
));
1173 if (!ssid
->dpp_csign
)
1175 os_memcpy(ssid
->dpp_csign
, wpabuf_head(auth
->c_sign_key
),
1176 wpabuf_len(auth
->c_sign_key
));
1177 ssid
->dpp_csign_len
= wpabuf_len(auth
->c_sign_key
);
1180 if (auth
->net_access_key
) {
1181 ssid
->dpp_netaccesskey
=
1182 os_malloc(wpabuf_len(auth
->net_access_key
));
1183 if (!ssid
->dpp_netaccesskey
)
1185 os_memcpy(ssid
->dpp_netaccesskey
,
1186 wpabuf_head(auth
->net_access_key
),
1187 wpabuf_len(auth
->net_access_key
));
1188 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
1189 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
1192 if (!auth
->connector
) {
1194 if (auth
->akm
== DPP_AKM_PSK
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1195 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
1196 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
1197 if (auth
->akm
== DPP_AKM_SAE
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1198 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
1199 WPA_KEY_MGMT_FT_SAE
;
1200 ssid
->ieee80211w
= 1;
1201 if (auth
->passphrase
[0]) {
1202 if (wpa_config_set_quoted(ssid
, "psk",
1203 auth
->passphrase
) < 0)
1205 wpa_config_update_psk(ssid
);
1206 ssid
->export_keys
= 1;
1208 ssid
->psk_set
= auth
->psk_set
;
1209 os_memcpy(ssid
->psk
, auth
->psk
, PMK_LEN
);
1215 wpas_notify_network_removed(wpa_s
, ssid
);
1216 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1221 static void wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
1222 struct dpp_authentication
*auth
)
1224 struct wpa_ssid
*ssid
;
1226 if (wpa_s
->conf
->dpp_config_processing
< 1)
1229 ssid
= wpas_dpp_add_network(wpa_s
, auth
);
1233 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1234 if (wpa_s
->conf
->dpp_config_processing
< 2)
1237 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
1239 wpa_s
->disconnected
= 0;
1240 wpa_s
->reassociate
= 1;
1241 wpa_s
->scan_runs
= 0;
1242 wpa_s
->normal_scans
= 0;
1243 wpa_supplicant_cancel_sched_scan(wpa_s
);
1244 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1248 static void wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1249 struct dpp_authentication
*auth
)
1251 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1253 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1254 wpa_ssid_txt(auth
->ssid
, auth
->ssid_len
));
1255 if (auth
->connector
) {
1256 /* TODO: Save the Connector and consider using a command
1257 * to fetch the value instead of sending an event with
1258 * it. The Connector could end up being larger than what
1259 * most clients are ready to receive as an event
1261 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1264 if (auth
->c_sign_key
) {
1268 hexlen
= 2 * wpabuf_len(auth
->c_sign_key
) + 1;
1269 hex
= os_malloc(hexlen
);
1271 wpa_snprintf_hex(hex
, hexlen
,
1272 wpabuf_head(auth
->c_sign_key
),
1273 wpabuf_len(auth
->c_sign_key
));
1274 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1279 if (auth
->net_access_key
) {
1283 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1284 hex
= os_malloc(hexlen
);
1286 wpa_snprintf_hex(hex
, hexlen
,
1287 wpabuf_head(auth
->net_access_key
),
1288 wpabuf_len(auth
->net_access_key
));
1289 if (auth
->net_access_key_expiry
)
1290 wpa_msg(wpa_s
, MSG_INFO
,
1291 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1293 auth
->net_access_key_expiry
);
1295 wpa_msg(wpa_s
, MSG_INFO
,
1296 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1301 wpas_dpp_process_config(wpa_s
, auth
);
1305 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1306 enum gas_query_result result
,
1307 const struct wpabuf
*adv_proto
,
1308 const struct wpabuf
*resp
, u16 status_code
)
1310 struct wpa_supplicant
*wpa_s
= ctx
;
1312 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1314 if (!auth
|| !auth
->auth_success
) {
1315 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1318 if (!resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1319 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1323 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1325 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1328 if (wpabuf_len(adv_proto
) != 10 ||
1329 !(pos
= wpabuf_head(adv_proto
)) ||
1330 pos
[0] != WLAN_EID_ADV_PROTO
||
1332 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1334 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1337 wpa_printf(MSG_DEBUG
,
1338 "DPP: Not a DPP Advertisement Protocol ID");
1342 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1343 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1347 wpas_dpp_handle_config_obj(wpa_s
, auth
);
1348 dpp_auth_deinit(wpa_s
->dpp_auth
);
1349 wpa_s
->dpp_auth
= NULL
;
1353 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1354 dpp_auth_deinit(wpa_s
->dpp_auth
);
1355 wpa_s
->dpp_auth
= NULL
;
1359 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1361 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1362 struct wpabuf
*buf
, *conf_req
;
1366 wpa_s
->dpp_gas_client
= 1;
1367 os_snprintf(json
, sizeof(json
),
1368 "{\"name\":\"Test\","
1369 "\"wi-fi_tech\":\"infra\","
1370 "\"netRole\":\"%s\"}",
1371 wpa_s
->dpp_netrole_ap
? "ap" : "sta");
1372 #ifdef CONFIG_TESTING_OPTIONS
1373 if (dpp_test
== DPP_TEST_INVALID_CONFIG_ATTR_OBJ_CONF_REQ
) {
1374 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Config Attr");
1375 json
[29] = 'k'; /* replace "infra" with "knfra" */
1377 #endif /* CONFIG_TESTING_OPTIONS */
1378 wpa_printf(MSG_DEBUG
, "DPP: GAS Config Attributes: %s", json
);
1380 offchannel_send_action_done(wpa_s
);
1381 wpas_dpp_listen_stop(wpa_s
);
1383 conf_req
= dpp_build_conf_req(auth
, json
);
1385 wpa_printf(MSG_DEBUG
,
1386 "DPP: No configuration request data available");
1390 buf
= gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req
));
1392 wpabuf_free(conf_req
);
1396 /* Advertisement Protocol IE */
1397 wpabuf_put_u8(buf
, WLAN_EID_ADV_PROTO
);
1398 wpabuf_put_u8(buf
, 8); /* Length */
1399 wpabuf_put_u8(buf
, 0x7f);
1400 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
1401 wpabuf_put_u8(buf
, 5);
1402 wpabuf_put_be24(buf
, OUI_WFA
);
1403 wpabuf_put_u8(buf
, DPP_OUI_TYPE
);
1404 wpabuf_put_u8(buf
, 0x01);
1407 wpabuf_put_le16(buf
, wpabuf_len(conf_req
));
1408 wpabuf_put_buf(buf
, conf_req
);
1409 wpabuf_free(conf_req
);
1411 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1412 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1414 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1415 buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1417 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1420 wpa_printf(MSG_DEBUG
,
1421 "DPP: GAS query started with dialog token %u", res
);
1426 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1428 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1429 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1431 if (wpa_s
->dpp_auth
->configurator
)
1432 wpas_dpp_start_gas_server(wpa_s
);
1434 wpas_dpp_start_gas_client(wpa_s
);
1438 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1439 const u8
*hdr
, const u8
*buf
, size_t len
,
1442 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1445 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1446 " (freq %u MHz)", MAC2STR(src
), freq
);
1449 wpa_printf(MSG_DEBUG
,
1450 "DPP: No DPP Authentication in progress - drop");
1454 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1455 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1456 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1457 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1461 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1463 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1464 wpa_printf(MSG_DEBUG
,
1465 "DPP: Responder accepted request for different negotiation channel");
1466 auth
->curr_freq
= freq
;
1469 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1470 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1472 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1473 wpa_printf(MSG_DEBUG
,
1474 "DPP: Start wait for full response");
1475 offchannel_send_action_done(wpa_s
);
1476 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1479 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1482 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1484 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1485 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1486 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1487 src
, wpa_s
->own_addr
, broadcast
,
1488 wpabuf_head(msg
), wpabuf_len(msg
),
1489 500, wpas_dpp_tx_status
, 0);
1491 wpa_s
->dpp_auth_ok_on_ack
= 1;
1495 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1496 const u8
*hdr
, const u8
*buf
, size_t len
)
1498 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1500 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1504 wpa_printf(MSG_DEBUG
,
1505 "DPP: No DPP Authentication in progress - drop");
1509 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1510 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1511 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1515 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1516 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1520 wpas_dpp_auth_success(wpa_s
, 0);
1524 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1526 const u8
*buf
, size_t len
)
1528 struct wpa_ssid
*ssid
;
1529 const u8
*connector
, *trans_id
, *status
;
1530 u16 connector_len
, trans_id_len
, status_len
;
1531 struct dpp_introduction intro
;
1532 struct rsn_pmksa_cache_entry
*entry
;
1534 struct os_reltime rnow
;
1536 unsigned int seconds
;
1537 enum dpp_status_error res
;
1539 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1541 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1542 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1543 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1544 MACSTR
" - drop", MAC2STR(src
));
1547 offchannel_send_action_done(wpa_s
);
1549 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1550 if (ssid
== wpa_s
->dpp_intro_network
)
1553 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1555 wpa_printf(MSG_DEBUG
,
1556 "DPP: Profile not found for network introduction");
1560 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1562 if (!trans_id
|| trans_id_len
!= 1) {
1563 wpa_printf(MSG_DEBUG
,
1564 "DPP: Peer did not include Transaction ID");
1565 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1566 " fail=missing_transaction_id", MAC2STR(src
));
1569 if (trans_id
[0] != TRANSACTION_ID
) {
1570 wpa_printf(MSG_DEBUG
,
1571 "DPP: Ignore frame with unexpected Transaction ID %u",
1573 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1574 " fail=transaction_id_mismatch", MAC2STR(src
));
1578 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1579 if (!status
|| status_len
!= 1) {
1580 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1581 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1582 " fail=missing_status", MAC2STR(src
));
1585 if (status
[0] != DPP_STATUS_OK
) {
1586 wpa_printf(MSG_DEBUG
,
1587 "DPP: Peer rejected network introduction: Status %u",
1589 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1590 " status=%u", MAC2STR(src
), status
[0]);
1594 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1596 wpa_printf(MSG_DEBUG
,
1597 "DPP: Peer did not include its Connector");
1598 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1599 " fail=missing_connector", MAC2STR(src
));
1603 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1604 ssid
->dpp_netaccesskey
,
1605 ssid
->dpp_netaccesskey_len
,
1607 ssid
->dpp_csign_len
,
1608 connector
, connector_len
, &expiry
);
1609 if (res
!= DPP_STATUS_OK
) {
1610 wpa_printf(MSG_INFO
,
1611 "DPP: Network Introduction protocol resulted in failure");
1612 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1613 " fail=peer_connector_validation_failed", MAC2STR(src
));
1617 entry
= os_zalloc(sizeof(*entry
));
1620 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1621 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1622 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1623 entry
->pmk_len
= intro
.pmk_len
;
1624 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1627 seconds
= expiry
- now
.sec
;
1629 seconds
= 86400 * 7;
1631 os_get_reltime(&rnow
);
1632 entry
->expiration
= rnow
.sec
+ seconds
;
1633 entry
->reauth_time
= rnow
.sec
+ seconds
;
1634 entry
->network_ctx
= ssid
;
1635 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1637 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1638 " status=%u", MAC2STR(src
), status
[0]);
1640 wpa_printf(MSG_DEBUG
,
1641 "DPP: Try connection again after successful network introduction");
1642 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1643 wpa_supplicant_cancel_sched_scan(wpa_s
);
1644 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1647 os_memset(&intro
, 0, sizeof(intro
));
1651 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1653 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1654 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1656 if (!pkex
|| !pkex
->exchange_req
)
1658 if (pkex
->exch_req_tries
>= 5) {
1659 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1660 "No response from PKEX peer");
1661 dpp_pkex_free(pkex
);
1662 wpa_s
->dpp_pkex
= NULL
;
1666 pkex
->exch_req_tries
++;
1667 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1668 pkex
->exch_req_tries
);
1669 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1670 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1671 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1672 wpa_s
->own_addr
, broadcast
,
1673 wpabuf_head(pkex
->exchange_req
),
1674 wpabuf_len(pkex
->exchange_req
),
1675 pkex
->exch_req_wait_time
,
1676 wpas_dpp_tx_pkex_status
, 0);
1681 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1682 unsigned int freq
, const u8
*dst
,
1683 const u8
*src
, const u8
*bssid
,
1684 const u8
*data
, size_t data_len
,
1685 enum offchannel_send_action_result result
)
1687 const char *res_txt
;
1688 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1690 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1691 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1693 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1694 " result=%s (PKEX)",
1695 freq
, MAC2STR(dst
), res_txt
);
1696 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1697 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1700 wpa_printf(MSG_DEBUG
,
1701 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1706 wpa_printf(MSG_DEBUG
,
1707 "DPP: Terminate PKEX exchange due to an earlier error");
1708 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1709 pkex
->own_bi
->pkex_t
= pkex
->t
;
1710 dpp_pkex_free(pkex
);
1711 wpa_s
->dpp_pkex
= NULL
;
1715 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1716 /* Wait for PKEX Exchange Response frame and retry request if
1717 * no response is seen. */
1718 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1719 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1720 (pkex
->exch_req_wait_time
% 1000) * 1000,
1721 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1728 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1729 const u8
*buf
, size_t len
, unsigned int freq
)
1732 unsigned int wait_time
;
1734 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1737 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1740 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1741 wpa_printf(MSG_DEBUG
,
1742 "DPP: No PKEX code configured - ignore request");
1746 if (wpa_s
->dpp_pkex
) {
1747 /* TODO: Support parallel operations */
1748 wpa_printf(MSG_DEBUG
,
1749 "DPP: Already in PKEX session - ignore new request");
1753 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1754 wpa_s
->own_addr
, src
,
1755 wpa_s
->dpp_pkex_identifier
,
1756 wpa_s
->dpp_pkex_code
,
1758 if (!wpa_s
->dpp_pkex
) {
1759 wpa_printf(MSG_DEBUG
,
1760 "DPP: Failed to process the request - ignore it");
1764 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1765 wait_time
= wpa_s
->max_remain_on_chan
;
1766 if (wait_time
> 2000)
1768 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1769 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1770 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1772 wpabuf_head(msg
), wpabuf_len(msg
),
1773 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1778 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1779 const u8
*buf
, size_t len
, unsigned int freq
)
1782 unsigned int wait_time
;
1784 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1787 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1790 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1791 wpa_s
->dpp_pkex
->exchange_done
) {
1792 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1796 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1797 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
1799 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, src
, buf
, len
);
1801 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1805 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1808 wait_time
= wpa_s
->max_remain_on_chan
;
1809 if (wait_time
> 2000)
1811 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1812 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1813 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1815 wpabuf_head(msg
), wpabuf_len(msg
),
1816 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1821 static struct dpp_bootstrap_info
*
1822 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
1825 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1826 struct dpp_bootstrap_info
*bi
;
1828 bi
= os_zalloc(sizeof(*bi
));
1831 bi
->id
= wpas_dpp_next_id(wpa_s
);
1832 bi
->type
= DPP_BOOTSTRAP_PKEX
;
1833 os_memcpy(bi
->mac_addr
, peer
, ETH_ALEN
);
1836 bi
->curve
= pkex
->own_bi
->curve
;
1837 bi
->pubkey
= pkex
->peer_bootstrap_key
;
1838 pkex
->peer_bootstrap_key
= NULL
;
1839 dpp_pkex_free(pkex
);
1840 wpa_s
->dpp_pkex
= NULL
;
1841 if (dpp_bootstrap_key_hash(bi
) < 0) {
1842 dpp_bootstrap_info_free(bi
);
1845 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
1851 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1852 const u8
*hdr
, const u8
*buf
, size_t len
,
1856 unsigned int wait_time
;
1857 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1859 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1862 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1863 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1867 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1869 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1871 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
1872 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1873 pkex
->own_bi
->pkex_t
= pkex
->t
;
1874 dpp_pkex_free(wpa_s
->dpp_pkex
);
1875 wpa_s
->dpp_pkex
= NULL
;
1880 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1881 MACSTR
, MAC2STR(src
));
1883 wait_time
= wpa_s
->max_remain_on_chan
;
1884 if (wait_time
> 2000)
1886 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1887 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
1888 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1890 wpabuf_head(msg
), wpabuf_len(msg
),
1891 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1894 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1899 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1900 const u8
*hdr
, const u8
*buf
, size_t len
,
1904 struct dpp_bootstrap_info
*bi
;
1905 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1908 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
1911 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
1912 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1916 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
1918 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1922 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
1926 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
1928 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
1929 wpa_printf(MSG_DEBUG
,
1930 "DPP: Start authentication after PKEX with parameters: %s",
1932 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
1933 wpa_printf(MSG_DEBUG
,
1934 "DPP: Authentication initialization failed");
1940 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1941 const u8
*buf
, size_t len
, unsigned int freq
)
1944 enum dpp_public_action_frame_type type
;
1946 unsigned int pkex_t
;
1948 if (len
< DPP_HDR_LEN
)
1950 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
1955 crypto_suite
= *buf
++;
1959 wpa_printf(MSG_DEBUG
,
1960 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1962 crypto_suite
, type
, MAC2STR(src
), freq
);
1963 if (crypto_suite
!= 1) {
1964 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
1966 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1967 " freq=%u type=%d ignore=unsupported-crypto-suite",
1968 MAC2STR(src
), freq
, type
);
1971 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
1972 if (dpp_check_attrs(buf
, len
) < 0) {
1973 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1974 " freq=%u type=%d ignore=invalid-attributes",
1975 MAC2STR(src
), freq
, type
);
1978 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
1979 MAC2STR(src
), freq
, type
);
1982 case DPP_PA_AUTHENTICATION_REQ
:
1983 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
1985 case DPP_PA_AUTHENTICATION_RESP
:
1986 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
1988 case DPP_PA_AUTHENTICATION_CONF
:
1989 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
1991 case DPP_PA_PEER_DISCOVERY_RESP
:
1992 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
1994 case DPP_PA_PKEX_EXCHANGE_REQ
:
1995 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
1997 case DPP_PA_PKEX_EXCHANGE_RESP
:
1998 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
2000 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
2001 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
2004 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
2005 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
2009 wpa_printf(MSG_DEBUG
,
2010 "DPP: Ignored unsupported frame subtype %d", type
);
2014 if (wpa_s
->dpp_pkex
)
2015 pkex_t
= wpa_s
->dpp_pkex
->t
;
2016 else if (wpa_s
->dpp_pkex_bi
)
2017 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
2020 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
2021 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
2022 wpas_dpp_pkex_remove(wpa_s
, "*");
2027 static struct wpabuf
*
2028 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
2031 struct wpa_supplicant
*wpa_s
= ctx
;
2032 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2033 struct wpabuf
*resp
;
2035 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
2037 if (!auth
|| !auth
->auth_success
||
2038 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
2039 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
2042 wpa_hexdump(MSG_DEBUG
,
2043 "DPP: Received Configuration Request (GAS Query Request)",
2045 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
2047 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2053 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
2055 struct wpa_supplicant
*wpa_s
= ctx
;
2056 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2063 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
2065 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2066 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2067 offchannel_send_action_done(wpa_s
);
2068 wpas_dpp_listen_stop(wpa_s
);
2070 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
2072 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2073 dpp_auth_deinit(wpa_s
->dpp_auth
);
2074 wpa_s
->dpp_auth
= NULL
;
2079 static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant
*wpa_s
)
2081 struct dpp_configurator
*conf
;
2082 unsigned int max_id
= 0;
2084 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
2085 struct dpp_configurator
, list
) {
2086 if (conf
->id
> max_id
)
2093 int wpas_dpp_configurator_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2098 size_t privkey_len
= 0;
2100 struct dpp_configurator
*conf
= NULL
;
2102 curve
= get_param(cmd
, " curve=");
2103 key
= get_param(cmd
, " key=");
2106 privkey_len
= os_strlen(key
) / 2;
2107 privkey
= os_malloc(privkey_len
);
2109 hexstr2bin(key
, privkey
, privkey_len
) < 0)
2113 conf
= dpp_keygen_configurator(curve
, privkey
, privkey_len
);
2117 conf
->id
= wpas_dpp_next_configurator_id(wpa_s
);
2118 dl_list_add(&wpa_s
->dpp_configurator
, &conf
->list
);
2123 str_clear_free(key
);
2124 bin_clear_free(privkey
, privkey_len
);
2125 dpp_configurator_free(conf
);
2130 static int dpp_configurator_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
2132 struct dpp_configurator
*conf
, *tmp
;
2135 dl_list_for_each_safe(conf
, tmp
, &wpa_s
->dpp_configurator
,
2136 struct dpp_configurator
, list
) {
2137 if (id
&& conf
->id
!= id
)
2140 dl_list_del(&conf
->list
);
2141 dpp_configurator_free(conf
);
2145 return 0; /* flush succeeds regardless of entries found */
2146 return found
? 0 : -1;
2150 int wpas_dpp_configurator_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2152 unsigned int id_val
;
2154 if (os_strcmp(id
, "*") == 0) {
2162 return dpp_configurator_del(wpa_s
, id_val
);
2166 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2168 struct dpp_authentication
*auth
;
2172 auth
= os_zalloc(sizeof(*auth
));
2176 curve
= get_param(cmd
, " curve=");
2177 wpas_dpp_set_configurator(wpa_s
, auth
, cmd
);
2179 if (dpp_configurator_own_config(auth
, curve
, 0) == 0) {
2180 wpas_dpp_handle_config_obj(wpa_s
, auth
);
2184 dpp_auth_deinit(auth
);
2192 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
2193 unsigned int freq
, const u8
*dst
,
2194 const u8
*src
, const u8
*bssid
,
2195 const u8
*data
, size_t data_len
,
2196 enum offchannel_send_action_result result
)
2198 const char *res_txt
;
2200 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
2201 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
2203 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
2204 " result=%s (DPP Peer Discovery Request)",
2205 freq
, MAC2STR(dst
), res_txt
);
2206 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
2207 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
2208 /* TODO: Time out wait for response more quickly in error cases? */
2212 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
2213 struct wpa_bss
*bss
)
2217 unsigned int wait_time
;
2219 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
2220 return 0; /* Not using DPP AKM - continue */
2221 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
2222 return 0; /* PMKSA exists for DPP AKM - continue */
2224 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
2226 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2228 !ssid
->dpp_connector
? "Connector" :
2229 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2236 if (ssid
->dpp_netaccesskey_expiry
&&
2237 (os_time_t
) ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2238 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2239 "netAccessKey expired");
2243 wpa_printf(MSG_DEBUG
,
2244 "DPP: Starting network introduction protocol to derive PMKSA for "
2245 MACSTR
, MAC2STR(bss
->bssid
));
2247 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2248 5 + 4 + os_strlen(ssid
->dpp_connector
));
2252 #ifdef CONFIG_TESTING_OPTIONS
2253 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2254 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2257 #endif /* CONFIG_TESTING_OPTIONS */
2259 /* Transaction ID */
2260 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2261 wpabuf_put_le16(msg
, 1);
2262 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2264 #ifdef CONFIG_TESTING_OPTIONS
2266 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2267 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2268 goto skip_connector
;
2270 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2273 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2274 connector
= dpp_corrupt_connector_signature(
2275 ssid
->dpp_connector
);
2280 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2281 wpabuf_put_le16(msg
, os_strlen(connector
));
2282 wpabuf_put_str(msg
, connector
);
2284 goto skip_connector
;
2286 #endif /* CONFIG_TESTING_OPTIONS */
2289 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2290 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2291 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2293 #ifdef CONFIG_TESTING_OPTIONS
2295 #endif /* CONFIG_TESTING_OPTIONS */
2297 /* TODO: Timeout on AP response */
2298 wait_time
= wpa_s
->max_remain_on_chan
;
2299 if (wait_time
> 2000)
2301 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2302 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2303 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2305 wpabuf_head(msg
), wpabuf_len(msg
),
2306 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2309 /* Request this connection attempt to terminate - new one will be
2310 * started when network introduction protocol completes */
2311 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2312 wpa_s
->dpp_intro_network
= ssid
;
2317 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2319 struct dpp_bootstrap_info
*own_bi
;
2320 const char *pos
, *end
;
2321 unsigned int wait_time
;
2323 pos
= os_strstr(cmd
, " own=");
2327 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
2329 wpa_printf(MSG_DEBUG
,
2330 "DPP: Identified bootstrap info not found");
2333 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2334 wpa_printf(MSG_DEBUG
,
2335 "DPP: Identified bootstrap info not for PKEX");
2338 wpa_s
->dpp_pkex_bi
= own_bi
;
2339 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2341 os_free(wpa_s
->dpp_pkex_identifier
);
2342 wpa_s
->dpp_pkex_identifier
= NULL
;
2343 pos
= os_strstr(cmd
, " identifier=");
2346 end
= os_strchr(pos
, ' ');
2349 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2350 if (!wpa_s
->dpp_pkex_identifier
)
2352 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2353 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2356 pos
= os_strstr(cmd
, " code=");
2359 os_free(wpa_s
->dpp_pkex_code
);
2360 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2361 if (!wpa_s
->dpp_pkex_code
)
2364 if (os_strstr(cmd
, " init=1")) {
2365 struct dpp_pkex
*pkex
;
2368 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2369 dpp_pkex_free(wpa_s
->dpp_pkex
);
2370 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2371 wpa_s
->dpp_pkex_identifier
,
2372 wpa_s
->dpp_pkex_code
);
2373 pkex
= wpa_s
->dpp_pkex
;
2377 msg
= pkex
->exchange_req
;
2378 wait_time
= wpa_s
->max_remain_on_chan
;
2379 if (wait_time
> 2000)
2381 /* TODO: Support for 5 GHz channels */
2383 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2385 MAC2STR(broadcast
), pkex
->freq
,
2386 DPP_PA_PKEX_EXCHANGE_REQ
);
2387 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2388 wpa_s
->own_addr
, broadcast
,
2389 wpabuf_head(msg
), wpabuf_len(msg
),
2390 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2393 pkex
->exch_req_wait_time
= wait_time
;
2394 pkex
->exch_req_tries
= 1;
2397 /* TODO: Support multiple PKEX info entries */
2399 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2400 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2406 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2408 unsigned int id_val
;
2410 if (os_strcmp(id
, "*") == 0) {
2418 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2421 /* TODO: Support multiple PKEX entries */
2422 os_free(wpa_s
->dpp_pkex_code
);
2423 wpa_s
->dpp_pkex_code
= NULL
;
2424 os_free(wpa_s
->dpp_pkex_identifier
);
2425 wpa_s
->dpp_pkex_identifier
= NULL
;
2426 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2427 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2428 wpa_s
->dpp_pkex_bi
= NULL
;
2429 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2430 dpp_pkex_free(wpa_s
->dpp_pkex
);
2431 wpa_s
->dpp_pkex
= NULL
;
2436 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2438 dpp_auth_deinit(wpa_s
->dpp_auth
);
2439 wpa_s
->dpp_auth
= NULL
;
2443 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2447 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2448 adv_proto_id
[1] = 5;
2449 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2450 adv_proto_id
[5] = DPP_OUI_TYPE
;
2451 adv_proto_id
[6] = 0x01;
2453 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2454 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2455 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2457 dl_list_init(&wpa_s
->dpp_bootstrap
);
2458 dl_list_init(&wpa_s
->dpp_configurator
);
2459 wpa_s
->dpp_init_done
= 1;
2464 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2466 #ifdef CONFIG_TESTING_OPTIONS
2467 os_free(wpa_s
->dpp_config_obj_override
);
2468 wpa_s
->dpp_config_obj_override
= NULL
;
2469 os_free(wpa_s
->dpp_discovery_override
);
2470 wpa_s
->dpp_discovery_override
= NULL
;
2471 os_free(wpa_s
->dpp_groups_override
);
2472 wpa_s
->dpp_groups_override
= NULL
;
2473 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2474 #endif /* CONFIG_TESTING_OPTIONS */
2475 if (!wpa_s
->dpp_init_done
)
2477 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2478 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2479 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2480 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2481 offchannel_send_action_done(wpa_s
);
2482 wpas_dpp_listen_stop(wpa_s
);
2483 dpp_bootstrap_del(wpa_s
, 0);
2484 dpp_configurator_del(wpa_s
, 0);
2485 dpp_auth_deinit(wpa_s
->dpp_auth
);
2486 wpa_s
->dpp_auth
= NULL
;
2487 wpas_dpp_pkex_remove(wpa_s
, "*");
2488 wpa_s
->dpp_pkex
= NULL
;
2489 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2490 os_free(wpa_s
->dpp_configurator_params
);
2491 wpa_s
->dpp_configurator_params
= NULL
;