mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-12 04:47:17 +04:00
wifi-scripts: no RSNO2E where the RSNE offers its items
On an EHT BSS or an AP MLD with sae, psk3, sae-mixed or psk3-mixed, the RSNE Override 2 element carries SAE-EXT-KEY and GCMP-256 (CCMP without phy support). An explicit sae_ext_key 1 and gcmp256 1 also put both items into the RSNE, and the element stayed as a duplicate. A configuration that asks for an RSNE with AKM 24 and GCMP-256 and an RSNXE only sets sae_ext_key 1 and gcmp256 1. The Beacon then had an RSNO2E and an RSNXOE in addition. A duplicate RSNO2E adds nothing. A client sees both items in the RSNE, and the RSNE meets WPA3 Specification v3.5 2.5 items 4 and 5. Build the element only when the RSNE lacks its AKM or its pairwise cipher. Without an RSNO2E, hostapd writes no RSNXOE either (wpa_auth_gen_wpa_ie()). The default keeps the element as before, with the client fixes of commitsfc652db52aand5e067465ff, and so does a BSS with one of the two options. One exception: without phy support for GCMP-256, the element carries SAE-EXT-KEY and CCMP, which an RSNE with sae_ext_key 1 already offers, so that BSS sends no element. 0 still keeps an item out of both elements. sae-compat keeps its own elements. On an AP MLD, the decision covers all links (ap.uc mld_rsno2()): WPA3 Specification v3.5 14.2 requires an identical RSNE Override 2 element on all links of an AP MLD that uses RSN overriding. The element goes only where the RSNE of every link offers both items. A psk2 or psk-mixed AP MLD has PSK in the RSNE of its 2.4 and 5 GHz links, so all its links keep the element, also the 6 GHz link, whose RSNE has SAE. An AP MLD of sae whose RSNE has both items on every link uses no RSN overriding. IEEE 802.11be-2024 12.6.2 then requires the same RSNE on every link except the AKM list and MFPR, and one common AKM. The links share SAE and SAE-EXT-KEY, also on a 6 GHz link. Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
1 parent
f3c75e3562
commit
e0e11b78f7
3 files changed
+49
-15
No files matched your search
+2
-2
@@ -397,7 +397,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"gcmp256": {
|
||||
"description": "Advertise the GCMP-256 pairwise cipher on HE/EHT BSSes (alongside CCMP for sae/sae-mixed, in the RSNE Override 2 element for sae-compat). Mandatory for EHT (WPA3 Specification v3.5 2.5), recommended otherwise. Off by default, because some clients and chipsets misbehave when GCMP-256 is offered. With an EHT htmode, sae, sae-mixed and sae-compat BSSes offer GCMP-256 in the RSNE Override 2 element unless this option is 0; 1 also offers it in the RSNE. Only advertised when the driver supports the GCMP-256 cipher.",
|
||||
"description": "Advertise the GCMP-256 pairwise cipher on HE/EHT BSSes (alongside CCMP for sae/sae-mixed, in the RSNE Override 2 element for sae-compat). Mandatory for EHT (WPA3 Specification v3.5 2.5), recommended otherwise. Off by default, because some clients and chipsets misbehave when GCMP-256 is offered. With an EHT htmode, sae, sae-mixed and sae-compat BSSes offer GCMP-256 in the RSNE Override 2 element unless this option is 0; 1 also offers it in the RSNE. Only advertised when the driver supports the GCMP-256 cipher. The sae and sae-mixed BSSes send no RSNE Override 2 element when the RSNE already offers SAE-EXT-KEY and GCMP-256 (CCMP without driver support for GCMP-256). An AP MLD sends none only when this holds on every link, so a psk2 AP MLD sends it on every link unless sae_ext_key is 0.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"hidden": {
|
||||
@@ -1021,7 +1021,7 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"sae_ext_key": {
|
||||
"description": "Advertise the SAE-EXT-KEY AKM (SAE using a group-dependent hash) alongside plain SAE. Mandatory for EHT (WPA3 Specification v3.5 2.5), recommended otherwise. Off by default in the RSNE, because some clients misbehave when SAE-EXT-KEY is offered there. With an EHT htmode, sae, sae-mixed and sae-compat BSSes offer it in the RSNE Override 2 element unless this option is 0; 1 also offers it in the RSNE (not for sae-compat).",
|
||||
"description": "Advertise the SAE-EXT-KEY AKM (SAE using a group-dependent hash) alongside plain SAE. Mandatory for EHT (WPA3 Specification v3.5 2.5), recommended otherwise. Off by default in the RSNE, because some clients misbehave when SAE-EXT-KEY is offered there. With an EHT htmode, sae, sae-mixed and sae-compat BSSes offer it in the RSNE Override 2 element unless this option is 0; 1 also offers it in the RSNE (not for sae-compat). The sae and sae-mixed BSSes send no RSNE Override 2 element when the RSNE already offers SAE-EXT-KEY and GCMP-256 (CCMP without driver support for GCMP-256). An AP MLD sends none only when this holds on every link, so a psk2 AP MLD sends it on every link unless sae_ext_key is 0.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"sae_password_file": {
|
||||
|
||||
@@ -89,14 +89,33 @@ function station_password_count(stas) {
|
||||
return n;
|
||||
}
|
||||
|
||||
/* a refusal on any band refuses every link of the AP MLD */
|
||||
function mld_refusal(link_config, dev_config, phy_features) {
|
||||
function mld_links(link_config, dev_config, phy_features, rsno2) {
|
||||
let links = [];
|
||||
|
||||
for (let band in link_config.mlo_bands) {
|
||||
let config = { ...link_config };
|
||||
config.encryption = iface.encryption_band(config.encryption, band, config.mlo_bands);
|
||||
iface.parse_encryption(config, { ...dev_config, band }, phy_features);
|
||||
iface.parse_encryption(config, { ...dev_config, band }, phy_features, rsno2);
|
||||
push(links, { band, config });
|
||||
}
|
||||
|
||||
const reason = bss_refusal(config, band);
|
||||
return links;
|
||||
}
|
||||
|
||||
/* WPA3 Specification v3.5 14.2: an AP MLD includes an identical RSNE
|
||||
* Override 2 element on all links, so a link that needs it adds it to all */
|
||||
function mld_rsno2(link_config, dev_config, phy_features) {
|
||||
for (let link in mld_links(link_config, dev_config, phy_features))
|
||||
if (link.config.rsno2_sae)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* a refusal on any band refuses every link of the AP MLD */
|
||||
function mld_refusal(link_config, dev_config, phy_features, rsno2) {
|
||||
for (let link in mld_links(link_config, dev_config, phy_features, rsno2)) {
|
||||
const reason = bss_refusal(link.config, link.band);
|
||||
if (reason)
|
||||
return reason;
|
||||
}
|
||||
@@ -691,12 +710,15 @@ export function generate(interface, data, config, vlans, stas, phy_features) {
|
||||
config.sae_station_passwords = station_password_count(stas);
|
||||
const link_config = { ...config };
|
||||
|
||||
const mld = config.mlo && length(config.mlo_bands);
|
||||
const rsno2 = mld ? mld_rsno2(link_config, data.config, phy_features) : null;
|
||||
|
||||
config.encryption = iface.encryption_band(config.encryption, data.config.band,
|
||||
config.mlo ? (config.mlo_bands ?? []) : null);
|
||||
iface.parse_encryption(config, data.config, phy_features);
|
||||
iface.parse_encryption(config, data.config, phy_features, rsno2);
|
||||
|
||||
const refusal = (config.mlo && length(config.mlo_bands)) ?
|
||||
mld_refusal(link_config, data.config, phy_features) : bss_refusal(config, data.config.band);
|
||||
const refusal = mld ?
|
||||
mld_refusal(link_config, data.config, phy_features, rsno2) : bss_refusal(config, data.config.band);
|
||||
if (refusal)
|
||||
return refusal;
|
||||
|
||||
|
||||
@@ -61,6 +61,11 @@ function encryption_map(encryption, modes) {
|
||||
return join('+', enc);
|
||||
}
|
||||
|
||||
function rsne_offers_rsno2(config, rsno2_pairwise) {
|
||||
return !!config.sae_ext_key && config.auth_type in [ 'sae', 'psk-sae' ] &&
|
||||
index(split(config.wpa_pairwise ?? '', ' '), rsno2_pairwise) >= 0;
|
||||
}
|
||||
|
||||
/* mld_bands: null for a single-link BSS, else the bands of the AP MLD */
|
||||
export function encryption_band(encryption, band, mld_bands) {
|
||||
if (band == '6g')
|
||||
@@ -85,7 +90,9 @@ export function encryption_sta_band(encryption, band, mld_bands) {
|
||||
return encryption_map(encryption, encryption_sta_mixed_6g);
|
||||
};
|
||||
|
||||
export function parse_encryption(config, dev_config, phy_features) {
|
||||
/* rsno2: null decides the RSNO2E for this link alone, a bool gives the
|
||||
* decision of the AP MLD */
|
||||
export function parse_encryption(config, dev_config, phy_features, rsno2) {
|
||||
if (!config.encryption)
|
||||
config.encryption = 'none';
|
||||
|
||||
@@ -105,19 +112,20 @@ export function parse_encryption(config, dev_config, phy_features) {
|
||||
* WPA3 Specification v3.5 2.5 requires SAE-EXT-KEY and GCMP-256 with
|
||||
* EHT or MLO. Some clients fail when these are offered in the RSNE, so on
|
||||
* EHT they go into the RSNE Override 2 element. Explicit sae_ext_key and
|
||||
* gcmp256 options apply to the RSNE; 0 also keeps them out of RSNO2.
|
||||
* gcmp256 options apply to the RSNE; 0 also keeps them out of RSNO2. An
|
||||
* RSNE that already offers the AKM and the pairwise cipher of the RSNO2E
|
||||
* makes the RSNO2E a duplicate, so the BSS sends none. An AP MLD sends
|
||||
* none only where that holds on every link (ap.uc mld_rsno2()).
|
||||
*/
|
||||
let eht = wildcard(dev_config?.htmode ?? '', 'EHT*');
|
||||
let compat = (config.auth_type == 'sae-compat');
|
||||
let rsno2_mode = config.auth_type in [ 'sae', 'psk3', 'sae-mixed', 'psk3-mixed' ] ||
|
||||
(!!config.mlo && config.auth_type == 'psk2');
|
||||
/* all links of an AP MLD must reach the same decision */
|
||||
config.rsno2_sae = (eht || !!config.mlo) && rsno2_mode && config.sae_ext_key !== false;
|
||||
let rsno2_gcmp256 = config.gcmp256 !== false && phy_features?.cipher_gcmp256;
|
||||
let rsno2_sae = (eht || !!config.mlo) && rsno2_mode && config.sae_ext_key !== false;
|
||||
let rsno2_pairwise = (config.gcmp256 !== false && phy_features?.cipher_gcmp256) ? 'GCMP-256' : 'CCMP';
|
||||
config.gcmp256 ??= compat && eht;
|
||||
config.sae_ext_key ??= compat && eht;
|
||||
if (config.rsno2_sae)
|
||||
config.rsn_override_pairwise_2 = rsno2_gcmp256 ? 'GCMP-256' : 'CCMP';
|
||||
|
||||
switch(config.auth_type) {
|
||||
case 'owe':
|
||||
@@ -213,6 +221,10 @@ export function parse_encryption(config, dev_config, phy_features) {
|
||||
config.wpa_pairwise ??= 'GCMP-256 CCMP';
|
||||
else
|
||||
config.wpa_pairwise ??= 'CCMP';
|
||||
|
||||
config.rsno2_sae = rsno2_sae && (rsno2 ?? !rsne_offers_rsno2(config, rsno2_pairwise));
|
||||
if (config.rsno2_sae)
|
||||
config.rsn_override_pairwise_2 = rsno2_pairwise;
|
||||
};
|
||||
|
||||
export function wpa_key_mgmt(config, band) {
|
||||
|
||||
Reference in new issue
Block a user