WPA3: Can I see which encryption each client is using?

I have a network which is configured to use WPA3 sae-mixed encryption, which allows both WPA3 and WPA2 clients.

Is there any way to see which clients are connected using WPA2 and which with WPA3?

Client-side yes (e.g. wpa_cli status on linux), but I haven't found that information AP side so far (hostapd_cli knows about PMF, but not SAE)

I'm sure nl80211 knows the answer it just might not be exposed to userspace utilities at the moment. I'd be interested in this info too

Looking at the "hostapd_cli -i wlan1 all_sta" output reveals some possible indicators.

I tested with my Android10 phone: when I forced the AP to WPA3 only, the phone's data in hostapd_cli output showed a field sae_group=19, which is not present on WPA2-connected devices. Similarly there is AKMSuiteSelector=00-0f-ac-8, which should indicate SAE.

Phone as seen with AP set as WPA3 only:

root@OpenWrt:~# hostapd_cli -i wlan1 all_sta
ac:57:....
flags=[AUTH][ASSOC][AUTHORIZED][SHORT_PREAMBLE][WMM][MFP][HT]
aid=1
capability=0x431
listen_interval=1
supported_rates=82 84 8b 96 0c 12 18 24 30 48 60 6c
timeout_next=NULLFUNC POLL
dot11RSNAStatsSTAAddress=ac:57:...
dot11RSNAStatsVersion=1
dot11RSNAStatsSelectedPairwiseCipher=00-0f-ac-4
dot11RSNAStatsTKIPLocalMICFailures=0
dot11RSNAStatsTKIPRemoteMICFailures=0
wpa=2
AKMSuiteSelector=00-0f-ac-8
hostapdWPAPTKState=11
hostapdWPAPTKGroupState=0
rx_packets=170
tx_packets=97
rx_bytes=29675
tx_bytes=45692
inactive_msec=2370
signal=-49
rx_rate_info=10
tx_rate_info=722 mcs 7 shortGI
ht_mcs_bitmask=ff000000000000000000
connected_time=9
sae_group=19
supp_op_classes=51515354737475767778797a7b7c7d7e7f808182
ht_caps_info=0x012d
ext_capab=04000002

Same phone when AP is in mixed WPA2/WPA3 mode, likely the phone has a WPA2 connection:

root@OpenWrt:~# hostapd_cli -i wlan1 all_sta
ac:57:...
flags=[AUTH][ASSOC][AUTHORIZED][SHORT_PREAMBLE][WMM][MFP][HT]
aid=3
capability=0x431
listen_interval=1
supported_rates=82 84 8b 96 0c 12 18 24 30 48 60 6c
timeout_next=NULLFUNC POLL
dot11RSNAStatsSTAAddress=ac:57:...
dot11RSNAStatsVersion=1
dot11RSNAStatsSelectedPairwiseCipher=00-0f-ac-4
dot11RSNAStatsTKIPLocalMICFailures=0
dot11RSNAStatsTKIPRemoteMICFailures=0
wpa=2
AKMSuiteSelector=00-0f-ac-6
hostapdWPAPTKState=11
hostapdWPAPTKGroupState=0
rx_packets=98
tx_packets=41
rx_bytes=9413
tx_bytes=6573
inactive_msec=20640
signal=-51
rx_rate_info=10
tx_rate_info=289 mcs 3 shortGI
ht_mcs_bitmask=ff000000000000000000
connected_time=32
supp_op_classes=51515354737475767778797a7b7c7d7e7f808182
ht_caps_info=0x012d
ext_capab=04000002

(Interestingly, the phone seems to prefer WPA2 in the mixed mode???? )

2 Likes

Yes, AKMSuiteSelector seems to provide some insight:

Starting with WPA2 and IEEE802.11w/ PMF enabled:

root@client# wpa_cli -i wlp3s0 
wpa_cli v2.9                                                                                                        
Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors                                                   
                                                                                                                    
This software may be distributed under the terms of the BSD license.                                                
See README for more details.                                                                                        
                                                                                                                    
                                                                                                                    
                                                                                                                    
