mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 02:29:01 +00:00
hostapd: Update to version 2.8 (2019-04-21)
This also syncs the configuration files with the default configuration
files, but no extra options are activated or deactivated.
The mesh patches were partially merged into hostapd 2.8, the remaining
patches were extracted from patchwork and are now applied by OpenWrt.
The patches still have open questions which are not fixed by the author.
They were taken from this page:
https://patchwork.ozlabs.org/project/hostap/list/?series=62725&state=*
The changes in 007-mesh-apply-channel-attributes-before-running-Mesh.patch
where first applied to hostapd, but later reverted in hostapd commit
3e949655ccc5 because they caused memory leaks.
The size of the ipkgs increase a bit (between 1.3% and 2.3%):
old 2018-12-02 (2.7):
283337 wpad-basic_2018-12-02-c2c6c01b-11_mipsel_24kc.ipk
252857 wpad-mini_2018-12-02-c2c6c01b-11_mipsel_24kc.ipk
417473 wpad-openssl_2018-12-02-c2c6c01b-11_mipsel_24kc.ipk
415105 wpad-wolfssl_2018-12-02-c2c6c01b-11_mipsel_24kc.ipk
new 2019-04-21 (2.8):
288264 wpad-basic_2019-04-21-63962824-1_mipsel_24kc.ipk
256188 wpad-mini_2019-04-21-63962824-1_mipsel_24kc.ipk
427475 wpad-openssl_2019-04-21-63962824-1_mipsel_24kc.ipk
423071 wpad-wolfssl_2019-04-21-63962824-1_mipsel_24kc.ipk
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Tested-by: Stefan Lippers-Hollmann <s.l-h@gmx.de>
(cherry picked from commit 8af79550e6
)
This commit is contained in:
parent
e1854815aa
commit
80b58a9db6
@ -7,13 +7,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=hostapd
|
||||
PKG_RELEASE:=11
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL:=http://w1.fi/hostap.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2018-12-02
|
||||
PKG_SOURCE_VERSION:=c2c6c01bb8b6fafc2074b46a53c4eab2c145ac6f
|
||||
PKG_MIRROR_HASH:=d381123fe42059b553d96122a03c35e7d1709153c3aaf10fa4e74fe59be243dd
|
||||
PKG_SOURCE_DATE:=2019-04-21
|
||||
PKG_SOURCE_VERSION:=63962824309bb428e5f73d9caae08fcb949fbe36
|
||||
PKG_MIRROR_HASH:=b31e09b22284785f84ee4d2dfc2b8fa94cad5d7375d957bf2862a50cb5bc1475
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
|
@ -50,13 +50,12 @@ CONFIG_DRIVER_NL80211=y
|
||||
# WPA2/IEEE 802.11i RSN pre-authentication
|
||||
CONFIG_RSN_PREAUTH=y
|
||||
|
||||
# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
|
||||
CONFIG_PEERKEY=y
|
||||
|
||||
# IEEE 802.11w (management frame protection)
|
||||
# Driver support is also needed for IEEE 802.11w.
|
||||
#CONFIG_IEEE80211W=y
|
||||
|
||||
# Support Operating Channel Validation
|
||||
#CONFIG_OCV=y
|
||||
|
||||
# Integrated EAP server
|
||||
#CONFIG_EAP=y
|
||||
|
||||
@ -253,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
|
||||
# requirements described above.
|
||||
CONFIG_NO_RANDOM_POOL=y
|
||||
|
||||
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||
#CONFIG_GETRANDOM=y
|
||||
|
||||
# Should we use poll instead of select? Select is used by default.
|
||||
#CONFIG_ELOOP_POLL=y
|
||||
|
||||
@ -360,8 +364,6 @@ CONFIG_TLS=internal
|
||||
#CONFIG_TAXONOMY=y
|
||||
|
||||
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||
# Note: This is an experimental and not yet complete implementation. This
|
||||
# should not be enabled for production use.
|
||||
#CONFIG_FILS=y
|
||||
# FILS shared key authentication with PFS
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
@ -374,6 +376,10 @@ CONFIG_TLS=internal
|
||||
# Experimental implementation of draft-harkins-owe-07.txt
|
||||
#CONFIG_OWE=y
|
||||
|
||||
# Override default value for the wpa_disable_eapol_key_retries configuration
|
||||
# parameter. See that parameter in hostapd.conf for more details.
|
||||
#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
|
||||
|
||||
# uBus IPC/RPC System
|
||||
# Services can connect to the bus and provide methods
|
||||
# that can be called by other services or clients.
|
||||
|
@ -53,6 +53,9 @@ CONFIG_RSN_PREAUTH=y
|
||||
# IEEE 802.11w (management frame protection)
|
||||
#CONFIG_IEEE80211W=y
|
||||
|
||||
# Support Operating Channel Validation
|
||||
#CONFIG_OCV=y
|
||||
|
||||
# Integrated EAP server
|
||||
CONFIG_EAP=y
|
||||
|
||||
@ -249,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
|
||||
# requirements described above.
|
||||
CONFIG_NO_RANDOM_POOL=y
|
||||
|
||||
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||
#CONFIG_GETRANDOM=y
|
||||
|
||||
# Should we use poll instead of select? Select is used by default.
|
||||
#CONFIG_ELOOP_POLL=y
|
||||
|
||||
@ -356,8 +364,6 @@ CONFIG_INTERNAL_LIBTOMMATH=y
|
||||
CONFIG_TAXONOMY=y
|
||||
|
||||
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||
# Note: This is an experimental and not yet complete implementation. This
|
||||
# should not be enabled for production use.
|
||||
#CONFIG_FILS=y
|
||||
# FILS shared key authentication with PFS
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
|
@ -53,6 +53,9 @@ CONFIG_RSN_PREAUTH=y
|
||||
# IEEE 802.11w (management frame protection)
|
||||
#CONFIG_IEEE80211W=y
|
||||
|
||||
# Support Operating Channel Validation
|
||||
#CONFIG_OCV=y
|
||||
|
||||
# Integrated EAP server
|
||||
#CONFIG_EAP=y
|
||||
|
||||
@ -249,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
|
||||
# requirements described above.
|
||||
CONFIG_NO_RANDOM_POOL=y
|
||||
|
||||
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||
#CONFIG_GETRANDOM=y
|
||||
|
||||
# Should we use poll instead of select? Select is used by default.
|
||||
#CONFIG_ELOOP_POLL=y
|
||||
|
||||
@ -356,8 +364,6 @@ CONFIG_TLS=internal
|
||||
#CONFIG_TAXONOMY=y
|
||||
|
||||
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||
# Note: This is an experimental and not yet complete implementation. This
|
||||
# should not be enabled for production use.
|
||||
#CONFIG_FILS=y
|
||||
# FILS shared key authentication with PFS
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
|
@ -73,6 +73,12 @@ CONFIG_DRIVER_NL80211=y
|
||||
# Driver interface for wired Ethernet drivers
|
||||
CONFIG_DRIVER_WIRED=y
|
||||
|
||||
# Driver interface for MACsec capable Qualcomm Atheros drivers
|
||||
#CONFIG_DRIVER_MACSEC_QCA=y
|
||||
|
||||
# Driver interface for Linux MACsec drivers
|
||||
#CONFIG_DRIVER_MACSEC_LINUX=y
|
||||
|
||||
# Driver interface for the Broadcom RoboSwitch family
|
||||
#CONFIG_DRIVER_ROBOSWITCH=y
|
||||
|
||||
@ -83,8 +89,8 @@ CONFIG_DRIVER_WIRED=y
|
||||
#LIBS += -lsocket -ldlpi -lnsl
|
||||
#LIBS_c += -lsocket
|
||||
|
||||
# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
|
||||
# included)
|
||||
# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
|
||||
# MACsec is included)
|
||||
#CONFIG_IEEE8021X_EAPOL=y
|
||||
|
||||
# EAP-MD5
|
||||
@ -103,9 +109,6 @@ CONFIG_DRIVER_WIRED=y
|
||||
#CONFIG_EAP_TTLS=y
|
||||
|
||||
# EAP-FAST
|
||||
# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
|
||||
# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
|
||||
# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
|
||||
#CONFIG_EAP_FAST=y
|
||||
|
||||
# EAP-GTC
|
||||
@ -166,6 +169,9 @@ CONFIG_DRIVER_WIRED=y
|
||||
# EAP-EKE
|
||||
#CONFIG_EAP_EKE=y
|
||||
|
||||
# MACsec
|
||||
#CONFIG_MACSEC=y
|
||||
|
||||
# PKCS#12 (PFX) support (used to read private key and certificate file from
|
||||
# a file that usually has extension .p12 or .pfx)
|
||||
#CONFIG_PKCS12=y
|
||||
@ -226,6 +232,9 @@ CONFIG_CTRL_IFACE=y
|
||||
# wpa_passphrase). This saves about 0.5 kB in code size.
|
||||
#CONFIG_NO_WPA_PASSPHRASE=y
|
||||
|
||||
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
|
||||
#CONFIG_SAE=y
|
||||
|
||||
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
|
||||
# This can be used if ap_scan=1 mode is never enabled.
|
||||
#CONFIG_NO_SCAN_PROCESSING=y
|
||||
@ -288,13 +297,13 @@ CONFIG_BACKEND=file
|
||||
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
|
||||
#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
|
||||
|
||||
# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
|
||||
#CONFIG_PEERKEY=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
|
||||
|
||||
# Select TLS implementation
|
||||
# openssl = OpenSSL (default)
|
||||
# gnutls = GnuTLS
|
||||
@ -343,10 +352,6 @@ CONFIG_TLS=internal
|
||||
#CONFIG_NDIS_EVENTS_INTEGRATED=y
|
||||
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
|
||||
|
||||
# Add support for old DBus control interface
|
||||
# (fi.epitest.hostap.WPASupplicant)
|
||||
#CONFIG_CTRL_IFACE_DBUS=y
|
||||
|
||||
# Add support for new DBus control interface
|
||||
# (fi.w1.hostap.wpa_supplicant1)
|
||||
#CONFIG_CTRL_IFACE_DBUS_NEW=y
|
||||
@ -378,10 +383,6 @@ CONFIG_TLS=internal
|
||||
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
|
||||
CONFIG_IEEE80211R=y
|
||||
|
||||
# IEEE Std 802.11r-2008 (Fast BSS Transition) for AP mode (implies
|
||||
# CONFIG_IEEE80211R).
|
||||
#CONFIG_IEEE80211R_AP=y
|
||||
|
||||
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
|
||||
#CONFIG_DEBUG_FILE=y
|
||||
|
||||
@ -456,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
|
||||
# that meet the requirements described above.
|
||||
CONFIG_NO_RANDOM_POOL=y
|
||||
|
||||
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||
#CONFIG_GETRANDOM=y
|
||||
|
||||
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
|
||||
#CONFIG_IEEE80211N=y
|
||||
|
||||
@ -497,8 +503,8 @@ CONFIG_NO_RANDOM_POOL=y
|
||||
# Enable TDLS support
|
||||
#CONFIG_TDLS=y
|
||||
|
||||
# Wi-Fi Direct
|
||||
# This can be used to enable Wi-Fi Direct extensions for P2P using an external
|
||||
# Wi-Fi Display
|
||||
# This can be used to enable Wi-Fi Display extensions for P2P using an external
|
||||
# program to control the additional information exchanges in the messages.
|
||||
#CONFIG_WIFI_DISPLAY=y
|
||||
|
||||
@ -559,8 +565,6 @@ CONFIG_NO_RANDOM_POOL=y
|
||||
#CONFIG_MBO=y
|
||||
|
||||
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||
# Note: This is an experimental and not yet complete implementation. This
|
||||
# should not be enabled for production use.
|
||||
#CONFIG_FILS=y
|
||||
# FILS shared key authentication with PFS
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
@ -592,6 +596,11 @@ CONFIG_NO_RANDOM_POOL=y
|
||||
# Experimental implementation of draft-harkins-owe-07.txt
|
||||
#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
|
||||
|
||||
# uBus IPC/RPC System
|
||||
# Services can connect to the bus and provide methods
|
||||
# that can be called by other services or clients.
|
||||
|
@ -109,9 +109,6 @@ CONFIG_EAP_PEAP=y
|
||||
CONFIG_EAP_TTLS=y
|
||||
|
||||
# EAP-FAST
|
||||
# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
|
||||
# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
|
||||
# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
|
||||
CONFIG_EAP_FAST=y
|
||||
|
||||
# EAP-GTC
|
||||
@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
|
||||
# wpa_passphrase). This saves about 0.5 kB in code size.
|
||||
#CONFIG_NO_WPA_PASSPHRASE=y
|
||||
|
||||
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
|
||||
#CONFIG_SAE=y
|
||||
|
||||
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
|
||||
# This can be used if ap_scan=1 mode is never enabled.
|
||||
#CONFIG_NO_SCAN_PROCESSING=y
|
||||
@ -301,6 +301,9 @@ CONFIG_BACKEND=file
|
||||
# Driver support is also needed for IEEE 802.11w.
|
||||
#CONFIG_IEEE80211W=y
|
||||
|
||||
# Support Operating Channel Validation
|
||||
#CONFIG_OCV=y
|
||||
|
||||
# Select TLS implementation
|
||||
# openssl = OpenSSL (default)
|
||||
# gnutls = GnuTLS
|
||||
@ -349,10 +352,6 @@ CONFIG_INTERNAL_LIBTOMMATH_FAST=y
|
||||
#CONFIG_NDIS_EVENTS_INTEGRATED=y
|
||||
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
|
||||
|
||||
# Add support for old DBus control interface
|
||||
# (fi.epitest.hostap.WPASupplicant)
|
||||
#CONFIG_CTRL_IFACE_DBUS=y
|
||||
|
||||
# Add support for new DBus control interface
|
||||
# (fi.w1.hostap.wpa_supplicant1)
|
||||
#CONFIG_CTRL_IFACE_DBUS_NEW=y
|
||||
@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
|
||||
# that meet the requirements described above.
|
||||
CONFIG_NO_RANDOM_POOL=y
|
||||
|
||||
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||
#CONFIG_GETRANDOM=y
|
||||
|
||||
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
|
||||
#CONFIG_IEEE80211N=y
|
||||
|
||||
@ -499,8 +503,8 @@ CONFIG_WNM=y
|
||||
# Enable TDLS support
|
||||
#CONFIG_TDLS=y
|
||||
|
||||
# Wi-Fi Direct
|
||||
# This can be used to enable Wi-Fi Direct extensions for P2P using an external
|
||||
# Wi-Fi Display
|
||||
# This can be used to enable Wi-Fi Display extensions for P2P using an external
|
||||
# program to control the additional information exchanges in the messages.
|
||||
#CONFIG_WIFI_DISPLAY=y
|
||||
|
||||
@ -561,8 +565,6 @@ CONFIG_WNM=y
|
||||
#CONFIG_MBO=y
|
||||
|
||||
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||
# Note: This is an experimental and not yet complete implementation. This
|
||||
# should not be enabled for production use.
|
||||
#CONFIG_FILS=y
|
||||
# FILS shared key authentication with PFS
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
@ -594,6 +596,11 @@ CONFIG_IBSS_RSN=y
|
||||
# Experimental implementation of draft-harkins-owe-07.txt
|
||||
#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
|
||||
|
||||
# uBus IPC/RPC System
|
||||
# Services can connect to the bus and provide methods
|
||||
# that can be called by other services or clients.
|
||||
|
@ -109,9 +109,6 @@ CONFIG_DRIVER_WIRED=y
|
||||
#CONFIG_EAP_TTLS=y
|
||||
|
||||
# EAP-FAST
|
||||
# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
|
||||
# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
|
||||
# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
|
||||
#CONFIG_EAP_FAST=y
|
||||
|
||||
# EAP-GTC
|
||||
@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
|
||||
# wpa_passphrase). This saves about 0.5 kB in code size.
|
||||
#CONFIG_NO_WPA_PASSPHRASE=y
|
||||
|
||||
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
|
||||
#CONFIG_SAE=y
|
||||
|
||||
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
|
||||
# This can be used if ap_scan=1 mode is never enabled.
|
||||
#CONFIG_NO_SCAN_PROCESSING=y
|
||||
@ -301,6 +301,9 @@ CONFIG_BACKEND=file
|
||||
# Driver support is also needed for IEEE 802.11w.
|
||||
#CONFIG_IEEE80211W=y
|
||||
|
||||
# Support Operating Channel Validation
|
||||
#CONFIG_OCV=y
|
||||
|
||||
# Select TLS implementation
|
||||
# openssl = OpenSSL (default)
|
||||
# gnutls = GnuTLS
|
||||
@ -349,10 +352,6 @@ CONFIG_TLS=internal
|
||||
#CONFIG_NDIS_EVENTS_INTEGRATED=y
|
||||
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
|
||||
|
||||
# Add support for old DBus control interface
|
||||
# (fi.epitest.hostap.WPASupplicant)
|
||||
#CONFIG_CTRL_IFACE_DBUS=y
|
||||
|
||||
# Add support for new DBus control interface
|
||||
# (fi.w1.hostap.wpa_supplicant1)
|
||||
#CONFIG_CTRL_IFACE_DBUS_NEW=y
|
||||
@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
|
||||
# that meet the requirements described above.
|
||||
CONFIG_NO_RANDOM_POOL=y
|
||||
|
||||
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||
#CONFIG_GETRANDOM=y
|
||||
|
||||
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
|
||||
#CONFIG_IEEE80211N=y
|
||||
|
||||
@ -499,8 +503,8 @@ CONFIG_NO_RANDOM_POOL=y
|
||||
# Enable TDLS support
|
||||
#CONFIG_TDLS=y
|
||||
|
||||
# Wi-Fi Direct
|
||||
# This can be used to enable Wi-Fi Direct extensions for P2P using an external
|
||||
# Wi-Fi Display
|
||||
# This can be used to enable Wi-Fi Display extensions for P2P using an external
|
||||
# program to control the additional information exchanges in the messages.
|
||||
#CONFIG_WIFI_DISPLAY=y
|
||||
|
||||
@ -561,8 +565,6 @@ CONFIG_NO_RANDOM_POOL=y
|
||||
#CONFIG_MBO=y
|
||||
|
||||
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||
# Note: This is an experimental and not yet complete implementation. This
|
||||
# should not be enabled for production use.
|
||||
#CONFIG_FILS=y
|
||||
# FILS shared key authentication with PFS
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
@ -594,6 +596,11 @@ CONFIG_NO_RANDOM_POOL=y
|
||||
# Experimental implementation of draft-harkins-owe-07.txt
|
||||
#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
|
||||
|
||||
# uBus IPC/RPC System
|
||||
# Services can connect to the bus and provide methods
|
||||
# that can be called by other services or clients.
|
||||
|
@ -109,9 +109,6 @@ CONFIG_EAP_PEAP=y
|
||||
CONFIG_EAP_TTLS=y
|
||||
|
||||
# EAP-FAST
|
||||
# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
|
||||
# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
|
||||
# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
|
||||
CONFIG_EAP_FAST=y
|
||||
|
||||
# EAP-GTC
|
||||
@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
|
||||
# wpa_passphrase). This saves about 0.5 kB in code size.
|
||||
#CONFIG_NO_WPA_PASSPHRASE=y
|
||||
|
||||
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
|
||||
#CONFIG_SAE=y
|
||||
|
||||
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
|
||||
# This can be used if ap_scan=1 mode is never enabled.
|
||||
#CONFIG_NO_SCAN_PROCESSING=y
|
||||
@ -301,6 +301,9 @@ CONFIG_BACKEND=file
|
||||
# Driver support is also needed for IEEE 802.11w.
|
||||
CONFIG_IEEE80211W=y
|
||||
|
||||
# Support Operating Channel Validation
|
||||
#CONFIG_OCV=y
|
||||
|
||||
# Select TLS implementation
|
||||
# openssl = OpenSSL (default)
|
||||
# gnutls = GnuTLS
|
||||
@ -349,10 +352,6 @@ CONFIG_INTERNAL_LIBTOMMATH_FAST=y
|
||||
#CONFIG_NDIS_EVENTS_INTEGRATED=y
|
||||
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
|
||||
|
||||
# Add support for old DBus control interface
|
||||
# (fi.epitest.hostap.WPASupplicant)
|
||||
#CONFIG_CTRL_IFACE_DBUS=y
|
||||
|
||||
# Add support for new DBus control interface
|
||||
# (fi.w1.hostap.wpa_supplicant1)
|
||||
#CONFIG_CTRL_IFACE_DBUS_NEW=y
|
||||
@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
|
||||
# that meet the requirements described above.
|
||||
CONFIG_NO_RANDOM_POOL=y
|
||||
|
||||
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||
#CONFIG_GETRANDOM=y
|
||||
|
||||
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
|
||||
#CONFIG_IEEE80211N=y
|
||||
|
||||
@ -499,8 +503,8 @@ CONFIG_P2P=y
|
||||
# Enable TDLS support
|
||||
#CONFIG_TDLS=y
|
||||
|
||||
# Wi-Fi Direct
|
||||
# This can be used to enable Wi-Fi Direct extensions for P2P using an external
|
||||
# Wi-Fi Display
|
||||
# This can be used to enable Wi-Fi Display extensions for P2P using an external
|
||||
# program to control the additional information exchanges in the messages.
|
||||
#CONFIG_WIFI_DISPLAY=y
|
||||
|
||||
@ -561,8 +565,6 @@ CONFIG_P2P=y
|
||||
#CONFIG_MBO=y
|
||||
|
||||
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||
# Note: This is an experimental and not yet complete implementation. This
|
||||
# should not be enabled for production use.
|
||||
#CONFIG_FILS=y
|
||||
# FILS shared key authentication with PFS
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
@ -594,6 +596,11 @@ CONFIG_IBSS_RSN=y
|
||||
# Experimental implementation of draft-harkins-owe-07.txt
|
||||
#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
|
||||
|
||||
# uBus IPC/RPC System
|
||||
# Services can connect to the bus and provide methods
|
||||
# that can be called by other services or clients.
|
||||
|
@ -1,211 +0,0 @@
|
||||
From 02ae4382f45f772e3630460459eb4e5af64e71b4 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:05 -0700
|
||||
Subject: [PATCH 01/18] mesh: factor out mesh join function
|
||||
|
||||
mesh join function consitss of 2 parts which are preparing
|
||||
configurations and sending join event to driver.
|
||||
Since physical mesh join event could happen either right
|
||||
after mesh configuration is done or after CAC is done
|
||||
in case of DFS channel is used, factor out the function
|
||||
into 2 parts to reduce redundant calls.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 119 ++++++++++++++++--------------
|
||||
wpa_supplicant/mesh.h | 1 +
|
||||
wpa_supplicant/wpa_supplicant_i.h | 1 +
|
||||
3 files changed, 67 insertions(+), 54 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -364,13 +364,48 @@ void wpa_supplicant_mesh_add_scan_ie(str
|
||||
}
|
||||
|
||||
|
||||
+void wpas_join_mesh(struct wpa_supplicant *wpa_s)
|
||||
+{
|
||||
+ struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
|
||||
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
|
||||
+ wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
|
||||
+ wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
|
||||
+ wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
|
||||
+ }
|
||||
+
|
||||
+ if (wpa_s->ifmsh) {
|
||||
+ params->ies = wpa_s->ifmsh->mconf->rsn_ie;
|
||||
+ params->ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
|
||||
+ params->basic_rates = wpa_s->ifmsh->basic_rates;
|
||||
+ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
|
||||
+ params->conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode;
|
||||
+ }
|
||||
+
|
||||
+ ret = wpa_drv_join_mesh(wpa_s, params);
|
||||
+ if (ret)
|
||||
+ wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d\n", ret);
|
||||
+
|
||||
+ /* hostapd sets the interface down until we associate */
|
||||
+ wpa_drv_set_operstate(wpa_s, 1);
|
||||
+
|
||||
+ if (!ret)
|
||||
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_ssid *ssid)
|
||||
{
|
||||
- struct wpa_driver_mesh_join_params params;
|
||||
+ struct wpa_driver_mesh_join_params *params =
|
||||
+ os_zalloc(sizeof(struct wpa_driver_mesh_join_params));
|
||||
int ret = 0;
|
||||
|
||||
- if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) {
|
||||
+ if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency || !params) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
@@ -381,22 +416,22 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
wpa_s->group_cipher = WPA_CIPHER_NONE;
|
||||
wpa_s->mgmt_group_cipher = 0;
|
||||
|
||||
- os_memset(¶ms, 0, sizeof(params));
|
||||
- params.meshid = ssid->ssid;
|
||||
- params.meshid_len = ssid->ssid_len;
|
||||
- ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq);
|
||||
- wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled;
|
||||
- wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled;
|
||||
- if (params.freq.ht_enabled && params.freq.sec_channel_offset)
|
||||
- ssid->ht40 = params.freq.sec_channel_offset;
|
||||
+ params->meshid = ssid->ssid;
|
||||
+ params->meshid_len = ssid->ssid_len;
|
||||
+ ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq);
|
||||
+ wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled;
|
||||
+ wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled;
|
||||
+ if (params->freq.ht_enabled && params->freq.sec_channel_offset)
|
||||
+ ssid->ht40 = params->freq.sec_channel_offset;
|
||||
+
|
||||
if (wpa_s->mesh_vht_enabled) {
|
||||
ssid->vht = 1;
|
||||
- switch (params.freq.bandwidth) {
|
||||
+ switch (params->freq.bandwidth) {
|
||||
case 80:
|
||||
- if (params.freq.center_freq2) {
|
||||
+ if (params->freq.center_freq2) {
|
||||
ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ;
|
||||
ssid->vht_center_freq2 =
|
||||
- params.freq.center_freq2;
|
||||
+ params->freq.center_freq2;
|
||||
} else {
|
||||
ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ;
|
||||
}
|
||||
@@ -410,67 +445,43 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
}
|
||||
}
|
||||
if (ssid->beacon_int > 0)
|
||||
- params.beacon_int = ssid->beacon_int;
|
||||
+ params->beacon_int = ssid->beacon_int;
|
||||
else if (wpa_s->conf->beacon_int > 0)
|
||||
- params.beacon_int = wpa_s->conf->beacon_int;
|
||||
+ params->beacon_int = wpa_s->conf->beacon_int;
|
||||
if (ssid->dtim_period > 0)
|
||||
- params.dtim_period = ssid->dtim_period;
|
||||
+ params->dtim_period = ssid->dtim_period;
|
||||
else if (wpa_s->conf->dtim_period > 0)
|
||||
- params.dtim_period = wpa_s->conf->dtim_period;
|
||||
- params.conf.max_peer_links = wpa_s->conf->max_peer_links;
|
||||
+ params->dtim_period = wpa_s->conf->dtim_period;
|
||||
+ params->conf.max_peer_links = wpa_s->conf->max_peer_links;
|
||||
if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) {
|
||||
- params.conf.rssi_threshold = ssid->mesh_rssi_threshold;
|
||||
- params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
|
||||
+ params->conf.rssi_threshold = ssid->mesh_rssi_threshold;
|
||||
+ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
|
||||
}
|
||||
|
||||
if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
|
||||
- params.flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
|
||||
- params.flags |= WPA_DRIVER_MESH_FLAG_AMPE;
|
||||
+ params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
|
||||
+ params->flags |= WPA_DRIVER_MESH_FLAG_AMPE;
|
||||
wpa_s->conf->user_mpm = 1;
|
||||
}
|
||||
|
||||
if (wpa_s->conf->user_mpm) {
|
||||
- params.flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
|
||||
- params.conf.auto_plinks = 0;
|
||||
+ params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
|
||||
+ params->conf.auto_plinks = 0;
|
||||
} else {
|
||||
- params.flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
|
||||
- params.conf.auto_plinks = 1;
|
||||
+ params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
|
||||
+ params->conf.auto_plinks = 1;
|
||||
}
|
||||
- params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
|
||||
+ params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
|
||||
|
||||
- if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms.freq)) {
|
||||
+ wpa_s->mesh_params = params;
|
||||
+ if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) {
|
||||
wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
|
||||
wpa_drv_leave_mesh(wpa_s);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
|
||||
- wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
|
||||
- wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
|
||||
- wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
|
||||
- }
|
||||
-
|
||||
- if (wpa_s->ifmsh) {
|
||||
- params.ies = wpa_s->ifmsh->mconf->rsn_ie;
|
||||
- params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
|
||||
- params.basic_rates = wpa_s->ifmsh->basic_rates;
|
||||
- params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
|
||||
- params.conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode;
|
||||
- }
|
||||
-
|
||||
- wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
|
||||
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
|
||||
- ret = wpa_drv_join_mesh(wpa_s, ¶ms);
|
||||
- if (ret)
|
||||
- wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
|
||||
-
|
||||
- /* hostapd sets the interface down until we associate */
|
||||
- wpa_drv_set_operstate(wpa_s, 1);
|
||||
-
|
||||
- if (!ret)
|
||||
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
|
||||
-
|
||||
+ wpas_join_mesh(wpa_s);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
--- a/wpa_supplicant/mesh.h
|
||||
+++ b/wpa_supplicant/mesh.h
|
||||
@@ -21,6 +21,7 @@ int wpas_mesh_add_interface(struct wpa_s
|
||||
int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
|
||||
int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||
int duration);
|
||||
+void wpas_join_mesh(struct wpa_supplicant *wpa_s);
|
||||
|
||||
#ifdef CONFIG_MESH
|
||||
|
||||
--- a/wpa_supplicant/wpa_supplicant_i.h
|
||||
+++ b/wpa_supplicant/wpa_supplicant_i.h
|
||||
@@ -814,6 +814,7 @@ struct wpa_supplicant {
|
||||
unsigned int mesh_if_created:1;
|
||||
unsigned int mesh_ht_enabled:1;
|
||||
unsigned int mesh_vht_enabled:1;
|
||||
+ struct wpa_driver_mesh_join_params *mesh_params;
|
||||
#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
|
||||
/* struct external_pmksa_cache::list */
|
||||
struct dl_list mesh_external_pmksa_cache;
|
@ -1,133 +0,0 @@
|
||||
From 89db76eeff6502dfa39b011962ec9d560ed4c2ee Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:06 -0700
|
||||
Subject: [PATCH 02/18] mesh: factor out rsn initialization
|
||||
|
||||
RSN initialization can be used in different phases
|
||||
if mesh initialization and mesh join don't happen
|
||||
in sequence such as DFS CAC is done in between,
|
||||
hence factor it out to help convering the case.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 84 +++++++++++++++++++++++++------------------
|
||||
wpa_supplicant/mesh.h | 1 +
|
||||
2 files changed, 50 insertions(+), 35 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -147,6 +147,53 @@ static void wpas_mesh_copy_groups(struct
|
||||
}
|
||||
|
||||
|
||||
+int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s)
|
||||
+{
|
||||
+ struct hostapd_iface *ifmsh = wpa_s->ifmsh;
|
||||
+ struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
|
||||
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
+ struct hostapd_data *bss = ifmsh->bss[0];
|
||||
+ static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
|
||||
+ const char *password;
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (mconf->security != MESH_CONF_SEC_NONE) {
|
||||
+ password = ssid->sae_password;
|
||||
+ if (!password)
|
||||
+ password = ssid->passphrase;
|
||||
+ if (!password) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "mesh: Passphrase for SAE not configured");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ bss->conf->wpa = ssid->proto;
|
||||
+ bss->conf->wpa_key_mgmt = ssid->key_mgmt;
|
||||
+
|
||||
+ if (wpa_s->conf->sae_groups &&
|
||||
+ wpa_s->conf->sae_groups[0] > 0) {
|
||||
+ wpas_mesh_copy_groups(bss, wpa_s);
|
||||
+ } else {
|
||||
+ bss->conf->sae_groups =
|
||||
+ os_memdup(default_groups,
|
||||
+ sizeof(default_groups));
|
||||
+ if (!bss->conf->sae_groups)
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ len = os_strlen(password);
|
||||
+ bss->conf->ssid.wpa_passphrase =
|
||||
+ dup_binstr(password, len);
|
||||
+
|
||||
+ wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
|
||||
+ if (!wpa_s->mesh_rsn)
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_ssid *ssid,
|
||||
struct hostapd_freq_params *freq)
|
||||
@@ -156,9 +203,6 @@ static int wpa_supplicant_mesh_init(stru
|
||||
struct hostapd_config *conf;
|
||||
struct mesh_conf *mconf;
|
||||
int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
|
||||
- static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
|
||||
- const char *password;
|
||||
- size_t len;
|
||||
int rate_len;
|
||||
int frequency;
|
||||
|
||||
@@ -292,38 +336,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (mconf->security != MESH_CONF_SEC_NONE) {
|
||||
- password = ssid->sae_password;
|
||||
- if (!password)
|
||||
- password = ssid->passphrase;
|
||||
- if (!password) {
|
||||
- wpa_printf(MSG_ERROR,
|
||||
- "mesh: Passphrase for SAE not configured");
|
||||
- goto out_free;
|
||||
- }
|
||||
-
|
||||
- bss->conf->wpa = ssid->proto;
|
||||
- bss->conf->wpa_key_mgmt = ssid->key_mgmt;
|
||||
-
|
||||
- if (wpa_s->conf->sae_groups &&
|
||||
- wpa_s->conf->sae_groups[0] > 0) {
|
||||
- wpas_mesh_copy_groups(bss, wpa_s);
|
||||
- } else {
|
||||
- bss->conf->sae_groups =
|
||||
- os_memdup(default_groups,
|
||||
- sizeof(default_groups));
|
||||
- if (!bss->conf->sae_groups)
|
||||
- goto out_free;
|
||||
- }
|
||||
-
|
||||
- len = os_strlen(password);
|
||||
- bss->conf->ssid.wpa_passphrase =
|
||||
- dup_binstr(password, len);
|
||||
-
|
||||
- wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
|
||||
- if (!wpa_s->mesh_rsn)
|
||||
- goto out_free;
|
||||
- }
|
||||
+ if (wpas_mesh_init_rsn(wpa_s))
|
||||
+ goto out_free;
|
||||
|
||||
wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
|
||||
|
||||
--- a/wpa_supplicant/mesh.h
|
||||
+++ b/wpa_supplicant/mesh.h
|
||||
@@ -22,6 +22,7 @@ int wpas_mesh_peer_remove(struct wpa_sup
|
||||
int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||
int duration);
|
||||
void wpas_join_mesh(struct wpa_supplicant *wpa_s);
|
||||
+int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s);
|
||||
|
||||
#ifdef CONFIG_MESH
|
||||
|
@ -1,41 +0,0 @@
|
||||
From 07bad5f256cbe8a4b45d32c5b43b870ee815fb42 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:07 -0700
|
||||
Subject: [PATCH 03/18] mesh: relocate RSN init function
|
||||
|
||||
RSN init function should work together with mesh join
|
||||
when it's used. Since mesh join could be called at different stage
|
||||
if DFS channel is used, relocate the function to mesh join.
|
||||
It is still the same call flows of mesh join before this changes
|
||||
if non-DFS channels are used, hence no side effect will occur.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -336,9 +336,6 @@ static int wpa_supplicant_mesh_init(stru
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (wpas_mesh_init_rsn(wpa_s))
|
||||
- goto out_free;
|
||||
-
|
||||
wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
|
||||
|
||||
return 0;
|
||||
@@ -384,6 +381,12 @@ void wpas_join_mesh(struct wpa_supplican
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
int ret = 0;
|
||||
|
||||
+ if (wpas_mesh_init_rsn(wpa_s)) {
|
||||
+ wpa_printf(MSG_ERROR, "Init RSN failed. Deinit mesh...");
|
||||
+ wpa_supplicant_mesh_deinit(wpa_s);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
|
||||
wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
|
||||
wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
|
@ -1,30 +1,103 @@
|
||||
From bd05de484bfa61def530d717c7234381f6b33cf7 Mon Sep 17 00:00:00 2001
|
||||
From c05ace7510ead96e72b97ce47b33f7b5865d6d36 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:08 -0700
|
||||
Subject: [PATCH 04/18] mesh: use setup completion callback to complete mesh
|
||||
join
|
||||
Date: Mon, 27 Aug 2018 14:28:38 -0700
|
||||
Subject: [PATCH 1/7] mesh: use setup completion callback to complete mesh join
|
||||
|
||||
mesh join function is the last function to be called during
|
||||
mesh join process, but it's been called a bit earlier than
|
||||
it's supposed to be, so that some mesh parameter values
|
||||
such as VHT capabilities not applied correct when mesh join
|
||||
is in process. Moreover current design of mesh join that is called
|
||||
directly after mesh initialization is not suitable for DFS channels
|
||||
to use, since mesh join process should be paused until DFS CAC is
|
||||
done and resumed once it's done.
|
||||
Using setup completion callback is how AP mode is using for DFS channels
|
||||
and mesh can use the same way.
|
||||
is in process.
|
||||
Moreover current design of mesh join that is called directly
|
||||
after mesh initialization isn't suitable for DFS channels to use,
|
||||
since mesh join process should be paused until DFS CAC is
|
||||
done and resumed after it's done.
|
||||
The callback will be called by hostapd_setup_interface_complete_sync.
|
||||
There is possiblity that completing mesh init fails, so add error
|
||||
handle codes.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 7 +++++--
|
||||
wpa_supplicant/mesh.h | 2 +-
|
||||
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||
src/ap/hostapd.c | 11 ++++++++++-
|
||||
wpa_supplicant/mesh.c | 13 +++++++------
|
||||
2 files changed, 17 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/src/ap/hostapd.c
|
||||
+++ b/src/ap/hostapd.c
|
||||
@@ -414,6 +414,8 @@ static void hostapd_free_hapd_data(struc
|
||||
#ifdef CONFIG_MESH
|
||||
wpabuf_free(hapd->mesh_pending_auth);
|
||||
hapd->mesh_pending_auth = NULL;
|
||||
+ /* handling setup failure is already done */
|
||||
+ hapd->setup_complete_cb = NULL;
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
hostapd_clean_rrm(hapd);
|
||||
@@ -1980,6 +1982,13 @@ dfs_offload:
|
||||
if (hapd->setup_complete_cb)
|
||||
hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
|
||||
|
||||
+#ifdef CONFIG_MESH
|
||||
+ if (delay_apply_cfg && !iface->mconf) {
|
||||
+ wpa_printf(MSG_ERROR, "Error while completing mesh init");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+#endif /* CONFIG_MESH */
|
||||
+
|
||||
wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
|
||||
iface->bss[0]->conf->iface);
|
||||
if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
|
||||
@@ -2123,7 +2132,7 @@ int hostapd_setup_interface(struct hosta
|
||||
ret = setup_interface(iface);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
|
||||
- iface->bss[0]->conf->iface);
|
||||
+ iface->conf ? iface->conf->bss[0]->iface : "N/A");
|
||||
return -1;
|
||||
}
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -217,6 +217,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -190,8 +190,9 @@ static int wpas_mesh_init_rsn(struct wpa
|
||||
}
|
||||
|
||||
|
||||
-static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
|
||||
+static void wpas_mesh_complete_cb(void *ctx)
|
||||
{
|
||||
+ struct wpa_supplicant *wpa_s = ctx;
|
||||
struct hostapd_iface *ifmsh = wpa_s->ifmsh;
|
||||
struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
@@ -200,7 +201,7 @@ static int wpas_mesh_complete(struct wpa
|
||||
if (!params || !ssid || !ifmsh) {
|
||||
wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
|
||||
__func__);
|
||||
- return -1;
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
|
||||
@@ -208,7 +209,7 @@ static int wpas_mesh_complete(struct wpa
|
||||
wpa_printf(MSG_ERROR,
|
||||
"mesh: RSN initialization failed - deinit mesh");
|
||||
wpa_supplicant_mesh_deinit(wpa_s);
|
||||
- return -1;
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
|
||||
@@ -234,8 +235,6 @@ static int wpas_mesh_complete(struct wpa
|
||||
|
||||
if (!ret)
|
||||
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
|
||||
-
|
||||
- return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -262,6 +261,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
if (!ifmsh)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -32,7 +105,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
ifmsh->drv_flags = wpa_s->drv_flags;
|
||||
ifmsh->num_bss = 1;
|
||||
ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
|
||||
@@ -234,6 +235,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -279,6 +279,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
bss->drv_priv = wpa_s->drv_priv;
|
||||
bss->iface = ifmsh;
|
||||
bss->mesh_sta_free_cb = mesh_mpm_free_sta;
|
||||
@ -41,33 +114,11 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
frequency = ssid->frequency;
|
||||
if (frequency != freq->freq &&
|
||||
frequency == freq->freq + freq->sec_channel_offset * 20) {
|
||||
@@ -375,8 +378,9 @@ void wpa_supplicant_mesh_add_scan_ie(str
|
||||
}
|
||||
|
||||
|
||||
-void wpas_join_mesh(struct wpa_supplicant *wpa_s)
|
||||
+void wpas_mesh_complete_cb(void *ctx)
|
||||
{
|
||||
+ struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)ctx;
|
||||
struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
int ret = 0;
|
||||
@@ -498,7 +502,6 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
@@ -517,7 +519,6 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
goto out;
|
||||
}
|
||||
|
||||
- wpas_join_mesh(wpa_s);
|
||||
- ret = wpas_mesh_complete(wpa_s);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
--- a/wpa_supplicant/mesh.h
|
||||
+++ b/wpa_supplicant/mesh.h
|
||||
@@ -21,7 +21,7 @@ int wpas_mesh_add_interface(struct wpa_s
|
||||
int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
|
||||
int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||
int duration);
|
||||
-void wpas_join_mesh(struct wpa_supplicant *wpa_s);
|
||||
+void wpas_mesh_complete_cb(void *ctx);
|
||||
int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s);
|
||||
|
||||
#ifdef CONFIG_MESH
|
||||
|
@ -1,35 +0,0 @@
|
||||
From dbe9afab3b2dceb35d478ac43dfcf8fdc5e23a22 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:09 -0700
|
||||
Subject: [PATCH 05/18] mesh: reflect country setting to mesh configuration
|
||||
|
||||
wpa_supplicant configuration has country parameter that is
|
||||
supposed to be used in AP mode to indicate supporting 802.11h
|
||||
and 802.11d. Reflect this configuration to Mesh also since Mesh
|
||||
is required to support 802.11h and 802.11d to use DFS channels.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
[daniel@makrotopia.org: adapted to changed ieee80211_is_dfs prototype]
|
||||
---
|
||||
wpa_supplicant/mesh.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -255,6 +255,15 @@ static int wpa_supplicant_mesh_init(stru
|
||||
bss->conf->start_disabled = 1;
|
||||
bss->conf->mesh = MESH_ENABLED;
|
||||
bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
|
||||
+
|
||||
+ if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
|
||||
+ wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
|
||||
+ conf->ieee80211h = 1;
|
||||
+ conf->ieee80211d = 1;
|
||||
+ conf->country[0] = wpa_s->conf->country[0];
|
||||
+ conf->country[1] = wpa_s->conf->country[1];
|
||||
+ }
|
||||
+
|
||||
bss->iconf = conf;
|
||||
ifmsh->conf = conf;
|
||||
|
@ -0,0 +1,26 @@
|
||||
From c56f18380d1d404a2abc0ea5373d294508ef1e54 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Mon, 27 Aug 2018 14:28:41 -0700
|
||||
Subject: [PATCH 2/7] mesh: update ssid->frequency as pri/sec channel switch
|
||||
|
||||
ssid->frequency is one of variables used to gets channel
|
||||
number from given frequency. Leave it as unchanged when
|
||||
pri/sec channel switched will cause picking up wrong
|
||||
channel number after applying secondary channel offset
|
||||
for HT40 and leads failing interface bring-up.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -286,6 +286,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
frequency == freq->freq + freq->sec_channel_offset * 20) {
|
||||
wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched");
|
||||
frequency = freq->freq;
|
||||
+ ssid->frequency = frequency;
|
||||
}
|
||||
wpa_s->assoc_freq = frequency;
|
||||
wpa_s->current_ssid = ssid;
|
@ -1,7 +1,7 @@
|
||||
From 51e759da5026b3e64f801135b5d53f2198bbd2f0 Mon Sep 17 00:00:00 2001
|
||||
From 593602b7f14be5c2695979639764b1c50f01bbec Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:10 -0700
|
||||
Subject: [PATCH 06/18] mesh: inform kernel driver DFS handler in userspace
|
||||
Date: Mon, 27 Aug 2018 14:28:49 -0700
|
||||
Subject: [PATCH 7/7] mesh: inform kernel driver DFS handler in userspace
|
||||
|
||||
NL80211_ATTR_HANDLE_DFS is required by kerenel space
|
||||
to enable DFS channels that indicates DFS handler
|
||||
@ -16,7 +16,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -1402,6 +1402,7 @@ struct wpa_driver_mesh_join_params {
|
||||
@@ -1436,6 +1436,7 @@ struct wpa_driver_mesh_join_params {
|
||||
#define WPA_DRIVER_MESH_FLAG_SAE_AUTH 0x00000004
|
||||
#define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008
|
||||
unsigned int flags;
|
||||
@ -26,7 +26,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
/**
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -9375,6 +9375,9 @@ static int nl80211_join_mesh(struct i802
|
||||
@@ -9544,6 +9544,9 @@ static int nl80211_join_mesh(struct i802
|
||||
|
||||
wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags);
|
||||
|
||||
@ -38,10 +38,10 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
goto fail;
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -262,6 +262,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
conf->ieee80211d = 1;
|
||||
@@ -308,6 +308,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
conf->country[0] = wpa_s->conf->country[0];
|
||||
conf->country[1] = wpa_s->conf->country[1];
|
||||
conf->country[2] = ' ';
|
||||
+ wpa_s->mesh_params->handle_dfs = 1;
|
||||
}
|
||||
|
||||
|
@ -1,28 +1,42 @@
|
||||
From bdc77efe681d5b88f3256e2bb6e706d4eaf09518 Mon Sep 17 00:00:00 2001
|
||||
From 2564184440d9d6041d11a8c7d50b31368634c3bd Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:11 -0700
|
||||
Subject: [PATCH 07/18] mesh: apply channel attributes before running Mesh
|
||||
Date: Mon, 27 Aug 2018 14:28:40 -0700
|
||||
Subject: [PATCH] mesh: Apply channel attributes before setup interface
|
||||
|
||||
This helps mesh interface initializes with correct
|
||||
channel parameters.
|
||||
This helps mesh interface initialization with correct channel
|
||||
parameters.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
wpa_supplicant/mesh.c | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -338,6 +338,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -248,7 +248,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
struct mesh_conf *mconf;
|
||||
int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
|
||||
int rate_len;
|
||||
- int frequency;
|
||||
+ int frequency, saved_freq;
|
||||
|
||||
if (!wpa_s->conf->user_mpm) {
|
||||
/* not much for us to do here */
|
||||
@@ -385,6 +385,13 @@ static int wpa_supplicant_mesh_init(stru
|
||||
conf->basic_rates[rate_len] = -1;
|
||||
}
|
||||
|
||||
+ /* Handle pri/sec switch frequency within AP configuration parameter
|
||||
+ * generation without changing the stored network profile in the end. */
|
||||
+ saved_freq = ssid->frequency;
|
||||
+ ssid->frequency = frequency;
|
||||
+ wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
|
||||
+ ssid->frequency = saved_freq;
|
||||
+
|
||||
if (hostapd_setup_interface(ifmsh)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Failed to initialize hostapd interface for mesh");
|
||||
@@ -349,8 +351,6 @@ static int wpa_supplicant_mesh_init(stru
|
||||
if (wpa_drv_init_mesh(wpa_s)) {
|
||||
wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
|
||||
return -1;
|
||||
@@ -396,8 +403,6 @@ static int wpa_supplicant_mesh_init(stru
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
From eb9888ba41faaeb8fd07392ad46808b7d894cc14 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:12 -0700
|
||||
Subject: [PATCH 08/18] mesh: set interface type to mesh before setting
|
||||
interface
|
||||
|
||||
Correct interface type is required to start DFS CAC that can be
|
||||
triggered during interface setup.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -340,14 +340,14 @@ static int wpa_supplicant_mesh_init(stru
|
||||
|
||||
wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
|
||||
|
||||
- if (hostapd_setup_interface(ifmsh)) {
|
||||
- wpa_printf(MSG_ERROR,
|
||||
- "Failed to initialize hostapd interface for mesh");
|
||||
+ if (wpa_drv_init_mesh(wpa_s)) {
|
||||
+ wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (wpa_drv_init_mesh(wpa_s)) {
|
||||
- wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
|
||||
+ if (hostapd_setup_interface(ifmsh)) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "Failed to initialize hostapd interface for mesh");
|
||||
return -1;
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
From fa3af966032267e618b19bbf06a536ddb81ddbdf Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:13 -0700
|
||||
Subject: [PATCH 09/18] mesh: set mesh center frequency
|
||||
|
||||
vht center frequency value is required to compose the correct channel info.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -457,6 +457,7 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
|
||||
if (wpa_s->mesh_vht_enabled) {
|
||||
ssid->vht = 1;
|
||||
+ ssid->vht_center_freq1 = params->freq.center_freq1;
|
||||
switch (params->freq.bandwidth) {
|
||||
case 80:
|
||||
if (params->freq.center_freq2) {
|
@ -1,176 +0,0 @@
|
||||
From 9a8ca54a264a2820af614043e7af853166b320b0 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:14 -0700
|
||||
Subject: [PATCH 10/18] mesh: consider mesh interface on dfs event handler
|
||||
|
||||
Once mesh starts supporting DFS channels, it has to handle DFS related events
|
||||
from drivers, hence add mesh interface to the check list.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
|
||||
---
|
||||
wpa_supplicant/ap.c | 71 ++++++++++++++++++++++++++++++-----------
|
||||
wpa_supplicant/events.c | 7 ++--
|
||||
2 files changed, 57 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/ap.c
|
||||
+++ b/wpa_supplicant/ap.c
|
||||
@@ -1379,13 +1379,18 @@ int ap_ctrl_iface_chanswitch(struct wpa_
|
||||
void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
|
||||
int offset, int width, int cf1, int cf2)
|
||||
{
|
||||
- if (!wpa_s->ap_iface)
|
||||
- return;
|
||||
+ struct hostapd_iface *iface = wpa_s->ap_iface;
|
||||
|
||||
+ if (!wpa_s->ap_iface) {
|
||||
+ if (!wpa_s->ifmsh)
|
||||
+ return;
|
||||
+ else
|
||||
+ iface = wpa_s->ifmsh;
|
||||
+ }
|
||||
wpa_s->assoc_freq = freq;
|
||||
if (wpa_s->current_ssid)
|
||||
wpa_s->current_ssid->frequency = freq;
|
||||
- hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht,
|
||||
+ hostapd_event_ch_switch(iface->bss[0], freq, ht,
|
||||
offset, width, cf1, cf2);
|
||||
}
|
||||
|
||||
@@ -1582,10 +1587,16 @@ int wpas_ap_pmksa_cache_add_external(str
|
||||
void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
|
||||
- return;
|
||||
+ struct hostapd_iface *iface = wpa_s->ap_iface;
|
||||
+
|
||||
+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
|
||||
+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
|
||||
+ return;
|
||||
+ else
|
||||
+ iface = wpa_s->ifmsh;
|
||||
+ }
|
||||
wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
|
||||
- hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq,
|
||||
+ hostapd_dfs_radar_detected(iface, radar->freq,
|
||||
radar->ht_enabled, radar->chan_offset,
|
||||
radar->chan_width,
|
||||
radar->cf1, radar->cf2);
|
||||
@@ -1595,10 +1606,16 @@ void wpas_ap_event_dfs_radar_detected(st
|
||||
void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
|
||||
- return;
|
||||
+ struct hostapd_iface *iface = wpa_s->ap_iface;
|
||||
+
|
||||
+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
|
||||
+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
|
||||
+ return;
|
||||
+ else
|
||||
+ iface = wpa_s->ifmsh;
|
||||
+ }
|
||||
wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq);
|
||||
- hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq,
|
||||
+ hostapd_dfs_start_cac(iface, radar->freq,
|
||||
radar->ht_enabled, radar->chan_offset,
|
||||
radar->chan_width, radar->cf1, radar->cf2);
|
||||
}
|
||||
@@ -1607,10 +1624,16 @@ void wpas_ap_event_dfs_cac_started(struc
|
||||
void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
|
||||
- return;
|
||||
+ struct hostapd_iface *iface = wpa_s->ap_iface;
|
||||
+
|
||||
+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
|
||||
+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
|
||||
+ return;
|
||||
+ else
|
||||
+ iface = wpa_s->ifmsh;
|
||||
+ }
|
||||
wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
|
||||
- hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq,
|
||||
+ hostapd_dfs_complete_cac(iface, 1, radar->freq,
|
||||
radar->ht_enabled, radar->chan_offset,
|
||||
radar->chan_width, radar->cf1, radar->cf2);
|
||||
}
|
||||
@@ -1619,10 +1642,16 @@ void wpas_ap_event_dfs_cac_finished(stru
|
||||
void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
|
||||
- return;
|
||||
+ struct hostapd_iface *iface = wpa_s->ap_iface;
|
||||
+
|
||||
+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
|
||||
+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
|
||||
+ return;
|
||||
+ else
|
||||
+ iface = wpa_s->ifmsh;
|
||||
+ }
|
||||
wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
|
||||
- hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq,
|
||||
+ hostapd_dfs_complete_cac(iface, 0, radar->freq,
|
||||
radar->ht_enabled, radar->chan_offset,
|
||||
radar->chan_width, radar->cf1, radar->cf2);
|
||||
}
|
||||
@@ -1631,10 +1660,16 @@ void wpas_ap_event_dfs_cac_aborted(struc
|
||||
void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
|
||||
- return;
|
||||
+ struct hostapd_iface *iface = wpa_s->ap_iface;
|
||||
+
|
||||
+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
|
||||
+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
|
||||
+ return;
|
||||
+ else
|
||||
+ iface = wpa_s->ifmsh;
|
||||
+ }
|
||||
wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
|
||||
- hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq,
|
||||
+ hostapd_dfs_nop_finished(iface, radar->freq,
|
||||
radar->ht_enabled, radar->chan_offset,
|
||||
radar->chan_width, radar->cf1, radar->cf2);
|
||||
}
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -3840,7 +3840,7 @@ static void wpas_event_dfs_cac_started(s
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
#if defined(NEED_AP_MLME) && defined(CONFIG_AP)
|
||||
- if (wpa_s->ap_iface) {
|
||||
+ if (wpa_s->ap_iface || wpa_s->ifmsh) {
|
||||
wpas_ap_event_dfs_cac_started(wpa_s, radar);
|
||||
} else
|
||||
#endif /* NEED_AP_MLME && CONFIG_AP */
|
||||
@@ -3861,7 +3861,7 @@ static void wpas_event_dfs_cac_finished(
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
#if defined(NEED_AP_MLME) && defined(CONFIG_AP)
|
||||
- if (wpa_s->ap_iface) {
|
||||
+ if (wpa_s->ap_iface || wpa_s->ifmsh) {
|
||||
wpas_ap_event_dfs_cac_finished(wpa_s, radar);
|
||||
} else
|
||||
#endif /* NEED_AP_MLME && CONFIG_AP */
|
||||
@@ -3877,7 +3877,7 @@ static void wpas_event_dfs_cac_aborted(s
|
||||
struct dfs_event *radar)
|
||||
{
|
||||
#if defined(NEED_AP_MLME) && defined(CONFIG_AP)
|
||||
- if (wpa_s->ap_iface) {
|
||||
+ if (wpa_s->ap_iface || wpa_s->ifmsh) {
|
||||
wpas_ap_event_dfs_cac_aborted(wpa_s, radar);
|
||||
} else
|
||||
#endif /* NEED_AP_MLME && CONFIG_AP */
|
||||
@@ -4328,6 +4328,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
#ifdef CONFIG_AP
|
||||
if (wpa_s->current_ssid->mode == WPAS_MODE_AP ||
|
||||
wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO ||
|
||||
+ wpa_s->current_ssid->mode == WPAS_MODE_MESH ||
|
||||
wpa_s->current_ssid->mode ==
|
||||
WPAS_MODE_P2P_GROUP_FORMATION) {
|
||||
wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
|
@ -1,8 +1,7 @@
|
||||
From bbaa6142eadf229334436fdbf51aa65bb819f771 Mon Sep 17 00:00:00 2001
|
||||
From 89fa0d75fb1be82330258082ed3d7fd452eb6076 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:15 -0700
|
||||
Subject: [PATCH 11/18] mesh: Allow DFS channels to be selected if dfs is
|
||||
enabled
|
||||
Date: Mon, 27 Aug 2018 14:28:45 -0700
|
||||
Subject: [PATCH 3/7] mesh: Allow DFS channels to be selected if dfs is enabled
|
||||
|
||||
Note: DFS is assumed to be usable if a country code has been set
|
||||
|
||||
@ -14,7 +13,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2090,6 +2090,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2148,6 +2148,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
struct hostapd_freq_params vht_freq;
|
||||
int chwidth, seg0, seg1;
|
||||
u32 vht_caps = 0;
|
||||
@ -23,7 +22,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
freq->freq = ssid->frequency;
|
||||
|
||||
@@ -2166,8 +2168,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2224,8 +2226,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
return;
|
||||
|
||||
/* Check primary channel flags */
|
||||
@ -34,9 +33,9 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
+ if (!dfs_enabled)
|
||||
+ return;
|
||||
|
||||
#ifdef CONFIG_HT_OVERRIDES
|
||||
if (ssid->disable_ht40)
|
||||
@@ -2193,8 +2198,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
freq->channel = pri_chan->chan;
|
||||
|
||||
@@ -2256,8 +2261,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
return;
|
||||
|
||||
/* Check secondary channel flags */
|
||||
@ -47,9 +46,9 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
+ if (!dfs_enabled)
|
||||
+ return;
|
||||
|
||||
freq->channel = pri_chan->chan;
|
||||
|
||||
@@ -2284,8 +2292,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
if (ht40 == -1) {
|
||||
if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
|
||||
@@ -2348,8 +2356,11 @@ skip_ht40:
|
||||
return;
|
||||
|
||||
/* Back to HT configuration if channel not usable */
|
||||
@ -62,7 +61,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
}
|
||||
|
||||
chwidth = VHT_CHANWIDTH_80MHZ;
|
||||
@@ -2305,10 +2316,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2369,10 +2380,11 @@ skip_ht40:
|
||||
if (!chan)
|
||||
continue;
|
||||
|
||||
|
@ -1,27 +1,29 @@
|
||||
From 267395271c1a36b54ef21070acff2cadce241035 Mon Sep 17 00:00:00 2001
|
||||
From 4f4a9b9e2e61fba334a21dadea749e4b440f42e6 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:17 -0700
|
||||
Subject: [PATCH 13/18] mesh: do not allow pri/sec channel switch
|
||||
Date: Mon, 27 Aug 2018 14:28:48 -0700
|
||||
Subject: [PATCH 6/7] mesh: don't allow pri/sec channel switch
|
||||
|
||||
We don't want mesh to switch the channel from primary to secondary,
|
||||
since mesh points are not able to join each other in that case.
|
||||
This limitation isn't backed by standard, but it is known that
|
||||
mesh doesn't have capability to handle 20/40 coex change in
|
||||
current implementation and it will not able to establish
|
||||
PLINK when channel switch between primary and secondary happens.
|
||||
|
||||
Since it's unknown when we will have the implementation of handling
|
||||
20/40 coex change for mesh, it'd better to avoid them from happening
|
||||
until standard based implementation is introduced.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
wpa_supplicant/mesh.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -337,7 +337,10 @@ static int wpa_supplicant_mesh_init(stru
|
||||
rate_len * sizeof(int));
|
||||
@@ -385,6 +385,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
conf->basic_rates[rate_len] = -1;
|
||||
}
|
||||
-
|
||||
+ /* Do not allow primary/secondary channel switch in mesh mode,
|
||||
+ * since mesh is not able to establish a physical link for it
|
||||
+ */
|
||||
+ conf->no_pri_sec_switch = 1;
|
||||
wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
|
||||
|
||||
if (wpa_drv_init_mesh(wpa_s)) {
|
||||
+ conf->no_pri_sec_switch = 1;
|
||||
/* Handle pri/sec switch frequency within AP configuration parameter
|
||||
* generation without changing the stored network profile in the end. */
|
||||
saved_freq = ssid->frequency;
|
||||
|
@ -1,24 +0,0 @@
|
||||
From f95897cef614fff710c31d9e478eacc85d6312d5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:18 -0700
|
||||
Subject: [PATCH 14/18] mesh: do not allow scan result to swap pri/sec
|
||||
|
||||
Swapping between primary and secondary channel will break
|
||||
mesh from joining, hence don't allow it.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/wpa_supplicant.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2215,7 +2215,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
}
|
||||
freq->sec_channel_offset = ht40;
|
||||
|
||||
- if (obss_scan) {
|
||||
+ if (ssid->mode != WPAS_MODE_MESH && obss_scan) {
|
||||
struct wpa_scan_results *scan_res;
|
||||
|
||||
scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
|
@ -1,44 +1,56 @@
|
||||
From 9423e8be0393e82c8622806a0529e47fd5583c0b Mon Sep 17 00:00:00 2001
|
||||
From 71e9c65a7c8af90a5fd11072062b596421316452 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:19 -0700
|
||||
Subject: [PATCH 15/18] mesh: do not use offchan mgmt tx on DFS
|
||||
Date: Mon, 27 Aug 2018 14:28:46 -0700
|
||||
Subject: [PATCH 4/7] mesh: do not set offchanok on DFS channels in non-ETSI
|
||||
|
||||
Drivers don't allow mesh to use offchannel on management Tx.
|
||||
mac80211 does not allow mgmt tx to use off channel on
|
||||
DFS channels in non-ETSI domain, because it will invalidate
|
||||
CAC result on current operating channel.
|
||||
(mac80211 commit: 34373d12f3cbb74960a73431138ef619d857996f)
|
||||
Hence don't set offchanok for mgmt tx in case of DFS channels
|
||||
in non-ETSI.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
[daniel@makrotopia.org: adapted to changed ieee80211_is_dfs prototype]
|
||||
---
|
||||
src/drivers/driver_nl80211.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
src/drivers/driver_nl80211.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -7268,6 +7268,10 @@ static int wpa_driver_nl80211_send_actio
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
@@ -7411,6 +7411,10 @@ static int wpa_driver_nl80211_send_actio
|
||||
int ret = -1;
|
||||
u8 *buf;
|
||||
+ int offchanok = 1;
|
||||
+ u16 num_modes, flags;
|
||||
+ struct hostapd_hw_modes *modes;
|
||||
+ u8 dfs_domain;
|
||||
struct ieee80211_hdr *hdr;
|
||||
+ struct hostapd_hw_modes *modes;
|
||||
+ int i, offchanok = 1;
|
||||
+ u16 num_modes, flags;
|
||||
+ u8 dfs_domain;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
|
||||
@@ -7292,7 +7296,11 @@ static int wpa_driver_nl80211_send_actio
|
||||
} else {
|
||||
"freq=%u MHz wait=%d ms no_cck=%d)",
|
||||
@@ -7435,6 +7439,21 @@ static int wpa_driver_nl80211_send_actio
|
||||
os_memset(bss->rand_addr, 0, ETH_ALEN);
|
||||
}
|
||||
-
|
||||
+ if (is_mesh_interface(drv->nlmode) &&
|
||||
+ (modes = nl80211_get_hw_feature_data(bss, &num_modes, &flags,
|
||||
+ &dfs_domain)) &&
|
||||
+ ieee80211_is_dfs(freq, modes, num_modes))
|
||||
+ offchanok = 0;
|
||||
|
||||
+ if (is_mesh_interface(drv->nlmode)) {
|
||||
+ modes = nl80211_get_hw_feature_data(bss, &num_modes,
|
||||
+ &flags, &dfs_domain);
|
||||
+ if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
|
||||
+ ieee80211_is_dfs(bss->freq, modes, num_modes))
|
||||
+ offchanok = 0;
|
||||
+ if (modes) {
|
||||
+ for (i = 0; i < num_modes; i++) {
|
||||
+ os_free(modes[i].channels);
|
||||
+ os_free(modes[i].rates);
|
||||
+ }
|
||||
+ os_free(modes);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (is_ap_interface(drv->nlmode) &&
|
||||
(!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
|
||||
(int) freq == bss->freq || drv->device_ap_sme ||
|
||||
@@ -7304,7 +7312,7 @@ static int wpa_driver_nl80211_send_actio
|
||||
@@ -7446,7 +7465,7 @@ static int wpa_driver_nl80211_send_actio
|
||||
ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
|
||||
24 + data_len,
|
||||
&drv->send_action_cookie,
|
||||
|
@ -1,7 +1,7 @@
|
||||
From fa9d565fe8841b288f29137c23a7ab2584dd9510 Mon Sep 17 00:00:00 2001
|
||||
From 5913d6e2a741683e7c747c046f72ca790bbe1337 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:20 -0700
|
||||
Subject: [PATCH 16/18] mesh: fix channel switch error during CAC
|
||||
Date: Mon, 27 Aug 2018 14:28:47 -0700
|
||||
Subject: [PATCH 5/7] mesh: fix channel switch error during CAC
|
||||
|
||||
Mesh interface has used its channel parameters that configured
|
||||
during its initialization even after channel switched due to
|
||||
@ -10,30 +10,23 @@ This change fixes the error by updating its channel parameters
|
||||
when channel's been changed from initial one.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
[daniel@makrotopia.org: added hw_features_common.h include]
|
||||
---
|
||||
wpa_supplicant/mesh.c | 25 +++++++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "utils/uuid.h"
|
||||
+#include "common/hw_features_common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/wpa_ctrl.h"
|
||||
+#include "common/hw_features_common.h"
|
||||
#include "ap/sta_info.h"
|
||||
@@ -394,10 +395,35 @@ void wpa_supplicant_mesh_add_scan_ie(str
|
||||
void wpas_mesh_complete_cb(void *ctx)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)ctx;
|
||||
+ struct hostapd_iface *ifmsh = wpa_s->ifmsh;
|
||||
struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
int ret = 0;
|
||||
#include "ap/hostapd.h"
|
||||
#include "ap/ieee802_11.h"
|
||||
@@ -204,6 +205,30 @@ static void wpas_mesh_complete_cb(void *
|
||||
return;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * inspect if channel's been changed since initialized.
|
||||
@ -59,6 +52,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (wpas_mesh_init_rsn(wpa_s)) {
|
||||
wpa_printf(MSG_ERROR, "Init RSN failed. Deinit mesh...");
|
||||
wpa_supplicant_mesh_deinit(wpa_s);
|
||||
if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
|
||||
wpas_mesh_init_rsn(wpa_s)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
|
@ -1,107 +0,0 @@
|
||||
From d3201adfe7d2219217a07ef16ef365ad59c1a89b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Tue, 29 May 2018 14:39:21 -0700
|
||||
Subject: [PATCH 17/18] mesh: use right interface context to send DFS event
|
||||
messages
|
||||
|
||||
use mesh interface context to send DFS event messages when
|
||||
DFS events are on mesh interface.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
|
||||
---
|
||||
src/ap/dfs.c | 27 +++++++++++++++++++--------
|
||||
1 file changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/src/ap/dfs.c
|
||||
+++ b/src/ap/dfs.c
|
||||
@@ -637,6 +637,17 @@ static unsigned int dfs_get_cac_time(str
|
||||
}
|
||||
|
||||
|
||||
+static void *get_message_ctx(struct hostapd_iface *iface)
|
||||
+{
|
||||
+#ifdef CONFIG_MESH
|
||||
+ if (iface->mconf)
|
||||
+ return iface->owner;
|
||||
+#endif /* CONFIG_MESH */
|
||||
+
|
||||
+ return iface->bss[0]->msg_ctx;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Main DFS handler
|
||||
* 1 - continue channel/ap setup
|
||||
@@ -719,7 +730,7 @@ int hostapd_handle_dfs(struct hostapd_if
|
||||
/* Finally start CAC */
|
||||
hostapd_set_state(iface, HAPD_IFACE_DFS);
|
||||
wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz", iface->freq);
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
|
||||
"freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds",
|
||||
iface->freq,
|
||||
iface->conf->channel, iface->conf->secondary_channel,
|
||||
@@ -768,7 +779,7 @@ int hostapd_dfs_complete_cac(struct host
|
||||
int ht_enabled, int chan_offset, int chan_width,
|
||||
int cf1, int cf2)
|
||||
{
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_COMPLETED
|
||||
"success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
|
||||
success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
|
||||
|
||||
@@ -810,7 +821,7 @@ int hostapd_dfs_pre_cac_expired(struct h
|
||||
int ht_enabled, int chan_offset, int chan_width,
|
||||
int cf1, int cf2)
|
||||
{
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
|
||||
"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
|
||||
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
|
||||
|
||||
@@ -848,7 +859,7 @@ static int hostapd_dfs_start_channel_swi
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
|
||||
channel->chan);
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
|
||||
"freq=%d chan=%d sec_chan=%d", channel->freq,
|
||||
channel->chan, secondary_channel);
|
||||
|
||||
@@ -935,7 +946,7 @@ static int hostapd_dfs_start_channel_swi
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
|
||||
channel->chan);
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
|
||||
"freq=%d chan=%d sec_chan=%d", channel->freq,
|
||||
channel->chan, secondary_channel);
|
||||
|
||||
@@ -997,7 +1008,7 @@ int hostapd_dfs_radar_detected(struct ho
|
||||
{
|
||||
int res;
|
||||
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_RADAR_DETECTED
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_RADAR_DETECTED
|
||||
"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
|
||||
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
|
||||
|
||||
@@ -1028,7 +1039,7 @@ int hostapd_dfs_nop_finished(struct host
|
||||
int ht_enabled, int chan_offset, int chan_width,
|
||||
int cf1, int cf2)
|
||||
{
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NOP_FINISHED
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NOP_FINISHED
|
||||
"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
|
||||
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
|
||||
|
||||
@@ -1078,7 +1089,7 @@ int hostapd_dfs_start_cac(struct hostapd
|
||||
int ht_enabled, int chan_offset, int chan_width,
|
||||
int cf1, int cf2)
|
||||
{
|
||||
- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
|
||||
+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
|
||||
"freq=%d chan=%d chan_offset=%d width=%d seg0=%d "
|
||||
"seg1=%d cac_time=%ds",
|
||||
freq, (freq - 5000) / 5, chan_offset, chan_width, cf1, cf2, 60);
|
@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -49,6 +49,7 @@ struct mesh_conf {
|
||||
@@ -50,6 +50,7 @@ struct mesh_conf {
|
||||
int dot11MeshRetryTimeout; /* msec */
|
||||
int dot11MeshConfirmTimeout; /* msec */
|
||||
int dot11MeshHoldingTimeout; /* msec */
|
||||
@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
};
|
||||
|
||||
#define MAX_STA_COUNT 2007
|
||||
@@ -628,6 +629,7 @@ struct hostapd_bss_config {
|
||||
@@ -645,6 +646,7 @@ struct hostapd_bss_config {
|
||||
|
||||
#define MESH_ENABLED BIT(0)
|
||||
int mesh;
|
||||
@ -41,7 +41,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -1375,6 +1375,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
@@ -1409,6 +1409,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
#define WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS 0x00000004
|
||||
#define WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE 0x00000008
|
||||
#define WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD 0x00000010
|
||||
@ -49,7 +49,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
/*
|
||||
* TODO: Other mesh configuration parameters would go here.
|
||||
* See NL80211_MESHCONF_* for all the mesh config parameters.
|
||||
@@ -1384,6 +1385,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
@@ -1418,6 +1419,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
int peer_link_timeout;
|
||||
int max_peer_links;
|
||||
int rssi_threshold;
|
||||
@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -9332,6 +9332,9 @@ static int nl80211_put_mesh_config(struc
|
||||
@@ -9512,6 +9512,9 @@ static int nl80211_put_mesh_config(struc
|
||||
if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
|
||||
nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
|
||||
params->auto_plinks)) ||
|
||||
@ -71,7 +71,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
params->max_peer_links)) ||
|
||||
--- a/wpa_supplicant/config.c
|
||||
+++ b/wpa_supplicant/config.c
|
||||
@@ -2228,6 +2228,7 @@ static const struct parse_data ssid_fiel
|
||||
@@ -2307,6 +2307,7 @@ static const struct parse_data ssid_fiel
|
||||
#ifdef CONFIG_MESH
|
||||
{ INT_RANGE(mode, 0, 5) },
|
||||
{ INT_RANGE(no_auto_peer, 0, 1) },
|
||||
@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{ INT_RANGE(mesh_rssi_threshold, -255, 1) },
|
||||
#else /* CONFIG_MESH */
|
||||
{ INT_RANGE(mode, 0, 4) },
|
||||
@@ -2779,6 +2780,7 @@ void wpa_config_set_network_defaults(str
|
||||
@@ -2868,6 +2869,7 @@ void wpa_config_set_network_defaults(str
|
||||
ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
|
||||
ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
|
||||
ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT;
|
||||
@ -87,7 +87,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD;
|
||||
#endif /* CONFIG_MESH */
|
||||
#ifdef CONFIG_HT_OVERRIDES
|
||||
@@ -3996,6 +3998,7 @@ struct wpa_config * wpa_config_alloc_emp
|
||||
@@ -4088,6 +4090,7 @@ struct wpa_config * wpa_config_alloc_emp
|
||||
config->user_mpm = DEFAULT_USER_MPM;
|
||||
config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
|
||||
config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
|
||||
@ -95,7 +95,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
config->dot11RSNASAERetransPeriod =
|
||||
DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
|
||||
config->fast_reauth = DEFAULT_FAST_REAUTH;
|
||||
@@ -4618,6 +4621,7 @@ static const struct global_parse_data gl
|
||||
@@ -4725,6 +4728,7 @@ static const struct global_parse_data gl
|
||||
{ INT(user_mpm), 0 },
|
||||
{ INT_RANGE(max_peer_links, 0, 255), 0 },
|
||||
{ INT(mesh_max_inactivity), 0 },
|
||||
@ -113,7 +113,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
/*
|
||||
* The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard,
|
||||
* but use 1000 ms in practice to avoid issues on low power CPUs.
|
||||
@@ -1306,6 +1307,14 @@ struct wpa_config {
|
||||
@@ -1326,6 +1327,14 @@ struct wpa_config {
|
||||
int mesh_max_inactivity;
|
||||
|
||||
/**
|
||||
@ -130,7 +130,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* This timeout value is used in mesh STA to retransmit
|
||||
--- a/wpa_supplicant/config_file.c
|
||||
+++ b/wpa_supplicant/config_file.c
|
||||
@@ -818,6 +818,7 @@ static void wpa_config_write_network(FIL
|
||||
@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
INT(mode);
|
||||
INT(no_auto_peer);
|
||||
@ -138,7 +138,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
INT(frequency);
|
||||
INT(fixed_freq);
|
||||
#ifdef CONFIG_ACS
|
||||
@@ -1450,6 +1451,9 @@ static void wpa_config_write_global(FILE
|
||||
@@ -1471,6 +1472,9 @@ static void wpa_config_write_global(FILE
|
||||
fprintf(f, "mesh_max_inactivity=%d\n",
|
||||
config->mesh_max_inactivity);
|
||||
|
||||
@ -150,7 +150,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
|
||||
--- a/wpa_supplicant/config_ssid.h
|
||||
+++ b/wpa_supplicant/config_ssid.h
|
||||
@@ -500,6 +500,11 @@ struct wpa_ssid {
|
||||
@@ -514,6 +514,11 @@ struct wpa_ssid {
|
||||
int dot11MeshConfirmTimeout; /* msec */
|
||||
int dot11MeshHoldingTimeout; /* msec */
|
||||
|
||||
@ -164,7 +164,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -121,6 +121,7 @@ static struct mesh_conf * mesh_config_cr
|
||||
@@ -126,6 +126,7 @@ static struct mesh_conf * mesh_config_cr
|
||||
conf->mesh_cc_id = 0;
|
||||
conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET;
|
||||
conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0;
|
||||
@ -172,7 +172,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
|
||||
conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
|
||||
conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
|
||||
@@ -256,6 +257,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -325,6 +326,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
bss->conf->start_disabled = 1;
|
||||
bss->conf->mesh = MESH_ENABLED;
|
||||
bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
|
||||
@ -180,7 +180,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
|
||||
wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
|
||||
@@ -534,6 +536,10 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
@@ -543,6 +545,10 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
}
|
||||
params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
|
||||
|
||||
@ -188,12 +188,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_FORWARDING;
|
||||
+ params->conf.forwarding = ssid->mesh_fwding;
|
||||
+
|
||||
os_free(wpa_s->mesh_params);
|
||||
wpa_s->mesh_params = params;
|
||||
if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) {
|
||||
wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
|
||||
--- a/wpa_supplicant/mesh_mpm.c
|
||||
+++ b/wpa_supplicant/mesh_mpm.c
|
||||
@@ -289,9 +289,9 @@ static void mesh_mpm_send_plink_action(s
|
||||
@@ -295,9 +295,9 @@ static void mesh_mpm_send_plink_action(s
|
||||
info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
|
||||
/* TODO: Add Connected to Mesh Gate/AS subfields */
|
||||
wpabuf_put_u8(buf, info);
|
||||
|
@ -1,49 +0,0 @@
|
||||
From 838225f2319348e430b553fd9bb3680bd7434ae3 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Wed, 18 Apr 2018 14:14:18 -0700
|
||||
Subject: [PATCH 1/2] mesh: add VHT_CHANWIDTH_USE_HT to max_oper_chwidth
|
||||
|
||||
Channel width in VHT mode refers HT capability when
|
||||
the width goes down to below 80MHz, hence add checking
|
||||
HT channel width to its max operation channel width.
|
||||
So that mesh has capable to select bandwidth below 80Mhz.
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/config.c | 1 +
|
||||
wpa_supplicant/config_ssid.h | 1 +
|
||||
wpa_supplicant/wpa_supplicant.c | 3 +++
|
||||
3 files changed, 5 insertions(+)
|
||||
|
||||
--- a/wpa_supplicant/config.c
|
||||
+++ b/wpa_supplicant/config.c
|
||||
@@ -2818,6 +2818,7 @@ void wpa_config_set_network_defaults(str
|
||||
ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
|
||||
#endif /* CONFIG_MACSEC */
|
||||
ssid->mac_addr = -1;
|
||||
+ ssid->max_oper_chwidth = (u8)DEFAULT_MAX_OPER_CHWIDTH;
|
||||
}
|
||||
|
||||
|
||||
--- a/wpa_supplicant/config_ssid.h
|
||||
+++ b/wpa_supplicant/config_ssid.h
|
||||
@@ -37,6 +37,7 @@
|
||||
#define DEFAULT_AMPDU_FACTOR -1 /* no change */
|
||||
#define DEFAULT_AMPDU_DENSITY -1 /* no change */
|
||||
#define DEFAULT_USER_SELECTED_SIM 1
|
||||
+#define DEFAULT_MAX_OPER_CHWIDTH -1
|
||||
|
||||
struct psk_list_entry {
|
||||
struct dl_list list;
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2342,6 +2342,9 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
|
||||
seg0 = 114;
|
||||
}
|
||||
+ } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) {
|
||||
+ chwidth = VHT_CHANWIDTH_USE_HT;
|
||||
+ seg0 = vht80[j] + 2;
|
||||
}
|
||||
|
||||
if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
|
@ -1,82 +0,0 @@
|
||||
From 24fc73b2470ff79cd8c92e029ca785c8e95a204c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
Date: Wed, 18 Apr 2018 14:14:19 -0700
|
||||
Subject: [PATCH 2/2] mesh: implement use of VHT20 config in mesh mode
|
||||
|
||||
mesh in VHT mode is supposed to be able to use any bandwidth
|
||||
that 11ac supports, but we don't have a way to set VHT20
|
||||
although there are parameters that are supposed to be used.
|
||||
This patch along with the patch of
|
||||
"mesh: add VHT_CHANWIDTH_USE_HT to max_oper_chwidth" makes mesh
|
||||
available to use of any bandwidth using combination of
|
||||
existing parameters like below shown.
|
||||
|
||||
VHT80:
|
||||
default
|
||||
do not set any parameters
|
||||
VHT40:
|
||||
max_oper_chwidth = 0
|
||||
VHT20:
|
||||
max_oper_chwidth=0
|
||||
disable_ht40=1
|
||||
HT40:
|
||||
disable_vht = 1
|
||||
HT20:
|
||||
disable_ht40 = 1
|
||||
disable HT:
|
||||
disable_ht = 1
|
||||
|
||||
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
---
|
||||
wpa_supplicant/wpa_supplicant.c | 18 +++++++++++++-----
|
||||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2174,9 +2174,15 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
if (!dfs_enabled)
|
||||
return;
|
||||
|
||||
+ freq->channel = pri_chan->chan;
|
||||
+
|
||||
#ifdef CONFIG_HT_OVERRIDES
|
||||
- if (ssid->disable_ht40)
|
||||
- return;
|
||||
+ if (ssid->disable_ht40) {
|
||||
+ if (ssid->disable_vht)
|
||||
+ return;
|
||||
+ else
|
||||
+ goto skip_ht40;
|
||||
+ }
|
||||
#endif /* CONFIG_HT_OVERRIDES */
|
||||
|
||||
/* Check/setup HT40+/HT40- */
|
||||
@@ -2204,8 +2210,6 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
if (!dfs_enabled)
|
||||
return;
|
||||
|
||||
- freq->channel = pri_chan->chan;
|
||||
-
|
||||
if (ht40 == -1) {
|
||||
if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
|
||||
return;
|
||||
@@ -2249,6 +2253,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
wpa_scan_results_free(scan_res);
|
||||
}
|
||||
|
||||
+skip_ht40:
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
|
||||
freq->channel, freq->sec_channel_offset);
|
||||
@@ -2344,7 +2349,10 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
}
|
||||
} else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) {
|
||||
chwidth = VHT_CHANWIDTH_USE_HT;
|
||||
- seg0 = vht80[j] + 2;
|
||||
+ if (ssid->disable_ht40)
|
||||
+ seg0 = 0;
|
||||
+ else
|
||||
+ seg0 = vht80[j] + 2;
|
||||
}
|
||||
|
||||
if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
|
@ -1,33 +0,0 @@
|
||||
From f2973fa39d6109f0f34969e91551a98dc340d537 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Mon, 3 Dec 2018 12:00:26 +0200
|
||||
Subject: FT: Fix CONFIG_IEEE80211X=y build without CONFIG_FILS=y
|
||||
|
||||
remove_ie() was defined within an ifdef CONFIG_FILS block while it is
|
||||
now needed even without CONFIG_FILS=y. Remove the CONFIG_FILS condition
|
||||
there.
|
||||
|
||||
Fixes 8c41734e5de1 ("FT: Fix Reassociation Request IEs during FT protocol")
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
wpa_supplicant/sme.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/wpa_supplicant/sme.c
|
||||
+++ b/wpa_supplicant/sme.c
|
||||
@@ -1386,7 +1386,6 @@ void sme_event_auth(struct wpa_supplican
|
||||
}
|
||||
|
||||
|
||||
-#ifdef CONFIG_FILS
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
static void remove_ie(u8 *buf, size_t *len, u8 eid)
|
||||
{
|
||||
@@ -1401,7 +1400,6 @@ static void remove_ie(u8 *buf, size_t *l
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
-#endif /* CONFIG_FILS */
|
||||
|
||||
|
||||
void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
|
@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/wpa_supplicant/mesh_mpm.c
|
||||
+++ b/wpa_supplicant/mesh_mpm.c
|
||||
@@ -663,11 +663,12 @@ static struct sta_info * mesh_mpm_add_pe
|
||||
@@ -685,11 +685,12 @@ static struct sta_info * mesh_mpm_add_pe
|
||||
}
|
||||
|
||||
sta = ap_get_sta(data, addr);
|
||||
|
@ -1,88 +0,0 @@
|
||||
From d42c477cc794163a3757956bbffca5cea000923c Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Tue, 26 Feb 2019 11:43:03 +0200
|
||||
Subject: [PATCH 01/14] OpenSSL: Use constant time operations for private
|
||||
bignums
|
||||
|
||||
This helps in reducing measurable timing differences in operations
|
||||
involving private information. BoringSSL has removed BN_FLG_CONSTTIME
|
||||
and expects specific constant time functions to be called instead, so a
|
||||
bit different approach is needed depending on which library is used.
|
||||
|
||||
The main operation that needs protection against side channel attacks is
|
||||
BN_mod_exp() that depends on private keys (the public key validation
|
||||
step in crypto_dh_derive_secret() is an exception that can use the
|
||||
faster version since it does not depend on private keys).
|
||||
|
||||
crypto_bignum_div() is currently used only in SAE FFC case with not
|
||||
safe-prime groups and only with values that do not depend on private
|
||||
keys, so it is not critical to protect it.
|
||||
|
||||
crypto_bignum_inverse() is currently used only in SAE FFC PWE
|
||||
derivation. The additional protection here is targeting only OpenSSL.
|
||||
BoringSSL may need conversion to using BN_mod_inverse_blinded().
|
||||
|
||||
This is related to CVE-2019-9494 and CVE-2019-9495.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/crypto/crypto_openssl.c | 20 +++++++++++++++-----
|
||||
1 file changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/src/crypto/crypto_openssl.c
|
||||
+++ b/src/crypto/crypto_openssl.c
|
||||
@@ -549,7 +549,8 @@ int crypto_mod_exp(const u8 *base, size_
|
||||
bn_result == NULL)
|
||||
goto error;
|
||||
|
||||
- if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
|
||||
+ if (BN_mod_exp_mont_consttime(bn_result, bn_base, bn_exp, bn_modulus,
|
||||
+ ctx, NULL) != 1)
|
||||
goto error;
|
||||
|
||||
*result_len = BN_bn2bin(bn_result, result);
|
||||
@@ -1295,8 +1296,9 @@ int crypto_bignum_exptmod(const struct c
|
||||
bnctx = BN_CTX_new();
|
||||
if (bnctx == NULL)
|
||||
return -1;
|
||||
- res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
|
||||
- (const BIGNUM *) c, bnctx);
|
||||
+ res = BN_mod_exp_mont_consttime((BIGNUM *) d, (const BIGNUM *) a,
|
||||
+ (const BIGNUM *) b, (const BIGNUM *) c,
|
||||
+ bnctx, NULL);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return res ? 0 : -1;
|
||||
@@ -1315,6 +1317,11 @@ int crypto_bignum_inverse(const struct c
|
||||
bnctx = BN_CTX_new();
|
||||
if (bnctx == NULL)
|
||||
return -1;
|
||||
+#ifdef OPENSSL_IS_BORINGSSL
|
||||
+ /* TODO: use BN_mod_inverse_blinded() ? */
|
||||
+#else /* OPENSSL_IS_BORINGSSL */
|
||||
+ BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
|
||||
+#endif /* OPENSSL_IS_BORINGSSL */
|
||||
res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
|
||||
(const BIGNUM *) b, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
@@ -1348,6 +1355,9 @@ int crypto_bignum_div(const struct crypt
|
||||
bnctx = BN_CTX_new();
|
||||
if (bnctx == NULL)
|
||||
return -1;
|
||||
+#ifndef OPENSSL_IS_BORINGSSL
|
||||
+ BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
|
||||
+#endif /* OPENSSL_IS_BORINGSSL */
|
||||
res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
|
||||
(const BIGNUM *) b, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
@@ -1439,8 +1449,8 @@ int crypto_bignum_legendre(const struct
|
||||
/* exp = (p-1) / 2 */
|
||||
!BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
|
||||
!BN_rshift1(exp, exp) ||
|
||||
- !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
|
||||
- bnctx))
|
||||
+ !BN_mod_exp_mont_consttime(tmp, (const BIGNUM *) a, exp,
|
||||
+ (const BIGNUM *) p, bnctx, NULL))
|
||||
goto fail;
|
||||
|
||||
if (BN_is_word(tmp, 1))
|
@ -1,212 +0,0 @@
|
||||
From 6e34f618d37ddbb5854c42e2ad4fca83492fa7b7 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Wed, 27 Feb 2019 18:38:30 +0200
|
||||
Subject: [PATCH 02/14] Add helper functions for constant time operations
|
||||
|
||||
These functions can be used to help implement constant time operations
|
||||
for various cryptographic operations that must minimize externally
|
||||
observable differences in processing (both in timing and also in
|
||||
internal cache use, etc.).
|
||||
|
||||
This is related to CVE-2019-9494 and CVE-2019-9495.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/utils/const_time.h | 191 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 191 insertions(+)
|
||||
create mode 100644 src/utils/const_time.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/src/utils/const_time.h
|
||||
@@ -0,0 +1,191 @@
|
||||
+/*
|
||||
+ * Helper functions for constant time operations
|
||||
+ * Copyright (c) 2019, The Linux Foundation
|
||||
+ *
|
||||
+ * This software may be distributed under the terms of the BSD license.
|
||||
+ * See README for more details.
|
||||
+ *
|
||||
+ * These helper functions can be used to implement logic that needs to minimize
|
||||
+ * externally visible differences in execution path by avoiding use of branches,
|
||||
+ * avoiding early termination or other time differences, and forcing same memory
|
||||
+ * access pattern regardless of values.
|
||||
+ */
|
||||
+
|
||||
+#ifndef CONST_TIME_H
|
||||
+#define CONST_TIME_H
|
||||
+
|
||||
+
|
||||
+#if defined(__clang__)
|
||||
+#define NO_UBSAN_UINT_OVERFLOW \
|
||||
+ __attribute__((no_sanitize("unsigned-integer-overflow")))
|
||||
+#else
|
||||
+#define NO_UBSAN_UINT_OVERFLOW
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * const_time_fill_msb - Fill all bits with MSB value
|
||||
+ * @val: Input value
|
||||
+ * Returns: Value with all the bits set to the MSB of the input val
|
||||
+ */
|
||||
+static inline unsigned int const_time_fill_msb(unsigned int val)
|
||||
+{
|
||||
+ /* Move the MSB to LSB and multiple by -1 to fill in all bits. */
|
||||
+ return (val >> (sizeof(val) * 8 - 1)) * ~0U;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Returns: -1 if val is zero; 0 if val is not zero */
|
||||
+static inline unsigned int const_time_is_zero(unsigned int val)
|
||||
+ NO_UBSAN_UINT_OVERFLOW
|
||||
+{
|
||||
+ /* Set MSB to 1 for 0 and fill rest of bits with the MSB value */
|
||||
+ return const_time_fill_msb(~val & (val - 1));
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Returns: -1 if a == b; 0 if a != b */
|
||||
+static inline unsigned int const_time_eq(unsigned int a, unsigned int b)
|
||||
+{
|
||||
+ return const_time_is_zero(a ^ b);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Returns: -1 if a == b; 0 if a != b */
|
||||
+static inline u8 const_time_eq_u8(unsigned int a, unsigned int b)
|
||||
+{
|
||||
+ return (u8) const_time_eq(a, b);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * const_time_eq_bin - Constant time memory comparison
|
||||
+ * @a: First buffer to compare
|
||||
+ * @b: Second buffer to compare
|
||||
+ * @len: Number of octets to compare
|
||||
+ * Returns: -1 if buffers are equal, 0 if not
|
||||
+ *
|
||||
+ * This function is meant for comparing passwords or hash values where
|
||||
+ * difference in execution time or memory access pattern could provide external
|
||||
+ * observer information about the location of the difference in the memory
|
||||
+ * buffers. The return value does not behave like memcmp(), i.e.,
|
||||
+ * const_time_eq_bin() cannot be used to sort items into a defined order. Unlike
|
||||
+ * memcmp(), the execution time of const_time_eq_bin() does not depend on the
|
||||
+ * contents of the compared memory buffers, but only on the total compared
|
||||
+ * length.
|
||||
+ */
|
||||
+static inline unsigned int const_time_eq_bin(const void *a, const void *b,
|
||||
+ size_t len)
|
||||
+{
|
||||
+ const u8 *aa = a;
|
||||
+ const u8 *bb = b;
|
||||
+ size_t i;
|
||||
+ u8 res = 0;
|
||||
+
|
||||
+ for (i = 0; i < len; i++)
|
||||
+ res |= aa[i] ^ bb[i];
|
||||
+
|
||||
+ return const_time_is_zero(res);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * const_time_select - Constant time unsigned int selection
|
||||
+ * @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
+ * @true_val: Value to select for the true case
|
||||
+ * @false_val: Value to select for the false case
|
||||
+ * Returns: true_val if mask == -1, false_val if mask == 0
|
||||
+ */
|
||||
+static inline unsigned int const_time_select(unsigned int mask,
|
||||
+ unsigned int true_val,
|
||||
+ unsigned int false_val)
|
||||
+{
|
||||
+ return (mask & true_val) | (~mask & false_val);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * const_time_select_int - Constant time int selection
|
||||
+ * @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
+ * @true_val: Value to select for the true case
|
||||
+ * @false_val: Value to select for the false case
|
||||
+ * Returns: true_val if mask == -1, false_val if mask == 0
|
||||
+ */
|
||||
+static inline int const_time_select_int(unsigned int mask, int true_val,
|
||||
+ int false_val)
|
||||
+{
|
||||
+ return (int) const_time_select(mask, (unsigned int) true_val,
|
||||
+ (unsigned int) false_val);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * const_time_select_u8 - Constant time u8 selection
|
||||
+ * @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
+ * @true_val: Value to select for the true case
|
||||
+ * @false_val: Value to select for the false case
|
||||
+ * Returns: true_val if mask == -1, false_val if mask == 0
|
||||
+ */
|
||||
+static inline u8 const_time_select_u8(u8 mask, u8 true_val, u8 false_val)
|
||||
+{
|
||||
+ return (u8) const_time_select(mask, true_val, false_val);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * const_time_select_s8 - Constant time s8 selection
|
||||
+ * @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
+ * @true_val: Value to select for the true case
|
||||
+ * @false_val: Value to select for the false case
|
||||
+ * Returns: true_val if mask == -1, false_val if mask == 0
|
||||
+ */
|
||||
+static inline s8 const_time_select_s8(u8 mask, s8 true_val, s8 false_val)
|
||||
+{
|
||||
+ return (s8) const_time_select(mask, (unsigned int) true_val,
|
||||
+ (unsigned int) false_val);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * const_time_select_bin - Constant time binary buffer selection copy
|
||||
+ * @mask: 0 (false) or -1 (true) to identify which value to copy
|
||||
+ * @true_val: Buffer to copy for the true case
|
||||
+ * @false_val: Buffer to copy for the false case
|
||||
+ * @len: Number of octets to copy
|
||||
+ * @dst: Destination buffer for the copy
|
||||
+ *
|
||||
+ * This function copies the specified buffer into the destination buffer using
|
||||
+ * operations with identical memory access pattern regardless of which buffer
|
||||
+ * is being copied.
|
||||
+ */
|
||||
+static inline void const_time_select_bin(u8 mask, const u8 *true_val,
|
||||
+ const u8 *false_val, size_t len,
|
||||
+ u8 *dst)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; i < len; i++)
|
||||
+ dst[i] = const_time_select_u8(mask, true_val[i], false_val[i]);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static inline int const_time_memcmp(const void *a, const void *b, size_t len)
|
||||
+{
|
||||
+ const u8 *aa = a;
|
||||
+ const u8 *bb = b;
|
||||
+ int diff, res = 0;
|
||||
+ unsigned int mask;
|
||||
+
|
||||
+ if (len == 0)
|
||||
+ return 0;
|
||||
+ do {
|
||||
+ len--;
|
||||
+ diff = (int) aa[len] - (int) bb[len];
|
||||
+ mask = const_time_is_zero((unsigned int) diff);
|
||||
+ res = const_time_select_int(mask, res, diff);
|
||||
+ } while (len);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+#endif /* CONST_TIME_H */
|
@ -1,55 +0,0 @@
|
||||
From c93461c1d98f52681717a088776ab32fd97872b0 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Fri, 8 Mar 2019 00:24:12 +0200
|
||||
Subject: [PATCH 03/14] OpenSSL: Use constant time selection for
|
||||
crypto_bignum_legendre()
|
||||
|
||||
Get rid of the branches that depend on the result of the Legendre
|
||||
operation. This is needed to avoid leaking information about different
|
||||
temporary results in blinding mechanisms.
|
||||
|
||||
This is related to CVE-2019-9494 and CVE-2019-9495.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/crypto/crypto_openssl.c | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/src/crypto/crypto_openssl.c
|
||||
+++ b/src/crypto/crypto_openssl.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#endif /* CONFIG_ECC */
|
||||
|
||||
#include "common.h"
|
||||
+#include "utils/const_time.h"
|
||||
#include "wpabuf.h"
|
||||
#include "dh_group5.h"
|
||||
#include "sha1.h"
|
||||
@@ -1435,6 +1436,7 @@ int crypto_bignum_legendre(const struct
|
||||
BN_CTX *bnctx;
|
||||
BIGNUM *exp = NULL, *tmp = NULL;
|
||||
int res = -2;
|
||||
+ unsigned int mask;
|
||||
|
||||
if (TEST_FAIL())
|
||||
return -2;
|
||||
@@ -1453,12 +1455,13 @@ int crypto_bignum_legendre(const struct
|
||||
(const BIGNUM *) p, bnctx, NULL))
|
||||
goto fail;
|
||||
|
||||
- if (BN_is_word(tmp, 1))
|
||||
- res = 1;
|
||||
- else if (BN_is_zero(tmp))
|
||||
- res = 0;
|
||||
- else
|
||||
- res = -1;
|
||||
+ /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need to use
|
||||
+ * constant time selection to avoid branches here. */
|
||||
+ res = -1;
|
||||
+ mask = const_time_eq(BN_is_word(tmp, 1), 1);
|
||||
+ res = const_time_select_int(mask, 1, res);
|
||||
+ mask = const_time_eq(BN_is_zero(tmp), 1);
|
||||
+ res = const_time_select_int(mask, 0, res);
|
||||
|
||||
fail:
|
||||
BN_clear_free(tmp);
|
@ -1,242 +0,0 @@
|
||||
From 6513db3e96c43c2e36805cf5ead349765d18eaf7 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Tue, 26 Feb 2019 13:05:09 +0200
|
||||
Subject: [PATCH 05/14] SAE: Minimize timing differences in PWE derivation
|
||||
|
||||
The QR test result can provide information about the password to an
|
||||
attacker, so try to minimize differences in how the
|
||||
sae_test_pwd_seed_ecc() result is used. (CVE-2019-9494)
|
||||
|
||||
Use heap memory for the dummy password to allow the same password length
|
||||
to be used even with long passwords.
|
||||
|
||||
Use constant time selection functions to track the real vs. dummy
|
||||
variables so that the exact same operations can be performed for both QR
|
||||
test results.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/common/sae.c | 106 ++++++++++++++++++++++++++++++-------------------------
|
||||
1 file changed, 57 insertions(+), 49 deletions(-)
|
||||
|
||||
--- a/src/common/sae.c
|
||||
+++ b/src/common/sae.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
+#include "utils/const_time.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/random.h"
|
||||
@@ -269,15 +270,12 @@ static int sae_test_pwd_seed_ecc(struct
|
||||
const u8 *prime,
|
||||
const struct crypto_bignum *qr,
|
||||
const struct crypto_bignum *qnr,
|
||||
- struct crypto_bignum **ret_x_cand)
|
||||
+ u8 *pwd_value)
|
||||
{
|
||||
- u8 pwd_value[SAE_MAX_ECC_PRIME_LEN];
|
||||
struct crypto_bignum *y_sqr, *x_cand;
|
||||
int res;
|
||||
size_t bits;
|
||||
|
||||
- *ret_x_cand = NULL;
|
||||
-
|
||||
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
|
||||
|
||||
/* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
|
||||
@@ -286,7 +284,7 @@ static int sae_test_pwd_seed_ecc(struct
|
||||
prime, sae->tmp->prime_len, pwd_value, bits) < 0)
|
||||
return -1;
|
||||
if (bits % 8)
|
||||
- buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
|
||||
+ buf_shift_right(pwd_value, sae->tmp->prime_len, 8 - bits % 8);
|
||||
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
|
||||
pwd_value, sae->tmp->prime_len);
|
||||
|
||||
@@ -297,20 +295,13 @@ static int sae_test_pwd_seed_ecc(struct
|
||||
if (!x_cand)
|
||||
return -1;
|
||||
y_sqr = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x_cand);
|
||||
- if (!y_sqr) {
|
||||
- crypto_bignum_deinit(x_cand, 1);
|
||||
+ crypto_bignum_deinit(x_cand, 1);
|
||||
+ if (!y_sqr)
|
||||
return -1;
|
||||
- }
|
||||
|
||||
res = is_quadratic_residue_blind(sae, prime, bits, qr, qnr, y_sqr);
|
||||
crypto_bignum_deinit(y_sqr, 1);
|
||||
- if (res <= 0) {
|
||||
- crypto_bignum_deinit(x_cand, 1);
|
||||
- return res;
|
||||
- }
|
||||
-
|
||||
- *ret_x_cand = x_cand;
|
||||
- return 1;
|
||||
+ return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -431,25 +422,30 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
const u8 *addr[3];
|
||||
size_t len[3];
|
||||
size_t num_elem;
|
||||
- u8 dummy_password[32];
|
||||
- size_t dummy_password_len;
|
||||
+ u8 *dummy_password, *tmp_password;
|
||||
int pwd_seed_odd = 0;
|
||||
u8 prime[SAE_MAX_ECC_PRIME_LEN];
|
||||
size_t prime_len;
|
||||
- struct crypto_bignum *x = NULL, *qr, *qnr;
|
||||
+ struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
|
||||
+ u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
|
||||
+ u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
|
||||
size_t bits;
|
||||
- int res;
|
||||
-
|
||||
- dummy_password_len = password_len;
|
||||
- if (dummy_password_len > sizeof(dummy_password))
|
||||
- dummy_password_len = sizeof(dummy_password);
|
||||
- if (random_get_bytes(dummy_password, dummy_password_len) < 0)
|
||||
- return -1;
|
||||
+ int res = -1;
|
||||
+ u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
|
||||
+ * mask */
|
||||
+
|
||||
+ os_memset(x_bin, 0, sizeof(x_bin));
|
||||
+
|
||||
+ dummy_password = os_malloc(password_len);
|
||||
+ tmp_password = os_malloc(password_len);
|
||||
+ if (!dummy_password || !tmp_password ||
|
||||
+ random_get_bytes(dummy_password, password_len) < 0)
|
||||
+ goto fail;
|
||||
|
||||
prime_len = sae->tmp->prime_len;
|
||||
if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
|
||||
prime_len) < 0)
|
||||
- return -1;
|
||||
+ goto fail;
|
||||
bits = crypto_ec_prime_len_bits(sae->tmp->ec);
|
||||
|
||||
/*
|
||||
@@ -458,7 +454,7 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
*/
|
||||
if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits,
|
||||
&qr, &qnr) < 0)
|
||||
- return -1;
|
||||
+ goto fail;
|
||||
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
|
||||
password, password_len);
|
||||
@@ -474,7 +470,7 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
*/
|
||||
sae_pwd_seed_key(addr1, addr2, addrs);
|
||||
|
||||
- addr[0] = password;
|
||||
+ addr[0] = tmp_password;
|
||||
len[0] = password_len;
|
||||
num_elem = 1;
|
||||
if (identifier) {
|
||||
@@ -491,9 +487,8 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
* attacks that attempt to determine the number of iterations required
|
||||
* in the loop.
|
||||
*/
|
||||
- for (counter = 1; counter <= k || !x; counter++) {
|
||||
+ for (counter = 1; counter <= k || !found; counter++) {
|
||||
u8 pwd_seed[SHA256_MAC_LEN];
|
||||
- struct crypto_bignum *x_cand;
|
||||
|
||||
if (counter > 200) {
|
||||
/* This should not happen in practice */
|
||||
@@ -501,40 +496,49 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
break;
|
||||
}
|
||||
|
||||
- wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
|
||||
+ wpa_printf(MSG_DEBUG, "SAE: counter = %03u", counter);
|
||||
+ const_time_select_bin(found, dummy_password, password,
|
||||
+ password_len, tmp_password);
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
|
||||
addr, len, pwd_seed) < 0)
|
||||
break;
|
||||
|
||||
res = sae_test_pwd_seed_ecc(sae, pwd_seed,
|
||||
- prime, qr, qnr, &x_cand);
|
||||
+ prime, qr, qnr, x_cand_bin);
|
||||
+ const_time_select_bin(found, x_bin, x_cand_bin, prime_len,
|
||||
+ x_bin);
|
||||
+ pwd_seed_odd = const_time_select_u8(
|
||||
+ found, pwd_seed_odd,
|
||||
+ pwd_seed[SHA256_MAC_LEN - 1] & 0x01);
|
||||
+ os_memset(pwd_seed, 0, sizeof(pwd_seed));
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
- if (res > 0 && !x) {
|
||||
- wpa_printf(MSG_DEBUG,
|
||||
- "SAE: Selected pwd-seed with counter %u",
|
||||
- counter);
|
||||
- x = x_cand;
|
||||
- pwd_seed_odd = pwd_seed[SHA256_MAC_LEN - 1] & 0x01;
|
||||
- os_memset(pwd_seed, 0, sizeof(pwd_seed));
|
||||
-
|
||||
- /*
|
||||
- * Use a dummy password for the following rounds, if
|
||||
- * any.
|
||||
- */
|
||||
- addr[0] = dummy_password;
|
||||
- len[0] = dummy_password_len;
|
||||
- } else if (res > 0) {
|
||||
- crypto_bignum_deinit(x_cand, 1);
|
||||
- }
|
||||
+ /* Need to minimize differences in handling res == 0 and 1 here
|
||||
+ * to avoid differences in timing and instruction cache access,
|
||||
+ * so use const_time_select_*() to make local copies of the
|
||||
+ * values based on whether this loop iteration was the one that
|
||||
+ * found the pwd-seed/x. */
|
||||
+
|
||||
+ /* found is 0 or 0xff here and res is 0 or 1. Bitwise OR of them
|
||||
+ * (with res converted to 0/0xff) handles this in constant time.
|
||||
+ */
|
||||
+ found |= res * 0xff;
|
||||
+ wpa_printf(MSG_DEBUG, "SAE: pwd-seed result %d found=0x%02x",
|
||||
+ res, found);
|
||||
}
|
||||
|
||||
- if (!x) {
|
||||
+ if (!found) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
|
||||
res = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ x = crypto_bignum_init_set(x_bin, prime_len);
|
||||
+ if (!x) {
|
||||
+ res = -1;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (!sae->tmp->pwe_ecc)
|
||||
sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec);
|
||||
if (!sae->tmp->pwe_ecc)
|
||||
@@ -543,7 +547,6 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
res = crypto_ec_point_solve_y_coord(sae->tmp->ec,
|
||||
sae->tmp->pwe_ecc, x,
|
||||
pwd_seed_odd);
|
||||
- crypto_bignum_deinit(x, 1);
|
||||
if (res < 0) {
|
||||
/*
|
||||
* This should not happen since we already checked that there
|
||||
@@ -555,6 +558,11 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
fail:
|
||||
crypto_bignum_deinit(qr, 0);
|
||||
crypto_bignum_deinit(qnr, 0);
|
||||
+ os_free(dummy_password);
|
||||
+ bin_clear_free(tmp_password, password_len);
|
||||
+ crypto_bignum_deinit(x, 1);
|
||||
+ os_memset(x_bin, 0, sizeof(x_bin));
|
||||
+ os_memset(x_cand_bin, 0, sizeof(x_cand_bin));
|
||||
|
||||
return res;
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
From 362704dda04507e7ebb8035122e83d9f0ae7c320 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Tue, 26 Feb 2019 19:34:38 +0200
|
||||
Subject: [PATCH 06/14] SAE: Avoid branches in is_quadratic_residue_blind()
|
||||
|
||||
Make the non-failure path in the function proceed without branches based
|
||||
on r_odd and in constant time to minimize risk of observable differences
|
||||
in timing or cache use. (CVE-2019-9494)
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/common/sae.c | 64 ++++++++++++++++++++++++++++++++------------------------
|
||||
1 file changed, 37 insertions(+), 27 deletions(-)
|
||||
|
||||
--- a/src/common/sae.c
|
||||
+++ b/src/common/sae.c
|
||||
@@ -209,12 +209,14 @@ get_rand_1_to_p_1(const u8 *prime, size_
|
||||
|
||||
static int is_quadratic_residue_blind(struct sae_data *sae,
|
||||
const u8 *prime, size_t bits,
|
||||
- const struct crypto_bignum *qr,
|
||||
- const struct crypto_bignum *qnr,
|
||||
+ const u8 *qr, const u8 *qnr,
|
||||
const struct crypto_bignum *y_sqr)
|
||||
{
|
||||
- struct crypto_bignum *r, *num;
|
||||
+ struct crypto_bignum *r, *num, *qr_or_qnr = NULL;
|
||||
int r_odd, check, res = -1;
|
||||
+ u8 qr_or_qnr_bin[SAE_MAX_ECC_PRIME_LEN];
|
||||
+ size_t prime_len = sae->tmp->prime_len;
|
||||
+ unsigned int mask;
|
||||
|
||||
/*
|
||||
* Use the blinding technique to mask y_sqr while determining
|
||||
@@ -225,7 +227,7 @@ static int is_quadratic_residue_blind(st
|
||||
* r = a random number between 1 and p-1, inclusive
|
||||
* num = (v * r * r) modulo p
|
||||
*/
|
||||
- r = get_rand_1_to_p_1(prime, sae->tmp->prime_len, bits, &r_odd);
|
||||
+ r = get_rand_1_to_p_1(prime, prime_len, bits, &r_odd);
|
||||
if (!r)
|
||||
return -1;
|
||||
|
||||
@@ -235,41 +237,45 @@ static int is_quadratic_residue_blind(st
|
||||
crypto_bignum_mulmod(num, r, sae->tmp->prime, num) < 0)
|
||||
goto fail;
|
||||
|
||||
- if (r_odd) {
|
||||
- /*
|
||||
- * num = (num * qr) module p
|
||||
- * LGR(num, p) = 1 ==> quadratic residue
|
||||
- */
|
||||
- if (crypto_bignum_mulmod(num, qr, sae->tmp->prime, num) < 0)
|
||||
- goto fail;
|
||||
- check = 1;
|
||||
- } else {
|
||||
- /*
|
||||
- * num = (num * qnr) module p
|
||||
- * LGR(num, p) = -1 ==> quadratic residue
|
||||
- */
|
||||
- if (crypto_bignum_mulmod(num, qnr, sae->tmp->prime, num) < 0)
|
||||
- goto fail;
|
||||
- check = -1;
|
||||
- }
|
||||
+ /*
|
||||
+ * Need to minimize differences in handling different cases, so try to
|
||||
+ * avoid branches and timing differences.
|
||||
+ *
|
||||
+ * If r_odd:
|
||||
+ * num = (num * qr) module p
|
||||
+ * LGR(num, p) = 1 ==> quadratic residue
|
||||
+ * else:
|
||||
+ * num = (num * qnr) module p
|
||||
+ * LGR(num, p) = -1 ==> quadratic residue
|
||||
+ */
|
||||
+ mask = const_time_is_zero(r_odd);
|
||||
+ const_time_select_bin(mask, qnr, qr, prime_len, qr_or_qnr_bin);
|
||||
+ qr_or_qnr = crypto_bignum_init_set(qr_or_qnr_bin, prime_len);
|
||||
+ if (!qr_or_qnr ||
|
||||
+ crypto_bignum_mulmod(num, qr_or_qnr, sae->tmp->prime, num) < 0)
|
||||
+ goto fail;
|
||||
+ /* r_odd is 0 or 1; branchless version of check = r_odd ? 1 : -1, */
|
||||
+ check = const_time_select_int(mask, -1, 1);
|
||||
|
||||
res = crypto_bignum_legendre(num, sae->tmp->prime);
|
||||
if (res == -2) {
|
||||
res = -1;
|
||||
goto fail;
|
||||
}
|
||||
- res = res == check;
|
||||
+ /* branchless version of res = res == check
|
||||
+ * (res is -1, 0, or 1; check is -1 or 1) */
|
||||
+ mask = const_time_eq(res, check);
|
||||
+ res = const_time_select_int(mask, 1, 0);
|
||||
fail:
|
||||
crypto_bignum_deinit(num, 1);
|
||||
crypto_bignum_deinit(r, 1);
|
||||
+ crypto_bignum_deinit(qr_or_qnr, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed,
|
||||
- const u8 *prime,
|
||||
- const struct crypto_bignum *qr,
|
||||
- const struct crypto_bignum *qnr,
|
||||
+ const u8 *prime, const u8 *qr, const u8 *qnr,
|
||||
u8 *pwd_value)
|
||||
{
|
||||
struct crypto_bignum *y_sqr, *x_cand;
|
||||
@@ -429,6 +435,8 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
|
||||
u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
|
||||
u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
|
||||
+ u8 qr_bin[SAE_MAX_ECC_PRIME_LEN];
|
||||
+ u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN];
|
||||
size_t bits;
|
||||
int res = -1;
|
||||
u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
|
||||
@@ -453,7 +461,9 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
* (qnr) modulo p for blinding purposes during the loop.
|
||||
*/
|
||||
if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits,
|
||||
- &qr, &qnr) < 0)
|
||||
+ &qr, &qnr) < 0 ||
|
||||
+ crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), prime_len) < 0 ||
|
||||
+ crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin), prime_len) < 0)
|
||||
goto fail;
|
||||
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
|
||||
@@ -504,7 +514,7 @@ static int sae_derive_pwe_ecc(struct sae
|
||||
break;
|
||||
|
||||
res = sae_test_pwd_seed_ecc(sae, pwd_seed,
|
||||
- prime, qr, qnr, x_cand_bin);
|
||||
+ prime, qr_bin, qnr_bin, x_cand_bin);
|
||||
const_time_select_bin(found, x_bin, x_cand_bin, prime_len,
|
||||
x_bin);
|
||||
pwd_seed_odd = const_time_select_u8(
|
@ -1,113 +0,0 @@
|
||||
From 90839597cc4016b33f00055b12d59174c62770a3 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Sat, 2 Mar 2019 12:24:09 +0200
|
||||
Subject: [PATCH 07/14] SAE: Mask timing of MODP groups 22, 23, 24
|
||||
|
||||
These groups have significant probability of coming up with pwd-value
|
||||
that is equal or greater than the prime and as such, need for going
|
||||
through the PWE derivation loop multiple times. This can result in
|
||||
sufficient timing different to allow an external observer to determine
|
||||
how many rounds are needed and that can leak information about the used
|
||||
password.
|
||||
|
||||
Force at least 40 loop rounds for these MODP groups similarly to the ECC
|
||||
group design to mask timing. This behavior is not described in IEEE Std
|
||||
802.11-2016 for SAE, but it does not result in different values (i.e.,
|
||||
only different timing), so such implementation specific countermeasures
|
||||
can be done without breaking interoperability with other implementation.
|
||||
|
||||
Note: These MODP groups 22, 23, and 24 are not considered sufficiently
|
||||
strong to be used with SAE (or more or less anything else). As such,
|
||||
they should never be enabled in runtime configuration for any production
|
||||
use cases. These changes to introduce additional protection to mask
|
||||
timing is only for completeness of implementation and not an indication
|
||||
that these groups should be used.
|
||||
|
||||
This is related to CVE-2019-9494.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/common/sae.c | 38 ++++++++++++++++++++++++++++----------
|
||||
1 file changed, 28 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/src/common/sae.c
|
||||
+++ b/src/common/sae.c
|
||||
@@ -578,22 +578,27 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
+static int sae_modp_group_require_masking(int group)
|
||||
+{
|
||||
+ /* Groups for which pwd-value is likely to be >= p frequently */
|
||||
+ return group == 22 || group == 23 || group == 24;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
|
||||
const u8 *addr2, const u8 *password,
|
||||
size_t password_len, const char *identifier)
|
||||
{
|
||||
- u8 counter;
|
||||
+ u8 counter, k;
|
||||
u8 addrs[2 * ETH_ALEN];
|
||||
const u8 *addr[3];
|
||||
size_t len[3];
|
||||
size_t num_elem;
|
||||
int found = 0;
|
||||
+ struct crypto_bignum *pwe = NULL;
|
||||
|
||||
- if (sae->tmp->pwe_ffc == NULL) {
|
||||
- sae->tmp->pwe_ffc = crypto_bignum_init();
|
||||
- if (sae->tmp->pwe_ffc == NULL)
|
||||
- return -1;
|
||||
- }
|
||||
+ crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
|
||||
+ sae->tmp->pwe_ffc = NULL;
|
||||
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
|
||||
password, password_len);
|
||||
@@ -617,7 +622,9 @@ static int sae_derive_pwe_ffc(struct sae
|
||||
len[num_elem] = sizeof(counter);
|
||||
num_elem++;
|
||||
|
||||
- for (counter = 1; !found; counter++) {
|
||||
+ k = sae_modp_group_require_masking(sae->group) ? 40 : 1;
|
||||
+
|
||||
+ for (counter = 1; counter <= k || !found; counter++) {
|
||||
u8 pwd_seed[SHA256_MAC_LEN];
|
||||
int res;
|
||||
|
||||
@@ -627,19 +634,30 @@ static int sae_derive_pwe_ffc(struct sae
|
||||
break;
|
||||
}
|
||||
|
||||
- wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
|
||||
+ wpa_printf(MSG_DEBUG, "SAE: counter = %02u", counter);
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
|
||||
addr, len, pwd_seed) < 0)
|
||||
break;
|
||||
- res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc);
|
||||
+ if (!pwe) {
|
||||
+ pwe = crypto_bignum_init();
|
||||
+ if (!pwe)
|
||||
+ break;
|
||||
+ }
|
||||
+ res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
|
||||
if (res < 0)
|
||||
break;
|
||||
if (res > 0) {
|
||||
- wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
|
||||
found = 1;
|
||||
+ if (!sae->tmp->pwe_ffc) {
|
||||
+ wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
|
||||
+ sae->tmp->pwe_ffc = pwe;
|
||||
+ pwe = NULL;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
+ crypto_bignum_deinit(pwe, 1);
|
||||
+
|
||||
return found ? 0 : -1;
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
From f8f20717f87eff1f025f48ed585c7684debacf72 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Sat, 2 Mar 2019 12:45:33 +0200
|
||||
Subject: [PATCH 08/14] SAE: Use const_time selection for PWE in FFC
|
||||
|
||||
This is an initial step towards making the FFC case use strictly
|
||||
constant time operations similarly to the ECC case.
|
||||
sae_test_pwd_seed_ffc() does not yet have constant time behavior,
|
||||
though.
|
||||
|
||||
This is related to CVE-2019-9494.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/common/sae.c | 53 +++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 35 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/src/common/sae.c
|
||||
+++ b/src/common/sae.c
|
||||
@@ -589,17 +589,28 @@ static int sae_derive_pwe_ffc(struct sae
|
||||
const u8 *addr2, const u8 *password,
|
||||
size_t password_len, const char *identifier)
|
||||
{
|
||||
- u8 counter, k;
|
||||
+ u8 counter, k, sel_counter = 0;
|
||||
u8 addrs[2 * ETH_ALEN];
|
||||
const u8 *addr[3];
|
||||
size_t len[3];
|
||||
size_t num_elem;
|
||||
- int found = 0;
|
||||
- struct crypto_bignum *pwe = NULL;
|
||||
+ u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
|
||||
+ * mask */
|
||||
+ u8 mask;
|
||||
+ struct crypto_bignum *pwe;
|
||||
+ size_t prime_len = sae->tmp->prime_len * 8;
|
||||
+ u8 *pwe_buf;
|
||||
|
||||
crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
|
||||
sae->tmp->pwe_ffc = NULL;
|
||||
|
||||
+ /* Allocate a buffer to maintain selected and candidate PWE for constant
|
||||
+ * time selection. */
|
||||
+ pwe_buf = os_zalloc(prime_len * 2);
|
||||
+ pwe = crypto_bignum_init();
|
||||
+ if (!pwe_buf || !pwe)
|
||||
+ goto fail;
|
||||
+
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
|
||||
password, password_len);
|
||||
|
||||
@@ -638,27 +649,33 @@ static int sae_derive_pwe_ffc(struct sae
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
|
||||
addr, len, pwd_seed) < 0)
|
||||
break;
|
||||
- if (!pwe) {
|
||||
- pwe = crypto_bignum_init();
|
||||
- if (!pwe)
|
||||
- break;
|
||||
- }
|
||||
res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
|
||||
+ /* res is -1 for fatal failure, 0 if a valid PWE was not found,
|
||||
+ * or 1 if a valid PWE was found. */
|
||||
if (res < 0)
|
||||
break;
|
||||
- if (res > 0) {
|
||||
- found = 1;
|
||||
- if (!sae->tmp->pwe_ffc) {
|
||||
- wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
|
||||
- sae->tmp->pwe_ffc = pwe;
|
||||
- pwe = NULL;
|
||||
- }
|
||||
- }
|
||||
+ /* Store the candidate PWE into the second half of pwe_buf and
|
||||
+ * the selected PWE in the beginning of pwe_buf using constant
|
||||
+ * time selection. */
|
||||
+ if (crypto_bignum_to_bin(pwe, pwe_buf + prime_len, prime_len,
|
||||
+ prime_len) < 0)
|
||||
+ break;
|
||||
+ const_time_select_bin(found, pwe_buf, pwe_buf + prime_len,
|
||||
+ prime_len, pwe_buf);
|
||||
+ sel_counter = const_time_select_u8(found, sel_counter, counter);
|
||||
+ mask = const_time_eq_u8(res, 1);
|
||||
+ found = const_time_select_u8(found, found, mask);
|
||||
}
|
||||
|
||||
- crypto_bignum_deinit(pwe, 1);
|
||||
+ if (!found)
|
||||
+ goto fail;
|
||||
|
||||
- return found ? 0 : -1;
|
||||
+ wpa_printf(MSG_DEBUG, "SAE: Use PWE from counter = %02u", sel_counter);
|
||||
+ sae->tmp->pwe_ffc = crypto_bignum_init_set(pwe_buf, prime_len);
|
||||
+fail:
|
||||
+ crypto_bignum_deinit(pwe, 1);
|
||||
+ bin_clear_free(pwe_buf, prime_len * 2);
|
||||
+ return sae->tmp->pwe_ffc ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -1,133 +0,0 @@
|
||||
From cff138b0747fa39765cbc641b66cfa5d7f1735d1 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Sat, 2 Mar 2019 16:05:56 +0200
|
||||
Subject: [PATCH 09/14] SAE: Use constant time operations in
|
||||
sae_test_pwd_seed_ffc()
|
||||
|
||||
Try to avoid showing externally visible timing or memory access
|
||||
differences regardless of whether the derived pwd-value is smaller than
|
||||
the group prime.
|
||||
|
||||
This is related to CVE-2019-9494.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/common/sae.c | 75 ++++++++++++++++++++++++++++++++++----------------------
|
||||
1 file changed, 46 insertions(+), 29 deletions(-)
|
||||
|
||||
--- a/src/common/sae.c
|
||||
+++ b/src/common/sae.c
|
||||
@@ -311,14 +311,17 @@ static int sae_test_pwd_seed_ecc(struct
|
||||
}
|
||||
|
||||
|
||||
+/* Returns -1 on fatal failure, 0 if PWE cannot be derived from the provided
|
||||
+ * pwd-seed, or 1 if a valid PWE was derived from pwd-seed. */
|
||||
static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed,
|
||||
struct crypto_bignum *pwe)
|
||||
{
|
||||
u8 pwd_value[SAE_MAX_PRIME_LEN];
|
||||
size_t bits = sae->tmp->prime_len * 8;
|
||||
u8 exp[1];
|
||||
- struct crypto_bignum *a, *b;
|
||||
- int res;
|
||||
+ struct crypto_bignum *a, *b = NULL;
|
||||
+ int res, is_val;
|
||||
+ u8 pwd_value_valid;
|
||||
|
||||
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
|
||||
|
||||
@@ -330,16 +333,29 @@ static int sae_test_pwd_seed_ffc(struct
|
||||
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value,
|
||||
sae->tmp->prime_len);
|
||||
|
||||
- if (os_memcmp(pwd_value, sae->tmp->dh->prime, sae->tmp->prime_len) >= 0)
|
||||
- {
|
||||
- wpa_printf(MSG_DEBUG, "SAE: pwd-value >= p");
|
||||
- return 0;
|
||||
- }
|
||||
+ /* Check whether pwd-value < p */
|
||||
+ res = const_time_memcmp(pwd_value, sae->tmp->dh->prime,
|
||||
+ sae->tmp->prime_len);
|
||||
+ /* pwd-value >= p is invalid, so res is < 0 for the valid cases and
|
||||
+ * the negative sign can be used to fill the mask for constant time
|
||||
+ * selection */
|
||||
+ pwd_value_valid = const_time_fill_msb(res);
|
||||
+
|
||||
+ /* If pwd-value >= p, force pwd-value to be < p and perform the
|
||||
+ * calculations anyway to hide timing difference. The derived PWE will
|
||||
+ * be ignored in that case. */
|
||||
+ pwd_value[0] = const_time_select_u8(pwd_value_valid, pwd_value[0], 0);
|
||||
|
||||
/* PWE = pwd-value^((p-1)/r) modulo p */
|
||||
|
||||
+ res = -1;
|
||||
a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
|
||||
+ if (!a)
|
||||
+ goto fail;
|
||||
|
||||
+ /* This is an optimization based on the used group that does not depend
|
||||
+ * on the password in any way, so it is fine to use separate branches
|
||||
+ * for this step without constant time operations. */
|
||||
if (sae->tmp->dh->safe_prime) {
|
||||
/*
|
||||
* r = (p-1)/2 for the group used here, so this becomes:
|
||||
@@ -353,33 +369,34 @@ static int sae_test_pwd_seed_ffc(struct
|
||||
b = crypto_bignum_init_set(exp, sizeof(exp));
|
||||
if (b == NULL ||
|
||||
crypto_bignum_sub(sae->tmp->prime, b, b) < 0 ||
|
||||
- crypto_bignum_div(b, sae->tmp->order, b) < 0) {
|
||||
- crypto_bignum_deinit(b, 0);
|
||||
- b = NULL;
|
||||
- }
|
||||
+ crypto_bignum_div(b, sae->tmp->order, b) < 0)
|
||||
+ goto fail;
|
||||
}
|
||||
|
||||
- if (a == NULL || b == NULL)
|
||||
- res = -1;
|
||||
- else
|
||||
- res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
|
||||
-
|
||||
- crypto_bignum_deinit(a, 0);
|
||||
- crypto_bignum_deinit(b, 0);
|
||||
-
|
||||
- if (res < 0) {
|
||||
- wpa_printf(MSG_DEBUG, "SAE: Failed to calculate PWE");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- /* if (PWE > 1) --> found */
|
||||
- if (crypto_bignum_is_zero(pwe) || crypto_bignum_is_one(pwe)) {
|
||||
- wpa_printf(MSG_DEBUG, "SAE: PWE <= 1");
|
||||
- return 0;
|
||||
- }
|
||||
+ if (!b)
|
||||
+ goto fail;
|
||||
|
||||
- wpa_printf(MSG_DEBUG, "SAE: PWE found");
|
||||
- return 1;
|
||||
+ res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
|
||||
+ if (res < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* There were no fatal errors in calculations, so determine the return
|
||||
+ * value using constant time operations. We get here for number of
|
||||
+ * invalid cases which are cleared here after having performed all the
|
||||
+ * computation. PWE is valid if pwd-value was less than prime and
|
||||
+ * PWE > 1. Start with pwd-value check first and then use constant time
|
||||
+ * operations to clear res to 0 if PWE is 0 or 1.
|
||||
+ */
|
||||
+ res = const_time_select_u8(pwd_value_valid, 1, 0);
|
||||
+ is_val = crypto_bignum_is_zero(pwe);
|
||||
+ res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
|
||||
+ is_val = crypto_bignum_is_one(pwe);
|
||||
+ res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
|
||||
+
|
||||
+fail:
|
||||
+ crypto_bignum_deinit(a, 1);
|
||||
+ crypto_bignum_deinit(b, 1);
|
||||
+ return res;
|
||||
}
|
||||
|
||||
|
@ -1,319 +0,0 @@
|
||||
From aaf65feac67c3993935634eefe5bc76b9fce03aa Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Tue, 26 Feb 2019 11:59:45 +0200
|
||||
Subject: [PATCH 04/14] EAP-pwd: Use constant time and memory access for
|
||||
finding the PWE
|
||||
|
||||
This algorithm could leak information to external observers in form of
|
||||
timing differences or memory access patterns (cache use). While the
|
||||
previous implementation had protection against the most visible timing
|
||||
differences (looping 40 rounds and masking the legendre operation), it
|
||||
did not protect against memory access patterns between the two possible
|
||||
code paths in the masking operations. That might be sufficient to allow
|
||||
an unprivileged process running on the same device to be able to
|
||||
determine which path is being executed through a cache attack and based
|
||||
on that, determine information about the used password.
|
||||
|
||||
Convert the PWE finding loop to use constant time functions and
|
||||
identical memory access path without different branches for the QR/QNR
|
||||
cases to minimize possible side-channel information similarly to the
|
||||
changes done for SAE authentication. (CVE-2019-9495)
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/eap_common/eap_pwd_common.c | 187 +++++++++++++++++++++-------------------
|
||||
1 file changed, 99 insertions(+), 88 deletions(-)
|
||||
|
||||
--- a/src/eap_common/eap_pwd_common.c
|
||||
+++ b/src/eap_common/eap_pwd_common.c
|
||||
@@ -8,11 +8,15 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "common.h"
|
||||
+#include "utils/const_time.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "eap_defs.h"
|
||||
#include "eap_pwd_common.h"
|
||||
|
||||
+#define MAX_ECC_PRIME_LEN 66
|
||||
+
|
||||
+
|
||||
/* The random function H(x) = HMAC-SHA256(0^32, x) */
|
||||
struct crypto_hash * eap_pwd_h_init(void)
|
||||
{
|
||||
@@ -102,6 +106,15 @@ EAP_PWD_group * get_eap_pwd_group(u16 nu
|
||||
}
|
||||
|
||||
|
||||
+static void buf_shift_right(u8 *buf, size_t len, size_t bits)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ for (i = len - 1; i > 0; i--)
|
||||
+ buf[i] = (buf[i - 1] << (8 - bits)) | (buf[i] >> bits);
|
||||
+ buf[0] >>= bits;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* compute a "random" secret point on an elliptic curve based
|
||||
* on the password and identities.
|
||||
@@ -113,17 +126,27 @@ int compute_password_element(EAP_PWD_gro
|
||||
const u8 *token)
|
||||
{
|
||||
struct crypto_bignum *qr = NULL, *qnr = NULL, *one = NULL;
|
||||
+ struct crypto_bignum *qr_or_qnr = NULL;
|
||||
+ u8 qr_bin[MAX_ECC_PRIME_LEN];
|
||||
+ u8 qnr_bin[MAX_ECC_PRIME_LEN];
|
||||
+ u8 qr_or_qnr_bin[MAX_ECC_PRIME_LEN];
|
||||
+ u8 x_bin[MAX_ECC_PRIME_LEN];
|
||||
struct crypto_bignum *tmp1 = NULL, *tmp2 = NULL, *pm1 = NULL;
|
||||
struct crypto_hash *hash;
|
||||
unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr;
|
||||
- int is_odd, ret = 0, check, found = 0;
|
||||
- size_t primebytelen, primebitlen;
|
||||
- struct crypto_bignum *x_candidate = NULL, *rnd = NULL, *cofactor = NULL;
|
||||
+ int ret = 0, check, res;
|
||||
+ u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
|
||||
+ * mask */
|
||||
+ size_t primebytelen = 0, primebitlen;
|
||||
+ struct crypto_bignum *x_candidate = NULL, *cofactor = NULL;
|
||||
const struct crypto_bignum *prime;
|
||||
+ u8 mask, found_ctr = 0, is_odd = 0;
|
||||
|
||||
if (grp->pwe)
|
||||
return -1;
|
||||
|
||||
+ os_memset(x_bin, 0, sizeof(x_bin));
|
||||
+
|
||||
prime = crypto_ec_get_prime(grp->group);
|
||||
cofactor = crypto_bignum_init();
|
||||
grp->pwe = crypto_ec_point_init(grp->group);
|
||||
@@ -152,8 +175,6 @@ int compute_password_element(EAP_PWD_gro
|
||||
|
||||
/* get a random quadratic residue and nonresidue */
|
||||
while (!qr || !qnr) {
|
||||
- int res;
|
||||
-
|
||||
if (crypto_bignum_rand(tmp1, prime) < 0)
|
||||
goto fail;
|
||||
res = crypto_bignum_legendre(tmp1, prime);
|
||||
@@ -167,6 +188,11 @@ int compute_password_element(EAP_PWD_gro
|
||||
if (!tmp1)
|
||||
goto fail;
|
||||
}
|
||||
+ if (crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin),
|
||||
+ primebytelen) < 0 ||
|
||||
+ crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin),
|
||||
+ primebytelen) < 0)
|
||||
+ goto fail;
|
||||
|
||||
os_memset(prfbuf, 0, primebytelen);
|
||||
ctr = 0;
|
||||
@@ -194,17 +220,16 @@ int compute_password_element(EAP_PWD_gro
|
||||
eap_pwd_h_update(hash, &ctr, sizeof(ctr));
|
||||
eap_pwd_h_final(hash, pwe_digest);
|
||||
|
||||
- crypto_bignum_deinit(rnd, 1);
|
||||
- rnd = crypto_bignum_init_set(pwe_digest, SHA256_MAC_LEN);
|
||||
- if (!rnd) {
|
||||
- wpa_printf(MSG_INFO, "EAP-pwd: unable to create rnd");
|
||||
- goto fail;
|
||||
- }
|
||||
+ is_odd = const_time_select_u8(
|
||||
+ found, is_odd, pwe_digest[SHA256_MAC_LEN - 1] & 0x01);
|
||||
if (eap_pwd_kdf(pwe_digest, SHA256_MAC_LEN,
|
||||
(u8 *) "EAP-pwd Hunting And Pecking",
|
||||
os_strlen("EAP-pwd Hunting And Pecking"),
|
||||
prfbuf, primebitlen) < 0)
|
||||
goto fail;
|
||||
+ if (primebitlen % 8)
|
||||
+ buf_shift_right(prfbuf, primebytelen,
|
||||
+ 8 - primebitlen % 8);
|
||||
|
||||
crypto_bignum_deinit(x_candidate, 1);
|
||||
x_candidate = crypto_bignum_init_set(prfbuf, primebytelen);
|
||||
@@ -214,24 +239,13 @@ int compute_password_element(EAP_PWD_gro
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * eap_pwd_kdf() returns a string of bits 0..primebitlen but
|
||||
- * BN_bin2bn will treat that string of bits as a big endian
|
||||
- * number. If the primebitlen is not an even multiple of 8
|
||||
- * then excessive bits-- those _after_ primebitlen-- so now
|
||||
- * we have to shift right the amount we masked off.
|
||||
- */
|
||||
- if ((primebitlen % 8) &&
|
||||
- crypto_bignum_rshift(x_candidate,
|
||||
- (8 - (primebitlen % 8)),
|
||||
- x_candidate) < 0)
|
||||
- goto fail;
|
||||
-
|
||||
if (crypto_bignum_cmp(x_candidate, prime) >= 0)
|
||||
continue;
|
||||
|
||||
- wpa_hexdump(MSG_DEBUG, "EAP-pwd: x_candidate",
|
||||
- prfbuf, primebytelen);
|
||||
+ wpa_hexdump_key(MSG_DEBUG, "EAP-pwd: x_candidate",
|
||||
+ prfbuf, primebytelen);
|
||||
+ const_time_select_bin(found, x_bin, prfbuf, primebytelen,
|
||||
+ x_bin);
|
||||
|
||||
/*
|
||||
* compute y^2 using the equation of the curve
|
||||
@@ -260,13 +274,15 @@ int compute_password_element(EAP_PWD_gro
|
||||
* Flip a coin, multiply by the random quadratic residue or the
|
||||
* random quadratic nonresidue and record heads or tails.
|
||||
*/
|
||||
- if (crypto_bignum_is_odd(tmp1)) {
|
||||
- crypto_bignum_mulmod(tmp2, qr, prime, tmp2);
|
||||
- check = 1;
|
||||
- } else {
|
||||
- crypto_bignum_mulmod(tmp2, qnr, prime, tmp2);
|
||||
- check = -1;
|
||||
- }
|
||||
+ mask = const_time_eq_u8(crypto_bignum_is_odd(tmp1), 1);
|
||||
+ check = const_time_select_s8(mask, 1, -1);
|
||||
+ const_time_select_bin(mask, qr_bin, qnr_bin, primebytelen,
|
||||
+ qr_or_qnr_bin);
|
||||
+ crypto_bignum_deinit(qr_or_qnr, 1);
|
||||
+ qr_or_qnr = crypto_bignum_init_set(qr_or_qnr_bin, primebytelen);
|
||||
+ if (!qr_or_qnr ||
|
||||
+ crypto_bignum_mulmod(tmp2, qr_or_qnr, prime, tmp2) < 0)
|
||||
+ goto fail;
|
||||
|
||||
/*
|
||||
* Now it's safe to do legendre, if check is 1 then it's
|
||||
@@ -274,59 +290,12 @@ int compute_password_element(EAP_PWD_gro
|
||||
* change result), if check is -1 then it's the opposite test
|
||||
* (multiplying a qr by qnr would make a qnr).
|
||||
*/
|
||||
- if (crypto_bignum_legendre(tmp2, prime) == check) {
|
||||
- if (found == 1)
|
||||
- continue;
|
||||
-
|
||||
- /* need to unambiguously identify the solution */
|
||||
- is_odd = crypto_bignum_is_odd(rnd);
|
||||
-
|
||||
- /*
|
||||
- * We know x_candidate is a quadratic residue so set
|
||||
- * it here.
|
||||
- */
|
||||
- if (crypto_ec_point_solve_y_coord(grp->group, grp->pwe,
|
||||
- x_candidate,
|
||||
- is_odd) != 0) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-pwd: Could not solve for y");
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * If there's a solution to the equation then the point
|
||||
- * must be on the curve so why check again explicitly?
|
||||
- * OpenSSL code says this is required by X9.62. We're
|
||||
- * not X9.62 but it can't hurt just to be sure.
|
||||
- */
|
||||
- if (!crypto_ec_point_is_on_curve(grp->group,
|
||||
- grp->pwe)) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-pwd: point is not on curve");
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (!crypto_bignum_is_one(cofactor)) {
|
||||
- /* make sure the point is not in a small
|
||||
- * sub-group */
|
||||
- if (crypto_ec_point_mul(grp->group, grp->pwe,
|
||||
- cofactor,
|
||||
- grp->pwe) != 0) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-pwd: cannot multiply generator by order");
|
||||
- continue;
|
||||
- }
|
||||
- if (crypto_ec_point_is_at_infinity(grp->group,
|
||||
- grp->pwe)) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-pwd: point is at infinity");
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
- wpa_printf(MSG_DEBUG,
|
||||
- "EAP-pwd: found a PWE in %d tries", ctr);
|
||||
- found = 1;
|
||||
- }
|
||||
+ res = crypto_bignum_legendre(tmp2, prime);
|
||||
+ if (res == -2)
|
||||
+ goto fail;
|
||||
+ mask = const_time_eq(res, check);
|
||||
+ found_ctr = const_time_select_u8(found, found_ctr, ctr);
|
||||
+ found |= mask;
|
||||
}
|
||||
if (found == 0) {
|
||||
wpa_printf(MSG_INFO,
|
||||
@@ -334,6 +303,44 @@ int compute_password_element(EAP_PWD_gro
|
||||
num);
|
||||
goto fail;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * We know x_candidate is a quadratic residue so set it here.
|
||||
+ */
|
||||
+ crypto_bignum_deinit(x_candidate, 1);
|
||||
+ x_candidate = crypto_bignum_init_set(x_bin, primebytelen);
|
||||
+ if (!x_candidate ||
|
||||
+ crypto_ec_point_solve_y_coord(grp->group, grp->pwe, x_candidate,
|
||||
+ is_odd) != 0) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: Could not solve for y");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * If there's a solution to the equation then the point must be on the
|
||||
+ * curve so why check again explicitly? OpenSSL code says this is
|
||||
+ * required by X9.62. We're not X9.62 but it can't hurt just to be sure.
|
||||
+ */
|
||||
+ if (!crypto_ec_point_is_on_curve(grp->group, grp->pwe)) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: point is not on curve");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (!crypto_bignum_is_one(cofactor)) {
|
||||
+ /* make sure the point is not in a small sub-group */
|
||||
+ if (crypto_ec_point_mul(grp->group, grp->pwe, cofactor,
|
||||
+ grp->pwe) != 0) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-pwd: cannot multiply generator by order");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (crypto_ec_point_is_at_infinity(grp->group, grp->pwe)) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: point is at infinity");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+ wpa_printf(MSG_DEBUG, "EAP-pwd: found a PWE in %02d tries", found_ctr);
|
||||
+
|
||||
if (0) {
|
||||
fail:
|
||||
crypto_ec_point_deinit(grp->pwe, 1);
|
||||
@@ -343,14 +350,18 @@ int compute_password_element(EAP_PWD_gro
|
||||
/* cleanliness and order.... */
|
||||
crypto_bignum_deinit(cofactor, 1);
|
||||
crypto_bignum_deinit(x_candidate, 1);
|
||||
- crypto_bignum_deinit(rnd, 1);
|
||||
crypto_bignum_deinit(pm1, 0);
|
||||
crypto_bignum_deinit(tmp1, 1);
|
||||
crypto_bignum_deinit(tmp2, 1);
|
||||
crypto_bignum_deinit(qr, 1);
|
||||
crypto_bignum_deinit(qnr, 1);
|
||||
+ crypto_bignum_deinit(qr_or_qnr, 1);
|
||||
crypto_bignum_deinit(one, 0);
|
||||
- os_free(prfbuf);
|
||||
+ bin_clear_free(prfbuf, primebytelen);
|
||||
+ os_memset(qr_bin, 0, sizeof(qr_bin));
|
||||
+ os_memset(qnr_bin, 0, sizeof(qnr_bin));
|
||||
+ os_memset(qr_or_qnr_bin, 0, sizeof(qr_or_qnr_bin));
|
||||
+ os_memset(pwe_digest, 0, sizeof(pwe_digest));
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
From ac8fa9ef198640086cf2ce7c94673be2b6a018a0 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Tue, 5 Mar 2019 23:43:25 +0200
|
||||
Subject: [PATCH 10/14] SAE: Fix confirm message validation in error cases
|
||||
|
||||
Explicitly verify that own and peer commit scalar/element are available
|
||||
when trying to check SAE confirm message. It could have been possible to
|
||||
hit a NULL pointer dereference if the peer element could not have been
|
||||
parsed. (CVE-2019-9496)
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/common/sae.c | 14 +++++++++++---
|
||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/common/sae.c
|
||||
+++ b/src/common/sae.c
|
||||
@@ -1464,23 +1464,31 @@ int sae_check_confirm(struct sae_data *s
|
||||
|
||||
wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data));
|
||||
|
||||
- if (sae->tmp == NULL) {
|
||||
+ if (!sae->tmp || !sae->peer_commit_scalar ||
|
||||
+ !sae->tmp->own_commit_scalar) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available");
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (sae->tmp->ec)
|
||||
+ if (sae->tmp->ec) {
|
||||
+ if (!sae->tmp->peer_commit_element_ecc ||
|
||||
+ !sae->tmp->own_commit_element_ecc)
|
||||
+ return -1;
|
||||
sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar,
|
||||
sae->tmp->peer_commit_element_ecc,
|
||||
sae->tmp->own_commit_scalar,
|
||||
sae->tmp->own_commit_element_ecc,
|
||||
verifier);
|
||||
- else
|
||||
+ } else {
|
||||
+ if (!sae->tmp->peer_commit_element_ffc ||
|
||||
+ !sae->tmp->own_commit_element_ffc)
|
||||
+ return -1;
|
||||
sae_cn_confirm_ffc(sae, data, sae->peer_commit_scalar,
|
||||
sae->tmp->peer_commit_element_ffc,
|
||||
sae->tmp->own_commit_scalar,
|
||||
sae->tmp->own_commit_element_ffc,
|
||||
verifier);
|
||||
+ }
|
||||
|
||||
if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch");
|
@ -1,53 +0,0 @@
|
||||
From 70ff850e89fbc8bc7da515321b4d15b5eef70581 Mon Sep 17 00:00:00 2001
|
||||
From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
|
||||
Date: Sun, 31 Mar 2019 17:13:06 +0200
|
||||
Subject: [PATCH 11/14] EAP-pwd server: Verify received scalar and element
|
||||
|
||||
When processing an EAP-pwd Commit frame, the peer's scalar and element
|
||||
(elliptic curve point) were not validated. This allowed an adversary to
|
||||
bypass authentication, and impersonate any user if the crypto
|
||||
implementation did not verify the validity of the EC point.
|
||||
|
||||
Fix this vulnerability by assuring the received scalar lies within the
|
||||
valid range, and by checking that the received element is not the point
|
||||
at infinity and lies on the elliptic curve being used. (CVE-2019-9498)
|
||||
|
||||
The vulnerability is only exploitable if OpenSSL version 1.0.2 or lower
|
||||
is used, or if LibreSSL or wolfssl is used. Newer versions of OpenSSL
|
||||
(and also BoringSSL) implicitly validate the elliptic curve point in
|
||||
EC_POINT_set_affine_coordinates_GFp(), preventing the attack.
|
||||
|
||||
Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
|
||||
---
|
||||
src/eap_server/eap_server_pwd.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
--- a/src/eap_server/eap_server_pwd.c
|
||||
+++ b/src/eap_server/eap_server_pwd.c
|
||||
@@ -718,6 +718,26 @@ eap_pwd_process_commit_resp(struct eap_s
|
||||
goto fin;
|
||||
}
|
||||
|
||||
+ /* verify received scalar */
|
||||
+ if (crypto_bignum_is_zero(data->peer_scalar) ||
|
||||
+ crypto_bignum_is_one(data->peer_scalar) ||
|
||||
+ crypto_bignum_cmp(data->peer_scalar,
|
||||
+ crypto_ec_get_order(data->grp->group)) >= 0) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-PWD (server): received scalar is invalid");
|
||||
+ goto fin;
|
||||
+ }
|
||||
+
|
||||
+ /* verify received element */
|
||||
+ if (!crypto_ec_point_is_on_curve(data->grp->group,
|
||||
+ data->peer_element) ||
|
||||
+ crypto_ec_point_is_at_infinity(data->grp->group,
|
||||
+ data->peer_element)) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-PWD (server): received element is invalid");
|
||||
+ goto fin;
|
||||
+ }
|
||||
+
|
||||
/* check to ensure peer's element is not in a small sub-group */
|
||||
if (!crypto_bignum_is_one(cofactor)) {
|
||||
if (crypto_ec_point_mul(data->grp->group, data->peer_element,
|
@ -1,40 +0,0 @@
|
||||
From d63edfa90243e9a7de6ae5c275032f2cc79fef95 Mon Sep 17 00:00:00 2001
|
||||
From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
|
||||
Date: Sun, 31 Mar 2019 17:26:01 +0200
|
||||
Subject: [PATCH 12/14] EAP-pwd server: Detect reflection attacks
|
||||
|
||||
When processing an EAP-pwd Commit frame, verify that the peer's scalar
|
||||
and elliptic curve element differ from the one sent by the server. This
|
||||
prevents reflection attacks where the adversary reflects the scalar and
|
||||
element sent by the server. (CVE-2019-9497)
|
||||
|
||||
The vulnerability allows an adversary to complete the EAP-pwd handshake
|
||||
as any user. However, the adversary does not learn the negotiated
|
||||
session key, meaning the subsequent 4-way handshake would fail. As a
|
||||
result, this cannot be abused to bypass authentication unless EAP-pwd is
|
||||
used in non-WLAN cases without any following key exchange that would
|
||||
require the attacker to learn the MSK.
|
||||
|
||||
Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
|
||||
---
|
||||
src/eap_server/eap_server_pwd.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/src/eap_server/eap_server_pwd.c
|
||||
+++ b/src/eap_server/eap_server_pwd.c
|
||||
@@ -753,6 +753,15 @@ eap_pwd_process_commit_resp(struct eap_s
|
||||
}
|
||||
}
|
||||
|
||||
+ /* detect reflection attacks */
|
||||
+ if (crypto_bignum_cmp(data->my_scalar, data->peer_scalar) == 0 ||
|
||||
+ crypto_ec_point_cmp(data->grp->group, data->my_element,
|
||||
+ data->peer_element) == 0) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-PWD (server): detected reflection attack!");
|
||||
+ goto fin;
|
||||
+ }
|
||||
+
|
||||
/* compute the shared key, k */
|
||||
if ((crypto_ec_point_mul(data->grp->group, data->grp->pwe,
|
||||
data->peer_scalar, K) < 0) ||
|
@ -1,53 +0,0 @@
|
||||
From 8ad8585f91823ddcc3728155e288e0f9f872e31a Mon Sep 17 00:00:00 2001
|
||||
From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
|
||||
Date: Sun, 31 Mar 2019 17:43:44 +0200
|
||||
Subject: [PATCH 13/14] EAP-pwd client: Verify received scalar and element
|
||||
|
||||
When processing an EAP-pwd Commit frame, the server's scalar and element
|
||||
(elliptic curve point) were not validated. This allowed an adversary to
|
||||
bypass authentication, and act as a rogue Access Point (AP) if the
|
||||
crypto implementation did not verify the validity of the EC point.
|
||||
|
||||
Fix this vulnerability by assuring the received scalar lies within the
|
||||
valid range, and by checking that the received element is not the point
|
||||
at infinity and lies on the elliptic curve being used. (CVE-2019-9499)
|
||||
|
||||
The vulnerability is only exploitable if OpenSSL version 1.0.2 or lower
|
||||
is used, or if LibreSSL or wolfssl is used. Newer versions of OpenSSL
|
||||
(and also BoringSSL) implicitly validate the elliptic curve point in
|
||||
EC_POINT_set_affine_coordinates_GFp(), preventing the attack.
|
||||
|
||||
Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
|
||||
---
|
||||
src/eap_peer/eap_pwd.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
--- a/src/eap_peer/eap_pwd.c
|
||||
+++ b/src/eap_peer/eap_pwd.c
|
||||
@@ -594,6 +594,26 @@ eap_pwd_perform_commit_exchange(struct e
|
||||
goto fin;
|
||||
}
|
||||
|
||||
+ /* verify received scalar */
|
||||
+ if (crypto_bignum_is_zero(data->server_scalar) ||
|
||||
+ crypto_bignum_is_one(data->server_scalar) ||
|
||||
+ crypto_bignum_cmp(data->server_scalar,
|
||||
+ crypto_ec_get_order(data->grp->group)) >= 0) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-PWD (peer): received scalar is invalid");
|
||||
+ goto fin;
|
||||
+ }
|
||||
+
|
||||
+ /* verify received element */
|
||||
+ if (!crypto_ec_point_is_on_curve(data->grp->group,
|
||||
+ data->server_element) ||
|
||||
+ crypto_ec_point_is_at_infinity(data->grp->group,
|
||||
+ data->server_element)) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-PWD (peer): received element is invalid");
|
||||
+ goto fin;
|
||||
+ }
|
||||
+
|
||||
/* check to ensure server's element is not in a small sub-group */
|
||||
if (!crypto_bignum_is_one(cofactor)) {
|
||||
if (crypto_ec_point_mul(data->grp->group, data->server_element,
|
@ -1,320 +0,0 @@
|
||||
From 16d4f1069118aa19bfce013493e1ac5783f92f1d Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Fri, 5 Apr 2019 02:12:50 +0300
|
||||
Subject: [PATCH 14/14] EAP-pwd: Check element x,y coordinates explicitly
|
||||
|
||||
This adds an explicit check for 0 < x,y < prime based on RFC 5931,
|
||||
2.8.5.2.2 requirement. The earlier checks might have covered this
|
||||
implicitly, but it is safer to avoid any dependency on implicit checks
|
||||
and specific crypto library behavior. (CVE-2019-9498 and CVE-2019-9499)
|
||||
|
||||
Furthermore, this moves the EAP-pwd element and scalar parsing and
|
||||
validation steps into shared helper functions so that there is no need
|
||||
to maintain two separate copies of this common functionality between the
|
||||
server and peer implementations.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/eap_common/eap_pwd_common.c | 106 ++++++++++++++++++++++++++++++++++++++++
|
||||
src/eap_common/eap_pwd_common.h | 3 ++
|
||||
src/eap_peer/eap_pwd.c | 45 ++---------------
|
||||
src/eap_server/eap_server_pwd.c | 45 ++---------------
|
||||
4 files changed, 117 insertions(+), 82 deletions(-)
|
||||
|
||||
--- a/src/eap_common/eap_pwd_common.c
|
||||
+++ b/src/eap_common/eap_pwd_common.c
|
||||
@@ -427,3 +427,109 @@ int compute_keys(EAP_PWD_group *grp, con
|
||||
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
+
|
||||
+static int eap_pwd_element_coord_ok(const struct crypto_bignum *prime,
|
||||
+ const u8 *buf, size_t len)
|
||||
+{
|
||||
+ struct crypto_bignum *val;
|
||||
+ int ok = 1;
|
||||
+
|
||||
+ val = crypto_bignum_init_set(buf, len);
|
||||
+ if (!val || crypto_bignum_is_zero(val) ||
|
||||
+ crypto_bignum_cmp(val, prime) >= 0)
|
||||
+ ok = 0;
|
||||
+ crypto_bignum_deinit(val, 0);
|
||||
+ return ok;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
|
||||
+ const u8 *buf)
|
||||
+{
|
||||
+ struct crypto_ec_point *element;
|
||||
+ const struct crypto_bignum *prime;
|
||||
+ size_t prime_len;
|
||||
+ struct crypto_bignum *cofactor = NULL;
|
||||
+
|
||||
+ prime = crypto_ec_get_prime(group->group);
|
||||
+ prime_len = crypto_ec_prime_len(group->group);
|
||||
+
|
||||
+ /* RFC 5931, 2.8.5.2.2: 0 < x,y < p */
|
||||
+ if (!eap_pwd_element_coord_ok(prime, buf, prime_len) ||
|
||||
+ !eap_pwd_element_coord_ok(prime, buf + prime_len, prime_len)) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: Invalid coordinate in element");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ element = crypto_ec_point_from_bin(group->group, buf);
|
||||
+ if (!element) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: EC point from element failed");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* RFC 5931, 2.8.5.2.2: on curve and not the point at infinity */
|
||||
+ if (!crypto_ec_point_is_on_curve(group->group, element) ||
|
||||
+ crypto_ec_point_is_at_infinity(group->group, element)) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: Invalid element");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ cofactor = crypto_bignum_init();
|
||||
+ if (!cofactor || crypto_ec_cofactor(group->group, cofactor) < 0) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-pwd: Unable to get cofactor for curve");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (!crypto_bignum_is_one(cofactor)) {
|
||||
+ struct crypto_ec_point *point;
|
||||
+ int ok = 1;
|
||||
+
|
||||
+ /* check to ensure peer's element is not in a small sub-group */
|
||||
+ point = crypto_ec_point_init(group->group);
|
||||
+ if (!point ||
|
||||
+ crypto_ec_point_mul(group->group, element,
|
||||
+ cofactor, point) != 0 ||
|
||||
+ crypto_ec_point_is_at_infinity(group->group, point))
|
||||
+ ok = 0;
|
||||
+ crypto_ec_point_deinit(point, 0);
|
||||
+
|
||||
+ if (!ok) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-pwd: Small sub-group check on peer element failed");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ crypto_bignum_deinit(cofactor, 0);
|
||||
+ return element;
|
||||
+fail:
|
||||
+ crypto_ec_point_deinit(element, 0);
|
||||
+ element = NULL;
|
||||
+ goto out;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf)
|
||||
+{
|
||||
+ struct crypto_bignum *scalar;
|
||||
+ const struct crypto_bignum *order;
|
||||
+ size_t order_len;
|
||||
+
|
||||
+ order = crypto_ec_get_order(group->group);
|
||||
+ order_len = crypto_ec_order_len(group->group);
|
||||
+
|
||||
+ /* RFC 5931, 2.8.5.2: 1 < scalar < r */
|
||||
+ scalar = crypto_bignum_init_set(buf, order_len);
|
||||
+ if (!scalar || crypto_bignum_is_zero(scalar) ||
|
||||
+ crypto_bignum_is_one(scalar) ||
|
||||
+ crypto_bignum_cmp(scalar, order) >= 0) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: received scalar is invalid");
|
||||
+ crypto_bignum_deinit(scalar, 0);
|
||||
+ scalar = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return scalar;
|
||||
+}
|
||||
--- a/src/eap_common/eap_pwd_common.h
|
||||
+++ b/src/eap_common/eap_pwd_common.h
|
||||
@@ -67,5 +67,8 @@ int compute_keys(EAP_PWD_group *grp, con
|
||||
struct crypto_hash * eap_pwd_h_init(void);
|
||||
void eap_pwd_h_update(struct crypto_hash *hash, const u8 *data, size_t len);
|
||||
void eap_pwd_h_final(struct crypto_hash *hash, u8 *digest);
|
||||
+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
|
||||
+ const u8 *buf);
|
||||
+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf);
|
||||
|
||||
#endif /* EAP_PWD_COMMON_H */
|
||||
--- a/src/eap_peer/eap_pwd.c
|
||||
+++ b/src/eap_peer/eap_pwd.c
|
||||
@@ -308,7 +308,7 @@ eap_pwd_perform_commit_exchange(struct e
|
||||
const struct wpabuf *reqData,
|
||||
const u8 *payload, size_t payload_len)
|
||||
{
|
||||
- struct crypto_ec_point *K = NULL, *point = NULL;
|
||||
+ struct crypto_ec_point *K = NULL;
|
||||
struct crypto_bignum *mask = NULL, *cofactor = NULL;
|
||||
const u8 *ptr = payload;
|
||||
u8 *scalar = NULL, *element = NULL;
|
||||
@@ -572,63 +572,27 @@ eap_pwd_perform_commit_exchange(struct e
|
||||
/* process the request */
|
||||
data->k = crypto_bignum_init();
|
||||
K = crypto_ec_point_init(data->grp->group);
|
||||
- point = crypto_ec_point_init(data->grp->group);
|
||||
- if (!data->k || !K || !point) {
|
||||
+ if (!data->k || !K) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation "
|
||||
"fail");
|
||||
goto fin;
|
||||
}
|
||||
|
||||
/* element, x then y, followed by scalar */
|
||||
- data->server_element = crypto_ec_point_from_bin(data->grp->group, ptr);
|
||||
+ data->server_element = eap_pwd_get_element(data->grp, ptr);
|
||||
if (!data->server_element) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element "
|
||||
"fail");
|
||||
goto fin;
|
||||
}
|
||||
ptr += prime_len * 2;
|
||||
- data->server_scalar = crypto_bignum_init_set(ptr, order_len);
|
||||
+ data->server_scalar = eap_pwd_get_scalar(data->grp, ptr);
|
||||
if (!data->server_scalar) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"EAP-PWD (peer): setting peer scalar fail");
|
||||
goto fin;
|
||||
}
|
||||
|
||||
- /* verify received scalar */
|
||||
- if (crypto_bignum_is_zero(data->server_scalar) ||
|
||||
- crypto_bignum_is_one(data->server_scalar) ||
|
||||
- crypto_bignum_cmp(data->server_scalar,
|
||||
- crypto_ec_get_order(data->grp->group)) >= 0) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-PWD (peer): received scalar is invalid");
|
||||
- goto fin;
|
||||
- }
|
||||
-
|
||||
- /* verify received element */
|
||||
- if (!crypto_ec_point_is_on_curve(data->grp->group,
|
||||
- data->server_element) ||
|
||||
- crypto_ec_point_is_at_infinity(data->grp->group,
|
||||
- data->server_element)) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-PWD (peer): received element is invalid");
|
||||
- goto fin;
|
||||
- }
|
||||
-
|
||||
- /* check to ensure server's element is not in a small sub-group */
|
||||
- if (!crypto_bignum_is_one(cofactor)) {
|
||||
- if (crypto_ec_point_mul(data->grp->group, data->server_element,
|
||||
- cofactor, point) < 0) {
|
||||
- wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
|
||||
- "server element by order!\n");
|
||||
- goto fin;
|
||||
- }
|
||||
- if (crypto_ec_point_is_at_infinity(data->grp->group, point)) {
|
||||
- wpa_printf(MSG_INFO, "EAP-PWD (peer): server element "
|
||||
- "is at infinity!\n");
|
||||
- goto fin;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* compute the shared key, k */
|
||||
if (crypto_ec_point_mul(data->grp->group, data->grp->pwe,
|
||||
data->server_scalar, K) < 0 ||
|
||||
@@ -702,7 +666,6 @@ fin:
|
||||
crypto_bignum_deinit(mask, 1);
|
||||
crypto_bignum_deinit(cofactor, 1);
|
||||
crypto_ec_point_deinit(K, 1);
|
||||
- crypto_ec_point_deinit(point, 1);
|
||||
if (data->outbuf == NULL)
|
||||
eap_pwd_state(data, FAILURE);
|
||||
else
|
||||
--- a/src/eap_server/eap_server_pwd.c
|
||||
+++ b/src/eap_server/eap_server_pwd.c
|
||||
@@ -669,7 +669,7 @@ eap_pwd_process_commit_resp(struct eap_s
|
||||
{
|
||||
const u8 *ptr;
|
||||
struct crypto_bignum *cofactor = NULL;
|
||||
- struct crypto_ec_point *K = NULL, *point = NULL;
|
||||
+ struct crypto_ec_point *K = NULL;
|
||||
int res = 0;
|
||||
size_t prime_len, order_len;
|
||||
|
||||
@@ -688,9 +688,8 @@ eap_pwd_process_commit_resp(struct eap_s
|
||||
|
||||
data->k = crypto_bignum_init();
|
||||
cofactor = crypto_bignum_init();
|
||||
- point = crypto_ec_point_init(data->grp->group);
|
||||
K = crypto_ec_point_init(data->grp->group);
|
||||
- if (!data->k || !cofactor || !point || !K) {
|
||||
+ if (!data->k || !cofactor || !K) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
|
||||
"fail");
|
||||
goto fin;
|
||||
@@ -704,55 +703,20 @@ eap_pwd_process_commit_resp(struct eap_s
|
||||
|
||||
/* element, x then y, followed by scalar */
|
||||
ptr = payload;
|
||||
- data->peer_element = crypto_ec_point_from_bin(data->grp->group, ptr);
|
||||
+ data->peer_element = eap_pwd_get_element(data->grp, ptr);
|
||||
if (!data->peer_element) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD (server): setting peer element "
|
||||
"fail");
|
||||
goto fin;
|
||||
}
|
||||
ptr += prime_len * 2;
|
||||
- data->peer_scalar = crypto_bignum_init_set(ptr, order_len);
|
||||
+ data->peer_scalar = eap_pwd_get_scalar(data->grp, ptr);
|
||||
if (!data->peer_scalar) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
|
||||
"fail");
|
||||
goto fin;
|
||||
}
|
||||
|
||||
- /* verify received scalar */
|
||||
- if (crypto_bignum_is_zero(data->peer_scalar) ||
|
||||
- crypto_bignum_is_one(data->peer_scalar) ||
|
||||
- crypto_bignum_cmp(data->peer_scalar,
|
||||
- crypto_ec_get_order(data->grp->group)) >= 0) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-PWD (server): received scalar is invalid");
|
||||
- goto fin;
|
||||
- }
|
||||
-
|
||||
- /* verify received element */
|
||||
- if (!crypto_ec_point_is_on_curve(data->grp->group,
|
||||
- data->peer_element) ||
|
||||
- crypto_ec_point_is_at_infinity(data->grp->group,
|
||||
- data->peer_element)) {
|
||||
- wpa_printf(MSG_INFO,
|
||||
- "EAP-PWD (server): received element is invalid");
|
||||
- goto fin;
|
||||
- }
|
||||
-
|
||||
- /* check to ensure peer's element is not in a small sub-group */
|
||||
- if (!crypto_bignum_is_one(cofactor)) {
|
||||
- if (crypto_ec_point_mul(data->grp->group, data->peer_element,
|
||||
- cofactor, point) != 0) {
|
||||
- wpa_printf(MSG_INFO, "EAP-PWD (server): cannot "
|
||||
- "multiply peer element by order");
|
||||
- goto fin;
|
||||
- }
|
||||
- if (crypto_ec_point_is_at_infinity(data->grp->group, point)) {
|
||||
- wpa_printf(MSG_INFO, "EAP-PWD (server): peer element "
|
||||
- "is at infinity!\n");
|
||||
- goto fin;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* detect reflection attacks */
|
||||
if (crypto_bignum_cmp(data->my_scalar, data->peer_scalar) == 0 ||
|
||||
crypto_ec_point_cmp(data->grp->group, data->my_element,
|
||||
@@ -804,7 +768,6 @@ eap_pwd_process_commit_resp(struct eap_s
|
||||
|
||||
fin:
|
||||
crypto_ec_point_deinit(K, 1);
|
||||
- crypto_ec_point_deinit(point, 1);
|
||||
crypto_bignum_deinit(cofactor, 1);
|
||||
|
||||
if (res)
|
@ -1,40 +0,0 @@
|
||||
From fe76f487e28bdc61940f304f153a954cf36935ea Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Wed, 17 Apr 2019 01:55:32 +0300
|
||||
Subject: [PATCH 1/3] EAP-pwd server: Fix reassembly buffer handling
|
||||
|
||||
data->inbuf allocation might fail and if that were to happen, the next
|
||||
fragment in the exchange could have resulted in NULL pointer
|
||||
dereference. Unexpected fragment with more bit might also be able to
|
||||
trigger this. Fix that by explicitly checking for data->inbuf to be
|
||||
available before using it.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/eap_server/eap_server_pwd.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/eap_server/eap_server_pwd.c
|
||||
+++ b/src/eap_server/eap_server_pwd.c
|
||||
@@ -947,6 +947,12 @@ static void eap_pwd_process(struct eap_s
|
||||
* the first and all intermediate fragments have the M bit set
|
||||
*/
|
||||
if (EAP_PWD_GET_MORE_BIT(lm_exch) || data->in_frag_pos) {
|
||||
+ if (!data->inbuf) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "EAP-pwd: No buffer for reassembly");
|
||||
+ eap_pwd_state(data, FAILURE);
|
||||
+ return;
|
||||
+ }
|
||||
if ((data->in_frag_pos + len) > wpabuf_size(data->inbuf)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-pwd: Buffer overflow "
|
||||
"attack detected! (%d+%d > %d)",
|
||||
@@ -967,7 +973,7 @@ static void eap_pwd_process(struct eap_s
|
||||
* last fragment won't have the M bit set (but we're obviously
|
||||
* buffering fragments so that's how we know it's the last)
|
||||
*/
|
||||
- if (data->in_frag_pos) {
|
||||
+ if (data->in_frag_pos && data->inbuf) {
|
||||
pos = wpabuf_head_u8(data->inbuf);
|
||||
len = data->in_frag_pos;
|
||||
wpa_printf(MSG_DEBUG, "EAP-pwd: Last fragment, %d bytes",
|
@ -1,40 +0,0 @@
|
||||
From d2d1a324ce937628e4d9d9999fe113819b7d4478 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Wed, 17 Apr 2019 02:21:20 +0300
|
||||
Subject: [PATCH 3/3] EAP-pwd peer: Fix reassembly buffer handling
|
||||
|
||||
Unexpected fragment might result in data->inbuf not being allocated
|
||||
before processing and that could have resulted in NULL pointer
|
||||
dereference. Fix that by explicitly checking for data->inbuf to be
|
||||
available before using it.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/eap_peer/eap_pwd.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/eap_peer/eap_pwd.c
|
||||
+++ b/src/eap_peer/eap_pwd.c
|
||||
@@ -969,6 +969,13 @@ eap_pwd_process(struct eap_sm *sm, void
|
||||
* buffer and ACK the fragment
|
||||
*/
|
||||
if (EAP_PWD_GET_MORE_BIT(lm_exch) || data->in_frag_pos) {
|
||||
+ if (!data->inbuf) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "EAP-pwd: No buffer for reassembly");
|
||||
+ ret->methodState = METHOD_DONE;
|
||||
+ ret->decision = DECISION_FAIL;
|
||||
+ return NULL;
|
||||
+ }
|
||||
data->in_frag_pos += len;
|
||||
if (data->in_frag_pos > wpabuf_size(data->inbuf)) {
|
||||
wpa_printf(MSG_INFO, "EAP-pwd: Buffer overflow attack "
|
||||
@@ -995,7 +1002,7 @@ eap_pwd_process(struct eap_sm *sm, void
|
||||
/*
|
||||
* we're buffering and this is the last fragment
|
||||
*/
|
||||
- if (data->in_frag_pos) {
|
||||
+ if (data->in_frag_pos && data->inbuf) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-pwd: Last fragment, %d bytes",
|
||||
(int) len);
|
||||
pos = wpabuf_head_u8(data->inbuf);
|
@ -1,40 +0,0 @@
|
||||
From 92e1b96c26a84e503847bdd22ebadf697c4031ad Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Sat, 13 Apr 2019 17:20:57 +0300
|
||||
Subject: EAP-pwd: Disallow ECC groups with a prime under 256 bits
|
||||
|
||||
Based on the SAE implementation guidance update to not allow ECC groups
|
||||
with a prime that is under 256 bits, reject groups 25, 26, and 27 in
|
||||
EAP-pwd.
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/eap_common/eap_pwd_common.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
--- a/src/eap_common/eap_pwd_common.c
|
||||
+++ b/src/eap_common/eap_pwd_common.c
|
||||
@@ -85,10 +85,23 @@ static int eap_pwd_kdf(const u8 *key, si
|
||||
}
|
||||
|
||||
|
||||
+static int eap_pwd_suitable_group(u16 num)
|
||||
+{
|
||||
+ /* Do not allow ECC groups with prime under 256 bits based on guidance
|
||||
+ * for the similar design in SAE. */
|
||||
+ return num == 19 || num == 20 || num == 21 ||
|
||||
+ num == 28 || num == 29 || num == 30;
|
||||
+}
|
||||
+
|
||||
+
|
||||
EAP_PWD_group * get_eap_pwd_group(u16 num)
|
||||
{
|
||||
EAP_PWD_group *grp;
|
||||
|
||||
+ if (!eap_pwd_suitable_group(num)) {
|
||||
+ wpa_printf(MSG_INFO, "EAP-pwd: unsuitable group %u", num);
|
||||
+ return NULL;
|
||||
+ }
|
||||
grp = os_zalloc(sizeof(EAP_PWD_group));
|
||||
if (!grp)
|
||||
return NULL;
|
@ -1,54 +0,0 @@
|
||||
From db54db11aec763b6fc74715c36e0f9de0d65e206 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Mon, 8 Apr 2019 18:01:07 +0300
|
||||
Subject: SAE: Reject unsuitable groups based on REVmd changes
|
||||
|
||||
The rules defining which DH groups are suitable for SAE use were
|
||||
accepted into IEEE 802.11 REVmd based on this document:
|
||||
https://mentor.ieee.org/802.11/dcn/19/11-19-0387-02-000m-addressing-some-sae-comments.docx
|
||||
|
||||
Enforce those rules in production builds of wpa_supplicant and hostapd.
|
||||
CONFIG_TESTING_OPTIONS=y builds can still be used to select any o the
|
||||
implemented groups to maintain testing coverage.
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/common/sae.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
--- a/src/common/sae.c
|
||||
+++ b/src/common/sae.c
|
||||
@@ -18,10 +18,33 @@
|
||||
#include "sae.h"
|
||||
|
||||
|
||||
+static int sae_suitable_group(int group)
|
||||
+{
|
||||
+#ifdef CONFIG_TESTING_OPTIONS
|
||||
+ /* Allow all groups for testing purposes in non-production builds. */
|
||||
+ return 1;
|
||||
+#else /* CONFIG_TESTING_OPTIONS */
|
||||
+ /* Enforce REVmd rules on which SAE groups are suitable for production
|
||||
+ * purposes: FFC groups whose prime is >= 3072 bits and ECC groups
|
||||
+ * defined over a prime field whose prime is >= 256 bits. Furthermore,
|
||||
+ * ECC groups defined over a characteristic 2 finite field and ECC
|
||||
+ * groups with a co-factor greater than 1 are not suitable. */
|
||||
+ return group == 19 || group == 20 || group == 21 ||
|
||||
+ group == 28 || group == 29 || group == 30 ||
|
||||
+ group == 15 || group == 16 || group == 17 || group == 18;
|
||||
+#endif /* CONFIG_TESTING_OPTIONS */
|
||||
+}
|
||||
+
|
||||
+
|
||||
int sae_set_group(struct sae_data *sae, int group)
|
||||
{
|
||||
struct sae_temporary_data *tmp;
|
||||
|
||||
+ if (!sae_suitable_group(group)) {
|
||||
+ wpa_printf(MSG_DEBUG, "SAE: Reject unsuitable group %d", group);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
sae_clear_data(sae);
|
||||
tmp = sae->tmp = os_zalloc(sizeof(*tmp));
|
||||
if (tmp == NULL)
|
@ -32,19 +32,19 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
+ if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
|
||||
+ primebytelen) < 0)
|
||||
+ return -1;
|
||||
cofactor = crypto_bignum_init();
|
||||
grp->pwe = crypto_ec_point_init(grp->group);
|
||||
tmp1 = crypto_bignum_init();
|
||||
@@ -176,8 +182,6 @@ int compute_password_element(EAP_PWD_gro
|
||||
"curve");
|
||||
pm1 = crypto_bignum_init();
|
||||
@@ -170,8 +176,6 @@ int compute_password_element(EAP_PWD_gro
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- primebitlen = crypto_ec_prime_len_bits(grp->group);
|
||||
- primebytelen = crypto_ec_prime_len(grp->group);
|
||||
if ((prfbuf = os_malloc(primebytelen)) == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-pwd: unable to malloc space for prf "
|
||||
"buffer");
|
||||
@@ -243,6 +247,8 @@ int compute_password_element(EAP_PWD_gro
|
||||
@@ -237,6 +241,8 @@ int compute_password_element(EAP_PWD_gro
|
||||
if (primebitlen % 8)
|
||||
buf_shift_right(prfbuf, primebytelen,
|
||||
8 - primebitlen % 8);
|
||||
@ -53,7 +53,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
|
||||
crypto_bignum_deinit(x_candidate, 1);
|
||||
x_candidate = crypto_bignum_init_set(prfbuf, primebytelen);
|
||||
@@ -252,9 +258,6 @@ int compute_password_element(EAP_PWD_gro
|
||||
@@ -246,9 +252,6 @@ int compute_password_element(EAP_PWD_gro
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
|
||||
--- a/src/crypto/crypto_openssl.c
|
||||
+++ b/src/crypto/crypto_openssl.c
|
||||
@@ -1227,7 +1227,13 @@ void crypto_bignum_deinit(struct crypto_
|
||||
@@ -1295,7 +1295,13 @@ void crypto_bignum_deinit(struct crypto_
|
||||
int crypto_bignum_to_bin(const struct crypto_bignum *a,
|
||||
u8 *buf, size_t buflen, size_t padlen)
|
||||
{
|
||||
@ -35,7 +35,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
|
||||
if (TEST_FAIL())
|
||||
return -1;
|
||||
@@ -1235,6 +1241,14 @@ int crypto_bignum_to_bin(const struct cr
|
||||
@@ -1303,6 +1309,14 @@ int crypto_bignum_to_bin(const struct cr
|
||||
if (padlen > buflen)
|
||||
return -1;
|
||||
|
||||
@ -50,7 +50,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
num_bytes = BN_num_bytes((const BIGNUM *) a);
|
||||
if ((size_t) num_bytes > buflen)
|
||||
return -1;
|
||||
@@ -1247,6 +1261,8 @@ int crypto_bignum_to_bin(const struct cr
|
||||
@@ -1315,6 +1329,8 @@ int crypto_bignum_to_bin(const struct cr
|
||||
BN_bn2bin((const BIGNUM *) a, buf + offset);
|
||||
|
||||
return num_bytes + offset;
|
||||
|
@ -17,7 +17,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
--- a/src/eap_common/eap_pwd_common.c
|
||||
+++ b/src/eap_common/eap_pwd_common.c
|
||||
@@ -155,6 +155,8 @@ int compute_password_element(EAP_PWD_gro
|
||||
struct crypto_bignum *x_candidate = NULL, *cofactor = NULL;
|
||||
struct crypto_bignum *x_candidate = NULL;
|
||||
const struct crypto_bignum *prime;
|
||||
u8 mask, found_ctr = 0, is_odd = 0;
|
||||
+ int cmp_prime;
|
||||
@ -25,7 +25,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
|
||||
if (grp->pwe)
|
||||
return -1;
|
||||
@@ -247,8 +249,13 @@ int compute_password_element(EAP_PWD_gro
|
||||
@@ -241,8 +243,13 @@ int compute_password_element(EAP_PWD_gro
|
||||
if (primebitlen % 8)
|
||||
buf_shift_right(prfbuf, primebytelen,
|
||||
8 - primebitlen % 8);
|
||||
@ -41,7 +41,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
|
||||
crypto_bignum_deinit(x_candidate, 1);
|
||||
x_candidate = crypto_bignum_init_set(prfbuf, primebytelen);
|
||||
@@ -311,7 +318,7 @@ int compute_password_element(EAP_PWD_gro
|
||||
@@ -306,7 +313,7 @@ int compute_password_element(EAP_PWD_gro
|
||||
goto fail;
|
||||
mask = const_time_eq(res, check);
|
||||
found_ctr = const_time_select_u8(found, found_ctr, ctr);
|
||||
|
@ -23,7 +23,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
|
||||
--- a/src/ap/drv_callbacks.c
|
||||
+++ b/src/ap/drv_callbacks.c
|
||||
@@ -129,6 +129,19 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
@@ -131,6 +131,19 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
"hostapd_notif_assoc: Skip event with no address");
|
||||
return -1;
|
||||
}
|
||||
@ -45,7 +45,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -3978,6 +3978,18 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||
@@ -4463,6 +4463,18 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||
fc = le_to_host16(mgmt->frame_control);
|
||||
stype = WLAN_FC_GET_STYPE(fc);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -295,9 +295,10 @@ void wpa_supplicant_cancel_auth_timeout(
|
||||
@@ -296,9 +296,10 @@ void wpa_supplicant_cancel_auth_timeout(
|
||||
*/
|
||||
void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
OBJS += ../src/ap/vlan_init.o
|
||||
OBJS += ../src/ap/vlan_ifconfig.o
|
||||
OBJS += ../src/ap/vlan.o
|
||||
@@ -354,10 +356,14 @@ CFLAGS += -DCONFIG_MBO
|
||||
@@ -360,10 +362,14 @@ CFLAGS += -DCONFIG_MBO
|
||||
OBJS += ../src/ap/mbo_ap.o
|
||||
endif
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
LIBS += $(DRV_AP_LIBS)
|
||||
|
||||
ifdef CONFIG_L2_PACKET
|
||||
@@ -1274,6 +1280,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
|
||||
@@ -1286,6 +1292,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
|
||||
|
||||
BCHECK=../src/drivers/build.hostapd
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
hostapd: $(BCHECK) $(OBJS)
|
||||
$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
|
||||
@$(E) " LD " $@
|
||||
@@ -1316,6 +1328,12 @@ ifeq ($(CONFIG_TLS), linux)
|
||||
@@ -1328,6 +1340,12 @@ ifeq ($(CONFIG_TLS), linux)
|
||||
HOBJS += ../src/crypto/crypto_linux.o
|
||||
endif
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
|
||||
ifndef CONFIG_NO_GITVER
|
||||
# Add VERSION_STR postfix for builds from a git repository
|
||||
@@ -354,7 +355,9 @@ endif
|
||||
@@ -362,7 +363,9 @@ endif
|
||||
ifdef CONFIG_IBSS_RSN
|
||||
NEED_RSN_AUTHENTICATOR=y
|
||||
CFLAGS += -DCONFIG_IBSS_RSN
|
||||
@ -82,7 +82,7 @@
|
||||
OBJS += ibss_rsn.o
|
||||
endif
|
||||
|
||||
@@ -862,6 +865,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
@@ -870,6 +873,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
|
||||
LIBS += -ldl -rdynamic
|
||||
endif
|
||||
@ -93,7 +93,7 @@
|
||||
endif
|
||||
|
||||
ifdef CONFIG_AP
|
||||
@@ -869,9 +876,11 @@ NEED_EAP_COMMON=y
|
||||
@@ -877,9 +884,11 @@ NEED_EAP_COMMON=y
|
||||
NEED_RSN_AUTHENTICATOR=y
|
||||
CFLAGS += -DCONFIG_AP
|
||||
OBJS += ap.o
|
||||
@ -105,7 +105,7 @@
|
||||
OBJS += ../src/ap/hostapd.o
|
||||
OBJS += ../src/ap/wpa_auth_glue.o
|
||||
OBJS += ../src/ap/utils.o
|
||||
@@ -953,6 +962,12 @@ endif
|
||||
@@ -961,6 +970,12 @@ endif
|
||||
ifdef CONFIG_HS20
|
||||
OBJS += ../src/ap/hs20.o
|
||||
endif
|
||||
@ -118,7 +118,7 @@
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MBO
|
||||
@@ -961,7 +976,9 @@ CFLAGS += -DCONFIG_MBO
|
||||
@@ -969,7 +984,9 @@ CFLAGS += -DCONFIG_MBO
|
||||
endif
|
||||
|
||||
ifdef NEED_RSN_AUTHENTICATOR
|
||||
@ -128,7 +128,7 @@
|
||||
NEED_AES_WRAP=y
|
||||
OBJS += ../src/ap/wpa_auth.o
|
||||
OBJS += ../src/ap/wpa_auth_ie.o
|
||||
@@ -1888,6 +1905,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
|
||||
@@ -1872,6 +1889,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
|
||||
|
||||
$(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config
|
||||
|
||||
@ -141,8 +141,8 @@
|
||||
wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
|
||||
$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
|
||||
@$(E) " LD " $@
|
||||
@@ -1990,6 +2013,12 @@ endif
|
||||
-e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
|
||||
@@ -1972,6 +1995,12 @@ endif
|
||||
$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
|
||||
@$(E) " sed" $<
|
||||
|
||||
+dump_cflags:
|
||||
@ -156,7 +156,7 @@
|
||||
wpa_cli.exe: wpa_cli
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -5476,8 +5476,8 @@ union wpa_event_data {
|
||||
@@ -5551,8 +5551,8 @@ union wpa_event_data {
|
||||
* Driver wrapper code should call this function whenever an event is received
|
||||
* from the driver.
|
||||
*/
|
||||
@ -167,7 +167,7 @@
|
||||
|
||||
/**
|
||||
* wpa_supplicant_event_global - Report a driver event for wpa_supplicant
|
||||
@@ -5489,7 +5489,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -5564,7 +5564,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
* Same as wpa_supplicant_event(), but we search for the interface in
|
||||
* wpa_global.
|
||||
*/
|
||||
@ -178,7 +178,7 @@
|
||||
/*
|
||||
--- a/src/ap/drv_callbacks.c
|
||||
+++ b/src/ap/drv_callbacks.c
|
||||
@@ -1540,8 +1540,8 @@ static void hostapd_event_wds_sta_interf
|
||||
@@ -1581,8 +1581,8 @@ static void hostapd_event_wds_sta_interf
|
||||
}
|
||||
|
||||
|
||||
@ -189,7 +189,7 @@
|
||||
{
|
||||
struct hostapd_data *hapd = ctx;
|
||||
#ifndef CONFIG_NO_STDOUT_DEBUG
|
||||
@@ -1770,7 +1770,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -1816,7 +1816,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
}
|
||||
|
||||
|
||||
@ -231,7 +231,7 @@
|
||||
os_memset(&global, 0, sizeof(global));
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -4026,8 +4026,8 @@ static void wpas_event_assoc_reject(stru
|
||||
@@ -4176,8 +4176,8 @@ static void wpas_event_assoc_reject(stru
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +242,7 @@
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = ctx;
|
||||
int resched;
|
||||
@@ -4796,7 +4796,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -4951,7 +4951,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
}
|
||||
|
||||
|
||||
@ -253,7 +253,7 @@
|
||||
struct wpa_supplicant *wpa_s;
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -5861,7 +5861,6 @@ struct wpa_interface * wpa_supplicant_ma
|
||||
@@ -6087,7 +6087,6 @@ struct wpa_interface * wpa_supplicant_ma
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@
|
||||
/**
|
||||
* wpa_supplicant_match_existing - Match existing interfaces
|
||||
* @global: Pointer to global data from wpa_supplicant_init()
|
||||
@@ -5898,6 +5897,11 @@ static int wpa_supplicant_match_existing
|
||||
@@ -6124,6 +6123,11 @@ static int wpa_supplicant_match_existing
|
||||
|
||||
#endif /* CONFIG_MATCH_IFACE */
|
||||
|
||||
@ -273,7 +273,7 @@
|
||||
|
||||
/**
|
||||
* wpa_supplicant_add_iface - Add a new network interface
|
||||
@@ -6154,6 +6158,8 @@ struct wpa_global * wpa_supplicant_init(
|
||||
@@ -6380,6 +6384,8 @@ struct wpa_global * wpa_supplicant_init(
|
||||
#ifndef CONFIG_NO_WPA_MSG
|
||||
wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
|
||||
#endif /* CONFIG_NO_WPA_MSG */
|
||||
@ -284,7 +284,7 @@
|
||||
wpa_debug_open_file(params->wpa_debug_file_path);
|
||||
--- a/hostapd/main.c
|
||||
+++ b/hostapd/main.c
|
||||
@@ -591,6 +591,11 @@ fail:
|
||||
@@ -592,6 +592,11 @@ fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -296,8 +296,8 @@
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
static int gen_uuid(const char *txt_addr)
|
||||
@@ -674,6 +679,8 @@ int main(int argc, char *argv[])
|
||||
hostapd_dpp_init_global(&interfaces);
|
||||
@@ -677,6 +682,8 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
#endif /* CONFIG_DPP */
|
||||
|
||||
+ wpa_supplicant_event = hostapd_wpa_event;
|
||||
@ -333,7 +333,7 @@
|
||||
|
||||
const struct wpa_driver_ops *const wpa_drivers[] = { NULL };
|
||||
|
||||
@@ -1295,6 +1300,10 @@ static void usage(void)
|
||||
@@ -1296,6 +1301,10 @@ static void usage(void)
|
||||
"option several times.\n");
|
||||
}
|
||||
|
||||
@ -344,7 +344,7 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -1315,6 +1324,8 @@ int main(int argc, char *argv[])
|
||||
@@ -1316,6 +1325,8 @@ int main(int argc, char *argv[])
|
||||
if (os_program_init())
|
||||
return -1;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3317,6 +3317,10 @@ static int hostapd_config_fill(struct ho
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
@@ -3390,6 +3390,10 @@ static int hostapd_config_fill(struct ho
|
||||
bss->ieee80211w = 1;
|
||||
#endif /* CONFIG_OCV */
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
+ } else if (os_strcmp(buf, "noscan") == 0) {
|
||||
+ conf->noscan = atoi(pos);
|
||||
@ -13,7 +13,7 @@
|
||||
} else if (os_strcmp(buf, "ht_capab") == 0) {
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -781,6 +781,8 @@ struct hostapd_config {
|
||||
@@ -803,6 +803,8 @@ struct hostapd_config {
|
||||
|
||||
int ht_op_mode_fixed;
|
||||
u16 ht_capab;
|
||||
@ -24,7 +24,7 @@
|
||||
int no_pri_sec_switch;
|
||||
--- a/src/ap/hw_features.c
|
||||
+++ b/src/ap/hw_features.c
|
||||
@@ -480,7 +480,8 @@ static int ieee80211n_check_40mhz(struct
|
||||
@@ -477,7 +477,8 @@ static int ieee80211n_check_40mhz(struct
|
||||
int ret;
|
||||
|
||||
/* Check that HT40 is used and PRI / SEC switch is allowed */
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/wpa_supplicant/config.c
|
||||
+++ b/wpa_supplicant/config.c
|
||||
@@ -2233,6 +2233,7 @@ static const struct parse_data ssid_fiel
|
||||
@@ -2312,6 +2312,7 @@ static const struct parse_data ssid_fiel
|
||||
#else /* CONFIG_MESH */
|
||||
{ INT_RANGE(mode, 0, 4) },
|
||||
#endif /* CONFIG_MESH */
|
||||
@ -10,7 +10,7 @@
|
||||
{ STR(id_str) },
|
||||
--- a/wpa_supplicant/config_file.c
|
||||
+++ b/wpa_supplicant/config_file.c
|
||||
@@ -818,6 +818,7 @@ static void wpa_config_write_network(FIL
|
||||
@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
INT(mode);
|
||||
INT(no_auto_peer);
|
||||
@ -20,7 +20,7 @@
|
||||
INT(fixed_freq);
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -288,6 +288,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -358,6 +358,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
frequency);
|
||||
goto out_free;
|
||||
}
|
||||
@ -31,7 +31,7 @@
|
||||
if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) {
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2081,12 +2081,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2139,12 +2139,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
{
|
||||
enum hostapd_hw_mode hw_mode;
|
||||
struct hostapd_hw_modes *mode = NULL;
|
||||
@ -46,7 +46,7 @@
|
||||
unsigned int j, k;
|
||||
struct hostapd_freq_params vht_freq;
|
||||
int chwidth, seg0, seg1;
|
||||
@@ -2156,7 +2156,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2214,7 +2214,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
return;
|
||||
|
||||
/* Setup higher BW only for 5 GHz */
|
||||
@ -57,7 +57,7 @@
|
||||
for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
|
||||
--- a/wpa_supplicant/config_ssid.h
|
||||
+++ b/wpa_supplicant/config_ssid.h
|
||||
@@ -856,6 +856,8 @@ struct wpa_ssid {
|
||||
@@ -916,6 +916,8 @@ struct wpa_ssid {
|
||||
*/
|
||||
int no_auto_peer;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -4312,7 +4312,7 @@ wpa_supplicant_alloc(struct wpa_supplica
|
||||
@@ -4465,7 +4465,7 @@ wpa_supplicant_alloc(struct wpa_supplica
|
||||
if (wpa_s == NULL)
|
||||
return NULL;
|
||||
wpa_s->scan_req = INITIAL_SCAN_REQ;
|
||||
|
@ -1,14 +1,14 @@
|
||||
--- a/src/drivers/drivers.mak
|
||||
+++ b/src/drivers/drivers.mak
|
||||
@@ -49,7 +49,6 @@ NEED_SME=y
|
||||
@@ -50,7 +50,6 @@ NEED_SME=y
|
||||
NEED_AP_MLME=y
|
||||
NEED_NETLINK=y
|
||||
NEED_LINUX_IOCTL=y
|
||||
-NEED_RFKILL=y
|
||||
NEED_RADIOTAP=y
|
||||
|
||||
ifdef CONFIG_LIBNL32
|
||||
@@ -136,7 +135,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
|
||||
NEED_LIBNL=y
|
||||
endif
|
||||
@@ -107,7 +106,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
|
||||
CONFIG_WIRELESS_EXTENSION=y
|
||||
NEED_NETLINK=y
|
||||
NEED_LINUX_IOCTL=y
|
||||
@ -16,7 +16,7 @@
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_NDIS
|
||||
@@ -162,7 +160,6 @@ endif
|
||||
@@ -133,7 +131,6 @@ endif
|
||||
ifdef CONFIG_WIRELESS_EXTENSION
|
||||
DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION
|
||||
DRV_WPA_OBJS += ../src/drivers/driver_wext.o
|
||||
@ -24,7 +24,7 @@
|
||||
endif
|
||||
|
||||
ifdef NEED_NETLINK
|
||||
@@ -175,6 +172,7 @@ endif
|
||||
@@ -146,6 +143,7 @@ endif
|
||||
|
||||
ifdef NEED_RFKILL
|
||||
DRV_OBJS += ../src/drivers/rfkill.o
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -4318,7 +4318,7 @@ static int nl80211_set_channel(struct i8
|
||||
@@ -4434,7 +4434,7 @@ static int nl80211_set_channel(struct i8
|
||||
freq->freq, freq->ht_enabled, freq->vht_enabled,
|
||||
freq->bandwidth, freq->center_freq1, freq->center_freq2);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/wpa_supplicant/ap.c
|
||||
+++ b/wpa_supplicant/ap.c
|
||||
@@ -1363,15 +1363,35 @@ int ap_switch_channel(struct wpa_supplic
|
||||
@@ -1373,15 +1373,35 @@ int ap_switch_channel(struct wpa_supplic
|
||||
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -2634,10 +2634,15 @@ static int wpa_driver_nl80211_del_beacon
|
||||
@@ -2722,10 +2722,15 @@ static int wpa_driver_nl80211_del_beacon
|
||||
struct nl_msg *msg;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
return send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -4919,7 +4924,7 @@ static void nl80211_teardown_ap(struct i
|
||||
@@ -5036,7 +5041,7 @@ static void nl80211_teardown_ap(struct i
|
||||
nl80211_mgmt_unsubscribe(bss, "AP teardown");
|
||||
|
||||
nl80211_put_wiphy_data_ap(bss);
|
||||
@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -7160,8 +7165,6 @@ static int wpa_driver_nl80211_if_remove(
|
||||
@@ -7302,8 +7307,6 @@ static int wpa_driver_nl80211_if_remove(
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
|
||||
nl80211_teardown_ap(bss);
|
||||
@ -36,7 +36,7 @@
|
||||
nl80211_destroy_bss(bss);
|
||||
if (!bss->added_if)
|
||||
i802_set_iface_flags(bss, 0);
|
||||
@@ -7540,7 +7543,6 @@ static int wpa_driver_nl80211_deinit_ap(
|
||||
@@ -7693,7 +7696,6 @@ static int wpa_driver_nl80211_deinit_ap(
|
||||
if (!is_ap_interface(drv->nlmode))
|
||||
return -1;
|
||||
wpa_driver_nl80211_del_beacon(bss);
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
/*
|
||||
* If the P2P GO interface was dynamically added, then it is
|
||||
@@ -7560,7 +7562,6 @@ static int wpa_driver_nl80211_stop_ap(vo
|
||||
@@ -7713,7 +7715,6 @@ static int wpa_driver_nl80211_stop_ap(vo
|
||||
if (!is_ap_interface(drv->nlmode))
|
||||
return -1;
|
||||
wpa_driver_nl80211_del_beacon(bss);
|
||||
|
@ -78,7 +78,7 @@
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
#ifdef NEED_AP_MLME
|
||||
@@ -3084,6 +3141,8 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
@@ -3172,6 +3229,8 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
} else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
|
||||
reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
|
||||
reply_size);
|
||||
@ -89,7 +89,7 @@
|
||||
#ifdef RADIUS_SERVER
|
||||
--- a/src/ap/ctrl_iface_ap.c
|
||||
+++ b/src/ap/ctrl_iface_ap.c
|
||||
@@ -864,7 +864,13 @@ int hostapd_parse_csa_settings(const cha
|
||||
@@ -872,7 +872,13 @@ int hostapd_parse_csa_settings(const cha
|
||||
|
||||
int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd)
|
||||
{
|
||||
|
@ -11,7 +11,7 @@
|
||||
-include .config
|
||||
-include $(if $(MULTICALL),../hostapd/.config)
|
||||
|
||||
@@ -117,6 +121,8 @@ OBJS_c += ../src/utils/common.o
|
||||
@@ -116,6 +120,8 @@ OBJS_c += ../src/utils/common.o
|
||||
OBJS_c += ../src/common/cli.o
|
||||
OBJS += wmm_ac.o
|
||||
|
||||
@ -110,7 +110,7 @@
|
||||
break;
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -125,6 +125,55 @@ static void wpas_update_fils_connect_par
|
||||
@@ -126,6 +126,55 @@ static void wpas_update_fils_connect_par
|
||||
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
|
||||
|
||||
|
||||
@ -166,7 +166,7 @@
|
||||
/* Configure default/group WEP keys for static WEP */
|
||||
int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
|
||||
{
|
||||
@@ -920,12 +969,16 @@ void wpa_supplicant_set_state(struct wpa
|
||||
@@ -940,12 +989,16 @@ void wpa_supplicant_set_state(struct wpa
|
||||
|
||||
sme_sched_obss_scan(wpa_s, 1);
|
||||
|
||||
@ -183,7 +183,7 @@
|
||||
wpa_s->new_connection = 1;
|
||||
wpa_drv_set_operstate(wpa_s, 0);
|
||||
#ifndef IEEE8021X_EAPOL
|
||||
@@ -1977,6 +2030,8 @@ void wpa_supplicant_associate(struct wpa
|
||||
@@ -2035,6 +2088,8 @@ void wpa_supplicant_associate(struct wpa
|
||||
wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
|
||||
ssid->id);
|
||||
wpas_notify_mesh_group_started(wpa_s, ssid);
|
||||
@ -192,7 +192,7 @@
|
||||
#else /* CONFIG_MESH */
|
||||
wpa_msg(wpa_s, MSG_ERROR,
|
||||
"mesh mode support not included in the build");
|
||||
@@ -5487,6 +5542,16 @@ static int wpa_supplicant_init_iface(str
|
||||
@@ -5707,6 +5762,16 @@ static int wpa_supplicant_init_iface(str
|
||||
sizeof(wpa_s->bridge_ifname));
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@
|
||||
/* RSNA Supplicant Key Management - INITIALIZE */
|
||||
eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
|
||||
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
|
||||
@@ -5808,6 +5873,11 @@ static void wpa_supplicant_deinit_iface(
|
||||
@@ -6034,6 +6099,11 @@ static void wpa_supplicant_deinit_iface(
|
||||
if (terminate)
|
||||
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
|
||||
|
||||
@ -235,7 +235,7 @@
|
||||
* bridge_ifname - Optional bridge interface name
|
||||
*
|
||||
* If the driver interface (ifname) is included in a Linux bridge
|
||||
@@ -513,6 +518,8 @@ struct wpa_supplicant {
|
||||
@@ -516,6 +521,8 @@ struct wpa_supplicant {
|
||||
#endif /* CONFIG_CTRL_IFACE_BINDER */
|
||||
char bridge_ifname[16];
|
||||
|
||||
@ -246,7 +246,7 @@
|
||||
|
||||
--- a/hostapd/ctrl_iface.c
|
||||
+++ b/hostapd/ctrl_iface.c
|
||||
@@ -2328,6 +2328,11 @@ static int hostapd_ctrl_iface_chan_switc
|
||||
@@ -2385,6 +2385,11 @@ static int hostapd_ctrl_iface_chan_switc
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -260,7 +260,7 @@
|
||||
/* Save CHAN_SWITCH VHT config */
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -1381,11 +1381,6 @@ int ieee802_11_set_beacon(struct hostapd
|
||||
@@ -1397,11 +1397,6 @@ int ieee802_11_set_beacon(struct hostapd
|
||||
struct wpabuf *beacon, *proberesp, *assocresp;
|
||||
int res, ret = -1;
|
||||
|
||||
@ -274,7 +274,7 @@
|
||||
if (ieee802_11_build_ap_params(hapd, ¶ms) < 0)
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -4469,6 +4469,13 @@ enum wpa_event_type {
|
||||
@@ -4544,6 +4544,13 @@ enum wpa_event_type {
|
||||
EVENT_CH_SWITCH,
|
||||
|
||||
/**
|
||||
@ -288,7 +288,7 @@
|
||||
* EVENT_WNM - Request WNM operation
|
||||
*
|
||||
* This event can be used to request a WNM operation to be performed.
|
||||
@@ -5306,6 +5313,7 @@ union wpa_event_data {
|
||||
@@ -5381,6 +5388,7 @@ union wpa_event_data {
|
||||
|
||||
/**
|
||||
* struct ch_switch
|
||||
@ -296,7 +296,7 @@
|
||||
* @freq: Frequency of new channel in MHz
|
||||
* @ht_enabled: Whether this is an HT channel
|
||||
* @ch_offset: Secondary channel offset
|
||||
@@ -5314,6 +5322,7 @@ union wpa_event_data {
|
||||
@@ -5389,6 +5397,7 @@ union wpa_event_data {
|
||||
* @cf2: Center frequency 2
|
||||
*/
|
||||
struct ch_switch {
|
||||
@ -306,7 +306,7 @@
|
||||
int ch_offset;
|
||||
--- a/src/drivers/driver_nl80211_event.c
|
||||
+++ b/src/drivers/driver_nl80211_event.c
|
||||
@@ -526,7 +526,8 @@ static int calculate_chan_offset(int wid
|
||||
@@ -534,7 +534,8 @@ static int calculate_chan_offset(int wid
|
||||
static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
|
||||
struct nlattr *ifindex, struct nlattr *freq,
|
||||
struct nlattr *type, struct nlattr *bw,
|
||||
@ -316,7 +316,7 @@
|
||||
{
|
||||
struct i802_bss *bss;
|
||||
union wpa_event_data data;
|
||||
@@ -584,11 +585,15 @@ static void mlme_event_ch_switch(struct
|
||||
@@ -592,11 +593,15 @@ static void mlme_event_ch_switch(struct
|
||||
data.ch_switch.cf1 = nla_get_u32(cf1);
|
||||
if (cf2)
|
||||
data.ch_switch.cf2 = nla_get_u32(cf2);
|
||||
@ -333,7 +333,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -2446,6 +2451,7 @@ static void do_process_drv_event(struct
|
||||
@@ -2508,6 +2513,7 @@ static void do_process_drv_event(struct
|
||||
tb[NL80211_ATTR_PMK],
|
||||
tb[NL80211_ATTR_PMKID]);
|
||||
break;
|
||||
@ -341,7 +341,7 @@
|
||||
case NL80211_CMD_CH_SWITCH_NOTIFY:
|
||||
mlme_event_ch_switch(drv,
|
||||
tb[NL80211_ATTR_IFINDEX],
|
||||
@@ -2453,7 +2459,8 @@ static void do_process_drv_event(struct
|
||||
@@ -2515,7 +2521,8 @@ static void do_process_drv_event(struct
|
||||
tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
|
||||
tb[NL80211_ATTR_CHANNEL_WIDTH],
|
||||
tb[NL80211_ATTR_CENTER_FREQ1],
|
||||
@ -353,7 +353,7 @@
|
||||
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -4026,6 +4026,60 @@ static void wpas_event_assoc_reject(stru
|
||||
@@ -4176,6 +4176,60 @@ static void wpas_event_assoc_reject(stru
|
||||
}
|
||||
|
||||
|
||||
@ -414,7 +414,7 @@
|
||||
void supplicant_event(void *ctx, enum wpa_event_type event,
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
@@ -4309,6 +4363,10 @@ void supplicant_event(void *ctx, enum wp
|
||||
@@ -4461,6 +4515,10 @@ void supplicant_event(void *ctx, enum wp
|
||||
data->rx_from_unknown.wds);
|
||||
break;
|
||||
#endif /* CONFIG_AP */
|
||||
|
@ -12,7 +12,7 @@
|
||||
else
|
||||
--- a/hostapd/ctrl_iface.c
|
||||
+++ b/hostapd/ctrl_iface.c
|
||||
@@ -2912,6 +2912,7 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
@@ -2997,6 +2997,7 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
reply_size);
|
||||
} else if (os_strcmp(buf, "STATUS-DRIVER") == 0) {
|
||||
reply_len = hostapd_drv_status(hapd, reply, reply_size);
|
||||
@ -20,7 +20,7 @@
|
||||
} else if (os_strcmp(buf, "MIB") == 0) {
|
||||
reply_len = ieee802_11_get_mib(hapd, reply, reply_size);
|
||||
if (reply_len >= 0) {
|
||||
@@ -2953,6 +2954,7 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
@@ -3038,6 +3039,7 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
|
||||
reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
|
||||
reply_size);
|
||||
@ -30,7 +30,7 @@
|
||||
reply_len = -1;
|
||||
--- a/wpa_supplicant/Makefile
|
||||
+++ b/wpa_supplicant/Makefile
|
||||
@@ -927,6 +927,9 @@ ifdef CONFIG_FILS
|
||||
@@ -935,6 +935,9 @@ ifdef CONFIG_FILS
|
||||
OBJS += ../src/ap/fils_hlp.o
|
||||
endif
|
||||
ifdef CONFIG_CTRL_IFACE
|
||||
@ -42,7 +42,7 @@
|
||||
|
||||
--- a/wpa_supplicant/ctrl_iface.c
|
||||
+++ b/wpa_supplicant/ctrl_iface.c
|
||||
@@ -2117,7 +2117,7 @@ static int wpa_supplicant_ctrl_iface_sta
|
||||
@@ -2144,7 +2144,7 @@ static int wpa_supplicant_ctrl_iface_sta
|
||||
pos += ret;
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
if (wpa_s->ap_iface) {
|
||||
pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
|
||||
end - pos,
|
||||
@@ -9852,6 +9852,7 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
@@ -9968,6 +9968,7 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
|
||||
wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
|
||||
@ -59,15 +59,15 @@
|
||||
} else if (os_strcmp(buf, "MIB") == 0) {
|
||||
reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
|
||||
if (reply_len >= 0) {
|
||||
@@ -9859,6 +9860,7 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
reply + reply_len,
|
||||
reply_size - reply_len);
|
||||
@@ -9980,6 +9981,7 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
reply_size - reply_len);
|
||||
#endif /* CONFIG_MACSEC */
|
||||
}
|
||||
+#endif
|
||||
} else if (os_strncmp(buf, "STATUS", 6) == 0) {
|
||||
reply_len = wpa_supplicant_ctrl_iface_status(
|
||||
wpa_s, buf + 6, reply, reply_size);
|
||||
@@ -10340,6 +10342,7 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
@@ -10461,6 +10463,7 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
reply_len = wpa_supplicant_ctrl_iface_bss(
|
||||
wpa_s, buf + 4, reply, reply_size);
|
||||
#ifdef CONFIG_AP
|
||||
@ -75,7 +75,7 @@
|
||||
} else if (os_strcmp(buf, "STA-FIRST") == 0) {
|
||||
reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
|
||||
} else if (os_strncmp(buf, "STA ", 4) == 0) {
|
||||
@@ -10348,12 +10351,15 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
@@ -10469,12 +10472,15 @@ char * wpa_supplicant_ctrl_iface_process
|
||||
} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
|
||||
reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
|
||||
reply_size);
|
||||
@ -101,7 +101,7 @@
|
||||
|
||||
static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen,
|
||||
size_t curr_len, const u8 *mcs_set)
|
||||
@@ -415,6 +416,7 @@ int hostapd_ctrl_iface_sta_next(struct h
|
||||
@@ -423,6 +424,7 @@ int hostapd_ctrl_iface_sta_next(struct h
|
||||
return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@
|
||||
|
||||
#ifdef CONFIG_P2P_MANAGER
|
||||
static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
|
||||
@@ -753,12 +755,12 @@ int hostapd_ctrl_iface_status(struct hos
|
||||
@@ -761,12 +763,12 @@ int hostapd_ctrl_iface_status(struct hos
|
||||
return len;
|
||||
len += ret;
|
||||
}
|
||||
@ -126,7 +126,7 @@
|
||||
if (os_snprintf_error(buflen - len, ret))
|
||||
--- a/src/ap/ieee802_1x.c
|
||||
+++ b/src/ap/ieee802_1x.c
|
||||
@@ -2581,6 +2581,7 @@ static const char * bool_txt(Boolean val
|
||||
@@ -2579,6 +2579,7 @@ static const char * bool_txt(Boolean val
|
||||
return val ? "TRUE" : "FALSE";
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@
|
||||
|
||||
int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
|
||||
{
|
||||
@@ -2756,6 +2757,7 @@ int ieee802_1x_get_mib_sta(struct hostap
|
||||
@@ -2765,6 +2766,7 @@ int ieee802_1x_get_mib_sta(struct hostap
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@
|
||||
static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx)
|
||||
--- a/src/ap/wpa_auth.c
|
||||
+++ b/src/ap/wpa_auth.c
|
||||
@@ -3798,6 +3798,7 @@ static const char * wpa_bool_txt(int val
|
||||
@@ -4112,6 +4112,7 @@ static const char * wpa_bool_txt(int val
|
||||
return val ? "TRUE" : "FALSE";
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@
|
||||
|
||||
#define RSN_SUITE "%02x-%02x-%02x-%d"
|
||||
#define RSN_SUITE_ARG(s) \
|
||||
@@ -3942,7 +3943,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
|
||||
@@ -4256,7 +4257,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -163,7 +163,7 @@
|
||||
{
|
||||
--- a/src/rsn_supp/wpa.c
|
||||
+++ b/src/rsn_supp/wpa.c
|
||||
@@ -2319,6 +2319,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
|
||||
@@ -2481,6 +2481,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
|
||||
}
|
||||
|
||||
|
||||
@ -172,7 +172,7 @@
|
||||
#define RSN_SUITE "%02x-%02x-%02x-%d"
|
||||
#define RSN_SUITE_ARG(s) \
|
||||
((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
|
||||
@@ -2402,6 +2404,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
|
||||
@@ -2564,6 +2566,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
@ -182,7 +182,7 @@
|
||||
|
||||
--- a/wpa_supplicant/ap.c
|
||||
+++ b/wpa_supplicant/ap.c
|
||||
@@ -1221,7 +1221,7 @@ int wpas_ap_wps_nfc_report_handover(stru
|
||||
@@ -1231,7 +1231,7 @@ int wpas_ap_wps_nfc_report_handover(stru
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/src/common/wpa_common.c
|
||||
+++ b/src/common/wpa_common.c
|
||||
@@ -2042,6 +2042,31 @@ u32 wpa_akm_to_suite(int akm)
|
||||
@@ -2079,6 +2079,31 @@ u32 wpa_akm_to_suite(int akm)
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
int wpa_compare_rsn_ie(int ft_initial_assoc,
|
||||
const u8 *ie1, size_t ie1len,
|
||||
const u8 *ie2, size_t ie2len)
|
||||
@@ -2049,8 +2074,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
|
||||
@@ -2086,8 +2111,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
|
||||
if (ie1 == NULL || ie2 == NULL)
|
||||
return -1;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
bss->wpa_pairwise |= WPA_CIPHER_TKIP;
|
||||
bss->rsn_pairwise = bss->wpa_pairwise;
|
||||
bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa,
|
||||
@@ -1069,8 +1068,7 @@ int hostapd_init_wps(struct hostapd_data
|
||||
@@ -1108,8 +1107,7 @@ int hostapd_init_wps(struct hostapd_data
|
||||
WPA_CIPHER_GCMP_256)) {
|
||||
wps->encr_types |= WPS_ENCR_AES;
|
||||
wps->encr_types_rsn |= WPS_ENCR_AES;
|
||||
|
@ -43,7 +43,7 @@
|
||||
{
|
||||
size_t i, llen;
|
||||
const u8 *pos = buf;
|
||||
@@ -499,20 +487,6 @@ static void _wpa_hexdump_ascii(int level
|
||||
@@ -505,20 +493,6 @@ static void _wpa_hexdump_ascii(int level
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
static char *last_path = NULL;
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
@@ -628,7 +602,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
|
||||
@@ -634,7 +608,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
|
||||
}
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
@@ -666,7 +640,7 @@ void wpa_msg(void *ctx, int level, const
|
||||
@@ -672,7 +646,7 @@ void wpa_msg(void *ctx, int level, const
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "crypto/random.h"
|
||||
#include "crypto/tls.h"
|
||||
#include "common/version.h"
|
||||
@@ -682,7 +683,7 @@ int main(int argc, char *argv[])
|
||||
@@ -685,7 +686,7 @@ int main(int argc, char *argv[])
|
||||
wpa_supplicant_event = hostapd_wpa_event;
|
||||
wpa_supplicant_event_global = hostapd_wpa_event_global;
|
||||
for (;;) {
|
||||
@ -17,7 +17,7 @@
|
||||
if (c < 0)
|
||||
break;
|
||||
switch (c) {
|
||||
@@ -719,6 +720,8 @@ int main(int argc, char *argv[])
|
||||
@@ -722,6 +723,8 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
#endif /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
case 'v':
|
||||
@ -47,7 +47,7 @@
|
||||
switch (c) {
|
||||
@@ -305,8 +306,12 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
#endif /* CONFIG_DBUS */
|
||||
#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
|
||||
case 'v':
|
||||
- printf("%s\n", wpa_supplicant_version);
|
||||
- exitcode = 0;
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
|
||||
@@ -1510,15 +1506,12 @@ static const struct hostapd_cli_cmd host
|
||||
@@ -1531,15 +1527,12 @@ static const struct hostapd_cli_cmd host
|
||||
{ "disassociate", hostapd_cli_cmd_disassociate,
|
||||
hostapd_complete_stations,
|
||||
"<addr> = disassociate a station" },
|
||||
@ -48,7 +48,7 @@
|
||||
{ "wps_pin", hostapd_cli_cmd_wps_pin, NULL,
|
||||
"<uuid> <pin> [timeout] [addr] = add WPS Enrollee PIN" },
|
||||
{ "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL,
|
||||
@@ -1543,7 +1536,6 @@ static const struct hostapd_cli_cmd host
|
||||
@@ -1564,7 +1557,6 @@ static const struct hostapd_cli_cmd host
|
||||
"<SSID> <auth> <encr> <key> = configure AP" },
|
||||
{ "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL,
|
||||
"= show current WPS status" },
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/hostapd/main.c
|
||||
+++ b/hostapd/main.c
|
||||
@@ -38,6 +38,8 @@ struct hapd_global {
|
||||
@@ -39,6 +39,8 @@ struct hapd_global {
|
||||
};
|
||||
|
||||
static struct hapd_global global;
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
||||
@@ -148,6 +150,14 @@ static void hostapd_logger_cb(void *ctx,
|
||||
@@ -149,6 +151,14 @@ static void hostapd_logger_cb(void *ctx,
|
||||
}
|
||||
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
/**
|
||||
* hostapd_driver_init - Preparate driver interface
|
||||
@@ -166,6 +176,8 @@ static int hostapd_driver_init(struct ho
|
||||
@@ -167,6 +177,8 @@ static int hostapd_driver_init(struct ho
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
/* Initialize the driver interface */
|
||||
if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
|
||||
b = NULL;
|
||||
@@ -406,8 +418,6 @@ static void hostapd_global_deinit(const
|
||||
@@ -407,8 +419,6 @@ static void hostapd_global_deinit(const
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
eap_server_unregister_methods();
|
||||
@ -42,7 +42,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -433,18 +443,6 @@ static int hostapd_global_run(struct hap
|
||||
@@ -434,18 +444,6 @@ static int hostapd_global_run(struct hap
|
||||
}
|
||||
#endif /* EAP_SERVER_TNC */
|
||||
|
||||
@ -61,7 +61,7 @@
|
||||
eloop_run();
|
||||
|
||||
return 0;
|
||||
@@ -646,8 +644,7 @@ int main(int argc, char *argv[])
|
||||
@@ -647,8 +645,7 @@ int main(int argc, char *argv[])
|
||||
struct hapd_interfaces interfaces;
|
||||
int ret = 1;
|
||||
size_t i, j;
|
||||
|
@ -22,7 +22,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
#include "common/defs.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/wpa_common.h"
|
||||
@@ -774,6 +775,9 @@ struct wpa_driver_associate_params {
|
||||
@@ -791,6 +792,9 @@ struct wpa_driver_associate_params {
|
||||
* responsible for selecting with which BSS to associate. */
|
||||
const u8 *bssid;
|
||||
|
||||
@ -42,7 +42,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@@ -2053,6 +2054,97 @@ static char * wpa_config_write_peerkey(c
|
||||
@@ -2130,6 +2131,97 @@ static char * wpa_config_write_peerkey(c
|
||||
#endif /* NO_CONFIG_WRITE */
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
/* Helper macros for network block parser */
|
||||
|
||||
#ifdef OFFSET
|
||||
@@ -2298,6 +2390,8 @@ static const struct parse_data ssid_fiel
|
||||
@@ -2382,6 +2474,8 @@ static const struct parse_data ssid_fiel
|
||||
{ INT(ap_max_inactivity) },
|
||||
{ INT(dtim_period) },
|
||||
{ INT(beacon_int) },
|
||||
@ -162,7 +162,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
|
||||
|
||||
#define DEFAULT_EAP_WORKAROUND ((unsigned int) -1)
|
||||
@@ -757,6 +759,9 @@ struct wpa_ssid {
|
||||
@@ -788,6 +790,9 @@ struct wpa_ssid {
|
||||
*/
|
||||
void *parent_cred;
|
||||
|
||||
@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
* macsec_policy - Determines the policy for MACsec secure session
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -3117,6 +3117,12 @@ static void wpas_start_assoc_cb(struct w
|
||||
@@ -3258,6 +3258,12 @@ static void wpas_start_assoc_cb(struct w
|
||||
params.beacon_int = ssid->beacon_int;
|
||||
else
|
||||
params.beacon_int = wpa_s->conf->beacon_int;
|
||||
|
@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -5178,7 +5178,7 @@ static int wpa_driver_nl80211_ibss(struc
|
||||
@@ -5295,7 +5295,7 @@ static int wpa_driver_nl80211_ibss(struc
|
||||
struct wpa_driver_associate_params *params)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
@ -19,7 +19,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
int count = 0;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
|
||||
@@ -5205,6 +5205,37 @@ retry:
|
||||
@@ -5322,6 +5322,37 @@ retry:
|
||||
nl80211_put_beacon_int(msg, params->beacon_int))
|
||||
goto fail;
|
||||
|
||||
|
@ -19,7 +19,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -1409,6 +1409,7 @@ struct wpa_driver_mesh_join_params {
|
||||
@@ -1443,6 +1443,7 @@ struct wpa_driver_mesh_join_params {
|
||||
#define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008
|
||||
unsigned int flags;
|
||||
u8 handle_dfs;
|
||||
@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||
/**
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -9352,6 +9352,18 @@ static int nl80211_put_mesh_id(struct nl
|
||||
@@ -9532,6 +9532,18 @@ static int nl80211_put_mesh_id(struct nl
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||
static int nl80211_put_mesh_config(struct nl_msg *msg,
|
||||
struct wpa_driver_mesh_bss_params *params)
|
||||
{
|
||||
@@ -9413,6 +9425,7 @@ static int nl80211_join_mesh(struct i802
|
||||
@@ -9593,6 +9605,7 @@ static int nl80211_join_mesh(struct i802
|
||||
nl80211_put_basic_rates(msg, params->basic_rates) ||
|
||||
nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
|
||||
nl80211_put_beacon_int(msg, params->beacon_int) ||
|
||||
@ -58,7 +58,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -482,6 +482,7 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
@@ -491,6 +491,7 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
|
||||
params->meshid = ssid->ssid;
|
||||
params->meshid_len = ssid->ssid_len;
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2154,11 +2154,13 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2212,11 +2212,13 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
for (j = 0; j < wpa_s->last_scan_res_used; j++) {
|
||||
struct wpa_bss *bss = wpa_s->last_scan_res[j];
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/src/ap/acs.c
|
||||
+++ b/src/ap/acs.c
|
||||
@@ -292,18 +292,12 @@ static void acs_fail(struct hostapd_ifac
|
||||
@@ -293,18 +293,12 @@ static void acs_fail(struct hostapd_ifac
|
||||
static long double
|
||||
acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf)
|
||||
{
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
total = survey->channel_time;
|
||||
|
||||
@@ -392,20 +386,19 @@ static int acs_usable_vht80_chan(struct
|
||||
@@ -406,20 +400,19 @@ static int acs_usable_vht160_chan(const
|
||||
static int acs_survey_is_sufficient(struct freq_survey *survey)
|
||||
{
|
||||
if (!(survey->filled & SURVEY_HAS_NF)) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/hostapd/Makefile
|
||||
+++ b/hostapd/Makefile
|
||||
@@ -1290,14 +1290,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS)
|
||||
@@ -1302,14 +1302,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS)
|
||||
@$(AR) cr $@ hostapd_multi.o $(OBJS)
|
||||
|
||||
hostapd: $(BCHECK) $(OBJS)
|
||||
@ -19,7 +19,7 @@
|
||||
NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS)
|
||||
--- a/wpa_supplicant/Makefile
|
||||
+++ b/wpa_supplicant/Makefile
|
||||
@@ -1921,23 +1921,23 @@ wpa_supplicant_multi.a: .config $(BCHECK
|
||||
@@ -1905,23 +1905,23 @@ wpa_supplicant_multi.a: .config $(BCHECK
|
||||
@$(AR) cr $@ wpa_supplicant_multi.o $(OBJS)
|
||||
|
||||
wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
|
||||
|
@ -1,306 +0,0 @@
|
||||
From 9c06f0f6aed26c1628acaa74df0232dd7b345e9a Mon Sep 17 00:00:00 2001
|
||||
From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
|
||||
Date: Wed, 5 Dec 2018 11:23:51 +0100
|
||||
Subject: [PATCH] hostapd: Add Multi-AP protocol support
|
||||
|
||||
The purpose of Multi-AP specification is to enable inter-operability
|
||||
across Wi-Fi access points (APs) from different vendors.
|
||||
|
||||
This patch introduces one new configuration parameter 'multi_ap' to
|
||||
enable Multi-AP functionality and to configure the BSS as a backhaul
|
||||
and/or fronthaul BSS.
|
||||
|
||||
Advertise vendor specific Multi-AP capabilities in (Re)Association
|
||||
Response frame, if Multi-AP functionality is enabled through the
|
||||
configuration parameter.
|
||||
|
||||
A backhaul AP must support receiving both 3addr and 4addr frames from a
|
||||
backhaul STA, so create a VLAN for it just like is done for WDS, i.e.,
|
||||
by calling hostapd_set_wds_sta(). Since Multi-AP requires WPA2 (never
|
||||
WEP), we can safely call hostapd_set_wds_encryption() as well and we can
|
||||
reuse the entire WDS condition.
|
||||
|
||||
To parse the Multi-AP Extension subelement, we use get_ie(): even though
|
||||
that function is meant for parsing IEs, it works for subelements.
|
||||
|
||||
Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
hostapd/config_file.c | 10 +++++
|
||||
hostapd/hostapd.conf | 7 ++++
|
||||
src/ap/ap_config.h | 4 ++
|
||||
src/ap/ieee802_11.c | 77 +++++++++++++++++++++++++++++++++-
|
||||
src/ap/sta_info.c | 2 +-
|
||||
src/ap/sta_info.h | 1 +
|
||||
src/common/ieee802_11_common.c | 24 +++++++++++
|
||||
src/common/ieee802_11_common.h | 4 ++
|
||||
src/common/ieee802_11_defs.h | 7 ++++
|
||||
9 files changed, 134 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -4115,6 +4115,16 @@ static int hostapd_config_fill(struct ho
|
||||
} else if (os_strcmp(buf, "coloc_intf_reporting") == 0) {
|
||||
bss->coloc_intf_reporting = atoi(pos);
|
||||
#endif /* CONFIG_OWE */
|
||||
+ } else if (os_strcmp(buf, "multi_ap") == 0) {
|
||||
+ int val = atoi(pos);
|
||||
+
|
||||
+ if (val < 0 || val > 3) {
|
||||
+ wpa_printf(MSG_ERROR, "Line %d: Invalid multi_ap '%s'",
|
||||
+ line, buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ bss->multi_ap = val;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Line %d: unknown configuration item '%s'",
|
||||
--- a/hostapd/hostapd.conf
|
||||
+++ b/hostapd/hostapd.conf
|
||||
@@ -438,6 +438,13 @@ wmm_ac_vo_txop_limit=47
|
||||
wmm_ac_vo_acm=0
|
||||
# Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
|
||||
|
||||
+# Enable Multi-AP functionality
|
||||
+# 0 = disabled (default)
|
||||
+# 1 = AP support backhaul BSS
|
||||
+# 2 = AP support fronthaul BSS
|
||||
+# 3 = AP supports both backhaul BSS and fronthaul BSS
|
||||
+#multi_ap=0
|
||||
+
|
||||
# Static WEP key configuration
|
||||
#
|
||||
# The key number to use when transmitting.
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -688,6 +688,10 @@ struct hostapd_bss_config {
|
||||
#endif /* CONFIG_OWE */
|
||||
|
||||
int coloc_intf_reporting;
|
||||
+
|
||||
+#define BACKHAUL_BSS 1
|
||||
+#define FRONTHAUL_BSS 2
|
||||
+ int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -62,6 +62,22 @@ prepare_auth_resp_fils(struct hostapd_da
|
||||
int *is_pub);
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
+
|
||||
+u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
|
||||
+{
|
||||
+ u8 multi_ap_val = 0;
|
||||
+
|
||||
+ if (!hapd->conf->multi_ap)
|
||||
+ return eid;
|
||||
+ if (hapd->conf->multi_ap & BACKHAUL_BSS)
|
||||
+ multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
|
||||
+ if (hapd->conf->multi_ap & FRONTHAUL_BSS)
|
||||
+ multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
|
||||
+
|
||||
+ return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
|
||||
+}
|
||||
+
|
||||
+
|
||||
u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
@@ -2210,6 +2226,57 @@ static u16 check_wmm(struct hostapd_data
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
+ const u8 *multi_ap_ie, size_t multi_ap_len)
|
||||
+{
|
||||
+ u8 multi_ap_value = 0;
|
||||
+
|
||||
+ sta->flags &= ~WLAN_STA_MULTI_AP;
|
||||
+
|
||||
+ if (!hapd->conf->multi_ap)
|
||||
+ return WLAN_STATUS_SUCCESS;
|
||||
+
|
||||
+ if (multi_ap_ie) {
|
||||
+ const u8 *multi_ap_subelem;
|
||||
+
|
||||
+ multi_ap_subelem = get_ie(multi_ap_ie + 4,
|
||||
+ multi_ap_len - 4,
|
||||
+ MULTI_AP_SUB_ELEM_TYPE);
|
||||
+ if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
|
||||
+ multi_ap_value = multi_ap_subelem[2];
|
||||
+ } else {
|
||||
+ hostapd_logger(hapd, sta->addr,
|
||||
+ HOSTAPD_MODULE_IEEE80211,
|
||||
+ HOSTAPD_LEVEL_INFO,
|
||||
+ "Multi-AP IE has missing or invalid Multi-AP subelement");
|
||||
+ return WLAN_STATUS_INVALID_IE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (multi_ap_value == MULTI_AP_BACKHAUL_STA)
|
||||
+ sta->flags |= WLAN_STA_MULTI_AP;
|
||||
+
|
||||
+ if ((hapd->conf->multi_ap & BACKHAUL_BSS) &&
|
||||
+ multi_ap_value == MULTI_AP_BACKHAUL_STA)
|
||||
+ return WLAN_STATUS_SUCCESS;
|
||||
+
|
||||
+ if (hapd->conf->multi_ap & FRONTHAUL_BSS) {
|
||||
+ if (multi_ap_value == MULTI_AP_BACKHAUL_STA) {
|
||||
+ hostapd_logger(hapd, sta->addr,
|
||||
+ HOSTAPD_MODULE_IEEE80211,
|
||||
+ HOSTAPD_LEVEL_INFO,
|
||||
+ "Backhaul STA tries to associate with fronthaul-only BSS");
|
||||
+ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
|
||||
+ }
|
||||
+ return WLAN_STATUS_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
+ HOSTAPD_LEVEL_INFO,
|
||||
+ "Non-Multi-AP STA tries to associate with backhaul-only BSS");
|
||||
+ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
|
||||
+}
|
||||
+
|
||||
|
||||
static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
struct ieee802_11_elems *elems)
|
||||
@@ -2466,6 +2533,11 @@ static u16 check_assoc_ies(struct hostap
|
||||
resp = copy_supp_rates(hapd, sta, &elems);
|
||||
if (resp != WLAN_STATUS_SUCCESS)
|
||||
return resp;
|
||||
+
|
||||
+ resp = check_multi_ap(hapd, sta, elems.multi_ap, elems.multi_ap_len);
|
||||
+ if (resp != WLAN_STATUS_SUCCESS)
|
||||
+ return resp;
|
||||
+
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
|
||||
if (resp != WLAN_STATUS_SUCCESS)
|
||||
@@ -2996,6 +3068,9 @@ static u16 send_assoc_resp(struct hostap
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
+ if (sta && (sta->flags & WLAN_STA_MULTI_AP))
|
||||
+ p = hostapd_eid_multi_ap(hapd, p);
|
||||
+
|
||||
#ifdef CONFIG_P2P
|
||||
if (sta && sta->p2p_ie && hapd->p2p_group) {
|
||||
struct wpabuf *p2p_resp_ie;
|
||||
@@ -4248,7 +4323,7 @@ static void handle_assoc_cb(struct hosta
|
||||
sta->flags |= WLAN_STA_WDS;
|
||||
}
|
||||
|
||||
- if (sta->flags & WLAN_STA_WDS) {
|
||||
+ if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) {
|
||||
int ret;
|
||||
char ifname_wds[IFNAMSIZ + 1];
|
||||
|
||||
--- a/src/ap/sta_info.c
|
||||
+++ b/src/ap/sta_info.c
|
||||
@@ -166,7 +166,7 @@ void ap_free_sta(struct hostapd_data *ha
|
||||
/* just in case */
|
||||
ap_sta_set_authorized(hapd, sta, 0);
|
||||
|
||||
- if (sta->flags & WLAN_STA_WDS)
|
||||
+ if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP))
|
||||
hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
|
||||
|
||||
if (sta->ipaddr)
|
||||
--- a/src/ap/sta_info.h
|
||||
+++ b/src/ap/sta_info.h
|
||||
@@ -36,6 +36,7 @@
|
||||
#define WLAN_STA_VHT_OPMODE_ENABLED BIT(20)
|
||||
#define WLAN_STA_VENDOR_VHT BIT(21)
|
||||
#define WLAN_STA_PENDING_FILS_ERP BIT(22)
|
||||
+#define WLAN_STA_MULTI_AP BIT(23)
|
||||
#define WLAN_STA_PENDING_DISASSOC_CB BIT(29)
|
||||
#define WLAN_STA_PENDING_DEAUTH_CB BIT(30)
|
||||
#define WLAN_STA_NONERP BIT(31)
|
||||
--- a/src/common/ieee802_11_common.c
|
||||
+++ b/src/common/ieee802_11_common.c
|
||||
@@ -126,6 +126,10 @@ static int ieee802_11_parse_vendor_speci
|
||||
elems->roaming_cons_sel = pos;
|
||||
elems->roaming_cons_sel_len = elen;
|
||||
break;
|
||||
+ case MULTI_AP_OUI_TYPE:
|
||||
+ elems->multi_ap = pos;
|
||||
+ elems->multi_ap_len = elen;
|
||||
+ break;
|
||||
default:
|
||||
wpa_printf(MSG_MSGDUMP, "Unknown WFA "
|
||||
"information element ignored "
|
||||
@@ -1519,6 +1523,26 @@ size_t mbo_add_ie(u8 *buf, size_t len, c
|
||||
}
|
||||
|
||||
|
||||
+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
|
||||
+{
|
||||
+ u8 *pos = buf;
|
||||
+
|
||||
+ if (len < 9)
|
||||
+ return 0;
|
||||
+
|
||||
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
|
||||
+ *pos++ = 7; /* len */
|
||||
+ WPA_PUT_BE24(pos, OUI_WFA);
|
||||
+ pos += 3;
|
||||
+ *pos++ = MULTI_AP_OUI_TYPE;
|
||||
+ *pos++ = MULTI_AP_SUB_ELEM_TYPE;
|
||||
+ *pos++ = 1; /* len */
|
||||
+ *pos++ = value;
|
||||
+
|
||||
+ return pos - buf;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static const struct country_op_class us_op_class[] = {
|
||||
{ 1, 115 },
|
||||
{ 2, 118 },
|
||||
--- a/src/common/ieee802_11_common.h
|
||||
+++ b/src/common/ieee802_11_common.h
|
||||
@@ -84,6 +84,7 @@ struct ieee802_11_elems {
|
||||
const u8 *power_capab;
|
||||
const u8 *roaming_cons_sel;
|
||||
const u8 *password_id;
|
||||
+ const u8 *multi_ap;
|
||||
|
||||
u8 ssid_len;
|
||||
u8 supp_rates_len;
|
||||
@@ -130,6 +131,7 @@ struct ieee802_11_elems {
|
||||
u8 power_capab_len;
|
||||
u8 roaming_cons_sel_len;
|
||||
u8 password_id_len;
|
||||
+ u8 multi_ap_len;
|
||||
|
||||
struct mb_ies_info mb_ies;
|
||||
};
|
||||
@@ -189,6 +191,8 @@ const u8 * get_ie_ext(const u8 *ies, siz
|
||||
|
||||
size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
|
||||
|
||||
+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value);
|
||||
+
|
||||
struct country_op_class {
|
||||
u8 country_op_class;
|
||||
u8 global_op_class;
|
||||
--- a/src/common/ieee802_11_defs.h
|
||||
+++ b/src/common/ieee802_11_defs.h
|
||||
@@ -1210,6 +1210,13 @@ struct ieee80211_ampe_ie {
|
||||
#define MBO_OUI_TYPE 22
|
||||
#define OWE_IE_VENDOR_TYPE 0x506f9a1c
|
||||
#define OWE_OUI_TYPE 28
|
||||
+#define MULTI_AP_OUI_TYPE 0x1B
|
||||
+
|
||||
+#define MULTI_AP_SUB_ELEM_TYPE 0x06
|
||||
+#define MULTI_AP_TEAR_DOWN BIT(4)
|
||||
+#define MULTI_AP_FRONTHAUL_BSS BIT(5)
|
||||
+#define MULTI_AP_BACKHAUL_BSS BIT(6)
|
||||
+#define MULTI_AP_BACKHAUL_STA BIT(7)
|
||||
|
||||
#define WMM_OUI_TYPE 2
|
||||
#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
|
@ -1,311 +0,0 @@
|
||||
From 5abc7823bd01f69b8afbe1fd19f65fff86137c44 Mon Sep 17 00:00:00 2001
|
||||
From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
|
||||
Date: Wed, 5 Dec 2018 11:23:53 +0100
|
||||
Subject: [PATCH] wpa_supplicant: Add Multi-AP backhaul STA support
|
||||
|
||||
Advertise vendor specific Multi-AP IE in (Re)Association Request frames
|
||||
and process Multi-AP IE from (Re)Association Response frames if the user
|
||||
enables Multi-AP fuctionality. If the (Re)Association Response frame
|
||||
does not contain the Multi-AP IE, disassociate.
|
||||
|
||||
This adds a new configuration parameter 'multi_ap_backhaul_sta' to
|
||||
enable/disable Multi-AP functionality.
|
||||
|
||||
Enable 4-address mode after association (if the Association Response
|
||||
frame contains the Multi-AP IE). Also enable the bridge in that case.
|
||||
This is necessary because wpa_supplicant only enables the bridge in
|
||||
wpa_drv_if_add(), which only gets called when an interface is added
|
||||
through the control interface, not when it is configured from the
|
||||
command line.
|
||||
|
||||
Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
src/drivers/driver.h | 9 ++++++
|
||||
src/drivers/driver_nl80211.c | 44 ++++++++++++++++++++++++++
|
||||
wpa_supplicant/config.c | 1 +
|
||||
wpa_supplicant/config_ssid.h | 7 +++++
|
||||
wpa_supplicant/driver_i.h | 8 +++++
|
||||
wpa_supplicant/events.c | 50 ++++++++++++++++++++++++++++++
|
||||
wpa_supplicant/sme.c | 16 ++++++++++
|
||||
wpa_supplicant/wpa_supplicant.c | 18 +++++++++++
|
||||
wpa_supplicant/wpa_supplicant.conf | 7 +++++
|
||||
wpa_supplicant/wpa_supplicant_i.h | 1 +
|
||||
10 files changed, 161 insertions(+)
|
||||
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -4100,6 +4100,15 @@ struct wpa_driver_ops {
|
||||
*/
|
||||
int (*send_external_auth_status)(void *priv,
|
||||
struct external_auth *params);
|
||||
+
|
||||
+ /**
|
||||
+ * set_4addr_mode - Set 4-address mode
|
||||
+ * @priv: Private driver interface data
|
||||
+ * @bridge_ifname: Bridge interface name
|
||||
+ * @val: 0 - disable 4addr mode, 1 - enable 4addr mode
|
||||
+ * Returns: 0 on success, < 0 on failure
|
||||
+ */
|
||||
+ int (*set_4addr_mode)(void *priv, const char *bridge_ifname, int val);
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -10728,6 +10728,49 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
+static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname,
|
||||
+ int val)
|
||||
+{
|
||||
+ struct i802_bss *bss = priv;
|
||||
+ struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
+ struct nl_msg *msg;
|
||||
+ int ret = -ENOBUFS;
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "nl80211: %s 4addr mode (bridge_ifname: %s)",
|
||||
+ val ? "Enable" : "Disable", bridge_ifname);
|
||||
+
|
||||
+ msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
|
||||
+ if (!msg || nla_put_u8(msg, NL80211_ATTR_4ADDR, val))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (bridge_ifname[0] && bss->added_if_into_bridge && !val) {
|
||||
+ if (linux_br_del_if(drv->global->ioctl_sock,
|
||||
+ bridge_ifname, bss->ifname)) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "nl80211: Failed to remove interface %s from bridge %s",
|
||||
+ bss->ifname, bridge_ifname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ bss->added_if_into_bridge = 0;
|
||||
+ }
|
||||
+
|
||||
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||
+ msg = NULL;
|
||||
+ if (!ret) {
|
||||
+ if (bridge_ifname[0] && val &&
|
||||
+ i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+fail:
|
||||
+ nlmsg_free(msg);
|
||||
+ wpa_printf(MSG_ERROR, "nl80211: Failed to enable/disable 4addr");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||
.name = "nl80211",
|
||||
.desc = "Linux nl80211/cfg80211",
|
||||
@@ -10856,4 +10899,5 @@ const struct wpa_driver_ops wpa_driver_n
|
||||
.get_ext_capab = nl80211_get_ext_capab,
|
||||
.update_connect_params = nl80211_update_connection_params,
|
||||
.send_external_auth_status = nl80211_send_external_auth_status,
|
||||
+ .set_4addr_mode = nl80211_set_4addr_mode,
|
||||
};
|
||||
--- a/wpa_supplicant/config.c
|
||||
+++ b/wpa_supplicant/config.c
|
||||
@@ -2416,6 +2416,7 @@ static const struct parse_data ssid_fiel
|
||||
#endif /* CONFIG_DPP */
|
||||
{ INT_RANGE(owe_group, 0, 65535) },
|
||||
{ INT_RANGE(owe_only, 0, 1) },
|
||||
+ { INT_RANGE(multi_ap_backhaul_sta, 0, 1) },
|
||||
};
|
||||
|
||||
#undef OFFSET
|
||||
--- a/wpa_supplicant/config_ssid.h
|
||||
+++ b/wpa_supplicant/config_ssid.h
|
||||
@@ -950,6 +950,13 @@ struct wpa_ssid {
|
||||
* the selection attempts for OWE BSS exceed the configured threshold.
|
||||
*/
|
||||
int owe_transition_bss_select_count;
|
||||
+
|
||||
+ /**
|
||||
+ * multi_ap_backhaul_sta - Multi-AP backhaul STA
|
||||
+ * 0 = normal (non-Multi-AP) station
|
||||
+ * 1 = Multi-AP backhaul station
|
||||
+ */
|
||||
+ int multi_ap_backhaul_sta;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SSID_H */
|
||||
--- a/wpa_supplicant/driver_i.h
|
||||
+++ b/wpa_supplicant/driver_i.h
|
||||
@@ -1046,4 +1046,12 @@ wpa_drv_send_external_auth_status(struct
|
||||
params);
|
||||
}
|
||||
|
||||
+static inline int wpa_drv_set_4addr_mode(struct wpa_supplicant *wpa_s, int val)
|
||||
+{
|
||||
+ if (!wpa_s->driver->set_4addr_mode)
|
||||
+ return -1;
|
||||
+ return wpa_s->driver->set_4addr_mode(wpa_s->drv_priv,
|
||||
+ wpa_s->bridge_ifname, val);
|
||||
+}
|
||||
+
|
||||
#endif /* DRIVER_I_H */
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -324,6 +324,9 @@ void wpa_supplicant_mark_disassoc(struct
|
||||
os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk));
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
wpa_s->ieee80211ac = 0;
|
||||
+
|
||||
+ if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
|
||||
+ wpa_s->enabled_4addr_mode = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2267,6 +2270,50 @@ static void interworking_process_assoc_r
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
|
||||
+static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
|
||||
+ const u8 *ies, size_t ies_len)
|
||||
+{
|
||||
+ struct ieee802_11_elems elems;
|
||||
+ const u8 *map_sub_elem, *pos;
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (!wpa_s->current_ssid ||
|
||||
+ !wpa_s->current_ssid->multi_ap_backhaul_sta ||
|
||||
+ !ies ||
|
||||
+ ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
|
||||
+ return;
|
||||
+
|
||||
+ if (!elems.multi_ap || elems.multi_ap_len < 7) {
|
||||
+ wpa_printf(MSG_INFO, "AP doesn't support Multi-AP protocol");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ pos = elems.multi_ap + 4;
|
||||
+ len = elems.multi_ap_len - 4;
|
||||
+
|
||||
+ map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
|
||||
+ if (!map_sub_elem || map_sub_elem[1] < 1) {
|
||||
+ wpa_printf(MSG_INFO, "invalid Multi-AP sub elem type");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
|
||||
+ wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
|
||||
+ wpa_printf(MSG_ERROR, "Failed to set 4addr mode");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ wpa_s->enabled_4addr_mode = 1;
|
||||
+ return;
|
||||
+
|
||||
+fail:
|
||||
+ wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
|
||||
+}
|
||||
+
|
||||
+
|
||||
#ifdef CONFIG_FST
|
||||
static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
|
||||
const u8 *ie, size_t ie_len)
|
||||
@@ -2343,6 +2390,9 @@ static int wpa_supplicant_event_associnf
|
||||
get_ie(data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
|
||||
wpa_s->ieee80211ac = 1;
|
||||
+
|
||||
+ multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
|
||||
+ data->assoc_info.resp_ies_len);
|
||||
}
|
||||
if (data->assoc_info.beacon_ies)
|
||||
wpa_hexdump(MSG_DEBUG, "beacon_ies",
|
||||
--- a/wpa_supplicant/sme.c
|
||||
+++ b/wpa_supplicant/sme.c
|
||||
@@ -1552,6 +1552,22 @@ void sme_associate(struct wpa_supplicant
|
||||
}
|
||||
#endif /* CONFIG_OWE */
|
||||
|
||||
+ if (wpa_s->current_ssid && wpa_s->current_ssid->multi_ap_backhaul_sta) {
|
||||
+ size_t multi_ap_ie_len;
|
||||
+
|
||||
+ multi_ap_ie_len = add_multi_ap_ie(
|
||||
+ wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
|
||||
+ sizeof(wpa_s->sme.assoc_req_ie) -
|
||||
+ wpa_s->sme.assoc_req_ie_len,
|
||||
+ MULTI_AP_BACKHAUL_STA);
|
||||
+ if (multi_ap_ie_len == 0) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "Multi-AP: Failed to build Multi-AP IE");
|
||||
+ return;
|
||||
+ }
|
||||
+ wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
|
||||
+ }
|
||||
+
|
||||
params.bssid = bssid;
|
||||
params.ssid = wpa_s->sme.ssid;
|
||||
params.ssid_len = wpa_s->sme.ssid_len;
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2893,6 +2893,21 @@ static u8 * wpas_populate_assoc_ies(
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
+ if (ssid->multi_ap_backhaul_sta) {
|
||||
+ size_t multi_ap_ie_len;
|
||||
+
|
||||
+ multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
|
||||
+ max_wpa_ie_len - wpa_ie_len,
|
||||
+ MULTI_AP_BACKHAUL_STA);
|
||||
+ if (multi_ap_ie_len == 0) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "Multi-AP: Failed to build Multi-AP IE");
|
||||
+ os_free(wpa_ie);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ wpa_ie_len += multi_ap_ie_len;
|
||||
+ }
|
||||
+
|
||||
params->wpa_ie = wpa_ie;
|
||||
params->wpa_ie_len = wpa_ie_len;
|
||||
params->auth_alg = algs;
|
||||
@@ -3377,6 +3392,9 @@ void wpa_supplicant_deauthenticate(struc
|
||||
zero_addr = 1;
|
||||
}
|
||||
|
||||
+ if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
|
||||
+ wpa_s->enabled_4addr_mode = 0;
|
||||
+
|
||||
#ifdef CONFIG_TDLS
|
||||
wpa_tdls_teardown_peers(wpa_s->wpa);
|
||||
#endif /* CONFIG_TDLS */
|
||||
--- a/wpa_supplicant/wpa_supplicant.conf
|
||||
+++ b/wpa_supplicant/wpa_supplicant.conf
|
||||
@@ -1399,6 +1399,13 @@ fast_reauth=1
|
||||
# 2: MCS 0-9
|
||||
# 3: not supported
|
||||
|
||||
+# multi_ap_backhaul_sta: Multi-AP backhaul STA functionality
|
||||
+# 0 = normal STA (default)
|
||||
+# 1 = backhaul STA
|
||||
+# A backhaul STA sends the Multi-AP IE, fails to associate if the AP does not
|
||||
+# support Multi-AP, and sets 4-address mode if it does. Thus, the netdev can be
|
||||
+# added to a bridge to allow forwarding frames over this backhaul link.
|
||||
+
|
||||
##### Fast Session Transfer (FST) support #####################################
|
||||
#
|
||||
# The options in this section are only available when the build configuration
|
||||
--- a/wpa_supplicant/wpa_supplicant_i.h
|
||||
+++ b/wpa_supplicant/wpa_supplicant_i.h
|
||||
@@ -1242,6 +1242,7 @@ struct wpa_supplicant {
|
||||
unsigned int disable_fils:1;
|
||||
#endif /* CONFIG_FILS */
|
||||
unsigned int ieee80211ac:1;
|
||||
+ unsigned int enabled_4addr_mode:1;
|
||||
};
|
||||
|
||||
|
@ -1,100 +0,0 @@
|
||||
From 7488e0ade6dffb6df4c1fb6526a9f3ede0eb18ef Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Thu, 20 Dec 2018 12:41:00 +0200
|
||||
Subject: [PATCH] tests: Multi-AP association
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
tests/hwsim/test_multi_ap.py | 73 ++++++++++++++++++++++++++++++++++++
|
||||
tests/hwsim/wpasupplicant.py | 3 +-
|
||||
2 files changed, 75 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tests/hwsim/test_multi_ap.py
|
||||
|
||||
--- /dev/null
|
||||
+++ b/tests/hwsim/test_multi_ap.py
|
||||
@@ -0,0 +1,73 @@
|
||||
+# Test cases for Multi-AP
|
||||
+# Copyright (c) 2018, The Linux Foundation
|
||||
+#
|
||||
+# This software may be distributed under the terms of the BSD license.
|
||||
+# See README for more details.
|
||||
+
|
||||
+import hostapd
|
||||
+
|
||||
+def test_multi_ap_association(dev, apdev):
|
||||
+ """Multi-AP association in backhaul BSS"""
|
||||
+ run_multi_ap_association(dev, apdev, 1)
|
||||
+ dev[1].connect("multi-ap", psk="12345678", scan_freq="2412",
|
||||
+ wait_connect=False)
|
||||
+ ev = dev[1].wait_event([ "CTRL-EVENT-DISCONNECTED",
|
||||
+ "CTRL-EVENT-CONNECTED",
|
||||
+ "CTRL-EVENT-ASSOC-REJECT" ],
|
||||
+ timeout=5)
|
||||
+ dev[1].request("DISCONNECT")
|
||||
+ if ev is None:
|
||||
+ raise Exception("Connection result not reported")
|
||||
+ if "CTRL-EVENT-ASSOC-REJECT" not in ev:
|
||||
+ raise Exception("Association rejection not reported")
|
||||
+ if "status_code=12" not in ev:
|
||||
+ raise Exception("Unexpected association status code: " + ev)
|
||||
+
|
||||
+def test_multi_ap_association_shared_bss(dev, apdev):
|
||||
+ """Multi-AP association in backhaul BSS (with fronthaul BSS enabled)"""
|
||||
+ run_multi_ap_association(dev, apdev, 3)
|
||||
+ dev[1].connect("multi-ap", psk="12345678", scan_freq="2412")
|
||||
+
|
||||
+def run_multi_ap_association(dev, apdev, multi_ap):
|
||||
+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
|
||||
+ params["multi_ap"] = str(multi_ap)
|
||||
+ hapd = hostapd.add_ap(apdev[0], params)
|
||||
+
|
||||
+ dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
|
||||
+ scan_freq="2412")
|
||||
+
|
||||
+def test_multi_ap_disabled_on_ap(dev, apdev):
|
||||
+ """Multi-AP association attempt when disabled on AP"""
|
||||
+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
|
||||
+ hapd = hostapd.add_ap(apdev[0], params)
|
||||
+
|
||||
+ dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
|
||||
+ scan_freq="2412", wait_connect=False)
|
||||
+ ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
|
||||
+ "CTRL-EVENT-CONNECTED" ],
|
||||
+ timeout=5)
|
||||
+ dev[0].request("DISCONNECT")
|
||||
+ if ev is None:
|
||||
+ raise Exception("Connection result not reported")
|
||||
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
|
||||
+ raise Exception("Unexpected connection result")
|
||||
+
|
||||
+def test_multi_ap_fronthaul_on_ap(dev, apdev):
|
||||
+ """Multi-AP association attempt when only fronthaul BSS on AP"""
|
||||
+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
|
||||
+ params["multi_ap"] = "2"
|
||||
+ hapd = hostapd.add_ap(apdev[0], params)
|
||||
+
|
||||
+ dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
|
||||
+ scan_freq="2412", wait_connect=False)
|
||||
+ ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
|
||||
+ "CTRL-EVENT-CONNECTED",
|
||||
+ "CTRL-EVENT-ASSOC-REJECT" ],
|
||||
+ timeout=5)
|
||||
+ dev[0].request("DISCONNECT")
|
||||
+ if ev is None:
|
||||
+ raise Exception("Connection result not reported")
|
||||
+ if "CTRL-EVENT-ASSOC-REJECT" not in ev:
|
||||
+ raise Exception("Association rejection not reported")
|
||||
+ if "status_code=12" not in ev:
|
||||
+ raise Exception("Unexpected association status code: " + ev)
|
||||
--- a/tests/hwsim/wpasupplicant.py
|
||||
+++ b/tests/hwsim/wpasupplicant.py
|
||||
@@ -1031,7 +1031,8 @@ class WpaSupplicant:
|
||||
"dpp_csign", "dpp_csign_expiry",
|
||||
"dpp_netaccesskey", "dpp_netaccesskey_expiry",
|
||||
"group_mgmt", "owe_group",
|
||||
- "roaming_consortium_selection" ]
|
||||
+ "roaming_consortium_selection", "multi_ap_backhaul_sta" ]
|
||||
+
|
||||
for field in not_quoted:
|
||||
if field in kwargs and kwargs[field]:
|
||||
self.set_network(id, field, kwargs[field])
|
@ -1,72 +0,0 @@
|
||||
From 0f5029ff41ef286aa7b3e4a3efd3f1a16be925e8 Mon Sep 17 00:00:00 2001
|
||||
From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
|
||||
Date: Wed, 9 Jan 2019 18:41:08 +0100
|
||||
Subject: [PATCH] tests: refactor test_multi_ap
|
||||
|
||||
With just one additional argument, the run_multi_ap_association function
|
||||
can be used for all tests.
|
||||
|
||||
While we're at it, also move it to the top of the file.
|
||||
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
v4: new patch
|
||||
---
|
||||
tests/hwsim/test_multi_ap.py | 30 +++++++++++-------------------
|
||||
1 file changed, 11 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/tests/hwsim/test_multi_ap.py
|
||||
+++ b/tests/hwsim/test_multi_ap.py
|
||||
@@ -6,6 +6,15 @@
|
||||
|
||||
import hostapd
|
||||
|
||||
+def run_multi_ap_association(dev, apdev, multi_ap, wait_connect=True):
|
||||
+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
|
||||
+ if multi_ap:
|
||||
+ params["multi_ap"] = str(multi_ap)
|
||||
+ hapd = hostapd.add_ap(apdev[0], params)
|
||||
+
|
||||
+ dev[0].connect("multi-ap", psk="12345678", scan_freq="2412",
|
||||
+ multi_ap_backhaul_sta="1", wait_connect=wait_connect)
|
||||
+
|
||||
def test_multi_ap_association(dev, apdev):
|
||||
"""Multi-AP association in backhaul BSS"""
|
||||
run_multi_ap_association(dev, apdev, 1)
|
||||
@@ -28,21 +37,9 @@ def test_multi_ap_association_shared_bss
|
||||
run_multi_ap_association(dev, apdev, 3)
|
||||
dev[1].connect("multi-ap", psk="12345678", scan_freq="2412")
|
||||
|
||||
-def run_multi_ap_association(dev, apdev, multi_ap):
|
||||
- params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
|
||||
- params["multi_ap"] = str(multi_ap)
|
||||
- hapd = hostapd.add_ap(apdev[0], params)
|
||||
-
|
||||
- dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
|
||||
- scan_freq="2412")
|
||||
-
|
||||
def test_multi_ap_disabled_on_ap(dev, apdev):
|
||||
"""Multi-AP association attempt when disabled on AP"""
|
||||
- params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
|
||||
- hapd = hostapd.add_ap(apdev[0], params)
|
||||
-
|
||||
- dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
|
||||
- scan_freq="2412", wait_connect=False)
|
||||
+ run_multi_ap_association(dev, apdev, 0, wait_connect=False)
|
||||
ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
|
||||
"CTRL-EVENT-CONNECTED" ],
|
||||
timeout=5)
|
||||
@@ -54,12 +51,7 @@ def test_multi_ap_disabled_on_ap(dev, ap
|
||||
|
||||
def test_multi_ap_fronthaul_on_ap(dev, apdev):
|
||||
"""Multi-AP association attempt when only fronthaul BSS on AP"""
|
||||
- params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
|
||||
- params["multi_ap"] = "2"
|
||||
- hapd = hostapd.add_ap(apdev[0], params)
|
||||
-
|
||||
- dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
|
||||
- scan_freq="2412", wait_connect=False)
|
||||
+ run_multi_ap_association(dev, apdev, 2, wait_connect=False)
|
||||
ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
|
||||
"CTRL-EVENT-CONNECTED",
|
||||
"CTRL-EVENT-ASSOC-REJECT" ],
|
@ -1,106 +0,0 @@
|
||||
From 71b061b8a13791a1ed858d924e401541c8584030 Mon Sep 17 00:00:00 2001
|
||||
From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
|
||||
Date: Wed, 9 Jan 2019 19:08:00 +0100
|
||||
Subject: [PATCH] multi_ap: don't reject backhaul STA on fronhaul BSS
|
||||
|
||||
The Multi-AP specification only specifies that information elements have
|
||||
to be added to the association requests and responses; it doesn't
|
||||
specify anything about what should be done in case they are missing.
|
||||
Currently, we reject non-backhaul associations on a backhaul-only BSS,
|
||||
and non-fronthaul associations on a fronthaul-only BSS.
|
||||
|
||||
However, this makes WPS fail when fronthaul and backhaul are separate
|
||||
SSIDs. Indeed, WPS for the backhaul link is performed on the *fronthaul*
|
||||
SSID. Thus, the association request used for WPS *will* contain the
|
||||
Multi-AP IE indicating a backhaul STA. Rejecting that association makes
|
||||
WPS fail.
|
||||
|
||||
Therefore, accept a multi-AP backhaul STA association request on a
|
||||
fronthaul-only BSS. Still issue a warning about it, but only at level
|
||||
DEBUG intead of INFO. Also change the condition checking to make it
|
||||
clearer.
|
||||
|
||||
While we're at it, also fix the handling of unexpected bits in the
|
||||
Multi-AP IE. 4 bits are reserved in the specification, so these
|
||||
certainly have to be ignored. The specification also doesn't say that
|
||||
setting one of the other bits is not allowed. Therefore, only report
|
||||
unexpected values in the Multi-AP IE, don't reject because of it.
|
||||
Note that a malformed IE (containing more than one byte) still triggers
|
||||
a rejection.
|
||||
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
v4: new patch
|
||||
|
||||
Cfr. discussion on http://lists.infradead.org/pipermail/hostap/2019-January/039232.html
|
||||
and follow-ups.
|
||||
---
|
||||
src/ap/ieee802_11.c | 38 +++++++++++++++++++-----------------
|
||||
tests/hwsim/test_multi_ap.py | 6 ++----
|
||||
2 files changed, 22 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -2253,28 +2253,30 @@ static u16 check_multi_ap(struct hostapd
|
||||
}
|
||||
}
|
||||
|
||||
- if (multi_ap_value == MULTI_AP_BACKHAUL_STA)
|
||||
- sta->flags |= WLAN_STA_MULTI_AP;
|
||||
-
|
||||
- if ((hapd->conf->multi_ap & BACKHAUL_BSS) &&
|
||||
- multi_ap_value == MULTI_AP_BACKHAUL_STA)
|
||||
- return WLAN_STATUS_SUCCESS;
|
||||
-
|
||||
- if (hapd->conf->multi_ap & FRONTHAUL_BSS) {
|
||||
- if (multi_ap_value == MULTI_AP_BACKHAUL_STA) {
|
||||
- hostapd_logger(hapd, sta->addr,
|
||||
- HOSTAPD_MODULE_IEEE80211,
|
||||
- HOSTAPD_LEVEL_INFO,
|
||||
- "Backhaul STA tries to associate with fronthaul-only BSS");
|
||||
- return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
|
||||
- }
|
||||
- return WLAN_STATUS_SUCCESS;
|
||||
+ if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
|
||||
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
+ HOSTAPD_LEVEL_INFO,
|
||||
+ "Multi-AP IE with unexpected value 0x%02x",
|
||||
+ multi_ap_value);
|
||||
+
|
||||
+ if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
|
||||
+ if (hapd->conf->multi_ap & FRONTHAUL_BSS)
|
||||
+ return WLAN_STATUS_SUCCESS;
|
||||
+
|
||||
+ hostapd_logger(hapd, sta->addr,
|
||||
+ HOSTAPD_MODULE_IEEE80211,
|
||||
+ HOSTAPD_LEVEL_INFO,
|
||||
+ "Non-Multi-AP STA tries to associate with backhaul-only BSS");
|
||||
+ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
|
||||
}
|
||||
|
||||
- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
- HOSTAPD_LEVEL_INFO,
|
||||
- "Non-Multi-AP STA tries to associate with backhaul-only BSS");
|
||||
- return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
|
||||
+ if (!(hapd->conf->multi_ap & BACKHAUL_BSS))
|
||||
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
+ HOSTAPD_LEVEL_DEBUG,
|
||||
+ "Backhaul STA tries to associate with fronthaul-only BSS");
|
||||
+
|
||||
+ sta->flags |= WLAN_STA_MULTI_AP;
|
||||
+ return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
--- a/tests/hwsim/test_multi_ap.py
|
||||
+++ b/tests/hwsim/test_multi_ap.py
|
||||
@@ -59,7 +59,5 @@ def test_multi_ap_fronthaul_on_ap(dev, a
|
||||
dev[0].request("DISCONNECT")
|
||||
if ev is None:
|
||||
raise Exception("Connection result not reported")
|
||||
- if "CTRL-EVENT-ASSOC-REJECT" not in ev:
|
||||
- raise Exception("Association rejection not reported")
|
||||
- if "status_code=12" not in ev:
|
||||
- raise Exception("Unexpected association status code: " + ev)
|
||||
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
|
||||
+ raise Exception("Unexpected connection result")
|
@ -1,342 +0,0 @@
|
||||
From ad3c6faca118c23cdafef418dc27b3cee7d0e06e Mon Sep 17 00:00:00 2001
|
||||
From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
|
||||
Date: Wed, 9 Jan 2019 19:19:26 +0100
|
||||
Subject: [PATCH] WPS: wps_build_wfa_ext(): add multi_ap_subelem parameter
|
||||
|
||||
The Multi-AP specification adds a new subelement to the WFA extension
|
||||
element in the WPS exchange. Add an additional parameter to
|
||||
wps_build_wfa_ext() to add this subelement. The subelement is only added
|
||||
if the parameter is non-0. Note that we don't reuse the existing
|
||||
MULTI_AP_SUB_ELEM_TYPE definition here, but rather define a new
|
||||
WFA_ELEM_MULTI_AP, to make sure the enum of WFA subelement types remains
|
||||
complete.
|
||||
|
||||
For now, all callers set the multi_ap_subelem parameter to 0.
|
||||
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
v4: Split off from supplicant WPS patch
|
||||
|
||||
Since the original patch from Davina Lyu didn't have this extra
|
||||
argument, I kept myself as the author of this patch.
|
||||
---
|
||||
src/p2p/p2p_build.c | 2 +-
|
||||
src/wps/wps.c | 6 +++---
|
||||
src/wps/wps_attr_build.c | 11 ++++++++++-
|
||||
src/wps/wps_common.c | 16 ++++++++--------
|
||||
src/wps/wps_defs.h | 3 ++-
|
||||
src/wps/wps_enrollee.c | 10 +++++-----
|
||||
src/wps/wps_er.c | 4 ++--
|
||||
src/wps/wps_i.h | 3 ++-
|
||||
src/wps/wps_registrar.c | 14 +++++++-------
|
||||
src/wps/wps_upnp.c | 2 +-
|
||||
10 files changed, 41 insertions(+), 30 deletions(-)
|
||||
|
||||
--- a/src/p2p/p2p_build.c
|
||||
+++ b/src/p2p/p2p_build.c
|
||||
@@ -802,7 +802,7 @@ int p2p_build_wps_ie(struct p2p_data *p2
|
||||
wpabuf_put_be16(buf, p2p->cfg->config_methods);
|
||||
}
|
||||
|
||||
- if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0)
|
||||
+ if (wps_build_wfa_ext(buf, 0, NULL, 0, 0) < 0)
|
||||
return -1;
|
||||
|
||||
if (all_attr && p2p->cfg->num_sec_dev_types) {
|
||||
--- a/src/wps/wps.c
|
||||
+++ b/src/wps/wps.c
|
||||
@@ -430,7 +430,7 @@ struct wpabuf * wps_build_assoc_req_ie(e
|
||||
|
||||
if (wps_build_version(ie) ||
|
||||
wps_build_req_type(ie, req_type) ||
|
||||
- wps_build_wfa_ext(ie, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(ie);
|
||||
return NULL;
|
||||
}
|
||||
@@ -464,7 +464,7 @@ struct wpabuf * wps_build_assoc_resp_ie(
|
||||
|
||||
if (wps_build_version(ie) ||
|
||||
wps_build_resp_type(ie, WPS_RESP_AP) ||
|
||||
- wps_build_wfa_ext(ie, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(ie);
|
||||
return NULL;
|
||||
}
|
||||
@@ -516,7 +516,7 @@ struct wpabuf * wps_build_probe_req_ie(u
|
||||
wps_build_model_name(dev, ie) ||
|
||||
wps_build_model_number(dev, ie) ||
|
||||
wps_build_dev_name(dev, ie) ||
|
||||
- wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0, 0) ||
|
||||
wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
|
||||
||
|
||||
wps_build_secondary_dev_type(dev, ie)
|
||||
--- a/src/wps/wps_attr_build.c
|
||||
+++ b/src/wps/wps_attr_build.c
|
||||
@@ -203,7 +203,8 @@ int wps_build_version(struct wpabuf *msg
|
||||
|
||||
|
||||
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
|
||||
- const u8 *auth_macs, size_t auth_macs_count)
|
||||
+ const u8 *auth_macs, size_t auth_macs_count,
|
||||
+ u8 multi_ap_subelem)
|
||||
{
|
||||
u8 *len;
|
||||
|
||||
@@ -244,6 +245,14 @@ int wps_build_wfa_ext(struct wpabuf *msg
|
||||
MAC2STR(&auth_macs[i * ETH_ALEN]));
|
||||
}
|
||||
|
||||
+ if (multi_ap_subelem) {
|
||||
+ wpa_printf(MSG_DEBUG, "WPS: * Multi-AP (0x%x)",
|
||||
+ multi_ap_subelem);
|
||||
+ wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP);
|
||||
+ wpabuf_put_u8(msg, 1); /* length */
|
||||
+ wpabuf_put_u8(msg, multi_ap_subelem);
|
||||
+ }
|
||||
+
|
||||
WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
|
||||
|
||||
#ifdef CONFIG_WPS_TESTING
|
||||
--- a/src/wps/wps_common.c
|
||||
+++ b/src/wps/wps_common.c
|
||||
@@ -374,7 +374,7 @@ struct wpabuf * wps_get_oob_cred(struct
|
||||
(rf_band && wps_build_rf_bands_attr(plain, rf_band)) ||
|
||||
(channel && wps_build_ap_channel(plain, channel)) ||
|
||||
wps_build_mac_addr(plain, wps->dev.mac_addr) ||
|
||||
- wps_build_wfa_ext(plain, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(plain, 0, NULL, 0, 0)) {
|
||||
os_free(data.new_psk);
|
||||
wpabuf_clear_free(plain);
|
||||
return NULL;
|
||||
@@ -421,7 +421,7 @@ struct wpabuf * wps_build_nfc_pw_token(u
|
||||
|
||||
if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
|
||||
wpabuf_head(dev_pw), wpabuf_len(dev_pw)) ||
|
||||
- wps_build_wfa_ext(data, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(data, 0, NULL, 0, 0)) {
|
||||
wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
|
||||
"token");
|
||||
wpabuf_clear_free(data);
|
||||
@@ -586,7 +586,7 @@ struct wpabuf * wps_build_wsc_ack(struct
|
||||
wps_build_msg_type(msg, WPS_WSC_ACK) ||
|
||||
wps_build_enrollee_nonce(wps, msg) ||
|
||||
wps_build_registrar_nonce(wps, msg) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -610,7 +610,7 @@ struct wpabuf * wps_build_wsc_nack(struc
|
||||
wps_build_enrollee_nonce(wps, msg) ||
|
||||
wps_build_registrar_nonce(wps, msg) ||
|
||||
wps_build_config_error(msg, wps->config_error) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -726,7 +726,7 @@ struct wpabuf * wps_build_nfc_handover_r
|
||||
if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
|
||||
nfc_dh_pubkey, NULL, 0) ||
|
||||
wps_build_uuid_e(msg, ctx->uuid) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -809,7 +809,7 @@ struct wpabuf * wps_build_nfc_handover_s
|
||||
wps_build_ssid(msg, ctx) ||
|
||||
wps_build_ap_freq(msg, freq) ||
|
||||
(bssid && wps_build_mac_addr(msg, bssid)) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -848,7 +848,7 @@ struct wpabuf * wps_build_nfc_handover_r
|
||||
wps_build_rf_bands(&ctx->dev, msg, 0) ||
|
||||
wps_build_serial_number(&ctx->dev, msg) ||
|
||||
wps_build_uuid_e(msg, ctx->uuid) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -900,7 +900,7 @@ struct wpabuf * wps_build_nfc_handover_s
|
||||
wps_build_rf_bands(&ctx->dev, msg, 0) ||
|
||||
wps_build_serial_number(&ctx->dev, msg) ||
|
||||
wps_build_uuid_e(msg, ctx->uuid) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
--- a/src/wps/wps_defs.h
|
||||
+++ b/src/wps/wps_defs.h
|
||||
@@ -152,7 +152,8 @@ enum {
|
||||
WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
|
||||
WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
|
||||
WFA_ELEM_SETTINGS_DELAY_TIME = 0x04,
|
||||
- WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05
|
||||
+ WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05,
|
||||
+ WFA_ELEM_MULTI_AP = 0x06
|
||||
};
|
||||
|
||||
/* Device Password ID */
|
||||
--- a/src/wps/wps_enrollee.c
|
||||
+++ b/src/wps/wps_enrollee.c
|
||||
@@ -152,7 +152,7 @@ static struct wpabuf * wps_build_m1(stru
|
||||
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
|
||||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
|
||||
wps_build_os_version(&wps->wps->dev, msg) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
@@ -190,7 +190,7 @@ static struct wpabuf * wps_build_m3(stru
|
||||
wps_build_msg_type(msg, WPS_M3) ||
|
||||
wps_build_registrar_nonce(wps, msg) ||
|
||||
wps_build_e_hash(wps, msg) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
wps_build_authenticator(wps, msg)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
@@ -223,7 +223,7 @@ static struct wpabuf * wps_build_m5(stru
|
||||
wps_build_e_snonce1(wps, plain) ||
|
||||
wps_build_key_wrap_auth(wps, plain) ||
|
||||
wps_build_encr_settings(wps, msg, plain) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
wps_build_authenticator(wps, msg)) {
|
||||
wpabuf_clear_free(plain);
|
||||
wpabuf_free(msg);
|
||||
@@ -393,7 +393,7 @@ static struct wpabuf * wps_build_m7(stru
|
||||
(wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
|
||||
wps_build_key_wrap_auth(wps, plain) ||
|
||||
wps_build_encr_settings(wps, msg, plain) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
wps_build_authenticator(wps, msg)) {
|
||||
wpabuf_clear_free(plain);
|
||||
wpabuf_free(msg);
|
||||
@@ -430,7 +430,7 @@ static struct wpabuf * wps_build_wsc_don
|
||||
wps_build_msg_type(msg, WPS_WSC_DONE) ||
|
||||
wps_build_enrollee_nonce(wps, msg) ||
|
||||
wps_build_registrar_nonce(wps, msg) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
--- a/src/wps/wps_er.c
|
||||
+++ b/src/wps/wps_er.c
|
||||
@@ -1530,7 +1530,7 @@ void wps_er_set_sel_reg(struct wps_er *e
|
||||
wps_er_build_selected_registrar(msg, sel_reg) ||
|
||||
wps_er_build_dev_password_id(msg, dev_passwd_id) ||
|
||||
wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) ||
|
||||
- wps_build_wfa_ext(msg, 0, auth_macs, count) ||
|
||||
+ wps_build_wfa_ext(msg, 0, auth_macs, count, 0) ||
|
||||
wps_er_build_uuid_r(msg, er->wps->uuid)) {
|
||||
wpabuf_free(msg);
|
||||
return;
|
||||
@@ -2048,7 +2048,7 @@ struct wpabuf * wps_er_config_token_from
|
||||
data.wps = wps;
|
||||
data.use_cred = cred;
|
||||
if (wps_build_cred(&data, ret) ||
|
||||
- wps_build_wfa_ext(ret, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(ret, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
--- a/src/wps/wps_i.h
|
||||
+++ b/src/wps/wps_i.h
|
||||
@@ -163,7 +163,8 @@ int wps_build_encr_settings(struct wps_d
|
||||
struct wpabuf *plain);
|
||||
int wps_build_version(struct wpabuf *msg);
|
||||
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
|
||||
- const u8 *auth_macs, size_t auth_macs_count);
|
||||
+ const u8 *auth_macs, size_t auth_macs_count,
|
||||
+ u8 multi_ap_subelem);
|
||||
int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
|
||||
int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
|
||||
int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
|
||||
--- a/src/wps/wps_registrar.c
|
||||
+++ b/src/wps/wps_registrar.c
|
||||
@@ -1281,7 +1281,7 @@ static int wps_set_ie(struct wps_registr
|
||||
wps_build_sel_reg_config_methods(reg, beacon) ||
|
||||
wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
|
||||
(reg->dualband && wps_build_rf_bands(®->wps->dev, beacon, 0)) ||
|
||||
- wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
|
||||
+ wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
|
||||
wps_build_vendor_ext(®->wps->dev, beacon)) {
|
||||
wpabuf_free(beacon);
|
||||
wpabuf_free(probe);
|
||||
@@ -1311,7 +1311,7 @@ static int wps_set_ie(struct wps_registr
|
||||
wps_build_device_attrs(®->wps->dev, probe) ||
|
||||
wps_build_probe_config_methods(reg, probe) ||
|
||||
(reg->dualband && wps_build_rf_bands(®->wps->dev, probe, 0)) ||
|
||||
- wps_build_wfa_ext(probe, 0, auth_macs, count) ||
|
||||
+ wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
|
||||
wps_build_vendor_ext(®->wps->dev, probe)) {
|
||||
wpabuf_free(beacon);
|
||||
wpabuf_free(probe);
|
||||
@@ -1845,7 +1845,7 @@ static struct wpabuf * wps_build_m2(stru
|
||||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
|
||||
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
|
||||
wps_build_os_version(&wps->wps->dev, msg) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1913,7 +1913,7 @@ static struct wpabuf * wps_build_m2d(str
|
||||
wps_build_assoc_state(wps, msg) ||
|
||||
wps_build_config_error(msg, err) ||
|
||||
wps_build_os_version(&wps->wps->dev, msg) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1949,7 +1949,7 @@ static struct wpabuf * wps_build_m4(stru
|
||||
wps_build_r_snonce1(wps, plain) ||
|
||||
wps_build_key_wrap_auth(wps, plain) ||
|
||||
wps_build_encr_settings(wps, msg, plain) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
wps_build_authenticator(wps, msg)) {
|
||||
wpabuf_clear_free(plain);
|
||||
wpabuf_free(msg);
|
||||
@@ -1984,7 +1984,7 @@ static struct wpabuf * wps_build_m6(stru
|
||||
wps_build_r_snonce2(wps, plain) ||
|
||||
wps_build_key_wrap_auth(wps, plain) ||
|
||||
wps_build_encr_settings(wps, msg, plain) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
wps_build_authenticator(wps, msg)) {
|
||||
wpabuf_clear_free(plain);
|
||||
wpabuf_free(msg);
|
||||
@@ -2021,7 +2021,7 @@ static struct wpabuf * wps_build_m8(stru
|
||||
(!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
|
||||
wps_build_key_wrap_auth(wps, plain) ||
|
||||
wps_build_encr_settings(wps, msg, plain) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
wps_build_authenticator(wps, msg)) {
|
||||
wpabuf_clear_free(plain);
|
||||
wpabuf_clear_free(msg);
|
||||
--- a/src/wps/wps_upnp.c
|
||||
+++ b/src/wps/wps_upnp.c
|
||||
@@ -599,7 +599,7 @@ static struct wpabuf * build_fake_wsc_ac
|
||||
wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
|
||||
wpabuf_put_be16(msg, WPS_NONCE_LEN);
|
||||
wpabuf_put(msg, WPS_NONCE_LEN);
|
||||
- if (wps_build_wfa_ext(msg, 0, NULL, 0)) {
|
||||
+ if (wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
From 6c4c98db9420a3321bbf091cfc254de5eba4b404 Mon Sep 17 00:00:00 2001
|
||||
From: Davina Lu <ylu@quantenna.com>
|
||||
Date: Tue, 15 Jan 2019 19:17:51 +0100
|
||||
Subject: [PATCH] wpa_supplicant: support Multi-AP backhaul STA onboarding
|
||||
|
||||
The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
|
||||
backhaul STA through WPS. To enable this, the backhaul STA needs to add
|
||||
a Multi-AP IE to the WFA vendor extension element in the WSC M1 message
|
||||
that indicates it supports the Multi-AP backhaul STA role. The registrar
|
||||
(if it support Multi-AP onboarding) will respond to that with a WSC M8
|
||||
message that also contains the Multi-AP IE, and that contains the
|
||||
credentials for the backhaul SSID (which may be different from the SSID
|
||||
on which WPS is performed).
|
||||
|
||||
Introduce a new parameter to wpas_wps_start_pbc() and allow it to be
|
||||
set via control interface's new multi_ap=1 parameter of WPS_PBC call.
|
||||
multi_ap_backhaul_sta is set to 1 in the automatically created SSID.
|
||||
Thus, if the AP does not support Multi-AP, association will fail and
|
||||
WPS will be terminated.
|
||||
|
||||
Only wps_pbc is supported.
|
||||
|
||||
The multi_ap argument is only added to the socket interface, not to the
|
||||
dbus interface.
|
||||
|
||||
Signed-off-by: Davina Lu <ylu@quantenna.com>
|
||||
Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
v4: use argument to wps_pbc instead of a global configuration option
|
||||
(requested by Jouni)
|
||||
---
|
||||
src/eap_peer/eap_wsc.c | 3 +++
|
||||
src/wps/wps.h | 6 ++++++
|
||||
src/wps/wps_enrollee.c | 6 +++++-
|
||||
wpa_supplicant/ctrl_iface.c | 5 ++++-
|
||||
wpa_supplicant/dbus/dbus_new_handlers_wps.c | 2 +-
|
||||
wpa_supplicant/dbus/dbus_old_handlers_wps.c | 4 ++--
|
||||
wpa_supplicant/events.c | 2 +-
|
||||
wpa_supplicant/p2p_supplicant.c | 2 +-
|
||||
wpa_supplicant/wps_supplicant.c | 9 +++++++--
|
||||
wpa_supplicant/wps_supplicant.h | 2 +-
|
||||
10 files changed, 31 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/src/eap_peer/eap_wsc.c
|
||||
+++ b/src/eap_peer/eap_wsc.c
|
||||
@@ -274,6 +274,9 @@ static void * eap_wsc_init(struct eap_sm
|
||||
cfg.pin, cfg.pin_len, 0);
|
||||
}
|
||||
|
||||
+ if (os_strstr(phase1, "multi_ap=1"))
|
||||
+ wps->multi_ap_backhaul_sta = 1;
|
||||
+
|
||||
/* Use reduced client timeout for WPS to avoid long wait */
|
||||
if (sm->ClientTimeout > 30)
|
||||
sm->ClientTimeout = 30;
|
||||
--- a/src/wps/wps.h
|
||||
+++ b/src/wps/wps.h
|
||||
@@ -613,6 +613,12 @@ struct wps_context {
|
||||
int ap_setup_locked;
|
||||
|
||||
/**
|
||||
+ * multi_ap_backhaul_sta - Whether this is a Multi-AP backhaul STA
|
||||
+ * enrollee
|
||||
+ */
|
||||
+ int multi_ap_backhaul_sta;
|
||||
+
|
||||
+ /**
|
||||
* uuid - Own UUID
|
||||
*/
|
||||
u8 uuid[16];
|
||||
--- a/src/wps/wps_enrollee.c
|
||||
+++ b/src/wps/wps_enrollee.c
|
||||
@@ -105,6 +105,7 @@ static struct wpabuf * wps_build_m1(stru
|
||||
{
|
||||
struct wpabuf *msg;
|
||||
u16 config_methods;
|
||||
+ u8 multi_ap_backhaul_sta = 0;
|
||||
|
||||
if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
|
||||
return NULL;
|
||||
@@ -134,6 +135,9 @@ static struct wpabuf * wps_build_m1(stru
|
||||
WPS_CONFIG_PHY_PUSHBUTTON);
|
||||
}
|
||||
|
||||
+ if (wps->wps->multi_ap_backhaul_sta)
|
||||
+ multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
|
||||
+
|
||||
if (wps_build_version(msg) ||
|
||||
wps_build_msg_type(msg, WPS_M1) ||
|
||||
wps_build_uuid_e(msg, wps->uuid_e) ||
|
||||
@@ -152,7 +156,7 @@ static struct wpabuf * wps_build_m1(stru
|
||||
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
|
||||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
|
||||
wps_build_os_version(&wps->wps->dev, msg) ||
|
||||
- wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
|
||||
+ wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
|
||||
wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
|
||||
wpabuf_free(msg);
|
||||
return NULL;
|
||||
--- a/wpa_supplicant/ctrl_iface.c
|
||||
+++ b/wpa_supplicant/ctrl_iface.c
|
||||
@@ -1167,6 +1167,7 @@ static int wpa_supplicant_ctrl_iface_wps
|
||||
#ifdef CONFIG_AP
|
||||
u8 *_p2p_dev_addr = NULL;
|
||||
#endif /* CONFIG_AP */
|
||||
+ int multi_ap = 0;
|
||||
|
||||
if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
|
||||
_bssid = NULL;
|
||||
@@ -1184,6 +1185,8 @@ static int wpa_supplicant_ctrl_iface_wps
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
|
||||
cmd);
|
||||
return -1;
|
||||
+ } else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
|
||||
+ multi_ap = atoi(cmd + 9);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AP
|
||||
@@ -1191,7 +1194,7 @@ static int wpa_supplicant_ctrl_iface_wps
|
||||
return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
|
||||
#endif /* CONFIG_AP */
|
||||
|
||||
- return wpas_wps_start_pbc(wpa_s, _bssid, 0);
|
||||
+ return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
|
||||
}
|
||||
|
||||
|
||||
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
|
||||
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
|
||||
@@ -289,7 +289,7 @@ DBusMessage * wpas_dbus_handler_wps_star
|
||||
if (ret > 0)
|
||||
os_snprintf(npin, sizeof(npin), "%08d", ret);
|
||||
} else {
|
||||
- ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
|
||||
+ ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
--- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
|
||||
+++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
|
||||
@@ -37,9 +37,9 @@ DBusMessage * wpas_dbus_iface_wps_pbc(DB
|
||||
return wpas_dbus_new_invalid_opts_error(message, NULL);
|
||||
|
||||
if (os_strcmp(arg_bssid, "any") == 0)
|
||||
- ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
|
||||
+ ret = wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
|
||||
else if (!hwaddr_aton(arg_bssid, bssid))
|
||||
- ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
|
||||
+ ret = wpas_wps_start_pbc(wpa_s, bssid, 0, 0);
|
||||
else {
|
||||
return wpas_dbus_new_invalid_opts_error(message,
|
||||
"Invalid BSSID");
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -4816,7 +4816,7 @@ void supplicant_event(void *ctx, enum wp
|
||||
break;
|
||||
case EVENT_WPS_BUTTON_PUSHED:
|
||||
#ifdef CONFIG_WPS
|
||||
- wpas_wps_start_pbc(wpa_s, NULL, 0);
|
||||
+ wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
|
||||
#endif /* CONFIG_WPS */
|
||||
break;
|
||||
case EVENT_AVOID_FREQUENCIES:
|
||||
--- a/wpa_supplicant/p2p_supplicant.c
|
||||
+++ b/wpa_supplicant/p2p_supplicant.c
|
||||
@@ -1649,7 +1649,7 @@ static void wpas_start_wps_enrollee(stru
|
||||
wpa_supplicant_ap_deinit(wpa_s);
|
||||
wpas_copy_go_neg_results(wpa_s, res);
|
||||
if (res->wps_method == WPS_PBC) {
|
||||
- wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
|
||||
+ wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
|
||||
#ifdef CONFIG_WPS_NFC
|
||||
} else if (res->wps_method == WPS_NFC) {
|
||||
wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
|
||||
--- a/wpa_supplicant/wps_supplicant.c
|
||||
+++ b/wpa_supplicant/wps_supplicant.c
|
||||
@@ -1137,9 +1137,10 @@ static void wpas_wps_reassoc(struct wpa_
|
||||
|
||||
|
||||
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||
- int p2p_group)
|
||||
+ int p2p_group, int multi_ap_backhaul_sta)
|
||||
{
|
||||
struct wpa_ssid *ssid;
|
||||
+ char phase1[32];
|
||||
|
||||
#ifdef CONFIG_AP
|
||||
if (wpa_s->ap_iface) {
|
||||
@@ -1177,10 +1178,14 @@ int wpas_wps_start_pbc(struct wpa_suppli
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_P2P */
|
||||
- if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
|
||||
+ if (os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
|
||||
+ multi_ap_backhaul_sta ? " multi_ap=1" : "") ||
|
||||
+ wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
|
||||
return -1;
|
||||
if (wpa_s->wps_fragment_size)
|
||||
ssid->eap.fragment_size = wpa_s->wps_fragment_size;
|
||||
+ if (multi_ap_backhaul_sta)
|
||||
+ ssid->multi_ap_backhaul_sta = 1;
|
||||
wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
|
||||
eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
|
||||
wpa_s, NULL);
|
||||
--- a/wpa_supplicant/wps_supplicant.h
|
||||
+++ b/wpa_supplicant/wps_supplicant.h
|
||||
@@ -30,7 +30,7 @@ void wpas_wps_deinit(struct wpa_supplica
|
||||
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
|
||||
enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
|
||||
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||
- int p2p_group);
|
||||
+ int p2p_group, int multi_ap_backhaul_sta);
|
||||
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||
const char *pin, int p2p_group, u16 dev_pw_id);
|
||||
void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);
|
@ -1,339 +0,0 @@
|
||||
From 8b04a4cddbd6dbadb24279713af7ac677e80d342 Mon Sep 17 00:00:00 2001
|
||||
From: Davina Lu <ylu@quantenna.com>
|
||||
Date: Tue, 2 Oct 2018 18:34:14 -0700
|
||||
Subject: [PATCH] hostapd: support Multi-AP backhaul STA onboarding
|
||||
|
||||
The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
|
||||
backhaul STA through WPS. To enable this, the WPS registrar offers a
|
||||
different set of credentials (backhaul credentials instead of fronthaul
|
||||
credentials) when the Multi-AP subelement is present in the WFA vendor
|
||||
extension element of the WSC M1 message.
|
||||
|
||||
Add 3 new configuration options to specify the backhaul credentials for
|
||||
the hostapd internal registrar: multi_ap_backhaul_ssid,
|
||||
multi_ap_backhaul_wpa_psk, multi_ap_backhaul_wpa_passphrase. These are
|
||||
only relevant for a fronthaul SSID, i.e. where multi_ap is set to 2 or
|
||||
3. When these options are set, pass the backhaul credentials instead of
|
||||
the normal credentials when the Multi-AP subelement is present.
|
||||
|
||||
Ignore the Multi-AP subelement if the backhaul config options are not
|
||||
set. Note that for an SSID which is fronthaul and backhaul at the same
|
||||
time (i.e., multi_ap == 3), this results in the correct credentials
|
||||
being sent anyway.
|
||||
|
||||
The security to be used for the backaul BSS is fixed to WPA2PSK. The
|
||||
Multi-AP Specification only allows Open and WPA2PSK networks to be
|
||||
configured. Although not stated explicitly, the backhaul link is
|
||||
intended to be always encrypted, hence WPA2PSK.
|
||||
|
||||
To build the credentials, the credential-building code is essentially
|
||||
copied and simplified. Indeed, the backhaul credentials are always
|
||||
WPA2PSK and never use per-device PSK. All the options set for the
|
||||
fronthaul BSS WPS are simply ignored.
|
||||
|
||||
Signed-off-by: Davina Lu <ylu@quantenna.com>
|
||||
Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
v4: no change
|
||||
---
|
||||
hostapd/config_file.c | 47 ++++++++++++++++++++++++++++++++++++++++
|
||||
hostapd/hostapd.conf | 9 ++++++++
|
||||
src/ap/ap_config.c | 2 ++
|
||||
src/ap/ap_config.h | 1 +
|
||||
src/ap/wps_hostapd.c | 26 ++++++++++++++++++++++
|
||||
src/wps/wps.h | 32 +++++++++++++++++++++++++++
|
||||
src/wps/wps_attr_parse.c | 11 ++++++++++
|
||||
src/wps/wps_attr_parse.h | 1 +
|
||||
src/wps/wps_dev_attr.c | 5 +++++
|
||||
src/wps/wps_dev_attr.h | 1 +
|
||||
src/wps/wps_registrar.c | 25 ++++++++++++++++++++-
|
||||
11 files changed, 159 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3479,6 +3479,53 @@ static int hostapd_config_fill(struct ho
|
||||
line, pos);
|
||||
return 1;
|
||||
}
|
||||
+ } else if (os_strcmp(buf, "multi_ap_backhaul_ssid") == 0) {
|
||||
+ size_t slen;
|
||||
+ char *str = wpa_config_parse_string(pos, &slen);
|
||||
+
|
||||
+ if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
|
||||
+ wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
|
||||
+ line, pos);
|
||||
+ os_free(str);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ os_memcpy(bss->multi_ap_backhaul_ssid.ssid, str, slen);
|
||||
+ bss->multi_ap_backhaul_ssid.ssid_len = slen;
|
||||
+ bss->multi_ap_backhaul_ssid.ssid_set = 1;
|
||||
+ os_free(str);
|
||||
+ } else if (os_strcmp(buf, "multi_ap_backhaul_wpa_passphrase") == 0) {
|
||||
+ int len = os_strlen(pos);
|
||||
+
|
||||
+ if (len < 8 || len > 63) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "Line %d: invalid WPA passphrase length %d (expected 8..63)",
|
||||
+ line, len);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
|
||||
+ bss->multi_ap_backhaul_ssid.wpa_passphrase = os_strdup(pos);
|
||||
+ if (bss->multi_ap_backhaul_ssid.wpa_passphrase) {
|
||||
+ hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
|
||||
+ bss->multi_ap_backhaul_ssid.wpa_passphrase_set = 1;
|
||||
+ }
|
||||
+ } else if (os_strcmp(buf, "multi_ap_backhaul_wpa_psk") == 0) {
|
||||
+ hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
|
||||
+ bss->multi_ap_backhaul_ssid.wpa_psk =
|
||||
+ os_zalloc(sizeof(struct hostapd_wpa_psk));
|
||||
+ if (bss->multi_ap_backhaul_ssid.wpa_psk == NULL)
|
||||
+ return 1;
|
||||
+ if (hexstr2bin(pos, bss->multi_ap_backhaul_ssid.wpa_psk->psk,
|
||||
+ PMK_LEN) ||
|
||||
+ pos[PMK_LEN * 2] != '\0') {
|
||||
+ wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
|
||||
+ line, pos);
|
||||
+ hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ bss->multi_ap_backhaul_ssid.wpa_psk->group = 1;
|
||||
+ os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
|
||||
+ bss->multi_ap_backhaul_ssid.wpa_passphrase = NULL;
|
||||
+ bss->multi_ap_backhaul_ssid.wpa_psk_set = 1;
|
||||
} else if (os_strcmp(buf, "upnp_iface") == 0) {
|
||||
os_free(bss->upnp_iface);
|
||||
bss->upnp_iface = os_strdup(pos);
|
||||
--- a/hostapd/hostapd.conf
|
||||
+++ b/hostapd/hostapd.conf
|
||||
@@ -1852,6 +1852,15 @@ own_ip_addr=127.0.0.1
|
||||
# attribute.
|
||||
#ap_settings=hostapd.ap_settings
|
||||
|
||||
+# Multi-AP backhaul BSS config
|
||||
+# Used in WPS when multi_ap=2 or 3. Defines "backhaul BSS" credentials.
|
||||
+# These are passed in WPS M8 instead of the normal (fronthaul) credentials
|
||||
+# if the enrollee has the Multi-AP subelement set. Backhaul SSID is formatted
|
||||
+# like ssid2. The key is set like wpa_psk or wpa_passphrase.
|
||||
+#multi_ap_backhaul_ssid="backhaul"
|
||||
+#multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
||||
+#multi_ap_backhaul_wpa_passphrase=secret passphrase
|
||||
+
|
||||
# WPS UPnP interface
|
||||
# If set, support for external Registrars is enabled.
|
||||
#upnp_iface=br0
|
||||
--- a/src/ap/ap_config.c
|
||||
+++ b/src/ap/ap_config.c
|
||||
@@ -582,6 +582,8 @@ void hostapd_config_free_bss(struct host
|
||||
os_free(conf->ap_pin);
|
||||
os_free(conf->extra_cred);
|
||||
os_free(conf->ap_settings);
|
||||
+ hostapd_config_clear_wpa_psk(&conf->multi_ap_backhaul_ssid.wpa_psk);
|
||||
+ str_clear_free(conf->multi_ap_backhaul_ssid.wpa_passphrase);
|
||||
os_free(conf->upnp_iface);
|
||||
os_free(conf->friendly_name);
|
||||
os_free(conf->manufacturer_url);
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -456,6 +456,7 @@ struct hostapd_bss_config {
|
||||
int force_per_enrollee_psk;
|
||||
u8 *ap_settings;
|
||||
size_t ap_settings_len;
|
||||
+ struct hostapd_ssid multi_ap_backhaul_ssid;
|
||||
char *upnp_iface;
|
||||
char *friendly_name;
|
||||
char *manufacturer_url;
|
||||
--- a/src/ap/wps_hostapd.c
|
||||
+++ b/src/ap/wps_hostapd.c
|
||||
@@ -962,6 +962,7 @@ static void hostapd_free_wps(struct wps_
|
||||
wpabuf_free(wps->dev.vendor_ext[i]);
|
||||
wps_device_data_free(&wps->dev);
|
||||
os_free(wps->network_key);
|
||||
+ os_free(wps->multi_ap_backhaul_network_key);
|
||||
hostapd_wps_nfc_clear(wps);
|
||||
wpabuf_free(wps->dh_pubkey);
|
||||
wpabuf_free(wps->dh_privkey);
|
||||
@@ -1131,6 +1132,31 @@ int hostapd_init_wps(struct hostapd_data
|
||||
wps->encr_types_wpa = WPS_ENCR_AES | WPS_ENCR_TKIP;
|
||||
}
|
||||
|
||||
+ if (hapd->conf->multi_ap & FRONTHAUL_BSS &&
|
||||
+ hapd->conf->multi_ap_backhaul_ssid.ssid_len) {
|
||||
+ wps->multi_ap_backhaul_ssid_len =
|
||||
+ hapd->conf->multi_ap_backhaul_ssid.ssid_len;
|
||||
+ os_memcpy(wps->multi_ap_backhaul_ssid,
|
||||
+ hapd->conf->multi_ap_backhaul_ssid.ssid,
|
||||
+ wps->multi_ap_backhaul_ssid_len);
|
||||
+ if (conf->multi_ap_backhaul_ssid.wpa_passphrase) {
|
||||
+ wps->multi_ap_backhaul_network_key =
|
||||
+ (u8 *) os_strdup(conf->multi_ap_backhaul_ssid.wpa_passphrase);
|
||||
+ wps->multi_ap_backhaul_network_key_len =
|
||||
+ os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase);
|
||||
+ } else if (conf->multi_ap_backhaul_ssid.wpa_psk) {
|
||||
+ wps->multi_ap_backhaul_network_key =
|
||||
+ os_malloc(2 * PMK_LEN + 1);
|
||||
+ if (wps->multi_ap_backhaul_network_key == NULL)
|
||||
+ goto fail;
|
||||
+ wpa_snprintf_hex((char *) wps->multi_ap_backhaul_network_key,
|
||||
+ 2 * PMK_LEN + 1,
|
||||
+ conf->multi_ap_backhaul_ssid.wpa_psk->psk,
|
||||
+ PMK_LEN);
|
||||
+ wps->multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
wps->ap_settings = conf->ap_settings;
|
||||
wps->ap_settings_len = conf->ap_settings_len;
|
||||
|
||||
--- a/src/wps/wps.h
|
||||
+++ b/src/wps/wps.h
|
||||
@@ -100,6 +100,7 @@ struct wps_device_data {
|
||||
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
||||
|
||||
int p2p;
|
||||
+ u8 multi_ap_ext;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -730,6 +731,37 @@ struct wps_context {
|
||||
int psk_set;
|
||||
|
||||
/**
|
||||
+ * multi_ap_backhaul_ssid - SSID to supply to a Multi-AP backhaul
|
||||
+ * enrollee
|
||||
+ *
|
||||
+ * This SSID is used by the Registrar to fill in information for
|
||||
+ * Credentials when the enrollee advertises it is a Multi-AP backhaul
|
||||
+ * STA.
|
||||
+ */
|
||||
+ u8 multi_ap_backhaul_ssid[SSID_MAX_LEN];
|
||||
+
|
||||
+ /**
|
||||
+ * multi_ap_backhaul_ssid_len - Length of multi_ap_backhaul_ssid in
|
||||
+ * octets
|
||||
+ */
|
||||
+ size_t multi_ap_backhaul_ssid_len;
|
||||
+
|
||||
+ /**
|
||||
+ * multi_ap_backhaul_network_key - The Network Key (PSK) for the
|
||||
+ * Multi-AP backhaul enrollee.
|
||||
+ *
|
||||
+ * This key can be either the ASCII passphrase (8..63 characters) or the
|
||||
+ * 32-octet PSK (64 hex characters).
|
||||
+ */
|
||||
+ u8 *multi_ap_backhaul_network_key;
|
||||
+
|
||||
+ /**
|
||||
+ * multi_ap_backhaul_network_key_len - Length of
|
||||
+ * multi_ap_backhaul_network_key in octets
|
||||
+ */
|
||||
+ size_t multi_ap_backhaul_network_key_len;
|
||||
+
|
||||
+ /**
|
||||
* ap_settings - AP Settings override for M7 (only used at AP)
|
||||
*
|
||||
* If %NULL, AP Settings attributes will be generated based on the
|
||||
--- a/src/wps/wps_attr_parse.c
|
||||
+++ b/src/wps/wps_attr_parse.c
|
||||
@@ -67,6 +67,17 @@ static int wps_set_vendor_ext_wfa_subele
|
||||
}
|
||||
attr->registrar_configuration_methods = pos;
|
||||
break;
|
||||
+ case WFA_ELEM_MULTI_AP:
|
||||
+ if (len != 1) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "WPS: Invalid Multi-AP Extension length %u",
|
||||
+ len);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ attr->multi_ap_ext = *pos;
|
||||
+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP Extension 0x%02x",
|
||||
+ attr->multi_ap_ext);
|
||||
+ break;
|
||||
default:
|
||||
wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
|
||||
"Extension subelement %u", id);
|
||||
--- a/src/wps/wps_attr_parse.h
|
||||
+++ b/src/wps/wps_attr_parse.h
|
||||
@@ -97,6 +97,7 @@ struct wps_parse_attr {
|
||||
const u8 *cred[MAX_CRED_COUNT];
|
||||
const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
|
||||
const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
|
||||
+ u8 multi_ap_ext;
|
||||
};
|
||||
|
||||
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
|
||||
--- a/src/wps/wps_dev_attr.c
|
||||
+++ b/src/wps/wps_dev_attr.c
|
||||
@@ -389,6 +389,11 @@ int wps_process_os_version(struct wps_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext)
|
||||
+{
|
||||
+ dev->multi_ap_ext = ext;
|
||||
+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP extension value %02x", dev->multi_ap_ext);
|
||||
+}
|
||||
|
||||
int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
|
||||
{
|
||||
--- a/src/wps/wps_dev_attr.h
|
||||
+++ b/src/wps/wps_dev_attr.h
|
||||
@@ -29,6 +29,7 @@ int wps_build_dev_name(struct wps_device
|
||||
int wps_process_device_attrs(struct wps_device_data *dev,
|
||||
struct wps_parse_attr *attr);
|
||||
int wps_process_os_version(struct wps_device_data *dev, const u8 *ver);
|
||||
+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
|
||||
int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
|
||||
void wps_device_data_free(struct wps_device_data *dev);
|
||||
int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
|
||||
--- a/src/wps/wps_registrar.c
|
||||
+++ b/src/wps/wps_registrar.c
|
||||
@@ -1588,7 +1588,6 @@ int wps_build_credential_wrap(struct wpa
|
||||
return 0;
|
||||
}
|
||||
|
||||
-
|
||||
int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
|
||||
{
|
||||
struct wpabuf *cred;
|
||||
@@ -1603,6 +1602,29 @@ int wps_build_cred(struct wps_data *wps,
|
||||
}
|
||||
os_memset(&wps->cred, 0, sizeof(wps->cred));
|
||||
|
||||
+ if (wps->peer_dev.multi_ap_ext == MULTI_AP_BACKHAUL_STA &&
|
||||
+ wps->wps->multi_ap_backhaul_ssid_len) {
|
||||
+ wpa_printf(MSG_DEBUG, "WPS: Use backhaul STA credentials");
|
||||
+ os_memcpy(wps->cred.ssid, wps->wps->multi_ap_backhaul_ssid,
|
||||
+ wps->wps->multi_ap_backhaul_ssid_len);
|
||||
+ wps->cred.ssid_len = wps->wps->multi_ap_backhaul_ssid_len;
|
||||
+ /* Backhaul is always WPA2PSK */
|
||||
+ wps->cred.auth_type = WPS_AUTH_WPA2PSK;
|
||||
+ wps->cred.encr_type = WPS_ENCR_AES;
|
||||
+ /* Set MAC address in the Credential to be the Enrollee's MAC
|
||||
+ * address
|
||||
+ */
|
||||
+ os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
|
||||
+ if (wps->wps->multi_ap_backhaul_network_key) {
|
||||
+ os_memcpy(wps->cred.key,
|
||||
+ wps->wps->multi_ap_backhaul_network_key,
|
||||
+ wps->wps->multi_ap_backhaul_network_key_len);
|
||||
+ wps->cred.key_len =
|
||||
+ wps->wps->multi_ap_backhaul_network_key_len;
|
||||
+ }
|
||||
+ goto use_provided;
|
||||
+ }
|
||||
+
|
||||
os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
|
||||
wps->cred.ssid_len = wps->wps->ssid_len;
|
||||
|
||||
@@ -2705,6 +2727,7 @@ static enum wps_process_res wps_process_
|
||||
wps->use_psk_key = 1;
|
||||
}
|
||||
#endif /* WPS_WORKAROUNDS */
|
||||
+ wps_process_vendor_ext_m1(&wps->peer_dev, attr->multi_ap_ext);
|
||||
|
||||
wps->state = SEND_M2;
|
||||
return WPS_CONTINUE;
|
@ -1,181 +0,0 @@
|
||||
From bd733055a22c8ca3bcd7648bf716da2713b3d9f1 Mon Sep 17 00:00:00 2001
|
||||
From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
|
||||
Date: Mon, 21 Jan 2019 16:44:06 +0100
|
||||
Subject: [PATCH] hostapd: add README-MULTI-AP
|
||||
|
||||
Document what hostapd and wpa_supplicant do for Multi-AP.
|
||||
|
||||
This is only included in hostapd, since a Multi-AP device is always an
|
||||
access point so it should have hostapd.
|
||||
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
v4: wps_pbc has multi_ap as a parameter instead of config option.
|
||||
---
|
||||
hostapd/README-MULTI-AP | 160 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 160 insertions(+)
|
||||
create mode 100644 hostapd/README-MULTI-AP
|
||||
|
||||
--- /dev/null
|
||||
+++ b/hostapd/README-MULTI-AP
|
||||
@@ -0,0 +1,160 @@
|
||||
+hostapd, wpa_supplicant and the Multi-AP Specification
|
||||
+======================================================
|
||||
+
|
||||
+This document describes how hostapd and wpa_supplicant can be configured to
|
||||
+support the Multi-AP Specification.
|
||||
+
|
||||
+Introduction to Multi-AP
|
||||
+------------------------
|
||||
+
|
||||
+The Wi-Fi Alliance Multi-AP Specification is the technical specification for
|
||||
+Wi-Fi CERTIFIED EasyMesh(TM) [1], the Wi-Fi Alliance® certification program for
|
||||
+Multi-AP. It defines control protocols between Wi-Fi® access points (APs) to
|
||||
+join them into a network with centralized control and operation. It is targeted
|
||||
+only at routers (repeaters, gateways, ...), not at clients. Clients are not
|
||||
+involved at all in the protocols.
|
||||
+
|
||||
+Most of the Multi-AP specification falls outside of the scope of
|
||||
+hostapd/wpa_supplicant. hostapd/wpa_supplicant is only involved for the items
|
||||
+summarized below. The rest of the protocol must be implemented by a separate
|
||||
+daemon, e.g. prplMesh [2]. That daemon also needs to communicate with hostapd,
|
||||
+e.g. to get a list of associated clients, but this can be done using the normal
|
||||
+hostapd interfaces.
|
||||
+
|
||||
+hostapd/wpa_supplicant needs to be configured specifically to support:
|
||||
+- the WPS onboarding process;
|
||||
+- configuring backhaul links.
|
||||
+
|
||||
+The text below refers to "Multi-AP Specification v1.0" [3].
|
||||
+
|
||||
+
|
||||
+Fronthaul and backhaul links
|
||||
+----------------------------
|
||||
+
|
||||
+In a Multi-AP network, the central controller can configure the SSIDs on the
|
||||
+devices that are joined into the network. These are called fronthaul SSIDs.
|
||||
+From the point of view of hostapd, there is nothing special about these
|
||||
+fronthaul SSIDs.
|
||||
+
|
||||
+In addition to fronthaul SSIDs, the controller can also configure backhaul
|
||||
+links. A backhaul link is a link between two access point devices, giving
|
||||
+internet access to access point devices that don't have a wired link. The
|
||||
+Multi-AP specification doesn't dictate this, but typically the backhaul link
|
||||
+will be bridged into a LAN together with (one of) the fronthaul SSID(s) and the
|
||||
+wired Ethernet ports.
|
||||
+
|
||||
+A backhaul link must be treated specially by hostapd and wpa_supplicant. One
|
||||
+side of the backhaul link is configured through the Multi-AP protocol as the
|
||||
+"backhaul STA", i.e. the client side of the link. A backhaul STA is like any
|
||||
+station and is handled appropriately by wpa_supplicant, but two additional
|
||||
+features are required. It must send an additional information element in each
|
||||
+(Re-)Association Request ([3], section 5.2, paragraph 4). In addition, it must
|
||||
+use 4-address mode for all frames sent over this link ([3], section 14).
|
||||
+Therefore, wpa_supplicant must be configured explicitly as the backhaul STA
|
||||
+role, by setting 'multi_ap_backhaul_sta=1' in the network configuration block
|
||||
+or when configuring the SSID through the client socket. When
|
||||
+'multi_ap_backhaul_sta=1', wpa_supplicant includes the Multi-AP IE in
|
||||
+(Re-)Association Request messages and verifies that it is included in the
|
||||
+(Re-)Association Response. If it is not, association fails. If it is,
|
||||
+wpa_supplicant sets 4-address mode for this interface through a driver
|
||||
+callback.
|
||||
+
|
||||
+The AP side of the backhaul link is called a "backhaul SSID". Such an SSID must
|
||||
+be handled specially by hostapd, because it must add an additional information
|
||||
+element in each (Re-)Association Response, but only to stations that have
|
||||
+identified themselves as backhaul stations ([3], section 5.2, paragraph 5-6).
|
||||
+This is important because it is possible to use the same BSS and SSID for
|
||||
+fronthaul and backhaul at the same time. The additional information element must
|
||||
+only be used for frames sent to a backhaul STA, not to a normal STA. Also,
|
||||
+frames sent to a backhaul STA must use 4-address mode, while frames sent to a
|
||||
+normal STA (fronthaul, when it's a fronthaul and backhaul SSID) must use
|
||||
+3-address mode.
|
||||
+
|
||||
+An SSID is configured in Multi-AP mode in hostapd by setting the 'multi_ap'
|
||||
+configuration option to 1 (backhaul SSID), 2 (fronthaul SSID) or 3
|
||||
+(simultaneous backhaul and fronthaul SSID). If this option is set, hostapd
|
||||
+parses the Multi-AP information element in the Association Request. If the
|
||||
+station is a backhaul STA and the SSID is configured as a backhaul SSID,
|
||||
+hostapd sets up 4-address mode. Since there may be multiple stations connected
|
||||
+simultaneously, and each of them has a different RA (receiver address), a VLAN
|
||||
+is created for each backhaul STA and it is automatically added to a bridge.
|
||||
+This is the same behavior as for WDS, and the relevant option ('bridge' or
|
||||
+'wds_bridge') applies here as well.
|
||||
+
|
||||
+If 'multi_ap' is 1 (backhaul SSID only), any station that tries to associate
|
||||
+without the Multi-AP information element will be denied.
|
||||
+
|
||||
+If 'multi_ap' is 2 (fronthaul SSID only), any station that tries to associate
|
||||
+with the Multi-AP information element will be denied. That is also the only
|
||||
+difference with 'multi_ap' set to 0: in the latter case, the Multi-AP
|
||||
+information element is simply ignored.
|
||||
+
|
||||
+In summary, this is the end-to-end behaviour for a backhaul BSS (i.e.,
|
||||
+multi_ap_backhaul_sta=1 in wpa_supplicant on STA, and multi_ap=1 or 3 in
|
||||
+hostapd on AP). Note that point 1 means that hostapd must not be configured
|
||||
+with WPS support on the backhaul BSS (multi_ap=1). hostapd does not check for
|
||||
+that.
|
||||
+
|
||||
+1. Backhaul BSS beacons do not advertise WPS support (other than that, nothing
|
||||
+ multi-ap specific).
|
||||
+2. STA sends authentication req (nothing multi-ap specific).
|
||||
+3. AP sends authentication resp (nothing multi-ap specific).
|
||||
+4. STA sends association req with Multi-AP IE.
|
||||
+5. AP send association resp with Multi-AP IE.
|
||||
+6. STA and AP both use 4-address mode for data.
|
||||
+
|
||||
+
|
||||
+WPS support
|
||||
+-----------
|
||||
+
|
||||
+WPS requires more special handling. WPS must only be advertised on fronthaul
|
||||
+SSIDs, not on backhaul SSIDs, so WPS should not be enabled on a backhaul-only
|
||||
+SSID in hostapd.conf. The WPS configuration purely works on the fronthaul SSID.
|
||||
+When a WPS M1 message has an additional subelement that indicates a request for
|
||||
+a multi-AP backhaul link, hostapd must not respond with the normal fronthaul
|
||||
+SSID credentials; instead, it should respond with the (potentially different)
|
||||
+backhaul SSID credentials.
|
||||
+
|
||||
+To support this, hostapd has the 'multi_ap_backhaul_ssid',
|
||||
+'multi_ap_backhaul_wpa_psk' and 'multi_ap_backhaul_wpa_passphrase' options.
|
||||
+When these are set on an SSID with WPS, they are used instead of the normal
|
||||
+credentials when hostapd receives a WPS M1 message with the Multi-AP IE. Only
|
||||
+WPA2 Personal is supported in the Multi-AP specification, so there is no need
|
||||
+to specify authentication or encryption options. For the backhaul credentials,
|
||||
+per-device PSK is not supported.
|
||||
+
|
||||
+If the SSID is a simultaneous backhaul and fronthaul SSID, there is no need to
|
||||
+specify the backhaul credentials, since the backhaul and fronthaul credentials
|
||||
+are identical.
|
||||
+
|
||||
+To enable the Multi-AP backhaul STA feature when it performs WPS, a new
|
||||
+parameter has been introduced to the WPS_PBC control interface call.
|
||||
+When this option is set, it adds the multi-AP backhaul subelement to
|
||||
+the association and M1 messages. It then configures the new SSID with
|
||||
+'multi_ap_backhaul_sta=1'. Note that this means that if the AP does not
|
||||
+follow the Multi-AP specification, wpa_supplicant will fail to
|
||||
+associate.
|
||||
+
|
||||
+In summary, this is the end-to-end behaviour for WPS of a backhaul link (i.e.,
|
||||
+multi_ap=1 option is given in the wps_pbc call on the STA side, and multi_ap=2
|
||||
+and multi_ap_backhaul_ssid and either multi_ap_backhaul_wpa_psk or
|
||||
+multi_ap_backhaul_wpa_passphrase are set to the credentials of a backhaul SSID
|
||||
+in hostapd on registrar AP).
|
||||
+
|
||||
+1. Fronthaul BSS beacons advertise WPS support (nothing multi-ap specific).
|
||||
+2. Enrollee sends authentication req (nothing multi-ap specific).
|
||||
+3. AP sends authentication resp (nothing multi-ap specific).
|
||||
+4. Enrollee sends association req with Multi-AP IE.
|
||||
+5. AP send association resp with Multi-AP IE.
|
||||
+6. Enrollee sends M1 with additional Multi-AP subelement
|
||||
+7. AP sends M8 with backhaul instead of fronthaul credentials.
|
||||
+8. Enrollee sends Deauth.
|
||||
+
|
||||
+
|
||||
+References
|
||||
+----------
|
||||
+
|
||||
+[1] https://www.wi-fi.org/discover-wi-fi/wi-fi-easymesh
|
||||
+[2] https://github.com/prplfoundation/prplMesh
|
||||
+[3] https://www.wi-fi.org/file/multi-ap-specification-v10
|
||||
+ (requires registration)
|
@ -1,182 +0,0 @@
|
||||
From 0729e01f5830ebf4701f0b1b7ff1bd2a2eedae40 Mon Sep 17 00:00:00 2001
|
||||
From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
|
||||
Date: Tue, 12 Feb 2019 11:02:42 +0100
|
||||
Subject: [PATCH] tests: add WPS tests to multi_ap hwsim tests
|
||||
|
||||
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
|
||||
---
|
||||
v4: new patch
|
||||
---
|
||||
tests/hwsim/test_multi_ap.py | 164 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 164 insertions(+)
|
||||
|
||||
--- a/tests/hwsim/test_multi_ap.py
|
||||
+++ b/tests/hwsim/test_multi_ap.py
|
||||
@@ -61,3 +61,167 @@ def test_multi_ap_fronthaul_on_ap(dev, a
|
||||
raise Exception("Connection result not reported")
|
||||
if "CTRL-EVENT-DISCONNECTED" not in ev:
|
||||
raise Exception("Unexpected connection result")
|
||||
+
|
||||
+def run_multi_ap_wps(dev, apdev, params, multi_ap_bssid = None):
|
||||
+ """Helper for running Multi-AP WPS tests
|
||||
+
|
||||
+ dev[0] does multi_ap WPS, dev[1] does normal WPS. apdev[0] is the fronthaul
|
||||
+ BSS. If there is a separate backhaul BSS, it must have been set up by the
|
||||
+ caller. params are the normal SSID parameters, they will be extended with
|
||||
+ the WPS parameters. multi_ap_bssid must be given if it is not equal to the
|
||||
+ fronthaul BSSID."""
|
||||
+
|
||||
+ if multi_ap_bssid is None:
|
||||
+ multi_ap_bssid = apdev[0]['bssid']
|
||||
+ params.update({"wps_state": "2", "eap_server": "1"})
|
||||
+
|
||||
+ # WPS with multi-ap station dev[0]
|
||||
+ hapd = hostapd.add_ap(apdev[0], params)
|
||||
+ hapd.request("WPS_PBC")
|
||||
+ if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
|
||||
+ raise Exception("PBC status not shown correctly")
|
||||
+
|
||||
+ dev[0].request("WPS_PBC multi_ap=1")
|
||||
+ dev[0].wait_connected(timeout=20)
|
||||
+ status = dev[0].get_status()
|
||||
+ if status['wpa_state'] != 'COMPLETED' or status['bssid'] != multi_ap_bssid:
|
||||
+ raise Exception("Not fully connected")
|
||||
+ if status['ssid'] != params['multi_ap_backhaul_ssid'].strip('"'):
|
||||
+ raise Exception("Unexpected SSID %s != %s" % (status['ssid'], params["multi_ap_backhaul_ssid"]))
|
||||
+ if status['pairwise_cipher'] != 'CCMP':
|
||||
+ raise Exception("Unexpected encryption configuration %s" % status['pairwise_cipher'])
|
||||
+ if status['key_mgmt'] != 'WPA2-PSK':
|
||||
+ raise Exception("Unexpected key_mgmt")
|
||||
+
|
||||
+ status = hapd.request("WPS_GET_STATUS")
|
||||
+ if "PBC Status: Disabled" not in status:
|
||||
+ raise Exception("PBC status not shown correctly")
|
||||
+ if "Last WPS result: Success" not in status:
|
||||
+ raise Exception("Last WPS result not shown correctly")
|
||||
+ if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
|
||||
+ raise Exception("Peer address not shown correctly")
|
||||
+
|
||||
+ if len(dev[0].list_networks()) != 1:
|
||||
+ raise Exception("Unexpected number of network blocks")
|
||||
+
|
||||
+ # WPS with non-multi-ap station dev[1]
|
||||
+ hapd.request("WPS_PBC")
|
||||
+ if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
|
||||
+ raise Exception("PBC status not shown correctly")
|
||||
+
|
||||
+ dev[1].request("WPS_PBC")
|
||||
+ dev[1].wait_connected(timeout=20)
|
||||
+ status = dev[1].get_status()
|
||||
+ if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
|
||||
+ raise Exception("Not fully connected")
|
||||
+ if status['ssid'] != params["ssid"]:
|
||||
+ raise Exception("Unexpected SSID")
|
||||
+ # Fronthaul may be something else than WPA2-PSK so don't test it.
|
||||
+
|
||||
+ status = hapd.request("WPS_GET_STATUS")
|
||||
+ if "PBC Status: Disabled" not in status:
|
||||
+ raise Exception("PBC status not shown correctly")
|
||||
+ if "Last WPS result: Success" not in status:
|
||||
+ raise Exception("Last WPS result not shown correctly")
|
||||
+ if "Peer Address: " + dev[1].p2p_interface_addr() not in status:
|
||||
+ raise Exception("Peer address not shown correctly")
|
||||
+
|
||||
+ if len(dev[1].list_networks()) != 1:
|
||||
+ raise Exception("Unexpected number of network blocks")
|
||||
+
|
||||
+
|
||||
+def test_multi_ap_wps_shared(dev, apdev):
|
||||
+ """WPS on shared fronthaul/backhaul AP"""
|
||||
+ ssid = "multi-ap-wps"
|
||||
+ passphrase = "12345678"
|
||||
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
|
||||
+ params.update({"multi_ap": "3",
|
||||
+ "multi_ap_backhaul_ssid": '"%s"' % ssid,
|
||||
+ "multi_ap_backhaul_wpa_passphrase": passphrase})
|
||||
+ run_multi_ap_wps(dev, apdev, params)
|
||||
+
|
||||
+def test_multi_ap_wps_shared_psk(dev, apdev):
|
||||
+ """WPS on shared fronthaul/backhaul AP using PSK"""
|
||||
+ ssid = "multi-ap-wps"
|
||||
+ psk = "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
+ params = hostapd.wpa2_params(ssid=ssid)
|
||||
+ params.update({"wpa_psk": psk, "multi_ap": "3",
|
||||
+ "multi_ap_backhaul_ssid": '"%s"' % ssid,
|
||||
+ "multi_ap_backhaul_wpa_psk": psk})
|
||||
+ run_multi_ap_wps(dev, apdev, params)
|
||||
+
|
||||
+def test_multi_ap_wps_split(dev, apdev):
|
||||
+ """WPS on split fronthaul and backhaul AP"""
|
||||
+ backhaul_ssid = "multi-ap-backhaul-wps"
|
||||
+ backhaul_passphrase = "87654321"
|
||||
+ params = hostapd.wpa2_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
|
||||
+ params.update({"multi_ap": "2",
|
||||
+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
|
||||
+ "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase})
|
||||
+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
|
||||
+ params_backhaul.update({"multi_ap": "1"})
|
||||
+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
|
||||
+
|
||||
+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
|
||||
+
|
||||
+def test_multi_ap_wps_split_psk(dev, apdev):
|
||||
+ """WPS on split fronthaul and backhaul AP"""
|
||||
+ backhaul_ssid = "multi-ap-backhaul-wps"
|
||||
+ backhaul_psk = "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
+ params = hostapd.wpa2_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
|
||||
+ params.update({"multi_ap": "2",
|
||||
+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
|
||||
+ "multi_ap_backhaul_wpa_psk": backhaul_psk})
|
||||
+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid)
|
||||
+ params_backhaul.update({"multi_ap": "1", "wpa_psk": backhaul_psk})
|
||||
+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
|
||||
+
|
||||
+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
|
||||
+
|
||||
+def test_multi_ap_wps_split_mixed(dev, apdev):
|
||||
+ """WPS on split fronthaul and backhaul AP with mixed-mode fronthaul"""
|
||||
+ backhaul_ssid = "multi-ap-backhaul-wps"
|
||||
+ backhaul_passphrase = "87654321"
|
||||
+ params = hostapd.wpa_mixed_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
|
||||
+ params.update({"multi_ap": "2",
|
||||
+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
|
||||
+ "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase})
|
||||
+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
|
||||
+ params_backhaul.update({"multi_ap": "1"})
|
||||
+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
|
||||
+
|
||||
+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
|
||||
+
|
||||
+def test_multi_ap_wps_split_open(dev, apdev):
|
||||
+ """WPS on split fronthaul and backhaul AP with open fronthaul"""
|
||||
+ backhaul_ssid = "multi-ap-backhaul-wps"
|
||||
+ backhaul_passphrase = "87654321"
|
||||
+ params = {"ssid": "multi-ap-wps-fronthaul", "multi_ap": "2",
|
||||
+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
|
||||
+ "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase}
|
||||
+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
|
||||
+ params_backhaul.update({"multi_ap": "1"})
|
||||
+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
|
||||
+
|
||||
+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
|
||||
+
|
||||
+def test_multi_ap_wps_fail_non_multi_ap(dev, apdev):
|
||||
+ """Multi-AP WPS on non-WPS AP fails"""
|
||||
+
|
||||
+ params = hostapd.wpa2_params(ssid="non-multi-ap-wps", passphrase="12345678")
|
||||
+ params.update({"wps_state": "2", "eap_server": "1"})
|
||||
+
|
||||
+ hapd = hostapd.add_ap(apdev[0], params)
|
||||
+ hapd.request("WPS_PBC")
|
||||
+ if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
|
||||
+ raise Exception("PBC status not shown correctly")
|
||||
+
|
||||
+ dev[0].request("WPS_PBC multi_ap=1")
|
||||
+ # Since we will fail to associate and WPS doesn't even get started, there
|
||||
+ # isn't much we can do except wait for timeout. For PBC, it is not possible
|
||||
+ # to change the timeout from 2 minutes. Instead of waiting for the timeout,
|
||||
+ # just check that WPS doesn't finish within reasonable time.
|
||||
+ ev = dev[0].wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=20)
|
||||
+ if ev:
|
||||
+ raise Exception("WPS operation completed: " + ev)
|
||||
+ dev[0].request("WPS_CANCEL")
|
@ -22,7 +22,7 @@
|
||||
|
||||
#define OCE_STA_CFON_ENABLED(hapd) \
|
||||
((hapd->conf->oce & OCE_STA_CFON) && \
|
||||
@@ -136,6 +137,7 @@ struct hostapd_data {
|
||||
@@ -141,6 +142,7 @@ struct hostapd_data {
|
||||
struct hostapd_iface *iface;
|
||||
struct hostapd_config *iconf;
|
||||
struct hostapd_bss_config *conf;
|
||||
@ -30,25 +30,17 @@
|
||||
int interface_added; /* virtual interface added for this BSS */
|
||||
unsigned int started:1;
|
||||
unsigned int disabled:1;
|
||||
@@ -547,6 +549,7 @@ hostapd_alloc_bss_data(struct hostapd_if
|
||||
struct hostapd_bss_config *bss);
|
||||
int hostapd_setup_interface(struct hostapd_iface *iface);
|
||||
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
|
||||
+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
|
||||
void hostapd_interface_deinit(struct hostapd_iface *iface);
|
||||
void hostapd_interface_free(struct hostapd_iface *iface);
|
||||
struct hostapd_iface * hostapd_alloc_iface(void);
|
||||
--- a/src/ap/hostapd.c
|
||||
+++ b/src/ap/hostapd.c
|
||||
@@ -373,6 +373,7 @@ static void hostapd_free_hapd_data(struc
|
||||
hapd->started = 0;
|
||||
@@ -374,6 +374,7 @@ static void hostapd_free_hapd_data(struc
|
||||
hapd->beacon_set_done = 0;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
|
||||
+ hostapd_ubus_free_bss(hapd);
|
||||
iapp_deinit(hapd->iapp);
|
||||
hapd->iapp = NULL;
|
||||
accounting_deinit(hapd);
|
||||
@@ -1295,6 +1296,8 @@ static int hostapd_setup_bss(struct host
|
||||
@@ -1314,6 +1315,8 @@ static int hostapd_setup_bss(struct host
|
||||
if (hapd->driver && hapd->driver->set_operstate)
|
||||
hapd->driver->set_operstate(hapd->drv_priv, 1);
|
||||
|
||||
@ -57,16 +49,7 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1709,7 +1712,7 @@ static enum nr_chan_width hostapd_get_nr
|
||||
#endif /* NEED_AP_MLME */
|
||||
|
||||
|
||||
-static void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
|
||||
+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
|
||||
{
|
||||
#ifdef NEED_AP_MLME
|
||||
u16 capab = hostapd_own_capab_info(hapd);
|
||||
@@ -1930,6 +1933,7 @@ static int hostapd_setup_interface_compl
|
||||
@@ -1828,6 +1831,7 @@ static int hostapd_setup_interface_compl
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
@ -74,7 +57,7 @@
|
||||
wpa_printf(MSG_DEBUG, "Completing interface initialization");
|
||||
if (iface->conf->channel) {
|
||||
#ifdef NEED_AP_MLME
|
||||
@@ -2110,6 +2114,7 @@ dfs_offload:
|
||||
@@ -2020,6 +2024,7 @@ dfs_offload:
|
||||
|
||||
fail:
|
||||
wpa_printf(MSG_ERROR, "Interface initialization failed");
|
||||
@ -82,7 +65,7 @@
|
||||
hostapd_set_state(iface, HAPD_IFACE_DISABLED);
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
|
||||
#ifdef CONFIG_FST
|
||||
@@ -2576,6 +2581,7 @@ void hostapd_interface_deinit_free(struc
|
||||
@@ -2489,6 +2494,7 @@ void hostapd_interface_deinit_free(struc
|
||||
(unsigned int) iface->conf->num_bss);
|
||||
driver = iface->bss[0]->driver;
|
||||
drv_priv = iface->bss[0]->drv_priv;
|
||||
@ -92,14 +75,7 @@
|
||||
__func__, driver, drv_priv);
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -1759,12 +1759,13 @@ ieee802_11_set_radius_info(struct hostap
|
||||
|
||||
|
||||
static void handle_auth(struct hostapd_data *hapd,
|
||||
- const struct ieee80211_mgmt *mgmt, size_t len)
|
||||
+ const struct ieee80211_mgmt *mgmt, size_t len,
|
||||
+ struct hostapd_frame_info *fi)
|
||||
{
|
||||
@@ -2029,7 +2029,7 @@ static void handle_auth(struct hostapd_d
|
||||
u16 auth_alg, auth_transaction, status_code;
|
||||
u16 resp = WLAN_STATUS_SUCCESS;
|
||||
struct sta_info *sta = NULL;
|
||||
@ -108,19 +84,19 @@
|
||||
u16 fc;
|
||||
const u8 *challenge = NULL;
|
||||
u32 session_timeout, acct_interim_interval;
|
||||
@@ -1775,6 +1776,11 @@ static void handle_auth(struct hostapd_d
|
||||
@@ -2040,6 +2040,11 @@ static void handle_auth(struct hostapd_d
|
||||
char *identity = NULL;
|
||||
char *radius_cui = NULL;
|
||||
u16 seq_ctrl;
|
||||
+ struct hostapd_ubus_request req = {
|
||||
+ .type = HOSTAPD_UBUS_AUTH_REQ,
|
||||
+ .mgmt_frame = mgmt,
|
||||
+ .frame_info = fi,
|
||||
+ .ssi_signal = rssi,
|
||||
+ };
|
||||
|
||||
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
|
||||
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
|
||||
@@ -1935,6 +1941,13 @@ static void handle_auth(struct hostapd_d
|
||||
@@ -2201,6 +2206,13 @@ static void handle_auth(struct hostapd_d
|
||||
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
@ -134,13 +110,7 @@
|
||||
if (res == HOSTAPD_ACL_PENDING)
|
||||
return;
|
||||
|
||||
@@ -3287,12 +3300,12 @@ void fils_hlp_timeout(void *eloop_ctx, v
|
||||
|
||||
static void handle_assoc(struct hostapd_data *hapd,
|
||||
const struct ieee80211_mgmt *mgmt, size_t len,
|
||||
- int reassoc)
|
||||
+ int reassoc, struct hostapd_frame_info *fi)
|
||||
{
|
||||
@@ -3699,7 +3711,7 @@ static void handle_assoc(struct hostapd_
|
||||
u16 capab_info, listen_interval, seq_ctrl, fc;
|
||||
u16 resp = WLAN_STATUS_SUCCESS, reply_res;
|
||||
const u8 *pos;
|
||||
@ -149,19 +119,19 @@
|
||||
struct sta_info *sta;
|
||||
u8 *tmp = NULL;
|
||||
struct hostapd_sta_wpa_psk_short *psk = NULL;
|
||||
@@ -3301,6 +3314,11 @@ static void handle_assoc(struct hostapd_
|
||||
@@ -3708,6 +3720,11 @@ static void handle_assoc(struct hostapd_
|
||||
#ifdef CONFIG_FILS
|
||||
int delay_assoc = 0;
|
||||
#endif /* CONFIG_FILS */
|
||||
+ struct hostapd_ubus_request req = {
|
||||
+ .type = HOSTAPD_UBUS_ASSOC_REQ,
|
||||
+ .mgmt_frame = mgmt,
|
||||
+ .frame_info = fi,
|
||||
+ .ssi_signal = rssi,
|
||||
+ };
|
||||
|
||||
if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
|
||||
sizeof(mgmt->u.assoc_req))) {
|
||||
@@ -3472,6 +3490,14 @@ static void handle_assoc(struct hostapd_
|
||||
@@ -3887,6 +3904,14 @@ static void handle_assoc(struct hostapd_
|
||||
}
|
||||
#endif /* CONFIG_MBO */
|
||||
|
||||
@ -176,7 +146,7 @@
|
||||
/*
|
||||
* sta->capability is used in check_assoc_ies() for RRM enabled
|
||||
* capability element.
|
||||
@@ -3685,6 +3711,7 @@ static void handle_disassoc(struct hosta
|
||||
@@ -4114,6 +4139,7 @@ static void handle_disassoc(struct hosta
|
||||
wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
|
||||
MAC2STR(mgmt->sa),
|
||||
le_to_host16(mgmt->u.disassoc.reason_code));
|
||||
@ -184,7 +154,7 @@
|
||||
|
||||
sta = ap_get_sta(hapd, mgmt->sa);
|
||||
if (sta == NULL) {
|
||||
@@ -3750,6 +3777,8 @@ static void handle_deauth(struct hostapd
|
||||
@@ -4179,6 +4205,8 @@ static void handle_deauth(struct hostapd
|
||||
" reason_code=%d",
|
||||
MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
|
||||
|
||||
@ -193,69 +163,22 @@
|
||||
sta = ap_get_sta(hapd, mgmt->sa);
|
||||
if (sta == NULL) {
|
||||
wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
|
||||
@@ -4089,7 +4118,7 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||
|
||||
|
||||
if (stype == WLAN_FC_STYPE_PROBE_REQ) {
|
||||
- handle_probe_req(hapd, mgmt, len, ssi_signal);
|
||||
+ handle_probe_req(hapd, mgmt, len, fi);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -4109,17 +4138,17 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||
switch (stype) {
|
||||
case WLAN_FC_STYPE_AUTH:
|
||||
wpa_printf(MSG_DEBUG, "mgmt::auth");
|
||||
- handle_auth(hapd, mgmt, len);
|
||||
+ handle_auth(hapd, mgmt, len, fi);
|
||||
ret = 1;
|
||||
break;
|
||||
case WLAN_FC_STYPE_ASSOC_REQ:
|
||||
wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
|
||||
- handle_assoc(hapd, mgmt, len, 0);
|
||||
+ handle_assoc(hapd, mgmt, len, 0, fi);
|
||||
ret = 1;
|
||||
break;
|
||||
case WLAN_FC_STYPE_REASSOC_REQ:
|
||||
wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
|
||||
- handle_assoc(hapd, mgmt, len, 1);
|
||||
+ handle_assoc(hapd, mgmt, len, 1, fi);
|
||||
ret = 1;
|
||||
break;
|
||||
case WLAN_FC_STYPE_DISASSOC:
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -725,7 +725,7 @@ void sta_track_claim_taxonomy_info(struc
|
||||
|
||||
void handle_probe_req(struct hostapd_data *hapd,
|
||||
const struct ieee80211_mgmt *mgmt, size_t len,
|
||||
- int ssi_signal)
|
||||
+ struct hostapd_frame_info *fi)
|
||||
{
|
||||
u8 *resp;
|
||||
struct ieee802_11_elems elems;
|
||||
@@ -734,6 +734,7 @@ void handle_probe_req(struct hostapd_dat
|
||||
size_t i, resp_len;
|
||||
int noack;
|
||||
enum ssid_match_result res;
|
||||
+ int ssi_signal = fi->ssi_signal;
|
||||
int ret;
|
||||
u16 csa_offs[2];
|
||||
size_t csa_offs_len;
|
||||
@@ -742,6 +743,12 @@ void handle_probe_req(struct hostapd_dat
|
||||
@@ -744,6 +744,12 @@ void handle_probe_req(struct hostapd_dat
|
||||
struct hostapd_sta_wpa_psk_short *psk = NULL;
|
||||
char *identity = NULL;
|
||||
char *radius_cui = NULL;
|
||||
+ struct hostapd_ubus_request req = {
|
||||
+ .type = HOSTAPD_UBUS_PROBE_REQ,
|
||||
+ .mgmt_frame = mgmt,
|
||||
+ .frame_info = fi,
|
||||
+ .ssi_signal = ssi_signal,
|
||||
+ .elems = &elems,
|
||||
+ };
|
||||
|
||||
if (len < IEEE80211_HDRLEN)
|
||||
return;
|
||||
@@ -919,6 +926,12 @@ void handle_probe_req(struct hostapd_dat
|
||||
@@ -921,6 +927,12 @@ void handle_probe_req(struct hostapd_dat
|
||||
}
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
@ -268,20 +191,9 @@
|
||||
/* TODO: verify that supp_rates contains at least one matching rate
|
||||
* with AP configuration */
|
||||
|
||||
--- a/src/ap/beacon.h
|
||||
+++ b/src/ap/beacon.h
|
||||
@@ -14,7 +14,7 @@ struct ieee80211_mgmt;
|
||||
|
||||
void handle_probe_req(struct hostapd_data *hapd,
|
||||
const struct ieee80211_mgmt *mgmt, size_t len,
|
||||
- int ssi_signal);
|
||||
+ struct hostapd_frame_info *fi);
|
||||
int ieee802_11_set_beacon(struct hostapd_data *hapd);
|
||||
int ieee802_11_set_beacons(struct hostapd_iface *iface);
|
||||
int ieee802_11_update_beacons(struct hostapd_iface *iface);
|
||||
--- a/src/ap/drv_callbacks.c
|
||||
+++ b/src/ap/drv_callbacks.c
|
||||
@@ -116,6 +116,10 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
@@ -118,6 +118,10 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
u16 reason = WLAN_REASON_UNSPECIFIED;
|
||||
u16 status = WLAN_STATUS_SUCCESS;
|
||||
const u8 *p2p_dev_addr = NULL;
|
||||
@ -292,7 +204,7 @@
|
||||
|
||||
if (addr == NULL) {
|
||||
/*
|
||||
@@ -208,6 +212,12 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
@@ -210,6 +214,12 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -307,7 +219,7 @@
|
||||
wpabuf_free(sta->p2p_ie);
|
||||
--- a/src/ap/sta_info.c
|
||||
+++ b/src/ap/sta_info.c
|
||||
@@ -416,6 +416,7 @@ void ap_handle_timer(void *eloop_ctx, vo
|
||||
@@ -423,6 +423,7 @@ void ap_handle_timer(void *eloop_ctx, vo
|
||||
HOSTAPD_LEVEL_INFO, "deauthenticated due to "
|
||||
"local deauth request");
|
||||
ap_free_sta(hapd, sta);
|
||||
@ -315,7 +227,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -563,6 +564,7 @@ skip_poll:
|
||||
@@ -577,6 +578,7 @@ skip_poll:
|
||||
hapd, sta,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
ap_free_sta(hapd, sta);
|
||||
@ -323,8 +235,8 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1224,6 +1226,7 @@ void ap_sta_set_authorized(struct hostap
|
||||
buf, ip_addr);
|
||||
@@ -1273,6 +1275,7 @@ void ap_sta_set_authorized(struct hostap
|
||||
buf, ip_addr, keyid_buf);
|
||||
} else {
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
|
||||
+ hostapd_ubus_notify(hapd, "disassoc", sta->addr);
|
||||
@ -333,7 +245,7 @@
|
||||
hapd->msg_ctx_parent != hapd->msg_ctx)
|
||||
--- a/src/ap/wpa_auth_glue.c
|
||||
+++ b/src/ap/wpa_auth_glue.c
|
||||
@@ -177,6 +177,7 @@ static void hostapd_wpa_auth_psk_failure
|
||||
@@ -181,6 +181,7 @@ static void hostapd_wpa_auth_psk_failure
|
||||
struct hostapd_data *hapd = ctx;
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
|
||||
MAC2STR(addr));
|
||||
@ -343,7 +255,7 @@
|
||||
|
||||
--- a/wpa_supplicant/Makefile
|
||||
+++ b/wpa_supplicant/Makefile
|
||||
@@ -189,6 +189,12 @@ ifdef CONFIG_EAPOL_TEST
|
||||
@@ -188,6 +188,12 @@ ifdef CONFIG_EAPOL_TEST
|
||||
CFLAGS += -Werror -DEAPOL_TEST
|
||||
endif
|
||||
|
||||
@ -356,7 +268,7 @@
|
||||
ifdef CONFIG_CODE_COVERAGE
|
||||
CFLAGS += -O0 -fprofile-arcs -ftest-coverage
|
||||
LIBS += -lgcov
|
||||
@@ -915,6 +921,9 @@ endif
|
||||
@@ -923,6 +929,9 @@ endif
|
||||
ifdef CONFIG_IEEE80211AX
|
||||
OBJS += ../src/ap/ieee802_11_he.o
|
||||
endif
|
||||
@ -368,7 +280,7 @@
|
||||
CFLAGS += -DCONFIG_WNM_AP
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -6080,6 +6080,8 @@ struct wpa_supplicant * wpa_supplicant_a
|
||||
@@ -6288,6 +6288,8 @@ struct wpa_supplicant * wpa_supplicant_a
|
||||
}
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
@ -377,7 +289,7 @@
|
||||
return wpa_s;
|
||||
}
|
||||
|
||||
@@ -6106,6 +6108,8 @@ int wpa_supplicant_remove_iface(struct w
|
||||
@@ -6314,6 +6316,8 @@ int wpa_supplicant_remove_iface(struct w
|
||||
struct wpa_supplicant *parent = wpa_s->parent;
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
@ -396,7 +308,7 @@
|
||||
|
||||
extern const char *const wpa_supplicant_version;
|
||||
extern const char *const wpa_supplicant_license;
|
||||
@@ -500,6 +501,7 @@ struct wpa_supplicant {
|
||||
@@ -506,6 +507,7 @@ struct wpa_supplicant {
|
||||
unsigned char own_addr[ETH_ALEN];
|
||||
unsigned char perm_addr[ETH_ALEN];
|
||||
char ifname[100];
|
||||
|
@ -546,7 +546,7 @@ __hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag)
|
||||
|
||||
bss->radio_measurements[0] |=
|
||||
WLAN_RRM_CAPS_NEIGHBOR_REPORT;
|
||||
hostapd_set_own_neighbor_report(hapd);
|
||||
hostapd_neighbor_set_own_report(hapd);
|
||||
return true;
|
||||
case BSS_MGMT_EN_BEACON:
|
||||
flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
|
||||
@ -1065,8 +1065,8 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req
|
||||
blobmsg_add_macaddr(&b, "address", addr);
|
||||
if (req->mgmt_frame)
|
||||
blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da);
|
||||
if (req->frame_info)
|
||||
blobmsg_add_u32(&b, "signal", req->frame_info->ssi_signal);
|
||||
if (req->ssi_signal)
|
||||
blobmsg_add_u32(&b, "signal", req->ssi_signal);
|
||||
blobmsg_add_u32(&b, "freq", hapd->iface->freq);
|
||||
|
||||
if (req->elems) {
|
||||
|
@ -19,7 +19,7 @@ struct hostapd_ubus_request {
|
||||
enum hostapd_ubus_event_type type;
|
||||
const struct ieee80211_mgmt *mgmt_frame;
|
||||
const struct ieee802_11_elems *elems;
|
||||
const struct hostapd_frame_info *frame_info;
|
||||
int ssi_signal; /* dBm */
|
||||
const u8 *addr;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user