[wpa_supplicant] Cumulative patch from 9fde14607
Changes include required updates to DPP R2.
Bug: 143479699
Test: Device boots up and connects to WPA3/OWE wifi networks, run traffic.
Test: Able to turn on/off softap, associate wifi STA, run traffic.
Test: Regression test Passed (Bug: 143485775)
9fde14607 Allow scans triggered by D-Bus to use MAC address randomization
10f8351d6 D-Bus: Add MAC address randomization endpoints
bb66d4675 Move ownership of MAC address randomization mask to scan params
6c2f70cc6 DPP: Mention ssid and pass parameters for DPP_AUTH_INIT in documentation
1030dec1f JSON: Fix escaping of characters that have MSB=1 with signed char
7800725af dbus: Export OWE capability and OWE BSS key_mgmt
b2ad4e6b2 D-Bus: Fix P2P NULL dereference after interface removal
937644aa2 nl80211: Indicate SUITE_B_192 capa only when CCMP-256/GCMP-256 supported
1b5865a53 SAE: Ignore commit message when waiting for confirm in STA mode
50a2c8c90 Do not indicate possible PSK failure when using SAE
df3b2e22a nl80211: Add STA node details in AP through QCA vendor subcommand
f273b2a5c Add QCA vendor cmd for setting BT coex chain mode
4dc860680 Extend QCA OEM data vendor subcmd to allow use as an event
93a1e275a SAE: Determine H2E vs. looping when restarting SAE auth in AP mode
de580bf6c crypto: Remove unused crypto_bignum_sqrtmod()
9b292a48f SAE: Drop sqrt() alternative from SSWU (H2E)
305369038 wpa_supplicant: Fix arithmetic on void pointer
00ddc1cc2 common: Fix same expression checked twice in fils_key_auth_sk()
327d09aa0 HE: Add 11ax info to ap mode ctrl iface STATUS command
d7678a084 Fix AP Extended Capability length determination
a592f2a9e P2P: Continue listening next request if no post-PD operations
a32acf391 Fix hostapd build with CONFIG_WPA_TRACE but no CONFIG_WPA_TRACE_BFD
b38c8c9cb dbus: Suppress to show NULL string
6807eee9c Interworking: Check NULL string to avoid compiler warning
ec1c0d154 Fix name of DBus interface in defconfig
f73dd0a69 FT-SAE: Add RSNXE into FT MIC
cb9925977 Add RSNXE into (Re)Association Response frames
865721c69 Merge wpa_supplicant and hostapd EAPOL-Key KDE parsers
898b6d58f SAE: Verify that STA negotiated H2E if it claims to support it
74866f537 RSN: Verify RSNXE match between (Re)AssocReq and EAPOL-Key msg 2/4
9981d5bf3 Add RSNXE into AP KDE parser
d3516cad7 Store a copy of Association Request RSNXE in AP mode for later use
6d6c88775 SAE: Add RSNXE in Association Request and EAPOL-Key msg 2/4
8401cdc8d Add RSNXE into IE parser
0b0ed907d WPS: Check SHA256 result success
8dda97c75 QCA vendor command for adding a STA node
b41dc61af Add a new QCA vendor attribute to carry device info for OEM data
bf185bfd5 QCA vendor attributes to indicate BW-based agile spectral capability
1317ea2c0 nl80211: Allow external auth based on SAE/FT-SAE key mgmt
cdb5774f4 FST: Update FST about MAC address change
49e95ee1e AP: Publish only HE capabilities and operation IEs on 6 GHz band
d7c2c5c98 AP: Add initial support for 6 GHz band
a5b2faa71 AP: Add op_class config item to specify 6 GHz channels uniquely
89450024a wpa_supplicant: Pass in operating class for channel validity checks
032c8264d SAE: Check that peer's rejected groups are not enabled in AP
a5dc2a5c1 SAE: H2E version of SAE commit message handling for AP
43b20b437 SAE: Derive H2E PT in AP when starting the AP
444d76f74 SAE: Check that peer's rejected groups are not enabled
cfe1ea5c9 SAE: H2E version of SAE commit message handling for STA
447cd5f2d SAE: Collect list of rejected groups for H2E in STA
05a2fb0d1 SAE: Derive H2E PT in STA before connection
146889e3c RSN: Verify RSNXE match between Beacon/ProbeResp and EAPOL-Key msg 3/4
3134bb13a SAE: Advertise Extended RSN Capabilities when H2E is enabled
293a01f3b SAE: Handle BSS membership selector indication for H2E-only in STA mode
cc0da0ff4 SAE: Advertise BSS membership selector for H2E-only case
85e64e634 SAE: Add sae_pwe configuration parameter for wpa_supplicant
a36e13a7c SAE: Add sae_pwe configuration parameter for hostapd
af4487148 tests: Module test for SAE hash-to-element crypto routines
cf84246eb SAE: Add Rejected Groups element into H2E Commit
efd428529 SAE: Hash algorithm selection for H2E KCK/CN()
aeb022f8e SAE: Implement hash-to-element PT/PWE crypto routines
ecd711407 SAE: Parse Rejected Groups element from H2E SAE commit
86f608486 SAE: Tell sae_parse_commit() whether H2E is used
316156739 SAE: H2E protocol defines
1766e608b wolfSSL: Fix crypto_bignum_sub()
2a1c84f4e crypto: Add more bignum/EC helper functions
9c08bfbd9 DPP: Fix confusing debug entry from Configurator
f7fe05522 SAE: Allow AP behavior for SAE Confirm to be configured
d6a7de60c wpa_cli: Clean up unnecessarily complex CONFIG_MESH use
8b426ab1e wpa_supplicant: Pass AP mode EDMG config to hostapd struct
a82aee1f4 wpa_supplicant: Add support for EDMG channels
35aed771f Indicate EDMG in scan results
f6f8c6ade AP: Show EDMG channel info in STATUS output
241dd76cf hostapd: Check EDMG configuration against capability
dc3457cc4 hostapd: Check usability of EDMG channel
bebd91e9c Add EDMG parameters to set_freq functions
fdd0fef2c EDMG: Helper functions for parameter encoding/checking
e8ff22f47 wpa_supplicant: Add EDMG channel configuration parameters
5c5ff22ef hostapd: Add EDMG channel configuration parameters
dda5d9e31 nl80211: Add support for EDMG channels
a19913c17 IEEE P802.11ay/D4.0 defines for EDMG
c34917403 MBO/OCE: Update disable_mbo_oce flag after association
b719a1568 DPP2: Parse AKM suite selector version of akm node
68fea9603 DPP2: Allow Configurator to use AKM suite selectors in Config Object
52d469de1 DPP2: Support multiple Config Objects in Enrollee
7eb06a336 DPP2: Allow multiple Config Objects to be build on Configurator
99918e069 DPP: Cleaned up netrole indication for config object building
e0d22c842 FILS+FT: Fix MFPR flag in RSNE during FILS exchange for FT
d0a4ed6a1 Allow SAE to be used in wpa_supplicant AP mode
7846e8d60 NetBSD: Fix compile
2e06cef80 MBO/OCE: Work around misbehaving MBO/OCE APs that use RSN without PMF
722c7d195 wlantest: Process VLAN tagged Data frames
83b83b461 nl80211: Migrate to current netlink key message format
7a4b01c87 AP: Provide correct keyid to wpa_send_eapol() for EAPOL-Key msg 3/4
a3ebf7175 BSD: Add support for route(4) message filtering
d9286d099 ACS: Stop before scan if no channels in chanlist are available
f32aa244e DPP: Debug print configRequest bandSupport on Configurator
8f8c423a5 DPP: Add bandSupport JSON array into config request
6d3dc9ba1 mka: Check OLPN for exhaustion on SAKuse decode
84851007d mka: Check OLPN for exhaustion on SAKuse encode
547ba732d mka: Clear out old/latest key values on CHANGE in CP state machine
536a7cfcf mka: Don't set newSAK to FALSE on ABANDON in CP state machine
0fedfba2e mka: Change RECEIVE and RETIRE states to match the standard
3f2641e7a Fix wpa_supplicant build with CONFIG_PCSC=y
5a5639b06 DPP: Allow name and mudurl to be configured for Config Request
3394def5a More consistent SA check for unexpected Data frames
16ef233bf DPP2: Connection status result (Enrollee)
b10e01a79 DPP2: Connection status result (Configurator)
e501a2eb5 DPP2: Connection status result defines
cc8399528 DPP2: Move dpp_build_conf_result() to be within ifdef block
3a6736fe8 DPP2: Fix a memory leak on error path for Config Result
21dc1627f wpa_supplicant: Don't return an error when successfully parsing WMM rules
8214b45ba P2P: Use latest BSS entry if multiple P2P Device Addr matches found
dc6c3be4e wpa_supplicant: Add support for 60 GHz band channels 5 and 6
018edec9b Remove IAPP functionality from hostapd
d86d66dc0 AP: Silently ignore management frame from unexpected source address
a84bf4438 HE: Send the AP's OBSS PD settings to the kernel
262b71eea Sync with mac80211-next.git include/uapi/linux/nl80211.h
8788a314d WPS: Update MAC address on address changes
39042d7f7 os_sleep: Use nanosleep for POSIX versions 2008 and higher
a69742c2f wpa_cli: Do not pick p2p-dev-* interfaces by default
d842e00bd SAE: Return result from confirm CN() operation to the caller
a8bfc6fff FILS: Update connect params after sending connection notification
0df82a3da Correct the type/usage of QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST
6bf6c6fec DPP: Fix hostapd build dependencies for DPP-only build
1eff2e7bf DPP2: Fix wpa_supplicant build dependencies for CONFIG_AP=y build
d2bae5763 DPP: Fix wpa_supplicant build dependencies for DPP-only build
7d2ed8bae Remove CONFIG_IEEE80211W build parameter
022926187 DFS offload: Fix hostapd state and CAC info in STATUS output
4d78ba990 EAP-TEAP peer: Clear Phase 2 EAP method on new Identity exchange
681618246 EAP-TEAP peer: Add support for machine credentials using certificates
ebee8232d Do not try to include net/ethernet.h in MinGW/Windows builds
bf15b1559 Fix Windows error code definition workaround
043de65f1 EAP peer config: Move ocsp param to phase1/phase2
8d76e0ad7 EAP server: Configurable maximum number of authentication message rounds
b99c4cadb EAP peer: Move certificate configuration params into shared struct
6e711e7ab mesh: Do not enable HE on 5 GHz without VHT
0497e4148 HE: Fix HE Capabilities element size
a2e0cc9e0 Add nl80211 vendor ACS trigger reasons related to interference
69e8e7817 HS 2.0: Do not add two copies of OSEN element into Beacon/Probe Resp
a762ba8b1 HS 2.0 AP: Do not mandate PMF for HS 2.0 Indication in open OSU network
e49ce2990 IEEE 802.1X authenticator: Coding style cleanup
31aaddc90 Clean up IEEE 802.1X authentication debug messages for EAP code
71419119f EAP-TEAP peer: Fix protected indication of inner EAP method failure
93cd29d2b EAP-TEAP server: Add support for requiring user and machine credentials
c38c62ff7 wlantest: Derive PMK-R1 and PTK for FT protocol cases
c41936566 EAP-TEAP peer: Add support for machine authentication
c724a0a16 EAP peer: Add a concept of a separate machine credential
9ce3bfaf4 RADIUS server: Abort startup on allocation failures
fa1f0751c RADIUS server: Use struct eap_config to avoid duplicated definitions
a00cb1b1f EAP-TEAP server: Fix eap_teap_pac_no_inner configuration
986033ff3 EAP-TEAP server: Fix Crypto-Binding check in PAC no-inner-auth case
e54cfbb56 EAP-TEAP server: Allow a specific Identity-Type to be requested/required
f186ec54c EAP-TEAP peer: Support Identity-Type TLV
cc661c160 EAP-TEAP: Add parsing and generation routines for Identity-Type TLV
100b2edb2 OpenSSL: Write peer certificate chain details in debug log
7eb157f1e EAP: Increase the maximum number of message exchanges
822e7c66a EAP server: Use struct eap_config to avoid duplicated definitions
62af2b18f EAP-TEAP peer: Support vendor EAP method in Phase 2
aba8dc82f EAP-PEAP server: Support vendor EAP types in Phase 2
357c1062d EAP-FAST peer: Support vendor EAP method in Phase 2
f32f76231 EAP-FAST server: Support vendor EAP types in Phase 2
887d8703b EAP-PEAP peer: Support vendor EAP method in Phase 2
f2ef4f255 EAP peer: Allow VENDOR-TEST method in Phase 2
5ddbd9e96 EAP-TTLS peer: Support vendor EAP method in Phase 2
5e94e7f23 EAP-TTLS server: Support vendor EAP types in Phase 2
5f2301a6d Replace EapType typedef with enum eap_type
76ddfae6e EAP-TEAP server: Testing mechanism for Result TLV in a separate message
4c327146f EAP-TEAP peer: Allow Result TLV without Crypto-Binding TLV
128d46be9 EAP-TEAP: Add parsing of Error TLV
234489efd EAP-TEAP server: Require Intermediate-Result TLV even with Result TLV
0f7c91f2b EAP-TEAP peer: Add Intermediate-Result TLV with Crypto-Binding TLV
a66e53c41 EAP-TEAP: Fix TLS-PRF for TLS ciphersuites that use SHA384
52069c7ef Add TLS-PRF using HMAC with P_SHA384 for TEAP
a647a0ad7 Extend server certificate TOD policy reporting to include TOD-TOFU
346d10cf8 SAE: Conditionally set PMKID while notifying the external auth status
b7cd64876 SAE: Use BSSID stored in ext_auth_bssid for set_pmk
e0b331d89 OWE: Update connect params with new DH attributes to the driver
c574a3ff1 nl80211: Request update connection params only for drivers with SME
528f263c4 FT: Reject over-the-DS response with MFPC=0 if PMF is required
ae05b6a21 RSN: Do not allow connection to proceed without MFPC=1 if PMF required
ded56f2fa FT: Fix MFPR flag in RSNE during FT protocol
0028d627c OCE: Mandate PMF for WPA2 association with OCE AP
84ebc759a HS 2.0: Match credentials based on required_roaming_consortium
d2b208384 SAE: Allow PMKID to be added into Association Request frame following SAE
2ca23faf1 Make wpa_insert_pmkid() more generic
05822609d HE: MCS size is always a minimum of 4 bytes
df4f95998 nl80211: Don't force VHT channel definition with HE
dd0153fce Check for LEAP before doing FT
6126e5f97 Fix a typo in hostapd config documentation
698a0067c Fix check_crl_strict documentation
485dd425b Add QCA vendor command for avoid frequency feature
6ae1247bf Update QCA vendor attributes for 6 GHz band support
aa23ece3d Add QCA vendor channel attribute to restart AP
85508ecf6 Add QCA vendor command to configure ACS policy
2395fdb67 Add QCA vendor attributes to enhance roaming configuration
1425caac2 Rename qca_wlan_vendor_attr_roam_subcmd to represent subcmds
f13119631 Document the attributes used by QCA_NL80211_VENDOR_SUBCMD_ROAM
b0b25c5bb Clear external eapSuccess setting in driver-authorized cases
fa1d5ec18 The master branch is now used for v2.10 development
ca8c2bd28 Preparations for v2.8 release
3263fca28 Set the default scan IEs on interface restart
d776bf8c6 EAP-TEAP peer: Fix fragmentation of final message
1c7e61a35 wolfssl: Avoid void pointer arithmetic
7122a02fa SAE: Fix order_len for FFC groups
422e73d62 DPP: Indicate authentication success on ConfReqRX if needed
d001fe31a OpenSSL: Handle EVP_PKEY_derive() secret_len changes for ECDH
29ef1c5ee DPP: Use a common helper function for ECDH operations
ac734a342 SAE: Fix KCK, PMK, and PMKID derivation for groups 22, 23, 24
c65168ccd OpenSSL: Fix crypto_bignum_to_bin() with padlen == 0
cb28bd52e nl80211: Use separate flag for 4-way handshake offload
6bb11c7a4 EAP-SIM/AKA server: Allow pseudonym/fast reauth to be disabled
c1b236521 EAP-SIM/AKA: Do not allow anonymous@realm "pseudonym" to be cleared
cc2fd9425 D-Bus: Demote timeout/flush messages to MSG_MSGDUMP
3b726df82 nl80211: Missing sysctl flags aren't fatal
f4111ff3d Extra RADIUS request attributes from SQLite
74707def8 Move hostapd_parse_radius_attr() into ap_config.c
1e5ea68d1 mka: Accept last two used MNs in Peers List of a received MKPDU
013686403 P2P: Pass HE flag to GO negotiation result
876c5eaa6 dragonfly: Disable use of groups using Brainpool curves
968520da8 nl80211: Add WMM parameters while updating TDLS peer entry
5a511924b wpa_cli: Add support to process DPP action events in action script
64e37be94 Avoid nested enum wpas_mode declaration to allow C++ compilation
fe2e1edf4 EAP-SIM server: Avoid void pointer arithmetic
cfc9ebea0 EAP-AKA server: Avoid void pointer arithmetic
bd0414043 trace: Avoid void pointer arithmetic
fc03ea2c1 DPP: Avoid void pointer arithmetic
d1b1f9fa9 Report WPA/RSN protocol and AKM suite selector in STA MIB
43aafef8d Add missed wpa_akm_to_suite() selectors
bfb6a482f dragonfly: SAE/EAP-pwd min PWE derivation iteration count to shared code
226da33d7 EAP-pwd peer: Configurable set of groups with reduced default
6a4406c01 Add QCA vendor attributes for ELNA bypass
176c133e9 Add a vendor attribute to configure disconnect IEs
123895228 Add QCA vendor command to support OEM data
Change-Id: Iaa497edcda7c5dcdad19db9d09ab09ef74e508bd
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 3298f91..8fd2710 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -123,6 +123,7 @@
OBJS += src/utils/wpa_debug.c
OBJS += src/utils/wpabuf.c
OBJS += src/utils/bitfield.c
+OBJS += src/utils/ip_addr.c
OBJS += wmm_ac.c
OBJS += op_classes.c
OBJS += rrm.c
@@ -228,8 +229,6 @@
ifdef CONFIG_SUITEB
L_CFLAGS += -DCONFIG_SUITEB
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_SUITEB192
@@ -240,25 +239,15 @@
ifdef CONFIG_OCV
L_CFLAGS += -DCONFIG_OCV
OBJS += src/common/ocv.c
-CONFIG_IEEE80211W=y
-endif
-
-ifdef CONFIG_IEEE80211W
-L_CFLAGS += -DCONFIG_IEEE80211W
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_IEEE80211R
L_CFLAGS += -DCONFIG_IEEE80211R
OBJS += src/rsn_supp/wpa_ft.c
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_MESH
NEED_80211_COMMON=y
-NEED_SHA256=y
NEED_AES_SIV=y
CONFIG_SAE=y
CONFIG_AP=y
@@ -284,9 +273,9 @@
NEED_HMAC_SHA256_KDF=y
NEED_HMAC_SHA384_KDF=y
NEED_HMAC_SHA512_KDF=y
-NEED_SHA256=y
NEED_SHA384=y
NEED_SHA512=y
+NEED_ECC=y
NEED_JSON=y
NEED_GAS_SERVER=y
NEED_BASE64=y
@@ -301,7 +290,6 @@
NEED_HMAC_SHA256_KDF=y
NEED_HMAC_SHA384_KDF=y
NEED_HMAC_SHA512_KDF=y
-NEED_SHA256=y
NEED_SHA384=y
NEED_SHA512=y
endif
@@ -328,8 +316,6 @@
ifdef CONFIG_TDLS
L_CFLAGS += -DCONFIG_TDLS
OBJS += src/rsn_supp/tdls.c
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_TDLS_TESTING
@@ -394,7 +380,6 @@
OBJS += hs20_supplicant.c
L_CFLAGS += -DCONFIG_HS20
CONFIG_INTERWORKING=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_INTERWORKING
@@ -461,7 +446,6 @@
ifdef CONFIG_ERP
L_CFLAGS += -DCONFIG_ERP
-NEED_SHA256=y
NEED_HMAC_SHA256_KDF=y
endif
@@ -616,7 +600,6 @@
endif
CONFIG_IEEE8021X_EAPOL=y
NEED_AES=y
-NEED_AES_OMAC1=y
NEED_AES_ENCBLOCK=y
NEED_AES_EAX=y
endif
@@ -649,7 +632,6 @@
else
L_CFLAGS += -DEAP_AKA_PRIME
endif
-NEED_SHA256=y
endif
ifdef CONFIG_EAP_SIM_COMMON
@@ -689,6 +671,8 @@
CONFIG_IEEE8021X_EAPOL=y
NEED_T_PRF=y
NEED_SHA384=y
+NEED_TLS_PRF_SHA256=y
+NEED_TLS_PRF_SHA384=y
endif
ifdef CONFIG_EAP_PAX
@@ -728,15 +712,12 @@
ifdef CONFIG_EAP_GPSK_SHA256
L_CFLAGS += -DEAP_GPSK_SHA256
endif
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_EAP_PWD
L_CFLAGS += -DEAP_PWD
OBJS += src/eap_peer/eap_pwd.c src/eap_common/eap_pwd_common.c
CONFIG_IEEE8021X_EAPOL=y
-NEED_SHA256=y
NEED_ECC=y
NEED_DRAGONFLY=y
endif
@@ -753,7 +734,6 @@
CONFIG_IEEE8021X_EAPOL=y
NEED_DH_GROUPS=y
NEED_DH_GROUPS_ALL=y
-NEED_SHA256=y
NEED_AES_CBC=y
endif
@@ -773,7 +753,6 @@
OBJS += src/wps/wps_registrar.c
CONFIG_IEEE8021X_EAPOL=y
NEED_DH_GROUPS=y
-NEED_SHA256=y
NEED_BASE64=y
NEED_AES_CBC=y
NEED_MODEXP=y
@@ -890,7 +869,6 @@
OBJS += src/ap/utils.c
OBJS += src/ap/authsrv.c
OBJS += src/ap/ap_config.c
-OBJS += src/utils/ip_addr.c
OBJS += src/ap/sta_info.c
OBJS += src/ap/tkip_countermeasures.c
OBJS += src/ap/ap_mlme.c
@@ -959,8 +937,12 @@
ifdef CONFIG_DPP
OBJS += src/ap/dpp_hostapd.c
OBJS += src/ap/gas_query_ap.c
+NEED_AP_GAS_SERV=y
endif
ifdef CONFIG_INTERWORKING
+NEED_AP_GAS_SERV=y
+endif
+ifdef NEED_AP_GAS_SERV
OBJS += src/ap/gas_serv.c
endif
ifdef CONFIG_HS20
@@ -1064,7 +1046,6 @@
ifdef CONFIG_TLSV12
L_CFLAGS += -DCONFIG_TLSV12
-NEED_SHA256=y
endif
ifeq ($(CONFIG_TLS), openssl)
@@ -1079,7 +1060,6 @@
ifdef NEED_FIPS186_2_PRF
OBJS += src/crypto/fips_prf_openssl.c
endif
-NEED_SHA256=y
NEED_TLS_PRF_SHA256=y
LIBS += -lcrypto
LIBS_p += -lcrypto
@@ -1142,7 +1122,6 @@
OBJS += src/tls/pkcs1.c
OBJS += src/tls/pkcs5.c
OBJS += src/tls/pkcs8.c
-NEED_SHA256=y
NEED_BASE64=y
NEED_TLS_PRF=y
ifdef CONFIG_TLSV12
@@ -1262,12 +1241,10 @@
ifdef NEED_AES_EAX
AESOBJS += src/crypto/aes-eax.c
NEED_AES_CTR=y
-NEED_AES_OMAC1=y
endif
ifdef NEED_AES_SIV
AESOBJS += src/crypto/aes-siv.c
NEED_AES_CTR=y
-NEED_AES_OMAC1=y
endif
ifdef NEED_AES_CTR
AESOBJS += src/crypto/aes-ctr.c
@@ -1275,14 +1252,12 @@
ifdef NEED_AES_ENCBLOCK
AESOBJS += src/crypto/aes-encblock.c
endif
-ifdef NEED_AES_OMAC1
NEED_AES_ENC=y
ifdef CONFIG_OPENSSL_CMAC
L_CFLAGS += -DCONFIG_OPENSSL_CMAC
else
AESOBJS += src/crypto/aes-omac1.c
endif
-endif
ifdef NEED_AES_WRAP
NEED_AES_ENC=y
ifdef NEED_INTERNAL_AES_WRAP
@@ -1375,7 +1350,6 @@
endif
SHA256OBJS = # none by default
-ifdef NEED_SHA256
L_CFLAGS += -DCONFIG_SHA256
ifneq ($(CONFIG_TLS), openssl)
ifneq ($(CONFIG_TLS), gnutls)
@@ -1397,6 +1371,9 @@
ifdef NEED_TLS_PRF_SHA256
SHA256OBJS += src/crypto/sha256-tlsprf.c
endif
+ifdef NEED_TLS_PRF_SHA384
+SHA256OBJS += src/crypto/sha384-tlsprf.c
+endif
ifdef NEED_HMAC_SHA256_KDF
L_CFLAGS += -DCONFIG_HMAC_SHA256_KDF
SHA256OBJS += src/crypto/sha256-kdf.c
@@ -1410,7 +1387,6 @@
SHA256OBJS += src/crypto/sha512-kdf.c
endif
OBJS += $(SHA256OBJS)
-endif
ifdef NEED_SHA384
L_CFLAGS += -DCONFIG_SHA384
ifneq ($(CONFIG_TLS), openssl)
@@ -1663,9 +1639,6 @@
OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.c
OBJS_t += src/radius/radius_client.c
OBJS_t += src/radius/radius.c
-ifndef CONFIG_AP
-OBJS_t += src/utils/ip_addr.c
-endif
OBJS_t2 := $(OBJS) $(OBJS_l2) preauth_test.c
OBJS += $(CONFIG_MAIN).c
diff --git a/wpa_supplicant/ChangeLog b/wpa_supplicant/ChangeLog
index 89119e7..f82e5e0 100644
--- a/wpa_supplicant/ChangeLog
+++ b/wpa_supplicant/ChangeLog
@@ -1,5 +1,34 @@
ChangeLog for wpa_supplicant
+2019-08-07 - v2.9
+ * SAE changes
+ - disable use of groups using Brainpool curves
+ - improved protection against side channel attacks
+ [https://w1.fi/security/2019-6/]
+ * EAP-pwd changes
+ - disable use of groups using Brainpool curves
+ - allow the set of groups to be configured (eap_pwd_groups)
+ - improved protection against side channel attacks
+ [https://w1.fi/security/2019-6/]
+ * fixed FT-EAP initial mobility domain association using PMKSA caching
+ (disabled by default for backwards compatibility; can be enabled
+ with ft_eap_pmksa_caching=1)
+ * fixed a regression in OpenSSL 1.1+ engine loading
+ * added validation of RSNE in (Re)Association Response frames
+ * fixed DPP bootstrapping URI parser of channel list
+ * extended EAP-SIM/AKA fast re-authentication to allow use with FILS
+ * extended ca_cert_blob to support PEM format
+ * improved robustness of P2P Action frame scheduling
+ * added support for EAP-SIM/AKA using anonymous@realm identity
+ * fixed Hotspot 2.0 credential selection based on roaming consortium
+ to ignore credentials without a specific EAP method
+ * added experimental support for EAP-TEAP peer (RFC 7170)
+ * added experimental support for EAP-TLS peer with TLS v1.3
+ * fixed a regression in WMM parameter configuration for a TDLS peer
+ * fixed a regression in operation with drivers that offload 802.1X
+ 4-way handshake
+ * fixed an ECDH operation corner case with OpenSSL
+
2019-04-21 - v2.8
* SAE changes
- added support for SAE Password Identifier
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index f1384d5..a6329c0 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -103,6 +103,7 @@
OBJS += ../src/utils/wpa_debug.o
OBJS += ../src/utils/wpabuf.o
OBJS += ../src/utils/bitfield.o
+OBJS += ../src/utils/ip_addr.o
OBJS += op_classes.o
OBJS += rrm.o
OBJS_p = wpa_passphrase.o
@@ -230,8 +231,6 @@
ifdef CONFIG_SUITEB
CFLAGS += -DCONFIG_SUITEB
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_SUITEB192
@@ -242,25 +241,15 @@
ifdef CONFIG_OCV
CFLAGS += -DCONFIG_OCV
OBJS += ../src/common/ocv.o
-CONFIG_IEEE80211W=y
-endif
-
-ifdef CONFIG_IEEE80211W
-CFLAGS += -DCONFIG_IEEE80211W
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_IEEE80211R
CFLAGS += -DCONFIG_IEEE80211R
OBJS += ../src/rsn_supp/wpa_ft.o
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_MESH
NEED_80211_COMMON=y
-NEED_SHA256=y
NEED_AES_SIV=y
CONFIG_SAE=y
CONFIG_AP=y
@@ -286,9 +275,9 @@
NEED_HMAC_SHA256_KDF=y
NEED_HMAC_SHA384_KDF=y
NEED_HMAC_SHA512_KDF=y
-NEED_SHA256=y
NEED_SHA384=y
NEED_SHA512=y
+NEED_ECC=y
NEED_JSON=y
NEED_GAS_SERVER=y
NEED_BASE64=y
@@ -303,7 +292,6 @@
NEED_HMAC_SHA256_KDF=y
NEED_HMAC_SHA384_KDF=y
NEED_HMAC_SHA512_KDF=y
-NEED_SHA256=y
NEED_SHA384=y
NEED_SHA512=y
endif
@@ -330,8 +318,6 @@
ifdef CONFIG_TDLS
CFLAGS += -DCONFIG_TDLS
OBJS += ../src/rsn_supp/tdls.o
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_TDLS_TESTING
@@ -404,7 +390,6 @@
OBJS += hs20_supplicant.o
CFLAGS += -DCONFIG_HS20
CONFIG_INTERWORKING=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_INTERWORKING
@@ -458,7 +443,6 @@
ifdef CONFIG_ERP
CFLAGS += -DCONFIG_ERP
-NEED_SHA256=y
NEED_HMAC_SHA256_KDF=y
endif
@@ -613,7 +597,6 @@
endif
CONFIG_IEEE8021X_EAPOL=y
NEED_AES=y
-NEED_AES_OMAC1=y
NEED_AES_ENCBLOCK=y
NEED_AES_EAX=y
endif
@@ -646,7 +629,6 @@
else
CFLAGS += -DEAP_AKA_PRIME
endif
-NEED_SHA256=y
endif
ifdef CONFIG_EAP_SIM_COMMON
@@ -686,6 +668,8 @@
CONFIG_IEEE8021X_EAPOL=y
NEED_T_PRF=y
NEED_SHA384=y
+NEED_TLS_PRF_SHA256=y
+NEED_TLS_PRF_SHA384=y
endif
ifdef CONFIG_EAP_PAX
@@ -725,8 +709,6 @@
ifdef CONFIG_EAP_GPSK_SHA256
CFLAGS += -DEAP_GPSK_SHA256
endif
-NEED_SHA256=y
-NEED_AES_OMAC1=y
endif
ifdef CONFIG_EAP_PWD
@@ -736,7 +718,6 @@
endif
OBJS += ../src/eap_peer/eap_pwd.o ../src/eap_common/eap_pwd_common.o
CONFIG_IEEE8021X_EAPOL=y
-NEED_SHA256=y
NEED_ECC=y
NEED_DRAGONFLY=y
endif
@@ -753,7 +734,6 @@
CONFIG_IEEE8021X_EAPOL=y
NEED_DH_GROUPS=y
NEED_DH_GROUPS_ALL=y
-NEED_SHA256=y
NEED_AES_CBC=y
endif
@@ -773,7 +753,6 @@
OBJS += ../src/wps/wps_registrar.o
CONFIG_IEEE8021X_EAPOL=y
NEED_DH_GROUPS=y
-NEED_SHA256=y
NEED_BASE64=y
NEED_AES_CBC=y
NEED_MODEXP=y
@@ -871,7 +850,6 @@
NEED_AES_ENCBLOCK=y
NEED_AES_UNWRAP=y
NEED_AES_WRAP=y
-NEED_AES_OMAC1=y
OBJS += wpas_kay.o
OBJS += ../src/pae/ieee802_1x_cp.o
OBJS += ../src/pae/ieee802_1x_kay.o
@@ -907,7 +885,6 @@
OBJS += ../src/ap/utils.o
OBJS += ../src/ap/authsrv.o
OBJS += ../src/ap/ap_config.o
-OBJS += ../src/utils/ip_addr.o
OBJS += ../src/ap/sta_info.o
OBJS += ../src/ap/tkip_countermeasures.o
OBJS += ../src/ap/ap_mlme.o
@@ -976,8 +953,12 @@
ifdef CONFIG_DPP
OBJS += ../src/ap/dpp_hostapd.o
OBJS += ../src/ap/gas_query_ap.o
+NEED_AP_GAS_SERV=y
endif
ifdef CONFIG_INTERWORKING
+NEED_AP_GAS_SERV=y
+endif
+ifdef NEED_AP_GAS_SERV
OBJS += ../src/ap/gas_serv.o
endif
ifdef CONFIG_HS20
@@ -1081,7 +1062,6 @@
ifdef CONFIG_TLSV12
CFLAGS += -DCONFIG_TLSV12
-NEED_SHA256=y
endif
ifeq ($(CONFIG_TLS), wolfssl)
@@ -1112,7 +1092,6 @@
ifdef NEED_FIPS186_2_PRF
OBJS += ../src/crypto/fips_prf_openssl.o
endif
-NEED_SHA256=y
NEED_TLS_PRF_SHA256=y
LIBS += -lcrypto
LIBS_p += -lcrypto
@@ -1176,7 +1155,6 @@
OBJS += ../src/tls/pkcs1.o
OBJS += ../src/tls/pkcs5.o
OBJS += ../src/tls/pkcs8.o
-NEED_SHA256=y
NEED_BASE64=y
NEED_TLS_PRF=y
ifdef CONFIG_TLSV12
@@ -1256,7 +1234,6 @@
OBJS += ../src/tls/pkcs1.o
OBJS += ../src/tls/pkcs5.o
OBJS += ../src/tls/pkcs8.o
-NEED_SHA256=y
NEED_BASE64=y
NEED_TLS_PRF=y
ifdef CONFIG_TLSV12
@@ -1342,12 +1319,10 @@
ifdef NEED_AES_EAX
AESOBJS += ../src/crypto/aes-eax.o
NEED_AES_CTR=y
-NEED_AES_OMAC1=y
endif
ifdef NEED_AES_SIV
AESOBJS += ../src/crypto/aes-siv.o
NEED_AES_CTR=y
-NEED_AES_OMAC1=y
endif
ifdef NEED_AES_CTR
AESOBJS += ../src/crypto/aes-ctr.o
@@ -1355,7 +1330,6 @@
ifdef NEED_AES_ENCBLOCK
AESOBJS += ../src/crypto/aes-encblock.o
endif
-ifdef NEED_AES_OMAC1
NEED_AES_ENC=y
ifdef CONFIG_OPENSSL_CMAC
CFLAGS += -DCONFIG_OPENSSL_CMAC
@@ -1366,7 +1340,6 @@
endif
endif
endif
-endif
ifdef NEED_AES_WRAP
NEED_AES_ENC=y
ifdef NEED_INTERNAL_AES_WRAP
@@ -1475,7 +1448,6 @@
endif
SHA256OBJS = # none by default
-ifdef NEED_SHA256
CFLAGS += -DCONFIG_SHA256
ifneq ($(CONFIG_TLS), openssl)
ifneq ($(CONFIG_TLS), linux)
@@ -1501,6 +1473,9 @@
ifdef NEED_TLS_PRF_SHA256
SHA256OBJS += ../src/crypto/sha256-tlsprf.o
endif
+ifdef NEED_TLS_PRF_SHA384
+SHA256OBJS += ../src/crypto/sha384-tlsprf.o
+endif
ifdef NEED_HMAC_SHA256_KDF
CFLAGS += -DCONFIG_HMAC_SHA256_KDF
OBJS += ../src/crypto/sha256-kdf.o
@@ -1514,7 +1489,6 @@
OBJS += ../src/crypto/sha512-kdf.o
endif
OBJS += $(SHA256OBJS)
-endif
ifdef NEED_SHA384
ifneq ($(CONFIG_TLS), openssl)
ifneq ($(CONFIG_TLS), linux)
@@ -1808,9 +1782,6 @@
OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.o
OBJS_t += ../src/radius/radius_client.o
OBJS_t += ../src/radius/radius.o
-ifndef CONFIG_AP
-OBJS_t += ../src/utils/ip_addr.o
-endif
OBJS_t2 := $(OBJS) $(OBJS_l2) preauth_test.o
OBJS_nfc := $(OBJS) $(OBJS_l2) nfc_pw_token.o
diff --git a/wpa_supplicant/README-DPP b/wpa_supplicant/README-DPP
index dcc15f1..457e32e 100644
--- a/wpa_supplicant/README-DPP
+++ b/wpa_supplicant/README-DPP
@@ -28,7 +28,6 @@
Enable DPP and protected management frame in wpa_supplicant build config
file
-CONFIG_IEEE80211W=y
CONFIG_DPP=y
hostapd build config
@@ -36,7 +35,6 @@
Enable DPP and protected management frame in hostapd build config file
-CONFIG_IEEE80211W=y
CONFIG_DPP=y
Configurator build config
@@ -120,7 +118,9 @@
Send provisioning request to enrollee. (conf is ap-dpp if enrollee is an
AP. conf is sta-dpp if enrollee is a client)
-> dpp_auth_init peer=<qr-code-id> conf=<ap-dpp|sta-dpp> configurator=<configurator-id>
+> dpp_auth_init peer=<qr-code-id> conf=<ap-dpp|sta-dpp> ssid=<SSID hexdump> configurator=<configurator-id>
+or for legacy (PSK/SAE) provisioning for a station Enrollee:
+> dpp_auth_init peer=<qr-code-id> conf=sta-psk ssid=<SSID hexdump> pass=<passphrase hexdump>
The DPP values will be printed in the console. Save this values into the
config file. If the enrollee is an AP, we need to manually write these
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index b9b5d9d..ad3af40 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -270,10 +270,6 @@
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
-# IEEE 802.11w (management frame protection), also known as PMF
-# Driver support is also needed for IEEE 802.11w.
-CONFIG_IEEE80211W=y
-
# Support Operating Channel Validation
#CONFIG_OCV=y
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 4e3c281..59ca153 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -381,7 +381,9 @@
else
bss->wpa_key_mgmt = ssid->key_mgmt;
bss->wpa_pairwise = ssid->pairwise_cipher;
- if (ssid->psk_set) {
+ if (wpa_key_mgmt_sae(bss->wpa_key_mgmt) && ssid->passphrase) {
+ bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
+ } else if (ssid->psk_set) {
bin_clear_free(bss->ssid.wpa_psk, sizeof(*bss->ssid.wpa_psk));
bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
if (bss->ssid.wpa_psk == NULL)
@@ -407,6 +409,34 @@
wep->idx = ssid->wep_tx_keyidx;
wep->keys_set = 1;
}
+#ifdef CONFIG_SAE
+ if (ssid->sae_password) {
+ struct sae_password_entry *pw;
+
+ pw = os_zalloc(sizeof(*pw));
+ if (!pw)
+ return -1;
+ os_memset(pw->peer_addr, 0xff, ETH_ALEN);
+ pw->password = os_strdup(ssid->sae_password);
+ if (!pw->password) {
+ os_free(pw);
+ return -1;
+ }
+ if (ssid->sae_password_id) {
+ pw->identifier = os_strdup(ssid->sae_password_id);
+ if (!pw->identifier) {
+ str_clear_free(pw->password);
+ os_free(pw);
+ return -1;
+ }
+ }
+
+ pw->next = bss->sae_passwords;
+ bss->sae_passwords = pw;
+ }
+
+ bss->sae_pwe = wpa_s->conf->sae_pwe;
+#endif /* CONFIG_SAE */
if (wpa_s->conf->go_interworking) {
wpa_printf(MSG_DEBUG,
@@ -500,10 +530,8 @@
bss->wpa_group_rekey = 86400;
}
-#ifdef CONFIG_IEEE80211W
if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
bss->ieee80211w = ssid->ieee80211w;
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_OCV
bss->ocv = ssid->ocv;
@@ -747,6 +775,20 @@
ssid->frequency = 2462; /* default channel 11 */
params.freq.freq = ssid->frequency;
+ if (ssid->mode == WPAS_MODE_AP && ssid->enable_edmg) {
+ u8 primary_channel;
+
+ if (ieee80211_freq_to_chan(ssid->frequency, &primary_channel) ==
+ NUM_HOSTAPD_MODES) {
+ wpa_printf(MSG_WARNING,
+ "EDMG: Failed to get the primary channel");
+ return -1;
+ }
+
+ hostapd_encode_edmg_chan(ssid->enable_edmg, ssid->edmg_channel,
+ primary_channel, ¶ms.freq.edmg);
+ }
+
params.wpa_proto = ssid->proto;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
@@ -885,6 +927,8 @@
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
wpa_s->assoc_freq = ssid->frequency;
+ wpa_s->ap_iface->conf->enable_edmg = ssid->enable_edmg;
+ wpa_s->ap_iface->conf->edmg_channel = ssid->edmg_channel;
#if defined(CONFIG_P2P) && defined(CONFIG_ACS)
if (wpa_s->p2p_go_do_acs) {
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 441529c..943a340 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -1038,23 +1038,30 @@
#ifdef CONFIG_P2P
/**
- * wpa_bss_get_p2p_dev_addr - Fetch a BSS table entry based on P2P Device Addr
+ * wpa_bss_get_p2p_dev_addr - Fetch the latest BSS table entry based on P2P Device Addr
* @wpa_s: Pointer to wpa_supplicant data
* @dev_addr: P2P Device Address of the GO
* Returns: Pointer to the BSS entry or %NULL if not found
+ *
+ * This function tries to find the entry that has the most recent update. This
+ * can help in finding the correct entry in cases where the SSID of the P2P
+ * Device may have changed recently.
*/
struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
const u8 *dev_addr)
{
- struct wpa_bss *bss;
+ struct wpa_bss *bss, *found = NULL;
dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
u8 addr[ETH_ALEN];
if (p2p_parse_dev_addr((const u8 *) (bss + 1), bss->ie_len,
- addr) == 0 &&
- os_memcmp(addr, dev_addr, ETH_ALEN) == 0)
- return bss;
+ addr) != 0 ||
+ os_memcmp(addr, dev_addr, ETH_ALEN) != 0)
+ continue;
+ if (!found ||
+ os_reltime_before(&found->last_update, &bss->last_update))
+ found = bss;
}
- return NULL;
+ return found;
}
#endif /* CONFIG_P2P */
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 2895dc8..d100c46 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / Configuration parser and common functions
- * Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -12,6 +12,7 @@
#include "utils/uuid.h"
#include "utils/ip_addr.h"
#include "common/ieee802_1x_defs.h"
+#include "common/sae.h"
#include "crypto/sha1.h"
#include "rsn_supp/wpa.h"
#include "eap_peer/eap.h"
@@ -740,12 +741,10 @@
val |= WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
#endif /* CONFIG_SHA384 */
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
val |= WPA_KEY_MGMT_PSK_SHA256;
else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WPS
else if (os_strcmp(start, "WPS") == 0)
val |= WPA_KEY_MGMT_WPS;
@@ -910,7 +909,6 @@
#endif /* CONFIG_SHA384 */
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
ret = os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
pos == buf ? "" : " ");
@@ -930,7 +928,6 @@
}
pos += ret;
}
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WPS
if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
@@ -1614,7 +1611,7 @@
#ifdef CONFIG_EXT_PASSWORD
if (os_strncmp(value, "ext:", 4) == 0) {
char *name = os_strdup(value + 4);
- if (name == NULL)
+ if (!name)
return -1;
bin_clear_free(ssid->eap.password, ssid->eap.password_len);
ssid->eap.password = (u8 *) name;
@@ -1630,9 +1627,9 @@
size_t res_len;
tmp = wpa_config_parse_string(value, &res_len);
- if (tmp == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: failed to parse "
- "password.", line);
+ if (!tmp) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: failed to parse password.", line);
return -1;
}
wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
@@ -1650,13 +1647,14 @@
/* NtPasswordHash: hash:<32 hex digits> */
if (os_strlen(value + 5) != 2 * 16) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid password hash length "
- "(expected 32 hex digits)", line);
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid password hash length (expected 32 hex digits)",
+ line);
return -1;
}
hash = os_malloc(16);
- if (hash == NULL)
+ if (!hash)
return -1;
if (hexstr2bin(value + 5, hash, 16)) {
@@ -1683,19 +1681,118 @@
}
+static int wpa_config_parse_machine_password(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ u8 *hash;
+
+ if (os_strcmp(value, "NULL") == 0) {
+ if (!ssid->eap.machine_password)
+ return 1; /* Already unset */
+ wpa_printf(MSG_DEBUG,
+ "Unset configuration string 'machine_password'");
+ bin_clear_free(ssid->eap.machine_password,
+ ssid->eap.machine_password_len);
+ ssid->eap.machine_password = NULL;
+ ssid->eap.machine_password_len = 0;
+ return 0;
+ }
+
+#ifdef CONFIG_EXT_PASSWORD
+ if (os_strncmp(value, "ext:", 4) == 0) {
+ char *name = os_strdup(value + 4);
+
+ if (!name)
+ return -1;
+ bin_clear_free(ssid->eap.machine_password,
+ ssid->eap.machine_password_len);
+ ssid->eap.machine_password = (u8 *) name;
+ ssid->eap.machine_password_len = os_strlen(name);
+ ssid->eap.flags &= ~EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
+ ssid->eap.flags |= EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
+ return 0;
+ }
+#endif /* CONFIG_EXT_PASSWORD */
+
+ if (os_strncmp(value, "hash:", 5) != 0) {
+ char *tmp;
+ size_t res_len;
+
+ tmp = wpa_config_parse_string(value, &res_len);
+ if (!tmp) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: failed to parse machine_password.",
+ line);
+ return -1;
+ }
+ wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
+ (u8 *) tmp, res_len);
+
+ bin_clear_free(ssid->eap.machine_password,
+ ssid->eap.machine_password_len);
+ ssid->eap.machine_password = (u8 *) tmp;
+ ssid->eap.machine_password_len = res_len;
+ ssid->eap.flags &= ~EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
+ ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
+
+ return 0;
+ }
+
+
+ /* NtPasswordHash: hash:<32 hex digits> */
+ if (os_strlen(value + 5) != 2 * 16) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid machine_password hash length (expected 32 hex digits)",
+ line);
+ return -1;
+ }
+
+ hash = os_malloc(16);
+ if (!hash)
+ return -1;
+
+ if (hexstr2bin(value + 5, hash, 16)) {
+ os_free(hash);
+ wpa_printf(MSG_ERROR, "Line %d: Invalid machine_password hash",
+ line);
+ return -1;
+ }
+
+ wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
+
+ if (ssid->eap.machine_password &&
+ ssid->eap.machine_password_len == 16 &&
+ os_memcmp(ssid->eap.machine_password, hash, 16) == 0 &&
+ (ssid->eap.flags & EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH)) {
+ bin_clear_free(hash, 16);
+ return 1;
+ }
+ bin_clear_free(ssid->eap.machine_password,
+ ssid->eap.machine_password_len);
+ ssid->eap.machine_password = hash;
+ ssid->eap.machine_password_len = 16;
+ ssid->eap.flags |= EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
+ ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
+
+ return 0;
+}
+
+
#ifndef NO_CONFIG_WRITE
+
static char * wpa_config_write_password(const struct parse_data *data,
struct wpa_ssid *ssid)
{
char *buf;
- if (ssid->eap.password == NULL)
+ if (!ssid->eap.password)
return NULL;
#ifdef CONFIG_EXT_PASSWORD
if (ssid->eap.flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
buf = os_zalloc(4 + ssid->eap.password_len + 1);
- if (buf == NULL)
+ if (!buf)
return NULL;
os_memcpy(buf, "ext:", 4);
os_memcpy(buf + 4, ssid->eap.password, ssid->eap.password_len);
@@ -1709,7 +1806,7 @@
}
buf = os_malloc(5 + 32 + 1);
- if (buf == NULL)
+ if (!buf)
return NULL;
os_memcpy(buf, "hash:", 5);
@@ -1717,6 +1814,44 @@
return buf;
}
+
+
+static char * wpa_config_write_machine_password(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ char *buf;
+
+ if (!ssid->eap.machine_password)
+ return NULL;
+
+#ifdef CONFIG_EXT_PASSWORD
+ if (ssid->eap.flags & EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD) {
+ buf = os_zalloc(4 + ssid->eap.machine_password_len + 1);
+ if (!buf)
+ return NULL;
+ os_memcpy(buf, "ext:", 4);
+ os_memcpy(buf + 4, ssid->eap.machine_password,
+ ssid->eap.machine_password_len);
+ return buf;
+ }
+#endif /* CONFIG_EXT_PASSWORD */
+
+ if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH)) {
+ return wpa_config_write_string(
+ ssid->eap.machine_password,
+ ssid->eap.machine_password_len);
+ }
+
+ buf = os_malloc(5 + 32 + 1);
+ if (!buf)
+ return NULL;
+
+ os_memcpy(buf, "hash:", 5);
+ wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.machine_password, 16);
+
+ return buf;
+}
+
#endif /* NO_CONFIG_WRITE */
#endif /* IEEE8021X_EAPOL */
@@ -2141,23 +2276,24 @@
/* STR: Define a string variable for an ASCII string; f = field name */
#ifdef NO_CONFIG_WRITE
#define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
-#define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f)
+#define _STRe(f, m) #f, wpa_config_parse_str, OFFSET(eap.m)
#else /* NO_CONFIG_WRITE */
#define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
-#define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f)
+#define _STRe(f, m) #f, wpa_config_parse_str, wpa_config_write_str, \
+ OFFSET(eap.m)
#endif /* NO_CONFIG_WRITE */
#define STR(f) _STR(f), NULL, NULL, NULL, 0
-#define STRe(f) _STRe(f), NULL, NULL, NULL, 0
+#define STRe(f, m) _STRe(f, m), NULL, NULL, NULL, 0
#define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
-#define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1
+#define STR_KEYe(f, m) _STRe(f, m), NULL, NULL, NULL, 1
/* STR_LEN: Define a string variable with a separate variable for storing the
* data length. Unlike STR(), this can be used to store arbitrary binary data
* (i.e., even nul termination character). */
#define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
-#define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len)
+#define _STR_LENe(f, m) _STRe(f, m), OFFSET(eap.m ## _len)
#define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
-#define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0
+#define STR_LENe(f, m) _STR_LENe(f, m), NULL, NULL, 0
#define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
/* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
@@ -2168,17 +2304,17 @@
#ifdef NO_CONFIG_WRITE
#define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
-#define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0
+#define _INTe(f, m) #f, wpa_config_parse_int, OFFSET(eap.m), (void *) 0
#else /* NO_CONFIG_WRITE */
#define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
OFFSET(f), (void *) 0
-#define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \
- OFFSET(eap.f), (void *) 0
+#define _INTe(f, m) #f, wpa_config_parse_int, wpa_config_write_int, \
+ OFFSET(eap.m), (void *) 0
#endif /* NO_CONFIG_WRITE */
/* INT: Define an integer variable */
#define INT(f) _INT(f), NULL, NULL, 0
-#define INTe(f) _INTe(f), NULL, NULL, 0
+#define INTe(f, m) _INTe(f, m), NULL, NULL, 0
/* INT_RANGE: Define an integer variable with allowed value range */
#define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
@@ -2246,51 +2382,74 @@
{ INT(vht_center_freq2) },
#ifdef IEEE8021X_EAPOL
{ FUNC(eap) },
- { STR_LENe(identity) },
- { STR_LENe(anonymous_identity) },
- { STR_LENe(imsi_identity) },
+ { STR_LENe(identity, identity) },
+ { STR_LENe(anonymous_identity, anonymous_identity) },
+ { STR_LENe(imsi_identity, imsi_identity) },
+ { STR_LENe(machine_identity, machine_identity) },
{ FUNC_KEY(password) },
- { STRe(ca_cert) },
- { STRe(ca_path) },
- { STRe(client_cert) },
- { STRe(private_key) },
- { STR_KEYe(private_key_passwd) },
- { STRe(dh_file) },
- { STRe(subject_match) },
- { STRe(check_cert_subject) },
- { STRe(altsubject_match) },
- { STRe(domain_suffix_match) },
- { STRe(domain_match) },
- { STRe(ca_cert2) },
- { STRe(ca_path2) },
- { STRe(client_cert2) },
- { STRe(private_key2) },
- { STR_KEYe(private_key2_passwd) },
- { STRe(dh_file2) },
- { STRe(subject_match2) },
- { STRe(check_cert_subject2) },
- { STRe(altsubject_match2) },
- { STRe(domain_suffix_match2) },
- { STRe(domain_match2) },
- { STRe(phase1) },
- { STRe(phase2) },
- { STRe(pcsc) },
- { STR_KEYe(pin) },
- { STRe(engine_id) },
- { STRe(key_id) },
- { STRe(cert_id) },
- { STRe(ca_cert_id) },
- { STR_KEYe(pin2) },
- { STRe(engine2_id) },
- { STRe(key2_id) },
- { STRe(cert2_id) },
- { STRe(ca_cert2_id) },
- { INTe(engine) },
- { INTe(engine2) },
+ { FUNC_KEY(machine_password) },
+ { STRe(ca_cert, cert.ca_cert) },
+ { STRe(ca_path, cert.ca_path) },
+ { STRe(client_cert, cert.client_cert) },
+ { STRe(private_key, cert.private_key) },
+ { STR_KEYe(private_key_passwd, cert.private_key_passwd) },
+ { STRe(dh_file, cert.dh_file) },
+ { STRe(subject_match, cert.subject_match) },
+ { STRe(check_cert_subject, cert.check_cert_subject) },
+ { STRe(altsubject_match, cert.altsubject_match) },
+ { STRe(domain_suffix_match, cert.domain_suffix_match) },
+ { STRe(domain_match, cert.domain_match) },
+ { STRe(ca_cert2, phase2_cert.ca_cert) },
+ { STRe(ca_path2, phase2_cert.ca_path) },
+ { STRe(client_cert2, phase2_cert.client_cert) },
+ { STRe(private_key2, phase2_cert.private_key) },
+ { STR_KEYe(private_key2_passwd, phase2_cert.private_key_passwd) },
+ { STRe(dh_file2, phase2_cert.dh_file) },
+ { STRe(subject_match2, phase2_cert.subject_match) },
+ { STRe(check_cert_subject2, phase2_cert.check_cert_subject) },
+ { STRe(altsubject_match2, phase2_cert.altsubject_match) },
+ { STRe(domain_suffix_match2, phase2_cert.domain_suffix_match) },
+ { STRe(domain_match2, phase2_cert.domain_match) },
+ { STRe(phase1, phase1) },
+ { STRe(phase2, phase2) },
+ { STRe(machine_phase2, machine_phase2) },
+ { STRe(pcsc, pcsc) },
+ { STR_KEYe(pin, cert.pin) },
+ { STRe(engine_id, cert.engine_id) },
+ { STRe(key_id, cert.key_id) },
+ { STRe(cert_id, cert.cert_id) },
+ { STRe(ca_cert_id, cert.ca_cert_id) },
+ { STR_KEYe(pin2, phase2_cert.pin) },
+ { STRe(engine_id2, phase2_cert.engine_id) },
+ { STRe(key_id2, phase2_cert.key_id) },
+ { STRe(cert_id2, phase2_cert.cert_id) },
+ { STRe(ca_cert_id2, phase2_cert.ca_cert_id) },
+ { INTe(engine, cert.engine) },
+ { INTe(engine2, phase2_cert.engine) },
+ { STRe(machine_ca_cert, machine_cert.ca_cert) },
+ { STRe(machine_ca_path, machine_cert.ca_path) },
+ { STRe(machine_client_cert, machine_cert.client_cert) },
+ { STRe(machine_private_key, machine_cert.private_key) },
+ { STR_KEYe(machine_private_key_passwd,
+ machine_cert.private_key_passwd) },
+ { STRe(machine_dh_file, machine_cert.dh_file) },
+ { STRe(machine_subject_match, machine_cert.subject_match) },
+ { STRe(machine_check_cert_subject, machine_cert.check_cert_subject) },
+ { STRe(machine_altsubject_match, machine_cert.altsubject_match) },
+ { STRe(machine_domain_suffix_match,
+ machine_cert.domain_suffix_match) },
+ { STRe(machine_domain_match, machine_cert.domain_match) },
+ { STR_KEYe(machine_pin, machine_cert.pin) },
+ { STRe(machine_engine_id, machine_cert.engine_id) },
+ { STRe(machine_key_id, machine_cert.key_id) },
+ { STRe(machine_cert_id, machine_cert.cert_id) },
+ { STRe(machine_ca_cert_id, machine_cert.ca_cert_id) },
+ { INTe(machine_engine, machine_cert.engine) },
+ { INTe(machine_ocsp, machine_cert.ocsp) },
{ INT(eapol_flags) },
- { INTe(sim_num) },
- { STRe(openssl_ciphers) },
- { INTe(erp) },
+ { INTe(sim_num, sim_num) },
+ { STRe(openssl_ciphers, openssl_ciphers) },
+ { INTe(erp, erp) },
#endif /* IEEE8021X_EAPOL */
{ FUNC_KEY(wep_key0) },
{ FUNC_KEY(wep_key1) },
@@ -2300,9 +2459,10 @@
{ INT(priority) },
#ifdef IEEE8021X_EAPOL
{ INT(eap_workaround) },
- { STRe(pac_file) },
- { INTe(fragment_size) },
- { INTe(ocsp) },
+ { STRe(pac_file, pac_file) },
+ { INTe(fragment_size, fragment_size) },
+ { INTe(ocsp, cert.ocsp) },
+ { INTe(ocsp2, phase2_cert.ocsp) },
#endif /* IEEE8021X_EAPOL */
#ifdef CONFIG_MESH
{ INT_RANGE(mode, 0, 5) },
@@ -2314,16 +2474,16 @@
{ INT_RANGE(proactive_key_caching, 0, 1) },
{ INT_RANGE(disabled, 0, 2) },
{ STR(id_str) },
-#ifdef CONFIG_IEEE80211W
{ INT_RANGE(ieee80211w, 0, 2) },
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_OCV
{ FUNC(ocv) },
#endif /* CONFIG_OCV */
{ FUNC(peerkey) /* obsolete - removed */ },
{ INT_RANGE(mixed_cell, 0, 1) },
- { INT_RANGE(frequency, 0, 65000) },
+ { INT_RANGE(frequency, 0, 70200) },
{ INT_RANGE(fixed_freq, 0, 1) },
+ { INT_RANGE(enable_edmg, 0, 1) },
+ { INT_RANGE(edmg_channel, 9, 13) },
#ifdef CONFIG_ACS
{ INT_RANGE(acs, 0, 1) },
#endif /* CONFIG_ACS */
@@ -2514,48 +2674,44 @@
#ifdef IEEE8021X_EAPOL
+
+static void eap_peer_config_free_cert(struct eap_peer_cert_config *cert)
+{
+ os_free(cert->ca_cert);
+ os_free(cert->ca_path);
+ os_free(cert->client_cert);
+ os_free(cert->private_key);
+ str_clear_free(cert->private_key_passwd);
+ os_free(cert->dh_file);
+ os_free(cert->subject_match);
+ os_free(cert->check_cert_subject);
+ os_free(cert->altsubject_match);
+ os_free(cert->domain_suffix_match);
+ os_free(cert->domain_match);
+ str_clear_free(cert->pin);
+ os_free(cert->engine_id);
+ os_free(cert->key_id);
+ os_free(cert->cert_id);
+ os_free(cert->ca_cert_id);
+}
+
+
static void eap_peer_config_free(struct eap_peer_config *eap)
{
os_free(eap->eap_methods);
bin_clear_free(eap->identity, eap->identity_len);
os_free(eap->anonymous_identity);
os_free(eap->imsi_identity);
+ os_free(eap->machine_identity);
bin_clear_free(eap->password, eap->password_len);
- os_free(eap->ca_cert);
- os_free(eap->ca_path);
- os_free(eap->client_cert);
- os_free(eap->private_key);
- str_clear_free(eap->private_key_passwd);
- os_free(eap->dh_file);
- os_free(eap->subject_match);
- os_free(eap->check_cert_subject);
- os_free(eap->altsubject_match);
- os_free(eap->domain_suffix_match);
- os_free(eap->domain_match);
- os_free(eap->ca_cert2);
- os_free(eap->ca_path2);
- os_free(eap->client_cert2);
- os_free(eap->private_key2);
- str_clear_free(eap->private_key2_passwd);
- os_free(eap->dh_file2);
- os_free(eap->subject_match2);
- os_free(eap->check_cert_subject2);
- os_free(eap->altsubject_match2);
- os_free(eap->domain_suffix_match2);
- os_free(eap->domain_match2);
+ bin_clear_free(eap->machine_password, eap->machine_password_len);
+ eap_peer_config_free_cert(&eap->cert);
+ eap_peer_config_free_cert(&eap->phase2_cert);
+ eap_peer_config_free_cert(&eap->machine_cert);
os_free(eap->phase1);
os_free(eap->phase2);
+ os_free(eap->machine_phase2);
os_free(eap->pcsc);
- str_clear_free(eap->pin);
- os_free(eap->engine_id);
- os_free(eap->key_id);
- os_free(eap->cert_id);
- os_free(eap->ca_cert_id);
- os_free(eap->key2_id);
- os_free(eap->cert2_id);
- os_free(eap->ca_cert2_id);
- str_clear_free(eap->pin2);
- os_free(eap->engine2_id);
os_free(eap->otp);
os_free(eap->pending_req_otp);
os_free(eap->pac_file);
@@ -2563,6 +2719,7 @@
str_clear_free(eap->external_sim_resp);
os_free(eap->openssl_ciphers);
}
+
#endif /* IEEE8021X_EAPOL */
@@ -2609,6 +2766,9 @@
dl_list_del(&psk->list);
bin_clear_free(psk, sizeof(*psk));
}
+#ifdef CONFIG_SAE
+ sae_deinit_pt(ssid->pt);
+#endif /* CONFIG_SAE */
bin_clear_free(ssid, sizeof(*ssid));
}
@@ -2727,6 +2887,8 @@
#ifdef CONFIG_MBO
os_free(config->non_pref_chan);
#endif /* CONFIG_MBO */
+ os_free(config->dpp_name);
+ os_free(config->dpp_mud_url);
os_free(config);
}
@@ -2901,9 +3063,7 @@
ssid->vht_tx_mcs_nss_8 = -1;
#endif /* CONFIG_VHT_OVERRIDES */
ssid->proactive_key_caching = -1;
-#ifdef CONFIG_IEEE80211W
ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_MACSEC
ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
#endif /* CONFIG_MACSEC */
@@ -2948,6 +3108,15 @@
}
ret = -1;
}
+#ifdef CONFIG_SAE
+ if (os_strcmp(var, "ssid") == 0 ||
+ os_strcmp(var, "psk") == 0 ||
+ os_strcmp(var, "sae_password") == 0 ||
+ os_strcmp(var, "sae_password_id") == 0) {
+ sae_deinit_pt(ssid->pt);
+ ssid->pt = NULL;
+ }
+#endif /* CONFIG_SAE */
break;
}
if (i == NUM_SSID_FIELDS) {
@@ -4827,6 +4996,8 @@
{ INT(okc), 0 },
{ INT(pmf), 0 },
{ FUNC(sae_groups), 0 },
+ { INT_RANGE(sae_pwe, 0, 2), 0 },
+ { INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
{ INT(dtim_period), 0 },
{ INT(beacon_int), 0 },
{ FUNC(ap_vendor_elements), 0 },
@@ -4866,7 +5037,11 @@
{ INT_RANGE(ftm_initiator, 0, 1), 0 },
{ INT(gas_rand_addr_lifetime), 0 },
{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
+#ifdef CONFIG_DPP
{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
+ { STR(dpp_name), 0 },
+ { STR(dpp_mud_url), 0 },
+#endif /* CONFIG_DPP */
{ INT_RANGE(coloc_intf_reporting, 0, 1), 0 },
{ INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
#ifdef CONFIG_WNM
@@ -4987,6 +5162,7 @@
"AC item", line);
return -1;
}
+ return ret;
}
#endif /* CONFIG_AP */
if (line < 0)
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 46ab9ca..922a75e 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1165,6 +1165,19 @@
int *sae_groups;
/**
+ * sae_pwe - SAE mechanism for PWE derivation
+ * 0 = hunting-and-pecking loop only
+ * 1 = hash-to-element only
+ * 2 = both hunting-and-pecking loop and hash-to-element enabled
+ */
+ int sae_pwe;
+
+ /**
+ * sae_pmkid_in_assoc - Whether to include PMKID in SAE Assoc Req
+ */
+ int sae_pmkid_in_assoc;
+
+ /**
* dtim_period - Default DTIM period in Beacon intervals
*
* This parameter can be used to set the default value for network
@@ -1492,6 +1505,16 @@
int dpp_config_processing;
/**
+ * dpp_name - Name for Enrollee's DPP Configuration Request
+ */
+ char *dpp_name;
+
+ /**
+ * dpp_mud_url - MUD URL for Enrollee's DPP Configuration Request
+ */
+ char *dpp_mud_url;
+
+ /**
* coloc_intf_reporting - Colocated interference reporting
*
* dot11CoLocIntfReportingActivated
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 6fc18ba..7651465 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / Configuration backend: text file
- * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -745,9 +745,9 @@
#define STR(t) write_str(f, #t, ssid)
#define INT(t) write_int(f, #t, ssid->t, 0)
-#define INTe(t) write_int(f, #t, ssid->eap.t, 0)
+#define INTe(t, m) write_int(f, #t, ssid->eap.m, 0)
#define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
-#define INT_DEFe(t, def) write_int(f, #t, ssid->eap.t, def)
+#define INT_DEFe(t, m, def) write_int(f, #t, ssid->eap.m, def)
STR(ssid);
INT(scan_ssid);
@@ -774,7 +774,9 @@
STR(identity);
STR(anonymous_identity);
STR(imsi_identity);
+ STR(machine_identity);
STR(password);
+ STR(machine_password);
STR(ca_cert);
STR(ca_path);
STR(client_cert);
@@ -797,8 +799,20 @@
STR(altsubject_match2);
STR(domain_suffix_match2);
STR(domain_match2);
+ STR(machine_ca_cert);
+ STR(machine_ca_path);
+ STR(machine_client_cert);
+ STR(machine_private_key);
+ STR(machine_private_key_passwd);
+ STR(machine_dh_file);
+ STR(machine_subject_match);
+ STR(machine_check_cert_subject);
+ STR(machine_altsubject_match);
+ STR(machine_domain_suffix_match);
+ STR(machine_domain_match);
STR(phase1);
STR(phase2);
+ STR(machine_phase2);
STR(pcsc);
STR(pin);
STR(engine_id);
@@ -810,11 +824,12 @@
STR(engine2_id);
STR(cert2_id);
STR(ca_cert2_id);
- INTe(engine);
- INTe(engine2);
+ INTe(engine, cert.engine);
+ INTe(engine2, phase2_cert.engine);
+ INTe(machine_engine, machine_cert.engine);
INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
STR(openssl_ciphers);
- INTe(erp);
+ INTe(erp, erp);
#endif /* IEEE8021X_EAPOL */
for (i = 0; i < 4; i++)
write_wep_key(f, i, ssid);
@@ -823,13 +838,17 @@
#ifdef IEEE8021X_EAPOL
INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
STR(pac_file);
- INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
- INTe(ocsp);
- INT_DEFe(sim_num, DEFAULT_USER_SELECTED_SIM);
+ INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
+ INTe(ocsp, cert.ocsp);
+ INTe(ocsp2, phase2_cert.ocsp);
+ INTe(machine_ocsp, machine_cert.ocsp);
+ INT_DEFe(sim_num, sim_num, DEFAULT_USER_SELECTED_SIM);
#endif /* IEEE8021X_EAPOL */
INT(mode);
INT(no_auto_peer);
INT(frequency);
+ INT(enable_edmg);
+ INT(edmg_channel);
INT(fixed_freq);
#ifdef CONFIG_ACS
INT(acs);
@@ -846,10 +865,8 @@
INT(pbss);
INT(wps_disabled);
INT(fils_dh_group);
-#ifdef CONFIG_IEEE80211W
write_int(f, "ieee80211w", ssid->ieee80211w,
MGMT_FRAME_PROTECTION_DEFAULT);
-#endif /* CONFIG_IEEE80211W */
STR(id_str);
#ifdef CONFIG_P2P
write_go_p2p_dev_addr(f, ssid);
@@ -1390,6 +1407,13 @@
fprintf(f, "\n");
}
+ if (config->sae_pwe)
+ fprintf(f, "sae_pwe=%d\n", config->sae_pwe);
+
+ if (config->sae_pmkid_in_assoc)
+ fprintf(f, "sae_pmkid_in_assoc=%d\n",
+ config->sae_pmkid_in_assoc);
+
if (config->ap_vendor_elements) {
int i, len = wpabuf_len(config->ap_vendor_elements);
const u8 *p = wpabuf_head_u8(config->ap_vendor_elements);
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 6fd3a01..af8317b 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -47,30 +47,6 @@
u8 p2p;
};
-/**
- * mode - IEEE 802.11 operation mode (Infrastucture/IBSS)
- *
- * 0 = infrastructure (Managed) mode, i.e., associate with an AP.
- *
- * 1 = IBSS (ad-hoc, peer-to-peer)
- *
- * 2 = AP (access point)
- *
- * 3 = P2P Group Owner (can be set in the configuration file)
- *
- * 4 = P2P Group Formation (used internally; not in configuration
- * files)
- *
- * 5 = Mesh
- *
- * Note: IBSS can only be used with key_mgmt NONE (plaintext and static
- * WEP) and WPA-PSK (with proto=RSN). In addition, key_mgmt=WPA-NONE
- * (fixed group key TKIP/CCMP) is available for backwards compatibility,
- * but its use is deprecated. WPA-None requires following network block
- * options: proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or
- * CCMP, but not both), and psk must also be set (either directly or
- * using ASCII passphrase).
- */
enum wpas_mode {
WPAS_MODE_INFRA = 0,
WPAS_MODE_IBSS = 1,
@@ -236,6 +212,8 @@
*/
char *sae_password_id;
+ struct sae_pt *pt;
+
/**
* ext_psk - PSK/passphrase name in external storage
*
@@ -469,7 +447,6 @@
*/
char *id_str;
-#ifdef CONFIG_IEEE80211W
/**
* ieee80211w - Whether management frame protection is enabled
*
@@ -483,7 +460,6 @@
* followed).
*/
enum mfp_options ieee80211w;
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_OCV
/**
@@ -509,6 +485,23 @@
int frequency;
/**
+ * enable_edmg - Enable EDMG feature in STA/AP mode
+ *
+ * This flag is used for enabling the EDMG capability in STA/AP mode.
+ */
+ int enable_edmg;
+
+ /**
+ * edmg_channel - EDMG channel number
+ *
+ * This value is used to configure the EDMG channel bonding feature.
+ * In AP mode it defines the EDMG channel to start the AP on.
+ * in STA mode it defines the EDMG channel to use for connection
+ * (if supported by AP).
+ */
+ u8 edmg_channel;
+
+ /**
* fixed_freq - Use fixed frequency for IBSS
*/
int fixed_freq;
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
index 3ea5c80..0f2a30a 100644
--- a/wpa_supplicant/config_winreg.c
+++ b/wpa_supplicant/config_winreg.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / Configuration backend: Windows registry
- * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -868,9 +868,9 @@
#define STR(t) write_str(netw, #t, ssid)
#define INT(t) write_int(netw, #t, ssid->t, 0)
-#define INTe(t) write_int(netw, #t, ssid->eap.t, 0)
+#define INTe(t, m) write_int(netw, #t, ssid->eap.m, 0)
#define INT_DEF(t, def) write_int(netw, #t, ssid->t, def)
-#define INT_DEFe(t, def) write_int(netw, #t, ssid->eap.t, def)
+#define INT_DEFe(t, m, def) write_int(netw, #t, ssid->eap.m, def)
STR(ssid);
INT(scan_ssid);
@@ -920,8 +920,8 @@
STR(engine2_id);
STR(cert2_id);
STR(ca_cert2_id);
- INTe(engine);
- INTe(engine2);
+ INTe(engine, cert.engine);
+ INTe(engine2, phase2_cert.engine);
INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
#endif /* IEEE8021X_EAPOL */
for (i = 0; i < 4; i++)
@@ -931,16 +931,14 @@
#ifdef IEEE8021X_EAPOL
INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
STR(pac_file);
- INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
+ INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
#endif /* IEEE8021X_EAPOL */
INT(mode);
write_int(netw, "proactive_key_caching", ssid->proactive_key_caching,
-1);
INT(disabled);
-#ifdef CONFIG_IEEE80211W
write_int(netw, "ieee80211w", ssid->ieee80211w,
MGMT_FRAME_PROTECTION_DEFAULT);
-#endif /* CONFIG_IEEE80211W */
STR(id_str);
#ifdef CONFIG_HS20
INT(update_identifier);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 8efc08d..7f8ec4a 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -11,7 +11,6 @@
#include <netinet/ip.h>
#endif /* CONFIG_TESTING_OPTIONS */
-#include <net/ethernet.h>
#include "utils/common.h"
#include "utils/eloop.h"
#include "utils/uuid.h"
@@ -58,6 +57,12 @@
#include "dpp_supplicant.h"
#include "sme.h"
+#ifdef __NetBSD__
+#include <net/if_ether.h>
+#elif !defined(__CYGWIN__) && !defined(CONFIG_NATIVE_WINDOWS)
+#include <net/ethernet.h>
+#endif
+
static int wpa_supplicant_global_iface_list(struct wpa_global *global,
char *buf, int len);
static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
@@ -2654,7 +2659,6 @@
pos += ret;
}
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
pos == start ? "" : "+");
@@ -2669,7 +2673,6 @@
return pos;
pos += ret;
}
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_SUITEB
if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
@@ -2873,6 +2876,15 @@
}
if (bss_is_dmg(bss)) {
const char *s;
+
+ if (get_ie_ext((const u8 *) (bss + 1), bss->ie_len,
+ WLAN_EID_EXT_EDMG_OPERATION)) {
+ ret = os_snprintf(pos, end - pos, "[EDMG]");
+ if (os_snprintf_error(end - pos, ret))
+ return -1;
+ pos += ret;
+ }
+
ret = os_snprintf(pos, end - pos, "[DMG]");
if (os_snprintf_error(end - pos, ret))
return -1;
@@ -5241,10 +5253,8 @@
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
-#ifdef CONFIG_IEEE80211W
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
-#endif /* CONFIG_IEEE80211W */
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
0);
@@ -10624,12 +10634,10 @@
} else if (os_strcmp(buf, "RESEND_ASSOC") == 0) {
if (wpas_ctrl_resend_assoc(wpa_s) < 0)
reply_len = -1;
-#ifdef CONFIG_IEEE80211W
} else if (os_strcmp(buf, "UNPROT_DEAUTH") == 0) {
sme_event_unprot_disconnect(
wpa_s, wpa_s->bssid, NULL,
WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
-#endif /* CONFIG_IEEE80211W */
#endif /* CONFIG_TESTING_OPTIONS */
} else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index fc2fc2e..5e6b522 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -3803,6 +3803,12 @@
NULL,
NULL
},
+ { "MACAddressRandomizationMask", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "a{say}",
+ wpas_dbus_getter_mac_address_randomization_mask,
+ wpas_dbus_setter_mac_address_randomization_mask,
+ NULL
+ },
{ NULL, NULL, NULL, NULL, NULL, NULL }
};
@@ -4791,8 +4797,8 @@
if (!wpa_s->dbus_groupobj_path) {
wpa_printf(MSG_DEBUG,
- "%s: Group object '%s' already unregistered",
- __func__, wpa_s->dbus_groupobj_path);
+ "%s: Group object has already unregistered",
+ __func__);
return;
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 6c36d91..2582092 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -984,8 +984,7 @@
const struct wpa_dbus_property_desc *property_desc,
DBusMessageIter *iter, DBusError *error, void *user_data)
{
- const char *capabilities[10] = { NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL };
+ const char *capabilities[11];
size_t num_items = 0;
#ifdef CONFIG_FILS
struct wpa_global *global = user_data;
@@ -1012,9 +1011,7 @@
#ifdef CONFIG_INTERWORKING
capabilities[num_items++] = "interworking";
#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_IEEE80211W
capabilities[num_items++] = "pmf";
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_MESH
capabilities[num_items++] = "mesh";
#endif /* CONFIG_MESH */
@@ -1030,6 +1027,9 @@
#ifdef CONFIG_SHA384
capabilities[num_items++] = "sha384";
#endif /* CONFIG_SHA384 */
+#ifdef CONFIG_OWE
+ capabilities[num_items++] = "owe";
+#endif /* CONFIG_OWE */
return wpas_dbus_simple_array_property_getter(iter,
DBUS_TYPE_STRING,
@@ -2753,11 +2753,9 @@
goto nomem;
/* TODO: Ensure that driver actually supports sha256 encryption. */
-#ifdef CONFIG_IEEE80211W
if (!wpa_dbus_dict_string_array_add_element(
&iter_array, "wpa-eap-sha256"))
goto nomem;
-#endif /* CONFIG_IEEE80211W */
}
if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
@@ -2771,11 +2769,9 @@
goto nomem;
/* TODO: Ensure that driver actually supports sha256 encryption. */
-#ifdef CONFIG_IEEE80211W
if (!wpa_dbus_dict_string_array_add_element(
&iter_array, "wpa-psk-sha256"))
goto nomem;
-#endif /* CONFIG_IEEE80211W */
}
if ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
@@ -3990,6 +3986,173 @@
/**
+ * wpas_dbus_setter_mac_address_randomization_mask - Set masks used for
+ * MAC address randomization
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Setter for "MACAddressRandomizationMask" property.
+ */
+dbus_bool_t wpas_dbus_setter_mac_address_randomization_mask(
+ const struct wpa_dbus_property_desc *property_desc,
+ DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+ struct wpa_supplicant *wpa_s = user_data;
+ DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
+ const char *key;
+ unsigned int rand_type = 0;
+ const u8 *mask;
+ int mask_len;
+ unsigned int rand_types_to_disable = MAC_ADDR_RAND_ALL;
+
+ dbus_message_iter_recurse(iter, &variant_iter);
+ if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY) {
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
+ return FALSE;
+ }
+ dbus_message_iter_recurse(&variant_iter, &dict_iter);
+ while (dbus_message_iter_get_arg_type(&dict_iter) ==
+ DBUS_TYPE_DICT_ENTRY) {
+ dbus_message_iter_recurse(&dict_iter, &entry_iter);
+ if (dbus_message_iter_get_arg_type(&entry_iter) !=
+ DBUS_TYPE_STRING) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: key not a string", __func__);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic(&entry_iter, &key);
+ dbus_message_iter_next(&entry_iter);
+ if (dbus_message_iter_get_arg_type(&entry_iter) !=
+ DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&entry_iter) !=
+ DBUS_TYPE_BYTE) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: mask was not a byte array",
+ __func__);
+ return FALSE;
+ }
+ dbus_message_iter_recurse(&entry_iter, &array_iter);
+ dbus_message_iter_get_fixed_array(&array_iter, &mask,
+ &mask_len);
+
+ if (os_strcmp(key, "scan") == 0) {
+ rand_type = MAC_ADDR_RAND_SCAN;
+ } else if (os_strcmp(key, "sched_scan") == 0) {
+ rand_type = MAC_ADDR_RAND_SCHED_SCAN;
+ } else if (os_strcmp(key, "pno") == 0) {
+ rand_type = MAC_ADDR_RAND_PNO;
+ } else {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: bad scan type \"%s\"",
+ __func__, key);
+ return FALSE;
+ }
+
+ if (mask_len != ETH_ALEN) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: malformed MAC mask given",
+ __func__);
+ return FALSE;
+ }
+
+ if (wpas_enable_mac_addr_randomization(
+ wpa_s, rand_type, wpa_s->perm_addr, mask)) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: failed to set up MAC address randomization for %s",
+ __func__, key);
+ return FALSE;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "%s: Enabled MAC address randomization for %s with mask: "
+ MACSTR, wpa_s->ifname, key, MAC2STR(mask));
+ rand_types_to_disable &= ~rand_type;
+ dbus_message_iter_next(&dict_iter);
+ }
+
+ if (rand_types_to_disable &&
+ wpas_disable_mac_addr_randomization(wpa_s, rand_types_to_disable)) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: failed to disable MAC address randomization",
+ __func__);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_mac_address_randomization_mask(
+ const struct wpa_dbus_property_desc *property_desc,
+ DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+ struct wpa_supplicant *wpa_s = user_data;
+ DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
+ unsigned int i;
+ u8 mask_buf[ETH_ALEN];
+ /* Read docs on dbus_message_iter_append_fixed_array() for why this
+ * is necessary... */
+ u8 *mask = mask_buf;
+ static const struct {
+ const char *key;
+ unsigned int type;
+ } types[] = {
+ { "scan", MAC_ADDR_RAND_SCAN },
+ { "sched_scan", MAC_ADDR_RAND_SCHED_SCAN },
+ { "pno", MAC_ADDR_RAND_PNO }
+ };
+
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+ "a{say}", &variant_iter) ||
+ !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
+ "{say}", &dict_iter)) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(types); i++) {
+ if (wpas_mac_addr_rand_scan_get_mask(wpa_s, types[i].type,
+ mask))
+ continue;
+
+ if (!dbus_message_iter_open_container(&dict_iter,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry_iter) ||
+ !dbus_message_iter_append_basic(&entry_iter,
+ DBUS_TYPE_STRING,
+ &types[i].key) ||
+ !dbus_message_iter_open_container(&entry_iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_BYTE_AS_STRING,
+ &array_iter) ||
+ !dbus_message_iter_append_fixed_array(&array_iter,
+ DBUS_TYPE_BYTE,
+ &mask,
+ ETH_ALEN) ||
+ !dbus_message_iter_close_container(&entry_iter,
+ &array_iter) ||
+ !dbus_message_iter_close_container(&dict_iter,
+ &entry_iter)) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+ "no memory");
+ return FALSE;
+ }
+ }
+
+ if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
+ !dbus_message_iter_close_container(iter, &variant_iter)) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
* wpas_dbus_getter_sta_address - Return the address of a connected station
* @iter: Pointer to incoming dbus message iter
* @error: Location to store error on failure
@@ -4497,7 +4660,7 @@
DBusMessageIter iter_dict, variant_iter;
const char *group;
const char *pairwise[5]; /* max 5 pairwise ciphers is supported */
- const char *key_mgmt[15]; /* max 15 key managements may be supported */
+ const char *key_mgmt[16]; /* max 16 key managements may be supported */
int n;
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
@@ -4550,6 +4713,10 @@
if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_SAE)
key_mgmt[n++] = "ft-sae";
#endif /* CONFIG_SAE */
+#ifdef CONFIG_OWE
+ if (ie_data->key_mgmt & WPA_KEY_MGMT_OWE)
+ key_mgmt[n++] = "owe";
+#endif /* CONFIG_OWE */
if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
key_mgmt[n++] = "wpa-none";
@@ -4608,11 +4775,9 @@
/* Management group (RSN only) */
if (ie_data->proto == WPA_PROTO_RSN) {
switch (ie_data->mgmt_group_cipher) {
-#ifdef CONFIG_IEEE80211W
case WPA_CIPHER_AES_128_CMAC:
group = "aes128cmac";
break;
-#endif /* CONFIG_IEEE80211W */
default:
group = "";
break;
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index d922ce1..afa26ef 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -177,6 +177,8 @@
DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_module_path);
DECLARE_ACCESSOR(wpas_dbus_getter_blobs);
DECLARE_ACCESSOR(wpas_dbus_getter_stas);
+DECLARE_ACCESSOR(wpas_dbus_getter_mac_address_randomization_mask);
+DECLARE_ACCESSOR(wpas_dbus_setter_mac_address_randomization_mask);
DECLARE_ACCESSOR(wpas_dbus_getter_sta_address);
DECLARE_ACCESSOR(wpas_dbus_getter_sta_aid);
DECLARE_ACCESSOR(wpas_dbus_getter_sta_caps);
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 8cdd885..19715eb 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -40,6 +40,14 @@
}
+static dbus_bool_t no_p2p_mgmt_interface(DBusError *error)
+{
+ dbus_set_error_const(error, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
+ "Could not find P2P mgmt interface");
+ return FALSE;
+}
+
+
/**
* Parses out the mac address from the peer object path.
* @peer_path - object path of the form
@@ -78,6 +86,22 @@
}
+/**
+ * wpas_dbus_error_no_p2p_mgmt_iface - Return a new InterfaceUnknown error
+ * message
+ * @message: Pointer to incoming dbus message this error refers to
+ * Returns: a dbus error message
+ *
+ * Convenience function to create and return an unknown interface error.
+ */
+static DBusMessage * wpas_dbus_error_no_p2p_mgmt_iface(DBusMessage *message)
+{
+ wpa_printf(MSG_DEBUG, "dbus: Could not find P2P mgmt interface");
+ return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
+ "Could not find P2P mgmt interface");
+}
+
+
DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
struct wpa_supplicant *wpa_s)
{
@@ -145,6 +169,10 @@
}
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s) {
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
+ goto error_nop2p;
+ }
if (wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types,
req_dev_types, NULL, 0, 0, NULL, freq))
@@ -157,8 +185,9 @@
error_clear:
wpa_dbus_dict_entry_clear(&entry);
error:
- os_free(req_dev_types);
reply = wpas_dbus_error_invalid_args(message, entry.key);
+error_nop2p:
+ os_free(req_dev_types);
return reply;
}
@@ -166,7 +195,9 @@
DBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message,
struct wpa_supplicant *wpa_s)
{
- wpas_p2p_stop_find(wpa_s->global->p2p_init_wpa_s);
+ wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (wpa_s)
+ wpas_p2p_stop_find(wpa_s);
return NULL;
}
@@ -185,6 +216,8 @@
return wpas_dbus_error_invalid_args(message, NULL);
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s)
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
if (wpas_p2p_reject(wpa_s, peer_addr) < 0)
return wpas_dbus_error_unknown_error(message,
@@ -204,6 +237,8 @@
return wpas_dbus_error_no_memory(message);
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s)
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
if (wpas_p2p_listen(wpa_s, (unsigned int) timeout)) {
return dbus_message_new_error(message,
@@ -245,6 +280,8 @@
}
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s)
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
if (wpas_p2p_ext_listen(wpa_s, period, interval))
return wpas_dbus_error_unknown_error(
@@ -350,6 +387,10 @@
}
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s) {
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
+ goto out;
+ }
if (pg_object_path != NULL) {
char *net_id_str;
@@ -433,6 +474,12 @@
"P2P is not available for this interface");
return FALSE;
}
+ if (!wpa_s->global->p2p_init_wpa_s) {
+ if (out_reply)
+ *out_reply = wpas_dbus_error_no_p2p_mgmt_iface(
+ message);
+ return no_p2p_mgmt_interface(error);
+ }
return TRUE;
}
@@ -822,6 +869,8 @@
return wpas_dbus_error_invalid_args(message, NULL);
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s)
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method,
WPAS_P2P_PD_FOR_GO_NEG, NULL) < 0)
@@ -1882,6 +1931,8 @@
wpa_s = peer_args->wpa_s;
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s)
+ return no_p2p_mgmt_interface(error);
wpa_s_go = wpas_get_p2p_client_iface(wpa_s, info->p2p_device_addr);
if (wpa_s_go) {
@@ -1963,6 +2014,9 @@
dbus_bool_t success = FALSE;
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s)
+ return no_p2p_mgmt_interface(error);
+
if (!wpa_s->parent->dbus_new_path)
return FALSE;
@@ -2077,6 +2131,11 @@
dbus_message_iter_init(message, &iter);
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s) {
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
+ goto err;
+ }
+
if (wpa_s->parent->dbus_new_path)
ssid = wpa_config_add_network(wpa_s->conf);
if (ssid == NULL) {
@@ -2159,6 +2218,10 @@
DBUS_TYPE_INVALID);
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s) {
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
+ goto out;
+ }
/*
* Extract the network ID and ensure the network is actually a child of
@@ -2235,6 +2298,8 @@
struct wpa_config *config;
wpa_s = wpa_s->global->p2p_init_wpa_s;
+ if (!wpa_s)
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
config = wpa_s->conf;
ssid = config->ssid;
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c
index d80e2d4..d9009ba 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.c
+++ b/wpa_supplicant/dbus/dbus_new_helpers.c
@@ -742,7 +742,7 @@
DBusConnection *con = eloop_ctx;
struct wpa_dbus_object_desc *obj_desc = timeout_ctx;
- wpa_printf(MSG_DEBUG,
+ wpa_printf(MSG_MSGDUMP,
"dbus: %s: Timeout - sending changed properties of object %s",
__func__, obj_desc->path);
wpa_dbus_flush_object_changed_properties(con, obj_desc->path);
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index cdfb197..792ab24 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -310,10 +310,6 @@
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
-# IEEE 802.11w (management frame protection), also known as PMF
-# Driver support is also needed for IEEE 802.11w.
-CONFIG_IEEE80211W=y
-
# Support Operating Channel Validation
#CONFIG_OCV=y
@@ -366,7 +362,7 @@
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
# Add support for new DBus control interface
-# (fi.w1.hostap.wpa_supplicant1)
+# (fi.w1.wpa_supplicant1)
CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
@@ -610,6 +606,4 @@
#CONFIG_OWE=y
# Device Provisioning Protocol (DPP)
-# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
-# wpa_supplicant/README-DPP for details)
CONFIG_DPP=y
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index 30ef5db..ff30e9a 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -149,6 +149,8 @@
static void wpas_dpp_try_to_connect(struct wpa_supplicant *wpa_s)
{
wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
+ wpa_s->suitable_network = 0;
+ wpa_s->no_suitable_network = 0;
wpa_s->disconnected = 0;
wpa_s->reassociate = 1;
wpa_s->scan_runs = 0;
@@ -158,6 +160,141 @@
}
+#ifdef CONFIG_DPP2
+
+static void wpas_dpp_conn_status_result_timeout(void *eloop_ctx,
+ void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+ enum dpp_status_error result;
+
+ if (!auth || !auth->conn_status_requested)
+ return;
+
+ wpa_printf(MSG_DEBUG,
+ "DPP: Connection timeout - report Connection Status Result");
+ if (wpa_s->suitable_network)
+ result = DPP_STATUS_AUTH_FAILURE;
+ else if (wpa_s->no_suitable_network)
+ result = DPP_STATUS_NO_AP;
+ else
+ result = 255; /* What to report here for unexpected state? */
+ wpas_dpp_send_conn_status_result(wpa_s, result);
+}
+
+
+static char * wpas_dpp_scan_channel_list(struct wpa_supplicant *wpa_s)
+{
+ char *str, *end, *pos;
+ size_t len;
+ unsigned int i;
+ u8 last_op_class = 0;
+ int res;
+
+ if (!wpa_s->last_scan_freqs || !wpa_s->num_last_scan_freqs)
+ return NULL;
+
+ len = wpa_s->num_last_scan_freqs * 8;
+ str = os_zalloc(len);
+ if (!str)
+ return NULL;
+ end = str + len;
+ pos = str;
+
+ for (i = 0; i < wpa_s->num_last_scan_freqs; i++) {
+ enum hostapd_hw_mode mode;
+ u8 op_class, channel;
+
+ mode = ieee80211_freq_to_channel_ext(wpa_s->last_scan_freqs[i],
+ 0, 0, &op_class, &channel);
+ if (mode == NUM_HOSTAPD_MODES)
+ continue;
+ if (op_class == last_op_class)
+ res = os_snprintf(pos, end - pos, ",%d", channel);
+ else
+ res = os_snprintf(pos, end - pos, "%s%d/%d",
+ pos == str ? "" : ",",
+ op_class, channel);
+ if (os_snprintf_error(end - pos, res)) {
+ *pos = '\0';
+ break;
+ }
+ pos += res;
+ last_op_class = op_class;
+ }
+
+ if (pos == str) {
+ os_free(str);
+ str = NULL;
+ }
+ return str;
+}
+
+
+void wpas_dpp_send_conn_status_result(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{
+ struct wpabuf *msg;
+ const char *channel_list = NULL;
+ char *channel_list_buf = NULL;
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+ eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout, wpa_s, NULL);
+
+ if (!auth || !auth->conn_status_requested)
+ return;
+ auth->conn_status_requested = 0;
+ wpa_printf(MSG_DEBUG, "DPP: Report connection status result %d",
+ result);
+
+ if (result == DPP_STATUS_NO_AP) {
+ channel_list_buf = wpas_dpp_scan_channel_list(wpa_s);
+ channel_list = channel_list_buf;
+ }
+
+ msg = dpp_build_conn_status_result(auth, result,
+ ssid ? ssid->ssid :
+ wpa_s->dpp_last_ssid,
+ ssid ? ssid->ssid_len :
+ wpa_s->dpp_last_ssid_len,
+ channel_list);
+ os_free(channel_list_buf);
+ if (!msg) {
+ dpp_auth_deinit(wpa_s->dpp_auth);
+ wpa_s->dpp_auth = NULL;
+ return;
+ }
+
+ wpa_msg(wpa_s, MSG_INFO,
+ DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
+ MAC2STR(auth->peer_mac_addr), auth->curr_freq,
+ DPP_PA_CONNECTION_STATUS_RESULT);
+ offchannel_send_action(wpa_s, auth->curr_freq,
+ auth->peer_mac_addr, wpa_s->own_addr, broadcast,
+ wpabuf_head(msg), wpabuf_len(msg),
+ 500, wpas_dpp_tx_status, 0);
+ wpabuf_free(msg);
+
+ /* This exchange will be terminated in the TX status handler */
+ auth->remove_on_tx_status = 1;
+
+ return;
+}
+
+
+void wpas_dpp_connected(struct wpa_supplicant *wpa_s)
+{
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+ if (auth && auth->conn_status_requested)
+ wpas_dpp_send_conn_status_result(wpa_s, DPP_STATUS_OK);
+}
+
+#endif /* CONFIG_DPP2 */
+
+
static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
unsigned int freq, const u8 *dst,
const u8 *src, const u8 *bssid,
@@ -183,18 +320,30 @@
#ifdef CONFIG_DPP2
if (auth->connect_on_tx_status) {
+ auth->connect_on_tx_status = 0;
wpa_printf(MSG_DEBUG,
"DPP: Try to connect after completed configuration result");
wpas_dpp_try_to_connect(wpa_s);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
+ if (auth->conn_status_requested) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: Start 15 second timeout for reporting connection status result");
+ eloop_cancel_timeout(
+ wpas_dpp_conn_status_result_timeout,
+ wpa_s, NULL);
+ eloop_register_timeout(
+ 15, 0, wpas_dpp_conn_status_result_timeout,
+ wpa_s, NULL);
+ } else {
+ dpp_auth_deinit(wpa_s->dpp_auth);
+ wpa_s->dpp_auth = NULL;
+ }
return;
}
#endif /* CONFIG_DPP2 */
if (wpa_s->dpp_auth->remove_on_tx_status) {
wpa_printf(MSG_DEBUG,
- "DPP: Terminate authentication exchange due to an earlier error");
+ "DPP: Terminate authentication exchange due to a request to do so on TX status");
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
@@ -812,12 +961,13 @@
static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth)
+ struct dpp_authentication *auth,
+ struct dpp_config_obj *conf)
{
struct wpa_ssid *ssid;
#ifdef CONFIG_DPP2
- if (auth->akm == DPP_AKM_SAE) {
+ if (conf->akm == DPP_AKM_SAE) {
#ifdef CONFIG_SAE
struct wpa_driver_capa capa;
int res;
@@ -844,27 +994,27 @@
wpa_config_set_network_defaults(ssid);
ssid->disabled = 1;
- ssid->ssid = os_malloc(auth->ssid_len);
+ ssid->ssid = os_malloc(conf->ssid_len);
if (!ssid->ssid)
goto fail;
- os_memcpy(ssid->ssid, auth->ssid, auth->ssid_len);
- ssid->ssid_len = auth->ssid_len;
+ os_memcpy(ssid->ssid, conf->ssid, conf->ssid_len);
+ ssid->ssid_len = conf->ssid_len;
- if (auth->connector) {
+ if (conf->connector) {
ssid->key_mgmt = WPA_KEY_MGMT_DPP;
ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
- ssid->dpp_connector = os_strdup(auth->connector);
+ ssid->dpp_connector = os_strdup(conf->connector);
if (!ssid->dpp_connector)
goto fail;
}
- if (auth->c_sign_key) {
- ssid->dpp_csign = os_malloc(wpabuf_len(auth->c_sign_key));
+ if (conf->c_sign_key) {
+ ssid->dpp_csign = os_malloc(wpabuf_len(conf->c_sign_key));
if (!ssid->dpp_csign)
goto fail;
- os_memcpy(ssid->dpp_csign, wpabuf_head(auth->c_sign_key),
- wpabuf_len(auth->c_sign_key));
- ssid->dpp_csign_len = wpabuf_len(auth->c_sign_key);
+ os_memcpy(ssid->dpp_csign, wpabuf_head(conf->c_sign_key),
+ wpabuf_len(conf->c_sign_key));
+ ssid->dpp_csign_len = wpabuf_len(conf->c_sign_key);
}
if (auth->net_access_key) {
@@ -879,29 +1029,32 @@
ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry;
}
- if (!auth->connector || dpp_akm_psk(auth->akm) ||
- dpp_akm_sae(auth->akm)) {
- if (!auth->connector)
+ if (!conf->connector || dpp_akm_psk(conf->akm) ||
+ dpp_akm_sae(conf->akm)) {
+ if (!conf->connector)
ssid->key_mgmt = 0;
- if (dpp_akm_psk(auth->akm))
+ if (dpp_akm_psk(conf->akm))
ssid->key_mgmt |= WPA_KEY_MGMT_PSK |
WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK;
- if (dpp_akm_sae(auth->akm))
+ if (dpp_akm_sae(conf->akm))
ssid->key_mgmt |= WPA_KEY_MGMT_SAE |
WPA_KEY_MGMT_FT_SAE;
ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
- if (auth->passphrase[0]) {
+ if (conf->passphrase[0]) {
if (wpa_config_set_quoted(ssid, "psk",
- auth->passphrase) < 0)
+ conf->passphrase) < 0)
goto fail;
wpa_config_update_psk(ssid);
ssid->export_keys = 1;
} else {
- ssid->psk_set = auth->psk_set;
- os_memcpy(ssid->psk, auth->psk, PMK_LEN);
+ ssid->psk_set = conf->psk_set;
+ os_memcpy(ssid->psk, conf->psk, PMK_LEN);
}
}
+ os_memcpy(wpa_s->dpp_last_ssid, conf->ssid, conf->ssid_len);
+ wpa_s->dpp_last_ssid_len = conf->ssid_len;
+
return ssid;
fail:
wpas_notify_network_removed(wpa_s, ssid);
@@ -911,14 +1064,15 @@
static int wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth)
+ struct dpp_authentication *auth,
+ struct dpp_config_obj *conf)
{
struct wpa_ssid *ssid;
if (wpa_s->conf->dpp_config_processing < 1)
return 0;
- ssid = wpas_dpp_add_network(wpa_s, auth);
+ ssid = wpas_dpp_add_network(wpa_s, auth, conf);
if (!ssid)
return -1;
@@ -935,49 +1089,56 @@
wpa_printf(MSG_DEBUG, "DPP: Failed to update configuration");
#endif /* CONFIG_NO_CONFIG_WRITE */
+ return 0;
+}
+
+
+static void wpas_dpp_post_process_config(struct wpa_supplicant *wpa_s,
+ struct dpp_authentication *auth)
+{
if (wpa_s->conf->dpp_config_processing < 2)
- return 0;
+ return;
#ifdef CONFIG_DPP2
if (auth->peer_version >= 2) {
wpa_printf(MSG_DEBUG,
"DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
auth->connect_on_tx_status = 1;
- return 0;
+ return;
}
#endif /* CONFIG_DPP2 */
wpas_dpp_try_to_connect(wpa_s);
- return 0;
}
static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth)
+ struct dpp_authentication *auth,
+ struct dpp_config_obj *conf)
{
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
- if (auth->ssid_len)
+ if (conf->ssid_len)
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
- wpa_ssid_txt(auth->ssid, auth->ssid_len));
- if (auth->connector) {
+ wpa_ssid_txt(conf->ssid, conf->ssid_len));
+ if (conf->connector) {
/* TODO: Save the Connector and consider using a command
* to fetch the value instead of sending an event with
* it. The Connector could end up being larger than what
* most clients are ready to receive as an event
* message. */
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
- auth->connector);
+ conf->connector);
}
- if (auth->c_sign_key) {
+ if (conf->c_sign_key) {
char *hex;
size_t hexlen;
- hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1;
+ hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
hex = os_malloc(hexlen);
if (hex) {
wpa_snprintf_hex(hex, hexlen,
- wpabuf_head(auth->c_sign_key),
- wpabuf_len(auth->c_sign_key));
+ wpabuf_head(conf->c_sign_key),
+ wpabuf_len(conf->c_sign_key));
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_C_SIGN_KEY "%s",
hex);
os_free(hex);
@@ -1005,7 +1166,7 @@
}
}
- return wpas_dpp_process_config(wpa_s, auth);
+ return wpas_dpp_process_config(wpa_s, auth, conf);
}
@@ -1019,6 +1180,7 @@
struct dpp_authentication *auth = wpa_s->dpp_auth;
int res;
enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
+ unsigned int i;
wpa_s->dpp_gas_dialog_token = -1;
@@ -1056,9 +1218,14 @@
goto fail;
}
- res = wpas_dpp_handle_config_obj(wpa_s, auth);
- if (res < 0)
- goto fail;
+ for (i = 0; i < auth->num_conf_obj; i++) {
+ res = wpas_dpp_handle_config_obj(wpa_s, auth,
+ &auth->conf_obj[i]);
+ if (res < 0)
+ goto fail;
+ }
+ if (auth->num_conf_obj)
+ wpas_dpp_post_process_config(wpa_s, auth);
status = DPP_STATUS_OK;
#ifdef CONFIG_TESTING_OPTIONS
@@ -1107,27 +1274,19 @@
{
struct dpp_authentication *auth = wpa_s->dpp_auth;
struct wpabuf *buf;
- char json[100];
int res;
+ int *supp_op_classes;
wpa_s->dpp_gas_client = 1;
- os_snprintf(json, sizeof(json),
- "{\"name\":\"Test\","
- "\"wi-fi_tech\":\"infra\","
- "\"netRole\":\"%s\"}",
- wpa_s->dpp_netrole_ap ? "ap" : "sta");
-#ifdef CONFIG_TESTING_OPTIONS
- if (dpp_test == DPP_TEST_INVALID_CONFIG_ATTR_OBJ_CONF_REQ) {
- wpa_printf(MSG_INFO, "DPP: TESTING - invalid Config Attr");
- json[29] = 'k'; /* replace "infra" with "knfra" */
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json);
-
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
- buf = dpp_build_conf_req(auth, json);
+ supp_op_classes = wpas_supp_op_classes(wpa_s);
+ buf = dpp_build_conf_req_helper(auth, wpa_s->conf->dpp_name,
+ wpa_s->dpp_netrole_ap,
+ wpa_s->conf->dpp_mud_url,
+ supp_op_classes);
+ os_free(supp_op_classes);
if (!buf) {
wpa_printf(MSG_DEBUG,
"DPP: No configuration request data available");
@@ -1281,6 +1440,24 @@
}
+static void wpas_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
+ void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+ if (!auth || !auth->waiting_conn_status_result)
+ return;
+
+ wpa_printf(MSG_DEBUG,
+ "DPP: Timeout while waiting for Connection Status Result");
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT "timeout");
+ wpas_dpp_listen_stop(wpa_s);
+ dpp_auth_deinit(auth);
+ wpa_s->dpp_auth = NULL;
+}
+
+
static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
const u8 *hdr, const u8 *buf, size_t len)
{
@@ -1304,6 +1481,23 @@
status = dpp_conf_result_rx(auth, hdr, buf, len);
+ if (status == DPP_STATUS_OK && auth->send_conn_status) {
+ wpa_msg(wpa_s, MSG_INFO,
+ DPP_EVENT_CONF_SENT "wait_conn_status=1");
+ wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
+ eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout,
+ wpa_s, NULL);
+ auth->waiting_conn_status_result = 1;
+ eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
+ wpa_s, NULL);
+ eloop_register_timeout(16, 0,
+ wpas_dpp_conn_status_result_wait_timeout,
+ wpa_s, NULL);
+ offchannel_send_action_done(wpa_s);
+ wpas_dpp_listen_start(wpa_s, auth->neg_freq ? auth->neg_freq :
+ auth->curr_freq);
+ return;
+ }
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
if (status == DPP_STATUS_OK)
@@ -1316,12 +1510,57 @@
}
+static void wpas_dpp_rx_conn_status_result(struct wpa_supplicant *wpa_s,
+ const u8 *src, const u8 *hdr,
+ const u8 *buf, size_t len)
+{
+ struct dpp_authentication *auth = wpa_s->dpp_auth;
+ enum dpp_status_error status;
+ u8 ssid[SSID_MAX_LEN];
+ size_t ssid_len = 0;
+ char *channel_list = NULL;
+
+ wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
+
+ if (!auth || !auth->waiting_conn_status_result) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: No DPP Configuration waiting for connection status result - drop");
+ return;
+ }
+
+ status = dpp_conn_status_result_rx(auth, hdr, buf, len,
+ ssid, &ssid_len, &channel_list);
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
+ "result=%d ssid=%s channel_list=%s",
+ status, wpa_ssid_txt(ssid, ssid_len),
+ channel_list ? channel_list : "N/A");
+ os_free(channel_list);
+ offchannel_send_action_done(wpa_s);
+ wpas_dpp_listen_stop(wpa_s);
+ dpp_auth_deinit(auth);
+ wpa_s->dpp_auth = NULL;
+ eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
+ wpa_s, NULL);
+}
+
+
static int wpas_dpp_process_conf_obj(void *ctx,
struct dpp_authentication *auth)
{
struct wpa_supplicant *wpa_s = ctx;
+ unsigned int i;
+ int res = -1;
- return wpas_dpp_handle_config_obj(wpa_s, auth);
+ for (i = 0; i < auth->num_conf_obj; i++) {
+ res = wpas_dpp_handle_config_obj(wpa_s, auth,
+ &auth->conf_obj[i]);
+ if (res)
+ break;
+ }
+ if (!res)
+ wpas_dpp_post_process_config(wpa_s, auth);
+
+ return res;
}
#endif /* CONFIG_DPP2 */
@@ -1394,6 +1633,9 @@
status[0]);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" status=%u", MAC2STR(src), status[0]);
+#ifdef CONFIG_DPP2
+ wpas_dpp_send_conn_status_result(wpa_s, status[0]);
+#endif /* CONFIG_DPP2 */
goto fail;
}
@@ -1417,6 +1659,9 @@
"DPP: Network Introduction protocol resulted in failure");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" fail=peer_connector_validation_failed", MAC2STR(src));
+#ifdef CONFIG_DPP2
+ wpas_dpp_send_conn_status_result(wpa_s, res);
+#endif /* CONFIG_DPP2 */
goto fail;
}
@@ -1859,6 +2104,9 @@
case DPP_PA_CONFIGURATION_RESULT:
wpas_dpp_rx_conf_result(wpa_s, src, hdr, buf, len);
break;
+ case DPP_PA_CONNECTION_STATUS_RESULT:
+ wpas_dpp_rx_conn_status_result(wpa_s, src, hdr, buf, len);
+ break;
#endif /* CONFIG_DPP2 */
default:
wpa_printf(MSG_DEBUG,
@@ -1894,6 +2142,18 @@
wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
return NULL;
}
+
+ if (wpa_s->dpp_auth_ok_on_ack && auth->configurator) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
+ /* wpas_dpp_auth_success() would normally have been called from
+ * TX status handler, but since there was no such handler call
+ * yet, simply send out the event message and proceed with
+ * exchange. */
+ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=1");
+ wpa_s->dpp_auth_ok_on_ack = 0;
+ }
+
wpa_hexdump(MSG_DEBUG,
"DPP: Received Configuration Request (GAS Query Request)",
query, query_len);
@@ -1976,7 +2236,10 @@
wpas_dpp_set_testing_options(wpa_s, auth);
if (dpp_set_configurator(wpa_s->dpp, wpa_s, auth, cmd) == 0 &&
dpp_configurator_own_config(auth, curve, 0) == 0)
- ret = wpas_dpp_handle_config_obj(wpa_s, auth);
+ ret = wpas_dpp_handle_config_obj(wpa_s, auth,
+ &auth->conf_obj[0]);
+ if (!ret)
+ wpas_dpp_post_process_config(wpa_s, auth);
dpp_auth_deinit(auth);
os_free(curve);
@@ -2299,6 +2562,9 @@
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
#ifdef CONFIG_DPP2
eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
+ eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
+ wpa_s, NULL);
+ eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout, wpa_s, NULL);
dpp_pfs_free(wpa_s->dpp_pfs);
wpa_s->dpp_pfs = NULL;
#endif /* CONFIG_DPP2 */
diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h
index 9ba315f..b337982 100644
--- a/wpa_supplicant/dpp_supplicant.h
+++ b/wpa_supplicant/dpp_supplicant.h
@@ -1,6 +1,7 @@
/*
* wpa_supplicant - DPP
* Copyright (c) 2017, Qualcomm Atheros, Inc.
+ * Copyright (c) 2018-2019, The Linux Foundation
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -9,6 +10,8 @@
#ifndef DPP_SUPPLICANT_H
#define DPP_SUPPLICANT_H
+enum dpp_status_error;
+
int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd);
int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd);
int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd);
@@ -26,5 +29,8 @@
int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
struct wpa_bss *bss);
int wpas_dpp_controller_start(struct wpa_supplicant *wpa_s, const char *cmd);
+void wpas_dpp_connected(struct wpa_supplicant *wpa_s);
+void wpas_dpp_send_conn_status_result(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result);
#endif /* DPP_SUPPLICANT_H */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 471fc17..139402e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -316,8 +316,9 @@
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
wpa_s->key_mgmt == WPA_KEY_MGMT_OWE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_DPP)
+ wpa_s->key_mgmt == WPA_KEY_MGMT_DPP || wpa_s->drv_authorized_port)
eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
+ wpa_s->drv_authorized_port = 0;
wpa_s->ap_ies_from_associnfo = 0;
wpa_s->current_ssid = NULL;
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
@@ -326,6 +327,7 @@
wpas_rrm_reset(wpa_s);
wpa_s->wnmsleep_used = 0;
wnm_clear_coloc_intf_reporting(wpa_s);
+ wpa_s->disable_mbo_oce = 0;
#ifdef CONFIG_TESTING_OPTIONS
wpa_s->last_tk_alg = WPA_ALG_NONE;
@@ -611,7 +613,6 @@
break;
}
-#ifdef CONFIG_IEEE80211W
if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
wpas_get_ssid_pmf(wpa_s, ssid) ==
MGMT_FRAME_PROTECTION_REQUIRED) {
@@ -620,7 +621,6 @@
" skip RSN IE - no mgmt frame protection");
break;
}
-#endif /* CONFIG_IEEE80211W */
if ((ie.capabilities & WPA_CAPABILITY_MFPR) &&
wpas_get_ssid_pmf(wpa_s, ssid) ==
NO_MGMT_FRAME_PROTECTION) {
@@ -629,17 +629,6 @@
" skip RSN IE - no mgmt frame protection enabled but AP requires it");
break;
}
-#ifdef CONFIG_MBO
- if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
- wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND) &&
- wpas_get_ssid_pmf(wpa_s, ssid) !=
- NO_MGMT_FRAME_PROTECTION) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - no mgmt frame protection enabled on MBO AP");
- break;
- }
-#endif /* CONFIG_MBO */
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG,
@@ -647,7 +636,6 @@
return 1;
}
-#ifdef CONFIG_IEEE80211W
if (wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED &&
(!(ssid->key_mgmt & WPA_KEY_MGMT_OWE) || ssid->owe_only)) {
if (debug_print)
@@ -655,7 +643,6 @@
" skip - MFP Required but network not MFP Capable");
return 0;
}
-#endif /* CONFIG_IEEE80211W */
wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
@@ -863,6 +850,19 @@
continue;
}
+#ifdef CONFIG_SAE
+ if (flagged && ((rate_ie[j] & 0x7f) ==
+ BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY)) {
+ if (wpa_s->conf->sae_pwe == 0) {
+ if (debug_print)
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ " SAE H2E disabled");
+ return 0;
+ }
+ continue;
+ }
+#endif /* CONFIG_SAE */
+
if (!flagged)
continue;
@@ -1262,6 +1262,19 @@
continue;
}
+#ifdef CONFIG_SAE
+ if (wpa_s->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(ssid->key_mgmt) &&
+ (!(ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX)) ||
+ ie[1] < 1 ||
+ !(ie[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E)))) {
+ if (debug_print)
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ " skip - SAE H2E required, but not supported by the AP");
+ continue;
+ }
+#endif /* CONFIG_SAE */
+
#ifndef CONFIG_IBSS_RSN
if (ssid->mode == WPAS_MODE_IBSS &&
!(ssid->key_mgmt & (WPA_KEY_MGMT_NONE |
@@ -1937,6 +1950,21 @@
radio_work_done(work);
}
+ os_free(wpa_s->last_scan_freqs);
+ wpa_s->last_scan_freqs = NULL;
+ wpa_s->num_last_scan_freqs = 0;
+ if (own_request && data &&
+ data->scan_info.freqs && data->scan_info.num_freqs) {
+ wpa_s->last_scan_freqs = os_malloc(sizeof(int) *
+ data->scan_info.num_freqs);
+ if (wpa_s->last_scan_freqs) {
+ os_memcpy(wpa_s->last_scan_freqs,
+ data->scan_info.freqs,
+ sizeof(int) * data->scan_info.num_freqs);
+ wpa_s->num_last_scan_freqs = data->scan_info.num_freqs;
+ }
+ }
+
return wpas_select_network_from_last_scan(wpa_s, 1, own_request);
scan_work_done:
@@ -1990,6 +2018,8 @@
return 0;
}
+ wpa_s->suitable_network++;
+
if (ssid != wpa_s->current_ssid &&
wpa_s->wpa_state >= WPA_AUTHENTICATING) {
wpa_s->own_disconnect_req = 1;
@@ -2010,6 +2040,7 @@
*/
return 1;
} else {
+ wpa_s->no_suitable_network++;
wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
ssid = wpa_supplicant_pick_new_network(wpa_s);
if (ssid) {
@@ -2380,7 +2411,7 @@
static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
union wpa_event_data *data)
{
- int l, len, found = 0, wpa_found, rsn_found;
+ int l, len, found = 0, found_x = 0, wpa_found, rsn_found;
const u8 *p;
#if defined(CONFIG_IEEE80211R) || defined(CONFIG_OWE)
u8 bssid[ETH_ALEN];
@@ -2452,22 +2483,29 @@
p, l);
break;
}
- if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
- (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
- (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
- (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
- (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
+ if (!found &&
+ ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
+ (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
+ (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
+ (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
+ (p[0] == WLAN_EID_RSN && p[1] >= 2))) {
if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
break;
found = 1;
wpa_find_assoc_pmkid(wpa_s);
- break;
+ }
+ if (!found_x && p[0] == WLAN_EID_RSNX) {
+ if (wpa_sm_set_assoc_rsnxe(wpa_s->wpa, p, len))
+ break;
+ found_x = 1;
}
l -= len;
p += len;
}
if (!found && data->assoc_info.req_ies)
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+ if (!found_x && data->assoc_info.req_ies)
+ wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
#ifdef CONFIG_FILS
#ifdef CONFIG_SME
@@ -2629,14 +2667,19 @@
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
}
+ if (p[0] == WLAN_EID_RSNX && p[1] >= 1)
+ wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len);
+
l -= len;
p += len;
}
if (!wpa_found && data->assoc_info.beacon_ies)
wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
- if (!rsn_found && data->assoc_info.beacon_ies)
+ if (!rsn_found && data->assoc_info.beacon_ies) {
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
+ wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0);
+ }
if (wpa_found || rsn_found)
wpa_s->ap_ies_from_associnfo = 1;
@@ -2656,7 +2699,7 @@
static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
{
- const u8 *bss_wpa = NULL, *bss_rsn = NULL;
+ const u8 *bss_wpa = NULL, *bss_rsn = NULL, *bss_rsnx = NULL;
if (!wpa_s->current_bss || !wpa_s->current_ssid)
return -1;
@@ -2667,11 +2710,14 @@
bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss,
WPA_IE_VENDOR_TYPE);
bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN);
+ bss_rsnx = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSNX);
if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
bss_wpa ? 2 + bss_wpa[1] : 0) ||
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
- bss_rsn ? 2 + bss_rsn[1] : 0))
+ bss_rsn ? 2 + bss_rsn[1] : 0) ||
+ wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx,
+ bss_rsnx ? 2 + bss_rsnx[1] : 0))
return -1;
return 0;
@@ -2723,6 +2769,9 @@
u8 bssid[ETH_ALEN];
int ft_completed, already_authorized;
int new_bss = 0;
+#if defined(CONFIG_FILS) || defined(CONFIG_MBO)
+ struct wpa_bss *bss;
+#endif /* CONFIG_FILS || CONFIG_MBO */
#ifdef CONFIG_AP
if (wpa_s->ap_iface) {
@@ -2831,7 +2880,7 @@
if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
wpa_s->key_mgmt == WPA_KEY_MGMT_DPP ||
wpa_s->key_mgmt == WPA_KEY_MGMT_OWE || ft_completed ||
- already_authorized)
+ already_authorized || wpa_s->drv_authorized_port)
eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
/* 802.1X::portControl = Auto */
eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
@@ -2946,15 +2995,21 @@
wmm_ac_restore_tspecs(wpa_s);
}
+#if defined(CONFIG_FILS) || defined(CONFIG_MBO)
+ bss = wpa_bss_get_bssid(wpa_s, bssid);
+#endif /* CONFIG_FILS || CONFIG_MBO */
#ifdef CONFIG_FILS
if (wpa_key_mgmt_fils(wpa_s->key_mgmt)) {
- struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, bssid);
const u8 *fils_cache_id = wpa_bss_get_fils_cache_id(bss);
if (fils_cache_id)
wpa_sm_set_fils_cache_id(wpa_s->wpa, fils_cache_id);
}
#endif /* CONFIG_FILS */
+
+#ifdef CONFIG_MBO
+ wpas_mbo_check_pmf(wpa_s, bss, wpa_s->current_ssid);
+#endif /* CONFIG_MBO */
}
@@ -2999,7 +3054,8 @@
int locally_generated)
{
if (wpa_s->wpa_state != WPA_4WAY_HANDSHAKE ||
- !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
+ !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
+ wpa_key_mgmt_sae(wpa_s->key_mgmt))
return 0; /* Not in 4-way handshake with PSK */
/*
@@ -3062,6 +3118,10 @@
if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
return; /* P2P group removed */
wpas_auth_failed(wpa_s, "WRONG_KEY");
+#ifdef CONFIG_DPP2
+ wpas_dpp_send_conn_status_result(wpa_s,
+ DPP_STATUS_AUTH_FAILURE);
+#endif /* CONFIG_DPP2 */
}
if (!wpa_s->disconnected &&
(!wpa_s->auto_reconnect_disabled ||
@@ -3510,26 +3570,22 @@
static void wpa_supplicant_event_unprot_deauth(struct wpa_supplicant *wpa_s,
struct unprot_deauth *e)
{
-#ifdef CONFIG_IEEE80211W
wpa_printf(MSG_DEBUG, "Unprotected Deauthentication frame "
"dropped: " MACSTR " -> " MACSTR
" (reason code %u)",
MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
-#endif /* CONFIG_IEEE80211W */
}
static void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s,
struct unprot_disassoc *e)
{
-#ifdef CONFIG_IEEE80211W
wpa_printf(MSG_DEBUG, "Unprotected Disassociation frame "
"dropped: " MACSTR " -> " MACSTR
" (reason code %u)",
MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
-#endif /* CONFIG_IEEE80211W */
}
@@ -3787,14 +3843,12 @@
}
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
#ifdef CONFIG_SME
if (category == WLAN_ACTION_SA_QUERY) {
sme_sa_query_rx(wpa_s, mgmt->sa, payload, plen);
return;
}
#endif /* CONFIG_SME */
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WNM
if (mgmt->u.action.category == WLAN_ACTION_WNM) {
@@ -3935,6 +3989,7 @@
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
+ wpa_s->drv_authorized_port = 1;
}
}
@@ -4508,9 +4563,7 @@
}
#endif /* CONFIG_AP */
-#ifdef CONFIG_IEEE80211W
sme_event_ch_switch(wpa_s);
-#endif /* CONFIG_IEEE80211W */
wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_CS);
wnm_clear_coloc_intf_reporting(wpa_s);
break;
@@ -4717,6 +4770,7 @@
wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
wpa_supplicant_update_mac_addr(wpa_s);
+ wpa_supplicant_set_default_scan_ies(wpa_s);
if (wpa_s->p2p_mgmt) {
wpa_supplicant_set_state(wpa_s,
WPA_DISCONNECTED);
diff --git a/wpa_supplicant/hidl/1.3/sta_iface.cpp b/wpa_supplicant/hidl/1.3/sta_iface.cpp
index 249eebc..e82305d 100644
--- a/wpa_supplicant/hidl/1.3/sta_iface.cpp
+++ b/wpa_supplicant/hidl/1.3/sta_iface.cpp
@@ -20,8 +20,8 @@
#include "interworking.h"
#include "hs20_supplicant.h"
#include "wps_supplicant.h"
-#include "dpp_supplicant.h"
#include "dpp.h"
+#include "dpp_supplicant.h"
#include "rsn_supp/wpa.h"
#include "rsn_supp/pmksa_cache.h"
}
diff --git a/wpa_supplicant/hidl/1.3/sta_network.cpp b/wpa_supplicant/hidl/1.3/sta_network.cpp
index 273687d..242d7d7 100644
--- a/wpa_supplicant/hidl/1.3/sta_network.cpp
+++ b/wpa_supplicant/hidl/1.3/sta_network.cpp
@@ -1199,7 +1199,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- path.c_str(), &(wpa_ssid->eap.ca_cert), "eap ca_cert")) {
+ path.c_str(), &(wpa_ssid->eap.cert.ca_cert), "eap ca_cert")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
return {SupplicantStatusCode::SUCCESS, ""};
@@ -1209,7 +1209,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- path.c_str(), &(wpa_ssid->eap.ca_path), "eap ca_path")) {
+ path.c_str(), &(wpa_ssid->eap.cert.ca_path), "eap ca_path")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
return {SupplicantStatusCode::SUCCESS, ""};
@@ -1219,7 +1219,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- path.c_str(), &(wpa_ssid->eap.client_cert),
+ path.c_str(), &(wpa_ssid->eap.cert.client_cert),
"eap client_cert")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
@@ -1230,7 +1230,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- id.c_str(), &(wpa_ssid->eap.key_id), "eap key_id")) {
+ id.c_str(), &(wpa_ssid->eap.cert.key_id), "eap key_id")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
return {SupplicantStatusCode::SUCCESS, ""};
@@ -1241,7 +1241,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- match.c_str(), &(wpa_ssid->eap.subject_match),
+ match.c_str(), &(wpa_ssid->eap.cert.subject_match),
"eap subject_match")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
@@ -1253,7 +1253,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- match.c_str(), &(wpa_ssid->eap.altsubject_match),
+ match.c_str(), &(wpa_ssid->eap.cert.altsubject_match),
"eap altsubject_match")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
@@ -1263,7 +1263,7 @@
SupplicantStatus StaNetwork::setEapEngineInternal(bool enable)
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- wpa_ssid->eap.engine = enable ? 1 : 0;
+ wpa_ssid->eap.cert.engine = enable ? 1 : 0;
return {SupplicantStatusCode::SUCCESS, ""};
}
@@ -1271,7 +1271,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- id.c_str(), &(wpa_ssid->eap.engine_id), "eap engine_id")) {
+ id.c_str(), &(wpa_ssid->eap.cert.engine_id), "eap engine_id")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
return {SupplicantStatusCode::SUCCESS, ""};
@@ -1282,7 +1282,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (setStringFieldAndResetState(
- match.c_str(), &(wpa_ssid->eap.domain_suffix_match),
+ match.c_str(), &(wpa_ssid->eap.cert.domain_suffix_match),
"eap domain_suffix_match")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
@@ -1463,7 +1463,7 @@
// the first EAP method for each network.
const std::string eap_method_str = eap_get_name(
wpa_ssid->eap.eap_methods[0].vendor,
- static_cast<EapType>(wpa_ssid->eap.eap_methods[0].method));
+ static_cast<enum eap_type>(wpa_ssid->eap.eap_methods[0].method));
size_t eap_method_idx =
std::find(
std::begin(kEapMethodStrings), std::end(kEapMethodStrings),
@@ -1557,89 +1557,89 @@
std::pair<SupplicantStatus, std::string> StaNetwork::getEapCACertInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.ca_cert) {
+ if (!wpa_ssid->eap.cert.ca_cert) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
return {{SupplicantStatusCode::SUCCESS, ""},
- reinterpret_cast<char *>(wpa_ssid->eap.ca_cert)};
+ reinterpret_cast<char *>(wpa_ssid->eap.cert.ca_cert)};
}
std::pair<SupplicantStatus, std::string> StaNetwork::getEapCAPathInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.ca_path) {
+ if (!wpa_ssid->eap.cert.ca_path) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
return {{SupplicantStatusCode::SUCCESS, ""},
- reinterpret_cast<char *>(wpa_ssid->eap.ca_path)};
+ reinterpret_cast<char *>(wpa_ssid->eap.cert.ca_path)};
}
std::pair<SupplicantStatus, std::string> StaNetwork::getEapClientCertInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.client_cert) {
+ if (!wpa_ssid->eap.cert.client_cert) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
return {{SupplicantStatusCode::SUCCESS, ""},
- reinterpret_cast<char *>(wpa_ssid->eap.client_cert)};
+ reinterpret_cast<char *>(wpa_ssid->eap.cert.client_cert)};
}
std::pair<SupplicantStatus, std::string>
StaNetwork::getEapPrivateKeyIdInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.key_id) {
+ if (!wpa_ssid->eap.cert.key_id) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
- return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.key_id};
+ return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.cert.key_id};
}
std::pair<SupplicantStatus, std::string>
StaNetwork::getEapSubjectMatchInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.subject_match) {
+ if (!wpa_ssid->eap.cert.subject_match) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
return {{SupplicantStatusCode::SUCCESS, ""},
- reinterpret_cast<char *>(wpa_ssid->eap.subject_match)};
+ reinterpret_cast<char *>(wpa_ssid->eap.cert.subject_match)};
}
std::pair<SupplicantStatus, std::string>
StaNetwork::getEapAltSubjectMatchInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.altsubject_match) {
+ if (!wpa_ssid->eap.cert.altsubject_match) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
return {{SupplicantStatusCode::SUCCESS, ""},
- reinterpret_cast<char *>(wpa_ssid->eap.altsubject_match)};
+ reinterpret_cast<char *>(wpa_ssid->eap.cert.altsubject_match)};
}
std::pair<SupplicantStatus, bool> StaNetwork::getEapEngineInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.engine == 1};
+ return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.cert.engine == 1};
}
std::pair<SupplicantStatus, std::string> StaNetwork::getEapEngineIDInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.engine_id) {
+ if (!wpa_ssid->eap.cert.engine_id) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
- return {{SupplicantStatusCode::SUCCESS, ""}, {wpa_ssid->eap.engine_id}};
+ return {{SupplicantStatusCode::SUCCESS, ""}, {wpa_ssid->eap.cert.engine_id}};
}
std::pair<SupplicantStatus, std::string>
StaNetwork::getEapDomainSuffixMatchInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
- if (!wpa_ssid->eap.domain_suffix_match) {
+ if (!wpa_ssid->eap.cert.domain_suffix_match) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
}
return {{SupplicantStatusCode::SUCCESS, ""},
- {wpa_ssid->eap.domain_suffix_match}};
+ {wpa_ssid->eap.cert.domain_suffix_match}};
}
std::pair<SupplicantStatus, std::string> StaNetwork::getIdStrInternal()
@@ -1977,9 +1977,9 @@
if (ocspType < OcspType::NONE || ocspType > OcspType::REQUIRE_ALL_CERTS_STATUS) {
return{ SupplicantStatusCode::FAILURE_ARGS_INVALID, "" };
}
- wpa_ssid->eap.ocsp = (int) ocspType;
+ wpa_ssid->eap.cert.ocsp = (int) ocspType;
wpa_printf(
- MSG_MSGDUMP, "ocsp: %d", wpa_ssid->eap.ocsp);
+ MSG_MSGDUMP, "ocsp: %d", wpa_ssid->eap.cert.ocsp);
resetInternalStateAfterParamsUpdate();
return {SupplicantStatusCode::SUCCESS, ""};
}
@@ -1988,7 +1988,7 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
return {{SupplicantStatusCode::SUCCESS, ""},
- (OcspType) wpa_ssid->eap.ocsp};
+ (OcspType) wpa_ssid->eap.cert.ocsp};
}
SupplicantStatus StaNetwork::setPmkCacheInternal(const std::vector<uint8_t>& serializedEntry) {
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 6934c47..36c0aff 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -111,6 +111,7 @@
wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
/* TODO: get correct RSN IE */
+ wpa_sm_set_ap_rsnxe(peer->supp, NULL, 0);
return wpa_sm_set_ap_rsn_ie(peer->supp,
(u8 *) "\x30\x14\x01\x00"
"\x00\x0f\xac\x04"
@@ -464,7 +465,7 @@
"\x00\x0f\xac\x04"
"\x01\x00\x00\x0f\xac\x04"
"\x01\x00\x00\x0f\xac\x02"
- "\x00\x00", 22, NULL, 0, NULL, 0) !=
+ "\x00\x00", 22, NULL, 0, NULL, 0, NULL, 0) !=
WPA_IE_OK) {
wpa_printf(MSG_DEBUG, "AUTH: wpa_validate_wpa_ie() failed");
return -1;
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index dabde82..585b7f0 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -1395,7 +1395,11 @@
!roaming_consortium_match(ie, anqp,
cred->roaming_consortium,
cred->roaming_consortium_len)) &&
- !cred_roaming_consortiums_match(ie, anqp, cred))
+ !cred_roaming_consortiums_match(ie, anqp, cred) &&
+ (cred->required_roaming_consortium_len == 0 ||
+ !roaming_consortium_match(
+ ie, anqp, cred->required_roaming_consortium,
+ cred->required_roaming_consortium_len)))
continue;
if (cred_no_required_oi_match(cred, bss))
@@ -1550,7 +1554,7 @@
cred->domain_suffix_match) < 0)
return -1;
- ssid->eap.ocsp = cred->ocsp;
+ ssid->eap.cert.ocsp = cred->ocsp;
return 0;
}
@@ -2258,7 +2262,7 @@
realm++;
wpa_msg(wpa_s, MSG_DEBUG,
"Interworking: Search for match with SIM/USIM domain %s",
- realm);
+ realm ? realm : "[NULL]");
if (realm &&
domain_name_list_contains(domain_names, realm, 1))
return 1;
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index 43b1fa7..3df86ef 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -15,6 +15,7 @@
#include "utils/common.h"
#include "common/ieee802_11_defs.h"
#include "common/gas.h"
+#include "rsn_supp/wpa.h"
#include "config.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
@@ -82,6 +83,35 @@
}
+void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ struct wpa_ssid *ssid)
+{
+ const u8 *rsne, *mbo, *oce;
+ struct wpa_ie_data ie;
+
+ wpa_s->disable_mbo_oce = 0;
+ if (!bss)
+ return;
+ mbo = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND);
+ oce = wpas_mbo_get_bss_attr(bss, OCE_ATTR_ID_CAPA_IND);
+ if (!mbo && !oce)
+ return;
+ if (oce && oce[1] >= 1 && (oce[2] & OCE_IS_STA_CFON))
+ return; /* STA-CFON is not required to enable PMF */
+ rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ if (!rsne || wpa_parse_wpa_ie(rsne, 2 + rsne[1], &ie) < 0)
+ return; /* AP is not using RSN */
+
+ if (!(ie.capabilities & WPA_CAPABILITY_MFPC))
+ wpa_s->disable_mbo_oce = 1; /* AP uses RSN without PMF */
+ if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION)
+ wpa_s->disable_mbo_oce = 1; /* STA uses RSN without PMF */
+ if (wpa_s->disable_mbo_oce)
+ wpa_printf(MSG_INFO,
+ "MBO: Disable MBO/OCE due to misbehaving AP not having enabled PMF");
+}
+
+
static void wpas_mbo_non_pref_chan_attr_body(struct wpa_supplicant *wpa_s,
struct wpabuf *mbo,
u8 start, u8 end)
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 7354c1b..5c1a47d 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -86,7 +86,6 @@
MESH_CONF_SEC_AMPE;
else
conf->security |= MESH_CONF_SEC_NONE;
-#ifdef CONFIG_IEEE80211W
conf->ieee80211w = ssid->ieee80211w;
if (conf->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
if (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)
@@ -94,7 +93,6 @@
else
conf->ieee80211w = NO_MGMT_FRAME_PROTECTION;
}
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_OCV
conf->ocv = ssid->ocv;
#endif /* CONFIG_OCV */
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 4b8d6c4..e730b63 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -165,11 +165,9 @@
conf.wpa_group_rekey = -1;
conf.wpa_group_update_count = 4;
conf.wpa_pairwise_update_count = 4;
-#ifdef CONFIG_IEEE80211W
conf.ieee80211w = ieee80211w;
if (ieee80211w != NO_MGMT_FRAME_PROTECTION)
conf.group_mgmt_cipher = rsn->mgmt_group_cipher;
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_OCV
conf.ocv = ocv;
#endif /* CONFIG_OCV */
@@ -186,7 +184,6 @@
return -1;
rsn->mgtk_key_id = 1;
-#ifdef CONFIG_IEEE80211W
if (ieee80211w != NO_MGMT_FRAME_PROTECTION) {
rsn->igtk_len = wpa_cipher_key_len(conf.group_mgmt_cipher);
if (random_get_bytes(rsn->igtk, rsn->igtk_len) < 0)
@@ -201,7 +198,6 @@
rsn->igtk_key_id, 1,
seq, sizeof(seq), rsn->igtk, rsn->igtk_len);
}
-#endif /* CONFIG_IEEE80211W */
/* group privacy / data frames */
wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX MGTK",
@@ -545,10 +541,8 @@
len = sizeof(*ampe);
if (cat[1] == PLINK_OPEN)
len += rsn->mgtk_len + WPA_KEY_RSC_LEN + 4;
-#ifdef CONFIG_IEEE80211W
if (cat[1] == PLINK_OPEN && rsn->igtk_len)
len += 2 + 6 + rsn->igtk_len;
-#endif /* CONFIG_IEEE80211W */
if (2 + AES_BLOCK_SIZE + 2 + len > wpabuf_tailroom(buf)) {
wpa_printf(MSG_ERROR, "protect frame: buffer too small");
@@ -591,7 +585,6 @@
WPA_PUT_LE32(pos, 0xffffffff);
pos += 4;
-#ifdef CONFIG_IEEE80211W
/*
* IGTKdata[variable]:
* Key ID[2], IPN[6], IGTK[variable]
@@ -603,7 +596,6 @@
pos += 6;
os_memcpy(pos, rsn->igtk, rsn->igtk_len);
}
-#endif /* CONFIG_IEEE80211W */
skip_keys:
wpa_hexdump_key(MSG_DEBUG, "mesh: Plaintext AMPE element",
@@ -774,7 +766,6 @@
WPA_GET_LE32(pos));
pos += 4;
-#ifdef CONFIG_IEEE80211W
/*
* IGTKdata[variable]:
* Key ID[2], IPN[6], IGTK[variable]
@@ -794,7 +785,6 @@
wpa_hexdump_key(MSG_DEBUG, "mesh: IGTKdata - IGTK",
sta->igtk, sta->igtk_len);
}
-#endif /* CONFIG_IEEE80211W */
free:
os_free(crypt);
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index ebefd48..2ebe034 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -865,10 +865,11 @@
int i;
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
- "depth=%d subject='%s'%s%s%s",
+ "depth=%d subject='%s'%s%s%s%s",
cert->depth, cert->subject, cert_hash ? " hash=" : "",
cert_hash ? cert_hash : "",
- cert->tod ? " tod=1" : "");
+ cert->tod == 2 ? " tod=2" : "",
+ cert->tod == 1 ? " tod=1" : "");
if (cert->cert) {
char *cert_hex;
diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c
index 6a85af4..b15ac9e 100644
--- a/wpa_supplicant/op_classes.c
+++ b/wpa_supplicant/op_classes.c
@@ -16,13 +16,19 @@
#include "wpa_supplicant_i.h"
-static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode, u8 chan,
+static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode,
+ u8 op_class, u8 chan,
unsigned int *flags)
{
int i;
+ int is_6ghz = op_class >= 131 && op_class <= 135;
for (i = 0; i < mode->num_channels; i++) {
- if (mode->channels[i].chan == chan)
+ int chan_is_6ghz;
+
+ chan_is_6ghz = mode->channels[i].freq > 5940 &&
+ mode->channels[i].freq <= 7105;
+ if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
break;
}
@@ -62,7 +68,8 @@
}
-static enum chan_allowed verify_80mhz(struct hostapd_hw_modes *mode, u8 channel)
+static enum chan_allowed verify_80mhz(struct hostapd_hw_modes *mode,
+ u8 op_class, u8 channel)
{
u8 center_chan;
unsigned int i;
@@ -77,7 +84,8 @@
unsigned int flags;
u8 adj_chan = center_chan - 6 + i * 4;
- if (allow_channel(mode, adj_chan, &flags) == NOT_ALLOWED)
+ if (allow_channel(mode, op_class, adj_chan, &flags) ==
+ NOT_ALLOWED)
return NOT_ALLOWED;
if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70)) ||
@@ -120,7 +128,7 @@
static enum chan_allowed verify_160mhz(struct hostapd_hw_modes *mode,
- u8 channel)
+ u8 op_class, u8 channel)
{
u8 center_chan;
unsigned int i;
@@ -135,7 +143,8 @@
unsigned int flags;
u8 adj_chan = center_chan - 14 + i * 4;
- if (allow_channel(mode, adj_chan, &flags) == NOT_ALLOWED)
+ if (allow_channel(mode, op_class, adj_chan, &flags) ==
+ NOT_ALLOWED)
return NOT_ALLOWED;
if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150)) ||
@@ -159,42 +168,42 @@
}
-enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 channel,
- u8 bw)
+enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
+ u8 channel, u8 bw)
{
unsigned int flag = 0;
enum chan_allowed res, res2;
- res2 = res = allow_channel(mode, channel, &flag);
+ res2 = res = allow_channel(mode, op_class, channel, &flag);
if (bw == BW40MINUS) {
if (!(flag & HOSTAPD_CHAN_HT40MINUS))
return NOT_ALLOWED;
- res2 = allow_channel(mode, channel - 4, NULL);
+ res2 = allow_channel(mode, op_class, channel - 4, NULL);
} else if (bw == BW40PLUS) {
if (!(flag & HOSTAPD_CHAN_HT40PLUS))
return NOT_ALLOWED;
- res2 = allow_channel(mode, channel + 4, NULL);
+ res2 = allow_channel(mode, op_class, channel + 4, NULL);
} else if (bw == BW80) {
/*
* channel is a center channel and as such, not necessarily a
* valid 20 MHz channels. Override earlier allow_channel()
* result and use only the 80 MHz specific version.
*/
- res2 = res = verify_80mhz(mode, channel);
+ res2 = res = verify_80mhz(mode, op_class, channel);
} else if (bw == BW160) {
/*
* channel is a center channel and as such, not necessarily a
* valid 20 MHz channels. Override earlier allow_channel()
* result and use only the 160 MHz specific version.
*/
- res2 = res = verify_160mhz(mode, channel);
+ res2 = res = verify_160mhz(mode, op_class, channel);
} else if (bw == BW80P80) {
/*
* channel is a center channel and as such, not necessarily a
* valid 20 MHz channels. Override earlier allow_channel()
* result and use only the 80 MHz specific version.
*/
- res2 = res = verify_80mhz(mode, channel);
+ res2 = res = verify_80mhz(mode, op_class, channel);
}
if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
@@ -225,7 +234,7 @@
/* If we are configured to disable certain things, take that into
* account here. */
- if (ssid->freq_list && ssid->freq_list[0]) {
+ if (ssid && ssid->freq_list && ssid->freq_list[0]) {
for (z = 0; ; z++) {
int f = ssid->freq_list[z];
@@ -248,7 +257,7 @@
return 0;
#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht) {
+ if (ssid && ssid->disable_ht) {
switch (op_class->op_class) {
case 83:
case 84:
@@ -272,7 +281,7 @@
#endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
- if (ssid->disable_vht) {
+ if (ssid && ssid->disable_vht) {
if (op_class->op_class >= 128 && op_class->op_class <= 130) {
/* Disable >= 80 MHz channels if VHT is disabled */
return 0;
@@ -284,7 +293,8 @@
u8 channels[] = { 42, 58, 106, 122, 138, 155 };
for (i = 0; i < ARRAY_SIZE(channels); i++) {
- if (verify_channel(mode, channels[i], op_class->bw) !=
+ if (verify_channel(mode, op_class->op_class,
+ channels[i], op_class->bw) !=
NOT_ALLOWED)
return 1;
}
@@ -294,25 +304,35 @@
if (op_class->op_class == 129) {
/* Check if either 160 MHz channels is allowed */
- return verify_channel(mode, 50, op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, 114, op_class->bw) != NOT_ALLOWED;
+ return verify_channel(mode, op_class->op_class, 50,
+ op_class->bw) != NOT_ALLOWED ||
+ verify_channel(mode, op_class->op_class, 114,
+ op_class->bw) != NOT_ALLOWED;
}
if (op_class->op_class == 130) {
/* Need at least two non-contiguous 80 MHz segments */
found = 0;
- if (verify_channel(mode, 42, op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, 58, op_class->bw) != NOT_ALLOWED)
+ if (verify_channel(mode, op_class->op_class, 42,
+ op_class->bw) != NOT_ALLOWED ||
+ verify_channel(mode, op_class->op_class, 58,
+ op_class->bw) != NOT_ALLOWED)
found++;
- if (verify_channel(mode, 106, op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, 122, op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, 138, op_class->bw) != NOT_ALLOWED)
+ if (verify_channel(mode, op_class->op_class, 106,
+ op_class->bw) != NOT_ALLOWED ||
+ verify_channel(mode, op_class->op_class, 122,
+ op_class->bw) != NOT_ALLOWED ||
+ verify_channel(mode, op_class->op_class, 138,
+ op_class->bw) != NOT_ALLOWED)
found++;
- if (verify_channel(mode, 106, op_class->bw) != NOT_ALLOWED &&
- verify_channel(mode, 138, op_class->bw) != NOT_ALLOWED)
+ if (verify_channel(mode, op_class->op_class, 106,
+ op_class->bw) != NOT_ALLOWED &&
+ verify_channel(mode, op_class->op_class, 138,
+ op_class->bw) != NOT_ALLOWED)
found++;
- if (verify_channel(mode, 155, op_class->bw) != NOT_ALLOWED)
+ if (verify_channel(mode, op_class->op_class, 155,
+ op_class->bw) != NOT_ALLOWED)
found++;
if (found >= 2)
@@ -324,7 +344,8 @@
found = 0;
for (chan = op_class->min_chan; chan <= op_class->max_chan;
chan += op_class->inc) {
- if (verify_channel(mode, chan, op_class->bw) != NOT_ALLOWED) {
+ if (verify_channel(mode, op_class->op_class, chan,
+ op_class->bw) != NOT_ALLOWED) {
found = 1;
break;
}
@@ -385,3 +406,24 @@
wpabuf_free(buf);
return res;
}
+
+
+int * wpas_supp_op_classes(struct wpa_supplicant *wpa_s)
+{
+ int op;
+ unsigned int pos, max_num = 0;
+ int *classes;
+
+ for (op = 0; global_op_class[op].op_class; op++)
+ max_num++;
+ classes = os_zalloc((max_num + 1) * sizeof(int));
+ if (!classes)
+ return NULL;
+
+ for (op = 0, pos = 0; global_op_class[op].op_class; op++) {
+ if (wpas_op_class_supported(wpa_s, NULL, &global_op_class[op]))
+ classes[pos++] = global_op_class[op].op_class;
+ }
+
+ return classes;
+}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 23bbc21..fb509a1 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2268,6 +2268,8 @@
res->ht40 = 1;
if (wpa_s->p2p_go_vht)
res->vht = 1;
+ if (wpa_s->p2p_go_he)
+ res->he = 1;
res->max_oper_chwidth = wpa_s->p2p_go_max_oper_chwidth;
res->vht_center_freq2 = wpa_s->p2p_go_vht_center_freq2;
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index 8468b2f..b78ff10 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -101,10 +101,16 @@
#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
/* Workaround different, undefined for Windows, error codes used here */
+#ifndef ENOTCONN
#define ENOTCONN -1
+#endif
+#ifndef EOPNOTSUPP
#define EOPNOTSUPP -1
+#endif
+#ifndef ECANCELED
#define ECANCELED -1
#endif
+#endif
/* Measurement Request element + Location Subject + Maximum Age subelement */
#define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4)
@@ -522,7 +528,8 @@
next_freq = freqs;
for (i = 0; i < num_chans; i++) {
u8 chan = channels ? channels[i] : op->min_chan + i * op->inc;
- enum chan_allowed res = verify_channel(mode, chan, op->bw);
+ enum chan_allowed res = verify_channel(mode, op->op_class, chan,
+ op->bw);
if (res == NOT_ALLOWED || (res == NO_IR && active))
continue;
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 7abb028..4d158a9 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -79,6 +79,33 @@
#endif /* CONFIG_WPS */
+static int wpa_setup_mac_addr_rand_params(struct wpa_driver_scan_params *params,
+ const u8 *mac_addr)
+{
+ u8 *tmp;
+
+ if (params->mac_addr) {
+ params->mac_addr_mask = NULL;
+ os_free(params->mac_addr);
+ params->mac_addr = NULL;
+ }
+
+ params->mac_addr_rand = 1;
+
+ if (!mac_addr)
+ return 0;
+
+ tmp = os_malloc(2 * ETH_ALEN);
+ if (!tmp)
+ return -1;
+
+ os_memcpy(tmp, mac_addr, 2 * ETH_ALEN);
+ params->mac_addr = tmp;
+ params->mac_addr_mask = tmp + ETH_ALEN;
+ return 0;
+}
+
+
/**
* wpa_supplicant_enabled_networks - Check whether there are enabled networks
* @wpa_s: Pointer to wpa_supplicant data
@@ -169,6 +196,10 @@
return;
}
+ if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) &&
+ wpa_s->wpa_state <= WPA_SCANNING)
+ wpa_setup_mac_addr_rand_params(params, wpa_s->mac_addr_scan);
+
if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
wpa_msg(wpa_s, MSG_INFO,
"Failed to assign random MAC address for a scan");
@@ -1211,13 +1242,8 @@
#endif /* CONFIG_P2P */
if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) &&
- wpa_s->wpa_state <= WPA_SCANNING) {
- params.mac_addr_rand = 1;
- if (wpa_s->mac_addr_scan) {
- params.mac_addr = wpa_s->mac_addr_scan;
- params.mac_addr_mask = wpa_s->mac_addr_scan + ETH_ALEN;
- }
- }
+ wpa_s->wpa_state <= WPA_SCANNING)
+ wpa_setup_mac_addr_rand_params(¶ms, wpa_s->mac_addr_scan);
if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
struct wpa_bss *bss;
@@ -1286,6 +1312,7 @@
wpabuf_free(extra_ie);
os_free(params.freqs);
os_free(params.filter_ssids);
+ os_free(params.mac_addr);
if (ret) {
wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
@@ -1664,20 +1691,16 @@
wpa_setband_scan_freqs(wpa_s, scan_params);
if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) &&
- wpa_s->wpa_state <= WPA_SCANNING) {
- params.mac_addr_rand = 1;
- if (wpa_s->mac_addr_sched_scan) {
- params.mac_addr = wpa_s->mac_addr_sched_scan;
- params.mac_addr_mask = wpa_s->mac_addr_sched_scan +
- ETH_ALEN;
- }
- }
+ wpa_s->wpa_state <= WPA_SCANNING)
+ wpa_setup_mac_addr_rand_params(¶ms,
+ wpa_s->mac_addr_sched_scan);
wpa_scan_set_relative_rssi_params(wpa_s, scan_params);
ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params);
wpabuf_free(extra_ie);
os_free(params.filter_ssids);
+ os_free(params.mac_addr);
if (ret) {
wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
if (prev_state != wpa_s->wpa_state)
@@ -2535,23 +2558,9 @@
params->sched_scan_plans_num = src->sched_scan_plans_num;
}
- if (src->mac_addr_rand) {
- params->mac_addr_rand = src->mac_addr_rand;
-
- if (src->mac_addr && src->mac_addr_mask) {
- u8 *mac_addr;
-
- mac_addr = os_malloc(2 * ETH_ALEN);
- if (!mac_addr)
- goto failed;
-
- os_memcpy(mac_addr, src->mac_addr, ETH_ALEN);
- os_memcpy(mac_addr + ETH_ALEN, src->mac_addr_mask,
- ETH_ALEN);
- params->mac_addr = mac_addr;
- params->mac_addr_mask = mac_addr + ETH_ALEN;
- }
- }
+ if (src->mac_addr_rand &&
+ wpa_setup_mac_addr_rand_params(params, src->mac_addr))
+ goto failed;
if (src->bssid) {
u8 *bssid;
@@ -2738,18 +2747,14 @@
}
if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) &&
- wpa_s->wpa_state <= WPA_SCANNING) {
- params.mac_addr_rand = 1;
- if (wpa_s->mac_addr_pno) {
- params.mac_addr = wpa_s->mac_addr_pno;
- params.mac_addr_mask = wpa_s->mac_addr_pno + ETH_ALEN;
- }
- }
+ wpa_s->wpa_state <= WPA_SCANNING)
+ wpa_setup_mac_addr_rand_params(¶ms, wpa_s->mac_addr_pno);
wpa_scan_set_relative_rssi_params(wpa_s, ¶ms);
ret = wpa_supplicant_start_sched_scan(wpa_s, ¶ms);
os_free(params.filter_ssids);
+ os_free(params.mac_addr);
if (ret == 0)
wpa_s->pno = 1;
else
@@ -2843,6 +2848,32 @@
}
+int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
+ unsigned int type, u8 *mask)
+{
+ const u8 *to_copy;
+
+ if ((wpa_s->mac_addr_rand_enable & type) != type)
+ return -1;
+
+ if (type == MAC_ADDR_RAND_SCAN) {
+ to_copy = wpa_s->mac_addr_scan;
+ } else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
+ to_copy = wpa_s->mac_addr_sched_scan;
+ } else if (type == MAC_ADDR_RAND_PNO) {
+ to_copy = wpa_s->mac_addr_pno;
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "scan: Invalid MAC randomization type=0x%x",
+ type);
+ return -1;
+ }
+
+ os_memcpy(mask, to_copy + ETH_ALEN, ETH_ALEN);
+ return 0;
+}
+
+
int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s)
{
struct wpa_radio_work *work;
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 2aa0a8b..58caa78 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -52,6 +52,8 @@
int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
unsigned int type, const u8 *addr,
const u8 *mask);
+int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
+ unsigned int type, u8 *mask);
int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s);
void filter_scan_res(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *res);
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index dd50201..cfb5bb3 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -37,9 +37,7 @@
static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx);
static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx);
static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx);
-#ifdef CONFIG_IEEE80211W
static void sme_stop_sa_query(struct wpa_supplicant *wpa_s);
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_SAE
@@ -86,11 +84,16 @@
static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
const u8 *bssid, int external,
- int reuse)
+ int reuse, int *ret_use_pt)
{
struct wpabuf *buf;
size_t len;
const char *password;
+ struct wpa_bss *bss;
+ int use_pt = 0;
+
+ if (ret_use_pt)
+ *ret_use_pt = 0;
#ifdef CONFIG_TESTING_OPTIONS
if (wpa_s->sae_commit_override) {
@@ -119,6 +122,7 @@
os_memcmp(bssid, wpa_s->sme.sae.tmp->bssid, ETH_ALEN) == 0) {
wpa_printf(MSG_DEBUG,
"SAE: Reuse previously generated PWE on a retry with the same AP");
+ use_pt = wpa_s->sme.sae.tmp->h2e;
goto reuse_data;
}
if (sme_set_sae_group(wpa_s) < 0) {
@@ -126,7 +130,31 @@
return NULL;
}
- if (sae_prepare_commit(wpa_s->own_addr, bssid,
+ if (wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
+ bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
+ if (bss) {
+ const u8 *rsnxe;
+
+ rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ if (rsnxe && rsnxe[1] >= 1)
+ use_pt = !!(rsnxe[2] &
+ BIT(WLAN_RSNX_CAPAB_SAE_H2E));
+ }
+
+ if (wpa_s->conf->sae_pwe == 1 && !use_pt) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Cannot use H2E with the selected AP");
+ return NULL;
+ }
+ }
+
+ if (use_pt &&
+ sae_prepare_commit_pt(&wpa_s->sme.sae, ssid->pt,
+ wpa_s->own_addr, bssid,
+ wpa_s->sme.sae_rejected_groups) < 0)
+ return NULL;
+ if (!use_pt &&
+ sae_prepare_commit(wpa_s->own_addr, bssid,
(u8 *) password, os_strlen(password),
ssid->sae_password_id,
&wpa_s->sme.sae) < 0) {
@@ -145,10 +173,13 @@
return NULL;
if (!external) {
wpabuf_put_le16(buf, 1); /* Transaction seq# */
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+ wpabuf_put_le16(buf, use_pt ? WLAN_STATUS_SAE_HASH_TO_ELEMENT :
+ WLAN_STATUS_SUCCESS);
}
sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
ssid->sae_password_id);
+ if (ret_use_pt)
+ *ret_use_pt = use_pt;
return buf;
}
@@ -492,7 +523,6 @@
}
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid);
if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
@@ -505,7 +535,6 @@
wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
}
}
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_P2P
if (wpa_s->global->p2p) {
@@ -562,6 +591,14 @@
os_memcpy(pos, ext_capab, ext_capab_len);
}
+ if (wpa_s->rsnxe_len > 0 &&
+ wpa_s->rsnxe_len <=
+ sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len) {
+ os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
+ wpa_s->rsnxe, wpa_s->rsnxe_len);
+ wpa_s->sme.assoc_req_ie_len += wpa_s->rsnxe_len;
+ }
+
#ifdef CONFIG_HS20
if (is_hs20_network(wpa_s, ssid, bss)) {
struct wpabuf *hs20;
@@ -623,7 +660,7 @@
#ifdef CONFIG_MBO
mbo_ie = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
- if (mbo_ie) {
+ if (!wpa_s->disable_mbo_oce && mbo_ie) {
int len;
len = wpas_mbo_ie(wpa_s, wpa_s->sme.assoc_req_ie +
@@ -655,7 +692,7 @@
if (start)
resp = sme_auth_build_sae_commit(wpa_s, ssid,
bss->bssid, 0,
- start == 2);
+ start == 2, NULL);
else
resp = sme_auth_build_sae_confirm(wpa_s, 0);
if (resp == NULL) {
@@ -855,6 +892,8 @@
/* Starting new connection, so clear the possibly used WPA IE from the
* previous association. */
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+ wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
+ wpa_s->rsnxe_len = 0;
sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1);
}
@@ -909,7 +948,8 @@
static int sme_external_auth_build_buf(struct wpabuf *buf,
struct wpabuf *params,
const u8 *sa, const u8 *da,
- u16 auth_transaction, u16 seq_num)
+ u16 auth_transaction, u16 seq_num,
+ u16 status_code)
{
struct ieee80211_mgmt *resp;
@@ -924,7 +964,7 @@
resp->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
resp->seq_ctrl = host_to_le16(seq_num << 4);
resp->u.auth.auth_transaction = host_to_le16(auth_transaction);
- resp->u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
+ resp->u.auth.status_code = host_to_le16(status_code);
if (params)
wpabuf_put_buf(buf, params);
@@ -937,8 +977,9 @@
struct wpa_ssid *ssid)
{
struct wpabuf *resp, *buf;
+ int use_pt;
- resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0);
+ resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0, &use_pt);
if (!resp) {
wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
return -1;
@@ -953,7 +994,9 @@
wpa_s->sme.seq_num++;
sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
- bssid, 1, wpa_s->sme.seq_num);
+ bssid, 1, wpa_s->sme.seq_num,
+ use_pt ? WLAN_STATUS_SAE_HASH_TO_ELEMENT :
+ WLAN_STATUS_SUCCESS);
wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0);
wpabuf_free(resp);
wpabuf_free(buf);
@@ -972,6 +1015,8 @@
params.ssid = wpa_s->sme.ext_auth_ssid;
params.ssid_len = wpa_s->sme.ext_auth_ssid_len;
params.bssid = wpa_s->sme.ext_auth_bssid;
+ if (wpa_s->conf->sae_pmkid_in_assoc && status == WLAN_STATUS_SUCCESS)
+ params.pmkid = wpa_s->sme.sae.pmkid;
wpa_drv_send_external_auth_status(wpa_s, ¶ms);
}
@@ -1020,7 +1065,8 @@
}
wpa_s->sme.seq_num++;
sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
- da, 2, wpa_s->sme.seq_num);
+ da, 2, wpa_s->sme.seq_num,
+ WLAN_STATUS_SUCCESS);
wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0);
wpabuf_free(resp);
wpabuf_free(buf);
@@ -1057,6 +1103,52 @@
}
+static int sme_sae_is_group_enabled(struct wpa_supplicant *wpa_s, int group)
+{
+ int *groups = wpa_s->conf->sae_groups;
+ int default_groups[] = { 19, 20, 21, 0 };
+ int i;
+
+ if (!groups)
+ groups = default_groups;
+
+ for (i = 0; groups[i] > 0; i++) {
+ if (groups[i] == group)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int sme_check_sae_rejected_groups(struct wpa_supplicant *wpa_s,
+ const struct wpabuf *groups)
+{
+ size_t i, count;
+ const u8 *pos;
+
+ if (!groups)
+ return 0;
+
+ pos = wpabuf_head(groups);
+ count = wpabuf_len(groups) / 2;
+ for (i = 0; i < count; i++) {
+ int enabled;
+ u16 group;
+
+ group = WPA_GET_LE16(pos);
+ pos += 2;
+ enabled = sme_sae_is_group_enabled(wpa_s, group);
+ wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
+ group, enabled ? "enabled" : "disabled");
+ if (enabled)
+ return 1;
+ }
+
+ return 0;
+}
+
+
static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
u16 status_code, const u8 *data, size_t len,
int external, const u8 *sa)
@@ -1111,6 +1203,8 @@
wpa_s->sme.sae.state == SAE_COMMITTED &&
(external || wpa_s->current_bss) && wpa_s->current_ssid) {
wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported");
+ int_array_add_unique(&wpa_s->sme.sae_rejected_groups,
+ wpa_s->sme.sae.group);
wpa_s->sme.sae_group_index++;
if (sme_set_sae_group(wpa_s) < 0)
return -1; /* no other groups enabled */
@@ -1135,7 +1229,8 @@
return -1;
}
- if (status_code != WLAN_STATUS_SUCCESS)
+ if (status_code != WLAN_STATUS_SUCCESS &&
+ status_code != WLAN_STATUS_SAE_HASH_TO_ELEMENT)
return -1;
if (auth_transaction == 1) {
@@ -1147,12 +1242,16 @@
if ((!external && wpa_s->current_bss == NULL) ||
wpa_s->current_ssid == NULL)
return -1;
- if (wpa_s->sme.sae.state != SAE_COMMITTED)
- return -1;
+ if (wpa_s->sme.sae.state != SAE_COMMITTED) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Ignore commit message while waiting for confirm");
+ return 0;
+ }
if (groups && groups[0] <= 0)
groups = NULL;
res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
- groups);
+ groups, status_code ==
+ WLAN_STATUS_SAE_HASH_TO_ELEMENT);
if (res == SAE_SILENTLY_DISCARD) {
wpa_printf(MSG_DEBUG,
"SAE: Drop commit message due to reflection attack");
@@ -1161,6 +1260,12 @@
if (res != WLAN_STATUS_SUCCESS)
return -1;
+ if (wpa_s->sme.sae.tmp &&
+ sme_check_sae_rejected_groups(
+ wpa_s,
+ wpa_s->sme.sae.tmp->peer_rejected_groups) < 0)
+ return -1;
+
if (sae_process_commit(&wpa_s->sme.sae) < 0) {
wpa_printf(MSG_DEBUG, "SAE: Failed to process peer "
"commit");
@@ -1176,6 +1281,8 @@
sme_external_auth_send_sae_confirm(wpa_s, sa);
return 0;
} else if (auth_transaction == 2) {
+ if (status_code != WLAN_STATUS_SUCCESS)
+ return -1;
wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm");
if (wpa_s->sme.sae.state != SAE_CONFIRMED)
return -1;
@@ -1197,6 +1304,37 @@
}
+static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+ wpa_printf(MSG_DEBUG,
+ "SME: SAE completed - setting PMK for 4-way handshake");
+ wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
+ wpa_s->sme.sae.pmkid, bssid);
+ if (wpa_s->conf->sae_pmkid_in_assoc) {
+ /* Update the own RSNE contents now that we have set the PMK
+ * and added a PMKSA cache entry based on the successfully
+ * completed SAE exchange. In practice, this will add the PMKID
+ * into RSNE. */
+ if (wpa_s->sme.assoc_req_ie_len + 2 + PMKID_LEN >
+ sizeof(wpa_s->sme.assoc_req_ie)) {
+ wpa_msg(wpa_s, MSG_WARNING,
+ "RSN: Not enough room for inserting own PMKID into RSNE");
+ return -1;
+ }
+ if (wpa_insert_pmkid(wpa_s->sme.assoc_req_ie,
+ &wpa_s->sme.assoc_req_ie_len,
+ wpa_s->sme.sae.pmkid) < 0)
+ return -1;
+ wpa_hexdump(MSG_DEBUG,
+ "SME: Updated Association Request IEs",
+ wpa_s->sme.assoc_req_ie,
+ wpa_s->sme.assoc_req_ie_len);
+ }
+
+ return 0;
+}
+
+
void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
const u8 *auth_frame, size_t len)
{
@@ -1230,10 +1368,8 @@
if (res != 1)
return;
- wpa_printf(MSG_DEBUG,
- "SME: SAE completed - setting PMK for 4-way handshake");
- wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
- wpa_s->sme.sae.pmkid, wpa_s->pending_bssid);
+ if (sme_sae_set_pmk(wpa_s, wpa_s->sme.ext_auth_bssid) < 0)
+ return;
}
}
@@ -1286,10 +1422,8 @@
if (res != 1)
return;
- wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for "
- "4-way handshake");
- wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
- wpa_s->sme.sae.pmkid, wpa_s->pending_bssid);
+ if (sme_sae_set_pmk(wpa_s, wpa_s->pending_bssid) < 0)
+ return;
}
#endif /* CONFIG_SAE */
@@ -1778,6 +1912,11 @@
elems.osen_len + 2);
} else
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+ if (elems.rsnxe)
+ wpa_sm_set_assoc_rsnxe(wpa_s->wpa, elems.rsnxe - 2,
+ elems.rsnxe_len + 2);
+ else
+ wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
params.p2p = 1;
@@ -1995,15 +2134,17 @@
if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
sme_update_ft_ies(wpa_s, NULL, NULL, 0);
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
sme_stop_sa_query(wpa_s);
-#endif /* CONFIG_IEEE80211W */
}
void sme_deinit(struct wpa_supplicant *wpa_s)
{
sme_clear_on_disassoc(wpa_s);
+#ifdef CONFIG_SAE
+ os_free(wpa_s->sme.sae_rejected_groups);
+ wpa_s->sme.sae_rejected_groups = NULL;
+#endif /* CONFIG_SAE */
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
@@ -2292,8 +2433,6 @@
}
-#ifdef CONFIG_IEEE80211W
-
static const unsigned int sa_query_max_timeout = 1000;
static const unsigned int sa_query_retry_timeout = 201;
static const unsigned int sa_query_ch_switch_max_delay = 5000; /* in usec */
@@ -2582,5 +2721,3 @@
else if (data[0] == WLAN_SA_QUERY_RESPONSE)
sme_process_sa_query_response(wpa_s, sa, data, len);
}
-
-#endif /* CONFIG_IEEE80211W */
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index c147649..270be9e 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -271,7 +271,6 @@
WNM_SLEEP_SUBELEM_GTK,
ptr);
ptr += 13 + gtk_len;
-#ifdef CONFIG_IEEE80211W
} else if (*ptr == WNM_SLEEP_SUBELEM_IGTK) {
if (ptr[1] < 2 + 6 + WPA_IGTK_LEN) {
wpa_printf(MSG_DEBUG, "WNM: Too short IGTK "
@@ -281,7 +280,6 @@
wpa_wnmsleep_install_key(wpa_s->wpa,
WNM_SLEEP_SUBELEM_IGTK, ptr);
ptr += 10 + WPA_IGTK_LEN;
-#endif /* CONFIG_IEEE80211W */
} else
break; /* skip the loop */
}
@@ -1371,7 +1369,7 @@
const u8 *vendor;
#endif /* CONFIG_MBO */
- if (wpa_s->conf->disable_btm)
+ if (wpa_s->disable_mbo_oce || wpa_s->conf->disable_btm)
return;
if (end - pos < 5)
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 5b2154e..47cec0b 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1427,22 +1427,18 @@
#ifdef IEEE8021X_EAPOL
"eap_workaround", "pac_file", "fragment_size", "ocsp",
#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_MESH
- "mode", "no_auto_peer", "mesh_rssi_threshold",
-#else /* CONFIG_MESH */
"mode",
-#endif /* CONFIG_MESH */
"proactive_key_caching", "disabled", "id_str",
-#ifdef CONFIG_IEEE80211W
"ieee80211w",
-#endif /* CONFIG_IEEE80211W */
"mixed_cell", "frequency", "fixed_freq",
#ifdef CONFIG_MESH
+ "no_auto_peer", "mesh_rssi_threshold",
"mesh_basic_rates", "dot11MeshMaxRetries",
"dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
"dot11MeshHoldingTimeout",
#endif /* CONFIG_MESH */
"wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
+ "enable_edmg", "edmg_channel",
#ifdef CONFIG_P2P
"go_p2p_dev_addr", "p2p_client_list", "psk_list",
#endif /* CONFIG_P2P */
@@ -4021,6 +4017,22 @@
wpa_cli_exec(action_file, ifname, pos);
} else if (str_starts(pos, HS20_T_C_ACCEPTANCE)) {
wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_CONF_RECEIVED)) {
+ wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_CONFOBJ_AKM)) {
+ wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_CONFOBJ_SSID)) {
+ wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_CONNECTOR)) {
+ wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PASS)) {
+ wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PSK)) {
+ wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_C_SIGN_KEY)) {
+ wpa_cli_exec(action_file, ifname, pos);
+ } else if (str_starts(pos, DPP_EVENT_NET_ACCESS_KEY)) {
+ wpa_cli_exec(action_file, ifname, pos);
} else if (str_starts(pos, WPA_EVENT_TERMINATING)) {
printf("wpa_supplicant is terminating - stop monitoring\n");
wpa_cli_quit = 1;
@@ -4592,8 +4604,11 @@
if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
continue;
#endif /* _DIRENT_HAVE_D_TYPE */
+ /* Skip current/previous directory and special P2P Device
+ * interfaces. */
if (os_strcmp(dent->d_name, ".") == 0 ||
- os_strcmp(dent->d_name, "..") == 0)
+ os_strcmp(dent->d_name, "..") == 0 ||
+ os_strncmp(dent->d_name, "p2p-dev-", 8) == 0)
continue;
printf("Selected interface '%s'\n", dent->d_name);
ifname = os_strdup(dent->d_name);
diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c
index b3ad45e..f197352 100644
--- a/wpa_supplicant/wpa_priv.c
+++ b/wpa_supplicant/wpa_priv.c
@@ -598,7 +598,7 @@
}
dst_addr = buf;
- os_memcpy(&proto, buf + ETH_ALEN, 2);
+ os_memcpy(&proto, (char *) buf + ETH_ALEN, 2);
if (!wpa_priv_allowed_l2_proto(proto)) {
wpa_printf(MSG_DEBUG, "Refused l2_packet send for ethertype "
@@ -607,7 +607,8 @@
}
res = l2_packet_send(iface->l2[idx], dst_addr, proto,
- buf + ETH_ALEN + 2, len - ETH_ALEN - 2);
+ (unsigned char *) buf + ETH_ALEN + 2,
+ len - ETH_ALEN - 2);
wpa_printf(MSG_DEBUG, "L2 send[idx=%d]: res=%d", idx, res);
}
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index d1dd540..e14bffd 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -125,6 +125,9 @@
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s);
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
+#ifdef CONFIG_OWE
+static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s);
+#endif /* CONFIG_OWE */
/* Configure default/group WEP keys for static WEP */
@@ -400,7 +403,10 @@
wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
+ wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0);
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+ wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
+ wpa_s->rsnxe_len = 0;
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
wpa_s->group_cipher = WPA_CIPHER_NONE;
wpa_s->mgmt_group_cipher = 0;
@@ -422,10 +428,8 @@
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
wpa_s->pairwise_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
-#ifdef CONFIG_IEEE80211W
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
wpa_s->mgmt_group_cipher);
-#endif /* CONFIG_IEEE80211W */
pmksa_cache_clear_current(wpa_s->wpa);
}
@@ -691,13 +695,7 @@
*/
void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
{
- int i, max;
-
-#ifdef CONFIG_IEEE80211W
- max = 6;
-#else /* CONFIG_IEEE80211W */
- max = 4;
-#endif /* CONFIG_IEEE80211W */
+ int i, max = 6;
/* MLME-DELETEKEYS.request */
for (i = 0; i < max; i++) {
@@ -846,6 +844,9 @@
enum wpa_states state)
{
enum wpa_states old_state = wpa_s->wpa_state;
+#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
+ Boolean update_fils_connect_params = FALSE;
+#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
wpa_supplicant_state_txt(wpa_s->wpa_state),
@@ -943,8 +944,12 @@
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
if (!fils_hlp_sent && ssid && ssid->eap.erp)
- wpas_update_fils_connect_params(wpa_s);
+ update_fils_connect_params = TRUE;
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
+#ifdef CONFIG_OWE
+ if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_OWE))
+ wpas_update_owe_connect_params(wpa_s);
+#endif /* CONFIG_OWE */
} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
state == WPA_ASSOCIATED) {
wpa_s->new_connection = 1;
@@ -984,7 +989,15 @@
if (wpa_s->wpa_state == WPA_COMPLETED ||
old_state == WPA_COMPLETED)
wpas_notify_auth_changed(wpa_s);
+#ifdef CONFIG_DPP2
+ if (wpa_s->wpa_state == WPA_COMPLETED)
+ wpas_dpp_connected(wpa_s);
+#endif /* CONFIG_DPP2 */
}
+#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
+ if (update_fils_connect_params)
+ wpas_update_fils_connect_params(wpa_s);
+#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
}
@@ -1180,7 +1193,6 @@
return -1;
}
-#ifdef CONFIG_IEEE80211W
if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
@@ -1188,7 +1200,6 @@
"reject");
return -1;
}
-#endif /* CONFIG_IEEE80211W */
return 0;
}
@@ -1226,14 +1237,16 @@
{
struct wpa_ie_data ie;
int sel, proto;
- const u8 *bss_wpa, *bss_rsn, *bss_osen;
+ const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen;
if (bss) {
bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
- } else
- bss_wpa = bss_rsn = bss_osen = NULL;
+ } else {
+ bss_wpa = bss_rsn = bss_rsnx = bss_osen = NULL;
+ }
if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
@@ -1313,7 +1326,6 @@
ie.group_cipher = ssid->group_cipher;
ie.pairwise_cipher = ssid->pairwise_cipher;
ie.key_mgmt = ssid->key_mgmt;
-#ifdef CONFIG_IEEE80211W
ie.mgmt_group_cipher = 0;
if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
if (ssid->group_mgmt_cipher &
@@ -1332,7 +1344,6 @@
ie.mgmt_group_cipher =
WPA_CIPHER_AES_128_CMAC;
}
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_OWE
if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
!ssid->owe_only &&
@@ -1352,12 +1363,10 @@
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
"pairwise %d key_mgmt %d proto %d",
ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
-#ifdef CONFIG_IEEE80211W
if (ssid->ieee80211w) {
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
ie.mgmt_group_cipher);
}
-#endif /* CONFIG_IEEE80211W */
wpa_s->wpa_proto = proto;
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
@@ -1368,7 +1377,9 @@
if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
bss_wpa ? 2 + bss_wpa[1] : 0) ||
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
- bss_rsn ? 2 + bss_rsn[1] : 0))
+ bss_rsn ? 2 + bss_rsn[1] : 0) ||
+ wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx,
+ bss_rsnx ? 2 + bss_rsnx[1] : 0))
return -1;
}
@@ -1414,7 +1425,8 @@
if (0) {
#ifdef CONFIG_IEEE80211R
#ifdef CONFIG_SHA384
- } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
+ } else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
+ os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
wpa_dbg(wpa_s, MSG_DEBUG,
"WPA: using KEY_MGMT FT/802.1X-SHA384");
@@ -1457,7 +1469,8 @@
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA256");
#endif /* CONFIG_FILS */
#ifdef CONFIG_IEEE80211R
- } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
+ } else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X) &&
+ os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
if (!ssid->ft_eap_pmksa_caching &&
@@ -1487,7 +1500,6 @@
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
} else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
wpa_dbg(wpa_s, MSG_DEBUG,
@@ -1496,7 +1508,6 @@
wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
wpa_dbg(wpa_s, MSG_DEBUG,
"WPA: using KEY_MGMT PSK with SHA256");
-#endif /* CONFIG_IEEE80211W */
} else if (sel & WPA_KEY_MGMT_IEEE8021X) {
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
@@ -1527,7 +1538,13 @@
wpa_s->pairwise_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
-#ifdef CONFIG_IEEE80211W
+ if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
+ wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "RSN: Management frame protection required but the selected AP does not enable it");
+ return -1;
+ }
+
sel = ie.mgmt_group_cipher;
if (ssid->group_mgmt_cipher)
sel &= ssid->group_mgmt_cipher;
@@ -1561,16 +1578,23 @@
wpa_s->mgmt_group_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
wpas_get_ssid_pmf(wpa_s, ssid));
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_OCV
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
#endif /* CONFIG_OCV */
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, wpa_s->conf->sae_pwe);
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
return -1;
}
+ wpa_s->rsnxe_len = sizeof(wpa_s->rsnxe);
+ if (wpa_sm_set_assoc_rsnxe_default(wpa_s->wpa, wpa_s->rsnxe,
+ &wpa_s->rsnxe_len)) {
+ wpa_msg(wpa_s, MSG_WARNING, "RSN: Failed to generate RSNXE");
+ return -1;
+ }
+
if (0) {
#ifdef CONFIG_DPP
} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
@@ -1712,7 +1736,7 @@
case 2: /* Bits 16-23 */
#ifdef CONFIG_WNM
*pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
- if (!wpa_s->conf->disable_btm)
+ if (!wpa_s->disable_mbo_oce && !wpa_s->conf->disable_btm)
*pos |= 0x08; /* Bit 19 - BSS Transition */
#endif /* CONFIG_WNM */
break;
@@ -1919,6 +1943,36 @@
}
+static void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid)
+{
+#ifdef CONFIG_SAE
+ int *groups = conf->sae_groups;
+ int default_groups[] = { 19, 20, 21, 0 };
+ const char *password;
+
+ if (!groups || groups[0] <= 0)
+ groups = default_groups;
+
+ password = ssid->sae_password;
+ if (!password)
+ password = ssid->passphrase;
+
+ if (conf->sae_pwe == 0 || !password) {
+ /* PT derivation not needed */
+ sae_deinit_pt(ssid->pt);
+ ssid->pt = NULL;
+ return;
+ }
+
+ if (ssid->pt)
+ return; /* PT already derived */
+ ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
+ (const u8 *) password, os_strlen(password),
+ ssid->sae_password_id);
+#endif /* CONFIG_SAE */
+}
+
+
static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
/**
@@ -1965,6 +2019,14 @@
} else if (wpa_s->current_bss && wpa_s->current_bss != bss) {
os_get_reltime(&wpa_s->roam_start);
}
+ } else {
+#ifdef CONFIG_SAE
+#ifdef CONFIG_SME
+ os_free(wpa_s->sme.sae_rejected_groups);
+ wpa_s->sme.sae_rejected_groups = NULL;
+#endif /* CONFIG_SME */
+ wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+#endif /* CONFIG_SAE */
}
if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
@@ -2066,6 +2128,10 @@
bss->ie_len);
#endif /* CONFIG_TDLS */
+#ifdef CONFIG_MBO
+ wpas_mbo_check_pmf(wpa_s, bss, ssid);
+#endif /* CONFIG_MBO */
+
if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
ssid->mode == WPAS_MODE_INFRA) {
sme_authenticate(wpa_s, bss, ssid);
@@ -2154,6 +2220,7 @@
struct hostapd_freq_params vht_freq;
int chwidth, seg0, seg1;
u32 vht_caps = 0;
+ int is_24ghz;
freq->freq = ssid->frequency;
@@ -2205,8 +2272,8 @@
if (!mode)
return;
- /* HE can work without HT + VHT */
- freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
+ is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
+ hw_mode == HOSTAPD_MODE_IEEE80211B;
#ifdef CONFIG_HT_OVERRIDES
if (ssid->disable_ht) {
@@ -2219,6 +2286,10 @@
if (!freq->ht_enabled)
return;
+ /* Allow HE on 2.4 GHz without VHT: see nl80211_put_freq_params() */
+ if (is_24ghz)
+ freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
+
/* Setup higher BW only for 5 GHz */
if (mode->mode != HOSTAPD_MODE_IEEE80211A)
return;
@@ -2339,6 +2410,9 @@
if (!vht_freq.vht_enabled)
return;
+ /* Enable HE for VHT */
+ vht_freq.he_enabled = mode->he_capab[ieee80211_mode].he_supported;
+
/* setup center_freq1, bandwidth */
for (j = 0; j < ARRAY_SIZE(vht80); j++) {
if (freq->channel >= vht80[j] &&
@@ -2413,7 +2487,8 @@
}
if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
- freq->channel, freq->ht_enabled,
+ freq->channel, ssid->enable_edmg,
+ ssid->edmg_channel, freq->ht_enabled,
vht_freq.vht_enabled, freq->he_enabled,
freq->sec_channel_offset,
chwidth, seg0, seg1, vht_caps,
@@ -2816,7 +2891,7 @@
#ifdef CONFIG_MBO
mbo_ie = bss ? wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE) : NULL;
- if (mbo_ie) {
+ if (!wpa_s->disable_mbo_oce && mbo_ie) {
int len;
len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
@@ -2931,6 +3006,12 @@
}
#endif /* CONFIG_IEEE80211R */
+ if (wpa_s->rsnxe_len > 0 &&
+ wpa_s->rsnxe_len <= max_wpa_ie_len - wpa_ie_len) {
+ os_memcpy(wpa_ie + wpa_ie_len, wpa_s->rsnxe, wpa_s->rsnxe_len);
+ wpa_ie_len += wpa_s->rsnxe_len;
+ }
+
if (ssid->multi_ap_backhaul_sta) {
size_t multi_ap_ie_len;
@@ -2956,6 +3037,24 @@
}
+#ifdef CONFIG_OWE
+static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_driver_associate_params params;
+ u8 *wpa_ie;
+
+ os_memset(¶ms, 0, sizeof(params));
+ wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
+ wpa_s->current_ssid, ¶ms, NULL);
+ if (!wpa_ie)
+ return;
+
+ wpa_drv_update_connect_params(wpa_s, ¶ms, WPA_DRV_UPDATE_ASSOC_IES);
+ os_free(wpa_ie);
+}
+#endif /* CONFIG_OWE */
+
+
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s)
{
@@ -2984,6 +3083,117 @@
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
+static u8 wpa_ie_get_edmg_oper_chans(const u8 *edmg_ie)
+{
+ if (!edmg_ie || edmg_ie[1] < 6)
+ return 0;
+ return edmg_ie[EDMG_BSS_OPERATING_CHANNELS_OFFSET];
+}
+
+
+static u8 wpa_ie_get_edmg_oper_chan_width(const u8 *edmg_ie)
+{
+ if (!edmg_ie || edmg_ie[1] < 6)
+ return 0;
+ return edmg_ie[EDMG_OPERATING_CHANNEL_WIDTH_OFFSET];
+}
+
+
+/* Returns the intersection of two EDMG configurations.
+ * Note: The current implementation is limited to CB2 only (CB1 included),
+ * i.e., the implementation supports up to 2 contiguous channels.
+ * For supporting non-contiguous (aggregated) channels and for supporting
+ * CB3 and above, this function will need to be extended.
+ */
+static struct ieee80211_edmg_config
+get_edmg_intersection(struct ieee80211_edmg_config a,
+ struct ieee80211_edmg_config b,
+ u8 primary_channel)
+{
+ struct ieee80211_edmg_config result;
+ int i, contiguous = 0;
+ int max_contiguous = 0;
+
+ result.channels = b.channels & a.channels;
+ if (!result.channels) {
+ wpa_printf(MSG_DEBUG,
+ "EDMG not possible: cannot intersect channels 0x%x and 0x%x",
+ a.channels, b.channels);
+ goto fail;
+ }
+
+ if (!(result.channels & BIT(primary_channel - 1))) {
+ wpa_printf(MSG_DEBUG,
+ "EDMG not possible: the primary channel %d is not one of the intersected channels 0x%x",
+ primary_channel, result.channels);
+ goto fail;
+ }
+
+ /* Find max contiguous channels */
+ for (i = 0; i < 6; i++) {
+ if (result.channels & BIT(i))
+ contiguous++;
+ else
+ contiguous = 0;
+
+ if (contiguous > max_contiguous)
+ max_contiguous = contiguous;
+ }
+
+ /* Assuming AP and STA supports ONLY contiguous channels,
+ * bw configuration can have value between 4-7.
+ */
+ if ((b.bw_config < a.bw_config))
+ result.bw_config = b.bw_config;
+ else
+ result.bw_config = a.bw_config;
+
+ if ((max_contiguous >= 2 && result.bw_config < EDMG_BW_CONFIG_5) ||
+ (max_contiguous >= 1 && result.bw_config < EDMG_BW_CONFIG_4)) {
+ wpa_printf(MSG_DEBUG,
+ "EDMG not possible: not enough contiguous channels %d for supporting CB1 or CB2",
+ max_contiguous);
+ goto fail;
+ }
+
+ return result;
+
+fail:
+ result.channels = 0;
+ result.bw_config = 0;
+ return result;
+}
+
+
+static struct ieee80211_edmg_config
+get_supported_edmg(struct wpa_supplicant *wpa_s,
+ struct hostapd_freq_params *freq,
+ struct ieee80211_edmg_config request_edmg)
+{
+ enum hostapd_hw_mode hw_mode;
+ struct hostapd_hw_modes *mode = NULL;
+ u8 primary_channel;
+
+ if (!wpa_s->hw.modes)
+ goto fail;
+
+ hw_mode = ieee80211_freq_to_chan(freq->freq, &primary_channel);
+ if (hw_mode == NUM_HOSTAPD_MODES)
+ goto fail;
+
+ mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode);
+ if (!mode)
+ goto fail;
+
+ return get_edmg_intersection(mode->edmg, request_edmg, primary_channel);
+
+fail:
+ request_edmg.channels = 0;
+ request_edmg.bw_config = 0;
+ return request_edmg;
+}
+
+
#ifdef CONFIG_MBO
void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s)
{
@@ -3019,6 +3229,7 @@
struct wpa_ssid *ssid = cwork->ssid;
struct wpa_supplicant *wpa_s = work->wpa_s;
u8 *wpa_ie;
+ const u8 *edmg_ie_oper;
int use_crypt, ret, i, bssid_changed;
unsigned int cipher_pairwise, cipher_group, cipher_group_mgmt;
struct wpa_driver_associate_params params;
@@ -3111,6 +3322,8 @@
/* Starting new association, so clear the possibly used WPA IE from the
* previous association. */
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+ wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
+ wpa_s->rsnxe_len = 0;
wpa_ie = wpas_populate_assoc_ies(wpa_s, bss, ssid, ¶ms, NULL);
if (!wpa_ie) {
@@ -3202,6 +3415,71 @@
params.beacon_int = wpa_s->conf->beacon_int;
}
+ if (bss && ssid->enable_edmg)
+ edmg_ie_oper = get_ie_ext((const u8 *) (bss + 1), bss->ie_len,
+ WLAN_EID_EXT_EDMG_OPERATION);
+ else
+ edmg_ie_oper = NULL;
+
+ if (edmg_ie_oper) {
+ params.freq.edmg.channels =
+ wpa_ie_get_edmg_oper_chans(edmg_ie_oper);
+ params.freq.edmg.bw_config =
+ wpa_ie_get_edmg_oper_chan_width(edmg_ie_oper);
+ wpa_printf(MSG_DEBUG,
+ "AP supports EDMG channels 0x%x, bw_config %d",
+ params.freq.edmg.channels,
+ params.freq.edmg.bw_config);
+
+ /* User may ask for specific EDMG channel for EDMG connection
+ * (must be supported by AP)
+ */
+ if (ssid->edmg_channel) {
+ struct ieee80211_edmg_config configured_edmg;
+ enum hostapd_hw_mode hw_mode;
+ u8 primary_channel;
+
+ hw_mode = ieee80211_freq_to_chan(bss->freq,
+ &primary_channel);
+ if (hw_mode == NUM_HOSTAPD_MODES)
+ goto edmg_fail;
+
+ hostapd_encode_edmg_chan(ssid->enable_edmg,
+ ssid->edmg_channel,
+ primary_channel,
+ &configured_edmg);
+
+ if (ieee802_edmg_is_allowed(params.freq.edmg,
+ configured_edmg)) {
+ params.freq.edmg = configured_edmg;
+ wpa_printf(MSG_DEBUG,
+ "Use EDMG channel %d for connection",
+ ssid->edmg_channel);
+ } else {
+ edmg_fail:
+ params.freq.edmg.channels = 0;
+ params.freq.edmg.bw_config = 0;
+ wpa_printf(MSG_WARNING,
+ "EDMG channel %d not supported by AP, fallback to DMG",
+ ssid->edmg_channel);
+ }
+ }
+
+ if (params.freq.edmg.channels) {
+ wpa_printf(MSG_DEBUG,
+ "EDMG before: channels 0x%x, bw_config %d",
+ params.freq.edmg.channels,
+ params.freq.edmg.bw_config);
+ params.freq.edmg = get_supported_edmg(wpa_s,
+ ¶ms.freq,
+ params.freq.edmg);
+ wpa_printf(MSG_DEBUG,
+ "EDMG after: channels 0x%x, bw_config %d",
+ params.freq.edmg.channels,
+ params.freq.edmg.bw_config);
+ }
+ }
+
params.pairwise_suite = cipher_pairwise;
params.group_suite = cipher_group;
params.mgmt_group_suite = cipher_group_mgmt;
@@ -3230,7 +3508,7 @@
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192))
- params.req_key_mgmt_offload = 1;
+ params.req_handshake_offload = 1;
if (wpa_s->conf->key_mgmt_offload) {
if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
@@ -3252,7 +3530,6 @@
params.drop_unencrypted = use_crypt;
-#ifdef CONFIG_IEEE80211W
params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
@@ -3271,7 +3548,6 @@
#endif /* CONFIG_OWE */
}
}
-#endif /* CONFIG_IEEE80211W */
params.p2p = ssid->p2p_group;
@@ -3764,9 +4040,15 @@
wpa_s->disconnected = 0;
wpa_s->reassociate = 1;
+#if defined(CONFIG_SAE) && defined(CONFIG_SME)
+ os_free(wpa_s->sme.sae_rejected_groups);
+ wpa_s->sme.sae_rejected_groups = NULL;
+#endif /* CONFIG_SAE && CONFIG_SME */
wpa_s->last_owe_group = 0;
- if (ssid)
+ if (ssid) {
ssid->owe_transition_bss_select_count = 0;
+ wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+ }
if (wpa_s->connect_without_scan ||
wpa_supplicant_fast_associate(wpa_s) != 1) {
@@ -4345,6 +4627,11 @@
wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
wpas_wps_update_mac_addr(wpa_s);
+#ifdef CONFIG_FST
+ if (wpa_s->fst)
+ fst_update_mac_addr(wpa_s->fst, wpa_s->own_addr);
+#endif /* CONFIG_FST */
+
return 0;
}
@@ -5953,7 +6240,7 @@
hs20_init(wpa_s);
#endif /* CONFIG_HS20 */
#ifdef CONFIG_MBO
- if (wpa_s->conf->oce) {
+ if (!wpa_s->disable_mbo_oce && wpa_s->conf->oce) {
if ((wpa_s->conf->oce & OCE_STA) &&
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA))
wpa_s->enable_oce = OCE_STA;
@@ -6051,6 +6338,7 @@
}
os_free(wpa_s->ssids_from_scan_req);
+ os_free(wpa_s->last_scan_freqs);
os_free(wpa_s);
}
@@ -6920,8 +7208,8 @@
wpa_s->reassociate = 1;
break;
case WPA_CTRL_REQ_EAP_PIN:
- str_clear_free(eap->pin);
- eap->pin = os_strdup(value);
+ str_clear_free(eap->cert.pin);
+ eap->cert.pin = os_strdup(value);
eap->pending_req_pin = 0;
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
@@ -6935,8 +7223,8 @@
eap->pending_req_otp_len = 0;
break;
case WPA_CTRL_REQ_EAP_PASSPHRASE:
- str_clear_free(eap->private_key_passwd);
- eap->private_key_passwd = os_strdup(value);
+ str_clear_free(eap->cert.private_key_passwd);
+ eap->cert.private_key_passwd = os_strdup(value);
eap->pending_req_passphrase = 0;
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
@@ -7023,7 +7311,6 @@
int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
{
-#ifdef CONFIG_IEEE80211W
if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
!(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
@@ -7052,9 +7339,6 @@
}
return ssid->ieee80211w;
-#else /* CONFIG_IEEE80211W */
- return NO_MGMT_FRAME_PROTECTION;
-#endif /* CONFIG_IEEE80211W */
}
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 1159bdc..ba511b9 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -311,6 +311,26 @@
# by executing the WPS protocol.
#wps_priority=0
+# Device Provisioning Protocol (DPP) parameters
+#
+# How to process DPP configuration
+# 0 = report received configuration to an external program for
+# processing; do not generate any network profile internally (default)
+# 1 = report received configuration to an external program and generate
+# a network profile internally, but do not automatically connect
+# to the created (disabled) profile; the network profile id is
+# reported to external programs
+# 2 = report received configuration to an external program, generate
+# a network profile internally, try to connect to the created
+# profile automatically
+#dpp_config_processing=0
+#
+# Name for Enrollee's DPP Configuration Request
+#dpp_name=Test
+#
+# MUD URL for Enrollee's DPP Configuration Request (optional)
+#dpp_mud_url=https://example.com/mud
+
# Maximum number of BSS entries to keep in memory
# Default: 200
# This can be used to limit memory use on the BSS entries (cached scan
@@ -405,6 +425,14 @@
# since all implementations are required to support group 19.
#sae_groups=19 20 21
+# SAE mechanism for PWE derivation
+# 0 = hunting-and-pecking loop only (default)
+# 1 = hash-to-element only
+# 2 = both hunting-and-pecking loop and hash-to-element enabled
+# Note: The default value is likely to change from 0 to 2 once the new
+# hash-to-element mechanism has received more interoperability testing.
+#sae_pwe=0
+
# Default value for DTIM period (if not overridden in network block)
#dtim_period=2
@@ -1323,6 +1351,12 @@
# certificate. See altsubject_match documentation for more details.
# domain_suffix_match2: Constraint for server domain name. See
# domain_suffix_match for more details.
+# ocsp2: See ocsp for more details.
+#
+# Separate machine credentials can be configured for EAP-TEAP Phase 2 with
+# "machine_" prefix (e.g., "machine_identity") in the configuration parameters.
+# See the parameters without that prefix for more details on the meaning and
+# format of each such parameter.
#
# fragment_size: Maximum EAP fragment size in bytes (default 1398).
# This value limits the fragment size for EAP methods that support
@@ -1522,6 +1556,16 @@
# Set to 1 to disable BSS transition management
#disable_btm=0
+# Enable EDMG capability in STA/AP mode, default value is false
+#enable_edmg=1
+
+# This value is used to configure the channel bonding feature.
+# Default value is 0.
+# Relevant only if enable_edmg is true
+# In AP mode it defines the EDMG channel to use for AP operation.
+# In STA mode it defines the EDMG channel for connection (if supported by AP).
+#edmg_channel=9
+
# Example blocks:
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index e59cf30..c5d2535 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -614,6 +614,9 @@
int eapol_received; /* number of EAPOL packets received after the
* previous association event */
+ u8 rsnxe[20];
+ size_t rsnxe_len;
+
struct scard_data *scard;
char imsi[20];
int mnc_len;
@@ -700,6 +703,10 @@
struct wpa_ssid_value *ssids_from_scan_req;
unsigned int num_ssids_from_scan_req;
+ int *last_scan_freqs;
+ unsigned int num_last_scan_freqs;
+ unsigned int suitable_network;
+ unsigned int no_suitable_network;
u64 drv_flags;
unsigned int drv_enc;
@@ -752,6 +759,7 @@
unsigned int connection_ht:1;
unsigned int connection_vht:1;
unsigned int connection_he:1;
+ unsigned int disable_mbo_oce:1;
struct os_reltime last_mac_addr_change;
int last_mac_addr_style;
@@ -805,6 +813,7 @@
u8 ext_auth_bssid[ETH_ALEN];
u8 ext_auth_ssid[SSID_MAX_LEN];
size_t ext_auth_ssid_len;
+ int *sae_rejected_groups;
#endif /* CONFIG_SAE */
} sme;
#endif /* CONFIG_SME */
@@ -1239,6 +1248,8 @@
unsigned int dpp_resp_wait_time;
unsigned int dpp_resp_max_tries;
unsigned int dpp_resp_retry_time;
+ u8 dpp_last_ssid[SSID_MAX_LEN];
+ size_t dpp_last_ssid_len;
#ifdef CONFIG_DPP2
struct dpp_pfs *dpp_pfs;
#endif /* CONFIG_DPP2 */
@@ -1256,6 +1267,7 @@
unsigned int ieee80211ac:1;
unsigned int enabled_4addr_mode:1;
unsigned int multi_bss_support:1;
+ unsigned int drv_authorized_port:1;
};
@@ -1391,6 +1403,8 @@
int add_oce_capa);
const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr);
const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr);
+void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ struct wpa_ssid *ssid);
const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len,
enum mbo_attr_id attr);
int wpas_mbo_update_non_pref_chan(struct wpa_supplicant *wpa_s,
@@ -1414,11 +1428,12 @@
NOT_ALLOWED, NO_IR, ALLOWED
};
-enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 channel,
- u8 bw);
+enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
+ u8 channel, u8 bw);
size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
int freq, u8 *pos, size_t len);
+int * wpas_supp_op_classes(struct wpa_supplicant *wpa_s);
int wpas_enable_mac_addr_randomization(struct wpa_supplicant *wpa_s,
unsigned int type, const u8 *addr,
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 62af7f6..d80b8f2 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -396,6 +396,10 @@
ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
ret = -1;
+
+ ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX);
+ if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
+ ret = -1;
} else {
ret = -1;
}
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 5da8154..f51340f 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -533,9 +533,7 @@
if (wpa_s->conf->wps_cred_add_sae &&
cred->key_len != 2 * PMK_LEN) {
ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
-#ifdef CONFIG_IEEE80211W
ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
-#endif /* CONFIG_IEEE80211W */
}
ssid->proto = WPA_PROTO_RSN;
break;
@@ -2691,7 +2689,7 @@
(attr.rf_bands == NULL ||
*attr.rf_bands & WPS_RF_50GHZ))
freq = 5000 + 5 * chan;
- else if (chan >= 1 && chan <= 4 &&
+ else if (chan >= 1 && chan <= 6 &&
(attr.rf_bands == NULL ||
*attr.rf_bands & WPS_RF_60GHZ))
freq = 56160 + 2160 * chan;