size_t len[2], siv_len, attr_len;
u8 *attr_start, *attr_end, *pos;
+ auth->waiting_auth_conf = 1;
+ auth->auth_resp_tries = 0;
+
/* Build DPP Authentication Response frame attributes */
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
4 + (pr ? wpabuf_len(pr) : 0) + 4 + sizeof(wrapped_data);
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
if (!msg)
return NULL;
- wpabuf_free(auth->resp_msg);
attr_start = wpabuf_put(msg, 0);
auth->k2);
if (!msg)
goto fail;
+ wpabuf_free(auth->resp_msg);
auth->resp_msg = msg;
ret = 0;
fail:
NULL, i_nonce, NULL, 0, auth->k1);
if (!msg)
return -1;
+ wpabuf_free(auth->resp_msg);
auth->resp_msg = msg;
return 0;
}
size_t unwrapped_len = 0;
u8 i_auth2[DPP_MAX_HASH_LEN];
+ auth->waiting_auth_conf = 0;
+
wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
&wrapped_data_len);
if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
}
+static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+ if (!auth || !auth->resp_msg)
+ return;
+
+ wpa_printf(MSG_DEBUG,
+ "DPP: Retry Authentication Response after timeout");
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
+ " freq=%u type=%d",
+ MAC2STR(auth->peer_mac_addr), auth->curr_freq,
+ DPP_PA_AUTHENTICATION_RESP);
+ offchannel_send_action(wpa_s, auth->curr_freq, auth->peer_mac_addr,
+ wpa_s->own_addr, broadcast,
+ wpabuf_head(auth->resp_msg),
+ wpabuf_len(auth->resp_msg),
+ 500, wpas_dpp_tx_status, 0);
+}
+
+
+static void wpas_dpp_auth_resp_retry(struct wpa_supplicant *wpa_s)
+{
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+ unsigned int wait_time, max_tries;
+
+ if (!auth || !auth->resp_msg)
+ return;
+
+ if (wpa_s->dpp_resp_max_tries)
+ max_tries = wpa_s->dpp_resp_max_tries;
+ else
+ max_tries = 5;
+ auth->auth_resp_tries++;
+ if (auth->auth_resp_tries >= max_tries) {
+ wpa_printf(MSG_INFO, "DPP: No confirm received from initiator - stopping exchange");
+ offchannel_send_action_done(wpa_s);
+ dpp_auth_deinit(wpa_s->dpp_auth);
+ wpa_s->dpp_auth = NULL;
+ return;
+ }
+
+ if (wpa_s->dpp_resp_retry_time)
+ wait_time = wpa_s->dpp_resp_retry_time;
+ else
+ wait_time = 10000;
+ wpa_printf(MSG_DEBUG,
+ "DPP: Schedule retransmission of Authentication Response frame in %u ms",
+ wait_time);
+ eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
+ eloop_register_timeout(wait_time / 1000,
+ (wait_time % 1000) * 1000,
+ wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
+}
+
+
static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
unsigned int freq, const u8 *dst,
const u8 *src, const u8 *bssid,
"DPP: Terminate authentication exchange due to an earlier error");
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
+ eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
+ NULL);
offchannel_send_action_done(wpa_s);
dpp_auth_deinit(wpa_s->dpp_auth);
wpa_s->dpp_auth = NULL;
wpas_dpp_auth_init_next(wpa_s);
return;
}
+ if (auth->waiting_auth_conf) {
+ wpas_dpp_auth_resp_retry(wpa_s);
+ return;
+ }
}
if (!wpa_s->dpp_auth_ok_on_ack && wpa_s->dpp_auth->neg_freq > 0 &&
if (wpa_s->dpp_auth) {
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
+ eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
+ NULL);
offchannel_send_action_done(wpa_s);
dpp_auth_deinit(wpa_s->dpp_auth);
}
wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
ok);
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
+ eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
if (ok)
return;
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
+ eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
dpp_bootstrap_del(wpa_s, 0);