Index | Thread | Search

From:
Kevin Lo <kevlo@kevlo.org>
Subject:
Re: wifi protected management frame (PMF) support
To:
tech@openbsd.org
Date:
Wed, 3 Dec 2025 14:59:04 +0800

Download raw body.

Thread
On Tue, Dec 02, 2025 at 02:30:53PM +0100, Stefan Sperling wrote:
> 
> On Fri, Nov 28, 2025 at 10:41:16AM +0100, Stefan Sperling wrote:
> > On Fri, Nov 28, 2025 at 09:29:06AM +0100, Remi Locherer wrote:
> > > Yes it connects whrn I disable PMF for the SSID.
> > > --> openbsd-arista_pmf-disabled_r-optional.pcap
> > 
> > Thanks, that is good to know.  Nothing seems wrong in this case.
> >  
> > > > Are there any obvious AP settings for enabling the AKM "PSK"?
> > > > Could you try disabling fast-transition roaming (11k / 11r) in AP settings?
> > > > Perhaps this will switch "FT using PSK" to regular "PSK"?
> > > 
> > > No success when I disable 11r but keep 11w required. Also not with the
> > > patch below applied on top of the PMF patches.
> > > --> openbsd-arista_pmf-required_r-disabled.pcap
> > 
> > Now this AP is only advertising PSK 256, no PSK anymore.
> 
> Turns out I also have an AP which switches to only PSK SHA256 once
> PMF is set to "required". The two patches below make it work.
> 
> The first patch is for /usr/src/sbin/ifconfig. You can apply this and
> rebuild just ifconfig to enable use of sha256-psk, even on an unpatched
> kernel:
> 
>   cd /usr/src/sbin/ifconfig; make obj; make; make install
> 
>   ifconfig iwx0 nwid A-LAB-PSK wpaakms "psk,sha256-psk" wpakey ...
> 
> This should give you a working connection.
> 
> 
> The second patch enables SHA256-PSK by default in the kernel if the driver
> supports PMF. With this, the extra ifconfig wpaakms parameter is not needed
> and the interface should be able to connect to your AP setup out of the box.

In my customized OpenWrt, with the following options enabled:
wpa_key_mgmt=WPA-PSK-SHA256
ieee80211w=2

Without your diff, iwx(4) couldn't connect.  After applying it,
iwx(4) works as expected.

Tested:
iwx0 at pci1 dev 0 function 0 "Intel Wi-Fi 6 AX210" rev 0x1a, msix
iwx0: hw rev 0x420, fw 77.f92b5fed.0, pnvm ce1a5094, address ac:82:47:xx:xx:xx

ifconfig iwx0 shows:
ieee80211: join xxx chan 100 bssid xx:xx:xx:xx:xx:xx 98% wpakey wpaprotos wpa2 wpaakms sha256-psk wpaciphers ccmp wpagroupcipher ccmp

> Ok for both diffs?

The diffs look ok, thanks!