Interactive mode                                                                                                    
                                                                                                                    
> status                                                                                                            
bssid=60:31:XX:XX:XX:XX                                                                                             
freq=2412                                                                                                           
ssid=XXX                                                                                                         
id=0
id_str=XXX
mode=station
pairwise_cipher=CCMP
group_cipher=CCMP
key_mgmt=WPA2-PSK
pmf=1
mgmt_group_cipher=BIP
wpa_state=COMPLETED
ip_address=172.22.19.1
address=00:22:XX:XX:XX:XX
uuid=XXX
> 

Results in this output on my router:

root@nbg6817# hostapd_cli -i wlan1 all_sta
00:22:XX:XX:XX:XX
flags=[AUTH][ASSOC][AUTHORIZED][SHORT_PREAMBLE][WMM][MFP]
aid=1
capability=0x1431
listen_interval=5
supported_rates=0c 12 18 24 30 48 60 6c
timeout_next=NULLFUNC POLL
dot11RSNAStatsSTAAddress=00:22:XX:XX:XX:XX
dot11RSNAStatsVersion=1
dot11RSNAStatsSelectedPairwiseCipher=00-0f-ac-4
dot11RSNAStatsTKIPLocalMICFailures=0
dot11RSNAStatsTKIPRemoteMICFailures=0
wpa=2
AKMSuiteSelector=00-0f-ac-2
hostapdWPAPTKState=11
hostapdWPAPTKGroupState=0
rx_packets=152
tx_packets=79
rx_bytes=23006
tx_bytes=13683
inactive_msec=2
signal=-37
rx_rate_info=540
tx_rate_info=540
connected_time=53
supp_op_classes=5151
min_txpower=0
max_txpower=20
ext_capab=0000000001000040

Now switching the client to WPA3/ SAE:

root@client# wpa_cli -i wlp3s0 
wpa_cli v2.9                                                                                                        
Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors                                                   
                                                                                                                    
This software may be distributed under the terms of the BSD license.                                                
See README for more details.                                                                                        
                                                                                                                    
                                                                                                                    
                                                                                                                    
Interactive mode                                                                                                    
  
> set_network 0 key_mgmt SAE
OK
> reassociate 
OK
<3>CTRL-EVENT-SCAN-STARTED 
<3>CTRL-EVENT-SCAN-RESULTS 
<3>SME: Trying to authenticate with 60:31:XX:XX:XX:XX (SSID='XXX' freq=2412 MHz)
<3>CTRL-EVENT-REGDOM-CHANGE init=CORE type=WORLD
<3>CTRL-EVENT-REGDOM-CHANGE init=USER type=COUNTRY alpha2=DE
<3>SME: Trying to authenticate with 60:31:XX:XX:XX:XX (SSID='XXX' freq=2412 MHz)
<3>PMKSA-CACHE-ADDED 60:31:XX:XX:XX:XX 0
<3>Trying to associate with 60:31:XX:XX:XX:XX (SSID='XXX' freq=2412 MHz)
<3>Associated with 60:31:XX:XX:XX:XX
<3>CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
<3>WPA: Key negotiation completed with 60:31:XX:XX:XX:XX [PTK=CCMP GTK=CCMP]
<3>CTRL-EVENT-CONNECTED - Connection to 60:31:XX:XX:XX:XX completed [id=0 id_str=XXX]
<3>CTRL-EVENT-REGDOM-CHANGE init=COUNTRY_IE type=COUNTRY alpha2=DE
> status
bssid=60:31:XX:XX:XX:XX
freq=2412
ssid=XXX
id=0
id_str=XXX
mode=station
pairwise_cipher=CCMP
group_cipher=CCMP
key_mgmt=SAE
pmf=1
mgmt_group_cipher=BIP
sae_group=19
wpa_state=COMPLETED
ip_address=172.22.19.1
address=00:XX:XX:XX:XX:XX
uuid=XXX
>

And checking on the router:

