From aa189ac9ddb4219ddb2ca372f24964a954fe0b19 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 28 Dec 2013 13:41:02 +0200 Subject: [PATCH] Enable FT with SAE It was already possible to configure hostapd and wpa_supplicant to use FT-SAE for the key management, but number of places were missing proper AKM checks to allow FT to be used with the new AKM. Signed-hostap: Jouni Malinen --- src/ap/ieee802_11.c | 4 +++- src/ap/wpa_auth.c | 8 ++++++++ src/ap/wpa_auth.h | 1 + src/ap/wpa_auth_ft.c | 3 +-- src/common/defs.h | 6 ++++-- src/common/sae.c | 5 +++++ src/rsn_supp/wpa_ft.c | 11 +++++------ 7 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 93edec120..2c610760c 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1057,7 +1057,9 @@ 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_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 ef33929e1..5993edf71 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3095,3 +3095,11 @@ int wpa_auth_uses_sae(struct wpa_state_machine *sm) return 0; return wpa_key_mgmt_sae(sm->wpa_key_mgmt); } + + +int wpa_auth_uses_ft_sae(struct wpa_state_machine *sm) +{ + if (sm == NULL) + return 0; + return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE; +} diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 47503d00c..4892e8b9a 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -295,5 +295,6 @@ int wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos); int wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos); int wpa_auth_uses_sae(struct wpa_state_machine *sm); +int wpa_auth_uses_ft_sae(struct wpa_state_machine *sm); #endif /* WPA_AUTH_H */ diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 29d9d29ea..b9e8b3d17 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -633,8 +633,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, conf = &sm->wpa_auth->conf; - if (sm->wpa_key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X && - sm->wpa_key_mgmt != WPA_KEY_MGMT_FT_PSK) + if (!wpa_key_mgmt_ft(sm->wpa_key_mgmt)) return pos; end = pos + max_len; diff --git a/src/common/defs.h b/src/common/defs.h index 4c78e70b6..c9956313d 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -64,7 +64,8 @@ static inline int wpa_key_mgmt_wpa_psk(int akm) return !!(akm & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_PSK_SHA256 | - WPA_KEY_MGMT_SAE)); + WPA_KEY_MGMT_SAE | + WPA_KEY_MGMT_FT_SAE)); } static inline int wpa_key_mgmt_ft(int akm) @@ -89,7 +90,8 @@ static inline int wpa_key_mgmt_sha256(int akm) static inline int wpa_key_mgmt_wpa(int akm) { return wpa_key_mgmt_wpa_ieee8021x(akm) || - wpa_key_mgmt_wpa_psk(akm); + wpa_key_mgmt_wpa_psk(akm) || + wpa_key_mgmt_sae(akm); } static inline int wpa_key_mgmt_wpa_any(int akm) diff --git a/src/common/sae.c b/src/common/sae.c index 4e9e4610e..c806b9faf 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -701,6 +701,11 @@ static u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED; } + if (sae->tmp == NULL) { + wpa_printf(MSG_DEBUG, "SAE: Group information not yet initialized"); + return WLAN_STATUS_UNSPECIFIED_FAILURE; + } + if (sae->tmp->dh && !allowed_groups) { wpa_printf(MSG_DEBUG, "SAE: Do not allow FFC group %u without " "explicit configuration enabling it", group); diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 3a40c96f2..c8d8cfc8b 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -207,6 +207,8 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X); else if (sm->key_mgmt == WPA_KEY_MGMT_FT_PSK) RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK); + else if (sm->key_mgmt == WPA_KEY_MGMT_FT_SAE) + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE); else { wpa_printf(MSG_WARNING, "FT: Invalid key management type (%d)", sm->key_mgmt); @@ -400,8 +402,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, } } - if (sm->key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X && - sm->key_mgmt != WPA_KEY_MGMT_FT_PSK) { + if (!wpa_key_mgmt_ft(sm->key_mgmt)) { wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not " "enabled for this connection"); return -1; @@ -526,8 +527,7 @@ int wpa_ft_is_completed(struct wpa_sm *sm) if (sm == NULL) return 0; - if (sm->key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X && - sm->key_mgmt != WPA_KEY_MGMT_FT_PSK) + if (!wpa_key_mgmt_ft(sm->key_mgmt)) return 0; return sm->ft_completed; @@ -678,8 +678,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len); - if (sm->key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X && - sm->key_mgmt != WPA_KEY_MGMT_FT_PSK) { + if (!wpa_key_mgmt_ft(sm->key_mgmt)) { wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not " "enabled for this connection"); return -1;