wlan-ap-Telecominfraproject/feeds/wifi-ax/hostapd/patches/e00-003-6G-security-constraints.patch
John Crispin 6b7f1b9009 hostapd-ax: update to ath11k-ed2 release
Signed-off-by: John Crispin <john@phrozen.org>
2020-12-02 09:48:18 +01:00

315 lines
9.9 KiB
Diff

From dea995bbaf7693c59c37c08b69ac23d5a04d25eb Mon Sep 17 00:00:00 2001
From: Aloka Dixit <alokad@codeaurora.org>
Date: Tue, 8 Sep 2020 16:36:32 -0700
Subject: [PATCH] AP: Add 6GHz security constraints
Add security constraints in 6GHz band as given in IEEE P802.11ax/D6.1,
section 12.13.2 (Security constraints in the 6 GHz band).
Additionally this commit also adds checks for following:
(1) Make management frame protection mandatory in 6GHz.
(2) For WPA3-SAE, only H2E mechanism is allowed.
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
---
src/ap/beacon.c | 2 +
src/drivers/driver.h | 14 ++++
src/drivers/driver_nl80211.c | 140 +++++++++++++++++++++++++++++++----
wpa_supplicant/ap.c | 1 +
4 files changed, 144 insertions(+), 13 deletions(-)
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 26422b65f321..3094979907c3 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1699,6 +1699,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
params->auth_algs = hapd->conf->auth_algs;
params->wpa_version = hapd->conf->wpa;
params->privacy = hapd->conf->wpa;
+ params->ieee80211w = hapd->conf->ieee80211w;
+ params->sae_pwe = hapd->conf->sae_pwe;
#ifdef CONFIG_WEP
params->privacy |= hapd->conf->ssid.wep.keys_set ||
(hapd->conf->ieee802_1x &&
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 1a44254405ef..d574d8179c65 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1201,6 +1201,10 @@ struct wpa_driver_associate_params {
*/
int disable_he;
#endif /* CONFIG_HE_OVERRIDES */
+ /**
+ * PWE derivation mechanism for SAE
+ */
+ int sae_pwe;
};
enum hide_ssid {
@@ -1592,6 +1596,16 @@ struct wpa_driver_ap_params {
* multiple_bssid_ie_count - The the number of offsets inside multiple_bssid_ie_offsets
*/
int multiple_bssid_ie_count;
+
+ /**
+ * Management frame protection
+ */
+ enum mfp_options ieee80211w;
+
+ /**
+ * PWE derivation mechanism for SAE
+ */
+ int sae_pwe;
};
struct wpa_driver_mesh_bss_params {
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 89607cfa3ecb..1c79c54c4018 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4369,6 +4369,46 @@ static int nl80211_unsol_bcast_probe_resp(struct i802_bss *bss,
}
#endif /* CONFIG_IEEE80211AX */
+
+static bool wpa_driver_6g_crypto_validity(int n_suite, u32 *suite,
+ u32 suite_type, int sae_pwe)
+{
+ int i;
+ switch (suite_type) {
+ case NL80211_ATTR_AKM_SUITES:
+ for (i = 0; i < n_suite; i++) {
+ if (suite[i] == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X ||
+ suite[i] == RSN_AUTH_KEY_MGMT_FT_PSK ||
+ suite[i] == RSN_AUTH_KEY_MGMT_PSK_SHA256) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Invalid AKM suite\n");
+ return false;
+ }
+ if (suite[i] == RSN_AUTH_KEY_MGMT_SAE && sae_pwe != 1) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Only H2E allowed for SAE in 6GHz\n");
+ return false;
+ }
+ }
+ break;
+ case NL80211_ATTR_CIPHER_SUITES_PAIRWISE:
+ case NL80211_ATTR_CIPHER_SUITE_GROUP:
+ for (i = 0; i < n_suite; i++) {
+ if (suite[i] == RSN_CIPHER_SUITE_NONE ||
+ suite[i] == RSN_CIPHER_SUITE_WEP40 ||
+ suite[i] == WPA_CIPHER_WEP104 ||
+ suite[i] == RSN_CIPHER_SUITE_TKIP) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Invalid cipher suite\n");
+ return false;
+ }
+ }
+ break;
+ }
+ return true;
+}
+
+
static int wpa_driver_nl80211_set_ap(void *priv,
struct wpa_driver_ap_params *params)
{
@@ -4380,7 +4420,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
int beacon_set;
int num_suites;
u32 suites[20], suite;
- u32 ver;
+ u32 ver, band = 0;
#ifdef CONFIG_MESH
struct wpa_driver_mesh_bss_params mesh_params;
#endif /* CONFIG_MESH */
@@ -4461,12 +4501,25 @@ static int wpa_driver_nl80211_set_ap(void *priv,
goto fail;
}
+ if ((params->freq->freq > 5950 && params->freq->freq <= 7115) ||
+ params->freq->freq == 5935)
+ band = NL80211_BAND_6GHZ;
+
wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
ver = 0;
if (params->wpa_version & WPA_PROTO_WPA)
ver |= NL80211_WPA_VERSION_1;
if (params->wpa_version & WPA_PROTO_RSN)
ver |= NL80211_WPA_VERSION_2;
+ if (band == NL80211_BAND_6GHZ) {
+ if (ver != NL80211_WPA_VERSION_2) {
+ wpa_printf(MSG_DEBUG, "nl80211: Only WPA3 allowed in 6GHz\n");
+ goto fail;
+ } else if (params->ieee80211w != MGMT_FRAME_PROTECTION_REQUIRED) {
+ wpa_printf(MSG_DEBUG, "nl80211: Management frame protection is required in 6GHz\n");
+ goto fail;
+ }
+ }
if (ver &&
nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
goto fail;
@@ -4479,10 +4532,17 @@ static int wpa_driver_nl80211_set_ap(void *priv,
wpa_printf(MSG_DEBUG,
"nl80211: Not enough room for all AKM suites (num_suites=%d > NL80211_MAX_NR_AKM_SUITES)",
num_suites);
- else if (num_suites &&
- nla_put(msg, NL80211_ATTR_AKM_SUITES, num_suites * sizeof(u32),
- suites))
- goto fail;
+ else if (num_suites) {
+ if (band == NL80211_BAND_6GHZ &&
+ !wpa_driver_6g_crypto_validity(num_suites, suites,
+ NL80211_ATTR_AKM_SUITES,
+ params->sae_pwe))
+ goto fail;
+
+ if (nla_put(msg, NL80211_ATTR_AKM_SUITES,
+ num_suites * sizeof(u32), suites))
+ goto fail;
+ }
if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
(!params->pairwise_ciphers ||
@@ -4500,17 +4560,31 @@ static int wpa_driver_nl80211_set_ap(void *priv,
params->pairwise_ciphers);
num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
suites, ARRAY_SIZE(suites));
- if (num_suites &&
- nla_put(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
- num_suites * sizeof(u32), suites))
+ if (num_suites) {
+ if (band == NL80211_BAND_6GHZ &&
+ !wpa_driver_6g_crypto_validity(num_suites, suites,
+ NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+ params->sae_pwe))
+ goto fail;
+
+ if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+ num_suites * sizeof(u32), suites))
goto fail;
+ }
wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
params->group_cipher);
suite = wpa_cipher_to_cipher_suite(params->group_cipher);
- if (suite &&
- nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite))
- goto fail;
+ if (suite) {
+ if (band == NL80211_BAND_6GHZ &&
+ !wpa_driver_6g_crypto_validity(num_suites, suites,
+ NL80211_ATTR_CIPHER_SUITE_GROUP,
+ params->sae_pwe))
+ goto fail;
+
+ if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite))
+ goto fail;
+ }
if (params->beacon_ies) {
wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
@@ -5977,6 +6051,8 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
struct wpa_driver_associate_params *params,
struct nl_msg *msg)
{
+ u32 band = 0;
+
if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
return -1;
@@ -6001,6 +6077,10 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
params->freq.freq))
return -1;
drv->assoc_freq = params->freq.freq;
+
+ if ((params->freq.freq > 5950 && params->freq.freq >= 7115) ||
+ params->freq.freq == 5935)
+ band = NL80211_BAND_6GHZ;
} else
drv->assoc_freq = 0;
@@ -6048,6 +6128,19 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len, params->wpa_ie))
return -1;
+ if (band == NL80211_BAND_6GHZ) {
+ if (params->wpa_proto != NL80211_WPA_VERSION_2) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Only WPA3 allowed in 6GHz\n");
+ return -1;
+ } else if (params->mgmt_frame_protection !=
+ MGMT_FRAME_PROTECTION_REQUIRED) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Management frame protection is required in 6GHz\n");
+ return -1;
+ }
+ }
+
if (params->wpa_proto) {
enum nl80211_wpa_versions ver = 0;
@@ -6064,6 +6157,13 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
if (params->pairwise_suite != WPA_CIPHER_NONE) {
u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
+
+ if (band == NL80211_BAND_6GHZ &&
+ !wpa_driver_6g_crypto_validity(1, &cipher,
+ NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+ params->sae_pwe))
+ return -1;
+
if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
cipher))
return -1;
@@ -6076,10 +6176,17 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
* advertise support for operations without GTK.
*/
wpa_printf(MSG_DEBUG, " * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
- } else if (params->group_suite != WPA_CIPHER_NONE) {
+ } else {
u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
- if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher))
+
+ if (band == NL80211_BAND_6GHZ &&
+ !wpa_driver_6g_crypto_validity(1, &cipher,
+ NL80211_ATTR_CIPHER_SUITE_GROUP,
+ params->sae_pwe))
+ return -1;
+ if (params->group_suite != WPA_CIPHER_NONE &&
+ nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher))
return -1;
}
@@ -6165,6 +6272,13 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
break;
}
wpa_printf(MSG_DEBUG, " * akm=0x%x", mgmt);
+
+ if (band == NL80211_BAND_6GHZ &&
+ !wpa_driver_6g_crypto_validity(1, &mgmt,
+ NL80211_ATTR_AKM_SUITES,
+ params->sae_pwe))
+ return -1;
+
if (nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, mgmt))
return -1;
}
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index e961ff2983c0..0a0bc22fc514 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -810,6 +810,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
}
params.pairwise_suite = wpa_s->pairwise_cipher;
params.group_suite = params.pairwise_suite;
+ params.sae_pwe = wpa_s->conf->sae_pwe;
#ifdef CONFIG_P2P
if (ssid->mode == WPAS_MODE_P2P_GO ||
--
2.25.0