FILS: Handle authentication/association in partial driver AP SME

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jeffin Mammen 2017-04-21 18:42:00 +03:00 committed by Jouni Malinen
parent 5cee22ca47
commit fa61bff6ae
3 changed files with 104 additions and 0 deletions

View file

@ -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);

View file

@ -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 */

View file

@ -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);