]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add support for configuring URNM_MFPR and URNM_MFPR_X20 (AP)
authorKhanjan Desai <khanjan@qti.qualcomm.com>
Mon, 9 Jun 2025 09:55:56 +0000 (15:25 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 24 Sep 2025 10:18:43 +0000 (13:18 +0300)
Add support for configuring Management Frame Protection flags URNM_MFPR
and URNM_MFPR_X20 through hostapd.conf, targeting AP deployments aligned
with IEEE 802.11az.

For drivers that default to URNM_MFPR=1 and URNM_MFPR_X20=0 in the RSNXE
this change enables initializing the AP with URNM_MFPR=0 and
URNM_MFPR_X20=1.

This configuration allows unassociated negotiation and measurement
operations on 20 MHz bandwidth channels without requiring PTKSA.
However, for bandwidths greater than 20 MHz, PTKSA is still required
when URNM_MFPR=0 and URNM_MFPR_X20=1.

When URNM_MFPR=1, PTKSA is mandatory across all supported bandwidths,
regardless of URNM_MFPR_X20.

This enhancement improves flexibility and standards compliance for IEEE
802.11az-based ranging and measurement procedures in AP scenarios.

Signed-off-by: Khanjan Desai <khanjan@qti.qualcomm.com>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/ieee802_11_shared.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c
src/ap/wpa_auth_ie.c

index c5b839cc7ff90a0199af909fd472fcf8ddacfc9f..d9fb42da958bc07949278b0840d8ac645a8db542 100644 (file)
@@ -4877,6 +4877,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->pasn_comeback_after = atoi(pos);
        } else if (os_strcmp(buf, "pasn_noauth") == 0) {
                bss->pasn_noauth = atoi(pos);
+       } else if (os_strcmp(buf, "urnm_mfpr") == 0) {
+               bss->urnm_mfpr = !!atoi(pos);
+       } else if (os_strcmp(buf, "urnm_mfpr_x20") == 0) {
+               bss->urnm_mfpr_x20 = !!atoi(pos);
 #endif /* CONFIG_PASN */
        } else if (os_strcmp(buf, "ext_capa_mask") == 0) {
                if (get_hex_config(bss->ext_capa_mask, EXT_CAPA_MAX_LEN,
index ffe6b5a6ec1b6c5b4f948b0cd4269d9bc7d69a0f..40dffca713a035e59c27143a7ec353d8aa358127 100644 (file)
@@ -2415,6 +2415,31 @@ own_ip_addr=127.0.0.1
 #sae_require_mfp=1
 #sae_pwe=2
 
+##### IEEE 802.11az configuration #############################################
+#
+# urnm_mfpr:
+# urnm_mfpr mandates use of management frame protection and establishment of
+# PTKSA across all supported bandwidths, regardless of the urnm_mfpr_x20
+# setting for unassociated negotiation and measurement operations.
+#
+# urnm_mfpr_x20:
+# urnm_mfpr_x20 allows unassociated negotiation and measurement
+# operations using 20 MHz bandwidth without requiring management frame
+# protection and a PTKSA while mandating the security for higher bandwidth
+# cases. This is only valid if urnm_mfpr is false.
+#
+# Behavior Summary:
+# - urnm_mfpr = 1:
+#   - PTKSA is required for all supported bandwidths.
+#   - urnm_mfpr_x20 is ignored.
+#
+# - urnm_mfpr = 0 and urnm_mfpr_x20 = 1:
+#   - PTKSA is required only for bandwidths greater than 20 MHz.
+#
+# - urnm_mfpr = 0 and urnm_mfpr_x20 = 0:
+#   - PTKSA is not required for any bandwidths.
+#urnm_mfpr=0
+#urnm_mfpr_x20=0
 
 ##### IEEE 802.11r configuration ##############################################
 
index 5b47f7da09da8db5851fb42b547d7a02cdc3fc76..ed1d13b70be003d0fd349a7fd0cfc6528297c900 100644 (file)
@@ -177,6 +177,8 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
        bss->pasn_comeback_after = 10;
        bss->pasn_noauth = 1;
 #endif /* CONFIG_PASN */
+       bss->urnm_mfpr_x20 = -1;
+       bss->urnm_mfpr = -1;
 }
 
 
index f38676ad87bf68ab3ae79306981e02111492407f..4cb0849a607610f60793370d6093a11b4f52136e 100644 (file)
@@ -947,6 +947,9 @@ struct hostapd_bss_config {
        u16 pasn_comeback_after;
 #endif /* CONFIG_PASN */
 
+       int urnm_mfpr_x20;
+       int urnm_mfpr;
+
        unsigned int unsol_bcast_probe_resp_interval;
 
        u8 ext_capa_mask[EXT_CAPA_MAX_LEN];
index e873e1c121d724525de3a2a9970f035dcc455646..346b7e10382a1405ce5a969221fb71ae10bac6c6 100644 (file)
@@ -1140,8 +1140,12 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
                capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
        if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT_AP)
                capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
-       if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP)
-               capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
+       if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP) {
+               if (hapd->conf->urnm_mfpr != 0)
+                       capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
+               if (hapd->conf->urnm_mfpr_x20 == 1)
+                       capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR_X20);
+       }
        if (hapd->conf->ssid_protection)
                capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
        if ((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU) &&
index 9e40c0b82d3b08de457a5fe703774ca5f0dcdc54..7b82b0881f1a92f499400a89716f90e258fc8c68 100644 (file)
@@ -284,6 +284,8 @@ struct wpa_auth_config {
 #endif /* CONFIG_FILS */
        enum sae_pwe sae_pwe;
        bool sae_pk;
+       bool urnm_mfpr_x20;
+       bool urnm_mfpr;
 
        unsigned int secure_ltf:1;
        unsigned int secure_rtt:1;
index 144e88e795d764d038af4b6ec6ca75274b8a18a8..50753f64c69a979e69e5fe6cb78d9f0069382124 100644 (file)
@@ -261,6 +261,10 @@ static void hostapd_wpa_auth_conf(struct hostapd_iface *iface,
 #endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_PASN */
 
+       if (conf->urnm_mfpr_x20 == 1)
+               wconf->urnm_mfpr_x20 = true;
+       if (conf->urnm_mfpr != 0)
+               wconf->urnm_mfpr = true;
        wconf->radius_psk = conf->wpa_psk_radius == PSK_RADIUS_DURING_4WAY_HS;
        wconf->no_disconnect_on_group_keyerror =
                conf->bss_max_idle && conf->ap_max_inactivity &&
index 058138996ef7021b9e0e02f5414a2d4bc7606532..4290c23215136593733f103363ab761b0a89496b 100644 (file)
@@ -493,8 +493,12 @@ static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt)
                capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
        if (conf->secure_rtt)
                capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
-       if (conf->prot_range_neg)
-               capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
+       if (conf->prot_range_neg) {
+               if (conf->urnm_mfpr)
+                       capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
+               if (conf->urnm_mfpr_x20)
+                       capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR_X20);
+       }
        if (conf->ssid_protection)
                capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
        if (conf->spp_amsdu)