FILS: Handle authentication/association in partial driver AP SME
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
5cee22ca47
commit
fa61bff6ae
3 changed files with 104 additions and 0 deletions
|
@ -31,6 +31,7 @@
|
|||
#include "wps_hostapd.h"
|
||||
#include "ap_drv_ops.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_mlme.h"
|
||||
#include "hw_features.h"
|
||||
#include "dfs.h"
|
||||
#include "beacon.h"
|
||||
|
@ -381,6 +382,39 @@ skip_wpa_check:
|
|||
sta->auth_alg, req_ies, req_ies_len);
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
|
||||
#ifdef CONFIG_FILS
|
||||
if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
|
||||
sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
|
||||
sta->auth_alg == WLAN_AUTH_FILS_PK) {
|
||||
if (!wpa_fils_validate_fils_session(sta->wpa_sm, req_ies,
|
||||
req_ies_len,
|
||||
sta->fils_session)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FILS: Session validation failed");
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
||||
res = wpa_fils_validate_key_confirm(sta->wpa_sm, req_ies,
|
||||
req_ies_len);
|
||||
if (res < 0) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FILS: Key Confirm validation failed");
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
||||
if (!elems.fils_session) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"FILS: Session element not found");
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
||||
p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
|
||||
elems.fils_session);
|
||||
wpa_hexdump(MSG_DEBUG, "FILS Assoc Resp BUF (IEs)",
|
||||
buf, p - buf);
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
#if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_FILS)
|
||||
hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
|
||||
|
||||
|
@ -723,6 +757,32 @@ static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
|
|||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
|
||||
|
||||
#ifdef CONFIG_FILS
|
||||
static void hostapd_notify_auth_fils_finish(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, u16 resp,
|
||||
struct wpabuf *data, int pub)
|
||||
{
|
||||
if (resp == WLAN_STATUS_SUCCESS) {
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_DEBUG, "authentication OK (FILS)");
|
||||
sta->flags |= WLAN_STA_AUTH;
|
||||
wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
|
||||
sta->auth_alg = WLAN_AUTH_FILS_SK;
|
||||
mlme_authenticate_indication(hapd, sta);
|
||||
} else {
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"authentication failed (FILS)");
|
||||
}
|
||||
|
||||
hostapd_sta_auth(hapd, sta->addr, 2, resp,
|
||||
data ? wpabuf_head(data) : NULL,
|
||||
data ? wpabuf_len(data) : 0);
|
||||
wpabuf_free(data);
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
|
||||
static void hostapd_notif_auth(struct hostapd_data *hapd,
|
||||
struct auth_info *rx_auth)
|
||||
{
|
||||
|
@ -760,6 +820,18 @@ static void hostapd_notif_auth(struct hostapd_data *hapd,
|
|||
return;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
|
||||
#ifdef CONFIG_FILS
|
||||
if (rx_auth->auth_type == WLAN_AUTH_FILS_SK) {
|
||||
sta->auth_alg = WLAN_AUTH_FILS_SK;
|
||||
handle_auth_fils(hapd, sta, rx_auth->ies, rx_auth->ies_len,
|
||||
rx_auth->auth_type, rx_auth->auth_transaction,
|
||||
rx_auth->status_code,
|
||||
hostapd_notify_auth_fils_finish);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
fail:
|
||||
hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
|
||||
status, resp_ies, resp_ies_len);
|
||||
|
|
|
@ -2509,6 +2509,36 @@ int fils_set_tk(struct wpa_state_machine *sm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_assoc_fils_session(struct wpa_state_machine *sm, u8 *buf,
|
||||
const u8 *fils_session)
|
||||
{
|
||||
struct wpabuf *plain;
|
||||
u8 *pos = buf;
|
||||
|
||||
/* FILS Session */
|
||||
*pos++ = WLAN_EID_EXTENSION; /* Element ID */
|
||||
*pos++ = 1 + FILS_SESSION_LEN; /* Length */
|
||||
*pos++ = WLAN_EID_EXT_FILS_SESSION; /* Element ID Extension */
|
||||
os_memcpy(pos, fils_session, FILS_SESSION_LEN);
|
||||
pos += FILS_SESSION_LEN;
|
||||
|
||||
plain = fils_prepare_plainbuf(sm, NULL);
|
||||
if (!plain) {
|
||||
wpa_printf(MSG_DEBUG, "FILS: Plain buffer prep failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_memcpy(pos, wpabuf_head(plain), wpabuf_len(plain));
|
||||
pos += wpabuf_len(plain);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: plain buf_len: %u", __func__,
|
||||
(unsigned int) wpabuf_len(plain));
|
||||
wpabuf_free(plain);
|
||||
sm->fils_completed = 1;
|
||||
return pos;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
|
||||
|
|
|
@ -374,6 +374,8 @@ int fils_encrypt_assoc(struct wpa_state_machine *sm, u8 *buf,
|
|||
size_t current_len, size_t max_len,
|
||||
const struct wpabuf *hlp);
|
||||
int fils_set_tk(struct wpa_state_machine *sm);
|
||||
u8 * hostapd_eid_assoc_fils_session(struct wpa_state_machine *sm, u8 *eid,
|
||||
const u8 *fils_session);
|
||||
const u8 * wpa_fils_validate_fils_session(struct wpa_state_machine *sm,
|
||||
const u8 *ies, size_t ies_len,
|
||||
const u8 *fils_session);
|
||||
|
|
Loading…
Reference in a new issue