> 
> add support for 802.11 AKM SHA256-PSK to ifconfig
> 
> M  sbin/ifconfig/ifconfig.8  |   8+  2-
> M  sbin/ifconfig/ifconfig.c  |  11+  0-
> 
> 2 files changed, 19 insertions(+), 2 deletions(-)
> 
> commit - a3f552335f9430f1104d6386773eb4a1f854d21f
> commit + 6aad21a921d3c66792022357a27183d168fee44d
> blob - 65ba2eabc00bf6a8391eeffc5e95b5628c2a184b
> blob + 9bde644c086d54094a40281b9e82870fbcbf8993
> --- sbin/ifconfig/ifconfig.8
> +++ sbin/ifconfig/ifconfig.8
> @@ -1261,7 +1261,8 @@ Set the comma-separated list of allowed authentication
>  protocols.
>  .Pp
>  The supported values are
> -.Dq psk
> +.Dq psk ,
> +.Dq sha256-psk ,
>  and
>  .Dq 802.1x .
>  .Ar psk
> @@ -1271,8 +1272,13 @@ authentication (also known as enterprise mode) is used
>  an external IEEE 802.1X authentication server,
>  such as wpa_supplicant.
>  The default value is
> -.Dq psk .
> +.Dq psk ,
> +or
> +.Dq psk,sha256-psk
> +if the driver for the interface supports protected management frames (PMF).
>  .Dq psk
> +and
> +.Dq sha256-psk
>  can only be used if a pre-shared key is configured using the
>  .Cm wpakey
>  option.
> blob - dce9d1a98e34e25bbc24d64f84bc7ceebe15835c
> blob + 2b0d1ccab3c968e216817c11c24ea22b2bdc3167
> --- sbin/ifconfig/ifconfig.c
> +++ sbin/ifconfig/ifconfig.c
> @@ -2118,6 +2118,8 @@ setifwpaakms(const char *val, int d)
>  	while (str != NULL) {
>  		if (strcasecmp(str, "psk") == 0)
>  			rval |= IEEE80211_WPA_AKM_PSK;
> +		else if (strcasecmp(str, "sha256-psk") == 0)
> +			rval |= IEEE80211_WPA_AKM_SHA256_PSK;
>  		else if (strcasecmp(str, "802.1x") == 0)
>  			rval |= IEEE80211_WPA_AKM_8021X;
>  		else
> @@ -2563,6 +2565,10 @@ ieee80211_status(void)
>  			fputs("psk", stdout);
>  			sep = ",";
>  		}
> +		if (wpa.i_akms & IEEE80211_WPA_AKM_SHA256_PSK) {
> +			printf("%ssha256-psk", sep);
> +			sep = ",";
> +		}
>  		if (wpa.i_akms & IEEE80211_WPA_AKM_8021X)
>  			printf("%s802.1x", sep);
>  
> @@ -2678,6 +2684,11 @@ join_status(void)
>  					printf("psk");
>  					sep = ",";
>  				}
> +				if (wpa->i_akms &
> +				    IEEE80211_WPA_AKM_SHA256_PSK) {
> +					printf("%ssha256-psk", sep);
> +					sep = ",";
> +				}
>  				if (wpa->i_akms & IEEE80211_WPA_AKM_8021X)
>  					printf("%s802.1x", sep);
>  
> 
> 
> enable 802.11 AKM SHA256-PSK by default if the driver supports PMF
> 
> M  sys/net80211/ieee80211_crypto.c  |   2+  0-
> M  sys/net80211/ieee80211_ioctl.c   |   4+  1-
> M  sys/net80211/ieee80211_node.c    |  11+  3-
> 
> 3 files changed, 17 insertions(+), 4 deletions(-)
> 
> commit - 6aad21a921d3c66792022357a27183d168fee44d
> commit + a7fbcfb0ae9c0fe6d7449664f5bd0eb024d87724
> blob - 265b82e816052b25f70a2bcf722454e238c90dbb
> blob + 8188360f72bd797a3d30f303da478ea463b65b85
> --- sys/net80211/ieee80211_crypto.c
> +++ sys/net80211/ieee80211_crypto.c
> @@ -62,6 +62,8 @@ ieee80211_crypto_attach(struct ifnet *ifp)
>  	if (ic->ic_caps & IEEE80211_C_RSN) {
>  		ic->ic_rsnprotos = IEEE80211_PROTO_RSN;
>  		ic->ic_rsnakms = IEEE80211_AKM_PSK;
> +		if (ic->ic_caps & IEEE80211_C_MFP)
> +			ic->ic_rsnakms |= IEEE80211_AKM_SHA256_PSK;
>  		ic->ic_rsnciphers = IEEE80211_CIPHER_CCMP;
>  		ic->ic_rsngroupcipher = IEEE80211_CIPHER_CCMP;
>  		ic->ic_rsngroupmgmtcipher = IEEE80211_CIPHER_BIP;
> blob - 5dbfc382e3770749adf0001148111deb3f3a6e49
> blob + 6d7142e64059ce1daff1018be1b805c47d38c649
> --- sys/net80211/ieee80211_ioctl.c
> +++ sys/net80211/ieee80211_ioctl.c
> @@ -325,8 +325,11 @@ ieee80211_ioctl_setwpaparms(struct ieee80211com *ic,
>  		ic->ic_rsnakms |= IEEE80211_AKM_8021X;
>  	if (wpa->i_akms & IEEE80211_WPA_AKM_SHA256_8021X)
>  		ic->ic_rsnakms |= IEEE80211_AKM_SHA256_8021X;
> -	if (ic->ic_rsnakms == 0)	/* set to default (PSK) */
> +	if (ic->ic_rsnakms == 0) {	/* set to default (PSK) */
>  		ic->ic_rsnakms = IEEE80211_AKM_PSK;
> +		if (ic->ic_caps & IEEE80211_C_MFP)
> +			ic->ic_rsnakms |= IEEE80211_AKM_SHA256_PSK;
> +	}
>  
>  	if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_WEP40)
>  		ic->ic_rsngroupcipher = IEEE80211_CIPHER_WEP40;
> blob - dec464f269c66186021c6de4e15cc13d2b71ef2d
> blob + dbf6d091fe9455b189852082b3e848750bc7bfd3
> --- sys/net80211/ieee80211_node.c
> +++ sys/net80211/ieee80211_node.c
> @@ -143,6 +143,11 @@ ieee80211_print_ess(struct ieee80211_ess *ess)
>  		if (ess->rsnprotos & IEEE80211_PROTO_WPA)
>  			printf(",wpa1");
>  
> +		if (ess->rsnakms & IEEE80211_AKM_PSK)
> +			printf(",psk");
> +		if (ess->rsnakms & IEEE80211_AKM_SHA256_PSK)
> +			printf(",sha256-psk");
> +
>  		if (ess->rsnakms & IEEE80211_AKM_8021X ||
>  		    ess->rsnakms & IEEE80211_AKM_SHA256_8021X)
>  			printf(",802.1x");
> @@ -264,7 +269,7 @@ ieee80211_ess_setnwkeys(struct ieee80211_ess *ess,
>  
>  /* Keep in sync with ieee80211_ioctl.c:ieee80211_ioctl_setwpaparms() */
>  static int
> -ieee80211_ess_setwpaparms(struct ieee80211_ess *ess,
> +ieee80211_ess_setwpaparms(struct ieee80211com *ic, struct ieee80211_ess *ess,
>      const struct ieee80211_wpaparams *wpa)
>  {
>  	if (!wpa->i_enabled) {
> @@ -297,8 +302,11 @@ ieee80211_ess_setwpaparms(struct ieee80211_ess *ess,
>  		ess->rsnakms |= IEEE80211_AKM_SHA256_8021X;
>  	if (wpa->i_akms & IEEE80211_WPA_AKM_SAE)
>  		ess->rsnakms |= IEEE80211_AKM_SAE;
> -	if (ess->rsnakms == 0)	/* set to default (PSK) */
> +	if (ess->rsnakms == 0)	{ /* set to default (PSK) */
>  		ess->rsnakms = IEEE80211_AKM_PSK;
> +		if (ic->ic_caps & IEEE80211_C_MFP)
> +			ess->rsnakms = IEEE80211_AKM_SHA256_PSK;
> +	}
>  
>  	if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_WEP40)
>  		ess->rsngroupcipher = IEEE80211_CIPHER_WEP40;
> @@ -399,7 +407,7 @@ ieee80211_add_ess(struct ieee80211com *ic, struct ieee
>  				free(ess, M_DEVBUF, sizeof(*ess));
>  				return ENODEV;
>  			}
> -			ieee80211_ess_setwpaparms(ess,
> +			ieee80211_ess_setwpaparms(ic, ess,
>  			    &join->i_wpaparams);
>  			if (join->i_flags & IEEE80211_JOIN_WPAPSK) {
>  				ess->flags |= IEEE80211_F_PSK;
> 
>