From: Khanjan Desai Date: Mon, 9 Jun 2025 09:55:56 +0000 (+0530) Subject: Add support for configuring URNM_MFPR and URNM_MFPR_X20 (AP) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=acdd80ec0d1c987fd47ca71be5e096958e0d00bf;p=thirdparty%2Fhostap.git Add support for configuring URNM_MFPR and URNM_MFPR_X20 (AP) 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 --- diff --git a/hostapd/config_file.c b/hostapd/config_file.c index c5b839cc7..d9fb42da9 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -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, diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index ffe6b5a6e..40dffca71 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -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 ############################################## diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 5b47f7da0..ed1d13b70 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -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; } diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index f38676ad8..4cb0849a6 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -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]; diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index e873e1c12..346b7e103 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -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) && diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 9e40c0b82..7b82b0881 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -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; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 144e88e79..50753f64c 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -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 && diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 058138996..4290c2321 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -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)