aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/dbus.doxygen2
-rw-r--r--hostapd/Android.mk5
-rw-r--r--hostapd/Makefile5
-rw-r--r--hostapd/android.config8
-rw-r--r--hostapd/config_file.c50
-rw-r--r--hostapd/ctrl_iface.c169
-rw-r--r--hostapd/defconfig8
-rw-r--r--hostapd/hostapd.conf39
-rw-r--r--hs20/client/osu_client.c12
-rwxr-xr-xhs20/server/ca/ocsp-responder.sh2
-rwxr-xr-xhs20/server/ca/ocsp-update-cache.sh1
-rw-r--r--src/ap/acs.c278
-rw-r--r--src/ap/ap_config.c25
-rw-r--r--src/ap/ap_config.h18
-rw-r--r--src/ap/ap_drv_ops.c5
-rw-r--r--src/ap/beacon.c15
-rw-r--r--src/ap/dfs.c260
-rw-r--r--src/ap/dfs.h3
-rw-r--r--src/ap/dpp_hostapd.c88
-rw-r--r--src/ap/drv_callbacks.c119
-rw-r--r--src/ap/hostapd.c22
-rw-r--r--src/ap/hw_features.c64
-rw-r--r--src/ap/hw_features.h8
-rw-r--r--src/ap/ieee802_11.c158
-rw-r--r--src/ap/ieee802_11.h3
-rw-r--r--src/ap/ieee802_11_he.c4
-rw-r--r--src/ap/ieee802_11_shared.c30
-rw-r--r--src/ap/ieee802_1x.c21
-rw-r--r--src/ap/neighbor_db.c2
-rw-r--r--src/ap/pmksa_cache_auth.c5
-rw-r--r--src/ap/sta_info.c46
-rw-r--r--src/ap/sta_info.h1
-rw-r--r--src/ap/utils.c4
-rw-r--r--src/ap/vlan_init.c5
-rw-r--r--src/ap/wnm_ap.c32
-rw-r--r--src/ap/wpa_auth.c706
-rw-r--r--src/ap/wpa_auth.h37
-rw-r--r--src/ap/wpa_auth_ft.c110
-rw-r--r--src/ap/wpa_auth_glue.c74
-rw-r--r--src/ap/wpa_auth_i.h6
-rw-r--r--src/ap/wpa_auth_ie.c54
-rw-r--r--src/ap/wps_hostapd.c6
-rw-r--r--src/common/common_module_tests.c3
-rw-r--r--src/common/defs.h23
-rw-r--r--src/common/dpp.c391
-rw-r--r--src/common/dpp.h35
-rw-r--r--src/common/hw_features_common.c71
-rw-r--r--src/common/ieee802_11_common.c131
-rw-r--r--src/common/ieee802_11_common.h27
-rw-r--r--src/common/ieee802_11_defs.h14
-rw-r--r--src/common/privsep_commands.h1
-rw-r--r--src/common/qca-vendor.h279
-rw-r--r--src/common/sae.c26
-rw-r--r--src/common/sae.h4
-rw-r--r--src/common/wpa_common.c42
-rw-r--r--src/common/wpa_common.h10
-rw-r--r--src/common/wpa_ctrl.h10
-rw-r--r--src/crypto/crypto.h1
-rw-r--r--src/crypto/crypto_openssl.c6
-rw-r--r--src/crypto/crypto_wolfssl.c6
-rw-r--r--src/drivers/driver.h47
-rw-r--r--src/drivers/driver_atheros.c2
-rw-r--r--src/drivers/driver_common.c2
-rw-r--r--src/drivers/driver_hostap.c10
-rw-r--r--src/drivers/driver_nl80211.c168
-rw-r--r--src/drivers/driver_nl80211_capa.c10
-rw-r--r--src/drivers/driver_nl80211_event.c110
-rw-r--r--src/drivers/driver_nl80211_scan.c5
-rw-r--r--src/drivers/driver_openbsd.c5
-rw-r--r--src/drivers/driver_privsep.c3
-rw-r--r--src/drivers/driver_wext.c53
-rw-r--r--src/drivers/nl80211_copy.h171
-rw-r--r--src/eapol_auth/eapol_auth_sm.c14
-rw-r--r--src/eapol_supp/eapol_supp_sm.c4
-rw-r--r--src/radius/radius.c2
-rw-r--r--src/rsn_supp/pmksa_cache.c37
-rw-r--r--src/rsn_supp/preauth.c2
-rw-r--r--src/rsn_supp/tdls.c2
-rw-r--r--src/rsn_supp/wpa.c154
-rw-r--r--src/rsn_supp/wpa.h18
-rw-r--r--src/rsn_supp/wpa_ft.c131
-rw-r--r--src/rsn_supp/wpa_i.h16
-rw-r--r--src/rsn_supp/wpa_ie.c27
-rw-r--r--src/rsn_supp/wpa_ie.h1
-rw-r--r--src/utils/browser.c18
-rw-r--r--src/utils/common.c38
-rw-r--r--src/utils/common.h2
-rw-r--r--src/utils/eloop.c47
-rw-r--r--src/utils/eloop_win.c8
-rw-r--r--src/utils/http-utils.h6
-rw-r--r--src/utils/os_unix.c5
-rw-r--r--src/utils/utils_module_tests.c2
-rw-r--r--src/wps/wps.h5
-rw-r--r--src/wps/wps_registrar.c25
-rw-r--r--tests/fuzzing/dpp-uri/Makefile33
-rw-r--r--tests/fuzzing/dpp-uri/corpus/1.dat1
-rw-r--r--tests/fuzzing/dpp-uri/corpus/2.dat1
-rw-r--r--tests/fuzzing/dpp-uri/corpus/3.dat1
-rw-r--r--tests/fuzzing/dpp-uri/dpp-uri.c51
-rw-r--r--tests/fuzzing/eapol-key-auth/eapol-key-auth.c7
-rw-r--r--tests/fuzzing/eapol-key-supp/eapol-key-supp.c6
-rw-r--r--tests/fuzzing/sae/Makefile24
-rw-r--r--tests/fuzzing/sae/corpus/sae-commit-h2e-rejected-groups.datbin0 -> 102 bytes
-rw-r--r--tests/fuzzing/sae/corpus/sae-commit-h2e-token.datbin0 -> 101 bytes
-rw-r--r--tests/fuzzing/sae/corpus/sae-commit-pw-id.datbin0 -> 101 bytes
-rw-r--r--tests/fuzzing/sae/corpus/sae-commit-token.datbin0 -> 130 bytes
-rw-r--r--tests/fuzzing/sae/corpus/sae-commit-valid.datbin0 -> 98 bytes
-rw-r--r--tests/fuzzing/sae/sae.c39
-rw-r--r--tests/hwsim/example-hostapd.config1
-rw-r--r--tests/hwsim/example-wpa_supplicant.config1
-rwxr-xr-xtests/hwsim/run-tests.py2
-rw-r--r--tests/hwsim/test_ap_acs.py59
-rw-r--r--tests/hwsim/test_ap_config.py22
-rw-r--r--tests/hwsim/test_ap_eap.py35
-rw-r--r--tests/hwsim/test_ap_ft.py200
-rw-r--r--tests/hwsim/test_ap_hs20.py5
-rw-r--r--tests/hwsim/test_ap_ht.py56
-rw-r--r--tests/hwsim/test_ap_params.py40
-rw-r--r--tests/hwsim/test_ap_pmf.py100
-rw-r--r--tests/hwsim/test_ap_psk.py151
-rw-r--r--tests/hwsim/test_ap_tdls.py3
-rw-r--r--tests/hwsim/test_ap_vht.py48
-rw-r--r--tests/hwsim/test_ap_wps.py42
-rw-r--r--tests/hwsim/test_bgscan.py33
-rw-r--r--tests/hwsim/test_cfg80211.py2
-rw-r--r--tests/hwsim/test_connect_cmd.py13
-rw-r--r--tests/hwsim/test_dbus.py61
-rw-r--r--tests/hwsim/test_dfs.py137
-rw-r--r--tests/hwsim/test_dpp.py287
-rw-r--r--tests/hwsim/test_fils.py32
-rw-r--r--tests/hwsim/test_ibss.py4
-rw-r--r--tests/hwsim/test_ieee8021x.py8
-rw-r--r--tests/hwsim/test_monitor_interface.py19
-rw-r--r--tests/hwsim/test_owe.py89
-rw-r--r--tests/hwsim/test_pmksa_cache.py27
-rw-r--r--tests/hwsim/test_radius.py4
-rw-r--r--tests/hwsim/test_sae.py289
-rw-r--r--tests/hwsim/test_scan.py36
-rw-r--r--tests/hwsim/test_sigma_dut.py596
-rw-r--r--tests/hwsim/test_wep.py15
-rw-r--r--tests/hwsim/test_wext.py3
-rw-r--r--tests/hwsim/test_wpas_ap.py114
-rw-r--r--tests/hwsim/test_wpas_config.py58
-rw-r--r--tests/hwsim/test_wpas_ctrl.py22
-rw-r--r--tests/hwsim/test_wpas_mesh.py18
-rw-r--r--tests/hwsim/utils.py7
-rw-r--r--tests/hwsim/vm/README24
-rw-r--r--tests/hwsim/vm/kernel-config2180
-rw-r--r--tests/hwsim/vm/kernel-config.uml131
-rwxr-xr-xtests/hwsim/vm/parallel-vm.py3
-rwxr-xr-xtests/hwsim/vm/vm-run.sh3
-rw-r--r--tests/hwsim/wlantest.py3
-rw-r--r--tests/hwsim/wpasupplicant.py40
-rwxr-xr-xtests/remote/run-tests.py27
-rw-r--r--wlantest/bss.c27
-rw-r--r--wlantest/readpcap.c1
-rw-r--r--wlantest/rx_data.c271
-rw-r--r--wlantest/rx_eapol.c78
-rw-r--r--wlantest/rx_mgmt.c9
-rw-r--r--wlantest/sta.c3
-rw-r--r--wlantest/wlantest.h5
-rw-r--r--wpa_supplicant/Android.mk9
-rw-r--r--wpa_supplicant/Makefile9
-rw-r--r--wpa_supplicant/README-DPP65
-rw-r--r--wpa_supplicant/android.config8
-rw-r--r--wpa_supplicant/ap.c13
-rw-r--r--wpa_supplicant/bss.c2
-rw-r--r--wpa_supplicant/bss.h1
-rw-r--r--wpa_supplicant/config.c19
-rw-r--r--wpa_supplicant/config.h16
-rw-r--r--wpa_supplicant/config_file.c58
-rw-r--r--wpa_supplicant/config_ssid.h48
-rw-r--r--wpa_supplicant/config_winreg.c25
-rw-r--r--wpa_supplicant/ctrl_iface.c40
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers.c40
-rw-r--r--wpa_supplicant/defconfig8
-rw-r--r--wpa_supplicant/dpp_supplicant.c372
-rw-r--r--wpa_supplicant/dpp_supplicant.h2
-rw-r--r--wpa_supplicant/driver_i.h13
-rw-r--r--wpa_supplicant/events.c187
-rw-r--r--wpa_supplicant/ibss_rsn.c2
-rw-r--r--wpa_supplicant/offchannel.c2
-rw-r--r--wpa_supplicant/op_classes.c29
-rw-r--r--wpa_supplicant/p2p_supplicant.c10
-rw-r--r--wpa_supplicant/preauth_test.c3
-rw-r--r--wpa_supplicant/rrm.c4
-rw-r--r--wpa_supplicant/scan.c146
-rw-r--r--wpa_supplicant/sme.c47
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant-nl80211.service.arg.in2
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant-wired.service.arg.in2
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant.service.arg.in2
-rw-r--r--wpa_supplicant/wpa_cli.c8
-rw-r--r--wpa_supplicant/wpa_priv.c1
-rw-r--r--wpa_supplicant/wpa_supplicant.c115
-rw-r--r--wpa_supplicant/wpa_supplicant.conf11
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h26
-rw-r--r--wpa_supplicant/wpas_glue.c94
-rw-r--r--wpa_supplicant/wps_supplicant.c1
198 files changed, 7970 insertions, 3817 deletions
diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index b2b4389..a2e5de2 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -651,7 +651,7 @@ fi.w1.wpa_supplicant1.CreateInterface.
<tr><td>Pairwise</td><td>as</td><td>Possible array elements: "ccmp-256", "gcmp-256", "ccmp", "gcmp", "tkip", "none"</td>
<tr><td>Group</td><td>as</td><td>Possible array elements: "ccmp-256", "gcmp-256", "ccmp", "gcmp", "tkip", "wep104", "wep40"</td>
<tr><td>GroupMgmt</td><td>as</td><td>Possible array elements: "aes-128-cmac", "bip-gmac-128", "bip-gmac-256", "bip-cmac-256"</td>
- <tr><td>KeyMgmt</td><td>as</td><td>Possible array elements: "wpa-psk", "wpa-ft-psk", "wpa-psk-sha256", "wpa-eap", "wpa-ft-eap", "wpa-eap-sha256", "ieee8021x", "wpa-none", "wps", "none"</td>
+ <tr><td>KeyMgmt</td><td>as</td><td>Possible array elements: "wpa-psk", "wpa-ft-psk", "wpa-psk-sha256", "wpa-eap", "wpa-ft-eap", "wpa-eap-sha256", "sae", "ieee8021x", "wpa-none", "wps", "none"</td>
<tr><td>Protocol</td><td>as</td><td>Possible array elements: "rsn", "wpa"</td>
<tr><td>AuthAlg</td><td>as</td><td>Possible array elements: "open", "shared", "leap"</td>
<tr><td>Scan</td><td>as</td><td>Possible array elements: "active", "passive", "ssid"</td>
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index 662a6cd..0f05565 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -252,6 +252,7 @@ L_CFLAGS += -DCONFIG_SAE
OBJS += src/common/sae.c
NEED_ECC=y
NEED_DH_GROUPS=y
+NEED_HMAC_SHA256_KDF=y
NEED_DRAGONFLY=y
endif
@@ -309,6 +310,10 @@ OBJS += src/fst/fst_ctrl_iface.c
endif
endif
+ifdef CONFIG_WEP
+L_CFLAGS += -DCONFIG_WEP
+endif
+
include $(LOCAL_PATH)/src/drivers/drivers.mk
diff --git a/hostapd/Makefile b/hostapd/Makefile
index dbe0403..326e91b 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -296,6 +296,7 @@ CFLAGS += -DCONFIG_SAE
OBJS += ../src/common/sae.o
NEED_ECC=y
NEED_DH_GROUPS=y
+NEED_HMAC_SHA256_KDF=y
NEED_AP_MLME=y
NEED_DRAGONFLY=y
endif
@@ -1238,6 +1239,10 @@ OBJS += ../src/fst/fst_ctrl_iface.o
endif
endif
+ifdef CONFIG_WEP
+CFLAGS += -DCONFIG_WEP
+endif
+
ALL=hostapd hostapd_cli
all: verify_config $(ALL)
diff --git a/hostapd/android.config b/hostapd/android.config
index d9200be..94a9bb4 100644
--- a/hostapd/android.config
+++ b/hostapd/android.config
@@ -201,3 +201,11 @@ CONFIG_WPA_CLI_EDIT=y
# /dev/urandom earlier in boot' seeds /dev/urandom with that entropy before
# either wpa_supplicant or hostapd are run.
CONFIG_NO_RANDOM_POOL=y
+
+# Wired equivalent privacy (WEP)
+# WEP is an obsolete cryptographic data confidentiality algorithm that is not
+# considered secure. It should not be used for anything anymore. The
+# functionality needed to use WEP is available in the current hostapd
+# release under this optional build parameter. This functionality is subject to
+# be completely removed in a future release.
+CONFIG_WEP=y
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 6dde59a..1d8c039 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -793,6 +793,7 @@ static int hostapd_config_parse_cipher(int line, const char *value)
}
+#ifdef CONFIG_WEP
static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
char *val)
{
@@ -843,6 +844,7 @@ static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
return 0;
}
+#endif /* CONFIG_WEP */
static int hostapd_parse_chanlist(struct hostapd_config *conf, char *val)
@@ -2461,6 +2463,13 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
bss->skip_inactivity_poll = atoi(pos);
} else if (os_strcmp(buf, "country_code") == 0) {
+ if (pos[0] < 'A' || pos[0] > 'Z' ||
+ pos[1] < 'A' || pos[1] > 'Z') {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid country_code '%s'",
+ line, pos);
+ return 1;
+ }
os_memcpy(conf->country, pos, 2);
} else if (os_strcmp(buf, "country3") == 0) {
conf->country[2] = strtol(pos, NULL, 16);
@@ -2664,6 +2673,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "erp_domain") == 0) {
os_free(bss->erp_domain);
bss->erp_domain = os_strdup(pos);
+#ifdef CONFIG_WEP
} else if (os_strcmp(buf, "wep_key_len_broadcast") == 0) {
int val = atoi(pos);
@@ -2691,6 +2701,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line, bss->wep_rekeying_period);
return 1;
}
+#endif /* CONFIG_WEP */
} else if (os_strcmp(buf, "eap_reauth_period") == 0) {
bss->eap_reauth_period = atoi(pos);
if (bss->eap_reauth_period < 0) {
@@ -2865,6 +2876,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
}
} else if (os_strcmp(buf, "wpa") == 0) {
bss->wpa = atoi(pos);
+ } else if (os_strcmp(buf, "extended_key_id") == 0) {
+ int val = atoi(pos);
+
+ if (val < 0 || val > 2) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid extended_key_id=%d; allowed range 0..2",
+ line, val);
+ return 1;
+ }
+ bss->extended_key_id = val;
} else if (os_strcmp(buf, "wpa_group_rekey") == 0) {
bss->wpa_group_rekey = atoi(pos);
bss->wpa_group_rekey_set = 1;
@@ -3311,6 +3332,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
bss->ignore_broadcast_ssid = atoi(pos);
} else if (os_strcmp(buf, "no_probe_resp_if_max_sta") == 0) {
bss->no_probe_resp_if_max_sta = atoi(pos);
+#ifdef CONFIG_WEP
} else if (os_strcmp(buf, "wep_default_key") == 0) {
bss->ssid.wep.idx = atoi(pos);
if (bss->ssid.wep.idx > 3) {
@@ -3329,6 +3351,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line, buf);
return 1;
}
+#endif /* CONFIG_WEP */
#ifndef CONFIG_NO_VLAN
} else if (os_strcmp(buf, "dynamic_vlan") == 0) {
bss->ssid.dynamic_vlan = atoi(pos);
@@ -4170,15 +4193,28 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "sae_commit_override") == 0) {
wpabuf_free(bss->sae_commit_override);
bss->sae_commit_override = wpabuf_parse_bin(pos);
+ } else if (os_strcmp(buf, "rsne_override_eapol") == 0) {
+ wpabuf_free(bss->rsne_override_eapol);
+ bss->rsne_override_eapol = wpabuf_parse_bin(pos);
} else if (os_strcmp(buf, "rsnxe_override_eapol") == 0) {
wpabuf_free(bss->rsnxe_override_eapol);
bss->rsnxe_override_eapol = wpabuf_parse_bin(pos);
+ } else if (os_strcmp(buf, "rsne_override_ft") == 0) {
+ wpabuf_free(bss->rsne_override_ft);
+ bss->rsne_override_ft = wpabuf_parse_bin(pos);
+ } else if (os_strcmp(buf, "rsnxe_override_ft") == 0) {
+ wpabuf_free(bss->rsnxe_override_ft);
+ bss->rsnxe_override_ft = wpabuf_parse_bin(pos);
} else if (os_strcmp(buf, "gtk_rsc_override") == 0) {
wpabuf_free(bss->gtk_rsc_override);
bss->gtk_rsc_override = wpabuf_parse_bin(pos);
} else if (os_strcmp(buf, "igtk_rsc_override") == 0) {
wpabuf_free(bss->igtk_rsc_override);
bss->igtk_rsc_override = wpabuf_parse_bin(pos);
+ } else if (os_strcmp(buf, "no_beacon_rsnxe") == 0) {
+ bss->no_beacon_rsnxe = atoi(pos);
+ } else if (os_strcmp(buf, "skip_prune_assoc") == 0) {
+ bss->skip_prune_assoc = atoi(pos);
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_SAE
} else if (os_strcmp(buf, "sae_password") == 0) {
@@ -4381,6 +4417,18 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "dpp_controller") == 0) {
if (hostapd_dpp_controller_parse(bss, pos))
return 1;
+ } else if (os_strcmp(buf, "dpp_configurator_connectivity") == 0) {
+ bss->dpp_configurator_connectivity = atoi(pos);
+ } else if (os_strcmp(buf, "dpp_pfs") == 0) {
+ int val = atoi(pos);
+
+ if (val < 0 || val > 2) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid dpp_pfs value '%s'",
+ line, pos);
+ return -1;
+ }
+ bss->dpp_pfs = val;
#endif /* CONFIG_DPP2 */
#endif /* CONFIG_DPP */
#ifdef CONFIG_OWE
@@ -4435,6 +4483,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->rssi_reject_assoc_timeout = atoi(pos);
} else if (os_strcmp(buf, "pbss") == 0) {
bss->pbss = atoi(pos);
+ } else if (os_strcmp(buf, "transition_disable") == 0) {
+ bss->transition_disable = strtol(pos, NULL, 16);
#ifdef CONFIG_AIRTIME_POLICY
} else if (os_strcmp(buf, "airtime_mode") == 0) {
int val = atoi(pos);
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 6d2ecbc..d90b5dc 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -59,6 +59,7 @@
#include "ap/neighbor_db.h"
#include "ap/rrm.h"
#include "ap/dpp_hostapd.h"
+#include "ap/dfs.h"
#include "wps/wps_defs.h"
#include "wps/wps.h"
#include "fst/fst_ctrl_iface.h"
@@ -1295,6 +1296,14 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
pos += ret;
}
+ if ((hapd->conf->wpa & WPA_PROTO_RSN) && hapd->conf->extended_key_id) {
+ ret = os_snprintf(pos, end - pos, "extended_key_id=%d\n",
+ hapd->conf->extended_key_id);
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+
return pos - buf;
}
@@ -2424,18 +2433,173 @@ static int hostapd_ctrl_get_pmk(struct hostapd_data *hapd, const char *cmd,
#endif /* CONFIG_TESTING_OPTIONS */
+static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
+{
+ switch (params->bandwidth) {
+ case 0:
+ /* bandwidth not specified: use 20 MHz by default */
+ /* fall-through */
+ case 20:
+ if (params->center_freq1 &&
+ params->center_freq1 != params->freq)
+ return -1;
+
+ if (params->center_freq2 || params->sec_channel_offset)
+ return -1;
+ break;
+ case 40:
+ if (params->center_freq2 || !params->sec_channel_offset)
+ return -1;
+
+ if (!params->center_freq1)
+ break;
+ switch (params->sec_channel_offset) {
+ case 1:
+ if (params->freq + 10 != params->center_freq1)
+ return -1;
+ break;
+ case -1:
+ if (params->freq - 10 != params->center_freq1)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ break;
+ case 80:
+ if (!params->center_freq1 || !params->sec_channel_offset)
+ return 1;
+
+ switch (params->sec_channel_offset) {
+ case 1:
+ if (params->freq - 10 != params->center_freq1 &&
+ params->freq + 30 != params->center_freq1)
+ return 1;
+ break;
+ case -1:
+ if (params->freq + 10 != params->center_freq1 &&
+ params->freq - 30 != params->center_freq1)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+
+ /* Adjacent and overlapped are not allowed for 80+80 */
+ if (params->center_freq2 &&
+ params->center_freq1 - params->center_freq2 <= 80 &&
+ params->center_freq2 - params->center_freq1 <= 80)
+ return 1;
+ break;
+ case 160:
+ if (!params->center_freq1 || params->center_freq2 ||
+ !params->sec_channel_offset)
+ return -1;
+
+ switch (params->sec_channel_offset) {
+ case 1:
+ if (params->freq + 70 != params->center_freq1 &&
+ params->freq + 30 != params->center_freq1 &&
+ params->freq - 10 != params->center_freq1 &&
+ params->freq - 50 != params->center_freq1)
+ return -1;
+ break;
+ case -1:
+ if (params->freq + 50 != params->center_freq1 &&
+ params->freq + 10 != params->center_freq1 &&
+ params->freq - 30 != params->center_freq1 &&
+ params->freq - 70 != params->center_freq1)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
char *pos)
{
#ifdef NEED_AP_MLME
struct csa_settings settings;
int ret;
+ int dfs_range = 0;
unsigned int i;
+ int bandwidth;
+ u8 chan;
ret = hostapd_parse_csa_settings(pos, &settings);
if (ret)
return ret;
+ ret = hostapd_ctrl_check_freq_params(&settings.freq_params);
+ if (ret) {
+ wpa_printf(MSG_INFO,
+ "chanswitch: invalid frequency settings provided");
+ return ret;
+ }
+
+ switch (settings.freq_params.bandwidth) {
+ case 40:
+ bandwidth = CHAN_WIDTH_40;
+ break;
+ case 80:
+ if (settings.freq_params.center_freq2)
+ bandwidth = CHAN_WIDTH_80P80;
+ else
+ bandwidth = CHAN_WIDTH_80;
+ break;
+ case 160:
+ bandwidth = CHAN_WIDTH_160;
+ break;
+ default:
+ bandwidth = CHAN_WIDTH_20;
+ break;
+ }
+
+ if (settings.freq_params.center_freq1)
+ dfs_range += hostapd_is_dfs_overlap(
+ iface, bandwidth, settings.freq_params.center_freq1);
+ else
+ dfs_range += hostapd_is_dfs_overlap(
+ iface, bandwidth, settings.freq_params.freq);
+
+ if (settings.freq_params.center_freq2)
+ dfs_range += hostapd_is_dfs_overlap(
+ iface, bandwidth, settings.freq_params.center_freq2);
+
+ if (dfs_range) {
+ ret = ieee80211_freq_to_chan(settings.freq_params.freq, &chan);
+ if (ret == NUM_HOSTAPD_MODES) {
+ wpa_printf(MSG_ERROR,
+ "Failed to get channel for (freq=%d, sec_channel_offset=%d, bw=%d)",
+ settings.freq_params.freq,
+ settings.freq_params.sec_channel_offset,
+ settings.freq_params.bandwidth);
+ return -1;
+ }
+
+ settings.freq_params.channel = chan;
+
+ wpa_printf(MSG_DEBUG,
+ "DFS/CAC to (channel=%u, freq=%d, sec_channel_offset=%d, bw=%d, center_freq1=%d)",
+ settings.freq_params.channel,
+ settings.freq_params.freq,
+ settings.freq_params.sec_channel_offset,
+ settings.freq_params.bandwidth,
+ settings.freq_params.center_freq1);
+
+ /* Perform CAC and switch channel */
+ hostapd_switch_channel_fallback(iface, &settings.freq_params);
+ return 0;
+ }
+
for (i = 0; i < iface->num_bss; i++) {
/* Save CHAN_SWITCH VHT config */
@@ -3455,6 +3619,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
reply_len = dpp_bootstrap_info(hapd->iface->interfaces->dpp,
atoi(buf + 19),
reply, reply_size);
+ } else if (os_strncmp(buf, "DPP_BOOTSTRAP_SET ", 18) == 0) {
+ if (dpp_bootstrap_set(hapd->iface->interfaces->dpp,
+ atoi(buf + 18),
+ os_strchr(buf + 18, ' ')) < 0)
+ reply_len = -1;
} else if (os_strncmp(buf, "DPP_AUTH_INIT ", 14) == 0) {
if (hostapd_dpp_auth_init(hapd, buf + 13) < 0)
reply_len = -1;
diff --git a/hostapd/defconfig b/hostapd/defconfig
index e12260f..5133db2 100644
--- a/hostapd/defconfig
+++ b/hostapd/defconfig
@@ -380,3 +380,11 @@ CONFIG_IPV6=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
+
+# Wired equivalent privacy (WEP)
+# WEP is an obsolete cryptographic data confidentiality algorithm that is not
+# considered secure. It should not be used for anything anymore. The
+# functionality needed to use WEP is available in the current hostapd
+# release under this optional build parameter. This functionality is subject to
+# be completely removed in a future release.
+#CONFIG_WEP=y
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index bc5d1a7..812c09a 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -1510,6 +1510,17 @@ own_ip_addr=127.0.0.1
# wpa_key_mgmt=SAE for WPA3-Personal instead of wpa_key_mgmt=WPA-PSK).
#wpa=2
+# Extended Key ID support for Individually Addressed frames
+#
+# Extended Key ID allows to rekey PTK keys without the impacts the "normal"
+# PTK rekeying with only a single Key ID 0 has. It can only be used when the
+# driver supports it and RSN/WPA2 is used with a CCMP/GCMP pairwise cipher.
+#
+# 0 = force off, i.e., use only Key ID 0 (default)
+# 1 = enable and use Extended Key ID support when possible
+# 2 = identical to 1 but start with Key ID 1 when possible
+#extended_key_id=0
+
# WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit
# secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase
# (8..63 characters) that will be converted to PSK. This conversion uses SSID
@@ -1894,6 +1905,23 @@ own_ip_addr=127.0.0.1
# default: 30 TUs (= 30.72 milliseconds)
#fils_hlp_wait_time=30
+# Transition Disable indication
+# The AP can notify authenticated stations to disable transition mode in their
+# network profiles when the network has completed transition steps, i.e., once
+# sufficiently large number of APs in the ESS have been updated to support the
+# more secure alternative. When this indication is used, the stations are
+# expected to automatically disable transition mode and less secure security
+# options. This includes use of WEP, TKIP (including use of TKIP as the group
+# cipher), and connections without PMF.
+# Bitmap bits:
+# bit 0 (0x01): WPA3-Personal (i.e., disable WPA2-Personal = WPA-PSK and only
+# allow SAE to be used)
+# bit 1 (0x02): SAE-PK (disable SAE without use of SAE-PK)
+# bit 2 (0x04): WPA3-Enterprise (move to requiring PMF)
+# bit 3 (0x08): Enhanced Open (disable use of open network; require OWE)
+# (default: 0 = do not include Transition Disable KDE)
+#transition_disable=0x01
+
##### IEEE 802.11r configuration ##############################################
# Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
@@ -2276,6 +2304,17 @@ own_ip_addr=127.0.0.1
#dpp_csign
#dpp_controller
+# Configurator Connectivity indication
+# 0: no Configurator is currently connected (default)
+# 1: advertise that a Configurator is available
+#dpp_configurator_connectivity=0
+
+# DPP PFS
+# 0: allow PFS to be used or not used (default)
+# 1: require PFS to be used (note: not compatible with DPP R1)
+# 2: do not allow PFS to be used
+#dpp_pfs=0
+
#### TDLS (IEEE 802.11z-2010) #################################################
# Prohibit use of TDLS in this BSS
diff --git a/hs20/client/osu_client.c b/hs20/client/osu_client.c
index f1b078b..11bf0db 100644
--- a/hs20/client/osu_client.c
+++ b/hs20/client/osu_client.c
@@ -2233,7 +2233,7 @@ static int osu_connect(struct hs20_osu_client *ctx, const char *bssid,
wpa_ctrl_close(mon);
if (res < 0) {
- wpa_printf(MSG_INFO, "Could not connect");
+ wpa_printf(MSG_INFO, "Could not connect to OSU network");
write_summary(ctx, "Could not connect to OSU network");
wpa_printf(MSG_INFO, "Remove OSU network connection");
snprintf(buf, sizeof(buf), "REMOVE_NETWORK %d", id);
@@ -2907,7 +2907,7 @@ static char * get_hostname(const char *url)
static int osu_cert_cb(void *_ctx, struct http_cert *cert)
{
struct hs20_osu_client *ctx = _ctx;
- unsigned int i, j;
+ size_t i, j;
int found;
char *host = NULL;
@@ -3002,7 +3002,7 @@ static int osu_cert_cb(void *_ctx, struct http_cert *cert)
size_t name_len = os_strlen(name);
wpa_printf(MSG_INFO,
- "[%i] Looking for icon file name '%s' match",
+ "[%zu] Looking for icon file name '%s' match",
j, name);
for (i = 0; i < cert->num_logo; i++) {
struct http_logo *logo = &cert->logo[i];
@@ -3010,7 +3010,7 @@ static int osu_cert_cb(void *_ctx, struct http_cert *cert)
char *pos;
wpa_printf(MSG_INFO,
- "[%i] Comparing to '%s' uri_len=%d name_len=%d",
+ "[%zu] Comparing to '%s' uri_len=%d name_len=%d",
i, logo->uri, (int) uri_len, (int) name_len);
if (uri_len < 1 + name_len) {
wpa_printf(MSG_INFO, "URI Length is too short");
@@ -3044,7 +3044,7 @@ static int osu_cert_cb(void *_ctx, struct http_cert *cert)
if (logo->hash_len != 32) {
wpa_printf(MSG_INFO,
- "[%i][%i] Icon hash length invalid (should be 32): %d",
+ "[%zu][%zu] Icon hash length invalid (should be 32): %d",
j, i, (int) logo->hash_len);
continue;
}
@@ -3054,7 +3054,7 @@ static int osu_cert_cb(void *_ctx, struct http_cert *cert)
}
wpa_printf(MSG_DEBUG,
- "[%u][%u] Icon hash did not match", j, i);
+ "[%zu][%zu] Icon hash did not match", j, i);
wpa_hexdump_ascii(MSG_DEBUG, "logo->hash",
logo->hash, 32);
wpa_hexdump_ascii(MSG_DEBUG, "ctx->icon_hash[j]",
diff --git a/hs20/server/ca/ocsp-responder.sh b/hs20/server/ca/ocsp-responder.sh
index 8cebd74..620947d 100755
--- a/hs20/server/ca/ocsp-responder.sh
+++ b/hs20/server/ca/ocsp-responder.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-openssl ocsp -index demoCA/index.txt -port 8888 -nmin 5 -rsigner ocsp.pem -rkey ocsp.key -CA demoCA/cacert.pem -text
+openssl ocsp -index demoCA/index.txt -port 8888 -nmin 5 -rsigner ocsp.pem -rkey ocsp.key -CA demoCA/cacert.pem -text -ignore_err
diff --git a/hs20/server/ca/ocsp-update-cache.sh b/hs20/server/ca/ocsp-update-cache.sh
index 8ddef9b..f2b2325 100755
--- a/hs20/server/ca/ocsp-update-cache.sh
+++ b/hs20/server/ca/ocsp-update-cache.sh
@@ -1,5 +1,6 @@
#!/bin/sh
+# NOTE: You may need to replace 'localhost' with your OCSP server hostname.
openssl ocsp \
-no_nonce \
-CAfile ca.pem \
diff --git a/src/ap/acs.c b/src/ap/acs.c
index 232afa8..5c01610 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -261,13 +261,13 @@ static void acs_clean_chan_surveys(struct hostapd_channel_data *chan)
}
-void acs_cleanup(struct hostapd_iface *iface)
+static void acs_cleanup_mode(struct hostapd_hw_modes *mode)
{
int i;
struct hostapd_channel_data *chan;
- for (i = 0; i < iface->current_mode->num_channels; i++) {
- chan = &iface->current_mode->channels[i];
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
if (chan->flag & HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED)
acs_clean_chan_surveys(chan);
@@ -276,6 +276,15 @@ void acs_cleanup(struct hostapd_iface *iface)
chan->flag |= HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED;
chan->min_nf = 0;
}
+}
+
+
+void acs_cleanup(struct hostapd_iface *iface)
+{
+ int i;
+
+ for (i = 0; i < iface->num_hw_features; i++)
+ acs_cleanup_mode(&iface->hw_features[i]);
iface->chans_surveyed = 0;
iface->acs_num_completed_scans = 0;
@@ -453,21 +462,35 @@ static int acs_survey_list_is_sufficient(struct hostapd_channel_data *chan)
}
-static int acs_surveys_are_sufficient(struct hostapd_iface *iface)
+static int acs_surveys_are_sufficient_mode(struct hostapd_hw_modes *mode)
{
int i;
struct hostapd_channel_data *chan;
- int valid = 0;
- for (i = 0; i < iface->current_mode->num_channels; i++) {
- chan = &iface->current_mode->channels[i];
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
acs_survey_list_is_sufficient(chan))
- valid++;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int acs_surveys_are_sufficient(struct hostapd_iface *iface)
+{
+ int i;
+ struct hostapd_hw_modes *mode;
+
+ for (i = 0; i < iface->num_hw_features; i++) {
+ mode = &iface->hw_features[i];
+ if (!hostapd_hw_skip_mode(iface, mode) &&
+ acs_surveys_are_sufficient_mode(mode))
+ return 1;
}
- /* We need at least survey data for one channel */
- return !!valid;
+ return 0;
}
@@ -489,14 +512,14 @@ static int is_in_chanlist(struct hostapd_iface *iface,
}
-static void acs_survey_all_chans_intereference_factor(
- struct hostapd_iface *iface)
+static void acs_survey_mode_interference_factor(
+ struct hostapd_iface *iface, struct hostapd_hw_modes *mode)
{
int i;
struct hostapd_channel_data *chan;
- for (i = 0; i < iface->current_mode->num_channels; i++) {
- chan = &iface->current_mode->channels[i];
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
if (!acs_usable_chan(chan))
continue;
@@ -515,14 +538,28 @@ static void acs_survey_all_chans_intereference_factor(
}
-static struct hostapd_channel_data *acs_find_chan(struct hostapd_iface *iface,
- int freq)
+static void acs_survey_all_chans_interference_factor(
+ struct hostapd_iface *iface)
+{
+ int i;
+ struct hostapd_hw_modes *mode;
+
+ for (i = 0; i < iface->num_hw_features; i++) {
+ mode = &iface->hw_features[i];
+ if (!hostapd_hw_skip_mode(iface, mode))
+ acs_survey_mode_interference_factor(iface, mode);
+ }
+}
+
+
+static struct hostapd_channel_data *
+acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
{
struct hostapd_channel_data *chan;
int i;
- for (i = 0; i < iface->current_mode->num_channels; i++) {
- chan = &iface->current_mode->channels[i];
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
if (chan->flag & HOSTAPD_CHAN_DISABLED)
continue;
@@ -535,6 +572,26 @@ static struct hostapd_channel_data *acs_find_chan(struct hostapd_iface *iface,
}
+static struct hostapd_channel_data *
+acs_find_chan(struct hostapd_iface *iface, int freq)
+{
+ int i;
+ struct hostapd_hw_modes *mode;
+ struct hostapd_channel_data *chan;
+
+ for (i = 0; i < iface->num_hw_features; i++) {
+ mode = &iface->hw_features[i];
+ if (!hostapd_hw_skip_mode(iface, mode)) {
+ chan = acs_find_chan_mode(mode, freq);
+ if (chan)
+ return chan;
+ }
+ }
+
+ return NULL;
+}
+
+
static int is_24ghz_mode(enum hostapd_hw_mode mode)
{
return mode == HOSTAPD_MODE_IEEE80211B ||
@@ -565,58 +622,24 @@ static int is_common_24ghz_chan(int chan)
#define ACS_24GHZ_PREFER_1_6_11 0.8
#endif /* ACS_24GHZ_PREFER_1_6_11 */
-/*
- * At this point it's assumed chan->interface_factor has been computed.
- * This function should be reusable regardless of interference computation
- * option (survey, BSS, spectral, ...). chan->interference factor must be
- * summable (i.e., must be always greater than zero).
- */
-static struct hostapd_channel_data *
-acs_find_ideal_chan(struct hostapd_iface *iface)
+static void
+acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ struct hostapd_hw_modes *mode,
+ int n_chans, u32 bw,
+ struct hostapd_channel_data **rand_chan,
+ struct hostapd_channel_data **ideal_chan,
+ long double *ideal_factor)
{
- struct hostapd_channel_data *chan, *adj_chan, *ideal_chan = NULL,
- *rand_chan = NULL;
- long double factor, ideal_factor = 0;
+ struct hostapd_channel_data *chan, *adj_chan = NULL;
+ long double factor;
int i, j;
- int n_chans = 1;
- u32 bw;
unsigned int k;
- /* TODO: HT40- support */
-
- if (iface->conf->ieee80211n &&
- iface->conf->secondary_channel == -1) {
- wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
- return NULL;
- }
-
- if (iface->conf->ieee80211n &&
- iface->conf->secondary_channel)
- n_chans = 2;
-
- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
- switch (hostapd_get_oper_chwidth(iface->conf)) {
- case CHANWIDTH_80MHZ:
- n_chans = 4;
- break;
- case CHANWIDTH_160MHZ:
- n_chans = 8;
- break;
- }
- }
-
- bw = num_chan_to_bw(n_chans);
-
- /* TODO: VHT/HE80+80. Update acs_adjust_center_freq() too. */
-
- wpa_printf(MSG_DEBUG,
- "ACS: Survey analysis for selected bandwidth %d MHz", bw);
-
- for (i = 0; i < iface->current_mode->num_channels; i++) {
+ for (i = 0; i < mode->num_channels; i++) {
double total_weight;
struct acs_bias *bias, tmp_bias;
- chan = &iface->current_mode->channels[i];
+ chan = &mode->channels[i];
/* Since in the current ACS implementation the first channel is
* always a primary channel, skip channels not available as
@@ -637,7 +660,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
/* HT40 on 5 GHz has a limited set of primary channels as per
* 11n Annex J */
- if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+ if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
iface->conf->ieee80211n &&
iface->conf->secondary_channel &&
!acs_usable_ht40_chan(chan)) {
@@ -646,7 +669,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
continue;
}
- if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+ if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
(iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
if (hostapd_get_oper_chwidth(iface->conf) ==
CHANWIDTH_80MHZ &&
@@ -698,7 +721,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
* channel interference factor. */
- if (is_24ghz_mode(iface->current_mode->mode)) {
+ if (is_24ghz_mode(mode->mode)) {
for (j = 0; j < n_chans; j++) {
adj_chan = acs_find_chan(iface, chan->freq +
(j * 20) - 5);
@@ -744,7 +767,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
break;
bias = NULL;
}
- } else if (is_24ghz_mode(iface->current_mode->mode) &&
+ } else if (is_24ghz_mode(mode->mode) &&
is_common_24ghz_chan(chan->chan)) {
tmp_bias.channel = chan->chan;
tmp_bias.bias = ACS_24GHZ_PREFER_1_6_11;
@@ -763,14 +786,71 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
}
if (acs_usable_chan(chan) &&
- (!ideal_chan || factor < ideal_factor)) {
- ideal_factor = factor;
- ideal_chan = chan;
+ (!*ideal_chan || factor < *ideal_factor)) {
+ *ideal_factor = factor;
+ *ideal_chan = chan;
}
/* This channel would at least be usable */
- if (!rand_chan)
- rand_chan = chan;
+ if (!(*rand_chan))
+ *rand_chan = chan;
+ }
+}
+
+
+/*
+ * At this point it's assumed chan->interference_factor has been computed.
+ * This function should be reusable regardless of interference computation
+ * option (survey, BSS, spectral, ...). chan->interference factor must be
+ * summable (i.e., must be always greater than zero).
+ */
+static struct hostapd_channel_data *
+acs_find_ideal_chan(struct hostapd_iface *iface)
+{
+ struct hostapd_channel_data *ideal_chan = NULL,
+ *rand_chan = NULL;
+ long double ideal_factor = 0;
+ int i;
+ int n_chans = 1;
+ u32 bw;
+ struct hostapd_hw_modes *mode;
+
+ /* TODO: HT40- support */
+
+ if (iface->conf->ieee80211n &&
+ iface->conf->secondary_channel == -1) {
+ wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
+ return NULL;
+ }
+
+ if (iface->conf->ieee80211n &&
+ iface->conf->secondary_channel)
+ n_chans = 2;
+
+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
+ switch (hostapd_get_oper_chwidth(iface->conf)) {
+ case CHANWIDTH_80MHZ:
+ n_chans = 4;
+ break;
+ case CHANWIDTH_160MHZ:
+ n_chans = 8;
+ break;
+ }
+ }
+
+ bw = num_chan_to_bw(n_chans);
+
+ /* TODO: VHT/HE80+80. Update acs_adjust_center_freq() too. */
+
+ wpa_printf(MSG_DEBUG,
+ "ACS: Survey analysis for selected bandwidth %d MHz", bw);
+
+ for (i = 0; i < iface->num_hw_features; i++) {
+ mode = &iface->hw_features[i];
+ if (!hostapd_hw_skip_mode(iface, mode))
+ acs_find_ideal_chan_mode(iface, mode, n_chans, bw,
+ &rand_chan, &ideal_chan,
+ &ideal_factor);
}
if (ideal_chan) {
@@ -826,7 +906,7 @@ static int acs_study_survey_based(struct hostapd_iface *iface)
return -1;
}
- acs_survey_all_chans_intereference_factor(iface);
+ acs_survey_all_chans_interference_factor(iface);
return 0;
}
@@ -918,29 +998,56 @@ fail:
}
+static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
+ struct hostapd_hw_modes *mode,
+ int *freq)
+{
+ struct hostapd_channel_data *chan;
+ int i;
+
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
+ if (chan->flag & HOSTAPD_CHAN_DISABLED)
+ continue;
+
+ if (!is_in_chanlist(iface, chan))
+ continue;
+
+ *freq++ = chan->freq;
+ }
+
+ return freq;
+}
+
+
static int acs_request_scan(struct hostapd_iface *iface)
{
struct wpa_driver_scan_params params;
- struct hostapd_channel_data *chan;
int i, *freq;
+ int num_channels;
+ struct hostapd_hw_modes *mode;
os_memset(&params, 0, sizeof(params));
- params.freqs = os_calloc(iface->current_mode->num_channels + 1,
- sizeof(params.freqs[0]));
+
+ num_channels = 0;
+ for (i = 0; i < iface->num_hw_features; i++) {
+ mode = &iface->hw_features[i];
+ if (!hostapd_hw_skip_mode(iface, mode))
+ num_channels += mode->num_channels;
+ }
+
+ params.freqs = os_calloc(num_channels + 1, sizeof(params.freqs[0]));
if (params.freqs == NULL)
return -1;
freq = params.freqs;
- for (i = 0; i < iface->current_mode->num_channels; i++) {
- chan = &iface->current_mode->channels[i];
- if (chan->flag & HOSTAPD_CHAN_DISABLED)
- continue;
- if (!is_in_chanlist(iface, chan))
- continue;
-
- *freq++ = chan->freq;
+ for (i = 0; i < iface->num_hw_features; i++) {
+ mode = &iface->hw_features[i];
+ if (!hostapd_hw_skip_mode(iface, mode))
+ freq = acs_request_scan_add_freqs(iface, mode, freq);
}
+
*freq = 0;
if (params.freqs == freq) {
@@ -978,7 +1085,8 @@ enum hostapd_chan_status acs_init(struct hostapd_iface *iface)
return HOSTAPD_CHAN_ACS;
}
- if (!iface->current_mode)
+ if (!iface->current_mode &&
+ iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY)
return HOSTAPD_CHAN_INVALID;
acs_cleanup(iface);
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index fddc8ca..5bf4502 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -54,12 +54,16 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
bss->logger_syslog = (unsigned int) -1;
bss->logger_stdout = (unsigned int) -1;
+#ifdef CONFIG_WEP
bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
bss->wep_rekeying_period = 300;
/* use key0 in individual key and key1 in broadcast key */
bss->broadcast_key_idx_min = 1;
bss->broadcast_key_idx_max = 2;
+#else /* CONFIG_WEP */
+ bss->auth_algs = WPA_AUTH_ALG_OPEN;
+#endif /* CONFIG_WEP */
bss->eap_reauth_period = 3600;
bss->wpa_group_rekey = 600;
@@ -636,6 +640,7 @@ void hostapd_config_free_eap_users(struct hostapd_eap_user *user)
}
+#ifdef CONFIG_WEP
static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
{
int i;
@@ -644,6 +649,7 @@ static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
keys->key[i] = NULL;
}
}
+#endif /* CONFIG_WEP */
void hostapd_config_clear_wpa_psk(struct hostapd_wpa_psk **l)
@@ -732,7 +738,9 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
str_clear_free(conf->ssid.wpa_passphrase);
os_free(conf->ssid.wpa_psk_file);
+#ifdef CONFIG_WEP
hostapd_config_free_wep(&conf->ssid.wep);
+#endif /* CONFIG_WEP */
#ifdef CONFIG_FULL_DYNAMIC_VLAN
os_free(conf->ssid.vlan_tagged_interface);
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
@@ -894,7 +902,10 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
#ifdef CONFIG_TESTING_OPTIONS
wpabuf_free(conf->own_ie_override);
wpabuf_free(conf->sae_commit_override);
+ wpabuf_free(conf->rsne_override_eapol);
wpabuf_free(conf->rsnxe_override_eapol);
+ wpabuf_free(conf->rsne_override_ft);
+ wpabuf_free(conf->rsnxe_override_ft);
wpabuf_free(conf->gtk_rsc_override);
wpabuf_free(conf->igtk_rsc_override);
#endif /* CONFIG_TESTING_OPTIONS */
@@ -1106,6 +1117,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
return -1;
}
+#ifdef CONFIG_WEP
if (bss->wpa) {
int wep, i;
@@ -1123,6 +1135,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
return -1;
}
}
+#endif /* CONFIG_WEP */
if (full_config && bss->wpa &&
bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
@@ -1177,12 +1190,14 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
"allowed, disabling HT capabilities");
}
+#ifdef CONFIG_WEP
if (full_config && conf->ieee80211n &&
bss->ssid.security_policy == SECURITY_STATIC_WEP) {
bss->disable_11n = 1;
wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WEP is not "
"allowed, disabling HT capabilities");
}
+#endif /* CONFIG_WEP */
if (full_config && conf->ieee80211n && bss->wpa &&
!(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
@@ -1196,12 +1211,14 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
}
#ifdef CONFIG_IEEE80211AC
+#ifdef CONFIG_WEP
if (full_config && conf->ieee80211ac &&
bss->ssid.security_policy == SECURITY_STATIC_WEP) {
bss->disable_11ac = 1;
wpa_printf(MSG_ERROR,
"VHT (IEEE 802.11ac) with WEP is not allowed, disabling VHT capabilities");
}
+#endif /* CONFIG_WEP */
if (full_config && conf->ieee80211ac && bss->wpa &&
!(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
@@ -1221,12 +1238,14 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
bss->wps_state = 0;
}
+#ifdef CONFIG_WEP
if (full_config && bss->wps_state &&
bss->ssid.wep.keys_set && bss->wpa == 0) {
wpa_printf(MSG_INFO, "WPS: WEP configuration forced WPS to be "
"disabled");
bss->wps_state = 0;
}
+#endif /* CONFIG_WEP */
if (full_config && bss->wps_state && bss->wpa &&
(!(bss->wpa & 2) ||
@@ -1350,11 +1369,13 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
void hostapd_set_security_params(struct hostapd_bss_config *bss,
int full_config)
{
+#ifdef CONFIG_WEP
if (bss->individual_wep_key_len == 0) {
/* individual keys are not use; can use key idx0 for
* broadcast keys */
bss->broadcast_key_idx_min = 0;
}
+#endif /* CONFIG_WEP */
if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
bss->rsn_pairwise = bss->wpa_pairwise;
@@ -1380,6 +1401,7 @@ void hostapd_set_security_params(struct hostapd_bss_config *bss,
} else if (bss->ieee802_1x) {
int cipher = WPA_CIPHER_NONE;
bss->ssid.security_policy = SECURITY_IEEE_802_1X;
+#ifdef CONFIG_WEP
bss->ssid.wep.default_len = bss->default_wep_key_len;
if (full_config && bss->default_wep_key_len) {
cipher = bss->default_wep_key_len >= 13 ?
@@ -1390,11 +1412,13 @@ void hostapd_set_security_params(struct hostapd_bss_config *bss,
else
cipher = WPA_CIPHER_WEP40;
}
+#endif /* CONFIG_WEP */
bss->wpa_group = cipher;
bss->wpa_pairwise = cipher;
bss->rsn_pairwise = cipher;
if (full_config)
bss->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
+#ifdef CONFIG_WEP
} else if (bss->ssid.wep.keys_set) {
int cipher = WPA_CIPHER_WEP40;
if (bss->ssid.wep.len[0] >= 13)
@@ -1405,6 +1429,7 @@ void hostapd_set_security_params(struct hostapd_bss_config *bss,
bss->rsn_pairwise = cipher;
if (full_config)
bss->wpa_key_mgmt = WPA_KEY_MGMT_NONE;
+#endif /* CONFIG_WEP */
} else if (bss->osen) {
bss->ssid.security_policy = SECURITY_OSEN;
bss->wpa_group = WPA_CIPHER_CCMP;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index b6e11f2..2a0bf07 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -67,6 +67,7 @@ struct hostapd_radius_servers;
struct ft_remote_r0kh;
struct ft_remote_r1kh;
+#ifdef CONFIG_WEP
#define NUM_WEP_KEYS 4
struct hostapd_wep_keys {
u8 idx;
@@ -75,10 +76,13 @@ struct hostapd_wep_keys {
int keys_set;
size_t default_len; /* key length used for dynamic key generation */
};
+#endif /* CONFIG_WEP */
typedef enum hostap_security_policy {
SECURITY_PLAINTEXT = 0,
+#ifdef CONFIG_WEP
SECURITY_STATIC_WEP = 1,
+#endif /* CONFIG_WEP */
SECURITY_IEEE_802_1X = 2,
SECURITY_WPA_PSK = 3,
SECURITY_WPA = 4,
@@ -102,7 +106,9 @@ struct hostapd_ssid {
char *wpa_psk_file;
struct sae_pt *pt;
+#ifdef CONFIG_WEP
struct hostapd_wep_keys wep;
+#endif /* CONFIG_WEP */
#define DYNAMIC_VLAN_DISABLED 0
#define DYNAMIC_VLAN_OPTIONAL 1
@@ -321,10 +327,12 @@ struct hostapd_bss_config {
size_t eap_req_id_text_len;
int eapol_key_index_workaround;
+#ifdef CONFIG_WEP
size_t default_wep_key_len;
int individual_wep_key_len;
int wep_rekeying_period;
int broadcast_key_idx_min, broadcast_key_idx_max;
+#endif /* CONFIG_WEP */
int eap_reauth_period;
int erp_send_reauth_start;
char *erp_domain;
@@ -346,6 +354,7 @@ struct hostapd_bss_config {
* algorithms, WPA_AUTH_ALG_{OPEN,SHARED,LEAP} */
int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */
+ int extended_key_id;
int wpa_key_mgmt;
enum mfp_options ieee80211w;
int group_mgmt_cipher;
@@ -669,9 +678,14 @@ struct hostapd_bss_config {
struct wpabuf *own_ie_override;
int sae_reflection_attack;
struct wpabuf *sae_commit_override;
+ struct wpabuf *rsne_override_eapol;
struct wpabuf *rsnxe_override_eapol;
+ struct wpabuf *rsne_override_ft;
+ struct wpabuf *rsnxe_override_ft;
struct wpabuf *gtk_rsc_override;
struct wpabuf *igtk_rsc_override;
+ int no_beacon_rsnxe;
+ int skip_prune_assoc;
#endif /* CONFIG_TESTING_OPTIONS */
#define MESH_ENABLED BIT(0)
@@ -727,6 +741,8 @@ struct hostapd_bss_config {
struct wpabuf *dpp_csign;
#ifdef CONFIG_DPP2
struct dpp_controller_conf *dpp_controller;
+ int dpp_configurator_connectivity;
+ int dpp_pfs;
#endif /* CONFIG_DPP2 */
#endif /* CONFIG_DPP */
@@ -743,6 +759,8 @@ struct hostapd_bss_config {
u8 send_probe_response;
+ u8 transition_disable;
+
#define BACKHAUL_BSS 1
#define FRONTHAUL_BSS 2
int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index c217d9b..1f284f0 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -588,7 +588,7 @@ int hostapd_set_frag(struct hostapd_data *hapd, int frag)
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
int total_flags, int flags_or, int flags_and)
{
- if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
+ if (!hapd->driver || !hapd->drv_priv || !hapd->driver->sta_set_flags)
return 0;
return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
flags_or, flags_and);
@@ -714,7 +714,7 @@ int hostapd_drv_send_mlme(struct hostapd_data *hapd,
if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
return 0;
return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
- csa_offs, csa_offs_len, no_encrypt);
+ csa_offs, csa_offs_len, no_encrypt, 0);
}
@@ -938,6 +938,7 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
}
params.freq_list = freq_list;
+ params.edmg_enabled = hapd->iface->conf->enable_edmg;
params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index f5de177..47ced9a 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -323,6 +323,12 @@ static u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len)
{
const u8 *ie;
+#ifdef CONFIG_TESTING_OPTIONS
+ if (hapd->conf->no_beacon_rsnxe) {
+ wpa_printf(MSG_INFO, "TESTING: Do not add RSNXE into Beacon");
+ return pos;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
if (!ie || 2U + ie[1] > len)
return pos;
@@ -462,6 +468,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
buflen += hostapd_mbo_ie_len(hapd);
buflen += hostapd_eid_owe_trans_len(hapd);
+ buflen += hostapd_eid_dpp_cc_len(hapd);
resp = os_zalloc(buflen);
if (resp == NULL)
@@ -606,6 +613,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
pos = hostapd_eid_owe_trans(hapd, pos, (u8 *) resp + buflen - pos);
+ pos = hostapd_eid_dpp_cc(hapd, pos, (u8 *) resp + buflen - pos);
if (hapd->conf->vendor_elements) {
os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
@@ -1158,6 +1166,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
tail_len += hostapd_mbo_ie_len(hapd);
tail_len += hostapd_eid_owe_trans_len(hapd);
+ tail_len += hostapd_eid_dpp_cc_len(hapd);
tailpos = tail = os_malloc(tail_len);
if (head == NULL || tail == NULL) {
@@ -1322,6 +1331,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos);
tailpos = hostapd_eid_owe_trans(hapd, tailpos,
tail + tail_len - tailpos);
+ tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos);
if (hapd->conf->vendor_elements) {
os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
@@ -1360,10 +1370,13 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
params->key_mgmt_suites = hapd->conf->wpa_key_mgmt;
params->auth_algs = hapd->conf->auth_algs;
params->wpa_version = hapd->conf->wpa;
- params->privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa ||
+ params->privacy = hapd->conf->wpa;
+#ifdef CONFIG_WEP
+ params->privacy |= hapd->conf->ssid.wep.keys_set ||
(hapd->conf->ieee802_1x &&
(hapd->conf->default_wep_key_len ||
hapd->conf->individual_wep_key_len));
+#endif /* CONFIG_WEP */
switch (hapd->conf->ignore_broadcast_ssid) {
case 0:
params->hide_ssid = NO_SSID_HIDING;
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index f70ecc9..3c078b9 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -144,30 +144,44 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
int i;
u32 bw = num_chan_to_bw(num_chans);
- if (first_chan_idx + num_chans > mode->num_channels)
+ if (first_chan_idx + num_chans > mode->num_channels) {
+ wpa_printf(MSG_DEBUG,
+ "DFS: some channels in range not defined");
return 0;
+ }
first_chan = &mode->channels[first_chan_idx];
/* hostapd DFS implementation assumes the first channel as primary.
* If it's not allowed to use the first channel as primary, decline the
* whole channel range. */
- if (!chan_pri_allowed(first_chan))
+ if (!chan_pri_allowed(first_chan)) {
+ wpa_printf(MSG_DEBUG, "DFS: primary chanenl not allowed");
return 0;
+ }
for (i = 0; i < num_chans; i++) {
chan = dfs_get_chan_data(mode, first_chan->freq + i * 20,
first_chan_idx);
- if (!chan)
+ if (!chan) {
+ wpa_printf(MSG_DEBUG, "DFS: no channel data for %d",
+ first_chan->freq + i * 20);
return 0;
+ }
/* HT 40 MHz secondary channel availability checked only for
* primary channel */
- if (!chan_bw_allowed(chan, bw, 1, !i))
+ if (!chan_bw_allowed(chan, bw, 1, !i)) {
+ wpa_printf(MSG_DEBUG, "DFS: bw now allowed for %d",
+ first_chan->freq + i * 20);
return 0;
+ }
- if (!dfs_channel_available(chan, skip_radar))
+ if (!dfs_channel_available(chan, skip_radar)) {
+ wpa_printf(MSG_DEBUG, "DFS: channel not available %d",
+ first_chan->freq + i * 20);
return 0;
+ }
}
return 1;
@@ -210,22 +224,36 @@ static int dfs_find_channel(struct hostapd_iface *iface,
if (iface->conf->ieee80211n &&
iface->conf->secondary_channel &&
(!dfs_is_chan_allowed(chan, n_chans) ||
- !(chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)))
+ !(chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P))) {
+ wpa_printf(MSG_DEBUG,
+ "DFS: channel %d (%d) is incompatible",
+ chan->freq, chan->chan);
continue;
+ }
/* Skip incompatible chandefs */
- if (!dfs_chan_range_available(mode, i, n_chans, skip_radar))
+ if (!dfs_chan_range_available(mode, i, n_chans, skip_radar)) {
+ wpa_printf(MSG_DEBUG,
+ "DFS: range not available for %d (%d)",
+ chan->freq, chan->chan);
continue;
+ }
- if (!is_in_chanlist(iface, chan))
+ if (!is_in_chanlist(iface, chan)) {
+ wpa_printf(MSG_DEBUG,
+ "DFS: channel %d (%d) not in chanlist",
+ chan->freq, chan->chan);
continue;
+ }
if (ret_chan && idx == channel_idx) {
- wpa_printf(MSG_DEBUG, "Selected ch. #%d", chan->chan);
+ wpa_printf(MSG_DEBUG, "Selected channel %d (%d)",
+ chan->freq, chan->chan);
*ret_chan = chan;
return idx;
}
- wpa_printf(MSG_DEBUG, "Adding channel: %d", chan->chan);
+ wpa_printf(MSG_DEBUG, "Adding channel %d (%d)",
+ chan->freq, chan->chan);
channel_idx++;
}
return channel_idx;
@@ -235,6 +263,7 @@ static int dfs_find_channel(struct hostapd_iface *iface,
static void dfs_adjust_center_freq(struct hostapd_iface *iface,
struct hostapd_channel_data *chan,
int secondary_channel,
+ int sec_chan_idx_80p80,
u8 *oper_centr_freq_seg0_idx,
u8 *oper_centr_freq_seg1_idx)
{
@@ -261,8 +290,14 @@ static void dfs_adjust_center_freq(struct hostapd_iface *iface,
case CHANWIDTH_160MHZ:
*oper_centr_freq_seg0_idx = chan->chan + 14;
break;
+ case CHANWIDTH_80P80MHZ:
+ *oper_centr_freq_seg0_idx = chan->chan + 6;
+ *oper_centr_freq_seg1_idx = sec_chan_idx_80p80 + 6;
+ break;
+
default:
- wpa_printf(MSG_INFO, "DFS only VHT20/40/80/160 is supported now");
+ wpa_printf(MSG_INFO,
+ "DFS: Unsupported channel width configuration");
*oper_centr_freq_seg0_idx = 0;
break;
}
@@ -441,8 +476,11 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
{
struct hostapd_hw_modes *mode;
struct hostapd_channel_data *chan = NULL;
+ struct hostapd_channel_data *chan2 = NULL;
int num_available_chandefs;
- int chan_idx;
+ int chan_idx, chan_idx2;
+ int sec_chan_idx_80p80 = -1;
+ int i;
u32 _rand;
wpa_printf(MSG_DEBUG, "DFS: Selecting random channel");
@@ -459,6 +497,8 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
/* Get the count first */
num_available_chandefs = dfs_find_channel(iface, NULL, 0, skip_radar);
+ wpa_printf(MSG_DEBUG, "DFS: num_available_chandefs=%d",
+ num_available_chandefs);
if (num_available_chandefs == 0)
return NULL;
@@ -466,6 +506,12 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
return NULL;
chan_idx = _rand % num_available_chandefs;
dfs_find_channel(iface, &chan, chan_idx, skip_radar);
+ if (!chan) {
+ wpa_printf(MSG_DEBUG, "DFS: no random channel found");
+ return NULL;
+ }
+ wpa_printf(MSG_DEBUG, "DFS: got random channel %d (%d)",
+ chan->freq, chan->chan);
/* dfs_find_channel() calculations assume HT40+ */
if (iface->conf->secondary_channel)
@@ -473,8 +519,45 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
else
*secondary_channel = 0;
+ /* Get secondary channel for HT80P80 */
+ if (hostapd_get_oper_chwidth(iface->conf) == CHANWIDTH_80P80MHZ) {
+ if (num_available_chandefs <= 1) {
+ wpa_printf(MSG_ERROR,
+ "only 1 valid chan, can't support 80+80");
+ return NULL;
+ }
+
+ /*
+ * Loop all channels except channel1 to find a valid channel2
+ * that is not adjacent to channel1.
+ */
+ for (i = 0; i < num_available_chandefs - 1; i++) {
+ /* start from chan_idx + 1, end when chan_idx - 1 */
+ chan_idx2 = (chan_idx + 1 + i) % num_available_chandefs;
+ dfs_find_channel(iface, &chan2, chan_idx2, skip_radar);
+ if (chan2 && abs(chan2->chan - chan->chan) > 12) {
+ /* two channels are not adjacent */
+ sec_chan_idx_80p80 = chan2->chan;
+ wpa_printf(MSG_DEBUG,
+ "DFS: got second chan: %d (%d)",
+ chan2->freq, chan2->chan);
+ break;
+ }
+ }
+
+ /* Check if we got a valid secondary channel which is not
+ * adjacent to the first channel.
+ */
+ if (sec_chan_idx_80p80 == -1) {
+ wpa_printf(MSG_INFO,
+ "DFS: failed to get chan2 for 80+80");
+ return NULL;
+ }
+ }
+
dfs_adjust_center_freq(iface, chan,
*secondary_channel,
+ sec_chan_idx_80p80,
oper_centr_freq_seg0_idx,
oper_centr_freq_seg1_idx);
@@ -773,7 +856,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
}
-static int hostapd_config_dfs_chan_available(struct hostapd_iface *iface)
+int hostapd_is_dfs_chan_available(struct hostapd_iface *iface)
{
int n_chans, n_chans1, start_chan_idx, start_chan_idx1;
@@ -821,7 +904,7 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
* another radio.
*/
if (iface->state != HAPD_IFACE_ENABLED &&
- hostapd_config_dfs_chan_available(iface)) {
+ hostapd_is_dfs_chan_available(iface)) {
hostapd_setup_interface_complete(iface, 0);
iface->cac_started = 0;
}
@@ -851,6 +934,41 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq,
}
+static struct hostapd_channel_data *
+dfs_downgrade_bandwidth(struct hostapd_iface *iface, int *secondary_channel,
+ u8 *oper_centr_freq_seg0_idx,
+ u8 *oper_centr_freq_seg1_idx, int *skip_radar)
+{
+ struct hostapd_channel_data *channel;
+
+ for (;;) {
+ channel = dfs_get_valid_channel(iface, secondary_channel,
+ oper_centr_freq_seg0_idx,
+ oper_centr_freq_seg1_idx,
+ *skip_radar);
+ if (channel) {
+ wpa_printf(MSG_DEBUG, "DFS: Selected channel: %d",
+ channel->chan);
+ return channel;
+ }
+
+ if (*skip_radar) {
+ *skip_radar = 0;
+ } else {
+ if (iface->conf->vht_oper_chwidth == CHANWIDTH_USE_HT)
+ break;
+ *skip_radar = 1;
+ iface->conf->vht_oper_chwidth--;
+ }
+ }
+
+ wpa_printf(MSG_INFO,
+ "%s: no DFS channels left, waiting for NOP to finish",
+ __func__);
+ return NULL;
+}
+
+
static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
{
struct hostapd_channel_data *channel;
@@ -868,8 +986,14 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
skip_radar);
if (!channel) {
- wpa_printf(MSG_ERROR, "No valid channel available");
- return err;
+ channel = dfs_downgrade_bandwidth(iface, &secondary_channel,
+ &oper_centr_freq_seg0_idx,
+ &oper_centr_freq_seg1_idx,
+ &skip_radar);
+ if (!channel) {
+ wpa_printf(MSG_ERROR, "No valid channel available");
+ return err;
+ }
}
wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
@@ -898,11 +1022,13 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
int secondary_channel;
u8 oper_centr_freq_seg0_idx;
u8 oper_centr_freq_seg1_idx;
+ u8 new_vht_oper_chwidth;
int skip_radar = 1;
struct csa_settings csa_settings;
unsigned int i;
int err = 1;
struct hostapd_hw_modes *cmode = iface->current_mode;
+ u8 current_vht_oper_chwidth = iface->conf->vht_oper_chwidth;
wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
__func__, iface->cac_started ? "yes" : "no",
@@ -936,28 +1062,25 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
* requires to perform a CAC first.
*/
skip_radar = 0;
- channel = dfs_get_valid_channel(iface, &secondary_channel,
- &oper_centr_freq_seg0_idx,
- &oper_centr_freq_seg1_idx,
- skip_radar);
- if (!channel) {
- wpa_printf(MSG_INFO,
- "%s: no DFS channels left, waiting for NOP to finish",
- __func__);
+ channel = dfs_downgrade_bandwidth(iface, &secondary_channel,
+ &oper_centr_freq_seg0_idx,
+ &oper_centr_freq_seg1_idx,
+ &skip_radar);
+ if (!channel)
return err;
+ if (!skip_radar) {
+ iface->freq = channel->freq;
+ iface->conf->channel = channel->chan;
+ iface->conf->secondary_channel = secondary_channel;
+ hostapd_set_oper_centr_freq_seg0_idx(
+ iface->conf, oper_centr_freq_seg0_idx);
+ hostapd_set_oper_centr_freq_seg1_idx(
+ iface->conf, oper_centr_freq_seg1_idx);
+
+ hostapd_disable_iface(iface);
+ hostapd_enable_iface(iface);
+ return 0;
}
-
- iface->freq = channel->freq;
- iface->conf->channel = channel->chan;
- iface->conf->secondary_channel = secondary_channel;
- hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
- oper_centr_freq_seg0_idx);
- hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
- oper_centr_freq_seg1_idx);
-
- hostapd_disable_iface(iface);
- hostapd_enable_iface(iface);
- return 0;
}
wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
@@ -966,6 +1089,9 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
"freq=%d chan=%d sec_chan=%d", channel->freq,
channel->chan, secondary_channel);
+ new_vht_oper_chwidth = iface->conf->vht_oper_chwidth;
+ iface->conf->vht_oper_chwidth = current_vht_oper_chwidth;
+
/* Setup CSA request */
os_memset(&csa_settings, 0, sizeof(csa_settings));
csa_settings.cs_count = 5;
@@ -980,7 +1106,7 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
iface->conf->ieee80211ac,
iface->conf->ieee80211ax,
secondary_channel,
- hostapd_get_oper_chwidth(iface->conf),
+ new_vht_oper_chwidth,
oper_centr_freq_seg0_idx,
oper_centr_freq_seg1_idx,
cmode->vht_capab,
@@ -1004,6 +1130,7 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
iface->freq = channel->freq;
iface->conf->channel = channel->chan;
iface->conf->secondary_channel = secondary_channel;
+ iface->conf->vht_oper_chwidth = new_vht_oper_chwidth;
hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
oper_centr_freq_seg0_idx);
hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
@@ -1040,8 +1167,10 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
return 0;
/* mark radar frequency as invalid */
- set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width,
- cf1, cf2, HOSTAPD_CHAN_DFS_UNAVAILABLE);
+ res = set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width,
+ cf1, cf2, HOSTAPD_CHAN_DFS_UNAVAILABLE);
+ if (!res)
+ return 0;
/* Skip if reported radar event not overlapped our channels */
res = dfs_are_channels_overlapped(iface, freq, chan_width, cf1, cf2);
@@ -1161,3 +1290,56 @@ int hostapd_handle_dfs_offload(struct hostapd_iface *iface)
__func__, iface->freq);
return 2;
}
+
+
+int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+ int center_freq)
+{
+ struct hostapd_channel_data *chan;
+ struct hostapd_hw_modes *mode = iface->current_mode;
+ int half_width;
+ int res = 0;
+ int i;
+
+ if (!iface->conf->ieee80211h || !mode ||
+ mode->mode != HOSTAPD_MODE_IEEE80211A)
+ return 0;
+
+ switch (width) {
+ case CHAN_WIDTH_20_NOHT:
+ case CHAN_WIDTH_20:
+ half_width = 10;
+ break;
+ case CHAN_WIDTH_40:
+ half_width = 20;
+ break;
+ case CHAN_WIDTH_80:
+ case CHAN_WIDTH_80P80:
+ half_width = 40;
+ break;
+ case CHAN_WIDTH_160:
+ half_width = 80;
+ break;
+ default:
+ wpa_printf(MSG_WARNING, "DFS chanwidth %d not supported",
+ width);
+ return 0;
+ }
+
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
+
+ if (!(chan->flag & HOSTAPD_CHAN_RADAR))
+ continue;
+
+ if (center_freq - chan->freq < half_width &&
+ chan->freq - center_freq < half_width)
+ res++;
+ }
+
+ wpa_printf(MSG_DEBUG, "DFS: (%d, %d): in range: %s",
+ center_freq - half_width, center_freq + half_width,
+ res ? "yes" : "no");
+
+ return res;
+}
diff --git a/src/ap/dfs.h b/src/ap/dfs.h
index f0fa6f6..606c1b3 100644
--- a/src/ap/dfs.h
+++ b/src/ap/dfs.h
@@ -25,9 +25,12 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
int ht_enabled,
int chan_offset, int chan_width, int cf1, int cf2);
int hostapd_is_dfs_required(struct hostapd_iface *iface);
+int hostapd_is_dfs_chan_available(struct hostapd_iface *iface);
int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
int ht_enabled, int chan_offset, int chan_width,
int cf1, int cf2);
int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
+int hostapd_is_dfs_overlap(struct hostapd_iface *iface, enum chan_width width,
+ int center_freq);
#endif /* DFS_H */
diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
index 8e22c8b..c86f01b 100644
--- a/src/ap/dpp_hostapd.c
+++ b/src/ap/dpp_hostapd.c
@@ -543,15 +543,15 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
dpp_auth_deinit(hapd->dpp_auth);
}
- hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi,
+ hapd->dpp_auth = dpp_auth_init(hapd->iface->interfaces->dpp,
+ hapd->msg_ctx, peer_bi, own_bi,
allowed_roles, neg_freq,
hapd->iface->hw_features,
hapd->iface->num_hw_features);
if (!hapd->dpp_auth)
goto fail;
hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
- if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
- hapd->dpp_auth, cmd) < 0) {
+ if (dpp_set_configurator(hapd->dpp_auth, cmd) < 0) {
dpp_auth_deinit(hapd->dpp_auth);
hapd->dpp_auth = NULL;
goto fail;
@@ -663,7 +663,8 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
}
hapd->dpp_auth_ok_on_ack = 0;
- hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles,
+ hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
+ hapd->msg_ctx, hapd->dpp_allowed_roles,
hapd->dpp_qr_mutual,
peer_bi, own_bi, freq, hdr, buf, len);
if (!hapd->dpp_auth) {
@@ -671,8 +672,7 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
return;
}
hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
- if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
- hapd->dpp_auth,
+ if (dpp_set_configurator(hapd->dpp_auth,
hapd->dpp_configurator_params) < 0) {
dpp_auth_deinit(hapd->dpp_auth);
hapd->dpp_auth = NULL;
@@ -708,7 +708,8 @@ static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
* message. */
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
conf->connector);
- } else if (conf->passphrase[0]) {
+ }
+ if (conf->passphrase[0]) {
char hex[64 * 2 + 1];
wpa_snprintf_hex(hex, sizeof(hex),
@@ -1132,6 +1133,70 @@ static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
}
+static void
+hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
+ const u8 *hdr, const u8 *buf, size_t len,
+ unsigned int freq)
+{
+ const u8 *r_bootstrap;
+ u16 r_bootstrap_len;
+ struct dpp_bootstrap_info *peer_bi;
+ struct dpp_authentication *auth;
+
+ wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
+ MAC2STR(src));
+
+ r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
+ &r_bootstrap_len);
+ if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
+ wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
+ "Missing or invalid required Responder Bootstrapping Key Hash attribute");
+ return;
+ }
+ wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
+ r_bootstrap, r_bootstrap_len);
+ peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
+ r_bootstrap);
+ if (!peer_bi) {
+ if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
+ src, hdr, buf, len, freq, NULL,
+ r_bootstrap) == 0)
+ return;
+ wpa_printf(MSG_DEBUG,
+ "DPP: No matching bootstrapping information found");
+ return;
+ }
+
+ if (hapd->dpp_auth) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: Ignore Presence Announcement during ongoing Authentication");
+ return;
+ }
+
+ auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
+ peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
+ 0);
+ if (!auth)
+ return;
+ hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
+ if (dpp_set_configurator(hapd->dpp_auth,
+ hapd->dpp_configurator_params) < 0) {
+ dpp_auth_deinit(auth);
+ return;
+ }
+
+ auth->neg_freq = freq;
+
+ if (!is_zero_ether_addr(peer_bi->mac_addr))
+ os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
+
+ hapd->dpp_auth = auth;
+ if (hostapd_dpp_auth_init_next(hapd) < 0) {
+ dpp_auth_deinit(hapd->dpp_auth);
+ hapd->dpp_auth = NULL;
+ }
+}
+
#endif /* CONFIG_DPP2 */
@@ -1581,6 +1646,10 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
case DPP_PA_CONNECTION_STATUS_RESULT:
hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
break;
+ case DPP_PA_PRESENCE_ANNOUNCEMENT:
+ hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
+ freq);
+ break;
#endif /* CONFIG_DPP2 */
default:
wpa_printf(MSG_DEBUG,
@@ -1675,14 +1744,13 @@ int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
int ret = -1;
char *curve = NULL;
- auth = os_zalloc(sizeof(*auth));
+ auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
if (!auth)
return -1;
curve = get_param(cmd, " curve=");
hostapd_dpp_set_testing_options(hapd, auth);
- if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
- auth, cmd) == 0 &&
+ if (dpp_set_configurator(auth, cmd) == 0 &&
dpp_configurator_own_config(auth, curve, 1) == 0) {
hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
ret = 0;
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 61e56b6..559bb87 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -109,7 +109,8 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
const u8 *req_ies, size_t req_ies_len, int reassoc)
{
struct sta_info *sta;
- int new_assoc, res;
+ int new_assoc;
+ enum wpa_validate_result res;
struct ieee802_11_elems elems;
const u8 *ie;
size_t ielen;
@@ -323,33 +324,67 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
elems.rsnxe ? elems.rsnxe_len + 2 : 0,
elems.mdie, elems.mdie_len,
elems.owe_dh, elems.owe_dh_len);
- if (res != WPA_IE_OK) {
+ reason = WLAN_REASON_INVALID_IE;
+ status = WLAN_STATUS_INVALID_IE;
+ switch (res) {
+ case WPA_IE_OK:
+ reason = WLAN_REASON_UNSPECIFIED;
+ status = WLAN_STATUS_SUCCESS;
+ break;
+ case WPA_INVALID_IE:
+ reason = WLAN_REASON_INVALID_IE;
+ status = WLAN_STATUS_INVALID_IE;
+ break;
+ case WPA_INVALID_GROUP:
+ reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
+ status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
+ break;
+ case WPA_INVALID_PAIRWISE:
+ reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
+ status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
+ break;
+ case WPA_INVALID_AKMP:
+ reason = WLAN_REASON_AKMP_NOT_VALID;
+ status = WLAN_STATUS_AKMP_NOT_VALID;
+ break;
+ case WPA_NOT_ENABLED:
+ reason = WLAN_REASON_INVALID_IE;
+ status = WLAN_STATUS_INVALID_IE;
+ break;
+ case WPA_ALLOC_FAIL:
+ reason = WLAN_REASON_UNSPECIFIED;
+ status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ break;
+ case WPA_MGMT_FRAME_PROTECTION_VIOLATION:
+ reason = WLAN_REASON_INVALID_IE;
+ status = WLAN_STATUS_INVALID_IE;
+ break;
+ case WPA_INVALID_MGMT_GROUP_CIPHER:
+ reason = WLAN_REASON_CIPHER_SUITE_REJECTED;
+ status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
+ break;
+ case WPA_INVALID_MDIE:
+ reason = WLAN_REASON_INVALID_MDE;
+ status = WLAN_STATUS_INVALID_MDIE;
+ break;
+ case WPA_INVALID_PROTO:
+ reason = WLAN_REASON_INVALID_IE;
+ status = WLAN_STATUS_INVALID_IE;
+ break;
+ case WPA_INVALID_PMKID:
+ reason = WLAN_REASON_INVALID_PMKID;
+ status = WLAN_STATUS_INVALID_PMKID;
+ break;
+ case WPA_DENIED_OTHER_REASON:
+ reason = WLAN_REASON_UNSPECIFIED;
+ status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
+ break;
+ }
+ if (status != WLAN_STATUS_SUCCESS) {
wpa_printf(MSG_DEBUG,
"WPA/RSN information element rejected? (res %u)",
res);
wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
- if (res == WPA_INVALID_GROUP) {
- reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
- status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
- } else if (res == WPA_INVALID_PAIRWISE) {
- reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
- status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
- } else if (res == WPA_INVALID_AKMP) {
- reason = WLAN_REASON_AKMP_NOT_VALID;
- status = WLAN_STATUS_AKMP_NOT_VALID;
- } else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) {
- reason = WLAN_REASON_INVALID_IE;
- status = WLAN_STATUS_INVALID_IE;
- } else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) {
- reason = WLAN_REASON_CIPHER_SUITE_REJECTED;
- status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
- } else if (res == WPA_INVALID_PMKID) {
- reason = WLAN_REASON_INVALID_PMKID;
- status = WLAN_STATUS_INVALID_PMKID;
- } else {
- reason = WLAN_REASON_INVALID_IE;
- status = WLAN_STATUS_INVALID_IE;
- }
goto fail;
}
@@ -483,7 +518,8 @@ skip_wpa_check:
#ifdef CONFIG_IEEE80211R_AP
p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf),
- sta->auth_alg, req_ies, req_ies_len);
+ sta->auth_alg, req_ies, req_ies_len,
+ !elems.rsnxe);
if (!p) {
wpa_printf(MSG_DEBUG, "FT: Failed to write AssocResp IEs");
return WLAN_STATUS_UNSPECIFIED_FAILURE;
@@ -711,6 +747,7 @@ void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
ap_sta_set_authorized(hapd, sta, 0);
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
+ hostapd_set_sta_flags(hapd, sta);
wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
@@ -908,6 +945,12 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
"freq=%d dfs=%d", freq, is_dfs);
+ } else if (is_dfs &&
+ hostapd_is_dfs_required(hapd->iface) &&
+ !hostapd_is_dfs_chan_available(hapd->iface) &&
+ !hapd->iface->cac_started) {
+ hostapd_disable_iface(hapd->iface);
+ hostapd_enable_iface(hapd->iface);
}
for (i = 0; i < hapd->iface->num_bss; i++)
@@ -1007,6 +1050,8 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
goto out;
}
+ hapd->iconf->edmg_channel = acs_res->edmg_channel;
+
if (hapd->iface->conf->ieee80211ac || hapd->iface->conf->ieee80211ax) {
/* set defaults for backwards compatibility */
hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, 0);
@@ -1429,15 +1474,33 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
#endif /* HOSTAPD */
+static struct hostapd_channel_data *
+hostapd_get_mode_chan(struct hostapd_hw_modes *mode, unsigned int freq)
+{
+ int i;
+ struct hostapd_channel_data *chan;
+
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
+ if ((unsigned int) chan->freq == freq)
+ return chan;
+ }
+
+ return NULL;
+}
+
+
static struct hostapd_channel_data * hostapd_get_mode_channel(
struct hostapd_iface *iface, unsigned int freq)
{
int i;
struct hostapd_channel_data *chan;
- for (i = 0; i < iface->current_mode->num_channels; i++) {
- chan = &iface->current_mode->channels[i];
- if ((unsigned int) chan->freq == freq)
+ for (i = 0; i < iface->num_hw_features; i++) {
+ if (hostapd_hw_skip_mode(iface, &iface->hw_features[i]))
+ continue;
+ chan = hostapd_get_mode_chan(&iface->hw_features[i], freq);
+ if (chan)
return chan;
}
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index ccf3f88..f2e964a 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -58,8 +58,10 @@
static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
+#ifdef CONFIG_WEP
static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
+#endif /* CONFIG_WEP */
static int setup_interface2(struct hostapd_iface *iface);
static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx);
static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
@@ -89,7 +91,9 @@ void hostapd_reconfig_encryption(struct hostapd_data *hapd)
return;
hostapd_set_privacy(hapd, 0);
+#ifdef CONFIG_WEP
hostapd_setup_encryption(hapd->conf->iface, hapd);
+#endif /* CONFIG_WEP */
}
@@ -142,7 +146,9 @@ static void hostapd_reload_bss(struct hostapd_data *hapd)
wpa_deinit(hapd->wpa_auth);
hapd->wpa_auth = NULL;
hostapd_set_privacy(hapd, 0);
+#ifdef CONFIG_WEP
hostapd_setup_encryption(hapd->conf->iface, hapd);
+#endif /* CONFIG_WEP */
hostapd_set_generic_elem(hapd, (u8 *) "", 0);
}
@@ -170,7 +176,9 @@ static void hostapd_clear_old(struct hostapd_iface *iface)
for (j = 0; j < iface->num_bss; j++) {
hostapd_flush_old_stations(iface->bss[j],
WLAN_REASON_PREV_AUTH_NOT_VALID);
+#ifdef CONFIG_WEP
hostapd_broadcast_wep_clear(iface->bss[j]);
+#endif /* CONFIG_WEP */
#ifndef CONFIG_NO_RADIUS
/* TODO: update dynamic data based on changed configuration
@@ -284,6 +292,8 @@ int hostapd_reload_config(struct hostapd_iface *iface)
}
+#ifdef CONFIG_WEP
+
static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
const char *ifname)
{
@@ -326,7 +336,7 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
struct hostapd_ssid *ssid = &hapd->conf->ssid;
idx = ssid->wep.idx;
- if (ssid->wep.default_len &&
+ if (ssid->wep.default_len && ssid->wep.key[idx] &&
hostapd_drv_set_key(hapd->conf->iface,
hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 0,
1, NULL, 0, ssid->wep.key[idx],
@@ -339,6 +349,8 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
return errors;
}
+#endif /* CONFIG_WEP */
+
static void hostapd_free_hapd_data(struct hostapd_data *hapd)
{
@@ -524,6 +536,8 @@ static void hostapd_cleanup_iface(struct hostapd_iface *iface)
}
+#ifdef CONFIG_WEP
+
static void hostapd_clear_wep(struct hostapd_data *hapd)
{
if (hapd->drv_priv && !hapd->iface->driver_ap_teardown && hapd->conf) {
@@ -571,6 +585,8 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
return 0;
}
+#endif /* CONFIG_WEP */
+
static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
{
@@ -606,7 +622,9 @@ static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
{
hostapd_free_stas(hapd);
hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
+#ifdef CONFIG_WEP
hostapd_clear_wep(hapd);
+#endif /* CONFIG_WEP */
}
@@ -1161,9 +1179,11 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
WLAN_REASON_PREV_AUTH_NOT_VALID);
hostapd_set_privacy(hapd, 0);
+#ifdef CONFIG_WEP
hostapd_broadcast_wep_clear(hapd);
if (hostapd_setup_encryption(conf->iface, hapd))
return -1;
+#endif /* CONFIG_WEP */
/*
* Fetch the SSID from the system and use it or,
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 0b922b9..f6e6903 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -785,7 +785,7 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface)
/* 60 GHz channels 1..6 */
for (i = 0; i < 6; i++) {
- int freq = 56160 + 2160 * i;
+ int freq = 56160 + 2160 * (i + 1);
if (edmg.channels & BIT(i)) {
contiguous++;
@@ -879,10 +879,43 @@ static int hostapd_is_usable_chans(struct hostapd_iface *iface)
}
+static void hostapd_determine_mode(struct hostapd_iface *iface)
+{
+ int i;
+ enum hostapd_hw_mode target_mode;
+
+ if (iface->current_mode ||
+ iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY)
+ return;
+
+ if (iface->freq < 4000)
+ target_mode = HOSTAPD_MODE_IEEE80211G;
+ else if (iface->freq > 50000)
+ target_mode = HOSTAPD_MODE_IEEE80211AD;
+ else
+ target_mode = HOSTAPD_MODE_IEEE80211A;
+
+ for (i = 0; i < iface->num_hw_features; i++) {
+ struct hostapd_hw_modes *mode;
+
+ mode = &iface->hw_features[i];
+ if (mode->mode == target_mode) {
+ iface->current_mode = mode;
+ iface->conf->hw_mode = mode->mode;
+ break;
+ }
+ }
+
+ if (!iface->current_mode)
+ wpa_printf(MSG_ERROR, "ACS: Cannot decide mode");
+}
+
+
static enum hostapd_chan_status
hostapd_check_chans(struct hostapd_iface *iface)
{
if (iface->freq) {
+ hostapd_determine_mode(iface);
if (hostapd_is_usable_chans(iface))
return HOSTAPD_CHAN_VALID;
else
@@ -1008,9 +1041,15 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
}
if (iface->current_mode == NULL) {
- if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) ||
- !(iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY))
- {
+ if ((iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) &&
+ (iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY)) {
+ wpa_printf(MSG_DEBUG,
+ "Using offloaded hw_mode=any ACS");
+ } else if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) &&
+ iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211ANY) {
+ wpa_printf(MSG_DEBUG,
+ "Using internal ACS for hw_mode=any");
+ } else {
wpa_printf(MSG_ERROR,
"Hardware does not support configured mode");
hostapd_logger(iface->bss[0], NULL,
@@ -1085,3 +1124,20 @@ int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
}
return 0;
}
+
+
+int hostapd_hw_skip_mode(struct hostapd_iface *iface,
+ struct hostapd_hw_modes *mode)
+{
+ int i;
+
+ if (iface->current_mode)
+ return mode != iface->current_mode;
+ if (mode->mode != HOSTAPD_MODE_IEEE80211B)
+ return 0;
+ for (i = 0; i < iface->num_hw_features; i++) {
+ if (iface->hw_features[i].mode == HOSTAPD_MODE_IEEE80211G)
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/ap/hw_features.h b/src/ap/hw_features.h
index 6749319..dd24f95 100644
--- a/src/ap/hw_features.h
+++ b/src/ap/hw_features.h
@@ -25,6 +25,8 @@ int hostapd_check_edmg_capab(struct hostapd_iface *iface);
int hostapd_prepare_rates(struct hostapd_iface *iface,
struct hostapd_hw_modes *mode);
void hostapd_stop_setup_timers(struct hostapd_iface *iface);
+int hostapd_hw_skip_mode(struct hostapd_iface *iface,
+ struct hostapd_hw_modes *mode);
#else /* NEED_AP_MLME */
static inline void
hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
@@ -77,6 +79,12 @@ static inline void hostapd_stop_setup_timers(struct hostapd_iface *iface)
{
}
+static inline int hostapd_hw_skip_mode(struct hostapd_iface *iface,
+ struct hostapd_hw_modes *mode)
+{
+ return 0;
+}
+
#endif /* NEED_AP_MLME */
#endif /* HW_FEATURES_H */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 03810de..2a5f6e5 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -223,7 +223,7 @@ u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
u16 hostapd_own_capab_info(struct hostapd_data *hapd)
{
int capab = WLAN_CAPABILITY_ESS;
- int privacy;
+ int privacy = 0;
int dfs;
int i;
@@ -239,12 +239,14 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd)
hapd->iconf->preamble == SHORT_PREAMBLE)
capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+#ifdef CONFIG_WEP
privacy = hapd->conf->ssid.wep.keys_set;
if (hapd->conf->ieee802_1x &&
(hapd->conf->default_wep_key_len ||
hapd->conf->individual_wep_key_len))
privacy = 1;
+#endif /* CONFIG_WEP */
if (hapd->conf->wpa)
privacy = 1;
@@ -284,6 +286,7 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd)
}
+#ifdef CONFIG_WEP
#ifndef CONFIG_NO_RC4
static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
u16 auth_transaction, const u8 *challenge,
@@ -340,6 +343,7 @@ static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
return 0;
}
#endif /* CONFIG_NO_RC4 */
+#endif /* CONFIG_WEP */
static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
@@ -379,7 +383,7 @@ static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
#ifdef CONFIG_SAE
if (hapd->conf->sae_confirm_immediate == 2 &&
auth_alg == WLAN_AUTH_SAE) {
- if (auth_transaction == 1 &&
+ if (auth_transaction == 1 && sta &&
(resp == WLAN_STATUS_SUCCESS ||
resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT)) {
wpa_printf(MSG_DEBUG,
@@ -532,10 +536,13 @@ static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN +
(rx_id ? 3 + os_strlen(rx_id) : 0));
- if (buf == NULL)
- return NULL;
- sae_write_commit(sta->sae, buf, sta->sae->tmp ?
- sta->sae->tmp->anti_clogging_token : NULL, rx_id);
+ if (buf &&
+ sae_write_commit(sta->sae, buf, sta->sae->tmp ?
+ sta->sae->tmp->anti_clogging_token : NULL,
+ rx_id) < 0) {
+ wpabuf_free(buf);
+ buf = NULL;
+ }
return buf;
}
@@ -635,13 +642,15 @@ static int use_sae_anti_clogging(struct hostapd_data *hapd)
}
-static u8 sae_token_hash(struct hostapd_data *hapd, const u8 *addr)
+static int sae_token_hash(struct hostapd_data *hapd, const u8 *addr, u8 *idx)
{
u8 hash[SHA256_MAC_LEN];
- hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
- addr, ETH_ALEN, hash);
- return hash[0];
+ if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
+ addr, ETH_ALEN, hash) < 0)
+ return -1;
+ *idx = hash[0];
+ return 0;
}
@@ -654,9 +663,8 @@ static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
u16 token_idx;
u8 idx;
- if (token_len != SHA256_MAC_LEN)
+ if (token_len != SHA256_MAC_LEN || sae_token_hash(hapd, addr, &idx) < 0)
return -1;
- idx = sae_token_hash(hapd, addr);
token_idx = hapd->sae_pending_token_idx[idx];
if (token_idx == 0 || token_idx != WPA_GET_BE16(token)) {
wpa_printf(MSG_DEBUG, "SAE: Invalid anti-clogging token from "
@@ -720,7 +728,10 @@ static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
wpabuf_put_u8(buf, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN);
}
- p_idx = sae_token_hash(hapd, addr);
+ if (sae_token_hash(hapd, addr, &p_idx) < 0) {
+ wpabuf_free(buf);
+ return NULL;
+ }
token_idx = hapd->sae_pending_token_idx[p_idx];
if (!token_idx) {
hapd->sae_token_idx++;
@@ -1600,27 +1611,37 @@ static int auth_sae_queued_addr(struct hostapd_data *hapd, const u8 *addr)
#endif /* CONFIG_SAE */
-static u16 wpa_res_to_status_code(int res)
+static u16 wpa_res_to_status_code(enum wpa_validate_result res)
{
- if (res == WPA_INVALID_GROUP)
+ switch (res) {
+ case WPA_IE_OK:
+ return WLAN_STATUS_SUCCESS;
+ case WPA_INVALID_IE:
+ return WLAN_STATUS_INVALID_IE;
+ case WPA_INVALID_GROUP:
return WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
- if (res == WPA_INVALID_PAIRWISE)
+ case WPA_INVALID_PAIRWISE:
return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
- if (res == WPA_INVALID_AKMP)
+ case WPA_INVALID_AKMP:
return WLAN_STATUS_AKMP_NOT_VALID;
- if (res == WPA_ALLOC_FAIL)
+ case WPA_NOT_ENABLED:
+ return WLAN_STATUS_INVALID_IE;
+ case WPA_ALLOC_FAIL:
return WLAN_STATUS_UNSPECIFIED_FAILURE;
- if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
+ case WPA_MGMT_FRAME_PROTECTION_VIOLATION:
return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
- if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
+ case WPA_INVALID_MGMT_GROUP_CIPHER:
return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
- if (res == WPA_INVALID_MDIE)
+ case WPA_INVALID_MDIE:
return WLAN_STATUS_INVALID_MDIE;
- if (res == WPA_INVALID_PMKID)
- return WLAN_STATUS_INVALID_PMKID;
- if (res != WPA_IE_OK)
+ case WPA_INVALID_PROTO:
return WLAN_STATUS_INVALID_IE;
- return WLAN_STATUS_SUCCESS;
+ case WPA_INVALID_PMKID:
+ return WLAN_STATUS_INVALID_PMKID;
+ case WPA_DENIED_OTHER_REASON:
+ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
+ }
+ return WLAN_STATUS_INVALID_IE;
}
@@ -1640,7 +1661,7 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
u16 resp = WLAN_STATUS_SUCCESS;
const u8 *end;
struct ieee802_11_elems elems;
- int res;
+ enum wpa_validate_result res;
struct wpa_ie_data rsn;
struct rsn_pmksa_cache_entry *pmksa = NULL;
@@ -1816,11 +1837,11 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
FILS_SESSION_LEN);
os_memcpy(sta->fils_session, elems.fils_session, FILS_SESSION_LEN);
- /* FILS Wrapped Data */
- if (elems.fils_wrapped_data) {
+ /* Wrapped Data */
+ if (elems.wrapped_data) {
wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
- elems.fils_wrapped_data,
- elems.fils_wrapped_data_len);
+ elems.wrapped_data,
+ elems.wrapped_data_len);
if (!pmksa) {
#ifndef CONFIG_NO_RADIUS
if (!sta->eapol_sm) {
@@ -1830,8 +1851,8 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
wpa_printf(MSG_DEBUG,
"FILS: Forward EAP-Initiate/Re-auth to authentication server");
ieee802_1x_encapsulate_radius(
- hapd, sta, elems.fils_wrapped_data,
- elems.fils_wrapped_data_len);
+ hapd, sta, elems.wrapped_data,
+ elems.wrapped_data_len);
sta->fils_pending_cb = cb;
wpa_printf(MSG_DEBUG,
"FILS: Will send Authentication frame once the response from authentication server is available");
@@ -1840,8 +1861,8 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
* to maintain a copy of the EAP-Initiate/Reauth
* message. */
if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta->wpa_sm),
- elems.fils_wrapped_data,
- elems.fils_wrapped_data_len,
+ elems.wrapped_data,
+ elems.wrapped_data_len,
sta->fils_erp_pmkid) == 0)
sta->fils_erp_pmkid_set = 1;
return;
@@ -1984,12 +2005,12 @@ prepare_auth_resp_fils(struct hostapd_data *hapd,
wpabuf_put_u8(data, WLAN_EID_EXT_FILS_SESSION);
wpabuf_put_data(data, sta->fils_session, FILS_SESSION_LEN);
- /* FILS Wrapped Data */
+ /* Wrapped Data */
if (!pmksa && erp_resp) {
wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
wpabuf_put_u8(data, 1 + wpabuf_len(erp_resp)); /* Length */
/* Element ID Extension */
- wpabuf_put_u8(data, WLAN_EID_EXT_FILS_WRAPPED_DATA);
+ wpabuf_put_u8(data, WLAN_EID_EXT_WRAPPED_DATA);
wpabuf_put_buf(data, erp_resp);
if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta->wpa_sm),
@@ -2505,32 +2526,10 @@ static void handle_auth(struct hostapd_data *hapd,
(!(sta->flags & WLAN_STA_MFP) || !ap_sta_is_authorized(sta)) &&
!(hapd->conf->mesh & MESH_ENABLED) &&
!(sta->added_unassoc)) {
- /*
- * If a station that is already associated to the AP, is trying
- * to authenticate again, remove the STA entry, in order to make
- * sure the STA PS state gets cleared and configuration gets
- * updated. To handle this, station's added_unassoc flag is
- * cleared once the station has completed association.
- */
- ap_sta_set_authorized(hapd, sta, 0);
- hostapd_drv_sta_remove(hapd, sta->addr);
- sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_AUTH |
- WLAN_STA_AUTHORIZED);
-
- if (hostapd_sta_add(hapd, sta->addr, 0, 0,
- sta->supported_rates,
- sta->supported_rates_len,
- 0, NULL, NULL, NULL, 0,
- sta->flags, 0, 0, 0, 0)) {
- hostapd_logger(hapd, sta->addr,
- HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_NOTICE,
- "Could not add STA to kernel driver");
+ if (ap_sta_re_add(hapd, sta) < 0) {
resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
goto fail;
}
-
- sta->added_unassoc = 1;
}
switch (auth_alg) {
@@ -2543,6 +2542,7 @@ static void handle_auth(struct hostapd_data *hapd,
sta->auth_alg = WLAN_AUTH_OPEN;
mlme_authenticate_indication(hapd, sta);
break;
+#ifdef CONFIG_WEP
#ifndef CONFIG_NO_RC4
case WLAN_AUTH_SHARED_KEY:
resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
@@ -2561,6 +2561,7 @@ static void handle_auth(struct hostapd_data *hapd,
}
break;
#endif /* CONFIG_NO_RC4 */
+#endif /* CONFIG_WEP */
#ifdef CONFIG_IEEE80211R_AP
case WLAN_AUTH_FT:
sta->auth_alg = WLAN_AUTH_FT;
@@ -3031,7 +3032,7 @@ u16 owe_process_rsn_ie(struct hostapd_data *hapd,
u16 status;
u8 *owe_buf, ie[256 * 2];
size_t ie_len = 0;
- int res;
+ enum wpa_validate_result res;
if (!rsn_ie || rsn_ie_len < 2) {
wpa_printf(MSG_DEBUG, "OWE: No RSNE in (Re)AssocReq");
@@ -3242,7 +3243,8 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
}
if (hapd->conf->wpa && wpa_ie) {
- int res;
+ enum wpa_validate_result res;
+
wpa_ie -= 2;
wpa_ie_len += 2;
if (sta->wpa_sm == NULL)
@@ -3648,7 +3650,8 @@ static int add_associated_sta(struct hostapd_data *hapd,
static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *addr, u16 status_code, int reassoc,
- const u8 *ies, size_t ies_len, int rssi)
+ const u8 *ies, size_t ies_len, int rssi,
+ int omit_rsnxe)
{
int send_len;
u8 *buf;
@@ -3718,7 +3721,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
* Transition Information, RSN, [RIC Response] */
p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
buf + buflen - p,
- sta->auth_alg, ies, ies_len);
+ sta->auth_alg, ies, ies_len,
+ omit_rsnxe);
if (!p) {
wpa_printf(MSG_DEBUG,
"FT: Failed to write AssocResp IEs");
@@ -3797,7 +3801,23 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
}
#endif /* CONFIG_FST */
- p = hostapd_eid_rsnxe(hapd, p, buf + buflen - p);
+#ifdef CONFIG_TESTING_OPTIONS
+ if (hapd->conf->rsnxe_override_ft &&
+ buf + buflen - p >=
+ (long int) wpabuf_len(hapd->conf->rsnxe_override_ft) &&
+ sta && sta->auth_alg == WLAN_AUTH_FT) {
+ wpa_printf(MSG_DEBUG, "TESTING: RSNXE FT override");
+ os_memcpy(p, wpabuf_head(hapd->conf->rsnxe_override_ft),
+ wpabuf_len(hapd->conf->rsnxe_override_ft));
+ p += wpabuf_len(hapd->conf->rsnxe_override_ft);
+ goto rsnxe_done;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+ if (!omit_rsnxe)
+ p = hostapd_eid_rsnxe(hapd, p, buf + buflen - p);
+#ifdef CONFIG_TESTING_OPTIONS
+rsnxe_done:
+#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_OWE
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
@@ -4015,7 +4035,7 @@ void fils_hlp_finish_assoc(struct hostapd_data *hapd, struct sta_info *sta)
reply_res = send_assoc_resp(hapd, sta, sta->addr, WLAN_STATUS_SUCCESS,
sta->fils_pending_assoc_is_reassoc,
sta->fils_pending_assoc_req,
- sta->fils_pending_assoc_req_len, 0);
+ sta->fils_pending_assoc_req_len, 0, 0);
os_free(sta->fils_pending_assoc_req);
sta->fils_pending_assoc_req = NULL;
sta->fils_pending_assoc_req_len = 0;
@@ -4063,6 +4083,7 @@ static void handle_assoc(struct hostapd_data *hapd,
#ifdef CONFIG_FILS
int delay_assoc = 0;
#endif /* CONFIG_FILS */
+ int omit_rsnxe = 0;
if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
sizeof(mgmt->u.assoc_req))) {
@@ -4275,6 +4296,7 @@ static void handle_assoc(struct hostapd_data *hapd,
resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
if (resp != WLAN_STATUS_SUCCESS)
goto fail;
+ omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX);
if (hostapd_get_aid(hapd, sta) < 0) {
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
@@ -4428,7 +4450,7 @@ static void handle_assoc(struct hostapd_data *hapd,
#endif /* CONFIG_FILS */
reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc, pos,
- left, rssi);
+ left, rssi, omit_rsnxe);
os_free(tmp);
/*
@@ -4469,6 +4491,7 @@ static void handle_disassoc(struct hostapd_data *hapd,
ap_sta_set_authorized(hapd, sta, 0);
sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
+ hostapd_set_sta_flags(hapd, sta);
wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_INFO, "disassociated");
@@ -4535,6 +4558,7 @@ static void handle_deauth(struct hostapd_data *hapd,
sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
WLAN_STA_ASSOC_REQ_OK);
+ hostapd_set_sta_flags(hapd, sta);
wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG, "deauthenticated");
@@ -4946,6 +4970,7 @@ static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
struct sta_info *sta,
char *ifname_wds)
{
+#ifdef CONFIG_WEP
int i;
struct hostapd_ssid *ssid = &hapd->conf->ssid;
@@ -4966,6 +4991,7 @@ static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
break;
}
}
+#endif /* CONFIG_WEP */
}
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 181cfaf..c7bdb4b 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -183,6 +183,9 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
size_t hostapd_eid_owe_trans_len(struct hostapd_data *hapd);
u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid, size_t len);
+size_t hostapd_eid_dpp_cc_len(struct hostapd_data *hapd);
+u8 * hostapd_eid_dpp_cc(struct hostapd_data *hapd, u8 *eid, size_t len);
+
int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
int ap_seg1_idx, int *bandwidth, int *seg1_idx);
diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
index 4b23e48..57c6b18 100644
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -421,10 +421,10 @@ int hostapd_get_he_twt_responder(struct hostapd_data *hapd,
u8 *mac_cap;
if (!hapd->iface->current_mode ||
- !hapd->iface->current_mode->he_capab)
+ !hapd->iface->current_mode->he_capab[mode].he_supported)
return 0;
mac_cap = hapd->iface->current_mode->he_capab[mode].mac_cap;
- return mac_cap[HE_MAC_CAPAB_0] & HE_MACCAP_TWT_RESPONDER;
+ return !!(mac_cap[HE_MAC_CAPAB_0] & HE_MACCAP_TWT_RESPONDER);
}
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index a225639..113b4ef 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -874,6 +874,36 @@ u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid,
}
+size_t hostapd_eid_dpp_cc_len(struct hostapd_data *hapd)
+{
+#ifdef CONFIG_DPP2
+ if (hapd->conf->dpp_configurator_connectivity)
+ return 6;
+#endif /* CONFIG_DPP2 */
+ return 0;
+}
+
+
+u8 * hostapd_eid_dpp_cc(struct hostapd_data *hapd, u8 *eid, size_t len)
+{
+#ifdef CONFIG_DPP2
+ u8 *pos = eid;
+
+ if (!hapd->conf->dpp_configurator_connectivity || len < 6)
+ return pos;
+
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = 4;
+ WPA_PUT_BE24(pos, OUI_WFA);
+ pos += 3;
+ *pos++ = DPP_CC_OUI_TYPE;
+
+ return pos;
+#endif /* CONFIG_DPP2 */
+ return eid;
+}
+
+
void ap_copy_sta_supp_op_classes(struct sta_info *sta,
const u8 *supp_op_classes,
size_t supp_op_classes_len)
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 001b261..6d4d435 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -137,6 +137,7 @@ void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
}
+#ifdef CONFIG_WEP
#ifndef CONFIG_FIPS
#ifndef CONFIG_NO_RC4
@@ -297,6 +298,7 @@ static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
#endif /* CONFIG_NO_RC4 */
#endif /* CONFIG_FIPS */
+#endif /* CONFIG_WEP */
const char *radius_mode_txt(struct hostapd_data *hapd)
@@ -2114,6 +2116,8 @@ void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
}
+#ifdef CONFIG_WEP
+
static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd)
{
struct eapol_authenticator *eapol = hapd->eapol_auth;
@@ -2198,6 +2202,8 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
}
}
+#endif /* CONFIG_WEP */
+
static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,
const u8 *data, size_t datalen)
@@ -2361,6 +2367,7 @@ static void _ieee802_1x_abort_auth(void *ctx, void *sta_ctx)
}
+#ifdef CONFIG_WEP
static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx)
{
#ifndef CONFIG_FIPS
@@ -2372,6 +2379,7 @@ static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx)
#endif /* CONFIG_NO_RC4 */
#endif /* CONFIG_FIPS */
}
+#endif /* CONFIG_WEP */
static void ieee802_1x_eapol_event(void *ctx, void *sta_ctx,
@@ -2422,7 +2430,6 @@ static int ieee802_1x_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
int ieee802_1x_init(struct hostapd_data *hapd)
{
- int i;
struct eapol_auth_config conf;
struct eapol_auth_cb cb;
@@ -2433,7 +2440,9 @@ int ieee802_1x_init(struct hostapd_data *hapd)
conf.ctx = hapd;
conf.eap_reauth_period = hapd->conf->eap_reauth_period;
conf.wpa = hapd->conf->wpa;
+#ifdef CONFIG_WEP
conf.individual_wep_key_len = hapd->conf->individual_wep_key_len;
+#endif /* CONFIG_WEP */
conf.eap_req_id_text = hapd->conf->eap_req_id_text;
conf.eap_req_id_text_len = hapd->conf->eap_req_id_text_len;
conf.erp_send_reauth_start = hapd->conf->erp_send_reauth_start;
@@ -2448,7 +2457,9 @@ int ieee802_1x_init(struct hostapd_data *hapd)
cb.logger = ieee802_1x_logger;
cb.set_port_authorized = ieee802_1x_set_port_authorized;
cb.abort_auth = _ieee802_1x_abort_auth;
+#ifdef CONFIG_WEP
cb.tx_key = _ieee802_1x_tx_key;
+#endif /* CONFIG_WEP */
cb.eapol_event = ieee802_1x_eapol_event;
#ifdef CONFIG_ERP
cb.erp_get_key = ieee802_1x_erp_get_key;
@@ -2469,17 +2480,21 @@ int ieee802_1x_init(struct hostapd_data *hapd)
return -1;
#endif /* CONFIG_NO_RADIUS */
+#ifdef CONFIG_WEP
if (hapd->conf->default_wep_key_len) {
+ int i;
+
for (i = 0; i < 4; i++)
hostapd_drv_set_key(hapd->conf->iface, hapd,
WPA_ALG_NONE, NULL, i, 0, 0, NULL,
- 0, NULL, 0, KEY_FLAG_GROUP_RX_TX);
+ 0, NULL, 0, KEY_FLAG_GROUP);
ieee802_1x_rekey(hapd, NULL);
if (!hapd->eapol_auth->default_wep_key)
return -1;
}
+#endif /* CONFIG_WEP */
return 0;
}
@@ -2499,7 +2514,9 @@ void ieee802_1x_erp_flush(struct hostapd_data *hapd)
void ieee802_1x_deinit(struct hostapd_data *hapd)
{
+#ifdef CONFIG_WEP
eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);
+#endif /* CONFIG_WEP */
if (hapd->driver && hapd->drv_priv &&
(hapd->conf->ieee802_1x || hapd->conf->wpa))
diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
index 4012ae4..01bf886 100644
--- a/src/ap/neighbor_db.c
+++ b/src/ap/neighbor_db.c
@@ -256,6 +256,8 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
/* VHT bit added in IEEE P802.11-REVmc/D4.3 */
if (vht)
bssid_info |= NEI_REP_BSSID_INFO_VHT;
+ if (he)
+ bssid_info |= NEI_REP_BSSID_INFO_HE;
}
/* TODO: Set NEI_REP_BSSID_INFO_MOBILITY_DOMAIN if MDE is set */
diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c
index 15e2c49..fe5f817 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -516,6 +516,11 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
for (entry = pmksa->pmksa; entry; entry = entry->next) {
if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
continue;
+ if (wpa_key_mgmt_sae(entry->akmp)) {
+ if (os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0)
+ return entry;
+ continue;
+ }
rsn_pmkid(entry->pmk, entry->pmk_len, aa, spa, new_pmkid,
entry->akmp);
if (os_memcmp(new_pmkid, pmkid, PMKID_LEN) == 0)
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 87a9fd4..93f1f0c 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -164,6 +164,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
/* just in case */
ap_sta_set_authorized(hapd, sta, 0);
+ hostapd_set_sta_flags(hapd, sta);
if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP))
hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
@@ -544,6 +545,7 @@ skip_poll:
case STA_DISASSOC_FROM_CLI:
ap_sta_set_authorized(hapd, sta, 0);
sta->flags &= ~WLAN_STA_ASSOC;
+ hostapd_set_sta_flags(hapd, sta);
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
if (!sta->acct_terminate_cause)
sta->acct_terminate_cause =
@@ -812,6 +814,7 @@ void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
sta->timeout_next = STA_DEAUTH;
}
ap_sta_set_authorized(hapd, sta, 0);
+ hostapd_set_sta_flags(hapd, sta);
wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
"for " MACSTR " (%d seconds - "
"AP_MAX_INACTIVITY_AFTER_DISASSOC)",
@@ -862,6 +865,7 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
ap_sta_set_authorized(hapd, sta, 0);
+ hostapd_set_sta_flags(hapd, sta);
sta->timeout_next = STA_REMOVE;
wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
"for " MACSTR " (%d seconds - "
@@ -1027,6 +1031,13 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta)
int ret;
int old_vlanid = sta->vlan_id_bound;
+ if ((sta->flags & WLAN_STA_WDS) && sta->vlan_id == 0) {
+ wpa_printf(MSG_DEBUG,
+ "Do not override WDS VLAN assignment for STA "
+ MACSTR, MAC2STR(sta->addr));
+ return 0;
+ }
+
iface = hapd->conf->iface;
if (hapd->conf->ssid.vlan[0])
iface = hapd->conf->ssid.vlan;
@@ -1133,6 +1144,8 @@ static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
if (sta->sa_query_count > 0 &&
ap_check_sa_query_timeout(hapd, sta))
return;
+ if (sta->sa_query_count >= 1000)
+ return;
nbuf = os_realloc_array(sta->sa_query_trans_id,
sta->sa_query_count + 1,
@@ -1320,9 +1333,10 @@ void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
if (sta == NULL)
return;
ap_sta_set_authorized(hapd, sta, 0);
+ sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
+ hostapd_set_sta_flags(hapd, sta);
wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
- sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
wpa_printf(MSG_DEBUG, "%s: %s: reschedule ap_handle_timer timeout "
"for " MACSTR " (%d seconds - "
"AP_MAX_INACTIVITY_AFTER_DEAUTH)",
@@ -1483,3 +1497,33 @@ int ap_sta_pending_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
return eloop_is_timeout_registered(ap_sta_delayed_1x_auth_fail_cb,
hapd, sta);
}
+
+
+int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta)
+{
+ /*
+ * If a station that is already associated to the AP, is trying to
+ * authenticate again, remove the STA entry, in order to make sure the
+ * STA PS state gets cleared and configuration gets updated. To handle
+ * this, station's added_unassoc flag is cleared once the station has
+ * completed association.
+ */
+ ap_sta_set_authorized(hapd, sta, 0);
+ hostapd_drv_sta_remove(hapd, sta->addr);
+ sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_AUTH | WLAN_STA_AUTHORIZED);
+
+ if (hostapd_sta_add(hapd, sta->addr, 0, 0,
+ sta->supported_rates,
+ sta->supported_rates_len,
+ 0, NULL, NULL, NULL, 0,
+ sta->flags, 0, 0, 0, 0)) {
+ hostapd_logger(hapd, sta->addr,
+ HOSTAPD_MODULE_IEEE80211,
+ HOSTAPD_LEVEL_NOTICE,
+ "Could not add STA to kernel driver");
+ return -1;
+ }
+
+ sta->added_unassoc = 1;
+ return 0;
+}
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 8ff6ac6..308aa29 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -358,5 +358,6 @@ void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
struct sta_info *sta);
int ap_sta_pending_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
struct sta_info *sta);
+int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta);
#endif /* STA_INFO_H */
diff --git a/src/ap/utils.c b/src/ap/utils.c
index fcb371b..bedad6e 100644
--- a/src/ap/utils.c
+++ b/src/ap/utils.c
@@ -56,6 +56,10 @@ static int prune_associations(struct hostapd_iface *iface, void *ctx)
ohapd = iface->bss[j];
if (ohapd == data->hapd)
continue;
+#ifdef CONFIG_TESTING_OPTIONS
+ if (ohapd->conf->skip_prune_assoc)
+ continue;
+#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_FST
/* Don't prune STAs belong to same FST */
if (ohapd->iface->fst &&
diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c
index e293a00..53eacfb 100644
--- a/src/ap/vlan_init.c
+++ b/src/ap/vlan_init.c
@@ -22,7 +22,9 @@
static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
int existsok)
{
- int ret, i;
+ int ret;
+#ifdef CONFIG_WEP
+ int i;
for (i = 0; i < NUM_WEP_KEYS; i++) {
if (!hapd->conf->ssid.wep.key[i])
@@ -32,6 +34,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
vlan->ifname);
return -1;
}
+#endif /* CONFIG_WEP */
if (!iface_exists(vlan->ifname))
ret = hostapd_vlan_if_add(hapd, vlan->ifname);
diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
index 891f90f..67281b3 100644
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -522,6 +522,30 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
}
+static void wnm_beacon_protection_failure(struct hostapd_data *hapd,
+ const u8 *addr)
+{
+ struct sta_info *sta;
+
+ if (!hapd->conf->beacon_prot)
+ return;
+
+ sta = ap_get_sta(hapd, addr);
+ if (!sta || !(sta->flags & WLAN_STA_AUTHORIZED)) {
+ wpa_printf(MSG_DEBUG, "Station " MACSTR
+ " not found for received WNM-Notification Request",
+ MAC2STR(addr));
+ return;
+ }
+
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+ HOSTAPD_LEVEL_INFO,
+ "Beacon protection failure reported");
+ wpa_msg(hapd->msg_ctx, MSG_INFO, WPA_EVENT_UNPROT_BEACON "reporter="
+ MACSTR, MAC2STR(addr));
+}
+
+
static void ieee802_11_rx_wnm_notification_req(struct hostapd_data *hapd,
const u8 *addr, const u8 *buf,
size_t len)
@@ -540,8 +564,14 @@ static void ieee802_11_rx_wnm_notification_req(struct hostapd_data *hapd,
MAC2STR(addr), dialog_token, type);
wpa_hexdump(MSG_MSGDUMP, "WNM: Notification Request subelements",
buf, len);
- if (type == WLAN_EID_VENDOR_SPECIFIC)
+ switch (type) {
+ case WNM_NOTIF_TYPE_BEACON_PROTECTION_FAILURE:
+ wnm_beacon_protection_failure(hapd, addr);
+ break;
+ case WNM_NOTIF_TYPE_VENDOR_SPECIFIC:
mbo_ap_wnm_notification_req(hapd, addr, buf, len);
+ break;
+ }
}
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index e67c344..070236a 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -106,7 +106,7 @@ static inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth,
static inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth,
const u8 *addr, wpa_eapol_variable var)
{
- if (wpa_auth->cb->get_eapol == NULL)
+ if (!wpa_auth->cb->get_eapol)
return -1;
return wpa_auth->cb->get_eapol(wpa_auth->cb_ctx, addr, var);
}
@@ -118,7 +118,7 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
const u8 *prev_psk, size_t *psk_len,
int *vlan_id)
{
- if (wpa_auth->cb->get_psk == NULL)
+ if (!wpa_auth->cb->get_psk)
return NULL;
return wpa_auth->cb->get_psk(wpa_auth->cb_ctx, addr, p2p_dev_addr,
prev_psk, psk_len, vlan_id);
@@ -128,7 +128,7 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
static inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth,
const u8 *addr, u8 *msk, size_t *len)
{
- if (wpa_auth->cb->get_msk == NULL)
+ if (!wpa_auth->cb->get_msk)
return -1;
return wpa_auth->cb->get_msk(wpa_auth->cb_ctx, addr, msk, len);
}
@@ -140,7 +140,7 @@ static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
u8 *key, size_t key_len,
enum key_flag key_flag)
{
- if (wpa_auth->cb->set_key == NULL)
+ if (!wpa_auth->cb->set_key)
return -1;
return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
key, key_len, key_flag);
@@ -152,7 +152,7 @@ static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
{
int res;
- if (wpa_auth->cb->get_seqnum == NULL)
+ if (!wpa_auth->cb->get_seqnum)
return -1;
res = wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
#ifdef CONFIG_TESTING_OPTIONS
@@ -184,7 +184,7 @@ static inline int
wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
const u8 *data, size_t data_len, int encrypt)
{
- if (wpa_auth->cb->send_eapol == NULL)
+ if (!wpa_auth->cb->send_eapol)
return -1;
return wpa_auth->cb->send_eapol(wpa_auth->cb_ctx, addr, data, data_len,
encrypt);
@@ -195,7 +195,7 @@ wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
static inline int wpa_auth_start_ampe(struct wpa_authenticator *wpa_auth,
const u8 *addr)
{
- if (wpa_auth->cb->start_ampe == NULL)
+ if (!wpa_auth->cb->start_ampe)
return -1;
return wpa_auth->cb->start_ampe(wpa_auth->cb_ctx, addr);
}
@@ -206,7 +206,7 @@ int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth,
int (*cb)(struct wpa_state_machine *sm, void *ctx),
void *cb_ctx)
{
- if (wpa_auth->cb->for_each_sta == NULL)
+ if (!wpa_auth->cb->for_each_sta)
return 0;
return wpa_auth->cb->for_each_sta(wpa_auth->cb_ctx, cb, cb_ctx);
}
@@ -216,7 +216,7 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
int (*cb)(struct wpa_authenticator *a, void *ctx),
void *cb_ctx)
{
- if (wpa_auth->cb->for_each_auth == NULL)
+ if (!wpa_auth->cb->for_each_auth)
return 0;
return wpa_auth->cb->for_each_auth(wpa_auth->cb_ctx, cb, cb_ctx);
}
@@ -225,7 +225,7 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,
logger_level level, const char *txt)
{
- if (wpa_auth->cb->logger == NULL)
+ if (!wpa_auth->cb->logger)
return;
wpa_auth->cb->logger(wpa_auth->cb_ctx, addr, level, txt);
}
@@ -238,7 +238,7 @@ void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr,
int maxlen;
va_list ap;
- if (wpa_auth->cb->logger == NULL)
+ if (!wpa_auth->cb->logger)
return;
maxlen = os_strlen(fmt) + 100;
@@ -259,7 +259,7 @@ void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr,
static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
const u8 *addr, u16 reason)
{
- if (wpa_auth->cb->disconnect == NULL)
+ if (!wpa_auth->cb->disconnect)
return;
wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR " (reason %u)",
MAC2STR(addr), reason);
@@ -292,8 +292,8 @@ static void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx)
struct wpa_authenticator *wpa_auth = eloop_ctx;
if (random_get_bytes(wpa_auth->group->GMK, WPA_GMK_LEN)) {
- wpa_printf(MSG_ERROR, "Failed to get random data for WPA "
- "initialization.");
+ wpa_printf(MSG_ERROR,
+ "Failed to get random data for WPA initialization.");
} else {
wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd");
wpa_hexdump_key(MSG_DEBUG, "GMK",
@@ -417,7 +417,7 @@ static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
struct wpa_group *group;
group = os_zalloc(sizeof(struct wpa_group));
- if (group == NULL)
+ if (!group)
return NULL;
group->GTKAuthenticator = TRUE;
@@ -425,9 +425,8 @@ static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group);
if (random_pool_ready() != 1) {
- wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool "
- "for secure operations - update keys later when "
- "the first station connects");
+ wpa_printf(MSG_INFO,
+ "WPA: Not enough entropy in random pool for secure operations - update keys later when the first station connects");
}
/*
@@ -437,16 +436,16 @@ static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
* on embedded devices.
*/
if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0) {
- wpa_printf(MSG_ERROR, "Failed to get random data for WPA "
- "initialization.");
+ wpa_printf(MSG_ERROR,
+ "Failed to get random data for WPA initialization.");
os_free(group);
return NULL;
}
group->GInit = TRUE;
if (delay_init) {
- wpa_printf(MSG_DEBUG, "WPA: Delay group state machine start "
- "until Beacon frames have been configured");
+ wpa_printf(MSG_DEBUG,
+ "WPA: Delay group state machine start until Beacon frames have been configured");
/* Initialization is completed in wpa_init_keys(). */
} else {
wpa_group_sm_step(wpa_auth, group);
@@ -473,7 +472,7 @@ struct wpa_authenticator * wpa_init(const u8 *addr,
struct wpa_authenticator *wpa_auth;
wpa_auth = os_zalloc(sizeof(struct wpa_authenticator));
- if (wpa_auth == NULL)
+ if (!wpa_auth)
return NULL;
os_memcpy(wpa_auth->addr, addr, ETH_ALEN);
os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
@@ -487,7 +486,7 @@ struct wpa_authenticator * wpa_init(const u8 *addr,
}
wpa_auth->group = wpa_group_init(wpa_auth, 0, 1);
- if (wpa_auth->group == NULL) {
+ if (!wpa_auth->group) {
os_free(wpa_auth->wpa_ie);
os_free(wpa_auth);
return NULL;
@@ -495,7 +494,7 @@ struct wpa_authenticator * wpa_init(const u8 *addr,
wpa_auth->pmksa = pmksa_cache_auth_init(wpa_auth_pmksa_free_cb,
wpa_auth);
- if (wpa_auth->pmksa == NULL) {
+ if (!wpa_auth->pmksa) {
wpa_printf(MSG_ERROR, "PMKSA cache initialization failed.");
os_free(wpa_auth->group);
os_free(wpa_auth->wpa_ie);
@@ -505,7 +504,7 @@ struct wpa_authenticator * wpa_init(const u8 *addr,
#ifdef CONFIG_IEEE80211R_AP
wpa_auth->ft_pmk_cache = wpa_ft_pmk_cache_init();
- if (wpa_auth->ft_pmk_cache == NULL) {
+ if (!wpa_auth->ft_pmk_cache) {
wpa_printf(MSG_ERROR, "FT PMK cache initialization failed.");
os_free(wpa_auth->group);
os_free(wpa_auth->wpa_ie);
@@ -544,8 +543,8 @@ int wpa_init_keys(struct wpa_authenticator *wpa_auth)
{
struct wpa_group *group = wpa_auth->group;
- wpa_printf(MSG_DEBUG, "WPA: Start group state machine to set initial "
- "keys");
+ wpa_printf(MSG_DEBUG,
+ "WPA: Start group state machine to set initial keys");
wpa_group_sm_step(wpa_auth, group);
group->GInit = FALSE;
wpa_group_sm_step(wpa_auth, group);
@@ -601,7 +600,8 @@ int wpa_reconfig(struct wpa_authenticator *wpa_auth,
struct wpa_auth_config *conf)
{
struct wpa_group *group;
- if (wpa_auth == NULL)
+
+ if (!wpa_auth)
return 0;
os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
@@ -635,7 +635,7 @@ wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr,
return NULL;
sm = os_zalloc(sizeof(struct wpa_state_machine));
- if (sm == NULL)
+ if (!sm)
return NULL;
os_memcpy(sm->addr, addr, ETH_ALEN);
if (p2p_dev_addr)
@@ -652,14 +652,13 @@ wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr,
int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm)
{
- if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
+ if (!wpa_auth || !wpa_auth->conf.wpa || !sm)
return -1;
#ifdef CONFIG_IEEE80211R_AP
if (sm->ft_completed) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "FT authentication already completed - do not "
- "start 4-way handshake");
+ "FT authentication already completed - do not start 4-way handshake");
/* Go to PTKINITDONE state to allow GTK rekeying */
sm->wpa_ptk_state = WPA_PTK_PTKINITDONE;
sm->Pair = TRUE;
@@ -702,7 +701,7 @@ void wpa_auth_sta_no_wpa(struct wpa_state_machine *sm)
/* WPA/RSN was not used - clear WPA state. This is needed if the STA
* reassociates back to the same AP while the previous entry for the
* STA has not yet been removed. */
- if (sm == NULL)
+ if (!sm)
return;
sm->wpa_key_mgmt = 0;
@@ -714,8 +713,9 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm)
#ifdef CONFIG_P2P
if (WPA_GET_BE32(sm->ip_addr)) {
u32 start;
- wpa_printf(MSG_DEBUG, "P2P: Free assigned IP "
- "address %u.%u.%u.%u from " MACSTR,
+ wpa_printf(MSG_DEBUG,
+ "P2P: Free assigned IP address %u.%u.%u.%u from "
+ MACSTR,
sm->ip_addr[0], sm->ip_addr[1],
sm->ip_addr[2], sm->ip_addr[3],
MAC2STR(sm->addr));
@@ -745,31 +745,34 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm)
void wpa_auth_sta_deinit(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ struct wpa_authenticator *wpa_auth;
+
+ if (!sm)
return;
- if (sm->wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) {
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "strict rekeying - force GTK rekey since STA "
- "is leaving");
+ wpa_auth = sm->wpa_auth;
+ if (wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) {
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
+ "strict rekeying - force GTK rekey since STA is leaving");
if (eloop_deplete_timeout(0, 500000, wpa_rekey_gtk,
- sm->wpa_auth, NULL) == -1)
- eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->wpa_auth,
- NULL);
+ wpa_auth, NULL) == -1)
+ eloop_register_timeout(0, 500000, wpa_rekey_gtk,
+ wpa_auth, NULL);
}
- eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
+ eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm);
sm->pending_1_of_4_timeout = 0;
eloop_cancel_timeout(wpa_sm_call_step, sm, NULL);
- eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
+ eloop_cancel_timeout(wpa_rekey_ptk, wpa_auth, sm);
#ifdef CONFIG_IEEE80211R_AP
wpa_ft_sta_deinit(sm);
#endif /* CONFIG_IEEE80211R_AP */
if (sm->in_step_loop) {
/* Must not free state machine while wpa_sm_step() is running.
* Freeing will be completed in the end of wpa_sm_step(). */
- wpa_printf(MSG_DEBUG, "WPA: Registering pending STA state "
- "machine deinit for " MACSTR, MAC2STR(sm->addr));
+ wpa_printf(MSG_DEBUG,
+ "WPA: Registering pending STA state machine deinit for "
+ MACSTR, MAC2STR(sm->addr));
sm->pending_deinit = 1;
} else
wpa_free_sta_sm(sm);
@@ -778,10 +781,10 @@ void wpa_auth_sta_deinit(struct wpa_state_machine *sm)
static void wpa_request_new_ptk(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ if (!sm)
return;
- if (sm->wpa_auth->conf.wpa_deny_ptk0_rekey) {
+ if (!sm->use_ext_key_id && sm->wpa_auth->conf.wpa_deny_ptk0_rekey) {
wpa_printf(MSG_INFO,
"WPA: PTK0 rekey not allowed, disconnect " MACSTR,
MAC2STR(sm->addr));
@@ -790,6 +793,8 @@ static void wpa_request_new_ptk(struct wpa_state_machine *sm)
sm->disconnect_reason =
WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA;
} else {
+ if (sm->use_ext_key_id)
+ sm->keyidx_active ^= 1; /* flip Key ID */
sm->PTKRequest = TRUE;
sm->PTK_valid = 0;
}
@@ -817,7 +822,7 @@ static void wpa_replay_counter_mark_invalid(struct wpa_key_replay_counter *ctr,
int i;
for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
if (ctr[i].valid &&
- (replay_counter == NULL ||
+ (!replay_counter ||
os_memcmp(replay_counter, ctr[i].counter,
WPA_REPLAY_COUNTER_LEN) == 0))
ctr[i].valid = FALSE;
@@ -834,9 +839,9 @@ static int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth,
struct rsn_mdie *mdie;
if (wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0 ||
- ie.num_pmkid != 1 || ie.pmkid == NULL) {
- wpa_printf(MSG_DEBUG, "FT: No PMKR1Name in "
- "FT 4-way handshake message 2/4");
+ ie.num_pmkid != 1 || !ie.pmkid) {
+ wpa_printf(MSG_DEBUG,
+ "FT: No PMKR1Name in FT 4-way handshake message 2/4");
return -1;
}
@@ -845,8 +850,9 @@ static int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth,
sm->sup_pmk_r1_name, PMKID_LEN);
if (!kde->mdie || !kde->ftie) {
- wpa_printf(MSG_DEBUG, "FT: No %s in FT 4-way handshake "
- "message 2/4", kde->mdie ? "FTIE" : "MDIE");
+ wpa_printf(MSG_DEBUG,
+ "FT: No %s in FT 4-way handshake message 2/4",
+ kde->mdie ? "FTIE" : "MDIE");
return -1;
}
@@ -880,18 +886,15 @@ static int wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
{
/* Supplicant reported a Michael MIC error */
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key Error Request "
- "(STA detected Michael MIC failure (group=%d))",
+ "received EAPOL-Key Error Request (STA detected Michael MIC failure (group=%d))",
group);
if (group && wpa_auth->conf.wpa_group != WPA_CIPHER_TKIP) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "ignore Michael MIC failure report since "
- "group cipher is not TKIP");
+ "ignore Michael MIC failure report since group cipher is not TKIP");
} else if (!group && sm->pairwise != WPA_CIPHER_TKIP) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "ignore Michael MIC failure report since "
- "pairwise cipher is not TKIP");
+ "ignore Michael MIC failure report since pairwise cipher is not TKIP");
} else {
if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0)
return 1; /* STA entry was removed */
@@ -924,7 +927,7 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data,
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
sm->p2p_dev_addr, pmk, &pmk_len,
&vlan_id);
- if (pmk == NULL)
+ if (!pmk)
break;
#ifdef CONFIG_IEEE80211R_AP
if (wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) {
@@ -993,7 +996,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
size_t keyhdrlen, mic_len;
u8 *mic;
- if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
+ if (!wpa_auth || !wpa_auth->conf.wpa || !sm)
return;
wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL data", data, data_len);
@@ -1012,20 +1015,19 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
key_data = mic + mic_len + 2;
key_data_length = WPA_GET_BE16(mic + mic_len);
wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR
- " key_info=0x%x type=%u mic_len=%u key_data_length=%u",
+ " key_info=0x%x type=%u mic_len=%zu key_data_length=%u",
MAC2STR(sm->addr), key_info, key->type,
- (unsigned int) mic_len, key_data_length);
+ mic_len, key_data_length);
wpa_hexdump(MSG_MSGDUMP,
"WPA: EAPOL-Key header (ending before Key MIC)",
key, sizeof(*key));
wpa_hexdump(MSG_MSGDUMP, "WPA: EAPOL-Key Key MIC",
mic, mic_len);
if (key_data_length > data_len - sizeof(*hdr) - keyhdrlen) {
- wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
- "key_data overflow (%d > %lu)",
+ wpa_printf(MSG_INFO,
+ "WPA: Invalid EAPOL-Key frame - key_data overflow (%d > %zu)",
key_data_length,
- (unsigned long) (data_len - sizeof(*hdr) -
- keyhdrlen));
+ data_len - sizeof(*hdr) - keyhdrlen);
return;
}
@@ -1035,18 +1037,18 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
* Some deployed station implementations seem to send
* msg 4/4 with incorrect type value in WPA2 mode.
*/
- wpa_printf(MSG_DEBUG, "Workaround: Allow EAPOL-Key "
- "with unexpected WPA type in RSN mode");
+ wpa_printf(MSG_DEBUG,
+ "Workaround: Allow EAPOL-Key with unexpected WPA type in RSN mode");
} else if (key->type != EAPOL_KEY_TYPE_RSN) {
- wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
- "unexpected type %d in RSN mode",
+ wpa_printf(MSG_DEBUG,
+ "Ignore EAPOL-Key with unexpected type %d in RSN mode",
key->type);
return;
}
} else {
if (key->type != EAPOL_KEY_TYPE_WPA) {
- wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
- "unexpected type %d in WPA mode",
+ wpa_printf(MSG_DEBUG,
+ "Ignore EAPOL-Key with unexpected type %d in WPA mode",
key->type);
return;
}
@@ -1091,9 +1093,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
wpa_auth_logger(wpa_auth, sm->addr,
LOGGER_WARNING,
- "advertised support for "
- "AES-128-CMAC, but did not "
- "use it");
+ "advertised support for AES-128-CMAC, but did not use it");
return;
}
@@ -1102,8 +1102,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
wpa_auth_logger(wpa_auth, sm->addr,
LOGGER_WARNING,
- "did not use HMAC-SHA1-AES "
- "with CCMP/GCMP");
+ "did not use HMAC-SHA1-AES with CCMP/GCMP");
return;
}
}
@@ -1121,8 +1120,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
os_memcmp(key->replay_counter, sm->req_replay_counter,
WPA_REPLAY_COUNTER_LEN) <= 0) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING,
- "received EAPOL-Key request with "
- "replayed counter");
+ "received EAPOL-Key request with replayed counter");
return;
}
}
@@ -1145,9 +1143,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
* even if we have already sent out EAPOL-Key 3/4.
*/
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "Process SNonce update from STA "
- "based on retransmitted EAPOL-Key "
- "1/4");
+ "Process SNonce update from STA based on retransmitted EAPOL-Key 1/4");
sm->update_snonce = 1;
os_memcpy(sm->alt_SNonce, sm->SNonce, WPA_NONCE_LEN);
sm->alt_snonce_valid = TRUE;
@@ -1176,12 +1172,12 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
key->replay_counter) &&
sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "ignore retransmitted EAPOL-Key %s - "
- "SNonce did not change", msgtxt);
+ "ignore retransmitted EAPOL-Key %s - SNonce did not change",
+ msgtxt);
} else {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "received EAPOL-Key %s with "
- "unexpected replay counter", msgtxt);
+ "received EAPOL-Key %s with unexpected replay counter",
+ msgtxt);
}
for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
if (!sm->key_replay[i].valid)
@@ -1212,8 +1208,7 @@ continue_processing:
(!sm->update_snonce ||
sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING)) {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key msg 2/4 in "
- "invalid state (%d) - dropped",
+ "received EAPOL-Key msg 2/4 in invalid state (%d) - dropped",
sm->wpa_ptk_state);
return;
}
@@ -1228,9 +1223,8 @@ continue_processing:
* Counter update and the station will be allowed to
* continue.
*/
- wpa_printf(MSG_DEBUG, "WPA: Reject 4-way handshake to "
- "collect more entropy for random number "
- "generation");
+ wpa_printf(MSG_DEBUG,
+ "WPA: Reject 4-way handshake to collect more entropy for random number generation");
random_mark_pool_ready();
wpa_sta_disconnect(wpa_auth, sm->addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
@@ -1241,8 +1235,7 @@ continue_processing:
if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING ||
!sm->PTK_valid) {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key msg 4/4 in "
- "invalid state (%d) - dropped",
+ "received EAPOL-Key msg 4/4 in invalid state (%d) - dropped",
sm->wpa_ptk_state);
return;
}
@@ -1251,8 +1244,7 @@ continue_processing:
if (sm->wpa_ptk_group_state != WPA_PTK_GROUP_REKEYNEGOTIATING
|| !sm->PTK_valid) {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key msg 2/2 in "
- "invalid state (%d) - dropped",
+ "received EAPOL-Key msg 2/2 in invalid state (%d) - dropped",
sm->wpa_ptk_group_state);
return;
}
@@ -1331,8 +1323,7 @@ continue_processing:
WPA_REPLAY_COUNTER_LEN);
} else {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key request with "
- "invalid MIC");
+ "received EAPOL-Key request with invalid MIC");
return;
}
@@ -1348,8 +1339,7 @@ continue_processing:
return; /* STA entry was removed */
} else if (key_info & WPA_KEY_INFO_KEY_TYPE) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key Request for new "
- "4-Way Handshake");
+ "received EAPOL-Key Request for new 4-Way Handshake");
wpa_request_new_ptk(sm);
} else if (key_data_length > 0 &&
wpa_parse_kde_ies(key_data, key_data_length,
@@ -1357,8 +1347,7 @@ continue_processing:
kde.mac_addr) {
} else {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key Request for GTK "
- "rekeying");
+ "received EAPOL-Key Request for GTK rekeying");
eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);
wpa_rekey_gtk(wpa_auth, NULL);
}
@@ -1391,7 +1380,7 @@ continue_processing:
os_free(sm->last_rx_eapol_key);
sm->last_rx_eapol_key = os_memdup(data, data_len);
- if (sm->last_rx_eapol_key == NULL)
+ if (!sm->last_rx_eapol_key)
return;
sm->last_rx_eapol_key_len = data_len;
@@ -1470,6 +1459,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
const u8 *kde, size_t kde_len,
int keyidx, int encr, int force_version)
{
+ struct wpa_auth_config *conf = &wpa_auth->conf;
struct ieee802_1x_hdr *hdr;
struct wpa_eapol_key *key;
size_t len, mic_len, keyhdrlen;
@@ -1498,15 +1488,14 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
pairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
- wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(version=%d secure=%d mic=%d "
- "ack=%d install=%d pairwise=%d kde_len=%lu keyidx=%d "
- "encr=%d)",
+ wpa_printf(MSG_DEBUG,
+ "WPA: Send EAPOL(version=%d secure=%d mic=%d ack=%d install=%d pairwise=%d kde_len=%zu keyidx=%d encr=%d)",
version,
(key_info & WPA_KEY_INFO_SECURE) ? 1 : 0,
(key_info & WPA_KEY_INFO_MIC) ? 1 : 0,
(key_info & WPA_KEY_INFO_ACK) ? 1 : 0,
(key_info & WPA_KEY_INFO_INSTALL) ? 1 : 0,
- pairwise, (unsigned long) kde_len, keyidx, encr);
+ pairwise, kde_len, keyidx, encr);
key_data_len = kde_len;
@@ -1524,9 +1513,9 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
len += AES_BLOCK_SIZE;
hdr = os_zalloc(len);
- if (hdr == NULL)
+ if (!hdr)
return;
- hdr->version = wpa_auth->conf.eapol_version;
+ hdr->version = conf->eapol_version;
hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
hdr->length = host_to_be16(len - sizeof(*hdr));
key = (struct wpa_eapol_key *) (hdr + 1);
@@ -1542,7 +1531,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
key_info |= keyidx << WPA_KEY_INFO_KEY_INDEX_SHIFT;
WPA_PUT_BE16(key->key_info, key_info);
- alg = pairwise ? sm->pairwise : wpa_auth->conf.wpa_group;
+ alg = pairwise ? sm->pairwise : conf->wpa_group;
if (sm->wpa == WPA_VERSION_WPA2 && !pairwise)
WPA_PUT_BE16(key->key_length, 0);
else
@@ -1596,7 +1585,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
#endif /* CONFIG_FILS */
} else if (encr && kde) {
buf = os_zalloc(key_data_len);
- if (buf == NULL) {
+ if (!buf) {
os_free(hdr);
return;
}
@@ -1613,8 +1602,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
wpa_use_aes_key_wrap(sm->wpa_key_mgmt) ||
version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
wpa_printf(MSG_DEBUG,
- "WPA: Encrypt Key Data using AES-WRAP (KEK length %u)",
- (unsigned int) sm->PTK.kek_len);
+ "WPA: Encrypt Key Data using AES-WRAP (KEK length %zu)",
+ sm->PTK.kek_len);
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len,
(key_data_len - 8) / 8, buf, key_data)) {
os_free(hdr);
@@ -1648,8 +1637,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
if (key_info & WPA_KEY_INFO_MIC) {
if (!sm->PTK_valid || !mic_len) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "PTK not valid when sending EAPOL-Key "
- "frame");
+ "PTK not valid when sending EAPOL-Key frame");
os_free(hdr);
return;
}
@@ -1662,9 +1650,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
}
#ifdef CONFIG_TESTING_OPTIONS
if (!pairwise &&
- wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0 &&
- drand48() <
- wpa_auth->conf.corrupt_gtk_rekey_mic_probability) {
+ conf->corrupt_gtk_rekey_mic_probability > 0.0 &&
+ drand48() < conf->corrupt_gtk_rekey_mic_probability) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
"Corrupting group EAPOL-Key Key MIC");
key_mic[0]++;
@@ -1672,8 +1659,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
#endif /* CONFIG_TESTING_OPTIONS */
}
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx,
- 1);
+ wpa_auth_set_eapol(wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx, 1);
wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len,
sm->pairwise_set);
os_free(hdr);
@@ -1690,7 +1676,7 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE;
u32 ctr;
- if (sm == NULL)
+ if (!sm)
return;
__wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len,
@@ -1710,8 +1696,9 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
#ifdef TEST_FUZZ
timeout_ms = 1;
#endif /* TEST_FUZZ */
- wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry "
- "counter %u)", timeout_ms, ctr);
+ wpa_printf(MSG_DEBUG,
+ "WPA: Use EAPOL-Key timeout of %u ms (retry counter %u)",
+ timeout_ms, ctr);
eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000,
wpa_send_eapol_timeout, wpa_auth, sm);
}
@@ -1754,6 +1741,11 @@ void wpa_remove_ptk(struct wpa_state_machine *sm)
0, KEY_FLAG_PAIRWISE))
wpa_printf(MSG_DEBUG,
"RSN: PTK removal from the driver failed");
+ if (sm->use_ext_key_id &&
+ wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 1, NULL,
+ 0, KEY_FLAG_PAIRWISE))
+ wpa_printf(MSG_DEBUG,
+ "RSN: PTK Key ID 1 removal from the driver failed");
sm->pairwise_set = FALSE;
eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
}
@@ -1763,7 +1755,7 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
{
int remove_ptk = 1;
- if (sm == NULL)
+ if (!sm)
return -1;
wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
@@ -1803,8 +1795,8 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
* sure that the WPA state machines gets initialized
* properly at this point.
*/
- wpa_printf(MSG_DEBUG, "WPA state machine had not been "
- "started - initialize now");
+ wpa_printf(MSG_DEBUG,
+ "WPA state machine had not been started - initialize now");
sm->started = 1;
sm->Init = TRUE;
if (wpa_sm_step(sm) == 1)
@@ -1812,16 +1804,23 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
sm->Init = FALSE;
sm->AuthenticationRequest = TRUE;
break;
- } else if (sm->wpa_auth->conf.wpa_deny_ptk0_rekey) {
+ }
+
+ if (!sm->use_ext_key_id &&
+ sm->wpa_auth->conf.wpa_deny_ptk0_rekey) {
wpa_printf(MSG_INFO,
"WPA: PTK0 rekey not allowed, disconnect "
MACSTR, MAC2STR(sm->addr));
sm->Disconnect = TRUE;
- /* Try to encourage the STA reconnect */
+ /* Try to encourage the STA to reconnect */
sm->disconnect_reason =
WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA;
break;
}
+
+ if (sm->use_ext_key_id)
+ sm->keyidx_active ^= 1; /* flip Key ID */
+
if (sm->GUpdateStationKeys) {
/*
* Reauthentication cancels the pending group key
@@ -1835,9 +1834,9 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
break;
case WPA_ASSOC_FT:
#ifdef CONFIG_IEEE80211R_AP
- wpa_printf(MSG_DEBUG, "FT: Retry PTK configuration "
- "after association");
- wpa_ft_install_ptk(sm);
+ wpa_printf(MSG_DEBUG,
+ "FT: Retry PTK configuration after association");
+ wpa_ft_install_ptk(sm, 1);
/* Using FT protocol, not WPA auth state machine */
sm->ft_completed = 1;
@@ -1969,11 +1968,11 @@ static void wpa_group_ensure_init(struct wpa_authenticator *wpa_auth,
* GMK and Counter here to improve their strength if there was not
* enough entropy available immediately after system startup.
*/
- wpa_printf(MSG_DEBUG, "WPA: Re-initialize GMK/Counter on first "
- "station");
+ wpa_printf(MSG_DEBUG,
+ "WPA: Re-initialize GMK/Counter on first station");
if (random_pool_ready() != 1) {
- wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool "
- "to proceed - reject first 4-way handshake");
+ wpa_printf(MSG_INFO,
+ "WPA: Not enough entropy in random pool to proceed - reject first 4-way handshake");
group->reject_4way_hs_for_entropy = TRUE;
} else {
group->first_sta_seen = TRUE;
@@ -2007,8 +2006,8 @@ SM_STATE(WPA_PTK, AUTHENTICATION2)
* stronger protection against potential precomputation attacks.
*/
if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
- wpa_printf(MSG_ERROR, "WPA: Failed to get random data for "
- "ANonce.");
+ wpa_printf(MSG_ERROR,
+ "WPA: Failed to get random data for ANonce.");
sm->Disconnect = TRUE;
return;
}
@@ -2065,13 +2064,13 @@ SM_STATE(WPA_PTK, INITPMK)
pmk_len = PMK_LEN_SUITE_B_192;
else
pmk_len = PMK_LEN;
- wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine "
- "(MSK len=%lu PMK len=%u)", (unsigned long) len,
- pmk_len);
+ wpa_printf(MSG_DEBUG,
+ "WPA: PMK from EAPOL state machine (MSK len=%zu PMK len=%u)",
+ len, pmk_len);
if (len < pmk_len) {
wpa_printf(MSG_DEBUG,
- "WPA: MSK not long enough (%u) to create PMK (%u)",
- (unsigned int) len, (unsigned int) pmk_len);
+ "WPA: MSK not long enough (%zu) to create PMK (%u)",
+ len, pmk_len);
sm->Disconnect = TRUE;
return;
}
@@ -2286,7 +2285,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
akmp = sm->wpa_key_mgmt;
if (force_sha256)
- akmp = WPA_KEY_MGMT_PSK_SHA256;
+ akmp |= WPA_KEY_MGMT_PSK_SHA256;
return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
ptk, akmp, sm->pairwise, z, z_len);
@@ -2503,9 +2502,9 @@ int wpa_fils_validate_key_confirm(struct wpa_state_machine *sm, const u8 *ies,
if (elems.fils_key_confirm_len != sm->fils_key_auth_len) {
wpa_printf(MSG_DEBUG,
- "FILS: Unexpected Key-Auth length %d (expected %d)",
+ "FILS: Unexpected Key-Auth length %d (expected %zu)",
elems.fils_key_confirm_len,
- (int) sm->fils_key_auth_len);
+ sm->fils_key_auth_len);
return -1;
}
@@ -2698,8 +2697,13 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
u8 *gtk, dummy_gtk[32];
size_t gtk_len;
struct wpa_group *gsm;
+ size_t plain_len;
+ struct wpa_auth_config *conf = &sm->wpa_auth->conf;
- plain = wpabuf_alloc(1000 + ieee80211w_kde_len(sm));
+ plain_len = 1000 + ieee80211w_kde_len(sm);
+ if (conf->transition_disable)
+ plain_len += 2 + RSN_SELECTOR_LEN + 1;
+ plain = wpabuf_alloc(plain_len);
if (!plain)
return NULL;
@@ -2728,8 +2732,7 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
/* GTK KDE */
gtk = gsm->GTK[gsm->GN - 1];
gtk_len = gsm->GTK_len;
- if (sm->wpa_auth->conf.disable_gtk ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) {
+ if (conf->disable_gtk || sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) {
/*
* Provide unique random GTK to each STA to prevent use
* of GTK in the BSS.
@@ -2752,6 +2755,13 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
tmp2 = ieee80211w_kde_add(sm, tmp);
wpabuf_put(plain, tmp2 - tmp);
+ if (conf->transition_disable) {
+ tmp = wpabuf_put(plain, 0);
+ tmp2 = wpa_add_kde(tmp, WFA_KEY_DATA_TRANSITION_DISABLE,
+ &conf->transition_disable, 1, NULL, 0);
+ wpabuf_put(plain, tmp2 - tmp);
+ }
+
*len = (u8 *) wpabuf_put(plain, 0) - len - 1;
#ifdef CONFIG_OCV
@@ -2829,8 +2839,8 @@ u8 * hostapd_eid_assoc_fils_session(struct wpa_state_machine *sm, u8 *buf,
os_memcpy(pos, wpabuf_head(plain), wpabuf_len(plain));
pos += wpabuf_len(plain);
- wpa_printf(MSG_DEBUG, "%s: plain buf_len: %u", __func__,
- (unsigned int) wpabuf_len(plain));
+ wpa_printf(MSG_DEBUG, "%s: plain buf_len: %zu", __func__,
+ wpabuf_len(plain));
wpabuf_clear_free(plain);
sm->fils_completed = 1;
return pos;
@@ -2887,7 +2897,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
sm->p2p_dev_addr, pmk, &pmk_len,
&vlan_id);
- if (pmk == NULL)
+ if (!pmk)
break;
psk_found = 1;
#ifdef CONFIG_IEEE80211R_AP
@@ -2984,7 +2994,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
eapol_key_ie_len = kde.wpa_ie_len;
}
ft = sm->wpa == WPA_VERSION_WPA2 && wpa_key_mgmt_ft(sm->wpa_key_mgmt);
- if (sm->wpa_ie == NULL ||
+ if (!sm->wpa_ie ||
wpa_compare_rsn_ie(ft, sm->wpa_ie, sm->wpa_ie_len,
eapol_key_ie, eapol_key_ie_len)) {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
@@ -3078,10 +3088,9 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
if (os_memcmp_const(sm->sup_pmk_r1_name, sm->pmk_r1_name,
WPA_PMK_NAME_LEN) != 0) {
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "PMKR1Name mismatch in FT 4-way "
- "handshake");
- wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from "
- "Supplicant",
+ "PMKR1Name mismatch in FT 4-way handshake");
+ wpa_hexdump(MSG_DEBUG,
+ "FT: PMKR1Name from Supplicant",
sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN);
wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
sm->pmk_r1_name, WPA_PMK_NAME_LEN);
@@ -3146,7 +3155,8 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
struct wpa_bigtk_kde bigtk;
struct wpa_group *gsm = sm->group;
u8 rsc[WPA_KEY_RSC_LEN];
- size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
+ struct wpa_auth_config *conf = &sm->wpa_auth->conf;
+ size_t len = wpa_cipher_key_len(conf->group_mgmt_cipher);
if (!sm->mgmt_frame_prot)
return pos;
@@ -3159,8 +3169,7 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
else
os_memcpy(igtk.pn, rsc, sizeof(igtk.pn));
os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], len);
- if (sm->wpa_auth->conf.disable_gtk ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) {
+ if (conf->disable_gtk || sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) {
/*
* Provide unique random IGTK to each STA to prevent use of
* IGTK in the BSS.
@@ -3172,7 +3181,7 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
(const u8 *) &igtk, WPA_IGTK_KDE_PREFIX_LEN + len,
NULL, 0);
- if (!sm->wpa_auth->conf.beacon_prot)
+ if (!conf->beacon_prot)
return pos;
bigtk.keyid[0] = gsm->GN_bigtk;
@@ -3221,25 +3230,58 @@ static int ocv_oci_add(struct wpa_state_machine *sm, u8 **argpos)
}
+#ifdef CONFIG_TESTING_OPTIONS
+static u8 * replace_ie(const char *name, const u8 *old_buf, size_t *len, u8 eid,
+ const u8 *ie, size_t ie_len)
+{
+ const u8 *elem;
+ u8 *buf;
+
+ wpa_printf(MSG_DEBUG, "TESTING: %s EAPOL override", name);
+ wpa_hexdump(MSG_DEBUG, "TESTING: wpa_ie before override",
+ old_buf, *len);
+ buf = os_malloc(*len + ie_len);
+ if (!buf)
+ return NULL;
+ os_memcpy(buf, old_buf, *len);
+ elem = get_ie(buf, *len, eid);
+ if (elem) {
+ u8 elem_len = 2 + elem[1];
+
+ os_memmove((void *) elem, elem + elem_len,
+ *len - (elem - buf) - elem_len);
+ *len -= elem_len;
+ }
+ os_memcpy(buf + *len, ie, ie_len);
+ *len += ie_len;
+ wpa_hexdump(MSG_DEBUG, "TESTING: wpa_ie after EAPOL override",
+ buf, *len);
+
+ return buf;
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
{
u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, dummy_gtk[32];
- size_t gtk_len, kde_len;
+ size_t gtk_len, kde_len, wpa_ie_len;
struct wpa_group *gsm = sm->group;
u8 *wpa_ie;
- int wpa_ie_len, secure, gtkidx, encr = 0;
- u8 *wpa_ie_buf = NULL;
+ int secure, gtkidx, encr = 0;
+ u8 *wpa_ie_buf = NULL, *wpa_ie_buf2 = NULL;
+ u8 hdr[2];
+ struct wpa_auth_config *conf = &sm->wpa_auth->conf;
SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk);
sm->TimeoutEvt = FALSE;
sm->TimeoutCtr++;
- if (sm->wpa_auth->conf.wpa_disable_eapol_key_retries &&
- sm->TimeoutCtr > 1) {
+ if (conf->wpa_disable_eapol_key_retries && sm->TimeoutCtr > 1) {
/* Do not allow retransmission of EAPOL-Key msg 3/4 */
return;
}
- if (sm->TimeoutCtr > sm->wpa_auth->conf.wpa_pairwise_update_count) {
+ if (sm->TimeoutCtr > conf->wpa_pairwise_update_count) {
/* No point in sending the EAPOL-Key - we will disconnect
* immediately following this. */
return;
@@ -3253,9 +3295,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
/* If FT is used, wpa_auth->wpa_ie includes both RSNIE and MDIE */
wpa_ie = sm->wpa_auth->wpa_ie;
wpa_ie_len = sm->wpa_auth->wpa_ie_len;
- if (sm->wpa == WPA_VERSION_WPA &&
- (sm->wpa_auth->conf.wpa & WPA_PROTO_RSN) &&
- wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) {
+ if (sm->wpa == WPA_VERSION_WPA && (conf->wpa & WPA_PROTO_RSN) &&
+ wpa_ie_len > wpa_ie[1] + 2U && wpa_ie[0] == WLAN_EID_RSN) {
/* WPA-only STA, remove RSN IE and possible MDIE */
wpa_ie = wpa_ie + wpa_ie[1] + 2;
if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN)
@@ -3263,42 +3304,45 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
wpa_ie_len = wpa_ie[1] + 2;
}
#ifdef CONFIG_TESTING_OPTIONS
- if (sm->wpa_auth->conf.rsnxe_override_eapol_len) {
- u8 *obuf = sm->wpa_auth->conf.rsnxe_override_eapol;
- size_t olen = sm->wpa_auth->conf.rsnxe_override_eapol_len;
- const u8 *rsnxe;
-
- wpa_hexdump(MSG_DEBUG,
- "TESTING: wpa_ie before RSNXE EAPOL override",
- wpa_ie, wpa_ie_len);
- wpa_ie_buf = os_malloc(wpa_ie_len + olen);
+ if (conf->rsne_override_eapol_set) {
+ wpa_ie_buf2 = replace_ie(
+ "RSNE", wpa_ie, &wpa_ie_len, WLAN_EID_RSN,
+ conf->rsne_override_eapol,
+ conf->rsne_override_eapol_len);
+ if (!wpa_ie_buf2)
+ goto done;
+ wpa_ie = wpa_ie_buf2;
+ }
+ if (conf->rsnxe_override_eapol_set) {
+ wpa_ie_buf = replace_ie(
+ "RSNXE", wpa_ie, &wpa_ie_len, WLAN_EID_RSNX,
+ conf->rsnxe_override_eapol,
+ conf->rsnxe_override_eapol_len);
if (!wpa_ie_buf)
- return;
- os_memcpy(wpa_ie_buf, wpa_ie, wpa_ie_len);
+ goto done;
wpa_ie = wpa_ie_buf;
- rsnxe = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_RSNX);
- if (rsnxe) {
- u8 rsnxe_len = 2 + rsnxe[1];
-
- os_memmove((void *) rsnxe, rsnxe + rsnxe_len,
- wpa_ie_len - (rsnxe - wpa_ie) - rsnxe_len);
- wpa_ie_len -= rsnxe_len;
- }
- os_memcpy(wpa_ie + wpa_ie_len, obuf, olen);
- wpa_ie_len += olen;
- wpa_hexdump(MSG_DEBUG,
- "TESTING: wpa_ie after RSNXE EAPOL override",
- wpa_ie, wpa_ie_len);
}
#endif /* CONFIG_TESTING_OPTIONS */
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
"sending 3/4 msg of 4-Way Handshake");
if (sm->wpa == WPA_VERSION_WPA2) {
+ if (sm->use_ext_key_id && sm->TimeoutCtr == 1 &&
+ wpa_auth_set_key(sm->wpa_auth, 0,
+ wpa_cipher_to_alg(sm->pairwise),
+ sm->addr,
+ sm->keyidx_active, sm->PTK.tk,
+ wpa_cipher_key_len(sm->pairwise),
+ KEY_FLAG_PAIRWISE_RX)) {
+ wpa_sta_disconnect(sm->wpa_auth, sm->addr,
+ WLAN_REASON_PREV_AUTH_NOT_VALID);
+ return;
+ }
+
/* WPA2 send GTK in the 4-way handshake */
secure = 1;
gtk = gsm->GTK[gsm->GN - 1];
gtk_len = gsm->GTK_len;
- if (sm->wpa_auth->conf.disable_gtk ||
+ if (conf->disable_gtk ||
sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) {
/*
* Provide unique random GTK to each STA to prevent use
@@ -3327,13 +3371,16 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
* WPA if the supplicant used it first.
*/
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "STA used Secure bit in WPA msg 2/4 - "
- "set Secure for 3/4 as workaround");
+ "STA used Secure bit in WPA msg 2/4 - set Secure for 3/4 as workaround");
secure = 1;
}
}
kde_len = wpa_ie_len + ieee80211w_kde_len(sm) + ocv_oci_len(sm);
+
+ if (sm->use_ext_key_id)
+ kde_len += 2 + RSN_SELECTOR_LEN + 2;
+
if (gtk)
kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len;
#ifdef CONFIG_IEEE80211R_AP
@@ -3346,8 +3393,12 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
if (WPA_GET_BE32(sm->ip_addr) > 0)
kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4;
#endif /* CONFIG_P2P */
+
+ if (conf->transition_disable)
+ kde_len += 2 + RSN_SELECTOR_LEN + 1;
+
kde = os_malloc(kde_len);
- if (kde == NULL)
+ if (!kde)
goto done;
pos = kde;
@@ -3361,18 +3412,23 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
elen = pos - kde;
res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name);
if (res < 0) {
- wpa_printf(MSG_ERROR, "FT: Failed to insert "
- "PMKR1Name into RSN IE in EAPOL-Key data");
+ wpa_printf(MSG_ERROR,
+ "FT: Failed to insert PMKR1Name into RSN IE in EAPOL-Key data");
goto done;
}
pos -= wpa_ie_len;
pos += elen;
}
#endif /* CONFIG_IEEE80211R_AP */
+ hdr[1] = 0;
+
+ if (sm->use_ext_key_id) {
+ hdr[0] = sm->keyidx_active & 0x01;
+ pos = wpa_add_kde(pos, RSN_KEY_DATA_KEYID, hdr, 2, NULL, 0);
+ }
+
if (gtk) {
- u8 hdr[2];
hdr[0] = gtkidx & 0x03;
- hdr[1] = 0;
pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
gtk, gtk_len);
}
@@ -3383,9 +3439,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
#ifdef CONFIG_IEEE80211R_AP
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
int res;
- struct wpa_auth_config *conf;
- conf = &sm->wpa_auth->conf;
if (sm->assoc_resp_ftie &&
kde + kde_len - pos >= 2 + sm->assoc_resp_ftie[1]) {
os_memcpy(pos, sm->assoc_resp_ftie,
@@ -3399,11 +3453,11 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
conf->r0_key_holder_len,
NULL, NULL, pos,
kde + kde_len - pos,
- NULL, 0);
+ NULL, 0, 0);
}
if (res < 0) {
- wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
- "into EAPOL-Key Key Data");
+ wpa_printf(MSG_ERROR,
+ "FT: Failed to insert FTIE into EAPOL-Key Key Data");
goto done;
}
pos += res;
@@ -3427,13 +3481,17 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
if (WPA_GET_BE32(sm->ip_addr) > 0) {
u8 addr[3 * 4];
os_memcpy(addr, sm->ip_addr, 4);
- os_memcpy(addr + 4, sm->wpa_auth->conf.ip_addr_mask, 4);
- os_memcpy(addr + 8, sm->wpa_auth->conf.ip_addr_go, 4);
+ os_memcpy(addr + 4, conf->ip_addr_mask, 4);
+ os_memcpy(addr + 8, conf->ip_addr_go, 4);
pos = wpa_add_kde(pos, WFA_KEY_DATA_IP_ADDR_ALLOC,
addr, sizeof(addr), NULL, 0);
}
#endif /* CONFIG_P2P */
+ if (conf->transition_disable)
+ pos = wpa_add_kde(pos, WFA_KEY_DATA_TRANSITION_DISABLE,
+ &conf->transition_disable, 1, NULL, 0);
+
wpa_send_eapol(sm->wpa_auth, sm,
(secure ? WPA_KEY_INFO_SECURE : 0) |
(wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
@@ -3444,6 +3502,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
done:
os_free(kde);
os_free(wpa_ie_buf);
+ os_free(wpa_ie_buf2);
}
@@ -3454,9 +3513,17 @@ SM_STATE(WPA_PTK, PTKINITDONE)
if (sm->Pair) {
enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise);
int klen = wpa_cipher_key_len(sm->pairwise);
- if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
- sm->PTK.tk, klen,
- KEY_FLAG_PAIRWISE_RX_TX)) {
+ int res;
+
+ if (sm->use_ext_key_id)
+ res = wpa_auth_set_key(sm->wpa_auth, 0, 0, sm->addr,
+ sm->keyidx_active, NULL, 0,
+ KEY_FLAG_PAIRWISE_RX_TX_MODIFY);
+ else
+ res = wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr,
+ 0, sm->PTK.tk, klen,
+ KEY_FLAG_PAIRWISE_RX_TX);
+ if (res) {
wpa_sta_disconnect(sm->wpa_auth, sm->addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
return;
@@ -3503,6 +3570,7 @@ SM_STATE(WPA_PTK, PTKINITDONE)
SM_STEP(WPA_PTK)
{
struct wpa_authenticator *wpa_auth = sm->wpa_auth;
+ struct wpa_auth_config *conf = &wpa_auth->conf;
if (sm->Init)
SM_ENTER(WPA_PTK, INITIALIZE);
@@ -3537,7 +3605,7 @@ SM_STEP(WPA_PTK)
break;
case WPA_PTK_AUTHENTICATION2:
if (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) &&
- wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
+ wpa_auth_get_eapol(wpa_auth, sm->addr,
WPA_EAPOL_keyRun) > 0)
SM_ENTER(WPA_PTK, INITPMK);
else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
@@ -3548,7 +3616,7 @@ SM_STEP(WPA_PTK)
SM_ENTER(WPA_PTK, INITPMK);
break;
case WPA_PTK_INITPMK:
- if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
+ if (wpa_auth_get_eapol(wpa_auth, sm->addr,
WPA_EAPOL_keyAvailable) > 0) {
SM_ENTER(WPA_PTK, PTKSTART);
#ifdef CONFIG_DPP
@@ -3557,13 +3625,13 @@ SM_STEP(WPA_PTK)
#endif /* CONFIG_DPP */
} else {
wpa_auth->dot11RSNA4WayHandshakeFailures++;
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO,
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
"INITPMK - keyAvailable = false");
SM_ENTER(WPA_PTK, DISCONNECT);
}
break;
case WPA_PTK_INITPSK:
- if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr,
+ if (wpa_auth_get_psk(wpa_auth, sm->addr, sm->p2p_dev_addr,
NULL, NULL, NULL)) {
SM_ENTER(WPA_PTK, PTKSTART);
#ifdef CONFIG_SAE
@@ -3571,7 +3639,7 @@ SM_STEP(WPA_PTK)
SM_ENTER(WPA_PTK, PTKSTART);
#endif /* CONFIG_SAE */
} else {
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO,
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
"no PSK configured for the STA");
wpa_auth->dot11RSNA4WayHandshakeFailures++;
SM_ENTER(WPA_PTK, DISCONNECT);
@@ -3581,13 +3649,11 @@ SM_STEP(WPA_PTK)
if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
sm->EAPOLKeyPairwise)
SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
- else if (sm->TimeoutCtr >
- sm->wpa_auth->conf.wpa_pairwise_update_count) {
+ else if (sm->TimeoutCtr > conf->wpa_pairwise_update_count) {
wpa_auth->dot11RSNA4WayHandshakeFailures++;
- wpa_auth_vlogger(
- sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "PTKSTART: Retry limit %u reached",
- sm->wpa_auth->conf.wpa_pairwise_update_count);
+ wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
+ "PTKSTART: Retry limit %u reached",
+ conf->wpa_pairwise_update_count);
SM_ENTER(WPA_PTK, DISCONNECT);
} else if (sm->TimeoutEvt)
SM_ENTER(WPA_PTK, PTKSTART);
@@ -3611,14 +3677,13 @@ SM_STEP(WPA_PTK)
sm->EAPOLKeyPairwise && sm->MICVerified)
SM_ENTER(WPA_PTK, PTKINITDONE);
else if (sm->TimeoutCtr >
- sm->wpa_auth->conf.wpa_pairwise_update_count ||
- (sm->wpa_auth->conf.wpa_disable_eapol_key_retries &&
+ conf->wpa_pairwise_update_count ||
+ (conf->wpa_disable_eapol_key_retries &&
sm->TimeoutCtr > 1)) {
wpa_auth->dot11RSNA4WayHandshakeFailures++;
- wpa_auth_vlogger(
- sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "PTKINITNEGOTIATING: Retry limit %u reached",
- sm->wpa_auth->conf.wpa_pairwise_update_count);
+ wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
+ "PTKINITNEGOTIATING: Retry limit %u reached",
+ conf->wpa_pairwise_update_count);
SM_ENTER(WPA_PTK, DISCONNECT);
} else if (sm->TimeoutEvt)
SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
@@ -3649,16 +3714,16 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
u8 *kde_buf = NULL, *pos, hdr[2];
size_t kde_len;
u8 *gtk, dummy_gtk[32];
+ struct wpa_auth_config *conf = &sm->wpa_auth->conf;
SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
sm->GTimeoutCtr++;
- if (sm->wpa_auth->conf.wpa_disable_eapol_key_retries &&
- sm->GTimeoutCtr > 1) {
+ if (conf->wpa_disable_eapol_key_retries && sm->GTimeoutCtr > 1) {
/* Do not allow retransmission of EAPOL-Key group msg 1/2 */
return;
}
- if (sm->GTimeoutCtr > sm->wpa_auth->conf.wpa_group_update_count) {
+ if (sm->GTimeoutCtr > conf->wpa_group_update_count) {
/* No point in sending the EAPOL-Key - we will disconnect
* immediately following this. */
return;
@@ -3675,8 +3740,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
"sending 1/2 msg of Group Key Handshake");
gtk = gsm->GTK[gsm->GN - 1];
- if (sm->wpa_auth->conf.disable_gtk ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) {
+ if (conf->disable_gtk || sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN) {
/*
* Provide unique random GTK to each STA to prevent use
* of GTK in the BSS.
@@ -3689,7 +3753,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
ieee80211w_kde_len(sm) + ocv_oci_len(sm);
kde_buf = os_malloc(kde_len);
- if (kde_buf == NULL)
+ if (!kde_buf)
return;
kde = pos = kde_buf;
@@ -3722,8 +3786,8 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED)
{
-#ifdef CONFIG_OCV
struct wpa_authenticator *wpa_auth = sm->wpa_auth;
+#ifdef CONFIG_OCV
const u8 *key_data, *mic;
struct ieee802_1x_hdr *hdr;
struct wpa_eapol_key *key;
@@ -3788,7 +3852,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED)
sm->GUpdateStationKeys = FALSE;
sm->GTimeoutCtr = 0;
/* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */
- wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO,
+ wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
"group key handshake completed (%s)",
sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
sm->has_GTK = TRUE;
@@ -3845,6 +3909,7 @@ SM_STEP(WPA_PTK_GROUP)
static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
struct wpa_group *group)
{
+ struct wpa_auth_config *conf = &wpa_auth->conf;
int ret = 0;
size_t len;
@@ -3857,8 +3922,8 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
wpa_hexdump_key(MSG_DEBUG, "GTK",
group->GTK[group->GN - 1], group->GTK_len);
- if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
- len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
+ if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
+ len = wpa_cipher_key_len(conf->group_mgmt_cipher);
os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
inc_byte_array(group->Counter, WPA_NONCE_LEN);
if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion",
@@ -3869,9 +3934,9 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
group->IGTK[group->GN_igtk - 4], len);
}
- if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION &&
- wpa_auth->conf.beacon_prot) {
- len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
+ if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
+ conf->beacon_prot) {
+ len = wpa_cipher_key_len(conf->group_mgmt_cipher);
os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
inc_byte_array(group->Counter, WPA_NONCE_LEN);
if (wpa_gmk_to_gtk(group->GMK, "BIGTK key expansion",
@@ -3889,8 +3954,9 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
static void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth,
struct wpa_group *group)
{
- wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
- "GTK_INIT (VLAN-ID %d)", group->vlan_id);
+ wpa_printf(MSG_DEBUG,
+ "WPA: group state machine entering state GTK_INIT (VLAN-ID %d)",
+ group->vlan_id);
group->changed = FALSE; /* GInit is not cleared here; avoid loop */
group->wpa_group_state = WPA_GROUP_GTK_INIT;
@@ -3925,8 +3991,7 @@ static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
* station needs to be counted here anyway.
*/
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "GUpdateStationKeys was already set when "
- "marking station for GTK rekeying");
+ "GUpdateStationKeys was already set when marking station for GTK rekeying");
}
/* Do not rekey GTK/IGTK when STA is in WNM-Sleep Mode */
@@ -3945,7 +4010,7 @@ static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
/* update GTK when exiting WNM-Sleep Mode */
void wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm)
{
- if (sm == NULL || sm->is_wnmsleep)
+ if (!sm || sm->is_wnmsleep)
return;
wpa_group_update_sta(sm, NULL);
@@ -4057,8 +4122,9 @@ static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth,
{
int tmp;
- wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
- "SETKEYS (VLAN-ID %d)", group->vlan_id);
+ wpa_printf(MSG_DEBUG,
+ "WPA: group state machine entering state SETKEYS (VLAN-ID %d)",
+ group->vlan_id);
group->changed = TRUE;
group->wpa_group_state = WPA_GROUP_SETKEYS;
group->GTKReKey = FALSE;
@@ -4077,8 +4143,8 @@ static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth,
wpa_gtk_update(wpa_auth, group);
if (group->GKeyDoneStations) {
- wpa_printf(MSG_DEBUG, "wpa_group_setkeys: Unexpected "
- "GKeyDoneStations=%d when starting new GTK rekey",
+ wpa_printf(MSG_DEBUG,
+ "wpa_group_setkeys: Unexpected GKeyDoneStations=%d when starting new GTK rekey",
group->GKeyDoneStations);
group->GKeyDoneStations = 0;
}
@@ -4091,21 +4157,22 @@ static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth,
static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
struct wpa_group *group)
{
+ struct wpa_auth_config *conf = &wpa_auth->conf;
int ret = 0;
if (wpa_auth_set_key(wpa_auth, group->vlan_id,
- wpa_cipher_to_alg(wpa_auth->conf.wpa_group),
+ wpa_cipher_to_alg(conf->wpa_group),
broadcast_ether_addr, group->GN,
group->GTK[group->GN - 1], group->GTK_len,
KEY_FLAG_GROUP_TX_DEFAULT) < 0)
ret = -1;
- if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
+ if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
enum wpa_alg alg;
size_t len;
- alg = wpa_cipher_to_alg(wpa_auth->conf.group_mgmt_cipher);
- len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
+ alg = wpa_cipher_to_alg(conf->group_mgmt_cipher);
+ len = wpa_cipher_key_len(conf->group_mgmt_cipher);
if (ret == 0 &&
wpa_auth_set_key(wpa_auth, group->vlan_id, alg,
@@ -4114,7 +4181,7 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
KEY_FLAG_GROUP_TX_DEFAULT) < 0)
ret = -1;
- if (ret == 0 && wpa_auth->conf.beacon_prot &&
+ if (ret == 0 && conf->beacon_prot &&
wpa_auth_set_key(wpa_auth, group->vlan_id, alg,
broadcast_ether_addr, group->GN_bigtk,
group->BIGTK[group->GN_bigtk - 6], len,
@@ -4130,7 +4197,7 @@ static int wpa_group_disconnect_cb(struct wpa_state_machine *sm, void *ctx)
{
if (sm->group == ctx) {
wpa_printf(MSG_DEBUG, "WPA: Mark STA " MACSTR
- " for discconnection due to fatal failure",
+ " for disconnection due to fatal failure",
MAC2STR(sm->addr));
sm->Disconnect = TRUE;
}
@@ -4142,7 +4209,8 @@ static int wpa_group_disconnect_cb(struct wpa_state_machine *sm, void *ctx)
static void wpa_group_fatal_failure(struct wpa_authenticator *wpa_auth,
struct wpa_group *group)
{
- wpa_printf(MSG_DEBUG, "WPA: group state machine entering state FATAL_FAILURE");
+ wpa_printf(MSG_DEBUG,
+ "WPA: group state machine entering state FATAL_FAILURE");
group->changed = TRUE;
group->wpa_group_state = WPA_GROUP_FATAL_FAILURE;
wpa_auth_for_each_sta(wpa_auth, wpa_group_disconnect_cb, group);
@@ -4152,8 +4220,9 @@ static void wpa_group_fatal_failure(struct wpa_authenticator *wpa_auth,
static int wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth,
struct wpa_group *group)
{
- wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
- "SETKEYSDONE (VLAN-ID %d)", group->vlan_id);
+ wpa_printf(MSG_DEBUG,
+ "WPA: group state machine entering state SETKEYSDONE (VLAN-ID %d)",
+ group->vlan_id);
group->changed = TRUE;
group->wpa_group_state = WPA_GROUP_SETKEYSDONE;
@@ -4190,7 +4259,7 @@ static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
static int wpa_sm_step(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ if (!sm)
return 0;
if (sm->in_step_loop) {
@@ -4220,8 +4289,9 @@ static int wpa_sm_step(struct wpa_state_machine *sm)
sm->in_step_loop = 0;
if (sm->pending_deinit) {
- wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state "
- "machine deinit for " MACSTR, MAC2STR(sm->addr));
+ wpa_printf(MSG_DEBUG,
+ "WPA: Completing pending STA state machine deinit for "
+ MACSTR, MAC2STR(sm->addr));
wpa_free_sta_sm(sm);
return 1;
}
@@ -4238,7 +4308,7 @@ static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx)
void wpa_auth_sm_notify(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ if (!sm)
return;
eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
}
@@ -4249,7 +4319,7 @@ void wpa_gtk_rekey(struct wpa_authenticator *wpa_auth)
int tmp, i;
struct wpa_group *group;
- if (wpa_auth == NULL)
+ if (!wpa_auth)
return;
group = wpa_auth->group;
@@ -4282,6 +4352,7 @@ static const char * wpa_bool_txt(int val)
int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
{
+ struct wpa_auth_config *conf;
int len = 0, ret;
char pmkid_txt[PMKID_LEN * 2 + 1];
#ifdef CONFIG_RSN_PREAUTH
@@ -4290,8 +4361,9 @@ int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
const int preauth = 0;
#endif /* CONFIG_RSN_PREAUTH */
- if (wpa_auth == NULL)
+ if (!wpa_auth)
return len;
+ conf = &wpa_auth->conf;
ret = os_snprintf(buf + len, buflen - len,
"dot11RSNAOptionImplemented=TRUE\n"
@@ -4299,8 +4371,8 @@ int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
"dot11RSNAEnabled=%s\n"
"dot11RSNAPreauthenticationEnabled=%s\n",
wpa_bool_txt(preauth),
- wpa_bool_txt(wpa_auth->conf.wpa & WPA_PROTO_RSN),
- wpa_bool_txt(wpa_auth->conf.rsn_preauth));
+ wpa_bool_txt(conf->wpa & WPA_PROTO_RSN),
+ wpa_bool_txt(conf->rsn_preauth));
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
@@ -4335,10 +4407,10 @@ int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
"dot11RSNA4WayHandshakeFailures=%u\n"
"dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n",
RSN_VERSION,
- !!wpa_auth->conf.wpa_strict_rekey,
- wpa_auth->conf.wpa_group_update_count,
- wpa_auth->conf.wpa_pairwise_update_count,
- wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8,
+ !!conf->wpa_strict_rekey,
+ conf->wpa_group_update_count,
+ conf->wpa_pairwise_update_count,
+ wpa_cipher_key_len(conf->wpa_group) * 8,
dot11RSNAConfigPMKLifetime,
dot11RSNAConfigPMKReauthThreshold,
dot11RSNAConfigSATimeout,
@@ -4374,7 +4446,7 @@ int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen)
int len = 0, ret;
u32 pairwise = 0;
- if (sm == NULL)
+ if (!sm)
return 0;
/* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */
@@ -4455,7 +4527,7 @@ const u8 * wpa_auth_get_pmk(struct wpa_state_machine *sm, int *len)
int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ if (!sm)
return -1;
return sm->wpa_key_mgmt;
}
@@ -4463,7 +4535,7 @@ int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm)
int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ if (!sm)
return 0;
return sm->wpa;
}
@@ -4488,7 +4560,7 @@ int wpa_auth_sta_fils_tk_already_set(struct wpa_state_machine *sm)
int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
struct rsn_pmksa_cache_entry *entry)
{
- if (sm == NULL || sm->pmksa != entry)
+ if (!sm || sm->pmksa != entry)
return -1;
sm->pmksa = NULL;
return 0;
@@ -4511,7 +4583,7 @@ void wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm)
const u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len)
{
- if (wpa_auth == NULL)
+ if (!wpa_auth)
return NULL;
*len = wpa_auth->wpa_ie_len;
return wpa_auth->wpa_ie;
@@ -4522,7 +4594,7 @@ int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk,
unsigned int pmk_len,
int session_timeout, struct eapol_state_machine *eapol)
{
- if (sm == NULL || sm->wpa != WPA_VERSION_WPA2 ||
+ if (!sm || sm->wpa != WPA_VERSION_WPA2 ||
sm->wpa_auth->conf.disable_pmksa_caching)
return -1;
@@ -4558,7 +4630,7 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
int session_timeout,
struct eapol_state_machine *eapol)
{
- if (wpa_auth == NULL)
+ if (!wpa_auth)
return -1;
wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from preauth", pmk, len);
@@ -4619,7 +4691,7 @@ void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth,
{
struct rsn_pmksa_cache_entry *pmksa;
- if (wpa_auth == NULL || wpa_auth->pmksa == NULL)
+ if (!wpa_auth || !wpa_auth->pmksa)
return;
pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sta_addr, NULL);
if (pmksa) {
@@ -4785,13 +4857,13 @@ wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id)
{
struct wpa_group *group;
- if (wpa_auth == NULL || wpa_auth->group == NULL)
+ if (!wpa_auth || !wpa_auth->group)
return NULL;
wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d",
vlan_id);
group = wpa_group_init(wpa_auth, vlan_id, 0);
- if (group == NULL)
+ if (!group)
return NULL;
group->next = wpa_auth->group->next;
@@ -4811,7 +4883,7 @@ int wpa_auth_ensure_group(struct wpa_authenticator *wpa_auth, int vlan_id)
{
struct wpa_group *group;
- if (wpa_auth == NULL)
+ if (!wpa_auth)
return 0;
group = wpa_auth->group;
@@ -4821,9 +4893,9 @@ int wpa_auth_ensure_group(struct wpa_authenticator *wpa_auth, int vlan_id)
group = group->next;
}
- if (group == NULL) {
+ if (!group) {
group = wpa_auth_add_group(wpa_auth, vlan_id);
- if (group == NULL)
+ if (!group)
return -1;
}
@@ -4852,7 +4924,7 @@ int wpa_auth_release_group(struct wpa_authenticator *wpa_auth, int vlan_id)
struct wpa_group *group;
int ret = 0;
- if (wpa_auth == NULL)
+ if (!wpa_auth)
return 0;
group = wpa_auth->group;
@@ -4862,7 +4934,7 @@ int wpa_auth_release_group(struct wpa_authenticator *wpa_auth, int vlan_id)
group = group->next;
}
- if (group == NULL)
+ if (!group)
return -1;
wpa_printf(MSG_DEBUG,
@@ -4897,7 +4969,7 @@ int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
{
struct wpa_group *group;
- if (sm == NULL || sm->wpa_auth == NULL)
+ if (!sm || !sm->wpa_auth)
return 0;
group = sm->wpa_auth->group;
@@ -4907,9 +4979,9 @@ int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
group = group->next;
}
- if (group == NULL) {
+ if (!group) {
group = wpa_auth_add_group(sm->wpa_auth, vlan_id);
- if (group == NULL)
+ if (!group)
return -1;
}
@@ -4919,8 +4991,9 @@ int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE)
return -1;
- wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state "
- "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id);
+ wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR
+ " to use group state machine for VLAN ID %d",
+ MAC2STR(sm->addr), vlan_id);
wpa_group_get(sm->wpa_auth, group);
wpa_group_put(sm->wpa_auth, sm->group);
@@ -4933,7 +5006,7 @@ int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm, int ack)
{
- if (wpa_auth == NULL || sm == NULL)
+ if (!wpa_auth || !sm)
return;
wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key TX status for STA " MACSTR
" ack=%d", MAC2STR(sm->addr), ack);
@@ -4949,8 +5022,8 @@ void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
* the station has received the frame.
*/
int timeout_ms = eapol_key_timeout_subseq;
- wpa_printf(MSG_DEBUG, "WPA: Increase initial EAPOL-Key 1/4 "
- "timeout by %u ms because of acknowledged frame",
+ wpa_printf(MSG_DEBUG,
+ "WPA: Increase initial EAPOL-Key 1/4 timeout by %u ms because of acknowledged frame",
timeout_ms);
eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm);
eloop_register_timeout(timeout_ms / 1000,
@@ -4970,7 +5043,7 @@ void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
int wpa_auth_uses_sae(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ if (!sm)
return 0;
return wpa_key_mgmt_sae(sm->wpa_key_mgmt);
}
@@ -4978,7 +5051,7 @@ int wpa_auth_uses_sae(struct wpa_state_machine *sm)
int wpa_auth_uses_ft_sae(struct wpa_state_machine *sm)
{
- if (sm == NULL)
+ if (!sm)
return 0;
return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE;
}
@@ -4987,7 +5060,7 @@ int wpa_auth_uses_ft_sae(struct wpa_state_machine *sm)
#ifdef CONFIG_P2P
int wpa_auth_get_ip_addr(struct wpa_state_machine *sm, u8 *addr)
{
- if (sm == NULL || WPA_GET_BE32(sm->ip_addr) == 0)
+ if (!sm || WPA_GET_BE32(sm->ip_addr) == 0)
return -1;
os_memcpy(addr, sm->ip_addr, 4);
return 0;
@@ -5063,7 +5136,7 @@ int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder,
conf->r0_key_holder_len,
- NULL, NULL, buf, len, NULL, 0);
+ NULL, NULL, buf, len, NULL, 0, 0);
}
#endif /* CONFIG_IEEE80211R_AP */
@@ -5143,6 +5216,7 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
struct wpa_group *gsm = sm->group;
u8 *wpa_ie;
int wpa_ie_len, secure, gtkidx, encr = 0;
+ u8 hdr[2];
/* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, [MDIE],
GTK[GN], IGTK, [BIGTK], [FTIE], [TIE * 2])
@@ -5188,13 +5262,16 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
* WPA if the supplicant used it first.
*/
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "STA used Secure bit in WPA msg 2/4 - "
- "set Secure for 3/4 as workaround");
+ "STA used Secure bit in WPA msg 2/4 - set Secure for 3/4 as workaround");
secure = 1;
}
}
kde_len = wpa_ie_len + ieee80211w_kde_len(sm) + ocv_oci_len(sm);
+
+ if (sm->use_ext_key_id)
+ kde_len += 2 + RSN_SELECTOR_LEN + 2;
+
if (gtk)
kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len;
#ifdef CONFIG_IEEE80211R_AP
@@ -5204,7 +5281,7 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
}
#endif /* CONFIG_IEEE80211R_AP */
kde = os_malloc(kde_len);
- if (kde == NULL)
+ if (!kde)
return -1;
pos = kde;
@@ -5218,8 +5295,8 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
elen = pos - kde;
res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name);
if (res < 0) {
- wpa_printf(MSG_ERROR, "FT: Failed to insert "
- "PMKR1Name into RSN IE in EAPOL-Key data");
+ wpa_printf(MSG_ERROR,
+ "FT: Failed to insert PMKR1Name into RSN IE in EAPOL-Key data");
os_free(kde);
return -1;
}
@@ -5227,10 +5304,15 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
pos += elen;
}
#endif /* CONFIG_IEEE80211R_AP */
+ hdr[1] = 0;
+
+ if (sm->use_ext_key_id) {
+ hdr[0] = sm->keyidx_active & 0x01;
+ pos = wpa_add_kde(pos, RSN_KEY_DATA_KEYID, hdr, 2, NULL, 0);
+ }
+
if (gtk) {
- u8 hdr[2];
hdr[0] = gtkidx & 0x03;
- hdr[1] = 0;
pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
gtk, gtk_len);
}
@@ -5265,11 +5347,11 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
conf->r0_key_holder_len,
NULL, NULL, pos,
kde + kde_len - pos,
- NULL, 0);
+ NULL, 0, 0);
}
if (res < 0) {
- wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
- "into EAPOL-Key Key Data");
+ wpa_printf(MSG_ERROR,
+ "FT: Failed to insert FTIE into EAPOL-Key Key Data");
os_free(kde);
return -1;
}
@@ -5326,7 +5408,7 @@ int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
ieee80211w_kde_len(sm) + ocv_oci_len(sm);
kde_buf = os_malloc(kde_len);
- if (kde_buf == NULL)
+ if (!kde_buf)
return -1;
kde = pos = kde_buf;
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 1f7ba48..fafabe9 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -169,6 +169,7 @@ struct ft_remote_r1kh {
struct wpa_auth_config {
int wpa;
+ int extended_key_id;
int wpa_key_mgmt;
int wpa_pairwise;
int wpa_group;
@@ -221,10 +222,20 @@ struct wpa_auth_config {
double corrupt_gtk_rekey_mic_probability;
u8 own_ie_override[MAX_OWN_IE_OVERRIDE];
size_t own_ie_override_len;
+ u8 rsne_override_eapol[MAX_OWN_IE_OVERRIDE];
+ size_t rsne_override_eapol_len;
u8 rsnxe_override_eapol[MAX_OWN_IE_OVERRIDE];
size_t rsnxe_override_eapol_len;
+ u8 rsne_override_ft[MAX_OWN_IE_OVERRIDE];
+ size_t rsne_override_ft_len;
+ u8 rsnxe_override_ft[MAX_OWN_IE_OVERRIDE];
+ size_t rsnxe_override_ft_len;
u8 gtk_rsc_override[WPA_KEY_RSC_LEN];
u8 igtk_rsc_override[WPA_KEY_RSC_LEN];
+ unsigned int rsne_override_eapol_set:1;
+ unsigned int rsnxe_override_eapol_set:1;
+ unsigned int rsne_override_ft_set:1;
+ unsigned int rsnxe_override_ft_set:1;
unsigned int gtk_rsc_override_set:1;
unsigned int igtk_rsc_override_set:1;
#endif /* CONFIG_TESTING_OPTIONS */
@@ -240,6 +251,10 @@ struct wpa_auth_config {
#endif /* CONFIG_FILS */
int sae_pwe;
int owe_ptk_workaround;
+ u8 transition_disable;
+#ifdef CONFIG_DPP2
+ int dpp_pfs;
+#endif /* CONFIG_DPP2 */
};
typedef enum {
@@ -286,6 +301,7 @@ struct wpa_auth_callbacks {
int *bandwidth, int *seg1_idx);
#ifdef CONFIG_IEEE80211R_AP
struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr);
+ int (*add_sta_ft)(void *ctx, const u8 *sta_addr);
int (*set_vlan)(void *ctx, const u8 *sta_addr,
struct vlan_description *vlan);
int (*get_vlan)(void *ctx, const u8 *sta_addr,
@@ -319,19 +335,21 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth);
int wpa_reconfig(struct wpa_authenticator *wpa_auth,
struct wpa_auth_config *conf);
-enum {
+enum wpa_validate_result {
WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE,
WPA_INVALID_AKMP, WPA_NOT_ENABLED, WPA_ALLOC_FAIL,
WPA_MGMT_FRAME_PROTECTION_VIOLATION, WPA_INVALID_MGMT_GROUP_CIPHER,
- WPA_INVALID_MDIE, WPA_INVALID_PROTO, WPA_INVALID_PMKID
+ WPA_INVALID_MDIE, WPA_INVALID_PROTO, WPA_INVALID_PMKID,
+ WPA_DENIED_OTHER_REASON
};
-int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm, int freq,
- const u8 *wpa_ie, size_t wpa_ie_len,
- const u8 *rsnxe, size_t rsnxe_len,
- const u8 *mdie, size_t mdie_len,
- const u8 *owe_dh, size_t owe_dh_len);
+enum wpa_validate_result
+wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
+ struct wpa_state_machine *sm, int freq,
+ const u8 *wpa_ie, size_t wpa_ie_len,
+ const u8 *rsnxe, size_t rsnxe_len,
+ const u8 *mdie, size_t mdie_len,
+ const u8 *owe_dh, size_t owe_dh_len);
int wpa_validate_osen(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm,
const u8 *osen_ie, size_t osen_ie_len);
@@ -415,7 +433,8 @@ void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
#ifdef CONFIG_IEEE80211R_AP
u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
size_t max_len, int auth_alg,
- const u8 *req_ies, size_t req_ies_len);
+ const u8 *req_ies, size_t req_ies_len,
+ int omit_rsnxe);
void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
u16 auth_transaction, const u8 *ies, size_t ies_len,
void (*cb)(void *ctx, const u8 *dst, const u8 *bssid,
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index c0b4625..4ca18ab 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -808,7 +808,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *anonce, const u8 *snonce,
u8 *buf, size_t len, const u8 *subelem,
- size_t subelem_len)
+ size_t subelem_len, int rsnxe_used)
{
u8 *pos = buf, *ielen;
size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) :
@@ -826,7 +826,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
os_memset(hdr, 0, sizeof(*hdr));
pos += sizeof(*hdr);
- WPA_PUT_LE16(hdr->mic_control, 0);
+ WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
if (anonce)
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
if (snonce)
@@ -836,7 +836,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
os_memset(hdr, 0, sizeof(*hdr));
pos += sizeof(*hdr);
- WPA_PUT_LE16(hdr->mic_control, 0);
+ WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
if (anonce)
os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
if (snonce)
@@ -2463,13 +2463,15 @@ static u8 * wpa_ft_process_ric(struct wpa_state_machine *sm, u8 *pos, u8 *end,
u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
size_t max_len, int auth_alg,
- const u8 *req_ies, size_t req_ies_len)
+ const u8 *req_ies, size_t req_ies_len,
+ int omit_rsnxe)
{
u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL;
u8 *fte_mic, *elem_count;
size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0;
- u8 rsnxe[10];
+ u8 rsnxe_buf[10], *rsnxe = rsnxe_buf;
size_t rsnxe_len;
+ int rsnxe_used;
int res;
struct wpa_auth_config *conf;
struct wpa_ft_ies parse;
@@ -2490,6 +2492,32 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
end = pos + max_len;
+#ifdef CONFIG_TESTING_OPTIONS
+ if (auth_alg == WLAN_AUTH_FT &&
+ sm->wpa_auth->conf.rsne_override_ft_set) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: RSNE FT override for MIC calculation");
+ rsnie = sm->wpa_auth->conf.rsne_override_ft;
+ rsnie_len = sm->wpa_auth->conf.rsne_override_ft_len;
+ if (end - pos < (long int) rsnie_len)
+ return pos;
+ os_memcpy(pos, rsnie, rsnie_len);
+ rsnie = pos;
+ pos += rsnie_len;
+ if (rsnie_len > PMKID_LEN && sm->pmk_r1_name_valid) {
+ int idx;
+
+ /* Replace all 0xff PMKID with the valid PMKR1Name */
+ for (idx = 0; idx < PMKID_LEN; idx++) {
+ if (rsnie[rsnie_len - 1 - idx] != 0xff)
+ break;
+ }
+ if (idx == PMKID_LEN)
+ os_memcpy(&rsnie[rsnie_len - PMKID_LEN],
+ sm->pmk_r1_name, WPA_PMK_NAME_LEN);
+ }
+ } else
+#endif /* CONFIG_TESTING_OPTIONS */
if (auth_alg == WLAN_AUTH_FT ||
((auth_alg == WLAN_AUTH_FILS_SK ||
auth_alg == WLAN_AUTH_FILS_SK_PFS ||
@@ -2617,9 +2645,11 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
anonce = NULL;
snonce = NULL;
}
+ rsnxe_used = (auth_alg == WLAN_AUTH_FT) &&
+ (conf->sae_pwe == 1 || conf->sae_pwe == 2);
res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
anonce, snonce, pos, end - pos,
- subelem, subelem_len);
+ subelem, subelem_len, rsnxe_used);
os_free(subelem);
if (res < 0)
return NULL;
@@ -2655,10 +2685,24 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
if (ric_start == pos)
ric_start = NULL;
- res = wpa_write_rsnxe(&sm->wpa_auth->conf, rsnxe, sizeof(rsnxe));
- if (res < 0)
- return NULL;
- rsnxe_len = res;
+ if (omit_rsnxe) {
+ rsnxe_len = 0;
+ } else {
+ res = wpa_write_rsnxe(&sm->wpa_auth->conf, rsnxe,
+ sizeof(rsnxe_buf));
+ if (res < 0)
+ return NULL;
+ rsnxe_len = res;
+ }
+#ifdef CONFIG_TESTING_OPTIONS
+ if (auth_alg == WLAN_AUTH_FT &&
+ sm->wpa_auth->conf.rsnxe_override_ft_set) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: RSNXE FT override for MIC calculation");
+ rsnxe = sm->wpa_auth->conf.rsnxe_override_ft;
+ rsnxe_len = sm->wpa_auth->conf.rsnxe_override_ft_len;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
if (auth_alg == WLAN_AUTH_FT && rsnxe_len)
*elem_count += 1;
@@ -2703,7 +2747,16 @@ static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
}
-void wpa_ft_install_ptk(struct wpa_state_machine *sm)
+static inline int wpa_auth_add_sta_ft(struct wpa_authenticator *wpa_auth,
+ const u8 *addr)
+{
+ if (!wpa_auth->cb->add_sta_ft)
+ return -1;
+ return wpa_auth->cb->add_sta_ft(wpa_auth->cb_ctx, addr);
+}
+
+
+void wpa_ft_install_ptk(struct wpa_state_machine *sm, int retry)
{
enum wpa_alg alg;
int klen;
@@ -2725,13 +2778,16 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
return;
}
+ if (!retry)
+ wpa_auth_add_sta_ft(sm->wpa_auth, sm->addr);
+
/* FIX: add STA entry to kernel/driver here? The set_key will fail
* most likely without this.. At the moment, STA entry is added only
* after association has been completed. This function will be called
* again after association to get the PTK configured, but that could be
* optimized by adding the STA entry earlier.
*/
- if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
+ if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, sm->keyidx_active,
sm->PTK.tk, klen, KEY_FLAG_PAIRWISE_RX_TX))
return;
@@ -3096,7 +3152,7 @@ pmk_r1_derived:
sm->pairwise = pairwise;
sm->PTK_valid = TRUE;
sm->tk_already_set = FALSE;
- wpa_ft_install_ptk(sm);
+ wpa_ft_install_ptk(sm, 0);
if (wpa_ft_set_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) {
wpa_printf(MSG_DEBUG, "FT: Failed to configure VLAN");
@@ -3131,7 +3187,8 @@ pmk_r1_derived:
pos += ret;
ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len,
- sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0);
+ sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0,
+ 0);
if (ret < 0)
goto fail;
pos += ret;
@@ -3203,10 +3260,13 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
int use_sha384;
const u8 *anonce, *snonce, *fte_mic;
u8 fte_elem_count;
+ int rsnxe_used;
+ struct wpa_auth_config *conf;
if (sm == NULL)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ conf = &sm->wpa_auth->conf;
use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
@@ -3235,8 +3295,7 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
mdie = (struct rsn_mdie *) parse.mdie;
if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
- os_memcmp(mdie->mobility_domain,
- sm->wpa_auth->conf.mobility_domain,
+ os_memcmp(mdie->mobility_domain, conf->mobility_domain,
MOBILITY_DOMAIN_ID_LEN) != 0) {
wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
return WLAN_STATUS_INVALID_MDIE;
@@ -3253,6 +3312,7 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
anonce = ftie->anonce;
snonce = ftie->snonce;
+ rsnxe_used = ftie->mic_control[0] & 0x01;
fte_elem_count = ftie->mic_control[1];
fte_mic = ftie->mic;
} else {
@@ -3266,6 +3326,7 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
anonce = ftie->anonce;
snonce = ftie->snonce;
+ rsnxe_used = ftie->mic_control[0] & 0x01;
fte_elem_count = ftie->mic_control[1];
fte_mic = ftie->mic;
}
@@ -3311,14 +3372,14 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
return WLAN_STATUS_INVALID_FTIE;
}
- if (os_memcmp_const(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder,
+ if (os_memcmp_const(parse.r1kh_id, conf->r1_key_holder,
FT_R1KH_ID_LEN) != 0) {
wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
"ReassocReq");
wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID in FTIE",
parse.r1kh_id, FT_R1KH_ID_LEN);
wpa_hexdump(MSG_DEBUG, "FT: Expected R1KH-ID",
- sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
+ conf->r1_key_holder, FT_R1KH_ID_LEN);
return WLAN_STATUS_INVALID_FTIE;
}
@@ -3380,6 +3441,13 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
return WLAN_STATUS_INVALID_FTIE;
}
+ if (rsnxe_used && (conf->sae_pwe == 1 || conf->sae_pwe == 2) &&
+ !parse.rsnxe) {
+ wpa_printf(MSG_INFO,
+ "FT: FTE indicated that STA uses RSNXE, but RSNXE was not included");
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ }
+
#ifdef CONFIG_OCV
if (wpa_auth_uses_ocv(sm)) {
struct wpa_channel_info ci;
@@ -4504,7 +4572,6 @@ int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
return -1;
}
status_code = WPA_GET_LE16(pos);
- pos += 2;
wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Response "
"(status_code=%d)", status_code);
@@ -4517,11 +4584,6 @@ int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
return -1;
}
- if (end > pos) {
- wpa_hexdump(MSG_DEBUG, "FT: Ignore extra data in end",
- pos, end - pos);
- }
-
return 0;
}
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 82e82a7..79880e4 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -41,6 +41,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
os_memset(wconf, 0, sizeof(*wconf));
wconf->wpa = conf->wpa;
+ wconf->extended_key_id = conf->extended_key_id;
wconf->wpa_key_mgmt = conf->wpa_key_mgmt;
wconf->wpa_pairwise = conf->wpa_pairwise;
wconf->wpa_group = conf->wpa_group;
@@ -121,14 +122,42 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
wpabuf_head(conf->own_ie_override),
wconf->own_ie_override_len);
}
+ if (conf->rsne_override_eapol &&
+ wpabuf_len(conf->rsne_override_eapol) <= MAX_OWN_IE_OVERRIDE) {
+ wconf->rsne_override_eapol_set = 1;
+ wconf->rsne_override_eapol_len =
+ wpabuf_len(conf->rsne_override_eapol);
+ os_memcpy(wconf->rsne_override_eapol,
+ wpabuf_head(conf->rsne_override_eapol),
+ wconf->rsne_override_eapol_len);
+ }
if (conf->rsnxe_override_eapol &&
wpabuf_len(conf->rsnxe_override_eapol) <= MAX_OWN_IE_OVERRIDE) {
+ wconf->rsnxe_override_eapol_set = 1;
wconf->rsnxe_override_eapol_len =
wpabuf_len(conf->rsnxe_override_eapol);
os_memcpy(wconf->rsnxe_override_eapol,
wpabuf_head(conf->rsnxe_override_eapol),
wconf->rsnxe_override_eapol_len);
}
+ if (conf->rsne_override_ft &&
+ wpabuf_len(conf->rsne_override_ft) <= MAX_OWN_IE_OVERRIDE) {
+ wconf->rsne_override_ft_set = 1;
+ wconf->rsne_override_ft_len =
+ wpabuf_len(conf->rsne_override_ft);
+ os_memcpy(wconf->rsne_override_ft,
+ wpabuf_head(conf->rsne_override_ft),
+ wconf->rsne_override_ft_len);
+ }
+ if (conf->rsnxe_override_ft &&
+ wpabuf_len(conf->rsnxe_override_ft) <= MAX_OWN_IE_OVERRIDE) {
+ wconf->rsnxe_override_ft_set = 1;
+ wconf->rsnxe_override_ft_len =
+ wpabuf_len(conf->rsnxe_override_ft);
+ os_memcpy(wconf->rsnxe_override_ft,
+ wpabuf_head(conf->rsnxe_override_ft),
+ wconf->rsnxe_override_ft_len);
+ }
if (conf->gtk_rsc_override &&
wpabuf_len(conf->gtk_rsc_override) > 0 &&
wpabuf_len(conf->gtk_rsc_override) <= WPA_KEY_RSC_LEN) {
@@ -166,6 +195,10 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
#ifdef CONFIG_OWE
wconf->owe_ptk_workaround = conf->owe_ptk_workaround;
#endif /* CONFIG_OWE */
+ wconf->transition_disable = conf->transition_disable;
+#ifdef CONFIG_DPP2
+ wconf->dpp_pfs = conf->dpp_pfs;
+#endif /* CONFIG_DPP2 */
}
@@ -405,7 +438,11 @@ static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
}
#ifdef CONFIG_TESTING_OPTIONS
- if (addr && !is_broadcast_ether_addr(addr)) {
+ if (key_flag & KEY_FLAG_MODIFY) {
+ /* We are updating an already installed key. Don't overwrite
+ * the already stored key information with zeros.
+ */
+ } else if (addr && !is_broadcast_ether_addr(addr)) {
struct sta_info *sta;
sta = ap_get_sta(hapd, addr);
@@ -1001,6 +1038,34 @@ hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr)
}
+static int hostapd_wpa_auth_add_sta_ft(void *ctx, const u8 *sta_addr)
+{
+ struct hostapd_data *hapd = ctx;
+ struct sta_info *sta;
+
+ sta = ap_get_sta(hapd, sta_addr);
+ if (!sta)
+ return -1;
+
+ if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
+ (sta->flags & WLAN_STA_MFP) && ap_sta_is_authorized(sta) &&
+ !(hapd->conf->mesh & MESH_ENABLED) && !(sta->added_unassoc)) {
+ /* We could not do this in handle_auth() since there was a
+ * PMF-enabled association for the STA and the new
+ * authentication attempt was not yet fully processed. Now that
+ * we are ready to configure the TK to the driver,
+ * authentication has succeeded and we can clean up the driver
+ * STA entry to avoid issues with any maintained state from the
+ * previous association. */
+ wpa_printf(MSG_DEBUG,
+ "FT: Remove and re-add driver STA entry after successful FT authentication");
+ return ap_sta_re_add(hapd, sta);
+ }
+
+ return 0;
+}
+
+
static int hostapd_wpa_auth_set_vlan(void *ctx, const u8 *sta_addr,
struct vlan_description *vlan)
{
@@ -1362,6 +1427,7 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
#ifdef CONFIG_IEEE80211R_AP
.send_ft_action = hostapd_wpa_auth_send_ft_action,
.add_sta = hostapd_wpa_auth_add_sta,
+ .add_sta_ft = hostapd_wpa_auth_add_sta_ft,
.add_tspec = hostapd_wpa_auth_add_tspec,
.set_vlan = hostapd_wpa_auth_set_vlan,
.get_vlan = hostapd_wpa_auth_get_vlan,
@@ -1391,6 +1457,12 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
_conf.wpa_deny_ptk0_rekey = 1;
}
+ if (_conf.extended_key_id &&
+ (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_EXTENDED_KEY_ID))
+ wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Extended Key ID supported");
+ else
+ _conf.extended_key_id = 0;
+
hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd);
if (hapd->wpa_auth == NULL) {
wpa_printf(MSG_ERROR, "WPA initialization failed.");
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index c2b22eb..813612e 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -61,6 +61,8 @@ struct wpa_state_machine {
unsigned int pmk_len;
u8 pmkid[PMKID_LEN]; /* valid if pmkid_set == 1 */
struct wpa_ptk PTK;
+ u8 keyidx_active;
+ Boolean use_ext_key_id;
Boolean PTK_valid;
Boolean pairwise_set;
Boolean tk_already_set;
@@ -294,11 +296,11 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *anonce, const u8 *snonce,
u8 *buf, size_t len, const u8 *subelem,
- size_t subelem_len);
+ size_t subelem_len, int rsnxe_used);
int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk);
struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
-void wpa_ft_install_ptk(struct wpa_state_machine *sm);
+void wpa_ft_install_ptk(struct wpa_state_machine *sm, int retry);
int wpa_ft_store_pmk_fils(struct wpa_state_machine *sm, const u8 *pmk_r0,
const u8 *pmk_r0_name);
#endif /* CONFIG_IEEE80211R_AP */
diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c
index 2e6d059..9bcb997 100644
--- a/src/ap/wpa_auth_ie.c
+++ b/src/ap/wpa_auth_ie.c
@@ -297,6 +297,8 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
if (rsn_testing)
capab |= BIT(8) | BIT(15);
#endif /* CONFIG_RSN_TESTING */
+ if (conf->extended_key_id)
+ capab |= WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST;
WPA_PUT_LE16(pos, capab);
pos += 2;
@@ -546,13 +548,15 @@ static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx)
}
-int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm, int freq,
- const u8 *wpa_ie, size_t wpa_ie_len,
- const u8 *rsnxe, size_t rsnxe_len,
- const u8 *mdie, size_t mdie_len,
- const u8 *owe_dh, size_t owe_dh_len)
+enum wpa_validate_result
+wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
+ struct wpa_state_machine *sm, int freq,
+ const u8 *wpa_ie, size_t wpa_ie_len,
+ const u8 *rsnxe, size_t rsnxe_len,
+ const u8 *mdie, size_t mdie_len,
+ const u8 *owe_dh, size_t owe_dh_len)
{
+ struct wpa_auth_config *conf = &wpa_auth->conf;
struct wpa_ie_data data;
int ciphers, key_mgmt, res, version;
u32 selector;
@@ -847,19 +851,18 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
"OWE: No Diffie-Hellman Parameter element");
return WPA_INVALID_AKMP;
}
-#ifdef CONFIG_DPP
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP && owe_dh) {
- /* Diffie-Hellman Parameter element can be used with DPP as
- * well, so allow this to proceed. */
- } else
-#endif /* CONFIG_DPP */
- if (sm->wpa_key_mgmt != WPA_KEY_MGMT_OWE && owe_dh) {
- wpa_printf(MSG_DEBUG,
- "OWE: Unexpected Diffie-Hellman Parameter element with non-OWE AKM");
- return WPA_INVALID_AKMP;
- }
#endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP2
+ if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP &&
+ ((conf->dpp_pfs == 1 && !owe_dh) ||
+ (conf->dpp_pfs == 2 && owe_dh))) {
+ wpa_printf(MSG_DEBUG, "DPP: PFS %s",
+ conf->dpp_pfs == 1 ? "required" : "not allowed");
+ return WPA_DENIED_OTHER_REASON;
+ }
+#endif /* CONFIG_DPP2 */
+
sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
if (sm->pairwise < 0)
return WPA_INVALID_PAIRWISE;
@@ -944,6 +947,23 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
}
#endif /* CONFIG_DPP */
+ if (conf->extended_key_id && sm->wpa == WPA_VERSION_WPA2 &&
+ sm->pairwise != WPA_CIPHER_TKIP &&
+ (data.capabilities & WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST)) {
+ sm->use_ext_key_id = TRUE;
+ if (conf->extended_key_id == 2 &&
+ !wpa_key_mgmt_ft(sm->wpa_key_mgmt) &&
+ !wpa_key_mgmt_fils(sm->wpa_key_mgmt))
+ sm->keyidx_active = 1;
+ else
+ sm->keyidx_active = 0;
+ wpa_printf(MSG_DEBUG,
+ "RSN: Extended Key ID supported (start with %d)",
+ sm->keyidx_active);
+ } else {
+ sm->use_ext_key_id = FALSE;
+ }
+
if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
os_free(sm->wpa_ie);
sm->wpa_ie = os_malloc(wpa_ie_len);
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index 5ea206c..1d77b94 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -651,8 +651,10 @@ static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx)
(str_starts(buf, "ssid=") ||
str_starts(buf, "ssid2=") ||
str_starts(buf, "auth_algs=") ||
+#ifdef CONFIG_WEP
str_starts(buf, "wep_default_key=") ||
str_starts(buf, "wep_key") ||
+#endif /* CONFIG_WEP */
str_starts(buf, "wps_state=") ||
(pmf_changed && str_starts(buf, "ieee80211w=")) ||
str_starts(buf, "wpa=") ||
@@ -1196,6 +1198,7 @@ int hostapd_init_wps(struct hostapd_data *hapd,
wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
conf->ssid.wpa_psk->psk, PMK_LEN);
wps->network_key_len = 2 * PMK_LEN;
+#ifdef CONFIG_WEP
} else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
wps->network_key = os_malloc(conf->ssid.wep.len[0]);
if (wps->network_key == NULL)
@@ -1203,6 +1206,7 @@ int hostapd_init_wps(struct hostapd_data *hapd,
os_memcpy(wps->network_key, conf->ssid.wep.key[0],
conf->ssid.wep.len[0]);
wps->network_key_len = conf->ssid.wep.len[0];
+#endif /* CONFIG_WEP */
}
if (conf->ssid.wpa_psk) {
@@ -1260,8 +1264,6 @@ int hostapd_init_wps(struct hostapd_data *hapd,
cfg.extra_cred_len = conf->extra_cred_len;
cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) &&
conf->skip_cred_build;
- if (conf->ssid.security_policy == SECURITY_STATIC_WEP)
- cfg.static_wep_only = 1;
cfg.dualband = interface_count(hapd->iface) > 1;
if ((wps->dev.rf_bands & (WPS_RF_50GHZ | WPS_RF_24GHZ)) ==
(WPS_RF_50GHZ | WPS_RF_24GHZ))
diff --git a/src/common/common_module_tests.c b/src/common/common_module_tests.c
index 7694c96..a58bf66 100644
--- a/src/common/common_module_tests.c
+++ b/src/common/common_module_tests.c
@@ -434,7 +434,8 @@ static int sae_tests(void)
goto fail;
/* Check that output matches the test vector */
- sae_write_commit(&sae, buf, NULL, pwid);
+ if (sae_write_commit(&sae, buf, NULL, pwid) < 0)
+ goto fail;
wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf);
if (wpabuf_len(buf) != sizeof(local_commit) ||
diff --git a/src/common/defs.h b/src/common/defs.h
index 1e21ec2..f62c3ce 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -82,6 +82,13 @@ static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
WPA_KEY_MGMT_FT_FILS_SHA384));
}
+static inline int wpa_key_mgmt_wpa_psk_no_sae(int akm)
+{
+ return !!(akm & (WPA_KEY_MGMT_PSK |
+ WPA_KEY_MGMT_FT_PSK |
+ WPA_KEY_MGMT_PSK_SHA256));
+}
+
static inline int wpa_key_mgmt_wpa_psk(int akm)
{
return !!(akm & (WPA_KEY_MGMT_PSK |
@@ -193,7 +200,6 @@ enum wpa_alg {
WPA_ALG_TKIP,
WPA_ALG_CCMP,
WPA_ALG_IGTK,
- WPA_ALG_PMK,
WPA_ALG_GCMP,
WPA_ALG_SMS4,
WPA_ALG_KRK,
@@ -443,8 +449,23 @@ enum key_flag {
KEY_FLAG_PAIRWISE_RX = KEY_FLAG_PAIRWISE | KEY_FLAG_RX,
KEY_FLAG_PAIRWISE_RX_TX_MODIFY = KEY_FLAG_PAIRWISE_RX_TX |
KEY_FLAG_MODIFY,
+ /* Max allowed flags for each key type */
+ KEY_FLAG_PAIRWISE_MASK = KEY_FLAG_PAIRWISE_RX_TX_MODIFY,
+ KEY_FLAG_GROUP_MASK = KEY_FLAG_GROUP_RX_TX_DEFAULT,
+ KEY_FLAG_PMK_MASK = KEY_FLAG_PMK,
};
+static inline int check_key_flag(enum key_flag key_flag)
+{
+ return !!(!key_flag ||
+ ((key_flag & (KEY_FLAG_PAIRWISE | KEY_FLAG_MODIFY)) &&
+ (key_flag & ~KEY_FLAG_PAIRWISE_MASK)) ||
+ ((key_flag & KEY_FLAG_GROUP) &&
+ (key_flag & ~KEY_FLAG_GROUP_MASK)) ||
+ ((key_flag & KEY_FLAG_PMK) &&
+ (key_flag & ~KEY_FLAG_PMK_MASK)));
+}
+
enum ptk0_rekey_handling {
PTK0_REKEY_ALLOW_ALWAYS,
PTK0_REKEY_ALLOW_LOCAL_OK,
diff --git a/src/common/dpp.c b/src/common/dpp.c
index b200d00..c4ee9b8 100644
--- a/src/common/dpp.c
+++ b/src/common/dpp.c
@@ -73,6 +73,14 @@ static void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr,
*ps = sig->s;
}
+
+static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_EC)
+ return NULL;
+ return pkey->pkey.ec;
+}
+
#endif
@@ -131,6 +139,7 @@ struct dpp_global {
struct dl_list tcp_init; /* struct dpp_connection */
void *cb_ctx;
int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
+ void (*remove_bi)(void *ctx, struct dpp_bootstrap_info *bi);
#endif /* CONFIG_DPP2 */
};
@@ -894,6 +903,7 @@ void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info)
os_free(info->chan);
os_free(info->pk);
EVP_PKEY_free(info->pubkey);
+ str_clear_free(info->configurator_params);
os_free(info);
}
@@ -1055,6 +1065,32 @@ static const struct dpp_curve_params * dpp_get_curve_nid(int nid)
}
+static int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi,
+ const u8 *data, size_t data_len)
+{
+ const u8 *addr[2];
+ size_t len[2];
+
+ addr[0] = data;
+ len[0] = data_len;
+ if (sha256_vector(1, addr, len, bi->pubkey_hash) < 0)
+ return -1;
+ wpa_hexdump(MSG_DEBUG, "DPP: Public key hash",
+ bi->pubkey_hash, SHA256_MAC_LEN);
+
+ addr[0] = (const u8 *) "chirp";
+ len[0] = 5;
+ addr[1] = data;
+ len[1] = data_len;
+ if (sha256_vector(2, addr, len, bi->pubkey_hash_chirp) < 0)
+ return -1;
+ wpa_hexdump(MSG_DEBUG, "DPP: Public key hash (chirp)",
+ bi->pubkey_hash_chirp, SHA256_MAC_LEN);
+
+ return 0;
+}
+
+
static int dpp_parse_uri_pk(struct dpp_bootstrap_info *bi, const char *info)
{
const char *end;
@@ -1093,14 +1129,11 @@ static int dpp_parse_uri_pk(struct dpp_bootstrap_info *bi, const char *info)
wpa_hexdump(MSG_DEBUG, "DPP: Base64 decoded URI public-key",
data, data_len);
- if (sha256_vector(1, (const u8 **) &data, &data_len,
- bi->pubkey_hash) < 0) {
+ if (dpp_bi_pubkey_hash(bi, data, data_len) < 0) {
wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
os_free(data);
return -1;
}
- wpa_hexdump(MSG_DEBUG, "DPP: Public key hash",
- bi->pubkey_hash, SHA256_MAC_LEN);
/* DER encoded ASN.1 SubjectPublicKeyInfo
*
@@ -1518,27 +1551,19 @@ fail:
}
-int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi)
+static int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi)
{
struct wpabuf *der;
int res;
- const u8 *addr[1];
- size_t len[1];
der = dpp_bootstrap_key_der(bi->pubkey);
if (!der)
return -1;
wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
der);
-
- addr[0] = wpabuf_head(der);
- len[0] = wpabuf_len(der);
- res = sha256_vector(1, addr, len, bi->pubkey_hash);
+ res = dpp_bi_pubkey_hash(bi, wpabuf_head(der), wpabuf_len(der));
if (res < 0)
wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
- else
- wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", bi->pubkey_hash,
- SHA256_MAC_LEN);
wpabuf_free(der);
return res;
}
@@ -1551,8 +1576,6 @@ static int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
char *pos, *end;
size_t len;
struct wpabuf *der = NULL;
- const u8 *addr[1];
- int res;
if (!curve) {
bi->curve = &dpp_curves[0];
@@ -1578,15 +1601,10 @@ static int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
der);
- addr[0] = wpabuf_head(der);
- len = wpabuf_len(der);
- res = sha256_vector(1, addr, &len, bi->pubkey_hash);
- if (res < 0) {
+ if (dpp_bi_pubkey_hash(bi, wpabuf_head(der), wpabuf_len(der)) < 0) {
wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
goto fail;
}
- wpa_hexdump(MSG_DEBUG, "DPP: Public key hash", bi->pubkey_hash,
- SHA256_MAC_LEN);
base64 = base64_encode(wpabuf_head(der), wpabuf_len(der), &len);
wpabuf_free(der);
@@ -2236,6 +2254,7 @@ static int dpp_channel_local_list(struct dpp_authentication *auth,
static int dpp_prepare_channel_list(struct dpp_authentication *auth,
+ unsigned int neg_freq,
struct hostapd_hw_modes *own_modes,
u16 num_modes)
{
@@ -2243,6 +2262,14 @@ static int dpp_prepare_channel_list(struct dpp_authentication *auth,
char freqs[DPP_BOOTSTRAP_MAX_FREQ * 6 + 10], *pos, *end;
unsigned int i;
+ if (!own_modes) {
+ if (!neg_freq)
+ return -1;
+ auth->num_freq = 1;
+ auth->freq[0] = neg_freq;
+ return 0;
+ }
+
if (auth->peer_bi->num_freq > 0)
res = dpp_channel_intersect(auth, own_modes, num_modes);
else
@@ -2335,20 +2362,22 @@ fail:
}
-static struct dpp_authentication * dpp_alloc_auth(void *msg_ctx)
+struct dpp_authentication *
+dpp_alloc_auth(struct dpp_global *dpp, void *msg_ctx)
{
struct dpp_authentication *auth;
auth = os_zalloc(sizeof(*auth));
if (!auth)
return NULL;
+ auth->global = dpp;
auth->msg_ctx = msg_ctx;
auth->conf_resp_status = 255;
return auth;
}
-struct dpp_authentication * dpp_auth_init(void *msg_ctx,
+struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
struct dpp_bootstrap_info *peer_bi,
struct dpp_bootstrap_info *own_bi,
u8 dpp_allowed_roles,
@@ -2365,9 +2394,12 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
u8 test_hash[SHA256_MAC_LEN];
#endif /* CONFIG_TESTING_OPTIONS */
- auth = dpp_alloc_auth(msg_ctx);
+ auth = dpp_alloc_auth(dpp, msg_ctx);
if (!auth)
return NULL;
+ if (peer_bi->configurator_params &&
+ dpp_set_configurator(auth, peer_bi->configurator_params) < 0)
+ goto fail;
auth->initiator = 1;
auth->waiting_auth_resp = 1;
auth->allowed_roles = dpp_allowed_roles;
@@ -2377,7 +2409,7 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
auth->curve = peer_bi->curve;
if (dpp_autogen_bootstrap_key(auth) < 0 ||
- dpp_prepare_channel_list(auth, own_modes, num_modes) < 0)
+ dpp_prepare_channel_list(auth, neg_freq, own_modes, num_modes) < 0)
goto fail;
#ifdef CONFIG_TESTING_OPTIONS
@@ -2473,6 +2505,8 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
}
#endif /* CONFIG_TESTING_OPTIONS */
+ if (neg_freq && auth->num_freq == 1 && auth->freq[0] == neg_freq)
+ neg_freq = 0;
auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash,
i_pubkey_hash, neg_freq);
if (!auth->req_msg)
@@ -3259,8 +3293,8 @@ static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
struct dpp_authentication *
-dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
- struct dpp_bootstrap_info *peer_bi,
+dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles,
+ int qr_mutual, struct dpp_bootstrap_info *peer_bi,
struct dpp_bootstrap_info *own_bi,
unsigned int freq, const u8 *hdr, const u8 *attr_start,
size_t attr_len)
@@ -3301,9 +3335,12 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
wrapped_data, wrapped_data_len);
attr_len = wrapped_data - 4 - attr_start;
- auth = dpp_alloc_auth(msg_ctx);
+ auth = dpp_alloc_auth(dpp, msg_ctx);
if (!auth)
goto fail;
+ if (peer_bi && peer_bi->configurator_params &&
+ dpp_set_configurator(auth, peer_bi->configurator_params) < 0)
+ goto fail;
auth->peer_bi = peer_bi;
auth->own_bi = own_bi;
auth->curve = own_bi->curve;
@@ -3915,6 +3952,14 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
dpp_auth_fail(auth,
"Missing Initiator Bootstrapping Key Hash attribute");
return NULL;
+ } else if (auth->own_bi &&
+ auth->own_bi->type == DPP_BOOTSTRAP_NFC_URI &&
+ auth->own_bi->nfc_negotiated) {
+ /* NFC negotiated connection handover bootstrapping mandates
+ * use of mutual authentication */
+ dpp_auth_fail(auth,
+ "Missing Initiator Bootstrapping Key Hash attribute");
+ return NULL;
}
auth->peer_version = 1; /* default to the first version */
@@ -4675,16 +4720,16 @@ dpp_configurator_get_id(struct dpp_global *dpp, unsigned int id)
}
-int dpp_set_configurator(struct dpp_global *dpp, void *msg_ctx,
- struct dpp_authentication *auth,
- const char *cmd)
+int dpp_set_configurator(struct dpp_authentication *auth, const char *cmd)
{
const char *pos;
char *tmp = NULL;
int ret = -1;
- if (!cmd)
+ if (!cmd || auth->configurator_set)
return 0;
+ auth->configurator_set = 1;
+
if (cmd[0] != ' ') {
size_t len;
@@ -4702,7 +4747,7 @@ int dpp_set_configurator(struct dpp_global *dpp, void *msg_ctx,
pos = os_strstr(cmd, " configurator=");
if (pos) {
pos += 14;
- auth->conf = dpp_configurator_get_id(dpp, atoi(pos));
+ auth->conf = dpp_configurator_get_id(auth->global, atoi(pos));
if (!auth->conf) {
wpa_printf(MSG_INFO,
"DPP: Could not find the specified configurator");
@@ -4723,7 +4768,7 @@ int dpp_set_configurator(struct dpp_global *dpp, void *msg_ctx,
}
if (dpp_configuration_parse(auth, cmd) < 0) {
- wpa_msg(msg_ctx, MSG_INFO,
+ wpa_msg(auth->msg_ctx, MSG_INFO,
"DPP: Failed to set configurator parameters");
goto fail;
}
@@ -5199,7 +5244,7 @@ dpp_build_conf_obj(struct dpp_authentication *auth, enum dpp_netrole netrole,
return NULL;
}
- if (dpp_akm_dpp(conf->akm))
+ if (dpp_akm_dpp(conf->akm) || (auth->peer_version >= 2 && auth->conf))
return dpp_build_conf_obj_dpp(auth, conf);
return dpp_build_conf_obj_legacy(auth, conf);
}
@@ -5230,7 +5275,7 @@ static struct wpabuf * dpp_build_conf_params(void)
asn1_put_utf8string(buf, conf_template);
if (connector_template)
- asn1_put_utf8string(buf, conf_template);
+ asn1_put_utf8string(buf, connector_template);
return asn1_encaps(buf, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
}
@@ -5375,7 +5420,6 @@ fail:
return asn1_encaps(asn1_encaps(key,
ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE),
ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
- return key;
}
@@ -6688,7 +6732,8 @@ static int dpp_parse_cred_dpp(struct dpp_authentication *auth,
conf->connector = os_strdup(signed_connector);
dpp_copy_csign(conf, csign_pub);
- dpp_copy_netaccesskey(auth, conf);
+ if (dpp_akm_dpp(conf->akm) || auth->peer_version >= 2)
+ dpp_copy_netaccesskey(auth, conf);
ret = 0;
fail:
@@ -6800,6 +6845,7 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth,
struct json_token *root, *token, *discovery, *cred;
struct dpp_config_obj *conf;
struct wpabuf *ssid64 = NULL;
+ int legacy;
root = json_parse((const char *) conf_obj, conf_obj_len);
if (!root)
@@ -6887,10 +6933,21 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth,
}
conf->akm = dpp_akm_from_str(token->string);
- if (dpp_akm_legacy(conf->akm)) {
+ legacy = dpp_akm_legacy(conf->akm);
+ if (legacy && auth->peer_version >= 2) {
+ struct json_token *csign, *s_conn;
+
+ csign = json_get_member(cred, "csign");
+ s_conn = json_get_member(cred, "signedConnector");
+ if (csign && csign->type == JSON_OBJECT &&
+ s_conn && s_conn->type == JSON_STRING)
+ legacy = 0;
+ }
+ if (legacy) {
if (dpp_parse_cred_legacy(conf, cred) < 0)
goto fail;
- } else if (dpp_akm_dpp(conf->akm)) {
+ } else if (dpp_akm_dpp(conf->akm) ||
+ (auth->peer_version >= 2 && dpp_akm_legacy(conf->akm))) {
if (dpp_parse_cred_dpp(auth, conf, cred) < 0)
goto fail;
} else {
@@ -10317,6 +10374,10 @@ static int dpp_bootstrap_del(struct dpp_global *dpp, unsigned int id)
if (id && bi->id != id)
continue;
found = 1;
+#ifdef CONFIG_DPP2
+ if (dpp->remove_bi)
+ dpp->remove_bi(dpp->cb_ctx, bi);
+#endif /* CONFIG_DPP2 */
dl_list_del(&bi->list);
dpp_bootstrap_info_free(bi);
}
@@ -10524,6 +10585,26 @@ int dpp_bootstrap_info(struct dpp_global *dpp, int id,
}
+int dpp_bootstrap_set(struct dpp_global *dpp, int id, const char *params)
+{
+ struct dpp_bootstrap_info *bi;
+
+ bi = dpp_bootstrap_get_id(dpp, id);
+ if (!bi)
+ return -1;
+
+ str_clear_free(bi->configurator_params);
+
+ if (params) {
+ bi->configurator_params = os_strdup(params);
+ return bi->configurator_params ? 0 : -1;
+ }
+
+ bi->configurator_params = NULL;
+ return 0;
+}
+
+
void dpp_bootstrap_find_pair(struct dpp_global *dpp, const u8 *i_bootstrap,
const u8 *r_bootstrap,
struct dpp_bootstrap_info **own_bi,
@@ -10556,8 +10637,27 @@ void dpp_bootstrap_find_pair(struct dpp_global *dpp, const u8 *i_bootstrap,
if (*own_bi && *peer_bi)
break;
}
+}
+
+
+#ifdef CONFIG_DPP2
+struct dpp_bootstrap_info * dpp_bootstrap_find_chirp(struct dpp_global *dpp,
+ const u8 *hash)
+{
+ struct dpp_bootstrap_info *bi;
+ if (!dpp)
+ return NULL;
+
+ dl_list_for_each(bi, &dpp->bootstrap, struct dpp_bootstrap_info, list) {
+ if (!bi->own && os_memcmp(bi->pubkey_hash_chirp, hash,
+ SHA256_MAC_LEN) == 0)
+ return bi;
+ }
+
+ return NULL;
}
+#endif /* CONFIG_DPP2 */
static int dpp_nfc_update_bi_channel(struct dpp_bootstrap_info *own_bi,
@@ -10867,6 +10967,7 @@ struct dpp_global * dpp_global_init(struct dpp_global_config *config)
#ifdef CONFIG_DPP2
dpp->cb_ctx = config->cb_ctx;
dpp->process_conf_obj = config->process_conf_obj;
+ dpp->remove_bi = config->remove_bi;
#endif /* CONFIG_DPP2 */
dl_list_init(&dpp->bootstrap);
@@ -11023,6 +11124,32 @@ static int dpp_tcp_send(struct dpp_connection *conn)
}
+static int dpp_tcp_send_msg(struct dpp_connection *conn,
+ const struct wpabuf *msg)
+{
+ wpabuf_free(conn->msg_out);
+ conn->msg_out_pos = 0;
+ conn->msg_out = wpabuf_alloc(4 + wpabuf_len(msg) - 1);
+ if (!conn->msg_out)
+ return -1;
+ wpabuf_put_be32(conn->msg_out, wpabuf_len(msg) - 1);
+ wpabuf_put_data(conn->msg_out, wpabuf_head_u8(msg) + 1,
+ wpabuf_len(msg) - 1);
+
+ if (dpp_tcp_send(conn) == 1) {
+ if (!conn->write_eloop) {
+ if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
+ dpp_conn_tx_ready,
+ conn, NULL) < 0)
+ return -1;
+ conn->write_eloop = 1;
+ }
+ }
+
+ return 0;
+}
+
+
static void dpp_controller_start_gas_client(struct dpp_connection *conn)
{
struct dpp_authentication *auth = conn->auth;
@@ -11036,27 +11163,8 @@ static void dpp_controller_start_gas_client(struct dpp_connection *conn)
return;
}
- wpabuf_free(conn->msg_out);
- conn->msg_out_pos = 0;
- conn->msg_out = wpabuf_alloc(4 + wpabuf_len(buf) - 1);
- if (!conn->msg_out) {
- wpabuf_free(buf);
- return;
- }
- wpabuf_put_be32(conn->msg_out, wpabuf_len(buf) - 1);
- wpabuf_put_data(conn->msg_out, wpabuf_head_u8(buf) + 1,
- wpabuf_len(buf) - 1);
+ dpp_tcp_send_msg(conn, buf);
wpabuf_free(buf);
-
- if (dpp_tcp_send(conn) == 1) {
- if (!conn->write_eloop) {
- if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
- dpp_conn_tx_ready,
- conn, NULL) < 0)
- return;
- conn->write_eloop = 1;
- }
- }
}
@@ -11255,7 +11363,8 @@ int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
* continue that session (send this over TCP) and return 0.
*/
if (type != DPP_PA_PEER_DISCOVERY_REQ &&
- type != DPP_PA_PEER_DISCOVERY_RESP) {
+ type != DPP_PA_PEER_DISCOVERY_RESP &&
+ type != DPP_PA_PRESENCE_ANNOUNCEMENT) {
dl_list_for_each(ctrl, &dpp->controllers,
struct dpp_relay_controller, list) {
dl_list_for_each(conn, &ctrl->conn,
@@ -11270,7 +11379,14 @@ int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
if (!r_bootstrap)
return -1;
- ctrl = dpp_relay_controller_get(dpp, r_bootstrap);
+ if (type == DPP_PA_PRESENCE_ANNOUNCEMENT) {
+ /* TODO: Could send this to all configured Controllers. For now,
+ * only the first Controller is supported. */
+ ctrl = dl_list_first(&dpp->controllers,
+ struct dpp_relay_controller, list);
+ } else {
+ ctrl = dpp_relay_controller_get(dpp, r_bootstrap);
+ }
if (!ctrl)
return -1;
@@ -11402,7 +11518,8 @@ static int dpp_controller_rx_auth_req(struct dpp_connection *conn,
return 0;
}
- conn->auth = dpp_auth_req_rx(conn->ctrl->global->msg_ctx,
+ conn->auth = dpp_auth_req_rx(conn->ctrl->global,
+ conn->ctrl->global->msg_ctx,
conn->ctrl->allowed_roles,
conn->ctrl->qr_mutual,
peer_bi, own_bi, -1, hdr, buf, len);
@@ -11411,33 +11528,13 @@ static int dpp_controller_rx_auth_req(struct dpp_connection *conn,
return -1;
}
- if (dpp_set_configurator(conn->ctrl->global, conn->ctrl->global->msg_ctx,
- conn->auth,
+ if (dpp_set_configurator(conn->auth,
conn->ctrl->configurator_params) < 0) {
dpp_connection_remove(conn);
return -1;
}
- wpabuf_free(conn->msg_out);
- conn->msg_out_pos = 0;
- conn->msg_out = wpabuf_alloc(4 + wpabuf_len(conn->auth->resp_msg) - 1);
- if (!conn->msg_out)
- return -1;
- wpabuf_put_be32(conn->msg_out, wpabuf_len(conn->auth->resp_msg) - 1);
- wpabuf_put_data(conn->msg_out, wpabuf_head_u8(conn->auth->resp_msg) + 1,
- wpabuf_len(conn->auth->resp_msg) - 1);
-
- if (dpp_tcp_send(conn) == 1) {
- if (!conn->write_eloop) {
- if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
- dpp_conn_tx_ready,
- conn, NULL) < 0)
- return -1;
- conn->write_eloop = 1;
- }
- }
-
- return 0;
+ return dpp_tcp_send_msg(conn, conn->auth->resp_msg);
}
@@ -11446,6 +11543,7 @@ static int dpp_controller_rx_auth_resp(struct dpp_connection *conn,
{
struct dpp_authentication *auth = conn->auth;
struct wpabuf *msg;
+ int res;
if (!auth)
return -1;
@@ -11464,30 +11562,10 @@ static int dpp_controller_rx_auth_resp(struct dpp_connection *conn,
return -1;
}
- wpabuf_free(conn->msg_out);
- conn->msg_out_pos = 0;
- conn->msg_out = wpabuf_alloc(4 + wpabuf_len(msg) - 1);
- if (!conn->msg_out) {
- wpabuf_free(msg);
- return -1;
- }
- wpabuf_put_be32(conn->msg_out, wpabuf_len(msg) - 1);
- wpabuf_put_data(conn->msg_out, wpabuf_head_u8(msg) + 1,
- wpabuf_len(msg) - 1);
- wpabuf_free(msg);
-
conn->on_tcp_tx_complete_auth_ok = 1;
- if (dpp_tcp_send(conn) == 1) {
- if (!conn->write_eloop) {
- if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
- dpp_conn_tx_ready,
- conn, NULL) < 0)
- return -1;
- conn->write_eloop = 1;
- }
- }
-
- return 0;
+ res = dpp_tcp_send_msg(conn, msg);
+ wpabuf_free(msg);
+ return res;
}
@@ -11604,6 +11682,56 @@ static int dpp_controller_rx_conn_status_result(struct dpp_connection *conn,
}
+static int dpp_controller_rx_presence_announcement(struct dpp_connection *conn,
+ const u8 *hdr, const u8 *buf,
+ size_t len)
+{
+ const u8 *r_bootstrap;
+ u16 r_bootstrap_len;
+ struct dpp_bootstrap_info *peer_bi;
+ struct dpp_authentication *auth;
+ struct dpp_global *dpp = conn->ctrl->global;
+
+ if (conn->auth) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: Ignore Presence Announcement during ongoing Authentication");
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG, "DPP: Presence Announcement");
+
+ r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
+ &r_bootstrap_len);
+ if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
+ wpa_msg(dpp->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
+ "Missing or invalid required Responder Bootstrapping Key Hash attribute");
+ return -1;
+ }
+ wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
+ r_bootstrap, r_bootstrap_len);
+ peer_bi = dpp_bootstrap_find_chirp(dpp, r_bootstrap);
+ if (!peer_bi) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: No matching bootstrapping information found");
+ return -1;
+ }
+
+ auth = dpp_auth_init(dpp, dpp->msg_ctx, peer_bi, NULL,
+ DPP_CAPAB_CONFIGURATOR, -1, NULL, 0);
+ if (!auth)
+ return -1;
+ if (dpp_set_configurator(conn->auth,
+ conn->ctrl->configurator_params) < 0) {
+ dpp_auth_deinit(auth);
+ dpp_connection_remove(conn);
+ return -1;
+ }
+
+ conn->auth = auth;
+ return dpp_tcp_send_msg(conn, conn->auth->req_msg);
+}
+
+
static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
size_t len)
{
@@ -11654,6 +11782,9 @@ static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
case DPP_PA_CONNECTION_STATUS_RESULT:
return dpp_controller_rx_conn_status_result(conn, msg, pos,
end - pos);
+ case DPP_PA_PRESENCE_ANNOUNCEMENT:
+ return dpp_controller_rx_presence_announcement(conn, msg, pos,
+ end - pos);
default:
/* TODO: missing messages types */
wpa_printf(MSG_DEBUG,
@@ -11748,7 +11879,7 @@ static int dpp_tcp_rx_gas_resp(struct dpp_connection *conn, struct wpabuf *resp)
{
struct dpp_authentication *auth = conn->auth;
int res;
- struct wpabuf *msg, *encaps;
+ struct wpabuf *msg;
enum dpp_status_error status;
wpa_printf(MSG_DEBUG,
@@ -11770,35 +11901,19 @@ static int dpp_tcp_rx_gas_resp(struct dpp_connection *conn, struct wpabuf *resp)
if (auth->peer_version < 2 || auth->conf_resp_status != DPP_STATUS_OK)
return -1;
-#ifdef CONFIG_DPP2
wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
status = res < 0 ? DPP_STATUS_CONFIG_REJECTED : DPP_STATUS_OK;
msg = dpp_build_conf_result(auth, status);
if (!msg)
return -1;
- encaps = wpabuf_alloc(4 + wpabuf_len(msg) - 1);
- if (!encaps) {
- wpabuf_free(msg);
- return -1;
- }
- wpabuf_put_be32(encaps, wpabuf_len(msg) - 1);
- wpabuf_put_data(encaps, wpabuf_head_u8(msg) + 1, wpabuf_len(msg) - 1);
- wpabuf_free(msg);
- wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", encaps);
-
- wpabuf_free(conn->msg_out);
- conn->msg_out_pos = 0;
- conn->msg_out = encaps;
conn->on_tcp_tx_complete_remove = 1;
- dpp_tcp_send(conn);
+ res = dpp_tcp_send_msg(conn, msg);
+ wpabuf_free(msg);
/* This exchange will be terminated in the TX status handler */
- return 0;
-#else /* CONFIG_DPP2 */
- return -1;
-#endif /* CONFIG_DPP2 */
+ return res;
}
@@ -12183,4 +12298,22 @@ void dpp_controller_stop(struct dpp_global *dpp)
}
}
+
+struct wpabuf * dpp_build_presence_announcement(struct dpp_bootstrap_info *bi)
+{
+ struct wpabuf *msg;
+
+ wpa_printf(MSG_DEBUG, "DPP: Build Presence Announcement frame");
+
+ msg = dpp_alloc_msg(DPP_PA_PRESENCE_ANNOUNCEMENT, 4 + SHA256_MAC_LEN);
+ if (!msg)
+ return NULL;
+
+ /* Responder Bootstrapping Key Hash */
+ dpp_build_attr_r_bootstrap_key_hash(msg, bi->pubkey_hash_chirp);
+ wpa_hexdump_buf(MSG_DEBUG,
+ "DPP: Presence Announcement frame attributes", msg);
+ return msg;
+}
+
#endif /* CONFIG_DPP2 */
diff --git a/src/common/dpp.h b/src/common/dpp.h
index ad1bcb0..afbedc5 100644
--- a/src/common/dpp.h
+++ b/src/common/dpp.h
@@ -36,6 +36,11 @@ enum dpp_public_action_frame_type {
DPP_PA_PKEX_COMMIT_REVEAL_RESP = 10,
DPP_PA_CONFIGURATION_RESULT = 11,
DPP_PA_CONNECTION_STATUS_RESULT = 12,
+ DPP_PA_PRESENCE_ANNOUNCEMENT = 13,
+ DPP_PA_RECONFIG_ANNOUNCEMENT = 14,
+ DPP_PA_RECONFIG_AUTH_REQ = 15,
+ DPP_PA_RECONFIG_AUTH_RESP = 16,
+ DPP_PA_RECONFIG_AUTH_CONF = 17,
};
enum dpp_attribute_id {
@@ -67,6 +72,9 @@ enum dpp_attribute_id {
DPP_ATTR_ENVELOPED_DATA = 0x101A,
DPP_ATTR_SEND_CONN_STATUS = 0x101B,
DPP_ATTR_CONN_STATUS = 0x101C,
+ DPP_ATTR_RECONFIG_FLAGS = 0x101D,
+ DPP_ATTR_C_SIGN_KEY_HASH = 0x101E,
+ DPP_ATTR_CSR_ATTR_REQ = 0x101F,
};
enum dpp_status_error {
@@ -81,6 +89,9 @@ enum dpp_status_error {
DPP_STATUS_NO_MATCH = 8,
DPP_STATUS_CONFIG_REJECTED = 9,
DPP_STATUS_NO_AP = 10,
+ DPP_STATUS_CONFIGURE_PENDING = 11,
+ DPP_STATUS_CSR_NEEDED = 12,
+ DPP_STATUS_CSR_BAD = 13,
};
#define DPP_CAPAB_ENROLLEE BIT(0)
@@ -123,9 +134,13 @@ struct dpp_bootstrap_info {
int own;
EVP_PKEY *pubkey;
u8 pubkey_hash[SHA256_MAC_LEN];
+ u8 pubkey_hash_chirp[SHA256_MAC_LEN];
const struct dpp_curve_params *curve;
unsigned int pkex_t; /* number of failures before dpp_pkex
* instantiation */
+ int nfc_negotiated; /* whether this has been used in NFC negotiated
+ * connection handover */
+ char *configurator_params;
};
#define PKEX_COUNTER_T_LIMIT 5
@@ -199,6 +214,7 @@ struct dpp_asymmetric_key {
#define DPP_MAX_CONF_OBJ 10
struct dpp_authentication {
+ struct dpp_global *global;
void *msg_ctx;
u8 peer_version;
const struct dpp_curve_params *curve;
@@ -274,6 +290,7 @@ struct dpp_authentication {
int send_conn_status;
int conn_status_requested;
int akm_use_selector;
+ int configurator_set;
#ifdef CONFIG_TESTING_OPTIONS
char *config_obj_override;
char *discovery_override;
@@ -422,15 +439,16 @@ extern size_t dpp_nonce_override_len;
void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info);
const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type);
-int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi);
int dpp_parse_uri_chan_list(struct dpp_bootstrap_info *bi,
const char *chan_list);
int dpp_parse_uri_mac(struct dpp_bootstrap_info *bi, const char *mac);
int dpp_parse_uri_info(struct dpp_bootstrap_info *bi, const char *info);
int dpp_nfc_update_bi(struct dpp_bootstrap_info *own_bi,
struct dpp_bootstrap_info *peer_bi);
+struct dpp_authentication *
+dpp_alloc_auth(struct dpp_global *dpp, void *msg_ctx);
struct hostapd_hw_modes;
-struct dpp_authentication * dpp_auth_init(void *msg_ctx,
+struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
struct dpp_bootstrap_info *peer_bi,
struct dpp_bootstrap_info *own_bi,
u8 dpp_allowed_roles,
@@ -438,8 +456,8 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
struct hostapd_hw_modes *own_modes,
u16 num_modes);
struct dpp_authentication *
-dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
- struct dpp_bootstrap_info *peer_bi,
+dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles,
+ int qr_mutual, struct dpp_bootstrap_info *peer_bi,
struct dpp_bootstrap_info *own_bi,
unsigned int freq, const u8 *hdr, const u8 *attr_start,
size_t attr_len);
@@ -464,9 +482,7 @@ int dpp_akm_dpp(enum dpp_akm akm);
int dpp_akm_ver2(enum dpp_akm akm);
int dpp_configuration_valid(const struct dpp_configuration *conf);
void dpp_configuration_free(struct dpp_configuration *conf);
-int dpp_set_configurator(struct dpp_global *dpp, void *msg_ctx,
- struct dpp_authentication *auth,
- const char *cmd);
+int dpp_set_configurator(struct dpp_authentication *auth, const char *cmd);
void dpp_auth_deinit(struct dpp_authentication *auth);
struct wpabuf *
dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
@@ -559,10 +575,13 @@ dpp_pkex_finish(struct dpp_global *dpp, struct dpp_pkex *pkex, const u8 *peer,
const char * dpp_bootstrap_get_uri(struct dpp_global *dpp, unsigned int id);
int dpp_bootstrap_info(struct dpp_global *dpp, int id,
char *reply, int reply_size);
+int dpp_bootstrap_set(struct dpp_global *dpp, int id, const char *params);
void dpp_bootstrap_find_pair(struct dpp_global *dpp, const u8 *i_bootstrap,
const u8 *r_bootstrap,
struct dpp_bootstrap_info **own_bi,
struct dpp_bootstrap_info **peer_bi);
+struct dpp_bootstrap_info * dpp_bootstrap_find_chirp(struct dpp_global *dpp,
+ const u8 *hash);
int dpp_configurator_add(struct dpp_global *dpp, const char *cmd);
int dpp_configurator_remove(struct dpp_global *dpp, const char *id);
int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
@@ -581,11 +600,13 @@ int dpp_controller_start(struct dpp_global *dpp,
void dpp_controller_stop(struct dpp_global *dpp);
int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
const struct hostapd_ip_addr *addr, int port);
+struct wpabuf * dpp_build_presence_announcement(struct dpp_bootstrap_info *bi);
struct dpp_global_config {
void *msg_ctx;
void *cb_ctx;
int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
+ void (*remove_bi)(void *ctx, struct dpp_bootstrap_info *bi);
};
struct dpp_global * dpp_global_init(struct dpp_global_config *config);
diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index 4f1c493..f6c67a3 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -475,13 +475,46 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
return 0;
}
- if (data->vht_enabled) switch (oper_chwidth) {
+ if (data->he_enabled) switch (oper_chwidth) {
case CHANWIDTH_USE_HT:
- if (center_segment1 ||
- (center_segment0 != 0 &&
- 5000 + center_segment0 * 5 != data->center_freq1 &&
- 2407 + center_segment0 * 5 != data->center_freq1))
+ if (mode == HOSTAPD_MODE_IEEE80211G && sec_channel_offset) {
+ if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G)) {
+ wpa_printf(MSG_ERROR,
+ "40 MHz channel width is not supported in 2.4 GHz");
+ return -1;
+ }
+ break;
+ }
+ /* fall through */
+ case CHANWIDTH_80MHZ:
+ if (mode == HOSTAPD_MODE_IEEE80211A) {
+ if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
+ wpa_printf(MSG_ERROR,
+ "40/80 MHz channel width is not supported in 5/6 GHz");
+ return -1;
+ }
+ }
+ break;
+ case CHANWIDTH_80P80MHZ:
+ if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)) {
+ wpa_printf(MSG_ERROR,
+ "80+80 MHz channel width is not supported in 5/6 GHz");
return -1;
+ }
+ break;
+ case CHANWIDTH_160MHZ:
+ if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)) {
+ wpa_printf(MSG_ERROR,
+ "160 MHz channel width is not supported in 5 / 6GHz");
+ return -1;
+ }
+ break;
+ } else if (data->vht_enabled) switch (oper_chwidth) {
+ case CHANWIDTH_USE_HT:
break;
case CHANWIDTH_80P80MHZ:
if (!(vht_caps & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) {
@@ -489,6 +522,28 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
"80+80 channel width is not supported!");
return -1;
}
+ /* fall through */
+ case CHANWIDTH_80MHZ:
+ break;
+ case CHANWIDTH_160MHZ:
+ if (!(vht_caps & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
+ VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
+ wpa_printf(MSG_ERROR,
+ "160 MHz channel width is not supported!");
+ return -1;
+ }
+ break;
+ }
+
+ if (data->he_enabled || data->vht_enabled) switch (oper_chwidth) {
+ case CHANWIDTH_USE_HT:
+ if (center_segment1 ||
+ (center_segment0 != 0 &&
+ 5000 + center_segment0 * 5 != data->center_freq1 &&
+ 2407 + center_segment0 * 5 != data->center_freq1))
+ return -1;
+ break;
+ case CHANWIDTH_80P80MHZ:
if (center_segment1 == center_segment0 + 4 ||
center_segment1 == center_segment0 - 4)
return -1;
@@ -533,12 +588,6 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
break;
case CHANWIDTH_160MHZ:
data->bandwidth = 160;
- if (!(vht_caps & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
- VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
- wpa_printf(MSG_ERROR,
- "160MHZ channel width is not supported!");
- return -1;
- }
if (center_segment1)
return -1;
if (!sec_channel_offset)
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 36005d7..e7ee24e 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -130,6 +130,12 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
elems->multi_ap = pos;
elems->multi_ap_len = elen;
break;
+ case OWE_OUI_TYPE:
+ /* OWE Transition Mode element */
+ break;
+ case DPP_CC_OUI_TYPE:
+ /* DPP Configurator Connectivity element */
+ break;
default:
wpa_printf(MSG_MSGDUMP, "Unknown WFA "
"information element ignored "
@@ -206,6 +212,8 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
ext_id = *pos++;
elen--;
+ elems->frag_ies.last_eid_ext = 0;
+
switch (ext_id) {
case WLAN_EID_EXT_ASSOC_DELAY_INFO:
if (elen != 1)
@@ -245,9 +253,9 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
elems->key_delivery = pos;
elems->key_delivery_len = elen;
break;
- case WLAN_EID_EXT_FILS_WRAPPED_DATA:
- elems->fils_wrapped_data = pos;
- elems->fils_wrapped_data_len = elen;
+ case WLAN_EID_EXT_WRAPPED_DATA:
+ elems->wrapped_data = pos;
+ elems->wrapped_data_len = elen;
break;
case WLAN_EID_EXT_FILS_PUBLIC_KEY:
if (elen < 1)
@@ -295,10 +303,39 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
return -1;
}
+ if (elen == 254)
+ elems->frag_ies.last_eid_ext = ext_id;
+
return 0;
}
+static void ieee802_11_parse_fragment(struct frag_ies_info *frag_ies,
+ const u8 *pos, u8 elen)
+{
+ if (frag_ies->n_frags >= MAX_NUM_FRAG_IES_SUPPORTED) {
+ wpa_printf(MSG_MSGDUMP, "Too many element fragments - skip");
+ return;
+ }
+
+ /*
+ * Note: while EID == 0 is a valid ID (SSID IE), it should not be
+ * fragmented.
+ */
+ if (!frag_ies->last_eid) {
+ wpa_printf(MSG_MSGDUMP,
+ "Fragment without a valid last element - skip");
+ return;
+ }
+
+ frag_ies->frags[frag_ies->n_frags].ie = pos;
+ frag_ies->frags[frag_ies->n_frags].ie_len = elen;
+ frag_ies->frags[frag_ies->n_frags].eid = frag_ies->last_eid;
+ frag_ies->frags[frag_ies->n_frags].eid_ext = frag_ies->last_eid_ext;
+ frag_ies->n_frags++;
+}
+
+
/**
* ieee802_11_parse_elems - Parse information elements in management frames
* @start: Pointer to the start of IEs
@@ -331,6 +368,11 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
elen);
break;
}
+ if (elems->ssid) {
+ wpa_printf(MSG_MSGDUMP,
+ "Ignored duplicated SSID element");
+ break;
+ }
elems->ssid = pos;
elems->ssid_len = elen;
break;
@@ -516,7 +558,7 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
elems->dils_len = elen;
break;
case WLAN_EID_FRAGMENT:
- /* TODO */
+ ieee802_11_parse_fragment(&elems->frag_ies, pos, elen);
break;
case WLAN_EID_EXTENSION:
if (ieee802_11_parse_extension(pos, elen, elems,
@@ -532,6 +574,12 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
id, elen);
break;
}
+
+ if (id != WLAN_EID_FRAGMENT && elen == 255)
+ elems->frag_ies.last_eid = id;
+
+ if (id == WLAN_EID_EXTENSION && !elems->frag_ies.last_eid_ext)
+ elems->frag_ies.last_eid = 0;
}
if (!for_each_element_completed(elem, start, len)) {
@@ -2391,3 +2439,78 @@ int op_class_to_ch_width(u8 op_class)
}
return CHANWIDTH_USE_HT;
}
+
+
+struct wpabuf * ieee802_11_defrag_data(struct ieee802_11_elems *elems,
+ u8 eid, u8 eid_ext,
+ const u8 *data, u8 len)
+{
+ struct frag_ies_info *frag_ies = &elems->frag_ies;
+ struct wpabuf *buf;
+ unsigned int i;
+
+ if (!elems || !data || !len)
+ return NULL;
+
+ buf = wpabuf_alloc_copy(data, len);
+ if (!buf)
+ return NULL;
+
+ for (i = 0; i < frag_ies->n_frags; i++) {
+ int ret;
+
+ if (frag_ies->frags[i].eid != eid ||
+ frag_ies->frags[i].eid_ext != eid_ext)
+ continue;
+
+ ret = wpabuf_resize(&buf, frag_ies->frags[i].ie_len);
+ if (ret < 0) {
+ wpabuf_free(buf);
+ return NULL;
+ }
+
+ /* Copy only the fragment data (without the EID and length) */
+ wpabuf_put_data(buf, frag_ies->frags[i].ie,
+ frag_ies->frags[i].ie_len);
+ }
+
+ return buf;
+}
+
+
+struct wpabuf * ieee802_11_defrag(struct ieee802_11_elems *elems,
+ u8 eid, u8 eid_ext)
+{
+ const u8 *data;
+ u8 len;
+
+ /*
+ * TODO: Defragmentation mechanism can be supported for all IEs. For now
+ * handle only those that are used (or use ieee802_11_defrag_data()).
+ */
+ switch (eid) {
+ case WLAN_EID_EXTENSION:
+ switch (eid_ext) {
+ case WLAN_EID_EXT_FILS_HLP_CONTAINER:
+ data = elems->fils_hlp;
+ len = elems->fils_hlp_len;
+ break;
+ case WLAN_EID_EXT_WRAPPED_DATA:
+ data = elems->wrapped_data;
+ len = elems->wrapped_data_len;
+ break;
+ default:
+ wpa_printf(MSG_DEBUG,
+ "Defragmentation not supported. eid_ext=%u",
+ eid_ext);
+ return NULL;
+ }
+ break;
+ default:
+ wpa_printf(MSG_DEBUG,
+ "Defragmentation not supported. eid=%u", eid);
+ return NULL;
+ }
+
+ return ieee802_11_defrag_data(elems, eid, eid_ext, data, len);
+}
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index d133169..7994cd7 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -21,6 +21,7 @@ struct element {
struct hostapd_hw_modes;
#define MAX_NOF_MB_IES_SUPPORTED 5
+#define MAX_NUM_FRAG_IES_SUPPORTED 3
struct mb_ies_info {
struct {
@@ -30,6 +31,21 @@ struct mb_ies_info {
u8 nof_ies;
};
+struct frag_ies_info {
+ struct {
+ u8 eid;
+ u8 eid_ext;
+ const u8 *ie;
+ u8 ie_len;
+ } frags[MAX_NUM_FRAG_IES_SUPPORTED];
+
+ u8 n_frags;
+
+ /* the last parsed element ID and element extension ID */
+ u8 last_eid;
+ u8 last_eid_ext;
+};
+
/* Parsed Information Elements */
struct ieee802_11_elems {
const u8 *ssid;
@@ -85,7 +101,7 @@ struct ieee802_11_elems {
const u8 *fils_hlp;
const u8 *fils_ip_addr_assign;
const u8 *key_delivery;
- const u8 *fils_wrapped_data;
+ const u8 *wrapped_data;
const u8 *fils_pk;
const u8 *fils_nonce;
const u8 *owe_dh;
@@ -138,7 +154,7 @@ struct ieee802_11_elems {
u8 fils_hlp_len;
u8 fils_ip_addr_assign_len;
u8 key_delivery_len;
- u8 fils_wrapped_data_len;
+ u8 wrapped_data_len;
u8 fils_pk_len;
u8 owe_dh_len;
u8 power_capab_len;
@@ -151,6 +167,7 @@ struct ieee802_11_elems {
u8 short_ssid_list_len;
struct mb_ies_info mb_ies;
+ struct frag_ies_info frag_ies;
};
typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
@@ -293,4 +310,10 @@ void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
struct ieee80211_edmg_config requested);
+struct wpabuf * ieee802_11_defrag_data(struct ieee802_11_elems *elems,
+ u8 eid, u8 eid_ext,
+ const u8 *data, u8 len);
+struct wpabuf * ieee802_11_defrag(struct ieee802_11_elems *elems,
+ u8 eid, u8 eid_ext);
+
#endif /* IEEE802_11_COMMON_H */
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index a78ed0a..7f31e09 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -458,7 +458,7 @@
#define WLAN_EID_EXT_FILS_HLP_CONTAINER 5
#define WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN 6
#define WLAN_EID_EXT_KEY_DELIVERY 7
-#define WLAN_EID_EXT_FILS_WRAPPED_DATA 8
+#define WLAN_EID_EXT_WRAPPED_DATA 8
#define WLAN_EID_EXT_FTM_SYNC_INFO 9
#define WLAN_EID_EXT_EXTENDED_REQUEST 10
#define WLAN_EID_EXT_ESTIMATED_SERVICE_PARAMS 11
@@ -1316,6 +1316,8 @@ struct ieee80211_ampe_ie {
#define OWE_IE_VENDOR_TYPE 0x506f9a1c
#define OWE_OUI_TYPE 28
#define MULTI_AP_OUI_TYPE 0x1B
+#define DPP_CC_IE_VENDOR_TYPE 0x506f9a1e
+#define DPP_CC_OUI_TYPE 0x1e
#define MULTI_AP_SUB_ELEM_TYPE 0x06
#define MULTI_AP_TEAR_DOWN BIT(4)
@@ -1879,6 +1881,13 @@ enum wnm_sleep_mode_subelement_id {
WNM_SLEEP_SUBELEM_BIGTK = 2,
};
+/* WNM notification type (IEEE P802.11-REVmd/D3.0, Table 9-430) */
+enum wnm_notification_Type {
+ WNM_NOTIF_TYPE_FIRMWARE_UPDATE = 0,
+ WNM_NOTIF_TYPE_BEACON_PROTECTION_FAILURE = 2,
+ WNM_NOTIF_TYPE_VENDOR_SPECIFIC = 221,
+};
+
/* Channel Switch modes (802.11h) */
#define CHAN_SWITCH_MODE_ALLOW_TX 0
#define CHAN_SWITCH_MODE_BLOCK_TX 1
@@ -2092,7 +2101,7 @@ enum phy_type {
PHY_TYPE_VHT = 9,
};
-/* IEEE P802.11-REVmc/D5.0, 9.4.2.37 - Neighbor Report element */
+/* IEEE P802.11-REVmd/D3.0, 9.4.2.36 - Neighbor Report element */
/* BSSID Information Field */
#define NEI_REP_BSSID_INFO_AP_NOT_REACH BIT(0)
#define NEI_REP_BSSID_INFO_AP_UNKNOWN_REACH BIT(1)
@@ -2109,6 +2118,7 @@ enum phy_type {
#define NEI_REP_BSSID_INFO_HT BIT(11)
#define NEI_REP_BSSID_INFO_VHT BIT(12)
#define NEI_REP_BSSID_INFO_FTM BIT(13)
+#define NEI_REP_BSSID_INFO_HE BIT(14)
/*
* IEEE P802.11-REVmc/D5.0 Table 9-152 - HT/VHT Operation Information
diff --git a/src/common/privsep_commands.h b/src/common/privsep_commands.h
index b85c6c3..d2c4bbd 100644
--- a/src/common/privsep_commands.h
+++ b/src/common/privsep_commands.h
@@ -82,6 +82,7 @@ struct privsep_cmd_set_key {
size_t seq_len;
u8 key[32];
size_t key_len;
+ enum key_flag key_flag;
};
enum privsep_event {
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index 1f2233d..02aa9fb 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -1279,6 +1279,15 @@ enum qca_wlan_vendor_attr_p2p_listen_offload {
* Note: If the driver supports the 6 GHz band, the event sent from the driver
* includes this attribute along with
* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED: Flag attribute.
+ * Used with command to notify the driver of EDMG request for ACS
+ * operation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL: Optional (u8).
+ * Used with event to notify the EDMG channel number selected in ACS
+ * operation.
+ * EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL
*/
enum qca_wlan_vendor_attr_acs_offload {
QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
@@ -1297,6 +1306,8 @@ enum qca_wlan_vendor_attr_acs_offload {
QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY = 13,
QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY = 14,
QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15,
+ QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16,
+ QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17,
/* keep last */
QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
@@ -1716,6 +1727,9 @@ enum qca_vendor_element_id {
* randomisation
* @QCA_WLAN_VENDOR_ATTR_SCAN_BSSID: 6-byte MAC address representing the
* specific BSSID to scan for.
+ * @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in
+ * microseconds. This is a common value which applies across all
+ * frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES.
*/
enum qca_wlan_vendor_attr_scan {
QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0,
@@ -1730,6 +1744,7 @@ enum qca_wlan_vendor_attr_scan {
QCA_WLAN_VENDOR_ATTR_SCAN_MAC = 9,
QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10,
QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11,
+ QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12,
QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_SCAN_MAX =
QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1
@@ -5719,6 +5734,39 @@ enum qca_wlan_vendor_hang_reason {
QCA_WLAN_HANG_DXE_FAILURE = 12,
/* WMI pending commands exceed the maximum count */
QCA_WLAN_HANG_WMI_EXCEED_MAX_PENDING_CMDS = 13,
+ /* Timeout for peer STA connection accept command's response from the
+ * FW in AP mode. This command is triggered when a STA (peer) connects
+ * to AP (DUT).
+ */
+ QCA_WLAN_HANG_AP_STA_CONNECT_REQ_TIMEOUT = 14,
+ /* Timeout for the AP connection accept command's response from the FW
+ * in STA mode. This command is triggered when the STA (DUT) connects
+ * to an AP (peer).
+ */
+ QCA_WLAN_HANG_STA_AP_CONNECT_REQ_TIMEOUT = 15,
+ /* Timeout waiting for the response to the MAC HW mode change command
+ * sent to FW as a part of MAC mode switch among DBS (Dual Band
+ * Simultaneous), SCC (Single Channel Concurrency), and MCC (Multi
+ * Channel Concurrency) mode.
+ */
+ QCA_WLAN_HANG_MAC_HW_MODE_CHANGE_TIMEOUT = 16,
+ /* Timeout waiting for the response from FW to configure the MAC HW's
+ * mode. This operation is to configure the single/two MACs in either
+ * SCC/MCC/DBS mode.
+ */
+ QCA_WLAN_HANG_MAC_HW_MODE_CONFIG_TIMEOUT = 17,
+ /* Timeout waiting for response of VDEV start command from the FW */
+ QCA_WLAN_HANG_VDEV_START_RESPONSE_TIMED_OUT = 18,
+ /* Timeout waiting for response of VDEV restart command from the FW */
+ QCA_WLAN_HANG_VDEV_RESTART_RESPONSE_TIMED_OUT = 19,
+ /* Timeout waiting for response of VDEV stop command from the FW */
+ QCA_WLAN_HANG_VDEV_STOP_RESPONSE_TIMED_OUT = 20,
+ /* Timeout waiting for response of VDEV delete command from the FW */
+ QCA_WLAN_HANG_VDEV_DELETE_RESPONSE_TIMED_OUT = 21,
+ /* Timeout waiting for response of peer all delete request command to
+ * the FW on a specific VDEV.
+ */
+ QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22,
};
/**
@@ -5731,6 +5779,12 @@ enum qca_wlan_vendor_attr_hang {
* qca_wlan_vendor_hang_reason.
*/
QCA_WLAN_VENDOR_ATTR_HANG_REASON = 1,
+ /* The binary blob data associated with the hang reason specified by
+ * QCA_WLAN_VENDOR_ATTR_HANG_REASON. This binary data is expected to
+ * contain the required dump to analyze the reason for the hang.
+ * NLA_BINARY attribute, the max size is 1024 bytes.
+ */
+ QCA_WLAN_VENDOR_ATTR_HANG_REASON_DATA = 2,
QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_HANG_MAX =
@@ -7368,10 +7422,42 @@ enum qca_wlan_vendor_attr_roam_scan {
* enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by
* attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor
* command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
+ * @QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL: CFR method using QoS Null frame
+ * @QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE: CFR method using QoS Null frame
+ * with phase
+ * @QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE: CFR method using Probe Response frame
*/
enum qca_wlan_vendor_cfr_method {
- /* CFR method using QOS Null frame */
QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL = 0,
+ QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE = 1,
+ QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_cfr_capture_type - QCA vendor CFR capture type used by
+ * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE.
+ * @QCA_WLAN_VENDOR_CFR_DIRECT_FTM: Filter directed FTM ACK frames.
+ * @QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK: Filter all FTM ACK frames.
+ * @QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP: Filter NDPA NDP directed frames.
+ * @QCA_WLAN_VENDOR_CFR_TA_RA: Filter frames based on TA/RA/Subtype which
+ * is provided by one or more of below attributes:
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER
+ * @QCA_WLAN_CFR_ALL_PACKET: Filter all packets.
+ * @QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL: Filter all NDPA NDP frames.
+ */
+enum qca_wlan_vendor_cfr_capture_type {
+ QCA_WLAN_VENDOR_CFR_DIRECT_FTM = 0,
+ QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK = 1,
+ QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP = 2,
+ QCA_WLAN_VENDOR_CFR_TA_RA = 3,
+ QCA_WLAN_VENDOR_CFR_ALL_PACKET = 4,
+ QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL = 5,
};
/**
@@ -7379,44 +7465,177 @@ enum qca_wlan_vendor_cfr_method {
* QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG to configure peer
* Channel Frequency Response capture parameters and enable periodic CFR
* capture.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR: Optional (6-byte MAC address)
+ * MAC address of peer. This is for CFR version 1 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE: Required (flag)
+ * Enable peer CFR capture. This attribute is mandatory to enable peer CFR
+ * capture. If this attribute is not present, peer CFR capture is disabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH: Optional (u8)
+ * BW of measurement, attribute uses the values in enum nl80211_chan_width
+ * Supported values: 20, 40, 80, 80+80, 160.
+ * Note that all targets may not support all bandwidths.
+ * This attribute is mandatory for version 1 if attribute
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY: Optional (u32)
+ * Periodicity of CFR measurement in milliseconds.
+ * Periodicity should be a multiple of Base timer.
+ * Current Base timer value supported is 10 milliseconds (default).
+ * 0 for one shot capture.
+ * This attribute is mandatory for version 1 if attribute
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD: Optional (u8)
+ * Method used to capture Channel Frequency Response.
+ * Attribute uses the values defined in enum qca_wlan_vendor_cfr_method.
+ * This attribute is mandatory for version 1 if attribute
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE: Optional (flag)
+ * Enable periodic CFR capture.
+ * This attribute is mandatory for version 1 to enable Periodic CFR capture.
+ * If this attribute is not present, periodic CFR capture is disabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION: Optional (u8)
+ * Value is 1 or 2 since there are two versions of CFR capture. Two versions
+ * can't be enabled at same time. This attribute is mandatory if target
+ * support both versions and use one of them.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP: Optional (u32)
+ * This attribute is mandatory for version 2 if
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY is used.
+ * Bits 15:0 bitfield indicates which group is to be enabled.
+ * Bits 31:16 Reserved for future use.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION: Optional (u32)
+ * CFR capture duration in microsecond. This attribute is mandatory for
+ * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL is used.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL: Optional (u32)
+ * CFR capture interval in microsecond. This attribute is mandatory for
+ * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION is used.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE: Optional (u32)
+ * CFR capture type is defined in enum qca_wlan_vendor_cfr_capture_type.
+ * This attribute is mandatory for version 2.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK: Optional (u64)
+ * Bitfield indicating which user in the current UL MU transmissions are
+ * enabled for CFR capture. Bits 36 to 0 indicate user indexes for 37 users in
+ * a UL MU transmission. If bit 0 is set, the CFR capture will happen for user
+ * index 0 in the current UL MU transmission. If bits 0 and 2 are set, CFR
+ * capture for UL MU TX corresponds to user indices 0 and 2. Bits 63:37 are
+ * reserved for future use. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT: Optional (u32)
+ * Indicates the number of consecutive RX frames to be skipped before CFR
+ * capture is enabled again. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE: Nested attribute containing
+ * one or more %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY attributes.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY: Nested attribute containing
+ * the following group attributes:
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER,
+ * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER: Optional (u32)
+ * Target supports multiple groups for some configurations. The group number
+ * can be any value between 0 and 15. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA: Optional (6-byte MAC address)
+ * Transmitter address which is used to filter frames. This MAC address takes
+ * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK. This is for CFR
+ * version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA: Optional (6-byte MAC address)
+ * Receiver address which is used to filter frames. This MAC address takes
+ * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK. This is for CFR
+ * version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK: Optional (6-byte MAC address)
+ * Mask of transmitter address which is used to filter frames. This is for CFR
+ * version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK: Optional (6-byte MAC address)
+ * Mask of receiver address which is used to filter frames. This is for CFR
+ * version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS: Optional (u32)
+ * Indicates frames with a specific NSS will be filtered for CFR capture.
+ * This is for CFR version 2 only. This is a bitmask. Bits 7:0 request CFR
+ * capture to be done for frames matching the NSS specified within this bitmask.
+ * Bits 31:8 are reserved for future use. Bits 7:0 map to NSS:
+ * bit 0 : NSS 1
+ * bit 1 : NSS 2
+ * ...
+ * bit 7 : NSS 8
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW: Optional (u32)
+ * Indicates frames with a specific bandwidth will be filtered for CFR capture.
+ * This is for CFR version 2 only. This is a bitmask. Bits 4:0 request CFR
+ * capture to be done for frames matching the bandwidths specified within this
+ * bitmask. Bits 31:5 are reserved for future use. Bits 4:0 map to bandwidth
+ * numerated in enum nl80211_band (although not all bands may be supported
+ * by a given device).
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER: Optional (u32)
+ * Management frames matching the subtype filter categories will be filtered in
+ * by MAC for CFR capture. This is a bitmask in which each bit represents the
+ * corresponding Management frame subtype value per IEEE Std 802.11-2016,
+ * 9.2.4.1.3 Type and Subtype subfields. For example, Beacon frame control type
+ * is 8 and its value is 1 << 8 = 0x100. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER: Optional (u32)
+ * Control frames matching the subtype filter categories will be filtered in by
+ * MAC for CFR capture. This is a bitmask in which each bit represents the
+ * corresponding Control frame subtype value per IEEE Std 802.11-2016,
+ * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER: Optional (u32)
+ * Data frames matching the subtype filter categories will be filtered in by
+ * MAC for CFR capture. This is a bitmask in which each bit represents the
+ * corresponding Data frame subtype value per IEEE Std 802.11-2016,
+ * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only.
*/
enum qca_wlan_vendor_peer_cfr_capture_attr {
QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0,
- /* 6-byte MAC address of the peer.
- * This attribute is mandatory.
- */
QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR = 1,
- /* Enable peer CFR Capture, flag attribute.
- * This attribute is mandatory to enable peer CFR capture.
- * If this attribute is not present, peer CFR capture is disabled.
- */
QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE = 2,
- /* BW of measurement, attribute uses the values in enum nl80211_chan_width
- * Supported values: 20, 40, 80, 80+80, 160.
- * Note that all targets may not support all bandwidths.
- * u8 attribute. This attribute is mandatory if attribute
- * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used.
- */
QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH = 3,
- /* Periodicity of CFR measurement in msec.
- * Periodicity should be a multiple of Base timer.
- * Current Base timer value supported is 10 msecs (default).
- * 0 for one shot capture. u32 attribute.
- * This attribute is mandatory if attribute
- * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used.
- */
QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY = 4,
- /* Method used to capture Channel Frequency Response.
- * Attribute uses the values defined in enum qca_wlan_vendor_cfr_method.
- * u8 attribute. This attribute is mandatory if attribute
- * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used.
- */
QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD = 5,
- /* Enable periodic CFR capture, flag attribute.
- * This attribute is mandatory to enable Periodic CFR capture.
- * If this attribute is not present, periodic CFR capture is disabled.
- */
QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE = 6,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION = 7,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP = 8,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION = 9,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL = 10,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE = 11,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK = 12,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT = 13,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE = 14,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY = 15,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER = 16,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA = 17,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA = 18,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK = 19,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK = 20,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS = 21,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW = 22,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24,
+ QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25,
/* Keep last */
QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST,
diff --git a/src/common/sae.c b/src/common/sae.c
index 7ed53be..543640d 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -1623,13 +1623,13 @@ int sae_process_commit(struct sae_data *sae)
}
-void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
- const struct wpabuf *token, const char *identifier)
+int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
+ const struct wpabuf *token, const char *identifier)
{
u8 *pos;
if (sae->tmp == NULL)
- return;
+ return -1;
wpabuf_put_le16(buf, sae->group); /* Finite Cyclic Group */
if (!sae->tmp->h2e && token) {
@@ -1638,23 +1638,27 @@ void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
wpabuf_head(token), wpabuf_len(token));
}
pos = wpabuf_put(buf, sae->tmp->prime_len);
- crypto_bignum_to_bin(sae->tmp->own_commit_scalar, pos,
- sae->tmp->prime_len, sae->tmp->prime_len);
+ if (crypto_bignum_to_bin(sae->tmp->own_commit_scalar, pos,
+ sae->tmp->prime_len, sae->tmp->prime_len) < 0)
+ return -1;
wpa_hexdump(MSG_DEBUG, "SAE: own commit-scalar",
pos, sae->tmp->prime_len);
if (sae->tmp->ec) {
pos = wpabuf_put(buf, 2 * sae->tmp->prime_len);
- crypto_ec_point_to_bin(sae->tmp->ec,
- sae->tmp->own_commit_element_ecc,
- pos, pos + sae->tmp->prime_len);
+ if (crypto_ec_point_to_bin(sae->tmp->ec,
+ sae->tmp->own_commit_element_ecc,
+ pos, pos + sae->tmp->prime_len) < 0)
+ return -1;
wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(x)",
pos, sae->tmp->prime_len);
wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(y)",
pos + sae->tmp->prime_len, sae->tmp->prime_len);
} else {
pos = wpabuf_put(buf, sae->tmp->prime_len);
- crypto_bignum_to_bin(sae->tmp->own_commit_element_ffc, pos,
- sae->tmp->prime_len, sae->tmp->prime_len);
+ if (crypto_bignum_to_bin(sae->tmp->own_commit_element_ffc, pos,
+ sae->tmp->prime_len,
+ sae->tmp->prime_len) < 0)
+ return -1;
wpa_hexdump(MSG_DEBUG, "SAE: own commit-element",
pos, sae->tmp->prime_len);
}
@@ -1688,6 +1692,8 @@ void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
"SAE: Anti-clogging token (in container)",
token);
}
+
+ return 0;
}
diff --git a/src/common/sae.h b/src/common/sae.h
index e3e7d0e..7966d70 100644
--- a/src/common/sae.h
+++ b/src/common/sae.h
@@ -88,8 +88,8 @@ int sae_prepare_commit_pt(struct sae_data *sae, const struct sae_pt *pt,
const u8 *addr1, const u8 *addr2,
int *rejected_groups);
int sae_process_commit(struct sae_data *sae);
-void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
- const struct wpabuf *token, const char *identifier);
+int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
+ const struct wpabuf *token, const char *identifier);
u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
const u8 **token, size_t *token_len, int *allowed_groups,
int h2e);
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 6cb9180..1284743 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -355,6 +355,14 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN;
u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
size_t ptk_len;
+#ifdef CONFIG_OWE
+ int owe_ptk_workaround = 0;
+
+ if (akmp == (WPA_KEY_MGMT_OWE | WPA_KEY_MGMT_PSK_SHA256)) {
+ owe_ptk_workaround = 1;
+ akmp = WPA_KEY_MGMT_OWE;
+ }
+#endif /* CONFIG_OWE */
if (pmk_len == 0) {
wpa_printf(MSG_ERROR, "WPA: No PMK set for PTK derivation");
@@ -413,7 +421,8 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
tmp, ptk_len) < 0)
return -1;
#ifdef CONFIG_OWE
- } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 32) {
+ } else if (akmp == WPA_KEY_MGMT_OWE && (pmk_len == 32 ||
+ owe_ptk_workaround)) {
wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
if (sha256_prf(pmk, pmk_len, label, data, data_len,
tmp, ptk_len) < 0)
@@ -1965,10 +1974,12 @@ const char * wpa_cipher_txt(int cipher)
switch (cipher) {
case WPA_CIPHER_NONE:
return "NONE";
+#ifdef CONFIG_WEP
case WPA_CIPHER_WEP40:
return "WEP-40";
case WPA_CIPHER_WEP104:
return "WEP-104";
+#endif /* CONFIG_WEP */
case WPA_CIPHER_TKIP:
return "TKIP";
case WPA_CIPHER_CCMP:
@@ -2467,10 +2478,12 @@ int wpa_parse_cipher(const char *value)
val |= WPA_CIPHER_GCMP;
else if (os_strcmp(start, "TKIP") == 0)
val |= WPA_CIPHER_TKIP;
+#ifdef CONFIG_WEP
else if (os_strcmp(start, "WEP104") == 0)
val |= WPA_CIPHER_WEP104;
else if (os_strcmp(start, "WEP40") == 0)
val |= WPA_CIPHER_WEP40;
+#endif /* CONFIG_WEP */
else if (os_strcmp(start, "NONE") == 0)
val |= WPA_CIPHER_NONE;
else if (os_strcmp(start, "GTK_NOT_USED") == 0)
@@ -2668,12 +2681,10 @@ static int wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
/**
* wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
* @pos: Pointer to the IE header
- * @end: Pointer to the end of the Key Data buffer
* @ie: Pointer to parsed IE data
* Returns: 0 on success, 1 if end mark is found, -1 on failure
*/
-static int wpa_parse_generic(const u8 *pos, const u8 *end,
- struct wpa_eapol_ie_parse *ie)
+static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
{
if (pos[1] == 0)
return 1;
@@ -2695,8 +2706,7 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
return 0;
}
- if (1 + RSN_SELECTOR_LEN < end - pos &&
- pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
+ if (pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key",
@@ -2704,6 +2714,14 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
return 0;
}
+ if (pos[1] >= RSN_SELECTOR_LEN + 2 &&
+ RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_KEYID) {
+ ie->key_id = pos + 2 + RSN_SELECTOR_LEN;
+ wpa_hexdump(MSG_DEBUG, "WPA: KeyID in EAPOL-Key",
+ pos, pos[1] + 2);
+ return 0;
+ }
+
if (pos[1] > RSN_SELECTOR_LEN + 2 &&
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
@@ -2766,6 +2784,16 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
return 0;
}
+ if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
+ RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_TRANSITION_DISABLE) {
+ ie->transition_disable = pos + 2 + RSN_SELECTOR_LEN;
+ ie->transition_disable_len = pos[1] - RSN_SELECTOR_LEN;
+ wpa_hexdump(MSG_DEBUG,
+ "WPA: Transition Disable KDE in EAPOL-Key",
+ pos, pos[1] + 2);
+ return 0;
+ }
+
return 0;
}
@@ -2874,7 +2902,7 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
ie->supp_oper_classes_len = pos[1];
}
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
- ret = wpa_parse_generic(pos, end, ie);
+ ret = wpa_parse_generic(pos, ie);
if (ret < 0)
break;
if (ret > 0) {
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index 7850c87..da58159 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -113,6 +113,7 @@ WPA_CIPHER_BIP_CMAC_256)
#define WFA_KEY_DATA_IP_ADDR_REQ RSN_SELECTOR(0x50, 0x6f, 0x9a, 4)
#define WFA_KEY_DATA_IP_ADDR_ALLOC RSN_SELECTOR(0x50, 0x6f, 0x9a, 5)
+#define WFA_KEY_DATA_TRANSITION_DISABLE RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x20)
#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
@@ -344,6 +345,12 @@ struct rsn_rdie {
le16 status_code;
} STRUCT_PACKED;
+/* WFA Transition Disable KDE (using OUI_WFA) */
+/* Transition Disable Bitmap bits */
+#define TRANSITION_DISABLE_WPA3_PERSONAL BIT(0)
+#define TRANSITION_DISABLE_SAE_PK BIT(1)
+#define TRANSITION_DISABLE_WPA3_ENTERPRISE BIT(2)
+#define TRANSITION_DISABLE_ENHANCED_OPEN BIT(3)
#ifdef _MSC_VER
#pragma pack(pop)
@@ -494,6 +501,7 @@ struct wpa_eapol_ie_parse {
const u8 *rsn_ie;
size_t rsn_ie_len;
const u8 *pmkid;
+ const u8 *key_id;
const u8 *gtk;
size_t gtk_len;
const u8 *mac_addr;
@@ -508,6 +516,8 @@ struct wpa_eapol_ie_parse {
size_t ftie_len;
const u8 *ip_addr_req;
const u8 *ip_addr_alloc;
+ const u8 *transition_disable;
+ size_t transition_disable_len;
const u8 *oci;
size_t oci_len;
const u8 *osen;
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 48002be..ca1c35f 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -95,6 +95,8 @@ extern "C" {
/** SAE authentication failed due to unknown password identifier */
#define WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER \
"CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER "
+/** Unprotected Beacon frame dropped */
+#define WPA_EVENT_UNPROT_BEACON "CTRL-EVENT-UNPROT-BEACON "
/** IP subnet status change notification
*
@@ -187,6 +189,7 @@ extern "C" {
#define DPP_EVENT_PKEX_T_LIMIT "DPP-PKEX-T-LIMIT "
#define DPP_EVENT_INTRO "DPP-INTRO "
#define DPP_EVENT_CONF_REQ_RX "DPP-CONF-REQ-RX "
+#define DPP_EVENT_CHIRP_STOPPED "DPP-CHIRP-STOPPED "
/* MESH events */
#define MESH_GROUP_STARTED "MESH-GROUP-STARTED "
@@ -380,6 +383,13 @@ extern "C" {
#define WDS_STA_INTERFACE_ADDED "WDS-STA-INTERFACE-ADDED "
#define WDS_STA_INTERFACE_REMOVED "WDS-STA-INTERFACE-REMOVED "
+/* Transition mode disabled indication - followed by bitmap */
+#define TRANSITION_DISABLE "TRANSITION-DISABLE "
+
+#ifndef BIT
+#define BIT(x) (1U << (x))
+#endif
+
/* BSS command information masks */
#define WPA_BSS_MASK_ALL 0xFFFDFFFF
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 440da03..7c7515f 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -916,5 +916,6 @@ struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y);
struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
const u8 *key, size_t len);
void crypto_ecdh_deinit(struct crypto_ecdh *ecdh);
+size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh);
#endif /* CRYPTO_H */
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 783b293..47b6ebb 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -2168,4 +2168,10 @@ void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
}
}
+
+size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
+{
+ return crypto_ec_prime_len(ecdh->ec);
+}
+
#endif /* CONFIG_ECC */
diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
index 85ce565..dc68bd6 100644
--- a/src/crypto/crypto_wolfssl.c
+++ b/src/crypto/crypto_wolfssl.c
@@ -1834,4 +1834,10 @@ fail:
goto done;
}
+
+size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
+{
+ return crypto_ec_prime_len(ecdh->ec);
+}
+
#endif /* CONFIG_ECC */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index cd1ec31..032bbd8 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1096,6 +1096,13 @@ struct wpa_driver_associate_params {
const struct ieee80211_vht_capabilities *vhtcaps_mask;
#endif /* CONFIG_VHT_OVERRIDES */
+#ifdef CONFIG_HE_OVERRIDES
+ /**
+ * disable_he - Disable HE for this connection
+ */
+ int disable_he;
+#endif /* CONFIG_HE_OVERRIDES */
+
/**
* req_key_mgmt_offload - Request key management offload for connection
*
@@ -1546,9 +1553,8 @@ struct wpa_driver_set_key_params {
* alg - Encryption algorithm
*
* (%WPA_ALG_NONE, %WPA_ALG_WEP, %WPA_ALG_TKIP, %WPA_ALG_CCMP,
- * %WPA_ALG_IGTK, %WPA_ALG_PMK, %WPA_ALG_GCMP, %WPA_ALG_GCMP_256,
- * %WPA_ALG_CCMP_256, %WPA_ALG_BIP_GMAC_128, %WPA_ALG_BIP_GMAC_256,
- * %WPA_ALG_BIP_CMAC_256);
+ * %WPA_ALG_IGTK, %WPA_ALG_GCMP, %WPA_ALG_GCMP_256, %WPA_ALG_CCMP_256,
+ * %WPA_ALG_BIP_GMAC_128, %WPA_ALG_BIP_GMAC_256, %WPA_ALG_BIP_CMAC_256);
* %WPA_ALG_NONE clears the key. */
enum wpa_alg alg;
@@ -1611,8 +1617,8 @@ struct wpa_driver_set_key_params {
*
* %KEY_FLAG_MODIFY
* Set when an already installed key must be updated.
- * So far the only use-case is changing RX/TX status of
- * installed keys. Must not be set when deleting a key.
+ * So far the only use-case is changing RX/TX status for
+ * pairwise keys. Must not be set when deleting a key.
* %KEY_FLAG_DEFAULT
* Set when the key is also a default key. Must not be set when
* deleting a key.
@@ -1705,7 +1711,7 @@ struct wpa_driver_capa {
/** Driver takes care of all DFS operations */
#define WPA_DRIVER_FLAGS_DFS_OFFLOAD 0x00000004
/** Driver takes care of RSN 4-way handshake internally; PMK is configured with
- * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */
+ * struct wpa_driver_ops::set_key using key_flag = KEY_FLAG_PMK */
#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X 0x00000008
/** Driver is for a wired Ethernet interface */
#define WPA_DRIVER_FLAGS_WIRED 0x00000010
@@ -1842,6 +1848,8 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS_SAFE_PTK0_REKEYS 0x2000000000000000ULL
/** Driver supports Beacon protection */
#define WPA_DRIVER_FLAGS_BEACON_PROTECTION 0x4000000000000000ULL
+/** Driver supports Extended Key ID */
+#define WPA_DRIVER_FLAGS_EXTENDED_KEY_ID 0x8000000000000000ULL
u64 flags;
#define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
@@ -2328,6 +2336,9 @@ struct drv_acs_params {
/* ACS frequency list info */
const int *freq_list;
+
+ /* Indicates whether EDMG is enabled */
+ int edmg_enabled;
};
struct wpa_bss_trans_info {
@@ -2353,6 +2364,8 @@ struct wpa_pmkid_params {
const u8 *pmkid;
const u8 *pmk;
size_t pmk_len;
+ u32 pmk_lifetime;
+ u8 pmk_reauth_threshold;
};
/* Mask used to specify which connection parameters have to be updated */
@@ -2715,11 +2728,13 @@ struct wpa_driver_ops {
* @csa_offs_len: Number of elements in csa_offs
* @no_encrypt: Do not encrypt frame even if appropriate key exists
* (used only for testing purposes)
+ * @wait: Time to wait off-channel for a response (in ms), or zero
* Returns: 0 on success, -1 on failure
*/
int (*send_mlme)(void *priv, const u8 *data, size_t data_len,
int noack, unsigned int freq, const u16 *csa_offs,
- size_t csa_offs_len, int no_encrypt);
+ size_t csa_offs_len, int no_encrypt,
+ unsigned int wait);
/**
* update_ft_ies - Update FT (IEEE 802.11r) IEs
@@ -4955,6 +4970,15 @@ enum wpa_event_type {
* EVENT_UPDATE_DH - Notification of updated DH information
*/
EVENT_UPDATE_DH,
+
+ /**
+ * EVENT_UNPROT_BEACON - Unprotected Beacon frame received
+ *
+ * This event should be called when a Beacon frame is dropped due to it
+ * not being protected correctly. union wpa_event_data::unprot_beacon
+ * is required to provide more details of the frame.
+ */
+ EVENT_UNPROT_BEACON,
};
@@ -5721,6 +5745,7 @@ union wpa_event_data {
* struct acs_selected_channels - Data for EVENT_ACS_CHANNEL_SELECTED
* @pri_freq: Selected primary frequency
* @sec_freq: Selected secondary frequency
+ * @edmg_channel: Selected EDMG channel
* @vht_seg0_center_ch: VHT mode Segment0 center channel
* The value is the index of the channel center frequency for
* 20 MHz, 40 MHz, and 80 MHz channels. The value is the center
@@ -5739,6 +5764,7 @@ union wpa_event_data {
struct acs_selected_channels {
unsigned int pri_freq;
unsigned int sec_freq;
+ u8 edmg_channel;
u8 vht_seg0_center_ch;
u8 vht_seg1_center_ch;
u16 ch_width;
@@ -5805,6 +5831,13 @@ union wpa_event_data {
const u8 *ie;
size_t ie_len;
} update_dh;
+
+ /**
+ * struct unprot_beacon - Data for EVENT_UNPROT_BEACON
+ */
+ struct unprot_beacon {
+ const u8 *sa;
+ } unprot_beacon;
};
/**
diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c
index 2014f9d..d630c3d 100644
--- a/src/drivers/driver_atheros.c
+++ b/src/drivers/driver_atheros.c
@@ -1965,7 +1965,7 @@ static int atheros_set_ap(void *priv, struct wpa_driver_ap_params *params)
static int atheros_send_mgmt(void *priv, const u8 *frm, size_t data_len,
int noack, unsigned int freq,
const u16 *csa_offs, size_t csa_offs_len,
- int no_encrypt)
+ int no_encrypt, unsigned int wait)
{
struct atheros_driver_data *drv = priv;
u8 buf[1510];
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index f4d06e4..63846db 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -89,6 +89,7 @@ const char * event_to_string(enum wpa_event_type event)
E2S(INTERFACE_MAC_CHANGED);
E2S(WDS_STA_INTERFACE_STATUS);
E2S(UPDATE_DH);
+ E2S(UNPROT_BEACON);
}
return "UNKNOWN";
@@ -315,6 +316,7 @@ const char * driver_flag_to_string(u64 flag)
DF2S(UPDATE_FT_IES);
DF2S(SAFE_PTK0_REKEYS);
DF2S(BEACON_PROTECTION);
+ DF2S(EXTENDED_KEY_ID);
}
return "UNKNOWN";
#undef DF2S
diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c
index cfc52c7..b9c42e4 100644
--- a/src/drivers/driver_hostap.c
+++ b/src/drivers/driver_hostap.c
@@ -264,7 +264,7 @@ static int hostap_init_sockets(struct hostap_driver_data *drv, u8 *own_addr)
static int hostap_send_mlme(void *priv, const u8 *msg, size_t len, int noack,
unsigned int freq,
const u16 *csa_offs, size_t csa_offs_len,
- int no_encrypt)
+ int no_encrypt, unsigned int wait)
{
struct hostap_driver_data *drv = priv;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) msg;
@@ -313,7 +313,7 @@ static int hostap_send_eapol(void *priv, const u8 *addr, const u8 *data,
pos += 2;
memcpy(pos, data, data_len);
- res = hostap_send_mlme(drv, (u8 *) hdr, len, 0, 0, NULL, 0, 0);
+ res = hostap_send_mlme(drv, (u8 *) hdr, len, 0, 0, NULL, 0, 0, 0);
if (res < 0) {
wpa_printf(MSG_ERROR, "hostap_send_eapol - packet len: %lu - "
"failed: %d (%s)",
@@ -1055,7 +1055,7 @@ static int hostap_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
memcpy(mgmt.bssid, own_addr, ETH_ALEN);
mgmt.u.deauth.reason_code = host_to_le16(reason);
return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
- sizeof(mgmt.u.deauth), 0, 0, NULL, 0, 0);
+ sizeof(mgmt.u.deauth), 0, 0, NULL, 0, 0, 0);
}
@@ -1093,7 +1093,7 @@ static int hostap_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
memcpy(mgmt.bssid, own_addr, ETH_ALEN);
mgmt.u.disassoc.reason_code = host_to_le16(reason);
return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
- sizeof(mgmt.u.disassoc), 0, 0, NULL, 0, 0);
+ sizeof(mgmt.u.disassoc), 0, 0, NULL, 0, 0, 0);
}
@@ -1173,7 +1173,7 @@ static void wpa_driver_hostap_poll_client(void *priv, const u8 *own_addr,
os_memcpy(hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
os_memcpy(hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
- hostap_send_mlme(priv, (u8 *) &hdr, sizeof(hdr), 0, 0, NULL, 0, 0);
+ hostap_send_mlme(priv, (u8 *)&hdr, sizeof(hdr), 0, 0, NULL, 0, 0, 0);
}
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 18e4b8e..3b7c31c 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1047,7 +1047,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
while (RTA_OK(attr, attrlen)) {
switch (attr->rta_type) {
case IFLA_IFNAME:
- if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
+ if (RTA_PAYLOAD(attr) > IFNAMSIZ)
break;
os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
ifname[RTA_PAYLOAD(attr)] = '\0';
@@ -1222,7 +1222,7 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
while (RTA_OK(attr, attrlen)) {
switch (attr->rta_type) {
case IFLA_IFNAME:
- if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
+ if (RTA_PAYLOAD(attr) > IFNAMSIZ)
break;
os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
ifname[RTA_PAYLOAD(attr)] = '\0';
@@ -2182,6 +2182,7 @@ static int nl80211_init_connect_handle(struct i802_bss *bss)
static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
+ u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
int ret = 0;
if (nl80211_alloc_mgmt_handle(bss))
@@ -2189,13 +2190,14 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
"handle %p", bss->nl_mgmt);
- if (drv->nlmode == NL80211_IFTYPE_ADHOC ||
- ((drv->capa.flags & WPA_DRIVER_FLAGS_SAE) &&
- !(drv->capa.flags & WPA_DRIVER_FLAGS_SME))) {
- u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
-
+ if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
/* register for any AUTH message */
nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0);
+ } else if ((drv->capa.flags & WPA_DRIVER_FLAGS_SAE) &&
+ !(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
+ /* register for SAE Authentication frames */
+ nl80211_register_frame(bss, bss->nl_mgmt, type,
+ (u8 *) "\x03\x00", 2);
}
#ifdef CONFIG_INTERWORKING
@@ -2881,7 +2883,6 @@ static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
case WPA_ALG_KRK:
return RSN_CIPHER_SUITE_KRK;
case WPA_ALG_NONE:
- case WPA_ALG_PMK:
wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
alg);
return 0;
@@ -3053,7 +3054,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
struct nl_msg *msg;
struct nl_msg *key_msg;
int ret;
- int tdls = 0;
+ int skip_set_key = 1;
const char *ifname = params->ifname;
enum wpa_alg alg = params->alg;
const u8 *addr = params->addr;
@@ -3064,6 +3065,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
const u8 *key = params->key;
size_t key_len = params->key_len;
int vlan_id = params->vlan_id;
+ enum key_flag key_flag = params->key_flag;
/* Ignore for P2P Device */
if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
@@ -3071,18 +3073,17 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
ifindex = if_nametoindex(ifname);
wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
- "set_tx=%d seq_len=%lu key_len=%lu",
+ "set_tx=%d seq_len=%lu key_len=%lu key_flag=0x%x",
__func__, ifindex, ifname, alg, addr, key_idx, set_tx,
- (unsigned long) seq_len, (unsigned long) key_len);
-#ifdef CONFIG_TDLS
- if (key_idx == -1) {
- key_idx = 0;
- tdls = 1;
+ (unsigned long) seq_len, (unsigned long) key_len, key_flag);
+
+ if (check_key_flag(key_flag)) {
+ wpa_printf(MSG_DEBUG, "%s: invalid key_flag", __func__);
+ return -EINVAL;
}
-#endif /* CONFIG_TDLS */
#ifdef CONFIG_DRIVER_NL80211_QCA
- if (alg == WPA_ALG_PMK &&
+ if ((key_flag & KEY_FLAG_PMK) &&
(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
wpa_printf(MSG_DEBUG, "%s: calling issue_key_mgmt_set_key",
__func__);
@@ -3091,15 +3092,33 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
}
#endif /* CONFIG_DRIVER_NL80211_QCA */
- if (alg == WPA_ALG_PMK &&
- (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
- return nl80211_set_pmk(drv, key, key_len, addr);
+ if (key_flag & KEY_FLAG_PMK) {
+ if (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)
+ return nl80211_set_pmk(drv, key, key_len, addr);
+ /* The driver does not have any offload mechanism for PMK, so
+ * there is no need to configure this key. */
+ return 0;
+ }
+ ret = -ENOBUFS;
key_msg = nlmsg_alloc();
if (!key_msg)
- return -ENOBUFS;
+ return ret;
- if (alg == WPA_ALG_NONE) {
+ if ((key_flag & KEY_FLAG_PAIRWISE_MASK) ==
+ KEY_FLAG_PAIRWISE_RX_TX_MODIFY) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: SET_KEY (pairwise RX/TX modify)");
+ msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY);
+ if (!msg)
+ goto fail2;
+ } else if (alg == WPA_ALG_NONE && (key_flag & KEY_FLAG_RX_TX)) {
+ wpa_printf(MSG_DEBUG, "%s: invalid key_flag to delete key",
+ __func__);
+ ret = -EINVAL;
+ goto fail2;
+ } else if (alg == WPA_ALG_NONE) {
+ wpa_printf(MSG_DEBUG, "nl80211: DEL_KEY");
msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY);
if (!msg)
goto fail2;
@@ -3107,8 +3126,11 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
u32 suite;
suite = wpa_alg_to_cipher_suite(alg, key_len);
- if (!suite)
+ if (!suite) {
+ ret = -EINVAL;
goto fail2;
+ }
+ wpa_printf(MSG_DEBUG, "nl80211: NEW_KEY");
msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_NEW_KEY);
if (!msg)
goto fail2;
@@ -3116,12 +3138,13 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
nla_put_u32(key_msg, NL80211_KEY_CIPHER, suite))
goto fail;
wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
- }
- if (seq && seq_len) {
- if (nla_put(key_msg, NL80211_KEY_SEQ, seq_len, seq))
- goto fail;
- wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
+ if (seq && seq_len) {
+ if (nla_put(key_msg, NL80211_KEY_SEQ, seq_len, seq))
+ goto fail;
+ wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ",
+ seq, seq_len);
+ }
}
if (addr && !is_broadcast_ether_addr(addr)) {
@@ -3129,22 +3152,42 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
goto fail;
- if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
+ if ((key_flag & KEY_FLAG_PAIRWISE_MASK) ==
+ KEY_FLAG_PAIRWISE_RX ||
+ (key_flag & KEY_FLAG_PAIRWISE_MASK) ==
+ KEY_FLAG_PAIRWISE_RX_TX_MODIFY) {
+ if (nla_put_u8(key_msg, NL80211_KEY_MODE,
+ key_flag == KEY_FLAG_PAIRWISE_RX ?
+ NL80211_KEY_NO_TX : NL80211_KEY_SET_TX))
+ goto fail;
+ } else if ((key_flag & KEY_FLAG_GROUP_MASK) ==
+ KEY_FLAG_GROUP_RX) {
wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK");
if (nla_put_u32(key_msg, NL80211_KEY_TYPE,
NL80211_KEYTYPE_GROUP))
goto fail;
+ } else if (!(key_flag & KEY_FLAG_PAIRWISE)) {
+ wpa_printf(MSG_DEBUG,
+ " key_flag missing PAIRWISE when setting a pairwise key");
+ ret = -EINVAL;
+ goto fail;
+ } else if (alg == WPA_ALG_WEP &&
+ (key_flag & KEY_FLAG_RX_TX) == KEY_FLAG_RX_TX) {
+ wpa_printf(MSG_DEBUG, " unicast WEP key");
+ skip_set_key = 0;
+ } else {
+ wpa_printf(MSG_DEBUG, " pairwise key");
}
- } else if (addr && is_broadcast_ether_addr(addr)) {
- struct nlattr *types;
-
+ } else if ((key_flag & KEY_FLAG_PAIRWISE) ||
+ !(key_flag & KEY_FLAG_GROUP)) {
+ wpa_printf(MSG_DEBUG,
+ " invalid key_flag for a broadcast key");
+ ret = -EINVAL;
+ goto fail;
+ } else {
wpa_printf(MSG_DEBUG, " broadcast key");
-
- types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES);
- if (!types ||
- nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
- goto fail;
- nla_nest_end(key_msg, types);
+ if (key_flag & KEY_FLAG_DEFAULT)
+ skip_set_key = 0;
}
if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) ||
nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
@@ -3167,18 +3210,17 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
ret, strerror(-ret));
/*
- * If we failed or don't need to set the default TX key (below),
+ * If we failed or don't need to set the key as default (below),
* we're done here.
*/
- if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
- return ret;
- if (is_ap_interface(drv->nlmode) && addr &&
- !is_broadcast_ether_addr(addr))
+ if (ret || skip_set_key)
return ret;
+ wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_SET_KEY - default key");
+ ret = -ENOBUFS;
key_msg = nlmsg_alloc();
if (!key_msg)
- return -ENOBUFS;
+ return ret;
msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY);
if (!msg)
@@ -3226,8 +3268,6 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
}
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
- if (ret == -ENOENT)
- ret = 0;
if (ret)
wpa_printf(MSG_DEBUG,
"nl80211: set_key default failed; err=%d %s",
@@ -3240,7 +3280,7 @@ fail:
fail2:
nl80211_nlmsg_clear(key_msg);
nlmsg_free(key_msg);
- return -ENOBUFS;
+ return ret;
}
@@ -3554,6 +3594,9 @@ retry:
p.set_tx = i == params->wep_tx_keyidx;
p.key = params->wep_key[i];
p.key_len = params->wep_key_len[i];
+ p.key_flag = i == params->wep_tx_keyidx ?
+ KEY_FLAG_GROUP_RX_TX_DEFAULT :
+ KEY_FLAG_GROUP_RX_TX;
wpa_driver_nl80211_set_key(bss, &p);
if (params->wep_tx_keyidx != i)
continue;
@@ -3733,7 +3776,7 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
mgmt = (struct ieee80211_mgmt *) data;
fc = le_to_host16(mgmt->frame_control);
- wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da= " MACSTR
+ wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da=" MACSTR
" noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u no_encrypt=%d fc=0x%x (%s) nlmode=%d",
MAC2STR(mgmt->da), noack, freq, no_cck, offchanok, wait_time,
no_encrypt, fc, fc2str(fc), drv->nlmode);
@@ -5194,7 +5237,7 @@ static int nl80211_tx_control_port(void *priv, const u8 *dest,
if (ret)
wpa_printf(MSG_DEBUG,
"nl80211: tx_control_port failed: ret=%d (%s)",
- ret, strerror(ret));
+ ret, strerror(-ret));
return ret;
}
@@ -5288,9 +5331,9 @@ static int wpa_driver_nl80211_hapd_send_eapol(
res = nl80211_send_monitor(drv, hdr, len, encrypt, 0);
if (res < 0) {
- wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
- "failed: %d (%s)",
- (unsigned long) len, res, strerror(res));
+ wpa_printf(MSG_ERROR,
+ "hapd_send_eapol - packet len: %lu - failed",
+ (unsigned long) len);
}
os_free(hdr);
@@ -8085,6 +8128,9 @@ static int nl80211_set_param(void *priv, const char *param)
if (os_strstr(param, "control_port=0"))
drv->capa.flags &= ~WPA_DRIVER_FLAGS_CONTROL_PORT;
+ if (os_strstr(param, "full_ap_client_state=0"))
+ drv->capa.flags &= ~WPA_DRIVER_FLAGS_FULL_AP_CLIENT_STATE;
+
return 0;
}
@@ -8185,6 +8231,12 @@ static int nl80211_pmkid(struct i802_bss *bss, int cmd,
(params->fils_cache_id &&
nla_put(msg, NL80211_ATTR_FILS_CACHE_ID, 2,
params->fils_cache_id)) ||
+ (params->pmk_lifetime &&
+ nla_put_u32(msg, NL80211_ATTR_PMK_LIFETIME,
+ params->pmk_lifetime)) ||
+ (params->pmk_reauth_threshold &&
+ nla_put_u8(msg, NL80211_ATTR_PMK_REAUTH_THRESHOLD,
+ params->pmk_reauth_threshold)) ||
(cmd != NL80211_CMD_DEL_PMKSA &&
params->pmk_len && params->pmk_len <= PMK_MAX_LEN &&
nla_put(msg, NL80211_ATTR_PMK, params->pmk_len, params->pmk))) {
@@ -8844,11 +8896,11 @@ static int driver_nl80211_send_mlme(void *priv, const u8 *data,
size_t data_len, int noack,
unsigned int freq,
const u16 *csa_offs, size_t csa_offs_len,
- int no_encrypt)
+ int no_encrypt, unsigned int wait)
{
struct i802_bss *bss = priv;
return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
- freq, 0, 0, 0, csa_offs,
+ freq, 0, 0, wait, csa_offs,
csa_offs_len, no_encrypt);
}
@@ -10393,16 +10445,18 @@ static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
nla_put_u16(msg, QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
params->ch_width) ||
add_acs_ch_list(msg, params->freq_list) ||
- add_acs_freq_list(msg, params->freq_list)) {
+ add_acs_freq_list(msg, params->freq_list) ||
+ (params->edmg_enabled &&
+ nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED))) {
nlmsg_free(msg);
return -ENOBUFS;
}
nla_nest_end(msg, data);
wpa_printf(MSG_DEBUG,
- "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d",
+ "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d EDMG: %d",
params->hw_mode, params->ht_enabled, params->ht40_enabled,
- params->vht_enabled, params->ch_width);
+ params->vht_enabled, params->ch_width, params->edmg_enabled);
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
if (ret) {
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index ea1ab8a..b4fed9e 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -453,6 +453,10 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
if (ext_feature_isset(ext_features, len,
NL80211_EXT_FEATURE_BEACON_PROTECTION))
capa->flags |= WPA_DRIVER_FLAGS_BEACON_PROTECTION;
+
+ if (ext_feature_isset(ext_features, len,
+ NL80211_EXT_FEATURE_EXT_KEY_ID))
+ capa->flags |= WPA_DRIVER_FLAGS_EXTENDED_KEY_ID;
}
@@ -1311,6 +1315,12 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS;
#endif /* CONFIG_DRIVER_NL80211_QCA */
+ wpa_printf(MSG_DEBUG,
+ "nl80211: key_mgmt=0x%x enc=0x%x auth=0x%x flags=0x%llx rrm_flags=0x%x probe_resp_offloads=0x%x max_stations=%u max_remain_on_chan=%u max_scan_ssids=%d",
+ drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth,
+ (unsigned long long) drv->capa.flags, drv->capa.rrm_flags,
+ drv->capa.probe_resp_offloads, drv->capa.max_stations,
+ drv->capa.max_remain_on_chan, drv->capa.max_scan_ssids);
return 0;
}
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 8327644..d4ca2eb 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -683,17 +683,28 @@ static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
size_t len, struct nlattr *ack)
{
union wpa_event_data event;
- const struct ieee80211_hdr *hdr;
- u16 fc;
+ const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame;
+ u16 fc = le_to_host16(hdr->frame_control);
+ u64 cookie_val = 0;
- wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
- if (!is_ap_interface(drv->nlmode)) {
- u64 cookie_val;
+ if (cookie)
+ cookie_val = nla_get_u64(cookie);
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Frame TX status event A1=" MACSTR
+ " %sstype=%d cookie=0x%llx%s ack=%d",
+ MAC2STR(hdr->addr1),
+ WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ? "not-mgmt " : "",
+ WLAN_FC_GET_STYPE(fc), (long long unsigned int) cookie_val,
+ cookie ? "" : "(N/A)", ack != NULL);
+
+ if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
+ return;
+ if (!is_ap_interface(drv->nlmode) &&
+ WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
if (!cookie)
return;
- cookie_val = nla_get_u64(cookie);
wpa_printf(MSG_DEBUG,
"nl80211: Frame TX status: cookie=0x%llx%s (ack=%d)",
(long long unsigned int) cookie_val,
@@ -701,11 +712,13 @@ static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
" (match)" : " (unknown)", ack != NULL);
if (cookie_val != drv->send_frame_cookie)
return;
+ } else if (!is_ap_interface(drv->nlmode) &&
+ WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Authentication frame TX status: ack=%d",
+ !!ack);
}
- hdr = (const struct ieee80211_hdr *) frame;
- fc = le_to_host16(hdr->frame_control);
-
os_memset(&event, 0, sizeof(event));
event.tx_status.type = WLAN_FC_GET_TYPE(fc);
event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
@@ -1740,8 +1753,41 @@ static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
}
-static unsigned int chan_2ghz_or_5ghz_to_freq(u8 chan)
+static unsigned int chan_to_freq(struct wpa_driver_nl80211_data *drv,
+ u8 chan, enum hostapd_hw_mode hw_mode)
{
+ if (hw_mode == NUM_HOSTAPD_MODES) {
+ /* For drivers that do not report ACS_HW_MODE */
+ u16 num_modes, flags;
+ struct hostapd_hw_modes *modes;
+ u8 dfs_domain;
+ int i;
+
+ modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes,
+ &flags, &dfs_domain);
+ if (!modes) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Fetching hardware mode failed");
+ goto try_2_4_or_5;
+ }
+ if (num_modes == 1)
+ hw_mode = modes[0].mode;
+
+ for (i = 0; i < num_modes; i++) {
+ os_free(modes[i].channels);
+ os_free(modes[i].rates);
+ }
+
+ os_free(modes);
+ }
+
+ if (hw_mode == HOSTAPD_MODE_IEEE80211AD) {
+ if (chan >= 1 && chan <= 6)
+ return 56160 + (2160 * chan);
+ return 0;
+ }
+
+try_2_4_or_5:
if (chan >= 1 && chan <= 13)
return 2407 + 5 * chan;
if (chan == 14)
@@ -1772,13 +1818,30 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
return;
os_memset(&event, 0, sizeof(event));
+ event.acs_selected_channels.hw_mode = NUM_HOSTAPD_MODES;
+
+ if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
+ u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+
+ event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
+ if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
+ event.acs_selected_channels.hw_mode ==
+ HOSTAPD_MODE_IEEE80211ANY) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Invalid hw_mode %d in ACS selection event",
+ hw_mode);
+ return;
+ }
+ }
+
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]) {
event.acs_selected_channels.pri_freq = nla_get_u32(
tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]);
} else {
chan = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
event.acs_selected_channels.pri_freq =
- chan_2ghz_or_5ghz_to_freq(chan);
+ chan_to_freq(drv, chan,
+ event.acs_selected_channels.hw_mode);
}
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]) {
@@ -1788,9 +1851,13 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
chan = nla_get_u8(
tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
event.acs_selected_channels.sec_freq =
- chan_2ghz_or_5ghz_to_freq(chan);
+ chan_to_freq(drv, chan,
+ event.acs_selected_channels.hw_mode);
}
+ if (tb[QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL])
+ event.acs_selected_channels.edmg_channel =
+ nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL]);
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
event.acs_selected_channels.vht_seg0_center_ch =
nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
@@ -1800,28 +1867,15 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
event.acs_selected_channels.ch_width =
nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
- if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
- u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
-
- event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
- if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
- event.acs_selected_channels.hw_mode ==
- HOSTAPD_MODE_IEEE80211ANY) {
- wpa_printf(MSG_DEBUG,
- "nl80211: Invalid hw_mode %d in ACS selection event",
- hw_mode);
- return;
- }
- }
-
wpa_printf(MSG_INFO,
- "nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
+ "nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d EDMGCH: %d",
event.acs_selected_channels.pri_freq,
event.acs_selected_channels.sec_freq,
event.acs_selected_channels.ch_width,
event.acs_selected_channels.vht_seg0_center_ch,
event.acs_selected_channels.vht_seg1_center_ch,
- event.acs_selected_channels.hw_mode);
+ event.acs_selected_channels.hw_mode,
+ event.acs_selected_channels.edmg_channel);
/* Ignore ACS channel list check for backwards compatibility */
diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c
index 413d6f7..04f6bb8 100644
--- a/src/drivers/driver_nl80211_scan.c
+++ b/src/drivers/driver_nl80211_scan.c
@@ -236,6 +236,11 @@ nl80211_scan_common(struct i802_bss *bss, u8 cmd,
params->filter_ssids = NULL;
drv->num_filter_ssids = params->num_filter_ssids;
+ if (!drv->hostapd && is_ap_interface(drv->nlmode)) {
+ wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_AP");
+ scan_flags |= NL80211_SCAN_FLAG_AP;
+ }
+
if (params->only_new_results) {
wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
scan_flags |= NL80211_SCAN_FLAG_FLUSH;
diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c
index e0eede9..bfc2311 100644
--- a/src/drivers/driver_openbsd.c
+++ b/src/drivers/driver_openbsd.c
@@ -73,11 +73,12 @@ wpa_driver_openbsd_set_key(void *priv, struct wpa_driver_set_key_params *params)
{
struct openbsd_driver_data *drv = priv;
struct ieee80211_keyavail keyavail;
- enum wpa_alg alg = params->alg;
+ enum key_flag key_flag = params->key_flag;
const u8 *key = params->key;
size_t key_len = params->key_len;
- if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN)
+ if (key_len > IEEE80211_PMK_LEN ||
+ (key_flag & KEY_FLAG_PMK_MASK) != KEY_FLAG_PMK) {
return -1;
memset(&keyavail, 0, sizeof(keyavail));
diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c
index 807657e..d6735b4 100644
--- a/src/drivers/driver_privsep.c
+++ b/src/drivers/driver_privsep.c
@@ -230,6 +230,7 @@ static int wpa_driver_privsep_set_key(void *priv,
os_memset(cmd.addr, 0xff, ETH_ALEN);
cmd.key_idx = key_idx;
cmd.set_tx = set_tx;
+ cmd.key_flag = params->key_flag;
if (seq && seq_len > 0 && seq_len < sizeof(cmd.seq)) {
os_memcpy(cmd.seq, seq, seq_len);
cmd.seq_len = seq_len;
@@ -796,6 +797,8 @@ static int wpa_driver_privsep_get_capa(void *priv,
capa->extended_capa = NULL;
capa->extended_capa_mask = NULL;
capa->extended_capa_len = 0;
+ /* Control port is not yet supported */
+ capa->flags &= ~WPA_DRIVER_FLAGS_CONTROL_PORT;
return 0;
}
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index 776eff7..978e1cf 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -1712,7 +1712,8 @@ static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg,
const u8 *addr, int key_idx,
int set_tx, const u8 *seq,
size_t seq_len,
- const u8 *key, size_t key_len)
+ const u8 *key, size_t key_len,
+ enum key_flag key_flag)
{
struct wpa_driver_wext_data *drv = priv;
struct iwreq iwr;
@@ -1751,30 +1752,31 @@ static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg,
os_memcpy(ext + 1, key, key_len);
ext->key_len = key_len;
}
- switch (alg) {
- case WPA_ALG_NONE:
- ext->alg = IW_ENCODE_ALG_NONE;
- break;
- case WPA_ALG_WEP:
- ext->alg = IW_ENCODE_ALG_WEP;
- break;
- case WPA_ALG_TKIP:
- ext->alg = IW_ENCODE_ALG_TKIP;
- break;
- case WPA_ALG_CCMP:
- ext->alg = IW_ENCODE_ALG_CCMP;
- break;
- case WPA_ALG_PMK:
+ if (key_flag & KEY_FLAG_PMK) {
ext->alg = IW_ENCODE_ALG_PMK;
- break;
- case WPA_ALG_IGTK:
- ext->alg = IW_ENCODE_ALG_AES_CMAC;
- break;
- default:
- wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
- __FUNCTION__, alg);
- os_free(ext);
- return -1;
+ } else {
+ switch (alg) {
+ case WPA_ALG_NONE:
+ ext->alg = IW_ENCODE_ALG_NONE;
+ break;
+ case WPA_ALG_WEP:
+ ext->alg = IW_ENCODE_ALG_WEP;
+ break;
+ case WPA_ALG_TKIP:
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ break;
+ case WPA_ALG_CCMP:
+ ext->alg = IW_ENCODE_ALG_CCMP;
+ break;
+ case WPA_ALG_IGTK:
+ ext->alg = IW_ENCODE_ALG_AES_CMAC;
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
+ __FUNCTION__, alg);
+ os_free(ext);
+ return -1;
+ }
}
if (seq && seq_len) {
@@ -1816,6 +1818,7 @@ static int wpa_driver_wext_set_key(void *priv,
struct iwreq iwr;
int ret = 0;
enum wpa_alg alg = params->alg;
+ enum key_flag key_flag = params->key_flag;
const u8 *addr = params->addr;
int key_idx = params->key_idx;
int set_tx = params->set_tx;
@@ -1830,7 +1833,7 @@ static int wpa_driver_wext_set_key(void *priv,
(unsigned long) seq_len, (unsigned long) key_len);
ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx,
- seq, seq_len, key, key_len);
+ seq, seq_len, key, key_len, key_flag);
if (ret == 0)
return 0;
diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index 934e62f..2b69116 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -11,7 +11,7 @@
* Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
* Copyright 2008 Colin McCabe <colin@cozybit.com>
* Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2019 Intel Corporation
+ * Copyright (C) 2018-2020 Intel Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -265,6 +265,29 @@
*/
/**
+ * DOC: TID configuration
+ *
+ * TID config support can be checked in the %NL80211_ATTR_TID_CONFIG
+ * attribute given in wiphy capabilities.
+ *
+ * The necessary configuration parameters are mentioned in
+ * &enum nl80211_tid_config_attr and it will be passed to the
+ * %NL80211_CMD_SET_TID_CONFIG command in %NL80211_ATTR_TID_CONFIG.
+ *
+ * If the configuration needs to be applied for specific peer then the MAC
+ * address of the peer needs to be passed in %NL80211_ATTR_MAC, otherwise the
+ * configuration will be applied for all the connected peers in the vif except
+ * any peers that have peer specific configuration for the TID by default; if
+ * the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer specific values
+ * will be overwritten.
+ *
+ * All this configuration is valid only for STA's current connection
+ * i.e. the configuration will be reset to default when the STA connects back
+ * after disconnection/roaming, and this configuration will be cleared when
+ * the interface goes down.
+ */
+
+/**
* enum nl80211_commands - supported nl80211 commands
*
* @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -1125,6 +1148,9 @@
* peer MAC address and %NL80211_ATTR_FRAME is used to specify the frame
* content. The frame is ethernet data.
*
+ * @NL80211_CMD_SET_TID_CONFIG: Data frame TID specific configuration
+ * is passed using %NL80211_ATTR_TID_CONFIG attribute.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1349,6 +1375,8 @@ enum nl80211_commands {
NL80211_CMD_PROBE_MESH_LINK,
+ NL80211_CMD_SET_TID_CONFIG,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1604,7 +1632,8 @@ enum nl80211_commands {
* flag is included, then control port frames are sent over NL80211 instead
* using %CMD_CONTROL_PORT_FRAME. If control port routing over NL80211 is
* to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
- * flag.
+ * flag. When used with %NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, pre-auth
+ * frames are not forwared over the control port.
*
* @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
* We recommend using nested, driver-specific attributes within this.
@@ -2409,6 +2438,38 @@ enum nl80211_commands {
* %NL80211_ATTR_AKM_SUITES are default capabilities if AKM suites not
* advertised for a specific interface type.
*
+ * @NL80211_ATTR_TID_CONFIG: TID specific configuration in a
+ * nested attribute with &enum nl80211_tid_config_attr sub-attributes;
+ * on output (in wiphy attributes) it contains only the feature sub-
+ * attributes.
+ *
+ * @NL80211_ATTR_CONTROL_PORT_NO_PREAUTH: disable preauth frame rx on control
+ * port in order to forward/receive them as ordinary data frames.
+ *
+ * @NL80211_ATTR_PMK_LIFETIME: Maximum lifetime for PMKSA in seconds (u32,
+ * dot11RSNAConfigPMKReauthThreshold; 0 is not a valid value).
+ * An optional parameter configured through %NL80211_CMD_SET_PMKSA.
+ * Drivers that trigger roaming need to know the lifetime of the
+ * configured PMKSA for triggering the full vs. PMKSA caching based
+ * authentication. This timeout helps authentication methods like SAE,
+ * where PMK gets updated only by going through a full (new SAE)
+ * authentication instead of getting updated during an association for EAP
+ * authentication. No new full authentication within the PMK expiry shall
+ * result in a disassociation at the end of the lifetime.
+ *
+ * @NL80211_ATTR_PMK_REAUTH_THRESHOLD: Reauthentication threshold time, in
+ * terms of percentage of %NL80211_ATTR_PMK_LIFETIME
+ * (u8, dot11RSNAConfigPMKReauthThreshold, 1..100). This is an optional
+ * parameter configured through %NL80211_CMD_SET_PMKSA. Requests the
+ * driver to trigger a full authentication roam (without PMKSA caching)
+ * after the reauthentication threshold time, but before the PMK lifetime
+ * has expired.
+ *
+ * Authentication methods like SAE need to be able to generate a new PMKSA
+ * entry without having to force a disconnection after the PMK timeout. If
+ * no roaming occurs between the reauth threshold and PMK expiration,
+ * disassociation is still forced.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2877,6 +2938,13 @@ enum nl80211_attrs {
NL80211_ATTR_IFTYPE_AKM_SUITES,
+ NL80211_ATTR_TID_CONFIG,
+
+ NL80211_ATTR_CONTROL_PORT_NO_PREAUTH,
+
+ NL80211_ATTR_PMK_LIFETIME,
+ NL80211_ATTR_PMK_REAUTH_THRESHOLD,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -4723,6 +4791,69 @@ enum nl80211_tx_power_setting {
};
/**
+ * enum nl80211_tid_config - TID config state
+ * @NL80211_TID_CONFIG_ENABLE: Enable config for the TID
+ * @NL80211_TID_CONFIG_DISABLE: Disable config for the TID
+ */
+enum nl80211_tid_config {
+ NL80211_TID_CONFIG_ENABLE,
+ NL80211_TID_CONFIG_DISABLE,
+};
+
+/* enum nl80211_tid_config_attr - TID specific configuration.
+ * @NL80211_TID_CONFIG_ATTR_PAD: pad attribute for 64-bit values
+ * @NL80211_TID_CONFIG_ATTR_VIF_SUPP: a bitmap (u64) of attributes supported
+ * for per-vif configuration; doesn't list the ones that are generic
+ * (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE).
+ * @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but
+ * per peer instead.
+ * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if no peer
+ * is selected, if set indicates that the new configuration overrides
+ * all previous peer configurations, otherwise previous peer specific
+ * configurations should be left untouched. If peer is selected then
+ * it will reset particular TID configuration of that peer and it will
+ * not accept other TID config attributes along with peer.
+ * @NL80211_TID_CONFIG_ATTR_TIDS: a bitmask value of TIDs (bit 0 to 7)
+ * Its type is u16.
+ * @NL80211_TID_CONFIG_ATTR_NOACK: Configure ack policy for the TID.
+ * specified in %NL80211_TID_CONFIG_ATTR_TID. see %enum nl80211_tid_config.
+ * Its type is u8.
+ * @NL80211_TID_CONFIG_ATTR_RETRY_SHORT: Number of retries used with data frame
+ * transmission, user-space sets this configuration in
+ * &NL80211_CMD_SET_TID_CONFIG. It is u8 type, min value is 1 and
+ * the max value is advertised by the driver in this attribute on
+ * output in wiphy capabilities.
+ * @NL80211_TID_CONFIG_ATTR_RETRY_LONG: Number of retries used with data frame
+ * transmission, user-space sets this configuration in
+ * &NL80211_CMD_SET_TID_CONFIG. Its type is u8, min value is 1 and
+ * the max value is advertised by the driver in this attribute on
+ * output in wiphy capabilities.
+ * @NL80211_TID_CONFIG_ATTR_AMPDU_CTRL: Enable/Disable aggregation for the TIDs
+ * specified in %NL80211_TID_CONFIG_ATTR_TIDS. Its type is u8, using
+ * the values from &nl80211_tid_config.
+ * @NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL: Enable/Disable RTS_CTS for the TIDs
+ * specified in %NL80211_TID_CONFIG_ATTR_TIDS. It is u8 type, using
+ * the values from &nl80211_tid_config.
+ */
+enum nl80211_tid_config_attr {
+ __NL80211_TID_CONFIG_ATTR_INVALID,
+ NL80211_TID_CONFIG_ATTR_PAD,
+ NL80211_TID_CONFIG_ATTR_VIF_SUPP,
+ NL80211_TID_CONFIG_ATTR_PEER_SUPP,
+ NL80211_TID_CONFIG_ATTR_OVERRIDE,
+ NL80211_TID_CONFIG_ATTR_TIDS,
+ NL80211_TID_CONFIG_ATTR_NOACK,
+ NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
+ NL80211_TID_CONFIG_ATTR_RETRY_LONG,
+ NL80211_TID_CONFIG_ATTR_AMPDU_CTRL,
+ NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL,
+
+ /* keep last */
+ __NL80211_TID_CONFIG_ATTR_AFTER_LAST,
+ NL80211_TID_CONFIG_ATTR_MAX = __NL80211_TID_CONFIG_ATTR_AFTER_LAST - 1
+};
+
+/**
* enum nl80211_packet_pattern_attr - packet pattern attribute
* @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
* @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
@@ -5544,6 +5675,15 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection
* and can receive key configuration for BIGTK using key indexes 6 and 7.
*
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH: The driver can disable the
+ * forwarding of preauth frames over the control port. They are then
+ * handled as ordinary data frames.
+ *
+ * @NL80211_EXT_FEATURE_PROTECTED_TWT: Driver supports protected TWT frames
+ *
+ * @NL80211_EXT_FEATURE_DEL_IBSS_STA: The driver supports removing stations
+ * in IBSS mode, essentially by dropping their state.
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -5592,6 +5732,9 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_VLAN_OFFLOAD,
NL80211_EXT_FEATURE_AQL,
NL80211_EXT_FEATURE_BEACON_PROTECTION,
+ NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH,
+ NL80211_EXT_FEATURE_PROTECTED_TWT,
+ NL80211_EXT_FEATURE_DEL_IBSS_STA,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
@@ -6214,12 +6357,14 @@ enum nl80211_ftm_responder_stats {
* @NL80211_PREAMBLE_HT: HT preamble
* @NL80211_PREAMBLE_VHT: VHT preamble
* @NL80211_PREAMBLE_DMG: DMG preamble
+ * @NL80211_PREAMBLE_HE: HE preamble
*/
enum nl80211_preamble {
NL80211_PREAMBLE_LEGACY,
NL80211_PREAMBLE_HT,
NL80211_PREAMBLE_VHT,
NL80211_PREAMBLE_DMG,
+ NL80211_PREAMBLE_HE,
};
/**
@@ -6412,6 +6557,10 @@ enum nl80211_peer_measurement_attrs {
* is valid)
* @NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST: u32 attribute indicating
* the maximum FTMs per burst (if not present anything is valid)
+ * @NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED: flag attribute indicating if
+ * trigger based ranging measurement is supported
+ * @NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED: flag attribute indicating
+ * if non trigger based ranging measurement is supported
*
* @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal
* @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number
@@ -6427,6 +6576,8 @@ enum nl80211_peer_measurement_ftm_capa {
NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
+ NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED,
+ NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED,
/* keep last */
NUM_NL80211_PMSR_FTM_CAPA_ATTR,
@@ -6456,6 +6607,20 @@ enum nl80211_peer_measurement_ftm_capa {
* @NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI: request LCI data (flag)
* @NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC: request civic location data
* (flag)
+ * @NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED: request trigger based ranging
+ * measurement (flag).
+ * This attribute and %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED are
+ * mutually exclusive.
+ * if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
+ * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
+ * ranging will be used.
+ * @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non trigger based
+ * ranging measurement (flag)
+ * This attribute and %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED are
+ * mutually exclusive.
+ * if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
+ * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
+ * ranging will be used.
*
* @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
* @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
@@ -6472,6 +6637,8 @@ enum nl80211_peer_measurement_ftm_req {
NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES,
NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI,
NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
+ NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
+ NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
/* keep last */
NUM_NL80211_PMSR_FTM_REQ_ATTR,
diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c
index 5a2ba26..2e79614 100644
--- a/src/eapol_auth/eapol_auth_sm.c
+++ b/src/eapol_auth/eapol_auth_sm.c
@@ -648,6 +648,8 @@ SM_STEP(REAUTH_TIMER)
+#ifdef CONFIG_WEP
+
/* Authenticator Key Transmit state machine */
SM_STATE(AUTH_KEY_TX, NO_KEY_TRANSMIT)
@@ -726,6 +728,8 @@ SM_STEP(KEY_RX)
}
}
+#endif /* CONFIG_WEP */
+
/* Controlled Directions state machine */
@@ -813,10 +817,12 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
sm->portControl = Auto;
+#ifdef CONFIG_WEP
if (!eapol->conf.wpa &&
(eapol->default_wep_key || eapol->conf.individual_wep_key_len > 0))
sm->keyTxEnabled = TRUE;
else
+#endif /* CONFIG_WEP */
sm->keyTxEnabled = FALSE;
if (eapol->conf.wpa)
sm->portValid = FALSE;
@@ -910,10 +916,12 @@ restart:
SM_STEP_RUN(BE_AUTH);
if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
SM_STEP_RUN(REAUTH_TIMER);
+#ifdef CONFIG_WEP
if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
SM_STEP_RUN(AUTH_KEY_TX);
if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
SM_STEP_RUN(KEY_RX);
+#endif /* CONFIG_WEP */
if (sm->initializing || eapol_sm_sta_entry_alive(eapol, addr))
SM_STEP_RUN(CTRL_DIR);
@@ -1167,7 +1175,9 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
dst->ctx = src->ctx;
dst->eap_reauth_period = src->eap_reauth_period;
dst->wpa = src->wpa;
+#ifdef CONFIG_WEP
dst->individual_wep_key_len = src->individual_wep_key_len;
+#endif /* CONFIG_WEP */
os_free(dst->eap_req_id_text);
if (src->eap_req_id_text) {
dst->eap_req_id_text = os_memdup(src->eap_req_id_text,
@@ -1221,10 +1231,12 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
return NULL;
}
+#ifdef CONFIG_WEP
if (conf->individual_wep_key_len > 0) {
/* use key0 in individual key and key1 in broadcast key */
eapol->default_wep_key_idx = 1;
}
+#endif /* CONFIG_WEP */
eapol->cb.eapol_send = cb->eapol_send;
eapol->cb.aaa_send = cb->aaa_send;
@@ -1249,6 +1261,8 @@ void eapol_auth_deinit(struct eapol_authenticator *eapol)
return;
eapol_auth_conf_free(&eapol->conf);
+#ifdef CONFIG_WEP
os_free(eapol->default_wep_key);
+#endif /* CONFIG_WEP */
os_free(eapol);
}
diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
index a34cc0b..7f04b01 100644
--- a/src/eapol_supp/eapol_supp_sm.c
+++ b/src/eapol_supp/eapol_supp_sm.c
@@ -692,6 +692,7 @@ struct eap_key_data {
static void eapol_sm_processKey(struct eapol_sm *sm)
{
+#ifdef CONFIG_WEP
#ifndef CONFIG_FIPS
struct ieee802_1x_hdr *hdr;
struct ieee802_1x_eapol_key *key;
@@ -842,7 +843,7 @@ static void eapol_sm_processKey(struct eapol_sm *sm)
if (sm->ctx->set_wep_key &&
sm->ctx->set_wep_key(sm->ctx->ctx,
- key->key_index & IEEE8021X_KEY_INDEX_FLAG,
+ !!(key->key_index & IEEE8021X_KEY_INDEX_FLAG),
key->key_index & IEEE8021X_KEY_INDEX_MASK,
datakey, key_len) < 0) {
wpa_printf(MSG_WARNING, "EAPOL: Failed to set WEP key to the "
@@ -866,6 +867,7 @@ static void eapol_sm_processKey(struct eapol_sm *sm)
}
}
#endif /* CONFIG_FIPS */
+#endif /* CONFIG_WEP */
}
diff --git a/src/radius/radius.c b/src/radius/radius.c
index 07240ea..be16e27 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -609,7 +609,7 @@ static int radius_msg_add_attr_to_array(struct radius_msg *msg,
{
if (msg->attr_used >= msg->attr_size) {
size_t *nattr_pos;
- int nlen = msg->attr_size * 2;
+ size_t nlen = msg->attr_size * 2;
nattr_pos = os_realloc_array(msg->attr_pos, nlen,
sizeof(*msg->attr_pos));
diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
index cd4b050..bd32cef 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -267,7 +267,9 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa,
entry->network_ctx, entry->akmp);
wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa, entry->pmkid,
entry->fils_cache_id_set ? entry->fils_cache_id : NULL,
- entry->pmk, entry->pmk_len);
+ entry->pmk, entry->pmk_len,
+ pmksa->sm->dot11RSNAConfigPMKLifetime,
+ pmksa->sm->dot11RSNAConfigPMKReauthThreshold);
return entry;
}
@@ -371,9 +373,12 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
{
struct rsn_pmksa_cache_entry *new_entry;
os_time_t old_expiration = old_entry->expiration;
+ const u8 *pmkid = NULL;
+ if (wpa_key_mgmt_sae(old_entry->akmp))
+ pmkid = old_entry->pmkid;
new_entry = pmksa_cache_add(pmksa, old_entry->pmk, old_entry->pmk_len,
- NULL, NULL, 0,
+ pmkid, NULL, 0,
aa, pmksa->sm->own_addr,
old_entry->network_ctx, old_entry->akmp,
old_entry->fils_cache_id_set ?
@@ -413,6 +418,20 @@ pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, void *network_ctx,
while (entry) {
if (entry->network_ctx == network_ctx &&
(!akmp || entry->akmp == akmp)) {
+ struct os_reltime now;
+
+ if (wpa_key_mgmt_sae(entry->akmp) &&
+ os_get_reltime(&now) == 0 &&
+ entry->reauth_time < now.sec) {
+ wpa_printf(MSG_DEBUG,
+ "RSN: Do not clone PMKSA cache entry for "
+ MACSTR
+ " since its reauth threshold has passed",
+ MAC2STR(entry->aa));
+ entry = entry->next;
+ continue;
+ }
+
entry = pmksa_cache_clone_entry(pmksa, entry, aa);
if (entry) {
wpa_printf(MSG_DEBUG, "RSN: added "
@@ -516,6 +535,20 @@ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
network_ctx,
fils_cache_id);
if (sm->cur_pmksa) {
+ struct os_reltime now;
+
+ if (wpa_key_mgmt_sae(sm->cur_pmksa->akmp) &&
+ os_get_reltime(&now) == 0 &&
+ sm->cur_pmksa->reauth_time < now.sec) {
+ wpa_printf(MSG_DEBUG,
+ "RSN: Do not allow PMKSA cache entry for "
+ MACSTR
+ " to be used for SAE since its reauth threshold has passed",
+ MAC2STR(sm->cur_pmksa->aa));
+ sm->cur_pmksa = NULL;
+ return -1;
+ }
+
wpa_hexdump(MSG_DEBUG, "RSN: PMKSA cache entry found - PMKID",
sm->cur_pmksa->pmkid, PMKID_LEN);
return 0;
diff --git a/src/rsn_supp/preauth.c b/src/rsn_supp/preauth.c
index a7ca2ed..a101921 100644
--- a/src/rsn_supp/preauth.c
+++ b/src/rsn_supp/preauth.c
@@ -349,7 +349,7 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm)
* PMKIDs again, so report the existing data now. */
if (p) {
wpa_sm_add_pmkid(sm, NULL, candidate->bssid, p->pmkid,
- NULL, p->pmk, p->pmk_len);
+ NULL, p->pmk, p->pmk_len, 0, 0);
}
dl_list_del(&candidate->list);
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index bb89739..7b47e3a 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -227,7 +227,7 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR,
MAC2STR(peer->addr));
- if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, rsc, sizeof(rsc),
+ if (wpa_sm_set_key(sm, alg, peer->addr, 0, 1, rsc, sizeof(rsc),
peer->tpk.tk, key_len,
KEY_FLAG_PAIRWISE_RX_TX) < 0) {
wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 263e210..1c89664 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -183,7 +183,7 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
int key_info, ver;
u8 bssid[ETH_ALEN], *rbuf, *key_mic, *mic;
- if (pairwise && sm->wpa_deny_ptk0_rekey &&
+ if (pairwise && sm->wpa_deny_ptk0_rekey && !sm->use_ext_key_id &&
wpa_sm_get_state(sm) == WPA_COMPLETED) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: PTK0 rekey not allowed, reconnecting");
@@ -598,7 +598,7 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
sm->pmk_len > 32) {
wpa_printf(MSG_DEBUG,
"OWE: Force SHA256 for PTK derivation");
- akmp = WPA_KEY_MGMT_PSK_SHA256;
+ akmp |= WPA_KEY_MGMT_PSK_SHA256;
}
#endif /* CONFIG_OWE */
return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
@@ -608,6 +608,51 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
}
+static int wpa_handle_ext_key_id(struct wpa_sm *sm,
+ struct wpa_eapol_ie_parse *kde)
+{
+ if (sm->ext_key_id) {
+ u16 key_id;
+
+ if (!kde->key_id) {
+ wpa_msg(sm->ctx->msg_ctx,
+ sm->use_ext_key_id ? MSG_INFO : MSG_DEBUG,
+ "RSN: No Key ID in Extended Key ID handshake");
+ sm->keyidx_active = 0;
+ return sm->use_ext_key_id ? -1 : 0;
+ }
+
+ key_id = kde->key_id[0] & 0x03;
+ if (key_id > 1) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "RSN: Invalid Extended Key ID: %d", key_id);
+ return -1;
+ }
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Using Extended Key ID %d", key_id);
+ sm->keyidx_active = key_id;
+ sm->use_ext_key_id = 1;
+ } else {
+ if (kde->key_id && (kde->key_id[0] & 0x03)) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "RSN: Non-zero Extended Key ID Key ID in PTK0 handshake");
+ return -1;
+ }
+
+ if (kde->key_id) {
+ /* This is not supposed to be included here, but ignore
+ * the case of matching Key ID 0 just in case. */
+ wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Extended Key ID Key ID 0 in PTK0 handshake");
+ }
+ sm->keyidx_active = 0;
+ sm->use_ext_key_id = 0;
+ }
+
+ return 0;
+}
+
+
static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
const unsigned char *src_addr,
const struct wpa_eapol_key *key,
@@ -626,7 +671,8 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
return;
}
- if (sm->wpa_deny_ptk0_rekey && wpa_sm_get_state(sm) == WPA_COMPLETED) {
+ if (sm->wpa_deny_ptk0_rekey && !sm->use_ext_key_id &&
+ wpa_sm_get_state(sm) == WPA_COMPLETED) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: PTK0 rekey not allowed, reconnecting");
wpa_sm_reconnect(sm);
@@ -859,13 +905,14 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
}
- if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
- sm->ptk.tk, keylen,
+ if (wpa_sm_set_key(sm, alg, sm->bssid, sm->keyidx_active, 1, key_rsc,
+ rsclen, sm->ptk.tk, keylen,
KEY_FLAG_PAIRWISE | key_flag) < 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
- "WPA: Failed to set PTK to the "
- "driver (alg=%d keylen=%d bssid=" MACSTR ")",
- alg, keylen, MAC2STR(sm->bssid));
+ "WPA: Failed to set PTK to the driver (alg=%d keylen=%d bssid="
+ MACSTR " idx=%d key_flag=0x%x)",
+ alg, keylen, MAC2STR(sm->bssid),
+ sm->keyidx_active, key_flag);
return -1;
}
@@ -879,7 +926,23 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
sm, NULL);
}
+ return 0;
+}
+
+static int wpa_supplicant_activate_ptk(struct wpa_sm *sm)
+{
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "WPA: Activate PTK (idx=%d bssid=" MACSTR ")",
+ sm->keyidx_active, MAC2STR(sm->bssid));
+
+ if (wpa_sm_set_key(sm, 0, sm->bssid, sm->keyidx_active, 0, NULL, 0,
+ NULL, 0, KEY_FLAG_PAIRWISE_RX_TX_MODIFY) < 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "WPA: Failed to activate PTK for TX (idx=%d bssid="
+ MACSTR ")", sm->keyidx_active, MAC2STR(sm->bssid));
+ return -1;
+ }
return 0;
}
@@ -1424,11 +1487,10 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Could not find AP from "
"the scan results");
- } else {
- wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
- "WPA: Found the current AP from "
- "updated scan results");
+ return -1;
}
+ wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "WPA: Found the current AP from updated scan results");
}
if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
@@ -1472,6 +1534,11 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
os_memcmp(sm->ap_rsnxe, ie->rsnxe, sm->ap_rsnxe_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: RSNXE mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
+ wpa_hexdump(MSG_INFO, "RSNXE in Beacon/ProbeResp",
+ sm->ap_rsnxe, sm->ap_rsnxe_len);
+ wpa_hexdump(MSG_INFO, "RSNXE in EAPOL-Key msg 3/4",
+ ie->rsnxe, ie->rsnxe_len);
+ wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
@@ -1578,6 +1645,9 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
goto failed;
+ if (wpa_handle_ext_key_id(sm, &ie))
+ goto failed;
+
if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: ANonce from message 1 of 4-Way Handshake "
@@ -1623,6 +1693,10 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
}
#endif /* CONFIG_OCV */
+ if (sm->use_ext_key_id &&
+ wpa_supplicant_install_ptk(sm, key, KEY_FLAG_RX))
+ goto failed;
+
if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
&sm->ptk) < 0) {
goto failed;
@@ -1634,7 +1708,14 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
sm->renew_snonce = 1;
if (key_info & WPA_KEY_INFO_INSTALL) {
- if (wpa_supplicant_install_ptk(sm, key, KEY_FLAG_RX_TX))
+ int res;
+
+ if (sm->use_ext_key_id)
+ res = wpa_supplicant_activate_ptk(sm);
+ else
+ res = wpa_supplicant_install_ptk(sm, key,
+ KEY_FLAG_RX_TX);
+ if (res)
goto failed;
}
@@ -1690,6 +1771,8 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
sm->cur_pmksa = sa;
}
+ if (ie.transition_disable)
+ wpa_sm_transition_disable(sm, ie.transition_disable[0]);
sm->msg_3_of_4_ok = 1;
return;
@@ -2876,6 +2959,8 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
#ifdef CONFIG_P2P
os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
#endif /* CONFIG_P2P */
+
+ sm->keyidx_active = 0;
}
@@ -2907,6 +2992,7 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm)
/* Keys are not needed in the WPA state machine anymore */
wpa_sm_drop_sa(sm);
+ sm->keyidx_active = 0;
sm->msg_3_of_4_ok = 0;
os_memset(sm->bssid, 0, ETH_ALEN);
@@ -3038,8 +3124,8 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
} else {
sm->fils_cache_id_set = 0;
}
- sm->beacon_prot = config->beacon_prot;
#endif /* CONFIG_FILS */
+ sm->beacon_prot = config->beacon_prot;
} else {
sm->network_ctx = NULL;
sm->allowed_pairwise_cipher = 0;
@@ -3160,6 +3246,12 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
case WPA_PARAM_DENY_PTK0_REKEY:
sm->wpa_deny_ptk0_rekey = value;
break;
+ case WPA_PARAM_EXT_KEY_ID:
+ sm->ext_key_id = value;
+ break;
+ case WPA_PARAM_USE_EXT_KEY_ID:
+ sm->use_ext_key_id = value;
+ break;
default:
break;
}
@@ -3234,6 +3326,18 @@ int wpa_sm_pmf_enabled(struct wpa_sm *sm)
}
+int wpa_sm_ext_key_id(struct wpa_sm *sm)
+{
+ return sm ? sm->ext_key_id : 0;
+}
+
+
+int wpa_sm_ext_key_id_active(struct wpa_sm *sm)
+{
+ return sm ? sm->use_ext_key_id : 0;
+}
+
+
int wpa_sm_ocv_enabled(struct wpa_sm *sm)
{
struct wpa_ie_data rsn;
@@ -3867,13 +3971,13 @@ struct wpabuf * fils_build_auth(struct wpa_sm *sm, int dh_group, const u8 *md)
wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
- /* FILS Wrapped Data */
+ /* Wrapped Data */
sm->fils_erp_pmkid_set = 0;
if (erp_msg) {
wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg)); /* Length */
/* Element ID Extension */
- wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_WRAPPED_DATA);
+ wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
wpabuf_put_buf(buf, erp_msg);
/* Calculate pending PMKID here so that we do not need to
* maintain a copy of the EAP-Initiate/Reauth message. */
@@ -4078,16 +4182,16 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
goto fail;
}
- /* FILS Wrapped Data */
- if (!sm->cur_pmksa && elems.fils_wrapped_data) {
+ /* Wrapped Data */
+ if (!sm->cur_pmksa && elems.wrapped_data) {
u8 rmsk[ERP_MAX_KEY_LEN];
size_t rmsk_len;
wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
- elems.fils_wrapped_data,
- elems.fils_wrapped_data_len);
- eapol_sm_process_erp_finish(sm->eapol, elems.fils_wrapped_data,
- elems.fils_wrapped_data_len);
+ elems.wrapped_data,
+ elems.wrapped_data_len);
+ eapol_sm_process_erp_finish(sm->eapol, elems.wrapped_data,
+ elems.wrapped_data_len);
if (eapol_sm_failed(sm->eapol))
goto fail;
@@ -4249,6 +4353,8 @@ static int fils_ft_build_assoc_req_rsne(struct wpa_sm *sm, struct wpabuf *buf)
capab |= WPA_CAPABILITY_MFPR;
if (sm->ocv)
capab |= WPA_CAPABILITY_OCVC;
+ if (sm->ext_key_id)
+ capab |= WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST;
wpabuf_put_le16(buf, capab);
/* PMKID Count */
@@ -4676,6 +4782,7 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
keylen, (long unsigned int) sm->ptk.tk_len);
goto fail;
}
+
rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
wpa_hexdump_key(MSG_DEBUG, "FILS: Set TK to driver",
sm->ptk.tk, keylen);
@@ -4704,6 +4811,9 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
sm->fils_completed = 1;
forced_memzero(&gd, sizeof(gd));
+ if (kde.transition_disable)
+ wpa_sm_transition_disable(sm, kde.transition_disable[0]);
+
return 0;
fail:
forced_memzero(&gd, sizeof(gd));
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 0bd1449..796f392 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -42,7 +42,8 @@ struct wpa_sm_ctx {
size_t *msg_len, void **data_pos);
int (*add_pmkid)(void *ctx, void *network_ctx, const u8 *bssid,
const u8 *pmkid, const u8 *fils_cache_id,
- const u8 *pmk, size_t pmk_len);
+ const u8 *pmk, size_t pmk_len, u32 pmk_lifetime,
+ u8 pmk_reauth_threshold);
int (*remove_pmkid)(void *ctx, void *network_ctx, const u8 *bssid,
const u8 *pmkid, const u8 *fils_cache_id);
void (*set_config_blob)(void *ctx, struct wpa_config_blob *blob);
@@ -85,6 +86,7 @@ struct wpa_sm_ctx {
void (*fils_hlp_rx)(void *ctx, const u8 *dst, const u8 *src,
const u8 *pkt, size_t pkt_len);
int (*channel_info)(void *ctx, struct wpa_channel_info *ci);
+ void (*transition_disable)(void *ctx, u8 bitmap);
};
@@ -102,6 +104,8 @@ enum wpa_sm_conf_params {
WPA_PARAM_OCV,
WPA_PARAM_SAE_PWE,
WPA_PARAM_DENY_PTK0_REKEY,
+ WPA_PARAM_EXT_KEY_ID,
+ WPA_PARAM_USE_EXT_KEY_ID,
};
struct rsn_supp_config {
@@ -154,6 +158,8 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
int verbose);
int wpa_sm_pmf_enabled(struct wpa_sm *sm);
+int wpa_sm_ext_key_id(struct wpa_sm *sm);
+int wpa_sm_ext_key_id_active(struct wpa_sm *sm);
int wpa_sm_ocv_enabled(struct wpa_sm *sm);
void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise);
@@ -300,6 +306,16 @@ static inline int wpa_sm_pmf_enabled(struct wpa_sm *sm)
return 0;
}
+static inline int wpa_sm_ext_key_id(struct wpa_sm *sm)
+{
+ return 0;
+}
+
+static inline int wpa_sm_ext_key_id_active(struct wpa_sm *sm)
+{
+ return 0;
+}
+
static inline int wpa_sm_ocv_enabled(struct wpa_sm *sm)
{
return 0;
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index 046bdfd..203a61c 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -82,23 +82,30 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
if (sm == NULL)
return 0;
+ if (!get_ie(ies, ies_len, WLAN_EID_MOBILITY_DOMAIN)) {
+ os_free(sm->assoc_resp_ies);
+ sm->assoc_resp_ies = NULL;
+ sm->assoc_resp_ies_len = 0;
+ os_memset(sm->mobility_domain, 0, MOBILITY_DOMAIN_ID_LEN);
+ os_memset(sm->r0kh_id, 0, FT_R0KH_ID_MAX_LEN);
+ sm->r0kh_id_len = 0;
+ os_memset(sm->r1kh_id, 0, FT_R1KH_ID_LEN);
+ return 0;
+ }
+
use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
if (wpa_ft_parse_ies(ies, ies_len, &ft, use_sha384) < 0)
return -1;
- if (ft.mdie && ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1)
+ if (ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1)
return -1;
- if (ft.mdie) {
- wpa_hexdump(MSG_DEBUG, "FT: Mobility domain",
- ft.mdie, MOBILITY_DOMAIN_ID_LEN);
- os_memcpy(sm->mobility_domain, ft.mdie,
- MOBILITY_DOMAIN_ID_LEN);
- sm->mdie_ft_capab = ft.mdie[MOBILITY_DOMAIN_ID_LEN];
- wpa_printf(MSG_DEBUG, "FT: Capability and Policy: 0x%02x",
- sm->mdie_ft_capab);
- } else
- os_memset(sm->mobility_domain, 0, MOBILITY_DOMAIN_ID_LEN);
+ wpa_hexdump(MSG_DEBUG, "FT: Mobility domain",
+ ft.mdie, MOBILITY_DOMAIN_ID_LEN);
+ os_memcpy(sm->mobility_domain, ft.mdie, MOBILITY_DOMAIN_ID_LEN);
+ sm->mdie_ft_capab = ft.mdie[MOBILITY_DOMAIN_ID_LEN];
+ wpa_printf(MSG_DEBUG, "FT: Capability and Policy: 0x%02x",
+ sm->mdie_ft_capab);
if (ft.r0kh_id) {
wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID",
@@ -125,10 +132,10 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
sm->assoc_resp_ies = os_malloc(ft.mdie_len + 2 + ft.ftie_len + 2);
if (sm->assoc_resp_ies) {
u8 *pos = sm->assoc_resp_ies;
- if (ft.mdie) {
- os_memcpy(pos, ft.mdie - 2, ft.mdie_len + 2);
- pos += ft.mdie_len + 2;
- }
+
+ os_memcpy(pos, ft.mdie - 2, ft.mdie_len + 2);
+ pos += ft.mdie_len + 2;
+
if (ft.ftie) {
os_memcpy(pos, ft.ftie - 2, ft.ftie_len + 2);
pos += ft.ftie_len + 2;
@@ -155,6 +162,7 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
* @ric_ies: Optional IE(s), e.g., WMM TSPEC(s), for RIC-Request or %NULL
* @ric_ies_len: Length of ric_ies buffer in octets
* @ap_mdie: Mobility Domain IE from the target AP
+ * @omit_rsnxe: Whether RSNXE is omitted from Reassociation Request frame
* Returns: Pointer to buffer with IEs or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free();
@@ -164,16 +172,16 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
const u8 *kck, size_t kck_len,
const u8 *target_ap,
const u8 *ric_ies, size_t ric_ies_len,
- const u8 *ap_mdie)
+ const u8 *ap_mdie, int omit_rsnxe)
{
size_t buf_len;
u8 *buf, *pos, *ftie_len, *ftie_pos, *fte_mic, *elem_count;
struct rsn_mdie *mdie;
struct rsn_ie_hdr *rsnie;
- u16 capab;
int mdie_len;
u8 rsnxe[10];
size_t rsnxe_len;
+ int rsnxe_used;
int res;
sm->ft_completed = 0;
@@ -249,14 +257,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
pos += RSN_SELECTOR_LEN;
/* RSN Capabilities */
- capab = 0;
- if (sm->mfp)
- capab |= WPA_CAPABILITY_MFPC;
- if (sm->mfp == 2)
- capab |= WPA_CAPABILITY_MFPR;
- if (sm->ocv)
- capab |= WPA_CAPABILITY_OCVC;
- WPA_PUT_LE16(pos, capab);
+ WPA_PUT_LE16(pos, rsn_supp_capab(sm));
pos += 2;
/* PMKID Count */
@@ -302,10 +303,13 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
ftie_pos = pos;
*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
ftie_len = pos++;
+ rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) && anonce &&
+ (sm->sae_pwe == 1 || sm->sae_pwe == 2);
if (wpa_key_mgmt_sha384(sm->key_mgmt)) {
struct rsn_ftie_sha384 *ftie;
ftie = (struct rsn_ftie_sha384 *) pos;
+ ftie->mic_control[0] = !!rsnxe_used;
fte_mic = ftie->mic;
elem_count = &ftie->mic_control[1];
pos += sizeof(*ftie);
@@ -316,6 +320,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
struct rsn_ftie *ftie;
ftie = (struct rsn_ftie *) pos;
+ ftie->mic_control[0] = !!rsnxe_used;
fte_mic = ftie->mic;
elem_count = &ftie->mic_control[1];
pos += sizeof(*ftie);
@@ -363,12 +368,16 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
pos += ric_ies_len;
}
- res = wpa_gen_rsnxe(sm, rsnxe, sizeof(rsnxe));
- if (res < 0) {
- os_free(buf);
- return NULL;
+ if (omit_rsnxe) {
+ rsnxe_len = 0;
+ } else {
+ res = wpa_gen_rsnxe(sm, rsnxe, sizeof(rsnxe));
+ if (res < 0) {
+ os_free(buf);
+ return NULL;
+ }
+ rsnxe_len = res;
}
- rsnxe_len = res;
if (kck) {
/*
@@ -451,7 +460,7 @@ int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie)
}
ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name,
- NULL, 0, sm->bssid, NULL, 0, mdie);
+ NULL, 0, sm->bssid, NULL, 0, mdie, 0);
if (ft_ies) {
wpa_sm_update_ft_ies(sm, sm->mobility_domain,
ft_ies, ft_ies_len);
@@ -647,7 +656,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
sm->pmk_r1_name,
kck, kck_len, bssid,
ric_ies, ric_ies_len,
- parse.mdie ? parse.mdie - 2 : NULL);
+ parse.mdie ? parse.mdie - 2 : NULL,
+ !sm->ap_rsnxe);
if (ft_ies) {
wpa_sm_update_ft_ies(sm, sm->mobility_domain,
ft_ies, ft_ies_len);
@@ -935,6 +945,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
const u8 *anonce, *snonce, *fte_mic;
u8 fte_elem_count;
+ int own_rsnxe_used, rsnxe_used;
wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
@@ -973,6 +984,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
anonce = ftie->anonce;
snonce = ftie->snonce;
+ rsnxe_used = ftie->mic_control[0] & 0x01;
fte_elem_count = ftie->mic_control[1];
fte_mic = ftie->mic;
} else {
@@ -986,6 +998,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
anonce = ftie->anonce;
snonce = ftie->snonce;
+ rsnxe_used = ftie->mic_control[0] & 0x01;
fte_elem_count = ftie->mic_control[1];
fte_mic = ftie->mic;
}
@@ -1083,6 +1096,58 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
return -1;
}
+ if (rsnxe_used && !sm->ap_rsnxe) {
+ wpa_printf(MSG_INFO,
+ "FT: FTE indicated that AP uses RSNXE, but RSNXE was not included in Beacon/Probe Response frames");
+ return -1;
+ }
+
+ if (!sm->ap_rsn_ie) {
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "FT: No RSNE for this AP known - trying to get from scan results");
+ if (wpa_sm_get_beacon_ie(sm) < 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "FT: Could not find AP from the scan results");
+ return -1;
+ }
+ wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "FT: Found the current AP from updated scan results");
+ }
+
+ if (sm->ap_rsn_ie &&
+ wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
+ sm->ap_rsn_ie, sm->ap_rsn_ie_len,
+ parse.rsn - 2, parse.rsn_len + 2)) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "FT: RSNE mismatch between Beacon/ProbeResp and FT protocol Reassociation Response frame");
+ wpa_hexdump(MSG_INFO, "RSNE in Beacon/ProbeResp",
+ sm->ap_rsn_ie, sm->ap_rsn_ie_len);
+ wpa_hexdump(MSG_INFO,
+ "RSNE in FT protocol Reassociation Response frame",
+ parse.rsn ? parse.rsn - 2 : NULL,
+ parse.rsn ? parse.rsn_len + 2 : 0);
+ return -1;
+ }
+
+ own_rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) &&
+ (sm->sae_pwe == 1 || sm->sae_pwe == 2);
+ if ((sm->ap_rsnxe && !parse.rsnxe && own_rsnxe_used) ||
+ (!sm->ap_rsnxe && parse.rsnxe) ||
+ (sm->ap_rsnxe && parse.rsnxe &&
+ (sm->ap_rsnxe_len != 2 + parse.rsnxe_len ||
+ os_memcmp(sm->ap_rsnxe, parse.rsnxe - 2,
+ sm->ap_rsnxe_len) != 0))) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "FT: RSNXE mismatch between Beacon/ProbeResp and FT protocol Reassociation Response frame");
+ wpa_hexdump(MSG_INFO, "RSNXE in Beacon/ProbeResp",
+ sm->ap_rsnxe, sm->ap_rsnxe_len);
+ wpa_hexdump(MSG_INFO,
+ "RSNXE in FT protocol Reassociation Response frame",
+ parse.rsnxe ? parse.rsnxe - 2 : NULL,
+ parse.rsnxe ? parse.rsnxe_len + 2 : 0);
+ return -1;
+ }
+
#ifdef CONFIG_OCV
if (wpa_sm_ocv_enabled(sm)) {
struct wpa_channel_info ci;
@@ -1153,7 +1218,7 @@ int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap,
}
ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name,
- NULL, 0, target_ap, NULL, 0, mdie);
+ NULL, 0, target_ap, NULL, 0, mdie, 0);
if (ft_ies) {
sm->over_the_ds_in_progress = 1;
os_memcpy(sm->target_ap, target_ap, ETH_ALEN);
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 7af678d..1ad75dc 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -68,6 +68,10 @@ struct wpa_sm {
int wpa_rsc_relaxation;
int owe_ptk_workaround;
int beacon_prot;
+ int ext_key_id; /* whether Extended Key ID is enabled */
+ int use_ext_key_id; /* whether Extended Key ID has been detected
+ * to be used */
+ int keyidx_active; /* Key ID for the active TK */
u8 own_addr[ETH_ALEN];
const char *ifname;
@@ -260,11 +264,13 @@ static inline u8 * wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
static inline int wpa_sm_add_pmkid(struct wpa_sm *sm, void *network_ctx,
const u8 *bssid, const u8 *pmkid,
const u8 *cache_id, const u8 *pmk,
- size_t pmk_len)
+ size_t pmk_len, u32 pmk_lifetime,
+ u8 pmk_reauth_threshold)
{
WPA_ASSERT(sm->ctx->add_pmkid);
return sm->ctx->add_pmkid(sm->ctx->ctx, network_ctx, bssid, pmkid,
- cache_id, pmk, pmk_len);
+ cache_id, pmk, pmk_len, pmk_lifetime,
+ pmk_reauth_threshold);
}
static inline int wpa_sm_remove_pmkid(struct wpa_sm *sm, void *network_ctx,
@@ -422,6 +428,12 @@ static inline int wpa_sm_channel_info(struct wpa_sm *sm,
return sm->ctx->channel_info(sm->ctx->ctx, ci);
}
+static inline void wpa_sm_transition_disable(struct wpa_sm *sm, u8 bitmap)
+{
+ if (sm->ctx->transition_disable)
+ sm->ctx->transition_disable(sm->ctx->ctx, bitmap);
+}
+
int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
int ver, const u8 *dest, u16 proto,
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index 03c0d7e..9068781 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -105,6 +105,23 @@ static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
}
+u16 rsn_supp_capab(struct wpa_sm *sm)
+{
+ u16 capab = 0;
+
+ if (sm->mfp)
+ capab |= WPA_CAPABILITY_MFPC;
+ if (sm->mfp == 2)
+ capab |= WPA_CAPABILITY_MFPR;
+ if (sm->ocv)
+ capab |= WPA_CAPABILITY_OCVC;
+ if (sm->ext_key_id)
+ capab |= WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST;
+
+ return capab;
+}
+
+
static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
int pairwise_cipher, int group_cipher,
int key_mgmt, int mgmt_group_cipher,
@@ -112,7 +129,6 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
{
u8 *pos;
struct rsn_ie_hdr *hdr;
- u16 capab;
u32 suite;
if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN +
@@ -214,14 +230,7 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
pos += RSN_SELECTOR_LEN;
/* RSN Capabilities */
- capab = 0;
- if (sm->mfp)
- capab |= WPA_CAPABILITY_MFPC;
- if (sm->mfp == 2)
- capab |= WPA_CAPABILITY_MFPR;
- if (sm->ocv)
- capab |= WPA_CAPABILITY_OCVC;
- WPA_PUT_LE16(pos, capab);
+ WPA_PUT_LE16(pos, rsn_supp_capab(sm));
pos += 2;
if (sm->cur_pmksa) {
diff --git a/src/rsn_supp/wpa_ie.h b/src/rsn_supp/wpa_ie.h
index 6dc6cf5..83a6727 100644
--- a/src/rsn_supp/wpa_ie.h
+++ b/src/rsn_supp/wpa_ie.h
@@ -13,5 +13,6 @@ struct wpa_sm;
int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len);
int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len);
+u16 rsn_supp_capab(struct wpa_sm *sm);
#endif /* WPA_IE_H */
diff --git a/src/utils/browser.c b/src/utils/browser.c
index f864fbf..c0f4380 100644
--- a/src/utils/browser.c
+++ b/src/utils/browser.c
@@ -107,9 +107,6 @@ static void view_cb_resource_load_starting(WebKitWebView *view,
const gchar *uri = webkit_uri_request_get_uri(req);
wpa_printf(MSG_DEBUG, "BROWSER:%s uri=%s", __func__, uri);
- if (g_str_has_suffix(uri, "/favicon.ico"))
- webkit_uri_request_set_uri(req, "about:blank");
-
process_request_starting_uri(ctx, uri);
}
@@ -134,6 +131,21 @@ static gboolean view_cb_decide_policy(WebKitWebView *view,
}
break;
}
+ case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: {
+ WebKitNavigationPolicyDecision *d;
+ WebKitNavigationAction *a;
+ WebKitURIRequest *req;
+ const gchar *uri;
+
+ d = WEBKIT_NAVIGATION_POLICY_DECISION(policy);
+ a = webkit_navigation_policy_decision_get_navigation_action(d);
+ req = webkit_navigation_action_get_request(a);
+ uri = webkit_uri_request_get_uri(req);
+ wpa_printf(MSG_DEBUG, "BROWSER:%s navigation action: uri=%s",
+ __func__, uri);
+ process_request_starting_uri(ctx, uri);
+ break;
+ }
default:
break;
}
diff --git a/src/utils/common.c b/src/utils/common.c
index 27bf435..2c12751 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -7,6 +7,7 @@
*/
#include "includes.h"
+#include <limits.h>
#include "common/ieee802_11_defs.h"
#include "common.h"
@@ -790,6 +791,10 @@ int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
*/
pos = value;
while (pos && pos[0]) {
+ if (count == UINT_MAX) {
+ os_free(freq);
+ return -1;
+ }
n = os_realloc_array(freq, count + 1,
sizeof(struct wpa_freq_range));
if (n == NULL) {
@@ -874,9 +879,10 @@ char * freq_range_list_str(const struct wpa_freq_range_list *list)
}
-int int_array_len(const int *a)
+size_t int_array_len(const int *a)
{
- int i;
+ size_t i;
+
for (i = 0; a && a[i]; i++)
;
return i;
@@ -885,12 +891,21 @@ int int_array_len(const int *a)
void int_array_concat(int **res, const int *a)
{
- int reslen, alen, i;
+ size_t reslen, alen, i, max_size;
int *n;
reslen = int_array_len(*res);
alen = int_array_len(a);
-
+ max_size = (size_t) -1;
+ if (alen >= max_size - reslen) {
+ /* This should not really happen, but if it did, something
+ * would overflow. Do not try to merge the arrays; instead, make
+ * this behave like memory allocation failure to avoid messing
+ * up memory. */
+ os_free(*res);
+ *res = NULL;
+ return;
+ }
n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
if (n == NULL) {
os_free(*res);
@@ -918,8 +933,7 @@ static int freq_cmp(const void *a, const void *b)
void int_array_sort_unique(int *a)
{
- int alen;
- int i, j;
+ size_t alen, i, j;
if (a == NULL)
return;
@@ -944,7 +958,7 @@ void int_array_sort_unique(int *a)
void int_array_add_unique(int **res, int a)
{
- int reslen;
+ size_t reslen, max_size;
int *n;
for (reslen = 0; *res && (*res)[reslen]; reslen++) {
@@ -952,6 +966,16 @@ void int_array_add_unique(int **res, int a)
return; /* already in the list */
}
+ max_size = (size_t) -1;
+ if (reslen > max_size - 2) {
+ /* This should not really happen in practice, but if it did,
+ * something would overflow. Do not try to add the new value;
+ * instead, make this behave like memory allocation failure to
+ * avoid messing up memory. */
+ os_free(*res);
+ *res = NULL;
+ return;
+ }
n = os_realloc_array(*res, reslen + 2, sizeof(int));
if (n == NULL) {
os_free(*res);
diff --git a/src/utils/common.h b/src/utils/common.h
index 833469a..8e5cfe1 100644
--- a/src/utils/common.h
+++ b/src/utils/common.h
@@ -547,7 +547,7 @@ int freq_range_list_includes(const struct wpa_freq_range_list *list,
unsigned int freq);
char * freq_range_list_str(const struct wpa_freq_range_list *list);
-int int_array_len(const int *a);
+size_t int_array_len(const int *a);
void int_array_concat(int **res, const int *a);
void int_array_sort_unique(int *a);
void int_array_add_unique(int **res, int a);
diff --git a/src/utils/eloop.c b/src/utils/eloop.c
index bb375be..b353ab0 100644
--- a/src/utils/eloop.c
+++ b/src/utils/eloop.c
@@ -68,7 +68,7 @@ struct eloop_signal {
};
struct eloop_sock_table {
- int count;
+ size_t count;
struct eloop_sock *table;
eloop_event_type type;
int changed;
@@ -77,10 +77,10 @@ struct eloop_sock_table {
struct eloop_data {
int max_sock;
- int count; /* sum of all table counts */
+ size_t count; /* sum of all table counts */
#ifdef CONFIG_ELOOP_POLL
- int max_pollfd_map; /* number of pollfds_map currently allocated */
- int max_poll_fds; /* number of pollfds currently allocated */
+ size_t max_pollfd_map; /* number of pollfds_map currently allocated */
+ size_t max_poll_fds; /* number of pollfds currently allocated */
struct pollfd *pollfds;
struct pollfd **pollfds_map;
#endif /* CONFIG_ELOOP_POLL */
@@ -90,12 +90,12 @@ struct eloop_data {
#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
#ifdef CONFIG_ELOOP_EPOLL
int epollfd;
- int epoll_max_event_num;
+ size_t epoll_max_event_num;
struct epoll_event *epoll_events;
#endif /* CONFIG_ELOOP_EPOLL */
#ifdef CONFIG_ELOOP_KQUEUE
int kqueuefd;
- int kqueue_nevents;
+ size_t kqueue_nevents;
struct kevent *kqueue_events;
#endif /* CONFIG_ELOOP_KQUEUE */
struct eloop_sock_table readers;
@@ -104,7 +104,7 @@ struct eloop_data {
struct dl_list timeout;
- int signal_count;
+ size_t signal_count;
struct eloop_signal *signals;
int signaled;
int pending_terminate;
@@ -125,7 +125,8 @@ static void eloop_sigsegv_handler(int sig)
static void eloop_trace_sock_add_ref(struct eloop_sock_table *table)
{
- int i;
+ size_t i;
+
if (table == NULL || table->table == NULL)
return;
for (i = 0; i < table->count; i++) {
@@ -139,7 +140,8 @@ static void eloop_trace_sock_add_ref(struct eloop_sock_table *table)
static void eloop_trace_sock_remove_ref(struct eloop_sock_table *table)
{
- int i;
+ size_t i;
+
if (table == NULL || table->table == NULL)
return;
for (i = 0; i < table->count; i++) {
@@ -266,7 +268,7 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
#endif /* CONFIG_ELOOP_EPOLL */
#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
struct eloop_sock *temp_table;
- int next;
+ size_t next;
#endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */
struct eloop_sock *tmp;
int new_max_sock;
@@ -280,7 +282,7 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
return -1;
#ifdef CONFIG_ELOOP_POLL
- if (new_max_sock >= eloop.max_pollfd_map) {
+ if ((size_t) new_max_sock >= eloop.max_pollfd_map) {
struct pollfd **nmap;
nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50,
sizeof(struct pollfd *));
@@ -293,7 +295,8 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
if (eloop.count + 1 > eloop.max_poll_fds) {
struct pollfd *n;
- int nmax = eloop.count + 1 + 50;
+ size_t nmax = eloop.count + 1 + 50;
+
n = os_realloc_array(eloop.pollfds, nmax,
sizeof(struct pollfd));
if (n == NULL)
@@ -385,7 +388,7 @@ static void eloop_sock_table_remove_sock(struct eloop_sock_table *table,
#ifdef CONFIG_ELOOP_KQUEUE
struct kevent ke;
#endif /* CONFIG_ELOOP_KQUEUE */
- int i;
+ size_t i;
if (table == NULL || table->table == NULL || table->count == 0)
return;
@@ -444,7 +447,7 @@ static int eloop_sock_table_set_fds(struct eloop_sock_table *readers,
struct pollfd **pollfds_map,
int max_pollfd_map)
{
- int i;
+ size_t i;
int nxt = 0;
int fd;
struct pollfd *pfd;
@@ -519,7 +522,7 @@ static int eloop_sock_table_dispatch_table(struct eloop_sock_table *table,
int max_pollfd_map,
short int revents)
{
- int i;
+ size_t i;
struct pollfd *pfd;
if (!table || !table->table)
@@ -572,7 +575,7 @@ static void eloop_sock_table_dispatch(struct eloop_sock_table *readers,
static void eloop_sock_table_set_fds(struct eloop_sock_table *table,
fd_set *fds)
{
- int i;
+ size_t i;
FD_ZERO(fds);
@@ -589,7 +592,7 @@ static void eloop_sock_table_set_fds(struct eloop_sock_table *table,
static void eloop_sock_table_dispatch(struct eloop_sock_table *table,
fd_set *fds)
{
- int i;
+ size_t i;
if (table == NULL || table->table == NULL)
return;
@@ -653,7 +656,8 @@ static void eloop_sock_table_dispatch(struct kevent *events, int nfds)
static int eloop_sock_table_requeue(struct eloop_sock_table *table)
{
- int i, r;
+ size_t i;
+ int r;
r = 0;
for (i = 0; i < table->count && table->table; i++) {
@@ -694,7 +698,8 @@ int eloop_sock_requeue(void)
static void eloop_sock_table_destroy(struct eloop_sock_table *table)
{
if (table) {
- int i;
+ size_t i;
+
for (i = 0; i < table->count && table->table; i++) {
wpa_printf(MSG_INFO, "ELOOP: remaining socket: "
"sock=%d eloop_data=%p user_data=%p "
@@ -968,7 +973,7 @@ static void eloop_handle_alarm(int sig)
static void eloop_handle_signal(int sig)
{
- int i;
+ size_t i;
#ifndef CONFIG_NATIVE_WINDOWS
if ((sig == SIGINT || sig == SIGTERM) && !eloop.pending_terminate) {
@@ -992,7 +997,7 @@ static void eloop_handle_signal(int sig)
static void eloop_process_pending_signals(void)
{
- int i;
+ size_t i;
if (eloop.signaled == 0)
return;
diff --git a/src/utils/eloop_win.c b/src/utils/eloop_win.c
index 9c8b12b..74eaa33 100644
--- a/src/utils/eloop_win.c
+++ b/src/utils/eloop_win.c
@@ -54,7 +54,7 @@ struct eloop_data {
struct dl_list timeout;
- int signal_count;
+ size_t signal_count;
struct eloop_signal *signals;
int signaled;
int pending_terminate;
@@ -422,7 +422,7 @@ int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs,
#if 0
static void eloop_handle_signal(int sig)
{
- int i;
+ size_t i;
eloop.signaled++;
for (i = 0; i < eloop.signal_count; i++) {
@@ -437,7 +437,7 @@ static void eloop_handle_signal(int sig)
static void eloop_process_pending_signals(void)
{
- int i;
+ size_t i;
if (eloop.signaled == 0)
return;
@@ -517,7 +517,7 @@ int eloop_register_signal_terminate(eloop_signal_handler handler,
eloop.term_signal.handler = handler;
eloop.term_signal.user_data = user_data;
-
+
return 0;
}
diff --git a/src/utils/http-utils.h b/src/utils/http-utils.h
index 8d4399a..d9fc925 100644
--- a/src/utils/http-utils.h
+++ b/src/utils/http-utils.h
@@ -28,11 +28,11 @@ struct http_logo {
struct http_cert {
char **dnsname;
- unsigned int num_dnsname;
+ size_t num_dnsname;
struct http_othername *othername;
- unsigned int num_othername;
+ size_t num_othername;
struct http_logo *logo;
- unsigned int num_logo;
+ size_t num_logo;
};
int soap_init_client(struct http_ctx *ctx, const char *address,
diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c
index dd504f3..6f0c177 100644
--- a/src/utils/os_unix.c
+++ b/src/utils/os_unix.c
@@ -337,6 +337,8 @@ char * os_rel2abs_path(const char *rel_path)
int os_program_init(void)
{
+ unsigned int seed;
+
#ifdef ANDROID
/*
* We ignore errors here since errors are normal if we
@@ -365,6 +367,9 @@ int os_program_init(void)
capset(&header, &cap);
#endif /* ANDROID */
+ if (os_get_random((unsigned char *) &seed, sizeof(seed)) == 0)
+ srandom(seed);
+
return 0;
}
diff --git a/src/utils/utils_module_tests.c b/src/utils/utils_module_tests.c
index f75d406..365f21f 100644
--- a/src/utils/utils_module_tests.c
+++ b/src/utils/utils_module_tests.c
@@ -226,7 +226,7 @@ static int int_array_tests(void)
int test3[] = { 1, 1, 1, -1, 2, 3, 4, 1, 2, 0 };
int test3_res[] = { -1, 1, 2, 3, 4, 0 };
int errors = 0;
- int len;
+ size_t len;
wpa_printf(MSG_INFO, "int_array tests");
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 3b56da7..93888b0 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -395,11 +395,6 @@ struct wps_registrar_config {
int disable_auto_conf;
/**
- * static_wep_only - Whether the BSS supports only static WEP
- */
- int static_wep_only;
-
- /**
* dualband - Whether this is a concurrent dualband AP
*/
int dualband;
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index fb6c71d..9ee89ae 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -173,7 +173,6 @@ struct wps_registrar {
int sel_reg_union;
int sel_reg_dev_password_id_override;
int sel_reg_config_methods_override;
- int static_wep_only;
int dualband;
int force_per_enrollee_psk;
@@ -697,7 +696,6 @@ wps_registrar_init(struct wps_context *wps,
reg->disable_auto_conf = cfg->disable_auto_conf;
reg->sel_reg_dev_password_id_override = -1;
reg->sel_reg_config_methods_override = -1;
- reg->static_wep_only = cfg->static_wep_only;
reg->dualband = cfg->dualband;
reg->force_per_enrollee_psk = cfg->force_per_enrollee_psk;
@@ -1390,28 +1388,6 @@ static int wps_set_ie(struct wps_registrar *reg)
return -1;
}
- if (reg->static_wep_only) {
- /*
- * Windows XP and Vista clients can get confused about
- * EAP-Identity/Request when they probe the network with
- * EAPOL-Start. In such a case, they may assume the network is
- * using IEEE 802.1X and prompt user for a certificate while
- * the correct (non-WPS) behavior would be to ask for the
- * static WEP key. As a workaround, use Microsoft Provisioning
- * IE to advertise that legacy 802.1X is not supported.
- */
- const u8 ms_wps[7] = {
- WLAN_EID_VENDOR_SPECIFIC, 5,
- /* Microsoft Provisioning IE (00:50:f2:5) */
- 0x00, 0x50, 0xf2, 5,
- 0x00 /* no legacy 802.1X or MS WPS */
- };
- wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
- "into Beacon/Probe Response frames");
- wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
- wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
- }
-
return wps_cb_set_ie(reg, beacon, probe);
}
@@ -3502,6 +3478,7 @@ static void wps_registrar_set_selected_timeout(void *eloop_ctx,
"unselect internal Registrar");
reg->selected_registrar = 0;
reg->pbc = 0;
+ wps_registrar_expire_pins(reg);
wps_registrar_selected_registrar_changed(reg, 0);
}
diff --git a/tests/fuzzing/dpp-uri/Makefile b/tests/fuzzing/dpp-uri/Makefile
new file mode 100644
index 0000000..27b2fdd
--- /dev/null
+++ b/tests/fuzzing/dpp-uri/Makefile
@@ -0,0 +1,33 @@
+all: dpp-uri
+include ../rules.include
+
+CFLAGS += -DCONFIG_DPP
+CFLAGS += -DCONFIG_DPP2
+CFLAGS += -DCONFIG_SHA256
+CFLAGS += -DCONFIG_SHA384
+CFLAGS += -DCONFIG_SHA512
+CFLAGS += -DCONFIG_ECC
+CFLAGS += -DCONFIG_OPENSSL_CMAC
+
+LIBS += $(SRC)/common/libcommon.a
+LIBS += $(SRC)/utils/libutils.a
+
+OBJS += $(SRC)/crypto/crypto_openssl.o
+LIBS += -lcrypto
+
+OBJS += $(SRC)/crypto/aes-ctr.o
+OBJS += $(SRC)/crypto/aes-siv.o
+OBJS += $(SRC)/crypto/sha256-kdf.o
+OBJS += $(SRC)/crypto/sha384-kdf.o
+OBJS += $(SRC)/crypto/sha512-kdf.o
+OBJS += $(SRC)/tls/asn1.o
+OBJS += $(SRC)/common/dpp.o
+
+dpp-uri: dpp-uri.o $(OBJS) $(LIBS)
+ $(LDO) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+ $(MAKE) -C $(SRC) clean
+ rm -f dpp-uri *~ *.o *.d ../*~ ../*.o ../*.d
+
+-include $(OBJS:%.o=%.d)
diff --git a/tests/fuzzing/dpp-uri/corpus/1.dat b/tests/fuzzing/dpp-uri/corpus/1.dat
new file mode 100644
index 0000000..b2387e0
--- /dev/null
+++ b/tests/fuzzing/dpp-uri/corpus/1.dat
@@ -0,0 +1 @@
+DPP:K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;; \ No newline at end of file
diff --git a/tests/fuzzing/dpp-uri/corpus/2.dat b/tests/fuzzing/dpp-uri/corpus/2.dat
new file mode 100644
index 0000000..ee2ff90
--- /dev/null
+++ b/tests/fuzzing/dpp-uri/corpus/2.dat
@@ -0,0 +1 @@
+DPP:C:81/1,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;; \ No newline at end of file
diff --git a/tests/fuzzing/dpp-uri/corpus/3.dat b/tests/fuzzing/dpp-uri/corpus/3.dat
new file mode 100644
index 0000000..ce7ad16
--- /dev/null
+++ b/tests/fuzzing/dpp-uri/corpus/3.dat
@@ -0,0 +1 @@
+DPP:I:SN=4774LH2b4044;M:010203040506;C:81/1,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;; \ No newline at end of file
diff --git a/tests/fuzzing/dpp-uri/dpp-uri.c b/tests/fuzzing/dpp-uri/dpp-uri.c
new file mode 100644
index 0000000..77db5b8
--- /dev/null
+++ b/tests/fuzzing/dpp-uri/dpp-uri.c
@@ -0,0 +1,51 @@
+/*
+ * DPP URI fuzzer
+ * Copyright (c) 2020, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "common/dpp.h"
+#include "../fuzzer-common.h"
+
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ struct dpp_global *dpp;
+ struct dpp_global_config config;
+ struct dpp_bootstrap_info *bi;
+ char *uri;
+ char buf[1000];
+ int ret = -1;
+
+ wpa_fuzzer_set_debug_level();
+
+ if (os_program_init())
+ return 0;
+
+ uri = os_malloc(size + 1);
+ if (!uri)
+ goto out;
+ os_memcpy(uri, data, size);
+ uri[size] = '\0';
+ os_memset(&config, 0, sizeof(config));
+ dpp = dpp_global_init(&config);
+ if (!dpp)
+ goto out;
+
+ bi = dpp_add_qr_code(dpp, uri);
+ if (bi && dpp_bootstrap_info(dpp, bi->id, buf, sizeof(buf)) > 0)
+ wpa_printf(MSG_DEBUG, "DPP: %s", buf);
+ dpp_global_deinit(dpp);
+
+ ret = 0;
+out:
+ os_free(uri);
+ os_program_deinit();
+
+ return ret;
+}
diff --git a/tests/fuzzing/eapol-key-auth/eapol-key-auth.c b/tests/fuzzing/eapol-key-auth/eapol-key-auth.c
index a909114..bb46422 100644
--- a/tests/fuzzing/eapol-key-auth/eapol-key-auth.c
+++ b/tests/fuzzing/eapol-key-auth/eapol-key-auth.c
@@ -169,12 +169,13 @@ static void supp_eapol_key_request(void *eloop_data, void *user_ctx)
static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
const u8 *addr, int idx, u8 *key,
- size_t key_len)
+ size_t key_len, enum key_flag key_flag)
{
struct wpa *wpa = ctx;
- wpa_printf(MSG_DEBUG, "AUTH: %s (vlan_id=%d alg=%d idx=%d key_len=%d)",
- __func__, vlan_id, alg, idx, (int) key_len);
+ wpa_printf(MSG_DEBUG,
+ "AUTH: %s (vlan_id=%d alg=%d idx=%d key_len=%d key_flag=0x%x)",
+ __func__, vlan_id, alg, idx, (int) key_len, key_flag);
if (addr)
wpa_printf(MSG_DEBUG, "AUTH: addr=" MACSTR, MAC2STR(addr));
diff --git a/tests/fuzzing/eapol-key-supp/eapol-key-supp.c b/tests/fuzzing/eapol-key-supp/eapol-key-supp.c
index eb565d7..487c889 100644
--- a/tests/fuzzing/eapol-key-supp/eapol-key-supp.c
+++ b/tests/fuzzing/eapol-key-supp/eapol-key-supp.c
@@ -175,11 +175,11 @@ static int supp_get_beacon_ie(void *ctx)
static int supp_set_key(void *ctx, enum wpa_alg alg,
const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
+ const u8 *key, size_t key_len, enum key_flag key_flag)
{
wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d "
- "set_tx=%d)",
- __func__, alg, MAC2STR(addr), key_idx, set_tx);
+ "set_tx=%d key_flag=0x%x)",
+ __func__, alg, MAC2STR(addr), key_idx, set_tx, key_flag);
wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len);
wpa_hexdump(MSG_DEBUG, "SUPP: set_key - key", key, key_len);
return 0;
diff --git a/tests/fuzzing/sae/Makefile b/tests/fuzzing/sae/Makefile
new file mode 100644
index 0000000..0a56e06
--- /dev/null
+++ b/tests/fuzzing/sae/Makefile
@@ -0,0 +1,24 @@
+all: sae
+include ../rules.include
+
+CFLAGS += -DCONFIG_SHA256
+CFLAGS += -DCONFIG_ECC
+
+LIBS += $(SRC)/common/libcommon.a
+LIBS += $(SRC)/utils/libutils.a
+
+OBJS += $(SRC)/crypto/crypto_openssl.o
+LIBS += -lcrypto
+OBJS += $(SRC)/crypto/dh_groups.o
+OBJS += $(SRC)/crypto/sha256-prf.o
+OBJS += $(SRC)/crypto/sha256-kdf.o
+OBJS += $(SRC)/common/dragonfly.o
+
+sae: sae.o $(OBJS) $(LIBS)
+ $(LDO) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+ $(MAKE) -C $(SRC) clean
+ rm -f sae *~ *.o *.d ../*~ ../*.o ../*.d
+
+-include $(OBJS:%.o=%.d)
diff --git a/tests/fuzzing/sae/corpus/sae-commit-h2e-rejected-groups.dat b/tests/fuzzing/sae/corpus/sae-commit-h2e-rejected-groups.dat
new file mode 100644
index 0000000..cd129a4
--- /dev/null
+++ b/tests/fuzzing/sae/corpus/sae-commit-h2e-rejected-groups.dat
Binary files differ
diff --git a/tests/fuzzing/sae/corpus/sae-commit-h2e-token.dat b/tests/fuzzing/sae/corpus/sae-commit-h2e-token.dat
new file mode 100644
index 0000000..b2886c7
--- /dev/null
+++ b/tests/fuzzing/sae/corpus/sae-commit-h2e-token.dat
Binary files differ
diff --git a/tests/fuzzing/sae/corpus/sae-commit-pw-id.dat b/tests/fuzzing/sae/corpus/sae-commit-pw-id.dat
new file mode 100644
index 0000000..5ca903e
--- /dev/null
+++ b/tests/fuzzing/sae/corpus/sae-commit-pw-id.dat
Binary files differ
diff --git a/tests/fuzzing/sae/corpus/sae-commit-token.dat b/tests/fuzzing/sae/corpus/sae-commit-token.dat
new file mode 100644
index 0000000..b25cc49
--- /dev/null
+++ b/tests/fuzzing/sae/corpus/sae-commit-token.dat
Binary files differ
diff --git a/tests/fuzzing/sae/corpus/sae-commit-valid.dat b/tests/fuzzing/sae/corpus/sae-commit-valid.dat
new file mode 100644
index 0000000..eadfa49
--- /dev/null
+++ b/tests/fuzzing/sae/corpus/sae-commit-valid.dat
Binary files differ
diff --git a/tests/fuzzing/sae/sae.c b/tests/fuzzing/sae/sae.c
new file mode 100644
index 0000000..8819a4a
--- /dev/null
+++ b/tests/fuzzing/sae/sae.c
@@ -0,0 +1,39 @@
+/*
+ * SAE fuzzer
+ * Copyright (c) 2020, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "common/sae.h"
+#include "../fuzzer-common.h"
+
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ struct sae_data sae;
+ u16 res;
+ const u8 *token = NULL;
+ size_t token_len = 0;
+ int groups[] = { 19, 0 };
+
+ wpa_fuzzer_set_debug_level();
+
+ if (os_program_init())
+ return 0;
+
+ os_memset(&sae, 0, sizeof(sae));
+ res = sae_parse_commit(&sae, data, size, &token, &token_len, groups, 0);
+ wpa_printf(MSG_DEBUG, "sae_parse_commit(0): %u", res);
+ sae_clear_data(&sae);
+ res = sae_parse_commit(&sae, data, size, &token, &token_len, groups, 1);
+ wpa_printf(MSG_DEBUG, "sae_parse_commit(1): %u", res);
+ sae_clear_data(&sae);
+ os_program_deinit();
+
+ return 0;
+}
diff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config
index 942134a..f1a9adf 100644
--- a/tests/hwsim/example-hostapd.config
+++ b/tests/hwsim/example-hostapd.config
@@ -110,3 +110,4 @@ CONFIG_FILS_SK_PFS=y
CONFIG_OWE=y
CONFIG_DPP=y
CONFIG_DPP2=y
+CONFIG_WEP=y
diff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config
index d494caf..253f329 100644
--- a/tests/hwsim/example-wpa_supplicant.config
+++ b/tests/hwsim/example-wpa_supplicant.config
@@ -153,3 +153,4 @@ CONFIG_PMKSA_CACHE_EXTERNAL=y
CONFIG_OWE=y
CONFIG_DPP=y
CONFIG_DPP2=y
+CONFIG_WEP=y
diff --git a/tests/hwsim/run-tests.py b/tests/hwsim/run-tests.py
index b201cd7..a0bcdf3 100755
--- a/tests/hwsim/run-tests.py
+++ b/tests/hwsim/run-tests.py
@@ -516,6 +516,8 @@ def main():
params = {}
params['logdir'] = args.logdir
params['long'] = args.long
+ params['name'] = name
+ params['prefix'] = os.path.join(args.logdir, name)
t(dev, apdev, params)
elif t.__code__.co_argcount > 1:
t(dev, apdev)
diff --git a/tests/hwsim/test_ap_acs.py b/tests/hwsim/test_ap_acs.py
index fe88d01..ed05c90 100644
--- a/tests/hwsim/test_ap_acs.py
+++ b/tests/hwsim/test_ap_acs.py
@@ -515,3 +515,62 @@ def test_ap_acs_vht160_dfs(dev, apdev, params):
hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00'])
dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
dev[0].flush_scan_cache()
+
+def test_ap_acs_hw_mode_any(dev, apdev):
+ """Automatic channel selection with hw_mode=any"""
+ force_prev_ap_on_24g(apdev[0])
+ params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
+ params['channel'] = '0'
+ params['hw_mode'] = 'any'
+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+ wait_acs(hapd)
+
+ freq = hapd.get_status_field("freq")
+ if int(freq) < 2400:
+ raise Exception("Unexpected frequency")
+
+ dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
+
+def test_ap_acs_hw_mode_any_5ghz(dev, apdev):
+ """Automatic channel selection with hw_mode=any and 5 GHz"""
+ try:
+ hapd = None
+ force_prev_ap_on_5g(apdev[0])
+ params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
+ params['hw_mode'] = 'any'
+ params['channel'] = '0'
+ params['country_code'] = 'US'
+ params['acs_chan_bias'] = '36:0.7 40:0.7 44:0.7 48:0.7'
+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+ wait_acs(hapd)
+ freq = hapd.get_status_field("freq")
+ if int(freq) < 5000:
+ raise Exception("Unexpected frequency")
+
+ dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
+ dev[0].wait_regdom(country_ie=True)
+ finally:
+ clear_regdom(hapd, dev)
+
+def test_ap_acs_with_fallback_to_20(dev, apdev):
+ """Automatic channel selection with fallback to 20 MHz"""
+ force_prev_ap_on_24g(apdev[0])
+ params = {"ssid": "legacy-20",
+ "channel": "7", "ieee80211n": "0"}
+ hostapd.add_ap(apdev[1], params)
+ params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
+ params['channel'] = '0'
+ params['acs_chan_bias'] = '6:0.1'
+ params['ht_capab'] = '[HT40+]'
+ hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+ wait_acs(hapd)
+
+ freq = hapd.get_status_field("freq")
+ if int(freq) < 2400:
+ raise Exception("Unexpected frequency")
+
+ dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
+ sig = dev[0].request("SIGNAL_POLL").splitlines()
+ logger.info("SIGNAL_POLL: " + str(sig))
+ if "WIDTH=20 MHz" not in sig:
+ raise Exception("Station did not report 20 MHz bandwidth")
diff --git a/tests/hwsim/test_ap_config.py b/tests/hwsim/test_ap_config.py
index dc05a48..e93c914 100644
--- a/tests/hwsim/test_ap_config.py
+++ b/tests/hwsim/test_ap_config.py
@@ -429,8 +429,6 @@ def test_ap_config_set_oom(dev, apdev):
tests = [(1, "hostapd_parse_das_client",
"SET radius_das_client 192.168.1.123 pw"),
- (1, "hostapd_config_read_wep", "SET wep_key0 \"hello\""),
- (1, "hostapd_config_read_wep", "SET wep_key0 0102030405"),
(1, "hostapd_parse_chanlist", "SET chanlist 1 6 11-13"),
(1, "hostapd_config_bss", "SET bss foo"),
(2, "hostapd_config_bss", "SET bss foo"),
@@ -486,6 +484,9 @@ def test_ap_config_set_oom(dev, apdev):
(1, "hostapd_parse_intlist", "SET sae_groups 19 25"),
(1, "hostapd_parse_intlist", "SET basic_rates 10 20 55 110"),
(1, "hostapd_parse_intlist", "SET supported_rates 10 20 55 110")]
+ if "WEP40" in dev[0].get_capability("group"):
+ tests += [(1, "hostapd_config_read_wep", "SET wep_key0 \"hello\""),
+ (1, "hostapd_config_read_wep", "SET wep_key0 0102030405")]
for count, func, cmd in tests:
with alloc_fail(hapd, count, func):
if "FAIL" not in hapd.request(cmd):
@@ -533,14 +534,15 @@ def test_ap_config_set_oom(dev, apdev):
def test_ap_config_set_errors(dev, apdev):
"""hostapd configuration parsing errors"""
hapd = hostapd.add_ap(apdev[0], {"ssid": "foobar"})
- hapd.set("wep_key0", '"hello"')
- hapd.set("wep_key1", '"hello"')
- hapd.set("wep_key0", '')
- hapd.set("wep_key0", '"hello"')
- if "FAIL" not in hapd.request("SET wep_key1 \"hello\""):
- raise Exception("SET wep_key1 allowed to override existing key")
- hapd.set("wep_key1", '')
- hapd.set("wep_key1", '"hello"')
+ if "WEP40" in dev[0].get_capability("group"):
+ hapd.set("wep_key0", '"hello"')
+ hapd.set("wep_key1", '"hello"')
+ hapd.set("wep_key0", '')
+ hapd.set("wep_key0", '"hello"')
+ if "FAIL" not in hapd.request("SET wep_key1 \"hello\""):
+ raise Exception("SET wep_key1 allowed to override existing key")
+ hapd.set("wep_key1", '')
+ hapd.set("wep_key1", '"hello"')
hapd.set("auth_server_addr", "127.0.0.1")
hapd.set("acct_server_addr", "127.0.0.1")
diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py
index bdfe961..026b995 100644
--- a/tests/hwsim/test_ap_eap.py
+++ b/tests/hwsim/test_ap_eap.py
@@ -7314,3 +7314,38 @@ def test_ap_wpa2_eap_sake_no_control_port(dev, apdev):
eap_connect(wpas, hapd, "SAKE", "sake user",
password_hex="ff23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
expect_failure=True)
+
+def test_ap_wpa3_eap_transition_disable(dev, apdev):
+ """WPA3-Enterprise transition disable indication"""
+ params = hostapd.wpa2_eap_params(ssid="test-wpa3-eap")
+ params["ieee80211w"] = "1"
+ params['transition_disable'] = '0x04'
+ hapd = hostapd.add_ap(apdev[0], params)
+ id = dev[0].connect("test-wpa3-eap", key_mgmt="WPA-EAP", ieee80211w="1",
+ proto="WPA WPA2", pairwise="CCMP", group="TKIP CCMP",
+ eap="GPSK", identity="gpsk user",
+ password="abcdefghijklmnop0123456789abcdef",
+ scan_freq="2412")
+ ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=1)
+ if ev is None:
+ raise Exception("Transition disable not indicated")
+ if ev.split(' ')[1] != "04":
+ raise Exception("Unexpected transition disable bitmap: " + ev)
+
+ val = dev[0].get_network(id, "ieee80211w")
+ if val != "2":
+ raise Exception("Unexpected ieee80211w value: " + val)
+ val = dev[0].get_network(id, "key_mgmt")
+ if val != "WPA-EAP":
+ raise Exception("Unexpected key_mgmt value: " + val)
+ val = dev[0].get_network(id, "group")
+ if val != "CCMP":
+ raise Exception("Unexpected group value: " + val)
+ val = dev[0].get_network(id, "proto")
+ if val != "RSN":
+ raise Exception("Unexpected proto value: " + val)
+
+ dev[0].request("DISCONNECT")
+ dev[0].wait_disconnected()
+ dev[0].request("RECONNECT")
+ dev[0].wait_connected()
diff --git a/tests/hwsim/test_ap_ft.py b/tests/hwsim/test_ap_ft.py
index e28ddd5..a7a7171 100644
--- a/tests/hwsim/test_ap_ft.py
+++ b/tests/hwsim/test_ap_ft.py
@@ -18,7 +18,7 @@ import hwsim_utils
from hwsim import HWSimRadio
import hostapd
from tshark import run_tshark
-from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger, skip_with_fips, parse_ie
+from utils import *
from wlantest import Wlantest
from test_ap_psk import check_mib, find_wpas_process, read_process_memory, verify_not_present, get_key_locations
from test_rrm import check_beacon_req
@@ -675,7 +675,7 @@ def run_ap_ft_separate_hostapd(dev, apdev, params, over_ds):
hapd1 = hostapd.add_ap(apdev2[1], params)
run_roams(dev[0], apdev2, hapd0, hapd1, ssid, passphrase,
- over_ds=over_ds, test_connectivity=False)
+ over_ds=over_ds, test_connectivity=False, roams=2)
hglobal.terminate()
@@ -993,7 +993,10 @@ def test_ap_ft_over_ds_pull_vlan(dev, apdev):
if filename.startswith('/tmp/'):
os.unlink(filename)
-def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None):
+def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None,
+ rsne_override=None, rsnxe_override=None,
+ no_beacon_rsnxe2=False, ext_key_id=False,
+ skip_prune_assoc=False):
if "SAE" not in dev.get_capability("auth_alg"):
raise HwsimSkip("SAE not supported")
ssid = "test-ft"
@@ -1005,6 +1008,14 @@ def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None):
params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
if sae_pwe is not None:
params['sae_pwe'] = sae_pwe
+ if rsne_override:
+ params['rsne_override_ft'] = rsne_override
+ if rsnxe_override:
+ params['rsnxe_override_ft'] = rsnxe_override
+ if ext_key_id:
+ params['extended_key_id'] = '1'
+ if skip_prune_assoc:
+ params['skip_prune_assoc'] = '1'
hapd0 = hostapd.add_ap(apdev[0], params)
params = ft_params2(ssid=ssid, passphrase=passphrase)
params['wpa_key_mgmt'] = "FT-SAE"
@@ -1012,6 +1023,16 @@ def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None):
params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
if sae_pwe is not None:
params['sae_pwe'] = sae_pwe
+ if rsne_override:
+ params['rsne_override_ft'] = rsne_override
+ if rsnxe_override:
+ params['rsnxe_override_ft'] = rsnxe_override
+ if no_beacon_rsnxe2:
+ params['no_beacon_rsnxe'] = "1"
+ if ext_key_id:
+ params['extended_key_id'] = '1'
+ if skip_prune_assoc:
+ params['skip_prune_assoc'] = '1'
hapd1 = hostapd.add_ap(apdev[1], params)
key_mgmt = hapd1.get_config()['key_mgmt']
if key_mgmt.split(' ')[0] != "FT-SAE":
@@ -1040,6 +1061,32 @@ def test_ap_ft_sae_h2e_and_loop(dev, apdev):
hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2")
run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
+def test_ap_ft_sae_h2e_and_loop2(dev, apdev):
+ """WPA2-PSK-FT-SAE AP (AP loop, STA H2E)"""
+ try:
+ dev[0].set("sae_pwe", "2")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="0")
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
+ finally:
+ dev[0].set("sae_pwe", "0")
+
+def test_ap_ft_sae_h2e_downgrade_attack(dev, apdev):
+ """WPA2-PSK-FT-SAE AP (H2E downgrade attack)"""
+ try:
+ dev[0].set("sae_pwe", "2")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
+ no_beacon_rsnxe2=True)
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
+ force_initial_conn_to_first_ap=True,
+ return_after_initial=True)
+ dev[0].scan_for_bss(hapd1.own_addr(), freq="2412")
+ dev[0].request("ROAM " + hapd1.own_addr())
+ ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
+ if ev is None:
+ raise Exception("Association not rejected")
+ finally:
+ dev[0].set("sae_pwe", "0")
+
def test_ap_ft_sae_ptk_rekey0(dev, apdev):
"""WPA2-PSK-FT-SAE AP and PTK rekey triggered by station"""
hapd0, hapd1 = start_ft_sae(dev[0], apdev)
@@ -1061,6 +1108,24 @@ def test_ap_ft_sae_ptk_rekey_ap(dev, apdev):
only_one_way=True)
check_ptk_rekey(dev[0], hapd0, hapd1)
+def test_ap_ft_sae_ptk_rekey_ap_ext_key_id(dev, apdev):
+ """WPA2-PSK-FT-SAE AP and PTK rekey triggered by AP (Ext Key ID)"""
+ check_ext_key_id_capa(dev[0])
+ try:
+ dev[0].set("extended_key_id", "1")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, wpa_ptk_rekey=2,
+ ext_key_id=True)
+ check_ext_key_id_capa(hapd0)
+ check_ext_key_id_capa(hapd1)
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
+ only_one_way=True)
+ check_ptk_rekey(dev[0], hapd0, hapd1)
+ idx = int(dev[0].request("GET last_tk_key_idx"))
+ if idx != 1:
+ raise Exception("Unexpected Key ID after TK rekey: %d" % idx)
+ finally:
+ dev[0].set("extended_key_id", "0")
+
def test_ap_ft_sae_over_ds(dev, apdev):
"""WPA2-PSK-FT-SAE AP over DS"""
hapd0, hapd1 = start_ft_sae(dev[0], apdev)
@@ -1088,6 +1153,59 @@ def test_ap_ft_sae_over_ds_ptk_rekey_ap(dev, apdev):
over_ds=True, only_one_way=True)
check_ptk_rekey(dev[0], hapd0, hapd1)
+def test_ap_ft_sae_h2e_rsne_override(dev, apdev):
+ """WPA2-PSK-FT-SAE AP (H2E) and RSNE override (same value)"""
+ try:
+ dev[0].set("sae_pwe", "2")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
+ rsne_override="30260100000fac040100000fac040100000fac090c000100" + 16*"ff")
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
+ finally:
+ dev[0].set("sae_pwe", "0")
+
+def test_ap_ft_sae_h2e_rsnxe_override(dev, apdev):
+ """WPA2-PSK-FT-SAE AP (H2E) and RSNXE override (same value)"""
+ try:
+ dev[0].set("sae_pwe", "2")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
+ rsnxe_override="F40120")
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
+ finally:
+ dev[0].set("sae_pwe", "0")
+
+def test_ap_ft_sae_h2e_rsne_mismatch(dev, apdev):
+ """WPA2-PSK-FT-SAE AP (H2E) and RSNE mismatch"""
+ try:
+ dev[0].set("sae_pwe", "2")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
+ rsne_override="30260100000fac040100000fac040100000fac090c010100" + 16*"ff")
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
+ fail_test=True)
+ finally:
+ dev[0].set("sae_pwe", "0")
+
+def test_ap_ft_sae_h2e_rsne_mismatch_pmkr1name(dev, apdev):
+ """WPA2-PSK-FT-SAE AP (H2E) and RSNE mismatch in PMKR1Name"""
+ try:
+ dev[0].set("sae_pwe", "2")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
+ rsne_override="30260100000fac040100000fac040100000fac090c000100" + 16*"00")
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
+ fail_test=True)
+ finally:
+ dev[0].set("sae_pwe", "0")
+
+def test_ap_ft_sae_h2e_rsnxe_mismatch(dev, apdev):
+ """WPA2-PSK-FT-SAE AP (H2E) and RSNXE mismatch"""
+ try:
+ dev[0].set("sae_pwe", "2")
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_pwe="2",
+ rsnxe_override="F40160")
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True,
+ fail_test=True)
+ finally:
+ dev[0].set("sae_pwe", "0")
+
def test_ap_ft_sae_pw_id(dev, apdev):
"""FT-SAE with Password Identifier"""
if "SAE" not in dev[0].get_capability("auth_alg"):
@@ -1906,7 +2024,7 @@ def test_ap_ft_oom(dev, apdev):
"""WPA2-PSK-FT and OOM"""
dst = setup_ap_ft_oom(dev, apdev)
with alloc_fail(dev[0], 1, "wpa_ft_gen_req_ies"):
- dev[0].roam(dst)
+ dev[0].roam(dst, check_bssid=False, fail_test=True)
def test_ap_ft_oom2(dev, apdev):
"""WPA2-PSK-FT and OOM (2)"""
@@ -1949,7 +2067,7 @@ def test_ap_ft_ap_oom(dev, apdev):
bssid1 = hapd1.own_addr()
dev[0].scan_for_bss(bssid1, freq="2412")
# This roam will fail due to missing PMK-R0 (OOM prevented storing it)
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
def test_ap_ft_ap_oom2(dev, apdev):
"""WPA2-PSK-FT and AP OOM 2"""
@@ -1994,15 +2112,15 @@ def test_ap_ft_ap_oom3(dev, apdev):
dev[0].scan_for_bss(bssid1, freq="2412")
with alloc_fail(hapd1, 1, "wpa_ft_pull_pmk_r1"):
# This will fail due to not being able to send out PMK-R1 pull request
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
with fail_test(hapd1, 2, "os_get_random;wpa_ft_pull_pmk_r1"):
# This will fail due to not being able to send out PMK-R1 pull request
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
with fail_test(hapd1, 2, "aes_siv_encrypt;wpa_ft_pull_pmk_r1"):
# This will fail due to not being able to send out PMK-R1 pull request
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
def test_ap_ft_ap_oom3b(dev, apdev):
"""WPA2-PSK-FT and AP OOM 3b"""
@@ -2076,23 +2194,23 @@ def test_ap_ft_ap_oom5(dev, apdev):
dev[0].scan_for_bss(bssid1, freq="2412")
with alloc_fail(hapd1, 1, "=wpa_ft_process_auth_req"):
# This will fail to roam
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
with fail_test(hapd1, 1, "os_get_random;wpa_ft_process_auth_req"):
# This will fail to roam
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
# This will fail to roam
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
# This will fail to roam
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
with fail_test(hapd1, 1, "wpa_derive_pmk_r1_name;wpa_ft_process_auth_req"):
# This will fail to roam
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
def test_ap_ft_ap_oom6(dev, apdev):
"""WPA2-PSK-FT and AP OOM 6"""
@@ -2231,10 +2349,10 @@ def test_ap_ft_ap_oom8(dev, apdev):
dev[0].scan_for_bss(bssid1, freq="2412")
with fail_test(hapd1, 1, "wpa_derive_pmk_r0;wpa_ft_psk_pmk_r1"):
# This will fail to roam
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
with fail_test(hapd1, 1, "wpa_derive_pmk_r1;wpa_ft_psk_pmk_r1"):
# This will fail to roam
- dev[0].roam(bssid1)
+ dev[0].roam(bssid1, check_bssid=False)
def test_ap_ft_ap_oom9(dev, apdev):
"""WPA2-PSK-FT and AP OOM 9"""
@@ -3181,3 +3299,55 @@ def test_ap_ft_r0_key_expiration(dev, apdev):
dev[0].dump_monitor()
dev[0].request("RECONNECT")
dev[0].wait_connected()
+
+def test_ap_ft_no_full_ap_client_state(dev, apdev):
+ """WPA2-PSK-FT AP with full_ap_client_state=0"""
+ run_ap_ft_skip_prune_assoc(dev, apdev, False, False)
+
+def test_ap_ft_skip_prune_assoc(dev, apdev):
+ """WPA2-PSK-FT AP with skip_prune_assoc"""
+ run_ap_ft_skip_prune_assoc(dev, apdev, True, True)
+
+def test_ap_ft_skip_prune_assoc2(dev, apdev):
+ """WPA2-PSK-FT AP with skip_prune_assoc (disable full_ap_client_state)"""
+ run_ap_ft_skip_prune_assoc(dev, apdev, True, False, test_connectivity=False)
+
+def test_ap_ft_skip_prune_assoc_pmf(dev, apdev):
+ """WPA2-PSK-FT/PMF AP with skip_prune_assoc"""
+ run_ap_ft_skip_prune_assoc(dev, apdev, True, True, pmf=True)
+
+def test_ap_ft_skip_prune_assoc_pmf_over_ds(dev, apdev):
+ """WPA2-PSK-FT/PMF AP with skip_prune_assoc (over DS)"""
+ run_ap_ft_skip_prune_assoc(dev, apdev, True, True, pmf=True, over_ds=True)
+
+def run_ap_ft_skip_prune_assoc(dev, apdev, skip_prune_assoc,
+ full_ap_client_state, test_connectivity=True,
+ pmf=False, over_ds=False):
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ if skip_prune_assoc:
+ params['skip_prune_assoc'] = '1'
+ if not full_ap_client_state:
+ params['driver_params'] = "full_ap_client_state=0"
+ if pmf:
+ params["ieee80211w"] = "2"
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ if skip_prune_assoc:
+ params['skip_prune_assoc'] = '1'
+ if not full_ap_client_state:
+ params['driver_params'] = "full_ap_client_state=0"
+ if pmf:
+ params["ieee80211w"] = "2"
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
+ ieee80211w="2" if pmf else "0",
+ over_ds=over_ds, test_connectivity=test_connectivity)
+
+def test_ap_ft_sae_skip_prune_assoc(dev, apdev):
+ """WPA2-PSK-FT-SAE AP with skip_prune_assoc"""
+ hapd0, hapd1 = start_ft_sae(dev[0], apdev, skip_prune_assoc=True)
+ run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
diff --git a/tests/hwsim/test_ap_hs20.py b/tests/hwsim/test_ap_hs20.py
index 374ba22..a8dac6b 100644
--- a/tests/hwsim/test_ap_hs20.py
+++ b/tests/hwsim/test_ap_hs20.py
@@ -2662,8 +2662,9 @@ def test_ap_hs20_osen(dev, apdev):
dev[1].connect("osen", key_mgmt="NONE", scan_freq="2412",
wait_connect=False)
- dev[2].connect("osen", key_mgmt="NONE", wep_key0='"hello"',
- scan_freq="2412", wait_connect=False)
+ if "WEP40" in dev[2].get_capability("group"):
+ dev[2].connect("osen", key_mgmt="NONE", wep_key0='"hello"',
+ scan_freq="2412", wait_connect=False)
dev[0].flush_scan_cache()
dev[0].connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
group="GTK_NOT_USED CCMP",
diff --git a/tests/hwsim/test_ap_ht.py b/tests/hwsim/test_ap_ht.py
index 66d30b4..c2b032c 100644
--- a/tests/hwsim/test_ap_ht.py
+++ b/tests/hwsim/test_ap_ht.py
@@ -73,6 +73,18 @@ def test_ap_ht40_scan(dev, apdev):
sta = hapd.get_sta(dev[0].own_addr())
logger.info("hostapd STA: " + str(sta))
+ res = dev[0].request("SIGNAL_POLL")
+ logger.info("STA SIGNAL_POLL:\n" + res.strip())
+ sig = res.splitlines()
+ if "WIDTH=40 MHz" not in sig:
+ raise Exception("Not a 40 MHz connection")
+
+ if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
+ raise Exception("No Supported Operating Classes information for STA")
+ opclass = int(sta['supp_op_classes'][0:2], 16)
+ if opclass != 84:
+ raise Exception("Unexpected Current Operating Class from STA: %d" % opclass)
+
def test_ap_ht_wifi_generation(dev, apdev):
"""HT and wifi_generation"""
clear_scan_cache(apdev[0])
@@ -892,6 +904,13 @@ def test_ap_require_ht(dev, apdev):
ampdu_density="1", disable_ht40="1", disable_sgi="1",
disable_ldpc="1", rx_stbc="2", tx_stbc="1")
+ sta = hapd.get_sta(dev[0].own_addr())
+ if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
+ raise Exception("No Supported Operating Classes information for STA")
+ opclass = int(sta['supp_op_classes'][0:2], 16)
+ if opclass != 81:
+ raise Exception("Unexpected Current Operating Class from STA: %d" % opclass)
+
def test_ap_ht_stbc(dev, apdev):
"""HT STBC overrides"""
params = {"ssid": "ht"}
@@ -1005,7 +1024,10 @@ def test_ap_ht_40mhz_intolerant_ap(dev, apdev):
logger.info("Waiting for co-ex report from STA")
ok = False
- for i in range(0, 20):
+ for i in range(4):
+ ev = dev[0].wait_event(['CTRL-EVENT-SCAN-RESULTS'], timeout=20)
+ if ev is None:
+ raise Exception("No OBSS scan seen")
time.sleep(1)
if hapd.get_status_field("secondary_channel") == "0":
logger.info("AP moved to 20 MHz channel")
@@ -1165,6 +1187,38 @@ def test_ap_ht40_csa3(dev, apdev):
set_world_reg(apdev[0], None, dev[0])
dev[0].flush_scan_cache()
+def test_ap_ht_20_to_40_csa(dev, apdev):
+ """HT with 20 MHz channel width doing CSA to 40 MHz"""
+ csa_supported(dev[0])
+
+ params = {"ssid": "ht",
+ "channel": "1",
+ "ieee80211n": "1"}
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].connect("ht", key_mgmt="NONE", scan_freq="2412")
+ hapd.wait_sta()
+ res = dev[0].request("SIGNAL_POLL")
+ logger.info("SIGNAL_POLL:\n" + res)
+ sig = res.splitlines()
+ if 'WIDTH=20 MHz' not in sig:
+ raise Exception("20 MHz channel bandwidth not used on the original channel")
+
+ hapd.request("CHAN_SWITCH 5 2462 ht sec_channel_offset=-1 bandwidth=40")
+ ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
+ if ev is None:
+ raise Exception("CSA finished event timed out")
+ if "freq=2462" not in ev:
+ raise Exception("Unexpected channel in CSA finished event")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
+ if ev is not None:
+ raise Exception("Unexpected STA disconnection during CSA")
+ res = dev[0].request("SIGNAL_POLL")
+ logger.info("SIGNAL_POLL:\n" + res)
+ sig = res.splitlines()
+ if 'WIDTH=40 MHz' not in sig:
+ raise Exception("40 MHz channel bandwidth not used on the new channel")
+
@remote_compatible
def test_prefer_ht20(dev, apdev):
"""Preference on HT20 over no-HT"""
diff --git a/tests/hwsim/test_ap_params.py b/tests/hwsim/test_ap_params.py
index aa0b281..4c5deb8 100644
--- a/tests/hwsim/test_ap_params.py
+++ b/tests/hwsim/test_ap_params.py
@@ -16,6 +16,7 @@ import hwsim_utils
import hostapd
from tshark import run_tshark
from utils import alloc_fail, HwsimSkip, parse_ie
+from test_wep import check_wep_capa
@remote_compatible
def test_ap_fragmentation_rts_set_high(dev, apdev):
@@ -300,6 +301,43 @@ def test_ap_wds_sta(dev, apdev):
dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'down'])
dev[0].cmd_execute(['brctl', 'delbr', 'wds-br0'])
+def test_ap_wds_sta_eap(dev, apdev):
+ """WPA2-EAP AP with STA using 4addr mode"""
+ ssid = "test-wpa2-eap"
+ params = hostapd.wpa2_eap_params(ssid=ssid)
+ params['wds_sta'] = "1"
+ params['wds_bridge'] = "wds-br0"
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ try:
+ dev[0].cmd_execute(['brctl', 'addbr', 'wds-br0'])
+ dev[0].cmd_execute(['brctl', 'setfd', 'wds-br0', '0'])
+ dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'up'])
+ dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'on'])
+ dev[0].connect(ssid, key_mgmt="WPA-EAP", eap="GPSK",
+ identity="gpsk user",
+ password="abcdefghijklmnop0123456789abcdef",
+ scan_freq="2412")
+ ev = hapd.wait_event(["WDS-STA-INTERFACE-ADDED"], timeout=10)
+ if ev is None:
+ raise Exception("No WDS-STA-INTERFACE-ADDED event seen")
+ if "sta_addr=" + dev[0].own_addr() not in ev:
+ raise Exception("No sta_addr match in " + ev)
+ if "ifname=" + hapd.ifname + ".sta" not in ev:
+ raise Exception("No ifname match in " + ev)
+ sta = hapd.get_sta(dev[0].own_addr())
+ if "wds_sta_ifname" not in sta:
+ raise Exception("Missing wds_sta_ifname in STA data")
+ if "ifname=" + sta['wds_sta_ifname'] not in ev:
+ raise Exception("wds_sta_ifname %s not in event: %s" %
+ (sta['wds_sta_ifname'], ev))
+ hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0",
+ max_tries=15)
+ finally:
+ dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'off'])
+ dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'down'])
+ dev[0].cmd_execute(['brctl', 'delbr', 'wds-br0'])
+
def test_ap_wds_sta_open(dev, apdev):
"""Open AP with STA using 4addr mode"""
ssid = "test-wds-open"
@@ -334,6 +372,7 @@ def test_ap_wds_sta_open(dev, apdev):
def test_ap_wds_sta_wep(dev, apdev):
"""WEP AP with STA using 4addr mode"""
+ check_wep_capa(dev[0])
ssid = "test-wds-wep"
params = {}
params['ssid'] = ssid
@@ -658,6 +697,7 @@ def test_ap_beacon_rate_vht(dev, apdev):
def test_ap_wep_to_wpa(dev, apdev):
"""WEP to WPA2-PSK configuration change in hostapd"""
+ check_wep_capa(dev[0])
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-to-wpa",
"wep_key0": '"hello"'})
diff --git a/tests/hwsim/test_ap_pmf.py b/tests/hwsim/test_ap_pmf.py
index 3913c5c..7feb173 100644
--- a/tests/hwsim/test_ap_pmf.py
+++ b/tests/hwsim/test_ap_pmf.py
@@ -927,58 +927,11 @@ def mac80211_read_key(keydir):
pass
return vals
-def test_ap_pmf_beacon_protection_bip(dev, apdev):
- """WPA2-PSK Beacon protection (BIP)"""
- """WPA2-PSK AP with PMF required and Beacon protection enabled (BIP)"""
- run_ap_pmf_beacon_protection(dev, apdev, "AES-128-CMAC")
-
-def test_ap_pmf_beacon_protection_bip_cmac_256(dev, apdev):
- """WPA2-PSK Beacon protection (BIP-CMAC-256)"""
- run_ap_pmf_beacon_protection(dev, apdev, "BIP-CMAC-256")
-
-def test_ap_pmf_beacon_protection_bip_gmac_128(dev, apdev):
- """WPA2-PSK Beacon protection (BIP-GMAC-128)"""
- run_ap_pmf_beacon_protection(dev, apdev, "BIP-GMAC-128")
-
-def test_ap_pmf_beacon_protection_bip_gmac_256(dev, apdev):
- """WPA2-PSK Beacon protection (BIP-GMAC-256)"""
- run_ap_pmf_beacon_protection(dev, apdev, "BIP-GMAC-256")
-
-def run_ap_pmf_beacon_protection(dev, apdev, cipher):
- ssid = "test-beacon-prot"
- params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
- params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
- params["ieee80211w"] = "2"
- params["beacon_prot"] = "1"
- params["group_mgmt_cipher"] = cipher
- try:
- hapd = hostapd.add_ap(apdev[0], params)
- except Exception as e:
- if "Failed to enable hostapd interface" in str(e):
- raise HwsimSkip("Beacon protection not supported")
- raise
-
- bssid = hapd.own_addr()
-
- Wlantest.setup(hapd)
- wt = Wlantest()
- wt.flush()
- wt.add_passphrase("12345678")
-
- # STA with Beacon protection enabled
- dev[0].connect(ssid, psk="12345678", ieee80211w="2", beacon_prot="1",
- key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
-
- # STA with Beacon protection disabled
- dev[1].connect(ssid, psk="12345678", ieee80211w="2",
- key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
-
- time.sleep(1)
-
+def check_mac80211_bigtk(dev, hapd):
sta_key = None
ap_key = None
- phy = dev[0].get_driver_status_field("phyname")
+ phy = dev.get_driver_status_field("phyname")
keys = "/sys/kernel/debug/ieee80211/%s/keys" % phy
try:
for key in os.listdir(keys):
@@ -1034,6 +987,55 @@ def run_ap_pmf_beacon_protection(dev, apdev, cipher):
if tx_spec < 3:
raise Exception("AP did not update BIGTK BIPN sufficiently")
+def test_ap_pmf_beacon_protection_bip(dev, apdev):
+ """WPA2-PSK Beacon protection (BIP)"""
+ """WPA2-PSK AP with PMF required and Beacon protection enabled (BIP)"""
+ run_ap_pmf_beacon_protection(dev, apdev, "AES-128-CMAC")
+
+def test_ap_pmf_beacon_protection_bip_cmac_256(dev, apdev):
+ """WPA2-PSK Beacon protection (BIP-CMAC-256)"""
+ run_ap_pmf_beacon_protection(dev, apdev, "BIP-CMAC-256")
+
+def test_ap_pmf_beacon_protection_bip_gmac_128(dev, apdev):
+ """WPA2-PSK Beacon protection (BIP-GMAC-128)"""
+ run_ap_pmf_beacon_protection(dev, apdev, "BIP-GMAC-128")
+
+def test_ap_pmf_beacon_protection_bip_gmac_256(dev, apdev):
+ """WPA2-PSK Beacon protection (BIP-GMAC-256)"""
+ run_ap_pmf_beacon_protection(dev, apdev, "BIP-GMAC-256")
+
+def run_ap_pmf_beacon_protection(dev, apdev, cipher):
+ ssid = "test-beacon-prot"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+ params["ieee80211w"] = "2"
+ params["beacon_prot"] = "1"
+ params["group_mgmt_cipher"] = cipher
+ try:
+ hapd = hostapd.add_ap(apdev[0], params)
+ except Exception as e:
+ if "Failed to enable hostapd interface" in str(e):
+ raise HwsimSkip("Beacon protection not supported")
+ raise
+
+ bssid = hapd.own_addr()
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase("12345678")
+
+ # STA with Beacon protection enabled
+ dev[0].connect(ssid, psk="12345678", ieee80211w="2", beacon_prot="1",
+ key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
+
+ # STA with Beacon protection disabled
+ dev[1].connect(ssid, psk="12345678", ieee80211w="2",
+ key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
+
+ time.sleep(1)
+ check_mac80211_bigtk(dev[0], hapd)
+
valid_bip = wt.get_bss_counter('valid_bip_mmie', bssid)
invalid_bip = wt.get_bss_counter('invalid_bip_mmie', bssid)
missing_bip = wt.get_bss_counter('missing_bip_mmie', bssid)
diff --git a/tests/hwsim/test_ap_psk.py b/tests/hwsim/test_ap_psk.py
index 2f2a354..b9abf5d 100644
--- a/tests/hwsim/test_ap_psk.py
+++ b/tests/hwsim/test_ap_psk.py
@@ -19,11 +19,11 @@ import subprocess
import time
import hostapd
-from utils import HwsimSkip, fail_test, skip_with_fips, start_monitor, stop_monitor, radiotap_build
+from utils import *
import hwsim_utils
from wpasupplicant import WpaSupplicant
from tshark import run_tshark
-from wlantest import WlantestCapture
+from wlantest import WlantestCapture, Wlantest
def check_mib(dev, vals):
mib = dev.get_mib()
@@ -210,6 +210,12 @@ def test_ap_wpa2_ptk_rekey(dev, apdev):
passphrase = 'qwertyuiop'
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
hapd = hostapd.add_ap(apdev[0], params)
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase(passphrase)
+
dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
ev = dev[0].wait_event(["WPA: Key negotiation completed",
"CTRL-EVENT-DISCONNECTED"])
@@ -3345,3 +3351,144 @@ def test_ap_wpa2_psk_no_control_port(dev, apdev):
wpas.request("DISCONNECT")
wpas.wait_disconnected()
wpas.dump_monitor()
+
+def test_ap_wpa2_psk_rsne_mismatch_ap(dev, apdev):
+ """RSNE mismatch in EAPOL-Key msg 3/4"""
+ ie = "30140100000fac040100000fac040100000fac020c80"
+ run_ap_wpa2_psk_rsne_mismatch_ap(dev, apdev, ie)
+
+def test_ap_wpa2_psk_rsne_mismatch_ap2(dev, apdev):
+ """RSNE mismatch in EAPOL-Key msg 3/4"""
+ ie = "30150100000fac040100000fac040100000fac020c0000"
+ run_ap_wpa2_psk_rsne_mismatch_ap(dev, apdev, ie)
+
+def test_ap_wpa2_psk_rsne_mismatch_ap3(dev, apdev):
+ """RSNE mismatch in EAPOL-Key msg 3/4"""
+ run_ap_wpa2_psk_rsne_mismatch_ap(dev, apdev, "")
+
+def run_ap_wpa2_psk_rsne_mismatch_ap(dev, apdev, rsne):
+ params = hostapd.wpa2_params(ssid="psk", passphrase="12345678")
+ params['rsne_override_eapol'] = rsne
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].connect("psk", psk="12345678", scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ dev[0].request("REMOVE_NETWORK all")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+ if "reason=17 locally_generated=1" not in ev:
+ raise Exception("Unexpected disconnection reason: " + ev)
+
+def test_ap_wpa2_psk_rsnxe_mismatch_ap(dev, apdev):
+ """RSNXE mismatch in EAPOL-Key msg 3/4"""
+ params = hostapd.wpa2_params(ssid="psk", passphrase="12345678")
+ params['rsnxe_override_eapol'] = "F40100"
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].connect("psk", psk="12345678", scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ dev[0].request("REMOVE_NETWORK all")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+ if "reason=17 locally_generated=1" not in ev:
+ raise Exception("Unexpected disconnection reason: " + ev)
+
+def test_ap_wpa2_psk_ext_key_id_ptk_rekey_ap0(dev, apdev):
+ """WPA2-PSK AP and PTK rekey by AP (disabled on STA)"""
+ run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, 1, 0)
+
+def test_ap_wpa2_psk_ext_key_id_ptk_rekey_ap1(dev, apdev):
+ """WPA2-PSK AP and PTK rekey by AP (start with Key ID 0)"""
+ run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, 1, 1)
+
+def test_ap_wpa2_psk_ext_key_id_ptk_rekey_ap2(dev, apdev):
+ """WPA2-PSK AP and PTK rekey by AP (start with Key ID 1)"""
+ run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, 2, 1)
+
+def run_ap_wpa2_psk_ext_key_id_ptk_rekey_ap(dev, apdev, ap_ext_key_id,
+ sta_ext_key_id):
+ check_ext_key_id_capa(dev[0])
+ ssid = "test-wpa2-psk"
+ passphrase = 'qwertyuiop'
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+ params['wpa_ptk_rekey'] = '2'
+ params['extended_key_id'] = str(ap_ext_key_id)
+ hapd = hostapd.add_ap(apdev[0], params)
+ check_ext_key_id_capa(hapd)
+ try:
+ dev[0].set("extended_key_id", str(sta_ext_key_id))
+ dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
+ idx = int(dev[0].request("GET last_tk_key_idx"))
+ expect_idx = 1 if ap_ext_key_id == 2 and sta_ext_key_id else 0
+ if idx != expect_idx:
+ raise Exception("Unexpected Key ID for the first TK: %d (expected %d)" % (idx, expect_idx))
+ ev = dev[0].wait_event(["WPA: Key negotiation completed"])
+ if ev is None:
+ raise Exception("PTK rekey timed out")
+ idx = int(dev[0].request("GET last_tk_key_idx"))
+ expect_idx = 1 if ap_ext_key_id == 1 and sta_ext_key_id else 0
+ if idx != expect_idx:
+ raise Exception("Unexpected Key ID for the second TK: %d (expected %d)" % (idx, expect_idx))
+ hwsim_utils.test_connectivity(dev[0], hapd)
+ finally:
+ dev[0].set("extended_key_id", "0")
+
+def test_ap_wpa2_psk_ext_key_id_ptk_rekey_sta0(dev, apdev):
+ """Extended Key ID and PTK rekey by station (Ext Key ID disabled on AP)"""
+ run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, 0)
+
+def test_ap_wpa2_psk_ext_key_id_ptk_rekey_sta1(dev, apdev):
+ """Extended Key ID and PTK rekey by station (start with Key ID 0)"""
+ run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, 1)
+
+def test_ap_wpa2_psk_ext_key_id_ptk_rekey_sta2(dev, apdev):
+ """Extended Key ID and PTK rekey by station (start with Key ID 1)"""
+ run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, 2)
+
+def run_ap_wpa2_psk_ext_key_id_ptk_rekey_sta(dev, apdev, ext_key_id):
+ check_ext_key_id_capa(dev[0])
+ ssid = "test-wpa2-psk"
+ passphrase = 'qwertyuiop'
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+ params['extended_key_id'] = str(ext_key_id)
+ hapd = hostapd.add_ap(apdev[0], params)
+ check_ext_key_id_capa(hapd)
+
+ Wlantest.setup(hapd)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase(passphrase)
+
+ try:
+ dev[0].set("extended_key_id", "1")
+ dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1",
+ scan_freq="2412")
+ idx = int(dev[0].request("GET last_tk_key_idx"))
+ expect_idx = 1 if ext_key_id == 2 else 0
+ if idx != expect_idx:
+ raise Exception("Unexpected Key ID for the first TK: %d (expected %d)" % (idx, expect_idx))
+ ev = dev[0].wait_event(["WPA: Key negotiation completed",
+ "CTRL-EVENT-DISCONNECTED"])
+ if ev is None:
+ raise Exception("PTK rekey timed out")
+ if "CTRL-EVENT-DISCONNECTED" in ev:
+ raise Exception("Disconnect instead of rekey")
+ idx = int(dev[0].request("GET last_tk_key_idx"))
+ expect_idx = 1 if ext_key_id == 1 else 0
+ if idx != expect_idx:
+ raise Exception("Unexpected Key ID for the second TK: %d (expected %d)" % (idx, expect_idx))
+ hwsim_utils.test_connectivity(dev[0], hapd)
+ finally:
+ dev[0].set("extended_key_id", "0")
diff --git a/tests/hwsim/test_ap_tdls.py b/tests/hwsim/test_ap_tdls.py
index caba13d..31d5815 100644
--- a/tests/hwsim/test_ap_tdls.py
+++ b/tests/hwsim/test_ap_tdls.py
@@ -17,6 +17,7 @@ import hostapd
from utils import HwsimSkip, skip_with_fips
from wlantest import Wlantest
from test_ap_vht import vht_supported
+from test_wep import check_wep_capa
def start_ap_wpa2_psk(ap):
params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
@@ -313,6 +314,8 @@ def test_ap_wpa_mixed_tdls(dev, apdev):
def test_ap_wep_tdls(dev, apdev):
"""WEP AP and two stations using TDLS"""
+ check_wep_capa(dev[0])
+ check_wep_capa(dev[1])
hapd = hostapd.add_ap(apdev[0],
{"ssid": "test-wep", "wep_key0": '"hello"'})
wlantest_setup(hapd)
diff --git a/tests/hwsim/test_ap_vht.py b/tests/hwsim/test_ap_vht.py
index ece0efd..24658d1 100644
--- a/tests/hwsim/test_ap_vht.py
+++ b/tests/hwsim/test_ap_vht.py
@@ -75,6 +75,11 @@ def test_ap_vht80(dev, apdev):
raise Exception("Missing STA flag: HT")
if "[VHT]" not in sta['flags']:
raise Exception("Missing STA flag: VHT")
+ if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
+ raise Exception("No Supported Operating Classes information for STA")
+ opclass = int(sta['supp_op_classes'][0:2], 16)
+ if opclass != 128:
+ raise Exception("Unexpected Current Operating Class from STA: %d" % opclass)
except Exception as e:
if isinstance(e, Exception) and str(e) == "AP startup failed":
if not vht_supported():
@@ -290,6 +295,13 @@ def test_ap_vht_20(devs, apdevs):
hapd = hostapd.add_ap(ap, params)
dev.connect("test-vht20", scan_freq="5180", key_mgmt="NONE")
hwsim_utils.test_connectivity(dev, hapd)
+
+ sta = hapd.get_sta(dev.own_addr())
+ if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
+ raise Exception("No Supported Operating Classes information for STA")
+ opclass = int(sta['supp_op_classes'][0:2], 16)
+ if opclass != 115:
+ raise Exception("Unexpected Current Operating Class from STA: %d" % opclass)
finally:
dev.request("DISCONNECT")
clear_regdom(hapd, devs)
@@ -313,6 +325,13 @@ def test_ap_vht_40(devs, apdevs):
hapd = hostapd.add_ap(ap, params)
dev.connect("test-vht40", scan_freq="5180", key_mgmt="NONE")
hwsim_utils.test_connectivity(dev, hapd)
+
+ sta = hapd.get_sta(dev.own_addr())
+ if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
+ raise Exception("No Supported Operating Classes information for STA")
+ opclass = int(sta['supp_op_classes'][0:2], 16)
+ if opclass != 116:
+ raise Exception("Unexpected Current Operating Class from STA: %d" % opclass)
finally:
dev.request("DISCONNECT")
clear_regdom(hapd, devs)
@@ -395,6 +414,13 @@ def test_ap_vht160(dev, apdev):
raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
if "WIDTH=160 MHz" not in sig:
raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
+
+ sta = hapd.get_sta(dev[0].own_addr())
+ if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
+ raise Exception("No Supported Operating Classes information for STA")
+ opclass = int(sta['supp_op_classes'][0:2], 16)
+ if opclass != 129:
+ raise Exception("Unexpected Current Operating Class from STA: %d" % opclass)
except Exception as e:
if isinstance(e, Exception) and str(e) == "AP startup failed":
if not vht_supported():
@@ -644,6 +670,13 @@ def test_ap_vht80plus80(dev, apdev):
raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
if "CENTER_FRQ2=5775" not in sig:
raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
+
+ sta = hapd2.get_sta(dev[1].own_addr())
+ if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
+ raise Exception("No Supported Operating Classes information for STA")
+ opclass = int(sta['supp_op_classes'][0:2], 16)
+ if opclass != 130:
+ raise Exception("Unexpected Current Operating Class from STA: %d" % opclass)
except Exception as e:
if isinstance(e, Exception) and str(e) == "AP startup failed":
if not vht_supported():
@@ -856,10 +889,10 @@ def test_ap_vht_csa_vht40_disable(dev, apdev):
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
- dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
+ dev[0].connect("vht", key_mgmt="NONE", scan_freq="5200 5745")
hwsim_utils.test_connectivity(dev[0], hapd)
- hapd.request("CHAN_SWITCH 5 5200 center_freq1=5200 bandwidth=40 ht")
+ hapd.request("CHAN_SWITCH 5 5200 center_freq1=5210 sec_channel_offset=1 bandwidth=40 ht")
ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
if ev is None:
raise Exception("CSA finished event timed out")
@@ -870,7 +903,14 @@ def test_ap_vht_csa_vht40_disable(dev, apdev):
raise Exception("Channel switch event not seen")
if "freq=5200" not in ev:
raise Exception("Channel mismatch: " + ev)
- time.sleep(0.5)
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
+ if ev:
+ # mac80211 does not support CSA to disable VHT, so the channel
+ # switch will be followed by disconnection and attempt to reconnect.
+ # Wait for that here to avoid failing the test case based on how
+ # example the connectivity test would get timed compared to getting
+ # disconnected or reconnected.
+ dev[0].wait_connected()
hwsim_utils.test_connectivity(dev[0], hapd)
dev[1].connect("vht", key_mgmt="NONE", scan_freq="5200")
@@ -1008,7 +1048,7 @@ def test_prefer_vht40(dev, apdev):
raise Exception("Unexpected BSS0 est_throughput: " + est)
est = dev[0].get_bss(bssid2)['est_throughput']
- if est != "135001":
+ if est != "180001":
raise Exception("Unexpected BSS1 est_throughput: " + est)
finally:
dev[0].request("DISCONNECT")
diff --git a/tests/hwsim/test_ap_wps.py b/tests/hwsim/test_ap_wps.py
index 9583416..b1b0331 100644
--- a/tests/hwsim/test_ap_wps.py
+++ b/tests/hwsim/test_ap_wps.py
@@ -45,6 +45,7 @@ from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
from utils import wait_fail_trigger, clear_regdom
from test_ap_eap import int_eap_server_params
from test_sae import check_sae_capab
+from test_wep import check_wep_capa
def wps_start_ap(apdev, ssid="test-wps-conf"):
params = {"ssid": ssid, "eap_server": "1", "wps_state": "2",
@@ -229,6 +230,7 @@ def test_ap_wps_conf(dev, apdev):
"wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
logger.info("WPS provisioning step")
hapd.request("WPS_PBC")
+ dev[0].set("device_name", "Device A")
dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
dev[0].dump_monitor()
dev[0].request("WPS_PBC " + apdev[0]['bssid'])
@@ -261,6 +263,7 @@ def test_ap_wps_conf_5ghz(dev, apdev):
hapd = hostapd.add_ap(apdev[0], params)
logger.info("WPS provisioning step")
hapd.request("WPS_PBC")
+ dev[0].set("device_name", "Device A")
dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
dev[0].request("WPS_PBC " + apdev[0]['bssid'])
dev[0].wait_connected(timeout=30)
@@ -284,6 +287,7 @@ def test_ap_wps_conf_chan14(dev, apdev):
hapd = hostapd.add_ap(apdev[0], params)
logger.info("WPS provisioning step")
hapd.request("WPS_PBC")
+ dev[0].set("device_name", "Device A")
dev[0].request("WPS_PBC")
dev[0].wait_connected(timeout=30)
@@ -10036,6 +10040,7 @@ def test_ap_wps_ignore_broadcast_ssid(dev, apdev):
def test_ap_wps_wep(dev, apdev):
"""WPS AP trying to enable WEP"""
+ check_wep_capa(dev[0])
ssid = "test-wps"
hapd = hostapd.add_ap(apdev[0],
{"ssid": ssid, "eap_server": "1", "wps_state": "1",
@@ -10395,3 +10400,40 @@ def test_ap_wps_appl_ext(dev, apdev):
dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
dev[0].wait_connected(timeout=30)
+
+def test_ap_wps_pbc_ap_timeout(dev, apdev, params):
+ """WPS PBC timeout on AP [long]"""
+ if not params['long']:
+ raise HwsimSkip("Skip test case with long duration due to --long not specified")
+ run_ap_wps_ap_timeout(dev, apdev, "WPS_PBC")
+
+def test_ap_wps_pin_ap_timeout(dev, apdev, params):
+ """WPS PIN timeout on AP [long]"""
+ if not params['long']:
+ raise HwsimSkip("Skip test case with long duration due to --long not specified")
+ run_ap_wps_ap_timeout(dev, apdev, "WPS_PIN any 12345670 10")
+
+def run_ap_wps_ap_timeout(dev, apdev, cmd):
+ ssid = "test-wps-conf"
+ hapd = hostapd.add_ap(apdev[0],
+ {"ssid": ssid, "eap_server": "1", "wps_state": "2",
+ "wpa_passphrase": "12345678", "wpa": "2",
+ "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
+ bssid = hapd.own_addr()
+ hapd.request(cmd)
+ time.sleep(1)
+ dev[0].scan_for_bss(bssid, freq="2412")
+ bss = dev[0].get_bss(bssid)
+ logger.info("BSS during active Registrar: " + str(bss))
+ if not bss['ie'].endswith("0106ffffffffffff"):
+ raise Exception("Authorized MAC not included")
+ ev = hapd.wait_event(["WPS-TIMEOUT"], timeout=130)
+ if ev is None and "PBC" in cmd:
+ raise Exception("WPS-TIMEOUT not reported")
+ time.sleep(5)
+ dev[0].flush_scan_cache()
+ dev[0].scan_for_bss(bssid, freq="2412", force_scan=True)
+ bss = dev[0].get_bss(bssid)
+ logger.info("BSS after timeout: " + str(bss))
+ if bss['ie'].endswith("0106ffffffffffff"):
+ raise Exception("Authorized MAC not removed")
diff --git a/tests/hwsim/test_bgscan.py b/tests/hwsim/test_bgscan.py
index f418f56..5951f82 100644
--- a/tests/hwsim/test_bgscan.py
+++ b/tests/hwsim/test_bgscan.py
@@ -71,13 +71,22 @@ def test_bgscan_simple(dev, apdev):
def test_bgscan_simple_beacon_loss(dev, apdev):
"""bgscan_simple and beacon loss"""
- hapd = hostapd.add_ap(apdev[0], {"ssid": "bgscan"})
-
- dev[0].connect("bgscan", key_mgmt="NONE", scan_freq="2412",
- bgscan="simple:1:-20:2")
+ params = hostapd.wpa2_params(ssid="bgscan", passphrase="12345678")
+ params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+ params["ieee80211w"] = "2"
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].set("disable_sa_query", "1")
+ dev[0].connect("bgscan", ieee80211w="2", key_mgmt="WPA-PSK-SHA256",
+ psk="12345678", scan_freq="2412",
+ bgscan="simple:100:-20:200")
hapd.set("ext_mgmt_frame_handling", "1")
if "OK" not in hapd.request("STOP_AP"):
raise Exception("Failed to stop AP")
+ hapd.disable()
+ hapd.set("ssid", "foo")
+ hapd.set("beacon_int", "10000")
+ hapd.enable()
ev = dev[0].wait_event(["CTRL-EVENT-BEACON-LOSS"], timeout=10)
if ev is None:
raise Exception("Beacon loss not reported")
@@ -238,13 +247,21 @@ def test_bgscan_learn(dev, apdev):
def test_bgscan_learn_beacon_loss(dev, apdev):
"""bgscan_simple and beacon loss"""
- hapd = hostapd.add_ap(apdev[0], {"ssid": "bgscan"})
-
- dev[0].connect("bgscan", key_mgmt="NONE", scan_freq="2412",
- bgscan="learn:1:-20:2")
+ params = hostapd.wpa2_params(ssid="bgscan", passphrase="12345678")
+ params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+ params["ieee80211w"] = "2"
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].set("disable_sa_query", "1")
+ dev[0].connect("bgscan", ieee80211w="2", key_mgmt="WPA-PSK-SHA256",
+ psk="12345678", scan_freq="2412", bgscan="learn:100:-20:200")
hapd.set("ext_mgmt_frame_handling", "1")
if "OK" not in hapd.request("STOP_AP"):
raise Exception("Failed to stop AP")
+ hapd.disable()
+ hapd.set("ssid", "foo")
+ hapd.set("beacon_int", "10000")
+ hapd.enable()
ev = dev[0].wait_event(["CTRL-EVENT-BEACON-LOSS"], timeout=10)
if ev is None:
raise Exception("Beacon loss not reported")
diff --git a/tests/hwsim/test_cfg80211.py b/tests/hwsim/test_cfg80211.py
index a461fe0..9c7935e 100644
--- a/tests/hwsim/test_cfg80211.py
+++ b/tests/hwsim/test_cfg80211.py
@@ -16,6 +16,7 @@ import hwsim_utils
from tshark import run_tshark
from nl80211 import *
from wpasupplicant import WpaSupplicant
+from test_wep import check_wep_capa
def nl80211_command(dev, cmd, attr):
res = dev.request("VENDOR ffffffff {} {}".format(nl80211_cmd[cmd],
@@ -101,6 +102,7 @@ def test_cfg80211_tx_frame(dev, apdev, params):
@remote_compatible
def test_cfg80211_wep_key_idx_change(dev, apdev):
"""WEP Shared Key authentication and key index change without deauth"""
+ check_wep_capa(dev[0])
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-shared-key",
"wep_key0": '"hello12345678"',
diff --git a/tests/hwsim/test_connect_cmd.py b/tests/hwsim/test_connect_cmd.py
index 87122aa..07a9ab6 100644
--- a/tests/hwsim/test_connect_cmd.py
+++ b/tests/hwsim/test_connect_cmd.py
@@ -12,6 +12,7 @@ import hwsim_utils
import hostapd
from wpasupplicant import WpaSupplicant
from p2p_utils import *
+from test_wep import check_wep_capa
def test_connect_cmd_open(dev, apdev):
"""Open connection using cfg80211 connect command"""
@@ -31,11 +32,13 @@ def test_connect_cmd_open(dev, apdev):
def test_connect_cmd_wep(dev, apdev):
"""WEP Open System using cfg80211 connect command"""
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
+ check_wep_capa(wpas)
+
params = {"ssid": "sta-connect-wep", "wep_key0": '"hello"'}
hapd = hostapd.add_ap(apdev[0], params)
- wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
- wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
wpas.connect("sta-connect-wep", key_mgmt="NONE", scan_freq="2412",
wep_key0='"hello"')
wpas.dump_monitor()
@@ -46,12 +49,14 @@ def test_connect_cmd_wep(dev, apdev):
def test_connect_cmd_wep_shared(dev, apdev):
"""WEP Shared key using cfg80211 connect command"""
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
+ check_wep_capa(wpas)
+
params = {"ssid": "sta-connect-wep", "wep_key0": '"hello"',
"auth_algs": "2"}
hapd = hostapd.add_ap(apdev[0], params)
- wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
- wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
id = wpas.connect("sta-connect-wep", key_mgmt="NONE", scan_freq="2412",
auth_alg="SHARED", wep_key0='"hello"')
wpas.dump_monitor()
diff --git a/tests/hwsim/test_dbus.py b/tests/hwsim/test_dbus.py
index 41661b8..64bf34b 100644
--- a/tests/hwsim/test_dbus.py
+++ b/tests/hwsim/test_dbus.py
@@ -5490,6 +5490,67 @@ def test_dbus_ap(dev, apdev):
if not t.success():
raise Exception("Expected signals not seen")
+def test_dbus_ap_scan(dev, apdev):
+ """D-Bus AddNetwork for AP mode and scan"""
+ (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
+ iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
+
+ ssid = "test-wpa2-psk"
+ passphrase = 'qwertyuiop'
+
+ hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
+ bssid = hapd.own_addr()
+
+ class TestDbusConnect(TestDbus):
+ def __init__(self, bus):
+ TestDbus.__init__(self, bus)
+ self.started = False
+ self.scan_completed = False
+
+ def __enter__(self):
+ gobject.timeout_add(1, self.run_connect)
+ gobject.timeout_add(15000, self.timeout)
+ self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
+ "PropertiesChanged")
+ self.add_signal(self.scanDone, WPAS_DBUS_IFACE, "ScanDone")
+ self.loop.run()
+ return self
+
+ def propertiesChanged(self, properties):
+ logger.debug("propertiesChanged: %s" % str(properties))
+ if 'State' in properties and properties['State'] == "completed":
+ self.started = True
+ logger.info("Try to scan in AP mode")
+ iface.Scan({'Type': 'active',
+ 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
+ logger.info("Scan() returned")
+
+ def scanDone(self, success):
+ logger.debug("scanDone: success=%s" % success)
+ if self.started:
+ self.scan_completed = True
+ self.loop.quit()
+
+ def run_connect(self, *args):
+ logger.debug("run_connect")
+ args = dbus.Dictionary({'ssid': ssid,
+ 'key_mgmt': 'WPA-PSK',
+ 'psk': passphrase,
+ 'mode': 2,
+ 'frequency': 2412,
+ 'scan_freq': 2412},
+ signature='sv')
+ self.netw = iface.AddNetwork(args)
+ iface.SelectNetwork(self.netw)
+ return False
+
+ def success(self):
+ return self.started and self.scan_completed
+
+ with TestDbusConnect(bus) as t:
+ if not t.success():
+ raise Exception("Expected signals not seen")
+
def test_dbus_connect_wpa_eap(dev, apdev):
"""D-Bus AddNetwork and connection with WPA+WPA2-Enterprise AP"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
diff --git a/tests/hwsim/test_dfs.py b/tests/hwsim/test_dfs.py
index a10d32b..8851de9 100644
--- a/tests/hwsim/test_dfs.py
+++ b/tests/hwsim/test_dfs.py
@@ -28,7 +28,8 @@ def wait_dfs_event(hapd, event, timeout):
def start_dfs_ap(ap, ssid="dfs", ht=True, ht40=False,
ht40minus=False, vht80=False, vht20=False, chanlist=None,
- channel=None, country="FI", rrm_beacon_report=False):
+ channel=None, country="FI", rrm_beacon_report=False,
+ chan100=False):
ifname = ap['ifname']
logger.info("Starting AP " + ifname + " on DFS channel")
hapd = hostapd.add_ap(ap, {}, no_enable=True)
@@ -37,7 +38,10 @@ def start_dfs_ap(ap, ssid="dfs", ht=True, ht40=False,
hapd.set("ieee80211d", "1")
hapd.set("ieee80211h", "1")
hapd.set("hw_mode", "a")
- hapd.set("channel", "52")
+ if chan100:
+ hapd.set("channel", "100")
+ else:
+ hapd.set("channel", "52")
if not ht:
hapd.set("ieee80211n", "0")
if ht40:
@@ -48,7 +52,10 @@ def start_dfs_ap(ap, ssid="dfs", ht=True, ht40=False,
if vht80:
hapd.set("ieee80211ac", "1")
hapd.set("vht_oper_chwidth", "1")
- hapd.set("vht_oper_centr_freq_seg0_idx", "58")
+ if chan100:
+ hapd.set("vht_oper_centr_freq_seg0_idx", "106")
+ else:
+ hapd.set("vht_oper_centr_freq_seg0_idx", "58")
if vht20:
hapd.set("ieee80211ac", "1")
hapd.set("vht_oper_chwidth", "0")
@@ -526,3 +533,127 @@ def test_dfs_rrm(dev, apdev, params):
raise Exception("Beacon report response not received")
finally:
clear_regdom(hapd, dev)
+
+def test_dfs_radar_vht80_downgrade(dev, apdev, params):
+ """DFS channel bandwidth downgrade from VHT80 to VHT40 [long]"""
+ if not params['long']:
+ raise HwsimSkip("Skip test case with long duration due to --long not specified")
+ try:
+ # Start with 80 MHz channel 100 (5500 MHz) to find a radar
+ hapd = None
+ hapd = start_dfs_ap(apdev[0], chanlist="100-140",
+ ht40=True, vht80=True, chan100=True)
+ time.sleep(1)
+ dfs_simulate_radar(hapd)
+
+ ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
+ if ev is None:
+ raise Exception("Timeout on DFS aborted event")
+ if "success=0 freq=5500" not in ev:
+ raise Exception("Unexpected DFS aborted event contents: " + ev)
+
+ ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
+ if "freq=5500" not in ev:
+ raise Exception("Unexpected DFS radar detection freq: " + ev)
+
+ # The only other available 80 MHz channel in the chanlist is
+ # 116 (5580 MHz), so that will be selected next.
+ ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
+ if "freq=5580 chan=116 sec_chan=1" not in ev:
+ raise Exception("Unexpected DFS new freq: " + ev)
+
+ ev = wait_dfs_event(hapd, None, 5)
+ if "DFS-CAC-START" not in ev:
+ raise Exception("Unexpected DFS event: " + ev)
+ if "freq=5580" not in ev:
+ raise Exception("Unexpected DFS CAC freq: " + ev)
+
+ time.sleep(1)
+ dfs_simulate_radar(hapd)
+ ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 5)
+ if ev is None:
+ raise Exception("Timeout on DFS aborted event (2)")
+ if "success=0 freq=5580" not in ev:
+ raise Exception("Unexpected DFS aborted event (2) contents: " + ev)
+
+ ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
+ if "freq=5580" not in ev:
+ raise Exception("Unexpected DFS radar detection (2) freq: " + ev)
+
+ # No more 80 MHz channels are available, so have to downgrade to 40 MHz
+ # channels and the only remaining one is channel 132 (5660 MHz).
+ ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
+ if "freq=5660 chan=132 sec_chan=1" not in ev:
+ raise Exception("Unexpected DFS new freq (2): " + ev)
+
+ ev = wait_dfs_event(hapd, None, 5)
+ if "DFS-CAC-START" not in ev:
+ raise Exception("Unexpected DFS event: " + ev)
+ if "freq=5660" not in ev:
+ raise Exception("Unexpected DFS CAC freq (2): " + ev)
+
+ ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
+ if "success=1" not in ev:
+ raise Exception("CAC failed")
+ if "freq=5660" not in ev:
+ raise Exception("Unexpected DFS freq result: " + ev)
+
+ ev = wait_dfs_event(hapd, None, 5)
+ if "AP-ENABLED" not in ev:
+ raise Exception("Unexpected DFS event: " + ev)
+ dev[0].connect("dfs", key_mgmt="NONE", scan_freq="5660")
+ dev[0].wait_regdom(country_ie=True)
+ sig = dev[0].request("SIGNAL_POLL").splitlines()
+ if "FREQUENCY=5660" not in sig or "WIDTH=40 MHz" not in sig:
+ raise Exception("Unexpected SIGNAL_POLL value: " + str(sig))
+ finally:
+ clear_regdom(hapd, dev)
+
+def test_dfs_chan_switch(dev, apdev, params):
+ """DFS channel switch [long]"""
+ if not params['long']:
+ raise HwsimSkip("Skip test case with long duration due to --long not specified")
+ try:
+ hapd = None
+ hapd = start_dfs_ap(apdev[0], country="US")
+
+ ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
+ if "success=1" not in ev:
+ raise Exception("CAC failed")
+ if "freq=5260" not in ev:
+ raise Exception("Unexpected DFS freq result")
+ ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
+ if not ev:
+ raise Exception("AP setup timed out")
+ freq = hapd.get_status_field("freq")
+ if freq != "5260":
+ raise Exception("Unexpected frequency")
+
+ dev[0].connect("dfs", key_mgmt="NONE", scan_freq="5260 5280")
+ dev[0].wait_regdom(country_ie=True)
+ hwsim_utils.test_connectivity(dev[0], hapd)
+
+ if "OK" not in hapd.request("CHAN_SWITCH 5 5280 ht"):
+ raise Exception("CHAN_SWITCH failed")
+ # This results in BSS going down before restart, so the STA is expected
+ # to report disconnection.
+ dev[0].wait_disconnected()
+ ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
+ if "freq=5280" not in ev:
+ raise Exception("Unexpected channel: " + ev)
+ ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
+ if "success=1" not in ev:
+ raise Exception("CAC failed")
+ if "freq=5280" not in ev:
+ raise Exception("Unexpected DFS freq result")
+ ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
+ if not ev:
+ raise Exception("AP setup timed out")
+ freq = hapd.get_status_field("freq")
+ if freq != "5280":
+ raise Exception("Unexpected frequency")
+
+ dev[0].wait_connected(timeout=30)
+ hwsim_utils.test_connectivity(dev[0], hapd)
+ finally:
+ clear_regdom(hapd, dev)
diff --git a/tests/hwsim/test_dpp.py b/tests/hwsim/test_dpp.py
index 46d29d4..7c55365 100644
--- a/tests/hwsim/test_dpp.py
+++ b/tests/hwsim/test_dpp.py
@@ -4571,18 +4571,29 @@ def test_dpp_controller_relay(dev, apdev, params):
dev[0].set("dpp_config_processing", "0", allow_fail=True)
dev[1].request("DPP_CONTROLLER_STOP")
-def run_dpp_controller_relay(dev, apdev, params):
+def test_dpp_controller_relay_chirp(dev, apdev, params):
+ """DPP Controller/Relay with chirping"""
+ try:
+ run_dpp_controller_relay(dev, apdev, params, chirp=True)
+ finally:
+ dev[0].set("dpp_config_processing", "0", allow_fail=True)
+ dev[1].request("DPP_CONTROLLER_STOP")
+
+def run_dpp_controller_relay(dev, apdev, params, chirp=False):
check_dpp_capab(dev[0])
check_dpp_capab(dev[1])
prefix = "dpp_controller_relay"
+ if chirp:
+ prefix += "_chirp"
cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap")
wt = WlantestCapture('lo', cap_lo)
# Controller
conf_id = dev[1].dpp_configurator_add()
- dev[1].set("dpp_configurator_params",
- " conf=sta-dpp configurator=%d" % conf_id)
+ if not chirp:
+ dev[1].set("dpp_configurator_params",
+ " conf=sta-dpp configurator=%d" % conf_id)
id_c = dev[1].dpp_bootstrap_gen()
uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c)
@@ -4601,20 +4612,40 @@ def run_dpp_controller_relay(dev, apdev, params):
params = {"ssid": "unconfigured",
"channel": "6",
"dpp_controller": "ipaddr=127.0.0.1 pkhash=" + pkhash}
+ if chirp:
+ params["channel"] = "11"
+ params["dpp_configurator_connectivity"] = "1"
relay = hostapd.add_ap(apdev[1], params)
check_dpp_capab(relay)
# Enroll Relay to the network
# TODO: Do this over TCP once direct Enrollee-over-TCP case is supported
- id_h = relay.dpp_bootstrap_gen(chan="81/6", mac=True)
+ if chirp:
+ id_h = relay.dpp_bootstrap_gen(chan="81/11", mac=True)
+ else:
+ id_h = relay.dpp_bootstrap_gen(chan="81/6", mac=True)
uri_r = relay.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
dev[1].dpp_auth_init(uri=uri_r, conf="ap-dpp", configurator=conf_id)
wait_auth_success(relay, dev[1], configurator=dev[1], enrollee=relay)
update_hapd_config(relay)
- # Initiate from Enrollee with broadcast DPP Authentication Request
+ # Initiate from Enrollee with broadcast DPP Authentication Request or
+ # using chirping
dev[0].set("dpp_config_processing", "2")
- dev[0].dpp_auth_init(uri=uri_c, role="enrollee")
+ if chirp:
+ id1 = dev[0].dpp_bootstrap_gen()
+ uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
+ idc = dev[1].dpp_qr_code(uri)
+ dev[1].dpp_bootstrap_set(idc, conf="sta-dpp", configurator=conf_id)
+ if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=5" % id1):
+ raise Exception("DPP_CHIRP failed")
+ ev = relay.wait_event(["DPP-RX"], timeout=10)
+ if ev is None:
+ raise Exception("Presence Announcement not seen")
+ if "type=13" not in ev:
+ raise Exception("Unexpected DPP frame received: " + ev)
+ else:
+ dev[0].dpp_auth_init(uri=uri_c, role="enrollee")
wait_auth_success(dev[1], dev[0], configurator=dev[1], enrollee=dev[0],
allow_enrollee_failure=True,
allow_configurator_failure=True)
@@ -4732,7 +4763,7 @@ def run_dpp_controller_rx_failure(dev, apdev):
"eloop_sock_table_add_sock;?eloop_register_sock;dpp_controller_tcp_cb",
"dpp_controller_rx",
"dpp_controller_rx_auth_req",
- "wpabuf_alloc;=dpp_controller_rx_auth_req"]
+ "wpabuf_alloc;=dpp_tcp_send_msg;dpp_controller_rx_auth_req"]
cmd = "DPP_AUTH_INIT peer=%d tcp_addr=127.0.0.1" % peer
for func in tests:
with alloc_fail(dev[0], 1, func):
@@ -5039,3 +5070,245 @@ def test_dpp_with_p2p_device(dev, apdev):
dev[0].dpp_auth_init(uri=uri1)
wait_auth_success(wpas, dev[0], configurator=dev[0], enrollee=wpas,
allow_enrollee_failure=True)
+
+def test_dpp_chirp(dev, apdev, params):
+ """DPP chirp [long]"""
+ if not params['long']:
+ raise HwsimSkip("Skip test case with long duration due to --long not specified")
+ check_dpp_capab(dev[0])
+ dev[0].flush_scan_cache()
+
+ params = {"ssid": "dpp",
+ "channel": "11"}
+ hapd = hostapd.add_ap(apdev[0], params)
+ check_dpp_capab(hapd)
+ dpp_cc = False
+
+ id1 = dev[0].dpp_bootstrap_gen(chan="81/1")
+ if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=5" % id1):
+ raise Exception("DPP_CHIRP failed")
+ chan1 = 0
+ chan6 = 0
+ chan11 = 0
+ for i in range(30):
+ ev = dev[0].wait_event(["DPP-CHIRP-STOPPED",
+ "DPP-TX "], timeout=60)
+ if ev is None:
+ raise Exception("DPP chirp stop not reported")
+ if "DPP-CHIRP-STOPPED" in ev:
+ break
+ if "type=13" not in ev:
+ continue
+ freq = int(ev.split(' ')[2].split('=')[1])
+ if freq == 2412:
+ chan1 += 1
+ elif freq == 2437:
+ chan6 += 1
+ elif freq == 2462:
+ chan11 += 1
+ if not dpp_cc:
+ hapd.set("dpp_configurator_connectivity", "1")
+ if "OK" not in hapd.request("UPDATE_BEACON"):
+ raise Exception("UPDATE_BEACON failed")
+ dpp_cc = True
+ if chan1 != 5 or chan6 != 5 or chan11 != 1:
+ raise Exception("Unexpected number of presence announcements sent: %d %d %d" % (chan1, chan6, chan11))
+
+def test_dpp_chirp_listen(dev, apdev, params):
+ """DPP chirp with listen [long]"""
+ if not params['long']:
+ raise HwsimSkip("Skip test case with long duration due to --long not specified")
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+
+ id1 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
+ uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
+
+ if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2 listen=2412" % id1):
+ raise Exception("DPP_CHIRP failed")
+ for i in range(30):
+ ev = dev[0].wait_event(["DPP-CHIRP-STOPPED",
+ "DPP-TX "], timeout=60)
+ if ev is None:
+ raise Exception("DPP chirp stop not reported")
+ if "DPP-CHIRP-STOPPED" in ev:
+ break
+
+def test_dpp_chirp_configurator(dev, apdev):
+ """DPP chirp with a standalone Configurator"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+
+ id1 = dev[0].dpp_bootstrap_gen(chan="81/1")
+ uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
+
+ conf_id = dev[1].dpp_configurator_add()
+ idc = dev[1].dpp_qr_code(uri)
+ dev[1].dpp_bootstrap_set(idc, conf="sta-dpp", configurator=conf_id)
+ dev[1].dpp_listen(2437)
+
+ if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2" % id1):
+ raise Exception("DPP_CHIRP failed")
+
+ ev = dev[1].wait_event(["DPP-RX"], timeout=10)
+ if ev is None:
+ raise Exception("Presence Announcement not seen")
+ if "type=13" not in ev:
+ raise Exception("Unexpected DPP frame received: " + ev)
+
+ wait_auth_success(dev[0], dev[1], dev[1], dev[0])
+
+def test_dpp_chirp_configurator_inits(dev, apdev):
+ """DPP chirp with a standalone Configurator initiating"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+
+ id1 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
+ uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
+
+ conf_id = dev[1].dpp_configurator_add()
+ idc = dev[1].dpp_qr_code(uri)
+
+ if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2 listen=2412" % id1):
+ raise Exception("DPP_CHIRP failed")
+ for i in range(2):
+ ev = dev[0].wait_event(["DPP-TX "], timeout=10)
+ if ev is None or "type=13" not in ev:
+ raise Exception("Presence Announcement not sent")
+
+ dev[1].dpp_auth_init(uri=uri, conf="sta-dpp", configurator=conf_id)
+ wait_auth_success(dev[0], dev[1], dev[1], dev[0])
+
+def start_dpp_pfs_ap(apdev, pfs):
+ params = {"ssid": "dpp",
+ "wpa": "2",
+ "wpa_key_mgmt": "DPP",
+ "dpp_pfs": str(pfs),
+ "ieee80211w": "2",
+ "rsn_pairwise": "CCMP",
+ "dpp_connector": params1_ap_connector,
+ "dpp_csign": params1_csign,
+ "dpp_netaccesskey": params1_ap_netaccesskey}
+ try:
+ hapd = hostapd.add_ap(apdev, params)
+ except:
+ raise HwsimSkip("DPP not supported")
+ return hapd
+
+def run_dpp_pfs_sta(dev, pfs, fail=False):
+ dev.connect("dpp", key_mgmt="DPP", scan_freq="2412",
+ ieee80211w="2", dpp_pfs=str(pfs),
+ dpp_csign=params1_csign,
+ dpp_connector=params1_sta_connector,
+ dpp_netaccesskey=params1_sta_netaccesskey,
+ wait_connect=not fail)
+ if fail:
+ for i in range(2):
+ ev = dev.wait_event(["CTRL-EVENT-ASSOC-REJECT",
+ "CTRL-EVENT-CONNECTED"], timeout=10)
+ if ev is None:
+ raise Exception("Connection result not reported")
+ if "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection")
+ dev.request("REMOVE_NETWORK all")
+ else:
+ dev.request("REMOVE_NETWORK all")
+ dev.wait_disconnected()
+ dev.dump_monitor()
+
+def test_dpp_pfs_ap_0(dev, apdev):
+ """DPP PFS AP default"""
+ check_dpp_capab(dev[0])
+ hapd = start_dpp_pfs_ap(apdev[0], 0)
+ run_dpp_pfs_sta(dev[0], 0)
+ run_dpp_pfs_sta(dev[0], 1)
+ run_dpp_pfs_sta(dev[0], 2)
+
+def test_dpp_pfs_ap_1(dev, apdev):
+ """DPP PFS AP required"""
+ check_dpp_capab(dev[0])
+ hapd = start_dpp_pfs_ap(apdev[0], 1)
+ run_dpp_pfs_sta(dev[0], 0)
+ run_dpp_pfs_sta(dev[0], 1)
+ run_dpp_pfs_sta(dev[0], 2, fail=True)
+
+def test_dpp_pfs_ap_2(dev, apdev):
+ """DPP PFS AP not allowed"""
+ check_dpp_capab(dev[0])
+ hapd = start_dpp_pfs_ap(apdev[0], 2)
+ run_dpp_pfs_sta(dev[0], 0)
+ run_dpp_pfs_sta(dev[0], 1, fail=True)
+ run_dpp_pfs_sta(dev[0], 2)
+
+def test_dpp_reconfig_connector(dev, apdev):
+ """DPP reconfiguration connector"""
+ try:
+ run_dpp_reconfig_connector(dev, apdev)
+ finally:
+ dev[0].set("dpp_config_processing", "0", allow_fail=True)
+
+def run_dpp_reconfig_connector(dev, apdev):
+ check_dpp_capab(dev[0], min_ver=2)
+ check_dpp_capab(dev[1], min_ver=2)
+
+ ssid = "reconfig"
+ passphrase = "secret passphrase"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].set("dpp_config_processing", "2")
+ id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
+ uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+ dev[0].dpp_listen(2412)
+ configurator = dev[1].dpp_configurator_add()
+ conf = 'sta-psk'
+ dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid=ssid,
+ passphrase=passphrase, configurator=configurator)
+ res = wait_auth_success(dev[0], dev[1], configurator=dev[1],
+ enrollee=dev[0])
+
+ ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=1)
+ if ev is None:
+ raise Exception("SSID not reported")
+ res_ssid = ev.split(' ')[1]
+ if res_ssid != ssid:
+ raise Exception("Unexpected SSID value")
+
+ ev = dev[0].wait_event(["DPP-CONNECTOR"], timeout=1)
+ if ev is None:
+ raise Exception("Connector not reported")
+ connector = ev.split(' ')[1]
+
+ ev = dev[0].wait_event(["DPP-C-SIGN-KEY"], timeout=1)
+ if ev is None:
+ raise Exception("C-sign-key not reported")
+ p = ev.split(' ')
+ csign = p[1]
+
+ ev = dev[0].wait_event(["DPP-NET-ACCESS-KEY"], timeout=1)
+ if ev is None:
+ raise Exception("netAccessKey not reported")
+ p = ev.split(' ')
+ net_access_key = p[1]
+ net_access_key_expiry = p[2] if len(p) > 2 else None
+
+ ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
+ if ev is None:
+ raise Exception("DPP network profile not generated")
+ id = ev.split(' ')[1]
+
+ dev[0].wait_connected()
+
+ n_key_mgmt = dev[0].get_network(id, "key_mgmt")
+ if n_key_mgmt != "WPA-PSK FT-PSK WPA-PSK-SHA256":
+ raise Exception("Unexpected key_mgmt: " + n_key_mgmt)
+ n_connector = dev[0].get_network(id, "dpp_connector")
+ if n_connector.strip('"') != connector:
+ raise Exception("Connector mismatch: %s %s" % (n_connector, connector))
+ n_csign = dev[0].get_network(id, "dpp_csign")
+ if n_csign.strip('"') != csign:
+ raise Exception("csign mismatch: %s %s" % (n_csign, csign))
+ n_net_access_key = dev[0].get_network(id, "dpp_netaccesskey")
+ if n_net_access_key.strip('"') != net_access_key:
+ raise Exception("net_access_key mismatch: %s %s" % (n_net_access_key,
+ net_access_key))
diff --git a/tests/hwsim/test_fils.py b/tests/hwsim/test_fils.py
index 16fc038..8e4df65 100644
--- a/tests/hwsim/test_fils.py
+++ b/tests/hwsim/test_fils.py
@@ -17,7 +17,7 @@ import hostapd
from tshark import run_tshark
from wpasupplicant import WpaSupplicant
import hwsim_utils
-from utils import HwsimSkip, alloc_fail
+from utils import *
from test_erp import check_erp_capa, start_erp_as
from test_ap_hs20 import ip_checksum
@@ -1655,7 +1655,7 @@ def test_fils_sk_auth_mismatch(dev, apdev, params):
hwsim_utils.test_connectivity(dev[0], hapd)
def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0,
- pmksa_caching=True):
+ pmksa_caching=True, ext_key_id=False):
check_fils_capa(dev[0])
check_erp_capa(dev[0])
@@ -1673,6 +1673,8 @@ def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0,
params['wpa_group_rekey'] = str(wpa_group_rekey)
if not pmksa_caching:
params['disable_pmksa_caching'] = '1'
+ if ext_key_id:
+ params['extended_key_id'] = '1'
hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412)
@@ -2302,3 +2304,29 @@ def test_fils_sk_erp_roam_diff_akm(dev, apdev, params):
raise Exception("Failed to connect to the second AP")
hwsim_utils.test_connectivity(dev[0], hapd2)
+
+def test_fils_auth_ptk_rekey_ap_ext_key_id(dev, apdev, params):
+ """PTK rekeying after FILS authentication triggered by AP (Ext Key ID)"""
+ check_ext_key_id_capa(dev[0])
+ try:
+ dev[0].set("extended_key_id", "1")
+ hapd = setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=2,
+ ext_key_id=True)
+ check_ext_key_id_capa(hapd)
+ idx = int(dev[0].request("GET last_tk_key_idx"))
+ if idx != 0:
+ raise Exception("Unexpected Key ID before TK rekey: %d" % idx)
+ ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=3)
+ if ev is None:
+ raise Exception("PTK rekey timed out")
+ idx = int(dev[0].request("GET last_tk_key_idx"))
+ if idx != 1:
+ raise Exception("Unexpected Key ID after TK rekey: %d" % idx)
+ hwsim_utils.test_connectivity(dev[0], hapd)
+
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+ if ev is not None:
+ raise Exception("Rekeying failed - disconnected")
+ hwsim_utils.test_connectivity(dev[0], hapd)
+ finally:
+ dev[0].set("extended_key_id", "0")
diff --git a/tests/hwsim/test_ibss.py b/tests/hwsim/test_ibss.py
index a9b7e11..ce7e5ed 100644
--- a/tests/hwsim/test_ibss.py
+++ b/tests/hwsim/test_ibss.py
@@ -13,6 +13,7 @@ import subprocess
import hwsim_utils
from utils import alloc_fail, wait_fail_trigger
+from test_wep import check_wep_capa
def connect_ibss_cmd(dev, id, freq=2412):
dev.dump_monitor()
@@ -395,6 +396,9 @@ def test_ibss_rsn_tkip(dev):
def test_ibss_wep(dev):
"""IBSS with WEP"""
+ check_wep_capa(dev[0])
+ check_wep_capa(dev[1])
+
ssid = "ibss-wep"
id = add_ibss(dev[0], ssid, key_mgmt="NONE", wep_key0='"hello"')
diff --git a/tests/hwsim/test_ieee8021x.py b/tests/hwsim/test_ieee8021x.py
index bc1c3c9..1946948 100644
--- a/tests/hwsim/test_ieee8021x.py
+++ b/tests/hwsim/test_ieee8021x.py
@@ -15,11 +15,13 @@ import hostapd
import hwsim_utils
from utils import skip_with_fips
from tshark import run_tshark
+from test_wep import check_wep_capa
logger = logging.getLogger()
def test_ieee8021x_wep104(dev, apdev):
"""IEEE 802.1X connection using dynamic WEP104"""
+ check_wep_capa(dev[0])
skip_with_fips(dev[0])
params = hostapd.radius_params()
params["ssid"] = "ieee8021x-wep"
@@ -36,6 +38,7 @@ def test_ieee8021x_wep104(dev, apdev):
def test_ieee8021x_wep40(dev, apdev):
"""IEEE 802.1X connection using dynamic WEP40"""
+ check_wep_capa(dev[0])
skip_with_fips(dev[0])
params = hostapd.radius_params()
params["ssid"] = "ieee8021x-wep"
@@ -52,6 +55,7 @@ def test_ieee8021x_wep40(dev, apdev):
def test_ieee8021x_wep_index_workaround(dev, apdev):
"""IEEE 802.1X and EAPOL-Key index workaround"""
+ check_wep_capa(dev[0])
skip_with_fips(dev[0])
params = hostapd.radius_params()
params["ssid"] = "ieee8021x-wep"
@@ -100,6 +104,7 @@ def test_ieee8021x_static_wep104(dev, apdev):
run_static_wep(dev, apdev, '"hello-there-/"')
def run_static_wep(dev, apdev, key):
+ check_wep_capa(dev[0])
params = hostapd.radius_params()
params["ssid"] = "ieee8021x-wep"
params["ieee8021x"] = "1"
@@ -252,6 +257,7 @@ def send_eapol_key(dev, bssid, signkey, frame_start, frame_end):
def test_ieee8021x_eapol_key(dev, apdev):
"""IEEE 802.1X connection and EAPOL-Key protocol tests"""
+ check_wep_capa(dev[0])
skip_with_fips(dev[0])
params = hostapd.radius_params()
params["ssid"] = "ieee8021x-wep"
@@ -317,6 +323,7 @@ def test_ieee8021x_reauth(dev, apdev):
def test_ieee8021x_reauth_wep(dev, apdev, params):
"""IEEE 802.1X and EAPOL_REAUTH request with WEP"""
+ check_wep_capa(dev[0])
logdir = params['logdir']
params = hostapd.radius_params()
@@ -492,6 +499,7 @@ def test_ieee8021x_open_leap(dev, apdev):
def test_ieee8021x_and_wpa_enabled(dev, apdev):
"""IEEE 802.1X connection using dynamic WEP104 when WPA enabled"""
+ check_wep_capa(dev[0])
skip_with_fips(dev[0])
params = hostapd.radius_params()
params["ssid"] = "ieee8021x-wep"
diff --git a/tests/hwsim/test_monitor_interface.py b/tests/hwsim/test_monitor_interface.py
index 62ce738..e1a48ae 100644
--- a/tests/hwsim/test_monitor_interface.py
+++ b/tests/hwsim/test_monitor_interface.py
@@ -4,6 +4,7 @@
# This software may be distributed under the terms of the BSD license.
# See README for more details.
+import binascii
from remotehost import remote_compatible
import logging
logger = logging.getLogger()
@@ -12,6 +13,7 @@ import time
import hwsim_utils
import hostapd
from wpasupplicant import WpaSupplicant
+from utils import radiotap_build, start_monitor, stop_monitor
def test_monitor_iface_open(dev, apdev):
"""Open connection using cfg80211 monitor interface on AP"""
@@ -72,9 +74,20 @@ def test_monitor_iface_unknown_sta(dev, apdev):
hapd.request("DEAUTHENTICATE " + addr)
# But the unprotected Deauth from TX frame-from-unassoc-STA will now be
# processed
- dev[0].request("DATA_TEST_CONFIG 1")
- dev[0].request("DATA_TEST_TX " + bssid + " " + addr + " 0")
- dev[0].request("DATA_TEST_CONFIG 0")
+ try:
+ sock = start_monitor(apdev[1]["ifname"])
+ radiotap = radiotap_build()
+
+ bssid = hapd.own_addr().replace(':', '')
+ addr = dev[0].own_addr().replace(':', '')
+
+ # Inject Data frame from STA to AP since we not have SA in place
+ # anymore for normal data TX
+ frame = binascii.unhexlify("48010000" + bssid + addr + bssid + "0000")
+ sock.send(radiotap + frame)
+ finally:
+ stop_monitor(apdev[1]["ifname"])
+
ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
if ev is None:
raise Exception("No disconnection")
diff --git a/tests/hwsim/test_owe.py b/tests/hwsim/test_owe.py
index 645e8d4..51cd7bf 100644
--- a/tests/hwsim/test_owe.py
+++ b/tests/hwsim/test_owe.py
@@ -329,6 +329,51 @@ def run_owe_transition_mode_multi_bss(dev, apdev):
raise Exception("Unexpected key_mgmt: " + val)
hwsim_utils.test_connectivity(dev[0], hapd2)
+def test_owe_transition_mode_rsne_mismatch(dev, apdev):
+ """Opportunistic Wireless Encryption transition mode and RSNE mismatch"""
+ if "OWE" not in dev[0].get_capability("key_mgmt"):
+ raise HwsimSkip("OWE not supported")
+ dev[0].flush_scan_cache()
+ params = {"ssid": "owe-random",
+ "wpa": "2",
+ "wpa_key_mgmt": "OWE",
+ "rsn_pairwise": "CCMP",
+ "ieee80211w": "2",
+ "rsne_override_eapol": "30140100000fac040100000fac040100000fac020c00",
+ "owe_transition_bssid": apdev[1]['bssid'],
+ "owe_transition_ssid": '"owe-test"',
+ "ignore_broadcast_ssid": "1"}
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ params = {"ssid": "owe-test",
+ "owe_transition_bssid": apdev[0]['bssid'],
+ "owe_transition_ssid": '"owe-random"'}
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid2 = hapd2.own_addr()
+
+ dev[0].scan_for_bss(bssid, freq="2412")
+ dev[0].scan_for_bss(bssid2, freq="2412")
+
+ id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5)
+ if ev is None:
+ raise Exception("OWE PMKSA not created")
+ ev = dev[0].wait_event(["WPA: IE in 3/4 msg does not match with IE in Beacon/ProbeResp"],
+ timeout=5)
+ if ev is None:
+ raise Exception("RSNE mismatch not reported")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ dev[0].request("REMOVE_NETWORK all")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+ if "reason=17 locally_generated=1" not in ev:
+ raise Exception("Unexpected disconnection reason: " + ev)
+
def test_owe_unsupported_group(dev, apdev):
"""Opportunistic Wireless Encryption and unsupported group"""
try:
@@ -716,3 +761,47 @@ def test_owe_ptk_hash(dev, apdev):
if ev is None:
raise Exception("No PMKSA cache removal event seen")
dev[0].dump_monitor()
+
+def test_owe_transition_mode_disable(dev, apdev):
+ """Opportunistic Wireless Encryption transition mode disable"""
+ if "OWE" not in dev[0].get_capability("key_mgmt"):
+ raise HwsimSkip("OWE not supported")
+ dev[0].flush_scan_cache()
+ params = {"ssid": "owe-random",
+ "wpa": "2",
+ "wpa_key_mgmt": "OWE",
+ "rsn_pairwise": "CCMP",
+ "ieee80211w": "2",
+ "transition_disable": '0x08',
+ "owe_transition_bssid": apdev[1]['bssid'],
+ "owe_transition_ssid": '"owe-test"',
+ "ignore_broadcast_ssid": "1"}
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ params = {"ssid": "owe-test",
+ "owe_transition_bssid": apdev[0]['bssid'],
+ "owe_transition_ssid": '"owe-random"'}
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid2 = hapd2.own_addr()
+
+ dev[0].scan_for_bss(bssid, freq="2412")
+ dev[0].scan_for_bss(bssid2, freq="2412")
+
+ id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
+ scan_freq="2412")
+
+ ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=1)
+ if ev is None:
+ raise Exception("Transition disable not indicated")
+ if ev.split(' ')[1] != "08":
+ raise Exception("Unexpected transition disable bitmap: " + ev)
+
+ val = dev[0].get_network(id, "owe_only")
+ if val != "1":
+ raise Exception("Unexpected owe_only value: " + val)
+
+ dev[0].request("DISCONNECT")
+ dev[0].wait_disconnected()
+ dev[0].request("RECONNECT")
+ dev[0].wait_connected()
diff --git a/tests/hwsim/test_pmksa_cache.py b/tests/hwsim/test_pmksa_cache.py
index 11daaaa..c334b48 100644
--- a/tests/hwsim/test_pmksa_cache.py
+++ b/tests/hwsim/test_pmksa_cache.py
@@ -662,6 +662,7 @@ def test_pmksa_cache_ap_expiration(dev, apdev):
params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
hapd = hostapd.add_ap(apdev[0], params)
bssid = apdev[0]['bssid']
+
dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
eap="GPSK", identity="gpsk-user-session-timeout",
password="abcdefghijklmnop0123456789abcdef",
@@ -669,20 +670,44 @@ def test_pmksa_cache_ap_expiration(dev, apdev):
ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
if ev is None:
raise Exception("No connection event received from hostapd")
+ hapd.dump_monitor()
+
dev[0].request("DISCONNECT")
+ ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=5)
+ if ev is None:
+ raise Exception("No disconnection event received from hostapd")
+ dev[0].wait_disconnected()
+
+ # Wait for session timeout to remove PMKSA cache entry
time.sleep(5)
dev[0].dump_monitor()
+ hapd.dump_monitor()
+
dev[0].request("RECONNECT")
ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
"CTRL-EVENT-CONNECTED"], timeout=20)
if ev is None:
- raise Exception("Roaming with the AP timed out")
+ raise Exception("Reconnection with the AP timed out")
if "CTRL-EVENT-CONNECTED" in ev:
raise Exception("EAP exchange missing")
dev[0].wait_connected(timeout=20, error="Reconnect timed out")
dev[0].dump_monitor()
+ ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
+ if ev is None:
+ raise Exception("No connection event received from hostapd [2]")
+ hapd.dump_monitor()
+
+ # Wait for session timeout
+ ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=10)
+ if ev is None:
+ raise Exception("No disconnection event received from hostapd [2]")
dev[0].wait_disconnected(timeout=20)
dev[0].wait_connected(timeout=20, error="Reassociation timed out")
+ ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
+ if ev is None:
+ raise Exception("No connection event received from hostapd [3]")
+ hapd.dump_monitor()
+ dev[0].dump_monitor()
def test_pmksa_cache_multiple_sta(dev, apdev):
"""PMKSA cache with multiple stations"""
diff --git a/tests/hwsim/test_radius.py b/tests/hwsim/test_radius.py
index fde5650..403fbd7 100644
--- a/tests/hwsim/test_radius.py
+++ b/tests/hwsim/test_radius.py
@@ -21,6 +21,7 @@ import hostapd
from utils import HwsimSkip, require_under_vm, skip_with_fips, alloc_fail, fail_test, wait_fail_trigger
from test_ap_hs20 import build_dhcp_ack
from test_ap_ft import ft_params1
+from test_wep import check_wep_capa
def connect(dev, ssid, wait_connect=True):
dev.connect(ssid, key_mgmt="WPA-EAP", scan_freq="2412",
@@ -442,6 +443,7 @@ def test_radius_acct_ft_psk(dev, apdev):
def test_radius_acct_ieee8021x(dev, apdev):
"""RADIUS Accounting - IEEE 802.1X"""
+ check_wep_capa(dev[0])
skip_with_fips(dev[0])
as_hapd = hostapd.Hostapd("as")
params = hostapd.radius_params()
@@ -961,7 +963,7 @@ def test_radius_macacl_unreachable(dev, apdev):
hapd.set("auth_server_port", "1812")
hapd.disable()
hapd.enable()
- dev[0].wait_connected()
+ dev[0].wait_connected(timeout=20)
dev[0].request("DISCONNECT")
dev[0].wait_disconnected()
diff --git a/tests/hwsim/test_sae.py b/tests/hwsim/test_sae.py
index a55bd07..63a61b8 100644
--- a/tests/hwsim/test_sae.py
+++ b/tests/hwsim/test_sae.py
@@ -363,6 +363,42 @@ def test_sae_mixed_mfp(dev, apdev):
dev[2].connect("test-sae", psk="12345678", ieee80211w="0", scan_freq="2412")
dev[2].dump_monitor()
+def test_sae_and_psk_transition_disable(dev, apdev):
+ """SAE and PSK transition disable indication"""
+ check_sae_capab(dev[0])
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params["ieee80211w"] = "1"
+ params['wpa_key_mgmt'] = 'SAE WPA-PSK'
+ params['transition_disable'] = '0x01'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].request("SET sae_groups ")
+ id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE WPA-PSK",
+ ieee80211w="1", scan_freq="2412")
+ ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=1)
+ if ev is None:
+ raise Exception("Transition disable not indicated")
+ if ev.split(' ')[1] != "01":
+ raise Exception("Unexpected transition disable bitmap: " + ev)
+
+ val = dev[0].get_network(id, "ieee80211w")
+ if val != "2":
+ raise Exception("Unexpected ieee80211w value: " + val)
+ val = dev[0].get_network(id, "key_mgmt")
+ if val != "SAE":
+ raise Exception("Unexpected key_mgmt value: " + val)
+ val = dev[0].get_network(id, "group")
+ if val != "CCMP":
+ raise Exception("Unexpected group value: " + val)
+ val = dev[0].get_network(id, "proto")
+ if val != "RSN":
+ raise Exception("Unexpected proto value: " + val)
+
+ dev[0].request("DISCONNECT")
+ dev[0].wait_disconnected()
+ dev[0].request("RECONNECT")
+ dev[0].wait_connected()
+
def test_sae_mfp(dev, apdev):
"""SAE and MFP enabled without sae_require_mfp"""
check_sae_capab(dev[0])
@@ -2150,6 +2186,42 @@ def test_sae_auth_restart(dev, apdev):
dev[0].set("sae_groups", "")
dev[0].set("sae_pwe", "0")
+def test_sae_rsne_mismatch(dev, apdev):
+ """SAE and RSNE mismatch in EAPOL-Key msg 2/4"""
+ check_sae_capab(dev[0])
+ dev[0].set("sae_groups", "")
+
+ params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ # First, test with matching RSNE to confirm testing capability
+ dev[0].set("rsne_override_eapol",
+ "30140100000fac040100000fac040100000fac080000")
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].dump_monitor()
+
+ # Then, test with modified RSNE
+ tests = ["30140100000fac040100000fac040100000fac080010", "0000"]
+ for ie in tests:
+ dev[0].set("rsne_override_eapol", ie)
+ dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["Associated with"], timeout=10)
+ if ev is None:
+ raise Exception("No indication of association seen")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-DISCONNECTED"], timeout=5)
+ dev[0].request("REMOVE_NETWORK all")
+ if ev is None:
+ raise Exception("No disconnection seen")
+ if "CTRL-EVENT-DISCONNECTED" not in ev:
+ raise Exception("Unexpected connection")
+ dev[0].dump_monitor()
+
def test_sae_h2e_rsnxe_mismatch(dev, apdev):
"""SAE H2E and RSNXE mismatch in EAPOL-Key msg 2/4"""
check_sae_capab(dev[0])
@@ -2253,6 +2325,10 @@ def test_sae_h2e_rsnxe_mismatch_ap2(dev, apdev):
"""SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "F400")
+def test_sae_h2e_rsnxe_mismatch_ap3(dev, apdev):
+ """SAE H2E and RSNXE mismatch in EAPOL-Key msg 3/4"""
+ run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, "")
+
def run_sae_h2e_rsnxe_mismatch_ap(dev, apdev, rsnxe):
check_sae_capab(dev[0])
params = hostapd.wpa2_params(ssid="sae-pwe", passphrase="12345678")
@@ -2318,3 +2394,216 @@ def test_sae_forced_anti_clogging_h2e_loop(dev, apdev):
finally:
for i in range(2):
dev[i].set("sae_pwe", "0")
+
+def test_sae_okc(dev, apdev):
+ """SAE and opportunistic key caching"""
+ check_sae_capab(dev[0])
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['okc'] = '1'
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ dev[0].set("sae_groups", "")
+ id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
+ okc=True, scan_freq="2412")
+ dev[0].dump_monitor()
+ hapd.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used")
+
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid2 = hapd2.own_addr()
+
+ dev[0].scan_for_bss(bssid2, freq=2412)
+ dev[0].roam(bssid2)
+ dev[0].dump_monitor()
+ hapd2.wait_sta()
+ if "sae_group" in dev[0].get_status():
+ raise Exception("SAE authentication used during roam to AP2")
+
+ dev[0].roam(bssid)
+ dev[0].dump_monitor()
+ hapd.wait_sta()
+ if "sae_group" in dev[0].get_status():
+ raise Exception("SAE authentication used during roam to AP1")
+
+def test_sae_okc_sta_only(dev, apdev):
+ """SAE and opportunistic key caching only on STA"""
+ check_sae_capab(dev[0])
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ dev[0].set("sae_groups", "")
+ id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
+ okc=True, scan_freq="2412")
+ dev[0].dump_monitor()
+ hapd.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used")
+
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid2 = hapd2.own_addr()
+
+ dev[0].scan_for_bss(bssid2, freq=2412)
+ dev[0].roam(bssid2, assoc_reject_ok=True)
+ dev[0].dump_monitor()
+ hapd2.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used during roam to AP2")
+
+def test_sae_okc_pmk_lifetime(dev, apdev):
+ """SAE and opportunistic key caching and PMK lifetime"""
+ check_sae_capab(dev[0])
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['okc'] = '1'
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ dev[0].set("sae_groups", "")
+ dev[0].set("dot11RSNAConfigPMKLifetime", "10")
+ dev[0].set("dot11RSNAConfigPMKReauthThreshold", "30")
+ id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
+ okc=True, scan_freq="2412")
+ dev[0].dump_monitor()
+ hapd.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used")
+
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid2 = hapd2.own_addr()
+
+ time.sleep(5)
+ dev[0].scan_for_bss(bssid2, freq=2412)
+ dev[0].roam(bssid2)
+ dev[0].dump_monitor()
+ hapd2.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used during roam to AP2 after reauth threshold")
+
+def test_sae_pmk_lifetime(dev, apdev):
+ """SAE and opportunistic key caching and PMK lifetime"""
+ check_sae_capab(dev[0])
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ dev[0].set("sae_groups", "")
+ dev[0].set("dot11RSNAConfigPMKLifetime", "10")
+ dev[0].set("dot11RSNAConfigPMKReauthThreshold", "50")
+ id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
+ scan_freq="2412")
+ dev[0].dump_monitor()
+ hapd.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used")
+
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid2 = hapd2.own_addr()
+
+ dev[0].scan_for_bss(bssid2, freq=2412)
+ dev[0].roam(bssid2)
+ dev[0].dump_monitor()
+ hapd2.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used during roam to AP2")
+
+ dev[0].roam(bssid)
+ dev[0].dump_monitor()
+ hapd.wait_sta()
+ if "sae_group" in dev[0].get_status():
+ raise Exception("SAE authentication used during roam to AP1")
+
+ time.sleep(6)
+ dev[0].scan_for_bss(bssid2, freq=2412)
+ dev[0].roam(bssid2)
+ dev[0].dump_monitor()
+ hapd2.wait_sta()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used during roam to AP2 after reauth threshold")
+
+ ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], 11)
+ if ev is None:
+ raise Exception("PMKSA cache entry did not expire")
+ if bssid2 not in ev:
+ ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], 11)
+ if ev is None:
+ raise Exception("PMKSA cache entry did not expire")
+ if bssid2 not in ev:
+ raise Exception("PMKSA cache entry for the current AP did not expire")
+ ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], 1)
+ if ev is None:
+ raise Exception("Disconnection not reported after PMKSA cache entry expiration")
+
+ dev[0].wait_connected()
+ if "sae_group" not in dev[0].get_status():
+ raise Exception("SAE authentication not used after PMKSA cache entry expiration")
+
+def test_sae_and_psk_multiple_passwords(dev, apdev, params):
+ """SAE and PSK with multiple passwords/passphrases"""
+ check_sae_capab(dev[0])
+ check_sae_capab(dev[1])
+ addr0 = dev[0].own_addr()
+ addr1 = dev[1].own_addr()
+ psk_file = os.path.join(params['logdir'],
+ 'sae_and_psk_multiple_passwords.wpa_psk')
+ with open(psk_file, 'w') as f:
+ f.write(addr0 + ' passphrase0\n')
+ f.write(addr1 + ' passphrase1\n')
+ params = hostapd.wpa2_params(ssid="test-sae")
+ params['wpa_key_mgmt'] = 'SAE WPA-PSK'
+ params['sae_password'] = ['passphrase0|mac=' + addr0,
+ 'passphrase1|mac=' + addr1]
+ params['wpa_psk_file'] = psk_file
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].set("sae_groups", "")
+ dev[0].connect("test-sae", sae_password="passphrase0",
+ key_mgmt="SAE", scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+
+ dev[0].connect("test-sae", psk="passphrase0", scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+
+ dev[1].set("sae_groups", "")
+ dev[1].connect("test-sae", sae_password="passphrase1",
+ key_mgmt="SAE", scan_freq="2412")
+ dev[1].request("REMOVE_NETWORK all")
+ dev[1].wait_disconnected()
+
+ dev[1].connect("test-sae", psk="passphrase1", scan_freq="2412")
+ dev[1].request("REMOVE_NETWORK all")
+ dev[1].wait_disconnected()
+
+def test_sae_pmf_roam(dev, apdev):
+ """SAE/PMF roam"""
+ check_sae_capab(dev[0])
+ params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
+ params['wpa_key_mgmt'] = 'SAE'
+ params['ieee80211w'] = '2'
+ params['skip_prune_assoc'] = '1'
+ hapd = hostapd.add_ap(apdev[0], params)
+ bssid = hapd.own_addr()
+
+ dev[0].set("sae_groups", "")
+ id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
+ ieee80211w="2", scan_freq="2412")
+ dev[0].dump_monitor()
+ hapd.wait_sta()
+
+ hapd2 = hostapd.add_ap(apdev[1], params)
+ bssid2 = hapd2.own_addr()
+
+ dev[0].scan_for_bss(bssid2, freq=2412)
+ dev[0].roam(bssid2)
+ dev[0].dump_monitor()
+ hapd2.wait_sta()
+
+ dev[0].roam(bssid)
+ dev[0].dump_monitor()
diff --git a/tests/hwsim/test_scan.py b/tests/hwsim/test_scan.py
index 682f427..56ab9c5 100644
--- a/tests/hwsim/test_scan.py
+++ b/tests/hwsim/test_scan.py
@@ -19,6 +19,7 @@ from utils import HwsimSkip, fail_test, alloc_fail, wait_fail_trigger, parse_ie
from utils import clear_regdom_dev
from tshark import run_tshark
from test_ap_csa import switch_channel, wait_channel_switch, csa_supported
+from test_wep import check_wep_capa
def check_scan(dev, params, other_started=False, test_busy=False):
if not other_started:
@@ -434,6 +435,7 @@ def test_scan_for_auth_fail(dev, apdev):
@remote_compatible
def test_scan_for_auth_wep(dev, apdev):
"""cfg80211 scan-for-auth workaround with WEP keys"""
+ check_wep_capa(dev[0])
dev[0].flush_scan_cache()
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep", "wep_key0": '"abcde"',
@@ -1454,6 +1456,17 @@ def test_scan_parsing(dev, apdev):
res = dev[0].request("BSS 02:ff:00:00:00:09")
logger.info("Updated BSS:\n" + res)
+def get_probe_req_ies(hapd):
+ for i in range(10):
+ msg = hapd.mgmt_rx()
+ if msg is None:
+ break
+ if msg['subtype'] != 4:
+ continue
+ return parse_ie(binascii.hexlify(msg['payload']).decode())
+
+ raise Exception("Probe Request not seen")
+
def test_scan_specific_bssid(dev, apdev):
"""Scan for a specific BSSID"""
dev[0].flush_scan_cache()
@@ -1484,6 +1497,29 @@ def test_scan_specific_bssid(dev, apdev):
if bss2 and 'beacon_ie' in bss2 and 'ie' in bss2 and bss2['beacon_ie'] == bss2['ie']:
raise Exception("Second scan did find Probe Response frame")
+ hapd.dump_monitor()
+ hapd.set("ext_mgmt_frame_handling", "1")
+
+ # With specific SSID in the Probe Request frame
+ dev[0].request("SCAN TYPE=ONLY freq=2412 bssid=" + bssid)
+ ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
+ if ev is None:
+ raise Exception("Scan did not complete")
+ ie = get_probe_req_ies(hapd)
+ if ie[0] != b"test-scan":
+ raise Exception("Specific SSID not seen in Probe Request frame")
+
+ hapd.dump_monitor()
+
+ # Without specific SSID in the Probe Request frame
+ dev[0].request("SCAN TYPE=ONLY freq=2412 wildcard_ssid=1 bssid=" + bssid)
+ ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
+ if ev is None:
+ raise Exception("Scan did not complete")
+ ie = get_probe_req_ies(hapd)
+ if len(ie[0]) != 0:
+ raise Exception("Wildcard SSID not seen in Probe Request frame")
+
def test_scan_probe_req_events(dev, apdev):
"""Probe Request frame RX events from hostapd"""
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
diff --git a/tests/hwsim/test_sigma_dut.py b/tests/hwsim/test_sigma_dut.py
index 89d96d1..32b0bf4 100644
--- a/tests/hwsim/test_sigma_dut.py
+++ b/tests/hwsim/test_sigma_dut.py
@@ -22,10 +22,12 @@ import hostapd
from utils import HwsimSkip
from hwsim import HWSimRadio
import hwsim_utils
+from wlantest import Wlantest
from test_dpp import check_dpp_capab, update_hapd_config, wait_auth_success
from test_suite_b import check_suite_b_192_capa, suite_b_as_params, suite_b_192_rsa_ap_params
from test_ap_eap import check_eap_capa, int_eap_server_params, check_domain_match, check_domain_suffix_match
from test_ap_hs20 import hs20_ap_params
+from test_ap_pmf import check_mac80211_bigtk
def check_sigma_dut():
if not os.path.exists("./sigma_dut"):
@@ -96,7 +98,7 @@ def sigma_dut_cmd_check(cmd, port=9000, timeout=2):
return res
def start_sigma_dut(ifname, hostapd_logdir=None, cert_path=None,
- bridge=None, sae_h2e=False):
+ bridge=None, sae_h2e=False, owe_ptk_workaround=False):
check_sigma_dut()
cmd = ['./sigma_dut',
'-d',
@@ -114,6 +116,8 @@ def start_sigma_dut(ifname, hostapd_logdir=None, cert_path=None,
cmd += ['-b', bridge]
if sae_h2e:
cmd += ['-2']
+ if owe_ptk_workaround:
+ cmd += ['-3']
sigma = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
for stream in [sigma.stdout, sigma.stderr]:
@@ -468,6 +472,43 @@ def test_sigma_dut_sae_pw_id(dev, apdev):
finally:
stop_sigma_dut(sigma)
+def test_sigma_dut_sae_pw_id_pwe_loop(dev, apdev):
+ """sigma_dut controlled SAE association with Password Identifier and forced PWE looping"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname)
+
+ try:
+ ssid = "test-sae"
+ params = hostapd.wpa2_params(ssid=ssid)
+ params['wpa_key_mgmt'] = 'SAE'
+ params["ieee80211w"] = "2"
+ params['sae_password'] = 'secret|id=pw id'
+ params['sae_groups'] = '19'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ sigma_dut_cmd_check("sta_reset_default,interface,%s" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,passphrase,%s,type,SAE,encpType,aes-ccmp,AKMSuiteType,8;9,PasswordID,pw id,sae_pwe,looping" % (ifname, "test-sae", "secret"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-sae"),
+ timeout=10)
+ for i in range(3):
+ ev = dev[0].wait_event(["SME: Trying to authenticate",
+ "CTRL-EVENT-CONNECTED"], timeout=10)
+ if ev is None:
+ raise Exception("Network selection result not indicated")
+ if "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection")
+ res = sigma_dut_cmd("sta_is_connected,interface," + ifname)
+ if "connected,1" in res:
+ raise Exception("Connection reported")
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
def test_sigma_dut_sae_pw_id_ft(dev, apdev):
"""sigma_dut controlled SAE association with Password Identifier and FT"""
run_sigma_dut_sae_pw_id_ft(dev, apdev)
@@ -605,7 +646,7 @@ def test_sigma_dut_ap_psk_sha256(dev, apdev, params):
logdir = os.path.join(params['logdir'],
"sigma_dut_ap_psk_sha256.sigma-hostapd")
with HWSimRadio() as (radio, iface):
- sigma = start_sigma_dut(iface)
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
try:
sigma_dut_cmd_check("ap_reset_default")
sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-psk,MODE,11ng")
@@ -1059,6 +1100,42 @@ def test_sigma_dut_ap_sae_pw_id(dev, apdev, params):
finally:
stop_sigma_dut(sigma)
+def test_sigma_dut_ap_sae_pw_id_pwe_loop(dev, apdev, params):
+ """sigma_dut controlled AP with SAE Password Identifier and forced PWE looping"""
+ logdir = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_pw_id_pwe_loop.sigma-hostapd")
+ conffile = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_pw_id_pwe_loop.sigma-conf")
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,AKMSuiteType,8,SAEPasswords,12345678:pwid,PMF,Required,sae_pwe,looping")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ with open("/tmp/sigma_dut-ap.conf", "rb") as f:
+ with open(conffile, "wb") as f2:
+ f2.write(f.read())
+
+ dev[0].set("sae_groups", "")
+ dev[0].connect("test-sae", key_mgmt="SAE", sae_password="12345678",
+ sae_password_id="pwid",
+ ieee80211w="2", scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
+ "CTRL-EVENT-CONNECTED"], timeout=10)
+ if ev is None:
+ raise Exception("Network selection result not indicated")
+ if "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Unexpected connection")
+ dev[0].request("REMOVE_NETWORK all")
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+
def test_sigma_dut_ap_sae_pw_id_ft(dev, apdev, params):
"""sigma_dut controlled AP with SAE Password Identifier and FT"""
logdir = os.path.join(params['logdir'],
@@ -1255,6 +1332,35 @@ def run_sigma_dut_owe(dev, apdev):
finally:
stop_sigma_dut(sigma)
+def test_sigma_dut_owe_ptk_workaround(dev, apdev):
+ """sigma_dut controlled OWE station with PTK workaround"""
+ if "OWE" not in dev[0].get_capability("key_mgmt"):
+ raise HwsimSkip("OWE not supported")
+
+ params = {"ssid": "owe",
+ "wpa": "2",
+ "wpa_key_mgmt": "OWE",
+ "owe_ptk_workaround": "1",
+ "owe_groups": "20",
+ "ieee80211w": "2",
+ "rsn_pairwise": "CCMP"}
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname, owe_ptk_workaround=True)
+
+ try:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,WPA3" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,owe,Type,OWE,ECGroupID,20" % ifname)
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,owe,channel,1" % ifname,
+ timeout=10)
+ sigma_dut_wait_connected(ifname)
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("ignore_old_scan_res", "0")
+
def test_sigma_dut_ap_owe(dev, apdev, params):
"""sigma_dut controlled AP with OWE"""
logdir = os.path.join(params['logdir'],
@@ -1319,6 +1425,25 @@ def test_sigma_dut_ap_owe_ecgroupid(dev, apdev):
finally:
stop_sigma_dut(sigma)
+def test_sigma_dut_ap_owe_ptk_workaround(dev, apdev):
+ """sigma_dut controlled AP with OWE PTK workaround"""
+ if "OWE" not in dev[0].get_capability("key_mgmt"):
+ raise HwsimSkip("OWE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, owe_ptk_workaround=True)
+ try:
+ sigma_dut_cmd_check("ap_reset_default,NAME,AP,Program,WPA3")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,owe,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,OWE,ECGroupID,20,PMF,Required")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ dev[0].connect("owe", key_mgmt="OWE", ieee80211w="2",
+ owe_group="20", owe_ptk_workaround="1",
+ scan_freq="2412")
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+
def test_sigma_dut_ap_owe_transition_mode(dev, apdev, params):
"""sigma_dut controlled AP with OWE and transition mode"""
if "OWE" not in dev[0].get_capability("key_mgmt"):
@@ -1494,16 +1619,12 @@ def run_sigma_dut_dpp_qr_resp(dev, apdev, conf_idx, chan_list=None,
finally:
stop_sigma_dut(sigma)
-def test_sigma_dut_dpp_qr_init_enrollee(dev, apdev):
- """sigma_dut DPP/QR initiator as Enrollee"""
- check_dpp_capab(dev[0])
- check_dpp_capab(dev[1])
-
- csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
- ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
+csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
+csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
+ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
+ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
+def start_dpp_ap(apdev):
params = {"ssid": "DPPNET01",
"wpa": "2",
"ieee80211w": "2",
@@ -1513,10 +1634,16 @@ def test_sigma_dut_dpp_qr_init_enrollee(dev, apdev):
"dpp_csign": csign_pub,
"dpp_netaccesskey": ap_netaccesskey}
try:
- hapd = hostapd.add_ap(apdev[0], params)
+ hapd = hostapd.add_ap(apdev, params)
except:
raise HwsimSkip("DPP not supported")
+ return hapd
+def test_sigma_dut_dpp_qr_init_enrollee(dev, apdev):
+ """sigma_dut DPP/QR initiator as Enrollee"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+ hapd = start_dpp_ap(apdev[0])
sigma = start_sigma_dut(dev[0].ifname)
try:
dev[0].set("dpp_config_processing", "2")
@@ -1592,25 +1719,7 @@ def test_sigma_dut_dpp_qr_mutual_init_enrollee_check(dev, apdev):
def run_sigma_dut_dpp_qr_mutual_init_enrollee_check(dev, apdev, extra=''):
check_dpp_capab(dev[0])
check_dpp_capab(dev[1])
-
- csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
- ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
-
- params = {"ssid": "DPPNET01",
- "wpa": "2",
- "ieee80211w": "2",
- "wpa_key_mgmt": "DPP",
- "rsn_pairwise": "CCMP",
- "dpp_connector": ap_connector,
- "dpp_csign": csign_pub,
- "dpp_netaccesskey": ap_netaccesskey}
- try:
- hapd = hostapd.add_ap(apdev[0], params)
- except:
- raise HwsimSkip("DPP not supported")
-
+ hapd = start_dpp_ap(apdev[0])
sigma = start_sigma_dut(dev[0].ifname)
try:
dev[0].set("dpp_config_processing", "2")
@@ -1674,25 +1783,7 @@ def test_sigma_dut_dpp_qr_mutual_resp_enrollee_pending(dev, apdev):
def run_sigma_dut_dpp_qr_mutual_resp_enrollee(dev, apdev, extra=None):
check_dpp_capab(dev[0])
check_dpp_capab(dev[1])
-
- csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
- ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
-
- params = {"ssid": "DPPNET01",
- "wpa": "2",
- "ieee80211w": "2",
- "wpa_key_mgmt": "DPP",
- "rsn_pairwise": "CCMP",
- "dpp_connector": ap_connector,
- "dpp_csign": csign_pub,
- "dpp_netaccesskey": ap_netaccesskey}
- try:
- hapd = hostapd.add_ap(apdev[0], params)
- except:
- raise HwsimSkip("DPP not supported")
-
+ hapd = start_dpp_ap(apdev[0])
sigma = start_sigma_dut(dev[0].ifname)
try:
dev[0].set("dpp_config_processing", "2")
@@ -1763,25 +1854,7 @@ def test_sigma_dut_dpp_qr_mutual_init_enrollee_pending(dev, apdev):
def run_sigma_dut_dpp_qr_mutual_init_enrollee(dev, apdev, resp_pending):
check_dpp_capab(dev[0])
check_dpp_capab(dev[1])
-
- csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
- ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
-
- params = {"ssid": "DPPNET01",
- "wpa": "2",
- "ieee80211w": "2",
- "wpa_key_mgmt": "DPP",
- "rsn_pairwise": "CCMP",
- "dpp_connector": ap_connector,
- "dpp_csign": csign_pub,
- "dpp_netaccesskey": ap_netaccesskey}
- try:
- hapd = hostapd.add_ap(apdev[0], params)
- except:
- raise HwsimSkip("DPP not supported")
-
+ hapd = start_dpp_ap(apdev[0])
sigma = start_sigma_dut(dev[0].ifname)
try:
dev[0].set("dpp_config_processing", "2")
@@ -2558,25 +2631,7 @@ def run_sigma_dut_dpp_proto_responder_pkex(dev, step, frame, attr, result, fail)
def init_sigma_dut_dpp_proto_peer_disc_req(dev, apdev):
check_dpp_capab(dev[0])
check_dpp_capab(dev[1])
-
- csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
- ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
- ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
-
- params = {"ssid": "DPPNET01",
- "wpa": "2",
- "ieee80211w": "2",
- "wpa_key_mgmt": "DPP",
- "rsn_pairwise": "CCMP",
- "dpp_connector": ap_connector,
- "dpp_csign": csign_pub,
- "dpp_netaccesskey": ap_netaccesskey}
- try:
- hapd = hostapd.add_ap(apdev[0], params)
- except:
- raise HwsimSkip("DPP not supported")
-
+ hapd = start_dpp_ap(apdev[0])
dev[0].set("dpp_config_processing", "2")
cmd = "DPP_CONFIGURATOR_ADD key=" + csign
@@ -2798,6 +2853,162 @@ def test_sigma_dut_dpp_tcp_enrollee_init(dev, apdev):
stop_sigma_dut(sigma)
dev[1].request("DPP_CONTROLLER_STOP")
+def test_sigma_dut_dpp_nfc_handover_requestor_enrollee(dev, apdev):
+ """sigma_dut DPP/NFC handover requestor as Enrollee"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+ hapd = start_dpp_ap(apdev[0])
+ sigma = start_sigma_dut(dev[0].ifname)
+ try:
+ dev[0].set("dpp_config_processing", "2")
+
+ cmd = "DPP_CONFIGURATOR_ADD key=" + csign
+ res = dev[1].request(cmd)
+ if "FAIL" in res:
+ raise Exception("Failed to add configurator")
+ conf_id = int(res)
+ dev[1].set("dpp_configurator_params",
+ " conf=sta-dpp ssid=%s configurator=%d" % (to_hex("DPPNET01"), conf_id))
+
+ id_own = dev[1].dpp_bootstrap_gen(type="nfc-uri", chan="81/1,6,11",
+ mac=True)
+ uri_own = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_own)
+
+ res = sigma_dut_cmd_check("dev_exec_action,program,DPP,DPPActionType,GetLocalBootstrap,DPPBS,NFC")
+ hex = res.split(',')[3]
+ uri_peer = from_hex(hex)
+ logger.info("URI from sigma_dut: " + uri_peer)
+
+ sigma_dut_cmd_check("dev_exec_action,program,DPP,DPPActionType,SetPeerBootstrap,DPPBootstrappingdata,%s,DPPBS,NFC" % to_hex(uri_own))
+
+ res = dev[1].request("DPP_NFC_HANDOVER_REQ own=%d uri=%s" % (id_own,
+ uri_peer))
+ if "FAIL" in res:
+ raise Exception("Failed to process NFC Handover Request")
+ info = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_own)
+ logger.info("Updated local bootstrapping info:\n" + info)
+ freq = None
+ for line in info.splitlines():
+ if line.startswith("use_freq="):
+ freq = int(line.split('=')[1])
+ if freq is None:
+ raise Exception("Selected channel not indicated")
+ uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_own)
+ logger.info("Updated URI[1]: " + uri1)
+ dev[1].dpp_listen(freq, role="configurator")
+
+ res = sigma_dut_cmd("dev_exec_action,program,DPP,DPPActionType,AutomaticDPP,DPPAuthRole,Initiator,DPPProvisioningRole,Enrollee,DPPBS,NFC,DPPNFCHandover,Negotiated_Requestor,DPPTimeout,6,DPPWaitForConnect,Yes", timeout=10)
+ if "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK" not in res:
+ raise Exception("Unexpected result: " + res)
+ finally:
+ dev[0].set("dpp_config_processing", "0")
+ stop_sigma_dut(sigma)
+
+def test_sigma_dut_dpp_nfc_handover_selector_enrollee(dev, apdev):
+ """sigma_dut DPP/NFC handover selector as Enrollee"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+ hapd = start_dpp_ap(apdev[0])
+ sigma = start_sigma_dut(dev[0].ifname)
+ try:
+ dev[0].set("dpp_config_processing", "2")
+
+ cmd = "DPP_CONFIGURATOR_ADD key=" + csign
+ res = dev[1].request(cmd)
+ if "FAIL" in res:
+ raise Exception("Failed to add configurator")
+ conf_id = int(res)
+ dev[1].set("dpp_configurator_params",
+ " conf=sta-dpp ssid=%s configurator=%d" % (to_hex("DPPNET01"), conf_id))
+
+ id_own = dev[1].dpp_bootstrap_gen(type="nfc-uri", chan="81/1,6,11",
+ mac=True)
+ uri_own = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_own)
+
+ res = sigma_dut_cmd_check("dev_exec_action,program,DPP,DPPActionType,GetLocalBootstrap,DPPBS,NFC")
+ hex = res.split(',')[3]
+ uri_peer = from_hex(hex)
+ logger.info("URI from sigma_dut: " + uri_peer)
+
+ sigma_dut_cmd_check("dev_exec_action,program,DPP,DPPActionType,SetPeerBootstrap,DPPBootstrappingdata,%s,DPPBS,NFC" % to_hex(uri_own))
+
+ res = dev[1].request("DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (id_own,
+ uri_peer))
+ if "FAIL" in res:
+ raise Exception("Failed to process NFC Handover Select")
+ peer = int(res)
+ dev[1].dpp_auth_init(peer=peer, own=id_own, configurator=conf_id,
+ conf="sta-dpp", ssid="DPPNET01")
+
+ res = sigma_dut_cmd("dev_exec_action,program,DPP,DPPActionType,AutomaticDPP,DPPAuthRole,Initiator,DPPProvisioningRole,Enrollee,DPPBS,NFC,DPPNFCHandover,Negotiated_Selector,DPPTimeout,6,DPPWaitForConnect,Yes", timeout=10)
+ if "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK" not in res:
+ raise Exception("Unexpected result: " + res)
+ finally:
+ dev[0].set("dpp_config_processing", "0")
+ stop_sigma_dut(sigma)
+
+def test_sigma_dut_dpp_nfc_static_read_enrollee(dev, apdev):
+ """sigma_dut DPP/NFC read tag as Enrollee"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+ hapd = start_dpp_ap(apdev[0])
+ sigma = start_sigma_dut(dev[0].ifname)
+ try:
+ dev[0].set("dpp_config_processing", "2")
+
+ cmd = "DPP_CONFIGURATOR_ADD key=" + csign
+ res = dev[1].request(cmd)
+ if "FAIL" in res:
+ raise Exception("Failed to add configurator")
+ conf_id = int(res)
+ dev[1].set("dpp_configurator_params",
+ " conf=sta-dpp ssid=%s configurator=%d" % (to_hex("DPPNET01"), conf_id))
+
+ id_own = dev[1].dpp_bootstrap_gen(type="nfc-uri", chan="81/6", mac=True)
+ uri_own = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_own)
+
+ sigma_dut_cmd_check("dev_exec_action,program,DPP,DPPActionType,SetPeerBootstrap,DPPBootstrappingdata,%s,DPPBS,NFC" % to_hex(uri_own))
+ dev[1].dpp_listen(2437, role="configurator")
+
+ res = sigma_dut_cmd("dev_exec_action,program,DPP,DPPActionType,AutomaticDPP,DPPAuthRole,Initiator,DPPProvisioningRole,Enrollee,DPPBS,NFC,DPPNFCHandover,Static,DPPTimeout,6,DPPWaitForConnect,Yes", timeout=10)
+ if "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK" not in res:
+ raise Exception("Unexpected result: " + res)
+ finally:
+ dev[0].set("dpp_config_processing", "0")
+ stop_sigma_dut(sigma)
+
+def test_sigma_dut_dpp_nfc_static_write_enrollee(dev, apdev):
+ """sigma_dut DPP/NFC write tag as Enrollee"""
+ check_dpp_capab(dev[0])
+ check_dpp_capab(dev[1])
+ hapd = start_dpp_ap(apdev[0])
+ sigma = start_sigma_dut(dev[0].ifname)
+ try:
+ dev[0].set("dpp_config_processing", "2")
+
+ cmd = "DPP_CONFIGURATOR_ADD key=" + csign
+ res = dev[1].request(cmd)
+ if "FAIL" in res:
+ raise Exception("Failed to add configurator")
+ conf_id = int(res)
+ dev[1].set("dpp_configurator_params",
+ " conf=sta-dpp ssid=%s configurator=%d" % (to_hex("DPPNET01"), conf_id))
+
+ res = sigma_dut_cmd_check("dev_exec_action,program,DPP,DPPActionType,GetLocalBootstrap,DPPBS,NFC")
+ hex = res.split(',')[3]
+ uri_peer = from_hex(hex)
+ logger.info("URI from sigma_dut: " + uri_peer)
+
+ dev[1].dpp_auth_init(nfc_uri=uri_peer, configurator=conf_id,
+ conf="sta-dpp", ssid="DPPNET01")
+
+ res = sigma_dut_cmd("dev_exec_action,program,DPP,DPPActionType,AutomaticDPP,DPPAuthRole,Responder,DPPProvisioningRole,Enrollee,DPPBS,NFC,DPPNFCHandover,Static,DPPTimeout,6,DPPWaitForConnect,Yes", timeout=10)
+ if "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK" not in res:
+ raise Exception("Unexpected result: " + res)
+ finally:
+ dev[0].set("dpp_config_processing", "0")
+ stop_sigma_dut(sigma)
+
def test_sigma_dut_preconfigured_profile(dev, apdev):
"""sigma_dut controlled connection using preconfigured profile"""
try:
@@ -2882,6 +3093,34 @@ def test_sigma_dut_sta_scan_ssid_bssid(dev, apdev):
finally:
stop_sigma_dut(sigma)
+def test_sigma_dut_sta_scan_short_ssid(dev, apdev):
+ """sigma_dut sta_scan ShortSSID"""
+ dev[0].flush_scan_cache()
+ ssid = "test-short-ssid-list"
+ hapd = hostapd.add_ap(apdev[0], {"ssid": ssid,
+ "ignore_broadcast_ssid": "1"})
+ bssid = apdev[0]['bssid']
+ payload = struct.pack('>L', binascii.crc32(ssid.encode()))
+ val = binascii.hexlify(payload).decode()
+ sigma = start_sigma_dut(dev[0].ifname)
+ found = False
+ try:
+ cmd = "sta_scan,Interface,%s,ChnlFreq,2412,ShortSSID,%s" % (dev[0].ifname, val)
+ for i in range(10):
+ sigma_dut_cmd_check(cmd, timeout=5)
+ ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
+ if ev is None:
+ raise Exception("Scan did not complete")
+ if bssid in dev[0].request("SCAN_RESULTS"):
+ found = True
+ break
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].request("VENDOR_ELEM_REMOVE 14 *")
+
+ if not found:
+ raise Exception("AP not found in scan results")
+
def test_sigma_dut_ap_osen(dev, apdev, params):
"""sigma_dut controlled AP with OSEN"""
logdir = os.path.join(params['logdir'],
@@ -3809,3 +4048,184 @@ def test_sigma_dut_ap_sae_h2e_group_rejection(dev, apdev, params):
finally:
stop_sigma_dut(sigma)
dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_ap_sae_h2e_anti_clogging(dev, apdev, params):
+ """sigma_dut controlled AP with SAE H2E and anti-clogging token"""
+ logdir = os.path.join(params['logdir'],
+ "sigma_dut_ap_sae_h2e_anti_clogging.sigma-hostapd")
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, sae_h2e=True, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,SAE,PSK,12345678,AntiCloggingThreshold,0")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ dev[0].set("sae_groups", "")
+ dev[0].set("sae_pwe", "2")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412")
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("sae_pwe", "0")
+
+def test_sigma_dut_ap_5ghz(dev, apdev, params):
+ """sigma_dut controlled AP on 5 GHz"""
+ run_sigma_dut_ap_channel(dev, apdev, params, 36, '11na', 5180,
+ check_signal="WIDTH=20 MHz")
+
+def test_sigma_dut_ap_ht40plus(dev, apdev, params):
+ """sigma_dut controlled AP and HT40+"""
+ run_sigma_dut_ap_channel(dev, apdev, params, 36, '11na', 5180,
+ extra="width,40", check_signal="WIDTH=40 MHz")
+
+def test_sigma_dut_ap_ht40minus(dev, apdev, params):
+ """sigma_dut controlled AP and HT40-"""
+ run_sigma_dut_ap_channel(dev, apdev, params, 40, '11na', 5200,
+ extra="width,40", check_signal="WIDTH=40 MHz")
+
+def test_sigma_dut_ap_vht40(dev, apdev, params):
+ """sigma_dut controlled AP and VHT40"""
+ run_sigma_dut_ap_channel(dev, apdev, params, 36, '11ac', 5180,
+ extra="width,40", check_signal="WIDTH=40 MHz",
+ program="VHT")
+
+def test_sigma_dut_ap_vht80(dev, apdev, params):
+ """sigma_dut controlled AP and VHT80"""
+ run_sigma_dut_ap_channel(dev, apdev, params, 36, '11ac', 5180,
+ extra="width,80", check_signal="WIDTH=80 MHz",
+ program="VHT")
+
+def run_sigma_dut_ap_channel(dev, apdev, params, channel, mode, scan_freq,
+ extra=None, check_signal=None, program=None):
+ logdir = params['prefix'] + ".sigma-hostapd"
+ with HWSimRadio() as (radio, iface):
+ subprocess.call(['iw', 'reg', 'set', 'US'])
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
+ try:
+ cmd = "ap_reset_default"
+ if program:
+ cmd += ",program," + program
+ sigma_dut_cmd_check(cmd)
+ cmd = "ap_set_wireless,NAME,AP,CHANNEL,%d,SSID,test-psk,MODE,%s" % (channel, mode)
+ if extra:
+ cmd += "," + extra
+ sigma_dut_cmd_check(cmd)
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-PSK,PSK,12345678")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+
+ with open("/tmp/sigma_dut-ap.conf", "rb") as f:
+ with open(params['prefix'] + ".sigma-conf", "wb") as f2:
+ f2.write(f.read())
+
+ dev[0].connect("test-psk", psk="12345678", scan_freq=str(scan_freq))
+ sig = dev[0].request("SIGNAL_POLL")
+ logger.info("SIGNAL_POLL:\n" + sig.strip())
+ dev[0].request("DISCONNECT")
+ dev[0].wait_disconnected()
+
+ sigma_dut_cmd_check("ap_reset_default")
+
+ if check_signal and check_signal not in sig:
+ raise Exception("Unexpected SIGNAL_POLL data")
+ finally:
+ stop_sigma_dut(sigma)
+ subprocess.call(['iw', 'reg', 'set', '00'])
+ dev[0].flush_scan_cache()
+
+def test_sigma_dut_beacon_prot(dev, apdev):
+ """sigma_dut controlled STA and beacon protection"""
+ ssid = "test-pmf-required"
+ params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
+ params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
+ params["ieee80211w"] = "2"
+ params["beacon_prot"] = "1"
+ try:
+ hapd = hostapd.add_ap(apdev[0], params)
+ except Exception as e:
+ if "Failed to enable hostapd interface" in str(e):
+ raise HwsimSkip("Beacon protection not supported")
+ raise
+
+ ifname = dev[0].ifname
+ sigma = start_sigma_dut(ifname)
+
+ try:
+ sigma_dut_cmd_check("sta_reset_default,interface,%s,prog,PMF" % ifname)
+ sigma_dut_cmd_check("sta_set_ip_config,interface,%s,dhcp,0,ip,127.0.0.11,mask,255.255.255.0" % ifname)
+ sigma_dut_cmd_check("sta_set_security,interface,%s,ssid,%s,type,PSK,passphrase,%s,encpType,aes-ccmp,keymgmttype,wpa2,PMF,Required,BeaconProtection,1" % (ifname, "test-pmf-required", "12345678"))
+ sigma_dut_cmd_check("sta_associate,interface,%s,ssid,%s,channel,1" % (ifname, "test-pmf-required"),
+ timeout=10)
+ sigma_dut_wait_connected(ifname)
+
+ time.sleep(1)
+ check_mac80211_bigtk(dev[0], hapd)
+
+ sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
+ finally:
+ stop_sigma_dut(sigma)
+ dev[0].set("ignore_old_scan_res", "0")
+
+def test_sigma_dut_ap_beacon_prot(dev, apdev, params):
+ """sigma_dut controlled AP and beacon protection"""
+ logdir = params['prefix'] + ".sigma-hostapd"
+
+ Wlantest.setup(None)
+ wt = Wlantest()
+ wt.flush()
+ wt.add_passphrase("12345678")
+
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-psk,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-PSK,PSK,12345678,PMF,Required,BeaconProtection,1")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+ bssid = sigma_dut_cmd_check("ap_get_mac_address,NAME,AP")
+
+ dev[0].connect("test-psk", key_mgmt="WPA-PSK-SHA256",
+ psk="12345678", scan_freq="2412",
+ ieee80211w="2", beacon_prot="1")
+ time.sleep(1)
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
+
+ valid_bip = wt.get_bss_counter('valid_bip_mmie', bssid)
+ invalid_bip = wt.get_bss_counter('invalid_bip_mmie', bssid)
+ missing_bip = wt.get_bss_counter('missing_bip_mmie', bssid)
+ logger.info("wlantest BIP counters: valid=%d invalid=%d missing=%d" % (valid_bip, invalid_bip, missing_bip))
+ if valid_bip < 0 or invalid_bip > 0 or missing_bip > 0:
+ raise Exception("Unexpected wlantest BIP counters: valid=%d invalid=%d missing=%d" % (valid_bip, invalid_bip, missing_bip))
+
+def test_sigma_dut_ap_transition_disable(dev, apdev, params):
+ """sigma_dut controlled AP and transition disabled indication"""
+ logdir = params['prefix'] + ".sigma-hostapd"
+
+ with HWSimRadio() as (radio, iface):
+ sigma = start_sigma_dut(iface, hostapd_logdir=logdir)
+ try:
+ sigma_dut_cmd_check("ap_reset_default")
+ sigma_dut_cmd_check("ap_set_wireless,NAME,AP,CHANNEL,1,SSID,test-sae,MODE,11ng")
+ sigma_dut_cmd_check("ap_set_security,NAME,AP,KEYMGNT,WPA2-SAE,PSK,12345678,PMF,Required,Transition_Disable,1,Transition_Disable_Index,0")
+ sigma_dut_cmd_check("ap_config_commit,NAME,AP")
+ bssid = sigma_dut_cmd_check("ap_get_mac_address,NAME,AP")
+
+ dev[0].set("sae_groups", "")
+ dev[0].connect("test-sae", key_mgmt="SAE", psk="12345678",
+ ieee80211w="2", scan_freq="2412")
+ ev = dev[0].wait_event(["TRANSITION-DISABLE"], timeout=1)
+ if ev is None:
+ raise Exception("Transition disable not indicated")
+ if ev.split(' ')[1] != "01":
+ raise Exception("Unexpected transition disable bitmap: " + ev)
+
+ sigma_dut_cmd_check("ap_reset_default")
+ finally:
+ stop_sigma_dut(sigma)
diff --git a/tests/hwsim/test_wep.py b/tests/hwsim/test_wep.py
index d6af730..38e3496 100644
--- a/tests/hwsim/test_wep.py
+++ b/tests/hwsim/test_wep.py
@@ -11,11 +11,16 @@ import subprocess
from remotehost import remote_compatible
import hostapd
import hwsim_utils
-from utils import clear_regdom
+from utils import clear_regdom, HwsimSkip
+
+def check_wep_capa(dev):
+ if "WEP40" not in dev.get_capability("group"):
+ raise HwsimSkip("WEP not supported")
@remote_compatible
def test_wep_open_auth(dev, apdev):
"""WEP Open System authentication"""
+ check_wep_capa(dev[0])
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-open",
"wep_key0": '"hello"'})
@@ -35,6 +40,8 @@ def test_wep_open_auth(dev, apdev):
@remote_compatible
def test_wep_shared_key_auth(dev, apdev):
"""WEP Shared Key authentication"""
+ check_wep_capa(dev[0])
+ check_wep_capa(dev[1])
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-shared-key",
"wep_key0": '"hello12345678"',
@@ -50,6 +57,7 @@ def test_wep_shared_key_auth(dev, apdev):
@remote_compatible
def test_wep_shared_key_auth_not_allowed(dev, apdev):
"""WEP Shared Key authentication not allowed"""
+ check_wep_capa(dev[0])
hostapd.add_ap(apdev[0],
{"ssid": "wep-shared-key",
"wep_key0": '"hello12345678"',
@@ -63,6 +71,9 @@ def test_wep_shared_key_auth_not_allowed(dev, apdev):
def test_wep_shared_key_auth_multi_key(dev, apdev):
"""WEP Shared Key authentication with multiple keys"""
+ check_wep_capa(dev[0])
+ check_wep_capa(dev[1])
+ check_wep_capa(dev[2])
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-shared-key",
"wep_key0": '"hello12345678"',
@@ -92,6 +103,7 @@ def test_wep_shared_key_auth_multi_key(dev, apdev):
def test_wep_ht_vht(dev, apdev):
"""WEP and HT/VHT"""
+ check_wep_capa(dev[0])
dev[0].flush_scan_cache()
try:
hapd = None
@@ -124,6 +136,7 @@ def test_wep_ht_vht(dev, apdev):
def test_wep_ifdown(dev, apdev):
"""AP with WEP and external ifconfig down"""
+ check_wep_capa(dev[0])
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-open",
"wep_key0": '"hello"'})
diff --git a/tests/hwsim/test_wext.py b/tests/hwsim/test_wext.py
index 1668ccd..8e1ed71 100644
--- a/tests/hwsim/test_wext.py
+++ b/tests/hwsim/test_wext.py
@@ -13,6 +13,7 @@ import hwsim_utils
from wpasupplicant import WpaSupplicant
from utils import HwsimSkip, skip_with_fips
from test_rfkill import get_rfkill
+from test_wep import check_wep_capa
def get_wext_interface():
if not os.path.exists("/proc/net/wireless"):
@@ -149,6 +150,7 @@ def test_wext_pmksa_cache(dev, apdev):
def test_wext_wep_open_auth(dev, apdev):
"""WEP Open System authentication"""
wpas = get_wext_interface()
+ check_wep_capa(wpas)
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-open",
@@ -162,6 +164,7 @@ def test_wext_wep_open_auth(dev, apdev):
def test_wext_wep_shared_key_auth(dev, apdev):
"""WEP Shared Key authentication"""
wpas = get_wext_interface()
+ check_wep_capa(wpas)
hapd = hostapd.add_ap(apdev[0],
{"ssid": "wep-shared-key",
diff --git a/tests/hwsim/test_wpas_ap.py b/tests/hwsim/test_wpas_ap.py
index 5d6dfed..8211b6b 100644
--- a/tests/hwsim/test_wpas_ap.py
+++ b/tests/hwsim/test_wpas_ap.py
@@ -4,6 +4,7 @@
# This software may be distributed under the terms of the BSD license.
# See README for more details.
+import hostapd
from remotehost import remote_compatible
import time
import logging
@@ -13,6 +14,7 @@ import hwsim_utils
from utils import HwsimSkip, alloc_fail, clear_regdom_dev
from wpasupplicant import WpaSupplicant
from test_p2p_channel import set_country
+from test_wep import check_wep_capa
def wait_ap_ready(dev):
ev = dev.wait_event(["CTRL-EVENT-CONNECTED"])
@@ -103,6 +105,7 @@ def test_wpas_ap_open_isolate(dev):
@remote_compatible
def test_wpas_ap_wep(dev):
"""wpa_supplicant AP mode - WEP"""
+ check_wep_capa(dev[0])
id = dev[0].add_network()
dev[0].set_network(id, "mode", "2")
dev[0].set_network_quoted(id, "ssid", "wpas-ap-wep")
@@ -540,17 +543,18 @@ def test_wpas_ap_oom(dev):
dev[0].wait_disconnected()
dev[0].request("REMOVE_NETWORK all")
- id = dev[0].add_network()
- dev[0].set_network(id, "mode", "2")
- dev[0].set_network_quoted(id, "ssid", "wpas-ap")
- dev[0].set_network(id, "key_mgmt", "NONE")
- dev[0].set_network_quoted(id, "wep_key0", "hello")
- dev[0].set_network(id, "frequency", "2412")
- dev[0].set_network(id, "scan_freq", "2412")
- with alloc_fail(dev[0], 1, "=wpa_supplicant_conf_ap"):
- dev[0].select_network(id)
- dev[0].wait_disconnected()
- dev[0].request("REMOVE_NETWORK all")
+ if "WEP40" in dev[0].get_capability("group"):
+ id = dev[0].add_network()
+ dev[0].set_network(id, "mode", "2")
+ dev[0].set_network_quoted(id, "ssid", "wpas-ap")
+ dev[0].set_network(id, "key_mgmt", "NONE")
+ dev[0].set_network_quoted(id, "wep_key0", "hello")
+ dev[0].set_network(id, "frequency", "2412")
+ dev[0].set_network(id, "scan_freq", "2412")
+ with alloc_fail(dev[0], 1, "=wpa_supplicant_conf_ap"):
+ dev[0].select_network(id)
+ dev[0].wait_disconnected()
+ dev[0].request("REMOVE_NETWORK all")
wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
wpas.interface_add("wlan5")
@@ -812,3 +816,91 @@ def run_wpas_ap_sae(dev, sae_password, sae_password_id=False):
dev[1].request("SET sae_groups ")
dev[1].connect("wpas-ap-sae", key_mgmt="SAE", sae_password="12345678",
sae_password_id=pw_id, scan_freq="2412")
+
+def test_wpas_ap_scan(dev, apdev):
+ """wpa_supplicant AP mode and scanning"""
+ dev[0].flush_scan_cache()
+
+ hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
+ bssid = hapd.own_addr()
+
+ id = dev[0].add_network()
+ dev[0].set_network(id, "mode", "2")
+ dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
+ dev[0].set_network(id, "key_mgmt", "NONE")
+ dev[0].set_network(id, "frequency", "2412")
+ dev[0].set_network(id, "scan_freq", "2412")
+ dev[0].select_network(id)
+ wait_ap_ready(dev[0])
+ dev[0].dump_monitor()
+
+ if "OK" not in dev[0].request("SCAN freq=2412"):
+ raise Exception("SCAN command not accepted")
+ ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS",
+ "CTRL-EVENT-SCAN-FAILED"], 15)
+ if ev is None:
+ raise Exception("Scan result timed out")
+ if "CTRL-EVENT-SCAN-FAILED ret=-95" in ev:
+ # Scanning in AP mode not supported
+ return
+ if "CTRL-EVENT-SCAN-FAILED" in ev:
+ raise Exception("Unexpected scan failure reason: " + ev)
+ if "CTRL-EVENT-SCAN-RESULTS" in ev:
+ bss = dev[0].get_bss(bssid)
+ if not bss:
+ raise Exception("AP not found in scan")
+
+def test_wpas_ap_sae(dev):
+ """wpa_supplicant AP mode - SAE using psk"""
+ run_wpas_ap_sae(dev, False)
+
+def test_wpas_ap_sae_and_psk_transition_disable(dev):
+ """wpa_supplicant AP mode - SAE+PSK transition disable indication"""
+ if "SAE" not in dev[0].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ if "SAE" not in dev[1].get_capability("auth_alg"):
+ raise HwsimSkip("SAE not supported")
+ dev[0].set("sae_groups", "")
+ id = dev[0].add_network()
+ dev[0].set_network(id, "mode", "2")
+ dev[0].set_network_quoted(id, "ssid", "wpas-ap-sae")
+ dev[0].set_network(id, "proto", "WPA2")
+ dev[0].set_network(id, "key_mgmt", "SAE")
+ dev[0].set_network(id, "transition_disable", "1")
+ dev[0].set_network(id, "ieee80211w", "1")
+ dev[0].set_network(id, "pairwise", "CCMP")
+ dev[0].set_network(id, "group", "CCMP")
+ dev[0].set_network_quoted(id, "psk", "12345678")
+ dev[0].set_network(id, "frequency", "2412")
+ dev[0].set_network(id, "scan_freq", "2412")
+ dev[0].set_network(id, "wps_disabled", "1")
+ dev[0].select_network(id)
+ wait_ap_ready(dev[0])
+
+ dev[1].set("sae_groups", "")
+ dev[1].connect("wpas-ap-sae", key_mgmt="SAE WPA-PSK",
+ psk="12345678", ieee80211w="1",
+ scan_freq="2412")
+ ev = dev[1].wait_event(["TRANSITION-DISABLE"], timeout=1)
+ if ev is None:
+ raise Exception("Transition disable not indicated")
+ if ev.split(' ')[1] != "01":
+ raise Exception("Unexpected transition disable bitmap: " + ev)
+
+ val = dev[1].get_network(id, "ieee80211w")
+ if val != "2":
+ raise Exception("Unexpected ieee80211w value: " + val)
+ val = dev[1].get_network(id, "key_mgmt")
+ if val != "SAE":
+ raise Exception("Unexpected key_mgmt value: " + val)
+ val = dev[1].get_network(id, "group")
+ if val != "CCMP":
+ raise Exception("Unexpected group value: " + val)
+ val = dev[1].get_network(id, "proto")
+ if val != "RSN":
+ raise Exception("Unexpected proto value: " + val)
+
+ dev[1].request("DISCONNECT")
+ dev[1].wait_disconnected()
+ dev[1].request("RECONNECT")
+ dev[1].wait_connected()
diff --git a/tests/hwsim/test_wpas_config.py b/tests/hwsim/test_wpas_config.py
index ba40825..14816a0 100644
--- a/tests/hwsim/test_wpas_config.py
+++ b/tests/hwsim/test_wpas_config.py
@@ -10,6 +10,7 @@ import os
from wpasupplicant import WpaSupplicant
import hostapd
+from test_sae import check_sae_capab
config_checks = [("ap_scan", "0"),
("update_config", "1"),
@@ -594,3 +595,60 @@ def test_wpas_config_file_key_mgmt(dev, apdev, params):
wpas.interface_remove("wlan5")
wpas.interface_add("wlan5", config=config)
+
+def check_network_config(config, network_expected, check=None):
+ with open(config, "r") as f:
+ data = f.read()
+ logger.info("Configuration file contents:\n" + data.rstrip())
+ if network_expected and "network=" not in data:
+ raise Exception("Missing network block in configuration data")
+ if not network_expected and "network=" in data:
+ raise Exception("Unexpected network block in configuration data")
+ if check and check not in data:
+ raise Exception("Missing " + check)
+
+def test_wpas_config_file_sae(dev, apdev, params):
+ """wpa_supplicant config file writing with SAE"""
+ config = os.path.join(params['logdir'], 'wpas_config_file_sae.conf')
+ with open(config, "w") as f:
+ f.write("update_config=1\n")
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5", config=config)
+ check_sae_capab(wpas)
+
+ # Valid SAE configuration with sae_password
+ wpas.connect("test-sae", sae_password="sae-password", key_mgmt="SAE",
+ only_add_network=True)
+ wpas.save_config()
+ check_network_config(config, True, check="key_mgmt=SAE")
+
+ wpas.request("REMOVE_NETWORK all")
+ wpas.save_config()
+ check_network_config(config, False)
+
+ # Valid SAE configuration with psk
+ wpas.connect("test-sae", psk="sae-password", key_mgmt="SAE",
+ only_add_network=True)
+ wpas.save_config()
+ check_network_config(config, True, check="key_mgmt=SAE")
+ wpas.request("REMOVE_NETWORK all")
+
+ # Invalid PSK configuration with sae_password
+ wpas.connect("test-psk", sae_password="sae-password", key_mgmt="WPA-PSK",
+ only_add_network=True)
+ wpas.save_config()
+ check_network_config(config, False)
+
+ # Invalid SAE configuration with raw_psk
+ wpas.connect("test-sae", raw_psk=32*"00", key_mgmt="SAE",
+ only_add_network=True)
+ wpas.save_config()
+ check_network_config(config, False)
+
+def test_wpas_config_update_without_file(dev, apdev):
+ """wpa_supplicant SAVE_CONFIG without config file"""
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5")
+ wpas.set("update_config", "1")
+ if "FAIL" not in wpas.request("SAVE_CONFIG"):
+ raise Exception("SAVE_CONFIG accepted unexpectedly")
diff --git a/tests/hwsim/test_wpas_ctrl.py b/tests/hwsim/test_wpas_ctrl.py
index 91f4401..cd30534 100644
--- a/tests/hwsim/test_wpas_ctrl.py
+++ b/tests/hwsim/test_wpas_ctrl.py
@@ -145,11 +145,12 @@ def test_wpas_ctrl_network(dev):
if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' identity 12x3'):
raise Exception("Unexpected success for invalid identity string")
- for i in range(0, 4):
- if "FAIL" in dev[0].request("SET_NETWORK " + str(id) + ' wep_key' + str(i) + ' aabbccddee'):
- raise Exception("Unexpected wep_key set failure")
- if dev[0].get_network(id, "wep_key" + str(i)) != '*':
- raise Exception("Unexpected wep_key get failure")
+ if "WEP40" in dev[0].get_capability("group"):
+ for i in range(0, 4):
+ if "FAIL" in dev[0].request("SET_NETWORK " + str(id) + ' wep_key' + str(i) + ' aabbccddee'):
+ raise Exception("Unexpected wep_key set failure")
+ if dev[0].get_network(id, "wep_key" + str(i)) != '*':
+ raise Exception("Unexpected wep_key get failure")
if "FAIL" in dev[0].request("SET_NETWORK " + str(id) + ' psk_list P2P-00:11:22:33:44:55-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'):
raise Exception("Unexpected failure for psk_list string")
@@ -205,11 +206,12 @@ def test_wpas_ctrl_network(dev):
raise Exception("Invalid WEP key accepted")
if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' wep_key0 "12345678901234567"'):
raise Exception("Too long WEP key accepted")
- # too short WEP key is ignored
- dev[0].set_network_quoted(id, "wep_key0", "1234")
- dev[0].set_network_quoted(id, "wep_key1", "12345")
- dev[0].set_network_quoted(id, "wep_key2", "1234567890123")
- dev[0].set_network_quoted(id, "wep_key3", "1234567890123456")
+ if "WEP40" in dev[0].get_capability("group"):
+ # too short WEP key is ignored
+ dev[0].set_network_quoted(id, "wep_key0", "1234")
+ dev[0].set_network_quoted(id, "wep_key1", "12345")
+ dev[0].set_network_quoted(id, "wep_key2", "1234567890123")
+ dev[0].set_network_quoted(id, "wep_key3", "1234567890123456")
dev[0].set_network(id, "go_p2p_dev_addr", "any")
if dev[0].get_network(id, "go_p2p_dev_addr") is not None:
diff --git a/tests/hwsim/test_wpas_mesh.py b/tests/hwsim/test_wpas_mesh.py
index 85dd384..ed38ac1 100644
--- a/tests/hwsim/test_wpas_mesh.py
+++ b/tests/hwsim/test_wpas_mesh.py
@@ -219,6 +219,16 @@ def test_wpas_mesh_open(dev, apdev):
if mode != "mesh":
raise Exception("Unexpected mode: " + mode)
+ dev[0].scan(freq="2462")
+ bss = dev[0].get_bss(dev[1].own_addr())
+ if bss and 'ie' in bss and "ff0724" in bss['ie']:
+ sta = dev[0].request("STA " + dev[1].own_addr())
+ logger.info("STA info:\n" + sta.rstrip())
+ if "[HE]" not in sta:
+ raise Exception("Missing STA HE flag")
+ if "[VHT]" in sta:
+ raise Exception("Unexpected STA VHT flag")
+
def test_wpas_mesh_open_no_auto(dev, apdev):
"""wpa_supplicant open MESH network connectivity"""
check_mesh_support(dev[0])
@@ -1059,6 +1069,14 @@ def _test_wpas_mesh_open_vht40(dev, apdev):
if "CENTER_FRQ1=5190" not in sig:
raise Exception("Unexpected SIGNAL_POLL value(3b): " + str(sig))
+ dev[0].scan(freq="5180")
+ bss = dev[0].get_bss(dev[1].own_addr())
+ if bss and 'ie' in bss and "ff0724" in bss['ie']:
+ sta = dev[0].request("STA " + dev[1].own_addr())
+ logger.info("STA info:\n" + sta.rstrip())
+ if "[HT][VHT][HE]" not in sta:
+ raise Exception("Missing STA flags")
+
dev[0].mesh_group_remove()
dev[1].mesh_group_remove()
check_mesh_group_removed(dev[0])
diff --git a/tests/hwsim/utils.py b/tests/hwsim/utils.py
index b3a8831..1e7e56c 100644
--- a/tests/hwsim/utils.py
+++ b/tests/hwsim/utils.py
@@ -89,6 +89,11 @@ def skip_with_fips(dev, reason="Not supported in FIPS mode"):
if res and 'FIPS' in res:
raise HwsimSkip(reason)
+def check_ext_key_id_capa(dev):
+ res = dev.get_driver_status_field('capa.flags')
+ if (int(res, 0) & 0x8000000000000000) == 0:
+ raise HwsimSkip("Extended Key ID not supported")
+
def get_phy(ap, ifname=None):
phy = "phy3"
try:
@@ -162,7 +167,7 @@ def clear_regdom_dev(dev, count=1):
dev[i].request("DISCONNECT")
for i in range(count):
dev[i].disconnect_and_stop_scan()
- subprocess.call(['iw', 'reg', 'set', '00'])
+ dev[0].cmd_execute(['iw', 'reg', 'set', '00'])
wait_regdom_changes(dev[0])
country = dev[0].get_driver_status_field("country")
logger.info("Country code at the end: " + country)
diff --git a/tests/hwsim/vm/README b/tests/hwsim/vm/README
index 4cea85b..224d65a 100644
--- a/tests/hwsim/vm/README
+++ b/tests/hwsim/vm/README
@@ -1,9 +1,23 @@
-These scripts allow you to run the hwsim tests inside a KVM virtual machine.
+These scripts allow you to run the hwsim tests inside a KVM virtual machine or
+as a UML (User Mode Linux) program.
-To set it up, first compile a kernel with the kernel-config file as the
-.config. You can adjust it as needed, the configuration is for a 64-bit
-x86 system and should be close to minimal. The architecture must be the
-same as your host since the host's filesystem is used.
+To set it up, first compile a kernel with the kernel-config[.uml] file as the
+.config. You can adjust it as needed, the configuration is for a 64-bit x86
+system and should be close to minimal. The architecture must be the same as
+your host since the host's filesystem is used.
+
+To build the regular x86_64 kernel, simply issue
+
+yes "" | make -j <n_cpus>
+
+or to build UML:
+
+yes "" | ARCH=um make -j <n_cpus>
+
+Running a UML kernel is recommended as it can optimize out any sleep()s or
+kernel timers by taking advantage of UML time travel mode, greatly increasing
+test efficiency (~3200 tests can be run in under 5 minutes using parallel-vm.py
+on a 24 core CPU).
Install the required tools: at least 'kvm', if you want tracing trace-cmd,
valgrind if you want, etc.
diff --git a/tests/hwsim/vm/kernel-config b/tests/hwsim/vm/kernel-config
index e41d698..2aff20a 100644
--- a/tests/hwsim/vm/kernel-config
+++ b/tests/hwsim/vm/kernel-config
@@ -1,905 +1,82 @@
-#
-# Automatically generated file; DO NOT EDIT.
-# Linux/x86 4.10.0-rc5 Kernel Configuration
-#
-CONFIG_64BIT=y
-CONFIG_X86_64=y
-CONFIG_X86=y
-CONFIG_INSTRUCTION_DECODER=y
-CONFIG_OUTPUT_FORMAT="elf64-x86-64"
-CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_MMU=y
-CONFIG_ARCH_MMAP_RND_BITS_MIN=28
-CONFIG_ARCH_MMAP_RND_BITS_MAX=32
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_HAS_CPU_RELAX=y
-CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
-CONFIG_HAVE_SETUP_PER_CPU_AREA=y
-CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
-CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
-CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
-CONFIG_ZONE_DMA32=y
-CONFIG_AUDIT_ARCH=y
-CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
-CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
-CONFIG_X86_64_SMP=y
-CONFIG_ARCH_SUPPORTS_UPROBES=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_DEBUG_RODATA=y
-CONFIG_PGTABLE_LEVELS=4
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_IRQ_WORK=y
-CONFIG_BUILDTIME_EXTABLE_SORT=y
-CONFIG_THREAD_INFO_IN_TASK=y
-
-#
-# General setup
-#
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE=""
-# CONFIG_COMPILE_TEST is not set
-CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_BZIP2=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_XZ=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_HAVE_KERNEL_LZ4=y
-# CONFIG_KERNEL_GZIP is not set
CONFIG_KERNEL_BZIP2=y
-# CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_XZ is not set
-# CONFIG_KERNEL_LZO is not set
-# CONFIG_KERNEL_LZ4 is not set
-CONFIG_DEFAULT_HOSTNAME="(none)"
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
-# CONFIG_FHANDLE is not set
-# CONFIG_USELIB is not set
-# CONFIG_AUDIT is not set
-CONFIG_HAVE_ARCH_AUDITSYSCALL=y
-
-#
-# IRQ subsystem
-#
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-# CONFIG_IRQ_DOMAIN_DEBUG is not set
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_CLOCKSOURCE_WATCHDOG=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-
-#
-# Timers subsystem
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ_COMMON=y
-# CONFIG_HZ_PERIODIC is not set
-CONFIG_NO_HZ_IDLE=y
-# CONFIG_NO_HZ_FULL is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
-
-#
-# CPU/Task time and stats accounting
-#
-CONFIG_TICK_CPU_ACCOUNTING=y
-# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
-# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_PREEMPT=y
CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
-
-#
-# RCU Subsystem
-#
-CONFIG_PREEMPT_RCU=y
-# CONFIG_RCU_EXPERT is not set
-CONFIG_SRCU=y
-# CONFIG_TASKS_RCU is not set
-CONFIG_RCU_STALL_COMMON=y
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_RCU_EXPEDITE_BOOT is not set
-# CONFIG_BUILD_BIN2C is not set
-# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=21
-CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
-CONFIG_NMI_LOG_BUF_SHIFT=13
-CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
-CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
-CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
-CONFIG_ARCH_SUPPORTS_INT128=y
-# CONFIG_CGROUPS is not set
-# CONFIG_CHECKPOINT_RESTORE is not set
-# CONFIG_NAMESPACES is not set
-# CONFIG_SCHED_AUTOGROUP is not set
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_HAVE_PCSPKR_PLATFORM=y
-CONFIG_BPF=y
-CONFIG_EXPERT=y
-CONFIG_MULTIUSER=y
-CONFIG_SGETMASK_SYSCALL=y
-CONFIG_SYSFS_SYSCALL=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_POSIX_TIMERS=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y
-CONFIG_KALLSYMS_BASE_RELATIVE=y
-CONFIG_PRINTK=y
-CONFIG_PRINTK_NMI=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_PCSPKR_PLATFORM=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-# CONFIG_BPF_SYSCALL is not set
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_ADVISE_SYSCALLS=y
-# CONFIG_USERFAULTFD is not set
-CONFIG_PCI_QUIRKS=y
-CONFIG_MEMBARRIER=y
+CONFIG_NAMESPACES=y
+# CONFIG_FHANDLE is not set
CONFIG_EMBEDDED=y
-CONFIG_HAVE_PERF_EVENTS=y
-
-#
-# Kernel Performance Events And Counters
-#
-CONFIG_PERF_EVENTS=y
-# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
# CONFIG_COMPAT_BRK is not set
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_SLAB_FREELIST_RANDOM is not set
-CONFIG_SLUB_CPU_PARTIAL=y
-# CONFIG_SYSTEM_DATA_VERIFICATION is not set
-# CONFIG_PROFILING is not set
-CONFIG_TRACEPOINTS=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_OPROFILE_NMI_TIMER=y
-CONFIG_JUMP_LABEL=y
-# CONFIG_STATIC_KEYS_SELFTEST is not set
-# CONFIG_UPROBES is not set
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_ARCH_USE_BUILTIN_BSWAP=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_OPTPROBES=y
-CONFIG_HAVE_KPROBES_ON_FTRACE=y
-CONFIG_HAVE_NMI=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_HW_BREAKPOINT=y
-CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
-CONFIG_HAVE_USER_RETURN_NOTIFIER=y
-CONFIG_HAVE_PERF_EVENTS_NMI=y
-CONFIG_HAVE_PERF_REGS=y
-CONFIG_HAVE_PERF_USER_STACK_DUMP=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
-CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
-CONFIG_HAVE_CMPXCHG_LOCAL=y
-CONFIG_HAVE_CMPXCHG_DOUBLE=y
-CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
-CONFIG_HAVE_GCC_PLUGINS=y
-# CONFIG_GCC_PLUGINS is not set
-CONFIG_HAVE_CC_STACKPROTECTOR=y
-# CONFIG_CC_STACKPROTECTOR is not set
-CONFIG_CC_STACKPROTECTOR_NONE=y
-# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
-# CONFIG_CC_STACKPROTECTOR_STRONG is not set
-CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
-CONFIG_HAVE_ARCH_HUGE_VMAP=y
-CONFIG_HAVE_ARCH_SOFT_DIRTY=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
-CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
-CONFIG_HAVE_EXIT_THREAD=y
-CONFIG_ARCH_MMAP_RND_BITS=28
-CONFIG_HAVE_COPY_THREAD_TLS=y
-CONFIG_HAVE_STACK_VALIDATION=y
-# CONFIG_HAVE_ARCH_HASH is not set
-# CONFIG_ISA_BUS_API is not set
-# CONFIG_CPU_NO_EFFICIENT_FFS is not set
-CONFIG_HAVE_ARCH_VMAP_STACK=y
-CONFIG_VMAP_STACK=y
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-# CONFIG_MODULES is not set
-CONFIG_MODULES_TREE_LOOKUP=y
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_BSGLIB is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_DEV_ZONED is not set
-# CONFIG_BLK_CMDLINE_PARSER is not set
-# CONFIG_BLK_WBT is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_AIX_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_SYSV68_PARTITION is not set
-# CONFIG_CMDLINE_PARTITION is not set
-CONFIG_BLK_MQ_PCI=y
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_RWLOCKS=y
-# CONFIG_FREEZER is not set
-
-#
-# Processor type and features
-#
-CONFIG_ZONE_DMA=y
CONFIG_SMP=y
-CONFIG_X86_FEATURE_NAMES=y
-CONFIG_X86_FAST_FEATURE_TESTS=y
-# CONFIG_X86_X2APIC is not set
-CONFIG_X86_MPPARSE=y
-# CONFIG_GOLDFISH is not set
-# CONFIG_INTEL_RDT_A is not set
# CONFIG_X86_EXTENDED_PLATFORM is not set
-# CONFIG_X86_INTEL_LPSS is not set
-# CONFIG_X86_AMD_PLATFORM_DEVICE is not set
-# CONFIG_IOSF_MBI is not set
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_HYPERVISOR_GUEST=y
CONFIG_PARAVIRT=y
-# CONFIG_PARAVIRT_DEBUG is not set
CONFIG_PARAVIRT_SPINLOCKS=y
-# CONFIG_QUEUED_LOCK_STAT is not set
-# CONFIG_XEN is not set
-CONFIG_KVM_GUEST=y
-# CONFIG_KVM_DEBUG_FS is not set
-# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
-CONFIG_PARAVIRT_CLOCK=y
-CONFIG_NO_BOOTMEM=y
-# CONFIG_MK8 is not set
-# CONFIG_MPSC is not set
CONFIG_MCORE2=y
-# CONFIG_MATOM is not set
-# CONFIG_GENERIC_CPU is not set
-CONFIG_X86_INTERNODE_CACHE_SHIFT=6
-CONFIG_X86_L1_CACHE_SHIFT=6
-CONFIG_X86_INTEL_USERCOPY=y
-CONFIG_X86_USE_PPRO_CHECKSUM=y
-CONFIG_X86_P6_NOP=y
-CONFIG_X86_TSC=y
-CONFIG_X86_CMPXCHG64=y
-CONFIG_X86_CMOV=y
-CONFIG_X86_MINIMUM_CPU_FAMILY=64
-CONFIG_X86_DEBUGCTLMSR=y
-# CONFIG_PROCESSOR_SELECT is not set
-CONFIG_CPU_SUP_INTEL=y
-CONFIG_CPU_SUP_AMD=y
-CONFIG_CPU_SUP_CENTAUR=y
-CONFIG_HPET_TIMER=y
-CONFIG_DMI=y
CONFIG_GART_IOMMU=y
-# CONFIG_CALGARY_IOMMU is not set
-CONFIG_SWIOTLB=y
-CONFIG_IOMMU_HELPER=y
-# CONFIG_MAXSMP is not set
CONFIG_NR_CPUS=4
-# CONFIG_SCHED_SMT is not set
-CONFIG_SCHED_MC=y
-CONFIG_SCHED_MC_PRIO=y
-# CONFIG_PREEMPT_NONE is not set
-# CONFIG_PREEMPT_VOLUNTARY is not set
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_COUNT=y
-CONFIG_X86_LOCAL_APIC=y
-CONFIG_X86_IO_APIC=y
-# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
# CONFIG_X86_MCE is not set
-
-#
-# Performance monitoring
-#
-CONFIG_PERF_EVENTS_INTEL_UNCORE=y
-CONFIG_PERF_EVENTS_INTEL_RAPL=y
-CONFIG_PERF_EVENTS_INTEL_CSTATE=y
-# CONFIG_PERF_EVENTS_AMD_POWER is not set
-# CONFIG_VM86 is not set
-CONFIG_X86_16BIT=y
-CONFIG_X86_ESPFIX64=y
-CONFIG_X86_VSYSCALL_EMULATION=y
-# CONFIG_I8K is not set
-CONFIG_MICROCODE=y
-CONFIG_MICROCODE_INTEL=y
-# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
-# CONFIG_X86_MSR is not set
-# CONFIG_X86_CPUID is not set
-CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-# CONFIG_NUMA is not set
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_PROC_KCORE_TEXT=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_SPARSEMEM_MANUAL=y
-CONFIG_SPARSEMEM=y
-CONFIG_HAVE_MEMORY_PRESENT=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
-CONFIG_SPARSEMEM_VMEMMAP=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
-CONFIG_ARCH_DISCARD_MEMBLOCK=y
-# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
-# CONFIG_MEMORY_HOTPLUG is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
-# CONFIG_COMPACTION is not set
-CONFIG_PHYS_ADDR_T_64BIT=y
-# CONFIG_BOUNCE is not set
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_KSM is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
-# CONFIG_TRANSPARENT_HUGEPAGE is not set
-# CONFIG_CLEANCACHE is not set
-# CONFIG_CMA is not set
-# CONFIG_ZPOOL is not set
-# CONFIG_ZBUD is not set
-# CONFIG_ZSMALLOC is not set
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y
-# CONFIG_IDLE_PAGE_TRACKING is not set
-CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
-CONFIG_ARCH_HAS_PKEYS=y
-# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
-CONFIG_X86_RESERVE_LOW=64
-CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
-CONFIG_X86_PAT=y
-CONFIG_ARCH_USES_PG_UNCACHED=y
-CONFIG_ARCH_RANDOM=y
-CONFIG_X86_SMAP=y
-# CONFIG_X86_INTEL_MPX is not set
-CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
-# CONFIG_EFI is not set
# CONFIG_SECCOMP is not set
CONFIG_HZ_100=y
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=100
-CONFIG_SCHED_HRTICK=y
-# CONFIG_KEXEC is not set
-# CONFIG_KEXEC_FILE is not set
-# CONFIG_CRASH_DUMP is not set
-CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x1000000
-# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_LEGACY_VSYSCALL_NATIVE is not set
CONFIG_LEGACY_VSYSCALL_EMULATE=y
-# CONFIG_LEGACY_VSYSCALL_NONE is not set
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_MODIFY_LDT_SYSCALL=y
-CONFIG_HAVE_LIVEPATCH=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-
-#
-# Power management and ACPI options
-#
# CONFIG_SUSPEND is not set
-# CONFIG_PM is not set
-CONFIG_ACPI=y
-CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
-CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
-CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
-# CONFIG_ACPI_DEBUGGER is not set
-# CONFIG_ACPI_PROCFS_POWER is not set
-CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y
-# CONFIG_ACPI_EC_DEBUGFS is not set
# CONFIG_ACPI_AC is not set
# CONFIG_ACPI_BATTERY is not set
# CONFIG_ACPI_BUTTON is not set
# CONFIG_ACPI_FAN is not set
-# CONFIG_ACPI_DOCK is not set
-CONFIG_ACPI_CPU_FREQ_PSS=y
-CONFIG_ACPI_PROCESSOR_CSTATE=y
-CONFIG_ACPI_PROCESSOR_IDLE=y
-CONFIG_ACPI_CPPC_LIB=y
-CONFIG_ACPI_PROCESSOR=y
-# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
-CONFIG_ACPI_THERMAL=y
-# CONFIG_ACPI_CUSTOM_DSDT is not set
-CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y
-# CONFIG_ACPI_DEBUG is not set
-# CONFIG_ACPI_PCI_SLOT is not set
-CONFIG_X86_PM_TIMER=y
-# CONFIG_ACPI_CONTAINER is not set
-CONFIG_ACPI_HOTPLUG_IOAPIC=y
-# CONFIG_ACPI_SBS is not set
-# CONFIG_ACPI_HED is not set
-# CONFIG_ACPI_CUSTOM_METHOD is not set
-# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
-CONFIG_HAVE_ACPI_APEI=y
-CONFIG_HAVE_ACPI_APEI_NMI=y
-# CONFIG_ACPI_APEI is not set
-# CONFIG_DPTF_POWER is not set
-# CONFIG_PMIC_OPREGION is not set
-# CONFIG_ACPI_CONFIGFS is not set
-# CONFIG_SFI is not set
-
-#
-# CPU Frequency scaling
-#
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_STAT is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set
-
-#
-# CPU frequency scaling drivers
-#
-CONFIG_X86_INTEL_PSTATE=y
-# CONFIG_X86_PCC_CPUFREQ is not set
-# CONFIG_X86_ACPI_CPUFREQ is not set
-# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
-# CONFIG_X86_P4_CLOCKMOD is not set
-
-#
-# shared options
-#
-# CONFIG_X86_SPEEDSTEP_LIB is not set
-
-#
-# CPU Idle
-#
-CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
-# CONFIG_INTEL_IDLE is not set
-
-#
-# Bus options (PCI etc.)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DIRECT=y
# CONFIG_PCI_MMCONFIG is not set
-CONFIG_PCI_DOMAINS=y
-# CONFIG_PCI_CNB20LE_QUIRK is not set
-# CONFIG_PCIEPORTBUS is not set
-CONFIG_PCI_BUS_ADDR_T_64BIT=y
-# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_DEBUG is not set
-# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
-# CONFIG_PCI_STUB is not set
-# CONFIG_HT_IRQ is not set
-# CONFIG_PCI_IOV is not set
-# CONFIG_PCI_PRI is not set
-# CONFIG_PCI_PASID is not set
-CONFIG_PCI_LABEL=y
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# PCI host controller drivers
-#
-# CONFIG_ISA_BUS is not set
# CONFIG_ISA_DMA_API is not set
-CONFIG_AMD_NB=y
-# CONFIG_PCCARD is not set
-# CONFIG_RAPIDIO is not set
-# CONFIG_X86_SYSFB is not set
-
-#
-# Executable file formats / Emulations
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_ELFCORE=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_BINFMT_SCRIPT=y
-# CONFIG_HAVE_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-CONFIG_COREDUMP=y
-# CONFIG_IA32_EMULATION is not set
-# CONFIG_X86_X32 is not set
-CONFIG_X86_DEV_DMA_OPS=y
-CONFIG_PMC_ATOM=y
+# CONFIG_DMIID is not set
+# CONFIG_VIRTUALIZATION is not set
+CONFIG_JUMP_LABEL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
+# CONFIG_COMPACTION is not set
+# CONFIG_BOUNCE is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
CONFIG_NET=y
-CONFIG_NET_INGRESS=y
-
-#
-# Networking options
-#
CONFIG_PACKET=y
-# CONFIG_PACKET_DIAG is not set
CONFIG_UNIX=y
-# CONFIG_UNIX_DIAG is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IP_FIB_TRIE_STATS is not set
CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_ROUTE_MULTIPATH is not set
-# CONFIG_IP_ROUTE_VERBOSE is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE_DEMUX is not set
-CONFIG_NET_IP_TUNNEL=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_NET_UDP_TUNNEL is not set
-# CONFIG_NET_FOU is not set
-# CONFIG_NET_FOU_IP_TUNNELS is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_DIAG is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=y
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_IPV6_ILA is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=y
-CONFIG_INET6_XFRM_MODE_TUNNEL=y
-CONFIG_INET6_XFRM_MODE_BEET=y
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-# CONFIG_IPV6_VTI is not set
-CONFIG_IPV6_SIT=y
-# CONFIG_IPV6_SIT_6RD is not set
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_FOU is not set
-# CONFIG_IPV6_FOU_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_IPV6_SEG6_LWTUNNEL is not set
-# CONFIG_IPV6_SEG6_HMAC is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NET_PTP_CLASSIFY is not set
-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=y
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_INGRESS=y
-CONFIG_NETFILTER_NETLINK=y
-# CONFIG_NETFILTER_NETLINK_ACCT is not set
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NF_LOG_NETDEV is not set
CONFIG_NF_TABLES=y
-# CONFIG_NF_TABLES_INET is not set
-# CONFIG_NF_TABLES_NETDEV is not set
-# CONFIG_NFT_EXTHDR is not set
-# CONFIG_NFT_META is not set
-# CONFIG_NFT_RT is not set
-# CONFIG_NFT_NUMGEN is not set
-# CONFIG_NFT_SET_RBTREE is not set
-# CONFIG_NFT_SET_HASH is not set
-# CONFIG_NFT_COUNTER is not set
-# CONFIG_NFT_LOG is not set
-# CONFIG_NFT_LIMIT is not set
-# CONFIG_NFT_OBJREF is not set
-# CONFIG_NFT_QUOTA is not set
-# CONFIG_NFT_REJECT is not set
-# CONFIG_NFT_COMPAT is not set
-# CONFIG_NFT_HASH is not set
CONFIG_NETFILTER_XTABLES=y
-
-#
-# Xtables combined modules
-#
-# CONFIG_NETFILTER_XT_MARK is not set
-
-#
-# Xtables targets
-#
-# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
-# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
-# CONFIG_NETFILTER_XT_TARGET_LOG is not set
-# CONFIG_NETFILTER_XT_TARGET_MARK is not set
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
-# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
-# CONFIG_NETFILTER_XT_TARGET_TEE is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-
-#
-# Xtables matches
-#
-# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_BPF is not set
-# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
-# CONFIG_NETFILTER_XT_MATCH_CPU is not set
-# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
-# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
-# CONFIG_NETFILTER_XT_MATCH_ECN is not set
-# CONFIG_NETFILTER_XT_MATCH_ESP is not set
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_HL is not set
-# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
-# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
-# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
-# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
-# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_MAC is not set
-# CONFIG_NETFILTER_XT_MATCH_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
-# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
-# CONFIG_NETFILTER_XT_MATCH_OSF is not set
-# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
-# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
-# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
-# CONFIG_NETFILTER_XT_MATCH_REALM is not set
-# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
-# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
-# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
-# CONFIG_NETFILTER_XT_MATCH_STRING is not set
-# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
-# CONFIG_NETFILTER_XT_MATCH_TIME is not set
-# CONFIG_NETFILTER_XT_MATCH_U32 is not set
-# CONFIG_IP_SET is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_NF_SOCKET_IPV4 is not set
-# CONFIG_NF_TABLES_IPV4 is not set
-# CONFIG_NF_TABLES_ARP is not set
-# CONFIG_NF_DUP_IPV4 is not set
-# CONFIG_NF_LOG_ARP is not set
-# CONFIG_NF_LOG_IPV4 is not set
-# CONFIG_NF_REJECT_IPV4 is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV6 is not set
-# CONFIG_NF_SOCKET_IPV6 is not set
-# CONFIG_NF_TABLES_IPV6 is not set
-# CONFIG_NF_DUP_IPV6 is not set
-# CONFIG_NF_REJECT_IPV6 is not set
-# CONFIG_NF_LOG_IPV6 is not set
-# CONFIG_IP6_NF_IPTABLES is not set
CONFIG_NF_TABLES_BRIDGE=y
-# CONFIG_NF_LOG_BRIDGE is not set
CONFIG_BRIDGE_NF_EBTABLES=y
-# CONFIG_BRIDGE_EBT_BROUTE is not set
CONFIG_BRIDGE_EBT_T_FILTER=y
-# CONFIG_BRIDGE_EBT_T_NAT is not set
-# CONFIG_BRIDGE_EBT_802_3 is not set
-# CONFIG_BRIDGE_EBT_AMONG is not set
CONFIG_BRIDGE_EBT_ARP=y
CONFIG_BRIDGE_EBT_IP=y
CONFIG_BRIDGE_EBT_IP6=y
-# CONFIG_BRIDGE_EBT_LIMIT is not set
-# CONFIG_BRIDGE_EBT_MARK is not set
CONFIG_BRIDGE_EBT_PKTTYPE=y
-# CONFIG_BRIDGE_EBT_STP is not set
-# CONFIG_BRIDGE_EBT_VLAN is not set
CONFIG_BRIDGE_EBT_ARPREPLY=y
-# CONFIG_BRIDGE_EBT_DNAT is not set
-# CONFIG_BRIDGE_EBT_MARK_T is not set
-# CONFIG_BRIDGE_EBT_REDIRECT is not set
-# CONFIG_BRIDGE_EBT_SNAT is not set
-# CONFIG_BRIDGE_EBT_LOG is not set
-# CONFIG_BRIDGE_EBT_NFLOG is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_RDS is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_L2TP is not set
-CONFIG_STP=y
CONFIG_BRIDGE=y
-CONFIG_BRIDGE_IGMP_SNOOPING=y
-# CONFIG_BRIDGE_VLAN_FILTERING is not set
-CONFIG_HAVE_NET_DSA=y
-# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=y
-# CONFIG_VLAN_8021Q_GVRP is not set
-# CONFIG_VLAN_8021Q_MVRP is not set
-# CONFIG_DECNET is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_PHONET is not set
-# CONFIG_6LOWPAN is not set
-# CONFIG_IEEE802154 is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-# CONFIG_BATMAN_ADV is not set
-# CONFIG_OPENVSWITCH is not set
-# CONFIG_VSOCKETS is not set
-# CONFIG_NETLINK_DIAG is not set
-# CONFIG_MPLS is not set
-# CONFIG_HSR is not set
-# CONFIG_NET_SWITCHDEV is not set
-# CONFIG_NET_L3_MASTER_DEV is not set
-# CONFIG_NET_NCSI is not set
-CONFIG_RPS=y
-CONFIG_RFS_ACCEL=y
-CONFIG_XPS=y
-CONFIG_NET_RX_BUSY_POLL=y
-CONFIG_BQL=y
-CONFIG_NET_FLOW_LIMIT=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_AF_KCM is not set
-# CONFIG_STREAM_PARSER is not set
-CONFIG_FIB_RULES=y
-CONFIG_WIRELESS=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
CONFIG_CFG80211=y
-# CONFIG_NL80211_TESTMODE is not set
CONFIG_CFG80211_DEVELOPER_WARNINGS=y
-# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
-CONFIG_CFG80211_DEFAULT_PS=y
CONFIG_CFG80211_DEBUGFS=y
-# CONFIG_CFG80211_INTERNAL_REGDB is not set
-CONFIG_CFG80211_CRDA_SUPPORT=y
CONFIG_CFG80211_WEXT=y
-# CONFIG_LIB80211 is not set
CONFIG_MAC80211=y
-CONFIG_MAC80211_HAS_RC=y
-CONFIG_MAC80211_RC_MINSTREL=y
-CONFIG_MAC80211_RC_MINSTREL_HT=y
-# CONFIG_MAC80211_RC_MINSTREL_VHT is not set
-CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
-CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
CONFIG_MAC80211_MESH=y
CONFIG_MAC80211_DEBUGFS=y
CONFIG_MAC80211_MESSAGE_TRACING=y
@@ -909,978 +86,68 @@ CONFIG_MAC80211_VERBOSE_DEBUG=y
CONFIG_MAC80211_MLME_DEBUG=y
CONFIG_MAC80211_STA_DEBUG=y
CONFIG_MAC80211_HT_DEBUG=y
-# CONFIG_MAC80211_OCB_DEBUG is not set
CONFIG_MAC80211_IBSS_DEBUG=y
CONFIG_MAC80211_PS_DEBUG=y
-# CONFIG_MAC80211_MPL_DEBUG is not set
-# CONFIG_MAC80211_MPATH_DEBUG is not set
-# CONFIG_MAC80211_MHWMP_DEBUG is not set
-# CONFIG_MAC80211_MESH_SYNC_DEBUG is not set
-# CONFIG_MAC80211_MESH_CSA_DEBUG is not set
-# CONFIG_MAC80211_MESH_PS_DEBUG is not set
CONFIG_MAC80211_TDLS_DEBUG=y
-# CONFIG_MAC80211_DEBUG_COUNTERS is not set
-CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
-# CONFIG_WIMAX is not set
CONFIG_RFKILL=y
-# CONFIG_RFKILL_INPUT is not set
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
-# CONFIG_NET_9P_DEBUG is not set
-# CONFIG_CAIF is not set
-# CONFIG_CEPH_LIB is not set
-# CONFIG_NFC is not set
-# CONFIG_LWTUNNEL is not set
-CONFIG_DST_CACHE=y
-# CONFIG_NET_DEVLINK is not set
-CONFIG_MAY_USE_DEVLINK=y
-CONFIG_HAVE_EBPF_JIT=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
+CONFIG_PCI=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
-CONFIG_ALLOW_DEV_COREDUMP=y
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_GENERIC_CPU_DEVICES is not set
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-# CONFIG_DMA_SHARED_BUFFER is not set
-
-#
-# Bus devices
-#
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_OF is not set
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-# CONFIG_PARPORT is not set
-CONFIG_PNP=y
# CONFIG_PNP_DEBUG_MESSAGES is not set
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
# CONFIG_BLK_DEV is not set
-# CONFIG_BLK_DEV_NVME is not set
-# CONFIG_NVME_FC is not set
-# CONFIG_NVME_TARGET is not set
-
-#
-# Misc devices
-#
-# CONFIG_SENSORS_LIS3LV02D is not set
-# CONFIG_DUMMY_IRQ is not set
-# CONFIG_IBM_ASM is not set
-# CONFIG_PHANTOM is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_SRAM is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_CB710_CORE is not set
-
-#
-# Texas Instruments shared transport line discipline
-#
-
-#
-# Altera FPGA firmware download module
-#
-# CONFIG_INTEL_MEI is not set
-# CONFIG_INTEL_MEI_ME is not set
-# CONFIG_INTEL_MEI_TXE is not set
-# CONFIG_VMWARE_VMCI is not set
-
-#
-# Intel MIC Bus Driver
-#
-# CONFIG_INTEL_MIC_BUS is not set
-
-#
-# SCIF Bus Driver
-#
-# CONFIG_SCIF_BUS is not set
-
-#
-# VOP Bus Driver
-#
-# CONFIG_VOP_BUS is not set
-
-#
-# Intel MIC Host Driver
-#
-
-#
-# Intel MIC Card Driver
-#
-
-#
-# SCIF Driver
-#
-
-#
-# Intel MIC Coprocessor State Management (COSM) Drivers
-#
-
-#
-# VOP Driver
-#
-# CONFIG_GENWQE is not set
-# CONFIG_ECHO is not set
-# CONFIG_CXL_BASE is not set
-# CONFIG_CXL_AFU_DRIVER_OPS is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI_MOD=y
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_FIREWIRE_NOSY is not set
-# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
-CONFIG_NET_CORE=y
-# CONFIG_BONDING is not set
CONFIG_DUMMY=y
-# CONFIG_EQUALIZER is not set
-# CONFIG_NET_TEAM is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_VXLAN is not set
-# CONFIG_MACSEC is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_TUN is not set
-# CONFIG_TUN_VNET_CROSS_LE is not set
-# CONFIG_VETH is not set
-# CONFIG_VIRTIO_NET is not set
-# CONFIG_NLMON is not set
-# CONFIG_ARCNET is not set
-
-#
-# CAIF transport drivers
-#
-
-#
-# Distributed Switch Architecture drivers
-#
+CONFIG_MACSEC=y
+CONFIG_VETH=y
# CONFIG_ETHERNET is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_NET_SB1000 is not set
-# CONFIG_PHYLIB is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Host-side USB support is needed for USB Network Adapter support
-#
-CONFIG_WLAN=y
-# CONFIG_WIRELESS_WDS is not set
-CONFIG_WLAN_VENDOR_ADMTEK=y
-# CONFIG_ADM8211 is not set
-CONFIG_WLAN_VENDOR_ATH=y
-# CONFIG_ATH_DEBUG is not set
-# CONFIG_ATH5K is not set
-# CONFIG_ATH5K_PCI is not set
-# CONFIG_ATH9K is not set
-# CONFIG_ATH6KL is not set
-# CONFIG_WIL6210 is not set
-# CONFIG_ATH10K is not set
-# CONFIG_WCN36XX is not set
-CONFIG_WLAN_VENDOR_ATMEL=y
-# CONFIG_ATMEL is not set
-CONFIG_WLAN_VENDOR_BROADCOM=y
-# CONFIG_B43 is not set
-# CONFIG_B43LEGACY is not set
-# CONFIG_BRCMSMAC is not set
-# CONFIG_BRCMFMAC is not set
-CONFIG_WLAN_VENDOR_CISCO=y
-CONFIG_WLAN_VENDOR_INTEL=y
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
-# CONFIG_IWL4965 is not set
-# CONFIG_IWL3945 is not set
-# CONFIG_IWLWIFI is not set
-CONFIG_WLAN_VENDOR_INTERSIL=y
-# CONFIG_HOSTAP is not set
-# CONFIG_HERMES is not set
-# CONFIG_P54_COMMON is not set
-# CONFIG_PRISM54 is not set
-CONFIG_WLAN_VENDOR_MARVELL=y
-# CONFIG_LIBERTAS is not set
-# CONFIG_LIBERTAS_THINFIRM is not set
-# CONFIG_MWIFIEX is not set
-# CONFIG_MWL8K is not set
-CONFIG_WLAN_VENDOR_MEDIATEK=y
-CONFIG_WLAN_VENDOR_RALINK=y
-# CONFIG_RT2X00 is not set
-CONFIG_WLAN_VENDOR_REALTEK=y
-# CONFIG_RTL8180 is not set
-CONFIG_RTL_CARDS=y
-# CONFIG_RTL8192CE is not set
-# CONFIG_RTL8192SE is not set
-# CONFIG_RTL8192DE is not set
-# CONFIG_RTL8723AE is not set
-# CONFIG_RTL8723BE is not set
-# CONFIG_RTL8188EE is not set
-# CONFIG_RTL8192EE is not set
-# CONFIG_RTL8821AE is not set
-CONFIG_WLAN_VENDOR_RSI=y
-# CONFIG_RSI_91X is not set
-CONFIG_WLAN_VENDOR_ST=y
-# CONFIG_CW1200 is not set
-CONFIG_WLAN_VENDOR_TI=y
-# CONFIG_WL1251 is not set
-# CONFIG_WL12XX is not set
-# CONFIG_WL18XX is not set
-# CONFIG_WLCORE is not set
-CONFIG_WLAN_VENDOR_ZYDAS=y
CONFIG_MAC80211_HWSIM=y
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-# CONFIG_WAN is not set
-# CONFIG_VMXNET3 is not set
-# CONFIG_FUJITSU_ES is not set
-# CONFIG_ISDN is not set
-# CONFIG_NVM is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-# CONFIG_INPUT_MATRIXKMAP is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-# CONFIG_RMI4_CORE is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-# CONFIG_SERIO_ALTERA_PS2 is not set
-# CONFIG_SERIO_PS2MULT is not set
-# CONFIG_SERIO_ARC_PS2 is not set
-# CONFIG_USERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_TTY=y
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_NOZOMI is not set
-# CONFIG_N_GSM is not set
-# CONFIG_TRACE_SINK is not set
-CONFIG_DEVMEM=y
-# CONFIG_DEVKMEM is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
# CONFIG_SERIAL_8250_PNP is not set
-# CONFIG_SERIAL_8250_FINTEK is not set
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_FSL is not set
-# CONFIG_SERIAL_8250_DW is not set
-# CONFIG_SERIAL_8250_RT288X is not set
-CONFIG_SERIAL_8250_LPSS=y
# CONFIG_SERIAL_8250_MID is not set
-# CONFIG_SERIAL_8250_MOXA is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_UARTLITE is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_SCCNXP is not set
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-# CONFIG_SERIAL_ARC is not set
-# CONFIG_SERIAL_RP2 is not set
-# CONFIG_SERIAL_FSL_LPUART is not set
-# CONFIG_TTY_PRINTK is not set
-# CONFIG_VIRTIO_CONSOLE is not set
-# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_MWAVE is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HPET is not set
-# CONFIG_HANGCHECK_TIMER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-CONFIG_DEVPORT=y
-# CONFIG_XILLYBUS is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
-# CONFIG_SPMI is not set
-# CONFIG_HSI is not set
-
-#
-# PPS support
-#
-# CONFIG_PPS is not set
-
-#
-# PPS generators support
-#
-
-#
-# PTP clock support
-#
-# CONFIG_PTP_1588_CLOCK is not set
-
-#
-# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
-#
-# CONFIG_GPIOLIB is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_AVS is not set
-# CONFIG_POWER_RESET is not set
CONFIG_POWER_SUPPLY=y
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_TEST_POWER is not set
-# CONFIG_BATTERY_DS2780 is not set
-# CONFIG_BATTERY_DS2781 is not set
-# CONFIG_BATTERY_BQ27XXX is not set
-# CONFIG_CHARGER_MAX8903 is not set
# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-# CONFIG_THERMAL_WRITABLE_TRIPS is not set
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
-# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
-# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set
-# CONFIG_THERMAL_GOV_FAIR_SHAR