root@nbg6817# hostapd_cli -i wlan1 all_sta
00:22:XX:XX:XX:XX
flags=[AUTH][ASSOC][AUTHORIZED][SHORT_PREAMBLE][WMM][MFP]
aid=1
capability=0x1431
listen_interval=5
supported_rates=0c 12 18 24 30 48 60 6c
timeout_next=NULLFUNC POLL
dot11RSNAStatsSTAAddress=00:22:XX:XX:XX:XX
dot11RSNAStatsVersion=1
dot11RSNAStatsSelectedPairwiseCipher=00-0f-ac-4
dot11RSNAStatsTKIPLocalMICFailures=0
dot11RSNAStatsTKIPRemoteMICFailures=0
wpa=2
AKMSuiteSelector=00-0f-ac-8
hostapdWPAPTKState=11
hostapdWPAPTKGroupState=0
rx_packets=425
tx_packets=317
rx_bytes=54332
tx_bytes=62237
inactive_msec=2
signal=-40
rx_rate_info=540
tx_rate_info=540
connected_time=244
sae_group=19
supp_op_classes=5151
min_txpower=0
max_txpower=20
ext_capab=0000000001000040
1 Like

Unfortunately the command "hostapd_cli -i wlan0 all_sta" does not work for me, but I can execute "hostapd_cli -i wlan0 status". Is there any other way to determine which client uses WPA3 at the access point, because with the iPhone or iPad you can't read it on the device itself?

root@avm3000:~# opkg install hostapd-utils

root@avm3000:~# hostapd_cli -i wlan0 all_sta
root@avm3000:~# 

root@avm3000:~# iwinfo wlan0 assoclist 
94:16:25:XX:XX:XX  -57 dBm / -106 dBm (SNR 49)  70 ms ago
	RX: 866.7 MBit/s, VHT-MCS 9, 80MHz, VHT-NSS 2     12391 Pkts.
	TX: 866.7 MBit/s, VHT-MCS 9, 80MHz, VHT-NSS 2      9641 Pkts.
	expected throughput: unknown

DC:A9:04:XX:XX:XX  -58 dBm / -106 dBm (SNR 48)  0 ms ago
	RX: 1053.0 MBit/s, VHT-MCS 8, 80MHz, VHT-NSS 3    136071 Pkts.
	TX: 1170.0 MBit/s, VHT-MCS 8, 80MHz, VHT-NSS 3    194130 Pkts.
	expected throughput: unknown

CC:9E:A2:XX:XX:XX  -60 dBm / -106 dBm (SNR 46)  160 ms ago
	RX: 6.0 MBit/s                                505804 Pkts.
	TX: 6.0 MBit/s                                985863 Pkts.
	expected throughput: unknown

D4:61:DA:XX:XX:XX  -55 dBm / -106 dBm (SNR 51)  2780 ms ago
	RX: 24.0 MBit/s                                 9328 Pkts.
	TX: 866.7 MBit/s, VHT-MCS 9, 80MHz, VHT-NSS 2      8143 Pkts.
	expected throughput: unknown


root@avm3000:~# hostapd_cli -i wlan0 status
state=ENABLED
phy=phy0
freq=5500
num_sta_non_erp=0
num_sta_no_short_slot_time=4
num_sta_no_short_preamble=4
olbc=0
num_sta_ht_no_gf=4
num_sta_no_ht=0
num_sta_ht_20_mhz=0
num_sta_ht40_intolerant=0
olbc_ht=0
ht_op_mode=0x4
cac_time_seconds=60
cac_time_left_seconds=N/A
channel=100
secondary_channel=1
ieee80211n=1
ieee80211ac=1
ieee80211ax=0
beacon_int=100
dtim_period=2
vht_oper_chwidth=1
vht_oper_centr_freq_seg0_idx=106
vht_oper_centr_freq_seg1_idx=0
vht_caps_info=338819fa
rx_vht_mcs_map=ffaa
tx_vht_mcs_map=ffaa
ht_caps_info=09ef
supported_rates=0c 12 18 24 30 48 60 6c
max_txpower=26
bss[0]=wlan0
bssid[0]=dc:39:6f:xx:xx:xx
ssid[0]=WLAN-CB
num_sta[0]=4
chan_util_avg=185


