developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1 | From 1a9b003e08a15df0e52604b991c1dd851a9bd265 Mon Sep 17 00:00:00 2001 |
| 2 | From: Shayne Chen <shayne.chen@mediatek.com> |
| 3 | Date: Fri, 19 Jul 2024 15:26:42 +0800 |
| 4 | Subject: [PATCH 010/126] sync 2024-08-13 openwrt/trunk patches folder |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 5 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 6 | Sync to e80520197c9ca7bced50d3605d6baba6dead6e35 |
| 7 | "hostapd: Add support for APuP" |
| 8 | |
| 9 | Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10 | --- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11 | hostapd/Makefile | 153 +- |
| 12 | hostapd/config_file.c | 42 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13 | hostapd/ctrl_iface.c | 4 + |
| 14 | hostapd/defconfig | 15 +- |
| 15 | hostapd/hostapd_cli.c | 10 +- |
| 16 | hostapd/main.c | 21 +- |
| 17 | src/ap/acs.c | 5 +- |
| 18 | src/ap/airtime_policy.c | 15 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 19 | src/ap/ap_config.h | 37 + |
| 20 | src/ap/ap_drv_ops.c | 28 +- |
| 21 | src/ap/ap_drv_ops.h | 24 +- |
| 22 | src/ap/apup.c | 168 + |
| 23 | src/ap/apup.h | 24 + |
| 24 | src/ap/beacon.c | 16 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 25 | src/ap/ctrl_iface_ap.c | 45 +- |
| 26 | src/ap/dfs.c | 22 +- |
| 27 | src/ap/drv_callbacks.c | 16 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 28 | src/ap/hostapd.c | 59 +- |
| 29 | src/ap/hostapd.h | 41 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 30 | src/ap/hw_features.c | 3 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 31 | src/ap/ieee802_11.c | 55 +- |
| 32 | src/ap/ieee802_11.h | 2 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 33 | src/ap/ieee802_11_ht.c | 15 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 34 | src/ap/ieee802_11_vht.c | 17 + |
| 35 | src/ap/ieee802_1x.c | 6 + |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 36 | src/ap/rrm.c | 10 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 37 | src/ap/sta_info.c | 35 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 38 | src/ap/sta_info.h | 16 +- |
| 39 | src/ap/ubus.c | 15 + |
| 40 | src/ap/ubus.h | 5 + |
| 41 | src/ap/ucode.c | 17 + |
| 42 | src/ap/ucode.h | 4 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 43 | src/ap/vlan_full.c | 4 + |
| 44 | src/ap/vlan_init.c | 8 +- |
| 45 | src/ap/wnm_ap.c | 16 +- |
| 46 | src/ap/wpa_auth.c | 3 +- |
| 47 | src/ap/wpa_auth_glue.c | 9 +- |
| 48 | src/ap/wps_hostapd.c | 6 +- |
| 49 | src/ap/x_snoop.c | 22 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 50 | src/common/defs.h | 4 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 51 | src/common/dpp_crypto.c | 10 +- |
| 52 | src/common/hw_features_common.c | 1 + |
| 53 | src/common/ieee802_11_defs.h | 2 + |
| 54 | src/common/sae.c | 7 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 55 | src/common/wpa_ctrl.c | 10 +- |
| 56 | src/crypto/Makefile | 129 +- |
| 57 | src/crypto/crypto_mbedtls.c | 4228 +++++++++++++++++++++ |
| 58 | src/crypto/crypto_module_tests.c | 134 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 59 | src/crypto/tls_mbedtls.c | 3313 ++++++++++++++++ |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 60 | src/drivers/driver.h | 38 +- |
| 61 | src/drivers/driver_nl80211.c | 174 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 62 | src/drivers/driver_nl80211_capa.c | 4 + |
| 63 | src/drivers/driver_nl80211_event.c | 5 + |
| 64 | src/drivers/driver_nl80211_scan.c | 2 +- |
| 65 | src/drivers/drivers.c | 4 + |
| 66 | src/drivers/drivers.mak | 4 +- |
| 67 | src/drivers/rfkill.h | 16 + |
| 68 | src/radius/radius_client.c | 34 + |
| 69 | src/radius/radius_client.h | 2 + |
| 70 | src/radius/radius_das.c | 201 +- |
| 71 | src/radius/radius_das.h | 1 + |
| 72 | src/radius/radius_server.c | 61 +- |
| 73 | src/rsn_supp/wpa.c | 3 + |
| 74 | src/tls/Makefile | 11 + |
| 75 | src/utils/eloop.c | 20 +- |
| 76 | src/utils/eloop.h | 8 + |
| 77 | src/utils/uloop.c | 64 + |
| 78 | src/utils/wpa_debug.c | 49 +- |
| 79 | src/utils/wpa_debug.h | 73 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 80 | tests/Makefile | 76 +- |
| 81 | tests/hwsim/example-hostapd.config | 8 +- |
| 82 | tests/hwsim/example-wpa_supplicant.config | 9 +- |
| 83 | tests/hwsim/test_ap_eap.py | 114 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 84 | tests/hwsim/test_ap_ft.py | 4 +- |
| 85 | tests/hwsim/test_authsrv.py | 9 +- |
| 86 | tests/hwsim/test_dpp.py | 19 +- |
| 87 | tests/hwsim/test_erp.py | 16 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 88 | tests/hwsim/test_fils.py | 4 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 89 | tests/hwsim/test_pmksa_cache.py | 4 +- |
| 90 | tests/hwsim/test_sae.py | 7 + |
| 91 | tests/hwsim/test_suite_b.py | 3 + |
| 92 | tests/hwsim/test_wpas_ctrl.py | 2 +- |
| 93 | tests/hwsim/utils.py | 8 +- |
| 94 | tests/test-crypto_module.c | 16 + |
| 95 | tests/test-https.c | 12 +- |
| 96 | tests/test-https_server.c | 12 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 97 | wpa_supplicant/Makefile | 143 +- |
| 98 | wpa_supplicant/ap.c | 28 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 99 | wpa_supplicant/config.c | 95 + |
| 100 | wpa_supplicant/config_file.c | 8 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 101 | wpa_supplicant/config_ssid.h | 5 + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 102 | wpa_supplicant/ctrl_iface.c | 12 +- |
| 103 | wpa_supplicant/defconfig | 6 +- |
| 104 | wpa_supplicant/eapol_test.c | 11 + |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 105 | wpa_supplicant/events.c | 7 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 106 | wpa_supplicant/main.c | 14 +- |
| 107 | wpa_supplicant/mesh.c | 3 + |
| 108 | wpa_supplicant/wpa_cli.c | 9 + |
| 109 | wpa_supplicant/wpa_priv.c | 8 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 110 | wpa_supplicant/wpa_supplicant.c | 76 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 111 | wpa_supplicant/wpa_supplicant_i.h | 6 + |
| 112 | wpa_supplicant/wps_supplicant.c | 3 + |
| 113 | wpa_supplicant/wps_supplicant.h | 3 +- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 114 | 103 files changed, 9984 insertions(+), 401 deletions(-) |
| 115 | create mode 100644 src/ap/apup.c |
| 116 | create mode 100644 src/ap/apup.h |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 117 | create mode 100644 src/crypto/crypto_mbedtls.c |
| 118 | create mode 100644 src/crypto/tls_mbedtls.c |
| 119 | create mode 100644 src/utils/uloop.c |
| 120 | create mode 100644 tests/test-crypto_module.c |
| 121 | |
| 122 | diff --git a/hostapd/Makefile b/hostapd/Makefile |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 123 | index 78171025e..8dc6e6216 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 124 | --- a/hostapd/Makefile |
| 125 | +++ b/hostapd/Makefile |
| 126 | @@ -1,6 +1,7 @@ |
| 127 | ALL=hostapd hostapd_cli |
| 128 | CONFIG_FILE = .config |
| 129 | |
| 130 | +-include $(if $(MULTICALL), ../wpa_supplicant/.config) |
| 131 | include ../src/build.rules |
| 132 | |
| 133 | ifdef LIBS |
| 134 | @@ -62,6 +63,10 @@ endif |
| 135 | OBJS += main.o |
| 136 | OBJS += config_file.o |
| 137 | |
| 138 | +ifdef CONFIG_RADIUS_SERVER |
| 139 | +OBJS += radius.o |
| 140 | +endif |
| 141 | + |
| 142 | OBJS += ../src/ap/hostapd.o |
| 143 | OBJS += ../src/ap/wpa_auth_glue.o |
| 144 | OBJS += ../src/ap/drv_callbacks.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 145 | @@ -174,6 +179,24 @@ OBJS += ../src/common/hw_features_common.o |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 146 | |
| 147 | OBJS += ../src/eapol_auth/eapol_auth_sm.o |
| 148 | |
| 149 | +ifdef CONFIG_UBUS |
| 150 | +CFLAGS += -DUBUS_SUPPORT |
| 151 | +OBJS += ../src/ap/ubus.o |
| 152 | +LIBS += -lubus |
| 153 | +NEED_ULOOP:=y |
| 154 | +endif |
| 155 | + |
| 156 | +ifdef CONFIG_UCODE |
| 157 | +CFLAGS += -DUCODE_SUPPORT |
| 158 | +OBJS += ../src/utils/ucode.o |
| 159 | +OBJS += ../src/ap/ucode.o |
| 160 | +NEED_ULOOP:=y |
| 161 | +endif |
| 162 | + |
| 163 | +ifdef NEED_ULOOP |
| 164 | +OBJS += ../src/utils/uloop.o |
| 165 | +LIBS += -lubox |
| 166 | +endif |
| 167 | |
| 168 | ifdef CONFIG_CODE_COVERAGE |
| 169 | CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 170 | @@ -208,7 +231,8 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 171 | |
| 172 | ifdef CONFIG_NO_VLAN |
| 173 | CFLAGS += -DCONFIG_NO_VLAN |
| 174 | -else |
| 175 | +endif |
| 176 | +ifneq ($(findstring CONFIG_NO_VLAN,$(CFLAGS)), CONFIG_NO_VLAN) |
| 177 | OBJS += ../src/ap/vlan_init.o |
| 178 | OBJS += ../src/ap/vlan_ifconfig.o |
| 179 | OBJS += ../src/ap/vlan.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 180 | @@ -228,6 +252,9 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 181 | ifdef CONFIG_NO_CTRL_IFACE |
| 182 | CFLAGS += -DCONFIG_NO_CTRL_IFACE |
| 183 | else |
| 184 | +ifdef CONFIG_CTRL_IFACE_MIB |
| 185 | +CFLAGS += -DCONFIG_CTRL_IFACE_MIB |
| 186 | +endif |
| 187 | ifeq ($(CONFIG_CTRL_IFACE), udp) |
| 188 | CFLAGS += -DCONFIG_CTRL_IFACE_UDP |
| 189 | else |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 190 | @@ -367,10 +394,14 @@ CFLAGS += -DCONFIG_MBO |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 191 | OBJS += ../src/ap/mbo_ap.o |
| 192 | endif |
| 193 | |
| 194 | +ifndef MULTICALL |
| 195 | +CFLAGS += -DNO_SUPPLICANT |
| 196 | +endif |
| 197 | + |
| 198 | include ../src/drivers/drivers.mak |
| 199 | -OBJS += $(DRV_AP_OBJS) |
| 200 | -CFLAGS += $(DRV_AP_CFLAGS) |
| 201 | -LDFLAGS += $(DRV_AP_LDFLAGS) |
| 202 | +OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS))) |
| 203 | +CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS)) |
| 204 | +LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS)) |
| 205 | LIBS += $(DRV_AP_LIBS) |
| 206 | |
| 207 | ifdef CONFIG_L2_PACKET |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 208 | @@ -716,6 +747,7 @@ CFLAGS += -DCONFIG_TLSV12 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 209 | endif |
| 210 | |
| 211 | ifeq ($(CONFIG_TLS), wolfssl) |
| 212 | +CFLAGS += -DCONFIG_TLS_WOLFSSL |
| 213 | CONFIG_CRYPTO=wolfssl |
| 214 | ifdef TLS_FUNCS |
| 215 | OBJS += ../src/crypto/tls_wolfssl.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 216 | @@ -736,6 +768,7 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 217 | endif |
| 218 | |
| 219 | ifeq ($(CONFIG_TLS), openssl) |
| 220 | +CFLAGS += -DCONFIG_TLS_OPENSSL |
| 221 | CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 222 | CONFIG_CRYPTO=openssl |
| 223 | ifdef TLS_FUNCS |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 224 | @@ -765,7 +798,39 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 225 | CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" |
| 226 | endif |
| 227 | |
| 228 | +ifeq ($(CONFIG_TLS), mbedtls) |
| 229 | +CFLAGS += -DCONFIG_TLS_MBEDTLS |
| 230 | +ifndef CONFIG_CRYPTO |
| 231 | +CONFIG_CRYPTO=mbedtls |
| 232 | +endif |
| 233 | +ifdef TLS_FUNCS |
| 234 | +OBJS += ../src/crypto/tls_mbedtls.o |
| 235 | +LIBS += -lmbedtls |
| 236 | +ifndef CONFIG_DPP |
| 237 | +LIBS += -lmbedx509 |
| 238 | +endif |
| 239 | +endif |
| 240 | +OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 241 | +HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 242 | +SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 243 | +ifeq ($(CONFIG_CRYPTO), mbedtls) |
| 244 | +ifdef CONFIG_DPP |
| 245 | +LIBS += -lmbedx509 |
| 246 | +LIBS_h += -lmbedx509 |
| 247 | +LIBS_n += -lmbedx509 |
| 248 | +LIBS_s += -lmbedx509 |
| 249 | +endif |
| 250 | +LIBS += -lmbedcrypto |
| 251 | +LIBS_h += -lmbedcrypto |
| 252 | +LIBS_n += -lmbedcrypto |
| 253 | +LIBS_s += -lmbedcrypto |
| 254 | +# XXX: create a config option? |
| 255 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 256 | +endif |
| 257 | +endif |
| 258 | + |
| 259 | ifeq ($(CONFIG_TLS), gnutls) |
| 260 | +CFLAGS += -DCONFIG_TLS_GNUTLS |
| 261 | ifndef CONFIG_CRYPTO |
| 262 | # default to libgcrypt |
| 263 | CONFIG_CRYPTO=gnutls |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 264 | @@ -796,6 +861,7 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 265 | endif |
| 266 | |
| 267 | ifeq ($(CONFIG_TLS), internal) |
| 268 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 269 | ifndef CONFIG_CRYPTO |
| 270 | CONFIG_CRYPTO=internal |
| 271 | endif |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 272 | @@ -874,6 +940,7 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 273 | endif |
| 274 | |
| 275 | ifeq ($(CONFIG_TLS), linux) |
| 276 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 277 | OBJS += ../src/crypto/crypto_linux.o |
| 278 | ifdef TLS_FUNCS |
| 279 | OBJS += ../src/crypto/crypto_internal-rsa.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 280 | @@ -944,9 +1011,11 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 281 | |
| 282 | ifneq ($(CONFIG_TLS), openssl) |
| 283 | ifneq ($(CONFIG_TLS), wolfssl) |
| 284 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 285 | AESOBJS += ../src/crypto/aes-wrap.o |
| 286 | endif |
| 287 | endif |
| 288 | +endif |
| 289 | ifdef NEED_AES_EAX |
| 290 | AESOBJS += ../src/crypto/aes-eax.o |
| 291 | NEED_AES_CTR=y |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 292 | @@ -956,38 +1025,48 @@ AESOBJS += ../src/crypto/aes-siv.o |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 293 | NEED_AES_CTR=y |
| 294 | endif |
| 295 | ifdef NEED_AES_CTR |
| 296 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 297 | AESOBJS += ../src/crypto/aes-ctr.o |
| 298 | endif |
| 299 | +endif |
| 300 | ifdef NEED_AES_ENCBLOCK |
| 301 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 302 | AESOBJS += ../src/crypto/aes-encblock.o |
| 303 | endif |
| 304 | +endif |
| 305 | ifneq ($(CONFIG_TLS), openssl) |
| 306 | ifneq ($(CONFIG_TLS), linux) |
| 307 | ifneq ($(CONFIG_TLS), wolfssl) |
| 308 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 309 | AESOBJS += ../src/crypto/aes-omac1.o |
| 310 | endif |
| 311 | endif |
| 312 | endif |
| 313 | +endif |
| 314 | ifdef NEED_AES_UNWRAP |
| 315 | ifneq ($(CONFIG_TLS), openssl) |
| 316 | ifneq ($(CONFIG_TLS), linux) |
| 317 | ifneq ($(CONFIG_TLS), wolfssl) |
| 318 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 319 | NEED_AES_DEC=y |
| 320 | AESOBJS += ../src/crypto/aes-unwrap.o |
| 321 | endif |
| 322 | endif |
| 323 | endif |
| 324 | endif |
| 325 | +endif |
| 326 | ifdef NEED_AES_CBC |
| 327 | NEED_AES_DEC=y |
| 328 | ifneq ($(CONFIG_TLS), openssl) |
| 329 | ifneq ($(CONFIG_TLS), linux) |
| 330 | ifneq ($(CONFIG_TLS), wolfssl) |
| 331 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 332 | AESOBJS += ../src/crypto/aes-cbc.o |
| 333 | endif |
| 334 | endif |
| 335 | endif |
| 336 | endif |
| 337 | +endif |
| 338 | ifdef NEED_AES_DEC |
| 339 | ifdef CONFIG_INTERNAL_AES |
| 340 | AESOBJS += ../src/crypto/aes-internal-dec.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 341 | @@ -1002,12 +1081,16 @@ ifneq ($(CONFIG_TLS), openssl) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 342 | ifneq ($(CONFIG_TLS), linux) |
| 343 | ifneq ($(CONFIG_TLS), gnutls) |
| 344 | ifneq ($(CONFIG_TLS), wolfssl) |
| 345 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 346 | SHA1OBJS += ../src/crypto/sha1.o |
| 347 | endif |
| 348 | endif |
| 349 | endif |
| 350 | endif |
| 351 | +endif |
| 352 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 353 | SHA1OBJS += ../src/crypto/sha1-prf.o |
| 354 | +endif |
| 355 | ifdef CONFIG_INTERNAL_SHA1 |
| 356 | SHA1OBJS += ../src/crypto/sha1-internal.o |
| 357 | ifdef NEED_FIPS186_2_PRF |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 358 | @@ -1016,16 +1099,22 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 359 | endif |
| 360 | ifneq ($(CONFIG_TLS), openssl) |
| 361 | ifneq ($(CONFIG_TLS), wolfssl) |
| 362 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 363 | SHA1OBJS += ../src/crypto/sha1-pbkdf2.o |
| 364 | endif |
| 365 | endif |
| 366 | +endif |
| 367 | ifdef NEED_T_PRF |
| 368 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 369 | SHA1OBJS += ../src/crypto/sha1-tprf.o |
| 370 | endif |
| 371 | +endif |
| 372 | ifdef NEED_TLS_PRF |
| 373 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 374 | SHA1OBJS += ../src/crypto/sha1-tlsprf.o |
| 375 | endif |
| 376 | endif |
| 377 | +endif |
| 378 | |
| 379 | ifdef NEED_SHA1 |
| 380 | OBJS += $(SHA1OBJS) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 381 | @@ -1035,11 +1124,13 @@ ifneq ($(CONFIG_TLS), openssl) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 382 | ifneq ($(CONFIG_TLS), linux) |
| 383 | ifneq ($(CONFIG_TLS), gnutls) |
| 384 | ifneq ($(CONFIG_TLS), wolfssl) |
| 385 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 386 | OBJS += ../src/crypto/md5.o |
| 387 | endif |
| 388 | endif |
| 389 | endif |
| 390 | endif |
| 391 | +endif |
| 392 | |
| 393 | ifdef NEED_MD5 |
| 394 | ifdef CONFIG_INTERNAL_MD5 |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 395 | @@ -1078,56 +1169,81 @@ ifneq ($(CONFIG_TLS), openssl) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 396 | ifneq ($(CONFIG_TLS), linux) |
| 397 | ifneq ($(CONFIG_TLS), gnutls) |
| 398 | ifneq ($(CONFIG_TLS), wolfssl) |
| 399 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 400 | OBJS += ../src/crypto/sha256.o |
| 401 | endif |
| 402 | endif |
| 403 | endif |
| 404 | endif |
| 405 | +endif |
| 406 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 407 | OBJS += ../src/crypto/sha256-prf.o |
| 408 | +endif |
| 409 | ifdef CONFIG_INTERNAL_SHA256 |
| 410 | OBJS += ../src/crypto/sha256-internal.o |
| 411 | endif |
| 412 | ifdef NEED_TLS_PRF_SHA256 |
| 413 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 414 | OBJS += ../src/crypto/sha256-tlsprf.o |
| 415 | endif |
| 416 | +endif |
| 417 | ifdef NEED_TLS_PRF_SHA384 |
| 418 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 419 | OBJS += ../src/crypto/sha384-tlsprf.o |
| 420 | endif |
| 421 | +endif |
| 422 | ifdef NEED_HMAC_SHA256_KDF |
| 423 | +CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 424 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 425 | OBJS += ../src/crypto/sha256-kdf.o |
| 426 | endif |
| 427 | +endif |
| 428 | ifdef NEED_HMAC_SHA384_KDF |
| 429 | +CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 430 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 431 | OBJS += ../src/crypto/sha384-kdf.o |
| 432 | endif |
| 433 | +endif |
| 434 | ifdef NEED_HMAC_SHA512_KDF |
| 435 | +CFLAGS += -DCONFIG_HMAC_SHA512_KDF |
| 436 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 437 | OBJS += ../src/crypto/sha512-kdf.o |
| 438 | endif |
| 439 | +endif |
| 440 | ifdef NEED_SHA384 |
| 441 | CFLAGS += -DCONFIG_SHA384 |
| 442 | ifneq ($(CONFIG_TLS), openssl) |
| 443 | ifneq ($(CONFIG_TLS), linux) |
| 444 | ifneq ($(CONFIG_TLS), gnutls) |
| 445 | ifneq ($(CONFIG_TLS), wolfssl) |
| 446 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 447 | OBJS += ../src/crypto/sha384.o |
| 448 | endif |
| 449 | endif |
| 450 | endif |
| 451 | endif |
| 452 | +endif |
| 453 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 454 | OBJS += ../src/crypto/sha384-prf.o |
| 455 | endif |
| 456 | +endif |
| 457 | ifdef NEED_SHA512 |
| 458 | CFLAGS += -DCONFIG_SHA512 |
| 459 | ifneq ($(CONFIG_TLS), openssl) |
| 460 | ifneq ($(CONFIG_TLS), linux) |
| 461 | ifneq ($(CONFIG_TLS), gnutls) |
| 462 | ifneq ($(CONFIG_TLS), wolfssl) |
| 463 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 464 | OBJS += ../src/crypto/sha512.o |
| 465 | endif |
| 466 | endif |
| 467 | endif |
| 468 | endif |
| 469 | +endif |
| 470 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 471 | OBJS += ../src/crypto/sha512-prf.o |
| 472 | endif |
| 473 | +endif |
| 474 | |
| 475 | ifdef CONFIG_INTERNAL_SHA384 |
| 476 | CFLAGS += -DCONFIG_INTERNAL_SHA384 |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 477 | @@ -1172,11 +1288,13 @@ HOBJS += $(SHA1OBJS) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 478 | ifneq ($(CONFIG_TLS), openssl) |
| 479 | ifneq ($(CONFIG_TLS), linux) |
| 480 | ifneq ($(CONFIG_TLS), wolfssl) |
| 481 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 482 | HOBJS += ../src/crypto/md5.o |
| 483 | endif |
| 484 | endif |
| 485 | endif |
| 486 | endif |
| 487 | +endif |
| 488 | |
| 489 | ifdef CONFIG_RADIUS_SERVER |
| 490 | CFLAGS += -DRADIUS_SERVER |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 491 | @@ -1306,6 +1424,11 @@ ifdef CONFIG_NO_TKIP |
| 492 | CFLAGS += -DCONFIG_NO_TKIP |
| 493 | endif |
| 494 | |
| 495 | +ifdef CONFIG_APUP |
| 496 | +CFLAGS += -DCONFIG_APUP |
| 497 | +OBJS += ../src/ap/apup.o |
| 498 | +endif |
| 499 | + |
| 500 | $(DESTDIR)$(BINDIR)/%: % |
| 501 | install -D $(<) $(@) |
| 502 | |
| 503 | @@ -1314,8 +1437,14 @@ install: $(addprefix $(DESTDIR)$(BINDIR)/,$(ALL)) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 504 | _OBJS_VAR := OBJS |
| 505 | include ../src/objs.mk |
| 506 | |
| 507 | +hostapd_multi.a: $(BCHECK) $(OBJS) |
| 508 | + $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c |
| 509 | + @$(E) " CC " $< |
| 510 | + @rm -f $@ |
| 511 | + @$(AR) cr $@ hostapd_multi.o $(OBJS) |
| 512 | + |
| 513 | hostapd: $(OBJS) |
| 514 | - $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) |
| 515 | + +$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) |
| 516 | @$(E) " LD " $@ |
| 517 | |
| 518 | ifdef CONFIG_WPA_TRACE |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 519 | @@ -1326,7 +1455,7 @@ _OBJS_VAR := OBJS_c |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 520 | include ../src/objs.mk |
| 521 | |
| 522 | hostapd_cli: $(OBJS_c) |
| 523 | - $(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) |
| 524 | + +$(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) |
| 525 | @$(E) " LD " $@ |
| 526 | |
| 527 | NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 528 | @@ -1350,7 +1479,9 @@ NOBJS += ../src/utils/trace.o |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 529 | endif |
| 530 | |
| 531 | HOBJS += hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/utils/wpabuf.o ../src/crypto/milenage.o |
| 532 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 533 | HOBJS += ../src/crypto/aes-encblock.o |
| 534 | +endif |
| 535 | ifdef CONFIG_INTERNAL_AES |
| 536 | HOBJS += ../src/crypto/aes-internal.o |
| 537 | HOBJS += ../src/crypto/aes-internal-enc.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 538 | @@ -1373,13 +1504,17 @@ SOBJS += ../src/common/sae.o |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 539 | SOBJS += ../src/common/sae_pk.o |
| 540 | SOBJS += ../src/common/dragonfly.o |
| 541 | SOBJS += $(AESOBJS) |
| 542 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 543 | SOBJS += ../src/crypto/sha256-prf.o |
| 544 | SOBJS += ../src/crypto/sha384-prf.o |
| 545 | SOBJS += ../src/crypto/sha512-prf.o |
| 546 | +endif |
| 547 | SOBJS += ../src/crypto/dh_groups.o |
| 548 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 549 | SOBJS += ../src/crypto/sha256-kdf.o |
| 550 | SOBJS += ../src/crypto/sha384-kdf.o |
| 551 | SOBJS += ../src/crypto/sha512-kdf.o |
| 552 | +endif |
| 553 | |
| 554 | _OBJS_VAR := NOBJS |
| 555 | include ../src/objs.mk |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 556 | @@ -1388,6 +1523,12 @@ include ../src/objs.mk |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 557 | _OBJS_VAR := SOBJS |
| 558 | include ../src/objs.mk |
| 559 | |
| 560 | +dump_cflags: |
| 561 | + @printf "%s " "$(CFLAGS)" |
| 562 | + |
| 563 | +dump_ldflags: |
| 564 | + @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" |
| 565 | + |
| 566 | nt_password_hash: $(NOBJS) |
| 567 | $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) |
| 568 | @$(E) " LD " $@ |
| 569 | diff --git a/hostapd/config_file.c b/hostapd/config_file.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 570 | index a86621ed9..f3968ec95 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 571 | --- a/hostapd/config_file.c |
| 572 | +++ b/hostapd/config_file.c |
| 573 | @@ -1229,6 +1229,8 @@ static int hostapd_config_vht_capab(struct hostapd_config *conf, |
| 574 | conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN; |
| 575 | if (os_strstr(capab, "[TX-ANTENNA-PATTERN]")) |
| 576 | conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN; |
| 577 | + if (os_strstr(capab, "[EXT-NSS-BW-SUPP]")) |
| 578 | + conf->vht_capab |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; |
| 579 | return 0; |
| 580 | } |
| 581 | #endif /* CONFIG_IEEE80211AC */ |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 582 | @@ -2654,8 +2656,12 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 583 | sizeof(conf->bss[0]->iface)); |
| 584 | } else if (os_strcmp(buf, "bridge") == 0) { |
| 585 | os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); |
| 586 | + if (!bss->wds_bridge[0]) |
| 587 | + os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); |
| 588 | } else if (os_strcmp(buf, "bridge_hairpin") == 0) { |
| 589 | bss->bridge_hairpin = atoi(pos); |
| 590 | + } else if (os_strcmp(buf, "snoop_iface") == 0) { |
| 591 | + os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); |
| 592 | } else if (os_strcmp(buf, "vlan_bridge") == 0) { |
| 593 | os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); |
| 594 | } else if (os_strcmp(buf, "wds_bridge") == 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 595 | @@ -3043,6 +3049,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 596 | } else if (os_strcmp(buf, "iapp_interface") == 0) { |
| 597 | wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); |
| 598 | #endif /* CONFIG_IAPP */ |
| 599 | + } else if (os_strcmp(buf, "dynamic_own_ip_addr") == 0) { |
| 600 | + bss->dynamic_own_ip_addr = atoi(pos); |
| 601 | } else if (os_strcmp(buf, "own_ip_addr") == 0) { |
| 602 | if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) { |
| 603 | wpa_printf(MSG_ERROR, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 604 | @@ -3270,6 +3278,14 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 605 | line, bss->max_num_sta, MAX_STA_COUNT); |
| 606 | return 1; |
| 607 | } |
| 608 | + } else if (os_strcmp(buf, "iface_max_num_sta") == 0) { |
| 609 | + conf->max_num_sta = atoi(pos); |
| 610 | + if (conf->max_num_sta < 0 || |
| 611 | + conf->max_num_sta > MAX_STA_COUNT) { |
| 612 | + wpa_printf(MSG_ERROR, "Line %d: Invalid max_num_sta=%d; allowed range 0..%d", |
| 613 | + line, conf->max_num_sta, MAX_STA_COUNT); |
| 614 | + return 1; |
| 615 | + } |
| 616 | } else if (os_strcmp(buf, "wpa") == 0) { |
| 617 | bss->wpa = atoi(pos); |
| 618 | } else if (os_strcmp(buf, "extended_key_id") == 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 619 | @@ -3459,6 +3475,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 620 | wpa_printf(MSG_INFO, |
| 621 | "Line %d: Obsolete peerkey parameter ignored", line); |
| 622 | #ifdef CONFIG_IEEE80211R_AP |
| 623 | + } else if (os_strcmp(buf, "ft_iface") == 0) { |
| 624 | + os_strlcpy(bss->ft_iface, pos, sizeof(bss->ft_iface)); |
| 625 | } else if (os_strcmp(buf, "mobility_domain") == 0) { |
| 626 | if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN || |
| 627 | hexstr2bin(pos, bss->mobility_domain, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 628 | @@ -3828,6 +3846,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 629 | #ifndef CONFIG_NO_VLAN |
| 630 | } else if (os_strcmp(buf, "dynamic_vlan") == 0) { |
| 631 | bss->ssid.dynamic_vlan = atoi(pos); |
| 632 | + } else if (os_strcmp(buf, "vlan_no_bridge") == 0) { |
| 633 | + bss->ssid.vlan_no_bridge = atoi(pos); |
| 634 | } else if (os_strcmp(buf, "per_sta_vif") == 0) { |
| 635 | bss->ssid.per_sta_vif = atoi(pos); |
| 636 | } else if (os_strcmp(buf, "vlan_file") == 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 637 | @@ -3929,6 +3949,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 638 | if (bss->ocv && !bss->ieee80211w) |
| 639 | bss->ieee80211w = 1; |
| 640 | #endif /* CONFIG_OCV */ |
| 641 | + } else if (os_strcmp(buf, "noscan") == 0) { |
| 642 | + conf->noscan = atoi(pos); |
| 643 | + } else if (os_strcmp(buf, "ht_coex") == 0) { |
| 644 | + conf->no_ht_coex = !atoi(pos); |
| 645 | } else if (os_strcmp(buf, "ieee80211n") == 0) { |
| 646 | conf->ieee80211n = atoi(pos); |
| 647 | } else if (os_strcmp(buf, "ht_capab") == 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 648 | @@ -3979,6 +4003,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 649 | } else if (os_strcmp(buf, "he_bss_color") == 0) { |
| 650 | conf->he_op.he_bss_color = atoi(pos) & 0x3f; |
| 651 | conf->he_op.he_bss_color_disabled = 0; |
| 652 | + if (atoi(pos) > 63) |
| 653 | + conf->he_op.he_bss_color = os_random() % 63 + 1; |
| 654 | } else if (os_strcmp(buf, "he_bss_color_partial") == 0) { |
| 655 | conf->he_op.he_bss_color_partial = atoi(pos); |
| 656 | } else if (os_strcmp(buf, "he_default_pe_duration") == 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 657 | @@ -5435,6 +5461,15 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 658 | bss->mld_indicate_disabled = atoi(pos); |
| 659 | #endif /* CONFIG_TESTING_OPTIONS */ |
| 660 | #endif /* CONFIG_IEEE80211BE */ |
| 661 | +#ifdef CONFIG_APUP |
| 662 | + } else if (os_strcmp(buf, "apup") == 0) { |
| 663 | + bss->apup = !!atoi(pos); |
| 664 | + if (bss->apup) |
| 665 | + bss->wds_sta = 1; |
| 666 | + } else if (os_strcmp(buf, "apup_peer_ifname_prefix") == 0) { |
| 667 | + os_strlcpy(bss->apup_peer_ifname_prefix, |
| 668 | + pos, sizeof(bss->apup_peer_ifname_prefix)); |
| 669 | +#endif // def CONFIG_APUP |
| 670 | } else { |
| 671 | wpa_printf(MSG_ERROR, |
| 672 | "Line %d: unknown configuration item '%s'", |
| 673 | @@ -5460,7 +5495,12 @@ struct hostapd_config * hostapd_config_read(const char *fname) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 674 | int errors = 0; |
| 675 | size_t i; |
| 676 | |
| 677 | - f = fopen(fname, "r"); |
| 678 | + if (!strncmp(fname, "data:", 5)) { |
| 679 | + f = fmemopen((void *)(fname + 5), strlen(fname + 5), "r"); |
| 680 | + fname = "<inline>"; |
| 681 | + } else { |
| 682 | + f = fopen(fname, "r"); |
| 683 | + } |
| 684 | if (f == NULL) { |
| 685 | wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " |
| 686 | "for reading.", fname); |
| 687 | diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 688 | index a584d370e..1d5922fab 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 689 | --- a/hostapd/ctrl_iface.c |
| 690 | +++ b/hostapd/ctrl_iface.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 691 | @@ -4005,6 +4005,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 692 | reply_size); |
| 693 | } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { |
| 694 | reply_len = hostapd_drv_status(hapd, reply, reply_size); |
| 695 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 696 | } else if (os_strcmp(buf, "MIB") == 0) { |
| 697 | reply_len = ieee802_11_get_mib(hapd, reply, reply_size); |
| 698 | if (reply_len >= 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 699 | @@ -4046,6 +4047,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 700 | } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { |
| 701 | reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, |
| 702 | reply_size); |
| 703 | +#endif |
| 704 | } else if (os_strcmp(buf, "ATTACH") == 0) { |
| 705 | if (hostapd_ctrl_iface_attach(hapd, from, fromlen, NULL)) |
| 706 | reply_len = -1; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 707 | @@ -5994,6 +5996,7 @@ try_again: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 708 | return -1; |
| 709 | } |
| 710 | |
| 711 | + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; |
| 712 | wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); |
| 713 | |
| 714 | return 0; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 715 | @@ -6095,6 +6098,7 @@ fail: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 716 | os_free(fname); |
| 717 | |
| 718 | interface->global_ctrl_sock = s; |
| 719 | + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; |
| 720 | eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive, |
| 721 | interface, NULL); |
| 722 | |
| 723 | diff --git a/hostapd/defconfig b/hostapd/defconfig |
| 724 | index 66bf894eb..f716553bb 100644 |
| 725 | --- a/hostapd/defconfig |
| 726 | +++ b/hostapd/defconfig |
| 727 | @@ -6,9 +6,21 @@ |
| 728 | # just setting VARIABLE=n is not disabling that variable. |
| 729 | # |
| 730 | # This file is included in Makefile, so variables like CFLAGS and LIBS can also |
| 731 | -# be modified from here. In most cass, these lines should use += in order not |
| 732 | +# be modified from here. In most cases, these lines should use += in order not |
| 733 | # to override previous values of the variables. |
| 734 | |
| 735 | + |
| 736 | +# Uncomment following two lines and fix the paths if you have installed TLS |
| 737 | +# libraries in a non-default location |
| 738 | +#CFLAGS += -I/usr/local/openssl/include |
| 739 | +#LIBS += -L/usr/local/openssl/lib |
| 740 | + |
| 741 | +# Some Red Hat versions seem to include kerberos header files from OpenSSL, but |
| 742 | +# the kerberos files are not in the default include path. Following line can be |
| 743 | +# used to fix build issues on such systems (krb5.h not found). |
| 744 | +#CFLAGS += -I/usr/include/kerberos |
| 745 | + |
| 746 | + |
| 747 | # Driver interface for Host AP driver |
| 748 | CONFIG_DRIVER_HOSTAP=y |
| 749 | |
| 750 | @@ -281,6 +293,7 @@ CONFIG_IPV6=y |
| 751 | # openssl = OpenSSL (default) |
| 752 | # gnutls = GnuTLS |
| 753 | # internal = Internal TLSv1 implementation (experimental) |
| 754 | +# mbedtls = mbed TLS |
| 755 | # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) |
| 756 | # none = Empty template |
| 757 | #CONFIG_TLS=openssl |
| 758 | diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 759 | index d69525502..ebf8addc1 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 760 | --- a/hostapd/hostapd_cli.c |
| 761 | +++ b/hostapd/hostapd_cli.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 762 | @@ -410,7 +410,6 @@ static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 763 | } |
| 764 | |
| 765 | |
| 766 | -#ifdef CONFIG_TAXONOMY |
| 767 | static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, |
| 768 | char *argv[]) |
| 769 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 770 | @@ -423,7 +422,6 @@ static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 771 | os_snprintf(buf, sizeof(buf), "SIGNATURE %s", argv[0]); |
| 772 | return wpa_ctrl_command(ctrl, buf); |
| 773 | } |
| 774 | -#endif /* CONFIG_TAXONOMY */ |
| 775 | |
| 776 | |
| 777 | static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 778 | @@ -440,7 +438,6 @@ static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 779 | } |
| 780 | |
| 781 | |
| 782 | -#ifdef CONFIG_WPS |
| 783 | static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, |
| 784 | char *argv[]) |
| 785 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 786 | @@ -666,7 +663,6 @@ static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 787 | ssid_hex, argv[1]); |
| 788 | return wpa_ctrl_command(ctrl, buf); |
| 789 | } |
| 790 | -#endif /* CONFIG_WPS */ |
| 791 | |
| 792 | |
| 793 | static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 794 | @@ -766,7 +762,7 @@ static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 795 | } |
| 796 | |
| 797 | buf[len] = '\0'; |
| 798 | - if (memcmp(buf, "FAIL", 4) == 0) |
| 799 | + if (memcmp(buf, "FAIL", 4) == 0 || memcmp(buf, "UNKNOWN COMMAND", 15) == 0) |
| 800 | return -1; |
| 801 | if (print) |
| 802 | printf("%s", buf); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 803 | @@ -1695,13 +1691,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 804 | { "disassociate", hostapd_cli_cmd_disassociate, |
| 805 | hostapd_complete_stations, |
| 806 | "<addr> = disassociate a station" }, |
| 807 | -#ifdef CONFIG_TAXONOMY |
| 808 | { "signature", hostapd_cli_cmd_signature, hostapd_complete_stations, |
| 809 | "<addr> = get taxonomy signature for a station" }, |
| 810 | -#endif /* CONFIG_TAXONOMY */ |
| 811 | { "sa_query", hostapd_cli_cmd_sa_query, hostapd_complete_stations, |
| 812 | "<addr> = send SA Query to a station" }, |
| 813 | -#ifdef CONFIG_WPS |
| 814 | { "wps_pin", hostapd_cli_cmd_wps_pin, NULL, |
| 815 | "<uuid> <pin> [timeout] [addr] = add WPS Enrollee PIN" }, |
| 816 | { "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 817 | @@ -1726,7 +1719,6 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 818 | "<SSID> <auth> <encr> <key> = configure AP" }, |
| 819 | { "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, |
| 820 | "= show current WPS status" }, |
| 821 | -#endif /* CONFIG_WPS */ |
| 822 | { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent, NULL, |
| 823 | "= send Disassociation Imminent notification" }, |
| 824 | { "ess_disassoc", hostapd_cli_cmd_ess_disassoc, NULL, |
| 825 | diff --git a/hostapd/main.c b/hostapd/main.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 826 | index aa1f69812..e790f18ce 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 827 | --- a/hostapd/main.c |
| 828 | +++ b/hostapd/main.c |
| 829 | @@ -31,7 +31,7 @@ |
| 830 | #include "config_file.h" |
| 831 | #include "eap_register.h" |
| 832 | #include "ctrl_iface.h" |
| 833 | - |
| 834 | +#include "build_features.h" |
| 835 | |
| 836 | struct hapd_global { |
| 837 | void **drv_priv; |
| 838 | @@ -40,6 +40,7 @@ struct hapd_global { |
| 839 | |
| 840 | static struct hapd_global global; |
| 841 | |
| 842 | +extern int radius_main(int argc, char **argv); |
| 843 | |
| 844 | #ifndef CONFIG_NO_HOSTAPD_LOGGER |
| 845 | static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 846 | @@ -692,6 +693,11 @@ fail: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 847 | return -1; |
| 848 | } |
| 849 | |
| 850 | +void hostapd_wpa_event(void *ctx, enum wpa_event_type event, |
| 851 | + union wpa_event_data *data); |
| 852 | + |
| 853 | +void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, |
| 854 | + union wpa_event_data *data); |
| 855 | |
| 856 | #ifdef CONFIG_WPS |
| 857 | static int gen_uuid(const char *txt_addr) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 858 | @@ -784,6 +790,11 @@ int main(int argc, char *argv[]) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 859 | if (os_program_init()) |
| 860 | return -1; |
| 861 | |
| 862 | +#ifdef RADIUS_SERVER |
| 863 | + if (strstr(argv[0], "radius")) |
| 864 | + return radius_main(argc, argv); |
| 865 | +#endif |
| 866 | + |
| 867 | os_memset(&interfaces, 0, sizeof(interfaces)); |
| 868 | interfaces.reload_config = hostapd_reload_config; |
| 869 | interfaces.config_read_cb = hostapd_config_read; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 870 | @@ -813,8 +824,10 @@ int main(int argc, char *argv[]) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 871 | return -1; |
| 872 | #endif /* CONFIG_DPP */ |
| 873 | |
| 874 | + wpa_supplicant_event = hostapd_wpa_event; |
| 875 | + wpa_supplicant_event_global = hostapd_wpa_event_global; |
| 876 | for (;;) { |
| 877 | - c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:q"); |
| 878 | + c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:g:G:qv::"); |
| 879 | if (c < 0) |
| 880 | break; |
| 881 | switch (c) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 882 | @@ -851,6 +864,8 @@ int main(int argc, char *argv[]) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 883 | break; |
| 884 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ |
| 885 | case 'v': |
| 886 | + if (optarg) |
| 887 | + exit(!has_feature(optarg)); |
| 888 | show_version(); |
| 889 | exit(1); |
| 890 | case 'g': |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 891 | @@ -1020,6 +1035,7 @@ int main(int argc, char *argv[]) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 892 | } |
| 893 | |
| 894 | hostapd_global_ctrl_iface_init(&interfaces); |
| 895 | + hostapd_ucode_init(&interfaces); |
| 896 | |
| 897 | if (hostapd_global_run(&interfaces, daemonize, pid_file)) { |
| 898 | wpa_printf(MSG_ERROR, "Failed to start eloop"); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 899 | @@ -1029,6 +1045,7 @@ int main(int argc, char *argv[]) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 900 | ret = 0; |
| 901 | |
| 902 | out: |
| 903 | + hostapd_ucode_free(); |
| 904 | hostapd_global_ctrl_iface_deinit(&interfaces); |
| 905 | /* Deinitialize all interfaces */ |
| 906 | for (i = 0; i < interfaces.count; i++) { |
| 907 | diff --git a/src/ap/acs.c b/src/ap/acs.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 908 | index f5b36d327..25fec499a 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 909 | --- a/src/ap/acs.c |
| 910 | +++ b/src/ap/acs.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 911 | @@ -471,17 +471,17 @@ static int acs_get_bw_center_chan(int freq, enum bw_type bw) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 912 | static int acs_survey_is_sufficient(struct freq_survey *survey) |
| 913 | { |
| 914 | if (!(survey->filled & SURVEY_HAS_NF)) { |
| 915 | + survey->nf = -95; |
| 916 | wpa_printf(MSG_INFO, |
| 917 | "ACS: Survey for freq %d is missing noise floor", |
| 918 | survey->freq); |
| 919 | - return 0; |
| 920 | } |
| 921 | |
| 922 | if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { |
| 923 | + survey->channel_time = 0; |
| 924 | wpa_printf(MSG_INFO, |
| 925 | "ACS: Survey for freq %d is missing channel time", |
| 926 | survey->freq); |
| 927 | - return 0; |
| 928 | } |
| 929 | |
| 930 | if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 931 | @@ -489,7 +489,6 @@ static int acs_survey_is_sufficient(struct freq_survey *survey) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 932 | wpa_printf(MSG_INFO, |
| 933 | "ACS: Survey for freq %d is missing RX and busy time (at least one is required)", |
| 934 | survey->freq); |
| 935 | - return 0; |
| 936 | } |
| 937 | |
| 938 | return 1; |
| 939 | diff --git a/src/ap/airtime_policy.c b/src/ap/airtime_policy.c |
| 940 | index 68443115f..26f11ad98 100644 |
| 941 | --- a/src/ap/airtime_policy.c |
| 942 | +++ b/src/ap/airtime_policy.c |
| 943 | @@ -112,8 +112,14 @@ static void set_sta_weights(struct hostapd_data *hapd, unsigned int weight) |
| 944 | { |
| 945 | struct sta_info *sta; |
| 946 | |
| 947 | - for (sta = hapd->sta_list; sta; sta = sta->next) |
| 948 | - sta_set_airtime_weight(hapd, sta, weight); |
| 949 | + for (sta = hapd->sta_list; sta; sta = sta->next) { |
| 950 | + unsigned int sta_weight = weight; |
| 951 | + |
| 952 | + if (sta->dyn_airtime_weight) |
| 953 | + sta_weight = (weight * sta->dyn_airtime_weight) / 256; |
| 954 | + |
| 955 | + sta_set_airtime_weight(hapd, sta, sta_weight); |
| 956 | + } |
| 957 | } |
| 958 | |
| 959 | |
| 960 | @@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostapd_data *hapd, struct sta_info *sta) |
| 961 | unsigned int weight; |
| 962 | |
| 963 | if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) { |
| 964 | - weight = get_weight_for_sta(hapd, sta->addr); |
| 965 | + if (sta->dyn_airtime_weight) |
| 966 | + weight = sta->dyn_airtime_weight; |
| 967 | + else |
| 968 | + weight = get_weight_for_sta(hapd, sta->addr); |
| 969 | if (weight) |
| 970 | return sta_set_airtime_weight(hapd, sta, weight); |
| 971 | } |
| 972 | diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 973 | index e6669e6a3..29a9ae7db 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 974 | --- a/src/ap/ap_config.h |
| 975 | +++ b/src/ap/ap_config.h |
| 976 | @@ -121,6 +121,7 @@ struct hostapd_ssid { |
| 977 | #define DYNAMIC_VLAN_OPTIONAL 1 |
| 978 | #define DYNAMIC_VLAN_REQUIRED 2 |
| 979 | int dynamic_vlan; |
| 980 | + int vlan_no_bridge; |
| 981 | #define DYNAMIC_VLAN_NAMING_WITHOUT_DEVICE 0 |
| 982 | #define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1 |
| 983 | #define DYNAMIC_VLAN_NAMING_END 2 |
| 984 | @@ -282,6 +283,8 @@ struct airtime_sta_weight { |
| 985 | struct hostapd_bss_config { |
| 986 | char iface[IFNAMSIZ + 1]; |
| 987 | char bridge[IFNAMSIZ + 1]; |
| 988 | + char ft_iface[IFNAMSIZ + 1]; |
| 989 | + char snoop_iface[IFNAMSIZ + 1]; |
| 990 | char vlan_bridge[IFNAMSIZ + 1]; |
| 991 | char wds_bridge[IFNAMSIZ + 1]; |
| 992 | int bridge_hairpin; /* hairpin_mode on bridge members */ |
| 993 | @@ -307,6 +310,7 @@ struct hostapd_bss_config { |
| 994 | unsigned int eap_sim_db_timeout; |
| 995 | int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ |
| 996 | struct hostapd_ip_addr own_ip_addr; |
| 997 | + int dynamic_own_ip_addr; |
| 998 | char *nas_identifier; |
| 999 | struct hostapd_radius_servers *radius; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1000 | int radius_require_message_authenticator; |
| 1001 | @@ -995,6 +999,35 @@ struct hostapd_bss_config { |
| 1002 | bool mld_indicate_disabled; |
| 1003 | #endif /* CONFIG_TESTING_OPTIONS */ |
| 1004 | #endif /* CONFIG_IEEE80211BE */ |
| 1005 | + |
| 1006 | +#ifdef CONFIG_APUP |
| 1007 | + /** |
| 1008 | + * Access Point Micro Peering |
| 1009 | + * A simpler and more useful successor to Ad Hoc, |
| 1010 | + * Wireless Distribution System, 802.11s mesh mode, Multi-AP and EasyMesh. |
| 1011 | + * |
| 1012 | + * Almost plain APs communicate between them via 4-address mode, like in WDS |
| 1013 | + * but all of them are AP, so they can eventually communicate also with |
| 1014 | + * plain stations and more AP nodes in sight. |
| 1015 | + * Low hardware requirements, just AP mode support + 4-address mode, and no |
| 1016 | + * more unnecessary complications, like hardcoded bridging or routing |
| 1017 | + * algorithm in WiFi stack. |
| 1018 | + * For each AP in sight an interface is created, and then it can be used as |
| 1019 | + * convenient in each case, bridging, routing etc. |
| 1020 | + */ |
| 1021 | + bool apup; |
| 1022 | + |
| 1023 | + /** |
| 1024 | + * In 4-address mode each peer AP in sight is associated to its own |
| 1025 | + * interface so we have more flexibility in "user-space". |
| 1026 | + * Those interfaces could be simply bridged in a trivial topology (which |
| 1027 | + * happens automatically if wds_bridge is not an empty string), or feeded to |
| 1028 | + * a routing daemon. |
| 1029 | + * |
| 1030 | + * If not defined interface names are generated following the WDS convention. |
| 1031 | + */ |
| 1032 | + char apup_peer_ifname_prefix[IFNAMSIZ + 1]; |
| 1033 | +#endif /* CONFIG_APUP */ |
| 1034 | }; |
| 1035 | |
| 1036 | /** |
| 1037 | @@ -1085,6 +1118,8 @@ struct hostapd_config { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1038 | unsigned int track_sta_max_num; |
| 1039 | unsigned int track_sta_max_age; |
| 1040 | |
| 1041 | + int max_num_sta; |
| 1042 | + |
| 1043 | char country[3]; /* first two octets: country code as described in |
| 1044 | * ISO/IEC 3166-1. Third octet: |
| 1045 | * ' ' (ascii 32): all environments |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1046 | @@ -1122,6 +1157,8 @@ struct hostapd_config { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1047 | |
| 1048 | int ht_op_mode_fixed; |
| 1049 | u16 ht_capab; |
| 1050 | + int noscan; |
| 1051 | + int no_ht_coex; |
| 1052 | int ieee80211n; |
| 1053 | int secondary_channel; |
| 1054 | int no_pri_sec_switch; |
| 1055 | diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1056 | index c47349110..7c9527cd3 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1057 | --- a/src/ap/ap_drv_ops.c |
| 1058 | +++ b/src/ap/ap_drv_ops.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1059 | @@ -385,13 +385,37 @@ int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds, |
| 1060 | const u8 *addr, int aid, int val) |
| 1061 | { |
| 1062 | const char *bridge = NULL; |
| 1063 | + char ifName[IFNAMSIZ + 1]; |
| 1064 | + |
| 1065 | + int mRet = 0; |
| 1066 | |
| 1067 | if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1068 | return -1; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1069 | + |
| 1070 | +#ifdef CONFIG_APUP |
| 1071 | + if (hapd->conf->apup && hapd->conf->apup_peer_ifname_prefix[0]) { |
| 1072 | + mRet = os_snprintf( |
| 1073 | + ifName, sizeof(ifName), "%s%d", |
| 1074 | + hapd->conf->apup_peer_ifname_prefix, aid); |
| 1075 | + } |
| 1076 | + else |
| 1077 | +#endif // def CONFIG_APUP |
| 1078 | + mRet = os_snprintf( |
| 1079 | + ifName, sizeof(ifName), "%s.sta%d", |
| 1080 | + hapd->conf->iface, aid); |
| 1081 | + |
| 1082 | + if (mRet >= (int) sizeof(ifName)) |
| 1083 | + wpa_printf(MSG_WARNING, |
| 1084 | + "nl80211: WDS interface name was truncated"); |
| 1085 | + else if (mRet < 0) |
| 1086 | + return mRet; |
| 1087 | + |
| 1088 | + // Pass back to the caller the resulting interface name |
| 1089 | + if (ifname_wds) |
| 1090 | + os_strlcpy(ifname_wds, ifName, IFNAMSIZ + 1); |
| 1091 | + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1092 | if (hapd->conf->wds_bridge[0]) |
| 1093 | bridge = hapd->conf->wds_bridge; |
| 1094 | - else if (hapd->conf->bridge[0]) |
| 1095 | - bridge = hapd->conf->bridge; |
| 1096 | return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val, |
| 1097 | bridge, ifname_wds); |
| 1098 | } |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1099 | diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1100 | index d7e79c840..58ca046c6 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1101 | --- a/src/ap/ap_drv_ops.h |
| 1102 | +++ b/src/ap/ap_drv_ops.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1103 | @@ -35,6 +35,9 @@ int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname, |
| 1104 | int enabled); |
| 1105 | int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname); |
| 1106 | int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname); |
| 1107 | + |
| 1108 | +/** @param val as per nl80211 driver implementation, 1 means add 0 means remove |
| 1109 | + */ |
| 1110 | int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds, |
| 1111 | const u8 *addr, int aid, int val); |
| 1112 | int hostapd_sta_add(struct hostapd_data *hapd, |
| 1113 | @@ -371,12 +374,12 @@ static inline int hostapd_drv_br_port_set_attr(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1114 | |
| 1115 | static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, |
| 1116 | enum drv_br_net_param param, |
| 1117 | - unsigned int val) |
| 1118 | + const char *ifname, unsigned int val) |
| 1119 | { |
| 1120 | if (hapd->driver == NULL || hapd->drv_priv == NULL || |
| 1121 | hapd->driver->br_set_net_param == NULL) |
| 1122 | return -1; |
| 1123 | - return hapd->driver->br_set_net_param(hapd->drv_priv, param, val); |
| 1124 | + return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val); |
| 1125 | } |
| 1126 | |
| 1127 | static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1128 | @@ -404,6 +407,23 @@ static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1129 | return hapd->driver->stop_ap(hapd->drv_priv, link_id); |
| 1130 | } |
| 1131 | |
| 1132 | +static inline int hostapd_drv_if_rename(struct hostapd_data *hapd, |
| 1133 | + enum wpa_driver_if_type type, |
| 1134 | + const char *ifname, |
| 1135 | + const char *new_name) |
| 1136 | +{ |
| 1137 | + if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv) |
| 1138 | + return -1; |
| 1139 | + return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name); |
| 1140 | +} |
| 1141 | + |
| 1142 | +static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd) |
| 1143 | +{ |
| 1144 | + if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv) |
| 1145 | + return 0; |
| 1146 | + return hapd->driver->set_first_bss(hapd->drv_priv); |
| 1147 | +} |
| 1148 | + |
| 1149 | static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, |
| 1150 | struct wpa_channel_info *ci) |
| 1151 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1152 | diff --git a/src/ap/apup.c b/src/ap/apup.c |
| 1153 | new file mode 100644 |
| 1154 | index 000000000..f736ddc8e |
| 1155 | --- /dev/null |
| 1156 | +++ b/src/ap/apup.c |
| 1157 | @@ -0,0 +1,168 @@ |
| 1158 | +/* |
| 1159 | + * hostapd / APuP Access Point Micro Peering |
| 1160 | + * |
| 1161 | + * Copyright (C) 2023-2024 Gioacchino Mazzurco <gio@polymathes.cc> |
| 1162 | + * |
| 1163 | + * This software may be distributed under the terms of the BSD license. |
| 1164 | + * See README for more details. |
| 1165 | + */ |
| 1166 | + |
| 1167 | +/* Be extremely careful altering include order, move just one in the wrong place |
| 1168 | + * and you will start getting a bunch of error of undefined bool, size_t etc. */ |
| 1169 | + |
| 1170 | +#include "utils/includes.h" |
| 1171 | +#include "utils/common.h" |
| 1172 | +#include "utils/os.h" |
| 1173 | + |
| 1174 | +#include "apup.h" |
| 1175 | + |
| 1176 | +#include "drivers/driver.h" |
| 1177 | +#include "wpa_auth.h" |
| 1178 | +#include "ap_mlme.h" |
| 1179 | +#include "ieee802_11.h" |
| 1180 | +#include "ap_drv_ops.h" |
| 1181 | +#include "sta_info.h" |
| 1182 | + |
| 1183 | +#ifdef UBUS_SUPPORT |
| 1184 | +# include "ubus.h" |
| 1185 | +#endif |
| 1186 | + |
| 1187 | +#ifdef UCODE_SUPPORT |
| 1188 | +# include "ucode.h" |
| 1189 | +#endif |
| 1190 | + |
| 1191 | +void apup_process_beacon(struct hostapd_data *hapd, |
| 1192 | + const struct ieee80211_mgmt *mgmt, size_t len, |
| 1193 | + const struct ieee802_11_elems *elems ) |
| 1194 | +{ |
| 1195 | + if (!os_memcmp(hapd->own_addr, mgmt->bssid, ETH_ALEN)) |
| 1196 | + { |
| 1197 | + wpa_printf(MSG_WARNING, |
| 1198 | + "apup_process_beacon(...) own beacon elems.ssid %.*s", |
| 1199 | + (int) elems->ssid_len, elems->ssid); |
| 1200 | + return; |
| 1201 | + } |
| 1202 | + |
| 1203 | + if (elems->ssid_len != hapd->conf->ssid.ssid_len || |
| 1204 | + os_memcmp(elems->ssid, hapd->conf->ssid.ssid, elems->ssid_len)) |
| 1205 | + return; |
| 1206 | + |
| 1207 | + struct sta_info* sta_ret = ap_get_sta(hapd, mgmt->bssid); |
| 1208 | + if (sta_ret) |
| 1209 | + return; |
| 1210 | + |
| 1211 | + sta_ret = ap_sta_add(hapd, mgmt->bssid); |
| 1212 | + |
| 1213 | + /* TODO: this has been added just to making compiler happy after breaking |
| 1214 | + * changes introduced in 11a607d121df512e010148bedcb4263a03329dc7 to support |
| 1215 | + * IEEE80211BE Multi Link Operation. Look at that commit with more time and |
| 1216 | + * understand what could be a proper implementation in this context too |
| 1217 | + */ |
| 1218 | + const u8 *mld_link_addr = NULL; |
| 1219 | + bool mld_link_sta = false; |
| 1220 | + |
| 1221 | + /* First add the station without more information */ |
| 1222 | + int aRet = hostapd_sta_add( |
| 1223 | + hapd, mgmt->bssid, sta_ret->aid, 0, |
| 1224 | + NULL, 0, 0, NULL, NULL, NULL, 0, NULL, 0, NULL, |
| 1225 | + sta_ret->flags, 0, 0, 0, |
| 1226 | + 0, // 0 add, 1 set |
| 1227 | + mld_link_addr, mld_link_sta); |
| 1228 | + |
| 1229 | + sta_ret->flags |= WLAN_STA_AUTH; |
| 1230 | + wpa_auth_sm_event(sta_ret->wpa_sm, WPA_AUTH); |
| 1231 | + |
| 1232 | + /* TODO: Investigate if supporting WPA or other encryption method is |
| 1233 | + * possible */ |
| 1234 | + sta_ret->auth_alg = WLAN_AUTH_OPEN; |
| 1235 | + mlme_authenticate_indication(hapd, sta_ret); |
| 1236 | + |
| 1237 | + sta_ret->capability = le_to_host16(mgmt->u.beacon.capab_info); |
| 1238 | + |
| 1239 | + if (sta_ret->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) |
| 1240 | + sta_ret->flags |= WLAN_STA_SHORT_PREAMBLE; |
| 1241 | + else |
| 1242 | + sta_ret->flags &= ~WLAN_STA_SHORT_PREAMBLE; |
| 1243 | + |
| 1244 | + hostapd_copy_supp_rates(hapd, sta_ret, elems); |
| 1245 | + |
| 1246 | + /* Whithout this flag copy_sta_[v]ht_capab will disable [V]HT |
| 1247 | + * capabilities even if available */ |
| 1248 | + if (elems->ht_capabilities || elems->vht_capabilities) |
| 1249 | + sta_ret->flags |= WLAN_STA_WMM; |
| 1250 | + |
| 1251 | + copy_sta_ht_capab(hapd, sta_ret, elems->ht_capabilities); |
| 1252 | +#ifdef CONFIG_IEEE80211AC |
| 1253 | + copy_sta_vht_capab(hapd, sta_ret, elems->vht_capabilities); |
| 1254 | + copy_sta_vht_oper(hapd, sta_ret, elems->vht_operation); |
| 1255 | + copy_sta_vendor_vht(hapd, sta_ret, elems->vendor_vht, elems->vendor_vht_len); |
| 1256 | +#endif // def CONFIG_IEEE80211AC |
| 1257 | +#ifdef CONFIG_IEEE80211AX |
| 1258 | + copy_sta_he_capab(hapd, sta_ret, IEEE80211_MODE_AP, |
| 1259 | + elems->he_capabilities, elems->he_capabilities_len); |
| 1260 | + copy_sta_he_6ghz_capab(hapd, sta_ret, elems->he_6ghz_band_cap); |
| 1261 | +#endif // def CONFIG_IEEE80211AX |
| 1262 | +#ifdef CONFIG_IEEE80211BE |
| 1263 | + copy_sta_eht_capab(hapd, sta_ret, |
| 1264 | + IEEE80211_MODE_AP, // TODO: Make sure is the right value |
| 1265 | + elems->he_capabilities, elems->he_capabilities_len, |
| 1266 | + elems->eht_capabilities, elems->eht_capabilities_len); |
| 1267 | +#endif //def CONFIG_IEEE80211BE |
| 1268 | + |
| 1269 | + update_ht_state(hapd, sta_ret); |
| 1270 | + |
| 1271 | + if (hostapd_get_aid(hapd, sta_ret) < 0) |
| 1272 | + { |
| 1273 | + wpa_printf(MSG_INFO, "apup_process_beacon(...) No room for more AIDs"); |
| 1274 | + return; |
| 1275 | + } |
| 1276 | + |
| 1277 | + sta_ret->flags |= WLAN_STA_ASSOC_REQ_OK; |
| 1278 | + |
| 1279 | + /* Make sure that the previously registered inactivity timer will not |
| 1280 | + * remove the STA immediately. */ |
| 1281 | + sta_ret->timeout_next = STA_NULLFUNC; |
| 1282 | + |
| 1283 | + sta_ret->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; |
| 1284 | + |
| 1285 | + /* Then set the paramethers */ |
| 1286 | + int sRet = hostapd_sta_add( |
| 1287 | + hapd, mgmt->bssid, sta_ret->aid, |
| 1288 | + sta_ret->capability, |
| 1289 | + sta_ret->supported_rates, sta_ret->supported_rates_len, |
| 1290 | + 0, // u16 listen_interval TODO ? |
| 1291 | + sta_ret->ht_capabilities, |
| 1292 | + sta_ret->vht_capabilities, |
| 1293 | + sta_ret->he_capab, sta_ret->he_capab_len, |
| 1294 | + sta_ret->eht_capab, sta_ret->eht_capab_len, |
| 1295 | + sta_ret->he_6ghz_capab, |
| 1296 | + sta_ret->flags, |
| 1297 | + 0, // u8 qosinfo |
| 1298 | + sta_ret->vht_opmode, |
| 1299 | + 0, // int supp_p2p_ps |
| 1300 | + 1, // 0 add, 1 set |
| 1301 | + mld_link_addr, mld_link_sta); |
| 1302 | + |
| 1303 | + ap_sta_set_authorized(hapd, sta_ret, 1); |
| 1304 | + hostapd_set_sta_flags(hapd, sta_ret); |
| 1305 | + |
| 1306 | + char mIfname[IFNAMSIZ + 1]; |
| 1307 | + os_memset(mIfname, 0, IFNAMSIZ + 1); |
| 1308 | + |
| 1309 | + // last param 1 means add 0 means remove |
| 1310 | + int mRet = hostapd_set_wds_sta( |
| 1311 | + hapd, mIfname, mgmt->bssid, sta_ret->aid, 1); |
| 1312 | + |
| 1313 | + wpa_printf(MSG_INFO, |
| 1314 | + "apup_process_beacon(...) Added APuP peer at %s with flags: %d," |
| 1315 | + " capabilities %d", |
| 1316 | + mIfname, sta_ret->flags, sta_ret->capability); |
| 1317 | + |
| 1318 | +#ifdef UBUS_SUPPORT |
| 1319 | + hostapd_ubus_notify_apup_newpeer(hapd, mgmt->bssid, mIfname); |
| 1320 | +#endif |
| 1321 | + |
| 1322 | +#ifdef UCODE_SUPPORT |
| 1323 | + hostapd_ucode_apup_newpeer(hapd, mIfname); |
| 1324 | +#endif |
| 1325 | +} |
| 1326 | diff --git a/src/ap/apup.h b/src/ap/apup.h |
| 1327 | new file mode 100644 |
| 1328 | index 000000000..a14a283bb |
| 1329 | --- /dev/null |
| 1330 | +++ b/src/ap/apup.h |
| 1331 | @@ -0,0 +1,24 @@ |
| 1332 | +/* |
| 1333 | + * hostapd / APuP Access Point Micro Peering |
| 1334 | + * |
| 1335 | + * Copyright (C) 2023-2024 Gioacchino Mazzurco <gio@polymathes.cc> |
| 1336 | + * |
| 1337 | + * This software may be distributed under the terms of the BSD license. |
| 1338 | + * See README for more details. |
| 1339 | + */ |
| 1340 | + |
| 1341 | +/* Be extremely careful altering include order, move just one in the wrong place |
| 1342 | + * and you will start getting a bunch of error of undefined bool, size_t etc. */ |
| 1343 | + |
| 1344 | +#include "utils/includes.h" |
| 1345 | +#include "utils/common.h" |
| 1346 | + |
| 1347 | +#include "hostapd.h" |
| 1348 | +#include "common/ieee802_11_defs.h" |
| 1349 | + |
| 1350 | +/** When beacons from other Access Point are received, if the SSID is matching |
| 1351 | + * add them as APuP peers (aka WDS STA to our own AP) the same happens on the |
| 1352 | + * peer when receiving our beacons */ |
| 1353 | +void apup_process_beacon(struct hostapd_data *hapd, |
| 1354 | + const struct ieee80211_mgmt *mgmt, size_t len, |
| 1355 | + const struct ieee802_11_elems *elems ); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1356 | diff --git a/src/ap/beacon.c b/src/ap/beacon.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1357 | index ddb99ca22..58b561661 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1358 | --- a/src/ap/beacon.c |
| 1359 | +++ b/src/ap/beacon.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1360 | @@ -1439,6 +1439,12 @@ void handle_probe_req(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1361 | int mld_id; |
| 1362 | u16 links; |
| 1363 | #endif /* CONFIG_IEEE80211BE */ |
| 1364 | + struct hostapd_ubus_request req = { |
| 1365 | + .type = HOSTAPD_UBUS_PROBE_REQ, |
| 1366 | + .mgmt_frame = mgmt, |
| 1367 | + .ssi_signal = ssi_signal, |
| 1368 | + .elems = &elems, |
| 1369 | + }; |
| 1370 | |
| 1371 | if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && |
| 1372 | ssi_signal < hapd->iconf->rssi_ignore_probe_request) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1373 | @@ -1492,7 +1498,7 @@ void handle_probe_req(struct hostapd_data *hapd, |
| 1374 | * is less likely to see them (Probe Request frame sent on a |
| 1375 | * neighboring, but partially overlapping, channel). |
| 1376 | */ |
| 1377 | - if (elems.ds_params && |
| 1378 | + if (elems.ds_params && 0 && |
| 1379 | hapd->iface->current_mode && |
| 1380 | (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G || |
| 1381 | hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B) && |
| 1382 | @@ -1625,6 +1631,12 @@ void handle_probe_req(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1383 | } |
| 1384 | #endif /* CONFIG_P2P */ |
| 1385 | |
| 1386 | + if (hostapd_ubus_handle_event(hapd, &req)) { |
| 1387 | + wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n", |
| 1388 | + MAC2STR(mgmt->sa)); |
| 1389 | + return; |
| 1390 | + } |
| 1391 | + |
| 1392 | /* TODO: verify that supp_rates contains at least one matching rate |
| 1393 | * with AP configuration */ |
| 1394 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1395 | @@ -1643,7 +1655,7 @@ void handle_probe_req(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1396 | if (hapd->conf->no_probe_resp_if_max_sta && |
| 1397 | is_multicast_ether_addr(mgmt->da) && |
| 1398 | is_multicast_ether_addr(mgmt->bssid) && |
| 1399 | - hapd->num_sta >= hapd->conf->max_num_sta && |
| 1400 | + hostapd_check_max_sta(hapd) && |
| 1401 | !ap_get_sta(hapd, mgmt->sa)) { |
| 1402 | wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR |
| 1403 | " since no room for additional STA", |
| 1404 | diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1405 | index d4d73de19..a1ddbda9f 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1406 | --- a/src/ap/ctrl_iface_ap.c |
| 1407 | +++ b/src/ap/ctrl_iface_ap.c |
| 1408 | @@ -26,6 +26,26 @@ |
| 1409 | #include "taxonomy.h" |
| 1410 | #include "wnm_ap.h" |
| 1411 | |
| 1412 | +static const char * hw_mode_str(enum hostapd_hw_mode mode) |
| 1413 | +{ |
| 1414 | + switch (mode) { |
| 1415 | + case HOSTAPD_MODE_IEEE80211B: |
| 1416 | + return "b"; |
| 1417 | + case HOSTAPD_MODE_IEEE80211G: |
| 1418 | + return "g"; |
| 1419 | + case HOSTAPD_MODE_IEEE80211A: |
| 1420 | + return "a"; |
| 1421 | + case HOSTAPD_MODE_IEEE80211AD: |
| 1422 | + return "ad"; |
| 1423 | + case HOSTAPD_MODE_IEEE80211ANY: |
| 1424 | + return "any"; |
| 1425 | + case NUM_HOSTAPD_MODES: |
| 1426 | + return "invalid"; |
| 1427 | + } |
| 1428 | + return "unknown"; |
| 1429 | +} |
| 1430 | + |
| 1431 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 1432 | |
| 1433 | static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen, |
| 1434 | size_t curr_len, const u8 *mcs_set) |
| 1435 | @@ -212,26 +232,6 @@ static const char * timeout_next_str(int val) |
| 1436 | } |
| 1437 | |
| 1438 | |
| 1439 | -static const char * hw_mode_str(enum hostapd_hw_mode mode) |
| 1440 | -{ |
| 1441 | - switch (mode) { |
| 1442 | - case HOSTAPD_MODE_IEEE80211B: |
| 1443 | - return "b"; |
| 1444 | - case HOSTAPD_MODE_IEEE80211G: |
| 1445 | - return "g"; |
| 1446 | - case HOSTAPD_MODE_IEEE80211A: |
| 1447 | - return "a"; |
| 1448 | - case HOSTAPD_MODE_IEEE80211AD: |
| 1449 | - return "ad"; |
| 1450 | - case HOSTAPD_MODE_IEEE80211ANY: |
| 1451 | - return "any"; |
| 1452 | - case NUM_HOSTAPD_MODES: |
| 1453 | - return "invalid"; |
| 1454 | - } |
| 1455 | - return "unknown"; |
| 1456 | -} |
| 1457 | - |
| 1458 | - |
| 1459 | static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd, |
| 1460 | struct sta_info *sta, |
| 1461 | char *buf, size_t buflen) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1462 | @@ -562,6 +562,7 @@ int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1463 | return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); |
| 1464 | } |
| 1465 | |
| 1466 | +#endif |
| 1467 | |
| 1468 | #ifdef CONFIG_P2P_MANAGER |
| 1469 | static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1470 | @@ -1010,12 +1011,12 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1471 | return len; |
| 1472 | len += ret; |
| 1473 | } |
| 1474 | - |
| 1475 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 1476 | if (iface->conf->ieee80211n && !hapd->conf->disable_11n && mode) { |
| 1477 | len = hostapd_write_ht_mcs_bitmask(buf, buflen, len, |
| 1478 | mode->mcs_set); |
| 1479 | } |
| 1480 | - |
| 1481 | +#endif /* CONFIG_CTRL_IFACE_MIB */ |
| 1482 | if (iface->current_rates && iface->num_rates) { |
| 1483 | ret = os_snprintf(buf + len, buflen - len, "supported_rates="); |
| 1484 | if (os_snprintf_error(buflen - len, ret)) |
| 1485 | diff --git a/src/ap/dfs.c b/src/ap/dfs.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1486 | index af9dc16f5..fe044297b 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1487 | --- a/src/ap/dfs.c |
| 1488 | +++ b/src/ap/dfs.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1489 | @@ -18,6 +18,7 @@ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1490 | #include "ap_drv_ops.h" |
| 1491 | #include "drivers/driver.h" |
| 1492 | #include "dfs.h" |
| 1493 | +#include "crypto/crypto.h" |
| 1494 | |
| 1495 | |
| 1496 | enum dfs_channel_type { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1497 | @@ -527,9 +528,14 @@ dfs_get_valid_channel(struct hostapd_iface *iface, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1498 | int num_available_chandefs; |
| 1499 | int chan_idx, chan_idx2; |
| 1500 | int sec_chan_idx_80p80 = -1; |
| 1501 | + bool is_mesh = false; |
| 1502 | int i; |
| 1503 | u32 _rand; |
| 1504 | |
| 1505 | +#ifdef CONFIG_MESH |
| 1506 | + is_mesh = iface->mconf; |
| 1507 | +#endif |
| 1508 | + |
| 1509 | wpa_printf(MSG_DEBUG, "DFS: Selecting random channel"); |
| 1510 | *secondary_channel = 0; |
| 1511 | *oper_centr_freq_seg0_idx = 0; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1512 | @@ -549,8 +555,20 @@ dfs_get_valid_channel(struct hostapd_iface *iface, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1513 | if (num_available_chandefs == 0) |
| 1514 | return NULL; |
| 1515 | |
| 1516 | - if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) |
| 1517 | + /* try to use deterministic channel in mesh, so that both sides |
| 1518 | + * have a chance to switch to the same channel */ |
| 1519 | + if (is_mesh) { |
| 1520 | +#ifdef CONFIG_MESH |
| 1521 | + u64 hash[4]; |
| 1522 | + const u8 *meshid[1] = { &iface->mconf->meshid[0] }; |
| 1523 | + const size_t meshid_len = iface->mconf->meshid_len; |
| 1524 | + |
| 1525 | + sha256_vector(1, meshid, &meshid_len, (u8 *)&hash[0]); |
| 1526 | + _rand = hash[0] + hash[1] + hash[2] + hash[3]; |
| 1527 | +#endif |
| 1528 | + } else if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) |
| 1529 | return NULL; |
| 1530 | + |
| 1531 | chan_idx = _rand % num_available_chandefs; |
| 1532 | wpa_printf(MSG_DEBUG, "DFS: Picked random entry from the list: %d/%d", |
| 1533 | chan_idx, num_available_chandefs); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1534 | @@ -1218,6 +1236,8 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1535 | "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", |
| 1536 | freq, ht_enabled, chan_offset, chan_width, cf1, cf2); |
| 1537 | |
| 1538 | + hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2); |
| 1539 | + |
| 1540 | /* Proceed only if DFS is not offloaded to the driver */ |
| 1541 | if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) |
| 1542 | return 0; |
| 1543 | diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1544 | index c74e551c5..6e76f697a 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1545 | --- a/src/ap/drv_callbacks.c |
| 1546 | +++ b/src/ap/drv_callbacks.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1547 | @@ -270,6 +270,10 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1548 | struct hostapd_iface *iface = hapd->iface; |
| 1549 | #endif /* CONFIG_OWE */ |
| 1550 | bool updated = false; |
| 1551 | + struct hostapd_ubus_request req = { |
| 1552 | + .type = HOSTAPD_UBUS_ASSOC_REQ, |
| 1553 | + .addr = addr, |
| 1554 | + }; |
| 1555 | |
| 1556 | if (addr == NULL) { |
| 1557 | /* |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1558 | @@ -414,6 +418,12 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1559 | goto fail; |
| 1560 | } |
| 1561 | |
| 1562 | + if (hostapd_ubus_handle_event(hapd, &req)) { |
| 1563 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", |
| 1564 | + MAC2STR(req.addr)); |
| 1565 | + goto fail; |
| 1566 | + } |
| 1567 | + |
| 1568 | #ifdef CONFIG_P2P |
| 1569 | if (elems.p2p) { |
| 1570 | wpabuf_free(sta->p2p_ie); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1571 | @@ -2416,8 +2426,8 @@ static void hostapd_event_color_change(struct hostapd_data *hapd, bool success) |
| 1572 | #endif /* CONFIG_IEEE80211AX */ |
| 1573 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1574 | |
| 1575 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 1576 | - union wpa_event_data *data) |
| 1577 | +void hostapd_wpa_event(void *ctx, enum wpa_event_type event, |
| 1578 | + union wpa_event_data *data) |
| 1579 | { |
| 1580 | struct hostapd_data *hapd = ctx; |
| 1581 | struct sta_info *sta; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1582 | @@ -2776,7 +2786,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1583 | } |
| 1584 | |
| 1585 | |
| 1586 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 1587 | +void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, |
| 1588 | union wpa_event_data *data) |
| 1589 | { |
| 1590 | struct hapd_interfaces *interfaces = ctx; |
| 1591 | diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1592 | index 5a8cdc90e..8159194e1 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1593 | --- a/src/ap/hostapd.c |
| 1594 | +++ b/src/ap/hostapd.c |
| 1595 | @@ -247,6 +247,29 @@ static int hostapd_iface_conf_changed(struct hostapd_config *newconf, |
| 1596 | return 0; |
| 1597 | } |
| 1598 | |
| 1599 | +static inline int hostapd_iface_num_sta(struct hostapd_iface *iface) |
| 1600 | +{ |
| 1601 | + int num_sta = 0; |
| 1602 | + int i; |
| 1603 | + |
| 1604 | + for (i = 0; i < iface->num_bss; i++) |
| 1605 | + num_sta += iface->bss[i]->num_sta; |
| 1606 | + |
| 1607 | + return num_sta; |
| 1608 | +} |
| 1609 | + |
| 1610 | + |
| 1611 | +int hostapd_check_max_sta(struct hostapd_data *hapd) |
| 1612 | +{ |
| 1613 | + if (hapd->num_sta >= hapd->conf->max_num_sta) |
| 1614 | + return 1; |
| 1615 | + |
| 1616 | + if (hapd->iconf->max_num_sta && |
| 1617 | + hostapd_iface_num_sta(hapd->iface) >= hapd->iconf->max_num_sta) |
| 1618 | + return 1; |
| 1619 | + |
| 1620 | + return 0; |
| 1621 | +} |
| 1622 | |
| 1623 | int hostapd_reload_config(struct hostapd_iface *iface) |
| 1624 | { |
| 1625 | @@ -255,6 +278,8 @@ int hostapd_reload_config(struct hostapd_iface *iface) |
| 1626 | struct hostapd_config *newconf, *oldconf; |
| 1627 | size_t j; |
| 1628 | |
| 1629 | + hostapd_ucode_reload_bss(hapd); |
| 1630 | + |
| 1631 | if (iface->config_fname == NULL) { |
| 1632 | /* Only in-memory config in use - assume it has been updated */ |
| 1633 | hostapd_clear_old(iface); |
| 1634 | @@ -475,6 +500,8 @@ void hostapd_free_hapd_data(struct hostapd_data *hapd) |
| 1635 | hapd->beacon_set_done = 0; |
| 1636 | |
| 1637 | wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); |
| 1638 | + hostapd_ucode_free_bss(hapd); |
| 1639 | + hostapd_ubus_free_bss(hapd); |
| 1640 | accounting_deinit(hapd); |
| 1641 | hostapd_deinit_wpa(hapd); |
| 1642 | vlan_deinit(hapd); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1643 | @@ -485,7 +512,7 @@ void hostapd_free_hapd_data(struct hostapd_data *hapd) |
| 1644 | struct hapd_interfaces *ifaces = hapd->iface->interfaces; |
| 1645 | size_t i; |
| 1646 | |
| 1647 | - for (i = 0; i < ifaces->count; i++) { |
| 1648 | + for (i = 0; ifaces && i < ifaces->count; i++) { |
| 1649 | struct hostapd_iface *iface = ifaces->iface[i]; |
| 1650 | size_t j; |
| 1651 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1652 | @@ -685,6 +712,7 @@ static void sta_track_deinit(struct hostapd_iface *iface) |
| 1653 | void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) |
| 1654 | { |
| 1655 | wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1656 | + hostapd_ucode_free_iface(iface); |
| 1657 | eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1658 | #ifdef NEED_AP_MLME |
| 1659 | hostapd_stop_setup_timers(iface); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1660 | @@ -1304,6 +1332,9 @@ static int hostapd_start_beacon(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1661 | if (hapd->driver && hapd->driver->set_operstate) |
| 1662 | hapd->driver->set_operstate(hapd->drv_priv, 1); |
| 1663 | |
| 1664 | + hostapd_ubus_add_bss(hapd); |
| 1665 | + hostapd_ucode_add_bss(hapd); |
| 1666 | + |
| 1667 | return 0; |
| 1668 | } |
| 1669 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1670 | @@ -1336,6 +1367,7 @@ static int hostapd_bss_radius_init(struct hostapd_data *hapd) |
| 1671 | |
| 1672 | os_memset(&das_conf, 0, sizeof(das_conf)); |
| 1673 | das_conf.port = conf->radius_das_port; |
| 1674 | + das_conf.nas_identifier = conf->nas_identifier; |
| 1675 | das_conf.shared_secret = conf->radius_das_shared_secret; |
| 1676 | das_conf.shared_secret_len = |
| 1677 | conf->radius_das_shared_secret_len; |
| 1678 | @@ -1378,8 +1410,7 @@ static int hostapd_bss_radius_init(struct hostapd_data *hapd) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1679 | * initialized. Most of the modules that are initialized here will be |
| 1680 | * deinitialized in hostapd_cleanup(). |
| 1681 | */ |
| 1682 | -static int hostapd_setup_bss(struct hostapd_data *hapd, int first, |
| 1683 | - bool start_beacon) |
| 1684 | +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon) |
| 1685 | { |
| 1686 | struct hostapd_bss_config *conf = hapd->conf; |
| 1687 | u8 ssid[SSID_MAX_LEN + 1]; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1688 | @@ -2510,6 +2541,7 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1689 | if (err) |
| 1690 | goto fail; |
| 1691 | |
| 1692 | + hostapd_ubus_add_iface(iface); |
| 1693 | wpa_printf(MSG_DEBUG, "Completing interface initialization"); |
| 1694 | if (iface->freq) { |
| 1695 | #ifdef NEED_AP_MLME |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1696 | @@ -2739,6 +2771,7 @@ dfs_offload: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1697 | |
| 1698 | fail: |
| 1699 | wpa_printf(MSG_ERROR, "Interface initialization failed"); |
| 1700 | + hostapd_ubus_free_iface(iface); |
| 1701 | |
| 1702 | if (iface->is_no_ir) { |
| 1703 | hostapd_set_state(iface, HAPD_IFACE_NO_IR); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1704 | @@ -2938,7 +2971,7 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1705 | } |
| 1706 | |
| 1707 | |
| 1708 | -static void hostapd_bss_deinit(struct hostapd_data *hapd) |
| 1709 | +void hostapd_bss_deinit(struct hostapd_data *hapd) |
| 1710 | { |
| 1711 | if (!hapd) |
| 1712 | return; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1713 | @@ -3471,6 +3504,7 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1714 | (unsigned int) iface->conf->num_bss); |
| 1715 | driver = iface->bss[0]->driver; |
| 1716 | drv_priv = iface->bss[0]->drv_priv; |
| 1717 | + hostapd_ubus_free_iface(iface); |
| 1718 | hostapd_interface_deinit(iface); |
| 1719 | wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", |
| 1720 | __func__, driver, drv_priv); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1721 | @@ -4002,7 +4036,8 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1722 | hapd_iface = interfaces->iface[i]; |
| 1723 | if (hapd_iface == NULL) |
| 1724 | return -1; |
| 1725 | - if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { |
| 1726 | + if (!os_strcmp(hapd_iface->phy, buf) || |
| 1727 | + !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { |
| 1728 | wpa_printf(MSG_INFO, "Remove interface '%s'", buf); |
| 1729 | hapd_iface->driver_ap_teardown = |
| 1730 | !!(hapd_iface->drv_flags & |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1731 | @@ -4048,6 +4083,8 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1732 | void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, |
| 1733 | int reassoc) |
| 1734 | { |
| 1735 | + int mld_assoc_link_id = -1; |
| 1736 | + |
| 1737 | if (hapd->tkip_countermeasures) { |
| 1738 | hostapd_drv_sta_deauth(hapd, sta->addr, |
| 1739 | WLAN_REASON_MICHAEL_MIC_FAILURE); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1740 | @@ -4055,10 +4092,16 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, |
| 1741 | } |
| 1742 | |
| 1743 | #ifdef CONFIG_IEEE80211BE |
| 1744 | - if (ap_sta_is_mld(hapd, sta) && |
| 1745 | - sta->mld_assoc_link_id != hapd->mld_link_id) |
| 1746 | - return; |
| 1747 | + if (ap_sta_is_mld(hapd, sta)) { |
| 1748 | + if (sta->mld_assoc_link_id == hapd->mld_link_id) { |
| 1749 | + mld_assoc_link_id = sta->mld_assoc_link_id; |
| 1750 | + } else { |
| 1751 | + return; |
| 1752 | + } |
| 1753 | + } |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1754 | #endif /* CONFIG_IEEE80211BE */ |
| 1755 | + if (mld_assoc_link_id != -2) |
| 1756 | + hostapd_prune_associations(hapd, sta->addr, mld_assoc_link_id); |
| 1757 | |
| 1758 | ap_sta_clear_disconnect_timeouts(hapd, sta); |
| 1759 | sta->post_csa_sa_query = 0; |
| 1760 | diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1761 | index 996977fdf..994e4681e 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1762 | --- a/src/ap/hostapd.h |
| 1763 | +++ b/src/ap/hostapd.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1764 | @@ -18,6 +18,8 @@ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1765 | #include "utils/list.h" |
| 1766 | #include "ap_config.h" |
| 1767 | #include "drivers/driver.h" |
| 1768 | +#include "ubus.h" |
| 1769 | +#include "ucode.h" |
| 1770 | |
| 1771 | #define OCE_STA_CFON_ENABLED(hapd) \ |
| 1772 | ((hapd->conf->oce & OCE_STA_CFON) && \ |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1773 | @@ -51,6 +53,10 @@ struct hapd_interfaces { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1774 | struct hostapd_config * (*config_read_cb)(const char *config_fname); |
| 1775 | int (*ctrl_iface_init)(struct hostapd_data *hapd); |
| 1776 | void (*ctrl_iface_deinit)(struct hostapd_data *hapd); |
| 1777 | + int (*ctrl_iface_recv)(struct hostapd_data *hapd, |
| 1778 | + char *buf, char *reply, int reply_size, |
| 1779 | + struct sockaddr_storage *from, |
| 1780 | + socklen_t fromlen); |
| 1781 | int (*for_each_interface)(struct hapd_interfaces *interfaces, |
| 1782 | int (*cb)(struct hostapd_iface *iface, |
| 1783 | void *ctx), void *ctx); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1784 | @@ -169,6 +175,21 @@ struct hostapd_sae_commit_queue { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1785 | u8 msg[]; |
| 1786 | }; |
| 1787 | |
| 1788 | +/** |
| 1789 | + * struct hostapd_openwrt_stats - OpenWrt custom STA/AP statistics |
| 1790 | + */ |
| 1791 | +struct hostapd_openwrt_stats { |
| 1792 | + struct { |
| 1793 | + u64 neighbor_report_tx; |
| 1794 | + } rrm; |
| 1795 | + |
| 1796 | + struct { |
| 1797 | + u64 bss_transition_query_rx; |
| 1798 | + u64 bss_transition_request_tx; |
| 1799 | + u64 bss_transition_response_rx; |
| 1800 | + } wnm; |
| 1801 | +}; |
| 1802 | + |
| 1803 | /** |
| 1804 | * struct hostapd_data - hostapd per-BSS data structure |
| 1805 | */ |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1806 | @@ -176,6 +197,8 @@ struct hostapd_data { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1807 | struct hostapd_iface *iface; |
| 1808 | struct hostapd_config *iconf; |
| 1809 | struct hostapd_bss_config *conf; |
| 1810 | + struct hostapd_ubus_bss ubus; |
| 1811 | + struct hostapd_ucode_bss ucode; |
| 1812 | int interface_added; /* virtual interface added for this BSS */ |
| 1813 | unsigned int started:1; |
| 1814 | unsigned int disabled:1; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1815 | @@ -183,6 +206,9 @@ struct hostapd_data { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1816 | |
| 1817 | u8 own_addr[ETH_ALEN]; |
| 1818 | |
| 1819 | + /* OpenWrt specific statistics */ |
| 1820 | + struct hostapd_openwrt_stats openwrt_stats; |
| 1821 | + |
| 1822 | int num_sta; /* number of entries in sta_list */ |
| 1823 | struct sta_info *sta_list; /* STA info list head */ |
| 1824 | #define STA_HASH_SIZE 256 |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1825 | @@ -535,6 +561,7 @@ struct hostapd_mld { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1826 | */ |
| 1827 | struct hostapd_iface { |
| 1828 | struct hapd_interfaces *interfaces; |
| 1829 | + struct hostapd_ucode_iface ucode; |
| 1830 | void *owner; |
| 1831 | char *config_fname; |
| 1832 | struct hostapd_config *conf; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1833 | @@ -786,6 +813,7 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1834 | struct hostapd_bss_config *bss); |
| 1835 | int hostapd_setup_interface(struct hostapd_iface *iface); |
| 1836 | int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); |
| 1837 | +void hostapd_set_own_neighbor_report(struct hostapd_data *hapd); |
| 1838 | void hostapd_interface_deinit(struct hostapd_iface *iface); |
| 1839 | void hostapd_interface_free(struct hostapd_iface *iface); |
| 1840 | struct hostapd_iface * hostapd_alloc_iface(void); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1841 | @@ -794,6 +822,8 @@ struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1842 | struct hostapd_iface * |
| 1843 | hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, |
| 1844 | const char *config_fname, int debug); |
| 1845 | +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon); |
| 1846 | +void hostapd_bss_deinit(struct hostapd_data *hapd); |
| 1847 | void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, |
| 1848 | int reassoc); |
| 1849 | void hostapd_interface_deinit_free(struct hostapd_iface *iface); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1850 | @@ -821,6 +851,7 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1851 | void hostapd_periodic_iface(struct hostapd_iface *iface); |
| 1852 | int hostapd_owe_trans_get_info(struct hostapd_data *hapd); |
| 1853 | void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); |
| 1854 | +int hostapd_check_max_sta(struct hostapd_data *hapd); |
| 1855 | |
| 1856 | void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); |
| 1857 | void hostapd_cleanup_cca_params(struct hostapd_data *hapd); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1858 | @@ -908,6 +939,16 @@ static inline bool hostapd_mld_is_first_bss(struct hostapd_data *hapd) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1859 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1860 | #endif /* CONFIG_IEEE80211BE */ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1861 | |
| 1862 | +static inline bool ap_sta_is_mld(struct hostapd_data *hapd, |
| 1863 | + struct sta_info *sta) |
| 1864 | +{ |
| 1865 | +#ifdef CONFIG_IEEE80211BE |
| 1866 | + return hapd->conf->mld_ap && sta && sta->mld_info.mld_sta; |
| 1867 | +#else /* CONFIG_IEEE80211BE */ |
| 1868 | + return false; |
| 1869 | +#endif /* CONFIG_IEEE80211BE */ |
| 1870 | +} |
| 1871 | + |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1872 | u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd); |
| 1873 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1874 | #endif /* HOSTAPD_H */ |
| 1875 | diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1876 | index 8aa0b3ab5..400c50988 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1877 | --- a/src/ap/hw_features.c |
| 1878 | +++ b/src/ap/hw_features.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1879 | @@ -553,7 +553,8 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1880 | int ret; |
| 1881 | |
| 1882 | /* Check that HT40 is used and PRI / SEC switch is allowed */ |
| 1883 | - if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch) |
| 1884 | + if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || |
| 1885 | + iface->conf->noscan) |
| 1886 | return 0; |
| 1887 | |
| 1888 | hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); |
| 1889 | diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1890 | index d8d82d737..39b1bb4c7 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1891 | --- a/src/ap/ieee802_11.c |
| 1892 | +++ b/src/ap/ieee802_11.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1893 | @@ -59,6 +59,9 @@ |
| 1894 | #include "nan_usd_ap.h" |
| 1895 | #include "pasn/pasn_common.h" |
| 1896 | |
| 1897 | +#ifdef CONFIG_APUP |
| 1898 | +# include "apup.h" |
| 1899 | +#endif // def CONFIG_APUP |
| 1900 | |
| 1901 | #ifdef CONFIG_FILS |
| 1902 | static struct wpabuf * |
| 1903 | @@ -2876,7 +2879,7 @@ static void handle_auth(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1904 | u16 auth_alg, auth_transaction, status_code; |
| 1905 | u16 resp = WLAN_STATUS_SUCCESS; |
| 1906 | struct sta_info *sta = NULL; |
| 1907 | - int res, reply_res; |
| 1908 | + int res, reply_res, ubus_resp; |
| 1909 | u16 fc; |
| 1910 | const u8 *challenge = NULL; |
| 1911 | u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1912 | @@ -2887,6 +2890,11 @@ static void handle_auth(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1913 | #ifdef CONFIG_IEEE80211BE |
| 1914 | bool mld_sta = false; |
| 1915 | #endif /* CONFIG_IEEE80211BE */ |
| 1916 | + struct hostapd_ubus_request req = { |
| 1917 | + .type = HOSTAPD_UBUS_AUTH_REQ, |
| 1918 | + .mgmt_frame = mgmt, |
| 1919 | + .ssi_signal = rssi, |
| 1920 | + }; |
| 1921 | |
| 1922 | if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { |
| 1923 | wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1924 | @@ -3083,6 +3091,13 @@ static void handle_auth(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1925 | resp = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 1926 | goto fail; |
| 1927 | } |
| 1928 | + ubus_resp = hostapd_ubus_handle_event(hapd, &req); |
| 1929 | + if (ubus_resp) { |
| 1930 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n", |
| 1931 | + MAC2STR(mgmt->sa)); |
| 1932 | + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 1933 | + goto fail; |
| 1934 | + } |
| 1935 | if (res == HOSTAPD_ACL_PENDING) |
| 1936 | return; |
| 1937 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1938 | @@ -3555,8 +3570,8 @@ static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta, |
| 1939 | } |
| 1940 | |
| 1941 | |
| 1942 | -static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta, |
| 1943 | - struct ieee802_11_elems *elems) |
| 1944 | +u16 hostapd_copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta, |
| 1945 | + const struct ieee802_11_elems *elems) |
| 1946 | { |
| 1947 | /* Supported rates not used in IEEE 802.11ad/DMG */ |
| 1948 | if (hapd->iface->current_mode && |
| 1949 | @@ -3943,7 +3958,7 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, |
| 1950 | elems->ext_capab_len); |
| 1951 | if (resp != WLAN_STATUS_SUCCESS) |
| 1952 | return resp; |
| 1953 | - resp = copy_supp_rates(hapd, sta, elems); |
| 1954 | + resp = hostapd_copy_supp_rates(hapd, sta, elems); |
| 1955 | if (resp != WLAN_STATUS_SUCCESS) |
| 1956 | return resp; |
| 1957 | |
| 1958 | @@ -4763,6 +4778,13 @@ static int add_associated_sta(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1959 | * drivers to accept the STA parameter configuration. Since this is |
| 1960 | * after a new FT-over-DS exchange, a new TK has been derived, so key |
| 1961 | * reinstallation is not a concern for this case. |
| 1962 | + * |
| 1963 | + * If the STA was associated and authorized earlier, but came for a new |
| 1964 | + * connection (!added_unassoc + !reassoc), remove the existing STA entry |
| 1965 | + * so that it can be re-added. This case is rarely seen when the AP could |
| 1966 | + * not receive the deauth/disassoc frame from the STA. And the STA comes |
| 1967 | + * back with new connection within a short period or before the inactive |
| 1968 | + * STA entry is removed from the list. |
| 1969 | */ |
| 1970 | wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR |
| 1971 | " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1972 | @@ -4776,7 +4798,8 @@ static int add_associated_sta(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1973 | (!(sta->flags & WLAN_STA_AUTHORIZED) || |
| 1974 | (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || |
| 1975 | (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && |
| 1976 | - !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) { |
| 1977 | + !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)) || |
| 1978 | + (!reassoc && (sta->flags & WLAN_STA_AUTHORIZED)))) { |
| 1979 | hostapd_drv_sta_remove(hapd, sta->addr); |
| 1980 | wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED); |
| 1981 | set = 0; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1982 | @@ -5337,7 +5360,7 @@ static void handle_assoc(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1983 | int resp = WLAN_STATUS_SUCCESS; |
| 1984 | u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 1985 | const u8 *pos; |
| 1986 | - int left, i; |
| 1987 | + int left, i, ubus_resp; |
| 1988 | struct sta_info *sta; |
| 1989 | u8 *tmp = NULL; |
| 1990 | #ifdef CONFIG_FILS |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 1991 | @@ -5579,6 +5602,11 @@ static void handle_assoc(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1992 | left = res; |
| 1993 | } |
| 1994 | #endif /* CONFIG_FILS */ |
| 1995 | + struct hostapd_ubus_request req = { |
| 1996 | + .type = HOSTAPD_UBUS_ASSOC_REQ, |
| 1997 | + .mgmt_frame = mgmt, |
| 1998 | + .ssi_signal = rssi, |
| 1999 | + }; |
| 2000 | |
| 2001 | /* followed by SSID and Supported rates; and HT capabilities if 802.11n |
| 2002 | * is used */ |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2003 | @@ -5681,6 +5709,13 @@ static void handle_assoc(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2004 | if (set_beacon) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2005 | ieee802_11_update_beacons(hapd->iface); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2006 | |
| 2007 | + ubus_resp = hostapd_ubus_handle_event(hapd, &req); |
| 2008 | + if (ubus_resp) { |
| 2009 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", |
| 2010 | + MAC2STR(mgmt->sa)); |
| 2011 | + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 2012 | + goto fail; |
| 2013 | + } |
| 2014 | fail: |
| 2015 | |
| 2016 | /* |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2017 | @@ -5910,6 +5945,7 @@ static void handle_disassoc(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2018 | (unsigned long) len); |
| 2019 | return; |
| 2020 | } |
| 2021 | + hostapd_ubus_notify(hapd, "disassoc", mgmt->sa); |
| 2022 | |
| 2023 | sta = ap_get_sta(hapd, mgmt->sa); |
| 2024 | if (!sta) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2025 | @@ -5941,6 +5977,8 @@ static void handle_deauth(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2026 | /* Clear the PTKSA cache entries for PASN */ |
| 2027 | ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); |
| 2028 | |
| 2029 | + hostapd_ubus_notify(hapd, "deauth", mgmt->sa); |
| 2030 | + |
| 2031 | sta = ap_get_sta(hapd, mgmt->sa); |
| 2032 | if (!sta) { |
| 2033 | wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2034 | @@ -5974,6 +6012,11 @@ static void handle_beacon(struct hostapd_data *hapd, |
| 2035 | 0); |
| 2036 | |
| 2037 | ap_list_process_beacon(hapd->iface, mgmt, &elems, fi); |
| 2038 | + |
| 2039 | +#ifdef CONFIG_APUP |
| 2040 | + if (hapd->conf->apup) |
| 2041 | + apup_process_beacon(hapd, mgmt, len, &elems); |
| 2042 | +#endif // def CONFIG_APUP |
| 2043 | } |
| 2044 | |
| 2045 | |
| 2046 | diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h |
| 2047 | index dd4995f3f..0e13d2940 100644 |
| 2048 | --- a/src/ap/ieee802_11.h |
| 2049 | +++ b/src/ap/ieee802_11.h |
| 2050 | @@ -108,6 +108,8 @@ int hostapd_process_ml_assoc_req_addr(struct hostapd_data *hapd, |
| 2051 | const u8 *basic_mle, size_t basic_mle_len, |
| 2052 | u8 *mld_addr); |
| 2053 | int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta); |
| 2054 | +u16 hostapd_copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta, |
| 2055 | + const struct ieee802_11_elems *elems); |
| 2056 | u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta, |
| 2057 | const u8 *ht_capab); |
| 2058 | u16 copy_sta_vendor_vht(struct hostapd_data *hapd, struct sta_info *sta, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2059 | diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c |
| 2060 | index f90f1254e..7f0a00f95 100644 |
| 2061 | --- a/src/ap/ieee802_11_ht.c |
| 2062 | +++ b/src/ap/ieee802_11_ht.c |
| 2063 | @@ -82,7 +82,9 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid) |
| 2064 | u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) |
| 2065 | { |
| 2066 | struct ieee80211_ht_operation *oper; |
| 2067 | + le32 vht_capabilities_info; |
| 2068 | u8 *pos = eid; |
| 2069 | + u8 chwidth; |
| 2070 | |
| 2071 | if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n || |
| 2072 | is_6ghz_op_class(hapd->iconf->op_class)) |
| 2073 | @@ -103,6 +105,13 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) |
| 2074 | oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | |
| 2075 | HT_INFO_HT_PARAM_STA_CHNL_WIDTH; |
| 2076 | |
| 2077 | + vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); |
| 2078 | + chwidth = hostapd_get_oper_chwidth(hapd->iconf); |
| 2079 | + if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT |
| 2080 | + && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { |
| 2081 | + oper->operation_mode = host_to_le16(hapd->iconf->vht_oper_centr_freq_seg0_idx << 5); |
| 2082 | + } |
| 2083 | + |
| 2084 | pos += sizeof(*oper); |
| 2085 | |
| 2086 | return pos; |
| 2087 | @@ -230,6 +239,9 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd, |
| 2088 | return; |
| 2089 | } |
| 2090 | |
| 2091 | + if (iface->conf->noscan || iface->conf->no_ht_coex) |
| 2092 | + return; |
| 2093 | + |
| 2094 | if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) { |
| 2095 | wpa_printf(MSG_DEBUG, |
| 2096 | "Ignore too short 20/40 BSS Coexistence Management frame"); |
| 2097 | @@ -390,6 +402,9 @@ void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta) |
| 2098 | if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) |
| 2099 | return; |
| 2100 | |
| 2101 | + if (iface->conf->noscan || iface->conf->no_ht_coex) |
| 2102 | + return; |
| 2103 | + |
| 2104 | wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR |
| 2105 | " in Association Request", MAC2STR(sta->addr)); |
| 2106 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2107 | diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c |
| 2108 | index 4dc325ce8..68880ab64 100644 |
| 2109 | --- a/src/ap/ieee802_11_vht.c |
| 2110 | +++ b/src/ap/ieee802_11_vht.c |
| 2111 | @@ -26,6 +26,7 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts) |
| 2112 | struct ieee80211_vht_capabilities *cap; |
| 2113 | struct hostapd_hw_modes *mode = hapd->iface->current_mode; |
| 2114 | u8 *pos = eid; |
| 2115 | + u8 chwidth; |
| 2116 | |
| 2117 | if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) |
| 2118 | return eid; |
| 2119 | @@ -63,6 +64,17 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts) |
| 2120 | host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET); |
| 2121 | } |
| 2122 | |
| 2123 | + chwidth = hostapd_get_oper_chwidth(hapd->iconf); |
| 2124 | + if (((host_to_le32(mode->vht_capab)) & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) |
| 2125 | + && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { |
| 2126 | + cap->vht_capabilities_info |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; |
| 2127 | + cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)); |
| 2128 | + cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)); |
| 2129 | + cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_MASK)); |
| 2130 | + } else { |
| 2131 | + cap->vht_capabilities_info &= ~VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK; |
| 2132 | + } |
| 2133 | + |
| 2134 | /* Supported MCS set comes from hw */ |
| 2135 | os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8); |
| 2136 | |
| 2137 | @@ -75,6 +87,7 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts) |
| 2138 | u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) |
| 2139 | { |
| 2140 | struct ieee80211_vht_operation *oper; |
| 2141 | + le32 vht_capabilities_info; |
| 2142 | u8 *pos = eid; |
| 2143 | enum oper_chan_width oper_chwidth = |
| 2144 | hostapd_get_oper_chwidth(hapd->iconf); |
| 2145 | @@ -110,6 +123,7 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) |
| 2146 | oper->vht_op_info_chan_center_freq_seg1_idx = seg1; |
| 2147 | |
| 2148 | oper->vht_op_info_chwidth = oper_chwidth; |
| 2149 | + vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); |
| 2150 | if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ) { |
| 2151 | /* |
| 2152 | * Convert 160 MHz channel width to new style as interop |
| 2153 | @@ -123,6 +137,9 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) |
| 2154 | oper->vht_op_info_chan_center_freq_seg0_idx -= 8; |
| 2155 | else |
| 2156 | oper->vht_op_info_chan_center_freq_seg0_idx += 8; |
| 2157 | + |
| 2158 | + if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) |
| 2159 | + oper->vht_op_info_chan_center_freq_seg1_idx = 0; |
| 2160 | } else if (oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ) { |
| 2161 | /* |
| 2162 | * Convert 80+80 MHz channel width to new style as interop |
| 2163 | diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2164 | index f4103ac9a..7b5b45a2b 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2165 | --- a/src/ap/ieee802_1x.c |
| 2166 | +++ b/src/ap/ieee802_1x.c |
| 2167 | @@ -600,6 +600,10 @@ int add_common_radius_attr(struct hostapd_data *hapd, |
| 2168 | struct hostapd_radius_attr *attr; |
| 2169 | int len; |
| 2170 | |
| 2171 | + if (hapd->conf->dynamic_own_ip_addr) |
| 2172 | + radius_client_get_local_addr(hapd->radius, |
| 2173 | + &hapd->conf->own_ip_addr); |
| 2174 | + |
| 2175 | if (!hostapd_config_get_radius_attr(req_attr, |
| 2176 | RADIUS_ATTR_NAS_IP_ADDRESS) && |
| 2177 | hapd->conf->own_ip_addr.af == AF_INET && |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2178 | @@ -2848,6 +2852,7 @@ static const char * bool_txt(bool val) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2179 | return val ? "TRUE" : "FALSE"; |
| 2180 | } |
| 2181 | |
| 2182 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 2183 | |
| 2184 | int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) |
| 2185 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2186 | @@ -3034,6 +3039,7 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2187 | return len; |
| 2188 | } |
| 2189 | |
| 2190 | +#endif |
| 2191 | |
| 2192 | #ifdef CONFIG_HS20 |
| 2193 | static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2194 | diff --git a/src/ap/rrm.c b/src/ap/rrm.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2195 | index fbcddf3f9..b024499ac 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2196 | --- a/src/ap/rrm.c |
| 2197 | +++ b/src/ap/rrm.c |
| 2198 | @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report(struct hostapd_data *hapd, |
| 2199 | return; |
| 2200 | wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", |
| 2201 | MAC2STR(addr), token, rep_mode, report); |
| 2202 | + if (len < sizeof(struct rrm_measurement_beacon_report)) |
| 2203 | + return; |
| 2204 | + hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len); |
| 2205 | } |
| 2206 | |
| 2207 | |
| 2208 | @@ -269,6 +272,8 @@ static void hostapd_send_nei_report_resp(struct hostapd_data *hapd, |
| 2209 | } |
| 2210 | } |
| 2211 | |
| 2212 | + hapd->openwrt_stats.rrm.neighbor_report_tx++; |
| 2213 | + |
| 2214 | hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, |
| 2215 | wpabuf_head(buf), wpabuf_len(buf)); |
| 2216 | wpabuf_free(buf); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2217 | @@ -397,15 +402,20 @@ void hostapd_handle_radio_measurement(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2218 | mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa)); |
| 2219 | |
| 2220 | switch (mgmt->u.action.u.rrm.action) { |
| 2221 | + case WLAN_RRM_LINK_MEASUREMENT_REPORT: |
| 2222 | + hostapd_ubus_handle_link_measurement(hapd, buf, len); |
| 2223 | + break; |
| 2224 | case WLAN_RRM_RADIO_MEASUREMENT_REPORT: |
| 2225 | hostapd_handle_radio_msmt_report(hapd, buf, len); |
| 2226 | break; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2227 | case WLAN_RRM_NEIGHBOR_REPORT_REQUEST: |
| 2228 | hostapd_handle_nei_report_req(hapd, buf, len); |
| 2229 | break; |
| 2230 | + /* |
| 2231 | case WLAN_RRM_LINK_MEASUREMENT_REPORT: |
| 2232 | hostapd_handle_link_mesr_report(hapd, buf, len); |
| 2233 | break; |
| 2234 | + */ |
| 2235 | default: |
| 2236 | wpa_printf(MSG_DEBUG, "RRM action %u is not supported", |
| 2237 | mgmt->u.action.u.rrm.action); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2238 | diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2239 | index 13613dbab..51978f45f 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2240 | --- a/src/ap/sta_info.c |
| 2241 | +++ b/src/ap/sta_info.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2242 | @@ -542,6 +542,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2243 | hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, |
| 2244 | HOSTAPD_LEVEL_INFO, "deauthenticated due to " |
| 2245 | "local deauth request"); |
| 2246 | + hostapd_ubus_notify(hapd, "local-deauth", sta->addr); |
| 2247 | ap_free_sta(hapd, sta); |
| 2248 | return; |
| 2249 | } |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2250 | @@ -699,6 +700,7 @@ skip_poll: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2251 | mlme_deauthenticate_indication( |
| 2252 | hapd, sta, |
| 2253 | WLAN_REASON_PREV_AUTH_NOT_VALID); |
| 2254 | + hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr); |
| 2255 | ap_free_sta(hapd, sta); |
| 2256 | break; |
| 2257 | } |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2258 | @@ -1485,9 +1487,6 @@ bool ap_sta_set_authorized_flag(struct hostapd_data *hapd, struct sta_info *sta, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2259 | mld_assoc_link_id = -2; |
| 2260 | } |
| 2261 | #endif /* CONFIG_IEEE80211BE */ |
| 2262 | - if (mld_assoc_link_id != -2) |
| 2263 | - hostapd_prune_associations(hapd, sta->addr, |
| 2264 | - mld_assoc_link_id); |
| 2265 | sta->flags |= WLAN_STA_AUTHORIZED; |
| 2266 | } else { |
| 2267 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2268 | @@ -1524,15 +1523,28 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2269 | os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); |
| 2270 | |
| 2271 | if (authorized) { |
| 2272 | + static const char * const auth_algs[] = { |
| 2273 | + [WLAN_AUTH_OPEN] = "open", |
| 2274 | + [WLAN_AUTH_SHARED_KEY] = "shared", |
| 2275 | + [WLAN_AUTH_FT] = "ft", |
| 2276 | + [WLAN_AUTH_SAE] = "sae", |
| 2277 | + [WLAN_AUTH_FILS_SK] = "fils-sk", |
| 2278 | + [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", |
| 2279 | + [WLAN_AUTH_FILS_PK] = "fils-pk", |
| 2280 | + [WLAN_AUTH_PASN] = "pasn", |
| 2281 | + }; |
| 2282 | + const char *auth_alg = NULL; |
| 2283 | const u8 *dpp_pkhash; |
| 2284 | const char *keyid; |
| 2285 | char dpp_pkhash_buf[100]; |
| 2286 | char keyid_buf[100]; |
| 2287 | char ip_addr[100]; |
| 2288 | + char alg_buf[100]; |
| 2289 | |
| 2290 | dpp_pkhash_buf[0] = '\0'; |
| 2291 | keyid_buf[0] = '\0'; |
| 2292 | ip_addr[0] = '\0'; |
| 2293 | + alg_buf[0] = '\0'; |
| 2294 | #ifdef CONFIG_P2P |
| 2295 | if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { |
| 2296 | os_snprintf(ip_addr, sizeof(ip_addr), |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2297 | @@ -1543,6 +1555,13 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2298 | } |
| 2299 | #endif /* CONFIG_P2P */ |
| 2300 | |
| 2301 | + if (sta->auth_alg < ARRAY_SIZE(auth_algs)) |
| 2302 | + auth_alg = auth_algs[sta->auth_alg]; |
| 2303 | + |
| 2304 | + if (auth_alg) |
| 2305 | + os_snprintf(alg_buf, sizeof(alg_buf), |
| 2306 | + " auth_alg=%s", auth_alg); |
| 2307 | + |
| 2308 | keyid = ap_sta_wpa_get_keyid(hapd, sta); |
| 2309 | if (keyid) { |
| 2310 | os_snprintf(keyid_buf, sizeof(keyid_buf), |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2311 | @@ -1561,17 +1580,19 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2312 | dpp_pkhash, SHA256_MAC_LEN); |
| 2313 | } |
| 2314 | |
| 2315 | - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", |
| 2316 | - buf, ip_addr, keyid_buf, dpp_pkhash_buf); |
| 2317 | + hostapd_ubus_notify_authorized(hapd, sta, auth_alg); |
| 2318 | + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s", |
| 2319 | + buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf); |
| 2320 | |
| 2321 | if (hapd->msg_ctx_parent && |
| 2322 | hapd->msg_ctx_parent != hapd->msg_ctx) |
| 2323 | wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, |
| 2324 | - AP_STA_CONNECTED "%s%s%s%s", |
| 2325 | + AP_STA_CONNECTED "%s%s%s%s%s", |
| 2326 | buf, ip_addr, keyid_buf, |
| 2327 | - dpp_pkhash_buf); |
| 2328 | + dpp_pkhash_buf, alg_buf); |
| 2329 | } else { |
| 2330 | wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); |
| 2331 | + hostapd_ubus_notify(hapd, "disassoc", sta->addr); |
| 2332 | |
| 2333 | if (hapd->msg_ctx_parent && |
| 2334 | hapd->msg_ctx_parent != hapd->msg_ctx) |
| 2335 | diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2336 | index 84629358c..d03d18b48 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2337 | --- a/src/ap/sta_info.h |
| 2338 | +++ b/src/ap/sta_info.h |
| 2339 | @@ -17,7 +17,6 @@ |
| 2340 | #include "common/sae.h" |
| 2341 | #include "crypto/sha384.h" |
| 2342 | #include "pasn/pasn_common.h" |
| 2343 | -#include "hostapd.h" |
| 2344 | |
| 2345 | /* STA flags */ |
| 2346 | #define WLAN_STA_AUTH BIT(0) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2347 | @@ -49,10 +48,6 @@ |
| 2348 | #define WLAN_STA_PENDING_DEAUTH_CB BIT(30) |
| 2349 | #define WLAN_STA_NONERP BIT(31) |
| 2350 | |
| 2351 | -/* Maximum number of supported rates (from both Supported Rates and Extended |
| 2352 | - * Supported Rates IEs). */ |
| 2353 | -#define WLAN_SUPP_RATES_MAX 32 |
| 2354 | - |
| 2355 | struct hostapd_data; |
| 2356 | |
| 2357 | struct mbo_non_pref_chan_info { |
| 2358 | @@ -321,6 +316,7 @@ struct sta_info { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2359 | #endif /* CONFIG_TESTING_OPTIONS */ |
| 2360 | #ifdef CONFIG_AIRTIME_POLICY |
| 2361 | unsigned int airtime_weight; |
| 2362 | + unsigned int dyn_airtime_weight; |
| 2363 | struct os_reltime backlogged_until; |
| 2364 | #endif /* CONFIG_AIRTIME_POLICY */ |
| 2365 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2366 | @@ -421,16 +417,6 @@ int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2367 | |
| 2368 | void ap_free_sta_pasn(struct hostapd_data *hapd, struct sta_info *sta); |
| 2369 | |
| 2370 | -static inline bool ap_sta_is_mld(struct hostapd_data *hapd, |
| 2371 | - struct sta_info *sta) |
| 2372 | -{ |
| 2373 | -#ifdef CONFIG_IEEE80211BE |
| 2374 | - return hapd->conf->mld_ap && sta && sta->mld_info.mld_sta; |
| 2375 | -#else /* CONFIG_IEEE80211BE */ |
| 2376 | - return false; |
| 2377 | -#endif /* CONFIG_IEEE80211BE */ |
| 2378 | -} |
| 2379 | - |
| 2380 | static inline void ap_sta_set_mld(struct sta_info *sta, bool mld) |
| 2381 | { |
| 2382 | #ifdef CONFIG_IEEE80211BE |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2383 | diff --git a/src/ap/ubus.c b/src/ap/ubus.c |
| 2384 | index 8689494bc..f21516fc3 100644 |
| 2385 | --- a/src/ap/ubus.c |
| 2386 | +++ b/src/ap/ubus.c |
| 2387 | @@ -2004,3 +2004,18 @@ int hostapd_ubus_notify_bss_transition_query( |
| 2388 | return ureq.resp; |
| 2389 | #endif |
| 2390 | } |
| 2391 | + |
| 2392 | +#ifdef CONFIG_APUP |
| 2393 | +void hostapd_ubus_notify_apup_newpeer( |
| 2394 | + struct hostapd_data *hapd, const u8 *addr, const char *ifname) |
| 2395 | +{ |
| 2396 | + if (!hapd->ubus.obj.has_subscribers) |
| 2397 | + return; |
| 2398 | + |
| 2399 | + blob_buf_init(&b, 0); |
| 2400 | + blobmsg_add_macaddr(&b, "address", addr); |
| 2401 | + blobmsg_add_string(&b, "ifname", ifname); |
| 2402 | + |
| 2403 | + ubus_notify(ctx, &hapd->ubus.obj, "apup-newpeer", b.head, -1); |
| 2404 | +} |
| 2405 | +#endif // def CONFIG_APUP |
| 2406 | diff --git a/src/ap/ubus.h b/src/ap/ubus.h |
| 2407 | index 22767d67e..1c65e4dcb 100644 |
| 2408 | --- a/src/ap/ubus.h |
| 2409 | +++ b/src/ap/ubus.h |
| 2410 | @@ -71,6 +71,11 @@ int hostapd_ubus_notify_bss_transition_query( |
| 2411 | void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, |
| 2412 | const char *auth_alg); |
| 2413 | |
| 2414 | +#ifdef CONFIG_APUP |
| 2415 | +void hostapd_ubus_notify_apup_newpeer( |
| 2416 | + struct hostapd_data *hapd, const u8 *addr, const char *ifname); |
| 2417 | +#endif // def CONFIG_APUP |
| 2418 | + |
| 2419 | #else |
| 2420 | |
| 2421 | struct hostapd_ubus_bss {}; |
| 2422 | diff --git a/src/ap/ucode.c b/src/ap/ucode.c |
| 2423 | index 68fb45088..3468615fd 100644 |
| 2424 | --- a/src/ap/ucode.c |
| 2425 | +++ b/src/ap/ucode.c |
| 2426 | @@ -815,3 +815,20 @@ void hostapd_ucode_free_bss(struct hostapd_data *hapd) |
| 2427 | ucv_put(wpa_ucode_call(2)); |
| 2428 | ucv_gc(vm); |
| 2429 | } |
| 2430 | + |
| 2431 | +#ifdef CONFIG_APUP |
| 2432 | +void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname) |
| 2433 | +{ |
| 2434 | + uc_value_t *val; |
| 2435 | + |
| 2436 | + if (wpa_ucode_call_prepare("apup_newpeer")) |
| 2437 | + return; |
| 2438 | + |
| 2439 | + val = hostapd_ucode_bss_get_uval(hapd); |
| 2440 | + uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); // BSS ifname |
| 2441 | + uc_value_push(ucv_get(val)); |
| 2442 | + uc_value_push(ucv_get(ucv_string_new(ifname))); // APuP peer ifname |
| 2443 | + ucv_put(wpa_ucode_call(2)); |
| 2444 | + ucv_gc(vm); |
| 2445 | +} |
| 2446 | +#endif // def CONFIG_APUP |
| 2447 | diff --git a/src/ap/ucode.h b/src/ap/ucode.h |
| 2448 | index d00b78716..c9bdde651 100644 |
| 2449 | --- a/src/ap/ucode.h |
| 2450 | +++ b/src/ap/ucode.h |
| 2451 | @@ -27,6 +27,10 @@ void hostapd_ucode_add_bss(struct hostapd_data *hapd); |
| 2452 | void hostapd_ucode_free_bss(struct hostapd_data *hapd); |
| 2453 | void hostapd_ucode_reload_bss(struct hostapd_data *hapd); |
| 2454 | |
| 2455 | +#ifdef CONFIG_APUP |
| 2456 | +void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname); |
| 2457 | +#endif // def CONFIG_APUP |
| 2458 | + |
| 2459 | #else |
| 2460 | |
| 2461 | static inline int hostapd_ucode_init(struct hapd_interfaces *ifaces) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2462 | diff --git a/src/ap/vlan_full.c b/src/ap/vlan_full.c |
| 2463 | index 19aa3c649..053d6338e 100644 |
| 2464 | --- a/src/ap/vlan_full.c |
| 2465 | +++ b/src/ap/vlan_full.c |
| 2466 | @@ -475,6 +475,9 @@ void vlan_newlink(const char *ifname, struct hostapd_data *hapd) |
| 2467 | if (!vlan) |
| 2468 | return; |
| 2469 | |
| 2470 | + if (hapd->conf->ssid.vlan_no_bridge) |
| 2471 | + goto out; |
| 2472 | + |
| 2473 | vlan->configured = 1; |
| 2474 | |
| 2475 | notempty = vlan->vlan_desc.notempty; |
| 2476 | @@ -506,6 +509,7 @@ void vlan_newlink(const char *ifname, struct hostapd_data *hapd) |
| 2477 | ifname, br_name, tagged[i], hapd); |
| 2478 | } |
| 2479 | |
| 2480 | +out: |
| 2481 | ifconfig_up(ifname); |
| 2482 | } |
| 2483 | |
| 2484 | diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c |
| 2485 | index 53eacfb45..b69f3de41 100644 |
| 2486 | --- a/src/ap/vlan_init.c |
| 2487 | +++ b/src/ap/vlan_init.c |
| 2488 | @@ -22,6 +22,7 @@ |
| 2489 | static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |
| 2490 | int existsok) |
| 2491 | { |
| 2492 | + bool vlan_exists = iface_exists(vlan->ifname); |
| 2493 | int ret; |
| 2494 | #ifdef CONFIG_WEP |
| 2495 | int i; |
| 2496 | @@ -36,7 +37,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |
| 2497 | } |
| 2498 | #endif /* CONFIG_WEP */ |
| 2499 | |
| 2500 | - if (!iface_exists(vlan->ifname)) |
| 2501 | + if (!vlan_exists) |
| 2502 | ret = hostapd_vlan_if_add(hapd, vlan->ifname); |
| 2503 | else if (!existsok) |
| 2504 | return -1; |
| 2505 | @@ -51,6 +52,9 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |
| 2506 | if (hapd->wpa_auth) |
| 2507 | ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); |
| 2508 | |
| 2509 | + if (!ret && !vlan_exists) |
| 2510 | + hostapd_ubus_add_vlan(hapd, vlan); |
| 2511 | + |
| 2512 | if (ret == 0) |
| 2513 | return ret; |
| 2514 | |
| 2515 | @@ -77,6 +81,8 @@ int vlan_if_remove(struct hostapd_data *hapd, struct hostapd_vlan *vlan) |
| 2516 | "WPA deinitialization for VLAN %d failed (%d)", |
| 2517 | vlan->vlan_id, ret); |
| 2518 | |
| 2519 | + hostapd_ubus_remove_vlan(hapd, vlan); |
| 2520 | + |
| 2521 | return hostapd_vlan_if_remove(hapd, vlan->ifname); |
| 2522 | } |
| 2523 | |
| 2524 | diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c |
| 2525 | index af8cccaef..d259200c9 100644 |
| 2526 | --- a/src/ap/wnm_ap.c |
| 2527 | +++ b/src/ap/wnm_ap.c |
| 2528 | @@ -410,6 +410,7 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd, |
| 2529 | mgmt->u.action.u.bss_tm_req.validity_interval = 1; |
| 2530 | pos = mgmt->u.action.u.bss_tm_req.variable; |
| 2531 | |
| 2532 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2533 | wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " |
| 2534 | MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u " |
| 2535 | "validity_interval=%u", |
| 2536 | @@ -478,7 +479,8 @@ static void ieee802_11_rx_bss_trans_mgmt_query(struct hostapd_data *hapd, |
| 2537 | MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); |
| 2538 | os_free(hex); |
| 2539 | |
| 2540 | - ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); |
| 2541 | + if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos)) |
| 2542 | + ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); |
| 2543 | } |
| 2544 | |
| 2545 | |
| 2546 | @@ -500,7 +502,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd, |
| 2547 | size_t len) |
| 2548 | { |
| 2549 | u8 dialog_token, status_code, bss_termination_delay; |
| 2550 | - const u8 *pos, *end; |
| 2551 | + const u8 *pos, *end, *target_bssid = NULL; |
| 2552 | int enabled = hapd->conf->bss_transition; |
| 2553 | struct sta_info *sta; |
| 2554 | |
| 2555 | @@ -547,6 +549,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd, |
| 2556 | wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); |
| 2557 | return; |
| 2558 | } |
| 2559 | + target_bssid = pos; |
| 2560 | sta->agreed_to_steer = 1; |
| 2561 | eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta); |
| 2562 | eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer, |
| 2563 | @@ -566,6 +569,10 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd, |
| 2564 | MAC2STR(addr), status_code, bss_termination_delay); |
| 2565 | } |
| 2566 | |
| 2567 | + hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token, |
| 2568 | + status_code, bss_termination_delay, |
| 2569 | + target_bssid, pos, end - pos); |
| 2570 | + |
| 2571 | wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", |
| 2572 | pos, end - pos); |
| 2573 | } |
| 2574 | @@ -814,10 +821,12 @@ int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd, |
| 2575 | plen); |
| 2576 | return 0; |
| 2577 | case WNM_BSS_TRANS_MGMT_QUERY: |
| 2578 | + hapd->openwrt_stats.wnm.bss_transition_query_rx++; |
| 2579 | ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, |
| 2580 | plen); |
| 2581 | return 0; |
| 2582 | case WNM_BSS_TRANS_MGMT_RESP: |
| 2583 | + hapd->openwrt_stats.wnm.bss_transition_response_rx++; |
| 2584 | ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload, |
| 2585 | plen); |
| 2586 | return 0; |
| 2587 | @@ -865,6 +874,7 @@ int wnm_send_disassoc_imminent(struct hostapd_data *hapd, |
| 2588 | |
| 2589 | pos = mgmt->u.action.u.bss_tm_req.variable; |
| 2590 | |
| 2591 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2592 | wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to " |
| 2593 | MACSTR, disassoc_timer, MAC2STR(sta->addr)); |
| 2594 | if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) { |
| 2595 | @@ -947,6 +957,7 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd, |
| 2596 | return -1; |
| 2597 | } |
| 2598 | |
| 2599 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2600 | if (disassoc_timer) { |
| 2601 | /* send disassociation frame after time-out */ |
| 2602 | set_disassoc_timer(hapd, sta, disassoc_timer); |
| 2603 | @@ -1028,6 +1039,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta, |
| 2604 | } |
| 2605 | os_free(buf); |
| 2606 | |
| 2607 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2608 | if (disassoc_timer) { |
| 2609 | #ifdef CONFIG_IEEE80211BE |
| 2610 | if (ap_sta_is_mld(hapd, sta)) { |
| 2611 | diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2612 | index 93f157d62..3a1d288dd 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2613 | --- a/src/ap/wpa_auth.c |
| 2614 | +++ b/src/ap/wpa_auth.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2615 | @@ -6095,6 +6095,7 @@ static const char * wpa_bool_txt(int val) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2616 | return val ? "TRUE" : "FALSE"; |
| 2617 | } |
| 2618 | |
| 2619 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 2620 | |
| 2621 | #define RSN_SUITE "%02x-%02x-%02x-%d" |
| 2622 | #define RSN_SUITE_ARG(s) \ |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2623 | @@ -6247,7 +6248,7 @@ int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2624 | |
| 2625 | return len; |
| 2626 | } |
| 2627 | - |
| 2628 | +#endif |
| 2629 | |
| 2630 | void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) |
| 2631 | { |
| 2632 | diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2633 | index 13685b7c2..eaded9434 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2634 | --- a/src/ap/wpa_auth_glue.c |
| 2635 | +++ b/src/ap/wpa_auth_glue.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2636 | @@ -328,6 +328,7 @@ static void hostapd_wpa_auth_psk_failure_report(void *ctx, const u8 *addr) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2637 | struct hostapd_data *hapd = ctx; |
| 2638 | wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, |
| 2639 | MAC2STR(addr)); |
| 2640 | + hostapd_ubus_notify(hapd, "key-mismatch", addr); |
| 2641 | } |
| 2642 | |
| 2643 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2644 | @@ -1811,8 +1812,12 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2645 | wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { |
| 2646 | const char *ft_iface; |
| 2647 | |
| 2648 | - ft_iface = hapd->conf->bridge[0] ? hapd->conf->bridge : |
| 2649 | - hapd->conf->iface; |
| 2650 | + if (hapd->conf->ft_iface[0]) |
| 2651 | + ft_iface = hapd->conf->ft_iface; |
| 2652 | + else if (hapd->conf->bridge[0]) |
| 2653 | + ft_iface = hapd->conf->bridge; |
| 2654 | + else |
| 2655 | + ft_iface = hapd->conf->iface; |
| 2656 | hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB, |
| 2657 | hostapd_rrb_receive, hapd, 1); |
| 2658 | if (!hapd->l2) { |
| 2659 | diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c |
| 2660 | index 82d4d5fdd..dfc5c3ecb 100644 |
| 2661 | --- a/src/ap/wps_hostapd.c |
| 2662 | +++ b/src/ap/wps_hostapd.c |
| 2663 | @@ -394,9 +394,8 @@ static int hapd_wps_reconfig_in_memory(struct hostapd_data *hapd, |
| 2664 | bss->wpa_pairwise |= WPA_CIPHER_GCMP; |
| 2665 | else |
| 2666 | bss->wpa_pairwise |= WPA_CIPHER_CCMP; |
| 2667 | - } |
| 2668 | #ifndef CONFIG_NO_TKIP |
| 2669 | - if (cred->encr_type & WPS_ENCR_TKIP) |
| 2670 | + } else if (cred->encr_type & WPS_ENCR_TKIP) |
| 2671 | bss->wpa_pairwise |= WPA_CIPHER_TKIP; |
| 2672 | #endif /* CONFIG_NO_TKIP */ |
| 2673 | bss->rsn_pairwise = bss->wpa_pairwise; |
| 2674 | @@ -1181,8 +1180,7 @@ int hostapd_init_wps(struct hostapd_data *hapd, |
| 2675 | WPA_CIPHER_GCMP_256)) { |
| 2676 | wps->encr_types |= WPS_ENCR_AES; |
| 2677 | wps->encr_types_rsn |= WPS_ENCR_AES; |
| 2678 | - } |
| 2679 | - if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { |
| 2680 | + } else if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { |
| 2681 | #ifdef CONFIG_NO_TKIP |
| 2682 | wpa_printf(MSG_INFO, "WPS: TKIP not supported"); |
| 2683 | goto fail; |
| 2684 | diff --git a/src/ap/x_snoop.c b/src/ap/x_snoop.c |
| 2685 | index 029f4de23..4c20f137f 100644 |
| 2686 | --- a/src/ap/x_snoop.c |
| 2687 | +++ b/src/ap/x_snoop.c |
| 2688 | @@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *hapd) |
| 2689 | |
| 2690 | hapd->x_snoop_initialized = true; |
| 2691 | |
| 2692 | - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, |
| 2693 | + if (!conf->snoop_iface[0] && |
| 2694 | + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, |
| 2695 | 1)) { |
| 2696 | wpa_printf(MSG_DEBUG, |
| 2697 | "x_snoop: Failed to enable hairpin_mode on the bridge port"); |
| 2698 | return -1; |
| 2699 | } |
| 2700 | |
| 2701 | - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { |
| 2702 | + if (!conf->snoop_iface[0] && |
| 2703 | + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { |
| 2704 | wpa_printf(MSG_DEBUG, |
| 2705 | "x_snoop: Failed to enable proxyarp on the bridge port"); |
| 2706 | return -1; |
| 2707 | } |
| 2708 | |
| 2709 | if (hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, |
| 2710 | - 1)) { |
| 2711 | + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 1)) { |
| 2712 | wpa_printf(MSG_DEBUG, |
| 2713 | "x_snoop: Failed to enable accepting gratuitous ARP on the bridge"); |
| 2714 | return -1; |
| 2715 | } |
| 2716 | |
| 2717 | #ifdef CONFIG_IPV6 |
| 2718 | - if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { |
| 2719 | + if (!conf->snoop_iface[0] && |
| 2720 | + hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, NULL, 1)) { |
| 2721 | wpa_printf(MSG_DEBUG, |
| 2722 | "x_snoop: Failed to enable multicast snooping on the bridge"); |
| 2723 | return -1; |
| 2724 | @@ -73,8 +76,12 @@ x_snoop_get_l2_packet(struct hostapd_data *hapd, |
| 2725 | { |
| 2726 | struct hostapd_bss_config *conf = hapd->conf; |
| 2727 | struct l2_packet_data *l2; |
| 2728 | + const char *ifname = conf->bridge; |
| 2729 | + |
| 2730 | + if (conf->snoop_iface[0]) |
| 2731 | + ifname = conf->snoop_iface; |
| 2732 | |
| 2733 | - l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1); |
| 2734 | + l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1); |
| 2735 | if (l2 == NULL) { |
| 2736 | wpa_printf(MSG_DEBUG, |
| 2737 | "x_snoop: Failed to initialize L2 packet processing %s", |
| 2738 | @@ -127,9 +134,12 @@ void x_snoop_mcast_to_ucast_convert_send(struct hostapd_data *hapd, |
| 2739 | |
| 2740 | void x_snoop_deinit(struct hostapd_data *hapd) |
| 2741 | { |
| 2742 | + struct hostapd_bss_config *conf = hapd->conf; |
| 2743 | + |
| 2744 | if (!hapd->x_snoop_initialized) |
| 2745 | return; |
| 2746 | - hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0); |
| 2747 | + hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, |
| 2748 | + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 0); |
| 2749 | hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0); |
| 2750 | hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0); |
| 2751 | hapd->x_snoop_initialized = false; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2752 | diff --git a/src/common/defs.h b/src/common/defs.h |
| 2753 | index 8cca094e8..151b69170 100644 |
| 2754 | --- a/src/common/defs.h |
| 2755 | +++ b/src/common/defs.h |
| 2756 | @@ -63,6 +63,10 @@ |
| 2757 | WPA_KEY_MGMT_FT_FILS_SHA256 | \ |
| 2758 | WPA_KEY_MGMT_FT_FILS_SHA384) |
| 2759 | |
| 2760 | +/* Maximum number of supported rates (from both Supported Rates and Extended |
| 2761 | + * Supported Rates IEs). */ |
| 2762 | +#define WLAN_SUPP_RATES_MAX 32 |
| 2763 | + |
| 2764 | static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) |
| 2765 | { |
| 2766 | return !!(akm & (WPA_KEY_MGMT_IEEE8021X | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2767 | diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c |
| 2768 | index f17f95a2c..39d39f429 100644 |
| 2769 | --- a/src/common/dpp_crypto.c |
| 2770 | +++ b/src/common/dpp_crypto.c |
| 2771 | @@ -269,6 +269,12 @@ int dpp_get_pubkey_hash(struct crypto_ec_key *key, u8 *hash) |
| 2772 | |
| 2773 | struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) |
| 2774 | { |
| 2775 | + if (curve == NULL) { |
| 2776 | + wpa_printf(MSG_DEBUG, |
| 2777 | + "DPP: %s curve must be initialized", __func__); |
| 2778 | + return NULL; |
| 2779 | + } |
| 2780 | + |
| 2781 | struct crypto_ec_key *key; |
| 2782 | |
| 2783 | wpa_printf(MSG_DEBUG, "DPP: Generating a keypair"); |
| 2784 | @@ -1582,7 +1588,9 @@ dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp, |
| 2785 | Pr = crypto_ec_key_get_public_key(Pr_key); |
| 2786 | Qr = crypto_ec_point_init(ec); |
| 2787 | hash_bn = crypto_bignum_init_set(hash, curve->hash_len); |
| 2788 | - if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) |
| 2789 | + if (!Pr || !Qr || !hash_bn || |
| 2790 | + crypto_bignum_mod(hash_bn, crypto_ec_get_prime(ec), hash_bn) || |
| 2791 | + crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) |
| 2792 | goto fail; |
| 2793 | |
| 2794 | if (crypto_ec_point_is_at_infinity(ec, Qr)) { |
| 2795 | diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c |
| 2796 | index 2c47bf812..8bd6e994d 100644 |
| 2797 | --- a/src/common/hw_features_common.c |
| 2798 | +++ b/src/common/hw_features_common.c |
| 2799 | @@ -898,6 +898,7 @@ int ieee80211ac_cap_check(u32 hw, u32 conf) |
| 2800 | VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB); |
| 2801 | VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN); |
| 2802 | VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN); |
| 2803 | + VHT_CAP_CHECK(VHT_CAP_EXTENDED_NSS_BW_SUPPORT); |
| 2804 | |
| 2805 | #undef VHT_CAP_CHECK |
| 2806 | #undef VHT_CAP_CHECK_MAX |
| 2807 | diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2808 | index db9e90355..269b1cf97 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2809 | --- a/src/common/ieee802_11_defs.h |
| 2810 | +++ b/src/common/ieee802_11_defs.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2811 | @@ -1398,6 +1398,8 @@ struct ieee80211_ampe_ie { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2812 | #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB ((u32) BIT(26) | BIT(27)) |
| 2813 | #define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28)) |
| 2814 | #define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29)) |
| 2815 | +#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT ((u32) BIT(30)) |
| 2816 | +#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK ((u32) BIT(30) | BIT(31)) |
| 2817 | |
| 2818 | #define VHT_OPMODE_CHANNEL_WIDTH_MASK ((u8) BIT(0) | BIT(1)) |
| 2819 | #define VHT_OPMODE_CHANNEL_RxNSS_MASK ((u8) BIT(4) | BIT(5) | \ |
| 2820 | diff --git a/src/common/sae.c b/src/common/sae.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2821 | index a65da6134..36f09e31b 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2822 | --- a/src/common/sae.c |
| 2823 | +++ b/src/common/sae.c |
| 2824 | @@ -1278,6 +1278,13 @@ void sae_deinit_pt(struct sae_pt *pt) |
| 2825 | static int sae_derive_commit_element_ecc(struct sae_data *sae, |
| 2826 | struct crypto_bignum *mask) |
| 2827 | { |
| 2828 | + if (sae->tmp->pwe_ecc == NULL) { |
| 2829 | + wpa_printf(MSG_DEBUG, |
| 2830 | + "SAE: %s sae->tmp->pwe_ecc must be initialized", |
| 2831 | + __func__); |
| 2832 | + return -1; |
| 2833 | + } |
| 2834 | + |
| 2835 | /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */ |
| 2836 | if (!sae->tmp->own_commit_element_ecc) { |
| 2837 | sae->tmp->own_commit_element_ecc = |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2838 | diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2839 | index d0c174c05..ba659fe0f 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2840 | --- a/src/common/wpa_ctrl.c |
| 2841 | +++ b/src/common/wpa_ctrl.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2842 | @@ -142,7 +142,7 @@ try_again: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2843 | return NULL; |
| 2844 | } |
| 2845 | tries++; |
| 2846 | -#ifdef ANDROID |
| 2847 | + |
| 2848 | /* Set client socket file permissions so that bind() creates the client |
| 2849 | * socket with these permissions and there is no need to try to change |
| 2850 | * them with chmod() after bind() which would have potential issues with |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2851 | @@ -154,7 +154,7 @@ try_again: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2852 | * operations to allow the response to go through. Those are using the |
| 2853 | * no-deference-symlinks version to avoid races. */ |
| 2854 | fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); |
| 2855 | -#endif /* ANDROID */ |
| 2856 | + |
| 2857 | if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, |
| 2858 | sizeof(ctrl->local)) < 0) { |
| 2859 | if (errno == EADDRINUSE && tries < 2) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 2860 | @@ -172,7 +172,11 @@ try_again: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2861 | return NULL; |
| 2862 | } |
| 2863 | |
| 2864 | -#ifdef ANDROID |
| 2865 | +#ifndef ANDROID |
| 2866 | + /* Set group even if we do not have privileges to change owner */ |
| 2867 | + lchown(ctrl->local.sun_path, -1, 101); |
| 2868 | + lchown(ctrl->local.sun_path, 101, 101); |
| 2869 | +#else |
| 2870 | /* Set group even if we do not have privileges to change owner */ |
| 2871 | lchown(ctrl->local.sun_path, -1, AID_WIFI); |
| 2872 | lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); |
| 2873 | diff --git a/src/crypto/Makefile b/src/crypto/Makefile |
| 2874 | index ce0997091..96bac9476 100644 |
| 2875 | --- a/src/crypto/Makefile |
| 2876 | +++ b/src/crypto/Makefile |
| 2877 | @@ -1,10 +1,121 @@ |
| 2878 | -CFLAGS += -DCONFIG_CRYPTO_INTERNAL |
| 2879 | -CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT |
| 2880 | -CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER |
| 2881 | #CFLAGS += -DALL_DH_GROUPS |
| 2882 | CFLAGS += -DCONFIG_SHA256 |
| 2883 | CFLAGS += -DCONFIG_SHA384 |
| 2884 | +CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 2885 | CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 2886 | + |
| 2887 | +# crypto_module_tests.c |
| 2888 | +CFLAGS += -DCONFIG_MODULE_TESTS |
| 2889 | +CFLAGS += -DCONFIG_DPP |
| 2890 | +#CFLAGS += -DCONFIG_DPP2 |
| 2891 | +#CFLAGS += -DCONFIG_DPP3 |
| 2892 | +CFLAGS += -DCONFIG_ECC |
| 2893 | +CFLAGS += -DCONFIG_MESH |
| 2894 | +CFLAGS += -DEAP_PSK |
| 2895 | +CFLAGS += -DEAP_FAST |
| 2896 | + |
| 2897 | +ifeq ($(CONFIG_TLS),mbedtls) |
| 2898 | + |
| 2899 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=mbedtls') |
| 2900 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 2901 | +CFLAGS += -DCONFIG_DES |
| 2902 | +CFLAGS += -DEAP_IKEV2 |
| 2903 | +CFLAGS += -DEAP_MSCHAPv2 |
| 2904 | +CFLAGS += -DEAP_SIM |
| 2905 | + |
| 2906 | +LIB_OBJS = tls_mbedtls.o crypto_mbedtls.o |
| 2907 | +LIB_OBJS+= \ |
| 2908 | + aes-eax.o \ |
| 2909 | + aes-siv.o \ |
| 2910 | + dh_groups.o \ |
| 2911 | + milenage.o \ |
| 2912 | + ms_funcs.o |
| 2913 | + |
| 2914 | +else |
| 2915 | +ifeq ($(CONFIG_TLS),openssl) |
| 2916 | + |
| 2917 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=openssl') |
| 2918 | +ifndef CONFIG_TLS_DEFAULT_CIPHERS |
| 2919 | +CONFIG_TLS_DEFAULT_CIPHERS = "DEFAULT:!EXP:!LOW" |
| 2920 | +endif |
| 2921 | +CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" |
| 2922 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 2923 | +CFLAGS += -DEAP_TLS_OPENSSL |
| 2924 | + |
| 2925 | +LIB_OBJS = tls_openssl.o fips_prf_openssl.o crypto_openssl.o |
| 2926 | +LIB_OBJS+= \ |
| 2927 | + aes-ctr.o \ |
| 2928 | + aes-eax.o \ |
| 2929 | + aes-encblock.o \ |
| 2930 | + aes-siv.o \ |
| 2931 | + dh_groups.o \ |
| 2932 | + milenage.o \ |
| 2933 | + ms_funcs.o \ |
| 2934 | + sha1-prf.o \ |
| 2935 | + sha1-tlsprf.o \ |
| 2936 | + sha1-tprf.o \ |
| 2937 | + sha256-kdf.o \ |
| 2938 | + sha256-prf.o \ |
| 2939 | + sha256-tlsprf.o |
| 2940 | + |
| 2941 | +else |
| 2942 | +ifeq ($(CONFIG_TLS),wolfssl) |
| 2943 | + |
| 2944 | +# (wolfssl libraries must be built with ./configure --enable-wpas) |
| 2945 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=wolfssl') |
| 2946 | +CFLAGS += -DWOLFSSL_DER_LOAD |
| 2947 | +CFLAGS += -DCONFIG_DES |
| 2948 | + |
| 2949 | +LIB_OBJS = tls_wolfssl.o fips_prf_wolfssl.o crypto_wolfssl.o |
| 2950 | +LIB_OBJS+= \ |
| 2951 | + aes-ctr.o \ |
| 2952 | + aes-eax.o \ |
| 2953 | + aes-encblock.o \ |
| 2954 | + aes-siv.o \ |
| 2955 | + dh_groups.o \ |
| 2956 | + milenage.o \ |
| 2957 | + ms_funcs.o \ |
| 2958 | + sha1-prf.o \ |
| 2959 | + sha1-tlsprf.o \ |
| 2960 | + sha1-tprf.o \ |
| 2961 | + sha256-kdf.o \ |
| 2962 | + sha256-prf.o \ |
| 2963 | + sha256-tlsprf.o |
| 2964 | + |
| 2965 | +else |
| 2966 | +ifeq ($(CONFIG_TLS),gnutls) |
| 2967 | + |
| 2968 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=gnutls') |
| 2969 | +LIB_OBJS = tls_gnutls.o crypto_gnutls.o |
| 2970 | +LIB_OBJS+= \ |
| 2971 | + aes-cbc.o \ |
| 2972 | + aes-ctr.o \ |
| 2973 | + aes-eax.o \ |
| 2974 | + aes-encblock.o \ |
| 2975 | + aes-omac1.o \ |
| 2976 | + aes-siv.o \ |
| 2977 | + aes-unwrap.o \ |
| 2978 | + aes-wrap.o \ |
| 2979 | + dh_group5.o \ |
| 2980 | + dh_groups.o \ |
| 2981 | + milenage.o \ |
| 2982 | + ms_funcs.o \ |
| 2983 | + rc4.o \ |
| 2984 | + sha1-pbkdf2.o \ |
| 2985 | + sha1-prf.o \ |
| 2986 | + fips_prf_internal.o \ |
| 2987 | + sha1-internal.o \ |
| 2988 | + sha1-tlsprf.o \ |
| 2989 | + sha1-tprf.o \ |
| 2990 | + sha256-kdf.o \ |
| 2991 | + sha256-prf.o \ |
| 2992 | + sha256-tlsprf.o |
| 2993 | + |
| 2994 | +else |
| 2995 | + |
| 2996 | +CFLAGS += -DCONFIG_CRYPTO_INTERNAL |
| 2997 | +CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT |
| 2998 | +CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER |
| 2999 | CFLAGS += -DCONFIG_INTERNAL_SHA384 |
| 3000 | |
| 3001 | LIB_OBJS= \ |
| 3002 | @@ -13,7 +124,6 @@ LIB_OBJS= \ |
| 3003 | aes-ctr.o \ |
| 3004 | aes-eax.o \ |
| 3005 | aes-encblock.o \ |
| 3006 | - aes-gcm.o \ |
| 3007 | aes-internal.o \ |
| 3008 | aes-internal-dec.o \ |
| 3009 | aes-internal-enc.o \ |
| 3010 | @@ -37,6 +147,7 @@ LIB_OBJS= \ |
| 3011 | sha1-tlsprf.o \ |
| 3012 | sha1-tprf.o \ |
| 3013 | sha256.o \ |
| 3014 | + sha256-kdf.o \ |
| 3015 | sha256-prf.o \ |
| 3016 | sha256-tlsprf.o \ |
| 3017 | sha256-internal.o \ |
| 3018 | @@ -53,6 +164,16 @@ LIB_OBJS += crypto_internal-modexp.o |
| 3019 | LIB_OBJS += crypto_internal-rsa.o |
| 3020 | LIB_OBJS += tls_internal.o |
| 3021 | LIB_OBJS += fips_prf_internal.o |
| 3022 | + |
| 3023 | +endif |
| 3024 | +endif |
| 3025 | +endif |
| 3026 | +endif |
| 3027 | + |
| 3028 | + |
| 3029 | +# (used by wlantest/{bip,gcmp,rx_mgmt}.c and tests/test-aes.c) |
| 3030 | +LIB_OBJS += aes-gcm.o |
| 3031 | + |
| 3032 | ifndef TEST_FUZZ |
| 3033 | LIB_OBJS += random.o |
| 3034 | endif |
| 3035 | diff --git a/src/crypto/crypto_mbedtls.c b/src/crypto/crypto_mbedtls.c |
| 3036 | new file mode 100644 |
| 3037 | index 000000000..7a91c965f |
| 3038 | --- /dev/null |
| 3039 | +++ b/src/crypto/crypto_mbedtls.c |
| 3040 | @@ -0,0 +1,4228 @@ |
| 3041 | +/* |
| 3042 | + * crypto wrapper functions for mbed TLS |
| 3043 | + * |
| 3044 | + * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com> |
| 3045 | + * SPDX-License-Identifier: BSD-3-Clause |
| 3046 | + */ |
| 3047 | + |
| 3048 | +#include "utils/includes.h" |
| 3049 | +#include "utils/common.h" |
| 3050 | + |
| 3051 | +#include <mbedtls/version.h> |
| 3052 | +#include <mbedtls/entropy.h> |
| 3053 | +#include <mbedtls/ctr_drbg.h> |
| 3054 | +#include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */ |
| 3055 | +#include <mbedtls/asn1.h> |
| 3056 | +#include <mbedtls/asn1write.h> |
| 3057 | +#include <mbedtls/aes.h> |
| 3058 | +#include <mbedtls/md.h> |
| 3059 | +#include <mbedtls/md5.h> |
| 3060 | +#include <mbedtls/sha1.h> |
| 3061 | +#include <mbedtls/sha256.h> |
| 3062 | +#include <mbedtls/sha512.h> |
| 3063 | + |
| 3064 | +#ifndef MBEDTLS_PRIVATE |
| 3065 | +#define MBEDTLS_PRIVATE(x) x |
| 3066 | +#endif |
| 3067 | + |
| 3068 | +/* hostapd/wpa_supplicant provides forced_memzero(), |
| 3069 | + * but prefer mbedtls_platform_zeroize() */ |
| 3070 | +#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) |
| 3071 | + |
| 3072 | +#ifndef __has_attribute |
| 3073 | +#define __has_attribute(x) 0 |
| 3074 | +#endif |
| 3075 | + |
| 3076 | +#ifndef __GNUC_PREREQ |
| 3077 | +#define __GNUC_PREREQ(maj,min) 0 |
| 3078 | +#endif |
| 3079 | + |
| 3080 | +#ifndef __attribute_cold__ |
| 3081 | +#if __has_attribute(cold) \ |
| 3082 | + || __GNUC_PREREQ(4,3) |
| 3083 | +#define __attribute_cold__ __attribute__((__cold__)) |
| 3084 | +#else |
| 3085 | +#define __attribute_cold__ |
| 3086 | +#endif |
| 3087 | +#endif |
| 3088 | + |
| 3089 | +#ifndef __attribute_noinline__ |
| 3090 | +#if __has_attribute(noinline) \ |
| 3091 | + || __GNUC_PREREQ(3,1) |
| 3092 | +#define __attribute_noinline__ __attribute__((__noinline__)) |
| 3093 | +#else |
| 3094 | +#define __attribute_noinline__ |
| 3095 | +#endif |
| 3096 | +#endif |
| 3097 | + |
| 3098 | +#include "crypto.h" |
| 3099 | +#include "aes_wrap.h" |
| 3100 | +#include "aes.h" |
| 3101 | +#include "md5.h" |
| 3102 | +#include "sha1.h" |
| 3103 | +#include "sha256.h" |
| 3104 | +#include "sha384.h" |
| 3105 | +#include "sha512.h" |
| 3106 | + |
| 3107 | + |
| 3108 | +/* |
| 3109 | + * selective code inclusion based on preprocessor defines |
| 3110 | + * |
| 3111 | + * future: additional code could be wrapped with preprocessor checks if |
| 3112 | + * wpa_supplicant/Makefile and hostap/Makefile were more consistent with |
| 3113 | + * setting preprocessor defines for named groups of functionality |
| 3114 | + */ |
| 3115 | + |
| 3116 | +#if defined(CONFIG_FIPS) |
| 3117 | +#undef MBEDTLS_MD4_C /* omit md4_vector() */ |
| 3118 | +#undef MBEDTLS_MD5_C /* omit md5_vector() hmac_md5_vector() hmac_md5() */ |
| 3119 | +#undef MBEDTLS_DES_C /* omit des_encrypt() */ |
| 3120 | +#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ |
| 3121 | +#define CRYPTO_MBEDTLS_CONFIG_FIPS |
| 3122 | +#endif |
| 3123 | + |
| 3124 | +#if !defined(CONFIG_FIPS) |
| 3125 | +#if defined(EAP_PWD) \ |
| 3126 | + || defined(EAP_LEAP) || defined(EAP_LEAP_DYNAMIC) \ |
| 3127 | + || defined(EAP_TTLS) || defined(EAP_TTLS_DYNAMIC) \ |
| 3128 | + || defined(EAP_MSCHAPv2) || defined(EAP_MSCHAPv2_DYNAMIC) \ |
| 3129 | + || defined(EAP_SERVER_MSCHAPV2) |
| 3130 | +#ifndef MBEDTLS_MD4_C /* (MD4 not in mbedtls 3.x) */ |
| 3131 | +#include "md4-internal.c"/* pull in hostap local implementation */ |
| 3132 | +#endif /* md4_vector() */ |
| 3133 | +#else |
| 3134 | +#undef MBEDTLS_MD4_C /* omit md4_vector() */ |
| 3135 | +#endif |
| 3136 | +#endif |
| 3137 | + |
| 3138 | +#if !defined(CONFIG_NO_RC4) && !defined(CONFIG_NO_WPA) |
| 3139 | +#ifndef MBEDTLS_ARC4_C /* (RC4 not in mbedtls 3.x) */ |
| 3140 | +#include "rc4.c" /* pull in hostap local implementation */ |
| 3141 | +#endif /* rc4_skip() */ |
| 3142 | +#else |
| 3143 | +#undef MBEDTLS_ARC4_C /* omit rc4_skip() */ |
| 3144 | +#endif |
| 3145 | + |
| 3146 | +#if defined(CONFIG_MACSEC) \ |
| 3147 | + || defined(CONFIG_NO_RADIUS) \ |
| 3148 | + || defined(CONFIG_IEEE80211R) \ |
| 3149 | + || defined(EAP_SERVER_FAST) \ |
| 3150 | + || defined(EAP_SERVER_TEAP) \ |
| 3151 | + || !defined(CONFIG_NO_WPA) |
| 3152 | + /* aes_wrap() aes_unwrap() */ |
| 3153 | +#else |
| 3154 | +#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ |
| 3155 | +#endif |
| 3156 | + |
| 3157 | +#if !defined(CONFIG_SHA256) |
| 3158 | +#undef MBEDTLS_SHA256_C |
| 3159 | +#endif |
| 3160 | + |
| 3161 | +#if !defined(CONFIG_SHA384) && !defined(CONFIG_SHA512) |
| 3162 | +#undef MBEDTLS_SHA512_C |
| 3163 | +#endif |
| 3164 | + |
| 3165 | +#if defined(CONFIG_HMAC_SHA256_KDF) |
| 3166 | +#define CRYPTO_MBEDTLS_HMAC_KDF_SHA256 |
| 3167 | +#endif |
| 3168 | +#if defined(CONFIG_HMAC_SHA384_KDF) |
| 3169 | +#define CRYPTO_MBEDTLS_HMAC_KDF_SHA384 |
| 3170 | +#endif |
| 3171 | +#if defined(CONFIG_HMAC_SHA512_KDF) |
| 3172 | +#define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 |
| 3173 | +#endif |
| 3174 | + |
| 3175 | +#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ |
| 3176 | + || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) |
| 3177 | +/* EAP_SIM=y EAP_AKA=y */ |
| 3178 | +#define CRYPTO_MBEDTLS_FIPS186_2_PRF |
| 3179 | +#endif |
| 3180 | + |
| 3181 | +#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ |
| 3182 | + || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) |
| 3183 | +#define CRYPTO_MBEDTLS_SHA1_T_PRF |
| 3184 | +#endif |
| 3185 | + |
| 3186 | +#if defined(CONFIG_DES) |
| 3187 | +#define CRYPTO_MBEDTLS_DES_ENCRYPT |
| 3188 | +#endif /* des_encrypt() */ |
| 3189 | + |
| 3190 | +#if !defined(CONFIG_NO_PBKDF2) |
| 3191 | +#define CRYPTO_MBEDTLS_PBKDF2_SHA1 |
| 3192 | +#endif /* pbkdf2_sha1() */ |
| 3193 | + |
| 3194 | +#if defined(EAP_IKEV2) \ |
| 3195 | + || defined(EAP_IKEV2_DYNAMIC) \ |
| 3196 | + || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ |
| 3197 | +#define CRYPTO_MBEDTLS_CRYPTO_CIPHER |
| 3198 | +#endif /* crypto_cipher_*() */ |
| 3199 | + |
| 3200 | +#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ |
| 3201 | +#define CRYPTO_MBEDTLS_CRYPTO_HASH |
| 3202 | +#endif /* crypto_hash_*() */ |
| 3203 | + |
| 3204 | +#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ \ |
| 3205 | + || defined(CONFIG_SAE) /* CONFIG_SAE=y */ |
| 3206 | +#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 3207 | +#endif /* crypto_bignum_*() */ |
| 3208 | + |
| 3209 | +#if defined(EAP_PWD) /* CONFIG_EAP_PWD=y */ \ |
| 3210 | + || defined(EAP_EKE) /* CONFIG_EAP_EKE=y */ \ |
| 3211 | + || defined(EAP_EKE_DYNAMIC) /* CONFIG_EAP_EKE=y */ \ |
| 3212 | + || defined(EAP_SERVER_EKE) /* CONFIG_EAP_EKE=y */ \ |
| 3213 | + || defined(EAP_IKEV2) /* CONFIG_EAP_IKEV2y */ \ |
| 3214 | + || defined(EAP_IKEV2_DYNAMIC)/* CONFIG_EAP_IKEV2=y */ \ |
| 3215 | + || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ \ |
| 3216 | + || defined(CONFIG_SAE) /* CONFIG_SAE=y */ \ |
| 3217 | + || defined(CONFIG_WPS) /* CONFIG_WPS=y */ |
| 3218 | +#define CRYPTO_MBEDTLS_CRYPTO_DH |
| 3219 | +#if defined(CONFIG_WPS_NFC) |
| 3220 | +#define CRYPTO_MBEDTLS_DH5_INIT_FIXED |
| 3221 | +#endif /* dh5_init_fixed() */ |
| 3222 | +#endif /* crypto_dh_*() */ |
| 3223 | + |
| 3224 | +#if !defined(CONFIG_NO_WPA) /* CONFIG_NO_WPA= */ |
| 3225 | +#define CRYPTO_MBEDTLS_CRYPTO_ECDH |
| 3226 | +#endif /* crypto_ecdh_*() */ |
| 3227 | + |
| 3228 | +#if defined(CONFIG_ECC) |
| 3229 | +#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 3230 | +#define CRYPTO_MBEDTLS_CRYPTO_EC |
| 3231 | +#endif /* crypto_ec_*() crypto_ec_key_*() */ |
| 3232 | + |
| 3233 | +#if defined(CONFIG_DPP) /* CONFIG_DPP=y */ |
| 3234 | +#define CRYPTO_MBEDTLS_CRYPTO_EC_DPP /* extra for DPP */ |
| 3235 | +#define CRYPTO_MBEDTLS_CRYPTO_CSR |
| 3236 | +#endif /* crypto_csr_*() */ |
| 3237 | + |
| 3238 | +#if defined(CONFIG_DPP3) /* CONFIG_DPP3=y */ |
| 3239 | +#define CRYPTO_MBEDTLS_CRYPTO_HPKE |
| 3240 | +#endif |
| 3241 | + |
| 3242 | +#if defined(CONFIG_DPP2) /* CONFIG_DPP2=y */ |
| 3243 | +#define CRYPTO_MBEDTLS_CRYPTO_PKCS7 |
| 3244 | +#endif /* crypto_pkcs7_*() */ |
| 3245 | + |
| 3246 | +#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ |
| 3247 | + || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) \ |
| 3248 | + || defined(CONFIG_AP) || defined(HOSTAPD) |
| 3249 | +/* CONFIG_EAP_SIM=y CONFIG_EAP_AKA=y CONFIG_AP=y HOSTAPD */ |
| 3250 | +#if defined(CRYPTO_RSA_OAEP_SHA256) |
| 3251 | +#define CRYPTO_MBEDTLS_CRYPTO_RSA |
| 3252 | +#endif |
| 3253 | +#endif /* crypto_rsa_*() */ |
| 3254 | + |
| 3255 | + |
| 3256 | +static int ctr_drbg_init_state; |
| 3257 | +static mbedtls_ctr_drbg_context ctr_drbg; |
| 3258 | +static mbedtls_entropy_context entropy; |
| 3259 | + |
| 3260 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 3261 | +#include <mbedtls/bignum.h> |
| 3262 | +static mbedtls_mpi mpi_sw_A; |
| 3263 | +#endif |
| 3264 | + |
| 3265 | +__attribute_cold__ |
| 3266 | +__attribute_noinline__ |
| 3267 | +static mbedtls_ctr_drbg_context * ctr_drbg_init(void) |
| 3268 | +{ |
| 3269 | + mbedtls_ctr_drbg_init(&ctr_drbg); |
| 3270 | + mbedtls_entropy_init(&entropy); |
| 3271 | + if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, |
| 3272 | + NULL, 0)) { |
| 3273 | + wpa_printf(MSG_ERROR, "Init of random number generator failed"); |
| 3274 | + /* XXX: abort? */ |
| 3275 | + } |
| 3276 | + else |
| 3277 | + ctr_drbg_init_state = 1; |
| 3278 | + |
| 3279 | + return &ctr_drbg; |
| 3280 | +} |
| 3281 | + |
| 3282 | +__attribute_cold__ |
| 3283 | +void crypto_unload(void) |
| 3284 | +{ |
| 3285 | + if (ctr_drbg_init_state) { |
| 3286 | + mbedtls_ctr_drbg_free(&ctr_drbg); |
| 3287 | + mbedtls_entropy_free(&entropy); |
| 3288 | + #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 3289 | + mbedtls_mpi_free(&mpi_sw_A); |
| 3290 | + #endif |
| 3291 | + ctr_drbg_init_state = 0; |
| 3292 | + } |
| 3293 | +} |
| 3294 | + |
| 3295 | +/* init ctr_drbg on first use |
| 3296 | + * crypto_global_init() and crypto_global_deinit() are not available here |
| 3297 | + * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */ |
| 3298 | +mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ |
| 3299 | +inline |
| 3300 | +mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void) |
| 3301 | +{ |
| 3302 | + return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init(); |
| 3303 | +} |
| 3304 | + |
| 3305 | +#ifdef CRYPTO_MBEDTLS_CONFIG_FIPS |
| 3306 | +int crypto_get_random(void *buf, size_t len) |
| 3307 | +{ |
| 3308 | + return mbedtls_ctr_drbg_random(crypto_mbedtls_ctr_drbg(),buf,len) ? -1 : 0; |
| 3309 | +} |
| 3310 | +#endif |
| 3311 | + |
| 3312 | + |
| 3313 | +#if 1 |
| 3314 | + |
| 3315 | +/* tradeoff: slightly smaller code size here at cost of slight increase |
| 3316 | + * in instructions and function calls at runtime versus the expanded |
| 3317 | + * per-message-digest code that follows in #else (~0.5 kib .text larger) */ |
| 3318 | + |
| 3319 | +__attribute_noinline__ |
| 3320 | +static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, |
| 3321 | + u8 *mac, mbedtls_md_type_t md_type) |
| 3322 | +{ |
| 3323 | + if (TEST_FAIL()) |
| 3324 | + return -1; |
| 3325 | + |
| 3326 | + mbedtls_md_context_t ctx; |
| 3327 | + mbedtls_md_init(&ctx); |
| 3328 | + if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ |
| 3329 | + mbedtls_md_free(&ctx); |
| 3330 | + return -1; |
| 3331 | + } |
| 3332 | + mbedtls_md_starts(&ctx); |
| 3333 | + for (size_t i = 0; i < num_elem; ++i) |
| 3334 | + mbedtls_md_update(&ctx, addr[i], len[i]); |
| 3335 | + mbedtls_md_finish(&ctx, mac); |
| 3336 | + mbedtls_md_free(&ctx); |
| 3337 | + return 0; |
| 3338 | +} |
| 3339 | + |
| 3340 | +#ifdef MBEDTLS_SHA512_C |
| 3341 | +int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3342 | +{ |
| 3343 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA512); |
| 3344 | +} |
| 3345 | + |
| 3346 | +int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3347 | +{ |
| 3348 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA384); |
| 3349 | +} |
| 3350 | +#endif |
| 3351 | + |
| 3352 | +#ifdef MBEDTLS_SHA256_C |
| 3353 | +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3354 | +{ |
| 3355 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256); |
| 3356 | +} |
| 3357 | +#endif |
| 3358 | + |
| 3359 | +#ifdef MBEDTLS_SHA1_C |
| 3360 | +int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3361 | +{ |
| 3362 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1); |
| 3363 | +} |
| 3364 | +#endif |
| 3365 | + |
| 3366 | +#ifdef MBEDTLS_MD5_C |
| 3367 | +int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3368 | +{ |
| 3369 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5); |
| 3370 | +} |
| 3371 | +#endif |
| 3372 | + |
| 3373 | +#ifdef MBEDTLS_MD4_C |
| 3374 | +#include <mbedtls/md4.h> |
| 3375 | +int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3376 | +{ |
| 3377 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD4); |
| 3378 | +} |
| 3379 | +#endif |
| 3380 | + |
| 3381 | +#else /* expanded per-message-digest functions */ |
| 3382 | + |
| 3383 | +#ifdef MBEDTLS_SHA512_C |
| 3384 | +#include <mbedtls/sha512.h> |
| 3385 | +__attribute_noinline__ |
| 3386 | +static int sha384_512_vector(size_t num_elem, const u8 *addr[], |
| 3387 | + const size_t *len, u8 *mac, int is384) |
| 3388 | +{ |
| 3389 | + if (TEST_FAIL()) |
| 3390 | + return -1; |
| 3391 | + |
| 3392 | + struct mbedtls_sha512_context ctx; |
| 3393 | + mbedtls_sha512_init(&ctx); |
| 3394 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3395 | + mbedtls_sha512_starts(&ctx, is384); |
| 3396 | + for (size_t i = 0; i < num_elem; ++i) |
| 3397 | + mbedtls_sha512_update(&ctx, addr[i], len[i]); |
| 3398 | + mbedtls_sha512_finish(&ctx, mac); |
| 3399 | + #else |
| 3400 | + mbedtls_sha512_starts_ret(&ctx, is384); |
| 3401 | + for (size_t i = 0; i < num_elem; ++i) |
| 3402 | + mbedtls_sha512_update_ret(&ctx, addr[i], len[i]); |
| 3403 | + mbedtls_sha512_finish_ret(&ctx, mac); |
| 3404 | + #endif |
| 3405 | + mbedtls_sha512_free(&ctx); |
| 3406 | + return 0; |
| 3407 | +} |
| 3408 | + |
| 3409 | +int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3410 | +{ |
| 3411 | + return sha384_512_vector(num_elem, addr, len, mac, 0); |
| 3412 | +} |
| 3413 | + |
| 3414 | +int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3415 | +{ |
| 3416 | + return sha384_512_vector(num_elem, addr, len, mac, 1); |
| 3417 | +} |
| 3418 | +#endif |
| 3419 | + |
| 3420 | +#ifdef MBEDTLS_SHA256_C |
| 3421 | +#include <mbedtls/sha256.h> |
| 3422 | +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3423 | +{ |
| 3424 | + if (TEST_FAIL()) |
| 3425 | + return -1; |
| 3426 | + |
| 3427 | + struct mbedtls_sha256_context ctx; |
| 3428 | + mbedtls_sha256_init(&ctx); |
| 3429 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3430 | + mbedtls_sha256_starts(&ctx, 0); |
| 3431 | + for (size_t i = 0; i < num_elem; ++i) |
| 3432 | + mbedtls_sha256_update(&ctx, addr[i], len[i]); |
| 3433 | + mbedtls_sha256_finish(&ctx, mac); |
| 3434 | + #else |
| 3435 | + mbedtls_sha256_starts_ret(&ctx, 0); |
| 3436 | + for (size_t i = 0; i < num_elem; ++i) |
| 3437 | + mbedtls_sha256_update_ret(&ctx, addr[i], len[i]); |
| 3438 | + mbedtls_sha256_finish_ret(&ctx, mac); |
| 3439 | + #endif |
| 3440 | + mbedtls_sha256_free(&ctx); |
| 3441 | + return 0; |
| 3442 | +} |
| 3443 | +#endif |
| 3444 | + |
| 3445 | +#ifdef MBEDTLS_SHA1_C |
| 3446 | +#include <mbedtls/sha1.h> |
| 3447 | +int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3448 | +{ |
| 3449 | + if (TEST_FAIL()) |
| 3450 | + return -1; |
| 3451 | + |
| 3452 | + struct mbedtls_sha1_context ctx; |
| 3453 | + mbedtls_sha1_init(&ctx); |
| 3454 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3455 | + mbedtls_sha1_starts(&ctx); |
| 3456 | + for (size_t i = 0; i < num_elem; ++i) |
| 3457 | + mbedtls_sha1_update(&ctx, addr[i], len[i]); |
| 3458 | + mbedtls_sha1_finish(&ctx, mac); |
| 3459 | + #else |
| 3460 | + mbedtls_sha1_starts_ret(&ctx); |
| 3461 | + for (size_t i = 0; i < num_elem; ++i) |
| 3462 | + mbedtls_sha1_update_ret(&ctx, addr[i], len[i]); |
| 3463 | + mbedtls_sha1_finish_ret(&ctx, mac); |
| 3464 | + #endif |
| 3465 | + mbedtls_sha1_free(&ctx); |
| 3466 | + return 0; |
| 3467 | +} |
| 3468 | +#endif |
| 3469 | + |
| 3470 | +#ifdef MBEDTLS_MD5_C |
| 3471 | +#include <mbedtls/md5.h> |
| 3472 | +int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3473 | +{ |
| 3474 | + if (TEST_FAIL()) |
| 3475 | + return -1; |
| 3476 | + |
| 3477 | + struct mbedtls_md5_context ctx; |
| 3478 | + mbedtls_md5_init(&ctx); |
| 3479 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3480 | + mbedtls_md5_starts(&ctx); |
| 3481 | + for (size_t i = 0; i < num_elem; ++i) |
| 3482 | + mbedtls_md5_update(&ctx, addr[i], len[i]); |
| 3483 | + mbedtls_md5_finish(&ctx, mac); |
| 3484 | + #else |
| 3485 | + mbedtls_md5_starts_ret(&ctx); |
| 3486 | + for (size_t i = 0; i < num_elem; ++i) |
| 3487 | + mbedtls_md5_update_ret(&ctx, addr[i], len[i]); |
| 3488 | + mbedtls_md5_finish_ret(&ctx, mac); |
| 3489 | + #endif |
| 3490 | + mbedtls_md5_free(&ctx); |
| 3491 | + return 0; |
| 3492 | +} |
| 3493 | +#endif |
| 3494 | + |
| 3495 | +#ifdef MBEDTLS_MD4_C |
| 3496 | +#include <mbedtls/md4.h> |
| 3497 | +int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3498 | +{ |
| 3499 | + if (TEST_FAIL()) |
| 3500 | + return -1; |
| 3501 | + |
| 3502 | + struct mbedtls_md4_context ctx; |
| 3503 | + mbedtls_md4_init(&ctx); |
| 3504 | + mbedtls_md4_starts_ret(&ctx); |
| 3505 | + for (size_t i = 0; i < num_elem; ++i) |
| 3506 | + mbedtls_md4_update_ret(&ctx, addr[i], len[i]); |
| 3507 | + mbedtls_md4_finish_ret(&ctx, mac); |
| 3508 | + mbedtls_md4_free(&ctx); |
| 3509 | + return 0; |
| 3510 | +} |
| 3511 | +#endif |
| 3512 | + |
| 3513 | +#endif /* expanded per-message-digest functions */ |
| 3514 | + |
| 3515 | + |
| 3516 | +__attribute_noinline__ |
| 3517 | +static int hmac_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3518 | + const u8 *addr[], const size_t *len, u8 *mac, |
| 3519 | + mbedtls_md_type_t md_type) |
| 3520 | +{ |
| 3521 | + if (TEST_FAIL()) |
| 3522 | + return -1; |
| 3523 | + |
| 3524 | + mbedtls_md_context_t ctx; |
| 3525 | + mbedtls_md_init(&ctx); |
| 3526 | + if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ |
| 3527 | + mbedtls_md_free(&ctx); |
| 3528 | + return -1; |
| 3529 | + } |
| 3530 | + mbedtls_md_hmac_starts(&ctx, key, key_len); |
| 3531 | + for (size_t i = 0; i < num_elem; ++i) |
| 3532 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3533 | + mbedtls_md_hmac_finish(&ctx, mac); |
| 3534 | + mbedtls_md_free(&ctx); |
| 3535 | + return 0; |
| 3536 | +} |
| 3537 | + |
| 3538 | +#ifdef MBEDTLS_SHA512_C |
| 3539 | +int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3540 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3541 | +{ |
| 3542 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3543 | + MBEDTLS_MD_SHA512); |
| 3544 | +} |
| 3545 | + |
| 3546 | +int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3547 | + u8 *mac) |
| 3548 | +{ |
| 3549 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3550 | + MBEDTLS_MD_SHA512); |
| 3551 | +} |
| 3552 | + |
| 3553 | +int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3554 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3555 | +{ |
| 3556 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3557 | + MBEDTLS_MD_SHA384); |
| 3558 | +} |
| 3559 | + |
| 3560 | +int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3561 | + u8 *mac) |
| 3562 | +{ |
| 3563 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3564 | + MBEDTLS_MD_SHA384); |
| 3565 | +} |
| 3566 | +#endif |
| 3567 | + |
| 3568 | +#ifdef MBEDTLS_SHA256_C |
| 3569 | +int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3570 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3571 | +{ |
| 3572 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3573 | + MBEDTLS_MD_SHA256); |
| 3574 | +} |
| 3575 | + |
| 3576 | +int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3577 | + u8 *mac) |
| 3578 | +{ |
| 3579 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3580 | + MBEDTLS_MD_SHA256); |
| 3581 | +} |
| 3582 | +#endif |
| 3583 | + |
| 3584 | +#ifdef MBEDTLS_SHA1_C |
| 3585 | +int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3586 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3587 | +{ |
| 3588 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3589 | + MBEDTLS_MD_SHA1); |
| 3590 | +} |
| 3591 | + |
| 3592 | +int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3593 | + u8 *mac) |
| 3594 | +{ |
| 3595 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3596 | + MBEDTLS_MD_SHA1); |
| 3597 | +} |
| 3598 | +#endif |
| 3599 | + |
| 3600 | +#ifdef MBEDTLS_MD5_C |
| 3601 | +int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3602 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3603 | +{ |
| 3604 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3605 | + MBEDTLS_MD_MD5); |
| 3606 | +} |
| 3607 | + |
| 3608 | +int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3609 | + u8 *mac) |
| 3610 | +{ |
| 3611 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3612 | + MBEDTLS_MD_MD5); |
| 3613 | +} |
| 3614 | +#endif |
| 3615 | + |
| 3616 | + |
| 3617 | +#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C) |
| 3618 | + |
| 3619 | +#if defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA256) \ |
| 3620 | + || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA384) \ |
| 3621 | + || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA512) |
| 3622 | + |
| 3623 | +#include <mbedtls/hkdf.h> |
| 3624 | + |
| 3625 | +/* sha256-kdf.c sha384-kdf.c sha512-kdf.c */ |
| 3626 | + |
| 3627 | +/* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */ |
| 3628 | +/* HMAC-SHA384 KDF (RFC 5295) and HKDF-Expand(SHA384) (RFC 5869) */ |
| 3629 | +/* HMAC-SHA512 KDF (RFC 5295) and HKDF-Expand(SHA512) (RFC 5869) */ |
| 3630 | +__attribute_noinline__ |
| 3631 | +static int hmac_kdf_expand(const u8 *prk, size_t prk_len, |
| 3632 | + const char *label, const u8 *info, size_t info_len, |
| 3633 | + u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) |
| 3634 | +{ |
| 3635 | + if (TEST_FAIL()) |
| 3636 | + return -1; |
| 3637 | + |
| 3638 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); |
| 3639 | + #ifdef MBEDTLS_HKDF_C |
| 3640 | + if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ |
| 3641 | + return mbedtls_hkdf_expand(md_info, prk, prk_len, info, |
| 3642 | + info_len, okm, okm_len) ? -1 : 0; |
| 3643 | + #endif |
| 3644 | + |
| 3645 | + const size_t mac_len = mbedtls_md_get_size(md_info); |
| 3646 | + /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */ |
| 3647 | + if (okm_len > ((mac_len << 8) - mac_len)) |
| 3648 | + return -1; |
| 3649 | + |
| 3650 | + mbedtls_md_context_t ctx; |
| 3651 | + mbedtls_md_init(&ctx); |
| 3652 | + if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { |
| 3653 | + mbedtls_md_free(&ctx); |
| 3654 | + return -1; |
| 3655 | + } |
| 3656 | + mbedtls_md_hmac_starts(&ctx, prk, prk_len); |
| 3657 | + |
| 3658 | + u8 iter = 1; |
| 3659 | + const u8 *addr[4] = { okm, (const u8 *)label, info, &iter }; |
| 3660 | + size_t len[4] = { 0, label ? os_strlen(label)+1 : 0, info_len, 1 }; |
| 3661 | + |
| 3662 | + for (; okm_len >= mac_len; okm_len -= mac_len, ++iter) { |
| 3663 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3664 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3665 | + mbedtls_md_hmac_finish(&ctx, okm); |
| 3666 | + mbedtls_md_hmac_reset(&ctx); |
| 3667 | + addr[0] = okm; |
| 3668 | + okm += mac_len; |
| 3669 | + len[0] = mac_len; /*(include digest in subsequent rounds)*/ |
| 3670 | + } |
| 3671 | + |
| 3672 | + if (okm_len) { |
| 3673 | + u8 hash[MBEDTLS_MD_MAX_SIZE]; |
| 3674 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3675 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3676 | + mbedtls_md_hmac_finish(&ctx, hash); |
| 3677 | + os_memcpy(okm, hash, okm_len); |
| 3678 | + forced_memzero(hash, mac_len); |
| 3679 | + } |
| 3680 | + |
| 3681 | + mbedtls_md_free(&ctx); |
| 3682 | + return 0; |
| 3683 | +} |
| 3684 | + |
| 3685 | +#ifdef MBEDTLS_SHA512_C |
| 3686 | +#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA512 |
| 3687 | +int hmac_sha512_kdf(const u8 *secret, size_t secret_len, |
| 3688 | + const char *label, const u8 *seed, size_t seed_len, |
| 3689 | + u8 *out, size_t outlen) |
| 3690 | +{ |
| 3691 | + return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, |
| 3692 | + out, outlen, MBEDTLS_MD_SHA512); |
| 3693 | +} |
| 3694 | +#endif |
| 3695 | + |
| 3696 | +#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA384 |
| 3697 | +int hmac_sha384_kdf(const u8 *secret, size_t secret_len, |
| 3698 | + const char *label, const u8 *seed, size_t seed_len, |
| 3699 | + u8 *out, size_t outlen) |
| 3700 | +{ |
| 3701 | + return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, |
| 3702 | + out, outlen, MBEDTLS_MD_SHA384); |
| 3703 | +} |
| 3704 | +#endif |
| 3705 | +#endif |
| 3706 | + |
| 3707 | +#ifdef MBEDTLS_SHA256_C |
| 3708 | +#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA256 |
| 3709 | +int hmac_sha256_kdf(const u8 *secret, size_t secret_len, |
| 3710 | + const char *label, const u8 *seed, size_t seed_len, |
| 3711 | + u8 *out, size_t outlen) |
| 3712 | +{ |
| 3713 | + return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, |
| 3714 | + out, outlen, MBEDTLS_MD_SHA256); |
| 3715 | +} |
| 3716 | +#endif |
| 3717 | +#endif |
| 3718 | + |
| 3719 | +#endif /* CRYPTO_MBEDTLS_HMAC_KDF_* */ |
| 3720 | + |
| 3721 | + |
| 3722 | +/* sha256-prf.c sha384-prf.c sha512-prf.c */ |
| 3723 | + |
| 3724 | +/* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */ |
| 3725 | +__attribute_noinline__ |
| 3726 | +static int hmac_prf_bits(const u8 *key, size_t key_len, const char *label, |
| 3727 | + const u8 *data, size_t data_len, u8 *buf, |
| 3728 | + size_t buf_len_bits, mbedtls_md_type_t md_type) |
| 3729 | +{ |
| 3730 | + if (TEST_FAIL()) |
| 3731 | + return -1; |
| 3732 | + |
| 3733 | + mbedtls_md_context_t ctx; |
| 3734 | + mbedtls_md_init(&ctx); |
| 3735 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); |
| 3736 | + if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { |
| 3737 | + mbedtls_md_free(&ctx); |
| 3738 | + return -1; |
| 3739 | + } |
| 3740 | + mbedtls_md_hmac_starts(&ctx, key, key_len); |
| 3741 | + |
| 3742 | + u16 ctr, n_le = host_to_le16(buf_len_bits); |
| 3743 | + const u8 * const addr[] = { (u8 *)&ctr,(u8 *)label,data,(u8 *)&n_le }; |
| 3744 | + const size_t len[] = { 2, os_strlen(label), data_len, 2 }; |
| 3745 | + const size_t mac_len = mbedtls_md_get_size(md_info); |
| 3746 | + size_t buf_len = (buf_len_bits + 7) / 8; |
| 3747 | + for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) { |
| 3748 | + #if __BYTE_ORDER == __BIG_ENDIAN |
| 3749 | + ctr = host_to_le16(ctr); |
| 3750 | + #endif |
| 3751 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3752 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3753 | + mbedtls_md_hmac_finish(&ctx, buf); |
| 3754 | + mbedtls_md_hmac_reset(&ctx); |
| 3755 | + buf += mac_len; |
| 3756 | + #if __BYTE_ORDER == __BIG_ENDIAN |
| 3757 | + ctr = le_to_host16(ctr); |
| 3758 | + #endif |
| 3759 | + } |
| 3760 | + |
| 3761 | + if (buf_len) { |
| 3762 | + u8 hash[MBEDTLS_MD_MAX_SIZE]; |
| 3763 | + #if __BYTE_ORDER == __BIG_ENDIAN |
| 3764 | + ctr = host_to_le16(ctr); |
| 3765 | + #endif |
| 3766 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3767 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3768 | + mbedtls_md_hmac_finish(&ctx, hash); |
| 3769 | + os_memcpy(buf, hash, buf_len); |
| 3770 | + buf += buf_len; |
| 3771 | + forced_memzero(hash, mac_len); |
| 3772 | + } |
| 3773 | + |
| 3774 | + /* Mask out unused bits in last octet if it does not use all the bits */ |
| 3775 | + if ((buf_len_bits &= 0x7)) |
| 3776 | + buf[-1] &= (u8)(0xff << (8 - buf_len_bits)); |
| 3777 | + |
| 3778 | + mbedtls_md_free(&ctx); |
| 3779 | + return 0; |
| 3780 | +} |
| 3781 | + |
| 3782 | +#ifdef MBEDTLS_SHA512_C |
| 3783 | +int sha512_prf(const u8 *key, size_t key_len, const char *label, |
| 3784 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3785 | +{ |
| 3786 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3787 | + buf_len * 8, MBEDTLS_MD_SHA512); |
| 3788 | +} |
| 3789 | + |
| 3790 | +int sha384_prf(const u8 *key, size_t key_len, const char *label, |
| 3791 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3792 | +{ |
| 3793 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3794 | + buf_len * 8, MBEDTLS_MD_SHA384); |
| 3795 | +} |
| 3796 | +#endif |
| 3797 | + |
| 3798 | +#ifdef MBEDTLS_SHA256_C |
| 3799 | +int sha256_prf(const u8 *key, size_t key_len, const char *label, |
| 3800 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3801 | +{ |
| 3802 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3803 | + buf_len * 8, MBEDTLS_MD_SHA256); |
| 3804 | +} |
| 3805 | + |
| 3806 | +int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, |
| 3807 | + const u8 *data, size_t data_len, u8 *buf, |
| 3808 | + size_t buf_len_bits) |
| 3809 | +{ |
| 3810 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3811 | + buf_len_bits, MBEDTLS_MD_SHA256); |
| 3812 | +} |
| 3813 | +#endif |
| 3814 | + |
| 3815 | +#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */ |
| 3816 | + |
| 3817 | + |
| 3818 | +#ifdef MBEDTLS_SHA1_C |
| 3819 | + |
| 3820 | +/* sha1-prf.c */ |
| 3821 | + |
| 3822 | +/* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) */ |
| 3823 | + |
| 3824 | +int sha1_prf(const u8 *key, size_t key_len, const char *label, |
| 3825 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3826 | +{ |
| 3827 | + /*(note: algorithm differs from hmac_prf_bits() */ |
| 3828 | + /*(note: smaller code size instead of expanding hmac_sha1_vector() |
| 3829 | + * as is done in hmac_prf_bits(); not expecting large num of loops) */ |
| 3830 | + u8 counter = 0; |
| 3831 | + const u8 *addr[] = { (u8 *)label, data, &counter }; |
| 3832 | + const size_t len[] = { os_strlen(label)+1, data_len, 1 }; |
| 3833 | + |
| 3834 | + for (; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++counter) { |
| 3835 | + if (hmac_sha1_vector(key, key_len, 3, addr, len, buf)) |
| 3836 | + return -1; |
| 3837 | + buf += SHA1_MAC_LEN; |
| 3838 | + } |
| 3839 | + |
| 3840 | + if (buf_len) { |
| 3841 | + u8 hash[SHA1_MAC_LEN]; |
| 3842 | + if (hmac_sha1_vector(key, key_len, 3, addr, len, hash)) |
| 3843 | + return -1; |
| 3844 | + os_memcpy(buf, hash, buf_len); |
| 3845 | + forced_memzero(hash, sizeof(hash)); |
| 3846 | + } |
| 3847 | + |
| 3848 | + return 0; |
| 3849 | +} |
| 3850 | + |
| 3851 | +#ifdef CRYPTO_MBEDTLS_SHA1_T_PRF |
| 3852 | + |
| 3853 | +/* sha1-tprf.c */ |
| 3854 | + |
| 3855 | +/* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) (RFC 4851,Section 5.5)*/ |
| 3856 | + |
| 3857 | +int sha1_t_prf(const u8 *key, size_t key_len, const char *label, |
| 3858 | + const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) |
| 3859 | +{ |
| 3860 | + /*(note: algorithm differs from hmac_prf_bits() and hmac_kdf() above)*/ |
| 3861 | + /*(note: smaller code size instead of expanding hmac_sha1_vector() |
| 3862 | + * as is done in hmac_prf_bits(); not expecting large num of loops) */ |
| 3863 | + u8 ctr; |
| 3864 | + u16 olen = host_to_be16(buf_len); |
| 3865 | + const u8 *addr[] = { buf, (u8 *)label, seed, (u8 *)&olen, &ctr }; |
| 3866 | + size_t len[] = { 0, os_strlen(label)+1, seed_len, 2, 1 }; |
| 3867 | + |
| 3868 | + for (ctr = 1; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++ctr) { |
| 3869 | + if (hmac_sha1_vector(key, key_len, 5, addr, len, buf)) |
| 3870 | + return -1; |
| 3871 | + addr[0] = buf; |
| 3872 | + buf += SHA1_MAC_LEN; |
| 3873 | + len[0] = SHA1_MAC_LEN; /*(include digest in subsequent rounds)*/ |
| 3874 | + } |
| 3875 | + |
| 3876 | + if (buf_len) { |
| 3877 | + u8 hash[SHA1_MAC_LEN]; |
| 3878 | + if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) |
| 3879 | + return -1; |
| 3880 | + os_memcpy(buf, hash, buf_len); |
| 3881 | + forced_memzero(hash, sizeof(hash)); |
| 3882 | + } |
| 3883 | + |
| 3884 | + return 0; |
| 3885 | +} |
| 3886 | + |
| 3887 | +#endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ |
| 3888 | + |
| 3889 | +#ifdef CRYPTO_MBEDTLS_FIPS186_2_PRF |
| 3890 | + |
| 3891 | +/* fips_prf_internal.c sha1-internal.c */ |
| 3892 | + |
| 3893 | +/* used only by src/eap_common/eap_sim_common.c:eap_sim_prf() |
| 3894 | + * for eap_sim_derive_keys() and eap_sim_derive_keys_reauth() |
| 3895 | + * where xlen is 160 */ |
| 3896 | + |
| 3897 | +int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) |
| 3898 | +{ |
| 3899 | + /* FIPS 186-2 + change notice 1 */ |
| 3900 | + |
| 3901 | + mbedtls_sha1_context ctx; |
| 3902 | + u8 * const xkey = ctx.MBEDTLS_PRIVATE(buffer); |
| 3903 | + u32 * const xstate = ctx.MBEDTLS_PRIVATE(state); |
| 3904 | + const u32 xstate_init[] = |
| 3905 | + { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; |
| 3906 | + |
| 3907 | + mbedtls_sha1_init(&ctx); |
| 3908 | + os_memcpy(xkey, seed, seed_len < 64 ? seed_len : 64); |
| 3909 | + |
| 3910 | + /* note: does not fill extra bytes if (xlen % 20) (SHA1_MAC_LEN) */ |
| 3911 | + for (; xlen >= 20; xlen -= 20) { |
| 3912 | + /* XSEED_j = 0 */ |
| 3913 | + /* XVAL = (XKEY + XSEED_j) mod 2^b */ |
| 3914 | + |
| 3915 | + /* w_i = G(t, XVAL) */ |
| 3916 | + os_memcpy(xstate, xstate_init, sizeof(xstate_init)); |
| 3917 | + mbedtls_internal_sha1_process(&ctx, xkey); |
| 3918 | + |
| 3919 | + #if __BYTE_ORDER == __LITTLE_ENDIAN |
| 3920 | + xstate[0] = host_to_be32(xstate[0]); |
| 3921 | + xstate[1] = host_to_be32(xstate[1]); |
| 3922 | + xstate[2] = host_to_be32(xstate[2]); |
| 3923 | + xstate[3] = host_to_be32(xstate[3]); |
| 3924 | + xstate[4] = host_to_be32(xstate[4]); |
| 3925 | + #endif |
| 3926 | + os_memcpy(x, xstate, 20); |
| 3927 | + if (xlen == 20) /*(done; skip prep for next loop)*/ |
| 3928 | + break; |
| 3929 | + |
| 3930 | + /* XKEY = (1 + XKEY + w_i) mod 2^b */ |
| 3931 | + for (u32 carry = 1, k = 20; k-- > 0; carry >>= 8) |
| 3932 | + xkey[k] = (carry += xkey[k] + x[k]) & 0xff; |
| 3933 | + x += 20; |
| 3934 | + /* x_j = w_0|w_1 (each pair of iterations through loop)*/ |
| 3935 | + } |
| 3936 | + |
| 3937 | + mbedtls_sha1_free(&ctx); |
| 3938 | + return 0; |
| 3939 | +} |
| 3940 | + |
| 3941 | +#endif /* CRYPTO_MBEDTLS_FIPS186_2_PRF */ |
| 3942 | + |
| 3943 | +#endif /* MBEDTLS_SHA1_C */ |
| 3944 | + |
| 3945 | + |
| 3946 | +#ifdef CRYPTO_MBEDTLS_DES_ENCRYPT |
| 3947 | +#ifdef MBEDTLS_DES_C |
| 3948 | +#include <mbedtls/des.h> |
| 3949 | +int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) |
| 3950 | +{ |
| 3951 | + u8 pkey[8], next, tmp; |
| 3952 | + int i; |
| 3953 | + |
| 3954 | + /* Add parity bits to the key */ |
| 3955 | + next = 0; |
| 3956 | + for (i = 0; i < 7; i++) { |
| 3957 | + tmp = key[i]; |
| 3958 | + pkey[i] = (tmp >> i) | next | 1; |
| 3959 | + next = tmp << (7 - i); |
| 3960 | + } |
| 3961 | + pkey[i] = next | 1; |
| 3962 | + |
| 3963 | + mbedtls_des_context des; |
| 3964 | + mbedtls_des_init(&des); |
| 3965 | + int ret = mbedtls_des_setkey_enc(&des, pkey) |
| 3966 | + || mbedtls_des_crypt_ecb(&des, clear, cypher) ? -1 : 0; |
| 3967 | + mbedtls_des_free(&des); |
| 3968 | + return ret; |
| 3969 | +} |
| 3970 | +#else |
| 3971 | +#include "des-internal.c"/* pull in hostap local implementation */ |
| 3972 | +#endif |
| 3973 | +#endif |
| 3974 | + |
| 3975 | + |
| 3976 | +#ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1 |
| 3977 | +/* sha1-pbkdf2.c */ |
| 3978 | +#include <mbedtls/pkcs5.h> |
| 3979 | +int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, |
| 3980 | + int iterations, u8 *buf, size_t buflen) |
| 3981 | +{ |
| 3982 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020200 /* mbedtls 3.2.2 */ |
| 3983 | + return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, |
| 3984 | + (const u8 *)passphrase, os_strlen(passphrase), |
| 3985 | + ssid, ssid_len, iterations, 32, buf) ? -1 : 0; |
| 3986 | + #else |
| 3987 | + const mbedtls_md_info_t *md_info; |
| 3988 | + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); |
| 3989 | + if (md_info == NULL) |
| 3990 | + return -1; |
| 3991 | + mbedtls_md_context_t ctx; |
| 3992 | + mbedtls_md_init(&ctx); |
| 3993 | + int ret = mbedtls_md_setup(&ctx, md_info, 1) |
| 3994 | + || mbedtls_pkcs5_pbkdf2_hmac(&ctx, |
| 3995 | + (const u8 *)passphrase, os_strlen(passphrase), |
| 3996 | + ssid, ssid_len, iterations, 32, buf) ? -1 : 0; |
| 3997 | + mbedtls_md_free(&ctx); |
| 3998 | + return ret; |
| 3999 | + #endif |
| 4000 | +} |
| 4001 | +#endif |
| 4002 | + |
| 4003 | + |
| 4004 | +/*#include "aes.h"*/ /* prototypes also included in "crypto.h" */ |
| 4005 | + |
| 4006 | +static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) |
| 4007 | +{ |
| 4008 | + if (TEST_FAIL()) |
| 4009 | + return NULL; |
| 4010 | + |
| 4011 | + mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); |
| 4012 | + if (!aes) |
| 4013 | + return NULL; |
| 4014 | + |
| 4015 | + mbedtls_aes_init(aes); |
| 4016 | + if ((mode == MBEDTLS_AES_ENCRYPT |
| 4017 | + ? mbedtls_aes_setkey_enc(aes, key, len * 8) |
| 4018 | + : mbedtls_aes_setkey_dec(aes, key, len * 8)) == 0) |
| 4019 | + return aes; |
| 4020 | + |
| 4021 | + mbedtls_aes_free(aes); |
| 4022 | + os_free(aes); |
| 4023 | + return NULL; |
| 4024 | +} |
| 4025 | + |
| 4026 | +void *aes_encrypt_init(const u8 *key, size_t len) |
| 4027 | +{ |
| 4028 | + return aes_crypt_init_mode(key, len, MBEDTLS_AES_ENCRYPT); |
| 4029 | +} |
| 4030 | + |
| 4031 | +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) |
| 4032 | +{ |
| 4033 | + return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt); |
| 4034 | +} |
| 4035 | + |
| 4036 | +void aes_encrypt_deinit(void *ctx) |
| 4037 | +{ |
| 4038 | + mbedtls_aes_free(ctx); |
| 4039 | + os_free(ctx); |
| 4040 | +} |
| 4041 | + |
| 4042 | +void *aes_decrypt_init(const u8 *key, size_t len) |
| 4043 | +{ |
| 4044 | + return aes_crypt_init_mode(key, len, MBEDTLS_AES_DECRYPT); |
| 4045 | +} |
| 4046 | + |
| 4047 | +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) |
| 4048 | +{ |
| 4049 | + return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_DECRYPT, crypt, plain); |
| 4050 | +} |
| 4051 | + |
| 4052 | +void aes_decrypt_deinit(void *ctx) |
| 4053 | +{ |
| 4054 | + mbedtls_aes_free(ctx); |
| 4055 | + os_free(ctx); |
| 4056 | +} |
| 4057 | + |
| 4058 | + |
| 4059 | +#include "aes_wrap.h" |
| 4060 | + |
| 4061 | + |
| 4062 | +#ifdef MBEDTLS_NIST_KW_C |
| 4063 | + |
| 4064 | +#include <mbedtls/nist_kw.h> |
| 4065 | + |
| 4066 | +/* aes-wrap.c */ |
| 4067 | +int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) |
| 4068 | +{ |
| 4069 | + if (TEST_FAIL()) |
| 4070 | + return -1; |
| 4071 | + |
| 4072 | + mbedtls_nist_kw_context ctx; |
| 4073 | + mbedtls_nist_kw_init(&ctx); |
| 4074 | + size_t olen; |
| 4075 | + int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, |
| 4076 | + kek, kek_len*8, 1) |
| 4077 | + || mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n*8, |
| 4078 | + cipher, &olen, (n+1)*8) ? -1 : 0; |
| 4079 | + mbedtls_nist_kw_free(&ctx); |
| 4080 | + return ret; |
| 4081 | +} |
| 4082 | + |
| 4083 | +/* aes-unwrap.c */ |
| 4084 | +int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) |
| 4085 | +{ |
| 4086 | + if (TEST_FAIL()) |
| 4087 | + return -1; |
| 4088 | + |
| 4089 | + mbedtls_nist_kw_context ctx; |
| 4090 | + mbedtls_nist_kw_init(&ctx); |
| 4091 | + size_t olen; |
| 4092 | + int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, |
| 4093 | + kek, kek_len*8, 0) |
| 4094 | + || mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, |
| 4095 | + (n+1)*8, plain, &olen, n*8) ? -1 : 0; |
| 4096 | + mbedtls_nist_kw_free(&ctx); |
| 4097 | + return ret; |
| 4098 | +} |
| 4099 | + |
| 4100 | +#else |
| 4101 | + |
| 4102 | +#ifndef CRYPTO_MBEDTLS_CONFIG_FIPS |
| 4103 | +#include "aes-wrap.c" /* pull in hostap local implementation */ |
| 4104 | +#include "aes-unwrap.c" /* pull in hostap local implementation */ |
| 4105 | +#endif |
| 4106 | + |
| 4107 | +#endif /* MBEDTLS_NIST_KW_C */ |
| 4108 | + |
| 4109 | + |
| 4110 | +#ifdef MBEDTLS_CMAC_C |
| 4111 | + |
| 4112 | +/* aes-omac1.c */ |
| 4113 | + |
| 4114 | +#include <mbedtls/cmac.h> |
| 4115 | + |
| 4116 | +int omac1_aes_vector( |
| 4117 | + const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], |
| 4118 | + const size_t *len, u8 *mac) |
| 4119 | +{ |
| 4120 | + if (TEST_FAIL()) |
| 4121 | + return -1; |
| 4122 | + |
| 4123 | + mbedtls_cipher_type_t cipher_type; |
| 4124 | + switch (key_len) { |
| 4125 | + case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; |
| 4126 | + case 24: cipher_type = MBEDTLS_CIPHER_AES_192_ECB; break; |
| 4127 | + case 32: cipher_type = MBEDTLS_CIPHER_AES_256_ECB; break; |
| 4128 | + default: return -1; |
| 4129 | + } |
| 4130 | + const mbedtls_cipher_info_t *cipher_info; |
| 4131 | + cipher_info = mbedtls_cipher_info_from_type(cipher_type); |
| 4132 | + if (cipher_info == NULL) |
| 4133 | + return -1; |
| 4134 | + |
| 4135 | + mbedtls_cipher_context_t ctx; |
| 4136 | + mbedtls_cipher_init(&ctx); |
| 4137 | + int ret = -1; |
| 4138 | + if (mbedtls_cipher_setup(&ctx, cipher_info) == 0 |
| 4139 | + && mbedtls_cipher_cmac_starts(&ctx, key, key_len*8) == 0) { |
| 4140 | + ret = 0; |
| 4141 | + for (size_t i = 0; i < num_elem && ret == 0; ++i) |
| 4142 | + ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); |
| 4143 | + } |
| 4144 | + if (ret == 0) |
| 4145 | + ret = mbedtls_cipher_cmac_finish(&ctx, mac); |
| 4146 | + mbedtls_cipher_free(&ctx); |
| 4147 | + return ret ? -1 : 0; |
| 4148 | +} |
| 4149 | + |
| 4150 | +int omac1_aes_128_vector(const u8 *key, size_t num_elem, |
| 4151 | + const u8 *addr[], const size_t *len, |
| 4152 | + u8 *mac) |
| 4153 | +{ |
| 4154 | + return omac1_aes_vector(key, 16, num_elem, addr, len, mac); |
| 4155 | +} |
| 4156 | + |
| 4157 | +int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) |
| 4158 | +{ |
| 4159 | + return omac1_aes_vector(key, 16, 1, &data, &data_len, mac); |
| 4160 | +} |
| 4161 | + |
| 4162 | +int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) |
| 4163 | +{ |
| 4164 | + return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); |
| 4165 | +} |
| 4166 | + |
| 4167 | +#else |
| 4168 | + |
| 4169 | +#include "aes-omac1.c" /* pull in hostap local implementation */ |
| 4170 | + |
| 4171 | +#ifndef MBEDTLS_AES_BLOCK_SIZE |
| 4172 | +#define MBEDTLS_AES_BLOCK_SIZE 16 |
| 4173 | +#endif |
| 4174 | + |
| 4175 | +#endif /* MBEDTLS_CMAC_C */ |
| 4176 | + |
| 4177 | + |
| 4178 | +/* These interfaces can be inefficient when used in loops, as the overhead of |
| 4179 | + * initialization each call is large for each block input (e.g. 16 bytes) */ |
| 4180 | + |
| 4181 | + |
| 4182 | +/* aes-encblock.c */ |
| 4183 | +int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) |
| 4184 | +{ |
| 4185 | + if (TEST_FAIL()) |
| 4186 | + return -1; |
| 4187 | + |
| 4188 | + mbedtls_aes_context aes; |
| 4189 | + mbedtls_aes_init(&aes); |
| 4190 | + int ret = mbedtls_aes_setkey_enc(&aes, key, 128) |
| 4191 | + || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out) |
| 4192 | + ? -1 |
| 4193 | + : 0; |
| 4194 | + mbedtls_aes_free(&aes); |
| 4195 | + return ret; |
| 4196 | +} |
| 4197 | + |
| 4198 | + |
| 4199 | +/* aes-ctr.c */ |
| 4200 | +int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, |
| 4201 | + u8 *data, size_t data_len) |
| 4202 | +{ |
| 4203 | + if (TEST_FAIL()) |
| 4204 | + return -1; |
| 4205 | + |
| 4206 | + unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; |
| 4207 | + unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; |
| 4208 | + os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ |
| 4209 | + |
| 4210 | + mbedtls_aes_context ctx; |
| 4211 | + mbedtls_aes_init(&ctx); |
| 4212 | + size_t nc_off = 0; |
| 4213 | + int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len*8) |
| 4214 | + || mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off, |
| 4215 | + counter, stream_block, |
| 4216 | + data, data) ? -1 : 0; |
| 4217 | + forced_memzero(stream_block, sizeof(stream_block)); |
| 4218 | + mbedtls_aes_free(&ctx); |
| 4219 | + return ret; |
| 4220 | +} |
| 4221 | + |
| 4222 | +int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, |
| 4223 | + u8 *data, size_t data_len) |
| 4224 | +{ |
| 4225 | + return aes_ctr_encrypt(key, 16, nonce, data, data_len); |
| 4226 | +} |
| 4227 | + |
| 4228 | + |
| 4229 | +/* aes-cbc.c */ |
| 4230 | +static int aes_128_cbc_oper(const u8 *key, const u8 *iv, |
| 4231 | + u8 *data, size_t data_len, int mode) |
| 4232 | +{ |
| 4233 | + unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE]; |
| 4234 | + os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/ |
| 4235 | + |
| 4236 | + mbedtls_aes_context ctx; |
| 4237 | + mbedtls_aes_init(&ctx); |
| 4238 | + int ret = (mode == MBEDTLS_AES_ENCRYPT |
| 4239 | + ? mbedtls_aes_setkey_enc(&ctx, key, 128) |
| 4240 | + : mbedtls_aes_setkey_dec(&ctx, key, 128)) |
| 4241 | + || mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data); |
| 4242 | + mbedtls_aes_free(&ctx); |
| 4243 | + return ret ? -1 : 0; |
| 4244 | +} |
| 4245 | + |
| 4246 | +int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) |
| 4247 | +{ |
| 4248 | + if (TEST_FAIL()) |
| 4249 | + return -1; |
| 4250 | + |
| 4251 | + return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); |
| 4252 | +} |
| 4253 | + |
| 4254 | +int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) |
| 4255 | +{ |
| 4256 | + if (TEST_FAIL()) |
| 4257 | + return -1; |
| 4258 | + |
| 4259 | + return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); |
| 4260 | +} |
| 4261 | + |
| 4262 | + |
| 4263 | +/* |
| 4264 | + * Much of the following is documented in crypto.h as for CONFIG_TLS=internal |
| 4265 | + * but such comments are not accurate: |
| 4266 | + * |
| 4267 | + * "This function is only used with internal TLSv1 implementation |
| 4268 | + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need |
| 4269 | + * to implement this." |
| 4270 | + */ |
| 4271 | + |
| 4272 | + |
| 4273 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_CIPHER |
| 4274 | + |
| 4275 | +#include <mbedtls/cipher.h> |
| 4276 | + |
| 4277 | +struct crypto_cipher |
| 4278 | +{ |
| 4279 | + mbedtls_cipher_context_t ctx_enc; |
| 4280 | + mbedtls_cipher_context_t ctx_dec; |
| 4281 | +}; |
| 4282 | + |
| 4283 | +struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, |
| 4284 | + const u8 *iv, const u8 *key, |
| 4285 | + size_t key_len) |
| 4286 | +{ |
| 4287 | + /* IKEv2 src/eap_common/ikev2_common.c:ikev2_{encr,decr}_encrypt() |
| 4288 | + * uses one of CRYPTO_CIPHER_ALG_AES or CRYPTO_CIPHER_ALG_3DES */ |
| 4289 | + |
| 4290 | + mbedtls_cipher_type_t cipher_type; |
| 4291 | + size_t iv_len; |
| 4292 | + switch (alg) { |
| 4293 | + #ifdef MBEDTLS_ARC4_C |
| 4294 | + #if 0 |
| 4295 | + case CRYPTO_CIPHER_ALG_RC4: |
| 4296 | + cipher_type = MBEDTLS_CIPHER_ARC4_128; |
| 4297 | + iv_len = 0; |
| 4298 | + break; |
| 4299 | + #endif |
| 4300 | + #endif |
| 4301 | + #ifdef MBEDTLS_AES_C |
| 4302 | + case CRYPTO_CIPHER_ALG_AES: |
| 4303 | + if (key_len == 16) cipher_type = MBEDTLS_CIPHER_AES_128_CTR; |
| 4304 | + if (key_len == 24) cipher_type = MBEDTLS_CIPHER_AES_192_CTR; |
| 4305 | + if (key_len == 32) cipher_type = MBEDTLS_CIPHER_AES_256_CTR; |
| 4306 | + iv_len = 16; |
| 4307 | + break; |
| 4308 | + #endif |
| 4309 | + #ifdef MBEDTLS_DES_C |
| 4310 | + case CRYPTO_CIPHER_ALG_3DES: |
| 4311 | + cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC; |
| 4312 | + iv_len = 8; |
| 4313 | + break; |
| 4314 | + #if 0 |
| 4315 | + case CRYPTO_CIPHER_ALG_DES: |
| 4316 | + cipher_type = MBEDTLS_CIPHER_DES_CBC; |
| 4317 | + iv_len = 8; |
| 4318 | + break; |
| 4319 | + #endif |
| 4320 | + #endif |
| 4321 | + default: |
| 4322 | + return NULL; |
| 4323 | + } |
| 4324 | + |
| 4325 | + const mbedtls_cipher_info_t *cipher_info; |
| 4326 | + cipher_info = mbedtls_cipher_info_from_type(cipher_type); |
| 4327 | + if (cipher_info == NULL) |
| 4328 | + return NULL; |
| 4329 | + |
| 4330 | + key_len *= 8; /* key_bitlen */ |
| 4331 | + #if 0 /*(were key_bitlen not already available)*/ |
| 4332 | + #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ |
| 4333 | + key_len = mbedtls_cipher_info_get_key_bitlen(cipher_info); |
| 4334 | + #else |
| 4335 | + key_len = cipher_info->MBEDTLS_PRIVATE(key_bitlen); |
| 4336 | + #endif |
| 4337 | + #endif |
| 4338 | + |
| 4339 | + #if 0 /*(were iv_len not known above, would need MBEDTLS_PRIVATE(iv_size))*/ |
| 4340 | + iv_len = cipher_info->MBEDTLS_PRIVATE(iv_size); |
| 4341 | + #endif |
| 4342 | + |
| 4343 | + struct crypto_cipher *ctx = os_malloc(sizeof(*ctx)); |
| 4344 | + if (!ctx) |
| 4345 | + return NULL; |
| 4346 | + |
| 4347 | + mbedtls_cipher_init(&ctx->ctx_enc); |
| 4348 | + mbedtls_cipher_init(&ctx->ctx_dec); |
| 4349 | + if ( mbedtls_cipher_setup(&ctx->ctx_enc,cipher_info) == 0 |
| 4350 | + && mbedtls_cipher_setup(&ctx->ctx_dec,cipher_info) == 0 |
| 4351 | + && mbedtls_cipher_setkey(&ctx->ctx_enc,key,key_len,MBEDTLS_ENCRYPT) == 0 |
| 4352 | + && mbedtls_cipher_setkey(&ctx->ctx_dec,key,key_len,MBEDTLS_DECRYPT) == 0 |
| 4353 | + && mbedtls_cipher_set_iv(&ctx->ctx_enc,iv,iv_len) == 0 |
| 4354 | + && mbedtls_cipher_set_iv(&ctx->ctx_dec,iv,iv_len) == 0 |
| 4355 | + && mbedtls_cipher_reset(&ctx->ctx_enc) == 0 |
| 4356 | + && mbedtls_cipher_reset(&ctx->ctx_dec) == 0) { |
| 4357 | + return ctx; |
| 4358 | + } |
| 4359 | + |
| 4360 | + mbedtls_cipher_free(&ctx->ctx_enc); |
| 4361 | + mbedtls_cipher_free(&ctx->ctx_dec); |
| 4362 | + os_free(ctx); |
| 4363 | + return NULL; |
| 4364 | +} |
| 4365 | + |
| 4366 | +int crypto_cipher_encrypt(struct crypto_cipher *ctx, |
| 4367 | + const u8 *plain, u8 *crypt, size_t len) |
| 4368 | +{ |
| 4369 | + size_t olen = 0; /*(poor interface above; unknown size of u8 *crypt)*/ |
| 4370 | + return (mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen) |
| 4371 | + || mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen)) ? -1 : 0; |
| 4372 | +} |
| 4373 | + |
| 4374 | +int crypto_cipher_decrypt(struct crypto_cipher *ctx, |
| 4375 | + const u8 *crypt, u8 *plain, size_t len) |
| 4376 | +{ |
| 4377 | + size_t olen = 0; /*(poor interface above; unknown size of u8 *plain)*/ |
| 4378 | + return (mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen) |
| 4379 | + || mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen)) ? -1 : 0; |
| 4380 | +} |
| 4381 | + |
| 4382 | +void crypto_cipher_deinit(struct crypto_cipher *ctx) |
| 4383 | +{ |
| 4384 | + mbedtls_cipher_free(&ctx->ctx_enc); |
| 4385 | + mbedtls_cipher_free(&ctx->ctx_dec); |
| 4386 | + os_free(ctx); |
| 4387 | +} |
| 4388 | + |
| 4389 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_CIPHER */ |
| 4390 | + |
| 4391 | + |
| 4392 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_HASH |
| 4393 | + |
| 4394 | +struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, |
| 4395 | + size_t key_len) |
| 4396 | +{ |
| 4397 | + mbedtls_md_type_t md_type; |
| 4398 | + int is_hmac = 0; |
| 4399 | + |
| 4400 | + switch (alg) { |
| 4401 | + #ifdef MBEDTLS_MD5_C |
| 4402 | + case CRYPTO_HASH_ALG_MD5: |
| 4403 | + md_type = MBEDTLS_MD_MD5; |
| 4404 | + break; |
| 4405 | + #endif |
| 4406 | + #ifdef MBEDTLS_SHA1_C |
| 4407 | + case CRYPTO_HASH_ALG_SHA1: |
| 4408 | + md_type = MBEDTLS_MD_SHA1; |
| 4409 | + break; |
| 4410 | + #endif |
| 4411 | + #ifdef MBEDTLS_MD5_C |
| 4412 | + case CRYPTO_HASH_ALG_HMAC_MD5: |
| 4413 | + md_type = MBEDTLS_MD_MD5; |
| 4414 | + is_hmac = 1; |
| 4415 | + break; |
| 4416 | + #endif |
| 4417 | + #ifdef MBEDTLS_SHA1_C |
| 4418 | + case CRYPTO_HASH_ALG_HMAC_SHA1: |
| 4419 | + md_type = MBEDTLS_MD_SHA1; |
| 4420 | + is_hmac = 1; |
| 4421 | + break; |
| 4422 | + #endif |
| 4423 | + #ifdef MBEDTLS_SHA256_C |
| 4424 | + case CRYPTO_HASH_ALG_SHA256: |
| 4425 | + md_type = MBEDTLS_MD_SHA256; |
| 4426 | + break; |
| 4427 | + case CRYPTO_HASH_ALG_HMAC_SHA256: |
| 4428 | + md_type = MBEDTLS_MD_SHA256; |
| 4429 | + is_hmac = 1; |
| 4430 | + break; |
| 4431 | + #endif |
| 4432 | + #ifdef MBEDTLS_SHA512_C |
| 4433 | + case CRYPTO_HASH_ALG_SHA384: |
| 4434 | + md_type = MBEDTLS_MD_SHA384; |
| 4435 | + break; |
| 4436 | + case CRYPTO_HASH_ALG_SHA512: |
| 4437 | + md_type = MBEDTLS_MD_SHA512; |
| 4438 | + break; |
| 4439 | + #endif |
| 4440 | + default: |
| 4441 | + return NULL; |
| 4442 | + } |
| 4443 | + |
| 4444 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); |
| 4445 | + if (!md_info) |
| 4446 | + return NULL; |
| 4447 | + |
| 4448 | + mbedtls_md_context_t *mctx = os_malloc(sizeof(*mctx)); |
| 4449 | + if (mctx == NULL) |
| 4450 | + return NULL; |
| 4451 | + |
| 4452 | + mbedtls_md_init(mctx); |
| 4453 | + if (mbedtls_md_setup(mctx, md_info, is_hmac) != 0) { |
| 4454 | + os_free(mctx); |
| 4455 | + return NULL; |
| 4456 | + } |
| 4457 | + |
| 4458 | + if (is_hmac) |
| 4459 | + mbedtls_md_hmac_starts(mctx, key, key_len); |
| 4460 | + else |
| 4461 | + mbedtls_md_starts(mctx); |
| 4462 | + return (struct crypto_hash *)((uintptr_t)mctx | is_hmac); |
| 4463 | +} |
| 4464 | + |
| 4465 | +void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) |
| 4466 | +{ |
| 4467 | + mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); |
| 4468 | + #if 0 |
| 4469 | + /*(mbedtls_md_hmac_update() and mbedtls_md_update() |
| 4470 | + * make same modifications under the hood in mbedtls)*/ |
| 4471 | + if ((uintptr_t)ctx & 1uL) |
| 4472 | + mbedtls_md_hmac_update(mctx, data, len); |
| 4473 | + else |
| 4474 | + #endif |
| 4475 | + mbedtls_md_update(mctx, data, len); |
| 4476 | +} |
| 4477 | + |
| 4478 | +int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) |
| 4479 | +{ |
| 4480 | + mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); |
| 4481 | + if (mac != NULL && len != NULL) { /*(NULL if caller just freeing context)*/ |
| 4482 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 4483 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_ctx(mctx); |
| 4484 | + #else |
| 4485 | + const mbedtls_md_info_t *md_info = mctx->MBEDTLS_PRIVATE(md_info); |
| 4486 | + #endif |
| 4487 | + size_t maclen = mbedtls_md_get_size(md_info); |
| 4488 | + if (*len < maclen) { |
| 4489 | + *len = maclen; |
| 4490 | + /*(note: ctx not freed; can call again with larger *len)*/ |
| 4491 | + return -1; |
| 4492 | + } |
| 4493 | + *len = maclen; |
| 4494 | + if ((uintptr_t)ctx & 1uL) |
| 4495 | + mbedtls_md_hmac_finish(mctx, mac); |
| 4496 | + else |
| 4497 | + mbedtls_md_finish(mctx, mac); |
| 4498 | + } |
| 4499 | + mbedtls_md_free(mctx); |
| 4500 | + os_free(mctx); |
| 4501 | + |
| 4502 | + if (TEST_FAIL()) |
| 4503 | + return -1; |
| 4504 | + |
| 4505 | + return 0; |
| 4506 | +} |
| 4507 | + |
| 4508 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_HASH */ |
| 4509 | + |
| 4510 | + |
| 4511 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 4512 | + |
| 4513 | +#include <mbedtls/bignum.h> |
| 4514 | + |
| 4515 | +/* crypto.h bignum interfaces */ |
| 4516 | + |
| 4517 | +struct crypto_bignum *crypto_bignum_init(void) |
| 4518 | +{ |
| 4519 | + if (TEST_FAIL()) |
| 4520 | + return NULL; |
| 4521 | + |
| 4522 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 4523 | + if (bn) |
| 4524 | + mbedtls_mpi_init(bn); |
| 4525 | + return (struct crypto_bignum *)bn; |
| 4526 | +} |
| 4527 | + |
| 4528 | +struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) |
| 4529 | +{ |
| 4530 | + if (TEST_FAIL()) |
| 4531 | + return NULL; |
| 4532 | + |
| 4533 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 4534 | + if (bn) { |
| 4535 | + mbedtls_mpi_init(bn); |
| 4536 | + if (mbedtls_mpi_read_binary(bn, buf, len) == 0) |
| 4537 | + return (struct crypto_bignum *)bn; |
| 4538 | + } |
| 4539 | + |
| 4540 | + os_free(bn); |
| 4541 | + return NULL; |
| 4542 | +} |
| 4543 | + |
| 4544 | +struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) |
| 4545 | +{ |
| 4546 | + if (TEST_FAIL()) |
| 4547 | + return NULL; |
| 4548 | + |
| 4549 | + #if 0 /*(hostap use of this interface passes int, not uint)*/ |
| 4550 | + val = host_to_be32(val); |
| 4551 | + return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); |
| 4552 | + #else |
| 4553 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 4554 | + if (bn) { |
| 4555 | + mbedtls_mpi_init(bn); |
| 4556 | + if (mbedtls_mpi_lset(bn, (int)val) == 0) |
| 4557 | + return (struct crypto_bignum *)bn; |
| 4558 | + } |
| 4559 | + |
| 4560 | + os_free(bn); |
| 4561 | + return NULL; |
| 4562 | + #endif |
| 4563 | +} |
| 4564 | + |
| 4565 | +void crypto_bignum_deinit(struct crypto_bignum *n, int clear) |
| 4566 | +{ |
| 4567 | + mbedtls_mpi_free((mbedtls_mpi *)n); |
| 4568 | + os_free(n); |
| 4569 | +} |
| 4570 | + |
| 4571 | +int crypto_bignum_to_bin(const struct crypto_bignum *a, |
| 4572 | + u8 *buf, size_t buflen, size_t padlen) |
| 4573 | +{ |
| 4574 | + if (TEST_FAIL()) |
| 4575 | + return -1; |
| 4576 | + |
| 4577 | + size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); |
| 4578 | + if (n < padlen) |
| 4579 | + n = padlen; |
| 4580 | + return n > buflen || mbedtls_mpi_write_binary((mbedtls_mpi *)a, buf, n) |
| 4581 | + ? -1 |
| 4582 | + : (int)(n); |
| 4583 | +} |
| 4584 | + |
| 4585 | +int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) |
| 4586 | +{ |
| 4587 | + if (TEST_FAIL()) |
| 4588 | + return -1; |
| 4589 | + |
| 4590 | + /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ |
| 4591 | + #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ |
| 4592 | + return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, |
| 4593 | + mbedtls_ctr_drbg_random, |
| 4594 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 4595 | + #else |
| 4596 | + /* (needed by EAP_PWD, SAE, DPP) */ |
| 4597 | + wpa_printf(MSG_ERROR, |
| 4598 | + "mbedtls 2.27.0 or later required for mbedtls_mpi_random()"); |
| 4599 | + return -1; |
| 4600 | + #endif |
| 4601 | +} |
| 4602 | + |
| 4603 | +int crypto_bignum_add(const struct crypto_bignum *a, |
| 4604 | + const struct crypto_bignum *b, |
| 4605 | + struct crypto_bignum *c) |
| 4606 | +{ |
| 4607 | + return mbedtls_mpi_add_mpi((mbedtls_mpi *)c, |
| 4608 | + (const mbedtls_mpi *)a, |
| 4609 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4610 | +} |
| 4611 | + |
| 4612 | +int crypto_bignum_mod(const struct crypto_bignum *a, |
| 4613 | + const struct crypto_bignum *b, |
| 4614 | + struct crypto_bignum *c) |
| 4615 | +{ |
| 4616 | + return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c, |
| 4617 | + (const mbedtls_mpi *)a, |
| 4618 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4619 | +} |
| 4620 | + |
| 4621 | +int crypto_bignum_exptmod(const struct crypto_bignum *a, |
| 4622 | + const struct crypto_bignum *b, |
| 4623 | + const struct crypto_bignum *c, |
| 4624 | + struct crypto_bignum *d) |
| 4625 | +{ |
| 4626 | + if (TEST_FAIL()) |
| 4627 | + return -1; |
| 4628 | + |
| 4629 | + /* (check if input params match d; d is the result) */ |
| 4630 | + /* (a == d) is ok in current mbedtls implementation */ |
| 4631 | + if (b == d || c == d) { /*(not ok; store result in intermediate)*/ |
| 4632 | + mbedtls_mpi R; |
| 4633 | + mbedtls_mpi_init(&R); |
| 4634 | + int rc = mbedtls_mpi_exp_mod(&R, |
| 4635 | + (const mbedtls_mpi *)a, |
| 4636 | + (const mbedtls_mpi *)b, |
| 4637 | + (const mbedtls_mpi *)c, |
| 4638 | + NULL) |
| 4639 | + || mbedtls_mpi_copy((mbedtls_mpi *)d, &R) ? -1 : 0; |
| 4640 | + mbedtls_mpi_free(&R); |
| 4641 | + return rc; |
| 4642 | + } |
| 4643 | + else { |
| 4644 | + return mbedtls_mpi_exp_mod((mbedtls_mpi *)d, |
| 4645 | + (const mbedtls_mpi *)a, |
| 4646 | + (const mbedtls_mpi *)b, |
| 4647 | + (const mbedtls_mpi *)c, |
| 4648 | + NULL) ? -1 : 0; |
| 4649 | + } |
| 4650 | +} |
| 4651 | + |
| 4652 | +int crypto_bignum_inverse(const struct crypto_bignum *a, |
| 4653 | + const struct crypto_bignum *b, |
| 4654 | + struct crypto_bignum *c) |
| 4655 | +{ |
| 4656 | + if (TEST_FAIL()) |
| 4657 | + return -1; |
| 4658 | + |
| 4659 | + return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, |
| 4660 | + (const mbedtls_mpi *)a, |
| 4661 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4662 | +} |
| 4663 | + |
| 4664 | +int crypto_bignum_sub(const struct crypto_bignum *a, |
| 4665 | + const struct crypto_bignum *b, |
| 4666 | + struct crypto_bignum *c) |
| 4667 | +{ |
| 4668 | + if (TEST_FAIL()) |
| 4669 | + return -1; |
| 4670 | + |
| 4671 | + return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, |
| 4672 | + (const mbedtls_mpi *)a, |
| 4673 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4674 | +} |
| 4675 | + |
| 4676 | +int crypto_bignum_div(const struct crypto_bignum *a, |
| 4677 | + const struct crypto_bignum *b, |
| 4678 | + struct crypto_bignum *c) |
| 4679 | +{ |
| 4680 | + if (TEST_FAIL()) |
| 4681 | + return -1; |
| 4682 | + |
| 4683 | + /*(most current use of this crypto.h interface has a == c (result), |
| 4684 | + * so store result in an intermediate to avoid overwritten input)*/ |
| 4685 | + mbedtls_mpi R; |
| 4686 | + mbedtls_mpi_init(&R); |
| 4687 | + int rc = mbedtls_mpi_div_mpi(&R, NULL, |
| 4688 | + (const mbedtls_mpi *)a, |
| 4689 | + (const mbedtls_mpi *)b) |
| 4690 | + || mbedtls_mpi_copy((mbedtls_mpi *)c, &R) ? -1 : 0; |
| 4691 | + mbedtls_mpi_free(&R); |
| 4692 | + return rc; |
| 4693 | +} |
| 4694 | + |
| 4695 | +int crypto_bignum_addmod(const struct crypto_bignum *a, |
| 4696 | + const struct crypto_bignum *b, |
| 4697 | + const struct crypto_bignum *c, |
| 4698 | + struct crypto_bignum *d) |
| 4699 | +{ |
| 4700 | + if (TEST_FAIL()) |
| 4701 | + return -1; |
| 4702 | + |
| 4703 | + return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, |
| 4704 | + (const mbedtls_mpi *)a, |
| 4705 | + (const mbedtls_mpi *)b) |
| 4706 | + || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, |
| 4707 | + (mbedtls_mpi *)d, |
| 4708 | + (const mbedtls_mpi *)c) ? -1 : 0; |
| 4709 | +} |
| 4710 | + |
| 4711 | +int crypto_bignum_mulmod(const struct crypto_bignum *a, |
| 4712 | + const struct crypto_bignum *b, |
| 4713 | + const struct crypto_bignum *c, |
| 4714 | + struct crypto_bignum *d) |
| 4715 | +{ |
| 4716 | + if (TEST_FAIL()) |
| 4717 | + return -1; |
| 4718 | + |
| 4719 | + return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, |
| 4720 | + (const mbedtls_mpi *)a, |
| 4721 | + (const mbedtls_mpi *)b) |
| 4722 | + || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, |
| 4723 | + (mbedtls_mpi *)d, |
| 4724 | + (const mbedtls_mpi *)c) ? -1 : 0; |
| 4725 | +} |
| 4726 | + |
| 4727 | +int crypto_bignum_sqrmod(const struct crypto_bignum *a, |
| 4728 | + const struct crypto_bignum *b, |
| 4729 | + struct crypto_bignum *c) |
| 4730 | +{ |
| 4731 | + if (TEST_FAIL()) |
| 4732 | + return -1; |
| 4733 | + |
| 4734 | + #if 1 |
| 4735 | + return crypto_bignum_mulmod(a, a, b, c); |
| 4736 | + #else |
| 4737 | + mbedtls_mpi bn; |
| 4738 | + mbedtls_mpi_init(&bn); |
| 4739 | + if (mbedtls_mpi_lset(&bn, 2)) /* alt?: mbedtls_mpi_set_bit(&bn, 1) */ |
| 4740 | + return -1; |
| 4741 | + int ret = mbedtls_mpi_exp_mod((mbedtls_mpi *)c, |
| 4742 | + (const mbedtls_mpi *)a, &bn, |
| 4743 | + (const mbedtls_mpi *)b, NULL) ? -1 : 0; |
| 4744 | + mbedtls_mpi_free(&bn); |
| 4745 | + return ret; |
| 4746 | + #endif |
| 4747 | +} |
| 4748 | + |
| 4749 | +int crypto_bignum_rshift(const struct crypto_bignum *a, int n, |
| 4750 | + struct crypto_bignum *r) |
| 4751 | +{ |
| 4752 | + return mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a) |
| 4753 | + || mbedtls_mpi_shift_r((mbedtls_mpi *)r, n) ? -1 : 0; |
| 4754 | +} |
| 4755 | + |
| 4756 | +int crypto_bignum_cmp(const struct crypto_bignum *a, |
| 4757 | + const struct crypto_bignum *b) |
| 4758 | +{ |
| 4759 | + return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b); |
| 4760 | +} |
| 4761 | + |
| 4762 | +int crypto_bignum_is_zero(const struct crypto_bignum *a) |
| 4763 | +{ |
| 4764 | + /* XXX: src/common/sae.c:sswu() contains comment: |
| 4765 | + * "TODO: Make sure crypto_bignum_is_zero() is constant time" |
| 4766 | + * Note: mbedtls_mpi_cmp_int() *is not* constant time */ |
| 4767 | + return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0); |
| 4768 | +} |
| 4769 | + |
| 4770 | +int crypto_bignum_is_one(const struct crypto_bignum *a) |
| 4771 | +{ |
| 4772 | + return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0); |
| 4773 | +} |
| 4774 | + |
| 4775 | +int crypto_bignum_is_odd(const struct crypto_bignum *a) |
| 4776 | +{ |
| 4777 | + return mbedtls_mpi_get_bit((const mbedtls_mpi *)a, 0); |
| 4778 | +} |
| 4779 | + |
| 4780 | +#include "utils/const_time.h" |
| 4781 | +int crypto_bignum_legendre(const struct crypto_bignum *a, |
| 4782 | + const struct crypto_bignum *p) |
| 4783 | +{ |
| 4784 | + if (TEST_FAIL()) |
| 4785 | + return -2; |
| 4786 | + |
| 4787 | + /* Security Note: |
| 4788 | + * mbedtls_mpi_exp_mod() is not documented to run in constant time, |
| 4789 | + * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. |
| 4790 | + * Compare to crypto_openssl.c:crypto_bignum_legendre() |
| 4791 | + * which uses openssl BN_mod_exp_mont_consttime() |
| 4792 | + * mbedtls/library/ecp.c has further countermeasures to timing attacks, |
| 4793 | + * (but ecp.c funcs are not used here) */ |
| 4794 | + |
| 4795 | + mbedtls_mpi exp, tmp; |
| 4796 | + mbedtls_mpi_init(&exp); |
| 4797 | + mbedtls_mpi_init(&tmp); |
| 4798 | + |
| 4799 | + /* exp = (p-1) / 2 */ |
| 4800 | + int res; |
| 4801 | + if (mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1) == 0 |
| 4802 | + && mbedtls_mpi_shift_r(&exp, 1) == 0 |
| 4803 | + && mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *)a, &exp, |
| 4804 | + (const mbedtls_mpi *)p, NULL) == 0) { |
| 4805 | + /*(modified from crypto_openssl.c:crypto_bignum_legendre())*/ |
| 4806 | + /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need |
| 4807 | + * to use constant time selection to avoid branches here. */ |
| 4808 | + unsigned int mask; |
| 4809 | + res = -1; |
| 4810 | + mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 1) == 0), 1); |
| 4811 | + res = const_time_select_int(mask, 1, res); |
| 4812 | + mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 0) == 0), 1); |
| 4813 | + res = const_time_select_int(mask, 0, res); |
| 4814 | + } else { |
| 4815 | + res = -2; |
| 4816 | + } |
| 4817 | + |
| 4818 | + mbedtls_mpi_free(&tmp); |
| 4819 | + mbedtls_mpi_free(&exp); |
| 4820 | + return res; |
| 4821 | +} |
| 4822 | + |
| 4823 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_BIGNUM */ |
| 4824 | + |
| 4825 | + |
| 4826 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_DH |
| 4827 | + |
| 4828 | +/* crypto_internal-modexp.c */ |
| 4829 | + |
| 4830 | +#include <mbedtls/bignum.h> |
| 4831 | +#include <mbedtls/dhm.h> |
| 4832 | + |
| 4833 | +#if 0 /* crypto_dh_init() and crypto_dh_derive_secret() prefer to use mbedtls */ |
| 4834 | +int crypto_mod_exp(const u8 *base, size_t base_len, |
| 4835 | + const u8 *power, size_t power_len, |
| 4836 | + const u8 *modulus, size_t modulus_len, |
| 4837 | + u8 *result, size_t *result_len) |
| 4838 | +{ |
| 4839 | + if (TEST_FAIL()) |
| 4840 | + return -1; |
| 4841 | + |
| 4842 | + mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; |
| 4843 | + mbedtls_mpi_init(&bn_base); |
| 4844 | + mbedtls_mpi_init(&bn_exp); |
| 4845 | + mbedtls_mpi_init(&bn_modulus); |
| 4846 | + mbedtls_mpi_init(&bn_result); |
| 4847 | + |
| 4848 | + size_t len; |
| 4849 | + int ret = mbedtls_mpi_read_binary(&bn_base, base, base_len) |
| 4850 | + || mbedtls_mpi_read_binary(&bn_exp, power, power_len) |
| 4851 | + || mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len) |
| 4852 | + || mbedtls_mpi_exp_mod(&bn_result,&bn_base,&bn_exp,&bn_modulus,NULL) |
| 4853 | + || (len = mbedtls_mpi_size(&bn_result)) > *result_len |
| 4854 | + || mbedtls_mpi_write_binary(&bn_result, result, (*result_len = len)) |
| 4855 | + ? -1 |
| 4856 | + : 0; |
| 4857 | + |
| 4858 | + mbedtls_mpi_free(&bn_base); |
| 4859 | + mbedtls_mpi_free(&bn_exp); |
| 4860 | + mbedtls_mpi_free(&bn_modulus); |
| 4861 | + mbedtls_mpi_free(&bn_result); |
| 4862 | + return ret; |
| 4863 | +} |
| 4864 | +#endif |
| 4865 | + |
| 4866 | +static int crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context *ctx, u8 generator, |
| 4867 | + const u8 *prime, size_t prime_len) |
| 4868 | +{ |
| 4869 | + /*(could set these directly in MBEDTLS_PRIVATE members)*/ |
| 4870 | + mbedtls_mpi P, G; |
| 4871 | + mbedtls_mpi_init(&P); |
| 4872 | + mbedtls_mpi_init(&G); |
| 4873 | + int ret = mbedtls_mpi_lset(&G, generator) |
| 4874 | + || mbedtls_mpi_read_binary(&P, prime, prime_len) |
| 4875 | + || mbedtls_dhm_set_group(ctx, &P, &G); |
| 4876 | + mbedtls_mpi_free(&P); |
| 4877 | + mbedtls_mpi_free(&G); |
| 4878 | + return ret; |
| 4879 | +} |
| 4880 | + |
| 4881 | +__attribute_noinline__ |
| 4882 | +static int crypto_mbedtls_dh_init_public(mbedtls_dhm_context *ctx, u8 generator, |
| 4883 | + const u8 *prime, size_t prime_len, |
| 4884 | + u8 *privkey, u8 *pubkey) |
| 4885 | +{ |
| 4886 | + if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) |
| 4887 | + || mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, |
| 4888 | + mbedtls_ctr_drbg_random, |
| 4889 | + crypto_mbedtls_ctr_drbg())) |
| 4890 | + return -1; |
| 4891 | + |
| 4892 | + /*(enable later when upstream mbedtls interface changes require)*/ |
| 4893 | + #if 0 && MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 4894 | + mbedtls_mpi X; |
| 4895 | + mbedtls_mpi_init(&X); |
| 4896 | + int ret = mbedtls_dhm_get_value(ctx, MBEDTLS_DHM_PARAM_X, &X) |
| 4897 | + || mbedtls_mpi_write_binary(&X, privkey, prime_len) ? -1 : 0; |
| 4898 | + mbedtls_mpi_free(&X); |
| 4899 | + return ret; |
| 4900 | + #else |
| 4901 | + return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X), |
| 4902 | + privkey, prime_len) ? -1 : 0; |
| 4903 | + #endif |
| 4904 | +} |
| 4905 | + |
| 4906 | +int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, |
| 4907 | + u8 *pubkey) |
| 4908 | +{ |
| 4909 | + if (TEST_FAIL()) |
| 4910 | + return -1; |
| 4911 | + |
| 4912 | + #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ |
| 4913 | + size_t pubkey_len, pad; |
| 4914 | + |
| 4915 | + if (os_get_random(privkey, prime_len) < 0) |
| 4916 | + return -1; |
| 4917 | + if (os_memcmp(privkey, prime, prime_len) > 0) { |
| 4918 | + /* Make sure private value is smaller than prime */ |
| 4919 | + privkey[0] = 0; |
| 4920 | + } |
| 4921 | + |
| 4922 | + pubkey_len = prime_len; |
| 4923 | + if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, |
| 4924 | + pubkey, &pubkey_len) < 0) |
| 4925 | + return -1; |
| 4926 | + if (pubkey_len < prime_len) { |
| 4927 | + pad = prime_len - pubkey_len; |
| 4928 | + os_memmove(pubkey + pad, pubkey, pubkey_len); |
| 4929 | + os_memset(pubkey, 0, pad); |
| 4930 | + } |
| 4931 | + |
| 4932 | + return 0; |
| 4933 | + #else |
| 4934 | + /* Prefer to use mbedtls to derive our public/private key, as doing so |
| 4935 | + * leverages mbedtls to properly format output and to perform blinding*/ |
| 4936 | + mbedtls_dhm_context ctx; |
| 4937 | + mbedtls_dhm_init(&ctx); |
| 4938 | + int ret = crypto_mbedtls_dh_init_public(&ctx, generator, prime, |
| 4939 | + prime_len, privkey, pubkey); |
| 4940 | + mbedtls_dhm_free(&ctx); |
| 4941 | + return ret; |
| 4942 | + #endif |
| 4943 | +} |
| 4944 | + |
| 4945 | +/*(crypto_dh_derive_secret() could be implemented using crypto.h APIs |
| 4946 | + * instead of being reimplemented in each crypto_*.c)*/ |
| 4947 | +int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, |
| 4948 | + const u8 *order, size_t order_len, |
| 4949 | + const u8 *privkey, size_t privkey_len, |
| 4950 | + const u8 *pubkey, size_t pubkey_len, |
| 4951 | + u8 *secret, size_t *len) |
| 4952 | +{ |
| 4953 | + if (TEST_FAIL()) |
| 4954 | + return -1; |
| 4955 | + |
| 4956 | + #if 0 |
| 4957 | + if (pubkey_len > prime_len || |
| 4958 | + (pubkey_len == prime_len && |
| 4959 | + os_memcmp(pubkey, prime, prime_len) >= 0)) |
| 4960 | + return -1; |
| 4961 | + |
| 4962 | + int res = 0; |
| 4963 | + mbedtls_mpi pub; |
| 4964 | + mbedtls_mpi_init(&pub); |
| 4965 | + if (mbedtls_mpi_read_binary(&pub, pubkey, pubkey_len) |
| 4966 | + || mbedtls_mpi_cmp_int(&pub, 1) <= 0) { |
| 4967 | + res = -1; |
| 4968 | + } else if (order) { |
| 4969 | + mbedtls_mpi p, q, tmp; |
| 4970 | + mbedtls_mpi_init(&p); |
| 4971 | + mbedtls_mpi_init(&q); |
| 4972 | + mbedtls_mpi_init(&tmp); |
| 4973 | + |
| 4974 | + /* verify: pubkey^q == 1 mod p */ |
| 4975 | + res = (mbedtls_mpi_read_binary(&p, prime, prime_len) |
| 4976 | + || mbedtls_mpi_read_binary(&q, order, order_len) |
| 4977 | + || mbedtls_mpi_exp_mod(&tmp, &pub, &q, &p, NULL) |
| 4978 | + || mbedtls_mpi_cmp_int(&tmp, 1) != 0); |
| 4979 | + |
| 4980 | + mbedtls_mpi_free(&p); |
| 4981 | + mbedtls_mpi_free(&q); |
| 4982 | + mbedtls_mpi_free(&tmp); |
| 4983 | + } |
| 4984 | + mbedtls_mpi_free(&pub); |
| 4985 | + |
| 4986 | + return (res == 0) |
| 4987 | + ? crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len, |
| 4988 | + prime, prime_len, secret, len) |
| 4989 | + : -1; |
| 4990 | + #else |
| 4991 | + /* Prefer to use mbedtls to derive DH shared secret, as doing so |
| 4992 | + * leverages mbedtls to validate params and to perform blinding. |
| 4993 | + * |
| 4994 | + * Attempt to reconstitute DH context to derive shared secret |
| 4995 | + * (due to limitations of the interface, which ought to pass context). |
| 4996 | + * Force provided G (our private key) into context without validation. |
| 4997 | + * Regenerating GX (our public key) not needed to derive shared secret. |
| 4998 | + */ |
| 4999 | + /*(older compilers might not support VLAs)*/ |
| 5000 | + /*unsigned char buf[2+prime_len+2+1+2+pubkey_len];*/ |
| 5001 | + unsigned char buf[2+MBEDTLS_MPI_MAX_SIZE+2+1+2+MBEDTLS_MPI_MAX_SIZE]; |
| 5002 | + unsigned char *p = buf + 2 + prime_len; |
| 5003 | + if (2+prime_len+2+1+2+pubkey_len > sizeof(buf)) |
| 5004 | + return -1; |
| 5005 | + WPA_PUT_BE16(buf, prime_len); /*(2-byte big-endian size of prime)*/ |
| 5006 | + p[0] = 0; /*(2-byte big-endian size of generator)*/ |
| 5007 | + p[1] = 1; |
| 5008 | + p[2] = generator; |
| 5009 | + WPA_PUT_BE16(p+3, pubkey_len); /*(2-byte big-endian size of pubkey)*/ |
| 5010 | + os_memcpy(p+5, pubkey, pubkey_len); |
| 5011 | + os_memcpy(buf+2, prime, prime_len); |
| 5012 | + |
| 5013 | + mbedtls_dhm_context ctx; |
| 5014 | + mbedtls_dhm_init(&ctx); |
| 5015 | + p = buf; |
| 5016 | + int ret = mbedtls_dhm_read_params(&ctx, &p, p+2+prime_len+5+pubkey_len) |
| 5017 | + || mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X), |
| 5018 | + privkey, privkey_len) |
| 5019 | + || mbedtls_dhm_calc_secret(&ctx, secret, *len, len, |
| 5020 | + mbedtls_ctr_drbg_random, |
| 5021 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 5022 | + mbedtls_dhm_free(&ctx); |
| 5023 | + return ret; |
| 5024 | + #endif |
| 5025 | +} |
| 5026 | + |
| 5027 | +/* dh_group5.c */ |
| 5028 | + |
| 5029 | +#include "dh_group5.h" |
| 5030 | + |
| 5031 | +/* RFC3526_PRIME_1536[] and RFC3526_GENERATOR_1536[] from crypto_wolfssl.c */ |
| 5032 | + |
| 5033 | +static const unsigned char RFC3526_PRIME_1536[] = { |
| 5034 | + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, |
| 5035 | + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, |
| 5036 | + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, |
| 5037 | + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, |
| 5038 | + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, |
| 5039 | + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, |
| 5040 | + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, |
| 5041 | + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, |
| 5042 | + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, |
| 5043 | + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, |
| 5044 | + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, |
| 5045 | + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, |
| 5046 | + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, |
| 5047 | + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, |
| 5048 | + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, |
| 5049 | + 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF |
| 5050 | +}; |
| 5051 | + |
| 5052 | +static const unsigned char RFC3526_GENERATOR_1536[] = { |
| 5053 | + 0x02 |
| 5054 | +}; |
| 5055 | + |
| 5056 | +void * dh5_init(struct wpabuf **priv, struct wpabuf **publ) |
| 5057 | +{ |
| 5058 | + const unsigned char * const prime = RFC3526_PRIME_1536; |
| 5059 | + const size_t prime_len = sizeof(RFC3526_PRIME_1536); |
| 5060 | + const u8 generator = *RFC3526_GENERATOR_1536; |
| 5061 | + struct wpabuf *wpubl = NULL, *wpriv = NULL; |
| 5062 | + |
| 5063 | + mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); |
| 5064 | + if (ctx == NULL) |
| 5065 | + return NULL; |
| 5066 | + mbedtls_dhm_init(ctx); |
| 5067 | + |
| 5068 | + if ( (wpubl = wpabuf_alloc(prime_len)) |
| 5069 | + && (wpriv = wpabuf_alloc(prime_len)) |
| 5070 | + && crypto_mbedtls_dh_init_public(ctx, generator, prime, prime_len, |
| 5071 | + wpabuf_put(wpriv, prime_len), |
| 5072 | + wpabuf_put(wpubl, prime_len))==0) { |
| 5073 | + wpabuf_free(*publ); |
| 5074 | + wpabuf_clear_free(*priv); |
| 5075 | + *publ = wpubl; |
| 5076 | + *priv = wpriv; |
| 5077 | + return ctx; |
| 5078 | + } |
| 5079 | + |
| 5080 | + wpabuf_clear_free(wpriv); |
| 5081 | + wpabuf_free(wpubl); |
| 5082 | + mbedtls_dhm_free(ctx); |
| 5083 | + os_free(ctx); |
| 5084 | + return NULL; |
| 5085 | +} |
| 5086 | + |
| 5087 | +#ifdef CRYPTO_MBEDTLS_DH5_INIT_FIXED |
| 5088 | +void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ) |
| 5089 | +{ |
| 5090 | + const unsigned char * const prime = RFC3526_PRIME_1536; |
| 5091 | + const size_t prime_len = sizeof(RFC3526_PRIME_1536); |
| 5092 | + const u8 generator = *RFC3526_GENERATOR_1536; |
| 5093 | + |
| 5094 | + mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); |
| 5095 | + if (ctx == NULL) |
| 5096 | + return NULL; |
| 5097 | + mbedtls_dhm_init(ctx); |
| 5098 | + |
| 5099 | + if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len)==0 |
| 5100 | + #if 0 /*(ignore; not required to derive shared secret)*/ |
| 5101 | + && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(GX), |
| 5102 | + wpabuf_head(publ),wpabuf_len(publ))==0 |
| 5103 | + #endif |
| 5104 | + && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(X), |
| 5105 | + wpabuf_head(priv),wpabuf_len(priv))==0) { |
| 5106 | + return ctx; |
| 5107 | + } |
| 5108 | + |
| 5109 | + mbedtls_dhm_free(ctx); |
| 5110 | + os_free(ctx); |
| 5111 | + return NULL; |
| 5112 | +} |
| 5113 | +#endif |
| 5114 | + |
| 5115 | +struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, |
| 5116 | + const struct wpabuf *own_private) |
| 5117 | +{ |
| 5118 | + /*((mbedtls_dhm_context *)ctx must already contain own_private)*/ |
| 5119 | + /* mbedtls 2.x: prime_len = ctx->len; */ |
| 5120 | + /* mbedtls 3.x: prime_len = mbedtls_dhm_get_len(ctx); */ |
| 5121 | + size_t olen = sizeof(RFC3526_PRIME_1536); /*(sizeof(); prime known)*/ |
| 5122 | + struct wpabuf *buf = wpabuf_alloc(olen); |
| 5123 | + if (buf == NULL) |
| 5124 | + return NULL; |
| 5125 | + if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx, |
| 5126 | + wpabuf_head(peer_public), |
| 5127 | + wpabuf_len(peer_public)) == 0 |
| 5128 | + && mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, |
| 5129 | + mbedtls_ctr_drbg_random, |
| 5130 | + crypto_mbedtls_ctr_drbg()) == 0) { |
| 5131 | + wpabuf_put(buf, olen); |
| 5132 | + return buf; |
| 5133 | + } |
| 5134 | + |
| 5135 | + wpabuf_free(buf); |
| 5136 | + return NULL; |
| 5137 | +} |
| 5138 | + |
| 5139 | +void dh5_free(void *ctx) |
| 5140 | +{ |
| 5141 | + mbedtls_dhm_free(ctx); |
| 5142 | + os_free(ctx); |
| 5143 | +} |
| 5144 | + |
| 5145 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_DH */ |
| 5146 | + |
| 5147 | + |
| 5148 | +#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC) |
| 5149 | + |
| 5150 | +#include <mbedtls/ecp.h> |
| 5151 | + |
| 5152 | +#define CRYPTO_EC_pbits(e) (((mbedtls_ecp_group *)(e))->pbits) |
| 5153 | +#define CRYPTO_EC_plen(e) ((((mbedtls_ecp_group *)(e))->pbits+7)>>3) |
| 5154 | +#define CRYPTO_EC_P(e) (&((mbedtls_ecp_group *)(e))->P) |
| 5155 | +#define CRYPTO_EC_N(e) (&((mbedtls_ecp_group *)(e))->N) |
| 5156 | +#define CRYPTO_EC_A(e) (&((mbedtls_ecp_group *)(e))->A) |
| 5157 | +#define CRYPTO_EC_B(e) (&((mbedtls_ecp_group *)(e))->B) |
| 5158 | +#define CRYPTO_EC_G(e) (&((mbedtls_ecp_group *)(e))->G) |
| 5159 | + |
| 5160 | +static mbedtls_ecp_group_id crypto_mbedtls_ecp_group_id_from_ike_id(int group) |
| 5161 | +{ |
| 5162 | + /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ |
| 5163 | + switch (group) { |
| 5164 | + #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED |
| 5165 | + case 19: return MBEDTLS_ECP_DP_SECP256R1; |
| 5166 | + #endif |
| 5167 | + #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED |
| 5168 | + case 20: return MBEDTLS_ECP_DP_SECP384R1; |
| 5169 | + #endif |
| 5170 | + #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED |
| 5171 | + case 21: return MBEDTLS_ECP_DP_SECP521R1; |
| 5172 | + #endif |
| 5173 | + #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED |
| 5174 | + case 25: return MBEDTLS_ECP_DP_SECP192R1; |
| 5175 | + #endif |
| 5176 | + #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED |
| 5177 | + case 26: return MBEDTLS_ECP_DP_SECP224R1; |
| 5178 | + #endif |
| 5179 | + #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED |
| 5180 | + case 28: return MBEDTLS_ECP_DP_BP256R1; |
| 5181 | + #endif |
| 5182 | + #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED |
| 5183 | + case 29: return MBEDTLS_ECP_DP_BP384R1; |
| 5184 | + #endif |
| 5185 | + #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED |
| 5186 | + case 30: return MBEDTLS_ECP_DP_BP512R1; |
| 5187 | + #endif |
| 5188 | + #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED |
| 5189 | + case 31: return MBEDTLS_ECP_DP_CURVE25519; |
| 5190 | + #endif |
| 5191 | + #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED |
| 5192 | + case 32: return MBEDTLS_ECP_DP_CURVE448; |
| 5193 | + #endif |
| 5194 | + default: return MBEDTLS_ECP_DP_NONE; |
| 5195 | + } |
| 5196 | +} |
| 5197 | + |
| 5198 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC |
| 5199 | +static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id) |
| 5200 | +{ |
| 5201 | + /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ |
| 5202 | + /*(for crypto_ec_key_group())*/ |
| 5203 | + switch (grp_id) { |
| 5204 | + #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED |
| 5205 | + case MBEDTLS_ECP_DP_SECP256R1: return 19; |
| 5206 | + #endif |
| 5207 | + #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED |
| 5208 | + case MBEDTLS_ECP_DP_SECP384R1: return 20; |
| 5209 | + #endif |
| 5210 | + #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED |
| 5211 | + case MBEDTLS_ECP_DP_SECP521R1: return 21; |
| 5212 | + #endif |
| 5213 | + #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED |
| 5214 | + case MBEDTLS_ECP_DP_SECP192R1: return 25; |
| 5215 | + #endif |
| 5216 | + #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED |
| 5217 | + case MBEDTLS_ECP_DP_SECP224R1: return 26; |
| 5218 | + #endif |
| 5219 | + #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED |
| 5220 | + case MBEDTLS_ECP_DP_BP256R1: return 28; |
| 5221 | + #endif |
| 5222 | + #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED |
| 5223 | + case MBEDTLS_ECP_DP_BP384R1: return 29; |
| 5224 | + #endif |
| 5225 | + #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED |
| 5226 | + case MBEDTLS_ECP_DP_BP512R1: return 30; |
| 5227 | + #endif |
| 5228 | + #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED |
| 5229 | + case MBEDTLS_ECP_DP_CURVE25519: return 31; |
| 5230 | + #endif |
| 5231 | + #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED |
| 5232 | + case MBEDTLS_ECP_DP_CURVE448: return 32; |
| 5233 | + #endif |
| 5234 | + default: return -1; |
| 5235 | + } |
| 5236 | +} |
| 5237 | +#endif |
| 5238 | + |
| 5239 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH || CRYPTO_MBEDTLS_CRYPTO_EC */ |
| 5240 | + |
| 5241 | + |
| 5242 | +#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC_DPP) |
| 5243 | + |
| 5244 | +#include <mbedtls/ecp.h> |
| 5245 | +#include <mbedtls/pk.h> |
| 5246 | + |
| 5247 | +static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk) |
| 5248 | +{ |
| 5249 | + mbedtls_ecp_group_id grp_id = |
| 5250 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 5251 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 5252 | + return -1; |
| 5253 | + const mbedtls_pk_info_t *pk_info = |
| 5254 | + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); |
| 5255 | + if (pk_info == NULL) |
| 5256 | + return -1; |
| 5257 | + return mbedtls_pk_setup(pk, pk_info) |
| 5258 | + || mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), |
| 5259 | + mbedtls_ctr_drbg_random, |
| 5260 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 5261 | +} |
| 5262 | + |
| 5263 | +#endif |
| 5264 | + |
| 5265 | + |
| 5266 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH |
| 5267 | + |
| 5268 | +#include <mbedtls/ecdh.h> |
| 5269 | +#include <mbedtls/ecdsa.h> |
| 5270 | +#include <mbedtls/ecp.h> |
| 5271 | +#include <mbedtls/pk.h> |
| 5272 | + |
| 5273 | +/* wrap mbedtls_ecdh_context for more future-proof direct access to components |
| 5274 | + * (mbedtls_ecdh_context internal implementation may change between releases) |
| 5275 | + * |
| 5276 | + * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair -- |
| 5277 | + * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context, |
| 5278 | + * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh |
| 5279 | + * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could |
| 5280 | + * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */ |
| 5281 | +struct crypto_ecdh { |
| 5282 | + mbedtls_ecdh_context ctx; |
| 5283 | + mbedtls_ecp_group grp; |
| 5284 | + mbedtls_ecp_point Q; |
| 5285 | +}; |
| 5286 | + |
| 5287 | +struct crypto_ecdh * crypto_ecdh_init(int group) |
| 5288 | +{ |
| 5289 | + mbedtls_pk_context pk; |
| 5290 | + mbedtls_pk_init(&pk); |
| 5291 | + struct crypto_ecdh *ecdh = crypto_mbedtls_keypair_gen(group, &pk) == 0 |
| 5292 | + ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk) |
| 5293 | + : NULL; |
| 5294 | + mbedtls_pk_free(&pk); |
| 5295 | + return ecdh; |
| 5296 | +} |
| 5297 | + |
| 5298 | +struct crypto_ecdh * crypto_ecdh_init2(int group, |
| 5299 | + struct crypto_ec_key *own_key) |
| 5300 | +{ |
| 5301 | + mbedtls_ecp_group_id grp_id = |
| 5302 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 5303 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 5304 | + return NULL; |
| 5305 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)own_key); |
| 5306 | + struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh)); |
| 5307 | + if (ecdh == NULL) |
| 5308 | + return NULL; |
| 5309 | + mbedtls_ecdh_init(&ecdh->ctx); |
| 5310 | + mbedtls_ecp_group_init(&ecdh->grp); |
| 5311 | + mbedtls_ecp_point_init(&ecdh->Q); |
| 5312 | + if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0 |
| 5313 | + && mbedtls_ecdh_get_params(&ecdh->ctx,ecp_kp,MBEDTLS_ECDH_OURS) == 0) { |
| 5314 | + /* copy grp and Q for later use |
| 5315 | + * (retrieving this info later is more convoluted |
| 5316 | + * even if mbedtls_ecdh_make_public() is considered)*/ |
| 5317 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 5318 | + mbedtls_mpi d; |
| 5319 | + mbedtls_mpi_init(&d); |
| 5320 | + if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0) { |
| 5321 | + mbedtls_mpi_free(&d); |
| 5322 | + return ecdh; |
| 5323 | + } |
| 5324 | + mbedtls_mpi_free(&d); |
| 5325 | + #else |
| 5326 | + if (mbedtls_ecp_group_load(&ecdh->grp, grp_id) == 0 |
| 5327 | + && mbedtls_ecp_copy(&ecdh->Q, &ecp_kp->MBEDTLS_PRIVATE(Q)) == 0) |
| 5328 | + return ecdh; |
| 5329 | + #endif |
| 5330 | + } |
| 5331 | + |
| 5332 | + mbedtls_ecp_point_free(&ecdh->Q); |
| 5333 | + mbedtls_ecp_group_free(&ecdh->grp); |
| 5334 | + mbedtls_ecdh_free(&ecdh->ctx); |
| 5335 | + os_free(ecdh); |
| 5336 | + return NULL; |
| 5337 | +} |
| 5338 | + |
| 5339 | +struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) |
| 5340 | +{ |
| 5341 | + mbedtls_ecp_group *grp = &ecdh->grp; |
| 5342 | + size_t prime_len = CRYPTO_EC_plen(grp); |
| 5343 | + size_t output_len = prime_len; |
| 5344 | + u8 output_offset = 0; |
| 5345 | + u8 buf[256]; |
| 5346 | + |
| 5347 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5348 | + /* len */ |
| 5349 | + #endif |
| 5350 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5351 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 5352 | + output_len = inc_y ? prime_len * 2 + 1 : prime_len + 1; |
| 5353 | + output_offset = 1; |
| 5354 | + } |
| 5355 | + #endif |
| 5356 | + |
| 5357 | + if (output_len > sizeof(buf)) |
| 5358 | + return NULL; |
| 5359 | + |
| 5360 | + inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; |
| 5361 | + if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &output_len, |
| 5362 | + buf, output_len) == 0) { |
| 5363 | + return wpabuf_alloc_copy(buf + output_offset, output_len - output_offset); |
| 5364 | + } |
| 5365 | + |
| 5366 | + return NULL; |
| 5367 | +} |
| 5368 | + |
| 5369 | +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) |
| 5370 | +static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp, |
| 5371 | + mbedtls_mpi *bn, |
| 5372 | + int parity_bit) |
| 5373 | +{ |
| 5374 | + /* y^2 = x^3 + ax + b |
| 5375 | + * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ |
| 5376 | + mbedtls_mpi *cy2 = (mbedtls_mpi *) |
| 5377 | + crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp, |
| 5378 | + (const struct crypto_bignum *)bn); /*x*/ |
| 5379 | + if (cy2 == NULL) |
| 5380 | + return -1; |
| 5381 | + |
| 5382 | + /*mbedtls_mpi_free(bn);*/ |
| 5383 | + /*(reuse bn to store result (y))*/ |
| 5384 | + |
| 5385 | + mbedtls_mpi exp; |
| 5386 | + mbedtls_mpi_init(&exp); |
| 5387 | + int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/ |
| 5388 | + || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/ |
| 5389 | + || mbedtls_mpi_add_int(&exp, &grp->P, 1) |
| 5390 | + || mbedtls_mpi_shift_r(&exp, 2) |
| 5391 | + || mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL) |
| 5392 | + || (mbedtls_mpi_get_bit(bn, 0) != parity_bit |
| 5393 | + && mbedtls_mpi_sub_mpi(bn, &grp->P, bn)); |
| 5394 | + mbedtls_mpi_free(&exp); |
| 5395 | + mbedtls_mpi_free(cy2); |
| 5396 | + os_free(cy2); |
| 5397 | + return ret; |
| 5398 | +} |
| 5399 | +#endif |
| 5400 | + |
| 5401 | +struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, |
| 5402 | + const u8 *key, size_t len) |
| 5403 | +{ |
| 5404 | + if (len == 0) /*(invalid peer key)*/ |
| 5405 | + return NULL; |
| 5406 | + |
| 5407 | + mbedtls_ecp_group *grp = &ecdh->grp; |
| 5408 | + |
| 5409 | + #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) |
| 5410 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 5411 | + /* add header for mbedtls_ecdh_read_public() */ |
| 5412 | + u8 buf[256]; |
| 5413 | + if (sizeof(buf)-1 < len) |
| 5414 | + return NULL; |
| 5415 | + buf[0] = (u8)(len); |
| 5416 | + os_memcpy(buf+1, key, len); |
| 5417 | + |
| 5418 | + if (inc_y) { |
| 5419 | + if (!(len & 1)) { /*(dpp code/tests does not include tag?!?)*/ |
| 5420 | + if (sizeof(buf)-2 < len) |
| 5421 | + return NULL; |
| 5422 | + buf[0] = (u8)(1+len); |
| 5423 | + buf[1] = 0x04; |
| 5424 | + os_memcpy(buf+2, key, len); |
| 5425 | + } |
| 5426 | + len >>= 1; /*(repurpose len to prime_len)*/ |
| 5427 | + } else { /* (inc_y == 0) */ |
| 5428 | + /* mbedtls_ecp_point_read_binary() does not currently support |
| 5429 | + * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) |
| 5430 | + * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ |
| 5431 | + |
| 5432 | + /* derive y, amend buf[] with y for UNCOMPRESSED format */ |
| 5433 | + if (sizeof(buf)-2 < len*2 || len == 0) |
| 5434 | + return NULL; |
| 5435 | + |
| 5436 | + buf[0] = (u8)(1+len*2); |
| 5437 | + buf[1] = 0x04; |
| 5438 | + os_memcpy(buf+2, key, len); |
| 5439 | + |
| 5440 | + mbedtls_mpi bn; |
| 5441 | + mbedtls_mpi_init(&bn); |
| 5442 | + int ret = mbedtls_mpi_read_binary(&bn, key, len) |
| 5443 | + || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, 0) |
| 5444 | + || mbedtls_mpi_write_binary(&bn, buf+2+len, len); |
| 5445 | + mbedtls_mpi_free(&bn); |
| 5446 | + if (ret != 0) |
| 5447 | + return NULL; |
| 5448 | + } |
| 5449 | + |
| 5450 | + if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1)) |
| 5451 | + return NULL; |
| 5452 | + } |
| 5453 | + #endif |
| 5454 | + #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) |
| 5455 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5456 | + if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len)) |
| 5457 | + return NULL; |
| 5458 | + } |
| 5459 | + #endif |
| 5460 | + |
| 5461 | + struct wpabuf *buf = wpabuf_alloc(len); |
| 5462 | + if (buf == NULL) |
| 5463 | + return NULL; |
| 5464 | + |
| 5465 | + if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, |
| 5466 | + wpabuf_mhead(buf), len, |
| 5467 | + mbedtls_ctr_drbg_random, |
| 5468 | + crypto_mbedtls_ctr_drbg()) == 0) { |
| 5469 | + wpabuf_put(buf, len); |
| 5470 | + return buf; |
| 5471 | + } |
| 5472 | + |
| 5473 | + wpabuf_clear_free(buf); |
| 5474 | + return NULL; |
| 5475 | +} |
| 5476 | + |
| 5477 | +void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) |
| 5478 | +{ |
| 5479 | + if (ecdh == NULL) |
| 5480 | + return; |
| 5481 | + mbedtls_ecp_point_free(&ecdh->Q); |
| 5482 | + mbedtls_ecp_group_free(&ecdh->grp); |
| 5483 | + mbedtls_ecdh_free(&ecdh->ctx); |
| 5484 | + os_free(ecdh); |
| 5485 | +} |
| 5486 | + |
| 5487 | +size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh) |
| 5488 | +{ |
| 5489 | + return CRYPTO_EC_plen(&ecdh->grp); |
| 5490 | +} |
| 5491 | + |
| 5492 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */ |
| 5493 | + |
| 5494 | + |
| 5495 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC |
| 5496 | + |
| 5497 | +#include <mbedtls/ecp.h> |
| 5498 | + |
| 5499 | +struct crypto_ec *crypto_ec_init(int group) |
| 5500 | +{ |
| 5501 | + mbedtls_ecp_group_id grp_id = |
| 5502 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 5503 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 5504 | + return NULL; |
| 5505 | + mbedtls_ecp_group *e = os_malloc(sizeof(*e)); |
| 5506 | + if (e == NULL) |
| 5507 | + return NULL; |
| 5508 | + mbedtls_ecp_group_init(e); |
| 5509 | + if (mbedtls_ecp_group_load(e, grp_id) == 0) |
| 5510 | + return (struct crypto_ec *)e; |
| 5511 | + |
| 5512 | + mbedtls_ecp_group_free(e); |
| 5513 | + os_free(e); |
| 5514 | + return NULL; |
| 5515 | +} |
| 5516 | + |
| 5517 | +void crypto_ec_deinit(struct crypto_ec *e) |
| 5518 | +{ |
| 5519 | + mbedtls_ecp_group_free((mbedtls_ecp_group *)e); |
| 5520 | + os_free(e); |
| 5521 | +} |
| 5522 | + |
| 5523 | +size_t crypto_ec_prime_len(struct crypto_ec *e) |
| 5524 | +{ |
| 5525 | + return CRYPTO_EC_plen(e); |
| 5526 | +} |
| 5527 | + |
| 5528 | +size_t crypto_ec_prime_len_bits(struct crypto_ec *e) |
| 5529 | +{ |
| 5530 | + return CRYPTO_EC_pbits(e); |
| 5531 | +} |
| 5532 | + |
| 5533 | +size_t crypto_ec_order_len(struct crypto_ec *e) |
| 5534 | +{ |
| 5535 | + return (mbedtls_mpi_bitlen(CRYPTO_EC_N(e)) + 7) / 8; |
| 5536 | +} |
| 5537 | + |
| 5538 | +const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e) |
| 5539 | +{ |
| 5540 | + return (const struct crypto_bignum *)CRYPTO_EC_P(e); |
| 5541 | +} |
| 5542 | + |
| 5543 | +const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e) |
| 5544 | +{ |
| 5545 | + return (const struct crypto_bignum *)CRYPTO_EC_N(e); |
| 5546 | +} |
| 5547 | + |
| 5548 | +const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *e) |
| 5549 | +{ |
| 5550 | + static const uint8_t secp256r1_a[] = |
| 5551 | + {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x01, |
| 5552 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| 5553 | + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, |
| 5554 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; |
| 5555 | + static const uint8_t secp384r1_a[] = |
| 5556 | + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5557 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5558 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5559 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, |
| 5560 | + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, |
| 5561 | + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfc}; |
| 5562 | + static const uint8_t secp521r1_a[] = |
| 5563 | + {0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5564 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5565 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5566 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5567 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5568 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5569 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5570 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5571 | + 0xff,0xfc}; |
| 5572 | + static const uint8_t secp192r1_a[] = |
| 5573 | + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5574 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, |
| 5575 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; |
| 5576 | + static const uint8_t secp224r1_a[] = |
| 5577 | + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5578 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, |
| 5579 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5580 | + 0xff,0xff,0xff,0xfe}; |
| 5581 | + |
| 5582 | + const uint8_t *bin = NULL; |
| 5583 | + size_t len = 0; |
| 5584 | + |
| 5585 | + /* (mbedtls groups matching supported sswu_curve_param() IKE groups) */ |
| 5586 | + switch (((mbedtls_ecp_group *)e)->id) { |
| 5587 | + #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED |
| 5588 | + case MBEDTLS_ECP_DP_SECP256R1: |
| 5589 | + bin = secp256r1_a; |
| 5590 | + len = sizeof(secp256r1_a); |
| 5591 | + break; |
| 5592 | + #endif |
| 5593 | + #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED |
| 5594 | + case MBEDTLS_ECP_DP_SECP384R1: |
| 5595 | + bin = secp384r1_a; |
| 5596 | + len = sizeof(secp384r1_a); |
| 5597 | + break; |
| 5598 | + #endif |
| 5599 | + #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED |
| 5600 | + case MBEDTLS_ECP_DP_SECP521R1: |
| 5601 | + bin = secp521r1_a; |
| 5602 | + len = sizeof(secp521r1_a); |
| 5603 | + break; |
| 5604 | + #endif |
| 5605 | + #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED |
| 5606 | + case MBEDTLS_ECP_DP_SECP192R1: |
| 5607 | + bin = secp192r1_a; |
| 5608 | + len = sizeof(secp192r1_a); |
| 5609 | + break; |
| 5610 | + #endif |
| 5611 | + #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED |
| 5612 | + case MBEDTLS_ECP_DP_SECP224R1: |
| 5613 | + bin = secp224r1_a; |
| 5614 | + len = sizeof(secp224r1_a); |
| 5615 | + break; |
| 5616 | + #endif |
| 5617 | + #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED |
| 5618 | + case MBEDTLS_ECP_DP_BP256R1: |
| 5619 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5620 | + #endif |
| 5621 | + #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED |
| 5622 | + case MBEDTLS_ECP_DP_BP384R1: |
| 5623 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5624 | + #endif |
| 5625 | + #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED |
| 5626 | + case MBEDTLS_ECP_DP_BP512R1: |
| 5627 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5628 | + #endif |
| 5629 | + #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED |
| 5630 | + case MBEDTLS_ECP_DP_CURVE25519: |
| 5631 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5632 | + #endif |
| 5633 | + #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED |
| 5634 | + case MBEDTLS_ECP_DP_CURVE448: |
| 5635 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5636 | + #endif |
| 5637 | + default: |
| 5638 | + return NULL; |
| 5639 | + } |
| 5640 | + |
| 5641 | + /*(note: not thread-safe; returns file-scoped static storage)*/ |
| 5642 | + if (mbedtls_mpi_read_binary(&mpi_sw_A, bin, len) == 0) |
| 5643 | + return (const struct crypto_bignum *)&mpi_sw_A; |
| 5644 | + return NULL; |
| 5645 | +} |
| 5646 | + |
| 5647 | +const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *e) |
| 5648 | +{ |
| 5649 | + return (const struct crypto_bignum *)CRYPTO_EC_B(e); |
| 5650 | +} |
| 5651 | + |
| 5652 | +const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e) |
| 5653 | +{ |
| 5654 | + return (const struct crypto_ec_point *)CRYPTO_EC_G(e); |
| 5655 | +} |
| 5656 | + |
| 5657 | +struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) |
| 5658 | +{ |
| 5659 | + if (TEST_FAIL()) |
| 5660 | + return NULL; |
| 5661 | + |
| 5662 | + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); |
| 5663 | + if (p != NULL) |
| 5664 | + mbedtls_ecp_point_init(p); |
| 5665 | + return (struct crypto_ec_point *)p; |
| 5666 | +} |
| 5667 | + |
| 5668 | +void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear) |
| 5669 | +{ |
| 5670 | + mbedtls_ecp_point_free((mbedtls_ecp_point *)p); |
| 5671 | + os_free(p); |
| 5672 | +} |
| 5673 | + |
| 5674 | +int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p, |
| 5675 | + struct crypto_bignum *x) |
| 5676 | +{ |
| 5677 | + mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); |
| 5678 | + return mbedtls_mpi_copy((mbedtls_mpi *)x, px) |
| 5679 | + ? -1 |
| 5680 | + : 0; |
| 5681 | +} |
| 5682 | + |
| 5683 | +int crypto_ec_point_to_bin(struct crypto_ec *e, |
| 5684 | + const struct crypto_ec_point *point, u8 *x, u8 *y) |
| 5685 | +{ |
| 5686 | + if (TEST_FAIL()) |
| 5687 | + return -1; |
| 5688 | + |
| 5689 | + /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ |
| 5690 | + size_t len = CRYPTO_EC_plen(e); |
| 5691 | + if (x) { |
| 5692 | + mbedtls_mpi *px = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(X); |
| 5693 | + if (mbedtls_mpi_write_binary(px, x, len)) |
| 5694 | + return -1; |
| 5695 | + } |
| 5696 | + if (y) { |
| 5697 | + #if 0 /*(should not be necessary; py mpi should be in initial state)*/ |
| 5698 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5699 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5700 | + == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5701 | + os_memset(y, 0, len); |
| 5702 | + return 0; |
| 5703 | + } |
| 5704 | + #endif |
| 5705 | + #endif |
| 5706 | + mbedtls_mpi *py = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(Y); |
| 5707 | + if (mbedtls_mpi_write_binary(py, y, len)) |
| 5708 | + return -1; |
| 5709 | + } |
| 5710 | + return 0; |
| 5711 | +} |
| 5712 | + |
| 5713 | +struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, |
| 5714 | + const u8 *val) |
| 5715 | +{ |
| 5716 | + if (TEST_FAIL()) |
| 5717 | + return NULL; |
| 5718 | + |
| 5719 | + size_t len = CRYPTO_EC_plen(e); |
| 5720 | + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); |
| 5721 | + u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; |
| 5722 | + if (p == NULL) |
| 5723 | + return NULL; |
| 5724 | + mbedtls_ecp_point_init(p); |
| 5725 | + |
| 5726 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5727 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5728 | + == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 5729 | + #if 0 /* prefer alternative to MBEDTLS_PRIVATE() access */ |
| 5730 | + mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); |
| 5731 | + mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); |
| 5732 | + mbedtls_mpi *pz = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z); |
| 5733 | + |
| 5734 | + if (mbedtls_mpi_read_binary(px, val, len) == 0 |
| 5735 | + && mbedtls_mpi_read_binary(py, val + len, len) == 0 |
| 5736 | + && mbedtls_mpi_lset(pz, 1) == 0) |
| 5737 | + return (struct crypto_ec_point *)p; |
| 5738 | + #else |
| 5739 | + buf[0] = 0x04; |
| 5740 | + os_memcpy(buf+1, val, len*2); |
| 5741 | + if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, |
| 5742 | + buf, 1+len*2) == 0) |
| 5743 | + return (struct crypto_ec_point *)p; |
| 5744 | + #endif |
| 5745 | + } |
| 5746 | + #endif |
| 5747 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5748 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5749 | + == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5750 | + /* crypto.h interface documents crypto_ec_point_from_bin() |
| 5751 | + * val is length: prime_len * 2 and is big-endian |
| 5752 | + * (Short Weierstrass is assumed by hostap) |
| 5753 | + * Reverse to little-endian format for Montgomery */ |
| 5754 | + for (unsigned int i = 0; i < len; ++i) |
| 5755 | + buf[i] = val[len-1-i]; |
| 5756 | + if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, |
| 5757 | + buf, len) == 0) |
| 5758 | + return (struct crypto_ec_point *)p; |
| 5759 | + } |
| 5760 | + #endif |
| 5761 | + |
| 5762 | + mbedtls_ecp_point_free(p); |
| 5763 | + os_free(p); |
| 5764 | + return NULL; |
| 5765 | +} |
| 5766 | + |
| 5767 | +int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a, |
| 5768 | + const struct crypto_ec_point *b, |
| 5769 | + struct crypto_ec_point *c) |
| 5770 | +{ |
| 5771 | + if (TEST_FAIL()) |
| 5772 | + return -1; |
| 5773 | + |
| 5774 | + /* mbedtls does not provide an mbedtls_ecp_point add function */ |
| 5775 | + mbedtls_mpi one; |
| 5776 | + mbedtls_mpi_init(&one); |
| 5777 | + int ret = mbedtls_mpi_lset(&one, 1) |
| 5778 | + || mbedtls_ecp_muladd( |
| 5779 | + (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)c, |
| 5780 | + &one, (const mbedtls_ecp_point *)a, |
| 5781 | + &one, (const mbedtls_ecp_point *)b) ? -1 : 0; |
| 5782 | + mbedtls_mpi_free(&one); |
| 5783 | + return ret; |
| 5784 | +} |
| 5785 | + |
| 5786 | +int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, |
| 5787 | + const struct crypto_bignum *b, |
| 5788 | + struct crypto_ec_point *res) |
| 5789 | +{ |
| 5790 | + if (TEST_FAIL()) |
| 5791 | + return -1; |
| 5792 | + |
| 5793 | + return mbedtls_ecp_mul( |
| 5794 | + (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, |
| 5795 | + (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, |
| 5796 | + mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 5797 | +} |
| 5798 | + |
| 5799 | +int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) |
| 5800 | +{ |
| 5801 | + if (TEST_FAIL()) |
| 5802 | + return -1; |
| 5803 | + |
| 5804 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5805 | + == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5806 | + /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ |
| 5807 | + wpa_printf(MSG_ERROR, |
| 5808 | + "%s not implemented for Montgomery curves",__func__); |
| 5809 | + return -1; |
| 5810 | + } |
| 5811 | + |
| 5812 | + /* mbedtls does not provide an mbedtls_ecp_point invert function */ |
| 5813 | + /* below works for Short Weierstrass; incorrect for Montgomery curves */ |
| 5814 | + mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); |
| 5815 | + return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p) /*point at infinity*/ |
| 5816 | + || mbedtls_mpi_cmp_int(py, 0) == 0 /*point is its own inverse*/ |
| 5817 | + || mbedtls_mpi_sub_abs(py, CRYPTO_EC_P(e), py) == 0 ? 0 : -1; |
| 5818 | +} |
| 5819 | + |
| 5820 | +#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5821 | +static int |
| 5822 | +crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group *e, const mbedtls_mpi *x, |
| 5823 | + mbedtls_mpi *y2) |
| 5824 | +{ |
| 5825 | + /* MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS y^2 = x^3 + a x + b */ |
| 5826 | + |
| 5827 | + /* Short Weierstrass elliptic curve group w/o A set treated as A = -3 */ |
| 5828 | + /* Attempt to match mbedtls/library/ecp.c:ecp_check_pubkey_sw() behavior |
| 5829 | + * and elsewhere in mbedtls/library/ecp.c where if A is not set, it is |
| 5830 | + * treated as if A = -3. */ |
| 5831 | + |
| 5832 | + #if 0 |
| 5833 | + /* y^2 = x^3 + ax + b */ |
| 5834 | + mbedtls_mpi *A = &e->A; |
| 5835 | + mbedtls_mpi t, A_neg3; |
| 5836 | + if (&e->A.p == NULL) { |
| 5837 | + mbedtls_mpi_init(&A_neg3); |
| 5838 | + if (mbedtls_mpi_lset(&A_neg3, -3) != 0) { |
| 5839 | + mbedtls_mpi_free(&A_neg3); |
| 5840 | + return -1; |
| 5841 | + } |
| 5842 | + A = &A_neg3; |
| 5843 | + } |
| 5844 | + mbedtls_mpi_init(&t); |
| 5845 | + int ret = /* x^3 */ |
| 5846 | + mbedtls_mpi_lset(&t, 3) |
| 5847 | + || mbedtls_mpi_exp_mod(y2, x, &t, &e->P, NULL) |
| 5848 | + /* ax */ |
| 5849 | + || mbedtls_mpi_mul_mpi(y2, y2, A) |
| 5850 | + || mbedtls_mpi_mod_mpi(&t, &t, &e->P) |
| 5851 | + /* ax + b */ |
| 5852 | + || mbedtls_mpi_add_mpi(&t, &t, &e->B) |
| 5853 | + || mbedtls_mpi_mod_mpi(&t, &t, &e->P) |
| 5854 | + /* x^3 + ax + b */ |
| 5855 | + || mbedtls_mpi_add_mpi(&t, &t, y2) /* ax + b + x^3 */ |
| 5856 | + || mbedtls_mpi_mod_mpi(y2, &t, &e->P); |
| 5857 | + mbedtls_mpi_free(&t); |
| 5858 | + if (A == &A_neg3) |
| 5859 | + mbedtls_mpi_free(&A_neg3); |
| 5860 | + return ret; /* 0: success, non-zero: failure */ |
| 5861 | + #else |
| 5862 | + /* y^2 = x^3 + ax + b = (x^2 + a)x + b */ |
| 5863 | + return /* x^2 */ |
| 5864 | + mbedtls_mpi_mul_mpi(y2, x, x) |
| 5865 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5866 | + /* x^2 + a */ |
| 5867 | + || (e->A.MBEDTLS_PRIVATE(p) |
| 5868 | + ? mbedtls_mpi_add_mpi(y2, y2, &e->A) |
| 5869 | + : mbedtls_mpi_sub_int(y2, y2, 3)) |
| 5870 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5871 | + /* (x^2 + a)x */ |
| 5872 | + || mbedtls_mpi_mul_mpi(y2, y2, x) |
| 5873 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5874 | + /* (x^2 + a)x + b */ |
| 5875 | + || mbedtls_mpi_add_mpi(y2, y2, &e->B) |
| 5876 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P); |
| 5877 | + #endif |
| 5878 | +} |
| 5879 | +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ |
| 5880 | + |
| 5881 | +#if 0 /* not used by hostap */ |
| 5882 | +#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5883 | +static int |
| 5884 | +crypto_ec_point_y_sqr_montgomery(mbedtls_ecp_group *e, const mbedtls_mpi *x, |
| 5885 | + mbedtls_mpi *y2) |
| 5886 | +{ |
| 5887 | + /* XXX: !!! must be reviewed and audited for correctness !!! */ |
| 5888 | + |
| 5889 | + /* MBEDTLS_ECP_TYPE_MONTGOMERY y^2 = x^3 + a x^2 + x */ |
| 5890 | + |
| 5891 | + /* y^2 = x^3 + a x^2 + x = (x + a)x^2 + x */ |
| 5892 | + mbedtls_mpi x2; |
| 5893 | + mbedtls_mpi_init(&x2); |
| 5894 | + int ret = /* x^2 */ |
| 5895 | + mbedtls_mpi_mul_mpi(&x2, x, x) |
| 5896 | + || mbedtls_mpi_mod_mpi(&x2, &x2, &e->P) |
| 5897 | + /* x + a */ |
| 5898 | + || mbedtls_mpi_add_mpi(y2, x, &e->A) |
| 5899 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5900 | + /* (x + a)x^2 */ |
| 5901 | + || mbedtls_mpi_mul_mpi(y2, y2, &x2) |
| 5902 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5903 | + /* (x + a)x^2 + x */ |
| 5904 | + || mbedtls_mpi_add_mpi(y2, y2, x) |
| 5905 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P); |
| 5906 | + mbedtls_mpi_free(&x2); |
| 5907 | + return ret; /* 0: success, non-zero: failure */ |
| 5908 | +} |
| 5909 | +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ |
| 5910 | +#endif |
| 5911 | + |
| 5912 | +struct crypto_bignum * |
| 5913 | +crypto_ec_point_compute_y_sqr(struct crypto_ec *e, |
| 5914 | + const struct crypto_bignum *x) |
| 5915 | +{ |
| 5916 | + if (TEST_FAIL()) |
| 5917 | + return NULL; |
| 5918 | + |
| 5919 | + mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); |
| 5920 | + if (y2 == NULL) |
| 5921 | + return NULL; |
| 5922 | + mbedtls_mpi_init(y2); |
| 5923 | + |
| 5924 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5925 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5926 | + == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS |
| 5927 | + && crypto_ec_point_y_sqr_weierstrass((mbedtls_ecp_group *)e, |
| 5928 | + (const mbedtls_mpi *)x, |
| 5929 | + y2) == 0) |
| 5930 | + return (struct crypto_bignum *)y2; |
| 5931 | + #endif |
| 5932 | + #if 0 /* not used by hostap */ |
| 5933 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5934 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5935 | + == MBEDTLS_ECP_TYPE_MONTGOMERY |
| 5936 | + && crypto_ec_point_y_sqr_montgomery((mbedtls_ecp_group *)e, |
| 5937 | + (const mbedtls_mpi *)x, |
| 5938 | + y2) == 0) |
| 5939 | + return (struct crypto_bignum *)y2; |
| 5940 | + #endif |
| 5941 | + #endif |
| 5942 | + |
| 5943 | + mbedtls_mpi_free(y2); |
| 5944 | + os_free(y2); |
| 5945 | + return NULL; |
| 5946 | +} |
| 5947 | + |
| 5948 | +int crypto_ec_point_is_at_infinity(struct crypto_ec *e, |
| 5949 | + const struct crypto_ec_point *p) |
| 5950 | +{ |
| 5951 | + return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p); |
| 5952 | +} |
| 5953 | + |
| 5954 | +int crypto_ec_point_is_on_curve(struct crypto_ec *e, |
| 5955 | + const struct crypto_ec_point *p) |
| 5956 | +{ |
| 5957 | + #if 1 |
| 5958 | + return mbedtls_ecp_check_pubkey((const mbedtls_ecp_group *)e, |
| 5959 | + (const mbedtls_ecp_point *)p) == 0; |
| 5960 | + #else |
| 5961 | + /* compute y^2 mod P and compare to y^2 mod P */ |
| 5962 | + /*(ref: src/eap_common/eap_pwd_common.c:compute_password_element())*/ |
| 5963 | + const mbedtls_mpi *px = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); |
| 5964 | + mbedtls_mpi *cy2 = (mbedtls_mpi *) |
| 5965 | + crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *)px); |
| 5966 | + if (cy2 == NULL) |
| 5967 | + return 0; |
| 5968 | + |
| 5969 | + mbedtls_mpi y2; |
| 5970 | + mbedtls_mpi_init(&y2); |
| 5971 | + const mbedtls_mpi *py = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); |
| 5972 | + int is_on_curve = mbedtls_mpi_mul_mpi(&y2, py, py) /* y^2 mod P */ |
| 5973 | + || mbedtls_mpi_mod_mpi(&y2, &y2, CRYPTO_EC_P(e)) |
| 5974 | + || mbedtls_mpi_cmp_mpi(&y2, cy2) != 0 ? 0 : 1; |
| 5975 | + |
| 5976 | + mbedtls_mpi_free(&y2); |
| 5977 | + mbedtls_mpi_free(cy2); |
| 5978 | + os_free(cy2); |
| 5979 | + return is_on_curve; |
| 5980 | + #endif |
| 5981 | +} |
| 5982 | + |
| 5983 | +int crypto_ec_point_cmp(const struct crypto_ec *e, |
| 5984 | + const struct crypto_ec_point *a, |
| 5985 | + const struct crypto_ec_point *b) |
| 5986 | +{ |
| 5987 | + return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *)a, |
| 5988 | + (const mbedtls_ecp_point *)b); |
| 5989 | +} |
| 5990 | + |
| 5991 | +#if !defined(CONFIG_NO_STDOUT_DEBUG) |
| 5992 | +void crypto_ec_point_debug_print(const struct crypto_ec *e, |
| 5993 | + const struct crypto_ec_point *p, |
| 5994 | + const char *title) |
| 5995 | +{ |
| 5996 | + u8 x[MBEDTLS_MPI_MAX_SIZE]; |
| 5997 | + u8 y[MBEDTLS_MPI_MAX_SIZE]; |
| 5998 | + size_t len = CRYPTO_EC_plen(e); |
| 5999 | + /* crypto_ec_point_to_bin ought to take (const struct crypto_ec *e) */ |
| 6000 | + struct crypto_ec *ee; |
| 6001 | + *(const struct crypto_ec **)&ee = e; /*(cast away const)*/ |
| 6002 | + if (crypto_ec_point_to_bin(ee, p, x, y) == 0) { |
| 6003 | + if (title) |
| 6004 | + wpa_printf(MSG_DEBUG, "%s", title); |
| 6005 | + wpa_hexdump(MSG_DEBUG, "x:", x, len); |
| 6006 | + wpa_hexdump(MSG_DEBUG, "y:", y, len); |
| 6007 | + } |
| 6008 | +} |
| 6009 | +#endif |
| 6010 | + |
| 6011 | + |
| 6012 | +struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len) |
| 6013 | +{ |
| 6014 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 6015 | + if (ctx == NULL) |
| 6016 | + return NULL; |
| 6017 | + mbedtls_pk_init(ctx); |
| 6018 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 6019 | + if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0) |
| 6020 | + #else |
| 6021 | + if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, |
| 6022 | + mbedtls_ctr_drbg_random, |
| 6023 | + crypto_mbedtls_ctr_drbg()) == 0) |
| 6024 | + #endif |
| 6025 | + return (struct crypto_ec_key *)ctx; |
| 6026 | + |
| 6027 | + mbedtls_pk_free(ctx); |
| 6028 | + os_free(ctx); |
| 6029 | + return NULL; |
| 6030 | +} |
| 6031 | + |
| 6032 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE |
| 6033 | +#ifdef CONFIG_MODULE_TESTS |
| 6034 | +/*(for crypto_module_tests.c)*/ |
| 6035 | +struct crypto_ec_key * crypto_ec_key_set_priv(int group, |
| 6036 | + const u8 *raw, size_t raw_len) |
| 6037 | +{ |
| 6038 | + mbedtls_ecp_group_id grp_id = |
| 6039 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 6040 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 6041 | + return NULL; |
| 6042 | + const mbedtls_pk_info_t *pk_info = |
| 6043 | + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); |
| 6044 | + if (pk_info == NULL) |
| 6045 | + return NULL; |
| 6046 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 6047 | + if (ctx == NULL) |
| 6048 | + return NULL; |
| 6049 | + mbedtls_pk_init(ctx); |
| 6050 | + if (mbedtls_pk_setup(ctx, pk_info) == 0 |
| 6051 | + && mbedtls_ecp_read_key(grp_id,mbedtls_pk_ec(*ctx),raw,raw_len) == 0) { |
| 6052 | + return (struct crypto_ec_key *)ctx; |
| 6053 | + } |
| 6054 | + |
| 6055 | + mbedtls_pk_free(ctx); |
| 6056 | + os_free(ctx); |
| 6057 | + return NULL; |
| 6058 | +} |
| 6059 | +#endif |
| 6060 | +#endif |
| 6061 | + |
| 6062 | +#include <mbedtls/error.h> |
| 6063 | +#include <mbedtls/oid.h> |
| 6064 | +static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len) |
| 6065 | +{ |
| 6066 | + /* The following is modified from: |
| 6067 | + * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey() |
| 6068 | + * mbedtls/library/pkparse.c:pk_get_pk_alg() |
| 6069 | + * mbedtls/library/pkparse.c:pk_use_ecparams() |
| 6070 | + */ |
| 6071 | + mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; |
| 6072 | + const mbedtls_pk_info_t *pk_info; |
| 6073 | + int ret; |
| 6074 | + size_t len; |
| 6075 | + const unsigned char *end = der+der_len; |
| 6076 | + unsigned char *p; |
| 6077 | + *(const unsigned char **)&p = der; |
| 6078 | + |
| 6079 | + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
| 6080 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
| 6081 | + { |
| 6082 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) ); |
| 6083 | + } |
| 6084 | + |
| 6085 | + end = p + len; |
| 6086 | + |
| 6087 | + /* |
| 6088 | + if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 ) |
| 6089 | + return( ret ); |
| 6090 | + */ |
| 6091 | + mbedtls_asn1_buf alg_oid, params; |
| 6092 | + memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); |
| 6093 | + if( ( ret = mbedtls_asn1_get_alg( &p, end, &alg_oid, ¶ms ) ) != 0 ) |
| 6094 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) ); |
| 6095 | + if( mbedtls_oid_get_pk_alg( &alg_oid, &pk_alg ) != 0 ) |
| 6096 | + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
| 6097 | + |
| 6098 | + if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end, &len ) ) != 0 ) |
| 6099 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) ); |
| 6100 | + |
| 6101 | + if( p + len != end ) |
| 6102 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, |
| 6103 | + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); |
| 6104 | + |
| 6105 | + if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) |
| 6106 | + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
| 6107 | + |
| 6108 | + if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) |
| 6109 | + return( ret ); |
| 6110 | + |
| 6111 | + /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx) |
| 6112 | + * has already run with ctx initialized up to pk_get_ecpubkey(), |
| 6113 | + * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE |
| 6114 | + * |
| 6115 | + * mbedtls mbedtls_ecp_point_read_binary() |
| 6116 | + * does not handle point in COMPRESSED format |
| 6117 | + * |
| 6118 | + * (validate assumption that algorithm is EC) */ |
| 6119 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); |
| 6120 | + if (ecp_kp == NULL) |
| 6121 | + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
| 6122 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6123 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6124 | + mbedtls_ecp_group_id grp_id; |
| 6125 | + |
| 6126 | + |
| 6127 | + /* mbedtls/library/pkparse.c:pk_use_ecparams() */ |
| 6128 | + |
| 6129 | + if( params.tag == MBEDTLS_ASN1_OID ) |
| 6130 | + { |
| 6131 | + if( mbedtls_oid_get_ec_grp( ¶ms, &grp_id ) != 0 ) |
| 6132 | + return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); |
| 6133 | + } |
| 6134 | + else |
| 6135 | + { |
| 6136 | +#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) |
| 6137 | + /*(large code block not copied from mbedtls; unsupported)*/ |
| 6138 | + #if 0 |
| 6139 | + if( ( ret = pk_group_id_from_specified( ¶ms, &grp_id ) ) != 0 ) |
| 6140 | + return( ret ); |
| 6141 | + #endif |
| 6142 | +#endif |
| 6143 | + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
| 6144 | + } |
| 6145 | + |
| 6146 | + /* |
| 6147 | + * grp may already be initialized; if so, make sure IDs match |
| 6148 | + */ |
| 6149 | + if( ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id ) |
| 6150 | + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
| 6151 | + |
| 6152 | + if( ( ret = mbedtls_ecp_group_load( ecp_kp_grp, grp_id ) ) != 0 ) |
| 6153 | + return( ret ); |
| 6154 | + |
| 6155 | + |
| 6156 | + /* (validate assumption that EC point is in COMPRESSED format) */ |
| 6157 | + len = CRYPTO_EC_plen(ecp_kp_grp); |
| 6158 | + if( mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS |
| 6159 | + || (end - p) != 1+len |
| 6160 | + || (*p != 0x02 && *p != 0x03) ) |
| 6161 | + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
| 6162 | + |
| 6163 | + /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call |
| 6164 | + * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */ |
| 6165 | + mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X); |
| 6166 | + mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y); |
| 6167 | + mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z); |
| 6168 | + ret = mbedtls_mpi_lset(Z, 1); |
| 6169 | + if (ret != 0) |
| 6170 | + return( ret ); |
| 6171 | + ret = mbedtls_mpi_read_binary(X, p+1, len); |
| 6172 | + if (ret != 0) |
| 6173 | + return( ret ); |
| 6174 | + /* derive Y |
| 6175 | + * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/ |
| 6176 | + ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/ |
| 6177 | + || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1)); |
| 6178 | + if (ret != 0) |
| 6179 | + return( ret ); |
| 6180 | + |
| 6181 | + return mbedtls_ecp_check_pubkey( ecp_kp_grp, ecp_kp_Q ); |
| 6182 | +} |
| 6183 | + |
| 6184 | +struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len) |
| 6185 | +{ |
| 6186 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 6187 | + if (ctx == NULL) |
| 6188 | + return NULL; |
| 6189 | + mbedtls_pk_init(ctx); |
| 6190 | + /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/ |
| 6191 | + int rc = mbedtls_pk_parse_public_key(ctx, der, der_len); |
| 6192 | + if (rc == 0) |
| 6193 | + return (struct crypto_ec_key *)ctx; |
| 6194 | + else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { |
| 6195 | + /* mbedtls mbedtls_ecp_point_read_binary() |
| 6196 | + * does not handle point in COMPRESSED format; parse internally */ |
| 6197 | + rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx,der,der_len); |
| 6198 | + if (rc == 0) |
| 6199 | + return (struct crypto_ec_key *)ctx; |
| 6200 | + } |
| 6201 | + |
| 6202 | + mbedtls_pk_free(ctx); |
| 6203 | + os_free(ctx); |
| 6204 | + return NULL; |
| 6205 | +} |
| 6206 | + |
| 6207 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6208 | + |
| 6209 | +static struct crypto_ec_key * |
| 6210 | +crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id, |
| 6211 | + const mbedtls_ecp_point *pub, |
| 6212 | + const u8 *buf, size_t len) |
| 6213 | +{ |
| 6214 | + const mbedtls_pk_info_t *pk_info = |
| 6215 | + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); |
| 6216 | + if (pk_info == NULL) |
| 6217 | + return NULL; |
| 6218 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 6219 | + if (ctx == NULL) |
| 6220 | + return NULL; |
| 6221 | + mbedtls_pk_init(ctx); |
| 6222 | + if (mbedtls_pk_setup(ctx, pk_info) == 0) { |
| 6223 | + /* (Is private key generation necessary for callers?) |
| 6224 | + * alt: gen key then overwrite Q |
| 6225 | + * mbedtls_ecp_gen_key(grp_id, ecp_kp, |
| 6226 | + * mbedtls_ctr_drbg_random, |
| 6227 | + * crypto_mbedtls_ctr_drbg()) == 0 |
| 6228 | + */ |
| 6229 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); |
| 6230 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6231 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6232 | + mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); |
| 6233 | + if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 |
| 6234 | + && (pub |
| 6235 | + ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 |
| 6236 | + : mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, |
| 6237 | + buf, len) == 0) |
| 6238 | + && mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, |
| 6239 | + mbedtls_ctr_drbg_random, |
| 6240 | + crypto_mbedtls_ctr_drbg()) == 0){ |
| 6241 | + return (struct crypto_ec_key *)ctx; |
| 6242 | + } |
| 6243 | + } |
| 6244 | + |
| 6245 | + mbedtls_pk_free(ctx); |
| 6246 | + os_free(ctx); |
| 6247 | + return NULL; |
| 6248 | +} |
| 6249 | + |
| 6250 | +struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x, |
| 6251 | + const u8 *y, size_t len) |
| 6252 | +{ |
| 6253 | + mbedtls_ecp_group_id grp_id = |
| 6254 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 6255 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 6256 | + return NULL; |
| 6257 | + if (len > MBEDTLS_MPI_MAX_SIZE) |
| 6258 | + return NULL; |
| 6259 | + u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; |
| 6260 | + buf[0] = 0x04; /* assume x,y for Short Weierstrass */ |
| 6261 | + os_memcpy(buf+1, x, len); |
| 6262 | + os_memcpy(buf+1+len, y, len); |
| 6263 | + |
| 6264 | + return crypto_ec_key_set_pub_point_for_group(grp_id,NULL,buf,1+len*2); |
| 6265 | +} |
| 6266 | + |
| 6267 | +struct crypto_ec_key * |
| 6268 | +crypto_ec_key_set_pub_point(struct crypto_ec *e, |
| 6269 | + const struct crypto_ec_point *pub) |
| 6270 | +{ |
| 6271 | + mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id; |
| 6272 | + mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub; |
| 6273 | + return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0); |
| 6274 | +} |
| 6275 | + |
| 6276 | + |
| 6277 | +struct crypto_ec_key * crypto_ec_key_gen(int group) |
| 6278 | +{ |
| 6279 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 6280 | + if (ctx == NULL) |
| 6281 | + return NULL; |
| 6282 | + mbedtls_pk_init(ctx); |
| 6283 | + if (crypto_mbedtls_keypair_gen(group, ctx) == 0) |
| 6284 | + return (struct crypto_ec_key *)ctx; |
| 6285 | + mbedtls_pk_free(ctx); |
| 6286 | + os_free(ctx); |
| 6287 | + return NULL; |
| 6288 | +} |
| 6289 | + |
| 6290 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6291 | + |
| 6292 | +void crypto_ec_key_deinit(struct crypto_ec_key *key) |
| 6293 | +{ |
| 6294 | + mbedtls_pk_free((mbedtls_pk_context *)key); |
| 6295 | + os_free(key); |
| 6296 | +} |
| 6297 | + |
| 6298 | +struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) |
| 6299 | +{ |
| 6300 | + /* (similar to crypto_ec_key_get_pubkey_point(), |
| 6301 | + * but compressed point format and ASN.1 DER wrapping)*/ |
| 6302 | +#ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ |
| 6303 | +#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) |
| 6304 | +#endif |
| 6305 | + unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES]; |
| 6306 | + int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, |
| 6307 | + buf, sizeof(buf)); |
| 6308 | + if (len < 0) |
| 6309 | + return NULL; |
| 6310 | + /* Note: data is written at the end of the buffer! Use the |
| 6311 | + * return value to determine where you should start |
| 6312 | + * using the buffer */ |
| 6313 | + unsigned char *p = buf+sizeof(buf)-len; |
| 6314 | + |
| 6315 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 6316 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6317 | + if (ecp_kp == NULL) |
| 6318 | + return NULL; |
| 6319 | + mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6320 | + /* Note: sae_pk.c expects pubkey point in compressed format, |
| 6321 | + * but mbedtls_pk_write_pubkey_der() writes uncompressed format. |
| 6322 | + * Manually translate format and update lengths in DER format */ |
| 6323 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 6324 | + unsigned char *end = buf+sizeof(buf); |
| 6325 | + size_t n; |
| 6326 | + /* SubjectPublicKeyInfo SEQUENCE */ |
| 6327 | + mbedtls_asn1_get_tag(&p, end, &n, |
| 6328 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6329 | + /* algorithm AlgorithmIdentifier */ |
| 6330 | + unsigned char *a = p; |
| 6331 | + size_t alen; |
| 6332 | + mbedtls_asn1_get_tag(&p, end, &alen, |
| 6333 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6334 | + p += alen; |
| 6335 | + alen = (size_t)(p - a); |
| 6336 | + /* subjectPublicKey BIT STRING */ |
| 6337 | + mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING); |
| 6338 | + /* rewrite into compressed point format and rebuild ASN.1 */ |
| 6339 | + p[1] = (buf[sizeof(buf)-1] & 1) ? 0x03 : 0x02; |
| 6340 | + n = 1 + 1 + (n-2)/2; |
| 6341 | + len = mbedtls_asn1_write_len(&p, buf, n) + (int)n; |
| 6342 | + len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING); |
| 6343 | + os_memmove(p-alen, a, alen); |
| 6344 | + len += alen; |
| 6345 | + p -= alen; |
| 6346 | + len += mbedtls_asn1_write_len(&p, buf, (size_t)len); |
| 6347 | + len += mbedtls_asn1_write_tag(&p, buf, |
| 6348 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6349 | + } |
| 6350 | + #endif |
| 6351 | + return wpabuf_alloc_copy(p, (size_t)len); |
| 6352 | +} |
| 6353 | + |
| 6354 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6355 | + |
| 6356 | +struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, |
| 6357 | + bool include_pub) |
| 6358 | +{ |
| 6359 | +#ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ |
| 6360 | +#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) |
| 6361 | +#endif |
| 6362 | + unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES]; |
| 6363 | + int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key, |
| 6364 | + priv, sizeof(priv)); |
| 6365 | + if (privlen < 0) |
| 6366 | + return NULL; |
| 6367 | + |
| 6368 | + struct wpabuf *wbuf; |
| 6369 | + |
| 6370 | + /* Note: data is written at the end of the buffer! Use the |
| 6371 | + * return value to determine where you should start |
| 6372 | + * using the buffer */ |
| 6373 | + /* mbedtls_pk_write_key_der() includes publicKey in DER */ |
| 6374 | + if (include_pub) |
| 6375 | + wbuf = wpabuf_alloc_copy(priv+sizeof(priv)-privlen, privlen); |
| 6376 | + else { |
| 6377 | + /* calculate publicKey offset and skip from end of buffer */ |
| 6378 | + unsigned char *p = priv+sizeof(priv)-privlen; |
| 6379 | + unsigned char *end = priv+sizeof(priv); |
| 6380 | + size_t len; |
| 6381 | + /* ECPrivateKey SEQUENCE */ |
| 6382 | + mbedtls_asn1_get_tag(&p, end, &len, |
| 6383 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6384 | + /* version INTEGER */ |
| 6385 | + unsigned char *v = p; |
| 6386 | + mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); |
| 6387 | + p += len; |
| 6388 | + /* privateKey OCTET STRING */ |
| 6389 | + mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); |
| 6390 | + p += len; |
| 6391 | + /* parameters ECParameters */ |
| 6392 | + mbedtls_asn1_get_tag(&p, end, &len, |
| 6393 | + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED); |
| 6394 | + p += len; |
| 6395 | + |
| 6396 | + /* write new SEQUENCE header (we know that it fits in priv[]) */ |
| 6397 | + len = (size_t)(p - v); |
| 6398 | + p = v; |
| 6399 | + len += mbedtls_asn1_write_len(&p, priv, len); |
| 6400 | + len += mbedtls_asn1_write_tag(&p, priv, |
| 6401 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6402 | + wbuf = wpabuf_alloc_copy(p, len); |
| 6403 | + } |
| 6404 | + |
| 6405 | + forced_memzero(priv, sizeof(priv)); |
| 6406 | + return wbuf; |
| 6407 | +} |
| 6408 | + |
| 6409 | +struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, |
| 6410 | + int prefix) |
| 6411 | +{ |
| 6412 | + /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/ |
| 6413 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6414 | + if (ecp_kp == NULL) |
| 6415 | + return NULL; |
| 6416 | + mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6417 | + size_t len = CRYPTO_EC_plen(grp); |
| 6418 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 6419 | + /* len */ |
| 6420 | + #endif |
| 6421 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 6422 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) |
| 6423 | + len = len*2+1; |
| 6424 | + #endif |
| 6425 | + struct wpabuf *buf = wpabuf_alloc(len); |
| 6426 | + if (buf == NULL) |
| 6427 | + return NULL; |
| 6428 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6429 | + if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q, |
| 6430 | + MBEDTLS_ECP_PF_UNCOMPRESSED, &len, |
| 6431 | + wpabuf_mhead_u8(buf), len) == 0) { |
| 6432 | + if (!prefix) /* Remove 0x04 prefix if requested */ |
| 6433 | + os_memmove(wpabuf_mhead(buf),wpabuf_mhead(buf)+1,--len); |
| 6434 | + wpabuf_put(buf, len); |
| 6435 | + return buf; |
| 6436 | + } |
| 6437 | + |
| 6438 | + wpabuf_free(buf); |
| 6439 | + return NULL; |
| 6440 | +} |
| 6441 | + |
| 6442 | +struct crypto_ec_point * |
| 6443 | +crypto_ec_key_get_public_key(struct crypto_ec_key *key) |
| 6444 | +{ |
| 6445 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6446 | + if (ecp_kp == NULL) |
| 6447 | + return NULL; |
| 6448 | + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); |
| 6449 | + if (p != NULL) { |
| 6450 | + /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ |
| 6451 | + mbedtls_ecp_point_init(p); |
| 6452 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6453 | + if (mbedtls_ecp_copy(p, ecp_kp_Q)) { |
| 6454 | + mbedtls_ecp_point_free(p); |
| 6455 | + os_free(p); |
| 6456 | + p = NULL; |
| 6457 | + } |
| 6458 | + } |
| 6459 | + return (struct crypto_ec_point *)p; |
| 6460 | +} |
| 6461 | + |
| 6462 | +struct crypto_bignum * |
| 6463 | +crypto_ec_key_get_private_key(struct crypto_ec_key *key) |
| 6464 | +{ |
| 6465 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6466 | + if (ecp_kp == NULL) |
| 6467 | + return NULL; |
| 6468 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 6469 | + if (bn) { |
| 6470 | + /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ |
| 6471 | + mbedtls_mpi_init(bn); |
| 6472 | + mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); |
| 6473 | + if (mbedtls_mpi_copy(bn, ecp_kp_d)) { |
| 6474 | + mbedtls_mpi_free(bn); |
| 6475 | + os_free(bn); |
| 6476 | + bn = NULL; |
| 6477 | + } |
| 6478 | + } |
| 6479 | + return (struct crypto_bignum *)bn; |
| 6480 | +} |
| 6481 | + |
| 6482 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6483 | + |
| 6484 | +static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len) |
| 6485 | +{ |
| 6486 | + /* get mbedtls_md_type_t from length of hash data to be signed */ |
| 6487 | + switch (len) { |
| 6488 | + case 64: return MBEDTLS_MD_SHA512; |
| 6489 | + case 48: return MBEDTLS_MD_SHA384; |
| 6490 | + case 32: return MBEDTLS_MD_SHA256; |
| 6491 | + case 20: return MBEDTLS_MD_SHA1; |
| 6492 | + case 16: return MBEDTLS_MD_MD5; |
| 6493 | + default: return MBEDTLS_MD_NONE; |
| 6494 | + } |
| 6495 | +} |
| 6496 | + |
| 6497 | +struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, |
| 6498 | + size_t len) |
| 6499 | +{ |
| 6500 | + #ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/ |
| 6501 | + #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE |
| 6502 | + #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN |
| 6503 | + #else |
| 6504 | + #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE |
| 6505 | + #endif |
| 6506 | + #endif |
| 6507 | + size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE; |
| 6508 | + struct wpabuf *buf = wpabuf_alloc(sig_len); |
| 6509 | + if (buf == NULL) |
| 6510 | + return NULL; |
| 6511 | + if (mbedtls_pk_sign((mbedtls_pk_context *)key, |
| 6512 | + crypto_ec_key_sign_md(len), data, len, |
| 6513 | + wpabuf_mhead_u8(buf), |
| 6514 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 6515 | + sig_len, |
| 6516 | + #endif |
| 6517 | + &sig_len, |
| 6518 | + mbedtls_ctr_drbg_random, |
| 6519 | + crypto_mbedtls_ctr_drbg()) == 0) { |
| 6520 | + wpabuf_put(buf, sig_len); |
| 6521 | + return buf; |
| 6522 | + } |
| 6523 | + |
| 6524 | + wpabuf_free(buf); |
| 6525 | + return NULL; |
| 6526 | +} |
| 6527 | + |
| 6528 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6529 | +struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key, |
| 6530 | + const u8 *data, size_t len) |
| 6531 | +{ |
| 6532 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6533 | + if (ecp_kp == NULL) |
| 6534 | + return NULL; |
| 6535 | + |
| 6536 | + size_t sig_len = MBEDTLS_ECDSA_MAX_LEN; |
| 6537 | + u8 buf[MBEDTLS_ECDSA_MAX_LEN]; |
| 6538 | + if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len), |
| 6539 | + data, len, buf, |
| 6540 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 6541 | + sig_len, |
| 6542 | + #endif |
| 6543 | + &sig_len, |
| 6544 | + mbedtls_ctr_drbg_random, |
| 6545 | + crypto_mbedtls_ctr_drbg())) { |
| 6546 | + return NULL; |
| 6547 | + } |
| 6548 | + |
| 6549 | + /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/ |
| 6550 | + /* parse ASN.1 to get r and s and lengths */ |
| 6551 | + u8 *p = buf, *r, *s; |
| 6552 | + u8 *end = p + sig_len; |
| 6553 | + size_t rlen, slen; |
| 6554 | + mbedtls_asn1_get_tag(&p, end, &rlen, |
| 6555 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6556 | + mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER); |
| 6557 | + r = p; |
| 6558 | + p += rlen; |
| 6559 | + mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER); |
| 6560 | + s = p; |
| 6561 | + |
| 6562 | + /* write raw r and s into out |
| 6563 | + * (including removal of leading 0 if added for ASN.1 integer) |
| 6564 | + * note: DPP caller expects raw r, s each padded to prime len */ |
| 6565 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6566 | + size_t plen = CRYPTO_EC_plen(ecp_kp_grp); |
| 6567 | + if (rlen > plen) { |
| 6568 | + r += (rlen - plen); |
| 6569 | + rlen = plen; |
| 6570 | + } |
| 6571 | + if (slen > plen) { |
| 6572 | + s += (slen - plen); |
| 6573 | + slen = plen; |
| 6574 | + } |
| 6575 | + struct wpabuf *out = wpabuf_alloc(plen*2); |
| 6576 | + if (out) { |
| 6577 | + wpabuf_put(out, plen*2); |
| 6578 | + p = wpabuf_mhead_u8(out); |
| 6579 | + os_memset(p, 0, plen*2); |
| 6580 | + os_memcpy(p+plen*1-rlen, r, rlen); |
| 6581 | + os_memcpy(p+plen*2-slen, s, slen); |
| 6582 | + } |
| 6583 | + return out; |
| 6584 | +} |
| 6585 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6586 | + |
| 6587 | +int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, |
| 6588 | + size_t len, const u8 *sig, size_t sig_len) |
| 6589 | +{ |
| 6590 | + switch (mbedtls_pk_verify((mbedtls_pk_context *)key, |
| 6591 | + crypto_ec_key_sign_md(len), data, len, |
| 6592 | + sig, sig_len)) { |
| 6593 | + case 0: |
| 6594 | + /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ |
| 6595 | + return 1; |
| 6596 | + case MBEDTLS_ERR_ECP_VERIFY_FAILED: |
| 6597 | + return 0; |
| 6598 | + default: |
| 6599 | + return -1; |
| 6600 | + } |
| 6601 | +} |
| 6602 | + |
| 6603 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6604 | +int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key, |
| 6605 | + const u8 *data, size_t len, |
| 6606 | + const u8 *r, size_t r_len, |
| 6607 | + const u8 *s, size_t s_len) |
| 6608 | +{ |
| 6609 | + /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s |
| 6610 | + * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */ |
| 6611 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6612 | + if (ecp_kp == NULL) |
| 6613 | + return -1; |
| 6614 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6615 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6616 | + |
| 6617 | + mbedtls_mpi mpi_r; |
| 6618 | + mbedtls_mpi mpi_s; |
| 6619 | + mbedtls_mpi_init(&mpi_r); |
| 6620 | + mbedtls_mpi_init(&mpi_s); |
| 6621 | + int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len) |
| 6622 | + || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0; |
| 6623 | + if (ret == 0) { |
| 6624 | + ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len, |
| 6625 | + ecp_kp_Q, &mpi_r, &mpi_s); |
| 6626 | + ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1; |
| 6627 | + } |
| 6628 | + mbedtls_mpi_free(&mpi_r); |
| 6629 | + mbedtls_mpi_free(&mpi_s); |
| 6630 | + return ret; |
| 6631 | +} |
| 6632 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6633 | + |
| 6634 | +int crypto_ec_key_group(struct crypto_ec_key *key) |
| 6635 | +{ |
| 6636 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6637 | + if (ecp_kp == NULL) |
| 6638 | + return -1; |
| 6639 | + mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6640 | + return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id); |
| 6641 | +} |
| 6642 | + |
| 6643 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6644 | + |
| 6645 | +int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2) |
| 6646 | +{ |
| 6647 | +#if 0 /*(DPP is passing two public keys; unable to use pk_check_pair())*/ |
| 6648 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 6649 | + return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, |
| 6650 | + (const mbedtls_pk_context *)key2) ? -1 : 0; |
| 6651 | + #else |
| 6652 | + return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, |
| 6653 | + (const mbedtls_pk_context *)key2, |
| 6654 | + mbedtls_ctr_drbg_random, |
| 6655 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 6656 | + #endif |
| 6657 | +#else |
| 6658 | + mbedtls_ecp_keypair *ecp_kp1=mbedtls_pk_ec(*(mbedtls_pk_context *)key1); |
| 6659 | + mbedtls_ecp_keypair *ecp_kp2=mbedtls_pk_ec(*(mbedtls_pk_context *)key2); |
| 6660 | + if (ecp_kp1 == NULL || ecp_kp2 == NULL) |
| 6661 | + return -1; |
| 6662 | + mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp); |
| 6663 | + mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp); |
| 6664 | + mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q); |
| 6665 | + mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q); |
| 6666 | + return ecp_kp1_grp->id != ecp_kp2_grp->id |
| 6667 | + || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0; |
| 6668 | +#endif |
| 6669 | +} |
| 6670 | + |
| 6671 | +void crypto_ec_key_debug_print(const struct crypto_ec_key *key, |
| 6672 | + const char *title) |
| 6673 | +{ |
| 6674 | + /* TBD: what info is desirable here and in what human readable format?*/ |
| 6675 | + /*(crypto_openssl.c prints a human-readably public key and attributes)*/ |
| 6676 | + #if 0 |
| 6677 | + struct mbedtls_pk_debug_item debug_item; |
| 6678 | + if (mbedtls_pk_debug((const mbedtls_pk_context *)key, &debug_item)) |
| 6679 | + return; |
| 6680 | + /* ... */ |
| 6681 | + #endif |
| 6682 | + wpa_printf(MSG_DEBUG, "%s: %s not implemented", title, __func__); |
| 6683 | +} |
| 6684 | + |
| 6685 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6686 | + |
| 6687 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC */ |
| 6688 | + |
| 6689 | + |
| 6690 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_CSR |
| 6691 | + |
| 6692 | +#include <mbedtls/x509_csr.h> |
| 6693 | +#include <mbedtls/oid.h> |
| 6694 | + |
| 6695 | +struct crypto_csr * crypto_csr_init(void) |
| 6696 | +{ |
| 6697 | + mbedtls_x509write_csr *csr = os_malloc(sizeof(*csr)); |
| 6698 | + if (csr != NULL) |
| 6699 | + mbedtls_x509write_csr_init(csr); |
| 6700 | + return (struct crypto_csr *)csr; |
| 6701 | +} |
| 6702 | + |
| 6703 | +struct crypto_csr * crypto_csr_verify(const struct wpabuf *req) |
| 6704 | +{ |
| 6705 | + /* future: look for alternatives to MBEDTLS_PRIVATE() access */ |
| 6706 | + |
| 6707 | + /* sole caller src/common/dpp_crypto.c:dpp_validate_csr() |
| 6708 | + * uses (mbedtls_x509_csr *) to obtain CSR_ATTR_CHALLENGE_PASSWORD |
| 6709 | + * so allocate different object (mbedtls_x509_csr *) and special-case |
| 6710 | + * object when used in crypto_csr_get_attribute() and when free()d in |
| 6711 | + * crypto_csr_deinit(). */ |
| 6712 | + |
| 6713 | + mbedtls_x509_csr *csr = os_malloc(sizeof(*csr)); |
| 6714 | + if (csr == NULL) |
| 6715 | + return NULL; |
| 6716 | + mbedtls_x509_csr_init(csr); |
| 6717 | + const mbedtls_md_info_t *md_info; |
| 6718 | + unsigned char digest[MBEDTLS_MD_MAX_SIZE]; |
| 6719 | + if (mbedtls_x509_csr_parse_der(csr,wpabuf_head(req),wpabuf_len(req))==0 |
| 6720 | + && (md_info=mbedtls_md_info_from_type(csr->MBEDTLS_PRIVATE(sig_md))) |
| 6721 | + != NULL |
| 6722 | + && mbedtls_md(md_info, csr->cri.p, csr->cri.len, digest) == 0) { |
| 6723 | + switch (mbedtls_pk_verify(&csr->pk,csr->MBEDTLS_PRIVATE(sig_md), |
| 6724 | + digest, mbedtls_md_get_size(md_info), |
| 6725 | + csr->MBEDTLS_PRIVATE(sig).p, |
| 6726 | + csr->MBEDTLS_PRIVATE(sig).len)) { |
| 6727 | + case 0: |
| 6728 | + /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ |
| 6729 | + return (struct crypto_csr *)((uintptr_t)csr | 1uL); |
| 6730 | + default: |
| 6731 | + break; |
| 6732 | + } |
| 6733 | + } |
| 6734 | + |
| 6735 | + mbedtls_x509_csr_free(csr); |
| 6736 | + os_free(csr); |
| 6737 | + return NULL; |
| 6738 | +} |
| 6739 | + |
| 6740 | +void crypto_csr_deinit(struct crypto_csr *csr) |
| 6741 | +{ |
| 6742 | + if ((uintptr_t)csr & 1uL) { |
| 6743 | + csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); |
| 6744 | + mbedtls_x509_csr_free((mbedtls_x509_csr *)csr); |
| 6745 | + } |
| 6746 | + else |
| 6747 | + mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr); |
| 6748 | + os_free(csr); |
| 6749 | +} |
| 6750 | + |
| 6751 | +int crypto_csr_set_ec_public_key(struct crypto_csr *csr, |
| 6752 | + struct crypto_ec_key *key) |
| 6753 | +{ |
| 6754 | + mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr, |
| 6755 | + (mbedtls_pk_context *)key); |
| 6756 | + return 0; |
| 6757 | +} |
| 6758 | + |
| 6759 | +int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type, |
| 6760 | + const char *name) |
| 6761 | +{ |
| 6762 | + /* specialized for src/common/dpp_crypto.c */ |
| 6763 | + |
| 6764 | + /* sole caller src/common/dpp_crypto.c:dpp_build_csr() |
| 6765 | + * calls this function only once, using type == CSR_NAME_CN |
| 6766 | + * (If called more than once, this code would need to append |
| 6767 | + * components to the subject name, which we could do by |
| 6768 | + * appending to (mbedtls_x509write_csr *) private member |
| 6769 | + * mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject)) */ |
| 6770 | + |
| 6771 | + const char *label; |
| 6772 | + switch (type) { |
| 6773 | + case CSR_NAME_CN: label = "CN="; break; |
| 6774 | + case CSR_NAME_SN: label = "SN="; break; |
| 6775 | + case CSR_NAME_C: label = "C="; break; |
| 6776 | + case CSR_NAME_O: label = "O="; break; |
| 6777 | + case CSR_NAME_OU: label = "OU="; break; |
| 6778 | + default: return -1; |
| 6779 | + } |
| 6780 | + |
| 6781 | + size_t len = strlen(name); |
| 6782 | + struct wpabuf *buf = wpabuf_alloc(3+len+1); |
| 6783 | + if (buf == NULL) |
| 6784 | + return -1; |
| 6785 | + wpabuf_put_data(buf, label, strlen(label)); |
| 6786 | + wpabuf_put_data(buf, name, len+1); /*(include trailing '\0')*/ |
| 6787 | + /* Note: 'name' provided is set as given and should be backslash-escaped |
| 6788 | + * by caller when necessary, e.g. literal ',' which are not separating |
| 6789 | + * components should be backslash-escaped */ |
| 6790 | + |
| 6791 | + int ret = |
| 6792 | + mbedtls_x509write_csr_set_subject_name((mbedtls_x509write_csr *)csr, |
| 6793 | + wpabuf_head(buf)) ? -1 : 0; |
| 6794 | + wpabuf_free(buf); |
| 6795 | + return ret; |
| 6796 | +} |
| 6797 | + |
| 6798 | +/* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ |
| 6799 | +static const char OBJ_pkcs9_challengePassword[] = MBEDTLS_OID_PKCS9 "\x07"; |
| 6800 | + |
| 6801 | +int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr, |
| 6802 | + int attr_type, const u8 *value, size_t len) |
| 6803 | +{ |
| 6804 | + /* specialized for src/common/dpp_crypto.c */ |
| 6805 | + /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes |
| 6806 | + * attr == CSR_ATTR_CHALLENGE_PASSWORD |
| 6807 | + * attr_type == ASN1_TAG_UTF8STRING */ |
| 6808 | + |
| 6809 | + const char *oid; |
| 6810 | + size_t oid_len; |
| 6811 | + switch (attr) { |
| 6812 | + case CSR_ATTR_CHALLENGE_PASSWORD: |
| 6813 | + oid = OBJ_pkcs9_challengePassword; |
| 6814 | + oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; |
| 6815 | + break; |
| 6816 | + default: |
| 6817 | + return -1; |
| 6818 | + } |
| 6819 | + |
| 6820 | + #if 0 /*(incorrect; sets an extension, not an attribute)*/ |
| 6821 | + return mbedtls_x509write_csr_set_extension((mbedtls_x509write_csr *)csr, |
| 6822 | + oid, oid_len, |
| 6823 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 6824 | + 0, /*(critical flag)*/ |
| 6825 | + #endif |
| 6826 | + value, len) ? -1 : 0; |
| 6827 | + #else |
| 6828 | + (void)oid; |
| 6829 | + (void)oid_len; |
| 6830 | + #endif |
| 6831 | + |
| 6832 | + /* mbedtls does not currently provide way to set an attribute in a CSR: |
| 6833 | + * https://github.com/Mbed-TLS/mbedtls/issues/4886 */ |
| 6834 | + wpa_printf(MSG_ERROR, |
| 6835 | + "mbedtls does not currently support setting challengePassword " |
| 6836 | + "attribute in CSR"); |
| 6837 | + return -1; |
| 6838 | +} |
| 6839 | + |
| 6840 | +const u8 * mbedtls_x509_csr_attr_oid_value(mbedtls_x509_csr *csr, |
| 6841 | + const char *oid, size_t oid_len, |
| 6842 | + size_t *vlen, int *vtype) |
| 6843 | +{ |
| 6844 | + /* Note: mbedtls_x509_csr_parse_der() has parsed and validated CSR, |
| 6845 | + * so validation checks are not repeated here |
| 6846 | + * |
| 6847 | + * It would be nicer if (mbedtls_x509_csr *) had an mbedtls_x509_buf of |
| 6848 | + * Attributes (or at least a pointer) since mbedtls_x509_csr_parse_der() |
| 6849 | + * already parsed the rest of CertificationRequestInfo, some of which is |
| 6850 | + * repeated here to step to Attributes. Since csr->subject_raw.p points |
| 6851 | + * into csr->cri.p, which points into csr->raw.p, step over version and |
| 6852 | + * subject of CertificationRequestInfo (SEQUENCE) */ |
| 6853 | + unsigned char *p = csr->subject_raw.p + csr->subject_raw.len; |
| 6854 | + unsigned char *end = csr->cri.p + csr->cri.len, *ext; |
| 6855 | + size_t len; |
| 6856 | + |
| 6857 | + /* step over SubjectPublicKeyInfo */ |
| 6858 | + mbedtls_asn1_get_tag(&p, end, &len, |
| 6859 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6860 | + p += len; |
| 6861 | + |
| 6862 | + /* Attributes |
| 6863 | + * { ATTRIBUTE:IOSet } ::= SET OF { SEQUENCE { OID, value } } |
| 6864 | + */ |
| 6865 | + if (mbedtls_asn1_get_tag(&p, end, &len, |
| 6866 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) { |
| 6867 | + return NULL; |
| 6868 | + } |
| 6869 | + while (p < end) { |
| 6870 | + if (mbedtls_asn1_get_tag(&p, end, &len, |
| 6871 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) { |
| 6872 | + return NULL; |
| 6873 | + } |
| 6874 | + ext = p; |
| 6875 | + p += len; |
| 6876 | + |
| 6877 | + if (mbedtls_asn1_get_tag(&ext,end,&len,MBEDTLS_ASN1_OID) != 0) |
| 6878 | + return NULL; |
| 6879 | + if (oid_len != len || 0 != memcmp(ext, oid, oid_len)) |
| 6880 | + continue; |
| 6881 | + |
| 6882 | + /* found oid; return value */ |
| 6883 | + *vtype = *ext++; /* tag */ |
| 6884 | + return (mbedtls_asn1_get_len(&ext,end,vlen) == 0) ? ext : NULL; |
| 6885 | + } |
| 6886 | + |
| 6887 | + return NULL; |
| 6888 | +} |
| 6889 | + |
| 6890 | +const u8 * crypto_csr_get_attribute(struct crypto_csr *csr, |
| 6891 | + enum crypto_csr_attr attr, |
| 6892 | + size_t *len, int *type) |
| 6893 | +{ |
| 6894 | + /* specialized for src/common/dpp_crypto.c */ |
| 6895 | + /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes |
| 6896 | + * attr == CSR_ATTR_CHALLENGE_PASSWORD */ |
| 6897 | + |
| 6898 | + const char *oid; |
| 6899 | + size_t oid_len; |
| 6900 | + switch (attr) { |
| 6901 | + case CSR_ATTR_CHALLENGE_PASSWORD: |
| 6902 | + oid = OBJ_pkcs9_challengePassword; |
| 6903 | + oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; |
| 6904 | + break; |
| 6905 | + default: |
| 6906 | + return NULL; |
| 6907 | + } |
| 6908 | + |
| 6909 | + /* see crypto_csr_verify(); expecting (mbedtls_x509_csr *) tagged |=1 */ |
| 6910 | + if (!((uintptr_t)csr & 1uL)) |
| 6911 | + return NULL; |
| 6912 | + csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); |
| 6913 | + |
| 6914 | + return mbedtls_x509_csr_attr_oid_value((mbedtls_x509_csr *)csr, |
| 6915 | + oid, oid_len, len, type); |
| 6916 | +} |
| 6917 | + |
| 6918 | +struct wpabuf * crypto_csr_sign(struct crypto_csr *csr, |
| 6919 | + struct crypto_ec_key *key, |
| 6920 | + enum crypto_hash_alg algo) |
| 6921 | +{ |
| 6922 | + mbedtls_md_type_t sig_md; |
| 6923 | + switch (algo) { |
| 6924 | + #ifdef MBEDTLS_SHA256_C |
| 6925 | + case CRYPTO_HASH_ALG_SHA256: sig_md = MBEDTLS_MD_SHA256; break; |
| 6926 | + #endif |
| 6927 | + #ifdef MBEDTLS_SHA512_C |
| 6928 | + case CRYPTO_HASH_ALG_SHA384: sig_md = MBEDTLS_MD_SHA384; break; |
| 6929 | + case CRYPTO_HASH_ALG_SHA512: sig_md = MBEDTLS_MD_SHA512; break; |
| 6930 | + #endif |
| 6931 | + default: |
| 6932 | + return NULL; |
| 6933 | + } |
| 6934 | + mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md); |
| 6935 | + |
| 6936 | + #if 0 |
| 6937 | + unsigned char key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
| 6938 | + | MBEDTLS_X509_KU_KEY_CERT_SIGN; |
| 6939 | + if (mbedtls_x509write_csr_set_key_usage((mbedtls_x509write_csr *)csr, |
| 6940 | + key_usage)) |
| 6941 | + return NULL; |
| 6942 | + #endif |
| 6943 | + |
| 6944 | + #if 0 |
| 6945 | + unsigned char ns_cert_type = MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT |
| 6946 | + | MBEDTLS_X509_NS_CERT_TYPE_EMAIL; |
| 6947 | + if (mbedtls_x509write_csr_set_ns_cert_type((mbedtls_x509write_csr *)csr, |
| 6948 | + ns_cert_type)) |
| 6949 | + return NULL; |
| 6950 | + #endif |
| 6951 | + |
| 6952 | + #if 0 |
| 6953 | + /* mbedtls does not currently provide way to set an attribute in a CSR: |
| 6954 | + * https://github.com/Mbed-TLS/mbedtls/issues/4886 |
| 6955 | + * XXX: hwsim dpp_enterprise test fails due to this limitation. |
| 6956 | + * |
| 6957 | + * Current usage of this function is solely by dpp_build_csr(), |
| 6958 | + * so as a kludge, might consider custom (struct crypto_csr *) |
| 6959 | + * containing (mbedtls_x509write_csr *) and a list of attributes |
| 6960 | + * (i.e. challengePassword). Might have to totally reimplement |
| 6961 | + * mbedtls_x509write_csr_der(); underlying x509write_csr_der_internal() |
| 6962 | + * handles signing the CSR. (This is more work that appending an |
| 6963 | + * Attributes section to end of CSR and adjusting ASN.1 length of CSR.) |
| 6964 | + */ |
| 6965 | + #endif |
| 6966 | + |
| 6967 | + unsigned char buf[4096]; /* XXX: large enough? too large? */ |
| 6968 | + int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, |
| 6969 | + buf, sizeof(buf), |
| 6970 | + mbedtls_ctr_drbg_random, |
| 6971 | + crypto_mbedtls_ctr_drbg()); |
| 6972 | + if (len < 0) |
| 6973 | + return NULL; |
| 6974 | + /* Note: data is written at the end of the buffer! Use the |
| 6975 | + * return value to determine where you should start |
| 6976 | + * using the buffer */ |
| 6977 | + return wpabuf_alloc_copy(buf+sizeof(buf)-len, (size_t)len); |
| 6978 | +} |
| 6979 | + |
| 6980 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_CSR */ |
| 6981 | + |
| 6982 | + |
| 6983 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_PKCS7 |
| 6984 | + |
| 6985 | +#if 0 |
| 6986 | +#include <mbedtls/pkcs7.h> /* PKCS7 is not currently supported in mbedtls */ |
| 6987 | +#include <mbedtls/pem.h> |
| 6988 | +#endif |
| 6989 | + |
| 6990 | +struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7) |
| 6991 | +{ |
| 6992 | + /* PKCS7 is not currently supported in mbedtls */ |
| 6993 | + return NULL; |
| 6994 | + |
| 6995 | +#if 0 |
| 6996 | + /* https://github.com/naynajain/mbedtls-1 branch: development-pkcs7 |
| 6997 | + * (??? potential future contribution to mbedtls ???) */ |
| 6998 | + |
| 6999 | + /* Note: PKCS7 signature *is not* verified by this function. |
| 7000 | + * The function interface does not provide for passing a certificate */ |
| 7001 | + |
| 7002 | + mbedtls_pkcs7 mpkcs7; |
| 7003 | + mbedtls_pkcs7_init(&mpkcs7); |
| 7004 | + int pkcs7_type = mbedtls_pkcs7_parse_der(wpabuf_head(pkcs7), |
| 7005 | + wpabuf_len(pkcs7), |
| 7006 | + &mpkcs7); |
| 7007 | + wpabuf *buf = NULL; |
| 7008 | + do { |
| 7009 | + if (pkcs7_type < 0) |
| 7010 | + break; |
| 7011 | + |
| 7012 | + /* src/common/dpp.c:dpp_parse_cred_dot1x() interested in certs |
| 7013 | + * for wpa_supplicant/dpp_supplicant.c:wpas_dpp_add_network() |
| 7014 | + * (? are adding certificate headers and footers desired ?) */ |
| 7015 | + |
| 7016 | + /* development-pkcs7 branch does not currently provide |
| 7017 | + * additional interfaces to retrieve the parsed data */ |
| 7018 | + |
| 7019 | + mbedtls_x509_crt *certs = |
| 7020 | + &mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(certs); |
| 7021 | + int ncerts = |
| 7022 | + mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(no_of_certs); |
| 7023 | + |
| 7024 | + /* allocate buffer for PEM (base64-encoded DER) |
| 7025 | + * plus header, footer, newlines, and some extra */ |
| 7026 | + buf = wpabuf_alloc((wpabuf_len(pkcs7)+2)/3*4 + ncerts*64); |
| 7027 | + if (buf == NULL) |
| 7028 | + break; |
| 7029 | + |
| 7030 | + #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" |
| 7031 | + #define PEM_END_CRT "-----END CERTIFICATE-----\n" |
| 7032 | + size_t olen; |
| 7033 | + for (int i = 0; i < ncerts; ++i) { |
| 7034 | + int ret = mbedtls_pem_write_buffer( |
| 7035 | + PEM_BEGIN_CRT, PEM_END_CRT, |
| 7036 | + certs[i].raw.p, certs[i].raw.len, |
| 7037 | + wpabuf_mhead(buf, 0), wpabuf_tailroom(buf), |
| 7038 | + &olen)); |
| 7039 | + if (ret == 0) |
| 7040 | + wpabuf_put(buf, olen); |
| 7041 | + } else { |
| 7042 | + if (ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) |
| 7043 | + ret = wpabuf_resize( |
| 7044 | + &buf,olen-wpabuf_tailroom(buf)); |
| 7045 | + if (ret == 0) { |
| 7046 | + --i;/*(adjust loop iterator for retry)*/ |
| 7047 | + continue; |
| 7048 | + } |
| 7049 | + wpabuf_free(buf); |
| 7050 | + buf = NULL; |
| 7051 | + break; |
| 7052 | + } |
| 7053 | + } |
| 7054 | + } while (0); |
| 7055 | + |
| 7056 | + mbedtls_pkcs7_free(&mpkcs7); |
| 7057 | + return buf; |
| 7058 | +#endif |
| 7059 | +} |
| 7060 | + |
| 7061 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_PKCS7 */ |
| 7062 | + |
| 7063 | + |
| 7064 | +#ifdef MBEDTLS_ARC4_C |
| 7065 | +#include <mbedtls/arc4.h> |
| 7066 | +int rc4_skip(const u8 *key, size_t keylen, size_t skip, |
| 7067 | + u8 *data, size_t data_len) |
| 7068 | +{ |
| 7069 | + mbedtls_arc4_context ctx; |
| 7070 | + mbedtls_arc4_init(&ctx); |
| 7071 | + mbedtls_arc4_setup(&ctx, key, keylen); |
| 7072 | + |
| 7073 | + if (skip) { |
| 7074 | + /*(prefer [16] on ancient hardware with smaller cache lines)*/ |
| 7075 | + unsigned char skip_buf[64]; /*('skip' is generally small)*/ |
| 7076 | + /*os_memset(skip_buf, 0, sizeof(skip_buf));*/ /*(necessary?)*/ |
| 7077 | + size_t len; |
| 7078 | + do { |
| 7079 | + len = skip > sizeof(skip_buf) ? sizeof(skip_buf) : skip; |
| 7080 | + mbedtls_arc4_crypt(&ctx, len, skip_buf, skip_buf); |
| 7081 | + } while ((skip -= len)); |
| 7082 | + } |
| 7083 | + |
| 7084 | + int ret = mbedtls_arc4_crypt(&ctx, data_len, data, data); |
| 7085 | + mbedtls_arc4_free(&ctx); |
| 7086 | + return ret; |
| 7087 | +} |
| 7088 | +#endif |
| 7089 | + |
| 7090 | + |
| 7091 | +/* duplicated in tls_mbedtls.c:tls_mbedtls_readfile()*/ |
| 7092 | +__attribute_noinline__ |
| 7093 | +static int crypto_mbedtls_readfile(const char *path, u8 **buf, size_t *n) |
| 7094 | +{ |
| 7095 | + #if 0 /* #ifdef MBEDTLS_FS_IO */ |
| 7096 | + /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ |
| 7097 | + if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { |
| 7098 | + wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); |
| 7099 | + return -1; |
| 7100 | + } |
| 7101 | + #else |
| 7102 | + /*(use os_readfile() so that we can use os_free() |
| 7103 | + *(if we use mbedtls_pk_load_file() above, macros prevent calling free() |
| 7104 | + * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() |
| 7105 | + * on buf aborts in tests if buf not allocated via os_malloc())*/ |
| 7106 | + *buf = (u8 *)os_readfile(path, n); |
| 7107 | + if (!*buf) { |
| 7108 | + wpa_printf(MSG_ERROR, "error: os_readfile %s", path); |
| 7109 | + return -1; |
| 7110 | + } |
| 7111 | + u8 *buf0 = os_realloc(*buf, *n+1); |
| 7112 | + if (!buf0) { |
| 7113 | + bin_clear_free(*buf, *n); |
| 7114 | + *buf = NULL; |
| 7115 | + return -1; |
| 7116 | + } |
| 7117 | + buf0[(*n)++] = '\0'; |
| 7118 | + *buf = buf0; |
| 7119 | + #endif |
| 7120 | + return 0; |
| 7121 | +} |
| 7122 | + |
| 7123 | + |
| 7124 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_RSA |
| 7125 | +#ifdef MBEDTLS_RSA_C |
| 7126 | + |
| 7127 | +#include <mbedtls/pk.h> |
| 7128 | +#include <mbedtls/rsa.h> |
| 7129 | + |
| 7130 | +struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key) |
| 7131 | +{ |
| 7132 | + /* mbedtls_pk_parse_keyfile() and mbedtls_pk_parse_public_keyfile() |
| 7133 | + * require #ifdef MBEDTLS_FS_IO in mbedtls library. Prefer to use |
| 7134 | + * crypto_mbedtls_readfile(), which wraps os_readfile() */ |
| 7135 | + u8 *data; |
| 7136 | + size_t len; |
| 7137 | + if (crypto_mbedtls_readfile(file, &data, &len) != 0) |
| 7138 | + return NULL; |
| 7139 | + |
| 7140 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 7141 | + if (ctx == NULL) { |
| 7142 | + bin_clear_free(data, len); |
| 7143 | + return NULL; |
| 7144 | + } |
| 7145 | + mbedtls_pk_init(ctx); |
| 7146 | + |
| 7147 | + int rc; |
| 7148 | + rc = (private_key |
| 7149 | + ? mbedtls_pk_parse_key(ctx, data, len, NULL, 0 |
| 7150 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 7151 | + ,mbedtls_ctr_drbg_random, |
| 7152 | + crypto_mbedtls_ctr_drbg() |
| 7153 | + #endif |
| 7154 | + ) |
| 7155 | + : mbedtls_pk_parse_public_key(ctx, data, len)) == 0 |
| 7156 | + && mbedtls_pk_can_do(ctx, MBEDTLS_PK_RSA); |
| 7157 | + |
| 7158 | + bin_clear_free(data, len); |
| 7159 | + |
| 7160 | + if (rc) { |
| 7161 | + /* use MBEDTLS_RSA_PKCS_V21 padding for RSAES-OAEP */ |
| 7162 | + /* use MBEDTLS_MD_SHA256 for these hostap interfaces */ |
| 7163 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 7164 | + /*(no return value in mbedtls 2.x)*/ |
| 7165 | + mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), |
| 7166 | + MBEDTLS_RSA_PKCS_V21, |
| 7167 | + MBEDTLS_MD_SHA256); |
| 7168 | + #else |
| 7169 | + if (mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), |
| 7170 | + MBEDTLS_RSA_PKCS_V21, |
| 7171 | + MBEDTLS_MD_SHA256) == 0) |
| 7172 | + #endif |
| 7173 | + return (struct crypto_rsa_key *)ctx; |
| 7174 | + } |
| 7175 | + |
| 7176 | + mbedtls_pk_free(ctx); |
| 7177 | + os_free(ctx); |
| 7178 | + return NULL; |
| 7179 | +} |
| 7180 | + |
| 7181 | +struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key, |
| 7182 | + const struct wpabuf *in) |
| 7183 | +{ |
| 7184 | + mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); |
| 7185 | + size_t olen = mbedtls_rsa_get_len(pk_rsa); |
| 7186 | + struct wpabuf *buf = wpabuf_alloc(olen); |
| 7187 | + if (buf == NULL) |
| 7188 | + return NULL; |
| 7189 | + |
| 7190 | + /* mbedtls_pk_encrypt() takes a few more hops to get to same func */ |
| 7191 | + if (mbedtls_rsa_rsaes_oaep_encrypt(pk_rsa, |
| 7192 | + mbedtls_ctr_drbg_random, |
| 7193 | + crypto_mbedtls_ctr_drbg(), |
| 7194 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 7195 | + MBEDTLS_RSA_PRIVATE, |
| 7196 | + #endif |
| 7197 | + NULL, 0, |
| 7198 | + wpabuf_len(in), wpabuf_head(in), |
| 7199 | + wpabuf_put(buf, olen)) == 0) { |
| 7200 | + return buf; |
| 7201 | + } |
| 7202 | + |
| 7203 | + wpabuf_clear_free(buf); |
| 7204 | + return NULL; |
| 7205 | +} |
| 7206 | + |
| 7207 | +struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key, |
| 7208 | + const struct wpabuf *in) |
| 7209 | +{ |
| 7210 | + mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); |
| 7211 | + size_t olen = mbedtls_rsa_get_len(pk_rsa); |
| 7212 | + struct wpabuf *buf = wpabuf_alloc(olen); |
| 7213 | + if (buf == NULL) |
| 7214 | + return NULL; |
| 7215 | + |
| 7216 | + /* mbedtls_pk_decrypt() takes a few more hops to get to same func */ |
| 7217 | + if (mbedtls_rsa_rsaes_oaep_decrypt(pk_rsa, |
| 7218 | + mbedtls_ctr_drbg_random, |
| 7219 | + crypto_mbedtls_ctr_drbg(), |
| 7220 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 7221 | + MBEDTLS_RSA_PUBLIC, |
| 7222 | + #endif |
| 7223 | + NULL, 0, &olen, wpabuf_head(in), |
| 7224 | + wpabuf_mhead(buf), olen) == 0) { |
| 7225 | + wpabuf_put(buf, olen); |
| 7226 | + return buf; |
| 7227 | + } |
| 7228 | + |
| 7229 | + wpabuf_clear_free(buf); |
| 7230 | + return NULL; |
| 7231 | +} |
| 7232 | + |
| 7233 | +void crypto_rsa_key_free(struct crypto_rsa_key *key) |
| 7234 | +{ |
| 7235 | + mbedtls_pk_free((mbedtls_pk_context *)key); |
| 7236 | + os_free(key); |
| 7237 | +} |
| 7238 | + |
| 7239 | +#endif /* MBEDTLS_RSA_C */ |
| 7240 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_RSA */ |
| 7241 | + |
| 7242 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE |
| 7243 | + |
| 7244 | +struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id, |
| 7245 | + enum hpke_kdf_id kdf_id, |
| 7246 | + enum hpke_aead_id aead_id, |
| 7247 | + struct crypto_ec_key *peer_pub, |
| 7248 | + const u8 *info, size_t info_len, |
| 7249 | + const u8 *aad, size_t aad_len, |
| 7250 | + const u8 *pt, size_t pt_len) |
| 7251 | +{ |
| 7252 | + /* not yet implemented */ |
| 7253 | + return NULL; |
| 7254 | +} |
| 7255 | + |
| 7256 | +struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id, |
| 7257 | + enum hpke_kdf_id kdf_id, |
| 7258 | + enum hpke_aead_id aead_id, |
| 7259 | + struct crypto_ec_key *own_priv, |
| 7260 | + const u8 *info, size_t info_len, |
| 7261 | + const u8 *aad, size_t aad_len, |
| 7262 | + const u8 *enc_ct, size_t enc_ct_len) |
| 7263 | +{ |
| 7264 | + /* not yet implemented */ |
| 7265 | + return NULL; |
| 7266 | +} |
| 7267 | + |
| 7268 | +#endif |
| 7269 | diff --git a/src/crypto/crypto_module_tests.c b/src/crypto/crypto_module_tests.c |
| 7270 | index ffeddbadd..07c36d850 100644 |
| 7271 | --- a/src/crypto/crypto_module_tests.c |
| 7272 | +++ b/src/crypto/crypto_module_tests.c |
| 7273 | @@ -2470,6 +2470,139 @@ static int test_hpke(void) |
| 7274 | } |
| 7275 | |
| 7276 | |
| 7277 | +static int test_ecc(void) |
| 7278 | +{ |
| 7279 | +#ifdef CONFIG_ECC |
| 7280 | +#ifndef CONFIG_TLS_INTERNAL |
| 7281 | +#ifndef CONFIG_TLS_GNUTLS |
| 7282 | +#if defined(CONFIG_TLS_MBEDTLS) \ |
| 7283 | + || defined(CONFIG_TLS_OPENSSL) \ |
| 7284 | + || defined(CONFIG_TLS_WOLFSSL) |
| 7285 | + wpa_printf(MSG_INFO, "Testing ECC"); |
| 7286 | + /* Note: some tests below are valid on supported Short Weierstrass |
| 7287 | + * curves, but not on Montgomery curves (e.g. IKE groups 31 and 32) |
| 7288 | + * (e.g. deriving and comparing y^2 test below not valid on Montgomery) |
| 7289 | + */ |
| 7290 | +#ifdef CONFIG_TLS_MBEDTLS |
| 7291 | + const int grps[] = {19, 20, 21, 25, 26, 28}; |
| 7292 | +#endif |
| 7293 | +#ifdef CONFIG_TLS_OPENSSL |
| 7294 | + const int grps[] = {19, 20, 21, 26}; |
| 7295 | +#endif |
| 7296 | +#ifdef CONFIG_TLS_WOLFSSL |
| 7297 | + const int grps[] = {19, 20, 21, 26}; |
| 7298 | +#endif |
| 7299 | + uint32_t i; |
| 7300 | + struct crypto_ec *e = NULL; |
| 7301 | + struct crypto_ec_point *p = NULL, *q = NULL; |
| 7302 | + struct crypto_bignum *x = NULL, *y = NULL; |
| 7303 | +#ifdef CONFIG_DPP |
| 7304 | + u8 bin[4096]; |
| 7305 | +#endif |
| 7306 | + for (i = 0; i < ARRAY_SIZE(grps); ++i) { |
| 7307 | + e = crypto_ec_init(grps[i]); |
| 7308 | + if (e == NULL |
| 7309 | + || crypto_ec_prime_len(e) == 0 |
| 7310 | + || crypto_ec_prime_len_bits(e) == 0 |
| 7311 | + || crypto_ec_order_len(e) == 0 |
| 7312 | + || crypto_ec_get_prime(e) == NULL |
| 7313 | + || crypto_ec_get_order(e) == NULL |
| 7314 | + || crypto_ec_get_a(e) == NULL |
| 7315 | + || crypto_ec_get_b(e) == NULL |
| 7316 | + || crypto_ec_get_generator(e) == NULL) { |
| 7317 | + break; |
| 7318 | + } |
| 7319 | +#ifdef CONFIG_DPP |
| 7320 | + struct crypto_ec_key *key = crypto_ec_key_gen(grps[i]); |
| 7321 | + if (key == NULL) |
| 7322 | + break; |
| 7323 | + p = crypto_ec_key_get_public_key(key); |
| 7324 | + q = crypto_ec_key_get_public_key(key); |
| 7325 | + crypto_ec_key_deinit(key); |
| 7326 | + if (p == NULL || q == NULL) |
| 7327 | + break; |
| 7328 | + if (!crypto_ec_point_is_on_curve(e, p)) |
| 7329 | + break; |
| 7330 | + |
| 7331 | + /* inverted point should not match original; |
| 7332 | + * double-invert should match */ |
| 7333 | + if (crypto_ec_point_invert(e, q) != 0 |
| 7334 | + || crypto_ec_point_cmp(e, p, q) == 0 |
| 7335 | + || crypto_ec_point_invert(e, q) != 0 |
| 7336 | + || crypto_ec_point_cmp(e, p, q) != 0) { |
| 7337 | + break; |
| 7338 | + } |
| 7339 | + |
| 7340 | + /* crypto_ec_point_to_bin() and crypto_ec_point_from_bin() |
| 7341 | + * imbalanced interfaces? */ |
| 7342 | + size_t prime_len = crypto_ec_prime_len(e); |
| 7343 | + if (prime_len * 2 > sizeof(bin)) |
| 7344 | + break; |
| 7345 | + if (crypto_ec_point_to_bin(e, p, bin, bin+prime_len) != 0) |
| 7346 | + break; |
| 7347 | + struct crypto_ec_point *tmp = crypto_ec_point_from_bin(e, bin); |
| 7348 | + if (tmp == NULL) |
| 7349 | + break; |
| 7350 | + if (crypto_ec_point_cmp(e, p, tmp) != 0) { |
| 7351 | + crypto_ec_point_deinit(tmp, 0); |
| 7352 | + break; |
| 7353 | + } |
| 7354 | + crypto_ec_point_deinit(tmp, 0); |
| 7355 | + |
| 7356 | + x = crypto_bignum_init(); |
| 7357 | + y = crypto_bignum_init_set(bin+prime_len, prime_len); |
| 7358 | + if (x == NULL || y == NULL || crypto_ec_point_x(e, p, x) != 0) |
| 7359 | + break; |
| 7360 | + struct crypto_bignum *y2 = crypto_ec_point_compute_y_sqr(e, x); |
| 7361 | + if (y2 == NULL) |
| 7362 | + break; |
| 7363 | + if (crypto_bignum_sqrmod(y, crypto_ec_get_prime(e), y) != 0 |
| 7364 | + || crypto_bignum_cmp(y, y2) != 0) { |
| 7365 | + crypto_bignum_deinit(y2, 0); |
| 7366 | + break; |
| 7367 | + } |
| 7368 | + crypto_bignum_deinit(y2, 0); |
| 7369 | + crypto_bignum_deinit(x, 0); |
| 7370 | + crypto_bignum_deinit(y, 0); |
| 7371 | + x = NULL; |
| 7372 | + y = NULL; |
| 7373 | + |
| 7374 | + x = crypto_bignum_init(); |
| 7375 | + if (x == NULL) |
| 7376 | + break; |
| 7377 | + if (crypto_bignum_rand(x, crypto_ec_get_prime(e)) != 0) |
| 7378 | + break; |
| 7379 | + crypto_bignum_deinit(x, 0); |
| 7380 | + x = NULL; |
| 7381 | + |
| 7382 | + crypto_ec_point_deinit(p, 0); |
| 7383 | + p = NULL; |
| 7384 | + crypto_ec_point_deinit(q, 0); |
| 7385 | + q = NULL; |
| 7386 | +#endif /* CONFIG_DPP */ |
| 7387 | + crypto_ec_deinit(e); |
| 7388 | + e = NULL; |
| 7389 | + } |
| 7390 | + if (i != ARRAY_SIZE(grps)) { |
| 7391 | + crypto_bignum_deinit(x, 0); |
| 7392 | + crypto_bignum_deinit(y, 0); |
| 7393 | + crypto_ec_point_deinit(p, 0); |
| 7394 | + crypto_ec_point_deinit(q, 0); |
| 7395 | + crypto_ec_deinit(e); |
| 7396 | + wpa_printf(MSG_INFO, |
| 7397 | + "ECC test case failed tls_id:%d", grps[i]); |
| 7398 | + return -1; |
| 7399 | + } |
| 7400 | + |
| 7401 | + wpa_printf(MSG_INFO, "ECC test cases passed"); |
| 7402 | +#endif |
| 7403 | +#endif /* !CONFIG_TLS_GNUTLS */ |
| 7404 | +#endif /* !CONFIG_TLS_INTERNAL */ |
| 7405 | +#endif /* CONFIG_ECC */ |
| 7406 | + return 0; |
| 7407 | +} |
| 7408 | + |
| 7409 | + |
| 7410 | static int test_ms_funcs(void) |
| 7411 | { |
| 7412 | #ifndef CONFIG_FIPS |
| 7413 | @@ -2591,6 +2724,7 @@ int crypto_module_tests(void) |
| 7414 | test_fips186_2_prf() || |
| 7415 | test_extract_expand_hkdf() || |
| 7416 | test_hpke() || |
| 7417 | + test_ecc() || |
| 7418 | test_ms_funcs()) |
| 7419 | ret = -1; |
| 7420 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 7421 | diff --git a/src/crypto/tls_mbedtls.c b/src/crypto/tls_mbedtls.c |
| 7422 | new file mode 100644 |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 7423 | index 000000000..d83a3db73 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 7424 | --- /dev/null |
| 7425 | +++ b/src/crypto/tls_mbedtls.c |
| 7426 | @@ -0,0 +1,3313 @@ |
| 7427 | +/* |
| 7428 | + * SSL/TLS interface functions for mbed TLS |
| 7429 | + * |
| 7430 | + * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com> |
| 7431 | + * SPDX-License-Identifier: BSD-3-Clause |
| 7432 | + * |
| 7433 | + * This software may be distributed under the terms of the BSD license. |
| 7434 | + * See README for more details. |
| 7435 | + * |
| 7436 | + * template: src/crypto/tls_none.c |
| 7437 | + * reference: src/crypto/tls_*.c |
| 7438 | + * |
| 7439 | + * Known Limitations: |
| 7440 | + * - no TLSv1.3 (not available in mbedtls 2.x; experimental in mbedtls 3.x) |
| 7441 | + * - no OCSP (not yet available in mbedtls) |
| 7442 | + * - mbedtls does not support all certificate encodings used by hwsim tests |
| 7443 | + * PCKS#5 v1.5 |
| 7444 | + * PCKS#12 |
| 7445 | + * DH DSA |
| 7446 | + * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c |
| 7447 | + * - mbedtls does not currently provide way to set an attribute in a CSR |
| 7448 | + * https://github.com/Mbed-TLS/mbedtls/issues/4886 |
| 7449 | + * so tests/hwsim dpp_enterprise tests fail |
| 7450 | + * - DPP2 not supported |
| 7451 | + * PKCS#7 parsing is not supported in mbedtls |
| 7452 | + * See crypto_mbedtls.c:crypto_pkcs7_get_certificates() comments |
| 7453 | + * - DPP3 not supported |
| 7454 | + * hpke_base_seal() and hpke_base_seal() not implemented in crypto_mbedtls.c |
| 7455 | + * |
| 7456 | + * Status: |
| 7457 | + * - code written to be compatible with mbedtls 2.x and mbedtls 3.x |
| 7458 | + * (currently requires mbedtls >= 2.27.0 for mbedtls_mpi_random()) |
| 7459 | + * (currently requires mbedtls >= 2.18.0 for mbedtls_ssl_tls_prf()) |
| 7460 | + * - builds with tests/build/build-wpa_supplicant-mbedtls.config |
| 7461 | + * - passes all tests/ crypto module tests (incomplete coverage) |
| 7462 | + * ($ cd tests; make clean; make -j 4 run-tests CONFIG_TLS=mbedtls) |
| 7463 | + * - passes almost all tests/hwsim tests |
| 7464 | + * (hwsim tests skipped for missing features) |
| 7465 | + * |
| 7466 | + * RFE: |
| 7467 | + * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c |
| 7468 | + * - client/server session resumption, and/or save client session ticket |
| 7469 | + */ |
| 7470 | + |
| 7471 | +#include "includes.h" |
| 7472 | +#include "common.h" |
| 7473 | + |
| 7474 | +#include <mbedtls/version.h> |
| 7475 | +#include <mbedtls/ctr_drbg.h> |
| 7476 | +#include <mbedtls/error.h> |
| 7477 | +#include <mbedtls/oid.h> |
| 7478 | +#include <mbedtls/pem.h> |
| 7479 | +#include <mbedtls/platform.h> /* mbedtls_calloc() mbedtls_free() */ |
| 7480 | +#include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */ |
| 7481 | +#include <mbedtls/ssl.h> |
| 7482 | +#include <mbedtls/ssl_ticket.h> |
| 7483 | +#include <mbedtls/x509.h> |
| 7484 | +#include <mbedtls/x509_crt.h> |
| 7485 | + |
| 7486 | +#if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.4.0 */ |
| 7487 | +#include <mbedtls/net_sockets.h> |
| 7488 | +#else |
| 7489 | +#include <mbedtls/net.h> |
| 7490 | +#endif |
| 7491 | + |
| 7492 | +#ifndef MBEDTLS_PRIVATE |
| 7493 | +#define MBEDTLS_PRIVATE(x) x |
| 7494 | +#endif |
| 7495 | + |
| 7496 | +#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ |
| 7497 | +#define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \ |
| 7498 | + ((ssl)->MBEDTLS_PRIVATE(session) \ |
| 7499 | + ?(ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite) \ |
| 7500 | + : 0) |
| 7501 | +#define mbedtls_ssl_ciphersuite_get_name(info) \ |
| 7502 | + (info)->MBEDTLS_PRIVATE(name) |
| 7503 | +#endif |
| 7504 | + |
| 7505 | +#include "crypto.h" /* sha256_vector() */ |
| 7506 | +#include "tls.h" |
| 7507 | + |
| 7508 | +#ifndef SHA256_DIGEST_LENGTH |
| 7509 | +#define SHA256_DIGEST_LENGTH 32 |
| 7510 | +#endif |
| 7511 | + |
| 7512 | +#ifndef MBEDTLS_EXPKEY_FIXED_SECRET_LEN |
| 7513 | +#define MBEDTLS_EXPKEY_FIXED_SECRET_LEN 48 |
| 7514 | +#endif |
| 7515 | + |
| 7516 | +#ifndef MBEDTLS_EXPKEY_RAND_LEN |
| 7517 | +#define MBEDTLS_EXPKEY_RAND_LEN 32 |
| 7518 | +#endif |
| 7519 | + |
| 7520 | +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 7521 | +static mbedtls_ssl_export_keys_t tls_connection_export_keys_cb; |
| 7522 | +#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 7523 | +static mbedtls_ssl_export_keys_ext_t tls_connection_export_keys_cb; |
| 7524 | +#else /*(not implemented; return error)*/ |
| 7525 | +#define mbedtls_ssl_tls_prf(a,b,c,d,e,f,g,h) (-1) |
| 7526 | +typedef mbedtls_tls_prf_types int; |
| 7527 | +#endif |
| 7528 | + |
| 7529 | + |
| 7530 | +/* hostapd/wpa_supplicant provides forced_memzero(), |
| 7531 | + * but prefer mbedtls_platform_zeroize() */ |
| 7532 | +#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) |
| 7533 | + |
| 7534 | + |
| 7535 | +#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ |
| 7536 | + || defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) |
| 7537 | +#ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7538 | +#ifdef MBEDTLS_SSL_TICKET_C |
| 7539 | +#define TLS_MBEDTLS_SESSION_TICKETS |
| 7540 | +#if defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) |
| 7541 | +#define TLS_MBEDTLS_EAP_TEAP |
| 7542 | +#endif |
| 7543 | +#if !defined(CONFIG_FIPS) /* EAP-FAST keys cannot be exported in FIPS mode */ |
| 7544 | +#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) |
| 7545 | +#define TLS_MBEDTLS_EAP_FAST |
| 7546 | +#endif |
| 7547 | +#endif |
| 7548 | +#endif |
| 7549 | +#endif |
| 7550 | +#endif |
| 7551 | + |
| 7552 | + |
| 7553 | +struct tls_conf { |
| 7554 | + mbedtls_ssl_config conf; |
| 7555 | + |
| 7556 | + unsigned int verify_peer:1; |
| 7557 | + unsigned int verify_depth0_only:1; |
| 7558 | + unsigned int check_crl:2; /*(needs :2 bits for 0, 1, 2)*/ |
| 7559 | + unsigned int check_crl_strict:1; /*(needs :1 bit for 0, 1)*/ |
| 7560 | + unsigned int ca_cert_probe:1; |
| 7561 | + unsigned int has_ca_cert:1; |
| 7562 | + unsigned int has_client_cert:1; |
| 7563 | + unsigned int has_private_key:1; |
| 7564 | + unsigned int suiteb128:1; |
| 7565 | + unsigned int suiteb192:1; |
| 7566 | + mbedtls_x509_crl *crl; |
| 7567 | + mbedtls_x509_crt ca_cert; |
| 7568 | + mbedtls_x509_crt client_cert; |
| 7569 | + mbedtls_pk_context private_key; |
| 7570 | + |
| 7571 | + uint32_t refcnt; |
| 7572 | + |
| 7573 | + unsigned int flags; |
| 7574 | + char *subject_match; |
| 7575 | + char *altsubject_match; |
| 7576 | + char *suffix_match; |
| 7577 | + char *domain_match; |
| 7578 | + char *check_cert_subject; |
| 7579 | + u8 ca_cert_hash[SHA256_DIGEST_LENGTH]; |
| 7580 | + |
| 7581 | + int *ciphersuites; /* list of ciphersuite ids for mbedtls_ssl_config */ |
| 7582 | +#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ |
| 7583 | + mbedtls_ecp_group_id *curves; |
| 7584 | +#else |
| 7585 | + uint16_t *curves; /* list of curve ids for mbedtls_ssl_config */ |
| 7586 | +#endif |
| 7587 | +}; |
| 7588 | + |
| 7589 | + |
| 7590 | +struct tls_global { |
| 7591 | + struct tls_conf *tls_conf; |
| 7592 | + char *ocsp_stapling_response; |
| 7593 | + mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/ |
| 7594 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7595 | + mbedtls_ssl_ticket_context ticket_ctx; |
| 7596 | + #endif |
| 7597 | + char *ca_cert_file; |
| 7598 | + struct os_reltime crl_reload_previous; |
| 7599 | + unsigned int crl_reload_interval; |
| 7600 | + uint32_t refcnt; |
| 7601 | + struct tls_config init_conf; |
| 7602 | +}; |
| 7603 | + |
| 7604 | +static struct tls_global tls_ctx_global; |
| 7605 | + |
| 7606 | + |
| 7607 | +struct tls_connection { |
| 7608 | + struct tls_conf *tls_conf; |
| 7609 | + struct wpabuf *push_buf; |
| 7610 | + struct wpabuf *pull_buf; |
| 7611 | + size_t pull_buf_offset; |
| 7612 | + |
| 7613 | + unsigned int established:1; |
| 7614 | + unsigned int resumed:1; |
| 7615 | + unsigned int verify_peer:1; |
| 7616 | + unsigned int is_server:1; |
| 7617 | + |
| 7618 | + mbedtls_ssl_context ssl; |
| 7619 | + |
| 7620 | + mbedtls_tls_prf_types tls_prf_type; |
| 7621 | + size_t expkey_keyblock_size; |
| 7622 | + size_t expkey_secret_len; |
| 7623 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 7624 | + unsigned char expkey_secret[MBEDTLS_EXPKEY_FIXED_SECRET_LEN]; |
| 7625 | + #else |
| 7626 | + unsigned char expkey_secret[MBEDTLS_MD_MAX_SIZE]; |
| 7627 | + #endif |
| 7628 | + unsigned char expkey_randbytes[MBEDTLS_EXPKEY_RAND_LEN*2]; |
| 7629 | + |
| 7630 | + int read_alerts, write_alerts, failed; |
| 7631 | + |
| 7632 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 7633 | + tls_session_ticket_cb session_ticket_cb; |
| 7634 | + void *session_ticket_cb_ctx; |
| 7635 | + unsigned char *clienthello_session_ticket; |
| 7636 | + size_t clienthello_session_ticket_len; |
| 7637 | + #endif |
| 7638 | + char *peer_subject; /* peer subject info for authenticated peer */ |
| 7639 | + struct wpabuf *success_data; |
| 7640 | +}; |
| 7641 | + |
| 7642 | + |
| 7643 | +#ifndef __has_attribute |
| 7644 | +#define __has_attribute(x) 0 |
| 7645 | +#endif |
| 7646 | + |
| 7647 | +#ifndef __GNUC_PREREQ |
| 7648 | +#define __GNUC_PREREQ(maj,min) 0 |
| 7649 | +#endif |
| 7650 | + |
| 7651 | +#ifndef __attribute_cold__ |
| 7652 | +#if __has_attribute(cold) \ |
| 7653 | + || __GNUC_PREREQ(4,3) |
| 7654 | +#define __attribute_cold__ __attribute__((__cold__)) |
| 7655 | +#else |
| 7656 | +#define __attribute_cold__ |
| 7657 | +#endif |
| 7658 | +#endif |
| 7659 | + |
| 7660 | +#ifndef __attribute_noinline__ |
| 7661 | +#if __has_attribute(noinline) \ |
| 7662 | + || __GNUC_PREREQ(3,1) |
| 7663 | +#define __attribute_noinline__ __attribute__((__noinline__)) |
| 7664 | +#else |
| 7665 | +#define __attribute_noinline__ |
| 7666 | +#endif |
| 7667 | +#endif |
| 7668 | + |
| 7669 | + |
| 7670 | +__attribute_cold__ |
| 7671 | +__attribute_noinline__ |
| 7672 | +static void emsg(int level, const char * const msg) |
| 7673 | +{ |
| 7674 | + wpa_printf(level, "MTLS: %s", msg); |
| 7675 | +} |
| 7676 | + |
| 7677 | + |
| 7678 | +__attribute_cold__ |
| 7679 | +__attribute_noinline__ |
| 7680 | +static void emsgrc(int level, const char * const msg, int rc) |
| 7681 | +{ |
| 7682 | + #ifdef MBEDTLS_ERROR_C |
| 7683 | + /* error logging convenience function that decodes mbedtls result codes */ |
| 7684 | + char buf[256]; |
| 7685 | + mbedtls_strerror(rc, buf, sizeof(buf)); |
| 7686 | + wpa_printf(level, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc); |
| 7687 | + #else |
| 7688 | + wpa_printf(level, "MTLS: %s: (-0x%04x)", msg, -rc); |
| 7689 | + #endif |
| 7690 | +} |
| 7691 | + |
| 7692 | + |
| 7693 | +#define elog(rc, msg) emsgrc(MSG_ERROR, (msg), (rc)) |
| 7694 | +#define ilog(rc, msg) emsgrc(MSG_INFO, (msg), (rc)) |
| 7695 | + |
| 7696 | + |
| 7697 | +struct tls_conf * tls_conf_init(void *tls_ctx) |
| 7698 | +{ |
| 7699 | + struct tls_conf *tls_conf = os_zalloc(sizeof(*tls_conf)); |
| 7700 | + if (tls_conf == NULL) |
| 7701 | + return NULL; |
| 7702 | + tls_conf->refcnt = 1; |
| 7703 | + |
| 7704 | + mbedtls_ssl_config_init(&tls_conf->conf); |
| 7705 | + mbedtls_ssl_conf_rng(&tls_conf->conf, |
| 7706 | + mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg); |
| 7707 | + mbedtls_x509_crt_init(&tls_conf->ca_cert); |
| 7708 | + mbedtls_x509_crt_init(&tls_conf->client_cert); |
| 7709 | + mbedtls_pk_init(&tls_conf->private_key); |
| 7710 | + |
| 7711 | + return tls_conf; |
| 7712 | +} |
| 7713 | + |
| 7714 | + |
| 7715 | +void tls_conf_deinit(struct tls_conf *tls_conf) |
| 7716 | +{ |
| 7717 | + if (tls_conf == NULL || --tls_conf->refcnt != 0) |
| 7718 | + return; |
| 7719 | + |
| 7720 | + mbedtls_x509_crt_free(&tls_conf->ca_cert); |
| 7721 | + mbedtls_x509_crt_free(&tls_conf->client_cert); |
| 7722 | + if (tls_conf->crl) { |
| 7723 | + mbedtls_x509_crl_free(tls_conf->crl); |
| 7724 | + os_free(tls_conf->crl); |
| 7725 | + } |
| 7726 | + mbedtls_pk_free(&tls_conf->private_key); |
| 7727 | + mbedtls_ssl_config_free(&tls_conf->conf); |
| 7728 | + os_free(tls_conf->curves); |
| 7729 | + os_free(tls_conf->ciphersuites); |
| 7730 | + os_free(tls_conf->subject_match); |
| 7731 | + os_free(tls_conf->altsubject_match); |
| 7732 | + os_free(tls_conf->suffix_match); |
| 7733 | + os_free(tls_conf->domain_match); |
| 7734 | + os_free(tls_conf->check_cert_subject); |
| 7735 | + os_free(tls_conf); |
| 7736 | +} |
| 7737 | + |
| 7738 | + |
| 7739 | +mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ |
| 7740 | + |
| 7741 | +__attribute_cold__ |
| 7742 | +void * tls_init(const struct tls_config *conf) |
| 7743 | +{ |
| 7744 | + /* RFE: review struct tls_config *conf (different from tls_conf) */ |
| 7745 | + |
| 7746 | + if (++tls_ctx_global.refcnt > 1) |
| 7747 | + return &tls_ctx_global; |
| 7748 | + |
| 7749 | + tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg(); |
| 7750 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7751 | + mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx); |
| 7752 | + mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, |
| 7753 | + mbedtls_ctr_drbg_random, |
| 7754 | + tls_ctx_global.ctr_drbg, |
| 7755 | + MBEDTLS_CIPHER_AES_256_GCM, |
| 7756 | + 43200); /* ticket timeout: 12 hours */ |
| 7757 | + #endif |
| 7758 | + /* copy struct for future use */ |
| 7759 | + tls_ctx_global.init_conf = *conf; |
| 7760 | + if (conf->openssl_ciphers) |
| 7761 | + tls_ctx_global.init_conf.openssl_ciphers = |
| 7762 | + os_strdup(conf->openssl_ciphers); |
| 7763 | + |
| 7764 | + tls_ctx_global.crl_reload_interval = conf->crl_reload_interval; |
| 7765 | + os_get_reltime(&tls_ctx_global.crl_reload_previous); |
| 7766 | + |
| 7767 | + return &tls_ctx_global; |
| 7768 | +} |
| 7769 | + |
| 7770 | + |
| 7771 | +__attribute_cold__ |
| 7772 | +void tls_deinit(void *tls_ctx) |
| 7773 | +{ |
| 7774 | + if (tls_ctx == NULL || --tls_ctx_global.refcnt != 0) |
| 7775 | + return; |
| 7776 | + |
| 7777 | + tls_conf_deinit(tls_ctx_global.tls_conf); |
| 7778 | + os_free(tls_ctx_global.ca_cert_file); |
| 7779 | + os_free(tls_ctx_global.ocsp_stapling_response); |
| 7780 | + char *openssl_ciphers; /*(allocated in tls_init())*/ |
| 7781 | + *(const char **)&openssl_ciphers = |
| 7782 | + tls_ctx_global.init_conf.openssl_ciphers; |
| 7783 | + os_free(openssl_ciphers); |
| 7784 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7785 | + mbedtls_ssl_ticket_free(&tls_ctx_global.ticket_ctx); |
| 7786 | + #endif |
| 7787 | + os_memset(&tls_ctx_global, 0, sizeof(tls_ctx_global)); |
| 7788 | +} |
| 7789 | + |
| 7790 | + |
| 7791 | +int tls_get_errors(void *tls_ctx) |
| 7792 | +{ |
| 7793 | + return 0; |
| 7794 | +} |
| 7795 | + |
| 7796 | + |
| 7797 | +static void tls_connection_deinit_expkey(struct tls_connection *conn) |
| 7798 | +{ |
| 7799 | + conn->tls_prf_type = 0; /* MBEDTLS_SSL_TLS_PRF_NONE; */ |
| 7800 | + conn->expkey_keyblock_size = 0; |
| 7801 | + conn->expkey_secret_len = 0; |
| 7802 | + forced_memzero(conn->expkey_secret, sizeof(conn->expkey_secret)); |
| 7803 | + forced_memzero(conn->expkey_randbytes, sizeof(conn->expkey_randbytes)); |
| 7804 | +} |
| 7805 | + |
| 7806 | + |
| 7807 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 7808 | +void tls_connection_deinit_clienthello_session_ticket(struct tls_connection *conn) |
| 7809 | +{ |
| 7810 | + if (conn->clienthello_session_ticket) { |
| 7811 | + mbedtls_platform_zeroize(conn->clienthello_session_ticket, |
| 7812 | + conn->clienthello_session_ticket_len); |
| 7813 | + mbedtls_free(conn->clienthello_session_ticket); |
| 7814 | + conn->clienthello_session_ticket = NULL; |
| 7815 | + conn->clienthello_session_ticket_len = 0; |
| 7816 | + } |
| 7817 | +} |
| 7818 | +#endif |
| 7819 | + |
| 7820 | + |
| 7821 | +void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) |
| 7822 | +{ |
| 7823 | + if (conn == NULL) |
| 7824 | + return; |
| 7825 | + |
| 7826 | + #if 0 /*(good intention, but never sent since we destroy self below)*/ |
| 7827 | + if (conn->established) |
| 7828 | + mbedtls_ssl_close_notify(&conn->ssl); |
| 7829 | + #endif |
| 7830 | + |
| 7831 | + if (conn->tls_prf_type) |
| 7832 | + tls_connection_deinit_expkey(conn); |
| 7833 | + |
| 7834 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 7835 | + if (conn->clienthello_session_ticket) |
| 7836 | + tls_connection_deinit_clienthello_session_ticket(conn); |
| 7837 | + #endif |
| 7838 | + |
| 7839 | + os_free(conn->peer_subject); |
| 7840 | + wpabuf_free(conn->success_data); |
| 7841 | + wpabuf_free(conn->push_buf); |
| 7842 | + wpabuf_free(conn->pull_buf); |
| 7843 | + mbedtls_ssl_free(&conn->ssl); |
| 7844 | + tls_conf_deinit(conn->tls_conf); |
| 7845 | + os_free(conn); |
| 7846 | +} |
| 7847 | + |
| 7848 | + |
| 7849 | +static void tls_mbedtls_refresh_crl(void); |
| 7850 | +static int tls_mbedtls_ssl_setup(struct tls_connection *conn); |
| 7851 | + |
| 7852 | +struct tls_connection * tls_connection_init(void *tls_ctx) |
| 7853 | +{ |
| 7854 | + struct tls_connection *conn = os_zalloc(sizeof(*conn)); |
| 7855 | + if (conn == NULL) |
| 7856 | + return NULL; |
| 7857 | + |
| 7858 | + mbedtls_ssl_init(&conn->ssl); |
| 7859 | + |
| 7860 | + conn->tls_conf = tls_ctx_global.tls_conf; /*(inherit global conf, if set)*/ |
| 7861 | + if (conn->tls_conf) { |
| 7862 | + ++conn->tls_conf->refcnt; |
| 7863 | + /* check for CRL refresh if inheriting from global config */ |
| 7864 | + tls_mbedtls_refresh_crl(); |
| 7865 | + |
| 7866 | + conn->verify_peer = conn->tls_conf->verify_peer; |
| 7867 | + if (tls_mbedtls_ssl_setup(conn) != 0) { |
| 7868 | + tls_connection_deinit(&tls_ctx_global, conn); |
| 7869 | + return NULL; |
| 7870 | + } |
| 7871 | + } |
| 7872 | + |
| 7873 | + return conn; |
| 7874 | +} |
| 7875 | + |
| 7876 | + |
| 7877 | +int tls_connection_established(void *tls_ctx, struct tls_connection *conn) |
| 7878 | +{ |
| 7879 | + return conn ? conn->established : 0; |
| 7880 | +} |
| 7881 | + |
| 7882 | + |
| 7883 | +__attribute_noinline__ |
| 7884 | +char * tls_mbedtls_peer_serial_num(const mbedtls_x509_crt *crt, char *serial_num, size_t len) |
| 7885 | +{ |
| 7886 | + /* mbedtls_x509_serial_gets() inefficiently formats to hex separated by |
| 7887 | + * colons, so generate the hex serial number here. The func |
| 7888 | + * wpa_snprintf_hex_uppercase() is similarly inefficient. */ |
| 7889 | + size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */ |
| 7890 | + while (i < crt->serial.len && crt->serial.p[i] == 0) ++i; |
| 7891 | + if (i == crt->serial.len) --i; |
| 7892 | + |
| 7893 | + const unsigned char *s = crt->serial.p + i; |
| 7894 | + const size_t e = (crt->serial.len - i) * 2; |
| 7895 | + if (e >= len) |
| 7896 | + return NULL; |
| 7897 | + #if 0 |
| 7898 | + wpa_snprintf_hex_uppercase(serial_num, len, s, crt->serial.len-i); |
| 7899 | + #else |
| 7900 | + for (i = 0; i < e; i+=2, ++s) { |
| 7901 | + serial_num[i+0] = "0123456789ABCDEF"[(*s >> 4)]; |
| 7902 | + serial_num[i+1] = "0123456789ABCDEF"[(*s & 0xF)]; |
| 7903 | + } |
| 7904 | + serial_num[e] = '\0'; |
| 7905 | + #endif |
| 7906 | + return serial_num; |
| 7907 | +} |
| 7908 | + |
| 7909 | + |
| 7910 | +char * tls_connection_peer_serial_num(void *tls_ctx, |
| 7911 | + struct tls_connection *conn) |
| 7912 | +{ |
| 7913 | + const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&conn->ssl); |
| 7914 | + if (crt == NULL) |
| 7915 | + return NULL; |
| 7916 | + size_t len = crt->serial.len * 2 + 1; |
| 7917 | + char *serial_num = os_malloc(len); |
| 7918 | + if (!serial_num) |
| 7919 | + return NULL; |
| 7920 | + return tls_mbedtls_peer_serial_num(crt, serial_num, len); |
| 7921 | +} |
| 7922 | + |
| 7923 | + |
| 7924 | +static void tls_pull_buf_reset(struct tls_connection *conn); |
| 7925 | + |
| 7926 | +int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) |
| 7927 | +{ |
| 7928 | + /* Note: this function called from eap_peer_tls_reauth_init() |
| 7929 | + * for session resumption, not for connection shutdown */ |
| 7930 | + |
| 7931 | + if (conn == NULL) |
| 7932 | + return -1; |
| 7933 | + |
| 7934 | + tls_pull_buf_reset(conn); |
| 7935 | + wpabuf_free(conn->push_buf); |
| 7936 | + conn->push_buf = NULL; |
| 7937 | + conn->established = 0; |
| 7938 | + conn->resumed = 0; |
| 7939 | + if (conn->tls_prf_type) |
| 7940 | + tls_connection_deinit_expkey(conn); |
| 7941 | + |
| 7942 | + /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */ |
| 7943 | + |
| 7944 | + return mbedtls_ssl_session_reset(&conn->ssl); |
| 7945 | +} |
| 7946 | + |
| 7947 | + |
| 7948 | +static int tls_wpabuf_resize_put_data(struct wpabuf **buf, |
| 7949 | + const unsigned char *data, size_t dlen) |
| 7950 | +{ |
| 7951 | + if (wpabuf_resize(buf, dlen) < 0) |
| 7952 | + return 0; |
| 7953 | + wpabuf_put_data(*buf, data, dlen); |
| 7954 | + return 1; |
| 7955 | +} |
| 7956 | + |
| 7957 | + |
| 7958 | +static int tls_pull_buf_append(struct tls_connection *conn, |
| 7959 | + const struct wpabuf *in_data) |
| 7960 | +{ |
| 7961 | + /*(interface does not lend itself to move semantics)*/ |
| 7962 | + return tls_wpabuf_resize_put_data(&conn->pull_buf, |
| 7963 | + wpabuf_head(in_data), |
| 7964 | + wpabuf_len(in_data)); |
| 7965 | +} |
| 7966 | + |
| 7967 | + |
| 7968 | +static void tls_pull_buf_reset(struct tls_connection *conn) |
| 7969 | +{ |
| 7970 | + /*(future: might consider reusing conn->pull_buf)*/ |
| 7971 | + wpabuf_free(conn->pull_buf); |
| 7972 | + conn->pull_buf = NULL; |
| 7973 | + conn->pull_buf_offset = 0; |
| 7974 | +} |
| 7975 | + |
| 7976 | + |
| 7977 | +__attribute_cold__ |
| 7978 | +static void tls_pull_buf_discard(struct tls_connection *conn, const char *func) |
| 7979 | +{ |
| 7980 | + size_t discard = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; |
| 7981 | + if (discard) |
| 7982 | + wpa_printf(MSG_DEBUG, |
| 7983 | + "%s - %zu bytes remaining in pull_buf; discarding", |
| 7984 | + func, discard); |
| 7985 | + tls_pull_buf_reset(conn); |
| 7986 | +} |
| 7987 | + |
| 7988 | + |
| 7989 | +static int tls_pull_func(void *ptr, unsigned char *buf, size_t len) |
| 7990 | +{ |
| 7991 | + struct tls_connection *conn = (struct tls_connection *) ptr; |
| 7992 | + if (conn->pull_buf == NULL) |
| 7993 | + return MBEDTLS_ERR_SSL_WANT_READ; |
| 7994 | + const size_t dlen = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; |
| 7995 | + if (dlen == 0) |
| 7996 | + return MBEDTLS_ERR_SSL_WANT_READ; |
| 7997 | + |
| 7998 | + if (len > dlen) |
| 7999 | + len = dlen; |
| 8000 | + os_memcpy(buf, wpabuf_head(conn->pull_buf)+conn->pull_buf_offset, len); |
| 8001 | + |
| 8002 | + if (len == dlen) { |
| 8003 | + tls_pull_buf_reset(conn); |
| 8004 | + /*wpa_printf(MSG_DEBUG, "%s - emptied pull_buf", __func__);*/ |
| 8005 | + } |
| 8006 | + else { |
| 8007 | + conn->pull_buf_offset += len; |
| 8008 | + /*wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf", |
| 8009 | + __func__, dlen - len);*/ |
| 8010 | + } |
| 8011 | + return (int)len; |
| 8012 | +} |
| 8013 | + |
| 8014 | + |
| 8015 | +static int tls_push_func(void *ptr, const unsigned char *buf, size_t len) |
| 8016 | +{ |
| 8017 | + struct tls_connection *conn = (struct tls_connection *) ptr; |
| 8018 | + return tls_wpabuf_resize_put_data(&conn->push_buf, buf, len) |
| 8019 | + ? (int)len |
| 8020 | + : MBEDTLS_ERR_SSL_ALLOC_FAILED; |
| 8021 | +} |
| 8022 | + |
| 8023 | + |
| 8024 | +static int |
| 8025 | +tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags); |
| 8026 | + |
| 8027 | + |
| 8028 | +static int tls_mbedtls_ssl_setup(struct tls_connection *conn) |
| 8029 | +{ |
| 8030 | + #if 0 |
| 8031 | + /* mbedtls_ssl_setup() must be called only once */ |
| 8032 | + /* If this func might be called multiple times (e.g. via set_params), |
| 8033 | + * then we should set a flag in conn that ssl was initialized */ |
| 8034 | + if (conn->ssl_is_init) { |
| 8035 | + mbedtls_ssl_free(&conn->ssl); |
| 8036 | + mbedtls_ssl_init(&conn->ssl); |
| 8037 | + } |
| 8038 | + #endif |
| 8039 | + |
| 8040 | + int ret = mbedtls_ssl_setup(&conn->ssl, &conn->tls_conf->conf); |
| 8041 | + if (ret != 0) { |
| 8042 | + elog(ret, "mbedtls_ssl_setup"); |
| 8043 | + return -1; |
| 8044 | + } |
| 8045 | + |
| 8046 | + mbedtls_ssl_set_bio(&conn->ssl, conn, tls_push_func, tls_pull_func, NULL); |
| 8047 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 8048 | + mbedtls_ssl_set_export_keys_cb( |
| 8049 | + &conn->ssl, tls_connection_export_keys_cb, conn); |
| 8050 | + #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 8051 | + mbedtls_ssl_conf_export_keys_ext_cb( |
| 8052 | + &conn->tls_conf->conf, tls_connection_export_keys_cb, conn); |
| 8053 | + #endif |
| 8054 | + if (conn->verify_peer) |
| 8055 | + mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); |
| 8056 | + |
| 8057 | + return 0; |
| 8058 | +} |
| 8059 | + |
| 8060 | + |
| 8061 | +static int tls_mbedtls_data_is_pem(const u8 *data) |
| 8062 | +{ |
| 8063 | + return (NULL != os_strstr((char *)data, "-----")); |
| 8064 | +} |
| 8065 | + |
| 8066 | + |
| 8067 | +static void tls_mbedtls_set_allowed_tls_vers(struct tls_conf *tls_conf, |
| 8068 | + mbedtls_ssl_config *conf) |
| 8069 | +{ |
| 8070 | + #if !defined(MBEDTLS_SSL_PROTO_TLS1_3) |
| 8071 | + tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_3; |
| 8072 | + #endif |
| 8073 | + |
| 8074 | + /* unconditionally require TLSv1.2+ for TLS_CONN_SUITEB */ |
| 8075 | + if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 8076 | + tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_0; |
| 8077 | + tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_1; |
| 8078 | + } |
| 8079 | + |
| 8080 | + const unsigned int flags = tls_conf->flags; |
| 8081 | + |
| 8082 | + /* attempt to map flags to min and max TLS protocol version */ |
| 8083 | + |
| 8084 | + int min = (flags & TLS_CONN_DISABLE_TLSv1_0) |
| 8085 | + ? (flags & TLS_CONN_DISABLE_TLSv1_1) |
| 8086 | + ? (flags & TLS_CONN_DISABLE_TLSv1_2) |
| 8087 | + ? (flags & TLS_CONN_DISABLE_TLSv1_3) |
| 8088 | + ? 4 |
| 8089 | + : 3 |
| 8090 | + : 2 |
| 8091 | + : 1 |
| 8092 | + : 0; |
| 8093 | + |
| 8094 | + int max = (flags & TLS_CONN_DISABLE_TLSv1_3) |
| 8095 | + ? (flags & TLS_CONN_DISABLE_TLSv1_2) |
| 8096 | + ? (flags & TLS_CONN_DISABLE_TLSv1_1) |
| 8097 | + ? (flags & TLS_CONN_DISABLE_TLSv1_0) |
| 8098 | + ? -1 |
| 8099 | + : 0 |
| 8100 | + : 1 |
| 8101 | + : 2 |
| 8102 | + : 3; |
| 8103 | + |
| 8104 | + if ((flags & TLS_CONN_ENABLE_TLSv1_2) && min > 2) min = 2; |
| 8105 | + if ((flags & TLS_CONN_ENABLE_TLSv1_1) && min > 1) min = 1; |
| 8106 | + if ((flags & TLS_CONN_ENABLE_TLSv1_0) && min > 0) min = 0; |
| 8107 | + if (max < min) { |
| 8108 | + emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); |
| 8109 | + return; |
| 8110 | + } |
| 8111 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 8112 | + /* mbed TLS 3.0.0 removes support for protocols < TLSv1.2 */ |
| 8113 | + if (min < 2 || max < 2) { |
| 8114 | + emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); |
| 8115 | + if (min < 2) min = 2; |
| 8116 | + if (max < 2) max = 2; |
| 8117 | + } |
| 8118 | + #endif |
| 8119 | + |
| 8120 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 8121 | + /* MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303 *//*!< (D)TLS 1.2 */ |
| 8122 | + /* MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304 *//*!< (D)TLS 1.3 */ |
| 8123 | + min = (min == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; |
| 8124 | + max = (max == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; |
| 8125 | + mbedtls_ssl_conf_min_tls_version(conf, min); |
| 8126 | + mbedtls_ssl_conf_max_tls_version(conf, max); |
| 8127 | + #else |
| 8128 | + #ifndef MBEDTLS_SSL_MINOR_VERSION_4 |
| 8129 | + if (min == 3) min = 2; |
| 8130 | + if (max == 3) max = 2; |
| 8131 | + #endif |
| 8132 | + /* MBEDTLS_SSL_MINOR_VERSION_0 0 *//*!< SSL v3.0 */ |
| 8133 | + /* MBEDTLS_SSL_MINOR_VERSION_1 1 *//*!< TLS v1.0 */ |
| 8134 | + /* MBEDTLS_SSL_MINOR_VERSION_2 2 *//*!< TLS v1.1 */ |
| 8135 | + /* MBEDTLS_SSL_MINOR_VERSION_3 3 *//*!< TLS v1.2 */ |
| 8136 | + /* MBEDTLS_SSL_MINOR_VERSION_4 4 *//*!< TLS v1.3 */ |
| 8137 | + mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, min+1); |
| 8138 | + mbedtls_ssl_conf_max_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, max+1); |
| 8139 | + #endif |
| 8140 | +} |
| 8141 | + |
| 8142 | + |
| 8143 | +__attribute_noinline__ |
| 8144 | +static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n); |
| 8145 | + |
| 8146 | + |
| 8147 | +static int |
| 8148 | +tls_mbedtls_set_dhparams(struct tls_conf *tls_conf, const char *dh_file) |
| 8149 | +{ |
| 8150 | + size_t len; |
| 8151 | + u8 *data; |
| 8152 | + if (tls_mbedtls_readfile(dh_file, &data, &len)) |
| 8153 | + return 0; |
| 8154 | + |
| 8155 | + /* parse only if DH parameters if in PEM format */ |
| 8156 | + if (tls_mbedtls_data_is_pem(data) |
| 8157 | + && NULL == os_strstr((char *)data, "-----BEGIN DH PARAMETERS-----")) { |
| 8158 | + if (os_strstr((char *)data, "-----BEGIN DSA PARAMETERS-----")) |
| 8159 | + wpa_printf(MSG_WARNING, "DSA parameters not handled (%s)", dh_file); |
| 8160 | + else |
| 8161 | + wpa_printf(MSG_WARNING, "unexpected DH param content (%s)",dh_file); |
| 8162 | + forced_memzero(data, len); |
| 8163 | + os_free(data); |
| 8164 | + return 0; |
| 8165 | + } |
| 8166 | + |
| 8167 | + /* mbedtls_dhm_parse_dhm() expects "-----BEGIN DH PARAMETERS-----" if PEM */ |
| 8168 | + mbedtls_dhm_context dhm; |
| 8169 | + mbedtls_dhm_init(&dhm); |
| 8170 | + int rc = mbedtls_dhm_parse_dhm(&dhm, data, len); |
| 8171 | + if (0 == rc) |
| 8172 | + rc = mbedtls_ssl_conf_dh_param_ctx(&tls_conf->conf, &dhm); |
| 8173 | + if (0 != rc) |
| 8174 | + elog(rc, dh_file); |
| 8175 | + mbedtls_dhm_free(&dhm); |
| 8176 | + |
| 8177 | + forced_memzero(data, len); |
| 8178 | + os_free(data); |
| 8179 | + return (0 == rc); |
| 8180 | +} |
| 8181 | + |
| 8182 | + |
| 8183 | +/* reference: lighttpd src/mod_mbedtls.c:mod_mbedtls_ssl_append_curve() |
| 8184 | + * (same author: gstrauss@gluelogic.com; same license: BSD-3-Clause) */ |
| 8185 | +#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ |
| 8186 | +static int |
| 8187 | +tls_mbedtls_append_curve (mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id) |
| 8188 | +{ |
| 8189 | + if (1 >= idsz - (nids + 1)) { |
| 8190 | + emsg(MSG_ERROR, "error: too many curves during list expand"); |
| 8191 | + return -1; |
| 8192 | + } |
| 8193 | + ids[++nids] = id; |
| 8194 | + return nids; |
| 8195 | +} |
| 8196 | + |
| 8197 | + |
| 8198 | +static int |
| 8199 | +tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) |
| 8200 | +{ |
| 8201 | + mbedtls_ecp_group_id ids[512]; |
| 8202 | + int nids = -1; |
| 8203 | + const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); |
| 8204 | + const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); |
| 8205 | + |
| 8206 | + for (const char *e = curvelist-1; e; ) { |
| 8207 | + const char * const n = e+1; |
| 8208 | + e = os_strchr(n, ':'); |
| 8209 | + size_t len = e ? (size_t)(e - n) : os_strlen(n); |
| 8210 | + mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; |
| 8211 | + switch (len) { |
| 8212 | + case 5: |
| 8213 | + if (0 == os_memcmp("P-521", n, 5)) |
| 8214 | + grp_id = MBEDTLS_ECP_DP_SECP521R1; |
| 8215 | + else if (0 == os_memcmp("P-384", n, 5)) |
| 8216 | + grp_id = MBEDTLS_ECP_DP_SECP384R1; |
| 8217 | + else if (0 == os_memcmp("P-256", n, 5)) |
| 8218 | + grp_id = MBEDTLS_ECP_DP_SECP256R1; |
| 8219 | + break; |
| 8220 | + case 6: |
| 8221 | + if (0 == os_memcmp("BP-521", n, 6)) |
| 8222 | + grp_id = MBEDTLS_ECP_DP_BP512R1; |
| 8223 | + else if (0 == os_memcmp("BP-384", n, 6)) |
| 8224 | + grp_id = MBEDTLS_ECP_DP_BP384R1; |
| 8225 | + else if (0 == os_memcmp("BP-256", n, 6)) |
| 8226 | + grp_id = MBEDTLS_ECP_DP_BP256R1; |
| 8227 | + break; |
| 8228 | + default: |
| 8229 | + break; |
| 8230 | + } |
| 8231 | + if (grp_id != MBEDTLS_ECP_DP_NONE) { |
| 8232 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, grp_id); |
| 8233 | + if (-1 == nids) return 0; |
| 8234 | + continue; |
| 8235 | + } |
| 8236 | + /* similar to mbedtls_ecp_curve_info_from_name() */ |
| 8237 | + const mbedtls_ecp_curve_info *info; |
| 8238 | + for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info) { |
| 8239 | + if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') |
| 8240 | + break; |
| 8241 | + } |
| 8242 | + if (info->grp_id == MBEDTLS_ECP_DP_NONE) { |
| 8243 | + wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); |
| 8244 | + return 0; |
| 8245 | + } |
| 8246 | + |
| 8247 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, info->grp_id); |
| 8248 | + if (-1 == nids) return 0; |
| 8249 | + } |
| 8250 | + |
| 8251 | + /* mod_openssl configures "prime256v1" if curve list not specified, |
| 8252 | + * but mbedtls provides a list of supported curves if not explicitly set */ |
| 8253 | + if (-1 == nids) return 1; /* empty list; no-op */ |
| 8254 | + |
| 8255 | + ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */ |
| 8256 | + ++nids; |
| 8257 | + |
| 8258 | + /* curves list must be persistent for lifetime of mbedtls_ssl_config */ |
| 8259 | + tls_conf->curves = os_malloc(nids * sizeof(mbedtls_ecp_group_id)); |
| 8260 | + if (tls_conf->curves == NULL) |
| 8261 | + return 0; |
| 8262 | + os_memcpy(tls_conf->curves, ids, nids * sizeof(mbedtls_ecp_group_id)); |
| 8263 | + |
| 8264 | + mbedtls_ssl_conf_curves(&tls_conf->conf, tls_conf->curves); |
| 8265 | + return 1; |
| 8266 | +} |
| 8267 | +#else |
| 8268 | +static int |
| 8269 | +tls_mbedtls_append_curve (uint16_t *ids, int nids, int idsz, const uint16_t id) |
| 8270 | +{ |
| 8271 | + if (1 >= idsz - (nids + 1)) { |
| 8272 | + emsg(MSG_ERROR, "error: too many curves during list expand"); |
| 8273 | + return -1; |
| 8274 | + } |
| 8275 | + ids[++nids] = id; |
| 8276 | + return nids; |
| 8277 | +} |
| 8278 | + |
| 8279 | + |
| 8280 | +static int |
| 8281 | +tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) |
| 8282 | +{ |
| 8283 | + /* TLS Supported Groups (renamed from "EC Named Curve Registry") |
| 8284 | + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 |
| 8285 | + */ |
| 8286 | + uint16_t ids[512]; |
| 8287 | + int nids = -1; |
| 8288 | + const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); |
| 8289 | + const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); |
| 8290 | + |
| 8291 | + for (const char *e = curvelist-1; e; ) { |
| 8292 | + const char * const n = e+1; |
| 8293 | + e = os_strchr(n, ':'); |
| 8294 | + size_t len = e ? (size_t)(e - n) : os_strlen(n); |
| 8295 | + uint16_t tls_id = 0; |
| 8296 | + switch (len) { |
| 8297 | + case 5: |
| 8298 | + if (0 == os_memcmp("P-521", n, 5)) |
| 8299 | + tls_id = 25; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP521R1 */ |
| 8300 | + else if (0 == os_memcmp("P-384", n, 5)) |
| 8301 | + tls_id = 24; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP384R1 */ |
| 8302 | + else if (0 == os_memcmp("P-256", n, 5)) |
| 8303 | + tls_id = 23; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP256R1 */ |
| 8304 | + break; |
| 8305 | + case 6: |
| 8306 | + if (0 == os_memcmp("BP-521", n, 6)) |
| 8307 | + tls_id = 28; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP512R1 */ |
| 8308 | + else if (0 == os_memcmp("BP-384", n, 6)) |
| 8309 | + tls_id = 27; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP384R1 */ |
| 8310 | + else if (0 == os_memcmp("BP-256", n, 6)) |
| 8311 | + tls_id = 26; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP256R1 */ |
| 8312 | + break; |
| 8313 | + default: |
| 8314 | + break; |
| 8315 | + } |
| 8316 | + if (tls_id != 0) { |
| 8317 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, tls_id); |
| 8318 | + if (-1 == nids) return 0; |
| 8319 | + continue; |
| 8320 | + } |
| 8321 | + /* similar to mbedtls_ecp_curve_info_from_name() */ |
| 8322 | + const mbedtls_ecp_curve_info *info; |
| 8323 | + for (info = curve_info; info->tls_id != 0; ++info) { |
| 8324 | + if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') |
| 8325 | + break; |
| 8326 | + } |
| 8327 | + if (info->tls_id == 0) { |
| 8328 | + wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); |
| 8329 | + return 0; |
| 8330 | + } |
| 8331 | + |
| 8332 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, info->tls_id); |
| 8333 | + if (-1 == nids) return 0; |
| 8334 | + } |
| 8335 | + |
| 8336 | + /* mod_openssl configures "prime256v1" if curve list not specified, |
| 8337 | + * but mbedtls provides a list of supported curves if not explicitly set */ |
| 8338 | + if (-1 == nids) return 1; /* empty list; no-op */ |
| 8339 | + |
| 8340 | + ids[++nids] = 0; /* terminate list */ |
| 8341 | + ++nids; |
| 8342 | + |
| 8343 | + /* curves list must be persistent for lifetime of mbedtls_ssl_config */ |
| 8344 | + tls_conf->curves = os_malloc(nids * sizeof(uint16_t)); |
| 8345 | + if (tls_conf->curves == NULL) |
| 8346 | + return 0; |
| 8347 | + os_memcpy(tls_conf->curves, ids, nids * sizeof(uint16_t)); |
| 8348 | + |
| 8349 | + mbedtls_ssl_conf_groups(&tls_conf->conf, tls_conf->curves); |
| 8350 | + return 1; |
| 8351 | +} |
| 8352 | +#endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.1.0 */ |
| 8353 | + |
| 8354 | + |
| 8355 | +/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ |
| 8356 | +static const int suite_AES_256_ephemeral[] = { |
| 8357 | + /* All AES-256 ephemeral suites */ |
| 8358 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
| 8359 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8360 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8361 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, |
| 8362 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, |
| 8363 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, |
| 8364 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, |
| 8365 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, |
| 8366 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, |
| 8367 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, |
| 8368 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, |
| 8369 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, |
| 8370 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 |
| 8371 | +}; |
| 8372 | + |
| 8373 | +/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ |
| 8374 | +static const int suite_AES_128_ephemeral[] = { |
| 8375 | + /* All AES-128 ephemeral suites */ |
| 8376 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
| 8377 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8378 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8379 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, |
| 8380 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, |
| 8381 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, |
| 8382 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8383 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8384 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
| 8385 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
| 8386 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, |
| 8387 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, |
| 8388 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 |
| 8389 | +}; |
| 8390 | + |
| 8391 | +/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ |
| 8392 | +/* HIGH cipher list (mapped from openssl list to mbedtls) */ |
| 8393 | +static const int suite_HIGH[] = { |
| 8394 | + MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
| 8395 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, |
| 8396 | + MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
| 8397 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
| 8398 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8399 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8400 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, |
| 8401 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, |
| 8402 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, |
| 8403 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, |
| 8404 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, |
| 8405 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, |
| 8406 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, |
| 8407 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, |
| 8408 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, |
| 8409 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, |
| 8410 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, |
| 8411 | + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, |
| 8412 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
| 8413 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, |
| 8414 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, |
| 8415 | + MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, |
| 8416 | + MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, |
| 8417 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
| 8418 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8419 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8420 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, |
| 8421 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, |
| 8422 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, |
| 8423 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8424 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8425 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
| 8426 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
| 8427 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, |
| 8428 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, |
| 8429 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, |
| 8430 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8431 | + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8432 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8433 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, |
| 8434 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, |
| 8435 | + MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, |
| 8436 | + MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, |
| 8437 | + MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8438 | + MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8439 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, |
| 8440 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, |
| 8441 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, |
| 8442 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, |
| 8443 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, |
| 8444 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, |
| 8445 | + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8446 | + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8447 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, |
| 8448 | + MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, |
| 8449 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, |
| 8450 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, |
| 8451 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, |
| 8452 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, |
| 8453 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, |
| 8454 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, |
| 8455 | + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8456 | + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8457 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, |
| 8458 | + MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, |
| 8459 | + MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, |
| 8460 | + MBEDTLS_TLS_RSA_WITH_AES_256_CCM, |
| 8461 | + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, |
| 8462 | + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, |
| 8463 | + MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, |
| 8464 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
| 8465 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, |
| 8466 | + MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, |
| 8467 | + MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, |
| 8468 | + MBEDTLS_TLS_RSA_WITH_AES_128_CCM, |
| 8469 | + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, |
| 8470 | + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, |
| 8471 | + MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, |
| 8472 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8473 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, |
| 8474 | + MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, |
| 8475 | + MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8476 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, |
| 8477 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, |
| 8478 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, |
| 8479 | + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8480 | + MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, |
| 8481 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, |
| 8482 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, |
| 8483 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, |
| 8484 | + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8485 | + MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, |
| 8486 | + MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8487 | + MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, |
| 8488 | + MBEDTLS_TLS_PSK_WITH_AES_256_CCM, |
| 8489 | + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, |
| 8490 | + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, |
| 8491 | + MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8492 | + MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, |
| 8493 | + MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, |
| 8494 | + MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, |
| 8495 | + MBEDTLS_TLS_PSK_WITH_AES_128_CCM, |
| 8496 | + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, |
| 8497 | + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, |
| 8498 | + MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8499 | + MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, |
| 8500 | + MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 |
| 8501 | +}; |
| 8502 | + |
| 8503 | + |
| 8504 | +__attribute_noinline__ |
| 8505 | +static int |
| 8506 | +tls_mbedtls_append_ciphersuite (int *ids, int nids, int idsz, const int *x, int xsz) |
| 8507 | +{ |
| 8508 | + if (xsz >= idsz - (nids + 1)) { |
| 8509 | + emsg(MSG_ERROR, "error: too many ciphers during list expand"); |
| 8510 | + return -1; |
| 8511 | + } |
| 8512 | + |
| 8513 | + for (int i = 0; i < xsz; ++i) |
| 8514 | + ids[++nids] = x[i]; |
| 8515 | + |
| 8516 | + return nids; |
| 8517 | +} |
| 8518 | + |
| 8519 | + |
| 8520 | +static int |
| 8521 | +tls_mbedtls_translate_ciphername(int id, char *buf, size_t buflen) |
| 8522 | +{ |
| 8523 | + const mbedtls_ssl_ciphersuite_t *info = |
| 8524 | + mbedtls_ssl_ciphersuite_from_id(id); |
| 8525 | + if (info == NULL) |
| 8526 | + return 0; |
| 8527 | + const char *name = mbedtls_ssl_ciphersuite_get_name(info); |
| 8528 | + const size_t len = os_strlen(name); |
| 8529 | + if (len == 7 && 0 == os_memcmp(name, "unknown", 7)) |
| 8530 | + return 0; |
| 8531 | + if (len >= buflen) |
| 8532 | + return 0; |
| 8533 | + os_strlcpy(buf, name, buflen); |
| 8534 | + |
| 8535 | + /* attempt to translate mbedtls string to openssl string |
| 8536 | + * (some heuristics; incomplete) */ |
| 8537 | + size_t i = 0, j = 0; |
| 8538 | + if (buf[0] == 'T') { |
| 8539 | + if (os_strncmp(buf, "TLS1-3-", 7) == 0) { |
| 8540 | + buf[3] = '-'; |
| 8541 | + j = 4; /* remove "1-3" from "TLS1-3-" prefix */ |
| 8542 | + i = 7; |
| 8543 | + } |
| 8544 | + else if (os_strncmp(buf, "TLS-", 4) == 0) |
| 8545 | + i = 4; /* remove "TLS-" prefix */ |
| 8546 | + } |
| 8547 | + for (; buf[i]; ++i) { |
| 8548 | + if (buf[i] == '-') { |
| 8549 | + if (i >= 3) { |
| 8550 | + if (0 == os_memcmp(buf+i-3, "AES", 3)) |
| 8551 | + continue; /* "AES-" -> "AES" */ |
| 8552 | + } |
| 8553 | + if (i >= 4) { |
| 8554 | + if (0 == os_memcmp(buf+i-4, "WITH", 4)) { |
| 8555 | + j -= 4; /* remove "WITH-" */ |
| 8556 | + continue; |
| 8557 | + } |
| 8558 | + } |
| 8559 | + } |
| 8560 | + buf[j++] = buf[i]; |
| 8561 | + } |
| 8562 | + buf[j] = '\0'; |
| 8563 | + |
| 8564 | + return j; |
| 8565 | +} |
| 8566 | + |
| 8567 | + |
| 8568 | +__attribute_noinline__ |
| 8569 | +static int |
| 8570 | +tls_mbedtls_set_ciphersuites(struct tls_conf *tls_conf, int *ids, int nids) |
| 8571 | +{ |
| 8572 | + /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/ |
| 8573 | + os_free(tls_conf->ciphersuites); |
| 8574 | + tls_conf->ciphersuites = os_malloc(nids * sizeof(int)); |
| 8575 | + if (tls_conf->ciphersuites == NULL) |
| 8576 | + return 0; |
| 8577 | + os_memcpy(tls_conf->ciphersuites, ids, nids * sizeof(int)); |
| 8578 | + mbedtls_ssl_conf_ciphersuites(&tls_conf->conf, tls_conf->ciphersuites); |
| 8579 | + return 1; |
| 8580 | +} |
| 8581 | + |
| 8582 | + |
| 8583 | +static int |
| 8584 | +tls_mbedtls_set_ciphers(struct tls_conf *tls_conf, const char *ciphers) |
| 8585 | +{ |
| 8586 | + char buf[64]; |
| 8587 | + int ids[512]; |
| 8588 | + int nids = -1; |
| 8589 | + const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); |
| 8590 | + const char *next; |
| 8591 | + size_t blen, clen; |
| 8592 | + do { |
| 8593 | + next = os_strchr(ciphers, ':'); |
| 8594 | + clen = next ? (size_t)(next - ciphers) : os_strlen(ciphers); |
| 8595 | + if (!clen) |
| 8596 | + continue; |
| 8597 | + |
| 8598 | + /* special-case a select set of openssl group names for hwsim tests */ |
| 8599 | + /* (review; remove excess code if tests are not run for non-OpenSSL?) */ |
| 8600 | + if (clen == 9 && os_memcmp(ciphers, "SUITEB192", 9) == 0) { |
| 8601 | + static int ssl_preset_suiteb192_ciphersuites[] = { |
| 8602 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
| 8603 | + 0 |
| 8604 | + }; |
| 8605 | + return tls_mbedtls_set_ciphersuites(tls_conf, |
| 8606 | + ssl_preset_suiteb192_ciphersuites, |
| 8607 | + 2); |
| 8608 | + } |
| 8609 | + if (clen == 9 && os_memcmp(ciphers, "SUITEB128", 9) == 0) { |
| 8610 | + static int ssl_preset_suiteb128_ciphersuites[] = { |
| 8611 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
| 8612 | + 0 |
| 8613 | + }; |
| 8614 | + return tls_mbedtls_set_ciphersuites(tls_conf, |
| 8615 | + ssl_preset_suiteb128_ciphersuites, |
| 8616 | + 2); |
| 8617 | + } |
| 8618 | + if (clen == 7 && os_memcmp(ciphers, "DEFAULT", 7) == 0) |
| 8619 | + continue; |
| 8620 | + if (clen == 6 && os_memcmp(ciphers, "AES128", 6) == 0) { |
| 8621 | + nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, |
| 8622 | + suite_AES_128_ephemeral, |
| 8623 | + (int)ARRAY_SIZE(suite_AES_128_ephemeral)); |
| 8624 | + if (nids == -1) |
| 8625 | + return 0; |
| 8626 | + continue; |
| 8627 | + } |
| 8628 | + if (clen == 6 && os_memcmp(ciphers, "AES256", 6) == 0) { |
| 8629 | + nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, |
| 8630 | + suite_AES_256_ephemeral, |
| 8631 | + (int)ARRAY_SIZE(suite_AES_256_ephemeral)); |
| 8632 | + if (nids == -1) |
| 8633 | + return 0; |
| 8634 | + continue; |
| 8635 | + } |
| 8636 | + if (clen == 4 && os_memcmp(ciphers, "HIGH", 4) == 0) { |
| 8637 | + nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_HIGH, |
| 8638 | + (int)ARRAY_SIZE(suite_HIGH)); |
| 8639 | + if (nids == -1) |
| 8640 | + return 0; |
| 8641 | + continue; |
| 8642 | + } |
| 8643 | + /* ignore anonymous cipher group names (?not supported by mbedtls?) */ |
| 8644 | + if (clen == 4 && os_memcmp(ciphers, "!ADH", 4) == 0) |
| 8645 | + continue; |
| 8646 | + if (clen == 6 && os_memcmp(ciphers, "-aECDH", 6) == 0) |
| 8647 | + continue; |
| 8648 | + if (clen == 7 && os_memcmp(ciphers, "-aECDSA", 7) == 0) |
| 8649 | + continue; |
| 8650 | + |
| 8651 | + /* attempt to match mbedtls cipher names |
| 8652 | + * nb: does not support openssl group names or list manipulation syntax |
| 8653 | + * (alt: could copy almost 1200 lines (!!!) of lighttpd mod_mbedtls.c |
| 8654 | + * mod_mbedtls_ssl_conf_ciphersuites() to translate strings) |
| 8655 | + * note: not efficient to rewrite list for each ciphers entry, |
| 8656 | + * but this code is expected to run only at startup |
| 8657 | + */ |
| 8658 | + const int *list = mbedtls_ssl_list_ciphersuites(); |
| 8659 | + for (; *list; ++list) { |
| 8660 | + blen = tls_mbedtls_translate_ciphername(*list,buf,sizeof(buf)); |
| 8661 | + if (!blen) |
| 8662 | + continue; |
| 8663 | + |
| 8664 | + /* matching heuristics additional to translate_ciphername above */ |
| 8665 | + if (blen == clen+4) { |
| 8666 | + char *cbc = os_strstr(buf, "CBC-"); |
| 8667 | + if (cbc) { |
| 8668 | + os_memmove(cbc, cbc+4, blen-(cbc+4-buf)+1); /*(w/ '\0')*/ |
| 8669 | + blen -= 4; |
| 8670 | + } |
| 8671 | + } |
| 8672 | + if (blen >= clen && os_memcmp(ciphers, buf, clen) == 0 |
| 8673 | + && (blen == clen |
| 8674 | + || (blen == clen+7 && os_memcmp(buf+clen, "-SHA256", 7)))) { |
| 8675 | + if (1 >= idsz - (nids + 1)) { |
| 8676 | + emsg(MSG_ERROR, |
| 8677 | + "error: too many ciphers during list expand"); |
| 8678 | + return 0; |
| 8679 | + } |
| 8680 | + ids[++nids] = *list; |
| 8681 | + break; |
| 8682 | + } |
| 8683 | + } |
| 8684 | + if (*list == 0) { |
| 8685 | + wpa_printf(MSG_ERROR, |
| 8686 | + "MTLS: unrecognized cipher: %.*s", (int)clen, ciphers); |
| 8687 | + return 0; |
| 8688 | + } |
| 8689 | + } while ((ciphers = next ? next+1 : NULL)); |
| 8690 | + |
| 8691 | + if (-1 == nids) return 1; /* empty list; no-op */ |
| 8692 | + |
| 8693 | + ids[++nids] = 0; /* terminate list */ |
| 8694 | + ++nids; |
| 8695 | + |
| 8696 | + return tls_mbedtls_set_ciphersuites(tls_conf, ids, nids); |
| 8697 | +} |
| 8698 | + |
| 8699 | + |
| 8700 | +__attribute_noinline__ |
| 8701 | +static int tls_mbedtls_set_item(char **config_item, const char *item) |
| 8702 | +{ |
| 8703 | + os_free(*config_item); |
| 8704 | + *config_item = NULL; |
| 8705 | + return item ? (*config_item = os_strdup(item)) != NULL : 1; |
| 8706 | +} |
| 8707 | + |
| 8708 | + |
| 8709 | +static int tls_connection_set_subject_match(struct tls_conf *tls_conf, |
| 8710 | + const struct tls_connection_params *params) |
| 8711 | +{ |
| 8712 | + int rc = 1; |
| 8713 | + rc &= tls_mbedtls_set_item(&tls_conf->subject_match, |
| 8714 | + params->subject_match); |
| 8715 | + rc &= tls_mbedtls_set_item(&tls_conf->altsubject_match, |
| 8716 | + params->altsubject_match); |
| 8717 | + rc &= tls_mbedtls_set_item(&tls_conf->suffix_match, |
| 8718 | + params->suffix_match); |
| 8719 | + rc &= tls_mbedtls_set_item(&tls_conf->domain_match, |
| 8720 | + params->domain_match); |
| 8721 | + rc &= tls_mbedtls_set_item(&tls_conf->check_cert_subject, |
| 8722 | + params->check_cert_subject); |
| 8723 | + return rc; |
| 8724 | +} |
| 8725 | + |
| 8726 | + |
| 8727 | +/* duplicated in crypto_mbedtls.c:crypto_mbedtls_readfile()*/ |
| 8728 | +__attribute_noinline__ |
| 8729 | +static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n) |
| 8730 | +{ |
| 8731 | + #if 0 /* #ifdef MBEDTLS_FS_IO */ |
| 8732 | + /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ |
| 8733 | + if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { |
| 8734 | + wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); |
| 8735 | + return -1; |
| 8736 | + } |
| 8737 | + #else |
| 8738 | + /*(use os_readfile() so that we can use os_free() |
| 8739 | + *(if we use mbedtls_pk_load_file() above, macros prevent calling free() |
| 8740 | + * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() |
| 8741 | + * on buf aborts in tests if buf not allocated via os_malloc())*/ |
| 8742 | + *buf = (u8 *)os_readfile(path, n); |
| 8743 | + if (!*buf) { |
| 8744 | + wpa_printf(MSG_ERROR, "error: os_readfile %s", path); |
| 8745 | + return -1; |
| 8746 | + } |
| 8747 | + u8 *buf0 = os_realloc(*buf, *n+1); |
| 8748 | + if (!buf0) { |
| 8749 | + bin_clear_free(*buf, *n); |
| 8750 | + *buf = NULL; |
| 8751 | + return -1; |
| 8752 | + } |
| 8753 | + buf0[(*n)++] = '\0'; |
| 8754 | + *buf = buf0; |
| 8755 | + #endif |
| 8756 | + return 0; |
| 8757 | +} |
| 8758 | + |
| 8759 | + |
| 8760 | +static int tls_mbedtls_set_crl(struct tls_conf *tls_conf, const u8 *data, size_t len) |
| 8761 | +{ |
| 8762 | + /* do not use mbedtls_x509_crl_parse() on PEM unless it contains CRL */ |
| 8763 | + if (len && data[len-1] == '\0' |
| 8764 | + && NULL == os_strstr((const char *)data,"-----BEGIN X509 CRL-----") |
| 8765 | + && tls_mbedtls_data_is_pem(data)) |
| 8766 | + return 0; |
| 8767 | + |
| 8768 | + mbedtls_x509_crl crl; |
| 8769 | + mbedtls_x509_crl_init(&crl); |
| 8770 | + int rc = mbedtls_x509_crl_parse(&crl, data, len); |
| 8771 | + if (rc < 0) { |
| 8772 | + mbedtls_x509_crl_free(&crl); |
| 8773 | + return rc == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ? 0 : rc; |
| 8774 | + } |
| 8775 | + |
| 8776 | + mbedtls_x509_crl *crl_new = os_malloc(sizeof(crl)); |
| 8777 | + if (crl_new == NULL) { |
| 8778 | + mbedtls_x509_crl_free(&crl); |
| 8779 | + return MBEDTLS_ERR_X509_ALLOC_FAILED; |
| 8780 | + } |
| 8781 | + os_memcpy(crl_new, &crl, sizeof(crl)); |
| 8782 | + |
| 8783 | + mbedtls_x509_crl *crl_old = tls_conf->crl; |
| 8784 | + tls_conf->crl = crl_new; |
| 8785 | + if (crl_old) { |
| 8786 | + mbedtls_x509_crl_free(crl_old); |
| 8787 | + os_free(crl_old); |
| 8788 | + } |
| 8789 | + return 0; |
| 8790 | +} |
| 8791 | + |
| 8792 | + |
| 8793 | +static int tls_mbedtls_set_ca(struct tls_conf *tls_conf, u8 *data, size_t len) |
| 8794 | +{ |
| 8795 | + /* load crt struct onto stack and then copy into tls_conf in |
| 8796 | + * order to preserve existing tls_conf value if error occurs |
| 8797 | + * |
| 8798 | + * hostapd is not threaded, or else should allocate memory and swap in |
| 8799 | + * pointer reduce race condition. (If threaded, would also need to |
| 8800 | + * keep reference count of use to avoid freeing while still in use.) */ |
| 8801 | + |
| 8802 | + mbedtls_x509_crt crt; |
| 8803 | + mbedtls_x509_crt_init(&crt); |
| 8804 | + int rc = mbedtls_x509_crt_parse(&crt, data, len); |
| 8805 | + if (rc < 0) { |
| 8806 | + mbedtls_x509_crt_free(&crt); |
| 8807 | + return rc; |
| 8808 | + } |
| 8809 | + |
| 8810 | + mbedtls_x509_crt_free(&tls_conf->ca_cert); |
| 8811 | + os_memcpy(&tls_conf->ca_cert, &crt, sizeof(crt)); |
| 8812 | + return 0; |
| 8813 | +} |
| 8814 | + |
| 8815 | + |
| 8816 | +static int tls_mbedtls_set_ca_and_crl(struct tls_conf *tls_conf, const char *ca_cert_file) |
| 8817 | +{ |
| 8818 | + size_t len; |
| 8819 | + u8 *data; |
| 8820 | + if (tls_mbedtls_readfile(ca_cert_file, &data, &len)) |
| 8821 | + return -1; |
| 8822 | + |
| 8823 | + int rc; |
| 8824 | + if (0 == (rc = tls_mbedtls_set_ca(tls_conf, data, len)) |
| 8825 | + && (!tls_mbedtls_data_is_pem(data) /*skip parse for CRL if not PEM*/ |
| 8826 | + || 0 == (rc = tls_mbedtls_set_crl(tls_conf, data, len)))) { |
| 8827 | + mbedtls_ssl_conf_ca_chain(&tls_conf->conf, |
| 8828 | + &tls_conf->ca_cert, |
| 8829 | + tls_conf->crl); |
| 8830 | + } |
| 8831 | + else { |
| 8832 | + elog(rc, __func__); |
| 8833 | + emsg(MSG_ERROR, ca_cert_file); |
| 8834 | + } |
| 8835 | + |
| 8836 | + forced_memzero(data, len); |
| 8837 | + os_free(data); |
| 8838 | + return rc; |
| 8839 | +} |
| 8840 | + |
| 8841 | + |
| 8842 | +static void tls_mbedtls_refresh_crl(void) |
| 8843 | +{ |
| 8844 | + /* check for CRL refresh |
| 8845 | + * continue even if error occurs; continue with previous cert, CRL */ |
| 8846 | + unsigned int crl_reload_interval = tls_ctx_global.crl_reload_interval; |
| 8847 | + const char *ca_cert_file = tls_ctx_global.ca_cert_file; |
| 8848 | + if (!crl_reload_interval || !ca_cert_file) |
| 8849 | + return; |
| 8850 | + |
| 8851 | + struct os_reltime *previous = &tls_ctx_global.crl_reload_previous; |
| 8852 | + struct os_reltime now; |
| 8853 | + if (os_get_reltime(&now) != 0 |
| 8854 | + || !os_reltime_expired(&now, previous, crl_reload_interval)) |
| 8855 | + return; |
| 8856 | + |
| 8857 | + /* Note: modifying global state is not thread-safe |
| 8858 | + * if in use by existing connections |
| 8859 | + * |
| 8860 | + * src/utils/os.h does not provide a portable stat() |
| 8861 | + * or else it would be a good idea to check mtime and size, |
| 8862 | + * and avoid reloading if file has not changed */ |
| 8863 | + |
| 8864 | + if (tls_mbedtls_set_ca_and_crl(tls_ctx_global.tls_conf, ca_cert_file) == 0) |
| 8865 | + *previous = now; |
| 8866 | +} |
| 8867 | + |
| 8868 | + |
| 8869 | +static int tls_mbedtls_set_ca_cert(struct tls_conf *tls_conf, |
| 8870 | + const struct tls_connection_params *params) |
| 8871 | +{ |
| 8872 | + if (params->ca_cert) { |
| 8873 | + if (os_strncmp(params->ca_cert, "probe://", 8) == 0) { |
| 8874 | + tls_conf->ca_cert_probe = 1; |
| 8875 | + tls_conf->has_ca_cert = 1; |
| 8876 | + return 0; |
| 8877 | + } |
| 8878 | + |
| 8879 | + if (os_strncmp(params->ca_cert, "hash://", 7) == 0) { |
| 8880 | + const char *pos = params->ca_cert + 7; |
| 8881 | + if (os_strncmp(pos, "server/sha256/", 14) != 0) { |
| 8882 | + emsg(MSG_ERROR, "unsupported ca_cert hash value"); |
| 8883 | + return -1; |
| 8884 | + } |
| 8885 | + pos += 14; |
| 8886 | + if (os_strlen(pos) != SHA256_DIGEST_LENGTH*2) { |
| 8887 | + emsg(MSG_ERROR, "unexpected ca_cert hash length"); |
| 8888 | + return -1; |
| 8889 | + } |
| 8890 | + if (hexstr2bin(pos, tls_conf->ca_cert_hash, |
| 8891 | + SHA256_DIGEST_LENGTH) < 0) { |
| 8892 | + emsg(MSG_ERROR, "invalid ca_cert hash value"); |
| 8893 | + return -1; |
| 8894 | + } |
| 8895 | + emsg(MSG_DEBUG, "checking only server certificate match"); |
| 8896 | + tls_conf->verify_depth0_only = 1; |
| 8897 | + tls_conf->has_ca_cert = 1; |
| 8898 | + return 0; |
| 8899 | + } |
| 8900 | + |
| 8901 | + if (tls_mbedtls_set_ca_and_crl(tls_conf, params->ca_cert) != 0) |
| 8902 | + return -1; |
| 8903 | + } |
| 8904 | + if (params->ca_cert_blob) { |
| 8905 | + size_t len = params->ca_cert_blob_len; |
| 8906 | + int is_pem = tls_mbedtls_data_is_pem(params->ca_cert_blob); |
| 8907 | + if (len && params->ca_cert_blob[len-1] != '\0' && is_pem) |
| 8908 | + ++len; /*(include '\0' in len for PEM)*/ |
| 8909 | + int ret = mbedtls_x509_crt_parse(&tls_conf->ca_cert, |
| 8910 | + params->ca_cert_blob, len); |
| 8911 | + if (ret != 0) { |
| 8912 | + elog(ret, "mbedtls_x509_crt_parse"); |
| 8913 | + return -1; |
| 8914 | + } |
| 8915 | + if (is_pem) { /*(ca_cert_blob in DER format contains ca cert only)*/ |
| 8916 | + ret = tls_mbedtls_set_crl(tls_conf, params->ca_cert_blob, len); |
| 8917 | + if (ret != 0) { |
| 8918 | + elog(ret, "mbedtls_x509_crl_parse"); |
| 8919 | + return -1; |
| 8920 | + } |
| 8921 | + } |
| 8922 | + } |
| 8923 | + |
| 8924 | + if (mbedtls_x509_time_is_future(&tls_conf->ca_cert.valid_from) |
| 8925 | + || mbedtls_x509_time_is_past(&tls_conf->ca_cert.valid_to)) { |
| 8926 | + emsg(MSG_WARNING, "ca_cert expired or not yet valid"); |
| 8927 | + if (params->ca_cert) |
| 8928 | + emsg(MSG_WARNING, params->ca_cert); |
| 8929 | + } |
| 8930 | + |
| 8931 | + tls_conf->has_ca_cert = 1; |
| 8932 | + return 0; |
| 8933 | +} |
| 8934 | + |
| 8935 | + |
| 8936 | +static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, |
| 8937 | + const struct tls_connection_params *params) |
| 8938 | +{ |
| 8939 | + int ret; |
| 8940 | + |
| 8941 | + if (params->ca_cert || params->ca_cert_blob) { |
| 8942 | + if (tls_mbedtls_set_ca_cert(tls_conf, params) != 0) |
| 8943 | + return -1; |
| 8944 | + } |
| 8945 | + else if (params->ca_path) { |
| 8946 | + emsg(MSG_INFO, "ca_path support not implemented"); |
| 8947 | + return -1; |
| 8948 | + } |
| 8949 | + |
| 8950 | + if (!tls_conf->has_ca_cert) |
| 8951 | + mbedtls_ssl_conf_authmode(&tls_conf->conf, MBEDTLS_SSL_VERIFY_NONE); |
| 8952 | + else { |
| 8953 | + /* Initial setting: REQUIRED for client, OPTIONAL for server |
| 8954 | + * (see also tls_connection_set_verify()) */ |
| 8955 | + tls_conf->verify_peer = (tls_ctx_global.tls_conf == NULL); |
| 8956 | + int authmode = tls_conf->verify_peer |
| 8957 | + ? MBEDTLS_SSL_VERIFY_REQUIRED |
| 8958 | + : MBEDTLS_SSL_VERIFY_OPTIONAL; |
| 8959 | + mbedtls_ssl_conf_authmode(&tls_conf->conf, authmode); |
| 8960 | + mbedtls_ssl_conf_ca_chain(&tls_conf->conf, |
| 8961 | + &tls_conf->ca_cert, |
| 8962 | + tls_conf->crl); |
| 8963 | + |
| 8964 | + if (!tls_connection_set_subject_match(tls_conf, params)) |
| 8965 | + return -1; |
| 8966 | + } |
| 8967 | + |
| 8968 | + if (params->client_cert2) /*(yes, server_cert2 in msg below)*/ |
| 8969 | + emsg(MSG_INFO, "server_cert2 support not implemented"); |
| 8970 | + |
| 8971 | + if (params->client_cert) { |
| 8972 | + size_t len; |
| 8973 | + u8 *data; |
| 8974 | + if (tls_mbedtls_readfile(params->client_cert, &data, &len)) |
| 8975 | + return -1; |
| 8976 | + ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, data, len); |
| 8977 | + forced_memzero(data, len); |
| 8978 | + os_free(data); |
| 8979 | + } |
| 8980 | + if (params->client_cert_blob) { |
| 8981 | + size_t len = params->client_cert_blob_len; |
| 8982 | + if (len && params->client_cert_blob[len-1] != '\0' |
| 8983 | + && tls_mbedtls_data_is_pem(params->client_cert_blob)) |
| 8984 | + ++len; /*(include '\0' in len for PEM)*/ |
| 8985 | + ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, |
| 8986 | + params->client_cert_blob, len); |
| 8987 | + } |
| 8988 | + if (params->client_cert || params->client_cert_blob) { |
| 8989 | + if (ret < 0) { |
| 8990 | + elog(ret, "mbedtls_x509_crt_parse"); |
| 8991 | + if (params->client_cert) |
| 8992 | + emsg(MSG_ERROR, params->client_cert); |
| 8993 | + return -1; |
| 8994 | + } |
| 8995 | + if (mbedtls_x509_time_is_future(&tls_conf->client_cert.valid_from) |
| 8996 | + || mbedtls_x509_time_is_past(&tls_conf->client_cert.valid_to)) { |
| 8997 | + emsg(MSG_WARNING, "cert expired or not yet valid"); |
| 8998 | + if (params->client_cert) |
| 8999 | + emsg(MSG_WARNING, params->client_cert); |
| 9000 | + } |
| 9001 | + tls_conf->has_client_cert = 1; |
| 9002 | + } |
| 9003 | + |
| 9004 | + if (params->private_key || params->private_key_blob) { |
| 9005 | + size_t len = params->private_key_blob_len; |
| 9006 | + u8 *data; |
| 9007 | + *(const u8 **)&data = params->private_key_blob; |
| 9008 | + if (len && data[len-1] != '\0' && tls_mbedtls_data_is_pem(data)) |
| 9009 | + ++len; /*(include '\0' in len for PEM)*/ |
| 9010 | + if (params->private_key |
| 9011 | + && tls_mbedtls_readfile(params->private_key, &data, &len)) { |
| 9012 | + return -1; |
| 9013 | + } |
| 9014 | + const char *pwd = params->private_key_passwd; |
| 9015 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9016 | + ret = mbedtls_pk_parse_key(&tls_conf->private_key, |
| 9017 | + data, len, |
| 9018 | + (const unsigned char *)pwd, |
| 9019 | + pwd ? os_strlen(pwd) : 0, |
| 9020 | + mbedtls_ctr_drbg_random, |
| 9021 | + tls_ctx_global.ctr_drbg); |
| 9022 | + #else |
| 9023 | + ret = mbedtls_pk_parse_key(&tls_conf->private_key, |
| 9024 | + data, len, |
| 9025 | + (const unsigned char *)pwd, |
| 9026 | + pwd ? os_strlen(pwd) : 0); |
| 9027 | + #endif |
| 9028 | + if (params->private_key) { |
| 9029 | + forced_memzero(data, len); |
| 9030 | + os_free(data); |
| 9031 | + } |
| 9032 | + if (ret < 0) { |
| 9033 | + elog(ret, "mbedtls_pk_parse_key"); |
| 9034 | + return -1; |
| 9035 | + } |
| 9036 | + tls_conf->has_private_key = 1; |
| 9037 | + } |
| 9038 | + |
| 9039 | + if (tls_conf->has_client_cert && tls_conf->has_private_key) { |
| 9040 | + ret = mbedtls_ssl_conf_own_cert( |
| 9041 | + &tls_conf->conf, &tls_conf->client_cert, &tls_conf->private_key); |
| 9042 | + if (ret < 0) { |
| 9043 | + elog(ret, "mbedtls_ssl_conf_own_cert"); |
| 9044 | + return -1; |
| 9045 | + } |
| 9046 | + } |
| 9047 | + |
| 9048 | + return 0; |
| 9049 | +} |
| 9050 | + |
| 9051 | + |
| 9052 | +/* mbedtls_x509_crt_profile_suiteb plus rsa_min_bitlen 2048 */ |
| 9053 | +/* (reference: see also mbedtls_x509_crt_profile_next) */ |
| 9054 | +/* ??? should permit SHA-512, too, and additional curves ??? */ |
| 9055 | +static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 = |
| 9056 | +{ |
| 9057 | + /* Only SHA-256 and 384 */ |
| 9058 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | |
| 9059 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), |
| 9060 | + /* Only ECDSA */ |
| 9061 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | |
| 9062 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), |
| 9063 | +#if defined(MBEDTLS_ECP_C) |
| 9064 | + /* Only NIST P-256 and P-384 */ |
| 9065 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | |
| 9066 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), |
| 9067 | +#else |
| 9068 | + 0, |
| 9069 | +#endif |
| 9070 | + 2048, |
| 9071 | +}; |
| 9072 | + |
| 9073 | + |
| 9074 | +/* stricter than mbedtls_x509_crt_profile_suiteb */ |
| 9075 | +/* (reference: see also mbedtls_x509_crt_profile_next) */ |
| 9076 | +/* ??? should permit SHA-512, too, and additional curves ??? */ |
| 9077 | +static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 = |
| 9078 | +{ |
| 9079 | + /* Only SHA-384 */ |
| 9080 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), |
| 9081 | + /* Only ECDSA */ |
| 9082 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | |
| 9083 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), |
| 9084 | +#if defined(MBEDTLS_ECP_C) |
| 9085 | + /* Only NIST P-384 */ |
| 9086 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), |
| 9087 | +#else |
| 9088 | + 0, |
| 9089 | +#endif |
| 9090 | + 3072, |
| 9091 | +}; |
| 9092 | + |
| 9093 | + |
| 9094 | +/* stricter than mbedtls_x509_crt_profile_suiteb except allow any PK alg */ |
| 9095 | +/* (reference: see also mbedtls_x509_crt_profile_next) */ |
| 9096 | +/* ??? should permit SHA-512, too, and additional curves ??? */ |
| 9097 | +static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192_anypk = |
| 9098 | +{ |
| 9099 | + /* Only SHA-384 */ |
| 9100 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), |
| 9101 | + 0xFFFFFFF, /* Any PK alg */ |
| 9102 | +#if defined(MBEDTLS_ECP_C) |
| 9103 | + /* Only NIST P-384 */ |
| 9104 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), |
| 9105 | +#else |
| 9106 | + 0, |
| 9107 | +#endif |
| 9108 | + 3072, |
| 9109 | +}; |
| 9110 | + |
| 9111 | + |
| 9112 | +static int tls_mbedtls_set_params(struct tls_conf *tls_conf, |
| 9113 | + const struct tls_connection_params *params) |
| 9114 | +{ |
| 9115 | + tls_conf->flags = params->flags; |
| 9116 | + |
| 9117 | + if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP_ALL) { |
| 9118 | + emsg(MSG_INFO, "ocsp=3 not supported"); |
| 9119 | + return -1; |
| 9120 | + } |
| 9121 | + |
| 9122 | + if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP) { |
| 9123 | + emsg(MSG_INFO, "ocsp not supported"); |
| 9124 | + return -1; |
| 9125 | + } |
| 9126 | + |
| 9127 | + int suiteb128 = 0; |
| 9128 | + int suiteb192 = 0; |
| 9129 | + if (params->openssl_ciphers) { |
| 9130 | + if (os_strcmp(params->openssl_ciphers, "SUITEB192") == 0) { |
| 9131 | + suiteb192 = 1; |
| 9132 | + tls_conf->flags |= TLS_CONN_SUITEB; |
| 9133 | + } |
| 9134 | + if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) { |
| 9135 | + suiteb128 = 1; |
| 9136 | + tls_conf->flags |= TLS_CONN_SUITEB; |
| 9137 | + } |
| 9138 | + } |
| 9139 | + |
| 9140 | + int ret = mbedtls_ssl_config_defaults( |
| 9141 | + &tls_conf->conf, tls_ctx_global.tls_conf ? MBEDTLS_SSL_IS_SERVER |
| 9142 | + : MBEDTLS_SSL_IS_CLIENT, |
| 9143 | + MBEDTLS_SSL_TRANSPORT_STREAM, |
| 9144 | + (tls_conf->flags & TLS_CONN_SUITEB) ? MBEDTLS_SSL_PRESET_SUITEB |
| 9145 | + : MBEDTLS_SSL_PRESET_DEFAULT); |
| 9146 | + if (ret != 0) { |
| 9147 | + elog(ret, "mbedtls_ssl_config_defaults"); |
| 9148 | + return -1; |
| 9149 | + } |
| 9150 | + |
| 9151 | + if (suiteb128) { |
| 9152 | + mbedtls_ssl_conf_cert_profile(&tls_conf->conf, |
| 9153 | + &tls_mbedtls_crt_profile_suiteb128); |
| 9154 | + mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 2048); |
| 9155 | + } |
| 9156 | + else if (suiteb192) { |
| 9157 | + mbedtls_ssl_conf_cert_profile(&tls_conf->conf, |
| 9158 | + &tls_mbedtls_crt_profile_suiteb192); |
| 9159 | + mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); |
| 9160 | + } |
| 9161 | + else if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 9162 | + /* treat as suiteb192 while allowing any PK algorithm */ |
| 9163 | + mbedtls_ssl_conf_cert_profile(&tls_conf->conf, |
| 9164 | + &tls_mbedtls_crt_profile_suiteb192_anypk); |
| 9165 | + mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); |
| 9166 | + } |
| 9167 | + |
| 9168 | + tls_mbedtls_set_allowed_tls_vers(tls_conf, &tls_conf->conf); |
| 9169 | + ret = tls_mbedtls_set_certs(tls_conf, params); |
| 9170 | + if (ret != 0) |
| 9171 | + return -1; |
| 9172 | + |
| 9173 | + if (params->dh_file |
| 9174 | + && !tls_mbedtls_set_dhparams(tls_conf, params->dh_file)) { |
| 9175 | + return -1; |
| 9176 | + } |
| 9177 | + |
| 9178 | + if (params->openssl_ecdh_curves |
| 9179 | + && !tls_mbedtls_set_curves(tls_conf, params->openssl_ecdh_curves)) { |
| 9180 | + return -1; |
| 9181 | + } |
| 9182 | + |
| 9183 | + if (params->openssl_ciphers) { |
| 9184 | + if (!tls_mbedtls_set_ciphers(tls_conf, params->openssl_ciphers)) |
| 9185 | + return -1; |
| 9186 | + } |
| 9187 | + else if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 9188 | + /* special-case a select set of ciphers for hwsim tests */ |
| 9189 | + if (!tls_mbedtls_set_ciphers(tls_conf, |
| 9190 | + (tls_conf->flags & TLS_CONN_SUITEB_NO_ECDH) |
| 9191 | + ? "DHE-RSA-AES256-GCM-SHA384" |
| 9192 | + : "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384")) |
| 9193 | + return -1; |
| 9194 | + } |
| 9195 | + |
| 9196 | + return 0; |
| 9197 | +} |
| 9198 | + |
| 9199 | + |
| 9200 | +int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, |
| 9201 | + const struct tls_connection_params *params) |
| 9202 | +{ |
| 9203 | + if (conn == NULL || params == NULL) |
| 9204 | + return -1; |
| 9205 | + |
| 9206 | + tls_conf_deinit(conn->tls_conf); |
| 9207 | + struct tls_conf *tls_conf = conn->tls_conf = tls_conf_init(tls_ctx); |
| 9208 | + if (tls_conf == NULL) |
| 9209 | + return -1; |
| 9210 | + |
| 9211 | + if (tls_ctx_global.tls_conf) { |
| 9212 | + tls_conf->check_crl = tls_ctx_global.tls_conf->check_crl; |
| 9213 | + tls_conf->check_crl_strict = tls_ctx_global.tls_conf->check_crl_strict; |
| 9214 | + /*(tls_openssl.c inherits check_cert_subject from global conf)*/ |
| 9215 | + if (tls_ctx_global.tls_conf->check_cert_subject) { |
| 9216 | + tls_conf->check_cert_subject = |
| 9217 | + os_strdup(tls_ctx_global.tls_conf->check_cert_subject); |
| 9218 | + if (tls_conf->check_cert_subject == NULL) |
| 9219 | + return -1; |
| 9220 | + } |
| 9221 | + } |
| 9222 | + |
| 9223 | + if (tls_mbedtls_set_params(tls_conf, params) != 0) |
| 9224 | + return -1; |
| 9225 | + conn->verify_peer = tls_conf->verify_peer; |
| 9226 | + |
| 9227 | + return tls_mbedtls_ssl_setup(conn); |
| 9228 | +} |
| 9229 | + |
| 9230 | + |
| 9231 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9232 | + |
| 9233 | +static int tls_mbedtls_clienthello_session_ticket_prep (struct tls_connection *conn, |
| 9234 | + const u8 *data, size_t len) |
| 9235 | +{ |
| 9236 | + if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) |
| 9237 | + return -1; |
| 9238 | + if (conn->clienthello_session_ticket) |
| 9239 | + tls_connection_deinit_clienthello_session_ticket(conn); |
| 9240 | + if (len) { |
| 9241 | + conn->clienthello_session_ticket = mbedtls_calloc(1, len); |
| 9242 | + if (conn->clienthello_session_ticket == NULL) |
| 9243 | + return -1; |
| 9244 | + conn->clienthello_session_ticket_len = len; |
| 9245 | + os_memcpy(conn->clienthello_session_ticket, data, len); |
| 9246 | + } |
| 9247 | + return 0; |
| 9248 | +} |
| 9249 | + |
| 9250 | + |
| 9251 | +static void tls_mbedtls_clienthello_session_ticket_set (struct tls_connection *conn) |
| 9252 | +{ |
| 9253 | + mbedtls_ssl_session *sess = conn->ssl.MBEDTLS_PRIVATE(session_negotiate); |
| 9254 | + if (sess->MBEDTLS_PRIVATE(ticket)) { |
| 9255 | + mbedtls_platform_zeroize(sess->MBEDTLS_PRIVATE(ticket), |
| 9256 | + sess->MBEDTLS_PRIVATE(ticket_len)); |
| 9257 | + mbedtls_free(sess->MBEDTLS_PRIVATE(ticket)); |
| 9258 | + } |
| 9259 | + sess->MBEDTLS_PRIVATE(ticket) = conn->clienthello_session_ticket; |
| 9260 | + sess->MBEDTLS_PRIVATE(ticket_len) = conn->clienthello_session_ticket_len; |
| 9261 | + sess->MBEDTLS_PRIVATE(ticket_lifetime) = 86400;/* XXX: can hint be 0? */ |
| 9262 | + |
| 9263 | + conn->clienthello_session_ticket = NULL; |
| 9264 | + conn->clienthello_session_ticket_len = 0; |
| 9265 | +} |
| 9266 | + |
| 9267 | + |
| 9268 | +static int tls_mbedtls_ssl_ticket_write(void *p_ticket, |
| 9269 | + const mbedtls_ssl_session *session, |
| 9270 | + unsigned char *start, |
| 9271 | + const unsigned char *end, |
| 9272 | + size_t *tlen, |
| 9273 | + uint32_t *lifetime) |
| 9274 | +{ |
| 9275 | + struct tls_connection *conn = p_ticket; |
| 9276 | + if (conn && conn->session_ticket_cb) { |
| 9277 | + /* see tls_mbedtls_clienthello_session_ticket_prep() */ |
| 9278 | + /* see tls_mbedtls_clienthello_session_ticket_set() */ |
| 9279 | + return 0; |
| 9280 | + } |
| 9281 | + |
| 9282 | + return mbedtls_ssl_ticket_write(&tls_ctx_global.ticket_ctx, |
| 9283 | + session, start, end, tlen, lifetime); |
| 9284 | +} |
| 9285 | + |
| 9286 | + |
| 9287 | +static int tls_mbedtls_ssl_ticket_parse(void *p_ticket, |
| 9288 | + mbedtls_ssl_session *session, |
| 9289 | + unsigned char *buf, |
| 9290 | + size_t len) |
| 9291 | +{ |
| 9292 | + /* XXX: TODO: not implemented in client; |
| 9293 | + * mbedtls_ssl_conf_session_tickets_cb() callbacks only for TLS server*/ |
| 9294 | + |
| 9295 | + if (len == 0) |
| 9296 | + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; |
| 9297 | + |
| 9298 | + struct tls_connection *conn = p_ticket; |
| 9299 | + if (conn && conn->session_ticket_cb) { |
| 9300 | + /* XXX: have random and secret been initialized yet? |
| 9301 | + * or must keys first be exported? |
| 9302 | + * EAP-FAST uses all args, EAP-TEAP only uses secret */ |
| 9303 | + struct tls_random data; |
| 9304 | + if (tls_connection_get_random(NULL, conn, &data) != 0) |
| 9305 | + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; |
| 9306 | + int ret = |
| 9307 | + conn->session_ticket_cb(conn->session_ticket_cb_ctx, |
| 9308 | + buf, len, |
| 9309 | + data.client_random, |
| 9310 | + data.server_random, |
| 9311 | + conn->expkey_secret); |
| 9312 | + if (ret == 1) { |
| 9313 | + conn->resumed = 1; |
| 9314 | + return 0; |
| 9315 | + } |
| 9316 | + emsg(MSG_ERROR, "EAP session ticket ext not implemented"); |
| 9317 | + return MBEDTLS_ERR_SSL_INVALID_MAC; |
| 9318 | + /*(non-zero return used for mbedtls debug logging)*/ |
| 9319 | + } |
| 9320 | + |
| 9321 | + /* XXX: TODO always use tls_mbedtls_ssl_ticket_parse() for callback? */ |
| 9322 | + int rc = mbedtls_ssl_ticket_parse(&tls_ctx_global.ticket_ctx, |
| 9323 | + session, buf, len); |
| 9324 | + if (conn) |
| 9325 | + conn->resumed = (rc == 0); |
| 9326 | + return rc; |
| 9327 | +} |
| 9328 | + |
| 9329 | +#endif /* TLS_MBEDTLS_SESSION_TICKETS */ |
| 9330 | + |
| 9331 | + |
| 9332 | +__attribute_cold__ |
| 9333 | +int tls_global_set_params(void *tls_ctx, |
| 9334 | + const struct tls_connection_params *params) |
| 9335 | +{ |
| 9336 | + /* XXX: why might global_set_params be called more than once? */ |
| 9337 | + if (tls_ctx_global.tls_conf) |
| 9338 | + tls_conf_deinit(tls_ctx_global.tls_conf); |
| 9339 | + tls_ctx_global.tls_conf = tls_conf_init(tls_ctx); |
| 9340 | + if (tls_ctx_global.tls_conf == NULL) |
| 9341 | + return -1; |
| 9342 | + |
| 9343 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 9344 | + #ifdef MBEDTLS_SSL_TICKET_C |
| 9345 | + if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET)) |
| 9346 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9347 | + mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, |
| 9348 | + tls_mbedtls_ssl_ticket_write, |
| 9349 | + tls_mbedtls_ssl_ticket_parse, |
| 9350 | + NULL); |
| 9351 | + #else |
| 9352 | + mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, |
| 9353 | + mbedtls_ssl_ticket_write, |
| 9354 | + mbedtls_ssl_ticket_parse, |
| 9355 | + &tls_ctx_global.ticket_ctx); |
| 9356 | + #endif |
| 9357 | + #endif |
| 9358 | + #endif |
| 9359 | + |
| 9360 | + os_free(tls_ctx_global.ocsp_stapling_response); |
| 9361 | + tls_ctx_global.ocsp_stapling_response = NULL; |
| 9362 | + if (params->ocsp_stapling_response) |
| 9363 | + tls_ctx_global.ocsp_stapling_response = |
| 9364 | + os_strdup(params->ocsp_stapling_response); |
| 9365 | + |
| 9366 | + os_free(tls_ctx_global.ca_cert_file); |
| 9367 | + tls_ctx_global.ca_cert_file = NULL; |
| 9368 | + if (params->ca_cert) |
| 9369 | + tls_ctx_global.ca_cert_file = os_strdup(params->ca_cert); |
| 9370 | + return tls_mbedtls_set_params(tls_ctx_global.tls_conf, params); |
| 9371 | +} |
| 9372 | + |
| 9373 | + |
| 9374 | +int tls_global_set_verify(void *tls_ctx, int check_crl, int strict) |
| 9375 | +{ |
| 9376 | + tls_ctx_global.tls_conf->check_crl = check_crl; |
| 9377 | + tls_ctx_global.tls_conf->check_crl_strict = strict; /*(time checks)*/ |
| 9378 | + return 0; |
| 9379 | +} |
| 9380 | + |
| 9381 | + |
| 9382 | +int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, |
| 9383 | + int verify_peer, unsigned int flags, |
| 9384 | + const u8 *session_ctx, size_t session_ctx_len) |
| 9385 | +{ |
| 9386 | + /*(EAP server-side calls this from eap_server_tls_ssl_init())*/ |
| 9387 | + if (conn == NULL) |
| 9388 | + return -1; |
| 9389 | + |
| 9390 | + conn->tls_conf->flags |= flags;/* TODO: reprocess flags, if necessary */ |
| 9391 | + |
| 9392 | + int authmode; |
| 9393 | + switch (verify_peer) { |
| 9394 | + case 2: authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; break;/*(eap_teap_init())*/ |
| 9395 | + case 1: authmode = MBEDTLS_SSL_VERIFY_REQUIRED; break; |
| 9396 | + default: authmode = MBEDTLS_SSL_VERIFY_NONE; break; |
| 9397 | + } |
| 9398 | + mbedtls_ssl_set_hs_authmode(&conn->ssl, authmode); |
| 9399 | + |
| 9400 | + if ((conn->verify_peer = (authmode != MBEDTLS_SSL_VERIFY_NONE))) |
| 9401 | + mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); |
| 9402 | + else |
| 9403 | + mbedtls_ssl_set_verify(&conn->ssl, NULL, NULL); |
| 9404 | + |
| 9405 | + return 0; |
| 9406 | +} |
| 9407 | + |
| 9408 | + |
| 9409 | +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9410 | +static void tls_connection_export_keys_cb( |
| 9411 | + void *p_expkey, mbedtls_ssl_key_export_type secret_type, |
| 9412 | + const unsigned char *secret, size_t secret_len, |
| 9413 | + const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9414 | + const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9415 | + mbedtls_tls_prf_types tls_prf_type) |
| 9416 | +{ |
| 9417 | + struct tls_connection *conn = p_expkey; |
| 9418 | + conn->tls_prf_type = tls_prf_type; |
| 9419 | + if (!tls_prf_type) |
| 9420 | + return; |
| 9421 | + if (secret_len > sizeof(conn->expkey_secret)) { |
| 9422 | + emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long"); |
| 9423 | + conn->tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE; /* 0 */ |
| 9424 | + return; |
| 9425 | + } |
| 9426 | + conn->expkey_secret_len = secret_len; |
| 9427 | + os_memcpy(conn->expkey_secret, secret, secret_len); |
| 9428 | + os_memcpy(conn->expkey_randbytes, |
| 9429 | + client_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9430 | + os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, |
| 9431 | + server_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9432 | +} |
| 9433 | +#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9434 | +static int tls_connection_export_keys_cb( |
| 9435 | + void *p_expkey, |
| 9436 | + const unsigned char *ms, |
| 9437 | + const unsigned char *kb, |
| 9438 | + size_t maclen, |
| 9439 | + size_t keylen, |
| 9440 | + size_t ivlen, |
| 9441 | + const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9442 | + const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9443 | + mbedtls_tls_prf_types tls_prf_type ) |
| 9444 | +{ |
| 9445 | + struct tls_connection *conn = p_expkey; |
| 9446 | + conn->tls_prf_type = tls_prf_type; |
| 9447 | + if (!tls_prf_type) |
| 9448 | + return -1; /*(return value ignored by mbedtls)*/ |
| 9449 | + conn->expkey_keyblock_size = maclen + keylen + ivlen; |
| 9450 | + conn->expkey_secret_len = MBEDTLS_EXPKEY_FIXED_SECRET_LEN; |
| 9451 | + os_memcpy(conn->expkey_secret, ms, MBEDTLS_EXPKEY_FIXED_SECRET_LEN); |
| 9452 | + os_memcpy(conn->expkey_randbytes, |
| 9453 | + client_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9454 | + os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, |
| 9455 | + server_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9456 | + return 0; |
| 9457 | +} |
| 9458 | +#endif |
| 9459 | + |
| 9460 | + |
| 9461 | +int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, |
| 9462 | + struct tls_random *data) |
| 9463 | +{ |
| 9464 | + if (!conn || !conn->tls_prf_type) |
| 9465 | + return -1; |
| 9466 | + data->client_random = conn->expkey_randbytes; |
| 9467 | + data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN; |
| 9468 | + data->server_random = conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN; |
| 9469 | + data->server_random_len = MBEDTLS_EXPKEY_RAND_LEN; |
| 9470 | + return 0; |
| 9471 | +} |
| 9472 | + |
| 9473 | + |
| 9474 | +int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, |
| 9475 | + const char *label, const u8 *context, |
| 9476 | + size_t context_len, u8 *out, size_t out_len) |
| 9477 | +{ |
| 9478 | + /* (EAP-PEAP EAP-TLS EAP-TTLS) */ |
| 9479 | + #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9480 | + return (conn && conn->established && conn->tls_prf_type) |
| 9481 | + ? mbedtls_ssl_tls_prf(conn->tls_prf_type, |
| 9482 | + conn->expkey_secret, conn->expkey_secret_len, label, |
| 9483 | + conn->expkey_randbytes, |
| 9484 | + sizeof(conn->expkey_randbytes), out, out_len) |
| 9485 | + : -1; |
| 9486 | + #else |
| 9487 | + /* not implemented here for mbedtls < 2.18.0 */ |
| 9488 | + return -1; |
| 9489 | + #endif |
| 9490 | +} |
| 9491 | + |
| 9492 | + |
| 9493 | +#ifdef TLS_MBEDTLS_EAP_FAST |
| 9494 | + |
| 9495 | +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9496 | +/* keyblock size info is not exposed in mbed TLS 3.0.0 */ |
| 9497 | +/* extracted from mbedtls library/ssl_tls.c:ssl_tls12_populate_transform() */ |
| 9498 | +#include <mbedtls/ssl_ciphersuites.h> |
| 9499 | +#include <mbedtls/cipher.h> |
| 9500 | +static size_t tls_mbedtls_ssl_keyblock_size (mbedtls_ssl_context *ssl) |
| 9501 | +{ |
| 9502 | + #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */ |
| 9503 | + #if defined(MBEDTLS_SSL_PROTO_TLS1_3) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 9504 | + if (mbedtls_ssl_get_version_number(ssl) == MBEDTLS_SSL_VERSION_TLS1_3) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 9505 | + return 0; /* (calculation not extracted) */ |
| 9506 | + #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ |
| 9507 | + |
| 9508 | + int ciphersuite = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); |
| 9509 | + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
| 9510 | + mbedtls_ssl_ciphersuite_from_id(ciphersuite); |
| 9511 | + if (ciphersuite_info == NULL) |
| 9512 | + return 0; |
| 9513 | + |
| 9514 | + const mbedtls_cipher_info_t *cipher_info = |
| 9515 | + mbedtls_cipher_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(cipher)); |
| 9516 | + if (cipher_info == NULL) |
| 9517 | + return 0; |
| 9518 | + |
| 9519 | + #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ |
| 9520 | + size_t keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; |
| 9521 | + mbedtls_cipher_mode_t mode = mbedtls_cipher_info_get_mode(cipher_info); |
| 9522 | + #else |
| 9523 | + size_t keylen = cipher_info->MBEDTLS_PRIVATE(key_bitlen) / 8; |
| 9524 | + mbedtls_cipher_mode_t mode = cipher_info->MBEDTLS_PRIVATE(mode); |
| 9525 | + #endif |
| 9526 | + #if defined(MBEDTLS_GCM_C) || \ |
| 9527 | + defined(MBEDTLS_CCM_C) || \ |
| 9528 | + defined(MBEDTLS_CHACHAPOLY_C) |
| 9529 | + if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM) |
| 9530 | + return keylen + 4; |
| 9531 | + else if (mode == MBEDTLS_MODE_CHACHAPOLY) |
| 9532 | + return keylen + 12; |
| 9533 | + else |
| 9534 | + #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ |
| 9535 | + #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) |
| 9536 | + { |
| 9537 | + const mbedtls_md_info_t *md_info = |
| 9538 | + mbedtls_md_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(mac)); |
| 9539 | + if (md_info == NULL) |
| 9540 | + return 0; |
| 9541 | + size_t mac_key_len = mbedtls_md_get_size(md_info); |
| 9542 | + size_t ivlen = mbedtls_cipher_info_get_iv_size(cipher_info); |
| 9543 | + return keylen + mac_key_len + ivlen; |
| 9544 | + } |
| 9545 | + #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ |
| 9546 | + #endif /* !MBEDTLS_USE_PSA_CRYPTO *//* (not extracted for PSA crypto) */ |
| 9547 | + return 0; |
| 9548 | +} |
| 9549 | +#endif /* MBEDTLS_VERSION_NUMBER >= 0x03000000 *//* mbedtls 3.0.0 */ |
| 9550 | + |
| 9551 | + |
| 9552 | +int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, |
| 9553 | + u8 *out, size_t out_len) |
| 9554 | +{ |
| 9555 | + /* XXX: has export keys callback been run? */ |
| 9556 | + if (!conn || !conn->tls_prf_type) |
| 9557 | + return -1; |
| 9558 | + |
| 9559 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9560 | + conn->expkey_keyblock_size = tls_mbedtls_ssl_keyblock_size(&conn->ssl); |
| 9561 | + if (conn->expkey_keyblock_size == 0) |
| 9562 | + return -1; |
| 9563 | + #endif |
| 9564 | + size_t skip = conn->expkey_keyblock_size * 2; |
| 9565 | + unsigned char *tmp_out = os_malloc(skip + out_len); |
| 9566 | + if (!tmp_out) |
| 9567 | + return -1; |
| 9568 | + |
| 9569 | + /* server_random and then client_random */ |
| 9570 | + unsigned char seed[MBEDTLS_EXPKEY_RAND_LEN*2]; |
| 9571 | + os_memcpy(seed, conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, |
| 9572 | + MBEDTLS_EXPKEY_RAND_LEN); |
| 9573 | + os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes, |
| 9574 | + MBEDTLS_EXPKEY_RAND_LEN); |
| 9575 | + |
| 9576 | + #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9577 | + int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, |
| 9578 | + conn->expkey_secret, conn->expkey_secret_len, |
| 9579 | + "key expansion", seed, sizeof(seed), |
| 9580 | + tmp_out, skip + out_len); |
| 9581 | + if (ret == 0) |
| 9582 | + os_memcpy(out, tmp_out + skip, out_len); |
| 9583 | + #else |
| 9584 | + int ret = -1; /*(not reached if not impl; return -1 at top of func)*/ |
| 9585 | + #endif |
| 9586 | + |
| 9587 | + bin_clear_free(tmp_out, skip + out_len); |
| 9588 | + forced_memzero(seed, sizeof(seed)); |
| 9589 | + return ret; |
| 9590 | +} |
| 9591 | + |
| 9592 | +#endif /* TLS_MBEDTLS_EAP_FAST */ |
| 9593 | + |
| 9594 | + |
| 9595 | +__attribute_cold__ |
| 9596 | +static void tls_mbedtls_suiteb_handshake_alert (struct tls_connection *conn) |
| 9597 | +{ |
| 9598 | + /* tests/hwsim/test_suite_b.py test_suite_b_192_rsa_insufficient_dh */ |
| 9599 | + if (!(conn->tls_conf->flags & TLS_CONN_SUITEB)) |
| 9600 | + return; |
| 9601 | + if (tls_ctx_global.tls_conf) /*(is server; want issue event on client)*/ |
| 9602 | + return; |
| 9603 | + #if 0 |
| 9604 | + /*(info not available on client; |
| 9605 | + * mbed TLS library enforces dhm min bitlen in ServerKeyExchange)*/ |
| 9606 | + if (MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 == |
| 9607 | + #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ |
| 9608 | + mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl) |
| 9609 | + #else |
| 9610 | + mbedtls_ssl_get_ciphersuite_id( |
| 9611 | + mbedtls_ssl_get_ciphersuite(&conn->ssl)) |
| 9612 | + #endif |
| 9613 | + && mbedtls_mpi_size(&conn->tls_conf->conf.MBEDTLS_PRIVATE(dhm_P)) |
| 9614 | + < 384 /*(3072/8)*/) |
| 9615 | + #endif |
| 9616 | + { |
| 9617 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 9618 | + if (init_conf->event_cb) { |
| 9619 | + union tls_event_data ev; |
| 9620 | + os_memset(&ev, 0, sizeof(ev)); |
| 9621 | + ev.alert.is_local = 1; |
| 9622 | + ev.alert.type = "fatal"; |
| 9623 | + /*"internal error" string for tests/hwsim/test_suiteb.py */ |
| 9624 | + ev.alert.description = "internal error: handshake failure"; |
| 9625 | + /*ev.alert.description = "insufficient security";*/ |
| 9626 | + init_conf->event_cb(init_conf->cb_ctx, TLS_ALERT, &ev); |
| 9627 | + } |
| 9628 | + } |
| 9629 | +} |
| 9630 | + |
| 9631 | + |
| 9632 | +struct wpabuf * tls_connection_handshake(void *tls_ctx, |
| 9633 | + struct tls_connection *conn, |
| 9634 | + const struct wpabuf *in_data, |
| 9635 | + struct wpabuf **appl_data) |
| 9636 | +{ |
| 9637 | + if (appl_data) |
| 9638 | + *appl_data = NULL; |
| 9639 | + |
| 9640 | + if (in_data && wpabuf_len(in_data)) { |
| 9641 | + /*(unsure why tls_gnutls.c discards buffer contents; skip here)*/ |
| 9642 | + if (conn->pull_buf && 0) /* disable; appears unwise */ |
| 9643 | + tls_pull_buf_discard(conn, __func__); |
| 9644 | + if (!tls_pull_buf_append(conn, in_data)) |
| 9645 | + return NULL; |
| 9646 | + } |
| 9647 | + |
| 9648 | + if (conn->tls_conf == NULL) { |
| 9649 | + struct tls_connection_params params; |
| 9650 | + os_memset(¶ms, 0, sizeof(params)); |
| 9651 | + params.openssl_ciphers = |
| 9652 | + tls_ctx_global.init_conf.openssl_ciphers; |
| 9653 | + params.flags = tls_ctx_global.tls_conf->flags; |
| 9654 | + if (tls_connection_set_params(tls_ctx, conn, ¶ms) != 0) |
| 9655 | + return NULL; |
| 9656 | + } |
| 9657 | + |
| 9658 | + if (conn->verify_peer) /*(call here might be redundant; nbd)*/ |
| 9659 | + mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); |
| 9660 | + |
| 9661 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9662 | + if (conn->clienthello_session_ticket) |
| 9663 | + /*(starting handshake for EAP-FAST and EAP-TEAP)*/ |
| 9664 | + tls_mbedtls_clienthello_session_ticket_set(conn); |
| 9665 | + |
| 9666 | + /* (not thread-safe due to need to set userdata 'conn' for callback) */ |
| 9667 | + /* (unable to use mbedtls_ssl_set_user_data_p() with mbedtls 3.2.0+ |
| 9668 | + * since ticket write and parse callbacks take (mbedtls_ssl_session *) |
| 9669 | + * param instead of (mbedtls_ssl_context *) param) */ |
| 9670 | + if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) |
| 9671 | + mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, |
| 9672 | + NULL, NULL, NULL); |
| 9673 | + else |
| 9674 | + mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, |
| 9675 | + tls_mbedtls_ssl_ticket_write, |
| 9676 | + tls_mbedtls_ssl_ticket_parse, |
| 9677 | + conn); |
| 9678 | + #endif |
| 9679 | + |
| 9680 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 9681 | + int ret = mbedtls_ssl_handshake(&conn->ssl); |
| 9682 | + #else |
| 9683 | + int ret = 0; |
| 9684 | + while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) { |
| 9685 | + ret = mbedtls_ssl_handshake_step(&conn->ssl); |
| 9686 | + if (ret != 0) |
| 9687 | + break; |
| 9688 | + } |
| 9689 | + #endif |
| 9690 | + |
| 9691 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9692 | + mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, |
| 9693 | + tls_mbedtls_ssl_ticket_write, |
| 9694 | + tls_mbedtls_ssl_ticket_parse, |
| 9695 | + NULL); |
| 9696 | + #endif |
| 9697 | + |
| 9698 | + switch (ret) { |
| 9699 | + case 0: |
| 9700 | + conn->established = 1; |
| 9701 | + if (conn->push_buf == NULL) |
| 9702 | + /* Need to return something to get final TLS ACK. */ |
| 9703 | + conn->push_buf = wpabuf_alloc(0); |
| 9704 | + |
| 9705 | + if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/) |
| 9706 | + *appl_data = NULL; /* RFE: check for application data */ |
| 9707 | + break; |
| 9708 | + case MBEDTLS_ERR_SSL_WANT_WRITE: |
| 9709 | + case MBEDTLS_ERR_SSL_WANT_READ: |
| 9710 | + case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: |
| 9711 | + case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: |
| 9712 | + if (tls_ctx_global.tls_conf /*(is server)*/ |
| 9713 | + && conn->established && conn->push_buf == NULL) |
| 9714 | + /* Need to return something to trigger completion of EAP-TLS. */ |
| 9715 | + conn->push_buf = wpabuf_alloc(0); |
| 9716 | + break; |
| 9717 | + default: |
| 9718 | + ++conn->failed; |
| 9719 | + switch (ret) { |
| 9720 | + case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: |
| 9721 | + case MBEDTLS_ERR_NET_CONN_RESET: |
| 9722 | + case MBEDTLS_ERR_NET_SEND_FAILED: |
| 9723 | + ++conn->write_alerts; |
| 9724 | + break; |
| 9725 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9726 | + case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: |
| 9727 | + #else |
| 9728 | + case MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE: |
| 9729 | + #endif |
| 9730 | + tls_mbedtls_suiteb_handshake_alert(conn); |
| 9731 | + /* fall through */ |
| 9732 | + case MBEDTLS_ERR_NET_RECV_FAILED: |
| 9733 | + case MBEDTLS_ERR_SSL_CONN_EOF: |
| 9734 | + case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: |
| 9735 | + case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE: |
| 9736 | + ++conn->read_alerts; |
| 9737 | + break; |
| 9738 | + default: |
| 9739 | + break; |
| 9740 | + } |
| 9741 | + |
| 9742 | + ilog(ret, "mbedtls_ssl_handshake"); |
| 9743 | + break; |
| 9744 | + } |
| 9745 | + |
| 9746 | + struct wpabuf *out_data = conn->push_buf; |
| 9747 | + conn->push_buf = NULL; |
| 9748 | + return out_data; |
| 9749 | +} |
| 9750 | + |
| 9751 | + |
| 9752 | +struct wpabuf * tls_connection_server_handshake(void *tls_ctx, |
| 9753 | + struct tls_connection *conn, |
| 9754 | + const struct wpabuf *in_data, |
| 9755 | + struct wpabuf **appl_data) |
| 9756 | +{ |
| 9757 | + conn->is_server = 1; |
| 9758 | + return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); |
| 9759 | +} |
| 9760 | + |
| 9761 | + |
| 9762 | +struct wpabuf * tls_connection_encrypt(void *tls_ctx, |
| 9763 | + struct tls_connection *conn, |
| 9764 | + const struct wpabuf *in_data) |
| 9765 | +{ |
| 9766 | + int res = mbedtls_ssl_write(&conn->ssl, |
| 9767 | + wpabuf_head_u8(in_data), wpabuf_len(in_data)); |
| 9768 | + if (res < 0) { |
| 9769 | + elog(res, "mbedtls_ssl_write"); |
| 9770 | + return NULL; |
| 9771 | + } |
| 9772 | + |
| 9773 | + struct wpabuf *buf = conn->push_buf; |
| 9774 | + conn->push_buf = NULL; |
| 9775 | + return buf; |
| 9776 | +} |
| 9777 | + |
| 9778 | + |
| 9779 | +struct wpabuf * tls_connection_decrypt(void *tls_ctx, |
| 9780 | + struct tls_connection *conn, |
| 9781 | + const struct wpabuf *in_data) |
| 9782 | +{ |
| 9783 | + int res; |
| 9784 | + struct wpabuf *out; |
| 9785 | + |
| 9786 | + /*assert(in_data != NULL);*/ |
| 9787 | + if (!tls_pull_buf_append(conn, in_data)) |
| 9788 | + return NULL; |
| 9789 | + |
| 9790 | + #if defined(MBEDTLS_ZLIB_SUPPORT) /* removed in mbedtls 3.x */ |
| 9791 | + /* Add extra buffer space to handle the possibility of decrypted |
| 9792 | + * data being longer than input data due to TLS compression. */ |
| 9793 | + out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); |
| 9794 | + #else /* TLS compression is disabled in mbedtls 3.x */ |
| 9795 | + out = wpabuf_alloc(wpabuf_len(in_data)); |
| 9796 | + #endif |
| 9797 | + if (out == NULL) |
| 9798 | + return NULL; |
| 9799 | + |
| 9800 | + res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(out), wpabuf_size(out)); |
| 9801 | + if (res < 0) { |
| 9802 | + #if 1 /*(seems like a different error if wpabuf_len(in_data) == 0)*/ |
| 9803 | + if (res == MBEDTLS_ERR_SSL_WANT_READ) |
| 9804 | + return out; |
| 9805 | + #endif |
| 9806 | + elog(res, "mbedtls_ssl_read"); |
| 9807 | + wpabuf_free(out); |
| 9808 | + return NULL; |
| 9809 | + } |
| 9810 | + wpabuf_put(out, res); |
| 9811 | + |
| 9812 | + return out; |
| 9813 | +} |
| 9814 | + |
| 9815 | + |
| 9816 | +int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) |
| 9817 | +{ |
| 9818 | + /* XXX: might need to detect if session resumed from TLS session ticket |
| 9819 | + * even if not special session ticket handling for EAP-FAST, EAP-TEAP */ |
| 9820 | + /* (?ssl->handshake->resume during session ticket validation?) */ |
| 9821 | + return conn && conn->resumed; |
| 9822 | +} |
| 9823 | + |
| 9824 | + |
| 9825 | +#ifdef TLS_MBEDTLS_EAP_FAST |
| 9826 | +int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, |
| 9827 | + u8 *ciphers) |
| 9828 | +{ |
| 9829 | + /* ciphers is list of TLS_CIPHER_* from hostap/src/crypto/tls.h */ |
| 9830 | + int ids[7]; |
| 9831 | + const int idsz = (int)sizeof(ids); |
| 9832 | + int nids = -1, id; |
| 9833 | + for ( ; *ciphers != TLS_CIPHER_NONE; ++ciphers) { |
| 9834 | + switch (*ciphers) { |
| 9835 | + case TLS_CIPHER_RC4_SHA: |
| 9836 | + #ifdef MBEDTLS_TLS_RSA_WITH_RC4_128_SHA |
| 9837 | + id = MBEDTLS_TLS_RSA_WITH_RC4_128_SHA; |
| 9838 | + break; |
| 9839 | + #else |
| 9840 | + continue; /*(not supported in mbedtls 3.x; ignore)*/ |
| 9841 | + #endif |
| 9842 | + case TLS_CIPHER_AES128_SHA: |
| 9843 | + id = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA; |
| 9844 | + break; |
| 9845 | + case TLS_CIPHER_RSA_DHE_AES128_SHA: |
| 9846 | + id = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA; |
| 9847 | + break; |
| 9848 | + case TLS_CIPHER_ANON_DH_AES128_SHA: |
| 9849 | + continue; /*(not supported in mbedtls; ignore)*/ |
| 9850 | + case TLS_CIPHER_RSA_DHE_AES256_SHA: |
| 9851 | + id = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA; |
| 9852 | + break; |
| 9853 | + case TLS_CIPHER_AES256_SHA: |
| 9854 | + id = MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA; |
| 9855 | + break; |
| 9856 | + default: |
| 9857 | + return -1; /* should not happen */ |
| 9858 | + } |
| 9859 | + if (++nids == idsz) |
| 9860 | + return -1; /* should not happen */ |
| 9861 | + ids[nids] = id; |
| 9862 | + } |
| 9863 | + if (nids < 0) |
| 9864 | + return 0; /* nothing to do */ |
| 9865 | + if (++nids == idsz) |
| 9866 | + return -1; /* should not happen */ |
| 9867 | + ids[nids] = 0; /* terminate list */ |
| 9868 | + ++nids; |
| 9869 | + |
| 9870 | + return tls_mbedtls_set_ciphersuites(conn->tls_conf, ids, nids) ? 0 : -1; |
| 9871 | +} |
| 9872 | +#endif |
| 9873 | + |
| 9874 | + |
| 9875 | +int tls_get_version(void *ssl_ctx, struct tls_connection *conn, |
| 9876 | + char *buf, size_t buflen) |
| 9877 | +{ |
| 9878 | + if (conn == NULL) |
| 9879 | + return -1; |
| 9880 | + os_strlcpy(buf, mbedtls_ssl_get_version(&conn->ssl), buflen); |
| 9881 | + return buf[0] != 'u' ? 0 : -1; /*(-1 if "unknown")*/ |
| 9882 | +} |
| 9883 | + |
| 9884 | + |
| 9885 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 9886 | +u16 tls_connection_get_cipher_suite(struct tls_connection *conn) |
| 9887 | +{ |
| 9888 | + if (conn == NULL) |
| 9889 | + return 0; |
| 9890 | + return (u16)mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); |
| 9891 | +} |
| 9892 | +#endif |
| 9893 | + |
| 9894 | + |
| 9895 | +int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, |
| 9896 | + char *buf, size_t buflen) |
| 9897 | +{ |
| 9898 | + if (conn == NULL) |
| 9899 | + return -1; |
| 9900 | + const int id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); |
| 9901 | + return tls_mbedtls_translate_ciphername(id, buf, buflen) ? 0 : -1; |
| 9902 | +} |
| 9903 | + |
| 9904 | + |
| 9905 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9906 | + |
| 9907 | +int tls_connection_enable_workaround(void *tls_ctx, |
| 9908 | + struct tls_connection *conn) |
| 9909 | +{ |
| 9910 | + /* (see comment in src/eap_peer/eap_fast.c:eap_fast_init()) */ |
| 9911 | + /* XXX: is there a relevant setting for this in mbed TLS? */ |
| 9912 | + /* (do we even care that much about older CBC ciphers?) */ |
| 9913 | + return 0; |
| 9914 | +} |
| 9915 | + |
| 9916 | + |
| 9917 | +int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, |
| 9918 | + int ext_type, const u8 *data, |
| 9919 | + size_t data_len) |
| 9920 | +{ |
| 9921 | + /* (EAP-FAST and EAP-TEAP) */ |
| 9922 | + if (ext_type == MBEDTLS_TLS_EXT_SESSION_TICKET) /*(ext_type == 35)*/ |
| 9923 | + return tls_mbedtls_clienthello_session_ticket_prep(conn, data, |
| 9924 | + data_len); |
| 9925 | + |
| 9926 | + return -1; |
| 9927 | +} |
| 9928 | + |
| 9929 | +#endif /* TLS_MBEDTLS_SESSION_TICKETS */ |
| 9930 | + |
| 9931 | + |
| 9932 | +int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) |
| 9933 | +{ |
| 9934 | + return conn ? conn->failed : -1; |
| 9935 | +} |
| 9936 | + |
| 9937 | + |
| 9938 | +int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) |
| 9939 | +{ |
| 9940 | + return conn ? conn->read_alerts : -1; |
| 9941 | +} |
| 9942 | + |
| 9943 | + |
| 9944 | +int tls_connection_get_write_alerts(void *tls_ctx, |
| 9945 | + struct tls_connection *conn) |
| 9946 | +{ |
| 9947 | + return conn ? conn->write_alerts : -1; |
| 9948 | +} |
| 9949 | + |
| 9950 | + |
| 9951 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9952 | +int tls_connection_set_session_ticket_cb( |
| 9953 | + void *tls_ctx, struct tls_connection *conn, |
| 9954 | + tls_session_ticket_cb cb, void *ctx) |
| 9955 | +{ |
| 9956 | + if (!(conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)) { |
| 9957 | + /* (EAP-FAST and EAP-TEAP) */ |
| 9958 | + conn->session_ticket_cb = cb; |
| 9959 | + conn->session_ticket_cb_ctx = ctx; |
| 9960 | + return 0; |
| 9961 | + } |
| 9962 | + return -1; |
| 9963 | +} |
| 9964 | +#endif |
| 9965 | + |
| 9966 | + |
| 9967 | +int tls_get_library_version(char *buf, size_t buf_len) |
| 9968 | +{ |
| 9969 | + #ifndef MBEDTLS_VERSION_C |
| 9970 | + const char * const ver = "n/a"; |
| 9971 | + #else |
| 9972 | + char ver[9]; |
| 9973 | + mbedtls_version_get_string(ver); |
| 9974 | + #endif |
| 9975 | + return os_snprintf(buf, buf_len, |
| 9976 | + "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver); |
| 9977 | +} |
| 9978 | + |
| 9979 | + |
| 9980 | +void tls_connection_set_success_data(struct tls_connection *conn, |
| 9981 | + struct wpabuf *data) |
| 9982 | +{ |
| 9983 | + wpabuf_free(conn->success_data); |
| 9984 | + conn->success_data = data; |
| 9985 | +} |
| 9986 | + |
| 9987 | + |
| 9988 | +void tls_connection_set_success_data_resumed(struct tls_connection *conn) |
| 9989 | +{ |
| 9990 | +} |
| 9991 | + |
| 9992 | + |
| 9993 | +const struct wpabuf * |
| 9994 | +tls_connection_get_success_data(struct tls_connection *conn) |
| 9995 | +{ |
| 9996 | + return conn->success_data; |
| 9997 | +} |
| 9998 | + |
| 9999 | + |
| 10000 | +void tls_connection_remove_session(struct tls_connection *conn) |
| 10001 | +{ |
| 10002 | +} |
| 10003 | + |
| 10004 | + |
| 10005 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 10006 | +int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len) |
| 10007 | +{ |
| 10008 | + #if defined(MBEDTLS_SSL_RENEGOTIATION) /* XXX: renegotiation or resumption? */ |
| 10009 | + /* data from TLS handshake Finished message */ |
| 10010 | + size_t verify_len = conn->ssl.MBEDTLS_PRIVATE(verify_data_len); |
| 10011 | + char *verify_data = (conn->is_server ^ conn->resumed) |
| 10012 | + ? conn->ssl.MBEDTLS_PRIVATE(peer_verify_data) |
| 10013 | + : conn->ssl.MBEDTLS_PRIVATE(own_verify_data); |
| 10014 | + if (verify_len && verify_len <= max_len) { |
| 10015 | + os_memcpy(buf, verify_data, verify_len); |
| 10016 | + return (int)verify_len; |
| 10017 | + } |
| 10018 | + #endif |
| 10019 | + return -1; |
| 10020 | +} |
| 10021 | +#endif |
| 10022 | + |
| 10023 | + |
| 10024 | +__attribute_noinline__ |
| 10025 | +static void tls_mbedtls_set_peer_subject(struct tls_connection *conn, const mbedtls_x509_crt *crt) |
| 10026 | +{ |
| 10027 | + if (conn->peer_subject) |
| 10028 | + return; |
| 10029 | + char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; |
| 10030 | + int buflen = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject); |
| 10031 | + if (buflen >= 0 && (conn->peer_subject = os_malloc((size_t)buflen+1))) |
| 10032 | + os_memcpy(conn->peer_subject, buf, (size_t)buflen+1); |
| 10033 | +} |
| 10034 | + |
| 10035 | + |
| 10036 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 10037 | +const char * tls_connection_get_peer_subject(struct tls_connection *conn) |
| 10038 | +{ |
| 10039 | + if (!conn) |
| 10040 | + return NULL; |
| 10041 | + if (!conn->peer_subject) { /*(if not set during cert verify)*/ |
| 10042 | + const mbedtls_x509_crt *peer_cert = |
| 10043 | + mbedtls_ssl_get_peer_cert(&conn->ssl); |
| 10044 | + if (peer_cert) |
| 10045 | + tls_mbedtls_set_peer_subject(conn, peer_cert); |
| 10046 | + } |
| 10047 | + return conn->peer_subject; |
| 10048 | +} |
| 10049 | +#endif |
| 10050 | + |
| 10051 | + |
| 10052 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 10053 | +bool tls_connection_get_own_cert_used(struct tls_connection *conn) |
| 10054 | +{ |
| 10055 | + /* XXX: availability of cert does not necessary mean that client |
| 10056 | + * received certificate request from server and then sent cert. |
| 10057 | + * ? step handshake in tls_connection_handshake() looking for |
| 10058 | + * MBEDTLS_SSL_CERTIFICATE_REQUEST ? */ |
| 10059 | + const struct tls_conf * const tls_conf = conn->tls_conf; |
| 10060 | + return (tls_conf->has_client_cert && tls_conf->has_private_key); |
| 10061 | +} |
| 10062 | +#endif |
| 10063 | + |
| 10064 | + |
| 10065 | +#if defined(CONFIG_FIPS) |
| 10066 | +#define TLS_MBEDTLS_CONFIG_FIPS |
| 10067 | +#endif |
| 10068 | + |
| 10069 | +#if defined(CONFIG_SHA256) |
| 10070 | +#define TLS_MBEDTLS_TLS_PRF_SHA256 |
| 10071 | +#endif |
| 10072 | + |
| 10073 | +#if defined(CONFIG_SHA384) |
| 10074 | +#define TLS_MBEDTLS_TLS_PRF_SHA384 |
| 10075 | +#endif |
| 10076 | + |
| 10077 | + |
| 10078 | +#ifndef TLS_MBEDTLS_CONFIG_FIPS |
| 10079 | +#if defined(CONFIG_MODULE_TESTS) |
| 10080 | +/* unused with CONFIG_TLS=mbedtls except in crypto_module_tests.c */ |
| 10081 | +#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ \ |
| 10082 | + && MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 10083 | +/* sha1-tlsprf.c */ |
| 10084 | +#include "sha1.h" |
| 10085 | +int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, |
| 10086 | + const u8 *seed, size_t seed_len, u8 *out, size_t outlen) |
| 10087 | +{ |
| 10088 | + return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, |
| 10089 | + secret, secret_len, label, |
| 10090 | + seed, seed_len, out, outlen) ? -1 : 0; |
| 10091 | +} |
| 10092 | +#else |
| 10093 | +#include "sha1-tlsprf.c" /* pull in hostap local implementation */ |
| 10094 | +#endif |
| 10095 | +#endif |
| 10096 | +#endif |
| 10097 | + |
| 10098 | +#ifdef TLS_MBEDTLS_TLS_PRF_SHA256 |
| 10099 | +/* sha256-tlsprf.c */ |
| 10100 | +#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 10101 | +#include "sha256.h" |
| 10102 | +int tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label, |
| 10103 | + const u8 *seed, size_t seed_len, u8 *out, size_t outlen) |
| 10104 | +{ |
| 10105 | + return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA256, |
| 10106 | + secret, secret_len, label, |
| 10107 | + seed, seed_len, out, outlen) ? -1 : 0; |
| 10108 | +} |
| 10109 | +#else |
| 10110 | +#include "sha256-tlsprf.c" /* pull in hostap local implementation */ |
| 10111 | +#endif |
| 10112 | +#endif |
| 10113 | + |
| 10114 | +#ifdef TLS_MBEDTLS_TLS_PRF_SHA384 |
| 10115 | +/* sha384-tlsprf.c */ |
| 10116 | +#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 10117 | +#include "sha384.h" |
| 10118 | +int tls_prf_sha384(const u8 *secret, size_t secret_len, const char *label, |
| 10119 | + const u8 *seed, size_t seed_len, u8 *out, size_t outlen) |
| 10120 | +{ |
| 10121 | + return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA384, |
| 10122 | + secret, secret_len, label, |
| 10123 | + seed, seed_len, out, outlen) ? -1 : 0; |
| 10124 | +} |
| 10125 | +#else |
| 10126 | +#include "sha384-tlsprf.c" /* pull in hostap local implementation */ |
| 10127 | +#endif |
| 10128 | +#endif |
| 10129 | + |
| 10130 | + |
| 10131 | +#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ |
| 10132 | +#define mbedtls_x509_crt_has_ext_type(crt, ext_type) \ |
| 10133 | + ((crt)->MBEDTLS_PRIVATE(ext_types) & (ext_type)) |
| 10134 | +#endif |
| 10135 | + |
| 10136 | +struct mlist { const char *p; size_t n; }; |
| 10137 | + |
| 10138 | + |
| 10139 | +static int |
| 10140 | +tls_mbedtls_match_altsubject(mbedtls_x509_crt *crt, const char *match) |
| 10141 | +{ |
| 10142 | + /* RFE: this could be pre-parsed into structured data at config time */ |
| 10143 | + struct mlist list[256]; /*(much larger than expected)*/ |
| 10144 | + int nlist = 0; |
| 10145 | + if ( os_strncmp(match, "EMAIL:", 6) != 0 |
| 10146 | + && os_strncmp(match, "DNS:", 4) != 0 |
| 10147 | + && os_strncmp(match, "URI:", 4) != 0 ) { |
| 10148 | + wpa_printf(MSG_INFO, "MTLS: Invalid altSubjectName match '%s'", match); |
| 10149 | + return 0; |
| 10150 | + } |
| 10151 | + for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { |
| 10152 | + do { } while ((tok = os_strchr(s, ';')) |
| 10153 | + && os_strncmp(tok+1, "EMAIL:", 6) != 0 |
| 10154 | + && os_strncmp(tok+1, "DNS:", 4) != 0 |
| 10155 | + && os_strncmp(tok+1, "URI:", 4) != 0); |
| 10156 | + list[nlist].p = s; |
| 10157 | + list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); |
| 10158 | + if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { |
| 10159 | + wpa_printf(MSG_INFO, "MTLS: excessive altSubjectName match '%s'", |
| 10160 | + match); |
| 10161 | + break; /* truncate huge list and continue */ |
| 10162 | + } |
| 10163 | + } |
| 10164 | + |
| 10165 | + if (!mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) |
| 10166 | + return 0; |
| 10167 | + |
| 10168 | + const mbedtls_x509_sequence *cur = &crt->subject_alt_names; |
| 10169 | + for (; cur != NULL; cur = cur->next) { |
| 10170 | + const unsigned char san_type = (unsigned char)cur->buf.tag |
| 10171 | + & MBEDTLS_ASN1_TAG_VALUE_MASK; |
| 10172 | + char t; |
| 10173 | + size_t step = 4; |
| 10174 | + switch (san_type) { /* "EMAIL:" or "DNS:" or "URI:" */ |
| 10175 | + case MBEDTLS_X509_SAN_RFC822_NAME: step = 6; t = 'E'; break; |
| 10176 | + case MBEDTLS_X509_SAN_DNS_NAME: t = 'D'; break; |
| 10177 | + case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: t = 'U'; break; |
| 10178 | + default: continue; |
| 10179 | + } |
| 10180 | + |
| 10181 | + for (int i = 0; i < nlist; ++i) { |
| 10182 | + /* step over "EMAIL:" or "DNS:" or "URI:" in list[i].p */ |
| 10183 | + /* Note: v is not '\0'-terminated, but is a known length vlen, |
| 10184 | + * so okay to pass to os_strncasecmp() even though not z-string */ |
| 10185 | + if (cur->buf.len == list[i].n - step && t == *list[i].p |
| 10186 | + && 0 == os_strncasecmp((char *)cur->buf.p, |
| 10187 | + list[i].p+step, cur->buf.len)) { |
| 10188 | + return 1; /* match */ |
| 10189 | + } |
| 10190 | + } |
| 10191 | + } |
| 10192 | + return 0; /* no match */ |
| 10193 | +} |
| 10194 | + |
| 10195 | + |
| 10196 | +static int |
| 10197 | +tls_mbedtls_match_suffix(const char *v, size_t vlen, |
| 10198 | + const struct mlist *list, int nlist, int full) |
| 10199 | +{ |
| 10200 | + /* Note: v is not '\0'-terminated, but is a known length vlen, |
| 10201 | + * so okay to pass to os_strncasecmp() even though not z-string */ |
| 10202 | + for (int i = 0; i < nlist; ++i) { |
| 10203 | + size_t n = list[i].n; |
| 10204 | + if ((n == vlen || (n < vlen && v[vlen-n-1] == '.' && !full)) |
| 10205 | + && 0 == os_strncasecmp(v+vlen-n, list[i].p, n)) |
| 10206 | + return 1; /* match */ |
| 10207 | + } |
| 10208 | + return 0; /* no match */ |
| 10209 | +} |
| 10210 | + |
| 10211 | + |
| 10212 | +static int |
| 10213 | +tls_mbedtls_match_suffixes(mbedtls_x509_crt *crt, const char *match, int full) |
| 10214 | +{ |
| 10215 | + /* RFE: this could be pre-parsed into structured data at config time */ |
| 10216 | + struct mlist list[256]; /*(much larger than expected)*/ |
| 10217 | + int nlist = 0; |
| 10218 | + for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { |
| 10219 | + tok = os_strchr(s, ';'); |
| 10220 | + list[nlist].p = s; |
| 10221 | + list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); |
| 10222 | + if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { |
| 10223 | + wpa_printf(MSG_INFO, "MTLS: excessive suffix match '%s'", match); |
| 10224 | + break; /* truncate huge list and continue */ |
| 10225 | + } |
| 10226 | + } |
| 10227 | + |
| 10228 | + /* check subjectAltNames */ |
| 10229 | + if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) { |
| 10230 | + const mbedtls_x509_sequence *cur = &crt->subject_alt_names; |
| 10231 | + for (; cur != NULL; cur = cur->next) { |
| 10232 | + const unsigned char san_type = (unsigned char)cur->buf.tag |
| 10233 | + & MBEDTLS_ASN1_TAG_VALUE_MASK; |
| 10234 | + if (san_type == MBEDTLS_X509_SAN_DNS_NAME |
| 10235 | + && tls_mbedtls_match_suffix((char *)cur->buf.p, |
| 10236 | + cur->buf.len, |
| 10237 | + list, nlist, full)) { |
| 10238 | + return 1; /* match */ |
| 10239 | + } |
| 10240 | + } |
| 10241 | + } |
| 10242 | + |
| 10243 | + /* check subject CN */ |
| 10244 | + const mbedtls_x509_name *name = &crt->subject; |
| 10245 | + for (; name != NULL; name = name->next) { |
| 10246 | + if (name->oid.p && MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0) |
| 10247 | + break; |
| 10248 | + } |
| 10249 | + if (name && tls_mbedtls_match_suffix((char *)name->val.p, name->val.len, |
| 10250 | + list, nlist, full)) { |
| 10251 | + return 1; /* match */ |
| 10252 | + } |
| 10253 | + |
| 10254 | + return 0; /* no match */ |
| 10255 | +} |
| 10256 | + |
| 10257 | + |
| 10258 | +static int |
| 10259 | +tls_mbedtls_match_dn_field(mbedtls_x509_crt *crt, const char *match) |
| 10260 | +{ |
| 10261 | + /* RFE: this could be pre-parsed into structured data at config time */ |
| 10262 | + struct mlistoid { const char *p; size_t n; |
| 10263 | + const char *oid; size_t olen; |
| 10264 | + int prefix; }; |
| 10265 | + struct mlistoid list[32]; /*(much larger than expected)*/ |
| 10266 | + int nlist = 0; |
| 10267 | + for (const char *s = match, *tok, *e; *s; s = tok ? tok+1 : "") { |
| 10268 | + tok = os_strchr(s, '/'); |
| 10269 | + list[nlist].oid = NULL; |
| 10270 | + list[nlist].olen = 0; |
| 10271 | + list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); |
| 10272 | + e = memchr(s, '=', list[nlist].n); |
| 10273 | + if (e == NULL) { |
| 10274 | + if (list[nlist].n == 0) |
| 10275 | + continue; /* skip consecutive, repeated '/' */ |
| 10276 | + if (list[nlist].n == 1 && *s == '*') { |
| 10277 | + /* special-case "*" to match any OID and value */ |
| 10278 | + s = e = "=*"; |
| 10279 | + list[nlist].n = 2; |
| 10280 | + list[nlist].oid = ""; |
| 10281 | + } |
| 10282 | + else { |
| 10283 | + wpa_printf(MSG_INFO, |
| 10284 | + "MTLS: invalid check_cert_subject '%s' missing '='", |
| 10285 | + match); |
| 10286 | + return 0; |
| 10287 | + } |
| 10288 | + } |
| 10289 | + switch (e - s) { |
| 10290 | + case 1: |
| 10291 | + if (*s == 'C') { |
| 10292 | + list[nlist].oid = MBEDTLS_OID_AT_COUNTRY; |
| 10293 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_COUNTRY)-1; |
| 10294 | + } |
| 10295 | + else if (*s == 'L') { |
| 10296 | + list[nlist].oid = MBEDTLS_OID_AT_LOCALITY; |
| 10297 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_LOCALITY)-1; |
| 10298 | + } |
| 10299 | + else if (*s == 'O') { |
| 10300 | + list[nlist].oid = MBEDTLS_OID_AT_ORGANIZATION; |
| 10301 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORGANIZATION)-1; |
| 10302 | + } |
| 10303 | + break; |
| 10304 | + case 2: |
| 10305 | + if (s[0] == 'C' && s[1] == 'N') { |
| 10306 | + list[nlist].oid = MBEDTLS_OID_AT_CN; |
| 10307 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_CN)-1; |
| 10308 | + } |
| 10309 | + else if (s[0] == 'S' && s[1] == 'T') { |
| 10310 | + list[nlist].oid = MBEDTLS_OID_AT_STATE; |
| 10311 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_STATE)-1; |
| 10312 | + } |
| 10313 | + else if (s[0] == 'O' && s[1] == 'U') { |
| 10314 | + list[nlist].oid = MBEDTLS_OID_AT_ORG_UNIT; |
| 10315 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORG_UNIT)-1; |
| 10316 | + } |
| 10317 | + break; |
| 10318 | + case 12: |
| 10319 | + if (os_memcmp(s, "emailAddress", 12) == 0) { |
| 10320 | + list[nlist].oid = MBEDTLS_OID_PKCS9_EMAIL; |
| 10321 | + list[nlist].olen = sizeof(MBEDTLS_OID_PKCS9_EMAIL)-1; |
| 10322 | + } |
| 10323 | + break; |
| 10324 | + default: |
| 10325 | + break; |
| 10326 | + } |
| 10327 | + if (list[nlist].oid == NULL) { |
| 10328 | + wpa_printf(MSG_INFO, |
| 10329 | + "MTLS: Unknown field in check_cert_subject '%s'", |
| 10330 | + match); |
| 10331 | + return 0; |
| 10332 | + } |
| 10333 | + list[nlist].n -= (size_t)(++e - s); |
| 10334 | + list[nlist].p = e; |
| 10335 | + if (list[nlist].n && e[list[nlist].n-1] == '*') { |
| 10336 | + --list[nlist].n; |
| 10337 | + list[nlist].prefix = 1; |
| 10338 | + } |
| 10339 | + /*(could easily add support for suffix matches if value begins with '*', |
| 10340 | + * but suffix match is not currently supported by other TLS modules)*/ |
| 10341 | + |
| 10342 | + if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { |
| 10343 | + wpa_printf(MSG_INFO, |
| 10344 | + "MTLS: excessive check_cert_subject match '%s'", |
| 10345 | + match); |
| 10346 | + break; /* truncate huge list and continue */ |
| 10347 | + } |
| 10348 | + } |
| 10349 | + |
| 10350 | + /* each component in match string must match cert Subject in order listed |
| 10351 | + * The behavior below preserves ordering but is slightly different than |
| 10352 | + * the grossly inefficient contortions implemented in tls_openssl.c */ |
| 10353 | + const mbedtls_x509_name *name = &crt->subject; |
| 10354 | + for (int i = 0; i < nlist; ++i) { |
| 10355 | + int found = 0; |
| 10356 | + for (; name != NULL && !found; name = name->next) { |
| 10357 | + if (!name->oid.p) |
| 10358 | + continue; |
| 10359 | + /* special-case "*" to match any OID and value */ |
| 10360 | + if (list[i].olen == 0) { |
| 10361 | + found = 1; |
| 10362 | + continue; |
| 10363 | + } |
| 10364 | + /* perform equalent of !MBEDTLS_OID_CMP() with oid ptr and len */ |
| 10365 | + if (list[i].olen != name->oid.len |
| 10366 | + || os_memcmp(list[i].oid, name->oid.p, name->oid.len) != 0) |
| 10367 | + continue; |
| 10368 | + /* Note: v is not '\0'-terminated, but is a known length vlen, |
| 10369 | + * so okay to pass to os_strncasecmp() even though not z-string */ |
| 10370 | + if ((list[i].prefix |
| 10371 | + ? list[i].n <= name->val.len /* prefix match */ |
| 10372 | + : list[i].n == name->val.len) /* full match */ |
| 10373 | + && 0 == os_strncasecmp((char *)name->val.p, |
| 10374 | + list[i].p, list[i].n)) { |
| 10375 | + found = 1; |
| 10376 | + continue; |
| 10377 | + } |
| 10378 | + } |
| 10379 | + if (!found) |
| 10380 | + return 0; /* no match */ |
| 10381 | + } |
| 10382 | + return 1; /* match */ |
| 10383 | +} |
| 10384 | + |
| 10385 | + |
| 10386 | +__attribute_cold__ |
| 10387 | +static void |
| 10388 | +tls_mbedtls_verify_fail_event (mbedtls_x509_crt *crt, int depth, |
| 10389 | + const char *errmsg, enum tls_fail_reason reason) |
| 10390 | +{ |
| 10391 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 10392 | + if (init_conf->event_cb == NULL) |
| 10393 | + return; |
| 10394 | + |
| 10395 | + struct wpabuf *certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); |
| 10396 | + char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; |
| 10397 | + if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) |
| 10398 | + subject[0] = '\0'; |
| 10399 | + union tls_event_data ev; |
| 10400 | + os_memset(&ev, 0, sizeof(ev)); |
| 10401 | + ev.cert_fail.reason = reason; |
| 10402 | + ev.cert_fail.depth = depth; |
| 10403 | + ev.cert_fail.subject = subject; |
| 10404 | + ev.cert_fail.reason_txt = errmsg; |
| 10405 | + ev.cert_fail.cert = certbuf; |
| 10406 | + |
| 10407 | + init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); |
| 10408 | + |
| 10409 | + wpabuf_free(certbuf); |
| 10410 | +} |
| 10411 | + |
| 10412 | + |
| 10413 | +__attribute_noinline__ |
| 10414 | +static void |
| 10415 | +tls_mbedtls_verify_cert_event (struct tls_connection *conn, |
| 10416 | + mbedtls_x509_crt *crt, int depth) |
| 10417 | +{ |
| 10418 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 10419 | + if (init_conf->event_cb == NULL) |
| 10420 | + return; |
| 10421 | + |
| 10422 | + struct wpabuf *certbuf = NULL; |
| 10423 | + union tls_event_data ev; |
| 10424 | + os_memset(&ev, 0, sizeof(ev)); |
| 10425 | + |
| 10426 | + #ifdef MBEDTLS_SHA256_C |
| 10427 | + u8 hash[SHA256_DIGEST_LENGTH]; |
| 10428 | + const u8 *addr[] = { (u8 *)crt->raw.p }; |
| 10429 | + if (sha256_vector(1, addr, &crt->raw.len, hash) == 0) { |
| 10430 | + ev.peer_cert.hash = hash; |
| 10431 | + ev.peer_cert.hash_len = sizeof(hash); |
| 10432 | + } |
| 10433 | + #endif |
| 10434 | + ev.peer_cert.depth = depth; |
| 10435 | + char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; |
| 10436 | + if (depth == 0) |
| 10437 | + ev.peer_cert.subject = conn->peer_subject; |
| 10438 | + if (ev.peer_cert.subject == NULL) { |
| 10439 | + ev.peer_cert.subject = subject; |
| 10440 | + if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) |
| 10441 | + subject[0] = '\0'; |
| 10442 | + } |
| 10443 | + |
| 10444 | + char serial_num[128+1]; |
| 10445 | + ev.peer_cert.serial_num = |
| 10446 | + tls_mbedtls_peer_serial_num(crt, serial_num, sizeof(serial_num)); |
| 10447 | + |
| 10448 | + const mbedtls_x509_sequence *cur; |
| 10449 | + |
| 10450 | + cur = NULL; |
| 10451 | + if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) |
| 10452 | + cur = &crt->subject_alt_names; |
| 10453 | + for (; cur != NULL; cur = cur->next) { |
| 10454 | + const unsigned char san_type = (unsigned char)cur->buf.tag |
| 10455 | + & MBEDTLS_ASN1_TAG_VALUE_MASK; |
| 10456 | + size_t prelen = 4; |
| 10457 | + const char *pre; |
| 10458 | + switch (san_type) { |
| 10459 | + case MBEDTLS_X509_SAN_RFC822_NAME: prelen = 6; pre = "EMAIL:";break; |
| 10460 | + case MBEDTLS_X509_SAN_DNS_NAME: pre = "DNS:"; break; |
| 10461 | + case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: pre = "URI:"; break; |
| 10462 | + default: continue; |
| 10463 | + } |
| 10464 | + |
| 10465 | + char *pos = os_malloc(prelen + cur->buf.len + 1); |
| 10466 | + if (pos == NULL) |
| 10467 | + break; |
| 10468 | + ev.peer_cert.altsubject[ev.peer_cert.num_altsubject] = pos; |
| 10469 | + os_memcpy(pos, pre, prelen); |
| 10470 | + /* data should be properly backslash-escaped if needed, |
| 10471 | + * so code below does not re-escape, but does replace CTLs */ |
| 10472 | + /*os_memcpy(pos+prelen, cur->buf.p, cur->buf.len);*/ |
| 10473 | + /*pos[prelen+cur->buf.len] = '\0';*/ |
| 10474 | + pos += prelen; |
| 10475 | + for (size_t i = 0; i < cur->buf.len; ++i) { |
| 10476 | + unsigned char c = cur->buf.p[i]; |
| 10477 | + *pos++ = (c >= 32 && c != 127) ? c : '?'; |
| 10478 | + } |
| 10479 | + *pos = '\0'; |
| 10480 | + |
| 10481 | + if (++ev.peer_cert.num_altsubject == TLS_MAX_ALT_SUBJECT) |
| 10482 | + break; |
| 10483 | + } |
| 10484 | + |
| 10485 | + cur = NULL; |
| 10486 | + if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_CERTIFICATE_POLICIES)) |
| 10487 | + cur = &crt->certificate_policies; |
| 10488 | + for (; cur != NULL; cur = cur->next) { |
| 10489 | + if (cur->buf.len != 11) /* len of OID_TOD_STRICT or OID_TOD_TOFU */ |
| 10490 | + continue; |
| 10491 | + /* TOD-STRICT "1.3.6.1.4.1.40808.1.3.1" */ |
| 10492 | + /* TOD-TOFU "1.3.6.1.4.1.40808.1.3.2" */ |
| 10493 | + #define OID_TOD_STRICT "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x01" |
| 10494 | + #define OID_TOD_TOFU "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x02" |
| 10495 | + if (os_memcmp(cur->buf.p, |
| 10496 | + OID_TOD_STRICT, sizeof(OID_TOD_STRICT)-1) == 0) { |
| 10497 | + ev.peer_cert.tod = 1; /* TOD-STRICT */ |
| 10498 | + break; |
| 10499 | + } |
| 10500 | + if (os_memcmp(cur->buf.p, |
| 10501 | + OID_TOD_TOFU, sizeof(OID_TOD_TOFU)-1) == 0) { |
| 10502 | + ev.peer_cert.tod = 2; /* TOD-TOFU */ |
| 10503 | + break; |
| 10504 | + } |
| 10505 | + } |
| 10506 | + |
| 10507 | + struct tls_conf *tls_conf = conn->tls_conf; |
| 10508 | + if (tls_conf->ca_cert_probe || (tls_conf->flags & TLS_CONN_EXT_CERT_CHECK) |
| 10509 | + || init_conf->cert_in_cb) { |
| 10510 | + certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); |
| 10511 | + ev.peer_cert.cert = certbuf; |
| 10512 | + } |
| 10513 | + |
| 10514 | + init_conf->event_cb(init_conf->cb_ctx, TLS_PEER_CERTIFICATE, &ev); |
| 10515 | + |
| 10516 | + wpabuf_free(certbuf); |
| 10517 | + char **altsubject; |
| 10518 | + *(const char ***)&altsubject = ev.peer_cert.altsubject; |
| 10519 | + for (size_t i = 0; i < ev.peer_cert.num_altsubject; ++i) |
| 10520 | + os_free(altsubject[i]); |
| 10521 | +} |
| 10522 | + |
| 10523 | + |
| 10524 | +static int |
| 10525 | +tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags) |
| 10526 | +{ |
| 10527 | + /* XXX: N.B. verify code not carefully tested besides hwsim tests |
| 10528 | + * |
| 10529 | + * RFE: mbedtls_x509_crt_verify_info() and enhance log trace messages |
| 10530 | + * RFE: review and add support for additional TLS_CONN_* flags |
| 10531 | + * not handling OCSP (not available in mbedtls) |
| 10532 | + * ... */ |
| 10533 | + |
| 10534 | + struct tls_connection *conn = (struct tls_connection *)arg; |
| 10535 | + struct tls_conf *tls_conf = conn->tls_conf; |
| 10536 | + uint32_t flags_in = *flags; |
| 10537 | + |
| 10538 | + if (depth > 8) { /*(depth 8 picked as arbitrary limit)*/ |
| 10539 | + emsg(MSG_WARNING, "client cert chain too long"); |
| 10540 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */ |
| 10541 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10542 | + "client cert chain too long", |
| 10543 | + TLS_FAIL_BAD_CERTIFICATE); |
| 10544 | + } |
| 10545 | + else if (tls_conf->verify_depth0_only) { |
| 10546 | + if (depth > 0) |
| 10547 | + *flags = 0; |
| 10548 | + else { |
| 10549 | + #ifdef MBEDTLS_SHA256_C |
| 10550 | + u8 hash[SHA256_DIGEST_LENGTH]; |
| 10551 | + const u8 *addr[] = { (u8 *)crt->raw.p }; |
| 10552 | + if (sha256_vector(1, addr, &crt->raw.len, hash) < 0 |
| 10553 | + || os_memcmp(tls_conf->ca_cert_hash, hash, sizeof(hash)) != 0) { |
| 10554 | + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; |
| 10555 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10556 | + "cert hash mismatch", |
| 10557 | + TLS_FAIL_UNTRUSTED); |
| 10558 | + } |
| 10559 | + else /* hash matches; ignore other issues *except* if revoked)*/ |
| 10560 | + *flags &= MBEDTLS_X509_BADCERT_REVOKED; |
| 10561 | + #endif |
| 10562 | + } |
| 10563 | + } |
| 10564 | + else if (depth == 0) { |
| 10565 | + if (!conn->peer_subject) |
| 10566 | + tls_mbedtls_set_peer_subject(conn, crt); |
| 10567 | + /*(use same labels to tls_mbedtls_verify_fail_event() as used in |
| 10568 | + * other TLS modules so that hwsim tests find exact string match)*/ |
| 10569 | + if (!conn->peer_subject) { /* error copying subject string */ |
| 10570 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; |
| 10571 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10572 | + "internal error", |
| 10573 | + TLS_FAIL_UNSPECIFIED); |
| 10574 | + } |
| 10575 | + /*(use os_strstr() for subject match as is done in tls_mbedtls.c |
| 10576 | + * to follow the same behavior, even though a suffix match would |
| 10577 | + * make more sense. Also, note that strstr match does not |
| 10578 | + * normalize whitespace (between components) for comparison)*/ |
| 10579 | + else if (tls_conf->subject_match |
| 10580 | + && os_strstr(conn->peer_subject, |
| 10581 | + tls_conf->subject_match) == NULL) { |
| 10582 | + wpa_printf(MSG_WARNING, |
| 10583 | + "MTLS: Subject '%s' did not match with '%s'", |
| 10584 | + conn->peer_subject, tls_conf->subject_match); |
| 10585 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10586 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10587 | + "Subject mismatch", |
| 10588 | + TLS_FAIL_SUBJECT_MISMATCH); |
| 10589 | + } |
| 10590 | + if (tls_conf->altsubject_match |
| 10591 | + && !tls_mbedtls_match_altsubject(crt, tls_conf->altsubject_match)) { |
| 10592 | + wpa_printf(MSG_WARNING, |
| 10593 | + "MTLS: altSubjectName match '%s' not found", |
| 10594 | + tls_conf->altsubject_match); |
| 10595 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10596 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10597 | + "AltSubject mismatch", |
| 10598 | + TLS_FAIL_ALTSUBJECT_MISMATCH); |
| 10599 | + } |
| 10600 | + if (tls_conf->suffix_match |
| 10601 | + && !tls_mbedtls_match_suffixes(crt, tls_conf->suffix_match, 0)) { |
| 10602 | + wpa_printf(MSG_WARNING, |
| 10603 | + "MTLS: Domain suffix match '%s' not found", |
| 10604 | + tls_conf->suffix_match); |
| 10605 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10606 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10607 | + "Domain suffix mismatch", |
| 10608 | + TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); |
| 10609 | + } |
| 10610 | + if (tls_conf->domain_match |
| 10611 | + && !tls_mbedtls_match_suffixes(crt, tls_conf->domain_match, 1)) { |
| 10612 | + wpa_printf(MSG_WARNING, |
| 10613 | + "MTLS: Domain match '%s' not found", |
| 10614 | + tls_conf->domain_match); |
| 10615 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10616 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10617 | + "Domain mismatch", |
| 10618 | + TLS_FAIL_DOMAIN_MISMATCH); |
| 10619 | + } |
| 10620 | + if (tls_conf->check_cert_subject |
| 10621 | + && !tls_mbedtls_match_dn_field(crt, tls_conf->check_cert_subject)) { |
| 10622 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10623 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10624 | + "Distinguished Name", |
| 10625 | + TLS_FAIL_DN_MISMATCH); |
| 10626 | + } |
| 10627 | + if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 10628 | + /* check RSA modulus size (public key bitlen) */ |
| 10629 | + const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk); |
| 10630 | + if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) |
| 10631 | + && mbedtls_pk_get_bitlen(&crt->pk) < 3072) { |
| 10632 | + /* hwsim suite_b RSA tests expect 3072 |
| 10633 | + * suite_b_192_rsa_ecdhe_radius_rsa2048_client |
| 10634 | + * suite_b_192_rsa_dhe_radius_rsa2048_client */ |
| 10635 | + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; |
| 10636 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10637 | + "Insufficient RSA modulus size", |
| 10638 | + TLS_FAIL_INSUFFICIENT_KEY_LEN); |
| 10639 | + } |
| 10640 | + } |
| 10641 | + if (tls_conf->check_crl && tls_conf->crl == NULL) { |
| 10642 | + /* see tests/hwsim test_ap_eap.py ap_wpa2_eap_tls_check_crl */ |
| 10643 | + emsg(MSG_WARNING, "check_crl set but no CRL loaded; reject all?"); |
| 10644 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; |
| 10645 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10646 | + "check_crl set but no CRL loaded; " |
| 10647 | + "reject all?", |
| 10648 | + TLS_FAIL_BAD_CERTIFICATE); |
| 10649 | + } |
| 10650 | + } |
| 10651 | + else { |
| 10652 | + if (tls_conf->check_crl != 2) /* 2 == verify CRLs for all certs */ |
| 10653 | + *flags &= ~MBEDTLS_X509_BADCERT_REVOKED; |
| 10654 | + } |
| 10655 | + |
| 10656 | + if (!tls_conf->check_crl_strict) { |
| 10657 | + *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED; |
| 10658 | + *flags &= ~MBEDTLS_X509_BADCRL_FUTURE; |
| 10659 | + } |
| 10660 | + |
| 10661 | + if (tls_conf->flags & TLS_CONN_DISABLE_TIME_CHECKS) { |
| 10662 | + *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED; |
| 10663 | + *flags &= ~MBEDTLS_X509_BADCERT_FUTURE; |
| 10664 | + } |
| 10665 | + |
| 10666 | + tls_mbedtls_verify_cert_event(conn, crt, depth); |
| 10667 | + |
| 10668 | + if (*flags) { |
| 10669 | + if (*flags & (MBEDTLS_X509_BADCERT_NOT_TRUSTED |
| 10670 | + |MBEDTLS_X509_BADCERT_CN_MISMATCH |
| 10671 | + |MBEDTLS_X509_BADCERT_REVOKED)) { |
| 10672 | + emsg(MSG_WARNING, "client cert not trusted"); |
| 10673 | + } |
| 10674 | + /* report event if flags set but no additional flags set above */ |
| 10675 | + /* (could translate flags to more detailed TLS_FAIL_* if needed) */ |
| 10676 | + if (!(*flags & ~flags_in)) { |
| 10677 | + enum tls_fail_reason reason = TLS_FAIL_UNSPECIFIED; |
| 10678 | + const char *errmsg = "cert verify fail unspecified"; |
| 10679 | + if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { |
| 10680 | + reason = TLS_FAIL_UNTRUSTED; |
| 10681 | + errmsg = "certificate not trusted"; |
| 10682 | + } |
| 10683 | + if (*flags & MBEDTLS_X509_BADCERT_REVOKED) { |
| 10684 | + reason = TLS_FAIL_REVOKED; |
| 10685 | + errmsg = "certificate has been revoked"; |
| 10686 | + } |
| 10687 | + if (*flags & MBEDTLS_X509_BADCERT_FUTURE) { |
| 10688 | + reason = TLS_FAIL_NOT_YET_VALID; |
| 10689 | + errmsg = "certificate not yet valid"; |
| 10690 | + } |
| 10691 | + if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) { |
| 10692 | + reason = TLS_FAIL_EXPIRED; |
| 10693 | + errmsg = "certificate has expired"; |
| 10694 | + } |
| 10695 | + if (*flags & MBEDTLS_X509_BADCERT_BAD_MD) { |
| 10696 | + reason = TLS_FAIL_BAD_CERTIFICATE; |
| 10697 | + errmsg = "certificate uses insecure algorithm"; |
| 10698 | + } |
| 10699 | + tls_mbedtls_verify_fail_event(crt, depth, errmsg, reason); |
| 10700 | + } |
| 10701 | + #if 0 |
| 10702 | + /* ??? send (again) cert events for all certs in chain ??? |
| 10703 | + * (should already have been called for greater depths) */ |
| 10704 | + /* tls_openssl.c:tls_verify_cb() sends cert events for all certs |
| 10705 | + * in chain if certificate validation fails, but sends all events |
| 10706 | + * with depth set to 0 (might be a bug) */ |
| 10707 | + if (depth > 0) { |
| 10708 | + int pdepth = depth + 1; |
| 10709 | + for (mbedtls_x509_crt *pcrt; (pcrt = crt->next); ++pdepth) { |
| 10710 | + tls_mbedtls_verify_cert_event(conn, pcrt, pdepth); |
| 10711 | + } |
| 10712 | + } |
| 10713 | + #endif |
| 10714 | + /*(do not preserve subject if verification failed but was optional)*/ |
| 10715 | + if (depth == 0 && conn->peer_subject) { |
| 10716 | + os_free(conn->peer_subject); |
| 10717 | + conn->peer_subject = NULL; |
| 10718 | + } |
| 10719 | + } |
| 10720 | + else if (depth == 0) { |
| 10721 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 10722 | + if (tls_conf->ca_cert_probe) { |
| 10723 | + /* reject server certificate on probe-only run */ |
| 10724 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; |
| 10725 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10726 | + "server chain probe", |
| 10727 | + TLS_FAIL_SERVER_CHAIN_PROBE); |
| 10728 | + } |
| 10729 | + else if (init_conf->event_cb) { |
| 10730 | + /* ??? send event as soon as depth == 0 is verified ??? |
| 10731 | + * What about rest of chain? |
| 10732 | + * Follows tls_mbedtls.c behavior: */ |
| 10733 | + init_conf->event_cb(init_conf->cb_ctx, |
| 10734 | + TLS_CERT_CHAIN_SUCCESS, NULL); |
| 10735 | + } |
| 10736 | + } |
| 10737 | + |
| 10738 | + return 0; |
| 10739 | +} |
| 10740 | diff --git a/src/drivers/driver.h b/src/drivers/driver.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10741 | index 4331782d8..e1a447333 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10742 | --- a/src/drivers/driver.h |
| 10743 | +++ b/src/drivers/driver.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10744 | @@ -979,6 +979,9 @@ struct wpa_driver_associate_params { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10745 | * responsible for selecting with which BSS to associate. */ |
| 10746 | const u8 *bssid; |
| 10747 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10748 | + unsigned char rates[WLAN_SUPP_RATES_MAX]; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10749 | + int mcast_rate; |
| 10750 | + |
| 10751 | /** |
| 10752 | * bssid_hint - BSSID of a proposed AP |
| 10753 | * |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10754 | @@ -1886,6 +1889,7 @@ struct wpa_driver_mesh_join_params { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10755 | #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 |
| 10756 | unsigned int flags; |
| 10757 | bool handle_dfs; |
| 10758 | + int mcast_rate; |
| 10759 | }; |
| 10760 | |
| 10761 | struct wpa_driver_set_key_params { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10762 | @@ -2357,6 +2361,9 @@ struct wpa_driver_capa { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10763 | /** Maximum number of iterations in a single scan plan */ |
| 10764 | u32 max_sched_scan_plan_iterations; |
| 10765 | |
| 10766 | + /** Maximum number of extra IE bytes for scans */ |
| 10767 | + u16 max_scan_ie_len; |
| 10768 | + |
| 10769 | /** Whether sched_scan (offloaded scanning) is supported */ |
| 10770 | int sched_scan_supported; |
| 10771 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10772 | @@ -3887,6 +3894,25 @@ struct wpa_driver_ops { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10773 | int (*if_remove)(void *priv, enum wpa_driver_if_type type, |
| 10774 | const char *ifname); |
| 10775 | |
| 10776 | + /** |
| 10777 | + * if_rename - Rename a virtual interface |
| 10778 | + * @priv: Private driver interface data |
| 10779 | + * @type: Interface type |
| 10780 | + * @ifname: Interface name of the virtual interface to be renamed |
| 10781 | + * (NULL when renaming the AP BSS interface) |
| 10782 | + * @new_name: New interface name of the virtual interface |
| 10783 | + * Returns: 0 on success, -1 on failure |
| 10784 | + */ |
| 10785 | + int (*if_rename)(void *priv, enum wpa_driver_if_type type, |
| 10786 | + const char *ifname, const char *new_name); |
| 10787 | + |
| 10788 | + /** |
| 10789 | + * set_first_bss - Make a virtual interface the first (primary) bss |
| 10790 | + * @priv: Private driver interface data |
| 10791 | + * Returns: 0 on success, -1 on failure |
| 10792 | + */ |
| 10793 | + int (*set_first_bss)(void *priv); |
| 10794 | + |
| 10795 | /** |
| 10796 | * set_sta_vlan - Bind a station into a specific interface (AP only) |
| 10797 | * @priv: Private driver interface data |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10798 | @@ -3989,7 +4015,7 @@ struct wpa_driver_ops { |
| 10799 | * Returns: 0 on success, -1 on failure |
| 10800 | */ |
| 10801 | int (*set_wds_sta)(void *priv, const u8 *addr, int aid, int val, |
| 10802 | - const char *bridge_ifname, char *ifname_wds); |
| 10803 | + const char *bridge_ifname, const char *ifname_wds); |
| 10804 | |
| 10805 | /** |
| 10806 | * send_action - Transmit an Action frame |
| 10807 | @@ -4291,7 +4317,7 @@ struct wpa_driver_ops { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10808 | * Returns: 0 on success, negative (<0) on failure |
| 10809 | */ |
| 10810 | int (*br_set_net_param)(void *priv, enum drv_br_net_param param, |
| 10811 | - unsigned int val); |
| 10812 | + const char *ifname, unsigned int val); |
| 10813 | |
| 10814 | /** |
| 10815 | * get_wowlan - Get wake-on-wireless status |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10816 | @@ -6588,6 +6614,7 @@ union wpa_event_data { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10817 | |
| 10818 | /** |
| 10819 | * struct ch_switch |
| 10820 | + * @count: Count until channel switch activates |
| 10821 | * @freq: Frequency of new channel in MHz |
| 10822 | * @ht_enabled: Whether this is an HT channel |
| 10823 | * @ch_offset: Secondary channel offset |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10824 | @@ -6598,6 +6625,7 @@ union wpa_event_data { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10825 | * @punct_bitmap: Puncturing bitmap |
| 10826 | */ |
| 10827 | struct ch_switch { |
| 10828 | + int count; |
| 10829 | int freq; |
| 10830 | int ht_enabled; |
| 10831 | int ch_offset; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10832 | @@ -6846,8 +6874,8 @@ union wpa_event_data { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10833 | * Driver wrapper code should call this function whenever an event is received |
| 10834 | * from the driver. |
| 10835 | */ |
| 10836 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 10837 | - union wpa_event_data *data); |
| 10838 | +extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, |
| 10839 | + union wpa_event_data *data); |
| 10840 | |
| 10841 | /** |
| 10842 | * wpa_supplicant_event_global - Report a driver event for wpa_supplicant |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10843 | @@ -6859,7 +6887,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10844 | * Same as wpa_supplicant_event(), but we search for the interface in |
| 10845 | * wpa_global. |
| 10846 | */ |
| 10847 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 10848 | +extern void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, |
| 10849 | union wpa_event_data *data); |
| 10850 | |
| 10851 | /* |
| 10852 | diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10853 | index 39f58ff83..a70eaae38 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10854 | --- a/src/drivers/driver_nl80211.c |
| 10855 | +++ b/src/drivers/driver_nl80211.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10856 | @@ -75,6 +75,16 @@ enum nlmsgerr_attrs { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10857 | |
| 10858 | #endif /* ANDROID */ |
| 10859 | |
| 10860 | +static void handle_nl_debug_hook(struct nl_msg *msg, int tx) |
| 10861 | +{ |
| 10862 | + const struct nlmsghdr *nlh; |
| 10863 | + |
| 10864 | + if (!wpa_netlink_hook) |
| 10865 | + return; |
| 10866 | + |
| 10867 | + nlh = nlmsg_hdr(msg); |
| 10868 | + wpa_netlink_hook(tx, nlh, nlh->nlmsg_len); |
| 10869 | +} |
| 10870 | |
| 10871 | static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg) |
| 10872 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10873 | @@ -429,6 +439,11 @@ static int no_seq_check(struct nl_msg *msg, void *arg) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10874 | return NL_OK; |
| 10875 | } |
| 10876 | |
| 10877 | +static int debug_handler(struct nl_msg *msg, void *arg) |
| 10878 | +{ |
| 10879 | + handle_nl_debug_hook(msg, 0); |
| 10880 | + return NL_OK; |
| 10881 | +} |
| 10882 | |
| 10883 | static void nl80211_nlmsg_clear(struct nl_msg *msg) |
| 10884 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10885 | @@ -502,6 +517,8 @@ int send_and_recv(struct nl80211_global *global, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10886 | if (!msg) |
| 10887 | return -ENOMEM; |
| 10888 | |
| 10889 | + handle_nl_debug_hook(msg, 1); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10890 | + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10891 | err.err = -ENOMEM; |
| 10892 | |
| 10893 | s_nl_cb = nl_socket_get_cb(nl_handle); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10894 | @@ -536,6 +553,7 @@ int send_and_recv(struct nl80211_global *global, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10895 | err.orig_msg = msg; |
| 10896 | err.err_info = err_info; |
| 10897 | |
| 10898 | + nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10899 | nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); |
| 10900 | nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err); |
| 10901 | if (ack_handler_custom) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10902 | @@ -939,6 +957,7 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10903 | os_free(w); |
| 10904 | return NULL; |
| 10905 | } |
| 10906 | + nl_cb_set(w->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10907 | nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, |
| 10908 | no_seq_check, NULL); |
| 10909 | nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10910 | @@ -1353,7 +1372,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10911 | } |
| 10912 | wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)", |
| 10913 | namebuf, ifname); |
| 10914 | - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) { |
| 10915 | + if (drv->first_bss->ifindex != ifi->ifi_index) { |
| 10916 | wpa_printf(MSG_DEBUG, |
| 10917 | "nl80211: Not the main interface (%s) - do not indicate interface down", |
| 10918 | drv->first_bss->ifname); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10919 | @@ -1389,7 +1408,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10920 | } |
| 10921 | wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)", |
| 10922 | namebuf, ifname); |
| 10923 | - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) { |
| 10924 | + if (drv->first_bss->ifindex != ifi->ifi_index) { |
| 10925 | wpa_printf(MSG_DEBUG, |
| 10926 | "nl80211: Not the main interface (%s) - do not indicate interface up", |
| 10927 | drv->first_bss->ifname); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10928 | @@ -2035,6 +2054,7 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10929 | genl_family_put(family); |
| 10930 | nl_cache_free(cache); |
| 10931 | |
| 10932 | + nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10933 | nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, |
| 10934 | no_seq_check, NULL); |
| 10935 | nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10936 | @@ -2205,6 +2225,7 @@ static int nl80211_init_bss(struct i802_bss *bss) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10937 | if (!bss->nl_cb) |
| 10938 | return -1; |
| 10939 | |
| 10940 | + nl_cb_set(bss->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10941 | nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, |
| 10942 | no_seq_check, NULL); |
| 10943 | nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10944 | @@ -3083,7 +3104,7 @@ static int wpa_driver_nl80211_del_beacon(struct i802_bss *bss, |
| 10945 | struct wpa_driver_nl80211_data *drv = bss->drv; |
| 10946 | struct i802_link *link = nl80211_get_link(bss, link_id); |
| 10947 | |
| 10948 | - if (!link->beacon_set) |
| 10949 | + if (!link || !link->beacon_set) |
| 10950 | return 0; |
| 10951 | |
| 10952 | wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", |
| 10953 | @@ -5494,7 +5515,7 @@ static int nl80211_set_channel(struct i802_bss *bss, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10954 | freq->he_enabled, freq->eht_enabled, freq->bandwidth, |
| 10955 | freq->center_freq1, freq->center_freq2); |
| 10956 | |
| 10957 | - msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL : |
| 10958 | + msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : |
| 10959 | NL80211_CMD_SET_WIPHY); |
| 10960 | if (!msg || nl80211_put_freq_params(msg, freq) < 0) { |
| 10961 | nlmsg_free(msg); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10962 | @@ -6183,8 +6204,7 @@ static void nl80211_teardown_ap(struct i802_bss *bss) |
| 10963 | nl80211_mgmt_unsubscribe(bss, "AP teardown"); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10964 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10965 | nl80211_put_wiphy_data_ap(bss); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10966 | - if (bss->flink) |
| 10967 | - bss->flink->beacon_set = 0; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 10968 | + wpa_driver_nl80211_del_beacon_all(bss); |
| 10969 | } |
| 10970 | |
| 10971 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 10972 | @@ -8414,24 +8434,14 @@ static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx, |
| 10973 | |
| 10974 | |
| 10975 | static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val, |
| 10976 | - const char *bridge_ifname, char *ifname_wds) |
| 10977 | + const char *bridge_ifname, const char *ifname_wds) |
| 10978 | { |
| 10979 | struct i802_bss *bss = priv; |
| 10980 | struct wpa_driver_nl80211_data *drv = bss->drv; |
| 10981 | - char name[IFNAMSIZ + 1]; |
| 10982 | + const char *name = ifname_wds; // Kept to reduce changes to the minimum |
| 10983 | union wpa_event_data event; |
| 10984 | int ret; |
| 10985 | |
| 10986 | - ret = os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid); |
| 10987 | - if (ret >= (int) sizeof(name)) |
| 10988 | - wpa_printf(MSG_WARNING, |
| 10989 | - "nl80211: WDS interface name was truncated"); |
| 10990 | - else if (ret < 0) |
| 10991 | - return ret; |
| 10992 | - |
| 10993 | - if (ifname_wds) |
| 10994 | - os_strlcpy(ifname_wds, name, IFNAMSIZ + 1); |
| 10995 | - |
| 10996 | wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR |
| 10997 | " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name); |
| 10998 | if (val) { |
| 10999 | @@ -8574,6 +8584,7 @@ static void *i802_init(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11000 | char master_ifname[IFNAMSIZ]; |
| 11001 | int ifindex, br_ifindex = 0; |
| 11002 | int br_added = 0; |
| 11003 | + int err; |
| 11004 | |
| 11005 | bss = wpa_driver_nl80211_drv_init(hapd, params->ifname, |
| 11006 | params->global_priv, 1, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11007 | @@ -8633,21 +8644,17 @@ static void *i802_init(struct hostapd_data *hapd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11008 | (params->num_bridge == 0 || !params->bridge[0])) |
| 11009 | add_ifidx(drv, br_ifindex, drv->ifindex); |
| 11010 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11011 | - if (bss->added_if_into_bridge || bss->already_in_bridge) { |
| 11012 | - int err; |
| 11013 | - |
| 11014 | - drv->rtnl_sk = nl_socket_alloc(); |
| 11015 | - if (drv->rtnl_sk == NULL) { |
| 11016 | - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock"); |
| 11017 | - goto failed; |
| 11018 | - } |
| 11019 | + drv->rtnl_sk = nl_socket_alloc(); |
| 11020 | + if (drv->rtnl_sk == NULL) { |
| 11021 | + wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock"); |
| 11022 | + goto failed; |
| 11023 | + } |
| 11024 | |
| 11025 | - err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE); |
| 11026 | - if (err) { |
| 11027 | - wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s", |
| 11028 | - nl_geterror(err)); |
| 11029 | - goto failed; |
| 11030 | - } |
| 11031 | + err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE); |
| 11032 | + if (err) { |
| 11033 | + wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s", |
| 11034 | + nl_geterror(err)); |
| 11035 | + goto failed; |
| 11036 | } |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11037 | |
| 11038 | if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11039 | @@ -8998,8 +9005,6 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, |
| 11040 | wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); |
| 11041 | nl80211_teardown_ap(bss); |
| 11042 | nl80211_remove_links(bss); |
| 11043 | - if (!bss->added_if && !drv->first_bss->next) |
| 11044 | - wpa_driver_nl80211_del_beacon_all(bss); |
| 11045 | nl80211_destroy_bss(bss); |
| 11046 | if (!bss->added_if) |
| 11047 | i802_set_iface_flags(bss, 0); |
| 11048 | @@ -9016,6 +9021,50 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11049 | return 0; |
| 11050 | } |
| 11051 | |
| 11052 | +static int wpa_driver_nl80211_if_rename(struct i802_bss *bss, |
| 11053 | + enum wpa_driver_if_type type, |
| 11054 | + const char *ifname, const char *new_name) |
| 11055 | +{ |
| 11056 | + struct wpa_driver_nl80211_data *drv = bss->drv; |
| 11057 | + struct ifinfomsg ifi = { |
| 11058 | + .ifi_family = AF_UNSPEC, |
| 11059 | + .ifi_index = bss->ifindex, |
| 11060 | + }; |
| 11061 | + struct nl_msg *msg; |
| 11062 | + int res = -ENOMEM; |
| 11063 | + |
| 11064 | + if (ifname) |
| 11065 | + ifi.ifi_index = if_nametoindex(ifname); |
| 11066 | + |
| 11067 | + msg = nlmsg_alloc_simple(RTM_SETLINK, 0); |
| 11068 | + if (!msg) |
| 11069 | + return res; |
| 11070 | + |
| 11071 | + if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) |
| 11072 | + goto out; |
| 11073 | + |
| 11074 | + if (nla_put_string(msg, IFLA_IFNAME, new_name)) |
| 11075 | + goto out; |
| 11076 | + |
| 11077 | + res = nl_send_auto_complete(drv->rtnl_sk, msg); |
| 11078 | + if (res < 0) |
| 11079 | + goto out; |
| 11080 | + |
| 11081 | + res = nl_wait_for_ack(drv->rtnl_sk); |
| 11082 | + if (res) { |
| 11083 | + wpa_printf(MSG_INFO, |
| 11084 | + "nl80211: Renaming device %s to %s failed: %s", |
| 11085 | + ifname ? ifname : bss->ifname, new_name, nl_geterror(res)); |
| 11086 | + goto out; |
| 11087 | + } |
| 11088 | + |
| 11089 | + if (type == WPA_IF_AP_BSS && !ifname) |
| 11090 | + os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname)); |
| 11091 | + |
| 11092 | +out: |
| 11093 | + nlmsg_free(msg); |
| 11094 | + return res; |
| 11095 | +} |
| 11096 | |
| 11097 | static int cookie_handler(struct nl_msg *msg, void *arg) |
| 11098 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11099 | @@ -10807,6 +10856,37 @@ static bool nl80211_is_drv_shared(void *priv, void *bss_ctx) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11100 | #endif /* CONFIG_IEEE80211BE */ |
| 11101 | |
| 11102 | |
| 11103 | +static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type, |
| 11104 | + const char *ifname, const char *new_name) |
| 11105 | +{ |
| 11106 | + struct i802_bss *bss = priv; |
| 11107 | + return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name); |
| 11108 | +} |
| 11109 | + |
| 11110 | + |
| 11111 | +static int driver_nl80211_set_first_bss(void *priv) |
| 11112 | +{ |
| 11113 | + struct i802_bss *bss = priv, *tbss; |
| 11114 | + struct wpa_driver_nl80211_data *drv = bss->drv; |
| 11115 | + |
| 11116 | + if (drv->first_bss == bss) |
| 11117 | + return 0; |
| 11118 | + |
| 11119 | + for (tbss = drv->first_bss; tbss; tbss = tbss->next) { |
| 11120 | + if (tbss->next != bss) |
| 11121 | + continue; |
| 11122 | + |
| 11123 | + tbss->next = bss->next; |
| 11124 | + bss->next = drv->first_bss; |
| 11125 | + drv->first_bss = bss; |
| 11126 | + drv->ctx = bss->ctx; |
| 11127 | + return 0; |
| 11128 | + } |
| 11129 | + |
| 11130 | + return -1; |
| 11131 | +} |
| 11132 | + |
| 11133 | + |
| 11134 | static int driver_nl80211_send_mlme(void *priv, const u8 *data, |
| 11135 | size_t data_len, int noack, |
| 11136 | unsigned int freq, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11137 | @@ -11309,6 +11389,10 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11138 | if (ret) |
| 11139 | goto error; |
| 11140 | |
| 11141 | + if (drv->nlmode == NL80211_IFTYPE_MESH_POINT) { |
| 11142 | + nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS); |
| 11143 | + } |
| 11144 | + |
| 11145 | /* beacon_csa params */ |
| 11146 | beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES); |
| 11147 | if (!beacon_csa) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11148 | @@ -11983,6 +12067,18 @@ static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11149 | } |
| 11150 | |
| 11151 | |
| 11152 | +static int nl80211_put_mcast_rate(struct nl_msg *msg, int mcast_rate) |
| 11153 | +{ |
| 11154 | + if (mcast_rate > 0) { |
| 11155 | + wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", |
| 11156 | + (double)mcast_rate / 10); |
| 11157 | + return nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, mcast_rate); |
| 11158 | + } |
| 11159 | + |
| 11160 | + return 0; |
| 11161 | +} |
| 11162 | + |
| 11163 | + |
| 11164 | static int nl80211_put_mesh_config(struct nl_msg *msg, |
| 11165 | struct wpa_driver_mesh_bss_params *params) |
| 11166 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11167 | @@ -12044,6 +12140,7 @@ static int nl80211_join_mesh(struct i802_bss *bss, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11168 | nl80211_put_basic_rates(msg, params->basic_rates) || |
| 11169 | nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || |
| 11170 | nl80211_put_beacon_int(msg, params->beacon_int) || |
| 11171 | + nl80211_put_mcast_rate(msg, params->mcast_rate) || |
| 11172 | nl80211_put_dtim_period(msg, params->dtim_period)) |
| 11173 | goto fail; |
| 11174 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11175 | @@ -12397,7 +12494,7 @@ static const char * drv_br_net_param_str(enum drv_br_net_param param) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11176 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11177 | |
| 11178 | static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, |
| 11179 | - unsigned int val) |
| 11180 | + const char *ifname, unsigned int val) |
| 11181 | { |
| 11182 | struct i802_bss *bss = priv; |
| 11183 | char path[128]; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11184 | @@ -12423,8 +12520,11 @@ static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11185 | return -EINVAL; |
| 11186 | } |
| 11187 | |
| 11188 | + if (!ifname) |
| 11189 | + ifname = bss->brname; |
| 11190 | + |
| 11191 | os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s", |
| 11192 | - ip_version, bss->brname, param_txt); |
| 11193 | + ip_version, ifname, param_txt); |
| 11194 | |
| 11195 | set_val: |
| 11196 | if (linux_write_system_file(path, val)) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11197 | @@ -14027,6 +14127,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11198 | .set_acl = wpa_driver_nl80211_set_acl, |
| 11199 | .if_add = wpa_driver_nl80211_if_add, |
| 11200 | .if_remove = driver_nl80211_if_remove, |
| 11201 | + .if_rename = driver_nl80211_if_rename, |
| 11202 | + .set_first_bss = driver_nl80211_set_first_bss, |
| 11203 | .send_mlme = driver_nl80211_send_mlme, |
| 11204 | .get_hw_feature_data = nl80211_get_hw_feature_data, |
| 11205 | .sta_add = wpa_driver_nl80211_sta_add, |
| 11206 | diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11207 | index 26c1f4140..d5ba66b10 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11208 | --- a/src/drivers/driver_nl80211_capa.c |
| 11209 | +++ b/src/drivers/driver_nl80211_capa.c |
| 11210 | @@ -976,6 +976,10 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg) |
| 11211 | nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]); |
| 11212 | } |
| 11213 | |
| 11214 | + if (tb[NL80211_ATTR_MAX_SCAN_IE_LEN]) |
| 11215 | + capa->max_scan_ie_len = |
| 11216 | + nla_get_u16(tb[NL80211_ATTR_MAX_SCAN_IE_LEN]); |
| 11217 | + |
| 11218 | if (tb[NL80211_ATTR_MAX_MATCH_SETS]) |
| 11219 | capa->max_match_sets = |
| 11220 | nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]); |
| 11221 | diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11222 | index aee815e97..768c72905 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11223 | --- a/src/drivers/driver_nl80211_event.c |
| 11224 | +++ b/src/drivers/driver_nl80211_event.c |
| 11225 | @@ -1196,6 +1196,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, |
| 11226 | struct nlattr *bw, struct nlattr *cf1, |
| 11227 | struct nlattr *cf2, |
| 11228 | struct nlattr *punct_bitmap, |
| 11229 | + struct nlattr *count, |
| 11230 | int finished) |
| 11231 | { |
| 11232 | struct i802_bss *bss; |
| 11233 | @@ -1259,6 +1260,8 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, |
| 11234 | data.ch_switch.cf1 = nla_get_u32(cf1); |
| 11235 | if (cf2) |
| 11236 | data.ch_switch.cf2 = nla_get_u32(cf2); |
| 11237 | + if (count) |
| 11238 | + data.ch_switch.count = nla_get_u32(count); |
| 11239 | |
| 11240 | if (link) |
| 11241 | data.ch_switch.link_id = nla_get_u8(link); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11242 | @@ -3999,6 +4002,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11243 | tb[NL80211_ATTR_CENTER_FREQ1], |
| 11244 | tb[NL80211_ATTR_CENTER_FREQ2], |
| 11245 | tb[NL80211_ATTR_PUNCT_BITMAP], |
| 11246 | + tb[NL80211_ATTR_CH_SWITCH_COUNT], |
| 11247 | 0); |
| 11248 | break; |
| 11249 | case NL80211_CMD_CH_SWITCH_NOTIFY: |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11250 | @@ -4011,6 +4015,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11251 | tb[NL80211_ATTR_CENTER_FREQ1], |
| 11252 | tb[NL80211_ATTR_CENTER_FREQ2], |
| 11253 | tb[NL80211_ATTR_PUNCT_BITMAP], |
| 11254 | + NULL, |
| 11255 | 1); |
| 11256 | break; |
| 11257 | case NL80211_CMD_DISCONNECT: |
| 11258 | diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11259 | index b055e684a..a8ea8f2cf 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11260 | --- a/src/drivers/driver_nl80211_scan.c |
| 11261 | +++ b/src/drivers/driver_nl80211_scan.c |
| 11262 | @@ -221,7 +221,7 @@ nl80211_scan_common(struct i802_bss *bss, u8 cmd, |
| 11263 | wpa_printf(MSG_DEBUG, "nl80211: Passive scan requested"); |
| 11264 | } |
| 11265 | |
| 11266 | - if (params->extra_ies) { |
| 11267 | + if (params->extra_ies && drv->capa.max_scan_ie_len >= params->extra_ies_len) { |
| 11268 | wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs", |
| 11269 | params->extra_ies, params->extra_ies_len); |
| 11270 | if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len, |
| 11271 | diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c |
| 11272 | index e95df6ddb..9071da3cf 100644 |
| 11273 | --- a/src/drivers/drivers.c |
| 11274 | +++ b/src/drivers/drivers.c |
| 11275 | @@ -10,6 +10,10 @@ |
| 11276 | #include "utils/common.h" |
| 11277 | #include "driver.h" |
| 11278 | |
| 11279 | +void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, |
| 11280 | + union wpa_event_data *data); |
| 11281 | +void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, |
| 11282 | + union wpa_event_data *data); |
| 11283 | |
| 11284 | const struct wpa_driver_ops *const wpa_drivers[] = |
| 11285 | { |
| 11286 | diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak |
| 11287 | index a03d4a034..8da44d9f5 100644 |
| 11288 | --- a/src/drivers/drivers.mak |
| 11289 | +++ b/src/drivers/drivers.mak |
| 11290 | @@ -54,7 +54,6 @@ NEED_SME=y |
| 11291 | NEED_AP_MLME=y |
| 11292 | NEED_NETLINK=y |
| 11293 | NEED_LINUX_IOCTL=y |
| 11294 | -NEED_RFKILL=y |
| 11295 | NEED_RADIOTAP=y |
| 11296 | NEED_LIBNL=y |
| 11297 | endif |
| 11298 | @@ -111,7 +110,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT |
| 11299 | CONFIG_WIRELESS_EXTENSION=y |
| 11300 | NEED_NETLINK=y |
| 11301 | NEED_LINUX_IOCTL=y |
| 11302 | -NEED_RFKILL=y |
| 11303 | endif |
| 11304 | |
| 11305 | ifdef CONFIG_DRIVER_NDIS |
| 11306 | @@ -137,7 +135,6 @@ endif |
| 11307 | ifdef CONFIG_WIRELESS_EXTENSION |
| 11308 | DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION |
| 11309 | DRV_WPA_OBJS += ../src/drivers/driver_wext.o |
| 11310 | -NEED_RFKILL=y |
| 11311 | endif |
| 11312 | |
| 11313 | ifdef NEED_NETLINK |
| 11314 | @@ -146,6 +143,7 @@ endif |
| 11315 | |
| 11316 | ifdef NEED_RFKILL |
| 11317 | DRV_OBJS += ../src/drivers/rfkill.o |
| 11318 | +DRV_WPA_CFLAGS += -DCONFIG_RFKILL |
| 11319 | endif |
| 11320 | |
| 11321 | ifdef NEED_RADIOTAP |
| 11322 | diff --git a/src/drivers/rfkill.h b/src/drivers/rfkill.h |
| 11323 | index 0412ac330..e27565375 100644 |
| 11324 | --- a/src/drivers/rfkill.h |
| 11325 | +++ b/src/drivers/rfkill.h |
| 11326 | @@ -18,8 +18,24 @@ struct rfkill_config { |
| 11327 | void (*unblocked_cb)(void *ctx); |
| 11328 | }; |
| 11329 | |
| 11330 | +#ifdef CONFIG_RFKILL |
| 11331 | struct rfkill_data * rfkill_init(struct rfkill_config *cfg); |
| 11332 | void rfkill_deinit(struct rfkill_data *rfkill); |
| 11333 | int rfkill_is_blocked(struct rfkill_data *rfkill); |
| 11334 | +#else |
| 11335 | +static inline struct rfkill_data * rfkill_init(struct rfkill_config *cfg) |
| 11336 | +{ |
| 11337 | + return (void *) 1; |
| 11338 | +} |
| 11339 | + |
| 11340 | +static inline void rfkill_deinit(struct rfkill_data *rfkill) |
| 11341 | +{ |
| 11342 | +} |
| 11343 | + |
| 11344 | +static inline int rfkill_is_blocked(struct rfkill_data *rfkill) |
| 11345 | +{ |
| 11346 | + return 0; |
| 11347 | +} |
| 11348 | +#endif |
| 11349 | |
| 11350 | #endif /* RFKILL_H */ |
| 11351 | diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c |
| 11352 | index 2a7f36170..8e8903051 100644 |
| 11353 | --- a/src/radius/radius_client.c |
| 11354 | +++ b/src/radius/radius_client.c |
| 11355 | @@ -165,6 +165,8 @@ struct radius_client_data { |
| 11356 | */ |
| 11357 | void *ctx; |
| 11358 | |
| 11359 | + struct hostapd_ip_addr local_ip; |
| 11360 | + |
| 11361 | /** |
| 11362 | * conf - RADIUS client configuration (list of RADIUS servers to use) |
| 11363 | */ |
| 11364 | @@ -818,6 +820,30 @@ static void radius_close_acct_socket(struct radius_client_data *radius) |
| 11365 | } |
| 11366 | |
| 11367 | |
| 11368 | +/** |
| 11369 | + * radius_client_send - Get local address for the RADIUS auth socket |
| 11370 | + * @radius: RADIUS client context from radius_client_init() |
| 11371 | + * @addr: pointer to store the address |
| 11372 | + * |
| 11373 | + * This function returns the local address for the connection to the RADIUS |
| 11374 | + * auth server. It also opens the socket if it's not available yet. |
| 11375 | + */ |
| 11376 | +int radius_client_get_local_addr(struct radius_client_data *radius, |
| 11377 | + struct hostapd_ip_addr *addr) |
| 11378 | +{ |
| 11379 | + struct hostapd_radius_servers *conf = radius->conf; |
| 11380 | + |
| 11381 | + if (conf->auth_server && radius->auth_sock < 0) |
| 11382 | + radius_client_init_auth(radius); |
| 11383 | + |
| 11384 | + if (radius->auth_sock < 0) |
| 11385 | + return -1; |
| 11386 | + |
| 11387 | + memcpy(addr, &radius->local_ip, sizeof(*addr)); |
| 11388 | + |
| 11389 | + return 0; |
| 11390 | +} |
| 11391 | + |
| 11392 | /** |
| 11393 | * radius_client_send - Send a RADIUS request |
| 11394 | * @radius: RADIUS client context from radius_client_init() |
| 11395 | @@ -1711,6 +1737,10 @@ radius_change_server(struct radius_client_data *radius, |
| 11396 | wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", |
| 11397 | inet_ntoa(claddr.sin_addr), |
| 11398 | ntohs(claddr.sin_port)); |
| 11399 | + if (auth) { |
| 11400 | + radius->local_ip.af = AF_INET; |
| 11401 | + radius->local_ip.u.v4 = claddr.sin_addr; |
| 11402 | + } |
| 11403 | } |
| 11404 | break; |
| 11405 | #ifdef CONFIG_IPV6 |
| 11406 | @@ -1722,6 +1752,10 @@ radius_change_server(struct radius_client_data *radius, |
| 11407 | inet_ntop(AF_INET6, &claddr6.sin6_addr, |
| 11408 | abuf, sizeof(abuf)), |
| 11409 | ntohs(claddr6.sin6_port)); |
| 11410 | + if (auth) { |
| 11411 | + radius->local_ip.af = AF_INET6; |
| 11412 | + radius->local_ip.u.v6 = claddr6.sin6_addr; |
| 11413 | + } |
| 11414 | } |
| 11415 | break; |
| 11416 | } |
| 11417 | diff --git a/src/radius/radius_client.h b/src/radius/radius_client.h |
| 11418 | index db40637ea..9a89b0382 100644 |
| 11419 | --- a/src/radius/radius_client.h |
| 11420 | +++ b/src/radius/radius_client.h |
| 11421 | @@ -274,6 +274,8 @@ int radius_client_register(struct radius_client_data *radius, |
| 11422 | void radius_client_set_interim_error_cb(struct radius_client_data *radius, |
| 11423 | void (*cb)(const u8 *addr, void *ctx), |
| 11424 | void *ctx); |
| 11425 | +int radius_client_get_local_addr(struct radius_client_data *radius, |
| 11426 | + struct hostapd_ip_addr * addr); |
| 11427 | int radius_client_send(struct radius_client_data *radius, |
| 11428 | struct radius_msg *msg, |
| 11429 | RadiusType msg_type, const u8 *addr); |
| 11430 | diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11431 | index 8d7c9b4c4..01913b08f 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11432 | --- a/src/radius/radius_das.c |
| 11433 | +++ b/src/radius/radius_das.c |
| 11434 | @@ -12,13 +12,26 @@ |
| 11435 | #include "utils/common.h" |
| 11436 | #include "utils/eloop.h" |
| 11437 | #include "utils/ip_addr.h" |
| 11438 | +#include "utils/list.h" |
| 11439 | #include "radius.h" |
| 11440 | #include "radius_das.h" |
| 11441 | |
| 11442 | |
| 11443 | -struct radius_das_data { |
| 11444 | +static struct dl_list das_ports = DL_LIST_HEAD_INIT(das_ports); |
| 11445 | + |
| 11446 | +struct radius_das_port { |
| 11447 | + struct dl_list list; |
| 11448 | + struct dl_list das_data; |
| 11449 | + |
| 11450 | + int port; |
| 11451 | int sock; |
| 11452 | +}; |
| 11453 | + |
| 11454 | +struct radius_das_data { |
| 11455 | + struct dl_list list; |
| 11456 | + struct radius_das_port *port; |
| 11457 | u8 *shared_secret; |
| 11458 | + u8 *nas_identifier; |
| 11459 | size_t shared_secret_len; |
| 11460 | struct hostapd_ip_addr client_addr; |
| 11461 | unsigned int time_window; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11462 | @@ -388,56 +401,17 @@ fail: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11463 | } |
| 11464 | |
| 11465 | |
| 11466 | -static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) |
| 11467 | +static void |
| 11468 | +radius_das_receive_msg(struct radius_das_data *das, struct radius_msg *msg, |
| 11469 | + struct sockaddr *from, socklen_t fromlen, |
| 11470 | + char *abuf, int from_port) |
| 11471 | { |
| 11472 | - struct radius_das_data *das = eloop_ctx; |
| 11473 | - u8 buf[1500]; |
| 11474 | - union { |
| 11475 | - struct sockaddr_storage ss; |
| 11476 | - struct sockaddr_in sin; |
| 11477 | -#ifdef CONFIG_IPV6 |
| 11478 | - struct sockaddr_in6 sin6; |
| 11479 | -#endif /* CONFIG_IPV6 */ |
| 11480 | - } from; |
| 11481 | - char abuf[50]; |
| 11482 | - int from_port = 0; |
| 11483 | - socklen_t fromlen; |
| 11484 | - int len; |
| 11485 | - struct radius_msg *msg, *reply = NULL; |
| 11486 | + struct radius_msg *reply = NULL; |
| 11487 | struct radius_hdr *hdr; |
| 11488 | struct wpabuf *rbuf; |
| 11489 | + struct os_time now; |
| 11490 | u32 val; |
| 11491 | int res; |
| 11492 | - struct os_time now; |
| 11493 | - |
| 11494 | - fromlen = sizeof(from); |
| 11495 | - len = recvfrom(sock, buf, sizeof(buf), 0, |
| 11496 | - (struct sockaddr *) &from.ss, &fromlen); |
| 11497 | - if (len < 0) { |
| 11498 | - wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); |
| 11499 | - return; |
| 11500 | - } |
| 11501 | - |
| 11502 | - os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); |
| 11503 | - from_port = ntohs(from.sin.sin_port); |
| 11504 | - |
| 11505 | - wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", |
| 11506 | - len, abuf, from_port); |
| 11507 | - if (das->client_addr.u.v4.s_addr && |
| 11508 | - das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) { |
| 11509 | - wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); |
| 11510 | - return; |
| 11511 | - } |
| 11512 | - |
| 11513 | - msg = radius_msg_parse(buf, len); |
| 11514 | - if (msg == NULL) { |
| 11515 | - wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " |
| 11516 | - "from %s:%d failed", abuf, from_port); |
| 11517 | - return; |
| 11518 | - } |
| 11519 | - |
| 11520 | - if (wpa_debug_level <= MSG_MSGDUMP) |
| 11521 | - radius_msg_dump(msg); |
| 11522 | |
| 11523 | if (radius_msg_verify_das_req(msg, das->shared_secret, |
| 11524 | das->shared_secret_len, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11525 | @@ -504,9 +478,8 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11526 | radius_msg_dump(reply); |
| 11527 | |
| 11528 | rbuf = radius_msg_get_buf(reply); |
| 11529 | - res = sendto(das->sock, wpabuf_head(rbuf), |
| 11530 | - wpabuf_len(rbuf), 0, |
| 11531 | - (struct sockaddr *) &from.ss, fromlen); |
| 11532 | + res = sendto(das->port->sock, wpabuf_head(rbuf), |
| 11533 | + wpabuf_len(rbuf), 0, from, fromlen); |
| 11534 | if (res < 0) { |
| 11535 | wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", |
| 11536 | abuf, from_port, strerror(errno)); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11537 | @@ -518,6 +491,72 @@ fail: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11538 | radius_msg_free(reply); |
| 11539 | } |
| 11540 | |
| 11541 | +static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) |
| 11542 | +{ |
| 11543 | + struct radius_das_port *p = eloop_ctx; |
| 11544 | + struct radius_das_data *das; |
| 11545 | + u8 buf[1500]; |
| 11546 | + union { |
| 11547 | + struct sockaddr_storage ss; |
| 11548 | + struct sockaddr_in sin; |
| 11549 | +#ifdef CONFIG_IPV6 |
| 11550 | + struct sockaddr_in6 sin6; |
| 11551 | +#endif /* CONFIG_IPV6 */ |
| 11552 | + } from; |
| 11553 | + struct radius_msg *msg; |
| 11554 | + size_t nasid_len = 0; |
| 11555 | + u8 *nasid_buf = NULL; |
| 11556 | + char abuf[50]; |
| 11557 | + int from_port = 0; |
| 11558 | + socklen_t fromlen; |
| 11559 | + int found = 0; |
| 11560 | + int len; |
| 11561 | + |
| 11562 | + fromlen = sizeof(from); |
| 11563 | + len = recvfrom(sock, buf, sizeof(buf), 0, |
| 11564 | + (struct sockaddr *) &from.ss, &fromlen); |
| 11565 | + if (len < 0) { |
| 11566 | + wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); |
| 11567 | + return; |
| 11568 | + } |
| 11569 | + |
| 11570 | + os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); |
| 11571 | + from_port = ntohs(from.sin.sin_port); |
| 11572 | + |
| 11573 | + msg = radius_msg_parse(buf, len); |
| 11574 | + if (msg == NULL) { |
| 11575 | + wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " |
| 11576 | + "from %s:%d failed", abuf, from_port); |
| 11577 | + return; |
| 11578 | + } |
| 11579 | + |
| 11580 | + wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", |
| 11581 | + len, abuf, from_port); |
| 11582 | + |
| 11583 | + if (wpa_debug_level <= MSG_MSGDUMP) |
| 11584 | + radius_msg_dump(msg); |
| 11585 | + |
| 11586 | + radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IDENTIFIER, |
| 11587 | + &nasid_buf, &nasid_len, NULL); |
| 11588 | + dl_list_for_each(das, &p->das_data, struct radius_das_data, list) { |
| 11589 | + if (das->client_addr.u.v4.s_addr && |
| 11590 | + das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) |
| 11591 | + continue; |
| 11592 | + |
| 11593 | + if (das->nas_identifier && nasid_buf && |
| 11594 | + (nasid_len != os_strlen(das->nas_identifier) || |
| 11595 | + os_memcmp(das->nas_identifier, nasid_buf, nasid_len) != 0)) |
| 11596 | + continue; |
| 11597 | + |
| 11598 | + found = 1; |
| 11599 | + radius_das_receive_msg(das, msg, (struct sockaddr *)&from.ss, |
| 11600 | + fromlen, abuf, from_port); |
| 11601 | + } |
| 11602 | + |
| 11603 | + if (!found) |
| 11604 | + wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); |
| 11605 | +} |
| 11606 | + |
| 11607 | |
| 11608 | static int radius_das_open_socket(int port) |
| 11609 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11610 | @@ -543,6 +582,49 @@ static int radius_das_open_socket(int port) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11611 | } |
| 11612 | |
| 11613 | |
| 11614 | +static struct radius_das_port * |
| 11615 | +radius_das_open_port(int port) |
| 11616 | +{ |
| 11617 | + struct radius_das_port *p; |
| 11618 | + |
| 11619 | + dl_list_for_each(p, &das_ports, struct radius_das_port, list) { |
| 11620 | + if (p->port == port) |
| 11621 | + return p; |
| 11622 | + } |
| 11623 | + |
| 11624 | + p = os_zalloc(sizeof(*p)); |
| 11625 | + if (p == NULL) |
| 11626 | + return NULL; |
| 11627 | + |
| 11628 | + dl_list_init(&p->das_data); |
| 11629 | + p->port = port; |
| 11630 | + p->sock = radius_das_open_socket(port); |
| 11631 | + if (p->sock < 0) |
| 11632 | + goto free_port; |
| 11633 | + |
| 11634 | + if (eloop_register_read_sock(p->sock, radius_das_receive, p, NULL)) |
| 11635 | + goto close_port; |
| 11636 | + |
| 11637 | + dl_list_add(&das_ports, &p->list); |
| 11638 | + |
| 11639 | + return p; |
| 11640 | + |
| 11641 | +close_port: |
| 11642 | + close(p->sock); |
| 11643 | +free_port: |
| 11644 | + os_free(p); |
| 11645 | + |
| 11646 | + return NULL; |
| 11647 | +} |
| 11648 | + |
| 11649 | +static void radius_das_close_port(struct radius_das_port *p) |
| 11650 | +{ |
| 11651 | + dl_list_del(&p->list); |
| 11652 | + eloop_unregister_read_sock(p->sock); |
| 11653 | + close(p->sock); |
| 11654 | + free(p); |
| 11655 | +} |
| 11656 | + |
| 11657 | struct radius_das_data * |
| 11658 | radius_das_init(struct radius_das_conf *conf) |
| 11659 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11660 | @@ -563,6 +645,8 @@ radius_das_init(struct radius_das_conf *conf) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11661 | das->ctx = conf->ctx; |
| 11662 | das->disconnect = conf->disconnect; |
| 11663 | das->coa = conf->coa; |
| 11664 | + if (conf->nas_identifier) |
| 11665 | + das->nas_identifier = os_strdup(conf->nas_identifier); |
| 11666 | |
| 11667 | os_memcpy(&das->client_addr, conf->client_addr, |
| 11668 | sizeof(das->client_addr)); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11669 | @@ -575,19 +659,15 @@ radius_das_init(struct radius_das_conf *conf) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11670 | } |
| 11671 | das->shared_secret_len = conf->shared_secret_len; |
| 11672 | |
| 11673 | - das->sock = radius_das_open_socket(conf->port); |
| 11674 | - if (das->sock < 0) { |
| 11675 | + das->port = radius_das_open_port(conf->port); |
| 11676 | + if (!das->port) { |
| 11677 | wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS " |
| 11678 | "DAS"); |
| 11679 | radius_das_deinit(das); |
| 11680 | return NULL; |
| 11681 | } |
| 11682 | |
| 11683 | - if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL)) |
| 11684 | - { |
| 11685 | - radius_das_deinit(das); |
| 11686 | - return NULL; |
| 11687 | - } |
| 11688 | + dl_list_add(&das->port->das_data, &das->list); |
| 11689 | |
| 11690 | return das; |
| 11691 | } |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11692 | @@ -598,11 +678,14 @@ void radius_das_deinit(struct radius_das_data *das) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11693 | if (das == NULL) |
| 11694 | return; |
| 11695 | |
| 11696 | - if (das->sock >= 0) { |
| 11697 | - eloop_unregister_read_sock(das->sock); |
| 11698 | - close(das->sock); |
| 11699 | + if (das->port) { |
| 11700 | + dl_list_del(&das->list); |
| 11701 | + |
| 11702 | + if (dl_list_empty(&das->port->das_data)) |
| 11703 | + radius_das_close_port(das->port); |
| 11704 | } |
| 11705 | |
| 11706 | + os_free(das->nas_identifier); |
| 11707 | os_free(das->shared_secret); |
| 11708 | os_free(das); |
| 11709 | } |
| 11710 | diff --git a/src/radius/radius_das.h b/src/radius/radius_das.h |
| 11711 | index 233d662f6..80dc13fc8 100644 |
| 11712 | --- a/src/radius/radius_das.h |
| 11713 | +++ b/src/radius/radius_das.h |
| 11714 | @@ -44,6 +44,7 @@ struct radius_das_attrs { |
| 11715 | struct radius_das_conf { |
| 11716 | int port; |
| 11717 | const u8 *shared_secret; |
| 11718 | + const u8 *nas_identifier; |
| 11719 | size_t shared_secret_len; |
| 11720 | const struct hostapd_ip_addr *client_addr; |
| 11721 | unsigned int time_window; |
| 11722 | diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11723 | index fa3691548..95a1cb994 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11724 | --- a/src/radius/radius_server.c |
| 11725 | +++ b/src/radius/radius_server.c |
| 11726 | @@ -63,6 +63,12 @@ struct radius_server_counters { |
| 11727 | u32 unknown_acct_types; |
| 11728 | }; |
| 11729 | |
| 11730 | +struct radius_accept_attr { |
| 11731 | + u8 type; |
| 11732 | + u16 len; |
| 11733 | + void *data; |
| 11734 | +}; |
| 11735 | + |
| 11736 | /** |
| 11737 | * struct radius_session - Internal RADIUS server data for a session |
| 11738 | */ |
| 11739 | @@ -90,7 +96,7 @@ struct radius_session { |
| 11740 | unsigned int macacl:1; |
| 11741 | unsigned int t_c_filtering:1; |
| 11742 | |
| 11743 | - struct hostapd_radius_attr *accept_attr; |
| 11744 | + struct radius_accept_attr *accept_attr; |
| 11745 | |
| 11746 | u32 t_c_timestamp; /* Last read T&C timestamp from user DB */ |
| 11747 | }; |
| 11748 | @@ -394,6 +400,7 @@ static void radius_server_session_free(struct radius_server_data *data, |
| 11749 | radius_msg_free(sess->last_reply); |
| 11750 | os_free(sess->username); |
| 11751 | os_free(sess->nas_ip); |
| 11752 | + os_free(sess->accept_attr); |
| 11753 | os_free(sess); |
| 11754 | data->num_sess--; |
| 11755 | } |
| 11756 | @@ -554,6 +561,36 @@ radius_server_erp_find_key(struct radius_server_data *data, const char *keyname) |
| 11757 | } |
| 11758 | #endif /* CONFIG_ERP */ |
| 11759 | |
| 11760 | +static struct radius_accept_attr * |
| 11761 | +radius_server_copy_attr(const struct hostapd_radius_attr *data) |
| 11762 | +{ |
| 11763 | + const struct hostapd_radius_attr *attr; |
| 11764 | + struct radius_accept_attr *attr_new; |
| 11765 | + size_t data_size = 0; |
| 11766 | + void *data_buf; |
| 11767 | + int n_attr = 1; |
| 11768 | + |
| 11769 | + for (attr = data; attr; attr = attr->next) { |
| 11770 | + n_attr++; |
| 11771 | + data_size += wpabuf_len(attr->val); |
| 11772 | + } |
| 11773 | + |
| 11774 | + attr_new = os_zalloc(n_attr * sizeof(*attr) + data_size); |
| 11775 | + if (!attr_new) |
| 11776 | + return NULL; |
| 11777 | + |
| 11778 | + data_buf = &attr_new[n_attr]; |
| 11779 | + for (n_attr = 0, attr = data; attr; attr = attr->next) { |
| 11780 | + struct radius_accept_attr *cur = &attr_new[n_attr++]; |
| 11781 | + |
| 11782 | + cur->type = attr->type; |
| 11783 | + cur->len = wpabuf_len(attr->val); |
| 11784 | + cur->data = memcpy(data_buf, wpabuf_head(attr->val), cur->len); |
| 11785 | + data_buf += cur->len; |
| 11786 | + } |
| 11787 | + |
| 11788 | + return attr_new; |
| 11789 | +} |
| 11790 | |
| 11791 | static struct radius_session * |
| 11792 | radius_server_get_new_session(struct radius_server_data *data, |
| 11793 | @@ -607,7 +644,7 @@ radius_server_get_new_session(struct radius_server_data *data, |
| 11794 | eap_user_free(tmp); |
| 11795 | return NULL; |
| 11796 | } |
| 11797 | - sess->accept_attr = tmp->accept_attr; |
| 11798 | + sess->accept_attr = radius_server_copy_attr(tmp->accept_attr); |
| 11799 | sess->macacl = tmp->macacl; |
| 11800 | eap_user_free(tmp); |
| 11801 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11802 | @@ -1123,11 +1160,10 @@ radius_server_encapsulate_eap(struct radius_server_data *data, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11803 | } |
| 11804 | |
| 11805 | if (code == RADIUS_CODE_ACCESS_ACCEPT) { |
| 11806 | - struct hostapd_radius_attr *attr; |
| 11807 | - for (attr = sess->accept_attr; attr; attr = attr->next) { |
| 11808 | - if (!radius_msg_add_attr(msg, attr->type, |
| 11809 | - wpabuf_head(attr->val), |
| 11810 | - wpabuf_len(attr->val))) { |
| 11811 | + struct radius_accept_attr *attr; |
| 11812 | + for (attr = sess->accept_attr; attr->data; attr++) { |
| 11813 | + if (!radius_msg_add_attr(msg, attr->type, attr->data, |
| 11814 | + attr->len)) { |
| 11815 | wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); |
| 11816 | radius_msg_free(msg); |
| 11817 | return NULL; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11818 | @@ -1221,11 +1257,10 @@ radius_server_macacl(struct radius_server_data *data, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11819 | } |
| 11820 | |
| 11821 | if (code == RADIUS_CODE_ACCESS_ACCEPT) { |
| 11822 | - struct hostapd_radius_attr *attr; |
| 11823 | - for (attr = sess->accept_attr; attr; attr = attr->next) { |
| 11824 | - if (!radius_msg_add_attr(msg, attr->type, |
| 11825 | - wpabuf_head(attr->val), |
| 11826 | - wpabuf_len(attr->val))) { |
| 11827 | + struct radius_accept_attr *attr; |
| 11828 | + for (attr = sess->accept_attr; attr->data; attr++) { |
| 11829 | + if (!radius_msg_add_attr(msg, attr->type, attr->data, |
| 11830 | + attr->len)) { |
| 11831 | wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); |
| 11832 | radius_msg_free(msg); |
| 11833 | return NULL; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11834 | @@ -2527,7 +2562,7 @@ static int radius_server_get_eap_user(void *ctx, const u8 *identity, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11835 | ret = data->get_eap_user(data->conf_ctx, identity, identity_len, |
| 11836 | phase2, user); |
| 11837 | if (ret == 0 && user) { |
| 11838 | - sess->accept_attr = user->accept_attr; |
| 11839 | + sess->accept_attr = radius_server_copy_attr(user->accept_attr); |
| 11840 | sess->remediation = user->remediation; |
| 11841 | sess->macacl = user->macacl; |
| 11842 | sess->t_c_timestamp = user->t_c_timestamp; |
| 11843 | diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11844 | index 52a4c7442..ce1aa60a9 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11845 | --- a/src/rsn_supp/wpa.c |
| 11846 | +++ b/src/rsn_supp/wpa.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11847 | @@ -4153,6 +4153,8 @@ static u32 wpa_key_mgmt_suite(struct wpa_sm *sm) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11848 | } |
| 11849 | |
| 11850 | |
| 11851 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 11852 | + |
| 11853 | #define RSN_SUITE "%02x-%02x-%02x-%d" |
| 11854 | #define RSN_SUITE_ARG(s) \ |
| 11855 | ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 11856 | @@ -4234,6 +4236,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11857 | |
| 11858 | return (int) len; |
| 11859 | } |
| 11860 | +#endif |
| 11861 | #endif /* CONFIG_CTRL_IFACE */ |
| 11862 | |
| 11863 | |
| 11864 | diff --git a/src/tls/Makefile b/src/tls/Makefile |
| 11865 | index c84fbe859..e974a41f0 100644 |
| 11866 | --- a/src/tls/Makefile |
| 11867 | +++ b/src/tls/Makefile |
| 11868 | @@ -1,3 +1,10 @@ |
| 11869 | +LIB_OBJS= asn1.o |
| 11870 | + |
| 11871 | +ifneq ($(CONFIG_TLS),gnutls) |
| 11872 | +ifneq ($(CONFIG_TLS),mbedtls) |
| 11873 | +ifneq ($(CONFIG_TLS),openssl) |
| 11874 | +ifneq ($(CONFIG_TLS),wolfssl) |
| 11875 | + |
| 11876 | CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH |
| 11877 | CFLAGS += -DCONFIG_CRYPTO_INTERNAL |
| 11878 | CFLAGS += -DCONFIG_TLSV11 |
| 11879 | @@ -21,5 +28,9 @@ LIB_OBJS= \ |
| 11880 | tlsv1_server_read.o \ |
| 11881 | tlsv1_server_write.o \ |
| 11882 | x509v3.o |
| 11883 | +endif |
| 11884 | +endif |
| 11885 | +endif |
| 11886 | +endif |
| 11887 | |
| 11888 | include ../lib.rules |
| 11889 | diff --git a/src/utils/eloop.c b/src/utils/eloop.c |
| 11890 | index 00b0beff0..50dd1beda 100644 |
| 11891 | --- a/src/utils/eloop.c |
| 11892 | +++ b/src/utils/eloop.c |
| 11893 | @@ -77,6 +77,9 @@ struct eloop_sock_table { |
| 11894 | struct eloop_data { |
| 11895 | int max_sock; |
| 11896 | |
| 11897 | + eloop_timeout_poll_handler timeout_poll_cb; |
| 11898 | + eloop_poll_handler poll_cb; |
| 11899 | + |
| 11900 | size_t count; /* sum of all table counts */ |
| 11901 | #ifdef CONFIG_ELOOP_POLL |
| 11902 | size_t max_pollfd_map; /* number of pollfds_map currently allocated */ |
| 11903 | @@ -1121,6 +1124,12 @@ void eloop_run(void) |
| 11904 | os_reltime_sub(&timeout->time, &now, &tv); |
| 11905 | else |
| 11906 | tv.sec = tv.usec = 0; |
| 11907 | + } |
| 11908 | + |
| 11909 | + if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout)) |
| 11910 | + timeout = (void *)1; |
| 11911 | + |
| 11912 | + if (timeout) { |
| 11913 | #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) |
| 11914 | timeout_ms = tv.sec * 1000 + tv.usec / 1000; |
| 11915 | #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ |
| 11916 | @@ -1190,7 +1199,8 @@ void eloop_run(void) |
| 11917 | eloop.exceptions.changed = 0; |
| 11918 | |
| 11919 | eloop_process_pending_signals(); |
| 11920 | - |
| 11921 | + if (eloop.poll_cb) |
| 11922 | + eloop.poll_cb(); |
| 11923 | |
| 11924 | /* check if some registered timeouts have occurred */ |
| 11925 | timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, |
| 11926 | @@ -1252,6 +1262,14 @@ out: |
| 11927 | return; |
| 11928 | } |
| 11929 | |
| 11930 | +int eloop_register_cb(eloop_poll_handler poll_cb, |
| 11931 | + eloop_timeout_poll_handler timeout_cb) |
| 11932 | +{ |
| 11933 | + eloop.poll_cb = poll_cb; |
| 11934 | + eloop.timeout_poll_cb = timeout_cb; |
| 11935 | + |
| 11936 | + return 0; |
| 11937 | +} |
| 11938 | |
| 11939 | void eloop_terminate(void) |
| 11940 | { |
| 11941 | diff --git a/src/utils/eloop.h b/src/utils/eloop.h |
| 11942 | index 04ee6d183..5452ea589 100644 |
| 11943 | --- a/src/utils/eloop.h |
| 11944 | +++ b/src/utils/eloop.h |
| 11945 | @@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(void *eloop_ctx, void *user_ctx); |
| 11946 | */ |
| 11947 | typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); |
| 11948 | |
| 11949 | +typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set); |
| 11950 | +typedef void (*eloop_poll_handler)(void); |
| 11951 | + |
| 11952 | /** |
| 11953 | * eloop_init() - Initialize global event loop data |
| 11954 | * Returns: 0 on success, -1 on failure |
| 11955 | @@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); |
| 11956 | */ |
| 11957 | int eloop_init(void); |
| 11958 | |
| 11959 | +int eloop_register_cb(eloop_poll_handler poll_cb, |
| 11960 | + eloop_timeout_poll_handler timeout_cb); |
| 11961 | + |
| 11962 | /** |
| 11963 | * eloop_register_read_sock - Register handler for read events |
| 11964 | * @sock: File descriptor number for the socket |
| 11965 | @@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop_signal_handler handler, |
| 11966 | */ |
| 11967 | int eloop_sock_requeue(void); |
| 11968 | |
| 11969 | +void eloop_add_uloop(void); |
| 11970 | + |
| 11971 | /** |
| 11972 | * eloop_run - Start the event loop |
| 11973 | * |
| 11974 | diff --git a/src/utils/uloop.c b/src/utils/uloop.c |
| 11975 | new file mode 100644 |
| 11976 | index 000000000..c0d26db93 |
| 11977 | --- /dev/null |
| 11978 | +++ b/src/utils/uloop.c |
| 11979 | @@ -0,0 +1,64 @@ |
| 11980 | +#include <libubox/uloop.h> |
| 11981 | +#include "includes.h" |
| 11982 | +#include "common.h" |
| 11983 | +#include "eloop.h" |
| 11984 | + |
| 11985 | +static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx) |
| 11986 | +{ |
| 11987 | +} |
| 11988 | + |
| 11989 | +static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events) |
| 11990 | +{ |
| 11991 | + unsigned int changed = events ^ fd->flags; |
| 11992 | + |
| 11993 | + if (changed & ULOOP_READ) { |
| 11994 | + if (events & ULOOP_READ) |
| 11995 | + eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd); |
| 11996 | + else |
| 11997 | + eloop_unregister_sock(fd->fd, EVENT_TYPE_READ); |
| 11998 | + } |
| 11999 | + |
| 12000 | + if (changed & ULOOP_WRITE) { |
| 12001 | + if (events & ULOOP_WRITE) |
| 12002 | + eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd); |
| 12003 | + else |
| 12004 | + eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE); |
| 12005 | + } |
| 12006 | +} |
| 12007 | + |
| 12008 | +static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set) |
| 12009 | +{ |
| 12010 | + struct os_reltime tv_uloop; |
| 12011 | + int timeout_ms = uloop_get_next_timeout(); |
| 12012 | + |
| 12013 | + if (timeout_ms < 0) |
| 12014 | + return false; |
| 12015 | + |
| 12016 | + tv_uloop.sec = timeout_ms / 1000; |
| 12017 | + tv_uloop.usec = (timeout_ms % 1000) * 1000; |
| 12018 | + |
| 12019 | + if (!tv_set || os_reltime_before(&tv_uloop, tv)) { |
| 12020 | + *tv = tv_uloop; |
| 12021 | + return true; |
| 12022 | + } |
| 12023 | + |
| 12024 | + return false; |
| 12025 | +} |
| 12026 | + |
| 12027 | +static void uloop_poll_handler(void) |
| 12028 | +{ |
| 12029 | + uloop_run_timeout(0); |
| 12030 | +} |
| 12031 | + |
| 12032 | +void eloop_add_uloop(void) |
| 12033 | +{ |
| 12034 | + static bool init_done = false; |
| 12035 | + |
| 12036 | + if (!init_done) { |
| 12037 | + uloop_init(); |
| 12038 | + uloop_fd_set_cb = eloop_uloop_fd_cb; |
| 12039 | + init_done = true; |
| 12040 | + } |
| 12041 | + |
| 12042 | + eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); |
| 12043 | +} |
| 12044 | diff --git a/src/utils/wpa_debug.c b/src/utils/wpa_debug.c |
| 12045 | index 7f3dd185f..627575e39 100644 |
| 12046 | --- a/src/utils/wpa_debug.c |
| 12047 | +++ b/src/utils/wpa_debug.c |
| 12048 | @@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NULL; |
| 12049 | #define WPAS_TRACE_PFX "wpas <%d>: " |
| 12050 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ |
| 12051 | |
| 12052 | +void (*wpa_printf_hook)(int level, const char *fmt, va_list ap); |
| 12053 | +void (*wpa_hexdump_hook)(int level, const char *title, const void *buf, |
| 12054 | + size_t len); |
| 12055 | +void (*wpa_netlink_hook)(int tx, const void *data, size_t len); |
| 12056 | |
| 12057 | int wpa_debug_level = MSG_INFO; |
| 12058 | int wpa_debug_show_keys = 0; |
| 12059 | @@ -206,10 +210,16 @@ void wpa_debug_close_linux_tracing(void) |
| 12060 | * |
| 12061 | * Note: New line '\n' is added to the end of the text when printing to stdout. |
| 12062 | */ |
| 12063 | -void wpa_printf(int level, const char *fmt, ...) |
| 12064 | +void _wpa_printf(int level, const char *fmt, ...) |
| 12065 | { |
| 12066 | va_list ap; |
| 12067 | |
| 12068 | + if (wpa_printf_hook) { |
| 12069 | + va_start(ap, fmt); |
| 12070 | + wpa_printf_hook(level, fmt, ap); |
| 12071 | + va_end(ap); |
| 12072 | + } |
| 12073 | + |
| 12074 | if (level >= wpa_debug_level) { |
| 12075 | #ifdef CONFIG_ANDROID_LOG |
| 12076 | va_start(ap, fmt); |
| 12077 | @@ -255,11 +265,14 @@ void wpa_printf(int level, const char *fmt, ...) |
| 12078 | } |
| 12079 | |
| 12080 | |
| 12081 | -static void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 12082 | +void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 12083 | size_t len, int show, int only_syslog) |
| 12084 | { |
| 12085 | size_t i; |
| 12086 | |
| 12087 | + if (wpa_hexdump_hook) |
| 12088 | + wpa_hexdump_hook(level, title, buf, len); |
| 12089 | + |
| 12090 | #ifdef CONFIG_DEBUG_LINUX_TRACING |
| 12091 | if (wpa_debug_tracing_file != NULL) { |
| 12092 | fprintf(wpa_debug_tracing_file, |
| 12093 | @@ -382,19 +395,7 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 12094 | #endif /* CONFIG_ANDROID_LOG */ |
| 12095 | } |
| 12096 | |
| 12097 | -void wpa_hexdump(int level, const char *title, const void *buf, size_t len) |
| 12098 | -{ |
| 12099 | - _wpa_hexdump(level, title, buf, len, 1, 0); |
| 12100 | -} |
| 12101 | - |
| 12102 | - |
| 12103 | -void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) |
| 12104 | -{ |
| 12105 | - _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0); |
| 12106 | -} |
| 12107 | - |
| 12108 | - |
| 12109 | -static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12110 | +void _wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12111 | size_t len, int show) |
| 12112 | { |
| 12113 | size_t i, llen; |
| 12114 | @@ -507,20 +508,6 @@ file_done: |
| 12115 | } |
| 12116 | |
| 12117 | |
| 12118 | -void wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12119 | - size_t len) |
| 12120 | -{ |
| 12121 | - _wpa_hexdump_ascii(level, title, buf, len, 1); |
| 12122 | -} |
| 12123 | - |
| 12124 | - |
| 12125 | -void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, |
| 12126 | - size_t len) |
| 12127 | -{ |
| 12128 | - _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); |
| 12129 | -} |
| 12130 | - |
| 12131 | - |
| 12132 | #ifdef CONFIG_DEBUG_FILE |
| 12133 | static char *last_path = NULL; |
| 12134 | #endif /* CONFIG_DEBUG_FILE */ |
| 12135 | @@ -644,7 +631,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) |
| 12136 | } |
| 12137 | |
| 12138 | |
| 12139 | -void wpa_msg(void *ctx, int level, const char *fmt, ...) |
| 12140 | +void _wpa_msg(void *ctx, int level, const char *fmt, ...) |
| 12141 | { |
| 12142 | va_list ap; |
| 12143 | char *buf; |
| 12144 | @@ -682,7 +669,7 @@ void wpa_msg(void *ctx, int level, const char *fmt, ...) |
| 12145 | } |
| 12146 | |
| 12147 | |
| 12148 | -void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12149 | +void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12150 | { |
| 12151 | va_list ap; |
| 12152 | char *buf; |
| 12153 | diff --git a/src/utils/wpa_debug.h b/src/utils/wpa_debug.h |
| 12154 | index 4c02ad3c7..854520bfe 100644 |
| 12155 | --- a/src/utils/wpa_debug.h |
| 12156 | +++ b/src/utils/wpa_debug.h |
| 12157 | @@ -11,6 +11,10 @@ |
| 12158 | |
| 12159 | #include "wpabuf.h" |
| 12160 | |
| 12161 | +extern void (*wpa_printf_hook)(int level, const char *fmt, va_list ap); |
| 12162 | +extern void (*wpa_hexdump_hook)(int level, const char *title, |
| 12163 | + const void *buf, size_t len); |
| 12164 | +extern void (*wpa_netlink_hook)(int tx, const void *data, size_t len); |
| 12165 | extern int wpa_debug_level; |
| 12166 | extern int wpa_debug_show_keys; |
| 12167 | extern int wpa_debug_timestamp; |
| 12168 | @@ -51,6 +55,17 @@ void wpa_debug_close_file(void); |
| 12169 | void wpa_debug_setup_stdout(void); |
| 12170 | void wpa_debug_stop_log(void); |
| 12171 | |
| 12172 | +/* internal */ |
| 12173 | +void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 12174 | + size_t len, int show, int only_syslog); |
| 12175 | +void _wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12176 | + size_t len, int show); |
| 12177 | +extern int wpa_debug_show_keys; |
| 12178 | + |
| 12179 | +#ifndef CONFIG_MSG_MIN_PRIORITY |
| 12180 | +#define CONFIG_MSG_MIN_PRIORITY 0 |
| 12181 | +#endif |
| 12182 | + |
| 12183 | /** |
| 12184 | * wpa_debug_printf_timestamp - Print timestamp for debug output |
| 12185 | * |
| 12186 | @@ -71,9 +86,15 @@ void wpa_debug_print_timestamp(void); |
| 12187 | * |
| 12188 | * Note: New line '\n' is added to the end of the text when printing to stdout. |
| 12189 | */ |
| 12190 | -void wpa_printf(int level, const char *fmt, ...) |
| 12191 | +void _wpa_printf(int level, const char *fmt, ...) |
| 12192 | PRINTF_FORMAT(2, 3); |
| 12193 | |
| 12194 | +#define wpa_printf(level, ...) \ |
| 12195 | + do { \ |
| 12196 | + if (level >= CONFIG_MSG_MIN_PRIORITY) \ |
| 12197 | + _wpa_printf(level, __VA_ARGS__); \ |
| 12198 | + } while(0) |
| 12199 | + |
| 12200 | /** |
| 12201 | * wpa_hexdump - conditional hex dump |
| 12202 | * @level: priority level (MSG_*) of the message |
| 12203 | @@ -85,7 +106,13 @@ PRINTF_FORMAT(2, 3); |
| 12204 | * output may be directed to stdout, stderr, and/or syslog based on |
| 12205 | * configuration. The contents of buf is printed out has hex dump. |
| 12206 | */ |
| 12207 | -void wpa_hexdump(int level, const char *title, const void *buf, size_t len); |
| 12208 | +static inline void wpa_hexdump(int level, const char *title, const void *buf, size_t len) |
| 12209 | +{ |
| 12210 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12211 | + return; |
| 12212 | + |
| 12213 | + _wpa_hexdump(level, title, buf, len, 1, 1); |
| 12214 | +} |
| 12215 | |
| 12216 | static inline void wpa_hexdump_buf(int level, const char *title, |
| 12217 | const struct wpabuf *buf) |
| 12218 | @@ -107,7 +134,13 @@ static inline void wpa_hexdump_buf(int level, const char *title, |
| 12219 | * like wpa_hexdump(), but by default, does not include secret keys (passwords, |
| 12220 | * etc.) in debug output. |
| 12221 | */ |
| 12222 | -void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); |
| 12223 | +static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) |
| 12224 | +{ |
| 12225 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12226 | + return; |
| 12227 | + |
| 12228 | + _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 1); |
| 12229 | +} |
| 12230 | |
| 12231 | static inline void wpa_hexdump_buf_key(int level, const char *title, |
| 12232 | const struct wpabuf *buf) |
| 12233 | @@ -129,8 +162,14 @@ static inline void wpa_hexdump_buf_key(int level, const char *title, |
| 12234 | * the hex numbers and ASCII characters (for printable range) are shown. 16 |
| 12235 | * bytes per line will be shown. |
| 12236 | */ |
| 12237 | -void wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12238 | - size_t len); |
| 12239 | +static inline void wpa_hexdump_ascii(int level, const char *title, |
| 12240 | + const u8 *buf, size_t len) |
| 12241 | +{ |
| 12242 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12243 | + return; |
| 12244 | + |
| 12245 | + _wpa_hexdump_ascii(level, title, buf, len, 1); |
| 12246 | +} |
| 12247 | |
| 12248 | /** |
| 12249 | * wpa_hexdump_ascii_key - conditional hex dump, hide keys |
| 12250 | @@ -146,8 +185,14 @@ void wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12251 | * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by |
| 12252 | * default, does not include secret keys (passwords, etc.) in debug output. |
| 12253 | */ |
| 12254 | -void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, |
| 12255 | - size_t len); |
| 12256 | +static inline void wpa_hexdump_ascii_key(int level, const char *title, |
| 12257 | + const u8 *buf, size_t len) |
| 12258 | +{ |
| 12259 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12260 | + return; |
| 12261 | + |
| 12262 | + _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); |
| 12263 | +} |
| 12264 | |
| 12265 | /* |
| 12266 | * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce |
| 12267 | @@ -184,7 +229,12 @@ void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, |
| 12268 | * |
| 12269 | * Note: New line '\n' is added to the end of the text when printing to stdout. |
| 12270 | */ |
| 12271 | -void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); |
| 12272 | +void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); |
| 12273 | +#define wpa_msg(ctx, level, ...) \ |
| 12274 | + do { \ |
| 12275 | + if (level >= CONFIG_MSG_MIN_PRIORITY) \ |
| 12276 | + _wpa_msg(ctx, level, __VA_ARGS__); \ |
| 12277 | + } while(0) |
| 12278 | |
| 12279 | /** |
| 12280 | * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors |
| 12281 | @@ -198,8 +248,13 @@ void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); |
| 12282 | * attached ctrl_iface monitors. In other words, it can be used for frequent |
| 12283 | * events that do not need to be sent to syslog. |
| 12284 | */ |
| 12285 | -void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12286 | +void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12287 | PRINTF_FORMAT(3, 4); |
| 12288 | +#define wpa_msg_ctrl(ctx, level, ...) \ |
| 12289 | + do { \ |
| 12290 | + if (level >= CONFIG_MSG_MIN_PRIORITY) \ |
| 12291 | + _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \ |
| 12292 | + } while(0) |
| 12293 | |
| 12294 | /** |
| 12295 | * wpa_msg_global - Global printf for ctrl_iface monitors |
| 12296 | diff --git a/tests/Makefile b/tests/Makefile |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12297 | index 8ec154bb3..25fdf9e00 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12298 | --- a/tests/Makefile |
| 12299 | +++ b/tests/Makefile |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12300 | @@ -1,10 +1,12 @@ |
| 12301 | -ALL=test-base64 test-md4 test-milenage \ |
| 12302 | - test-rsa-sig-ver \ |
| 12303 | - test-sha1 \ |
| 12304 | - test-https test-https_server \ |
| 12305 | - test-sha256 test-aes test-x509v3 test-list test-rc4 \ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12306 | +RUN_TESTS= \ |
| 12307 | + test-list \ |
| 12308 | + test-md4 test-rc4 test-sha1 test-sha256 \ |
| 12309 | + test-milenage test-aes \ |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12310 | + test-crypto_module \ |
| 12311 | test-bss |
| 12312 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12313 | +ALL=$(RUN_TESTS) test-base64 test-https test-https_server |
| 12314 | + |
| 12315 | include ../src/build.rules |
| 12316 | |
| 12317 | ifdef LIBFUZZER |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12318 | @@ -25,13 +27,27 @@ CFLAGS += -DCONFIG_IEEE80211R_AP |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12319 | CFLAGS += -DCONFIG_IEEE80211R |
| 12320 | CFLAGS += -DCONFIG_TDLS |
| 12321 | |
| 12322 | +# test-crypto_module |
| 12323 | +CFLAGS += -DCONFIG_MODULE_TESTS |
| 12324 | +CFLAGS += -DCONFIG_DPP |
| 12325 | +#CFLAGS += -DCONFIG_DPP2 |
| 12326 | +#CFLAGS += -DCONFIG_DPP3 |
| 12327 | +CFLAGS += -DCONFIG_ECC |
| 12328 | +CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 12329 | +CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 12330 | +CFLAGS += -DCONFIG_MESH |
| 12331 | +CFLAGS += -DCONFIG_SHA256 |
| 12332 | +CFLAGS += -DCONFIG_SHA384 |
| 12333 | +CFLAGS += -DEAP_PSK |
| 12334 | +CFLAGS += -DEAP_FAST |
| 12335 | + |
| 12336 | CFLAGS += -I../src |
| 12337 | CFLAGS += -I../src/utils |
| 12338 | |
| 12339 | SLIBS = ../src/utils/libutils.a |
| 12340 | |
| 12341 | -DLIBS = ../src/crypto/libcrypto.a \ |
| 12342 | - ../src/tls/libtls.a |
| 12343 | +DLIBS = ../src/tls/libtls.a \ |
| 12344 | + ../src/crypto/libcrypto.a |
| 12345 | |
| 12346 | _OBJS_VAR := LLIBS |
| 12347 | include ../src/objs.mk |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12348 | @@ -43,12 +59,43 @@ include ../src/objs.mk |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12349 | LIBS = $(SLIBS) $(DLIBS) |
| 12350 | LLIBS = -Wl,--start-group $(DLIBS) -Wl,--end-group $(SLIBS) |
| 12351 | |
| 12352 | +ifeq ($(CONFIG_TLS),mbedtls) |
| 12353 | +CFLAGS += -DCONFIG_TLS_MBEDTLS |
| 12354 | +LLIBS += -lmbedtls -lmbedx509 -lmbedcrypto |
| 12355 | +else |
| 12356 | +ifeq ($(CONFIG_TLS),openssl) |
| 12357 | +CFLAGS += -DCONFIG_TLS_OPENSSL |
| 12358 | +LLIBS += -lssl -lcrypto |
| 12359 | +else |
| 12360 | +ifeq ($(CONFIG_TLS),gnutls) |
| 12361 | +CFLAGS += -DCONFIG_TLS_GNUTLS |
| 12362 | +LLIBS += -lgnutls -lgpg-error -lgcrypt |
| 12363 | +else |
| 12364 | +ifeq ($(CONFIG_TLS),wolfssl) |
| 12365 | +CFLAGS += -DCONFIG_TLS_WOLFSSL |
| 12366 | +LLIBS += -lwolfssl -lm |
| 12367 | +else |
| 12368 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 12369 | +CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER |
| 12370 | +ALL += test-rsa-sig-ver |
| 12371 | +ALL += test-x509v3 |
| 12372 | +clean-config_tls_internal: |
| 12373 | + rm -f test_x509v3_nist.out.* |
| 12374 | + rm -f test_x509v3_nist2.out.* |
| 12375 | +endif |
| 12376 | +endif |
| 12377 | +endif |
| 12378 | +endif |
| 12379 | + |
| 12380 | # glibc < 2.17 needs -lrt for clock_gettime() |
| 12381 | LLIBS += -lrt |
| 12382 | |
| 12383 | test-aes: $(call BUILDOBJ,test-aes.o) $(LIBS) |
| 12384 | $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) |
| 12385 | |
| 12386 | +test-crypto_module: $(call BUILDOBJ,test-crypto_module.o) $(LIBS) |
| 12387 | + $(LDO) $(LDFLAGS) -o $@ $< $(LLIBS) |
| 12388 | + |
| 12389 | test-base64: $(call BUILDOBJ,test-base64.o) $(LIBS) |
| 12390 | $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) |
| 12391 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12392 | @@ -141,18 +188,11 @@ test-bss: $(call BUILDOBJ,test-bss.o) $(WPA_OBJS) $(LIBS) |
| 12393 | $(LDO) $(LDFLAGS) -o $@ $< $(LLIBS) $(WPA_CFLAGS) $(WPA_OBJS) $(LIBS) |
| 12394 | |
| 12395 | run-tests: $(ALL) |
| 12396 | - ./test-aes |
| 12397 | - ./test-list |
| 12398 | - ./test-md4 |
| 12399 | - ./test-milenage |
| 12400 | - ./test-rsa-sig-ver |
| 12401 | - ./test-sha1 |
| 12402 | - ./test-sha256 |
| 12403 | - ./test-bss |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12404 | + @set -ex; for i in $(RUN_TESTS); do ./$$i; done |
| 12405 | @echo |
| 12406 | @echo All tests completed successfully. |
| 12407 | |
| 12408 | -clean: common-clean |
| 12409 | +clean: common-clean clean-config_tls_internal |
| 12410 | rm -f *~ |
| 12411 | - rm -f test_x509v3_nist.out.* |
| 12412 | - rm -f test_x509v3_nist2.out.* |
| 12413 | + |
| 12414 | +.PHONY: run-tests clean-config_tls_internal |
| 12415 | diff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12416 | index 210b7fb86..5f326da07 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12417 | --- a/tests/hwsim/example-hostapd.config |
| 12418 | +++ b/tests/hwsim/example-hostapd.config |
| 12419 | @@ -4,6 +4,7 @@ CONFIG_DRIVER_NONE=y |
| 12420 | CONFIG_DRIVER_NL80211=y |
| 12421 | CONFIG_RSN_PREAUTH=y |
| 12422 | |
| 12423 | +#CONFIG_TLS=mbedtls |
| 12424 | #CONFIG_TLS=internal |
| 12425 | #CONFIG_INTERNAL_LIBTOMMATH=y |
| 12426 | #CONFIG_INTERNAL_LIBTOMMATH_FAST=y |
| 12427 | @@ -33,12 +34,7 @@ CONFIG_EAP_TNC=y |
| 12428 | CFLAGS += -DTNC_CONFIG_FILE=\"tnc/tnc_config\" |
| 12429 | LIBS += -rdynamic |
| 12430 | CONFIG_EAP_UNAUTH_TLS=y |
| 12431 | -ifeq ($(CONFIG_TLS), openssl) |
| 12432 | -CONFIG_EAP_PWD=y |
| 12433 | -endif |
| 12434 | -ifeq ($(CONFIG_TLS), wolfssl) |
| 12435 | -CONFIG_EAP_PWD=y |
| 12436 | -endif |
| 12437 | +CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) |
| 12438 | CONFIG_EAP_EKE=y |
| 12439 | CONFIG_PKCS12=y |
| 12440 | CONFIG_RADIUS_SERVER=y |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12441 | diff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12442 | index 123f397e3..c69b1f9cd 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12443 | --- a/tests/hwsim/example-wpa_supplicant.config |
| 12444 | +++ b/tests/hwsim/example-wpa_supplicant.config |
| 12445 | @@ -2,6 +2,7 @@ |
| 12446 | |
| 12447 | CONFIG_TLS=openssl |
| 12448 | #CONFIG_TLS=wolfssl |
| 12449 | +#CONFIG_TLS=mbedtls |
| 12450 | #CONFIG_TLS=internal |
| 12451 | #CONFIG_INTERNAL_LIBTOMMATH=y |
| 12452 | #CONFIG_INTERNAL_LIBTOMMATH_FAST=y |
| 12453 | @@ -34,13 +35,7 @@ LIBS += -rdynamic |
| 12454 | CONFIG_EAP_FAST=y |
| 12455 | CONFIG_EAP_TEAP=y |
| 12456 | CONFIG_EAP_IKEV2=y |
| 12457 | - |
| 12458 | -ifeq ($(CONFIG_TLS), openssl) |
| 12459 | -CONFIG_EAP_PWD=y |
| 12460 | -endif |
| 12461 | -ifeq ($(CONFIG_TLS), wolfssl) |
| 12462 | -CONFIG_EAP_PWD=y |
| 12463 | -endif |
| 12464 | +CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) |
| 12465 | |
| 12466 | CONFIG_USIM_SIMULATOR=y |
| 12467 | CONFIG_SIM_SIMULATOR=y |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12468 | diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12469 | index f8e75b5fb..48e4dedcc 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12470 | --- a/tests/hwsim/test_ap_eap.py |
| 12471 | +++ b/tests/hwsim/test_ap_eap.py |
| 12472 | @@ -42,20 +42,42 @@ def check_eap_capa(dev, method): |
| 12473 | res = dev.get_capability("eap") |
| 12474 | if method not in res: |
| 12475 | raise HwsimSkip("EAP method %s not supported in the build" % method) |
| 12476 | + if method == "FAST" or method == "TEAP": |
| 12477 | + tls = dev.request("GET tls_library") |
| 12478 | + if tls.startswith("mbed TLS"): |
| 12479 | + raise HwsimSkip("EAP-%s not supported with this TLS library: " % method + tls) |
| 12480 | |
| 12481 | def check_subject_match_support(dev): |
| 12482 | tls = dev.request("GET tls_library") |
| 12483 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12484 | + if tls.startswith("OpenSSL"): |
| 12485 | + return |
| 12486 | + elif tls.startswith("wolfSSL"): |
| 12487 | + return |
| 12488 | + elif tls.startswith("mbed TLS"): |
| 12489 | + return |
| 12490 | + else: |
| 12491 | raise HwsimSkip("subject_match not supported with this TLS library: " + tls) |
| 12492 | |
| 12493 | def check_check_cert_subject_support(dev): |
| 12494 | tls = dev.request("GET tls_library") |
| 12495 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12496 | + if tls.startswith("OpenSSL"): |
| 12497 | + return |
| 12498 | + elif tls.startswith("wolfSSL"): |
| 12499 | + return |
| 12500 | + elif tls.startswith("mbed TLS"): |
| 12501 | + return |
| 12502 | + else: |
| 12503 | raise HwsimSkip("check_cert_subject not supported with this TLS library: " + tls) |
| 12504 | |
| 12505 | def check_altsubject_match_support(dev): |
| 12506 | tls = dev.request("GET tls_library") |
| 12507 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12508 | + if tls.startswith("OpenSSL"): |
| 12509 | + return |
| 12510 | + elif tls.startswith("wolfSSL"): |
| 12511 | + return |
| 12512 | + elif tls.startswith("mbed TLS"): |
| 12513 | + return |
| 12514 | + else: |
| 12515 | raise HwsimSkip("altsubject_match not supported with this TLS library: " + tls) |
| 12516 | |
| 12517 | def check_domain_match(dev): |
| 12518 | @@ -70,7 +92,13 @@ def check_domain_suffix_match(dev): |
| 12519 | |
| 12520 | def check_domain_match_full(dev): |
| 12521 | tls = dev.request("GET tls_library") |
| 12522 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12523 | + if tls.startswith("OpenSSL"): |
| 12524 | + return |
| 12525 | + elif tls.startswith("wolfSSL"): |
| 12526 | + return |
| 12527 | + elif tls.startswith("mbed TLS"): |
| 12528 | + return |
| 12529 | + else: |
| 12530 | raise HwsimSkip("domain_suffix_match requires full match with this TLS library: " + tls) |
| 12531 | |
| 12532 | def check_cert_probe_support(dev): |
| 12533 | @@ -79,8 +107,15 @@ def check_cert_probe_support(dev): |
| 12534 | raise HwsimSkip("Certificate probing not supported with this TLS library: " + tls) |
| 12535 | |
| 12536 | def check_ext_cert_check_support(dev): |
| 12537 | + if not openssl_imported: |
| 12538 | + raise HwsimSkip("OpenSSL python method not available") |
| 12539 | + |
| 12540 | tls = dev.request("GET tls_library") |
| 12541 | - if not tls.startswith("OpenSSL"): |
| 12542 | + if tls.startswith("OpenSSL"): |
| 12543 | + return |
| 12544 | + elif tls.startswith("mbed TLS"): |
| 12545 | + return |
| 12546 | + else: |
| 12547 | raise HwsimSkip("ext_cert_check not supported with this TLS library: " + tls) |
| 12548 | |
| 12549 | def check_ocsp_support(dev): |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12550 | @@ -91,14 +126,18 @@ def check_ocsp_support(dev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12551 | # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) |
| 12552 | #if tls.startswith("wolfSSL"): |
| 12553 | # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) |
| 12554 | + if tls.startswith("mbed TLS"): |
| 12555 | + raise HwsimSkip("OCSP not supported with this TLS library: " + tls) |
| 12556 | |
| 12557 | def check_pkcs5_v15_support(dev): |
| 12558 | tls = dev.request("GET tls_library") |
| 12559 | - if "BoringSSL" in tls or "GnuTLS" in tls: |
| 12560 | + if "BoringSSL" in tls or "GnuTLS" in tls or "mbed TLS" in tls: |
| 12561 | raise HwsimSkip("PKCS#5 v1.5 not supported with this TLS library: " + tls) |
| 12562 | |
| 12563 | def check_tls13_support(dev): |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12564 | tls = dev.request("GET tls_library") |
| 12565 | + if tls.startswith("mbed TLS"): |
| 12566 | + raise HwsimSkip("TLS v1.3 not supported") |
| 12567 | ok = ['run=OpenSSL 1.1.1', 'run=OpenSSL 3.0', 'run=OpenSSL 3.1', |
| 12568 | 'run=OpenSSL 3.2', 'run=OpenSSL 3.3', 'wolfSSL'] |
| 12569 | for s in ok: |
| 12570 | @@ -122,11 +161,15 @@ def check_pkcs12_support(dev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12571 | # raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) |
| 12572 | if tls.startswith("wolfSSL"): |
| 12573 | raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) |
| 12574 | + if tls.startswith("mbed TLS"): |
| 12575 | + raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) |
| 12576 | |
| 12577 | def check_dh_dsa_support(dev): |
| 12578 | tls = dev.request("GET tls_library") |
| 12579 | if tls.startswith("internal"): |
| 12580 | raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) |
| 12581 | + if tls.startswith("mbed TLS"): |
| 12582 | + raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) |
| 12583 | |
| 12584 | def check_ec_support(dev): |
| 12585 | tls = dev.request("GET tls_library") |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12586 | @@ -1741,7 +1784,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_match(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12587 | eap_connect(dev[0], hapd, "TTLS", "pap user", |
| 12588 | anonymous_identity="ttls", password="password", |
| 12589 | ca_cert="auth_serv/ca.pem", phase2="auth=PAP", |
| 12590 | - subject_match="/C=FI/O=w1.fi/CN=server.w1.fi", |
| 12591 | + check_cert_subject="/C=FI/O=w1.fi/CN=server.w1.fi", |
| 12592 | altsubject_match="EMAIL:noone@example.com;DNS:server.w1.fi;URI:http://example.com/") |
| 12593 | eap_reauth(dev[0], "TTLS") |
| 12594 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12595 | @@ -2976,6 +3019,7 @@ def test_ap_wpa2_eap_tls_neg_domain_match(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12596 | |
| 12597 | def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): |
| 12598 | """WPA2-Enterprise negative test - subject mismatch""" |
| 12599 | + check_subject_match_support(dev[0]) |
| 12600 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12601 | hostapd.add_ap(apdev[0], params) |
| 12602 | dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12603 | @@ -3036,6 +3080,7 @@ def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12604 | |
| 12605 | def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): |
| 12606 | """WPA2-Enterprise negative test - altsubject mismatch""" |
| 12607 | + check_altsubject_match_support(dev[0]) |
| 12608 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12609 | hostapd.add_ap(apdev[0], params) |
| 12610 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12611 | @@ -3582,7 +3627,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12612 | dev[0].request("REMOVE_NETWORK all") |
| 12613 | |
| 12614 | tls = dev[0].request("GET tls_library") |
| 12615 | - if not tls.startswith("wolfSSL"): |
| 12616 | + if not tls.startswith("wolfSSL") and not tls.startswith("mbed TLS"): |
| 12617 | tests = [(1, "os_get_random;dh_init")] |
| 12618 | else: |
| 12619 | tests = [(1, "crypto_dh_init;dh_init")] |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12620 | @@ -4896,7 +4941,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca(dev, apdev, params): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12621 | params["private_key"] = "auth_serv/iCA-server/server.key" |
| 12622 | hostapd.add_ap(apdev[0], params) |
| 12623 | tls = dev[0].request("GET tls_library") |
| 12624 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12625 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12626 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12627 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12628 | else: |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12629 | @@ -4962,6 +5007,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_sha1(dev, apdev, params): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12630 | run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, "-sha1") |
| 12631 | |
| 12632 | def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): |
| 12633 | + check_ocsp_support(dev[0]) |
| 12634 | params = int_eap_server_params() |
| 12635 | params["ca_cert"] = "auth_serv/iCA-server/ca-and-root.pem" |
| 12636 | params["server_cert"] = "auth_serv/iCA-server/server.pem" |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12637 | @@ -4971,7 +5017,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12638 | try: |
| 12639 | hostapd.add_ap(apdev[0], params) |
| 12640 | tls = dev[0].request("GET tls_library") |
| 12641 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12642 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12643 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12644 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12645 | else: |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12646 | @@ -5007,7 +5053,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked(dev, apdev, params, md): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12647 | try: |
| 12648 | hostapd.add_ap(apdev[0], params) |
| 12649 | tls = dev[0].request("GET tls_library") |
| 12650 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12651 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12652 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12653 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12654 | else: |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12655 | @@ -5057,7 +5103,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi_missing_resp(dev, apdev, par |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12656 | try: |
| 12657 | hostapd.add_ap(apdev[0], params) |
| 12658 | tls = dev[0].request("GET tls_library") |
| 12659 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12660 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12661 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12662 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12663 | else: |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12664 | @@ -5124,7 +5170,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi(dev, apdev, params): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12665 | |
| 12666 | hostapd.add_ap(apdev[0], params) |
| 12667 | tls = dev[0].request("GET tls_library") |
| 12668 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12669 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12670 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12671 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12672 | else: |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12673 | @@ -5382,6 +5428,7 @@ def test_ap_wpa2_eap_ttls_server_cert_eku_client_server(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12674 | |
| 12675 | def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): |
| 12676 | """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" |
| 12677 | + check_pkcs12_support(dev[0]) |
| 12678 | skip_with_fips(dev[0]) |
| 12679 | params = int_eap_server_params() |
| 12680 | del params["server_cert"] |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12681 | @@ -5394,6 +5441,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12682 | |
| 12683 | def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): |
| 12684 | """EAP-TTLS and server PKCS#12 file with extra certs""" |
| 12685 | + check_pkcs12_support(dev[0]) |
| 12686 | skip_with_fips(dev[0]) |
| 12687 | params = int_eap_server_params() |
| 12688 | del params["server_cert"] |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12689 | @@ -5416,6 +5464,7 @@ def test_ap_wpa2_eap_ttls_dh_params_server(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12690 | |
| 12691 | def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): |
| 12692 | """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" |
| 12693 | + check_dh_dsa_support(dev[0]) |
| 12694 | params = int_eap_server_params() |
| 12695 | params["dh_file"] = "auth_serv/dsaparam.pem" |
| 12696 | hapd = hostapd.add_ap(apdev[0], params) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12697 | @@ -5727,8 +5776,8 @@ def test_ap_wpa2_eap_non_ascii_identity2(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12698 | def test_openssl_cipher_suite_config_wpas(dev, apdev): |
| 12699 | """OpenSSL cipher suite configuration on wpa_supplicant""" |
| 12700 | tls = dev[0].request("GET tls_library") |
| 12701 | - if not tls.startswith("OpenSSL"): |
| 12702 | - raise HwsimSkip("TLS library is not OpenSSL: " + tls) |
| 12703 | + if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): |
| 12704 | + raise HwsimSkip("TLS library is not OpenSSL or mbed TLS: " + tls) |
| 12705 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12706 | hapd = hostapd.add_ap(apdev[0], params) |
| 12707 | eap_connect(dev[0], hapd, "TTLS", "pap user", |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12708 | @@ -5754,14 +5803,14 @@ def test_openssl_cipher_suite_config_wpas(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12709 | def test_openssl_cipher_suite_config_hapd(dev, apdev): |
| 12710 | """OpenSSL cipher suite configuration on hostapd""" |
| 12711 | tls = dev[0].request("GET tls_library") |
| 12712 | - if not tls.startswith("OpenSSL"): |
| 12713 | - raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL: " + tls) |
| 12714 | + if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): |
| 12715 | + raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL or mbed TLS: " + tls) |
| 12716 | params = int_eap_server_params() |
| 12717 | params['openssl_ciphers'] = "AES256" |
| 12718 | hapd = hostapd.add_ap(apdev[0], params) |
| 12719 | tls = hapd.request("GET tls_library") |
| 12720 | - if not tls.startswith("OpenSSL"): |
| 12721 | - raise HwsimSkip("hostapd TLS library is not OpenSSL: " + tls) |
| 12722 | + if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): |
| 12723 | + raise HwsimSkip("hostapd TLS library is not OpenSSL or mbed TLS: " + tls) |
| 12724 | eap_connect(dev[0], hapd, "TTLS", "pap user", |
| 12725 | anonymous_identity="ttls", password="password", |
| 12726 | ca_cert="auth_serv/ca.pem", phase2="auth=PAP") |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12727 | @@ -6207,13 +6256,17 @@ def test_ap_wpa2_eap_tls_versions(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12728 | check_tls_ver(dev[0], hapd, |
| 12729 | "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", |
| 12730 | "TLSv1.2") |
| 12731 | - elif tls.startswith("internal"): |
| 12732 | + elif tls.startswith("internal") or tls.startswith("mbed TLS"): |
| 12733 | check_tls_ver(dev[0], hapd, |
| 12734 | "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12735 | - check_tls_ver(dev[1], hapd, |
| 12736 | - "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1") |
| 12737 | - check_tls_ver(dev[2], hapd, |
| 12738 | - "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1") |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12739 | + if tls.startswith("mbed TLS"): |
| 12740 | + check_tls_ver(dev[2], hapd, |
| 12741 | + "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1.0") |
| 12742 | + else: |
| 12743 | + check_tls_ver(dev[1], hapd, |
| 12744 | + "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1") |
| 12745 | + check_tls_ver(dev[2], hapd, |
| 12746 | + "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1") |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12747 | if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3." in tls: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12748 | check_tls_ver(dev[0], hapd, |
| 12749 | "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0", "TLSv1.3") |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12750 | @@ -6235,6 +6288,11 @@ def test_ap_wpa2_eap_tls_versions_server(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12751 | tests = [("TLSv1", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12752 | ("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12753 | ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] |
| 12754 | + tls = dev[0].request("GET tls_library") |
| 12755 | + if tls.startswith("mbed TLS"): |
| 12756 | + tests = [#("TLSv1.0", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12757 | + #("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12758 | + ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] |
| 12759 | for exp, flags in tests: |
| 12760 | hapd.disable() |
| 12761 | hapd.set("tls_flags", flags) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12762 | @@ -7305,6 +7363,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12763 | def test_eap_tls_ext_cert_check(dev, apdev): |
| 12764 | """EAP-TLS and external server certification validation""" |
| 12765 | # With internal server certificate chain validation |
| 12766 | + check_ext_cert_check_support(dev[0]) |
| 12767 | id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", |
| 12768 | identity="tls user", |
| 12769 | ca_cert="auth_serv/ca.pem", |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12770 | @@ -7317,6 +7376,7 @@ def test_eap_tls_ext_cert_check(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12771 | def test_eap_ttls_ext_cert_check(dev, apdev): |
| 12772 | """EAP-TTLS and external server certification validation""" |
| 12773 | # Without internal server certificate chain validation |
| 12774 | + check_ext_cert_check_support(dev[0]) |
| 12775 | id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", |
| 12776 | identity="pap user", anonymous_identity="ttls", |
| 12777 | password="password", phase2="auth=PAP", |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12778 | @@ -7327,6 +7387,7 @@ def test_eap_ttls_ext_cert_check(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12779 | def test_eap_peap_ext_cert_check(dev, apdev): |
| 12780 | """EAP-PEAP and external server certification validation""" |
| 12781 | # With internal server certificate chain validation |
| 12782 | + check_ext_cert_check_support(dev[0]) |
| 12783 | id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", |
| 12784 | identity="user", anonymous_identity="peap", |
| 12785 | ca_cert="auth_serv/ca.pem", |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12786 | @@ -7337,6 +7398,7 @@ def test_eap_peap_ext_cert_check(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12787 | |
| 12788 | def test_eap_fast_ext_cert_check(dev, apdev): |
| 12789 | """EAP-FAST and external server certification validation""" |
| 12790 | + check_ext_cert_check_support(dev[0]) |
| 12791 | check_eap_capa(dev[0], "FAST") |
| 12792 | # With internal server certificate chain validation |
| 12793 | dev[0].request("SET blob fast_pac_auth_ext ") |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12794 | @@ -7351,10 +7413,6 @@ def test_eap_fast_ext_cert_check(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12795 | run_ext_cert_check(dev, apdev, id) |
| 12796 | |
| 12797 | def run_ext_cert_check(dev, apdev, net_id): |
| 12798 | - check_ext_cert_check_support(dev[0]) |
| 12799 | - if not openssl_imported: |
| 12800 | - raise HwsimSkip("OpenSSL python method not available") |
| 12801 | - |
| 12802 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12803 | hapd = hostapd.add_ap(apdev[0], params) |
| 12804 | |
| 12805 | diff --git a/tests/hwsim/test_ap_ft.py b/tests/hwsim/test_ap_ft.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12806 | index 13461f014..8ffb5042c 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12807 | --- a/tests/hwsim/test_ap_ft.py |
| 12808 | +++ b/tests/hwsim/test_ap_ft.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12809 | @@ -2494,11 +2494,11 @@ def test_ap_ft_ap_oom5(dev, apdev): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12810 | # This will fail to roam |
| 12811 | dev[0].roam(bssid1, check_bssid=False) |
| 12812 | |
| 12813 | - with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12814 | + with fail_test(hapd1, 1, "sha256_prf;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12815 | # This will fail to roam |
| 12816 | dev[0].roam(bssid1, check_bssid=False) |
| 12817 | |
| 12818 | - with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12819 | + with fail_test(hapd1, 2, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12820 | # This will fail to roam |
| 12821 | dev[0].roam(bssid1, check_bssid=False) |
| 12822 | |
| 12823 | diff --git a/tests/hwsim/test_authsrv.py b/tests/hwsim/test_authsrv.py |
| 12824 | index e0665bcb2..02ec301e5 100644 |
| 12825 | --- a/tests/hwsim/test_authsrv.py |
| 12826 | +++ b/tests/hwsim/test_authsrv.py |
| 12827 | @@ -156,9 +156,12 @@ def test_authsrv_oom(dev, apdev): |
| 12828 | if "FAIL" not in authsrv.request("ENABLE"): |
| 12829 | raise Exception("ENABLE succeeded during OOM") |
| 12830 | |
| 12831 | - with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): |
| 12832 | - if "FAIL" not in authsrv.request("ENABLE"): |
| 12833 | - raise Exception("ENABLE succeeded during OOM") |
| 12834 | + # tls_mbedtls.c:tls_init() does not alloc memory (no alloc fail trigger) |
| 12835 | + tls = dev[0].request("GET tls_library") |
| 12836 | + if not tls.startswith("mbed TLS"): |
| 12837 | + with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): |
| 12838 | + if "FAIL" not in authsrv.request("ENABLE"): |
| 12839 | + raise Exception("ENABLE succeeded during OOM") |
| 12840 | |
| 12841 | for count in range(1, 3): |
| 12842 | with alloc_fail(authsrv, count, "eap_sim_db_init;authsrv_init"): |
| 12843 | diff --git a/tests/hwsim/test_dpp.py b/tests/hwsim/test_dpp.py |
| 12844 | index 518983bd0..077de58c9 100644 |
| 12845 | --- a/tests/hwsim/test_dpp.py |
| 12846 | +++ b/tests/hwsim/test_dpp.py |
| 12847 | @@ -39,7 +39,8 @@ def check_dpp_capab(dev, brainpool=False, min_ver=1): |
| 12848 | raise HwsimSkip("DPP not supported") |
| 12849 | if brainpool: |
| 12850 | tls = dev.request("GET tls_library") |
| 12851 | - if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL"): |
| 12852 | + if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL") \ |
| 12853 | + and not tls.startswith("mbed TLS"): |
| 12854 | raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls) |
| 12855 | capa = dev.request("GET_CAPABILITY dpp") |
| 12856 | ver = 1 |
| 12857 | @@ -3902,6 +3903,9 @@ def test_dpp_proto_auth_req_no_i_proto_key(dev, apdev): |
| 12858 | |
| 12859 | def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): |
| 12860 | """DPP protocol testing - invalid I-proto key in Auth Req""" |
| 12861 | + tls = dev[0].request("GET tls_library") |
| 12862 | + if tls.startswith("mbed TLS"): |
| 12863 | + raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") |
| 12864 | run_dpp_proto_auth_req_missing(dev, 66, "Invalid Initiator Protocol Key") |
| 12865 | |
| 12866 | def test_dpp_proto_auth_req_no_i_nonce(dev, apdev): |
| 12867 | @@ -3997,7 +4001,12 @@ def test_dpp_proto_auth_resp_no_r_proto_key(dev, apdev): |
| 12868 | |
| 12869 | def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): |
| 12870 | """DPP protocol testing - invalid R-Proto Key in Auth Resp""" |
| 12871 | - run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") |
| 12872 | + tls = dev[0].request("GET tls_library") |
| 12873 | + if tls.startswith("mbed TLS"): |
| 12874 | + # mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key |
| 12875 | + run_dpp_proto_auth_resp_missing(dev, 67, "Failed to derive ECDH shared secret") |
| 12876 | + else: |
| 12877 | + run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") |
| 12878 | |
| 12879 | def test_dpp_proto_auth_resp_no_r_nonce(dev, apdev): |
| 12880 | """DPP protocol testing - no R-nonce in Auth Resp""" |
| 12881 | @@ -4359,11 +4368,17 @@ def test_dpp_proto_pkex_exchange_resp_invalid_status(dev, apdev): |
| 12882 | |
| 12883 | def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): |
| 12884 | """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" |
| 12885 | + tls = dev[0].request("GET tls_library") |
| 12886 | + if tls.startswith("mbed TLS"): |
| 12887 | + raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") |
| 12888 | run_dpp_proto_pkex_req_missing(dev, 47, |
| 12889 | "Peer bootstrapping key is invalid") |
| 12890 | |
| 12891 | def test_dpp_proto_pkex_cr_resp_invalid_bootstrap_key(dev, apdev): |
| 12892 | """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Response""" |
| 12893 | + tls = dev[0].request("GET tls_library") |
| 12894 | + if tls.startswith("mbed TLS"): |
| 12895 | + raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") |
| 12896 | run_dpp_proto_pkex_resp_missing(dev, 48, |
| 12897 | "Peer bootstrapping key is invalid") |
| 12898 | |
| 12899 | diff --git a/tests/hwsim/test_erp.py b/tests/hwsim/test_erp.py |
| 12900 | index d083993e8..262e9f095 100644 |
| 12901 | --- a/tests/hwsim/test_erp.py |
| 12902 | +++ b/tests/hwsim/test_erp.py |
| 12903 | @@ -12,7 +12,7 @@ import time |
| 12904 | |
| 12905 | import hostapd |
| 12906 | from utils import * |
| 12907 | -from test_ap_eap import int_eap_server_params, check_tls13_support |
| 12908 | +from test_ap_eap import int_eap_server_params, check_tls13_support, check_eap_capa |
| 12909 | from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations |
| 12910 | |
| 12911 | def test_erp_initiate_reauth_start(dev, apdev): |
| 12912 | @@ -276,6 +276,7 @@ def test_erp_radius_eap_methods(dev, apdev): |
| 12913 | params['erp_domain'] = 'example.com' |
| 12914 | params['disable_pmksa_caching'] = '1' |
| 12915 | hapd = hostapd.add_ap(apdev[0], params) |
| 12916 | + tls = dev[0].request("GET tls_library") |
| 12917 | |
| 12918 | erp_test(dev[0], hapd, eap="AKA", identity="0232010000000000@example.com", |
| 12919 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") |
| 12920 | @@ -289,7 +290,7 @@ def test_erp_radius_eap_methods(dev, apdev): |
| 12921 | password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") |
| 12922 | erp_test(dev[0], hapd, eap="EKE", identity="erp-eke@example.com", |
| 12923 | password="hello") |
| 12924 | - if "FAST" in eap_methods: |
| 12925 | + if "FAST" in eap_methods and check_eap_capa(dev[0], "FAST"): |
| 12926 | erp_test(dev[0], hapd, eap="FAST", identity="erp-fast@example.com", |
| 12927 | password="password", ca_cert="auth_serv/ca.pem", |
| 12928 | phase2="auth=GTC", |
| 12929 | @@ -301,13 +302,14 @@ def test_erp_radius_eap_methods(dev, apdev): |
| 12930 | password="password") |
| 12931 | erp_test(dev[0], hapd, eap="PAX", identity="erp-pax@example.com", |
| 12932 | password_hex="0123456789abcdef0123456789abcdef") |
| 12933 | - if "MSCHAPV2" in eap_methods: |
| 12934 | + if "MSCHAPV2" in eap_methods and check_eap_capa(dev[0], "MSCHAPV2"): |
| 12935 | erp_test(dev[0], hapd, eap="PEAP", identity="erp-peap@example.com", |
| 12936 | password="password", ca_cert="auth_serv/ca.pem", |
| 12937 | phase2="auth=MSCHAPV2") |
| 12938 | - erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", |
| 12939 | - password="password", ca_cert="auth_serv/ca.pem", |
| 12940 | - phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") |
| 12941 | + if check_eap_capa(dev[0], "TEAP"): |
| 12942 | + erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", |
| 12943 | + password="password", ca_cert="auth_serv/ca.pem", |
| 12944 | + phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") |
| 12945 | erp_test(dev[0], hapd, eap="PSK", identity="erp-psk@example.com", |
| 12946 | password_hex="0123456789abcdef0123456789abcdef") |
| 12947 | if "PWD" in eap_methods: |
| 12948 | @@ -640,7 +642,7 @@ def test_erp_local_errors(dev, apdev): |
| 12949 | dev[0].request("REMOVE_NETWORK all") |
| 12950 | dev[0].wait_disconnected() |
| 12951 | |
| 12952 | - for count in range(1, 6): |
| 12953 | + for count in range(1, 4): |
| 12954 | dev[0].request("ERP_FLUSH") |
| 12955 | with fail_test(dev[0], count, "hmac_sha256_kdf;eap_peer_erp_init"): |
| 12956 | dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", |
| 12957 | diff --git a/tests/hwsim/test_fils.py b/tests/hwsim/test_fils.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12958 | index 6f857243a..de65c57a7 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12959 | --- a/tests/hwsim/test_fils.py |
| 12960 | +++ b/tests/hwsim/test_fils.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12961 | @@ -1477,6 +1477,10 @@ def check_ec_group(dev, group): |
| 12962 | tls = dev.request("GET tls_library") |
| 12963 | if tls.startswith("wolfSSL"): |
| 12964 | return |
| 12965 | + elif tls.startswith("mbed TLS"): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12966 | + if int(group) == 27: |
| 12967 | + raise HwsimSkip("Brainpool EC group 27 not supported by mbed TLS") |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12968 | + return |
| 12969 | if int(group) in [25]: |
| 12970 | if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3." in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3." in tls)): |
| 12971 | raise HwsimSkip("EC group not supported") |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12972 | diff --git a/tests/hwsim/test_pmksa_cache.py b/tests/hwsim/test_pmksa_cache.py |
| 12973 | index 4a3b444ff..4f7f7f760 100644 |
| 12974 | --- a/tests/hwsim/test_pmksa_cache.py |
| 12975 | +++ b/tests/hwsim/test_pmksa_cache.py |
| 12976 | @@ -958,7 +958,7 @@ def test_pmksa_cache_preauth_wpas_oom(dev, apdev): |
| 12977 | eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", |
| 12978 | password_hex="0123456789abcdef0123456789abcdef", |
| 12979 | bssid=apdev[0]['bssid']) |
| 12980 | - for i in range(1, 11): |
| 12981 | + for i in range(1, 10): |
| 12982 | with alloc_fail(dev[0], i, "rsn_preauth_init"): |
| 12983 | res = dev[0].request("PREAUTH f2:11:22:33:44:55").strip() |
| 12984 | logger.info("Iteration %d - PREAUTH command results: %s" % (i, res)) |
| 12985 | @@ -966,7 +966,7 @@ def test_pmksa_cache_preauth_wpas_oom(dev, apdev): |
| 12986 | state = dev[0].request('GET_ALLOC_FAIL') |
| 12987 | if state.startswith('0:'): |
| 12988 | break |
| 12989 | - time.sleep(0.05) |
| 12990 | + time.sleep(0.10) |
| 12991 | |
| 12992 | def test_pmksa_cache_ctrl(dev, apdev): |
| 12993 | """PMKSA cache control interface operations""" |
| 12994 | diff --git a/tests/hwsim/test_sae.py b/tests/hwsim/test_sae.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 12995 | index 679db0e2d..4ea9bd6a4 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12996 | --- a/tests/hwsim/test_sae.py |
| 12997 | +++ b/tests/hwsim/test_sae.py |
| 12998 | @@ -178,6 +178,11 @@ def test_sae_groups(dev, apdev): |
| 12999 | if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls: |
| 13000 | logger.info("Add Brainpool EC groups since OpenSSL is new enough") |
| 13001 | sae_groups += [27, 28, 29, 30] |
| 13002 | + if tls.startswith("mbed TLS"): |
| 13003 | + # secp224k1 and secp224r1 (26) have prime p = 1 mod 4, and mbedtls |
| 13004 | + # does not have code to derive y from compressed format for those curves |
| 13005 | + sae_groups = [19, 25, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24] |
| 13006 | + sae_groups += [27, 28, 29, 30] |
| 13007 | heavy_groups = [14, 15, 16] |
| 13008 | suitable_groups = [15, 16, 17, 18, 19, 20, 21] |
| 13009 | groups = [str(g) for g in sae_groups] |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13010 | @@ -2232,6 +2237,8 @@ def run_sae_pwe_group(dev, apdev, group): |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13011 | logger.info("Add Brainpool EC groups since OpenSSL is new enough") |
| 13012 | elif tls.startswith("wolfSSL"): |
| 13013 | logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL") |
| 13014 | + elif tls.startswith("mbed TLS"): |
| 13015 | + logger.info("Make sure Brainpool EC groups were enabled when compiling mbed TLS") |
| 13016 | else: |
| 13017 | raise HwsimSkip("Brainpool curve not supported") |
| 13018 | start_sae_pwe_ap(apdev[0], group, 2) |
| 13019 | diff --git a/tests/hwsim/test_suite_b.py b/tests/hwsim/test_suite_b.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13020 | index ddd1c2ee7..a44f32955 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13021 | --- a/tests/hwsim/test_suite_b.py |
| 13022 | +++ b/tests/hwsim/test_suite_b.py |
| 13023 | @@ -27,6 +27,8 @@ def check_suite_b_tls_lib(dev, dhe=False, level128=False): |
| 13024 | return |
| 13025 | if tls.startswith("wolfSSL"): |
| 13026 | return |
| 13027 | + if tls.startswith("mbed TLS"): |
| 13028 | + return |
| 13029 | if not tls.startswith("OpenSSL"): |
| 13030 | raise HwsimSkip("TLS library not supported for Suite B: " + tls) |
| 13031 | supported = False |
| 13032 | @@ -520,6 +522,7 @@ def test_suite_b_192_rsa_insufficient_dh(dev, apdev): |
| 13033 | |
| 13034 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", |
| 13035 | ieee80211w="2", |
| 13036 | + openssl_ciphers="DHE-RSA-AES256-GCM-SHA384", |
| 13037 | phase1="tls_suiteb=1", |
| 13038 | eap="TLS", identity="tls user", |
| 13039 | ca_cert="auth_serv/rsa3072-ca.pem", |
| 13040 | diff --git a/tests/hwsim/test_wpas_ctrl.py b/tests/hwsim/test_wpas_ctrl.py |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13041 | index cf6d3211e..cbf136eaf 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13042 | --- a/tests/hwsim/test_wpas_ctrl.py |
| 13043 | +++ b/tests/hwsim/test_wpas_ctrl.py |
| 13044 | @@ -1856,7 +1856,7 @@ def _test_wpas_ctrl_oom(dev): |
| 13045 | tls = dev[0].request("GET tls_library") |
| 13046 | if not tls.startswith("internal"): |
| 13047 | tests.append(('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', 'FAIL', |
| 13048 | - 4, 'wpas_ctrl_nfc_get_handover_sel_p2p')) |
| 13049 | + 3, 'wpas_ctrl_nfc_get_handover_sel_p2p')) |
| 13050 | for cmd, exp, count, func in tests: |
| 13051 | with alloc_fail(dev[0], count, func): |
| 13052 | res = dev[0].request(cmd) |
| 13053 | diff --git a/tests/hwsim/utils.py b/tests/hwsim/utils.py |
| 13054 | index 7e3608284..b23c1ee0b 100644 |
| 13055 | --- a/tests/hwsim/utils.py |
| 13056 | +++ b/tests/hwsim/utils.py |
| 13057 | @@ -145,7 +145,13 @@ def check_imsi_privacy_support(dev): |
| 13058 | |
| 13059 | def check_tls_tod(dev): |
| 13060 | tls = dev.request("GET tls_library") |
| 13061 | - if not tls.startswith("OpenSSL") and not tls.startswith("internal"): |
| 13062 | + if tls.startswith("OpenSSL"): |
| 13063 | + return |
| 13064 | + elif tls.startswith("internal"): |
| 13065 | + return |
| 13066 | + elif tls.startswith("mbed TLS"): |
| 13067 | + return |
| 13068 | + else: |
| 13069 | raise HwsimSkip("TLS TOD-TOFU/STRICT not supported with this TLS library: " + tls) |
| 13070 | |
| 13071 | def vht_supported(): |
| 13072 | diff --git a/tests/test-crypto_module.c b/tests/test-crypto_module.c |
| 13073 | new file mode 100644 |
| 13074 | index 000000000..0f1156142 |
| 13075 | --- /dev/null |
| 13076 | +++ b/tests/test-crypto_module.c |
| 13077 | @@ -0,0 +1,16 @@ |
| 13078 | +/* |
| 13079 | + * crypto module tests - test program |
| 13080 | + * Copyright (c) 2022, Glenn Strauss <gstrauss@gluelogic.com> |
| 13081 | + * |
| 13082 | + * This software may be distributed under the terms of the BSD license. |
| 13083 | + * See README for more details. |
| 13084 | + */ |
| 13085 | + |
| 13086 | +#include "utils/includes.h" |
| 13087 | +#include "utils/module_tests.h" |
| 13088 | +#include "crypto/crypto_module_tests.c" |
| 13089 | + |
| 13090 | +int main(int argc, char *argv[]) |
| 13091 | +{ |
| 13092 | + return crypto_module_tests(); |
| 13093 | +} |
| 13094 | diff --git a/tests/test-https.c b/tests/test-https.c |
| 13095 | index a72e56f9d..e9df82f1d 100644 |
| 13096 | --- a/tests/test-https.c |
| 13097 | +++ b/tests/test-https.c |
| 13098 | @@ -75,7 +75,7 @@ static int https_client(int s, const char *path) |
| 13099 | struct tls_connection *conn; |
| 13100 | struct wpabuf *in, *out, *appl; |
| 13101 | int res = -1; |
| 13102 | - int need_more_data; |
| 13103 | + int need_more_data = 0; |
| 13104 | |
| 13105 | os_memset(&conf, 0, sizeof(conf)); |
| 13106 | conf.event_cb = https_tls_event_cb; |
| 13107 | @@ -93,8 +93,12 @@ static int https_client(int s, const char *path) |
| 13108 | |
| 13109 | for (;;) { |
| 13110 | appl = NULL; |
| 13111 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13112 | out = tls_connection_handshake2(tls, conn, in, &appl, |
| 13113 | &need_more_data); |
| 13114 | +#else |
| 13115 | + out = tls_connection_handshake(tls, conn, in, &appl); |
| 13116 | +#endif |
| 13117 | wpabuf_free(in); |
| 13118 | in = NULL; |
| 13119 | if (out == NULL) { |
| 13120 | @@ -152,11 +156,15 @@ static int https_client(int s, const char *path) |
| 13121 | |
| 13122 | wpa_printf(MSG_INFO, "Reading HTTP response"); |
| 13123 | for (;;) { |
| 13124 | - int need_more_data; |
| 13125 | + int need_more_data = 0; |
| 13126 | in = https_recv(s); |
| 13127 | if (in == NULL) |
| 13128 | goto done; |
| 13129 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13130 | out = tls_connection_decrypt2(tls, conn, in, &need_more_data); |
| 13131 | +#else |
| 13132 | + out = tls_connection_decrypt(tls, conn, in); |
| 13133 | +#endif |
| 13134 | if (need_more_data) |
| 13135 | wpa_printf(MSG_DEBUG, "HTTP: Need more data"); |
| 13136 | wpabuf_free(in); |
| 13137 | diff --git a/tests/test-https_server.c b/tests/test-https_server.c |
| 13138 | index 33b448682..9dcca5596 100644 |
| 13139 | --- a/tests/test-https_server.c |
| 13140 | +++ b/tests/test-https_server.c |
| 13141 | @@ -67,10 +67,12 @@ static struct wpabuf * https_recv(int s, int timeout_ms) |
| 13142 | } |
| 13143 | |
| 13144 | |
| 13145 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13146 | static void https_tls_log_cb(void *ctx, const char *msg) |
| 13147 | { |
| 13148 | wpa_printf(MSG_DEBUG, "TLS: %s", msg); |
| 13149 | } |
| 13150 | +#endif |
| 13151 | |
| 13152 | |
| 13153 | static int https_server(int s) |
| 13154 | @@ -79,7 +81,7 @@ static int https_server(int s) |
| 13155 | void *tls; |
| 13156 | struct tls_connection_params params; |
| 13157 | struct tls_connection *conn; |
| 13158 | - struct wpabuf *in, *out, *appl; |
| 13159 | + struct wpabuf *in = NULL, *out = NULL, *appl = NULL; |
| 13160 | int res = -1; |
| 13161 | |
| 13162 | os_memset(&conf, 0, sizeof(conf)); |
| 13163 | @@ -106,7 +108,9 @@ static int https_server(int s) |
| 13164 | return -1; |
| 13165 | } |
| 13166 | |
| 13167 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13168 | tls_connection_set_log_cb(conn, https_tls_log_cb, NULL); |
| 13169 | +#endif |
| 13170 | |
| 13171 | for (;;) { |
| 13172 | in = https_recv(s, 5000); |
| 13173 | @@ -147,12 +151,16 @@ static int https_server(int s) |
| 13174 | |
| 13175 | wpa_printf(MSG_INFO, "Reading HTTP request"); |
| 13176 | for (;;) { |
| 13177 | - int need_more_data; |
| 13178 | + int need_more_data = 0; |
| 13179 | |
| 13180 | in = https_recv(s, 5000); |
| 13181 | if (!in) |
| 13182 | goto done; |
| 13183 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13184 | out = tls_connection_decrypt2(tls, conn, in, &need_more_data); |
| 13185 | +#else |
| 13186 | + out = tls_connection_decrypt(tls, conn, in); |
| 13187 | +#endif |
| 13188 | wpabuf_free(in); |
| 13189 | in = NULL; |
| 13190 | if (need_more_data) { |
| 13191 | diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13192 | index 743c8acd6..c40e8d70d 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13193 | --- a/wpa_supplicant/Makefile |
| 13194 | +++ b/wpa_supplicant/Makefile |
| 13195 | @@ -10,6 +10,7 @@ ALL += dbus/fi.w1.wpa_supplicant1.service |
| 13196 | EXTRA_TARGETS=dynamic_eap_methods |
| 13197 | |
| 13198 | CONFIG_FILE=.config |
| 13199 | +-include $(if $(MULTICALL),../hostapd/.config) |
| 13200 | include ../src/build.rules |
| 13201 | |
| 13202 | ifdef CONFIG_BUILD_PASN_SO |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13203 | @@ -190,6 +191,25 @@ ifdef CONFIG_EAPOL_TEST |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13204 | CFLAGS += -Werror -DEAPOL_TEST |
| 13205 | endif |
| 13206 | |
| 13207 | +ifdef CONFIG_UBUS |
| 13208 | +CFLAGS += -DUBUS_SUPPORT |
| 13209 | +OBJS += ubus.o |
| 13210 | +LIBS += -lubus |
| 13211 | +NEED_ULOOP:=y |
| 13212 | +endif |
| 13213 | + |
| 13214 | +ifdef CONFIG_UCODE |
| 13215 | +CFLAGS += -DUCODE_SUPPORT |
| 13216 | +OBJS += ../src/utils/ucode.o |
| 13217 | +OBJS += ucode.o |
| 13218 | +NEED_ULOOP:=y |
| 13219 | +endif |
| 13220 | + |
| 13221 | +ifdef NEED_ULOOP |
| 13222 | +OBJS += ../src/utils/uloop.o |
| 13223 | +LIBS += -lubox |
| 13224 | +endif |
| 13225 | + |
| 13226 | ifdef CONFIG_CODE_COVERAGE |
| 13227 | CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE |
| 13228 | LIBS += -lgcov |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13229 | @@ -389,7 +409,9 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13230 | ifdef CONFIG_IBSS_RSN |
| 13231 | NEED_RSN_AUTHENTICATOR=y |
| 13232 | CFLAGS += -DCONFIG_IBSS_RSN |
| 13233 | +ifndef MULTICALL |
| 13234 | CFLAGS += -DCONFIG_NO_VLAN |
| 13235 | +endif |
| 13236 | OBJS += ibss_rsn.o |
| 13237 | endif |
| 13238 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13239 | @@ -981,6 +1003,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13240 | CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS |
| 13241 | LIBS += -ldl -rdynamic |
| 13242 | endif |
| 13243 | +else |
| 13244 | + ifdef MULTICALL |
| 13245 | + OBJS += ../src/eap_common/eap_common.o |
| 13246 | + endif |
| 13247 | endif |
| 13248 | |
| 13249 | ifdef CONFIG_AP |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13250 | @@ -988,9 +1014,11 @@ NEED_EAP_COMMON=y |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13251 | NEED_RSN_AUTHENTICATOR=y |
| 13252 | CFLAGS += -DCONFIG_AP |
| 13253 | OBJS += ap.o |
| 13254 | +ifndef MULTICALL |
| 13255 | CFLAGS += -DCONFIG_NO_RADIUS |
| 13256 | CFLAGS += -DCONFIG_NO_ACCOUNTING |
| 13257 | CFLAGS += -DCONFIG_NO_VLAN |
| 13258 | +endif |
| 13259 | OBJS += ../src/ap/hostapd.o |
| 13260 | OBJS += ../src/ap/wpa_auth_glue.o |
| 13261 | OBJS += ../src/ap/utils.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13262 | @@ -1030,7 +1058,16 @@ ifdef CONFIG_FILS |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13263 | OBJS += ../src/ap/fils_hlp.o |
| 13264 | endif |
| 13265 | ifdef CONFIG_CTRL_IFACE |
| 13266 | +ifdef CONFIG_CTRL_IFACE_MIB |
| 13267 | +CFLAGS += -DCONFIG_CTRL_IFACE_MIB |
| 13268 | +endif |
| 13269 | OBJS += ../src/ap/ctrl_iface_ap.o |
| 13270 | +ifdef CONFIG_UBUS |
| 13271 | +OBJS += ../src/ap/ubus.o |
| 13272 | +endif |
| 13273 | +ifdef CONFIG_UCODE |
| 13274 | +OBJS += ../src/ap/ucode.o |
| 13275 | +endif |
| 13276 | endif |
| 13277 | |
| 13278 | CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13279 | @@ -1081,6 +1118,12 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13280 | ifdef CONFIG_HS20 |
| 13281 | OBJS += ../src/ap/hs20.o |
| 13282 | endif |
| 13283 | +else |
| 13284 | + ifdef MULTICALL |
| 13285 | + OBJS += ../src/eap_server/eap_server.o |
| 13286 | + OBJS += ../src/eap_server/eap_server_identity.o |
| 13287 | + OBJS += ../src/eap_server/eap_server_methods.o |
| 13288 | + endif |
| 13289 | endif |
| 13290 | |
| 13291 | ifdef CONFIG_MBO |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13292 | @@ -1090,7 +1133,9 @@ NEED_GAS=y |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13293 | endif |
| 13294 | |
| 13295 | ifdef NEED_RSN_AUTHENTICATOR |
| 13296 | +ifndef MULTICALL |
| 13297 | CFLAGS += -DCONFIG_NO_RADIUS |
| 13298 | +endif |
| 13299 | NEED_AES_WRAP=y |
| 13300 | OBJS += ../src/ap/wpa_auth.o |
| 13301 | OBJS += ../src/ap/wpa_auth_ie.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13302 | @@ -1189,6 +1234,7 @@ TLS_FUNCS=y |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13303 | endif |
| 13304 | |
| 13305 | ifeq ($(CONFIG_TLS), wolfssl) |
| 13306 | +CFLAGS += -DCONFIG_TLS_WOLFSSL |
| 13307 | ifdef TLS_FUNCS |
| 13308 | CFLAGS += -DWOLFSSL_DER_LOAD |
| 13309 | OBJS += ../src/crypto/tls_wolfssl.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13310 | @@ -1204,6 +1250,7 @@ LIBS_p += -lwolfssl -lm |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13311 | endif |
| 13312 | |
| 13313 | ifeq ($(CONFIG_TLS), openssl) |
| 13314 | +CFLAGS += -DCONFIG_TLS_OPENSSL |
| 13315 | CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 13316 | ifdef TLS_FUNCS |
| 13317 | CFLAGS += -DEAP_TLS_OPENSSL |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13318 | @@ -1230,7 +1277,28 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13319 | CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" |
| 13320 | endif |
| 13321 | |
| 13322 | +ifeq ($(CONFIG_TLS), mbedtls) |
| 13323 | +CFLAGS += -DCONFIG_TLS_MBEDTLS |
| 13324 | +ifndef CONFIG_CRYPTO |
| 13325 | +CONFIG_CRYPTO=mbedtls |
| 13326 | +endif |
| 13327 | +ifdef TLS_FUNCS |
| 13328 | +OBJS += ../src/crypto/tls_mbedtls.o |
| 13329 | +LIBS += -lmbedtls -lmbedx509 |
| 13330 | +endif |
| 13331 | +OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 13332 | +OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 13333 | +OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 13334 | +ifeq ($(CONFIG_CRYPTO), mbedtls) |
| 13335 | +LIBS += -lmbedcrypto |
| 13336 | +LIBS_p += -lmbedcrypto |
| 13337 | +# XXX: create a config option? |
| 13338 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 13339 | +endif |
| 13340 | +endif |
| 13341 | + |
| 13342 | ifeq ($(CONFIG_TLS), gnutls) |
| 13343 | +CFLAGS += -DCONFIG_TLS_GNUTLS |
| 13344 | ifndef CONFIG_CRYPTO |
| 13345 | # default to libgcrypt |
| 13346 | CONFIG_CRYPTO=gnutls |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13347 | @@ -1261,6 +1329,7 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13348 | endif |
| 13349 | |
| 13350 | ifeq ($(CONFIG_TLS), internal) |
| 13351 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 13352 | ifndef CONFIG_CRYPTO |
| 13353 | CONFIG_CRYPTO=internal |
| 13354 | endif |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13355 | @@ -1341,6 +1410,7 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13356 | endif |
| 13357 | |
| 13358 | ifeq ($(CONFIG_TLS), linux) |
| 13359 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 13360 | OBJS += ../src/crypto/crypto_linux.o |
| 13361 | OBJS_p += ../src/crypto/crypto_linux.o |
| 13362 | ifdef TLS_FUNCS |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13363 | @@ -1422,9 +1492,11 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13364 | |
| 13365 | ifneq ($(CONFIG_TLS), openssl) |
| 13366 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13367 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13368 | NEED_INTERNAL_AES_WRAP=y |
| 13369 | endif |
| 13370 | endif |
| 13371 | +endif |
| 13372 | ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP |
| 13373 | # Seems to be needed at least with BoringSSL |
| 13374 | NEED_INTERNAL_AES_WRAP=y |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13375 | @@ -1438,9 +1510,11 @@ endif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13376 | |
| 13377 | ifdef NEED_INTERNAL_AES_WRAP |
| 13378 | ifneq ($(CONFIG_TLS), linux) |
| 13379 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13380 | AESOBJS += ../src/crypto/aes-unwrap.o |
| 13381 | endif |
| 13382 | endif |
| 13383 | +endif |
| 13384 | ifdef NEED_AES_EAX |
| 13385 | AESOBJS += ../src/crypto/aes-eax.o |
| 13386 | NEED_AES_CTR=y |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13387 | @@ -1450,35 +1524,45 @@ AESOBJS += ../src/crypto/aes-siv.o |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13388 | NEED_AES_CTR=y |
| 13389 | endif |
| 13390 | ifdef NEED_AES_CTR |
| 13391 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13392 | AESOBJS += ../src/crypto/aes-ctr.o |
| 13393 | endif |
| 13394 | +endif |
| 13395 | ifdef NEED_AES_ENCBLOCK |
| 13396 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13397 | AESOBJS += ../src/crypto/aes-encblock.o |
| 13398 | endif |
| 13399 | +endif |
| 13400 | NEED_AES_ENC=y |
| 13401 | ifneq ($(CONFIG_TLS), openssl) |
| 13402 | ifneq ($(CONFIG_TLS), linux) |
| 13403 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13404 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13405 | AESOBJS += ../src/crypto/aes-omac1.o |
| 13406 | endif |
| 13407 | endif |
| 13408 | endif |
| 13409 | +endif |
| 13410 | ifdef NEED_AES_WRAP |
| 13411 | NEED_AES_ENC=y |
| 13412 | ifdef NEED_INTERNAL_AES_WRAP |
| 13413 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13414 | AESOBJS += ../src/crypto/aes-wrap.o |
| 13415 | endif |
| 13416 | endif |
| 13417 | +endif |
| 13418 | ifdef NEED_AES_CBC |
| 13419 | NEED_AES_ENC=y |
| 13420 | ifneq ($(CONFIG_TLS), openssl) |
| 13421 | ifneq ($(CONFIG_TLS), linux) |
| 13422 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13423 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13424 | AESOBJS += ../src/crypto/aes-cbc.o |
| 13425 | endif |
| 13426 | endif |
| 13427 | endif |
| 13428 | endif |
| 13429 | +endif |
| 13430 | ifdef NEED_AES_ENC |
| 13431 | ifdef CONFIG_INTERNAL_AES |
| 13432 | AESOBJS += ../src/crypto/aes-internal-enc.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13433 | @@ -1493,12 +1577,16 @@ ifneq ($(CONFIG_TLS), openssl) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13434 | ifneq ($(CONFIG_TLS), linux) |
| 13435 | ifneq ($(CONFIG_TLS), gnutls) |
| 13436 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13437 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13438 | SHA1OBJS += ../src/crypto/sha1.o |
| 13439 | endif |
| 13440 | endif |
| 13441 | endif |
| 13442 | endif |
| 13443 | +endif |
| 13444 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13445 | SHA1OBJS += ../src/crypto/sha1-prf.o |
| 13446 | +endif |
| 13447 | ifdef CONFIG_INTERNAL_SHA1 |
| 13448 | SHA1OBJS += ../src/crypto/sha1-internal.o |
| 13449 | ifdef NEED_FIPS186_2_PRF |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13450 | @@ -1510,29 +1598,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13451 | else |
| 13452 | ifneq ($(CONFIG_TLS), openssl) |
| 13453 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13454 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13455 | SHA1OBJS += ../src/crypto/sha1-pbkdf2.o |
| 13456 | endif |
| 13457 | endif |
| 13458 | endif |
| 13459 | +endif |
| 13460 | ifdef NEED_T_PRF |
| 13461 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13462 | SHA1OBJS += ../src/crypto/sha1-tprf.o |
| 13463 | endif |
| 13464 | +endif |
| 13465 | ifdef NEED_TLS_PRF |
| 13466 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13467 | SHA1OBJS += ../src/crypto/sha1-tlsprf.o |
| 13468 | endif |
| 13469 | endif |
| 13470 | +endif |
| 13471 | |
| 13472 | ifndef CONFIG_FIPS |
| 13473 | ifneq ($(CONFIG_TLS), openssl) |
| 13474 | ifneq ($(CONFIG_TLS), linux) |
| 13475 | ifneq ($(CONFIG_TLS), gnutls) |
| 13476 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13477 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13478 | MD5OBJS += ../src/crypto/md5.o |
| 13479 | endif |
| 13480 | endif |
| 13481 | endif |
| 13482 | endif |
| 13483 | endif |
| 13484 | +endif |
| 13485 | ifdef NEED_MD5 |
| 13486 | ifdef CONFIG_INTERNAL_MD5 |
| 13487 | MD5OBJS += ../src/crypto/md5-internal.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13488 | @@ -1587,12 +1683,17 @@ ifneq ($(CONFIG_TLS), openssl) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13489 | ifneq ($(CONFIG_TLS), linux) |
| 13490 | ifneq ($(CONFIG_TLS), gnutls) |
| 13491 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13492 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13493 | SHA256OBJS += ../src/crypto/sha256.o |
| 13494 | endif |
| 13495 | endif |
| 13496 | endif |
| 13497 | endif |
| 13498 | +endif |
| 13499 | + |
| 13500 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13501 | SHA256OBJS += ../src/crypto/sha256-prf.o |
| 13502 | +endif |
| 13503 | ifdef CONFIG_INTERNAL_SHA256 |
| 13504 | SHA256OBJS += ../src/crypto/sha256-internal.o |
| 13505 | endif |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13506 | @@ -1605,50 +1706,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13507 | SHA256OBJS += ../src/crypto/sha512-internal.o |
| 13508 | endif |
| 13509 | ifdef NEED_TLS_PRF_SHA256 |
| 13510 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13511 | SHA256OBJS += ../src/crypto/sha256-tlsprf.o |
| 13512 | endif |
| 13513 | +endif |
| 13514 | ifdef NEED_TLS_PRF_SHA384 |
| 13515 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13516 | SHA256OBJS += ../src/crypto/sha384-tlsprf.o |
| 13517 | endif |
| 13518 | +endif |
| 13519 | ifdef NEED_HMAC_SHA256_KDF |
| 13520 | CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 13521 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13522 | OBJS += ../src/crypto/sha256-kdf.o |
| 13523 | endif |
| 13524 | +endif |
| 13525 | ifdef NEED_HMAC_SHA384_KDF |
| 13526 | CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 13527 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13528 | OBJS += ../src/crypto/sha384-kdf.o |
| 13529 | endif |
| 13530 | +endif |
| 13531 | ifdef NEED_HMAC_SHA512_KDF |
| 13532 | CFLAGS += -DCONFIG_HMAC_SHA512_KDF |
| 13533 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13534 | OBJS += ../src/crypto/sha512-kdf.o |
| 13535 | endif |
| 13536 | +endif |
| 13537 | OBJS += $(SHA256OBJS) |
| 13538 | ifdef NEED_SHA384 |
| 13539 | ifneq ($(CONFIG_TLS), openssl) |
| 13540 | ifneq ($(CONFIG_TLS), linux) |
| 13541 | ifneq ($(CONFIG_TLS), gnutls) |
| 13542 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13543 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13544 | OBJS += ../src/crypto/sha384.o |
| 13545 | endif |
| 13546 | endif |
| 13547 | endif |
| 13548 | endif |
| 13549 | +endif |
| 13550 | CFLAGS += -DCONFIG_SHA384 |
| 13551 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13552 | OBJS += ../src/crypto/sha384-prf.o |
| 13553 | endif |
| 13554 | +endif |
| 13555 | ifdef NEED_SHA512 |
| 13556 | ifneq ($(CONFIG_TLS), openssl) |
| 13557 | ifneq ($(CONFIG_TLS), linux) |
| 13558 | ifneq ($(CONFIG_TLS), gnutls) |
| 13559 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13560 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13561 | OBJS += ../src/crypto/sha512.o |
| 13562 | endif |
| 13563 | endif |
| 13564 | endif |
| 13565 | endif |
| 13566 | +endif |
| 13567 | CFLAGS += -DCONFIG_SHA512 |
| 13568 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13569 | OBJS += ../src/crypto/sha512-prf.o |
| 13570 | endif |
| 13571 | +endif |
| 13572 | |
| 13573 | ifdef NEED_ASN1 |
| 13574 | OBJS += ../src/tls/asn1.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13575 | @@ -1823,10 +1942,12 @@ ifdef CONFIG_FIPS |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13576 | CFLAGS += -DCONFIG_FIPS |
| 13577 | ifneq ($(CONFIG_TLS), openssl) |
| 13578 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13579 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13580 | $(error CONFIG_FIPS=y requires CONFIG_TLS=openssl) |
| 13581 | endif |
| 13582 | endif |
| 13583 | endif |
| 13584 | +endif |
| 13585 | |
| 13586 | OBJS += $(SHA1OBJS) $(DESOBJS) |
| 13587 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13588 | @@ -2004,32 +2125,38 @@ wpa_priv: $(BCHECK) $(OBJS_priv) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13589 | |
| 13590 | _OBJS_VAR := OBJS |
| 13591 | include ../src/objs.mk |
| 13592 | +wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) |
| 13593 | + $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c |
| 13594 | + @$(E) " CC " $< |
| 13595 | + @rm -f $@ |
| 13596 | + @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) |
| 13597 | + |
| 13598 | wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) |
| 13599 | - $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) |
| 13600 | + +$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) |
| 13601 | @$(E) " LD " $@ |
| 13602 | |
| 13603 | _OBJS_VAR := OBJS_t |
| 13604 | include ../src/objs.mk |
| 13605 | eapol_test: $(OBJS_t) |
| 13606 | - $(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) |
| 13607 | + +$(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) |
| 13608 | @$(E) " LD " $@ |
| 13609 | |
| 13610 | _OBJS_VAR := OBJS_t2 |
| 13611 | include ../src/objs.mk |
| 13612 | preauth_test: $(OBJS_t2) |
| 13613 | - $(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) |
| 13614 | + +$(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) |
| 13615 | @$(E) " LD " $@ |
| 13616 | |
| 13617 | _OBJS_VAR := OBJS_p |
| 13618 | include ../src/objs.mk |
| 13619 | wpa_passphrase: $(OBJS_p) |
| 13620 | - $(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) |
| 13621 | + +$(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) |
| 13622 | @$(E) " LD " $@ |
| 13623 | |
| 13624 | _OBJS_VAR := OBJS_c |
| 13625 | include ../src/objs.mk |
| 13626 | wpa_cli: $(OBJS_c) |
| 13627 | - $(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) |
| 13628 | + +$(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) |
| 13629 | @$(E) " LD " $@ |
| 13630 | |
| 13631 | LIBCTRL += ../src/common/wpa_ctrl.o |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13632 | @@ -2136,6 +2263,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13633 | $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ |
| 13634 | @$(E) " sed" $< |
| 13635 | |
| 13636 | +dump_cflags: |
| 13637 | + @printf "%s " "$(CFLAGS)" |
| 13638 | + |
| 13639 | +dump_ldflags: |
| 13640 | + @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" |
| 13641 | + |
| 13642 | wpa_supplicant.exe: wpa_supplicant |
| 13643 | mv -f $< $@ |
| 13644 | wpa_cli.exe: wpa_cli |
| 13645 | diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13646 | index 69a0e5ee1..7e8c97c38 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13647 | --- a/wpa_supplicant/ap.c |
| 13648 | +++ b/wpa_supplicant/ap.c |
| 13649 | @@ -1520,7 +1520,7 @@ int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s, |
| 13650 | #endif /* CONFIG_WPS */ |
| 13651 | |
| 13652 | |
| 13653 | -#ifdef CONFIG_CTRL_IFACE |
| 13654 | +#if defined(CONFIG_CTRL_IFACE) && defined(CONFIG_CTRL_IFACE_MIB) |
| 13655 | |
| 13656 | int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s, |
| 13657 | char *buf, size_t buflen) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13658 | @@ -1846,17 +1846,37 @@ int ap_switch_channel(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13659 | |
| 13660 | |
| 13661 | #ifdef CONFIG_CTRL_IFACE |
| 13662 | + |
| 13663 | +static int __ap_ctrl_iface_chanswitch(struct hostapd_iface *iface, |
| 13664 | + struct csa_settings *settings) |
| 13665 | +{ |
| 13666 | +#ifdef NEED_AP_MLME |
| 13667 | + if (!iface || !iface->bss[0]) |
| 13668 | + return 0; |
| 13669 | + |
| 13670 | + return hostapd_switch_channel(iface->bss[0], settings); |
| 13671 | +#else |
| 13672 | + return -1; |
| 13673 | +#endif |
| 13674 | +} |
| 13675 | + |
| 13676 | + |
| 13677 | int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) |
| 13678 | { |
| 13679 | struct csa_settings settings; |
| 13680 | int ret = hostapd_parse_csa_settings(pos, &settings); |
| 13681 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13682 | - if (ret) |
| 13683 | - return ret; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13684 | + if (!(wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) && |
| 13685 | + !(wpa_s->ifmsh && wpa_s->ifmsh->bss[0])) |
| 13686 | + return -1; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13687 | |
| 13688 | settings.link_id = -1; |
| 13689 | |
| 13690 | - return ap_switch_channel(wpa_s, &settings); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13691 | + ret = __ap_ctrl_iface_chanswitch(wpa_s->ap_iface, &settings); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13692 | + if (ret) |
| 13693 | + return ret; |
| 13694 | + |
| 13695 | + return __ap_ctrl_iface_chanswitch(wpa_s->ifmsh, &settings); |
| 13696 | } |
| 13697 | #endif /* CONFIG_CTRL_IFACE */ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13698 | |
| 13699 | diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13700 | index b02b694a3..dc4b0636a 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13701 | --- a/wpa_supplicant/config.c |
| 13702 | +++ b/wpa_supplicant/config.c |
| 13703 | @@ -18,6 +18,7 @@ |
| 13704 | #include "eap_peer/eap.h" |
| 13705 | #include "p2p/p2p.h" |
| 13706 | #include "fst/fst.h" |
| 13707 | +#include "ap/sta_info.h" |
| 13708 | #include "config.h" |
| 13709 | |
| 13710 | |
| 13711 | @@ -2421,6 +2422,97 @@ static char * wpa_config_write_mac_value(const struct parse_data *data, |
| 13712 | #endif /* NO_CONFIG_WRITE */ |
| 13713 | |
| 13714 | |
| 13715 | +static int wpa_config_parse_mcast_rate(const struct parse_data *data, |
| 13716 | + struct wpa_ssid *ssid, int line, |
| 13717 | + const char *value) |
| 13718 | +{ |
| 13719 | + ssid->mcast_rate = (int)(strtod(value, NULL) * 10); |
| 13720 | + |
| 13721 | + return 0; |
| 13722 | +} |
| 13723 | + |
| 13724 | +#ifndef NO_CONFIG_WRITE |
| 13725 | +static char * wpa_config_write_mcast_rate(const struct parse_data *data, |
| 13726 | + struct wpa_ssid *ssid) |
| 13727 | +{ |
| 13728 | + char *value; |
| 13729 | + int res; |
| 13730 | + |
| 13731 | + if (!ssid->mcast_rate == 0) |
| 13732 | + return NULL; |
| 13733 | + |
| 13734 | + value = os_malloc(6); /* longest: 300.0 */ |
| 13735 | + if (value == NULL) |
| 13736 | + return NULL; |
| 13737 | + res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10); |
| 13738 | + if (res < 0) { |
| 13739 | + os_free(value); |
| 13740 | + return NULL; |
| 13741 | + } |
| 13742 | + return value; |
| 13743 | +} |
| 13744 | +#endif /* NO_CONFIG_WRITE */ |
| 13745 | + |
| 13746 | +static int wpa_config_parse_rates(const struct parse_data *data, |
| 13747 | + struct wpa_ssid *ssid, int line, |
| 13748 | + const char *value) |
| 13749 | +{ |
| 13750 | + int i; |
| 13751 | + char *pos, *r, *sptr, *end; |
| 13752 | + double rate; |
| 13753 | + |
| 13754 | + pos = (char *)value; |
| 13755 | + r = strtok_r(pos, ",", &sptr); |
| 13756 | + i = 0; |
| 13757 | + while (pos && i < WLAN_SUPP_RATES_MAX) { |
| 13758 | + rate = 0.0; |
| 13759 | + if (r) |
| 13760 | + rate = strtod(r, &end); |
| 13761 | + ssid->rates[i] = rate * 2; |
| 13762 | + if (*end != '\0' || rate * 2 != ssid->rates[i]) |
| 13763 | + return 1; |
| 13764 | + |
| 13765 | + i++; |
| 13766 | + r = strtok_r(NULL, ",", &sptr); |
| 13767 | + } |
| 13768 | + |
| 13769 | + return 0; |
| 13770 | +} |
| 13771 | + |
| 13772 | +#ifndef NO_CONFIG_WRITE |
| 13773 | +static char * wpa_config_write_rates(const struct parse_data *data, |
| 13774 | + struct wpa_ssid *ssid) |
| 13775 | +{ |
| 13776 | + char *value, *pos; |
| 13777 | + int res, i; |
| 13778 | + |
| 13779 | + if (ssid->rates[0] <= 0) |
| 13780 | + return NULL; |
| 13781 | + |
| 13782 | + value = os_malloc(6 * WLAN_SUPP_RATES_MAX + 1); |
| 13783 | + if (value == NULL) |
| 13784 | + return NULL; |
| 13785 | + pos = value; |
| 13786 | + for (i = 0; i < WLAN_SUPP_RATES_MAX - 1; i++) { |
| 13787 | + res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2); |
| 13788 | + if (res < 0) { |
| 13789 | + os_free(value); |
| 13790 | + return NULL; |
| 13791 | + } |
| 13792 | + pos += res; |
| 13793 | + } |
| 13794 | + res = os_snprintf(pos, 6, "%.1f", |
| 13795 | + (double)ssid->rates[WLAN_SUPP_RATES_MAX - 1] / 2); |
| 13796 | + if (res < 0) { |
| 13797 | + os_free(value); |
| 13798 | + return NULL; |
| 13799 | + } |
| 13800 | + |
| 13801 | + value[6 * WLAN_SUPP_RATES_MAX] = '\0'; |
| 13802 | + return value; |
| 13803 | +} |
| 13804 | +#endif /* NO_CONFIG_WRITE */ |
| 13805 | + |
| 13806 | /* Helper macros for network block parser */ |
| 13807 | |
| 13808 | #ifdef OFFSET |
| 13809 | @@ -2639,6 +2731,7 @@ static const struct parse_data ssid_fields[] = { |
| 13810 | #else /* CONFIG_MESH */ |
| 13811 | { INT_RANGE(mode, 0, 4) }, |
| 13812 | #endif /* CONFIG_MESH */ |
| 13813 | + { INT_RANGE(noscan, 0, 1) }, |
| 13814 | { INT_RANGE(proactive_key_caching, 0, 1) }, |
| 13815 | { INT_RANGE(disabled, 0, 2) }, |
| 13816 | { STR(id_str) }, |
| 13817 | @@ -2712,6 +2805,8 @@ static const struct parse_data ssid_fields[] = { |
| 13818 | { INT(ap_max_inactivity) }, |
| 13819 | { INT(dtim_period) }, |
| 13820 | { INT(beacon_int) }, |
| 13821 | + { FUNC(rates) }, |
| 13822 | + { FUNC(mcast_rate) }, |
| 13823 | #ifdef CONFIG_MACSEC |
| 13824 | { INT_RANGE(macsec_policy, 0, 1) }, |
| 13825 | { INT_RANGE(macsec_integ_only, 0, 1) }, |
| 13826 | diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13827 | index fd8eafe2b..5ce616129 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13828 | --- a/wpa_supplicant/config_file.c |
| 13829 | +++ b/wpa_supplicant/config_file.c |
| 13830 | @@ -326,8 +326,13 @@ struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp, |
| 13831 | while (cred_tail && cred_tail->next) |
| 13832 | cred_tail = cred_tail->next; |
| 13833 | |
| 13834 | + if (!strncmp(name, "data:", 5)) { |
| 13835 | + f = fmemopen((void *)(name + 5), strlen(name + 5), "r"); |
| 13836 | + name = "<inline>"; |
| 13837 | + } else { |
| 13838 | + f = fopen(name, "r"); |
| 13839 | + } |
| 13840 | wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); |
| 13841 | - f = fopen(name, "r"); |
| 13842 | if (f == NULL) { |
| 13843 | wpa_printf(MSG_ERROR, "Failed to open config file '%s', " |
| 13844 | "error: %s", name, strerror(errno)); |
| 13845 | @@ -775,6 +780,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) |
| 13846 | #endif /* IEEE8021X_EAPOL */ |
| 13847 | INT(mode); |
| 13848 | INT(no_auto_peer); |
| 13849 | + INT(noscan); |
| 13850 | INT(mesh_fwding); |
| 13851 | INT(frequency); |
| 13852 | INT(enable_edmg); |
| 13853 | diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13854 | index d64c30508..872bcc270 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13855 | --- a/wpa_supplicant/config_ssid.h |
| 13856 | +++ b/wpa_supplicant/config_ssid.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13857 | @@ -879,6 +879,9 @@ struct wpa_ssid { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13858 | */ |
| 13859 | void *parent_cred; |
| 13860 | |
| 13861 | + unsigned char rates[WLAN_SUPP_RATES_MAX]; |
| 13862 | + double mcast_rate; |
| 13863 | + |
| 13864 | #ifdef CONFIG_MACSEC |
| 13865 | /** |
| 13866 | * macsec_policy - Determines the policy for MACsec secure session |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13867 | @@ -1035,6 +1038,8 @@ struct wpa_ssid { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13868 | */ |
| 13869 | int no_auto_peer; |
| 13870 | |
| 13871 | + int noscan; |
| 13872 | + |
| 13873 | /** |
| 13874 | * mesh_rssi_threshold - Set mesh parameter mesh_rssi_threshold (dBm) |
| 13875 | * |
| 13876 | diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13877 | index d245531cd..4777c3abe 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13878 | --- a/wpa_supplicant/ctrl_iface.c |
| 13879 | +++ b/wpa_supplicant/ctrl_iface.c |
| 13880 | @@ -2355,7 +2355,7 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, |
| 13881 | pos += ret; |
| 13882 | } |
| 13883 | |
| 13884 | -#ifdef CONFIG_AP |
| 13885 | +#if defined(CONFIG_AP) && defined(CONFIG_CTRL_IFACE_MIB) |
| 13886 | if (wpa_s->ap_iface) { |
| 13887 | pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, |
| 13888 | end - pos, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13889 | @@ -12561,6 +12561,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13890 | reply_len = -1; |
| 13891 | } else if (os_strncmp(buf, "NOTE ", 5) == 0) { |
| 13892 | wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); |
| 13893 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 13894 | } else if (os_strcmp(buf, "MIB") == 0) { |
| 13895 | reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); |
| 13896 | if (reply_len >= 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13897 | @@ -12573,6 +12574,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13898 | reply_size - reply_len); |
| 13899 | #endif /* CONFIG_MACSEC */ |
| 13900 | } |
| 13901 | +#endif |
| 13902 | } else if (os_strncmp(buf, "STATUS", 6) == 0) { |
| 13903 | reply_len = wpa_supplicant_ctrl_iface_status( |
| 13904 | wpa_s, buf + 6, reply, reply_size); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13905 | @@ -13061,6 +13063,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13906 | reply_len = wpa_supplicant_ctrl_iface_bss( |
| 13907 | wpa_s, buf + 4, reply, reply_size); |
| 13908 | #ifdef CONFIG_AP |
| 13909 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 13910 | } else if (os_strcmp(buf, "STA-FIRST") == 0) { |
| 13911 | reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); |
| 13912 | } else if (os_strncmp(buf, "STA ", 4) == 0) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13913 | @@ -13069,12 +13072,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13914 | } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { |
| 13915 | reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, |
| 13916 | reply_size); |
| 13917 | +#endif |
| 13918 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 13919 | } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { |
| 13920 | if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) |
| 13921 | reply_len = -1; |
| 13922 | } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) { |
| 13923 | if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13)) |
| 13924 | reply_len = -1; |
| 13925 | +#endif |
| 13926 | } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { |
| 13927 | if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12)) |
| 13928 | reply_len = -1; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13929 | @@ -13233,7 +13239,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13930 | if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18)) |
| 13931 | reply_len = -1; |
| 13932 | #endif /* CONFIG_WNM */ |
| 13933 | -#ifdef CONFIG_WNM_AP |
| 13934 | +#if defined(CONFIG_AP) && defined(CONFIG_WNM_AP) |
| 13935 | } else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) { |
| 13936 | if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18)) |
| 13937 | reply_len = -1; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13938 | @@ -13243,7 +13249,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13939 | } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) { |
| 13940 | if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11)) |
| 13941 | reply_len = -1; |
| 13942 | -#endif /* CONFIG_WNM_AP */ |
| 13943 | +#endif /* CONFIG_AP && CONFIG_WNM_AP */ |
| 13944 | } else if (os_strcmp(buf, "FLUSH") == 0) { |
| 13945 | wpa_supplicant_ctrl_iface_flush(wpa_s); |
| 13946 | } else if (os_strncmp(buf, "RADIO_WORK ", 11) == 0) { |
| 13947 | diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig |
| 13948 | index 52befd8f1..ace6c5530 100644 |
| 13949 | --- a/wpa_supplicant/defconfig |
| 13950 | +++ b/wpa_supplicant/defconfig |
| 13951 | @@ -10,8 +10,8 @@ |
| 13952 | # to override previous values of the variables. |
| 13953 | |
| 13954 | |
| 13955 | -# Uncomment following two lines and fix the paths if you have installed OpenSSL |
| 13956 | -# or GnuTLS in non-default location |
| 13957 | +# Uncomment following two lines and fix the paths if you have installed TLS |
| 13958 | +# libraries in a non-default location |
| 13959 | #CFLAGS += -I/usr/local/openssl/include |
| 13960 | #LIBS += -L/usr/local/openssl/lib |
| 13961 | |
| 13962 | @@ -20,6 +20,7 @@ |
| 13963 | # used to fix build issues on such systems (krb5.h not found). |
| 13964 | #CFLAGS += -I/usr/include/kerberos |
| 13965 | |
| 13966 | + |
| 13967 | # Driver interface for generic Linux wireless extensions |
| 13968 | # Note: WEXT is deprecated in the current Linux kernel version and no new |
| 13969 | # functionality is added to it. nl80211-based interface is the new |
| 13970 | @@ -329,6 +330,7 @@ CONFIG_BACKEND=file |
| 13971 | # openssl = OpenSSL (default) |
| 13972 | # gnutls = GnuTLS |
| 13973 | # internal = Internal TLSv1 implementation (experimental) |
| 13974 | +# mbedtls = mbed TLS |
| 13975 | # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) |
| 13976 | # none = Empty template |
| 13977 | #CONFIG_TLS=openssl |
| 13978 | diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13979 | index 0c17aaea4..3d35757bf 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13980 | --- a/wpa_supplicant/eapol_test.c |
| 13981 | +++ b/wpa_supplicant/eapol_test.c |
| 13982 | @@ -31,7 +31,12 @@ |
| 13983 | #include "ctrl_iface.h" |
| 13984 | #include "pcsc_funcs.h" |
| 13985 | #include "wpas_glue.h" |
| 13986 | +#include "drivers/driver.h" |
| 13987 | |
| 13988 | +void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, |
| 13989 | + union wpa_event_data *data); |
| 13990 | +void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, |
| 13991 | + union wpa_event_data *data); |
| 13992 | |
| 13993 | const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; |
| 13994 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 13995 | @@ -1328,6 +1333,10 @@ static void usage(void) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 13996 | "option several times.\n"); |
| 13997 | } |
| 13998 | |
| 13999 | +extern void supplicant_event(void *ctx, enum wpa_event_type event, |
| 14000 | + union wpa_event_data *data); |
| 14001 | +extern void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14002 | + union wpa_event_data *data); |
| 14003 | |
| 14004 | int main(int argc, char *argv[]) |
| 14005 | { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14006 | @@ -1351,6 +1360,8 @@ int main(int argc, char *argv[]) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14007 | if (os_program_init()) |
| 14008 | return -1; |
| 14009 | |
| 14010 | + wpa_supplicant_event = supplicant_event; |
| 14011 | + wpa_supplicant_event_global = supplicant_event_global; |
| 14012 | hostapd_logger_register_cb(hostapd_logger_cb); |
| 14013 | |
| 14014 | os_memset(&eapol_test, 0, sizeof(eapol_test)); |
| 14015 | diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14016 | index bb0e95ba4..5c08d4a19 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14017 | --- a/wpa_supplicant/events.c |
| 14018 | +++ b/wpa_supplicant/events.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14019 | @@ -6038,8 +6038,8 @@ static void wpas_link_reconfig(struct wpa_supplicant *wpa_s) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14020 | } |
| 14021 | |
| 14022 | |
| 14023 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 14024 | - union wpa_event_data *data) |
| 14025 | +void supplicant_event(void *ctx, enum wpa_event_type event, |
| 14026 | + union wpa_event_data *data) |
| 14027 | { |
| 14028 | struct wpa_supplicant *wpa_s = ctx; |
| 14029 | int resched; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14030 | @@ -6074,6 +6074,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14031 | event_to_string(event), event); |
| 14032 | #endif /* CONFIG_NO_STDOUT_DEBUG */ |
| 14033 | |
| 14034 | + wpas_ucode_event(wpa_s, event, data); |
| 14035 | switch (event) { |
| 14036 | case EVENT_AUTH: |
| 14037 | #ifdef CONFIG_FST |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14038 | @@ -6991,7 +6992,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14039 | } |
| 14040 | |
| 14041 | |
| 14042 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14043 | +void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14044 | union wpa_event_data *data) |
| 14045 | { |
| 14046 | struct wpa_supplicant *wpa_s; |
| 14047 | diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c |
| 14048 | index 9229eb51f..ee152c5b9 100644 |
| 14049 | --- a/wpa_supplicant/main.c |
| 14050 | +++ b/wpa_supplicant/main.c |
| 14051 | @@ -12,6 +12,7 @@ |
| 14052 | #endif /* __linux__ */ |
| 14053 | |
| 14054 | #include "common.h" |
| 14055 | +#include "build_features.h" |
| 14056 | #include "crypto/crypto.h" |
| 14057 | #include "fst/fst.h" |
| 14058 | #include "wpa_supplicant_i.h" |
| 14059 | @@ -202,7 +203,7 @@ int main(int argc, char *argv[]) |
| 14060 | |
| 14061 | for (;;) { |
| 14062 | c = getopt(argc, argv, |
| 14063 | - "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); |
| 14064 | + "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W"); |
| 14065 | if (c < 0) |
| 14066 | break; |
| 14067 | switch (c) { |
| 14068 | @@ -267,6 +268,9 @@ int main(int argc, char *argv[]) |
| 14069 | params.conf_p2p_dev = optarg; |
| 14070 | break; |
| 14071 | #endif /* CONFIG_P2P */ |
| 14072 | + case 'n': |
| 14073 | + iface_count = 0; |
| 14074 | + break; |
| 14075 | case 'o': |
| 14076 | params.override_driver = optarg; |
| 14077 | break; |
| 14078 | @@ -302,8 +306,12 @@ int main(int argc, char *argv[]) |
| 14079 | break; |
| 14080 | #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ |
| 14081 | case 'v': |
| 14082 | - printf("%s\n", wpa_supplicant_version); |
| 14083 | - exitcode = 0; |
| 14084 | + if (optarg) { |
| 14085 | + exitcode = !has_feature(optarg); |
| 14086 | + } else { |
| 14087 | + printf("%s\n", wpa_supplicant_version); |
| 14088 | + exitcode = 0; |
| 14089 | + } |
| 14090 | goto out; |
| 14091 | case 'W': |
| 14092 | params.wait_for_monitor++; |
| 14093 | diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c |
| 14094 | index 85c1ea8ba..dabbb0334 100644 |
| 14095 | --- a/wpa_supplicant/mesh.c |
| 14096 | +++ b/wpa_supplicant/mesh.c |
| 14097 | @@ -506,6 +506,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, |
| 14098 | frequency); |
| 14099 | goto out_free; |
| 14100 | } |
| 14101 | + if (conf->noscan) |
| 14102 | + ssid->noscan = 1; |
| 14103 | |
| 14104 | if (ssid->mesh_basic_rates == NULL) { |
| 14105 | /* |
| 14106 | @@ -630,6 +632,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, |
| 14107 | |
| 14108 | params->meshid = ssid->ssid; |
| 14109 | params->meshid_len = ssid->ssid_len; |
| 14110 | + params->mcast_rate = ssid->mcast_rate; |
| 14111 | ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); |
| 14112 | wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; |
| 14113 | wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; |
| 14114 | diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14115 | index af00e7910..b239410e8 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14116 | --- a/wpa_supplicant/wpa_cli.c |
| 14117 | +++ b/wpa_supplicant/wpa_cli.c |
| 14118 | @@ -26,6 +26,15 @@ |
| 14119 | #include <cutils/properties.h> |
| 14120 | #endif /* ANDROID */ |
| 14121 | |
| 14122 | +#ifndef CONFIG_P2P |
| 14123 | +#define CONFIG_P2P |
| 14124 | +#endif |
| 14125 | +#ifndef CONFIG_AP |
| 14126 | +#define CONFIG_AP |
| 14127 | +#endif |
| 14128 | +#ifndef CONFIG_MESH |
| 14129 | +#define CONFIG_MESH |
| 14130 | +#endif |
| 14131 | |
| 14132 | static const char *const wpa_cli_version = |
| 14133 | "wpa_cli v" VERSION_STR "\n" |
| 14134 | diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c |
| 14135 | index 88f3f2a52..92efe5629 100644 |
| 14136 | --- a/wpa_supplicant/wpa_priv.c |
| 14137 | +++ b/wpa_supplicant/wpa_priv.c |
| 14138 | @@ -1042,8 +1042,8 @@ static void wpa_priv_send_ft_response(struct wpa_priv_interface *iface, |
| 14139 | } |
| 14140 | |
| 14141 | |
| 14142 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 14143 | - union wpa_event_data *data) |
| 14144 | +static void supplicant_event(void *ctx, enum wpa_event_type event, |
| 14145 | + union wpa_event_data *data) |
| 14146 | { |
| 14147 | struct wpa_priv_interface *iface = ctx; |
| 14148 | |
| 14149 | @@ -1106,7 +1106,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 14150 | } |
| 14151 | |
| 14152 | |
| 14153 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14154 | +void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14155 | union wpa_event_data *data) |
| 14156 | { |
| 14157 | struct wpa_priv_global *global = ctx; |
| 14158 | @@ -1220,6 +1220,8 @@ int main(int argc, char *argv[]) |
| 14159 | if (os_program_init()) |
| 14160 | return -1; |
| 14161 | |
| 14162 | + wpa_supplicant_event = supplicant_event; |
| 14163 | + wpa_supplicant_event_global = supplicant_event_global; |
| 14164 | wpa_priv_fd_workaround(); |
| 14165 | |
| 14166 | os_memset(&global, 0, sizeof(global)); |
| 14167 | diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14168 | index 1e77493ef..32b178560 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14169 | --- a/wpa_supplicant/wpa_supplicant.c |
| 14170 | +++ b/wpa_supplicant/wpa_supplicant.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14171 | @@ -1151,6 +1151,7 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14172 | sme_sched_obss_scan(wpa_s, 0); |
| 14173 | } |
| 14174 | wpa_s->wpa_state = state; |
| 14175 | + wpas_ucode_update_state(wpa_s); |
| 14176 | |
| 14177 | #ifdef CONFIG_BGSCAN |
| 14178 | if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14179 | @@ -2831,7 +2832,7 @@ static int drv_supports_vht(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14180 | } |
| 14181 | |
| 14182 | |
| 14183 | -static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode) |
| 14184 | +static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode, bool dfs_enabled) |
| 14185 | { |
| 14186 | int i; |
| 14187 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14188 | @@ -2840,7 +2841,10 @@ static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14189 | |
| 14190 | chan = hw_get_channel_chan(mode, i, NULL); |
| 14191 | if (!chan || |
| 14192 | - chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) |
| 14193 | + chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14194 | + return false; |
| 14195 | + |
| 14196 | + if (!dfs_enabled && chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) |
| 14197 | return false; |
| 14198 | } |
| 14199 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14200 | @@ -2900,7 +2904,7 @@ static bool ibss_mesh_can_use_vht(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14201 | const struct wpa_ssid *ssid, |
| 14202 | struct hostapd_hw_modes *mode) |
| 14203 | { |
| 14204 | - if (mode->mode != HOSTAPD_MODE_IEEE80211A) |
| 14205 | + if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) |
| 14206 | return false; |
| 14207 | |
| 14208 | if (!drv_supports_vht(wpa_s, ssid)) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14209 | @@ -2967,13 +2971,13 @@ static void ibss_mesh_select_40mhz(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14210 | const struct wpa_ssid *ssid, |
| 14211 | struct hostapd_hw_modes *mode, |
| 14212 | struct hostapd_freq_params *freq, |
| 14213 | - int obss_scan) { |
| 14214 | + int obss_scan, bool dfs_enabled) { |
| 14215 | int chan_idx; |
| 14216 | struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; |
| 14217 | int i, res; |
| 14218 | unsigned int j; |
| 14219 | static const int ht40plus[] = { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14220 | - 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, |
| 14221 | + 1, 2, 3, 4, 5, 6, 7, 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14222 | 149, 157, 165, 173, 184, 192 |
| 14223 | }; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14224 | int ht40 = -1; |
| 14225 | @@ -2991,8 +2995,11 @@ static void ibss_mesh_select_40mhz(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14226 | return; |
| 14227 | |
| 14228 | /* Check primary channel flags */ |
| 14229 | - if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) |
| 14230 | + if (pri_chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14231 | return; |
| 14232 | + if (pri_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) |
| 14233 | + if (!dfs_enabled) |
| 14234 | + return; |
| 14235 | |
| 14236 | #ifdef CONFIG_HT_OVERRIDES |
| 14237 | if (ssid->disable_ht40) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14238 | @@ -3018,8 +3025,11 @@ static void ibss_mesh_select_40mhz(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14239 | return; |
| 14240 | |
| 14241 | /* Check secondary channel flags */ |
| 14242 | - if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) |
| 14243 | + if (sec_chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14244 | return; |
| 14245 | + if (sec_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) |
| 14246 | + if (!dfs_enabled) |
| 14247 | + return; |
| 14248 | |
| 14249 | if (ht40 == -1) { |
| 14250 | if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14251 | @@ -3074,7 +3084,7 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14252 | const struct wpa_ssid *ssid, |
| 14253 | struct hostapd_hw_modes *mode, |
| 14254 | struct hostapd_freq_params *freq, |
| 14255 | - int ieee80211_mode, bool is_6ghz) { |
| 14256 | + int ieee80211_mode, bool is_6ghz, bool dfs_enabled) { |
| 14257 | static const int bw80[] = { |
| 14258 | 5180, 5260, 5500, 5580, 5660, 5745, 5825, |
| 14259 | 5955, 6035, 6115, 6195, 6275, 6355, 6435, |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14260 | @@ -3119,7 +3129,7 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14261 | goto skip_80mhz; |
| 14262 | |
| 14263 | /* Use 40 MHz if channel not usable */ |
| 14264 | - if (!ibss_mesh_is_80mhz_avail(channel, mode)) |
| 14265 | + if (!ibss_mesh_is_80mhz_avail(channel, mode, dfs_enabled)) |
| 14266 | goto skip_80mhz; |
| 14267 | |
| 14268 | chwidth = CONF_OPER_CHWIDTH_80MHZ; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14269 | @@ -3133,7 +3143,7 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14270 | if ((mode->he_capab[ieee80211_mode].phy_cap[ |
| 14271 | HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & |
| 14272 | HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz && |
| 14273 | - ibss_mesh_is_80mhz_avail(channel + 16, mode)) { |
| 14274 | + ibss_mesh_is_80mhz_avail(channel + 16, mode, dfs_enabled)) { |
| 14275 | for (j = 0; j < ARRAY_SIZE(bw160); j++) { |
| 14276 | if (freq->freq == bw160[j]) { |
| 14277 | chwidth = CONF_OPER_CHWIDTH_160MHZ; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14278 | @@ -3161,10 +3171,12 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14279 | if (!chan) |
| 14280 | continue; |
| 14281 | |
| 14282 | - if (chan->flag & (HOSTAPD_CHAN_DISABLED | |
| 14283 | - HOSTAPD_CHAN_NO_IR | |
| 14284 | - HOSTAPD_CHAN_RADAR)) |
| 14285 | + if (chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14286 | continue; |
| 14287 | + if (chan->flag & (HOSTAPD_CHAN_RADAR | |
| 14288 | + HOSTAPD_CHAN_NO_IR)) |
| 14289 | + if (!dfs_enabled) |
| 14290 | + continue; |
| 14291 | |
| 14292 | /* Found a suitable second segment for 80+80 */ |
| 14293 | chwidth = CONF_OPER_CHWIDTH_80P80MHZ; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14294 | @@ -3216,12 +3228,17 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14295 | int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode); |
| 14296 | enum hostapd_hw_mode hw_mode; |
| 14297 | struct hostapd_hw_modes *mode = NULL; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14298 | - int obss_scan = 1; |
| 14299 | + int obss_scan = !(ssid->noscan); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14300 | u8 channel; |
| 14301 | bool is_6ghz, is_24ghz; |
| 14302 | + bool dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); |
| 14303 | |
| 14304 | freq->freq = ssid->frequency; |
| 14305 | |
| 14306 | + if (ssid->fixed_freq) { |
| 14307 | + obss_scan = 0; |
| 14308 | + } |
| 14309 | + |
| 14310 | if (ssid->mode == WPAS_MODE_IBSS && !ssid->fixed_freq) { |
| 14311 | struct wpa_bss *bss = ibss_find_existing_bss(wpa_s, ssid); |
| 14312 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14313 | @@ -3259,11 +3276,13 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14314 | freq->he_enabled = ibss_mesh_can_use_he(wpa_s, ssid, mode, |
| 14315 | ieee80211_mode); |
| 14316 | freq->channel = channel; |
| 14317 | + if (mode->mode == HOSTAPD_MODE_IEEE80211G && ssid->noscan) |
| 14318 | + ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); |
| 14319 | /* Setup higher BW only for 5 GHz */ |
| 14320 | if (mode->mode == HOSTAPD_MODE_IEEE80211A) { |
| 14321 | - ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan); |
| 14322 | + ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); |
| 14323 | if (!ibss_mesh_select_80_160mhz(wpa_s, ssid, mode, freq, |
| 14324 | - ieee80211_mode, is_6ghz)) |
| 14325 | + ieee80211_mode, is_6ghz, dfs_enabled)) |
| 14326 | freq->he_enabled = freq->vht_enabled = false; |
| 14327 | } |
| 14328 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14329 | @@ -4449,6 +4468,12 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14330 | params.beacon_int = ssid->beacon_int; |
| 14331 | else |
| 14332 | params.beacon_int = wpa_s->conf->beacon_int; |
| 14333 | + int i = 0; |
| 14334 | + while (i < WLAN_SUPP_RATES_MAX) { |
| 14335 | + params.rates[i] = ssid->rates[i]; |
| 14336 | + i++; |
| 14337 | + } |
| 14338 | + params.mcast_rate = ssid->mcast_rate; |
| 14339 | } |
| 14340 | |
| 14341 | if (bss && ssid->enable_edmg) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14342 | @@ -6093,7 +6118,7 @@ wpa_supplicant_alloc(struct wpa_supplicant *parent) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14343 | if (wpa_s == NULL) |
| 14344 | return NULL; |
| 14345 | wpa_s->scan_req = INITIAL_SCAN_REQ; |
| 14346 | - wpa_s->scan_interval = 5; |
| 14347 | + wpa_s->scan_interval = 1; |
| 14348 | wpa_s->new_connection = 1; |
| 14349 | wpa_s->parent = parent ? parent : wpa_s; |
| 14350 | wpa_s->p2pdev = wpa_s->parent; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14351 | @@ -7809,7 +7834,6 @@ struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14352 | return NULL; |
| 14353 | } |
| 14354 | |
| 14355 | - |
| 14356 | /** |
| 14357 | * wpa_supplicant_match_existing - Match existing interfaces |
| 14358 | * @global: Pointer to global data from wpa_supplicant_init() |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14359 | @@ -7844,6 +7868,11 @@ static int wpa_supplicant_match_existing(struct wpa_global *global) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14360 | |
| 14361 | #endif /* CONFIG_MATCH_IFACE */ |
| 14362 | |
| 14363 | +extern void supplicant_event(void *ctx, enum wpa_event_type event, |
| 14364 | + union wpa_event_data *data); |
| 14365 | + |
| 14366 | +extern void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14367 | + union wpa_event_data *data); |
| 14368 | |
| 14369 | /** |
| 14370 | * wpa_supplicant_add_iface - Add a new network interface |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14371 | @@ -7926,6 +7955,9 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14372 | } |
| 14373 | #endif /* CONFIG_P2P */ |
| 14374 | |
| 14375 | + wpas_ubus_add_bss(wpa_s); |
| 14376 | + wpas_ucode_add_bss(wpa_s); |
| 14377 | + |
| 14378 | return wpa_s; |
| 14379 | } |
| 14380 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14381 | @@ -7952,6 +7984,9 @@ int wpa_supplicant_remove_iface(struct wpa_global *global, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14382 | struct wpa_supplicant *parent = wpa_s->parent; |
| 14383 | #endif /* CONFIG_MESH */ |
| 14384 | |
| 14385 | + wpas_ucode_free_bss(wpa_s); |
| 14386 | + wpas_ubus_free_bss(wpa_s); |
| 14387 | + |
| 14388 | /* Remove interface from the global list of interfaces */ |
| 14389 | prev = global->ifaces; |
| 14390 | if (prev == wpa_s) { |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14391 | @@ -8100,6 +8135,8 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14392 | #ifndef CONFIG_NO_WPA_MSG |
| 14393 | wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); |
| 14394 | #endif /* CONFIG_NO_WPA_MSG */ |
| 14395 | + wpa_supplicant_event = supplicant_event; |
| 14396 | + wpa_supplicant_event_global = supplicant_event_global; |
| 14397 | |
| 14398 | if (params->wpa_debug_file_path) |
| 14399 | wpa_debug_open_file(params->wpa_debug_file_path); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14400 | @@ -8258,6 +8295,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14401 | |
| 14402 | eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, |
| 14403 | wpas_periodic, global, NULL); |
| 14404 | + wpas_ucode_init(global); |
| 14405 | |
| 14406 | return global; |
| 14407 | } |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14408 | @@ -8330,6 +8368,8 @@ void wpa_supplicant_deinit(struct wpa_global *global) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14409 | |
| 14410 | wpas_notify_supplicant_deinitialized(global); |
| 14411 | |
| 14412 | + wpas_ucode_free(); |
| 14413 | + |
| 14414 | eap_peer_unregister_methods(); |
| 14415 | #ifdef CONFIG_AP |
| 14416 | eap_server_unregister_methods(); |
| 14417 | diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14418 | index 48ec95fa5..952a3bd5a 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14419 | --- a/wpa_supplicant/wpa_supplicant_i.h |
| 14420 | +++ b/wpa_supplicant/wpa_supplicant_i.h |
| 14421 | @@ -21,6 +21,8 @@ |
| 14422 | #include "config_ssid.h" |
| 14423 | #include "wmm_ac.h" |
| 14424 | #include "pasn/pasn_common.h" |
| 14425 | +#include "ubus.h" |
| 14426 | +#include "ucode.h" |
| 14427 | |
| 14428 | extern const char *const wpa_supplicant_version; |
| 14429 | extern const char *const wpa_supplicant_license; |
| 14430 | @@ -319,6 +321,8 @@ struct wpa_global { |
| 14431 | #endif /* CONFIG_WIFI_DISPLAY */ |
| 14432 | |
| 14433 | struct psk_list_entry *add_psk; /* From group formation */ |
| 14434 | + |
| 14435 | + struct ubus_object ubus_global; |
| 14436 | }; |
| 14437 | |
| 14438 | |
| 14439 | @@ -693,6 +697,8 @@ struct wpa_supplicant { |
| 14440 | unsigned char own_addr[ETH_ALEN]; |
| 14441 | unsigned char perm_addr[ETH_ALEN]; |
| 14442 | char ifname[100]; |
| 14443 | + struct wpas_ubus_bss ubus; |
| 14444 | + struct wpas_ucode_bss ucode; |
| 14445 | #ifdef CONFIG_MATCH_IFACE |
| 14446 | int matched; |
| 14447 | #endif /* CONFIG_MATCH_IFACE */ |
| 14448 | diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14449 | index 7b9cf7f9e..03748f4bb 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14450 | --- a/wpa_supplicant/wps_supplicant.c |
| 14451 | +++ b/wpa_supplicant/wps_supplicant.c |
| 14452 | @@ -33,6 +33,7 @@ |
| 14453 | #include "p2p/p2p.h" |
| 14454 | #include "p2p_supplicant.h" |
| 14455 | #include "wps_supplicant.h" |
| 14456 | +#include "ubus.h" |
| 14457 | |
| 14458 | |
| 14459 | #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG |
| 14460 | @@ -401,6 +402,8 @@ static int wpa_supplicant_wps_cred(void *ctx, |
| 14461 | wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", |
| 14462 | cred->cred_attr, cred->cred_attr_len); |
| 14463 | |
| 14464 | + wpas_ubus_notify(wpa_s, cred); |
| 14465 | + |
| 14466 | if (wpa_s->conf->wps_cred_processing == 1) |
| 14467 | return 0; |
| 14468 | |
| 14469 | diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h |
| 14470 | index aae3f7cb5..30b4e9105 100644 |
| 14471 | --- a/wpa_supplicant/wps_supplicant.h |
| 14472 | +++ b/wpa_supplicant/wps_supplicant.h |
| 14473 | @@ -9,6 +9,7 @@ |
| 14474 | #ifndef WPS_SUPPLICANT_H |
| 14475 | #define WPS_SUPPLICANT_H |
| 14476 | |
| 14477 | +struct wpa_bss; |
| 14478 | struct wpa_scan_results; |
| 14479 | |
| 14480 | #ifdef CONFIG_WPS |
| 14481 | @@ -16,8 +17,6 @@ struct wpa_scan_results; |
| 14482 | #include "wps/wps.h" |
| 14483 | #include "wps/wps_defs.h" |
| 14484 | |
| 14485 | -struct wpa_bss; |
| 14486 | - |
| 14487 | struct wps_new_ap_settings { |
| 14488 | const char *ssid_hex; |
| 14489 | const char *auth; |
| 14490 | -- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame^] | 14491 | 2.18.0 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14492 | |