{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct sta_info *sta = user_data;
+ struct hostapd_data *hapd;
if (sta->sae->state != SAE_ACCEPTED) {
wpa_printf(MSG_DEBUG, "AUTH: Re-authenticate with " MACSTR
" (attempt %d) ",
MAC2STR(sta->addr), sta->sae_auth_retry);
+ wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_FAILURE "addr=" MACSTR,
+ MAC2STR(sta->addr));
if (sta->sae_auth_retry < MESH_AUTH_RETRY) {
mesh_rsn_auth_sae_sta(wpa_s, sta);
} else {
+ hapd = wpa_s->ifmsh->bss[0];
+
+ if (sta->sae_auth_retry > MESH_AUTH_RETRY) {
+ ap_free_sta(hapd, sta);
+ return;
+ }
+
/* block the STA if exceeded the number of attempts */
wpa_mesh_set_plink_state(wpa_s, sta, PLINK_BLOCKED);
sta->sae->state = SAE_NOTHING;
+ wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_BLOCKED "addr="
+ MACSTR " duration=%d",
+ MAC2STR(sta->addr),
+ hapd->conf->ap_max_inactivity);
}
sta->sae_auth_retry++;
}
static void mesh_rsn_deinit(struct mesh_rsn *rsn)
{
os_memset(rsn->mgtk, 0, sizeof(rsn->mgtk));
- wpa_deinit(rsn->auth);
+ if (rsn->auth)
+ wpa_deinit(rsn->auth);
}
if (__mesh_rsn_auth_init(mesh_rsn, wpa_s->own_addr) < 0) {
mesh_rsn_deinit(mesh_rsn);
+ os_free(mesh_rsn);
return NULL;
}
bss->wpa_auth = mesh_rsn->auth;
ie = wpa_auth_get_wpa_ie(mesh_rsn->auth, &ie_len);
- conf->ies = (u8 *) ie;
- conf->ie_len = ie_len;
+ conf->rsn_ie = (u8 *) ie;
+ conf->rsn_ie_len = ie_len;
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
{
struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
struct wpa_ssid *ssid = wpa_s->current_ssid;
+ struct rsn_pmksa_cache_entry *pmksa;
unsigned int rnd;
int ret;
return -1;
}
+ pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr);
+ if (pmksa) {
+ if (!sta->wpa_sm)
+ sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
+ sta->addr, NULL);
+ if (!sta->wpa_sm) {
+ wpa_printf(MSG_ERROR,
+ "mesh: Failed to initialize RSN state machine");
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "AUTH: Mesh PMKSA cache entry found for " MACSTR
+ " - try to use PMKSA caching instead of new SAE authentication",
+ MAC2STR(sta->addr));
+ wpa_auth_pmksa_set_to_sm(pmksa, sta->wpa_sm, hapd->wpa_auth,
+ sta->sae->pmkid, sta->sae->pmk);
+ sae_accept_sta(hapd, sta);
+ sta->mesh_sae_pmksa_caching = 1;
+ return 0;
+ }
+ sta->mesh_sae_pmksa_caching = 0;
+
if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta))
return -1;
if (ret)
return ret;
+ eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta);
rnd = rand() % MESH_AUTH_TIMEOUT;
eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
wpa_s, sta);
void mesh_rsn_get_pmkid(struct mesh_rsn *rsn, struct sta_info *sta, u8 *pmkid)
{
- /* don't expect wpa auth to cache the pmkid for now */
- rsn_pmkid(sta->sae->pmk, PMK_LEN, rsn->wpa_s->own_addr,
- sta->addr, pmkid,
- wpa_key_mgmt_sha256(wpa_auth_sta_key_mgmt(sta->wpa_sm)));
+ os_memcpy(pmkid, sta->sae->pmkid, SAE_PMKID_LEN);
}
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
struct ieee802_11_elems *elems, const u8 *cat,
+ const u8 *chosen_pmk,
const u8 *start, size_t elems_len)
{
int ret = 0;
const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
(elems->mic - 2) - cat };
+ if (!sta->sae) {
+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
+
+ if (!wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr)) {
+ wpa_printf(MSG_INFO,
+ "Mesh RSN: SAE is not prepared yet");
+ return -1;
+ }
+ mesh_rsn_auth_sae_sta(wpa_s, sta);
+ }
+
+ if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) {
+ wpa_msg(wpa_s, MSG_DEBUG,
+ "Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)");
+ return -1;
+ }
+
if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) {
wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie");
return -1;