root@avm3000:~# cat /etc/banner |grep Open
 OpenWrt 19.07.0, r10860-a3ffeb413b

 root@avm3000:~# cat /etc/board.json |grep AVM
		"name": "AVM FRITZ!Repeater 3000"

In case anyone stumbles upon this thread via google, like I did, there’s a relatively easy way to determine WPA2 or WPA3 on iOS devices at least.

Courtesy of another forum (https://www.neowin.net/forum/topic/1404677-how-to-know-if-your-iphone-is-using-wpa3-or-wpa2/), you can install the Wi-Fi developer diagnostic profile located here: https://developer.apple.com/bug-reporting/profiles-and-logs/

A diagnostic panel shows up when you drill down into your connected network. I’ve confirmed that my iPhone running iOS 15.1 does connect via WPA3 to WPA2/WPA3 mixed networks. Of tangential note, there’s also a responsiveness test, which I believe was only recently added.

root@OpenWrt:~# hostapd_cli -i wlan1 all_sta
ac:57:....

AKMSuiteSelector tells the encryption suite/method

E.g.
AKMSuiteSelector=00-0f-ac-8 == SAE (WPA3)

Link to the Linux upstream about the "AKM suite selector" code definitions:

#define WLAN_AKM_SUITE_8021X			SUITE(0x000FAC, 1)
#define WLAN_AKM_SUITE_PSK			SUITE(0x000FAC, 2)
#define WLAN_AKM_SUITE_FT_8021X			SUITE(0x000FAC, 3)
#define WLAN_AKM_SUITE_FT_PSK			SUITE(0x000FAC, 4)
#define WLAN_AKM_SUITE_8021X_SHA256		SUITE(0x000FAC, 5)
#define WLAN_AKM_SUITE_PSK_SHA256		SUITE(0x000FAC, 6)
#define WLAN_AKM_SUITE_TDLS			SUITE(0x000FAC, 7)
#define WLAN_AKM_SUITE_SAE			SUITE(0x000FAC, 8)
#define WLAN_AKM_SUITE_FT_OVER_SAE		SUITE(0x000FAC, 9)
#define WLAN_AKM_SUITE_AP_PEER_KEY		SUITE(0x000FAC, 10)
#define WLAN_AKM_SUITE_8021X_SUITE_B		SUITE(0x000FAC, 11)
#define WLAN_AKM_SUITE_8021X_SUITE_B_192	SUITE(0x000FAC, 12)
#define WLAN_AKM_SUITE_FT_8021X_SHA384		SUITE(0x000FAC, 13)
#define WLAN_AKM_SUITE_FILS_SHA256		SUITE(0x000FAC, 14)
#define WLAN_AKM_SUITE_FILS_SHA384		SUITE(0x000FAC, 15)
#define WLAN_AKM_SUITE_FT_FILS_SHA256		SUITE(0x000FAC, 16)
#define WLAN_AKM_SUITE_FT_FILS_SHA384		SUITE(0x000FAC, 17)
#define WLAN_AKM_SUITE_OWE			SUITE(0x000FAC, 18)
#define WLAN_AKM_SUITE_FT_PSK_SHA384		SUITE(0x000FAC, 19)
#define WLAN_AKM_SUITE_PSK_SHA384		SUITE(0x000FAC, 20)

Below is a proof-of-concept script providing this output:

root@router1:/etc# ./wifi_suite.sh
Associated wifi stations' AKM suites:
wlan0: AKM suite of e0:c3:77:ae:0a:30 is 00-0f-ac-8 (WPA3-SAE)
wlan0: AKM suite of ac:57:75:56:c1:e0 is 00-0f-ac-6 (WPA-PSK-SHA256)
wlan1: AKM suite of 30:cd:a7:b3:33:5d is 00-0f-ac-2 (WPA-PSK)

Script:

#!/bin/sh
# Copyright 2021-2023 Hannu Nyman
# SPDX-License-Identifier: GPL-2.0-only

echo "Associated wifi stations' AKM suites:"
cd /var/run/hostapd
for socket in *; do
  [ -S "$socket" ] || continue
  [ "$socket" = "global" ] && continue
  for assoc in $(hostapd_cli -i "$socket" list_sta); do
    suite=$(hostapd_cli -i "$socket" sta "$assoc" | grep "AKMSuiteSelector" | cut -f 2 -d"=")
    case "$suite" in
        00-0f-ac-1) akm=802.1x  ;;
        00-0f-ac-2) akm=WPA-PSK  ;;
        00-0f-ac-3) akm=FT-802.1x  ;;
        00-0f-ac-4) akm=WPA-PSK-FT  ;;
        00-0f-ac-5) akm=802.1x-SHA256  ;;
        00-0f-ac-6) akm=WPA-PSK-SHA256  ;;
        00-0f-ac-7) akm=TDLS  ;;
        00-0f-ac-8) akm=WPA3-SAE  ;;
        00-0f-ac-9) akm=FT-SAE  ;;
        00-0f-ac-10) akm=AP-PEER-KEY  ;;
        00-0f-ac-11) akm=802.1x-suite-B  ;;
        00-0f-ac-12) akm=802.1x-suite-B-192  ;;
        00-0f-ac-13) akm=FT-802.1x-SHA384  ;;
        00-0f-ac-14) akm=FILS-SHA256  ;;
        00-0f-ac-15) akm=FILS-SHA384  ;;
        00-0f-ac-16) akm=FT-FILS-SHA256  ;;
        00-0f-ac-17) akm=FT-FILS-SHA384  ;;
        00-0f-ac-18) akm=OWE  ;;
        00-0f-ac-19) akm=FT-WPA2-PSK-SHA384  ;;
        00-0f-ac-20) akm=WPA2-PSK-SHA384  ;;
        *) akm="undefined" ;;
    esac
    echo "$socket: AKM suite of $assoc is $suite ($akm)"
  done
