mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-18 01:41:24 +00:00
315 lines
9.9 KiB
Diff
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
|
|
|