aboutsummaryrefslogtreecommitdiff
path: root/contrib/wpa/src/ap/wpa_auth_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/wpa/src/ap/wpa_auth_glue.c')
-rw-r--r--contrib/wpa/src/ap/wpa_auth_glue.c343
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);