2 * hostapd / DPP integration
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/wpa_ctrl.h"
17 #include "ap_drv_ops.h"
18 #include "gas_query_ap.h"
21 #include "dpp_hostapd.h"
24 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
25 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
26 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
27 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
29 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
33 * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
34 * @hapd: Pointer to hostapd_data
35 * @cmd: DPP URI read from a QR Code
36 * Returns: Identifier of the stored info or -1 on failure
38 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
40 struct dpp_bootstrap_info *bi;
41 struct dpp_authentication *auth = hapd->dpp_auth;
43 bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
47 if (auth && auth->response_pending &&
48 dpp_notify_new_qr_code(auth, bi) == 1) {
50 "DPP: Sending out pending authentication response");
51 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
53 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
54 DPP_PA_AUTHENTICATION_RESP);
55 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
57 wpabuf_head(hapd->dpp_auth->resp_msg),
58 wpabuf_len(hapd->dpp_auth->resp_msg));
65 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
68 struct hostapd_data *hapd = eloop_ctx;
69 struct dpp_authentication *auth = hapd->dpp_auth;
71 if (!auth || !auth->resp_msg)
75 "DPP: Retry Authentication Response after timeout");
76 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
78 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
79 DPP_PA_AUTHENTICATION_RESP);
80 hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
81 wpabuf_head(auth->resp_msg),
82 wpabuf_len(auth->resp_msg));
86 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
88 struct dpp_authentication *auth = hapd->dpp_auth;
89 unsigned int wait_time, max_tries;
91 if (!auth || !auth->resp_msg)
94 if (hapd->dpp_resp_max_tries)
95 max_tries = hapd->dpp_resp_max_tries;
98 auth->auth_resp_tries++;
99 if (auth->auth_resp_tries >= max_tries) {
101 "DPP: No confirm received from initiator - stopping exchange");
102 hostapd_drv_send_action_cancel_wait(hapd);
103 dpp_auth_deinit(hapd->dpp_auth);
104 hapd->dpp_auth = NULL;
108 if (hapd->dpp_resp_retry_time)
109 wait_time = hapd->dpp_resp_retry_time;
112 wpa_printf(MSG_DEBUG,
113 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
115 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
116 eloop_register_timeout(wait_time / 1000,
117 (wait_time % 1000) * 1000,
118 hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
122 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
123 const u8 *data, size_t data_len, int ok)
125 struct dpp_authentication *auth = hapd->dpp_auth;
127 wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
129 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
130 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
132 if (!hapd->dpp_auth) {
133 wpa_printf(MSG_DEBUG,
134 "DPP: Ignore TX status since there is no ongoing authentication exchange");
139 if (auth->connect_on_tx_status) {
140 wpa_printf(MSG_DEBUG,
141 "DPP: Complete exchange on configuration result");
142 dpp_auth_deinit(hapd->dpp_auth);
143 hapd->dpp_auth = NULL;
146 #endif /* CONFIG_DPP2 */
148 if (hapd->dpp_auth->remove_on_tx_status) {
149 wpa_printf(MSG_DEBUG,
150 "DPP: Terminate authentication exchange due to an earlier error");
151 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
152 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
154 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
156 hostapd_drv_send_action_cancel_wait(hapd);
157 dpp_auth_deinit(hapd->dpp_auth);
158 hapd->dpp_auth = NULL;
162 if (hapd->dpp_auth_ok_on_ack)
163 hostapd_dpp_auth_success(hapd, 1);
165 if (!is_broadcast_ether_addr(dst) && !ok) {
166 wpa_printf(MSG_DEBUG,
167 "DPP: Unicast DPP Action frame was not ACKed");
168 if (auth->waiting_auth_resp) {
169 /* In case of DPP Authentication Request frame, move to
170 * the next channel immediately. */
171 hostapd_drv_send_action_cancel_wait(hapd);
172 hostapd_dpp_auth_init_next(hapd);
175 if (auth->waiting_auth_conf) {
176 hostapd_dpp_auth_resp_retry(hapd);
181 if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
182 /* Allow timeout handling to stop iteration if no response is
183 * received from a peer that has ACKed a request. */
184 auth->auth_req_ack = 1;
187 if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
188 hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
189 wpa_printf(MSG_DEBUG,
190 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
191 hapd->dpp_auth->curr_freq,
192 hapd->dpp_auth->neg_freq);
193 hostapd_drv_send_action_cancel_wait(hapd);
195 if (hapd->dpp_auth->neg_freq !=
196 (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
197 /* TODO: Listen operation on non-operating channel */
199 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
200 hapd->dpp_auth->neg_freq, hapd->iface->freq);
204 if (hapd->dpp_auth_ok_on_ack)
205 hapd->dpp_auth_ok_on_ack = 0;
209 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
211 struct hostapd_data *hapd = eloop_ctx;
212 struct dpp_authentication *auth = hapd->dpp_auth;
214 struct os_reltime now, diff;
215 unsigned int wait_time, diff_ms;
217 if (!auth || !auth->waiting_auth_resp)
220 wait_time = hapd->dpp_resp_wait_time ?
221 hapd->dpp_resp_wait_time : 2000;
222 os_get_reltime(&now);
223 os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
224 diff_ms = diff.sec * 1000 + diff.usec / 1000;
225 wpa_printf(MSG_DEBUG,
226 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
229 if (auth->auth_req_ack && diff_ms >= wait_time) {
230 /* Peer ACK'ed Authentication Request frame, but did not reply
231 * with Authentication Response frame within two seconds. */
233 "DPP: No response received from responder - stopping initiation attempt");
234 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
235 hostapd_drv_send_action_cancel_wait(hapd);
236 hostapd_dpp_listen_stop(hapd);
237 dpp_auth_deinit(auth);
238 hapd->dpp_auth = NULL;
242 if (diff_ms >= wait_time) {
243 /* Authentication Request frame was not ACK'ed and no reply
244 * was receiving within two seconds. */
245 wpa_printf(MSG_DEBUG,
246 "DPP: Continue Initiator channel iteration");
247 hostapd_drv_send_action_cancel_wait(hapd);
248 hostapd_dpp_listen_stop(hapd);
249 hostapd_dpp_auth_init_next(hapd);
253 /* Driver did not support 2000 ms long wait_time with TX command, so
254 * schedule listen operation to continue waiting for the response.
256 * DPP listen operations continue until stopped, so simply schedule a
257 * new call to this function at the point when the two second reply
258 * wait has expired. */
259 wait_time -= diff_ms;
261 freq = auth->curr_freq;
262 if (auth->neg_freq > 0)
263 freq = auth->neg_freq;
264 wpa_printf(MSG_DEBUG,
265 "DPP: Continue reply wait on channel %u MHz for %u ms",
267 hapd->dpp_in_response_listen = 1;
269 if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
270 /* TODO: Listen operation on non-operating channel */
272 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
273 freq, hapd->iface->freq);
276 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
277 hostapd_dpp_reply_wait_timeout, hapd, NULL);
281 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
282 struct dpp_authentication *auth)
284 #ifdef CONFIG_TESTING_OPTIONS
285 if (hapd->dpp_config_obj_override)
286 auth->config_obj_override =
287 os_strdup(hapd->dpp_config_obj_override);
288 if (hapd->dpp_discovery_override)
289 auth->discovery_override =
290 os_strdup(hapd->dpp_discovery_override);
291 if (hapd->dpp_groups_override)
292 auth->groups_override = os_strdup(hapd->dpp_groups_override);
293 auth->ignore_netaccesskey_mismatch =
294 hapd->dpp_ignore_netaccesskey_mismatch;
295 #endif /* CONFIG_TESTING_OPTIONS */
299 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
301 struct hostapd_data *hapd = eloop_ctx;
305 wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
306 hostapd_dpp_auth_init_next(hapd);
310 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
312 struct dpp_authentication *auth = hapd->dpp_auth;
314 unsigned int wait_time, max_wait_time, freq, max_tries, used;
315 struct os_reltime now, diff;
320 if (auth->freq_idx == 0)
321 os_get_reltime(&hapd->dpp_init_iter_start);
323 if (auth->freq_idx >= auth->num_freq) {
324 auth->num_freq_iters++;
325 if (hapd->dpp_init_max_tries)
326 max_tries = hapd->dpp_init_max_tries;
329 if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
331 "DPP: No response received from responder - stopping initiation attempt");
332 wpa_msg(hapd->msg_ctx, MSG_INFO,
333 DPP_EVENT_AUTH_INIT_FAILED);
334 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
336 hostapd_drv_send_action_cancel_wait(hapd);
337 dpp_auth_deinit(hapd->dpp_auth);
338 hapd->dpp_auth = NULL;
342 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
343 if (hapd->dpp_init_retry_time)
344 wait_time = hapd->dpp_init_retry_time;
347 os_get_reltime(&now);
348 os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
349 used = diff.sec * 1000 + diff.usec / 1000;
350 if (used > wait_time)
354 wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
356 eloop_register_timeout(wait_time / 1000,
357 (wait_time % 1000) * 1000,
358 hostapd_dpp_init_timeout, hapd,
362 freq = auth->freq[auth->freq_idx++];
363 auth->curr_freq = freq;
365 if (is_zero_ether_addr(auth->peer_bi->mac_addr))
368 dst = auth->peer_bi->mac_addr;
369 hapd->dpp_auth_ok_on_ack = 0;
370 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
371 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
372 max_wait_time = hapd->dpp_resp_wait_time ?
373 hapd->dpp_resp_wait_time : 2000;
374 if (wait_time > max_wait_time)
375 wait_time = max_wait_time;
376 wait_time += 10; /* give the driver some extra time to complete */
377 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
378 hostapd_dpp_reply_wait_timeout, hapd, NULL);
380 if (auth->neg_freq > 0 && freq != auth->neg_freq) {
381 wpa_printf(MSG_DEBUG,
382 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
383 freq, auth->neg_freq);
385 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
387 MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
388 auth->auth_req_ack = 0;
389 os_get_reltime(&hapd->dpp_last_init);
390 return hostapd_drv_send_action(hapd, freq, wait_time,
392 wpabuf_head(hapd->dpp_auth->req_msg),
393 wpabuf_len(hapd->dpp_auth->req_msg));
397 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
400 struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
401 u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
402 unsigned int neg_freq = 0;
404 pos = os_strstr(cmd, " peer=");
408 peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
411 "DPP: Could not find bootstrapping info for the identified peer");
415 pos = os_strstr(cmd, " own=");
418 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
422 "DPP: Could not find bootstrapping info for the identified local entry");
426 if (peer_bi->curve != own_bi->curve) {
428 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
429 peer_bi->curve->name, own_bi->curve->name);
434 pos = os_strstr(cmd, " role=");
437 if (os_strncmp(pos, "configurator", 12) == 0)
438 allowed_roles = DPP_CAPAB_CONFIGURATOR;
439 else if (os_strncmp(pos, "enrollee", 8) == 0)
440 allowed_roles = DPP_CAPAB_ENROLLEE;
441 else if (os_strncmp(pos, "either", 6) == 0)
442 allowed_roles = DPP_CAPAB_CONFIGURATOR |
448 pos = os_strstr(cmd, " neg_freq=");
450 neg_freq = atoi(pos + 10);
452 if (hapd->dpp_auth) {
453 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
454 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
456 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
458 hostapd_drv_send_action_cancel_wait(hapd);
459 dpp_auth_deinit(hapd->dpp_auth);
462 hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi,
463 allowed_roles, neg_freq,
464 hapd->iface->hw_features,
465 hapd->iface->num_hw_features);
468 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
469 if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
470 hapd->dpp_auth, cmd) < 0) {
471 dpp_auth_deinit(hapd->dpp_auth);
472 hapd->dpp_auth = NULL;
476 hapd->dpp_auth->neg_freq = neg_freq;
478 if (!is_zero_ether_addr(peer_bi->mac_addr))
479 os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
482 return hostapd_dpp_auth_init_next(hapd);
488 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
496 if (os_strstr(cmd, " role=configurator"))
497 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
498 else if (os_strstr(cmd, " role=enrollee"))
499 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
501 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
503 hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
505 if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
506 /* TODO: Listen operation on non-operating channel */
508 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
509 freq, hapd->iface->freq);
517 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
519 /* TODO: Stop listen operation on non-operating channel */
523 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
524 const u8 *hdr, const u8 *buf, size_t len,
527 const u8 *r_bootstrap, *i_bootstrap;
528 u16 r_bootstrap_len, i_bootstrap_len;
529 struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
531 if (!hapd->iface->interfaces->dpp)
534 wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
537 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
539 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
540 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
541 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
544 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
545 r_bootstrap, r_bootstrap_len);
547 i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
549 if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
550 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
551 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
554 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
555 i_bootstrap, i_bootstrap_len);
557 /* Try to find own and peer bootstrapping key matches based on the
558 * received hash values */
559 dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
560 r_bootstrap, &own_bi, &peer_bi);
563 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
564 src, hdr, buf, len, freq, i_bootstrap,
568 #endif /* CONFIG_DPP2 */
570 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
571 "No matching own bootstrapping key found - ignore message");
575 if (hapd->dpp_auth) {
576 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
577 "Already in DPP authentication exchange - ignore new one");
581 hapd->dpp_auth_ok_on_ack = 0;
582 hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles,
584 peer_bi, own_bi, freq, hdr, buf, len);
585 if (!hapd->dpp_auth) {
586 wpa_printf(MSG_DEBUG, "DPP: No response generated");
589 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
590 if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
592 hapd->dpp_configurator_params) < 0) {
593 dpp_auth_deinit(hapd->dpp_auth);
594 hapd->dpp_auth = NULL;
597 os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
599 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
601 MAC2STR(src), hapd->dpp_auth->curr_freq,
602 DPP_PA_AUTHENTICATION_RESP);
603 hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
604 src, wpabuf_head(hapd->dpp_auth->resp_msg),
605 wpabuf_len(hapd->dpp_auth->resp_msg));
609 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
610 struct dpp_authentication *auth)
612 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
613 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
614 dpp_akm_str(auth->akm));
616 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
617 wpa_ssid_txt(auth->ssid, auth->ssid_len));
618 if (auth->connector) {
619 /* TODO: Save the Connector and consider using a command
620 * to fetch the value instead of sending an event with
621 * it. The Connector could end up being larger than what
622 * most clients are ready to receive as an event
624 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
626 } else if (auth->passphrase[0]) {
627 char hex[64 * 2 + 1];
629 wpa_snprintf_hex(hex, sizeof(hex),
630 (const u8 *) auth->passphrase,
631 os_strlen(auth->passphrase));
632 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
634 } else if (auth->psk_set) {
635 char hex[PMK_LEN * 2 + 1];
637 wpa_snprintf_hex(hex, sizeof(hex), auth->psk, PMK_LEN);
638 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
641 if (auth->c_sign_key) {
645 hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1;
646 hex = os_malloc(hexlen);
648 wpa_snprintf_hex(hex, hexlen,
649 wpabuf_head(auth->c_sign_key),
650 wpabuf_len(auth->c_sign_key));
651 wpa_msg(hapd->msg_ctx, MSG_INFO,
652 DPP_EVENT_C_SIGN_KEY "%s", hex);
656 if (auth->net_access_key) {
660 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
661 hex = os_malloc(hexlen);
663 wpa_snprintf_hex(hex, hexlen,
664 wpabuf_head(auth->net_access_key),
665 wpabuf_len(auth->net_access_key));
666 if (auth->net_access_key_expiry)
667 wpa_msg(hapd->msg_ctx, MSG_INFO,
668 DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
670 auth->net_access_key_expiry);
672 wpa_msg(hapd->msg_ctx, MSG_INFO,
673 DPP_EVENT_NET_ACCESS_KEY "%s", hex);
680 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
681 enum gas_query_ap_result result,
682 const struct wpabuf *adv_proto,
683 const struct wpabuf *resp, u16 status_code)
685 struct hostapd_data *hapd = ctx;
687 struct dpp_authentication *auth = hapd->dpp_auth;
688 enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
690 if (!auth || !auth->auth_success) {
691 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
694 if (!resp || status_code != WLAN_STATUS_SUCCESS) {
695 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
699 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
701 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
704 if (wpabuf_len(adv_proto) != 10 ||
705 !(pos = wpabuf_head(adv_proto)) ||
706 pos[0] != WLAN_EID_ADV_PROTO ||
708 pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
710 WPA_GET_BE24(&pos[5]) != OUI_WFA ||
713 wpa_printf(MSG_DEBUG,
714 "DPP: Not a DPP Advertisement Protocol ID");
718 if (dpp_conf_resp_rx(auth, resp) < 0) {
719 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
723 hostapd_dpp_handle_config_obj(hapd, auth);
724 status = DPP_STATUS_OK;
725 #ifdef CONFIG_TESTING_OPTIONS
726 if (dpp_test == DPP_TEST_REJECT_CONFIG) {
727 wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
728 status = DPP_STATUS_CONFIG_REJECTED;
730 #endif /* CONFIG_TESTING_OPTIONS */
732 if (status != DPP_STATUS_OK)
733 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
735 if (auth->peer_version >= 2 &&
736 auth->conf_resp_status == DPP_STATUS_OK) {
739 wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
740 msg = dpp_build_conf_result(auth, status);
744 wpa_msg(hapd->msg_ctx, MSG_INFO,
745 DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
746 MAC2STR(addr), auth->curr_freq,
747 DPP_PA_CONFIGURATION_RESULT);
748 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
749 addr, wpabuf_head(msg),
753 /* This exchange will be terminated in the TX status handler */
754 auth->connect_on_tx_status = 1;
758 #endif /* CONFIG_DPP2 */
759 dpp_auth_deinit(hapd->dpp_auth);
760 hapd->dpp_auth = NULL;
764 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
766 struct dpp_authentication *auth = hapd->dpp_auth;
772 os_snprintf(json, sizeof(json),
773 "{\"name\":\"Test\","
774 "\"wi-fi_tech\":\"infra\","
775 "\"netRole\":\"%s\"}",
776 netrole_ap ? "ap" : "sta");
777 wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json);
779 buf = dpp_build_conf_req(auth, json);
781 wpa_printf(MSG_DEBUG,
782 "DPP: No configuration request data available");
786 wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
787 MAC2STR(auth->peer_mac_addr), auth->curr_freq);
789 res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
790 buf, hostapd_dpp_gas_resp_cb, hapd);
792 wpa_msg(hapd->msg_ctx, MSG_DEBUG,
793 "GAS: Failed to send Query Request");
796 wpa_printf(MSG_DEBUG,
797 "DPP: GAS query started with dialog token %u", res);
802 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
804 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
805 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
807 #ifdef CONFIG_TESTING_OPTIONS
808 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
810 "DPP: TESTING - stop at Authentication Confirm");
811 if (hapd->dpp_auth->configurator) {
812 /* Prevent GAS response */
813 hapd->dpp_auth->auth_success = 0;
817 #endif /* CONFIG_TESTING_OPTIONS */
819 if (!hapd->dpp_auth->configurator)
820 hostapd_dpp_start_gas_client(hapd);
824 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
825 const u8 *hdr, const u8 *buf, size_t len,
828 struct dpp_authentication *auth = hapd->dpp_auth;
831 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
835 wpa_printf(MSG_DEBUG,
836 "DPP: No DPP Authentication in progress - drop");
840 if (!is_zero_ether_addr(auth->peer_mac_addr) &&
841 os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
842 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
843 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
847 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
849 if (auth->curr_freq != freq && auth->neg_freq == freq) {
850 wpa_printf(MSG_DEBUG,
851 "DPP: Responder accepted request for different negotiation channel");
852 auth->curr_freq = freq;
855 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
856 msg = dpp_auth_resp_rx(auth, hdr, buf, len);
858 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
859 wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
862 wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
865 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
867 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
868 " freq=%u type=%d", MAC2STR(src), auth->curr_freq,
869 DPP_PA_AUTHENTICATION_CONF);
870 hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
871 wpabuf_head(msg), wpabuf_len(msg));
873 hapd->dpp_auth_ok_on_ack = 1;
877 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
878 const u8 *hdr, const u8 *buf, size_t len)
880 struct dpp_authentication *auth = hapd->dpp_auth;
882 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
886 wpa_printf(MSG_DEBUG,
887 "DPP: No DPP Authentication in progress - drop");
891 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
892 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
893 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
897 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
898 wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
902 hostapd_dpp_auth_success(hapd, 0);
908 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
911 struct hostapd_data *hapd = eloop_ctx;
912 struct dpp_authentication *auth = hapd->dpp_auth;
914 if (!auth || !auth->waiting_conf_result)
917 wpa_printf(MSG_DEBUG,
918 "DPP: Timeout while waiting for Configuration Result");
919 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
920 dpp_auth_deinit(auth);
921 hapd->dpp_auth = NULL;
925 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
926 const u8 *hdr, const u8 *buf, size_t len)
928 struct dpp_authentication *auth = hapd->dpp_auth;
929 enum dpp_status_error status;
931 wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
934 if (!auth || !auth->waiting_conf_result) {
935 wpa_printf(MSG_DEBUG,
936 "DPP: No DPP Configuration waiting for result - drop");
940 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
941 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
942 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
946 status = dpp_conf_result_rx(auth, hdr, buf, len);
948 hostapd_drv_send_action_cancel_wait(hapd);
949 hostapd_dpp_listen_stop(hapd);
950 if (status == DPP_STATUS_OK)
951 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
953 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
954 dpp_auth_deinit(auth);
955 hapd->dpp_auth = NULL;
956 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
960 #endif /* CONFIG_DPP2 */
963 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
964 const u8 *src, unsigned int freq,
966 enum dpp_status_error status)
970 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP,
971 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector));
975 #ifdef CONFIG_TESTING_OPTIONS
976 if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
977 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
980 if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
981 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
984 #endif /* CONFIG_TESTING_OPTIONS */
987 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
988 wpabuf_put_le16(msg, 1);
989 wpabuf_put_u8(msg, trans_id);
991 #ifdef CONFIG_TESTING_OPTIONS
993 if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
994 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
997 if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
998 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1001 #endif /* CONFIG_TESTING_OPTIONS */
1004 wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1005 wpabuf_put_le16(msg, 1);
1006 wpabuf_put_u8(msg, status);
1008 #ifdef CONFIG_TESTING_OPTIONS
1010 if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1011 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1012 goto skip_connector;
1014 if (status == DPP_STATUS_OK &&
1015 dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1018 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1019 connector = dpp_corrupt_connector_signature(
1020 hapd->conf->dpp_connector);
1025 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1026 wpabuf_put_le16(msg, os_strlen(connector));
1027 wpabuf_put_str(msg, connector);
1029 goto skip_connector;
1031 #endif /* CONFIG_TESTING_OPTIONS */
1034 if (status == DPP_STATUS_OK) {
1035 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1036 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1037 wpabuf_put_str(msg, hapd->conf->dpp_connector);
1040 #ifdef CONFIG_TESTING_OPTIONS
1042 #endif /* CONFIG_TESTING_OPTIONS */
1044 wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
1045 " status=%d", MAC2STR(src), status);
1046 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1047 " freq=%u type=%d status=%d", MAC2STR(src), freq,
1048 DPP_PA_PEER_DISCOVERY_RESP, status);
1049 hostapd_drv_send_action(hapd, freq, 0, src,
1050 wpabuf_head(msg), wpabuf_len(msg));
1055 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
1057 const u8 *buf, size_t len,
1060 const u8 *connector, *trans_id;
1061 u16 connector_len, trans_id_len;
1063 struct dpp_introduction intro;
1066 enum dpp_status_error res;
1068 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
1070 if (!hapd->wpa_auth ||
1071 !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
1072 !(hapd->conf->wpa & WPA_PROTO_RSN)) {
1073 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
1077 if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
1078 !hapd->conf->dpp_csign) {
1079 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
1085 if (hapd->conf->dpp_netaccesskey_expiry &&
1086 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
1087 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
1091 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
1093 if (!trans_id || trans_id_len != 1) {
1094 wpa_printf(MSG_DEBUG,
1095 "DPP: Peer did not include Transaction ID");
1099 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
1101 wpa_printf(MSG_DEBUG,
1102 "DPP: Peer did not include its Connector");
1106 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
1107 wpabuf_head(hapd->conf->dpp_netaccesskey),
1108 wpabuf_len(hapd->conf->dpp_netaccesskey),
1109 wpabuf_head(hapd->conf->dpp_csign),
1110 wpabuf_len(hapd->conf->dpp_csign),
1111 connector, connector_len, &expire);
1113 wpa_printf(MSG_INFO,
1114 "DPP: Network Introduction protocol resulted in internal failure (peer "
1115 MACSTR ")", MAC2STR(src));
1118 if (res != DPP_STATUS_OK) {
1119 wpa_printf(MSG_INFO,
1120 "DPP: Network Introduction protocol resulted in failure (peer "
1121 MACSTR " status %d)", MAC2STR(src), res);
1122 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1127 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
1128 expire = hapd->conf->dpp_netaccesskey_expiry;
1130 expiration = expire - now.sec;
1134 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
1135 intro.pmkid, expiration,
1136 WPA_KEY_MGMT_DPP) < 0) {
1137 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
1141 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1147 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
1148 const u8 *buf, size_t len,
1153 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
1156 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1159 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
1160 wpa_printf(MSG_DEBUG,
1161 "DPP: No PKEX code configured - ignore request");
1165 if (hapd->dpp_pkex) {
1166 /* TODO: Support parallel operations */
1167 wpa_printf(MSG_DEBUG,
1168 "DPP: Already in PKEX session - ignore new request");
1172 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
1174 hapd->own_addr, src,
1175 hapd->dpp_pkex_identifier,
1176 hapd->dpp_pkex_code,
1178 if (!hapd->dpp_pkex) {
1179 wpa_printf(MSG_DEBUG,
1180 "DPP: Failed to process the request - ignore it");
1184 msg = hapd->dpp_pkex->exchange_resp;
1185 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1186 " freq=%u type=%d", MAC2STR(src), freq,
1187 DPP_PA_PKEX_EXCHANGE_RESP);
1188 hostapd_drv_send_action(hapd, freq, 0, src,
1189 wpabuf_head(msg), wpabuf_len(msg));
1190 if (hapd->dpp_pkex->failed) {
1191 wpa_printf(MSG_DEBUG,
1192 "DPP: Terminate PKEX exchange due to an earlier error");
1193 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1194 hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
1195 dpp_pkex_free(hapd->dpp_pkex);
1196 hapd->dpp_pkex = NULL;
1202 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
1203 const u8 *buf, size_t len, unsigned int freq)
1207 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
1210 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1213 if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
1214 hapd->dpp_pkex->exchange_done) {
1215 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1219 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
1221 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1225 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
1228 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1229 " freq=%u type=%d", MAC2STR(src), freq,
1230 DPP_PA_PKEX_COMMIT_REVEAL_REQ);
1231 hostapd_drv_send_action(hapd, freq, 0, src,
1232 wpabuf_head(msg), wpabuf_len(msg));
1238 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
1239 const u8 *hdr, const u8 *buf, size_t len,
1243 struct dpp_pkex *pkex = hapd->dpp_pkex;
1244 struct dpp_bootstrap_info *bi;
1246 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
1249 if (!pkex || pkex->initiator || !pkex->exchange_done) {
1250 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1254 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1256 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1257 if (hapd->dpp_pkex->failed) {
1258 wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
1259 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1260 hapd->dpp_pkex->own_bi->pkex_t =
1262 dpp_pkex_free(hapd->dpp_pkex);
1263 hapd->dpp_pkex = NULL;
1268 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
1269 MACSTR, MAC2STR(src));
1271 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1272 " freq=%u type=%d", MAC2STR(src), freq,
1273 DPP_PA_PKEX_COMMIT_REVEAL_RESP);
1274 hostapd_drv_send_action(hapd, freq, 0, src,
1275 wpabuf_head(msg), wpabuf_len(msg));
1278 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1281 hapd->dpp_pkex = NULL;
1286 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
1287 const u8 *hdr, const u8 *buf, size_t len,
1291 struct dpp_bootstrap_info *bi;
1292 struct dpp_pkex *pkex = hapd->dpp_pkex;
1295 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
1298 if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1299 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1303 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1305 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1309 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1312 hapd->dpp_pkex = NULL;
1314 os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
1316 hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
1317 wpa_printf(MSG_DEBUG,
1318 "DPP: Start authentication after PKEX with parameters: %s",
1320 if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
1321 wpa_printf(MSG_DEBUG,
1322 "DPP: Authentication initialization failed");
1328 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
1329 const u8 *buf, size_t len, unsigned int freq)
1332 enum dpp_public_action_frame_type type;
1334 unsigned int pkex_t;
1336 if (len < DPP_HDR_LEN)
1338 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
1343 crypto_suite = *buf++;
1347 wpa_printf(MSG_DEBUG,
1348 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1350 crypto_suite, type, MAC2STR(src), freq);
1351 if (crypto_suite != 1) {
1352 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
1354 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1355 " freq=%u type=%d ignore=unsupported-crypto-suite",
1356 MAC2STR(src), freq, type);
1359 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
1360 if (dpp_check_attrs(buf, len) < 0) {
1361 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1362 " freq=%u type=%d ignore=invalid-attributes",
1363 MAC2STR(src), freq, type);
1366 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1367 " freq=%u type=%d", MAC2STR(src), freq, type);
1370 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1371 src, hdr, buf, len, freq, NULL, NULL) == 0)
1373 #endif /* CONFIG_DPP2 */
1376 case DPP_PA_AUTHENTICATION_REQ:
1377 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
1379 case DPP_PA_AUTHENTICATION_RESP:
1380 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
1382 case DPP_PA_AUTHENTICATION_CONF:
1383 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
1385 case DPP_PA_PEER_DISCOVERY_REQ:
1386 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
1388 case DPP_PA_PKEX_EXCHANGE_REQ:
1389 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq);
1391 case DPP_PA_PKEX_EXCHANGE_RESP:
1392 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
1394 case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1395 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
1398 case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1399 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
1403 case DPP_PA_CONFIGURATION_RESULT:
1404 hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
1406 #endif /* CONFIG_DPP2 */
1408 wpa_printf(MSG_DEBUG,
1409 "DPP: Ignored unsupported frame subtype %d", type);
1414 pkex_t = hapd->dpp_pkex->t;
1415 else if (hapd->dpp_pkex_bi)
1416 pkex_t = hapd->dpp_pkex_bi->pkex_t;
1419 if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
1420 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
1421 hostapd_dpp_pkex_remove(hapd, "*");
1427 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
1428 const u8 *query, size_t query_len,
1429 const u8 *data, size_t data_len)
1431 struct dpp_authentication *auth = hapd->dpp_auth;
1432 struct wpabuf *resp;
1434 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
1435 if (!auth || !auth->auth_success ||
1436 os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
1438 if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
1440 /* Response will be forwarded once received over TCP */
1443 #endif /* CONFIG_DPP2 */
1444 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1447 wpa_hexdump(MSG_DEBUG,
1448 "DPP: Received Configuration Request (GAS Query Request)",
1450 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
1452 resp = dpp_conf_req_rx(auth, query, query_len);
1454 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1459 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
1461 struct dpp_authentication *auth = hapd->dpp_auth;
1466 wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
1468 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1469 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
1471 if (ok && auth->peer_version >= 2 &&
1472 auth->conf_resp_status == DPP_STATUS_OK) {
1473 wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
1474 auth->waiting_conf_result = 1;
1475 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1477 eloop_register_timeout(2, 0,
1478 hostapd_dpp_config_result_wait_timeout,
1482 #endif /* CONFIG_DPP2 */
1483 hostapd_drv_send_action_cancel_wait(hapd);
1486 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1488 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1489 dpp_auth_deinit(hapd->dpp_auth);
1490 hapd->dpp_auth = NULL;
1494 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
1496 struct dpp_authentication *auth;
1500 auth = os_zalloc(sizeof(*auth));
1504 curve = get_param(cmd, " curve=");
1505 hostapd_dpp_set_testing_options(hapd, auth);
1506 if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1508 dpp_configurator_own_config(auth, curve, 1) == 0) {
1509 hostapd_dpp_handle_config_obj(hapd, auth);
1513 dpp_auth_deinit(auth);
1520 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
1522 struct dpp_bootstrap_info *own_bi;
1523 const char *pos, *end;
1525 pos = os_strstr(cmd, " own=");
1529 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
1531 wpa_printf(MSG_DEBUG,
1532 "DPP: Identified bootstrap info not found");
1535 if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
1536 wpa_printf(MSG_DEBUG,
1537 "DPP: Identified bootstrap info not for PKEX");
1540 hapd->dpp_pkex_bi = own_bi;
1541 own_bi->pkex_t = 0; /* clear pending errors on new code */
1543 os_free(hapd->dpp_pkex_identifier);
1544 hapd->dpp_pkex_identifier = NULL;
1545 pos = os_strstr(cmd, " identifier=");
1548 end = os_strchr(pos, ' ');
1551 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
1552 if (!hapd->dpp_pkex_identifier)
1554 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
1555 hapd->dpp_pkex_identifier[end - pos] = '\0';
1558 pos = os_strstr(cmd, " code=");
1561 os_free(hapd->dpp_pkex_code);
1562 hapd->dpp_pkex_code = os_strdup(pos + 6);
1563 if (!hapd->dpp_pkex_code)
1566 if (os_strstr(cmd, " init=1")) {
1569 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
1570 dpp_pkex_free(hapd->dpp_pkex);
1571 hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
1573 hapd->dpp_pkex_identifier,
1574 hapd->dpp_pkex_code);
1575 if (!hapd->dpp_pkex)
1578 msg = hapd->dpp_pkex->exchange_req;
1579 /* TODO: Which channel to use? */
1580 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1581 " freq=%u type=%d", MAC2STR(broadcast), 2437,
1582 DPP_PA_PKEX_EXCHANGE_REQ);
1583 hostapd_drv_send_action(hapd, 2437, 0, broadcast,
1584 wpabuf_head(msg), wpabuf_len(msg));
1587 /* TODO: Support multiple PKEX info entries */
1589 os_free(hapd->dpp_pkex_auth_cmd);
1590 hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
1596 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
1598 unsigned int id_val;
1600 if (os_strcmp(id, "*") == 0) {
1608 if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
1611 /* TODO: Support multiple PKEX entries */
1612 os_free(hapd->dpp_pkex_code);
1613 hapd->dpp_pkex_code = NULL;
1614 os_free(hapd->dpp_pkex_identifier);
1615 hapd->dpp_pkex_identifier = NULL;
1616 os_free(hapd->dpp_pkex_auth_cmd);
1617 hapd->dpp_pkex_auth_cmd = NULL;
1618 hapd->dpp_pkex_bi = NULL;
1619 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
1620 dpp_pkex_free(hapd->dpp_pkex);
1621 hapd->dpp_pkex = NULL;
1626 void hostapd_dpp_stop(struct hostapd_data *hapd)
1628 dpp_auth_deinit(hapd->dpp_auth);
1629 hapd->dpp_auth = NULL;
1630 dpp_pkex_free(hapd->dpp_pkex);
1631 hapd->dpp_pkex = NULL;
1637 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
1638 const u8 *msg, size_t len)
1640 struct hostapd_data *hapd = ctx;
1643 wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
1644 MAC2STR(addr), freq);
1645 buf = os_malloc(2 + len);
1648 buf[0] = WLAN_ACTION_PUBLIC;
1649 buf[1] = WLAN_PA_VENDOR_SPECIFIC;
1650 os_memcpy(buf + 2, msg, len);
1651 hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
1656 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
1657 u8 dialog_token, int prot,
1660 struct hostapd_data *hapd = ctx;
1662 gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf);
1665 #endif /* CONFIG_DPP2 */
1668 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
1671 struct dpp_controller_conf *ctrl;
1672 struct dpp_relay_config config;
1674 os_memset(&config, 0, sizeof(config));
1675 config.cb_ctx = hapd;
1676 config.tx = hostapd_dpp_relay_tx;
1677 config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
1678 for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
1679 config.ipaddr = &ctrl->ipaddr;
1680 config.pkhash = ctrl->pkhash;
1681 if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
1685 #endif /* CONFIG_DPP2 */
1691 int hostapd_dpp_init(struct hostapd_data *hapd)
1693 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
1694 hapd->dpp_init_done = 1;
1695 return hostapd_dpp_add_controllers(hapd);
1699 void hostapd_dpp_deinit(struct hostapd_data *hapd)
1701 #ifdef CONFIG_TESTING_OPTIONS
1702 os_free(hapd->dpp_config_obj_override);
1703 hapd->dpp_config_obj_override = NULL;
1704 os_free(hapd->dpp_discovery_override);
1705 hapd->dpp_discovery_override = NULL;
1706 os_free(hapd->dpp_groups_override);
1707 hapd->dpp_groups_override = NULL;
1708 hapd->dpp_ignore_netaccesskey_mismatch = 0;
1709 #endif /* CONFIG_TESTING_OPTIONS */
1710 if (!hapd->dpp_init_done)
1712 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1713 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1714 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
1716 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1718 #endif /* CONFIG_DPP2 */
1719 dpp_auth_deinit(hapd->dpp_auth);
1720 hapd->dpp_auth = NULL;
1721 hostapd_dpp_pkex_remove(hapd, "*");
1722 hapd->dpp_pkex = NULL;
1723 os_free(hapd->dpp_configurator_params);
1724 hapd->dpp_configurator_params = NULL;