done

Ps. Based on hostapd sources, it looks like the deciding byte is handled as decimal, although the preceding bytes are hex.

5 Likes

Is this only available over hostapd_cli? I think it would be useful to expose it over ubus as part of the station dump feature.
I’ll have to have a look, I’ve not played in that space before but the information must be there.

1 Like

Nice!

  1. Consider modifying line 4 to use cd /var/run/hostapd || exit in case the cd command fails
  2. Do you want to add a check for executable /sbin/hostapd_cli to fail telling the user to install hostapd-utils?

Thanks for suggestions.
I made this script mostly out of curiosity, so I haven't polished it much.

It would be nice to integrate that client info to LuCI, likely via iwinfo/libiwinfo, but I am not good enough with those mac80211/hostapd backends to do that iwinfo integration.

(I highlighted the idea to @jow but I haven't yet heard any feedback.)

3 Likes

This would be excellent!

Unfortunately something seems broken in hostapd_cli for this, as @christian1982 mentioned. Possibly only when multiple SSIDs are enabled? But all_sta and list_sta return nothing on any interface, even though there are clearly clients connected:

root@OpenWrt:/tmp/run# hostapd_cli interface
Selected interface 'wlan0-1'
Available interfaces:
wlan0-1
wlan0
wlan1-1
wlan1
global
root@OpenWrt:/tmp/run# hostapd_cli -i wlan0-1 all_sta
root@OpenWrt:/tmp/run# hostapd_cli -i wlan0 all_sta
root@OpenWrt:/tmp/run# hostapd_cli -i wlan1-1 all_sta
root@OpenWrt:/tmp/run# hostapd_cli -i wlan1 all_sta
root@OpenWrt:/tmp/run# hostapd_cli -i global all_sta
root@OpenWrt:/tmp/run# 

This is on Linksys E8450 running master, SNAPSHOT r19773-f5a87a0a7b.

It seems this command only works when using wpad-wolfssl, not wpad-basic-wolfssl. After switching the package via attended-sysupgrade, it seems to work.