[wpa_supplicant] Cumulative patch from commit 59e9794c7
Bug: 180762886
Test: Verify Passpoint ANQP functionality and Passpoint association
Test: Connect to Passpoint, Open, WPA2, WPA3 networks and run traffic
Test: Regression test passed (Bug: 180943193)
BYPASS_INCLUSIVE_LANGUAGE_REASON=Merged from Open source
59e9794c7 QCA vendor attribute to configure Punctured Preamble Rx in HE cap
875d7be38 QCA vendor attribute to disable data and management frame Tx
ecb7590f3 QCA vendor attribute to configure RU 242 tone for data Tx
8d2329712 QCA vendor attribute to configure BSS max idle period
dc72854fe Fix handle_auth_cb() message length check regression
f03580e31 Restore permanent MAC address on the FLUSH command
976c3c161 DPP2: Accept Config Result before GAS response TX status
6518c72b0 Multi-AP: Fix backhaul SSID printing condition
1ba8a315c Avoid use of C++ keyword in a header file
10502ad59 radiotap: Fix compiler issues with packed structures
0dee287c8 EAP server: Extend EAP-TLS Commitment Message use to PEAP and EAP-TTLS
fae4eafe4 EAP-TTLS peer: Handle Commitment Message for TLS 1.3
155125b02 EAP-TLS peer: Handle Commitment Message for TLS 1.3
3a457509d EAP: Extend Session-Id derivation with TLS 1.3 to PEAP and EAP-TTLS
647db6a6b EAP-TTLS: Key derivation per draft-ietf-emu-tls-eap-types-00
c74f23020 EAP-PEAP: Key derivation per draft-ietf-emu-tls-eap-types-00
872609c15 EAP-TTLS/PEAP peer: Fix failure when using session tickets under TLS 1.3
8265f8453 nl80211: Unconditionally clear nl_msg
6c7b0a965 PASN: Correctly set RSNXE bits from AP
85eb47e3a PASN: Correctly set RSNXE bits from STA
be5f7f374 wpa_supplicant: Fix potential memleak on an error path
8f248d1ac Check for message truncation in RADIUS client
5cb25307e Set RADIUS message length to reflect RFC 2865
7df089b56 Create RADIUS_MAX_MSG_LEN param in the shared radius.h
98a52b09c Add new attributes in get_sta_info QCA vendor command
8f204f69a Show OCV and beacon protection capabilities in control interface
6f92f81da AP: Check driver's capability to enable OCV when driver SME is used
73ebd58fc STA: Check driver capability to enable OCV when driver SME is used
f3dfe42c7 Clean up RSN parameter setting for PASN
d36d4209f Enable beacon protection only when driver indicates support
9d99814e2 Update sgml to generate reproducible manpages
e680a51e9 ext_password: Implement new file-based backend
e9f449ba5 wpa_supplicant: Move wpa_config_get_line() into utils
b1c23d3f2 HE: Fall back to 20 MHz on 2.4 GHz if 40 MHz is not supported
f1c6c9d3e ACS: Allow downgrading to 20 MHz based on OBSS results
9bb2f7529 Sync with mac80211-next.git include/uapi/linux/nl80211.h
cfc45a98d nl80211: Unsolicited broadcast Probe Response configuration
024b4b2a2 AP: Unsolicited broadcast Probe Response configuration
6fb626412 P2P: Clear unexpected HT40 configuration on 2.4 GHz band
6b59e63f0 Include secondary channel config in no-hw-channel-found message
d76ba2b31 nl80211: Add FILS Discovery frame configuration
9c02a0f5a FILS: Add generation of FILS Discovery frame template
c4c529e9c Add a helper function for determining RSN capabilities field value
272466518 Define FILS Discovery frame subfields
3eb5f7128 Do not include VHT elements in Beacon frames on the 6 GHz band
2c2b6d265 Add Transmit Power Envelope also for 6 GHz HE AP
6c2b729de Use hostapd_get_oper_chwidth() when build Transmit Power Envelope element
5d3c4496f Make VHT Transmit Power Envelope element helper more generic
58bbbb598 nl80211: Ignore 4addr mode enabling error if it was already enabled
1b45b8d3f wpa_supplicant: Don't exit scanning state on config reload
581df2d52 DPP2: Defer chirp scan if other scan is queued up
35756c02e mesh: Assign channel in frequency params in all bands
b1c3e4d07 nl80211: Send HE 6 GHz capability parameters to the driver
8d10831dc wolfSSL: wolfSSL_use_PrivateKey_* correct return codes
7e823d4df DPP: Expose config object PSK/passphrase in wpa_supplicant
1029f16a9 DPP: Expose config object AKM in wpa_supplicant control interface
ad59639ed DPP2: Fix Authentication Request destination in the chirping case
598f67132 SAE: Avoid driver STA entry removal unnecessarily when using H2E/PK
99cd45372 hw_feature: Correctly select mode in case of the 6 GHz band
f728c867e AP: Extend Spatial Reuse Parameter Set
9f9d3d362 Allow HE MCS rate selection for Beacon frames
7f2f262e6 nl80211: Support the 6 GHz band for beacon rate configuration
c3d557b4d hostapd: Add HE 6 GHz band capability configuration
bd8b17030 EAP-AKA: Check that ID message storing succeeds
e781f7c86 Fix compiler warning on CONFIG_AP without CONFIG_P2P builds
4c9b16602 Update Visual Studio projects to match file renaming
48cfb52b7 Rename blacklist.[ch] to bssid_ignore.[ch]
626fc0dcd Rename wpa_blacklist to wpa_bssid_ignore
b58ac90c3 Rename INTERWORKING_BLACKLISTED define
72cd4293f Rename the control interface BLACKLIST command to BSSID_IGNORE
752b1c608 Rename network profiles parameters for ignoring/accepted BSSIDs
e6ac26943 radiotap: Update radiotap parser
136bbf15c wlantest: Add more details about protected FTM frames
f56eec7c1 wlantest: Process Action No Ack frames like Action frames
ef26fc19f DFS: Allow switch to an available channel
f98fe2fd0 hostapd: Report errors ACCEPT_ACL/DENY_ACL control interface commands
15251c658 hostapd: Fix dynamic ACCEPT_ACL management over control interface
871d6648f hostapd: Add multi_ap settings to get_config() output
f95ccc102 WPS: Reconfigure credentials on hostapd config reload
2fd90eb09 WPS: Use helper variables to clean up code
f7bbad576 wpa_supplicant: Configurable fast-associate timer threshold
b829b7003 wpa_supplicant: Notify freq change on CH_SWITCH
3a00a86bb hostapd: Fix dpp_listen in DPP responder scenario
4a7e0ac26 hostapd: Add an option to notify management frames on ctrl_iface
e79febb3f P2P: Adding option to manage device drivers creating random MAC addresses
a579642bc BSD: If route socket overflows, sync drivers to system interfaces
fa859ebb1 RSN+WPA: Fix RSNE removing in EAPOL-Key msg 3/4 when RSNXE is included
dc1977959 RSN: Validate RSNXE match in EAPOL-Key msg 3/4 only when RSN is used
0b7895750 DPP: Silence compiler warning about signed/unsigned comparison
8f557d204 Make wpa_bss_ext_capab() handle NULL bss argument
2cadb60ab robust_av: Use wpa_bss_ext_capab() helper
a287c2078 Disable HE capabilities when using unacceptable security config
56c192c5e nl80211: Skip frame filter config for P2P-Device
2b916c9fd dbus: Fix IEs getter to use wpa_bss_ie_ptr()
9416b5f32 Add HE in ieee80211_freq_to_channel_ext() documentation
2acfd15a2 hostapd: Generalize channel switch methods to incorperated HE mode
2908dc91c hostapd: Enable HE for channel switch commmand
1c3e71d14 P2P: Add a maximum length limit for peer vendor IEs
947272feb P2P: Fix copying of secondary device types for P2P group client
25df656a8 Remove pointless defines for ext capab bits
11355a122 Reset external_scan_running on interface deletion
630b1fdba AP: Add 6 GHz security constraints
df0bfe475 mesh: Fix for leaving mesh
24f0507af WPA: Support deriving KDK based on capabilities (Authenticator)
dccb6cde0 WPA: Support deriving KDK based on capabilities
9e7b980d6 PASN: Include RSNXE in the PASN negotiation
d8cd20e37 RSN: Add RSNXE new definitions
2eb2fb8bd AP: Support PASN with FT key derivation
5c65ad6c0 PASN: Support PASN with FT key derivation
62edb79a0 AP: Support PASN with FILS key derivation
8c6d2e252 PASN: Support PASN with FILS key derivation
da35e1214 AP: Support PASN with SAE key derivation
a93ec28d1 PASN: Support PASN with SAE key derivation
3040c8a2d AP: Add support for PASN processing to the SME
f2f8e4f45 Add PTKSA cache to hostapd
2c963a117 AP: Add support for configuring PASN
ad338cfe5 ctrl_iface: Add support for PASN authentication
363768c8a PASN: Add support for PASN processing to wpa_supplicant
d70060f96 WPA: Add PTKSA cache to wpa_supplicant for PASN
a4e369161 WPA: Add PTKSA cache implementation
a84ba92fa WPA: Add a function to get PMKSA cache entry
6709b4ceb common: Add PASN parsing to ieee802_11_parse_extension()
46bfc3a84 tests: Add module tests for PASN PTK derivation
9ce123cdb PASN: Add common Authentication frame build/validation functions
c6d1a33bb PASN: Add functions to compute PTK, MIC and hash
d87f4aea1 FILS: Extend the fils_pmk_to_ptk() function to also derive KDK
6e834db74 FT: Extend the wpa_pmk_r1_to_ptk() function to also derive KDK
46c232eb7 WPA: Extend the wpa_pmk_to_ptk() function to also derive KDK
019507e10 common: Allow WPA_CIPHER_GTK_NOT_USED as a valid group management cipher
244721221 nl80211: Always register for RX authentication frames with PASN
a728449a0 nl80211: Allow off-channel of PASN authentication frames in send_mlme()
367e79231 PASN: Add some specification definitions
833cdbe97 Add support for new 5 GHz channels 173 and 177
21fdb454d P2P: Fix channel selection for operating class 129
959af4f57 DPP: Abort authentication if no Auth Confirm is received within a second
62657365f Add a configuration to disconnect on deinit if WoWLAN is enabled
8f5897294 dbus: Export new 'suiteb192' capability
9cdcc8823 DBus: Add 'owe' to interface Capabilities
8e8406469 wpa_cli: Add WPS_EVENT_OVERLAP to action scripts
41fae6e0b nl80211: Add missing WPA3-SAE auth_data in auth retry case
71718b628 FT: Update key mgmt properly in RSNE during roaming
ea77568d8 Add user configured vendor IEs to default scan IEs
b6947f01a Android: Pass the vendor events to $(BOARD_WPA_SUPPLICANT_PRIVATE_LIB)
7b121af26 P2P: Delay P2P scan when an external scan is in progress
f39d6aacb P2P: Recover p2p_find operation in case of failure to fetch scan results
74818ca63 Process QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH after NL80211_CMD_ROAM
b4a41abad nl80211: Do not ignore disconnection event after a connection event
084b3d2f8 Drop unexpected connection event while disconnected
73c7c2da9 Vendor feature capability to notify TWT asynchronous response support
a337c1d7c New TWT operations and attributes to TWT Setup and Nudge
b709bb40f DPP2: Add DPP_CONTROLLER commands to hostapd_cli and wpa_cli
6ead8b897 Use bool for is_6ghz variables and functions
7131fede3 Extend the setband support for 6 GHz and band combinations
2a37cda74 scan: Add a helper function to append supported freqs from a given band
bba926350 Fix gcc-10 build with -Werror=array-bounds and dl_list_for_each()
0225301fd wolfSSL: Client cert loading API fix
297050b46 nl80211: Report invalid signal and noise when info is unavailable
be96f4e8d wlantest: Allow missing RSNE in S1G beacon
d83eaa351 Add option to ignore Probe Request frames when RSSI is too low
f2a010140 wpa_supplicant: Initial connection speedup
4683b7218 DFS: Enter DFS state if no available channel is found
eee0d242b hostapd: Add ability to disable HT/VHT/HE per BSS
89ad24379 mesh: Move mesh frequency setting to its own function
7c2cad969 mesh: Fix DFS deinit/init
0896c442d mesh: Fix for mesh init/deinit
06161d4f1 mesh: Fix mesh_oom test
12ae3e3db mesh: Inform kernel driver about DFS handler in userspace
a27faf2c9 mesh: Fix channel switch error during CAC
872590978 nl80211: Do not set offchanok on DFS channels in non-ETSI for mesh
e3608040c mesh: Update ssid->frequency as pri/sec channels switch
f1df4fbfc mesh: Use setup completion callback to complete mesh join
3c9abc785 QCA vendor attributes to configure TX and RX NSS
ed24bad1d AP: Check driver support while auto-selecting bandwidth for AP/P2P GO
5b782ff62 Add bus failure reason code to vendor indication
1c77f3d3f Indicate whether additional ANQP elements were protected
90ca804e4 Add vendor attributes for TWT nudge request
454ebb504 BSS: Use variable length array for IEs at the end of struct wpa_bss
be7ee264f BSS: Use wrapper function for getting a pointer to the IE buffer
95edd8144 BSS: Add wpa_bss_get_ie_ext() wrapper
dba4f7a54 Mark wpa_bss_get_fils_cache_id() argument const
2a7023ba6 Change list arguments to const where possible
fdf114641 nl80211: Send the sae_pwe value to the driver
2576f27e0 P2P: Disable P2P in the 6 GHz band for now
2ffd3bb4b P2P: Include p2p_6ghz_disable in global configuration
60c902f40 Add connect fail reason code from the driver to assoc reject event
7423fa6e8 Vendor feature capability to support concurrent sessions on Wi-Fi bands
1934ad9b2 Add extra parameters to vendor command GPIO attribute
d0e0d2283 Sync with mac80211-next.git include/uapi/linux/nl80211.h
c2c468622 Set NLA_F_NESTED flag with NL80211_ATTR_VENDOR_DATA conditionally
cd3aa54a3 Add test configuration attr to enable/disable full bandwidth UL MU-MIMO
f4de21a77 BSS/scan: More conversions to for_each_element_id()
aa06444f2 dbus: Check eloop registration failure in add_watch handler
56a1df71e BSS: Convert wpa_bss_get_vendor_ie() to use for_each_element_id()
ec1f4f3c8 Make GTK length validation for RSN Group 1/2 easier to analyze
c42d41bf3 EAP-IKEv2: Try to make transform parser simpler to understand
ec0d99c00 HS 2.0: Clarify OSU Friendly Name length validation
05962099c TDLS: Fix error path for TPK M1 send failure in testing functionality
a9fed5f5b Avoid undefined behavior with memcpy PMK/PSK update
c643c3928 nl80211: Fix filtering of unsupported bands/modes
a86078c87 TDLS: Fix error path handling for TPK M1 send failures
3d490296b DPP2: Fix error path handling in enterprise provisioning
f724dd1bf Remove unused variable update
589bf1f7a DPP2: Fix ppkey parsing
79e3f08d3 6 GHz: Add support for missing 6 GHz operating classes
66bed14b2 6 GHz: Fix opclasses mapping in ieee80211_freq_to_channel_ext()
5e779873e EAP-SIM peer: Send AT_IDENTITY first
0577e8e67 nl80211: Check for proper nlmsg allocation in send_and_recv_msgs_owner()
02289ab53 DPP2: Explicitly check EC_KEY before dereferencing it
c57590476 P2P: Consider BSS entry pending for P2P joining as a known BSS
106d67a93 nl80211: Filter out unsupported bands
9c39c1a6d P2P: Include p2p_add_cli_chan parameter while cloning the configuration
8f0ed71ff Vendor specific feature capability for Adaptive 11r
45ae6ae8e Add additional vendor specific hang reason codes
d2190cdc6 DPP2: Update the default port number for DPP-over-TCP
5d988b4a5 Fix couple more typos
b439b21a2 wpa_supplicant: Fix typos
183e72ae1 SAE-PK: Do not accept SAE-PK status code when no PK is configured
80662accb SAE: Don't use potentially uninitialized keys
b4c7114cf wpa_supplicant: Remove unfeasible conditions in config parsing
ff7e0c1cf wpa_cli: Don't access uninitialized variables
e364a34c6 OpenSSL: Make openssl_debug_dump_certificate() more robust
Change-Id: Ia7e3838712a621fe0341464dd04671f708d8cde4
diff --git a/src/common/Makefile b/src/common/Makefile
index 59ba6c5..e2c5f03 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -3,12 +3,14 @@
CFLAGS += -DCONFIG_SAE
CFLAGS += -DCONFIG_SUITE
CFLAGS += -DCONFIG_SUITEB
+CFLAGS += -DCONFIG_PTKSA_CACHE
LIB_OBJS= \
gas.o \
hw_features_common.o \
ieee802_11_common.o \
sae.o \
+ ptksa_cache.o \
wpa_common.o
include ../lib.rules
diff --git a/src/common/common_module_tests.c b/src/common/common_module_tests.c
index 00308d4..50ce192 100644
--- a/src/common/common_module_tests.c
+++ b/src/common/common_module_tests.c
@@ -637,6 +637,178 @@
}
+#ifdef CONFIG_PASN
+
+static int pasn_test_pasn_auth(void)
+{
+ /* Test vector taken from IEEE P802.11az/D2.6, J.12 */
+ const u8 pmk[] = {
+ 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
+ 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
+ 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
+ 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
+ };
+
+ const u8 spa_addr[] = {
+ 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
+ };
+ const u8 bssid[] = {
+ 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
+ };
+ const u8 dhss[] = {
+ 0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37,
+ 0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda,
+ 0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0,
+ 0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93
+ };
+ const u8 kck[] = {
+ 0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d,
+ 0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77,
+ 0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0,
+ 0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06
+ };
+ const u8 tk[] = {
+ 0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8,
+ 0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e
+ };
+ const u8 kdk[] = {
+ 0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b,
+ 0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2,
+ 0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5,
+ 0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6
+ };
+ struct wpa_ptk ptk;
+ int ret;
+
+ ret = pasn_pmk_to_ptk(pmk, sizeof(pmk),
+ spa_addr, bssid,
+ dhss, sizeof(dhss),
+ &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP,
+ WPA_KDK_MAX_LEN);
+
+ if (ret)
+ return ret;
+
+ if (ptk.kck_len != sizeof(kck) ||
+ os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
+ wpa_printf(MSG_ERROR, "PASN: Mismatched KCK");
+ return -1;
+ }
+
+ if (ptk.tk_len != sizeof(tk) ||
+ os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
+ wpa_printf(MSG_ERROR, "PASN: Mismatched TK");
+ return -1;
+ }
+
+ if (ptk.kdk_len != sizeof(kdk) ||
+ os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
+ wpa_printf(MSG_ERROR, "PASN: Mismatched KDK");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int pasn_test_no_pasn_auth(void)
+{
+ /* Test vector taken from IEEE P802.11az/D2.6, J.13 */
+ const u8 pmk[] = {
+ 0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
+ 0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
+ 0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
+ 0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
+ };
+ const u8 aa[] = {
+ 0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
+ };
+ const u8 spa[] = {
+ 0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
+ };
+ const u8 anonce[] = {
+ 0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b,
+ 0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f,
+ 0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00,
+ 0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f
+ };
+ const u8 snonce[] = {
+ 0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f,
+ 0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25,
+ 0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e,
+ 0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71
+ };
+ const u8 kck[] = {
+ 0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0,
+ 0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5
+ };
+ const u8 kek[] = {
+ 0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6,
+ 0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b
+ };
+ const u8 tk[] = {
+ 0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73,
+ 0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03
+ };
+ const u8 kdk[] = {
+ 0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a,
+ 0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5,
+ 0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36,
+ 0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff
+ };
+ struct wpa_ptk ptk;
+ int ret;
+
+ ret = wpa_pmk_to_ptk(pmk, sizeof(pmk),
+ "Pairwise key expansion",
+ spa, aa, snonce, anonce,
+ &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP,
+ NULL, 0, WPA_KDK_MAX_LEN);
+
+ if (ret)
+ return ret;
+
+ if (ptk.kck_len != sizeof(kck) ||
+ os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
+ wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK");
+ return -1;
+ }
+
+ if (ptk.kek_len != sizeof(kek) ||
+ os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) {
+ wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK");
+ return -1;
+ }
+
+ if (ptk.tk_len != sizeof(tk) ||
+ os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
+ wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK");
+ return -1;
+ }
+
+ if (ptk.kdk_len != sizeof(kdk) ||
+ os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
+ wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK");
+ return -1;
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_PASN */
+
+
+static int pasn_tests(void)
+{
+#ifdef CONFIG_PASN
+ if (pasn_test_pasn_auth() ||
+ pasn_test_no_pasn_auth())
+ return -1;
+#endif /* CONFIG_PASN */
+ return 0;
+}
+
+
int common_module_tests(void)
{
int ret = 0;
@@ -647,6 +819,7 @@
gas_tests() < 0 ||
sae_tests() < 0 ||
sae_pk_tests() < 0 ||
+ pasn_tests() < 0 ||
rsn_ie_parse_tests() < 0)
ret = -1;
diff --git a/src/common/defs.h b/src/common/defs.h
index bbe3120..f43bdb5 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -49,6 +49,8 @@
#define WPA_KEY_MGMT_OWE BIT(22)
#define WPA_KEY_MGMT_DPP BIT(23)
#define WPA_KEY_MGMT_FT_IEEE8021X_SHA384 BIT(24)
+#define WPA_KEY_MGMT_PASN BIT(25)
+
#define WPA_KEY_MGMT_FT (WPA_KEY_MGMT_FT_PSK | \
WPA_KEY_MGMT_FT_IEEE8021X | \
@@ -388,9 +390,10 @@
};
enum set_band {
- WPA_SETBAND_AUTO,
- WPA_SETBAND_5G,
- WPA_SETBAND_2G
+ WPA_SETBAND_AUTO = 0,
+ WPA_SETBAND_5G = BIT(0),
+ WPA_SETBAND_2G = BIT(1),
+ WPA_SETBAND_6G = BIT(2),
};
enum wpa_radio_work_band {
@@ -402,7 +405,8 @@
enum beacon_rate_type {
BEACON_RATE_LEGACY,
BEACON_RATE_HT,
- BEACON_RATE_VHT
+ BEACON_RATE_VHT,
+ BEACON_RATE_HE
};
enum eap_proxy_sim_state {
diff --git a/src/common/dpp.c b/src/common/dpp.c
index 67b8f07..e8697c5 100644
--- a/src/common/dpp.c
+++ b/src/common/dpp.c
@@ -4195,7 +4195,7 @@
}
if (ppkey) {
- pp_key_len = os_strlen(key) / 2;
+ pp_key_len = os_strlen(ppkey) / 2;
pp_key = os_malloc(pp_key_len);
if (!pp_key ||
hexstr2bin(ppkey, pp_key, pp_key_len) < 0)
diff --git a/src/common/dpp.h b/src/common/dpp.h
index 99a1ca7..6e397c3 100644
--- a/src/common/dpp.h
+++ b/src/common/dpp.h
@@ -35,7 +35,7 @@
#endif /* CONFIG_TESTING_OPTIONS */
#define DPP_HDR_LEN (4 + 2) /* OUI, OUI Type, Crypto Suite, DPP frame type */
-#define DPP_TCP_PORT 7871
+#define DPP_TCP_PORT 8908
enum dpp_public_action_frame_type {
DPP_PA_AUTHENTICATION_REQ = 0,
@@ -349,6 +349,7 @@
struct wpabuf *cacert;
struct wpabuf *certbag;
void *cert_resp_ctx;
+ void *gas_server_ctx;
#ifdef CONFIG_TESTING_OPTIONS
char *config_obj_override;
char *discovery_override;
diff --git a/src/common/dpp_auth.c b/src/common/dpp_auth.c
index f79cfef..0cabd64 100644
--- a/src/common/dpp_auth.c
+++ b/src/common/dpp_auth.c
@@ -251,6 +251,7 @@
u8 *attr_start, *attr_end, *pos;
auth->waiting_auth_conf = 1;
+ auth->auth_resp_status = status;
auth->auth_resp_tries = 0;
/* Build DPP Authentication Response frame attributes */
diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c
index 7c48015..c75fc78 100644
--- a/src/common/dpp_crypto.c
+++ b/src/common/dpp_crypto.c
@@ -2305,13 +2305,15 @@
/* M = { cR + pR } * CI */
cR = EVP_PKEY_get0_EC_KEY(own_key);
pR = EVP_PKEY_get0_EC_KEY(auth->own_protocol_key);
+ if (!pR)
+ goto fail;
group = EC_KEY_get0_group(pR);
bnctx = BN_CTX_new();
sum = BN_new();
mx = BN_new();
q = BN_new();
m = EC_POINT_new(group);
- if (!cR || !pR || !bnctx || !sum || !mx || !q || !m)
+ if (!cR || !bnctx || !sum || !mx || !q || !m)
goto fail;
cR_bn = EC_KEY_get0_private_key(cR);
pR_bn = EC_KEY_get0_private_key(pR);
@@ -2866,6 +2868,7 @@
res = BIO_read(out, wpabuf_put(pem, 0), rlen);
if (res <= 0) {
wpabuf_free(pem);
+ pem = NULL;
goto fail;
}
wpabuf_put(pem, res);
diff --git a/src/common/dpp_tcp.c b/src/common/dpp_tcp.c
index 7e330d6..609c243 100644
--- a/src/common/dpp_tcp.c
+++ b/src/common/dpp_tcp.c
@@ -1279,7 +1279,7 @@
const u8 *pos, *end, *next, *adv_proto;
u16 status, slen, comeback_delay;
- if (len < 5 + 2 + (comeback ? 1 : 0))
+ if (len < (size_t) (5 + 2 + (comeback ? 1 : 0)))
return -1;
wpa_printf(MSG_DEBUG,
diff --git a/src/common/gas_server.c b/src/common/gas_server.c
index c000aeb..5f44ffe 100644
--- a/src/common/gas_server.c
+++ b/src/common/gas_server.c
@@ -489,6 +489,21 @@
}
+bool gas_server_response_sent(struct gas_server *gas, void *resp_ctx)
+{
+ struct gas_server_response *tmp;
+
+ dl_list_for_each(tmp, &gas->responses, struct gas_server_response,
+ list) {
+ if (tmp == resp_ctx)
+ return tmp->resp &&
+ tmp->offset == wpabuf_len(tmp->resp);
+ }
+
+ return false;
+}
+
+
struct gas_server * gas_server_init(void *ctx,
void (*tx)(void *ctx, int freq,
const u8 *da,
diff --git a/src/common/gas_server.h b/src/common/gas_server.h
index 2611dde..db00f87 100644
--- a/src/common/gas_server.h
+++ b/src/common/gas_server.h
@@ -36,6 +36,7 @@
size_t data_len, int ack);
int gas_server_set_resp(struct gas_server *gas, void *resp_ctx,
struct wpabuf *resp);
+bool gas_server_response_sent(struct gas_server *gas, void *resp_ctx);
#else /* CONFIG_GAS_SERVER */
diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index 511e68f..b8b886f 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -41,10 +41,30 @@
struct hostapd_channel_data *
+hw_mode_get_channel(struct hostapd_hw_modes *mode, int freq, int *chan)
+{
+ int i;
+
+ for (i = 0; i < mode->num_channels; i++) {
+ struct hostapd_channel_data *ch = &mode->channels[i];
+
+ if (ch->freq == freq) {
+ if (chan)
+ *chan = ch->chan;
+ return ch;
+ }
+ }
+
+ return NULL;
+}
+
+
+struct hostapd_channel_data *
hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
struct hostapd_hw_modes *hw_features, int num_hw_features)
{
- int i, j;
+ struct hostapd_channel_data *chan_data;
+ int i;
if (chan)
*chan = 0;
@@ -52,21 +72,15 @@
if (!hw_features)
return NULL;
- for (j = 0; j < num_hw_features; j++) {
- struct hostapd_hw_modes *curr_mode = &hw_features[j];
+ for (i = 0; i < num_hw_features; i++) {
+ struct hostapd_hw_modes *curr_mode = &hw_features[i];
if (curr_mode->mode != mode)
continue;
- for (i = 0; i < curr_mode->num_channels; i++) {
- struct hostapd_channel_data *ch =
- &curr_mode->channels[i];
- if (ch->freq == freq) {
- if (chan)
- *chan = ch->chan;
- return ch;
- }
- }
+ chan_data = hw_mode_get_channel(curr_mode, freq, chan);
+ if (chan_data)
+ return chan_data;
}
return NULL;
@@ -580,6 +594,8 @@
center_segment0 = 138;
else if (channel <= 161)
center_segment0 = 155;
+ else if (channel <= 177)
+ center_segment0 = 171;
data->center_freq1 = 5000 + center_segment0 * 5;
} else {
/*
diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h
index e57a8d6..ddde36b 100644
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -15,6 +15,9 @@
struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
int chan, int *freq);
struct hostapd_channel_data *
+hw_mode_get_channel(struct hostapd_hw_modes *mode, int freq, int *chan);
+
+struct hostapd_channel_data *
hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
struct hostapd_hw_modes *hw_features, int num_hw_features);
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 72d7dda..fa39761 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -307,6 +307,10 @@
break;
elems->he_6ghz_band_cap = pos;
break;
+ case WLAN_EID_EXT_PASN_PARAMS:
+ elems->pasn_params = pos;
+ elems->pasn_params_len = elen;
+ break;
default:
if (show_errors) {
wpa_printf(MSG_MSGDUMP,
@@ -570,6 +574,11 @@
elems->dils = pos;
elems->dils_len = elen;
break;
+ case WLAN_EID_S1G_CAPABILITIES:
+ if (elen < 15)
+ break;
+ elems->s1g_capab = pos;
+ break;
case WLAN_EID_FRAGMENT:
ieee802_11_parse_fragment(&elems->frag_ies, pos, elen);
break;
@@ -876,7 +885,7 @@
/**
* ieee80211_freq_to_channel_ext - Convert frequency into channel info
- * for HT40 and VHT. DFS channels are not covered.
+ * for HT40, VHT, and HE. DFS channels are not covered.
* @freq: Frequency (MHz) to convert
* @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
* @chanwidth: VHT/EDMG channel width (CHANWIDTH_*)
@@ -987,8 +996,8 @@
return HOSTAPD_MODE_IEEE80211A;
}
- /* 5 GHz, channels 149..169 */
- if (freq >= 5745 && freq <= 5845) {
+ /* 5 GHz, channels 149..177 */
+ if (freq >= 5745 && freq <= 5885) {
if ((freq - 5000) % 5)
return NUM_HOSTAPD_MODES;
@@ -1036,15 +1045,28 @@
}
if (freq > 5950 && freq <= 7115) {
- int bw;
- u8 idx = (freq - 5950) / 5;
-
- bw = center_idx_to_bw_6ghz(idx);
- if (bw < 0)
+ if ((freq - 5950) % 5)
return NUM_HOSTAPD_MODES;
- *channel = idx;
- *op_class = 131 + bw;
+ switch (chanwidth) {
+ case CHANWIDTH_80MHZ:
+ *op_class = 133;
+ break;
+ case CHANWIDTH_160MHZ:
+ *op_class = 134;
+ break;
+ case CHANWIDTH_80P80MHZ:
+ *op_class = 135;
+ break;
+ default:
+ if (sec_channel)
+ *op_class = 132;
+ else
+ *op_class = 131;
+ break;
+ }
+
+ *channel = (freq - 5950) / 5;
return HOSTAPD_MODE_IEEE80211A;
}
@@ -1405,22 +1427,22 @@
return -1;
return 5000 + 5 * chan;
case 124: /* channels 149,153,157,161 */
- case 126: /* channels 149,157; 40 MHz */
- case 127: /* channels 153,161; 40 MHz */
if (chan < 149 || chan > 161)
return -1;
return 5000 + 5 * chan;
- case 125: /* channels 149,153,157,161,165,169 */
- if (chan < 149 || chan > 169)
+ case 125: /* channels 149,153,157,161,165,169,173,177 */
+ case 126: /* channels 149,157,165,173; 40 MHz */
+ case 127: /* channels 153,161,169,177; 40 MHz */
+ if (chan < 149 || chan > 177)
return -1;
return 5000 + 5 * chan;
- case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
- case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
- if (chan < 36 || chan > 161)
+ case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
+ case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
+ if (chan < 36 || chan > 177)
return -1;
return 5000 + 5 * chan;
- case 129: /* center freqs 50, 114; 160 MHz */
- if (chan < 36 || chan > 128)
+ case 129: /* center freqs 50, 114, 163; 160 MHz */
+ if (chan < 36 || chan > 177)
return -1;
return 5000 + 5 * chan;
case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
@@ -1865,21 +1887,26 @@
{ HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
- { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
- { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
- { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 125, 149, 177, 4, BW20, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 126, 149, 173, 8, BW40PLUS, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 127, 153, 177, 8, BW40MINUS, P2P_SUPP },
/*
- * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
- * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
- * 80 MHz, but currently use the following definition for simplicity
+ * IEEE P802.11ax/D8.0 Table E-4 actually talks about channel center
+ * frequency index 42, 58, 106, 122, 138, 155, 171 with channel spacing
+ * of 80 MHz, but currently use the following definition for simplicity
* (these center frequencies are not actual channels, which makes
- * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
+ * wpas_p2p_verify_channel() fail). wpas_p2p_verify_80mhz() should take
* care of removing invalid channels.
*/
- { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
- { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
- { HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, NO_P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, NO_P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, NO_P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, NO_P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
/*
* IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
@@ -1895,7 +1922,7 @@
* the OneHundredAndThirty Delimiter value used in the Supported
* Operating Classes element to indicate the end of the Operating
* Classes field. */
- { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
};
@@ -2193,6 +2220,7 @@
switch (map->bw) {
case BW20:
return 20;
+ case BW40:
case BW40PLUS:
case BW40MINUS:
return 40;
@@ -2228,44 +2256,44 @@
}
-int is_6ghz_freq(int freq)
+bool is_6ghz_freq(int freq)
{
if (freq < 5935 || freq > 7115)
- return 0;
+ return false;
if (freq == 5935)
- return 1;
+ return true;
if (center_idx_to_bw_6ghz((freq - 5950) / 5) < 0)
- return 0;
+ return false;
- return 1;
+ return true;
}
-int is_6ghz_op_class(u8 op_class)
+bool is_6ghz_op_class(u8 op_class)
{
return op_class >= 131 && op_class <= 136;
}
-int is_6ghz_psc_frequency(int freq)
+bool is_6ghz_psc_frequency(int freq)
{
int i;
if (!is_6ghz_freq(freq) || freq == 5935)
- return 0;
+ return false;
if ((((freq - 5950) / 5) & 0x3) != 0x1)
- return 0;
+ return false;
i = (freq - 5950 + 55) % 80;
if (i == 0)
i = (freq - 5950 + 55) / 80;
if (i >= 1 && i <= 15)
- return 1;
+ return true;
- return 0;
+ return false;
}
@@ -2476,16 +2504,16 @@
case 123: /* channels 104-136; 40 MHz */
return 40;
case 124: /* channels 149,153,157,161 */
- case 125: /* channels 149,153,157,161,165,169 */
+ case 125: /* channels 149,153,157,161,165,169,173,177 */
return 20;
- case 126: /* channels 149,157; 40 MHz */
- case 127: /* channels 153,161; 40 MHz */
+ case 126: /* channels 149,157,161,165,169,173; 40 MHz */
+ case 127: /* channels 153..177; 40 MHz */
return 40;
- case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
+ case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
return 80;
- case 129: /* center freqs 50, 114; 160 MHz */
+ case 129: /* center freqs 50, 114, 163; 160 MHz */
return 160;
- case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
+ case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
return 80;
case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
return 20;
@@ -2537,16 +2565,16 @@
case 123: /* channels 104-136; 40 MHz */
return CHANWIDTH_USE_HT;
case 124: /* channels 149,153,157,161 */
- case 125: /* channels 149,153,157,161,165,169 */
+ case 125: /* channels 149,153,157,161,165,169,171 */
return CHANWIDTH_USE_HT;
- case 126: /* channels 149,157; 40 MHz */
- case 127: /* channels 153,161; 40 MHz */
+ case 126: /* channels 149,157,165, 173; 40 MHz */
+ case 127: /* channels 153,161,169,177; 40 MHz */
return CHANWIDTH_USE_HT;
- case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
+ case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
return CHANWIDTH_80MHZ;
- case 129: /* center freqs 50, 114; 160 MHz */
+ case 129: /* center freqs 50, 114, 163; 160 MHz */
return CHANWIDTH_160MHZ;
- case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
+ case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
return CHANWIDTH_80P80MHZ;
case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
return CHANWIDTH_USE_HT;
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 98a55ec..e4992b3 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -115,6 +115,8 @@
const u8 *short_ssid_list;
const u8 *he_6ghz_band_cap;
const u8 *sae_pk;
+ const u8 *s1g_capab;
+ const u8 *pasn_params;
u8 ssid_len;
u8 supp_rates_len;
@@ -168,6 +170,7 @@
u8 he_operation_len;
u8 short_ssid_list_len;
u8 sae_pk_len;
+ u8 pasn_params_len;
struct mb_ies_info mb_ies;
struct frag_ies_info frag_ies;
@@ -232,8 +235,8 @@
u8 min_chan;
u8 max_chan;
u8 inc;
- enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160, BW160, BW80P80, BW4320,
- BW6480, BW8640} bw;
+ enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80,
+ BW4320, BW6480, BW8640} bw;
enum { P2P_SUPP, NO_P2P_SUPP } p2p;
};
@@ -258,9 +261,9 @@
const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
int oper_class_bw_to_int(const struct oper_class_map *map);
int center_idx_to_bw_6ghz(u8 idx);
-int is_6ghz_freq(int freq);
-int is_6ghz_op_class(u8 op_class);
-int is_6ghz_psc_frequency(int freq);
+bool is_6ghz_freq(int freq);
+bool is_6ghz_op_class(u8 op_class);
+bool is_6ghz_psc_frequency(int freq);
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
size_t nei_rep_len);
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index de41d7f..c385923 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -50,6 +50,7 @@
#define WLAN_FC_STYPE_AUTH 11
#define WLAN_FC_STYPE_DEAUTH 12
#define WLAN_FC_STYPE_ACTION 13
+#define WLAN_FC_STYPE_ACTION_NO_ACK 14
/* control */
#define WLAN_FC_STYPE_PSPOLL 10
@@ -84,6 +85,7 @@
#define WLAN_AUTH_FILS_SK 4
#define WLAN_AUTH_FILS_SK_PFS 5
#define WLAN_AUTH_FILS_PK 6
+#define WLAN_AUTH_PASN 7
#define WLAN_AUTH_LEAP 128
#define WLAN_AUTH_CHALLENGE_LEN 128
@@ -432,7 +434,7 @@
#define WLAN_EID_VHT_OPERATION 192
#define WLAN_EID_VHT_EXTENDED_BSS_LOAD 193
#define WLAN_EID_VHT_WIDE_BW_CHSWITCH 194
-#define WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE 195
+#define WLAN_EID_TRANSMIT_POWER_ENVELOPE 195
#define WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER 196
#define WLAN_EID_VHT_AID 197
#define WLAN_EID_VHT_QUIET_CHANNEL 198
@@ -443,7 +445,10 @@
#define WLAN_EID_DEVICE_LOCATION 204
#define WLAN_EID_WHITE_SPACE_MAP 205
#define WLAN_EID_FTM_PARAMETERS 206
+#define WLAN_EID_S1G_BCN_COMPAT 213
+#define WLAN_EID_S1G_CAPABILITIES 217
#define WLAN_EID_VENDOR_SPECIFIC 221
+#define WLAN_EID_S1G_OPERATION 232
#define WLAN_EID_CAG_NUMBER 237
#define WLAN_EID_AP_CSN 239
#define WLAN_EID_FILS_INDICATION 240
@@ -482,6 +487,7 @@
#define WLAN_EID_EXT_TCLAS_MASK 89
#define WLAN_EID_EXT_REJECTED_GROUPS 92
#define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93
+#define WLAN_EID_EXT_PASN_PARAMS 100
/* Extended Capabilities field */
#define WLAN_EXT_CAPAB_20_40_COEX 0
@@ -525,7 +531,6 @@
#define WLAN_EXT_CAPAB_TDLS_PROHIBITED 38
#define WLAN_EXT_CAPAB_TDLS_CHANNEL_SWITCH_PROHIBITED 39
#define WLAN_EXT_CAPAB_REJECT_UNADMITTED_FRAME 40
-#define WLAN_EXT_CAPAB_
/* 41-43 - Service Interval Granularity */
#define WLAN_EXT_CAPAB_IDENTIFIER_LOCATION 44
#define WLAN_EXT_CAPAB_U_APSD_COEX 45
@@ -546,7 +551,6 @@
#define WLAN_EXT_CAPAB_PROT_QLOAD_REPORT 60
#define WLAN_EXT_CAPAB_TDLS_WIDER_BW 61
#define WLAN_EXT_CAPAB_OPMODE_NOTIF 62
-#define WLAN_EXT_CAPAB_
/* 63-64 - Max Number of MSDUs In A-MSDU */
#define WLAN_EXT_CAPAB_CHANNEL_SCHEDULE_MGMT 65
#define WLAN_EXT_CAPAB_GEODB_INBAND_ENABLING_SIGNAL 66
@@ -572,6 +576,9 @@
#define WLAN_RSNX_CAPAB_PROTECTED_TWT 4
#define WLAN_RSNX_CAPAB_SAE_H2E 5
#define WLAN_RSNX_CAPAB_SAE_PK 6
+#define WLAN_RSNX_CAPAB_SECURE_LTF 8
+#define WLAN_RSNX_CAPAB_SECURE_RTT 9
+#define WLAN_RSNX_CAPAB_PROT_RANGE_NEG 10
/* Action frame categories (IEEE Std 802.11-2016, 9.4.1.11, Table 9-76) */
#define WLAN_ACTION_SPECTRUM_MGMT 0
@@ -597,6 +604,7 @@
#define WLAN_ACTION_UNPROTECTED_DMG 20
#define WLAN_ACTION_VHT 21
#define WLAN_ACTION_FILS 26
+#define WLAN_ACTION_PROTECTED_FTM 34
#define WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED 126
#define WLAN_ACTION_VENDOR_SPECIFIC 127
/* Note: 128-255 used to report errors by setting category | 0x80 */
@@ -637,6 +645,7 @@
#define WLAN_PA_FTM_REQUEST 32
#define WLAN_PA_FTM 33
#define WLAN_PA_FILS_DISCOVERY 34
+#define WLAN_PA_LOCATION_MEASUREMENT_REPORT 47
/* Protected Dual of Public Action frames (IEEE Std 802.11-2016, 9.6.11,
* Table 9-332) */
@@ -694,6 +703,11 @@
#define WLAN_RRM_NEIGHBOR_REPORT_REQUEST 4
#define WLAN_RRM_NEIGHBOR_REPORT_RESPONSE 5
+/* Protected Fine Timing Frame Action Field value */
+#define WLAN_PROT_FTM_REQUEST 1
+#define WLAN_PROT_FTM 2
+#define WLAN_PROT_FTM_REPORT 3
+
/* Radio Measurement capabilities (from RM Enabled Capabilities element)
* IEEE Std 802.11-2016, 9.4.2.45, Table 9-157 */
/* byte 1 (out of 5) */
@@ -2392,4 +2406,51 @@
MCSC_SUBELEM_STATUS = 1,
};
+/*
+ * IEEE Std 802.11ai-2016, 9.6.8.36 FILS Discovery frame format,
+ * Figure 9-687b - FILS Discovery Frame Control subfield format
+ */
+#define FD_FRAME_CTL_CAP_PRESENT ((u16) BIT(5))
+#define FD_FRAME_CTL_SHORT_SSID_PRESENT ((u16) BIT(6))
+#define FD_FRAME_CTL_AP_CSN_PRESENT ((u16) BIT(7))
+#define FD_FRAME_CTL_ANO_PRESENT ((u16) BIT(8))
+#define FD_FRAME_CTL_FREQ_SEG1_PRESENT ((u16) BIT(9))
+#define FD_FRAME_CTL_PRI_CHAN_PRESENT ((u16) BIT(10))
+#define FD_FRAME_CTL_RSN_INFO_PRESENT ((u16) BIT(11))
+#define FD_FRAME_CTL_LENGTH_PRESENT ((u16) BIT(12))
+#define FD_FRAME_CTL_MD_PRESENT ((u16) BIT(13))
+
+/*
+ * IEEE Std 802.11ai-2016, 9.6.8.36 FILS Discovery frame format,
+ * Figure 9-687c - FD Capability subfield format
+ */
+#define FD_CAP_ESS BIT(0)
+#define FD_CAP_PRIVACY BIT(1)
+#define FD_CAP_MULTI_BSSID_PRESENT BIT(9)
+
+#define FD_CAP_BSS_CHWIDTH_20 0
+#define FD_CAP_BSS_CHWIDTH_40 1
+#define FD_CAP_BSS_CHWIDTH_80 2
+#define FD_CAP_BSS_CHWIDTH_160_80_80 3
+#define FD_CAP_BSS_CHWIDTH_SHIFT 2
+
+#define FD_CAP_NSS_1 0
+#define FD_CAP_NSS_2 1
+#define FD_CAP_NSS_3 2
+#define FD_CAP_NSS_4 3
+#define FD_CAP_NSS_5_8 4
+#define FD_CAP_NSS_SHIFT 5
+
+#define FD_CAP_PHY_INDEX_HR_DSSS 0
+#define FD_CAP_PHY_INDEX_ERP_OFDM 1
+#define FD_CAP_PHY_INDEX_HT 2
+#define FD_CAP_PHY_INDEX_VHT 3
+#define FD_CAP_PHY_INDEX_HE 4 /* P802.11ax */
+#define FD_CAP_PHY_INDEX_SHIFT 10
+
+/*
+ * IEEE P802.11ax/D8.0 26.17.2.3.2, AP behavior for fast passive scanning
+ */
+#define FD_MAX_INTERVAL_6GHZ 20 /* TUs */
+
#endif /* IEEE802_11_DEFS_H */
diff --git a/src/common/ocv.c b/src/common/ocv.c
index 4bc2749..c9dc14f 100644
--- a/src/common/ocv.c
+++ b/src/common/ocv.c
@@ -45,6 +45,8 @@
oci->sec_channel = 1;
else if (op_class_map->bw == BW40MINUS)
oci->sec_channel = -1;
+ else if (op_class_map->bw == BW40)
+ oci->sec_channel = (((oci->channel - 1) / 4) % 2) ? -1 : 1;
return 0;
}
diff --git a/src/common/ptksa_cache.c b/src/common/ptksa_cache.c
new file mode 100644
index 0000000..6a053d6
--- /dev/null
+++ b/src/common/ptksa_cache.c
@@ -0,0 +1,321 @@
+/*
+ * RSN PTKSA cache implementation
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+#include "utils/common.h"
+#include "eloop.h"
+#include "common/ptksa_cache.h"
+
+#define PTKSA_CACHE_MAX_ENTRIES 16
+
+struct ptksa_cache {
+ struct dl_list ptksa;
+ unsigned int n_ptksa;
+};
+
+static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa);
+
+
+static void ptksa_cache_free_entry(struct ptksa_cache *ptksa,
+ struct ptksa_cache_entry *entry)
+{
+ ptksa->n_ptksa--;
+
+ dl_list_del(&entry->list);
+ bin_clear_free(entry, sizeof(*entry));
+}
+
+
+static void ptksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
+{
+ struct ptksa_cache *ptksa = eloop_ctx;
+ struct ptksa_cache_entry *e, *next;
+ struct os_reltime now;
+
+ if (!ptksa)
+ return;
+
+ os_get_reltime(&now);
+
+ dl_list_for_each_safe(e, next, &ptksa->ptksa,
+ struct ptksa_cache_entry, list) {
+ if (e->expiration > now.sec)
+ continue;
+
+ wpa_printf(MSG_DEBUG, "Expired PTKSA cache entry for " MACSTR,
+ MAC2STR(e->addr));
+
+ ptksa_cache_free_entry(ptksa, e);
+ }
+
+ ptksa_cache_set_expiration(ptksa);
+}
+
+
+static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa)
+{
+ struct ptksa_cache_entry *e;
+ int sec;
+ struct os_reltime now;
+
+ eloop_cancel_timeout(ptksa_cache_expire, ptksa, NULL);
+
+ if (!ptksa || !ptksa->n_ptksa)
+ return;
+
+ e = dl_list_first(&ptksa->ptksa, struct ptksa_cache_entry, list);
+ if (!e)
+ return;
+
+ os_get_reltime(&now);
+ sec = e->expiration - now.sec;
+ if (sec < 0)
+ sec = 0;
+
+ eloop_register_timeout(sec + 1, 0, ptksa_cache_expire, ptksa, NULL);
+}
+
+
+/*
+ * ptksa_cache_init - Initialize PTKSA cache
+ *
+ * Returns: Pointer to PTKSA cache data or %NULL on failure
+ */
+struct ptksa_cache * ptksa_cache_init(void)
+{
+ struct ptksa_cache *ptksa = os_zalloc(sizeof(struct ptksa_cache));
+
+ wpa_printf(MSG_DEBUG, "PTKSA: Initializing");
+
+ if (ptksa)
+ dl_list_init(&ptksa->ptksa);
+
+ return ptksa;
+}
+
+
+/*
+ * ptksa_cache_deinit - Free all entries in PTKSA cache
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ */
+void ptksa_cache_deinit(struct ptksa_cache *ptksa)
+{
+ struct ptksa_cache_entry *e, *next;
+
+ if (!ptksa)
+ return;
+
+ wpa_printf(MSG_DEBUG, "PTKSA: Deinit. n_ptksa=%u", ptksa->n_ptksa);
+
+ dl_list_for_each_safe(e, next, &ptksa->ptksa,
+ struct ptksa_cache_entry, list)
+ ptksa_cache_free_entry(ptksa, e);
+
+ eloop_cancel_timeout(ptksa_cache_expire, ptksa, NULL);
+ os_free(ptksa);
+}
+
+
+/*
+ * ptksa_cache_get - Fetch a PTKSA cache entry
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @addr: Peer address or %NULL to match any
+ * @cipher: Specific cipher suite to search for or WPA_CIPHER_NONE for any
+ * Returns: Pointer to PTKSA cache entry or %NULL if no match was found
+ */
+struct ptksa_cache_entry * ptksa_cache_get(struct ptksa_cache *ptksa,
+ const u8 *addr, u32 cipher)
+{
+ struct ptksa_cache_entry *e;
+
+ if (!ptksa)
+ return NULL;
+
+ dl_list_for_each(e, &ptksa->ptksa, struct ptksa_cache_entry, list) {
+ if ((!addr || os_memcmp(e->addr, addr, ETH_ALEN) == 0) &&
+ (cipher == WPA_CIPHER_NONE || cipher == e->cipher))
+ return e;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * ptksa_cache_list - Dump text list of entries in PTKSA cache
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @buf: Buffer for the list
+ * @len: Length of the buffer
+ * Returns: Number of bytes written to buffer
+ *
+ * This function is used to generate a text format representation of the
+ * current PTKSA cache contents for the ctrl_iface PTKSA command.
+ */
+int ptksa_cache_list(struct ptksa_cache *ptksa, char *buf, size_t len)
+{
+ struct ptksa_cache_entry *e;
+ int i = 0, ret;
+ char *pos = buf;
+ struct os_reltime now;
+
+ if (!ptksa)
+ return 0;
+
+ os_get_reltime(&now);
+
+ ret = os_snprintf(pos, buf + len - pos,
+ "Index / ADDR / Cipher / expiration (secs) / TK / KDK\n");
+ if (os_snprintf_error(buf + len - pos, ret))
+ return pos - buf;
+ pos += ret;
+
+ dl_list_for_each(e, &ptksa->ptksa, struct ptksa_cache_entry, list) {
+ ret = os_snprintf(pos, buf + len - pos, "%u " MACSTR,
+ i, MAC2STR(e->addr));
+ if (os_snprintf_error(buf + len - pos, ret))
+ return pos - buf;
+ pos += ret;
+
+ ret = os_snprintf(pos, buf + len - pos, " %s %lu ",
+ wpa_cipher_txt(e->cipher),
+ e->expiration - now.sec);
+ if (os_snprintf_error(buf + len - pos, ret))
+ return pos - buf;
+ pos += ret;
+
+ ret = wpa_snprintf_hex(pos, buf + len - pos, e->ptk.tk,
+ e->ptk.tk_len);
+ if (os_snprintf_error(buf + len - pos, ret))
+ return pos - buf;
+ pos += ret;
+
+ ret = os_snprintf(pos, buf + len - pos, " ");
+ if (os_snprintf_error(buf + len - pos, ret))
+ return pos - buf;
+ pos += ret;
+
+ ret = wpa_snprintf_hex(pos, buf + len - pos, e->ptk.kdk,
+ e->ptk.kdk_len);
+ if (os_snprintf_error(buf + len - pos, ret))
+ return pos - buf;
+ pos += ret;
+
+ ret = os_snprintf(pos, buf + len - pos, "\n");
+ if (os_snprintf_error(buf + len - pos, ret))
+ return pos - buf;
+ pos += ret;
+
+ i++;
+ }
+
+ return pos - buf;
+}
+
+
+/*
+ * ptksa_cache_flush - Flush PTKSA cache entries
+ *
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @addr: Peer address or %NULL to match any
+ * @cipher: Specific cipher suite to search for or WPA_CIPHER_NONE for any
+ */
+void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
+{
+ struct ptksa_cache_entry *e, *next;
+ bool removed = false;
+
+ if (!ptksa)
+ return;
+
+ dl_list_for_each_safe(e, next, &ptksa->ptksa, struct ptksa_cache_entry,
+ list) {
+ if ((!addr || os_memcmp(e->addr, addr, ETH_ALEN) == 0) &&
+ (cipher == WPA_CIPHER_NONE || cipher == e->cipher)) {
+ wpa_printf(MSG_DEBUG,
+ "Flush PTKSA cache entry for " MACSTR,
+ MAC2STR(e->addr));
+
+ ptksa_cache_free_entry(ptksa, e);
+ removed = true;
+ }
+ }
+
+ if (removed)
+ ptksa_cache_set_expiration(ptksa);
+}
+
+
+/*
+ * ptksa_cache_add - Add a PTKSA cache entry
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @addr: Peer address
+ * @cipher: The cipher used
+ * @life_time: The PTK life time in seconds
+ * @ptk: The PTK
+ * Returns: Pointer to the added PTKSA cache entry or %NULL on error
+ *
+ * This function creates a PTKSA entry and adds it to the PTKSA cache.
+ * If an old entry is already in the cache for the same peer and cipher
+ * this entry will be replaced with the new entry.
+ */
+struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
+ const u8 *addr, u32 cipher,
+ u32 life_time,
+ const struct wpa_ptk *ptk)
+{
+ struct ptksa_cache_entry *entry, *tmp;
+ struct os_reltime now;
+
+ if (!ptksa || !ptk || !addr || !life_time || cipher == WPA_CIPHER_NONE)
+ return NULL;
+
+ /* remove a previous entry if present */
+ ptksa_cache_flush(ptksa, addr, cipher);
+
+ /* no place to add another entry */
+ if (ptksa->n_ptksa >= PTKSA_CACHE_MAX_ENTRIES)
+ return NULL;
+
+ entry = os_zalloc(sizeof(*entry));
+ if (!entry)
+ return NULL;
+
+ dl_list_init(&entry->list);
+ os_memcpy(entry->addr, addr, ETH_ALEN);
+ entry->cipher = cipher;
+
+ os_memcpy(&entry->ptk, ptk, sizeof(entry->ptk));
+
+ os_get_reltime(&now);
+ entry->expiration = now.sec + life_time;
+
+ dl_list_for_each(tmp, &ptksa->ptksa, struct ptksa_cache_entry, list) {
+ if (tmp->expiration > entry->expiration)
+ break;
+ }
+
+ /*
+ * If the list was empty add to the head; otherwise if the expiration is
+ * later then all other entries, add it to the end of the list;
+ * otherwise add it before the relevant entry.
+ */
+ if (!tmp)
+ dl_list_add(&ptksa->ptksa, &entry->list);
+ else if (tmp->expiration < entry->expiration)
+ dl_list_add(&tmp->list, &entry->list);
+ else
+ dl_list_add_tail(&tmp->list, &entry->list);
+
+ ptksa->n_ptksa++;
+ wpa_printf(MSG_DEBUG,
+ "Added PTKSA cache entry addr=" MACSTR " cipher=%u",
+ MAC2STR(addr), cipher);
+
+ return entry;
+}
diff --git a/src/common/ptksa_cache.h b/src/common/ptksa_cache.h
new file mode 100644
index 0000000..28ef291
--- /dev/null
+++ b/src/common/ptksa_cache.h
@@ -0,0 +1,79 @@
+/*
+ * RSN PTKSA cache interface
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef PTKSA_CACHE_H
+#define PTKSA_CACHE_H
+
+#include "wpa_common.h"
+#include "defs.h"
+#include "list.h"
+
+/**
+ * struct ptksa_cache_entry - PTKSA cache entry
+ */
+struct ptksa_cache_entry {
+ struct dl_list list;
+ struct wpa_ptk ptk;
+ os_time_t expiration;
+ u32 cipher;
+ u8 addr[ETH_ALEN];
+};
+
+#ifdef CONFIG_PTKSA_CACHE
+
+struct ptksa_cache;
+
+struct ptksa_cache * ptksa_cache_init(void);
+void ptksa_cache_deinit(struct ptksa_cache *ptksa);
+struct ptksa_cache_entry * ptksa_cache_get(struct ptksa_cache *ptksa,
+ const u8 *addr, u32 cipher);
+int ptksa_cache_list(struct ptksa_cache *ptksa, char *buf, size_t len);
+struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
+ const u8 *addr, u32 cipher,
+ u32 life_time,
+ const struct wpa_ptk *ptk);
+void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher);
+
+#else /* CONFIG_PTKSA_CACHE */
+
+static inline struct ptksa_cache * ptksa_cache_init(void)
+{
+ return (struct ptksa_cache *) 1;
+}
+
+static inline void ptksa_cache_deinit(struct ptksa_cache *ptksa)
+{
+}
+
+static inline struct ptksa_cache_entry *
+ptksa_cache_get(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
+{
+ return NULL;
+}
+
+static inline int ptksa_cache_list(struct ptksa_cache *ptksa,
+ char *buf, size_t len)
+{
+ return -1;
+}
+
+static inline struct ptksa_cache_entry *
+ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher,
+ u32 life_time, const struct wpa_ptk *ptk)
+{
+ return NULL;
+}
+
+static inline void ptksa_cache_flush(struct ptksa_cache *ptksa,
+ const u8 *addr, u32 cipher)
+{
+}
+
+#endif /* CONFIG_PTKSA_CACHE */
+#endif /* PTKSA_CACHE_H */
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index eb6a2c1..f7e5571 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -1445,6 +1445,25 @@
* %QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL and
* %QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW attributes from
* userspace.
+ * @QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R: Device supports Adaptive 11r.
+ * With Adaptive 11r feature, access points advertise the vendor
+ * specific IEs and MDE but do not include FT AKM in the RSNE.
+ * The Adaptive 11r supported stations are expected to identify
+ * such vendor specific IEs and connect to the AP in FT mode though
+ * the profile is configured in non-FT mode.
+ * The driver-based SME cases also need to have this support for
+ * Adaptive 11r to handle the connection and roaming scenarios.
+ * This flag indicates the support for the same to the user space.
+ * @QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS: Device supports
+ * concurrent network sessions on different Wi-Fi bands. This feature
+ * capability is attributed to the hardware's capability to support
+ * the same (e.g., DBS).
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT: Flag indicating whether the
+ * responses for the respective TWT operations are asynchronous (separate
+ * event message) from the driver. If not specified, the responses are
+ * synchronous (in vendor command reply) to the request. Each TWT
+ * operation is specifically mentioned (against its respective
+ * documentation) to support either of these or both modes.
* @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
*/
enum qca_wlan_vendor_features {
@@ -1460,6 +1479,9 @@
QCA_WLAN_VENDOR_FEATURE_11AX = 9,
QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT = 10,
QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG = 11,
+ QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R = 12,
+ QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13,
+ QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT = 14,
NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
};
@@ -2285,6 +2307,10 @@
* frame. The updated NSS value after the connection shall not be
* greater than the one negotiated during the connection. Any such
* higher value configuration shall be returned with a failure.
+ * Only symmetric NSS configuration (such as 2X2 or 1X1) can be done
+ * using this attribute. QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes shall be used to
+ * configure the asymmetric NSS configuration (such as 1X2).
*/
QCA_WLAN_VENDOR_ATTR_CONFIG_NSS = 70,
/* 8-bit unsigned value to trigger Optimized Power Management:
@@ -2333,6 +2359,46 @@
*/
QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL = 76,
+ /* 8-bit unsigned value. This attribute is used to dynamically configure
+ * the number of spatial streams used for transmitting the data. When
+ * configured in the disconnected state, the configured value will
+ * be considered for the following connection attempt.
+ * If the NSS is updated after the connection, the updated NSS value
+ * is notified to the peer using the Operating Mode Notification/Spatial
+ * Multiplexing Power Save frame.
+ * The TX NSS value configured after the connection shall not be greater
+ * than the value negotiated during the connection. Any such higher
+ * value configuration shall be treated as invalid configuration by
+ * the driver. This attribute shall be configured along with
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric
+ * configuration (such as 2X2 or 1X1) or the asymmetric
+ * configuration (such as 1X2).
+ * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+ * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver
+ * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS.
+ */
+ QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77,
+
+ /* 8-bit unsigned value. This attribute is used to dynamically configure
+ * the number of spatial streams used for receiving the data. When
+ * configured in the disconnected state, the configured value will
+ * be considered for the following connection attempt.
+ * If the NSS is updated after the connection, the updated NSS value
+ * is notified to the peer using the Operating Mode Notification/Spatial
+ * Multiplexing Power Save frame.
+ * The RX NSS value configured after the connection shall not be greater
+ * than the value negotiated during the connection. Any such higher
+ * value configuration shall be treated as invalid configuration by
+ * the driver. This attribute shall be configured along with
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric
+ * configuration (such as 2X2 or 1X1) or the asymmetric
+ * configuration (such as 1X2).
+ * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+ * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver
+ * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS.
+ */
+ QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78,
+
/* keep last */
QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@@ -2428,23 +2494,50 @@
* This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
* %QCA_WLAN_VENDOR_GPIO_OUTPUT.
*
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Optional (u32)
* value to specify the GPIO pull type. Please refer to enum qca_gpio_pull_type
* for the available values.
* This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
*
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Optional (u32)
* value to specify the GPIO interrupt mode. Please refer to enum
* qca_gpio_interrupt_mode for the available values.
* This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
*
- * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Required (u32)
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Optional (u32)
* value to specify the GPIO direction. Please refer to enum qca_gpio_direction
* for the available values.
* This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
- * %QCA_WLAN_VENDOR_GPIO_CONFIG.
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG and
+ * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG
+ * attribute is present.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG: Optional (u32)
+ * Value to specify the mux config. Meaning of a given value is dependent
+ * on the target chipset and GPIO pin. Must be of the range 0-15.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to 0.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE: Optional (u32)
+ * Value to specify the drive, refer to enum qca_gpio_drive.
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to QCA_WLAN_GPIO_DRIVE_2MA(0).
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG: Optional (flag)
+ * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is
+ * %QCA_WLAN_VENDOR_GPIO_CONFIG. When present this attribute signals that all
+ * other parameters for the given GPIO will be obtained from internal
+ * configuration. Only %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM must be
+ * specified to indicate the GPIO pin being configured.
*/
enum qca_wlan_gpio_attr {
QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INVALID = 0,
@@ -2460,6 +2553,12 @@
QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE = 5,
/* Unsigned 32-bit attribute for GPIO direction to configure */
QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR = 6,
+ /* Unsigned 32-bit attribute for GPIO mux config */
+ QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG = 7,
+ /* Unsigned 32-bit attribute for GPIO drive */
+ QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE = 8,
+ /* Flag attribute for using internal GPIO configuration */
+ QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG = 9,
/* keep last */
QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST,
@@ -2535,6 +2634,30 @@
};
/**
+ * enum qca_gpio_drive - GPIO drive
+ * @QCA_WLAN_GPIO_DRIVE_2MA: drive 2MA
+ * @QCA_WLAN_GPIO_DRIVE_4MA: drive 4MA
+ * @QCA_WLAN_GPIO_DRIVE_6MA: drive 6MA
+ * @QCA_WLAN_GPIO_DRIVE_8MA: drive 8MA
+ * @QCA_WLAN_GPIO_DRIVE_10MA: drive 10MA
+ * @QCA_WLAN_GPIO_DRIVE_12MA: drive 12MA
+ * @QCA_WLAN_GPIO_DRIVE_14MA: drive 14MA
+ * @QCA_WLAN_GPIO_DRIVE_16MA: drive 16MA
+ * @QCA_WLAN_GPIO_DRIVE_MAX: invalid GPIO drive
+ */
+enum qca_gpio_drive {
+ QCA_WLAN_GPIO_DRIVE_2MA = 0,
+ QCA_WLAN_GPIO_DRIVE_4MA = 1,
+ QCA_WLAN_GPIO_DRIVE_6MA = 2,
+ QCA_WLAN_GPIO_DRIVE_8MA = 3,
+ QCA_WLAN_GPIO_DRIVE_10MA = 4,
+ QCA_WLAN_GPIO_DRIVE_12MA = 5,
+ QCA_WLAN_GPIO_DRIVE_14MA = 6,
+ QCA_WLAN_GPIO_DRIVE_16MA = 7,
+ QCA_WLAN_GPIO_DRIVE_MAX,
+};
+
+/**
* qca_wlan_set_qdepth_thresh_attr - Parameters for setting
* MSDUQ depth threshold per peer per tid in the target
*
@@ -4120,6 +4243,139 @@
QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN = 1 << 12,
};
+/*
+ * enum qca_vendor_roam_fail_reasons: Defines the various roam
+ * fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED: Roam module in the firmware is not
+ * able to trigger the scan.
+ * @QCA_ROAM_FAIL_REASON_NO_AP_FOUND: No roamable APs found during roam scan.
+ * @QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: No candidate APs found during roam
+ * scan.
+ * @QCA_ROAM_FAIL_REASON_HOST: Roam fail due to disconnect issued from host.
+ * @QCA_ROAM_FAIL_REASON_AUTH_SEND: Unable to send Authentication frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_RECV: Received Authentication frame with error
+ * status code.
+ * @QCA_ROAM_FAIL_REASON_NO_AUTH_RESP: Authentication frame not received.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_SEND: Unable to send Reassociation Request
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_RECV: Received Reassociation Response frame
+ * with error status code.
+ * @QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP: Reassociation Response frame not
+ * received.
+ * @QCA_ROAM_FAIL_REASON_SCAN_FAIL: Scan module not able to start scan.
+ * @QCA_ROAM_FAIL_REASON_AUTH_NO_ACK: No ACK is received for Authentication
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: Authentication frame is dropped
+ * internally before transmission.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK: No ACK is received for Reassociation
+ * Request frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: Reassociation Request frame is
+ * dropped internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT: EAPOL-Key M1 is not received and
+ * times out.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND: Unable to send EAPOL-Key M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: EAPOL-Key M2 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: No ACK is received for EAPOL-Key
+ * M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: EAPOL-Key M3 frame is not received.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND: Unable to send EAPOL-Key M4 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: EAPOL-Key M4 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: No ACK is received for EAPOL-Key M4
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS: Roam scan is not
+ * started for final beacon miss case.
+ * @QCA_ROAM_FAIL_REASON_DISCONNECT: Deauthentication or Disassociation frame
+ * received from the AP during roaming handoff.
+ * @QCA_ROAM_FAIL_REASON_RESUME_ABORT: Firmware roams to the AP when the Apps
+ * or host is suspended and gives the indication of the last roamed AP only
+ * when the Apps is resumed. If the Apps is resumed while the roaming is in
+ * progress, this ongoing roaming is aborted and the last roamed AP is
+ * indicated to host.
+ * @QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID: WPA3-SAE invalid PMKID.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: WPA3-SAE pre-authentication times
+ * out.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: WPA3-SAE pre-authentication fails.
+ */
+enum qca_vendor_roam_fail_reasons {
+ QCA_ROAM_FAIL_REASON_NONE = 0,
+ QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED = 1,
+ QCA_ROAM_FAIL_REASON_NO_AP_FOUND = 2,
+ QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND = 3,
+ QCA_ROAM_FAIL_REASON_HOST = 4,
+ QCA_ROAM_FAIL_REASON_AUTH_SEND = 5,
+ QCA_ROAM_FAIL_REASON_AUTH_RECV = 6,
+ QCA_ROAM_FAIL_REASON_NO_AUTH_RESP = 7,
+ QCA_ROAM_FAIL_REASON_REASSOC_SEND = 8,
+ QCA_ROAM_FAIL_REASON_REASSOC_RECV = 9,
+ QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP = 10,
+ QCA_ROAM_FAIL_REASON_SCAN_FAIL = 11,
+ QCA_ROAM_FAIL_REASON_AUTH_NO_ACK = 12,
+ QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP = 13,
+ QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK = 14,
+ QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP = 15,
+ QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT = 16,
+ QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND = 17,
+ QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP = 18,
+ QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK = 19,
+ QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT = 20,
+ QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND = 21,
+ QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP = 22,
+ QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK = 23,
+ QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS = 24,
+ QCA_ROAM_FAIL_REASON_DISCONNECT = 25,
+ QCA_ROAM_FAIL_REASON_RESUME_ABORT = 26,
+ QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID = 27,
+ QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT = 28,
+ QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL = 29,
+};
+
+/*
+ * enum qca_vendor_roam_invoke_fail_reasons: Defines the various roam
+ * invoke fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_INVOKE_STATUS_IFACE_INVALID: Invalid interface ID is passed
+ * in roam invoke command.
+ * @QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE: Roam offload in firmware is not
+ * enabled.
+ * @QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID: Connected AP profile SSID
+ * length is invalid.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW: Firmware internal roaming is already
+ * in progress.
+ * @QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP: Host sends the Beacon/Probe Response
+ * of the AP in the roam invoke command to firmware. This reason is sent by the
+ * firmware when the given AP is configured to be ignored or SSID/security
+ * does not match.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL: Roam handoff failed because of
+ * firmware internal reasons.
+ * @QCA_ROAM_INVOKE_STATUS_DISALLOW: Roam invoke trigger is not enabled.
+ * @QCA_ROAM_INVOKE_STATUS_SCAN_FAIL: Scan start fail for roam invoke.
+ * @QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL: Roam handoff start fail.
+ * @QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS: Roam invoke parameters are invalid.
+ * @QCA_ROAM_INVOKE_STATUS_NO_CAND_AP: No candidate AP found to roam to.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_FAIL: Roam handoff failed.
+ */
+enum qca_vendor_roam_invoke_fail_reasons {
+ QCA_ROAM_INVOKE_STATUS_NONE = 0,
+ QCA_ROAM_INVOKE_STATUS_IFACE_INVALID = 1,
+ QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE = 2,
+ QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID = 3,
+ QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW = 4,
+ QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP = 5,
+ QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL = 6,
+ QCA_ROAM_INVOKE_STATUS_DISALLOW = 7,
+ QCA_ROAM_INVOKE_STATUS_SCAN_FAIL = 8,
+ QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL = 9,
+ QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS = 10,
+ QCA_ROAM_INVOKE_STATUS_NO_CAND_AP = 11,
+ QCA_ROAM_INVOKE_STATUS_ROAM_FAIL = 12,
+
+};
+
/**
* enum qca_vendor_attr_roam_candidate_selection_criteria:
*
@@ -6222,6 +6478,14 @@
* the FW on a specific VDEV.
*/
QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22,
+ /* WMI sequence mismatch between WMI command and Tx completion */
+ QCA_WLAN_HANG_WMI_BUF_SEQUENCE_MISMATCH = 23,
+ /* Write to Device HAL register failed */
+ QCA_WLAN_HANG_REG_WRITE_FAILURE = 24,
+ /* No credit left to send the wow_wakeup_from_sleep to firmware */
+ QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25,
+ /* Bus failure */
+ QCA_WLAN_HANG_BUS_FAILURE = 26,
};
/**
@@ -7685,6 +7949,46 @@
*/
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX = 44,
+ /* 8-bit unsigned value to configure the driver/firmware to enable or
+ * disable full bandwidth UL MU-MIMO subfield in the HE PHY capabilities
+ * information field.
+ * 0 - Disable full bandwidth UL MU-MIMO subfield
+ * 1 - Enable full bandwidth UL MU-MIMO subfield
+ * This attribute is used to configure the testbed device.
+ */
+ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO = 45,
+
+ /* 16-bit unsigned value to configure the driver with a specific BSS
+ * max idle period to advertise in the BSS Max Idle Period element
+ * (IEEE Std 802.11-2016, 9.4.2.79) in (Re)Association Request frames.
+ * This attribute is used to configure the testbed device.
+ */
+ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD = 46,
+
+ /* 8-bit unsigned value to configure the driver to use only RU 242 tone
+ * for data transmission.
+ * 0 - Default behavior, 1 - Configure RU 242 tone for data Tx.
+ * This attribute is used to configure the testbed device.
+ */
+ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX = 47,
+
+ /* 8-bit unsigned value to configure the driver to disable data and
+ * management response frame transmission to test the BSS max idle
+ * feature.
+ * 0 - Default behavior, 1 - Disable data and management response Tx.
+ * This attribute is used to configure the testbed device.
+ */
+ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX = 48,
+
+ /* 8-bit unsigned value to configure the driver/firmware to enable or
+ * disable Punctured Preamble Rx subfield in the HE PHY capabilities
+ * information field.
+ * 0 - Disable Punctured Preamble Rx subfield
+ * 1 - Enable Punctured Preamble Rx subfield
+ * This attribute is used to configure the testbed device.
+ */
+ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX = 49,
+
/* keep last */
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@@ -7694,26 +7998,69 @@
/**
* enum qca_wlan_twt_operation - Operation of the config TWT request
* Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION.
+ * The response for the respective operations can be either synchronous or
+ * asynchronous (wherever specified). If synchronous, the response to this
+ * operation is obtained in the corresponding vendor command reply to the user
+ * space. For the asynchronous case the response is obtained as an event with
+ * the same operation type.
+ *
+ * Drivers shall support either of these modes but not both simultaneously.
+ * This support for asynchronous mode is advertised through the flag
+ * QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT. If this flag is not advertised,
+ * the driver shall support synchronous mode.
*
* @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured
* through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. Depending upon the
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, this is either a
+ * synchronous or asynchronous operation.
*
* @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are
* obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. This is a synchronous operation.
*
* @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Required parameters are
* obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
* qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * This terminate can either get triggered by the user space or can as well be
+ * a notification from the firmware if it initiates a terminate.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * the request from user space can either be a synchronous or asynchronous
+ * operation.
*
* @QCA_WLAN_TWT_SUSPEND: Suspend the TWT session. Required parameters are
* obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
* qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * this is either a synchronous or asynchronous operation.
*
* @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are
* configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
* qca_wlan_vendor_attr_twt_resume. Valid only after the TWT session is setup.
+ * This can as well be a notification from the firmware on a QCA_WLAN_TWT_NUDGE
+ * request. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_NUDGE: Suspend and resume the TWT session. TWT nudge is a
+ * combination of suspend and resume in a single request. Required parameters
+ * are configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the
+ * enum qca_wlan_vendor_attr_twt_nudge. Valid only after the TWT session is
+ * setup. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_STATS: Get the TWT session traffic statistics information.
+ * Refers the enum qca_wlan_vendor_attr_twt_stats. Valid only after the TWT
+ * session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_CLEAR_STATS: Clear TWT session traffic statistics information.
+ * Valid only after the TWT session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_CAPABILITIES: Get TWT capabilities of this device and its
+ * peer. Refers the enum qca_wlan_vendor_attr_twt_capability. It's a synchronous
+ * operation.
+ *
+ * @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmare is
+ * ready for a new TWT session setup after it issued a TWT teardown.
*/
enum qca_wlan_twt_operation {
QCA_WLAN_TWT_SET = 0,
@@ -7721,6 +8068,11 @@
QCA_WLAN_TWT_TERMINATE = 2,
QCA_WLAN_TWT_SUSPEND = 3,
QCA_WLAN_TWT_RESUME = 4,
+ QCA_WLAN_TWT_NUDGE = 5,
+ QCA_WLAN_TWT_GET_STATS = 6,
+ QCA_WLAN_TWT_CLEAR_STATS = 7,
+ QCA_WLAN_TWT_GET_CAPABILITIES = 8,
+ QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9,
};
/**
@@ -7734,8 +8086,8 @@
*
* @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the
* parameters configured for TWT. These parameters are represented by
- * enum qca_wlan_vendor_attr_twt_setup or enum qca_wlan_vendor_attr_twt_resume
- * based on the operation.
+ * enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume,
+ * or enum qca_wlan_vendor_attr_twt_stats based on the operation.
*/
enum qca_wlan_vendor_attr_config_twt {
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0,
@@ -7896,6 +8248,19 @@
};
/**
+ * qca_wlan_twt_setup_state: Represents the TWT session states.
+ *
+ * QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: TWT session not established.
+ * QCA_WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active.
+ * QCA_WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is in suspended state.
+ */
+enum qca_wlan_twt_setup_state {
+ QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0,
+ QCA_WLAN_TWT_SETUP_STATE_ACTIVE = 1,
+ QCA_WLAN_TWT_SETUP_STATE_SUSPEND = 2,
+};
+
+/**
* enum qca_wlan_vendor_attr_twt_setup: Represents attributes for
* TWT (Target Wake Time) setup request. These attributes are sent as part of
* %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and
@@ -7945,6 +8310,14 @@
* 2. TWT GET Request and Response
* 3. TWT TERMINATE Request and Response
* 4. TWT SUSPEND Request and Response
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions for the following
+ * 1. TWT TERMINATE Request and Response
+ * 2. TWT SUSPEND Request and Response
+ * 4. TWT CLEAR STATISTICS request
+ * 5. TWT GET STATISTICS request and response
+ * If an invalid dialog ID is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
*
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8)
* This attribute (exp) is used along with the mantissa to derive the
@@ -7995,6 +8368,7 @@
* 2. TWT TERMINATE Response
* 3. TWT SUSPEND Response
* 4. TWT RESUME Response
+ * 5. TWT NUDGE Response
*
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE: Required (u8)
* This field is applicable for TWT response only.
@@ -8031,6 +8405,23 @@
* 4. TWT SUSPEND Request
* In STA mode, this is an optional parameter in request and response for
* the above four TWT operations.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL: Optional (u32)
+ * Minimum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL: Optional (u32)
+ * Maximum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION: Optional (u32)
+ * Minimum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION: Optional (u32)
+ * Maximum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE: Optional (u32)
+ * TWT state for the given dialog id. The values for this are represented
+ * by enum qca_wlan_twt_setup_state.
+ * This is obtained through TWT GET operation.
*/
enum qca_wlan_vendor_attr_twt_setup {
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0,
@@ -8052,6 +8443,11 @@
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED = 14,
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR = 15,
+ QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL = 16,
+ QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL = 17,
+ QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION = 18,
+ QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION = 19,
+ QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE = 20,
/* keep last */
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST,
@@ -8081,6 +8477,16 @@
* unknown reason
* @QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: TWT session already in
* suspend state
+ * @QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: FW has dropped the frame due to
+ * invalid IE in the received TWT frame
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: Parameters received from
+ * the responder are not in the specified range
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to request from the responder. Used on the TWT_TERMINATE
+ * notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to roaming. Used on the TWT_TERMINATE notification from the
+ * firmware.
*/
enum qca_wlan_vendor_twt_status {
QCA_WLAN_VENDOR_TWT_STATUS_OK = 0,
@@ -8097,6 +8503,10 @@
QCA_WLAN_VENDOR_TWT_STATUS_DENIED = 11,
QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR = 12,
QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED = 13,
+ QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID = 14,
+ QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE = 15,
+ QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE = 16,
+ QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE = 17,
};
/**
@@ -8123,6 +8533,10 @@
* @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID: Required (u8).
* Flow ID is the unique identifier for each TWT session. This attribute
* represents the respective TWT session to resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
*
* @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR: 6-byte MAC address
* Represents the MAC address of the peer to which TWT Resume is
@@ -8145,6 +8559,210 @@
};
/**
+ * enum qca_wlan_vendor_attr_twt_nudge - Represents attributes for
+ * TWT (Target Wake Time) nudge request. TWT nudge is a combination of suspend
+ * and resume in a single request. These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session to suspend and resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in TWT NUDGE request
+ * and response.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME: Required (u32)
+ * This attribute is used as the SP offset which is the offset from
+ * TSF after which the wake happens. The units are in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE: Required (u32)
+ * This attribute represents the next TWT subfield size.
+ * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits,
+ * and 4 for 64 bits.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer to which TWT Suspend and Resume is
+ * being sent. This is used in AP mode to represent the respective
+ * client and is a required parameter. In STA mode, this is an optional
+ * parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF: Optional (u64)
+ * This field contains absolute TSF value of the time at which the TWT
+ * session will be resumed.
+ */
+enum qca_wlan_vendor_attr_twt_nudge {
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID = 1,
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME = 2,
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE = 3,
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR = 4,
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF = 5,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX =
+ QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_stats: Represents attributes for
+ * TWT (Target Wake Time) get statistics and clear statistics request.
+ * These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session for get and clear TWT statistics.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which TWT Statistics
+ * is required.
+ * In AP mode this is used to represent the respective
+ * client and is a required parameter for
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request and response
+ * In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION: Required (u32)
+ * This is the duration of the service period in microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION: Required (u32)
+ * Average of the actual wake duration observed so far. Unit is microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS: Required (u32)
+ * The number of TWT service periods elapsed so far.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION: Required (u32)
+ * This is the minimum value of the wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION: Required (u32)
+ * This is the maximum value of wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU: Required (u32)
+ * Average number of MPDUs transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU: Required (u32)
+ * Average number of MPDUs received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE: Required (u32)
+ * Average number of bytes transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE: Required (u32)
+ * Average number of bytes received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS: Required (u32)
+ * Status of the TWT GET STATISTICS request.
+ * This contains status values in enum qca_wlan_vendor_twt_status
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ */
+enum qca_wlan_vendor_attr_twt_stats {
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID = 1,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR = 2,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION = 3,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION = 4,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS = 5,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION = 6,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION = 7,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU = 8,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU = 9,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE = 10,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE = 11,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS = 12,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX =
+ QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_twt_get_capa - Represents the bitmap of TWT capabilities
+ * supported by the device and the peer.
+ * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_GET_CAPABILITIES
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by
+ * TWT non-scheduling STA. This capability is advertised in the HE
+ * Capability/Extended Capabilities information element in the
+ * Association Request frame by the device.
+ *
+ * @QCA_WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by
+ * the TWT scheduling AP. This capability is advertised in the Extended
+ * Capabilities/HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_BROADCAST: On the requestor side, this indicates support
+ * for the broadcast TWT functionality. On the responder side, this indicates
+ * support for the role of broadcast TWT scheduling functionality. This
+ * capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_TWT_FLEXIBLE: The device supports flexible TWT schedule.
+ * This capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate
+ * that it mandates the associated HE STAs to support TWT. This capability is
+ * advertised by AP in the HE Operation Parameters field of the HE Operation
+ * information element.
+ */
+enum qca_wlan_twt_capa {
+ QCA_WLAN_TWT_CAPA_REQUESTOR = BIT(0),
+ QCA_WLAN_TWT_CAPA_RESPONDER = BIT(1),
+ QCA_WLAN_TWT_CAPA_BROADCAST = BIT(2),
+ QCA_WLAN_TWT_CAPA_FLEXIBLE = BIT(3),
+ QCA_WLAN_TWT_CAPA_REQUIRED = BIT(4),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_capability - Represents attributes for TWT
+ * get capabilities request type. Used by QCA_WLAN_TWT_GET_CAPABILITIES TWT
+ * operation.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which the TWT capabilities
+ * are being queried. This is used in AP mode to represent the respective
+ * client. In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF: (u16).
+ * Self TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER: (u16).
+ * Peer TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ */
+enum qca_wlan_vendor_attr_twt_capability {
+ QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR = 1,
+ QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF = 2,
+ QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER = 3,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAX =
+ QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1,
+};
+
+/**
* enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by
* the TWT responder
*
@@ -9488,6 +10106,40 @@
* include this attribute in response to the
* QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no connection
* failure observed in the last attempted connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE: u32, latest TX rate (Kbps)
+ * used by the station in its last TX frame while communicating to the AP in the
+ * connected state. When queried in the disconnected state, this represents the
+ * rate used by the STA in the last TX frame to the AP when it was connected.
+ * This attribute is used for STA mode only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX: u32, used in STA mode only.
+ * This represents the rate index used by the STA for the last TX frame to the
+ * AP. When queried in the disconnected state, this gives the last RIX used by
+ * the STA in the last TX frame to the AP when it was connected.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT: u32, used in STA
+ * mode only. This represents the number of times the STA TSF goes out of sync
+ * from the AP after the connection. If queried in the disconnected state, this
+ * gives the count of TSF out of sync for the last connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. This can be queried either in connected state or
+ * disconnected state. Each bit of this attribute represents the different
+ * roam trigger reason code which are defined in enum qca_vendor_roam_triggers.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON: u32, used in STA mode
+ * only. This represents the roam fail reason for the last failed roaming
+ * attempt by the firmware. Different roam failure reason codes are specified
+ * in enum qca_vendor_roam_fail_reasons. This can be queried either in
+ * connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be
+ * queried either in connected state or disconnected state.
*/
enum qca_wlan_vendor_attr_get_sta_info {
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0,
@@ -9534,6 +10186,12 @@
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41,
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42,
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE = 44,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX = 45,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT = 46,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48,
+ QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49,
/* keep last */
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST,
diff --git a/src/common/sae.c b/src/common/sae.c
index 057e1ce..372905d 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -1609,18 +1609,26 @@
* octets). */
crypto_bignum_to_bin(tmp, val, sizeof(val), sae->tmp->order_len);
wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
- if (!sae->pk &&
- sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
+
+#ifdef CONFIG_SAE_PK
+ if (sae->pk) {
+ if (sae_kdf_hash(hash_len, keyseed, "SAE-PK keys",
+ val, sae->tmp->order_len,
+ keys, 2 * hash_len + SAE_PMK_LEN) < 0)
+ goto fail;
+ } else {
+ if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
+ val, sae->tmp->order_len,
+ keys, hash_len + SAE_PMK_LEN) < 0)
+ goto fail;
+ }
+#else /* CONFIG_SAE_PK */
+ if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
val, sae->tmp->order_len,
keys, hash_len + SAE_PMK_LEN) < 0)
goto fail;
-#ifdef CONFIG_SAE_PK
- if (sae->pk &&
- sae_kdf_hash(hash_len, keyseed, "SAE-PK keys",
- val, sae->tmp->order_len,
- keys, 2 * hash_len + SAE_PMK_LEN) < 0)
- goto fail;
-#endif /* CONFIG_SAE_PK */
+#endif /* !CONFIG_SAE_PK */
+
forced_memzero(keyseed, sizeof(keyseed));
os_memcpy(sae->tmp->kck, keys, hash_len);
sae->tmp->kck_len = hash_len;
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 82a5a17..2b8c7f6 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -333,6 +333,7 @@
* @ptk: Buffer for pairwise transient key
* @akmp: Negotiated AKM
* @cipher: Negotiated pairwise cipher
+ * @kdk_len: The length in octets that should be derived for KDK
* Returns: 0 on success, -1 on failure
*
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
@@ -348,12 +349,13 @@
const u8 *addr1, const u8 *addr2,
const u8 *nonce1, const u8 *nonce2,
struct wpa_ptk *ptk, int akmp, int cipher,
- const u8 *z, size_t z_len)
+ const u8 *z, size_t z_len, size_t kdk_len)
{
#define MAX_Z_LEN 66 /* with NIST P-521 */
u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN + MAX_Z_LEN];
size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN;
- u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
+ u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
+ WPA_KDK_MAX_LEN];
size_t ptk_len;
#ifdef CONFIG_OWE
int owe_ptk_workaround = 0;
@@ -395,16 +397,24 @@
data_len += z_len;
}
+ if (kdk_len > WPA_KDK_MAX_LEN) {
+ wpa_printf(MSG_ERROR,
+ "WPA: KDK len=%zu exceeds max supported len",
+ kdk_len);
+ return -1;
+ }
+
ptk->kck_len = wpa_kck_len(akmp, pmk_len);
ptk->kek_len = wpa_kek_len(akmp, pmk_len);
ptk->tk_len = wpa_cipher_key_len(cipher);
+ ptk->kdk_len = kdk_len;
if (ptk->tk_len == 0) {
wpa_printf(MSG_ERROR,
"WPA: Unsupported cipher (0x%x) used in PTK derivation",
cipher);
return -1;
}
- ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
+ ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len + ptk->kdk_len;
if (wpa_key_mgmt_sha384(akmp)) {
#if defined(CONFIG_SUITEB192) || defined(CONFIG_FILS)
@@ -488,6 +498,12 @@
os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
+ if (kdk_len) {
+ os_memcpy(ptk->kdk, tmp + ptk->kck_len + ptk->kek_len +
+ ptk->tk_len, ptk->kdk_len);
+ wpa_hexdump_key(MSG_DEBUG, "WPA: KDK", ptk->kdk, ptk->kdk_len);
+ }
+
ptk->kek2_len = 0;
ptk->kck2_len = 0;
@@ -576,15 +592,16 @@
const u8 *snonce, const u8 *anonce, const u8 *dhss,
size_t dhss_len, struct wpa_ptk *ptk,
u8 *ick, size_t *ick_len, int akmp, int cipher,
- u8 *fils_ft, size_t *fils_ft_len)
+ u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len)
{
u8 *data, *pos;
size_t data_len;
u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
- FILS_FT_MAX_LEN];
+ FILS_FT_MAX_LEN + WPA_KDK_MAX_LEN];
size_t key_data_len;
const char *label = "FILS PTK Derivation";
int ret = -1;
+ size_t offset;
/*
* FILS-Key-Data = PRF-X(PMK, "FILS PTK Derivation",
@@ -595,6 +612,9 @@
* If doing FT initial mobility domain association:
* FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
* FILS-FT_bits)
+ * When a KDK is derived:
+ * KDK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits + FILS-FT_bits,
+ * KDK_bits)
*/
data_len = 2 * ETH_ALEN + 2 * FILS_NONCE_LEN + dhss_len;
data = os_malloc(data_len);
@@ -623,6 +643,19 @@
goto err;
key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
+ if (kdk_len) {
+ if (kdk_len > WPA_KDK_MAX_LEN) {
+ wpa_printf(MSG_ERROR, "FILS: KDK len=%zu too big",
+ kdk_len);
+ goto err;
+ }
+
+ ptk->kdk_len = kdk_len;
+ key_data_len += kdk_len;
+ } else {
+ ptk->kdk_len = 0;
+ }
+
if (fils_ft && fils_ft_len) {
if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
*fils_ft_len = 32;
@@ -657,19 +690,27 @@
wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-Key-Data", tmp, key_data_len);
os_memcpy(ick, tmp, *ick_len);
+ offset = *ick_len;
wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, *ick_len);
- os_memcpy(ptk->kek, tmp + *ick_len, ptk->kek_len);
+ os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", ptk->kek, ptk->kek_len);
+ offset += ptk->kek_len;
- os_memcpy(ptk->tk, tmp + *ick_len + ptk->kek_len, ptk->tk_len);
+ os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
+ offset += ptk->tk_len;
if (fils_ft && fils_ft_len) {
- os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len,
- *fils_ft_len);
+ os_memcpy(fils_ft, tmp + offset, *fils_ft_len);
wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
fils_ft, *fils_ft_len);
+ offset += *fils_ft_len;
+ }
+
+ if (ptk->kdk_len) {
+ os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
+ wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk, ptk->kdk_len);
}
ptk->kek2_len = 0;
@@ -1127,6 +1168,266 @@
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_PASN
+
+/*
+ * pasn_use_sha384 - Should SHA384 be used or SHA256
+ *
+ * @akmp: Authentication and key management protocol
+ * @cipher: The cipher suite
+ *
+ * According to IEEE P802.11az/D2.7, 12.12.7, the hash algorithm to use is the
+ * hash algorithm defined for the Base AKM (see Table 9-151 (AKM suite
+ * selectors)). When there is no Base AKM, the hash algorithm is selected based
+ * on the pairwise cipher suite provided in the RSNE by the AP in the second
+ * PASN frame. SHA-256 is used as the hash algorithm, except for the ciphers
+ * 00-0F-AC:9 and 00-0F-AC:10 for which SHA-384 is used.
+ */
+static bool pasn_use_sha384(int akmp, int cipher)
+{
+ return (akmp == WPA_KEY_MGMT_PASN && (cipher == WPA_CIPHER_CCMP_256 ||
+ cipher == WPA_CIPHER_GCMP_256)) ||
+ wpa_key_mgmt_sha384(akmp);
+}
+
+
+/**
+ * pasn_pmk_to_ptk - Calculate PASN PTK from PMK, addresses, etc.
+ * @pmk: Pairwise master key
+ * @pmk_len: Length of PMK
+ * @spa: Suppplicant address
+ * @bssid: AP BSSID
+ * @dhss: Is the shared secret (DHss) derived from the PASN ephemeral key
+ * exchange encoded as an octet string
+ * @dhss_len: The length of dhss in octets
+ * @ptk: Buffer for pairwise transient key
+ * @akmp: Negotiated AKM
+ * @cipher: Negotiated pairwise cipher
+ * @kdk_len: the length in octets that should be derived for HTLK. Can be zero.
+ * Returns: 0 on success, -1 on failure
+ */
+int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
+ const u8 *spa, const u8 *bssid,
+ const u8 *dhss, size_t dhss_len,
+ struct wpa_ptk *ptk, int akmp, int cipher,
+ size_t kdk_len)
+{
+ u8 tmp[WPA_KCK_MAX_LEN + WPA_TK_MAX_LEN + WPA_KDK_MAX_LEN];
+ u8 *data;
+ size_t data_len, ptk_len;
+ int ret = -1;
+ const char *label = "PASN PTK Derivation";
+
+ if (!pmk || !pmk_len) {
+ wpa_printf(MSG_ERROR, "PASN: No PMK set for PTK derivation");
+ return -1;
+ }
+
+ if (!dhss || !dhss_len) {
+ wpa_printf(MSG_ERROR, "PASN: No DHss set for PTK derivation");
+ return -1;
+ }
+
+ /*
+ * PASN-PTK = KDF(PMK, “PASN PTK Derivation”, SPA || BSSID || DHss)
+ *
+ * KCK = L(PASN-PTK, 0, 256)
+ * TK = L(PASN-PTK, 256, TK_bits)
+ * KDK = L(PASN-PTK, 256 + TK_bits, kdk_len * 8)
+ */
+ data_len = 2 * ETH_ALEN + dhss_len;
+ data = os_zalloc(data_len);
+ if (!data)
+ return -1;
+
+ os_memcpy(data, spa, ETH_ALEN);
+ os_memcpy(data + ETH_ALEN, bssid, ETH_ALEN);
+ os_memcpy(data + 2 * ETH_ALEN, dhss, dhss_len);
+
+ ptk->kck_len = WPA_PASN_KCK_LEN;
+ ptk->tk_len = wpa_cipher_key_len(cipher);
+ ptk->kdk_len = kdk_len;
+ ptk->kek_len = 0;
+ ptk->kek2_len = 0;
+ ptk->kck2_len = 0;
+
+ if (ptk->tk_len == 0) {
+ wpa_printf(MSG_ERROR,
+ "PASN: Unsupported cipher (0x%x) used in PTK derivation",
+ cipher);
+ goto err;
+ }
+
+ ptk_len = ptk->kck_len + ptk->tk_len + ptk->kdk_len;
+ if (ptk_len > sizeof(tmp))
+ goto err;
+
+ if (pasn_use_sha384(akmp, cipher)) {
+ wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA384");
+
+ if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp,
+ ptk_len) < 0)
+ goto err;
+ } else {
+ wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA256");
+
+ if (sha256_prf(pmk, pmk_len, label, data, data_len, tmp,
+ ptk_len) < 0)
+ goto err;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "PASN: PTK derivation: SPA=" MACSTR " BSSID=" MACSTR,
+ MAC2STR(spa), MAC2STR(bssid));
+
+ wpa_hexdump_key(MSG_DEBUG, "PASN: DHss", dhss, dhss_len);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: PMK", pmk, pmk_len);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: PASN-PTK", tmp, ptk_len);
+
+ os_memcpy(ptk->kck, tmp, WPA_PASN_KCK_LEN);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: KCK:", ptk->kck, WPA_PASN_KCK_LEN);
+
+ os_memcpy(ptk->tk, tmp + WPA_PASN_KCK_LEN, ptk->tk_len);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: TK:", ptk->tk, ptk->tk_len);
+
+ if (kdk_len) {
+ os_memcpy(ptk->kdk, tmp + WPA_PASN_KCK_LEN + ptk->tk_len,
+ ptk->kdk_len);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: KDK:",
+ ptk->kdk, ptk->kdk_len);
+ }
+
+ forced_memzero(tmp, sizeof(tmp));
+ ret = 0;
+err:
+ bin_clear_free(data, data_len);
+ return ret;
+}
+
+
+/*
+ * pasn_mic_len - Returns the MIC length for PASN authentication
+ */
+u8 pasn_mic_len(int akmp, int cipher)
+{
+ if (pasn_use_sha384(akmp, cipher))
+ return 24;
+
+ return 16;
+}
+
+
+/**
+ * pasn_mic - Calculate PASN MIC
+ * @kck: The key confirmation key for the PASN PTKSA
+ * @akmp: Negotiated AKM
+ * @cipher: Negotiated pairwise cipher
+ * @addr1: For the 2nd PASN frame supplicant address; for the 3rd frame the
+ * BSSID
+ * @addr2: For the 2nd PASN frame the BSSID; for the 3rd frame the supplicant
+ * address
+ * @data: For calculating the MIC for the 2nd PASN frame, this should hold the
+ * Beacon frame RSNE + RSNXE. For calculating the MIC for the 3rd PASN
+ * frame, this should hold the hash of the body of the PASN 1st frame.
+ * @data_len: The length of data
+ * @frame: The body of the PASN frame including the MIC element with the octets
+ * in the MIC field of the MIC element set to 0.
+ * @frame_len: The length of frame
+ * @mic: Buffer to hold the MIC on success. Should be big enough to handle the
+ * maximal MIC length
+ * Returns: 0 on success, -1 on failure
+ */
+int pasn_mic(const u8 *kck, int akmp, int cipher,
+ const u8 *addr1, const u8 *addr2,
+ const u8 *data, size_t data_len,
+ const u8 *frame, size_t frame_len, u8 *mic)
+{
+ u8 *buf;
+ u8 hash[SHA384_MAC_LEN];
+ size_t buf_len = 2 * ETH_ALEN + data_len + frame_len;
+ int ret = -1;
+
+ if (!kck) {
+ wpa_printf(MSG_ERROR, "PASN: No KCK for MIC calculation");
+ return -1;
+ }
+
+ if (!data || !data_len) {
+ wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
+ return -1;
+ }
+
+ if (!frame || !frame_len) {
+ wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
+ return -1;
+ }
+
+ buf = os_zalloc(buf_len);
+ if (!buf)
+ return -1;
+
+ os_memcpy(buf, addr1, ETH_ALEN);
+ os_memcpy(buf + ETH_ALEN, addr2, ETH_ALEN);
+
+ wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: data", data, data_len);
+ os_memcpy(buf + 2 * ETH_ALEN, data, data_len);
+
+ wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: frame", frame, frame_len);
+ os_memcpy(buf + 2 * ETH_ALEN + data_len, frame, frame_len);
+
+ wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: KCK", kck, WPA_PASN_KCK_LEN);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: buf", buf, buf_len);
+
+ if (pasn_use_sha384(akmp, cipher)) {
+ wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA384");
+
+ if (hmac_sha384(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
+ goto err;
+
+ os_memcpy(mic, hash, 24);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 24);
+ } else {
+ wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA256");
+
+ if (hmac_sha256(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
+ goto err;
+
+ os_memcpy(mic, hash, 16);
+ wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 16);
+ }
+
+ ret = 0;
+err:
+ bin_clear_free(buf, buf_len);
+ return ret;
+}
+
+
+/**
+ * pasn_auth_frame_hash - Computes a hash of an Authentication frame body
+ * @akmp: Negotiated AKM
+ * @cipher: Negotiated pairwise cipher
+ * @data: Pointer to the Authentication frame body
+ * @len: Length of the Authentication frame body
+ * @hash: On return would hold the computed hash. Should be big enough to handle
+ * SHA384.
+ * Returns: 0 on success, -1 on failure
+ */
+int pasn_auth_frame_hash(int akmp, int cipher, const u8 *data, size_t len,
+ u8 *hash)
+{
+ if (pasn_use_sha384(akmp, cipher)) {
+ wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-384");
+ return sha384_vector(1, &data, &len, hash);
+ } else {
+ wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-256");
+ return sha256_vector(1, &data, &len, hash);
+ }
+}
+
+#endif /* CONFIG_PASN */
+
+
static int rsn_selector_to_bitfield(const u8 *s)
{
if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
@@ -1203,6 +1504,10 @@
#endif /* CONFIG_DPP */
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN)
return WPA_KEY_MGMT_OSEN;
+#ifdef CONFIG_PASN
+ if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PASN)
+ return WPA_KEY_MGMT_PASN;
+#endif /* CONFIG_PASN */
return 0;
}
@@ -1216,7 +1521,8 @@
int wpa_cipher_valid_mgmt_group(int cipher)
{
- return cipher == WPA_CIPHER_AES_128_CMAC ||
+ return cipher == WPA_CIPHER_GTK_NOT_USED ||
+ cipher == WPA_CIPHER_AES_128_CMAC ||
cipher == WPA_CIPHER_BIP_GMAC_128 ||
cipher == WPA_CIPHER_BIP_GMAC_256 ||
cipher == WPA_CIPHER_BIP_CMAC_256;
@@ -1733,16 +2039,25 @@
const u8 *snonce, const u8 *anonce,
const u8 *sta_addr, const u8 *bssid,
const u8 *pmk_r1_name,
- struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher)
+ struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher,
+ size_t kdk_len)
{
u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
u8 *pos, hash[32];
const u8 *addr[6];
size_t len[6];
- u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
+ u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
+ WPA_KDK_MAX_LEN];
size_t ptk_len, offset;
int use_sha384 = wpa_key_mgmt_sha384(akmp);
+ if (kdk_len > WPA_KDK_MAX_LEN) {
+ wpa_printf(MSG_ERROR,
+ "FT: KDK len=%zu exceeds max supported len",
+ kdk_len);
+ return -1;
+ }
+
/*
* PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
* BSSID || STA-ADDR)
@@ -1769,8 +2084,9 @@
ptk->kek_len = wpa_kek_len(akmp, PMK_LEN);
ptk->kek2_len = wpa_kek2_len(akmp);
ptk->tk_len = wpa_cipher_key_len(cipher);
+ ptk->kdk_len = kdk_len;
ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
- ptk->kck2_len + ptk->kek2_len;
+ ptk->kck2_len + ptk->kek2_len + ptk->kdk_len;
#ifdef CONFIG_SHA384
if (use_sha384) {
@@ -1829,6 +2145,8 @@
os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len);
offset += ptk->kck2_len;
os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len);
+ offset += ptk->kek2_len;
+ os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
@@ -1838,6 +2156,9 @@
if (ptk->kek2_len)
wpa_hexdump_key(MSG_DEBUG, "FT: KEK2",
ptk->kek2, ptk->kek2_len);
+ if (ptk->kdk_len)
+ wpa_hexdump_key(MSG_DEBUG, "FT: KDK", ptk->kdk, ptk->kdk_len);
+
wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
@@ -2071,6 +2392,8 @@
return "OWE";
case WPA_KEY_MGMT_DPP:
return "DPP";
+ case WPA_KEY_MGMT_PASN:
+ return "PASN";
default:
return "UNKNOWN";
}
@@ -2942,3 +3265,451 @@
return ret;
}
+
+
+#ifdef CONFIG_PASN
+
+/*
+ * wpa_pasn_build_auth_header - Add the MAC header and initialize Authentication
+ * frame for PASN
+ *
+ * @buf: Buffer in which the header will be added
+ * @bssid: The BSSID of the AP
+ * @src: Source address
+ * @dst: Destination address
+ * @trans_seq: Authentication transaction sequence number
+ * @status: Authentication status
+ */
+void wpa_pasn_build_auth_header(struct wpabuf *buf, const u8 *bssid,
+ const u8 *src, const u8 *dst,
+ u8 trans_seq, u16 status)
+{
+ struct ieee80211_mgmt *auth;
+
+ wpa_printf(MSG_DEBUG, "PASN: Add authentication header. trans_seq=%u",
+ trans_seq);
+
+ auth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
+ u.auth.variable));
+
+ auth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_AUTH << 4));
+
+ os_memcpy(auth->da, dst, ETH_ALEN);
+ os_memcpy(auth->sa, src, ETH_ALEN);
+ os_memcpy(auth->bssid, bssid, ETH_ALEN);
+ auth->seq_ctrl = 0;
+
+ auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_PASN);
+ auth->u.auth.auth_transaction = host_to_le16(trans_seq);
+ auth->u.auth.status_code = host_to_le16(status);
+}
+
+
+/*
+ * wpa_pasn_add_rsne - Add an RSNE for PASN authentication
+ * @buf: Buffer in which the IE will be added
+ * @pmkid: Optional PMKID. Can be NULL.
+ * @akmp: Authentication and key management protocol
+ * @cipher: The cipher suite
+ */
+int wpa_pasn_add_rsne(struct wpabuf *buf, const u8 *pmkid, int akmp, int cipher)
+{
+ struct rsn_ie_hdr *hdr;
+ u32 suite;
+ u16 capab;
+ u8 *pos;
+ u8 rsne_len;
+
+ wpa_printf(MSG_DEBUG, "PASN: Add RSNE");
+
+ rsne_len = sizeof(*hdr) + RSN_SELECTOR_LEN +
+ 2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN +
+ 2 + RSN_SELECTOR_LEN + 2 + (pmkid ? PMKID_LEN : 0);
+
+ if (wpabuf_tailroom(buf) < rsne_len)
+ return -1;
+ hdr = wpabuf_put(buf, rsne_len);
+ hdr->elem_id = WLAN_EID_RSN;
+ hdr->len = rsne_len - 2;
+ WPA_PUT_LE16(hdr->version, RSN_VERSION);
+ pos = (u8 *) (hdr + 1);
+
+ /* Group addressed data is not allowed */
+ RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
+ pos += RSN_SELECTOR_LEN;
+
+ /* Add the pairwise cipher */
+ WPA_PUT_LE16(pos, 1);
+ pos += 2;
+ suite = wpa_cipher_to_suite(WPA_PROTO_RSN, cipher);
+ RSN_SELECTOR_PUT(pos, suite);
+ pos += RSN_SELECTOR_LEN;
+
+ /* Add the AKM suite */
+ WPA_PUT_LE16(pos, 1);
+ pos += 2;
+
+ switch (akmp) {
+ case WPA_KEY_MGMT_PASN:
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN);
+ break;
+#ifdef CONFIG_SAE
+ case WPA_KEY_MGMT_SAE:
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
+ break;
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+ case WPA_KEY_MGMT_FILS_SHA256:
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
+ break;
+ case WPA_KEY_MGMT_FILS_SHA384:
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
+ break;
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211R
+ case WPA_KEY_MGMT_FT_PSK:
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
+ break;
+ case WPA_KEY_MGMT_FT_IEEE8021X:
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
+ break;
+ case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
+ break;
+#endif /* CONFIG_IEEE80211R */
+ default:
+ wpa_printf(MSG_ERROR, "PASN: Invalid AKMP=0x%x", akmp);
+ return -1;
+ }
+ pos += RSN_SELECTOR_LEN;
+
+ /* RSN Capabilities: PASN mandates both MFP capable and required */
+ capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
+ WPA_PUT_LE16(pos, capab);
+ pos += 2;
+
+ if (pmkid) {
+ wpa_printf(MSG_DEBUG, "PASN: Adding PMKID");
+
+ WPA_PUT_LE16(pos, 1);
+ pos += 2;
+ os_memcpy(pos, pmkid, PMKID_LEN);
+ pos += PMKID_LEN;
+ } else {
+ WPA_PUT_LE16(pos, 0);
+ pos += 2;
+ }
+
+ /* Group addressed management is not allowed */
+ RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
+
+ return 0;
+}
+
+
+/*
+ * wpa_pasn_add_parameter_ie - Add PASN Parameters IE for PASN authentication
+ * @buf: Buffer in which the IE will be added
+ * @pasn_group: Finite Cyclic Group ID for PASN authentication
+ * @wrapped_data_format: Format of the data in the Wrapped Data IE
+ * @pubkey: A buffer holding the local public key. Can be NULL
+ * @comeback: A buffer holding the comeback token. Can be NULL
+ * @after: If comeback is set, defined the comeback time in seconds. -1 to not
+ * include the Comeback After field (frames from non-AP STA).
+ */
+void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
+ u8 wrapped_data_format,
+ struct wpabuf *pubkey,
+ struct wpabuf *comeback, int after)
+{
+ struct pasn_parameter_ie *params;
+
+ wpa_printf(MSG_DEBUG, "PASN: Add PASN Parameters element");
+
+ params = wpabuf_put(buf, sizeof(*params));
+
+ params->id = WLAN_EID_EXTENSION;
+ params->len = sizeof(*params) - 2;
+ params->id_ext = WLAN_EID_EXT_PASN_PARAMS;
+ params->control = 0;
+ params->wrapped_data_format = wrapped_data_format;
+
+ if (comeback) {
+ wpa_printf(MSG_DEBUG, "PASN: Adding comeback data");
+
+ /*
+ * 2 octets for the 'after' field + 1 octet for the length +
+ * actual cookie data
+ */
+ if (after >= 0)
+ params->len += 2;
+ params->len += 1 + wpabuf_len(comeback);
+ params->control |= WPA_PASN_CTRL_COMEBACK_INFO_PRESENT;
+
+ if (after >= 0)
+ wpabuf_put_le16(buf, after);
+ wpabuf_put_u8(buf, wpabuf_len(comeback));
+ wpabuf_put_buf(buf, comeback);
+ }
+
+ if (pubkey) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Adding public key and group ID %u",
+ pasn_group);
+
+ /*
+ * 2 octets for the finite cyclic group + 2 octets public key
+ * length + the actual key
+ */
+ params->len += 2 + 1 + wpabuf_len(pubkey);
+ params->control |= WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT;
+
+ wpabuf_put_le16(buf, pasn_group);
+ wpabuf_put_u8(buf, wpabuf_len(pubkey));
+ wpabuf_put_buf(buf, pubkey);
+ }
+}
+
+/*
+ * wpa_pasn_add_wrapped_data - Add a Wrapped Data IE to PASN Authentication
+ * frame. If needed, the Wrapped Data IE would be fragmented.
+ *
+ * @buf: Buffer in which the IE will be added
+ * @wrapped_data_buf: Buffer holding the wrapped data
+ */
+int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
+ struct wpabuf *wrapped_data_buf)
+{
+ const u8 *data;
+ size_t data_len;
+ u8 len;
+
+ if (!wrapped_data_buf)
+ return 0;
+
+ wpa_printf(MSG_DEBUG, "PASN: Add wrapped data");
+
+ data = wpabuf_head_u8(wrapped_data_buf);
+ data_len = wpabuf_len(wrapped_data_buf);
+
+ /* nothing to add */
+ if (!data_len)
+ return 0;
+
+ if (data_len <= 254)
+ len = 1 + data_len;
+ else
+ len = 255;
+
+ if (wpabuf_tailroom(buf) < 3 + data_len)
+ return -1;
+
+ wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+ wpabuf_put_u8(buf, len);
+ wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
+ wpabuf_put_data(buf, data, len - 1);
+
+ data += len - 1;
+ data_len -= len - 1;
+
+ while (data_len) {
+ if (wpabuf_tailroom(buf) < 1 + data_len)
+ return -1;
+ wpabuf_put_u8(buf, WLAN_EID_FRAGMENT);
+ len = data_len > 255 ? 255 : data_len;
+ wpabuf_put_u8(buf, len);
+ wpabuf_put_data(buf, data, len);
+ data += len;
+ data_len -= len;
+ }
+
+ return 0;
+}
+
+
+/*
+ * wpa_pasn_validate_rsne - Validate PSAN specific data of RSNE
+ * @data: Parsed representation of an RSNE
+ * Returns -1 for invalid data; otherwise 0
+ */
+int wpa_pasn_validate_rsne(const struct wpa_ie_data *data)
+{
+ u16 capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
+
+ if (data->proto != WPA_PROTO_RSN)
+ return -1;
+
+ if ((data->capabilities & capab) != capab) {
+ wpa_printf(MSG_DEBUG, "PASN: Invalid RSNE capabilities");
+ return -1;
+ }
+
+ if (!data->has_group || data->group_cipher != WPA_CIPHER_GTK_NOT_USED) {
+ wpa_printf(MSG_DEBUG, "PASN: Invalid group data cipher");
+ return -1;
+ }
+
+ if (!data->has_pairwise || !data->pairwise_cipher ||
+ (data->pairwise_cipher & (data->pairwise_cipher - 1))) {
+ wpa_printf(MSG_DEBUG, "PASN: No valid pairwise suite");
+ return -1;
+ }
+
+ switch (data->key_mgmt) {
+#ifdef CONFIG_SAE
+ case WPA_KEY_MGMT_SAE:
+ /* fall through */
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+ case WPA_KEY_MGMT_FILS_SHA256:
+ case WPA_KEY_MGMT_FILS_SHA384:
+ /* fall through */
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211R
+ case WPA_KEY_MGMT_FT_PSK:
+ case WPA_KEY_MGMT_FT_IEEE8021X:
+ case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+ /* fall through */
+#endif /* CONFIG_IEEE80211R */
+ case WPA_KEY_MGMT_PASN:
+ break;
+ default:
+ wpa_printf(MSG_ERROR, "PASN: invalid key_mgmt: 0x%0x",
+ data->key_mgmt);
+ return -1;
+ }
+
+ if (data->mgmt_group_cipher != WPA_CIPHER_GTK_NOT_USED) {
+ wpa_printf(MSG_DEBUG, "PASN: Invalid group mgmt cipher");
+ return -1;
+ }
+
+ if (data->num_pmkid > 1) {
+ wpa_printf(MSG_DEBUG, "PASN: Invalid number of PMKIDs");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * wpa_pasn_parse_parameter_ie - Validates PASN Parameters IE
+ * @data: Pointer to the PASN Parameters IE (starting with the EID).
+ * @len: Length of the data in the PASN Parameters IE
+ * @from_ap: Whether this was received from an AP
+ * @pasn_params: On successful return would hold the parsed PASN parameters.
+ * Returns: -1 for invalid data; otherwise 0
+ *
+ * Note: On successful return, the pointers in &pasn_params point to the data in
+ * the IE and are not locally allocated (so they should not be freed etc.).
+ */
+int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
+ struct wpa_pasn_params_data *pasn_params)
+{
+ struct pasn_parameter_ie *params = (struct pasn_parameter_ie *) data;
+ const u8 *pos = (const u8 *) (params + 1);
+
+ if (!pasn_params) {
+ wpa_printf(MSG_DEBUG, "PASN: Invalid params");
+ return -1;
+ }
+
+ if (!params || ((size_t) (params->len + 2) < sizeof(*params)) ||
+ len < sizeof(*params) || params->len + 2 != len) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Invalid parameters IE. len=(%u, %u)",
+ params ? params->len : 0, len);
+ return -1;
+ }
+
+ os_memset(pasn_params, 0, sizeof(*pasn_params));
+
+ switch (params->wrapped_data_format) {
+ case WPA_PASN_WRAPPED_DATA_NO:
+ case WPA_PASN_WRAPPED_DATA_SAE:
+ case WPA_PASN_WRAPPED_DATA_FILS_SK:
+ case WPA_PASN_WRAPPED_DATA_FT:
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "PASN: Invalid wrapped data format");
+ return -1;
+ }
+
+ pasn_params->wrapped_data_format = params->wrapped_data_format;
+
+ len -= sizeof(*params);
+
+ if (params->control & WPA_PASN_CTRL_COMEBACK_INFO_PRESENT) {
+ if (from_ap) {
+ if (len < 2) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Invalid Parameters IE: Truncated Comeback After");
+ return -1;
+ }
+ pasn_params->after = WPA_GET_LE16(pos);
+ pos += 2;
+ len -= 2;
+ }
+
+ if (len < 1 || len < 1 + *pos) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Invalid Parameters IE: comeback len");
+ return -1;
+ }
+
+ pasn_params->comeback_len = *pos++;
+ len--;
+ pasn_params->comeback = pos;
+ len -= pasn_params->comeback_len;
+ pos += pasn_params->comeback_len;
+ }
+
+ if (params->control & WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT) {
+ if (len < 3 || len < 3 + pos[2]) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Invalid Parameters IE: group and key");
+ return -1;
+ }
+
+ pasn_params->group = WPA_GET_LE16(pos);
+ pos += 2;
+ len -= 2;
+ pasn_params->pubkey_len = *pos++;
+ len--;
+ pasn_params->pubkey = pos;
+ len -= pasn_params->pubkey_len;
+ pos += pasn_params->pubkey_len;
+ }
+
+ if (len) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Invalid Parameters IE. Bytes left=%u", len);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab)
+{
+ size_t flen;
+
+ flen = (capab & 0xff00) ? 2 : 1;
+ if (!capab)
+ return; /* no supported extended RSN capabilities */
+ if (wpabuf_tailroom(buf) < 2 + flen)
+ return;
+ capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
+
+ wpabuf_put_u8(buf, WLAN_EID_RSNX);
+ wpabuf_put_u8(buf, flen);
+ wpabuf_put_u8(buf, capab & 0x00ff);
+ capab >>= 8;
+ if (capab)
+ wpabuf_put_u8(buf, capab);
+}
+
+#endif /* CONFIG_PASN */
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index 065dc71..c31e1a0 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -19,6 +19,9 @@
#define WPA_KEY_RSC_LEN 8
#define WPA_GMK_LEN 32
#define WPA_GTK_MAX_LEN 32
+#define WPA_PASN_PMK_LEN 32
+#define WPA_PASN_MAX_MIC_LEN 24
+#define WPA_MAX_RSNXE_LEN 4
#define OWE_DH_GROUP 19
@@ -78,6 +81,9 @@
#define RSN_AUTH_KEY_MGMT_FT_FILS_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 16)
#define RSN_AUTH_KEY_MGMT_FT_FILS_SHA384 RSN_SELECTOR(0x00, 0x0f, 0xac, 17)
#define RSN_AUTH_KEY_MGMT_OWE RSN_SELECTOR(0x00, 0x0f, 0xac, 18)
+
+#define RSN_AUTH_KEY_MGMT_PASN RSN_SELECTOR(0x00, 0x0f, 0xac, 21)
+
#define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00)
#define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
#define RSN_AUTH_KEY_MGMT_DPP RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x02)
@@ -211,8 +217,11 @@
#define WPA_KCK_MAX_LEN 32
#define WPA_KEK_MAX_LEN 64
#define WPA_TK_MAX_LEN 32
+#define WPA_KDK_MAX_LEN 32
#define FILS_ICK_MAX_LEN 48
#define FILS_FT_MAX_LEN 48
+#define WPA_PASN_KCK_LEN 32
+#define WPA_PASN_MIC_MAX_LEN 24
/**
* struct wpa_ptk - WPA Pairwise Transient Key
@@ -224,11 +233,13 @@
u8 tk[WPA_TK_MAX_LEN]; /* Temporal Key (TK) */
u8 kck2[WPA_KCK_MAX_LEN]; /* FT reasoc Key Confirmation Key (KCK2) */
u8 kek2[WPA_KEK_MAX_LEN]; /* FT reassoc Key Encryption Key (KEK2) */
+ u8 kdk[WPA_KDK_MAX_LEN]; /* Key Derivation Key */
size_t kck_len;
size_t kek_len;
size_t tk_len;
size_t kck2_len;
size_t kek2_len;
+ size_t kdk_len;
int installed; /* 1 if key has already been installed to driver */
};
@@ -378,7 +389,7 @@
const u8 *addr1, const u8 *addr2,
const u8 *nonce1, const u8 *nonce2,
struct wpa_ptk *ptk, int akmp, int cipher,
- const u8 *z, size_t z_len);
+ const u8 *z, size_t z_len, size_t kdk_len);
int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
size_t dh_ss_len, u8 *pmk, size_t *pmk_len);
@@ -388,7 +399,7 @@
const u8 *snonce, const u8 *anonce, const u8 *dhss,
size_t dhss_len, struct wpa_ptk *ptk,
u8 *ick, size_t *ick_len, int akmp, int cipher,
- u8 *fils_ft, size_t *fils_ft_len);
+ u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len);
int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
const u8 *g_sta, size_t g_sta_len,
@@ -419,7 +430,8 @@
int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len, const u8 *snonce,
const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
const u8 *pmk_r1_name,
- struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher);
+ struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher,
+ size_t kdk_len);
#endif /* CONFIG_IEEE80211R */
struct wpa_ie_data {
@@ -507,6 +519,33 @@
size_t rsnxe_len;
};
+/* IEEE P802.11az/D2.6 - 9.4.2.303 PASN Parameters element */
+#define WPA_PASN_CTRL_COMEBACK_INFO_PRESENT BIT(0)
+#define WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT BIT(1)
+
+#define WPA_PASN_WRAPPED_DATA_NO 0
+#define WPA_PASN_WRAPPED_DATA_FT 1
+#define WPA_PASN_WRAPPED_DATA_FILS_SK 2
+#define WPA_PASN_WRAPPED_DATA_SAE 3
+
+struct pasn_parameter_ie {
+ u8 id;
+ u8 len;
+ u8 id_ext;
+ u8 control; /* WPA_PASN_CTRL_* */
+ u8 wrapped_data_format; /* WPA_PASN_WRAPPED_DATA_* */
+} STRUCT_PACKED;
+
+struct wpa_pasn_params_data {
+ u8 wrapped_data_format;
+ u16 after;
+ u8 comeback_len;
+ const u8 *comeback;
+ u16 group;
+ u8 pubkey_len;
+ const u8 *pubkey;
+};
+
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
int use_sha384);
@@ -591,4 +630,41 @@
int wpa_use_aes_key_wrap(int akmp);
int fils_domain_name_hash(const char *domain, u8 *hash);
+int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
+ const u8 *spa, const u8 *bssid,
+ const u8 *dhss, size_t dhss_len,
+ struct wpa_ptk *ptk, int akmp, int cipher,
+ size_t kdk_len);
+
+u8 pasn_mic_len(int akmp, int cipher);
+
+int pasn_mic(const u8 *kck, int akmp, int cipher,
+ const u8 *addr1, const u8 *addr2,
+ const u8 *data, size_t data_len,
+ const u8 *frame, size_t frame_len, u8 *mic);
+
+int pasn_auth_frame_hash(int akmp, int cipher, const u8 *data, size_t len,
+ u8 *hash);
+
+void wpa_pasn_build_auth_header(struct wpabuf *buf, const u8 *bssid,
+ const u8 *src, const u8 *dst,
+ u8 trans_seq, u16 status);
+
+int wpa_pasn_add_rsne(struct wpabuf *buf, const u8 *pmkid,
+ int akmp, int cipher);
+
+void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
+ u8 wrapped_data_format,
+ struct wpabuf *pubkey,
+ struct wpabuf *comeback, int after);
+
+int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
+ struct wpabuf *wrapped_data_buf);
+
+int wpa_pasn_validate_rsne(const struct wpa_ie_data *data);
+int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
+ struct wpa_pasn_params_data *pasn_params);
+
+void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab);
+
#endif /* WPA_COMMON_H */
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index acc2d6c..126a789 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -271,7 +271,7 @@
#define P2P_EVENT_P2PS_PROVISION_DONE "P2PS-PROV-DONE "
#define INTERWORKING_AP "INTERWORKING-AP "
-#define INTERWORKING_BLACKLISTED "INTERWORKING-BLACKLISTED "
+#define INTERWORKING_EXCLUDED "INTERWORKING-BLACKLISTED "
#define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH "
#define INTERWORKING_ALREADY_CONNECTED "INTERWORKING-ALREADY-CONNECTED "
#define INTERWORKING_SELECTED "INTERWORKING-SELECTED "
@@ -404,10 +404,16 @@
* frame=<saqueryreq/saqueryresp> error=<error string> */
#define OCV_FAILURE "OCV-FAILURE "
+/* Event triggered for received management frame */
+#define AP_MGMT_FRAME_RECEIVED "AP-MGMT-FRAME-RECEIVED "
+
#ifndef BIT
#define BIT(x) (1U << (x))
#endif
+/* PASN authentication status */
+#define PASN_AUTH_STATUS "PASN-AUTH-STATUS "
+
/* BSS command information masks */
#define WPA_BSS_MASK_ALL 0xFFFDFFFF