From f2991170937d1c90e1261fae692e0c1cbc70b6a9 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 18 Oct 2014 13:00:29 +0300 Subject: [PATCH] SAE: Add support for PMKSA caching on the AP side This makes hostapd create PMKSA cache entries from SAE authentication and allow PMKSA caching to be used with the SAE AKM. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11.c | 24 ++++++++++++++++++++---- src/ap/wpa_auth.c | 15 +++++++++++++++ src/ap/wpa_auth.h | 2 ++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index de1ee5ed0..ed4f55a4f 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1,6 +1,6 @@ /* * hostapd / IEEE 802.11 Management - * Copyright (c) 2002-2013, Jouni Malinen + * Copyright (c) 2002-2014, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -29,6 +29,7 @@ #include "sta_info.h" #include "ieee802_1x.h" #include "wpa_auth.h" +#include "pmksa_cache_auth.h" #include "wmm.h" #include "ap_list.h" #include "accounting.h" @@ -517,6 +518,9 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, resp = WLAN_STATUS_UNSPECIFIED_FAILURE; else { sta->sae->state = SAE_ACCEPTED; + wpa_auth_pmksa_add_sae(hapd->wpa_auth, + sta->addr, + sta->sae->pmk); sae_clear_temp_data(sta->sae); } } @@ -1072,9 +1076,21 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, #ifdef CONFIG_SAE if (wpa_auth_uses_sae(sta->wpa_sm) && - sta->auth_alg != WLAN_AUTH_SAE && - !(sta->auth_alg == WLAN_AUTH_FT && - wpa_auth_uses_ft_sae(sta->wpa_sm))) { + sta->auth_alg == WLAN_AUTH_OPEN) { + struct rsn_pmksa_cache_entry *sa; + sa = wpa_auth_sta_get_pmksa(sta->wpa_sm); + if (!sa || sa->akmp != WPA_KEY_MGMT_SAE) { + wpa_printf(MSG_DEBUG, + "SAE: No PMKSA cache entry found for " + MACSTR, MAC2STR(sta->addr)); + return WLAN_STATUS_INVALID_PMKID; + } + wpa_printf(MSG_DEBUG, "SAE: " MACSTR + " using PMKSA caching", MAC2STR(sta->addr)); + } else if (wpa_auth_uses_sae(sta->wpa_sm) && + sta->auth_alg != WLAN_AUTH_SAE && + !(sta->auth_alg == WLAN_AUTH_FT && + wpa_auth_uses_ft_sae(sta->wpa_sm))) { wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use " "SAE AKM after non-SAE auth_alg %u", MAC2STR(sta->addr), sta->auth_alg); diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index a884d9faf..102845b36 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3082,6 +3082,21 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, } +int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, + const u8 *pmk) +{ + if (wpa_auth->conf.disable_pmksa_caching) + return -1; + + if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, + wpa_auth->addr, addr, 0, NULL, + WPA_KEY_MGMT_SAE)) + return 0; + + return -1; +} + + void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, const u8 *sta_addr) { diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 929a25359..2a5bc1a85 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -276,6 +276,8 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, const u8 *pmk, size_t len, const u8 *sta_addr, int session_timeout, struct eapol_state_machine *eapol); +int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, + const u8 *pmk); void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, const u8 *sta_addr); int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id);