From d90f10fa418521ba787f1e69290ab11df17c8590 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 9 Oct 2017 12:08:12 +0300 Subject: [PATCH] OWE: PMKSA caching in AP mode This extends OWE support in hostapd to allow PMKSA caching to be used. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11.c | 13 ++++++++++--- src/ap/pmksa_cache_auth.h | 1 + src/ap/wpa_auth.c | 1 + src/ap/wpa_auth_glue.c | 11 +++++++++++ src/ap/wpa_auth_ie.c | 3 ++- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 25d8e3b2d..7e30219f0 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2128,7 +2128,8 @@ static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, #ifdef CONFIG_OWE -static u16 owe_process_assoc_req(struct sta_info *sta, const u8 *owe_dh, +static u16 owe_process_assoc_req(struct hostapd_data *hapd, + struct sta_info *sta, const u8 *owe_dh, u8 owe_dh_len) { struct wpabuf *secret, *pub, *hkey; @@ -2140,6 +2141,11 @@ static u16 owe_process_assoc_req(struct sta_info *sta, const u8 *owe_dh, u16 group; size_t hash_len, prime_len; + if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) { + wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching"); + return WLAN_STATUS_SUCCESS; + } + group = WPA_GET_LE16(owe_dh); if (group == 19) prime_len = 32; @@ -2254,7 +2260,8 @@ static u16 owe_process_assoc_req(struct sta_info *sta, const u8 *owe_dh, wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sta->owe_pmk, sta->owe_pmk_len); wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN); - /* TODO: Add PMKSA cache entry */ + wpa_auth_pmksa_add2(hapd->wpa_auth, sta->addr, sta->owe_pmk, + sta->owe_pmk_len, pmkid, 0, WPA_KEY_MGMT_OWE); return WLAN_STATUS_SUCCESS; } @@ -2477,7 +2484,7 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE && elems.owe_dh) { - resp = owe_process_assoc_req(sta, elems.owe_dh, + resp = owe_process_assoc_req(hapd, sta, elems.owe_dh, elems.owe_dh_len); if (resp != WLAN_STATUS_SUCCESS) return resp; diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h index bd1b67237..2ef217435 100644 --- a/src/ap/pmksa_cache_auth.h +++ b/src/ap/pmksa_cache_auth.h @@ -35,6 +35,7 @@ struct rsn_pmksa_cache_entry { }; struct rsn_pmksa_cache; +struct radius_das_attrs; struct rsn_pmksa_cache * pmksa_cache_auth_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry, diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 5a37a09cc..dd4b9b78d 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2068,6 +2068,7 @@ SM_STATE(WPA_PTK, PTKSTART) */ if (sm->wpa == WPA_VERSION_WPA2 && (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) || + (sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE && sm->pmksa) || wpa_key_mgmt_sae(sm->wpa_key_mgmt)) && sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN) { pmkid = buf; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index a44fd90fb..412a05df3 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -27,6 +27,7 @@ #include "tkip_countermeasures.h" #include "ap_drv_ops.h" #include "ap_config.h" +#include "pmksa_cache_auth.h" #include "wpa_auth.h" #include "wpa_auth_glue.h" @@ -267,6 +268,16 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr, *psk_len = sta->owe_pmk_len; return sta->owe_pmk; } + if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && sta) { + struct rsn_pmksa_cache_entry *sa; + + sa = wpa_auth_sta_get_pmksa(sta->wpa_sm); + if (sa && sa->akmp == WPA_KEY_MGMT_OWE) { + if (psk_len) + *psk_len = sa->pmk_len; + return sa->pmk; + } + } #endif /* CONFIG_OWE */ psk = hostapd_get_psk(hapd->conf, addr, p2p_dev_addr, prev_psk); diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 889afcb77..dd0c7dbcc 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -1051,7 +1051,8 @@ u8 * wpa_auth_write_assoc_resp_owe(struct wpa_state_machine *sm, { int res; - res = wpa_write_rsn_ie(&sm->wpa_auth->conf, pos, max_len, NULL); + res = wpa_write_rsn_ie(&sm->wpa_auth->conf, pos, max_len, + sm->pmksa ? sm->pmksa->pmkid : NULL); if (res < 0) return pos; return pos + res;