diff options
Diffstat (limited to 'contrib/wpa/src/ap/wpa_auth_glue.c')
-rw-r--r-- | contrib/wpa/src/ap/wpa_auth_glue.c | 343 |
1 files changed, 287 insertions, 56 deletions
diff --git a/contrib/wpa/src/ap/wpa_auth_glue.c b/contrib/wpa/src/ap/wpa_auth_glue.c index 0800a874875a..3e992155395e 100644 --- a/contrib/wpa/src/ap/wpa_auth_glue.c +++ b/contrib/wpa/src/ap/wpa_auth_glue.c @@ -14,6 +14,7 @@ #include "common/ieee802_11_defs.h" #include "common/sae.h" #include "common/wpa_ctrl.h" +#include "common/ptksa_cache.h" #include "crypto/sha1.h" #include "eapol_auth/eapol_auth_sm.h" #include "eapol_auth/eapol_auth_sm_i.h" @@ -37,8 +38,11 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, struct hostapd_config *iconf, struct wpa_auth_config *wconf) { + int sae_pw_id; + os_memset(wconf, 0, sizeof(*wconf)); wconf->wpa = conf->wpa; + wconf->extended_key_id = conf->extended_key_id; wconf->wpa_key_mgmt = conf->wpa_key_mgmt; wconf->wpa_pairwise = conf->wpa_pairwise; wconf->wpa_group = conf->wpa_group; @@ -64,11 +68,10 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, wconf->ocv = conf->ocv; #endif /* CONFIG_OCV */ wconf->okc = conf->okc; -#ifdef CONFIG_IEEE80211W wconf->ieee80211w = conf->ieee80211w; + wconf->beacon_prot = conf->beacon_prot; wconf->group_mgmt_cipher = conf->group_mgmt_cipher; wconf->sae_require_mfp = conf->sae_require_mfp; -#endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_IEEE80211R_AP wconf->ssid_len = conf->ssid.ssid_len; if (wconf->ssid_len > SSID_MAX_LEN) @@ -107,9 +110,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, wconf->rsn_pairwise = WPA_CIPHER_CCMP; wconf->rsn_preauth = 0; wconf->disable_pmksa_caching = 1; -#ifdef CONFIG_IEEE80211W wconf->ieee80211w = 1; -#endif /* CONFIG_IEEE80211W */ } #endif /* CONFIG_HS20 */ #ifdef CONFIG_TESTING_OPTIONS @@ -122,6 +123,64 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, wpabuf_head(conf->own_ie_override), wconf->own_ie_override_len); } + if (conf->rsne_override_eapol && + wpabuf_len(conf->rsne_override_eapol) <= MAX_OWN_IE_OVERRIDE) { + wconf->rsne_override_eapol_set = 1; + wconf->rsne_override_eapol_len = + wpabuf_len(conf->rsne_override_eapol); + os_memcpy(wconf->rsne_override_eapol, + wpabuf_head(conf->rsne_override_eapol), + wconf->rsne_override_eapol_len); + } + if (conf->rsnxe_override_eapol && + wpabuf_len(conf->rsnxe_override_eapol) <= MAX_OWN_IE_OVERRIDE) { + wconf->rsnxe_override_eapol_set = 1; + wconf->rsnxe_override_eapol_len = + wpabuf_len(conf->rsnxe_override_eapol); + os_memcpy(wconf->rsnxe_override_eapol, + wpabuf_head(conf->rsnxe_override_eapol), + wconf->rsnxe_override_eapol_len); + } + if (conf->rsne_override_ft && + wpabuf_len(conf->rsne_override_ft) <= MAX_OWN_IE_OVERRIDE) { + wconf->rsne_override_ft_set = 1; + wconf->rsne_override_ft_len = + wpabuf_len(conf->rsne_override_ft); + os_memcpy(wconf->rsne_override_ft, + wpabuf_head(conf->rsne_override_ft), + wconf->rsne_override_ft_len); + } + if (conf->rsnxe_override_ft && + wpabuf_len(conf->rsnxe_override_ft) <= MAX_OWN_IE_OVERRIDE) { + wconf->rsnxe_override_ft_set = 1; + wconf->rsnxe_override_ft_len = + wpabuf_len(conf->rsnxe_override_ft); + os_memcpy(wconf->rsnxe_override_ft, + wpabuf_head(conf->rsnxe_override_ft), + wconf->rsnxe_override_ft_len); + } + if (conf->gtk_rsc_override && + wpabuf_len(conf->gtk_rsc_override) > 0 && + wpabuf_len(conf->gtk_rsc_override) <= WPA_KEY_RSC_LEN) { + os_memcpy(wconf->gtk_rsc_override, + wpabuf_head(conf->gtk_rsc_override), + wpabuf_len(conf->gtk_rsc_override)); + wconf->gtk_rsc_override_set = 1; + } + if (conf->igtk_rsc_override && + wpabuf_len(conf->igtk_rsc_override) > 0 && + wpabuf_len(conf->igtk_rsc_override) <= WPA_KEY_RSC_LEN) { + os_memcpy(wconf->igtk_rsc_override, + wpabuf_head(conf->igtk_rsc_override), + wpabuf_len(conf->igtk_rsc_override)); + wconf->igtk_rsc_override_set = 1; + } + wconf->ft_rsnxe_used = conf->ft_rsnxe_used; + wconf->oci_freq_override_eapol_m3 = conf->oci_freq_override_eapol_m3; + wconf->oci_freq_override_eapol_g1 = conf->oci_freq_override_eapol_g1; + wconf->oci_freq_override_ft_assoc = conf->oci_freq_override_ft_assoc; + wconf->oci_freq_override_fils_assoc = + conf->oci_freq_override_fils_assoc; #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_P2P os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4); @@ -134,6 +193,27 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, os_memcpy(wconf->fils_cache_id, conf->fils_cache_id, FILS_CACHE_ID_LEN); #endif /* CONFIG_FILS */ + wconf->sae_pwe = conf->sae_pwe; + sae_pw_id = hostapd_sae_pw_id_in_use(conf); + if (sae_pw_id == 2 && wconf->sae_pwe != 3) + wconf->sae_pwe = 1; + else if (sae_pw_id == 1 && wconf->sae_pwe == 0) + wconf->sae_pwe = 2; +#ifdef CONFIG_SAE_PK + wconf->sae_pk = hostapd_sae_pk_in_use(conf); +#endif /* CONFIG_SAE_PK */ +#ifdef CONFIG_OWE + wconf->owe_ptk_workaround = conf->owe_ptk_workaround; +#endif /* CONFIG_OWE */ + wconf->transition_disable = conf->transition_disable; +#ifdef CONFIG_DPP2 + wconf->dpp_pfs = conf->dpp_pfs; +#endif /* CONFIG_DPP2 */ +#ifdef CONFIG_PASN +#ifdef CONFIG_TESTING_OPTIONS + wconf->force_kdk_derivation = conf->force_kdk_derivation; +#endif /* CONFIG_TESTING_OPTIONS */ +#endif /* CONFIG_PASN */ } @@ -211,16 +291,15 @@ static void hostapd_wpa_auth_set_eapol(void *ctx, const u8 *addr, break; case WPA_EAPOL_keyRun: if (sta->eapol_sm) - sta->eapol_sm->keyRun = value ? TRUE : FALSE; + sta->eapol_sm->keyRun = value; break; case WPA_EAPOL_keyAvailable: if (sta->eapol_sm) - sta->eapol_sm->eap_if->eapKeyAvailable = - value ? TRUE : FALSE; + sta->eapol_sm->eap_if->eapKeyAvailable = value; break; case WPA_EAPOL_keyDone: if (sta->eapol_sm) - sta->eapol_sm->keyDone = value ? TRUE : FALSE; + sta->eapol_sm->keyDone = value; break; case WPA_EAPOL_inc_EapolFramesTx: if (sta->eapol_sm) @@ -357,19 +436,27 @@ static int hostapd_wpa_auth_get_msk(void *ctx, const u8 *addr, u8 *msk, static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, const u8 *addr, int idx, u8 *key, - size_t key_len) + size_t key_len, enum key_flag key_flag) { struct hostapd_data *hapd = ctx; const char *ifname = hapd->conf->iface; if (vlan_id > 0) { ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id); - if (ifname == NULL) - return -1; + if (!ifname) { + if (!(hapd->iface->drv_flags & + WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) + return -1; + ifname = hapd->conf->iface; + } } #ifdef CONFIG_TESTING_OPTIONS - if (addr && !is_broadcast_ether_addr(addr)) { + if (key_flag & KEY_FLAG_MODIFY) { + /* We are updating an already installed key. Don't overwrite + * the already stored key information with zeros. + */ + } else if (addr && !is_broadcast_ether_addr(addr)) { struct sta_info *sta; sta = ap_get_sta(hapd, addr); @@ -380,17 +467,23 @@ static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, os_memcpy(sta->last_tk, key, key_len); sta->last_tk_len = key_len; } -#ifdef CONFIG_IEEE80211W - } else if (alg == WPA_ALG_IGTK || + } else if (alg == WPA_ALG_BIP_CMAC_128 || alg == WPA_ALG_BIP_GMAC_128 || alg == WPA_ALG_BIP_GMAC_256 || alg == WPA_ALG_BIP_CMAC_256) { - hapd->last_igtk_alg = alg; - hapd->last_igtk_key_idx = idx; - if (key) - os_memcpy(hapd->last_igtk, key, key_len); - hapd->last_igtk_len = key_len; -#endif /* CONFIG_IEEE80211W */ + if (idx == 4 || idx == 5) { + hapd->last_igtk_alg = alg; + hapd->last_igtk_key_idx = idx; + if (key) + os_memcpy(hapd->last_igtk, key, key_len); + hapd->last_igtk_len = key_len; + } else if (idx == 6 || idx == 7) { + hapd->last_bigtk_alg = alg; + hapd->last_bigtk_key_idx = idx; + if (key) + os_memcpy(hapd->last_bigtk, key, key_len); + hapd->last_bigtk_len = key_len; + } } else { hapd->last_gtk_alg = alg; hapd->last_gtk_key_idx = idx; @@ -399,8 +492,8 @@ static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, hapd->last_gtk_len = key_len; } #endif /* CONFIG_TESTING_OPTIONS */ - return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, 1, NULL, 0, - key, key_len); + return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, vlan_id, 1, + NULL, 0, key, key_len, key_flag); } @@ -412,9 +505,9 @@ static int hostapd_wpa_auth_get_seqnum(void *ctx, const u8 *addr, int idx, } -static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr, - const u8 *data, size_t data_len, - int encrypt) +int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr, + const u8 *data, size_t data_len, + int encrypt) { struct hostapd_data *hapd = ctx; struct sta_info *sta; @@ -620,10 +713,6 @@ static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto, } #endif /* CONFIG_IEEE80211R_AP */ - if (hapd->driver && hapd->driver->send_ether) - return hapd->driver->send_ether(hapd->drv_priv, dst, - hapd->own_addr, proto, - data, data_len); if (hapd->l2 == NULL) return -1; @@ -685,6 +774,12 @@ static void hostapd_oui_deliver_later(void *eloop_ctx, void *timeout_ctx) dl_list_for_each_safe(data, n, &hapd->l2_oui_queue, struct oui_deliver_later_data, list) { oui_ctx = hostapd_wpa_get_oui(hapd, data->oui_suffix); + wpa_printf(MSG_DEBUG, "RRB(%s): %s src=" MACSTR " dst=" MACSTR + " oui_suffix=%u data_len=%u data=%p", + hapd->conf->iface, __func__, + MAC2STR(data->src_addr), MAC2STR(data->dst_addr), + data->oui_suffix, (unsigned int) data->data_len, + data); if (hapd->wpa_auth && oui_ctx) { eth_p_oui_deliver(oui_ctx, data->src_addr, data->dst_addr, @@ -709,16 +804,26 @@ static int hostapd_wpa_auth_oui_iter(struct hostapd_iface *iface, void *ctx) { struct wpa_auth_oui_iface_iter_data *idata = ctx; struct oui_deliver_later_data *data; - struct hostapd_data *hapd; + struct hostapd_data *hapd, *src_hapd = idata->src_hapd; size_t j; for (j = 0; j < iface->num_bss; j++) { hapd = iface->bss[j]; - if (hapd == idata->src_hapd) - continue; + if (hapd == src_hapd) + continue; /* don't deliver back to same interface */ + if (!wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) || + hapd->conf->ssid.ssid_len != + src_hapd->conf->ssid.ssid_len || + os_memcmp(hapd->conf->ssid.ssid, + src_hapd->conf->ssid.ssid, + hapd->conf->ssid.ssid_len) != 0 || + os_memcmp(hapd->conf->mobility_domain, + src_hapd->conf->mobility_domain, + MOBILITY_DOMAIN_ID_LEN) != 0) + continue; /* no matching FT SSID/mobility domain */ if (!is_multicast_ether_addr(idata->dst_addr) && os_memcmp(hapd->own_addr, idata->dst_addr, ETH_ALEN) != 0) - continue; + continue; /* destination address does not match */ /* defer eth_p_oui_deliver until next eloop step as this is * when it would be triggerd from reading from sock @@ -730,14 +835,20 @@ static int hostapd_wpa_auth_oui_iter(struct hostapd_iface *iface, void *ctx) data = os_zalloc(sizeof(*data) + idata->data_len); if (!data) return 1; + wpa_printf(MSG_DEBUG, + "RRB(%s): local delivery to %s dst=" MACSTR + " oui_suffix=%u data_len=%u data=%p", + src_hapd->conf->iface, hapd->conf->iface, + MAC2STR(idata->dst_addr), idata->oui_suffix, + (unsigned int) idata->data_len, data); - os_memcpy(data->src_addr, idata->src_hapd->own_addr, ETH_ALEN); + os_memcpy(data->src_addr, src_hapd->own_addr, ETH_ALEN); os_memcpy(data->dst_addr, idata->dst_addr, ETH_ALEN); os_memcpy(data + 1, idata->data, idata->data_len); data->data_len = idata->data_len; data->oui_suffix = idata->oui_suffix; - dl_list_add(&hapd->l2_oui_queue, &data->list); + dl_list_add_tail(&hapd->l2_oui_queue, &data->list); if (!eloop_is_timeout_registered(hostapd_oui_deliver_later, hapd, NULL)) @@ -745,7 +856,11 @@ static int hostapd_wpa_auth_oui_iter(struct hostapd_iface *iface, void *ctx) hostapd_oui_deliver_later, hapd, NULL); - return 1; + /* If dst_addr is a multicast address, do not return any + * non-zero value here. Otherwise, the iteration of + * for_each_interface() will be stopped. */ + if (!is_multicast_ether_addr(idata->dst_addr)) + return 1; } return 0; @@ -761,6 +876,10 @@ static int hostapd_wpa_auth_send_oui(void *ctx, const u8 *dst, u8 oui_suffix, struct hostapd_data *hapd = ctx; struct eth_p_oui_ctx *oui_ctx; + wpa_printf(MSG_DEBUG, "RRB(%s): send to dst=" MACSTR + " oui_suffix=%u data_len=%u", + hapd->conf->iface, MAC2STR(dst), oui_suffix, + (unsigned int) data_len); #ifdef CONFIG_IEEE80211R_AP if (hapd->iface->interfaces && hapd->iface->interfaces->for_each_interface) { @@ -799,31 +918,58 @@ static int hostapd_channel_info(void *ctx, struct wpa_channel_info *ci) } +#ifdef CONFIG_PASN + +static void hostapd_store_ptksa(void *ctx, const u8 *addr,int cipher, + u32 life_time, const struct wpa_ptk *ptk) +{ + struct hostapd_data *hapd = ctx; + + ptksa_cache_add(hapd->ptksa, addr, cipher, life_time, ptk); +} + + +static void hostapd_clear_ptksa(void *ctx, const u8 *addr, int cipher) +{ + struct hostapd_data *hapd = ctx; + + ptksa_cache_flush(hapd->ptksa, addr, cipher); +} + +#endif /* CONFIG_PASN */ + + static int hostapd_wpa_auth_update_vlan(void *ctx, const u8 *addr, int vlan_id) { #ifndef CONFIG_NO_VLAN struct hostapd_data *hapd = ctx; struct sta_info *sta; - struct vlan_description vlan_desc; sta = ap_get_sta(hapd, addr); if (!sta) return -1; - os_memset(&vlan_desc, 0, sizeof(vlan_desc)); - vlan_desc.notempty = 1; - vlan_desc.untagged = vlan_id; - if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) { - wpa_printf(MSG_INFO, "Invalid VLAN ID %d in wpa_psk_file", - vlan_id); - return -1; - } + if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) { + struct vlan_description vlan_desc; - if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) { - wpa_printf(MSG_INFO, - "Failed to assign VLAN ID %d from wpa_psk_file to " - MACSTR, vlan_id, MAC2STR(sta->addr)); - return -1; + os_memset(&vlan_desc, 0, sizeof(vlan_desc)); + vlan_desc.notempty = 1; + vlan_desc.untagged = vlan_id; + if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) { + wpa_printf(MSG_INFO, + "Invalid VLAN ID %d in wpa_psk_file", + vlan_id); + return -1; + } + + if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) { + wpa_printf(MSG_INFO, + "Failed to assign VLAN ID %d from wpa_psk_file to " + MACSTR, vlan_id, MAC2STR(sta->addr)); + return -1; + } + } else { + sta->vlan_id = vlan_id; } wpa_printf(MSG_INFO, @@ -885,7 +1031,7 @@ static int hostapd_wpa_auth_send_ft_action(void *ctx, const u8 *dst, os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN); os_memcpy(&m->u, data, data_len); - res = hostapd_drv_send_mlme(hapd, (u8 *) m, mlen, 0); + res = hostapd_drv_send_mlme(hapd, (u8 *) m, mlen, 0, NULL, 0, 0); os_free(m); return res; } @@ -896,18 +1042,28 @@ hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr) { struct hostapd_data *hapd = ctx; struct sta_info *sta; + int ret; wpa_printf(MSG_DEBUG, "Add station entry for " MACSTR " based on WPA authenticator callback", MAC2STR(sta_addr)); - if (hostapd_add_sta_node(hapd, sta_addr, WLAN_AUTH_FT) < 0) + ret = hostapd_add_sta_node(hapd, sta_addr, WLAN_AUTH_FT); + + /* + * The expected return values from hostapd_add_sta_node() are + * 0: successfully added STA entry + * -EOPNOTSUPP: driver or driver wrapper does not support/need this + * operations + * any other negative value: error in adding the STA entry */ + if (ret < 0 && ret != -EOPNOTSUPP) return NULL; sta = ap_sta_add(hapd, sta_addr); if (sta == NULL) return NULL; - if (hapd->driver && hapd->driver->add_sta_node) + if (ret == 0) sta->added_unassoc = 1; + sta->ft_over_ds = 1; if (sta->wpa_sm) { sta->auth_alg = WLAN_AUTH_FT; @@ -925,6 +1081,34 @@ hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr) } +static int hostapd_wpa_auth_add_sta_ft(void *ctx, const u8 *sta_addr) +{ + struct hostapd_data *hapd = ctx; + struct sta_info *sta; + + sta = ap_get_sta(hapd, sta_addr); + if (!sta) + return -1; + + if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) && + (sta->flags & WLAN_STA_MFP) && ap_sta_is_authorized(sta) && + !(hapd->conf->mesh & MESH_ENABLED) && !(sta->added_unassoc)) { + /* We could not do this in handle_auth() since there was a + * PMF-enabled association for the STA and the new + * authentication attempt was not yet fully processed. Now that + * we are ready to configure the TK to the driver, + * authentication has succeeded and we can clean up the driver + * STA entry to avoid issues with any maintained state from the + * previous association. */ + wpa_printf(MSG_DEBUG, + "FT: Remove and re-add driver STA entry after successful FT authentication"); + return ap_sta_re_add(hapd, sta); + } + + return 0; +} + + static int hostapd_wpa_auth_set_vlan(void *ctx, const u8 *sta_addr, struct vlan_description *vlan) { @@ -1280,12 +1464,18 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) .send_oui = hostapd_wpa_auth_send_oui, .channel_info = hostapd_channel_info, .update_vlan = hostapd_wpa_auth_update_vlan, +#ifdef CONFIG_PASN + .store_ptksa = hostapd_store_ptksa, + .clear_ptksa = hostapd_clear_ptksa, +#endif /* CONFIG_PASN */ + #ifdef CONFIG_OCV .get_sta_tx_params = hostapd_get_sta_tx_params, #endif /* CONFIG_OCV */ #ifdef CONFIG_IEEE80211R_AP .send_ft_action = hostapd_wpa_auth_send_ft_action, .add_sta = hostapd_wpa_auth_add_sta, + .add_sta_ft = hostapd_wpa_auth_add_sta_ft, .add_tspec = hostapd_wpa_auth_add_tspec, .set_vlan = hostapd_wpa_auth_set_vlan, .get_vlan = hostapd_wpa_auth_get_vlan, @@ -1301,10 +1491,43 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) size_t wpa_ie_len; hostapd_wpa_auth_conf(hapd->conf, hapd->iconf, &_conf); + _conf.msg_ctx = hapd->msg_ctx; if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_EAPOL_TX_STATUS) _conf.tx_status = 1; if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_MLME) _conf.ap_mlme = 1; + + if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) && + (hapd->conf->wpa_deny_ptk0_rekey == PTK0_REKEY_ALLOW_NEVER || + (hapd->conf->wpa_deny_ptk0_rekey == PTK0_REKEY_ALLOW_LOCAL_OK && + !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_SAFE_PTK0_REKEYS)))) { + wpa_msg(hapd->msg_ctx, MSG_INFO, + "Disable PTK0 rekey support - replaced with disconnect"); + _conf.wpa_deny_ptk0_rekey = 1; + } + + if (_conf.extended_key_id && + (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_EXTENDED_KEY_ID)) + wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Extended Key ID supported"); + else + _conf.extended_key_id = 0; + + if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION)) + _conf.beacon_prot = 0; + +#ifdef CONFIG_OCV + if (!(hapd->iface->drv_flags2 & + (WPA_DRIVER_FLAGS2_AP_SME | WPA_DRIVER_FLAGS2_OCV))) + _conf.ocv = 0; +#endif /* CONFIG_OCV */ + + _conf.secure_ltf = + !!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF); + _conf.secure_rtt = + !!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT); + _conf.prot_range_neg = + !!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG); + hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd); if (hapd->wpa_auth == NULL) { wpa_printf(MSG_ERROR, "WPA initialization failed."); @@ -1330,6 +1553,13 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) return -1; } + if (!hapd->ptksa) + hapd->ptksa = ptksa_cache_init(); + if (!hapd->ptksa) { + wpa_printf(MSG_ERROR, "Failed to allocate PTKSA cache"); + return -1; + } + #ifdef CONFIG_IEEE80211R_AP if (!hostapd_drv_none(hapd) && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { @@ -1339,9 +1569,7 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) hapd->conf->iface; hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB, hostapd_rrb_receive, hapd, 1); - if (hapd->l2 == NULL && - (hapd->driver == NULL || - hapd->driver->send_ether == NULL)) { + if (!hapd->l2) { wpa_printf(MSG_ERROR, "Failed to open l2_packet " "interface"); return -1; @@ -1371,6 +1599,9 @@ void hostapd_reconfig_wpa(struct hostapd_data *hapd) void hostapd_deinit_wpa(struct hostapd_data *hapd) { ieee80211_tkip_countermeasures_deinit(hapd); + ptksa_cache_deinit(hapd->ptksa); + hapd->ptksa = NULL; + rsn_preauth_iface_deinit(hapd); if (hapd->wpa_auth) { wpa_deinit(hapd->wpa_auth); |