From 7c021dec3a95803fc129d8533adcaeea82910c9c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 28 Mar 2020 12:33:48 +0200 Subject: [PATCH] DPP2: Allow AP to require or reject PFS The new hostapd configuration parameter dpp_pfs can be used to specify how PFS is applied to associations. The default behavior (dpp_pfs=0) remains same as it was previously, i.e., allow the station to decide whether to use PFS. PFS use can now be required (dpp_pfs=1) or rejected (dpp_pfs=2). Signed-off-by: Jouni Malinen --- hostapd/config_file.c | 10 ++++++++++ hostapd/hostapd.conf | 6 ++++++ src/ap/ap_config.h | 1 + src/ap/drv_callbacks.c | 4 ++++ src/ap/ieee802_11.c | 2 ++ src/ap/wpa_auth.h | 6 +++++- src/ap/wpa_auth_glue.c | 3 +++ src/ap/wpa_auth_ie.c | 10 ++++++++++ 8 files changed, 41 insertions(+), 1 deletion(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 1e640c790..7a184c440 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4410,6 +4410,16 @@ static int hostapd_config_fill(struct hostapd_config *conf, return 1; } else if (os_strcmp(buf, "dpp_configurator_connectivity") == 0) { bss->dpp_configurator_connectivity = atoi(pos); + } else if (os_strcmp(buf, "dpp_pfs") == 0) { + int val = atoi(pos); + + if (val < 0 || val > 2) { + wpa_printf(MSG_ERROR, + "Line %d: Invalid dpp_pfs value '%s'", + line, pos); + return -1; + } + bss->dpp_pfs = val; #endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP */ #ifdef CONFIG_OWE diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index bcddc6b30..812c09a9f 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -2309,6 +2309,12 @@ own_ip_addr=127.0.0.1 # 1: advertise that a Configurator is available #dpp_configurator_connectivity=0 +# DPP PFS +# 0: allow PFS to be used or not used (default) +# 1: require PFS to be used (note: not compatible with DPP R1) +# 2: do not allow PFS to be used +#dpp_pfs=0 + #### TDLS (IEEE 802.11z-2010) ################################################# # Prohibit use of TDLS in this BSS diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index e0f645f7b..7930fc374 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -741,6 +741,7 @@ struct hostapd_bss_config { #ifdef CONFIG_DPP2 struct dpp_controller_conf *dpp_controller; int dpp_configurator_connectivity; + int dpp_pfs; #endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP */ diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index f80a3857b..64cbd84d8 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -375,6 +375,10 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, reason = WLAN_REASON_INVALID_PMKID; status = WLAN_STATUS_INVALID_PMKID; break; + case WPA_DENIED_OTHER_REASON: + reason = WLAN_REASON_UNSPECIFIED; + status = WLAN_STATUS_ASSOC_DENIED_UNSPEC; + break; } if (status != WLAN_STATUS_SUCCESS) { wpa_printf(MSG_DEBUG, diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 50120c448..045a6cbcd 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1638,6 +1638,8 @@ static u16 wpa_res_to_status_code(enum wpa_validate_result res) return WLAN_STATUS_INVALID_IE; case WPA_INVALID_PMKID: return WLAN_STATUS_INVALID_PMKID; + case WPA_DENIED_OTHER_REASON: + return WLAN_STATUS_ASSOC_DENIED_UNSPEC; } return WLAN_STATUS_INVALID_IE; } diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 85fb3d6f6..868aaa1fa 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -252,6 +252,9 @@ struct wpa_auth_config { int sae_pwe; int owe_ptk_workaround; u8 transition_disable; +#ifdef CONFIG_DPP2 + int dpp_pfs; +#endif /* CONFIG_DPP2 */ }; typedef enum { @@ -335,7 +338,8 @@ enum wpa_validate_result { WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE, WPA_INVALID_AKMP, WPA_NOT_ENABLED, WPA_ALLOC_FAIL, WPA_MGMT_FRAME_PROTECTION_VIOLATION, WPA_INVALID_MGMT_GROUP_CIPHER, - WPA_INVALID_MDIE, WPA_INVALID_PROTO, WPA_INVALID_PMKID + WPA_INVALID_MDIE, WPA_INVALID_PROTO, WPA_INVALID_PMKID, + WPA_DENIED_OTHER_REASON }; enum wpa_validate_result diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 41df213b9..7a1ed24e8 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -196,6 +196,9 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, wconf->owe_ptk_workaround = conf->owe_ptk_workaround; #endif /* CONFIG_OWE */ wconf->transition_disable = conf->transition_disable; +#ifdef CONFIG_DPP2 + wconf->dpp_pfs = conf->dpp_pfs; +#endif /* CONFIG_DPP2 */ } diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 496e8e946..2ac1df47e 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -864,6 +864,16 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, } #endif /* CONFIG_OWE */ +#ifdef CONFIG_DPP2 + if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP && + ((conf->dpp_pfs == 1 && !owe_dh) || + (conf->dpp_pfs == 2 && owe_dh))) { + wpa_printf(MSG_DEBUG, "DPP: PFS %s", + conf->dpp_pfs == 1 ? "required" : "not allowed"); + return WPA_DENIED_OTHER_REASON; + } +#endif /* CONFIG_DPP2 */ + sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0); if (sm->pairwise < 0) return WPA_INVALID_PAIRWISE;