developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1 | From 2eff271199b22ce44432d531e8b44809368ac5d2 Mon Sep 17 00:00:00 2001 |
| 2 | From: Evelyn Tsai <evelyn.tsai@mediatek.com> |
| 3 | Date: Tue, 23 Jan 2024 17:07:17 +0800 |
| 4 | Subject: [PATCH 028/104] hostapd: sync 2024-01-18 openwrt/trunk patch folder |
| 5 | |
| 6 | --- |
| 7 | hostapd/Makefile | 149 +- |
| 8 | hostapd/config_file.c | 39 +- |
| 9 | hostapd/ctrl_iface.c | 4 + |
| 10 | hostapd/defconfig | 15 +- |
| 11 | hostapd/hostapd_cli.c | 10 +- |
| 12 | hostapd/main.c | 21 +- |
| 13 | src/ap/acs.c | 5 +- |
| 14 | src/ap/airtime_policy.c | 15 +- |
| 15 | src/ap/ap_config.h | 8 + |
| 16 | src/ap/ap_drv_ops.c | 5 +- |
| 17 | src/ap/ap_drv_ops.h | 21 +- |
| 18 | src/ap/beacon.c | 14 +- |
| 19 | src/ap/ctrl_iface_ap.c | 45 +- |
| 20 | src/ap/dfs.c | 22 +- |
| 21 | src/ap/drv_callbacks.c | 16 +- |
| 22 | src/ap/hostapd.c | 51 +- |
| 23 | src/ap/hostapd.h | 42 + |
| 24 | src/ap/hw_features.c | 3 +- |
| 25 | src/ap/ieee802_11.c | 50 +- |
| 26 | src/ap/ieee802_11_ht.c | 15 + |
| 27 | src/ap/ieee802_11_shared.c | 2 - |
| 28 | src/ap/ieee802_11_vht.c | 17 + |
| 29 | src/ap/ieee802_1x.c | 6 + |
| 30 | src/ap/ndisc_snoop.c | 1 + |
| 31 | src/ap/rrm.c | 8 + |
| 32 | src/ap/sta_info.c | 35 +- |
| 33 | src/ap/sta_info.h | 12 +- |
| 34 | src/ap/vlan_full.c | 4 + |
| 35 | src/ap/vlan_init.c | 8 +- |
| 36 | src/ap/wnm_ap.c | 16 +- |
| 37 | src/ap/wpa_auth.c | 3 +- |
| 38 | src/ap/wpa_auth_glue.c | 9 +- |
| 39 | src/ap/wps_hostapd.c | 6 +- |
| 40 | src/ap/x_snoop.c | 22 +- |
| 41 | src/common/dpp_crypto.c | 10 +- |
| 42 | src/common/hw_features_common.c | 1 + |
| 43 | src/common/ieee802_11_defs.h | 2 + |
| 44 | src/common/sae.c | 7 + |
| 45 | src/common/wpa_common.c | 40 +- |
| 46 | src/common/wpa_ctrl.c | 10 +- |
| 47 | src/crypto/Makefile | 129 +- |
| 48 | src/crypto/crypto_mbedtls.c | 4228 +++++++++++++++++++++ |
| 49 | src/crypto/crypto_module_tests.c | 134 + |
| 50 | src/crypto/crypto_wolfssl.c | 18 + |
| 51 | src/crypto/tls_mbedtls.c | 3313 ++++++++++++++++ |
| 52 | src/drivers/driver.h | 36 +- |
| 53 | src/drivers/driver_nl80211.c | 300 +- |
| 54 | src/drivers/driver_nl80211_capa.c | 4 + |
| 55 | src/drivers/driver_nl80211_event.c | 5 + |
| 56 | src/drivers/driver_nl80211_scan.c | 2 +- |
| 57 | src/drivers/drivers.c | 4 + |
| 58 | src/drivers/drivers.mak | 4 +- |
| 59 | src/drivers/rfkill.h | 16 + |
| 60 | src/radius/radius_client.c | 34 + |
| 61 | src/radius/radius_client.h | 2 + |
| 62 | src/radius/radius_das.c | 201 +- |
| 63 | src/radius/radius_das.h | 1 + |
| 64 | src/radius/radius_server.c | 61 +- |
| 65 | src/rsn_supp/wpa.c | 3 + |
| 66 | src/tls/Makefile | 11 + |
| 67 | src/utils/eloop.c | 20 +- |
| 68 | src/utils/eloop.h | 8 + |
| 69 | src/utils/uloop.c | 64 + |
| 70 | src/utils/wpa_debug.c | 49 +- |
| 71 | src/utils/wpa_debug.h | 73 +- |
| 72 | tests/Makefile | 65 +- |
| 73 | tests/hwsim/example-hostapd.config | 10 +- |
| 74 | tests/hwsim/example-wpa_supplicant.config | 11 +- |
| 75 | tests/hwsim/test_ap_eap.py | 112 +- |
| 76 | tests/hwsim/test_ap_ft.py | 4 +- |
| 77 | tests/hwsim/test_authsrv.py | 9 +- |
| 78 | tests/hwsim/test_dpp.py | 19 +- |
| 79 | tests/hwsim/test_erp.py | 16 +- |
| 80 | tests/hwsim/test_fils.py | 12 + |
| 81 | tests/hwsim/test_pmksa_cache.py | 4 +- |
| 82 | tests/hwsim/test_sae.py | 7 + |
| 83 | tests/hwsim/test_suite_b.py | 3 + |
| 84 | tests/hwsim/test_wpas_ctrl.py | 2 +- |
| 85 | tests/hwsim/utils.py | 8 +- |
| 86 | tests/test-crypto_module.c | 16 + |
| 87 | tests/test-https.c | 12 +- |
| 88 | tests/test-https_server.c | 12 +- |
| 89 | wpa_supplicant/Makefile | 144 +- |
| 90 | wpa_supplicant/ap.c | 22 +- |
| 91 | wpa_supplicant/config.c | 95 + |
| 92 | wpa_supplicant/config_file.c | 8 +- |
| 93 | wpa_supplicant/config_ssid.h | 7 + |
| 94 | wpa_supplicant/ctrl_iface.c | 12 +- |
| 95 | wpa_supplicant/defconfig | 6 +- |
| 96 | wpa_supplicant/eapol_test.c | 11 + |
| 97 | wpa_supplicant/events.c | 13 +- |
| 98 | wpa_supplicant/main.c | 14 +- |
| 99 | wpa_supplicant/mesh.c | 3 + |
| 100 | wpa_supplicant/wpa_cli.c | 9 + |
| 101 | wpa_supplicant/wpa_priv.c | 8 +- |
| 102 | wpa_supplicant/wpa_supplicant.c | 75 +- |
| 103 | wpa_supplicant/wpa_supplicant_i.h | 6 + |
| 104 | wpa_supplicant/wps_supplicant.c | 3 + |
| 105 | wpa_supplicant/wps_supplicant.h | 3 +- |
| 106 | 99 files changed, 9786 insertions(+), 464 deletions(-) |
| 107 | create mode 100644 src/crypto/crypto_mbedtls.c |
| 108 | create mode 100644 src/crypto/tls_mbedtls.c |
| 109 | create mode 100644 src/utils/uloop.c |
| 110 | create mode 100644 tests/test-crypto_module.c |
| 111 | |
| 112 | diff --git a/hostapd/Makefile b/hostapd/Makefile |
| 113 | index 405e05e5f..f5c1dc029 100644 |
| 114 | --- a/hostapd/Makefile |
| 115 | +++ b/hostapd/Makefile |
| 116 | @@ -1,6 +1,7 @@ |
| 117 | ALL=hostapd hostapd_cli |
| 118 | CONFIG_FILE = .config |
| 119 | |
| 120 | +-include $(if $(MULTICALL), ../wpa_supplicant/.config) |
| 121 | include ../src/build.rules |
| 122 | |
| 123 | ifdef LIBS |
| 124 | @@ -62,6 +63,10 @@ endif |
| 125 | OBJS += main.o |
| 126 | OBJS += config_file.o |
| 127 | |
| 128 | +ifdef CONFIG_RADIUS_SERVER |
| 129 | +OBJS += radius.o |
| 130 | +endif |
| 131 | + |
| 132 | OBJS += ../src/ap/hostapd.o |
| 133 | OBJS += ../src/ap/wpa_auth_glue.o |
| 134 | OBJS += ../src/ap/drv_callbacks.o |
| 135 | @@ -171,6 +176,24 @@ OBJS += ../src/common/hw_features_common.o |
| 136 | |
| 137 | OBJS += ../src/eapol_auth/eapol_auth_sm.o |
| 138 | |
| 139 | +ifdef CONFIG_UBUS |
| 140 | +CFLAGS += -DUBUS_SUPPORT |
| 141 | +OBJS += ../src/ap/ubus.o |
| 142 | +LIBS += -lubus |
| 143 | +NEED_ULOOP:=y |
| 144 | +endif |
| 145 | + |
| 146 | +ifdef CONFIG_UCODE |
| 147 | +CFLAGS += -DUCODE_SUPPORT |
| 148 | +OBJS += ../src/utils/ucode.o |
| 149 | +OBJS += ../src/ap/ucode.o |
| 150 | +NEED_ULOOP:=y |
| 151 | +endif |
| 152 | + |
| 153 | +ifdef NEED_ULOOP |
| 154 | +OBJS += ../src/utils/uloop.o |
| 155 | +LIBS += -lubox |
| 156 | +endif |
| 157 | |
| 158 | ifdef CONFIG_CODE_COVERAGE |
| 159 | CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE |
| 160 | @@ -205,7 +228,8 @@ endif |
| 161 | |
| 162 | ifdef CONFIG_NO_VLAN |
| 163 | CFLAGS += -DCONFIG_NO_VLAN |
| 164 | -else |
| 165 | +endif |
| 166 | +ifneq ($(findstring CONFIG_NO_VLAN,$(CFLAGS)), CONFIG_NO_VLAN) |
| 167 | OBJS += ../src/ap/vlan_init.o |
| 168 | OBJS += ../src/ap/vlan_ifconfig.o |
| 169 | OBJS += ../src/ap/vlan.o |
| 170 | @@ -225,6 +249,9 @@ endif |
| 171 | ifdef CONFIG_NO_CTRL_IFACE |
| 172 | CFLAGS += -DCONFIG_NO_CTRL_IFACE |
| 173 | else |
| 174 | +ifdef CONFIG_CTRL_IFACE_MIB |
| 175 | +CFLAGS += -DCONFIG_CTRL_IFACE_MIB |
| 176 | +endif |
| 177 | ifeq ($(CONFIG_CTRL_IFACE), udp) |
| 178 | CFLAGS += -DCONFIG_CTRL_IFACE_UDP |
| 179 | else |
| 180 | @@ -332,6 +359,7 @@ ifdef CONFIG_FILS |
| 181 | CFLAGS += -DCONFIG_FILS |
| 182 | OBJS += ../src/ap/fils_hlp.o |
| 183 | NEED_SHA384=y |
| 184 | +NEED_HMAC_SHA384_KDF=y |
| 185 | NEED_AES_SIV=y |
| 186 | ifdef CONFIG_FILS_SK_PFS |
| 187 | CFLAGS += -DCONFIG_FILS_SK_PFS |
| 188 | @@ -364,10 +392,14 @@ CFLAGS += -DCONFIG_MBO |
| 189 | OBJS += ../src/ap/mbo_ap.o |
| 190 | endif |
| 191 | |
| 192 | +ifndef MULTICALL |
| 193 | +CFLAGS += -DNO_SUPPLICANT |
| 194 | +endif |
| 195 | + |
| 196 | include ../src/drivers/drivers.mak |
| 197 | -OBJS += $(DRV_AP_OBJS) |
| 198 | -CFLAGS += $(DRV_AP_CFLAGS) |
| 199 | -LDFLAGS += $(DRV_AP_LDFLAGS) |
| 200 | +OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS))) |
| 201 | +CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS)) |
| 202 | +LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS)) |
| 203 | LIBS += $(DRV_AP_LIBS) |
| 204 | |
| 205 | ifdef CONFIG_L2_PACKET |
| 206 | @@ -714,6 +746,7 @@ CFLAGS += -DCONFIG_TLSV12 |
| 207 | endif |
| 208 | |
| 209 | ifeq ($(CONFIG_TLS), wolfssl) |
| 210 | +CFLAGS += -DCONFIG_TLS_WOLFSSL |
| 211 | CONFIG_CRYPTO=wolfssl |
| 212 | ifdef TLS_FUNCS |
| 213 | OBJS += ../src/crypto/tls_wolfssl.o |
| 214 | @@ -734,6 +767,7 @@ endif |
| 215 | endif |
| 216 | |
| 217 | ifeq ($(CONFIG_TLS), openssl) |
| 218 | +CFLAGS += -DCONFIG_TLS_OPENSSL |
| 219 | CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 220 | CONFIG_CRYPTO=openssl |
| 221 | ifdef TLS_FUNCS |
| 222 | @@ -763,7 +797,39 @@ endif |
| 223 | CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" |
| 224 | endif |
| 225 | |
| 226 | +ifeq ($(CONFIG_TLS), mbedtls) |
| 227 | +CFLAGS += -DCONFIG_TLS_MBEDTLS |
| 228 | +ifndef CONFIG_CRYPTO |
| 229 | +CONFIG_CRYPTO=mbedtls |
| 230 | +endif |
| 231 | +ifdef TLS_FUNCS |
| 232 | +OBJS += ../src/crypto/tls_mbedtls.o |
| 233 | +LIBS += -lmbedtls |
| 234 | +ifndef CONFIG_DPP |
| 235 | +LIBS += -lmbedx509 |
| 236 | +endif |
| 237 | +endif |
| 238 | +OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 239 | +HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 240 | +SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 241 | +ifeq ($(CONFIG_CRYPTO), mbedtls) |
| 242 | +ifdef CONFIG_DPP |
| 243 | +LIBS += -lmbedx509 |
| 244 | +LIBS_h += -lmbedx509 |
| 245 | +LIBS_n += -lmbedx509 |
| 246 | +LIBS_s += -lmbedx509 |
| 247 | +endif |
| 248 | +LIBS += -lmbedcrypto |
| 249 | +LIBS_h += -lmbedcrypto |
| 250 | +LIBS_n += -lmbedcrypto |
| 251 | +LIBS_s += -lmbedcrypto |
| 252 | +# XXX: create a config option? |
| 253 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 254 | +endif |
| 255 | +endif |
| 256 | + |
| 257 | ifeq ($(CONFIG_TLS), gnutls) |
| 258 | +CFLAGS += -DCONFIG_TLS_GNUTLS |
| 259 | ifndef CONFIG_CRYPTO |
| 260 | # default to libgcrypt |
| 261 | CONFIG_CRYPTO=gnutls |
| 262 | @@ -794,6 +860,7 @@ endif |
| 263 | endif |
| 264 | |
| 265 | ifeq ($(CONFIG_TLS), internal) |
| 266 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 267 | ifndef CONFIG_CRYPTO |
| 268 | CONFIG_CRYPTO=internal |
| 269 | endif |
| 270 | @@ -872,6 +939,7 @@ endif |
| 271 | endif |
| 272 | |
| 273 | ifeq ($(CONFIG_TLS), linux) |
| 274 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 275 | OBJS += ../src/crypto/crypto_linux.o |
| 276 | ifdef TLS_FUNCS |
| 277 | OBJS += ../src/crypto/crypto_internal-rsa.o |
| 278 | @@ -942,9 +1010,11 @@ endif |
| 279 | |
| 280 | ifneq ($(CONFIG_TLS), openssl) |
| 281 | ifneq ($(CONFIG_TLS), wolfssl) |
| 282 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 283 | AESOBJS += ../src/crypto/aes-wrap.o |
| 284 | endif |
| 285 | endif |
| 286 | +endif |
| 287 | ifdef NEED_AES_EAX |
| 288 | AESOBJS += ../src/crypto/aes-eax.o |
| 289 | NEED_AES_CTR=y |
| 290 | @@ -954,38 +1024,48 @@ AESOBJS += ../src/crypto/aes-siv.o |
| 291 | NEED_AES_CTR=y |
| 292 | endif |
| 293 | ifdef NEED_AES_CTR |
| 294 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 295 | AESOBJS += ../src/crypto/aes-ctr.o |
| 296 | endif |
| 297 | +endif |
| 298 | ifdef NEED_AES_ENCBLOCK |
| 299 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 300 | AESOBJS += ../src/crypto/aes-encblock.o |
| 301 | endif |
| 302 | +endif |
| 303 | ifneq ($(CONFIG_TLS), openssl) |
| 304 | ifneq ($(CONFIG_TLS), linux) |
| 305 | ifneq ($(CONFIG_TLS), wolfssl) |
| 306 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 307 | AESOBJS += ../src/crypto/aes-omac1.o |
| 308 | endif |
| 309 | endif |
| 310 | endif |
| 311 | +endif |
| 312 | ifdef NEED_AES_UNWRAP |
| 313 | ifneq ($(CONFIG_TLS), openssl) |
| 314 | ifneq ($(CONFIG_TLS), linux) |
| 315 | ifneq ($(CONFIG_TLS), wolfssl) |
| 316 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 317 | NEED_AES_DEC=y |
| 318 | AESOBJS += ../src/crypto/aes-unwrap.o |
| 319 | endif |
| 320 | endif |
| 321 | endif |
| 322 | endif |
| 323 | +endif |
| 324 | ifdef NEED_AES_CBC |
| 325 | NEED_AES_DEC=y |
| 326 | ifneq ($(CONFIG_TLS), openssl) |
| 327 | ifneq ($(CONFIG_TLS), linux) |
| 328 | ifneq ($(CONFIG_TLS), wolfssl) |
| 329 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 330 | AESOBJS += ../src/crypto/aes-cbc.o |
| 331 | endif |
| 332 | endif |
| 333 | endif |
| 334 | endif |
| 335 | +endif |
| 336 | ifdef NEED_AES_DEC |
| 337 | ifdef CONFIG_INTERNAL_AES |
| 338 | AESOBJS += ../src/crypto/aes-internal-dec.o |
| 339 | @@ -1000,12 +1080,16 @@ ifneq ($(CONFIG_TLS), openssl) |
| 340 | ifneq ($(CONFIG_TLS), linux) |
| 341 | ifneq ($(CONFIG_TLS), gnutls) |
| 342 | ifneq ($(CONFIG_TLS), wolfssl) |
| 343 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 344 | SHA1OBJS += ../src/crypto/sha1.o |
| 345 | endif |
| 346 | endif |
| 347 | endif |
| 348 | endif |
| 349 | +endif |
| 350 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 351 | SHA1OBJS += ../src/crypto/sha1-prf.o |
| 352 | +endif |
| 353 | ifdef CONFIG_INTERNAL_SHA1 |
| 354 | SHA1OBJS += ../src/crypto/sha1-internal.o |
| 355 | ifdef NEED_FIPS186_2_PRF |
| 356 | @@ -1014,16 +1098,22 @@ endif |
| 357 | endif |
| 358 | ifneq ($(CONFIG_TLS), openssl) |
| 359 | ifneq ($(CONFIG_TLS), wolfssl) |
| 360 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 361 | SHA1OBJS += ../src/crypto/sha1-pbkdf2.o |
| 362 | endif |
| 363 | endif |
| 364 | +endif |
| 365 | ifdef NEED_T_PRF |
| 366 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 367 | SHA1OBJS += ../src/crypto/sha1-tprf.o |
| 368 | endif |
| 369 | +endif |
| 370 | ifdef NEED_TLS_PRF |
| 371 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 372 | SHA1OBJS += ../src/crypto/sha1-tlsprf.o |
| 373 | endif |
| 374 | endif |
| 375 | +endif |
| 376 | |
| 377 | ifdef NEED_SHA1 |
| 378 | OBJS += $(SHA1OBJS) |
| 379 | @@ -1033,11 +1123,13 @@ ifneq ($(CONFIG_TLS), openssl) |
| 380 | ifneq ($(CONFIG_TLS), linux) |
| 381 | ifneq ($(CONFIG_TLS), gnutls) |
| 382 | ifneq ($(CONFIG_TLS), wolfssl) |
| 383 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 384 | OBJS += ../src/crypto/md5.o |
| 385 | endif |
| 386 | endif |
| 387 | endif |
| 388 | endif |
| 389 | +endif |
| 390 | |
| 391 | ifdef NEED_MD5 |
| 392 | ifdef CONFIG_INTERNAL_MD5 |
| 393 | @@ -1076,56 +1168,81 @@ ifneq ($(CONFIG_TLS), openssl) |
| 394 | ifneq ($(CONFIG_TLS), linux) |
| 395 | ifneq ($(CONFIG_TLS), gnutls) |
| 396 | ifneq ($(CONFIG_TLS), wolfssl) |
| 397 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 398 | OBJS += ../src/crypto/sha256.o |
| 399 | endif |
| 400 | endif |
| 401 | endif |
| 402 | endif |
| 403 | +endif |
| 404 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 405 | OBJS += ../src/crypto/sha256-prf.o |
| 406 | +endif |
| 407 | ifdef CONFIG_INTERNAL_SHA256 |
| 408 | OBJS += ../src/crypto/sha256-internal.o |
| 409 | endif |
| 410 | ifdef NEED_TLS_PRF_SHA256 |
| 411 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 412 | OBJS += ../src/crypto/sha256-tlsprf.o |
| 413 | endif |
| 414 | +endif |
| 415 | ifdef NEED_TLS_PRF_SHA384 |
| 416 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 417 | OBJS += ../src/crypto/sha384-tlsprf.o |
| 418 | endif |
| 419 | +endif |
| 420 | ifdef NEED_HMAC_SHA256_KDF |
| 421 | +CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 422 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 423 | OBJS += ../src/crypto/sha256-kdf.o |
| 424 | endif |
| 425 | +endif |
| 426 | ifdef NEED_HMAC_SHA384_KDF |
| 427 | +CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 428 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 429 | OBJS += ../src/crypto/sha384-kdf.o |
| 430 | endif |
| 431 | +endif |
| 432 | ifdef NEED_HMAC_SHA512_KDF |
| 433 | +CFLAGS += -DCONFIG_HMAC_SHA512_KDF |
| 434 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 435 | OBJS += ../src/crypto/sha512-kdf.o |
| 436 | endif |
| 437 | +endif |
| 438 | ifdef NEED_SHA384 |
| 439 | CFLAGS += -DCONFIG_SHA384 |
| 440 | ifneq ($(CONFIG_TLS), openssl) |
| 441 | ifneq ($(CONFIG_TLS), linux) |
| 442 | ifneq ($(CONFIG_TLS), gnutls) |
| 443 | ifneq ($(CONFIG_TLS), wolfssl) |
| 444 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 445 | OBJS += ../src/crypto/sha384.o |
| 446 | endif |
| 447 | endif |
| 448 | endif |
| 449 | endif |
| 450 | +endif |
| 451 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 452 | OBJS += ../src/crypto/sha384-prf.o |
| 453 | endif |
| 454 | +endif |
| 455 | ifdef NEED_SHA512 |
| 456 | CFLAGS += -DCONFIG_SHA512 |
| 457 | ifneq ($(CONFIG_TLS), openssl) |
| 458 | ifneq ($(CONFIG_TLS), linux) |
| 459 | ifneq ($(CONFIG_TLS), gnutls) |
| 460 | ifneq ($(CONFIG_TLS), wolfssl) |
| 461 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 462 | OBJS += ../src/crypto/sha512.o |
| 463 | endif |
| 464 | endif |
| 465 | endif |
| 466 | endif |
| 467 | +endif |
| 468 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 469 | OBJS += ../src/crypto/sha512-prf.o |
| 470 | endif |
| 471 | +endif |
| 472 | |
| 473 | ifdef CONFIG_INTERNAL_SHA384 |
| 474 | CFLAGS += -DCONFIG_INTERNAL_SHA384 |
| 475 | @@ -1170,11 +1287,13 @@ HOBJS += $(SHA1OBJS) |
| 476 | ifneq ($(CONFIG_TLS), openssl) |
| 477 | ifneq ($(CONFIG_TLS), linux) |
| 478 | ifneq ($(CONFIG_TLS), wolfssl) |
| 479 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 480 | HOBJS += ../src/crypto/md5.o |
| 481 | endif |
| 482 | endif |
| 483 | endif |
| 484 | endif |
| 485 | +endif |
| 486 | |
| 487 | ifdef CONFIG_RADIUS_SERVER |
| 488 | CFLAGS += -DRADIUS_SERVER |
| 489 | @@ -1311,8 +1430,14 @@ install: $(addprefix $(DESTDIR)$(BINDIR)/,$(ALL)) |
| 490 | _OBJS_VAR := OBJS |
| 491 | include ../src/objs.mk |
| 492 | |
| 493 | +hostapd_multi.a: $(BCHECK) $(OBJS) |
| 494 | + $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c |
| 495 | + @$(E) " CC " $< |
| 496 | + @rm -f $@ |
| 497 | + @$(AR) cr $@ hostapd_multi.o $(OBJS) |
| 498 | + |
| 499 | hostapd: $(OBJS) |
| 500 | - $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) |
| 501 | + +$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) |
| 502 | @$(E) " LD " $@ |
| 503 | |
| 504 | ifdef CONFIG_WPA_TRACE |
| 505 | @@ -1323,7 +1448,7 @@ _OBJS_VAR := OBJS_c |
| 506 | include ../src/objs.mk |
| 507 | |
| 508 | hostapd_cli: $(OBJS_c) |
| 509 | - $(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) |
| 510 | + +$(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) |
| 511 | @$(E) " LD " $@ |
| 512 | |
| 513 | NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) |
| 514 | @@ -1347,7 +1472,9 @@ NOBJS += ../src/utils/trace.o |
| 515 | endif |
| 516 | |
| 517 | 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 |
| 518 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 519 | HOBJS += ../src/crypto/aes-encblock.o |
| 520 | +endif |
| 521 | ifdef CONFIG_INTERNAL_AES |
| 522 | HOBJS += ../src/crypto/aes-internal.o |
| 523 | HOBJS += ../src/crypto/aes-internal-enc.o |
| 524 | @@ -1370,13 +1497,17 @@ SOBJS += ../src/common/sae.o |
| 525 | SOBJS += ../src/common/sae_pk.o |
| 526 | SOBJS += ../src/common/dragonfly.o |
| 527 | SOBJS += $(AESOBJS) |
| 528 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 529 | SOBJS += ../src/crypto/sha256-prf.o |
| 530 | SOBJS += ../src/crypto/sha384-prf.o |
| 531 | SOBJS += ../src/crypto/sha512-prf.o |
| 532 | +endif |
| 533 | SOBJS += ../src/crypto/dh_groups.o |
| 534 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 535 | SOBJS += ../src/crypto/sha256-kdf.o |
| 536 | SOBJS += ../src/crypto/sha384-kdf.o |
| 537 | SOBJS += ../src/crypto/sha512-kdf.o |
| 538 | +endif |
| 539 | |
| 540 | _OBJS_VAR := NOBJS |
| 541 | include ../src/objs.mk |
| 542 | @@ -1385,6 +1516,12 @@ include ../src/objs.mk |
| 543 | _OBJS_VAR := SOBJS |
| 544 | include ../src/objs.mk |
| 545 | |
| 546 | +dump_cflags: |
| 547 | + @printf "%s " "$(CFLAGS)" |
| 548 | + |
| 549 | +dump_ldflags: |
| 550 | + @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" |
| 551 | + |
| 552 | nt_password_hash: $(NOBJS) |
| 553 | $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) |
| 554 | @$(E) " LD " $@ |
| 555 | diff --git a/hostapd/config_file.c b/hostapd/config_file.c |
| 556 | index 261905368..0094db279 100644 |
| 557 | --- a/hostapd/config_file.c |
| 558 | +++ b/hostapd/config_file.c |
| 559 | @@ -1229,6 +1229,8 @@ static int hostapd_config_vht_capab(struct hostapd_config *conf, |
| 560 | conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN; |
| 561 | if (os_strstr(capab, "[TX-ANTENNA-PATTERN]")) |
| 562 | conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN; |
| 563 | + if (os_strstr(capab, "[EXT-NSS-BW-SUPP]")) |
| 564 | + conf->vht_capab |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; |
| 565 | return 0; |
| 566 | } |
| 567 | #endif /* CONFIG_IEEE80211AC */ |
| 568 | @@ -1678,6 +1680,8 @@ static int parse_anqp_elem(struct hostapd_bss_config *bss, char *buf, int line) |
| 569 | return 0; |
| 570 | } |
| 571 | |
| 572 | +#endif /* CONFIG_INTERWORKING */ |
| 573 | + |
| 574 | |
| 575 | static int parse_qos_map_set(struct hostapd_bss_config *bss, |
| 576 | char *buf, int line) |
| 577 | @@ -1719,8 +1723,6 @@ static int parse_qos_map_set(struct hostapd_bss_config *bss, |
| 578 | return 0; |
| 579 | } |
| 580 | |
| 581 | -#endif /* CONFIG_INTERWORKING */ |
| 582 | - |
| 583 | |
| 584 | #ifdef CONFIG_HS20 |
| 585 | static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, |
| 586 | @@ -2630,8 +2632,12 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 587 | sizeof(conf->bss[0]->iface)); |
| 588 | } else if (os_strcmp(buf, "bridge") == 0) { |
| 589 | os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); |
| 590 | + if (!bss->wds_bridge[0]) |
| 591 | + os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); |
| 592 | } else if (os_strcmp(buf, "bridge_hairpin") == 0) { |
| 593 | bss->bridge_hairpin = atoi(pos); |
| 594 | + } else if (os_strcmp(buf, "snoop_iface") == 0) { |
| 595 | + os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); |
| 596 | } else if (os_strcmp(buf, "vlan_bridge") == 0) { |
| 597 | os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); |
| 598 | } else if (os_strcmp(buf, "wds_bridge") == 0) { |
| 599 | @@ -2998,6 +3004,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 600 | } else if (os_strcmp(buf, "iapp_interface") == 0) { |
| 601 | wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); |
| 602 | #endif /* CONFIG_IAPP */ |
| 603 | + } else if (os_strcmp(buf, "dynamic_own_ip_addr") == 0) { |
| 604 | + bss->dynamic_own_ip_addr = atoi(pos); |
| 605 | } else if (os_strcmp(buf, "own_ip_addr") == 0) { |
| 606 | if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) { |
| 607 | wpa_printf(MSG_ERROR, |
| 608 | @@ -3222,6 +3230,14 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 609 | line, bss->max_num_sta, MAX_STA_COUNT); |
| 610 | return 1; |
| 611 | } |
| 612 | + } else if (os_strcmp(buf, "iface_max_num_sta") == 0) { |
| 613 | + conf->max_num_sta = atoi(pos); |
| 614 | + if (conf->max_num_sta < 0 || |
| 615 | + conf->max_num_sta > MAX_STA_COUNT) { |
| 616 | + wpa_printf(MSG_ERROR, "Line %d: Invalid max_num_sta=%d; allowed range 0..%d", |
| 617 | + line, conf->max_num_sta, MAX_STA_COUNT); |
| 618 | + return 1; |
| 619 | + } |
| 620 | } else if (os_strcmp(buf, "wpa") == 0) { |
| 621 | bss->wpa = atoi(pos); |
| 622 | } else if (os_strcmp(buf, "extended_key_id") == 0) { |
| 623 | @@ -3373,6 +3389,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 624 | wpa_printf(MSG_INFO, |
| 625 | "Line %d: Obsolete peerkey parameter ignored", line); |
| 626 | #ifdef CONFIG_IEEE80211R_AP |
| 627 | + } else if (os_strcmp(buf, "ft_iface") == 0) { |
| 628 | + os_strlcpy(bss->ft_iface, pos, sizeof(bss->ft_iface)); |
| 629 | } else if (os_strcmp(buf, "mobility_domain") == 0) { |
| 630 | if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN || |
| 631 | hexstr2bin(pos, bss->mobility_domain, |
| 632 | @@ -3742,6 +3760,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 633 | #ifndef CONFIG_NO_VLAN |
| 634 | } else if (os_strcmp(buf, "dynamic_vlan") == 0) { |
| 635 | bss->ssid.dynamic_vlan = atoi(pos); |
| 636 | + } else if (os_strcmp(buf, "vlan_no_bridge") == 0) { |
| 637 | + bss->ssid.vlan_no_bridge = atoi(pos); |
| 638 | } else if (os_strcmp(buf, "per_sta_vif") == 0) { |
| 639 | bss->ssid.per_sta_vif = atoi(pos); |
| 640 | } else if (os_strcmp(buf, "vlan_file") == 0) { |
| 641 | @@ -3839,6 +3859,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 642 | if (bss->ocv && !bss->ieee80211w) |
| 643 | bss->ieee80211w = 1; |
| 644 | #endif /* CONFIG_OCV */ |
| 645 | + } else if (os_strcmp(buf, "noscan") == 0) { |
| 646 | + conf->noscan = atoi(pos); |
| 647 | + } else if (os_strcmp(buf, "ht_coex") == 0) { |
| 648 | + conf->no_ht_coex = !atoi(pos); |
| 649 | } else if (os_strcmp(buf, "ieee80211n") == 0) { |
| 650 | conf->ieee80211n = atoi(pos); |
| 651 | } else if (os_strcmp(buf, "ht_capab") == 0) { |
| 652 | @@ -3887,6 +3911,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 653 | } else if (os_strcmp(buf, "he_bss_color") == 0) { |
| 654 | conf->he_op.he_bss_color = atoi(pos) & 0x3f; |
| 655 | conf->he_op.he_bss_color_disabled = 0; |
| 656 | + if (atoi(pos) > 63) |
| 657 | + conf->he_op.he_bss_color = os_random() % 63 + 1; |
| 658 | } else if (os_strcmp(buf, "he_bss_color_partial") == 0) { |
| 659 | conf->he_op.he_bss_color_partial = atoi(pos); |
| 660 | } else if (os_strcmp(buf, "he_default_pe_duration") == 0) { |
| 661 | @@ -4520,10 +4546,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 662 | bss->gas_frag_limit = val; |
| 663 | } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { |
| 664 | bss->gas_comeback_delay = atoi(pos); |
| 665 | +#endif /* CONFIG_INTERWORKING */ |
| 666 | } else if (os_strcmp(buf, "qos_map_set") == 0) { |
| 667 | if (parse_qos_map_set(bss, pos, line) < 0) |
| 668 | return 1; |
| 669 | -#endif /* CONFIG_INTERWORKING */ |
| 670 | #ifdef CONFIG_RADIUS_TEST |
| 671 | } else if (os_strcmp(buf, "dump_msk_file") == 0) { |
| 672 | os_free(bss->dump_msk_file); |
| 673 | @@ -5347,7 +5373,12 @@ struct hostapd_config * hostapd_config_read(const char *fname) |
| 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 |
| 688 | index 10cb186f1..f76226cf4 100644 |
| 689 | --- a/hostapd/ctrl_iface.c |
| 690 | +++ b/hostapd/ctrl_iface.c |
| 691 | @@ -3876,6 +3876,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, |
| 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) { |
| 699 | @@ -3917,6 +3918,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, |
| 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; |
| 707 | @@ -5464,6 +5466,7 @@ try_again: |
| 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; |
| 715 | @@ -5565,6 +5568,7 @@ fail: |
| 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 |
| 759 | index a9d326de8..a469b1f4d 100644 |
| 760 | --- a/hostapd/hostapd_cli.c |
| 761 | +++ b/hostapd/hostapd_cli.c |
| 762 | @@ -401,7 +401,6 @@ static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, |
| 763 | } |
| 764 | |
| 765 | |
| 766 | -#ifdef CONFIG_TAXONOMY |
| 767 | static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, |
| 768 | char *argv[]) |
| 769 | { |
| 770 | @@ -414,7 +413,6 @@ static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, |
| 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, |
| 778 | @@ -431,7 +429,6 @@ static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, |
| 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 | { |
| 786 | @@ -657,7 +654,6 @@ static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc, |
| 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, |
| 794 | @@ -757,7 +753,7 @@ static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, |
| 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); |
| 803 | @@ -1670,13 +1666,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { |
| 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, |
| 817 | @@ -1701,7 +1694,6 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { |
| 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 |
| 826 | index 524a10274..0ccd4a5d7 100644 |
| 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, |
| 846 | @@ -690,6 +691,11 @@ fail: |
| 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) |
| 858 | @@ -781,6 +787,11 @@ int main(int argc, char *argv[]) |
| 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; |
| 870 | @@ -806,8 +817,10 @@ int main(int argc, char *argv[]) |
| 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) { |
| 882 | @@ -844,6 +857,8 @@ int main(int argc, char *argv[]) |
| 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': |
| 891 | @@ -1013,6 +1028,7 @@ int main(int argc, char *argv[]) |
| 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"); |
| 899 | @@ -1022,6 +1038,7 @@ int main(int argc, char *argv[]) |
| 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 |
| 908 | index 28b0ba71c..4c4c750ab 100644 |
| 909 | --- a/src/ap/acs.c |
| 910 | +++ b/src/ap/acs.c |
| 911 | @@ -467,17 +467,17 @@ static int acs_get_bw_center_chan(int freq, enum bw_type bw) |
| 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) && |
| 931 | @@ -485,7 +485,6 @@ static int acs_survey_is_sufficient(struct freq_survey *survey) |
| 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 |
| 973 | index 2330163c4..d10b00be9 100644 |
| 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; |
| 1000 | int acct_interim_interval; |
| 1001 | @@ -1064,6 +1068,8 @@ struct hostapd_config { |
| 1002 | unsigned int track_sta_max_num; |
| 1003 | unsigned int track_sta_max_age; |
| 1004 | |
| 1005 | + int max_num_sta; |
| 1006 | + |
| 1007 | char country[3]; /* first two octets: country code as described in |
| 1008 | * ISO/IEC 3166-1. Third octet: |
| 1009 | * ' ' (ascii 32): all environments |
| 1010 | @@ -1101,6 +1107,8 @@ struct hostapd_config { |
| 1011 | |
| 1012 | int ht_op_mode_fixed; |
| 1013 | u16 ht_capab; |
| 1014 | + int noscan; |
| 1015 | + int no_ht_coex; |
| 1016 | int ieee80211n; |
| 1017 | int secondary_channel; |
| 1018 | int no_pri_sec_switch; |
| 1019 | diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c |
| 1020 | index 32722084d..527b2c984 100644 |
| 1021 | --- a/src/ap/ap_drv_ops.c |
| 1022 | +++ b/src/ap/ap_drv_ops.c |
| 1023 | @@ -387,8 +387,6 @@ int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds, |
| 1024 | return -1; |
| 1025 | if (hapd->conf->wds_bridge[0]) |
| 1026 | bridge = hapd->conf->wds_bridge; |
| 1027 | - else if (hapd->conf->bridge[0]) |
| 1028 | - bridge = hapd->conf->bridge; |
| 1029 | return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val, |
| 1030 | bridge, ifname_wds); |
| 1031 | } |
| 1032 | @@ -1031,7 +1029,8 @@ int hostapd_start_dfs_cac(struct hostapd_iface *iface, |
| 1033 | int hostapd_drv_set_qos_map(struct hostapd_data *hapd, |
| 1034 | const u8 *qos_map_set, u8 qos_map_set_len) |
| 1035 | { |
| 1036 | - if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv) |
| 1037 | + if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv || |
| 1038 | + !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING)) |
| 1039 | return 0; |
| 1040 | return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set, |
| 1041 | qos_map_set_len); |
| 1042 | diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h |
| 1043 | index d7e79c840..f8a8725be 100644 |
| 1044 | --- a/src/ap/ap_drv_ops.h |
| 1045 | +++ b/src/ap/ap_drv_ops.h |
| 1046 | @@ -371,12 +371,12 @@ static inline int hostapd_drv_br_port_set_attr(struct hostapd_data *hapd, |
| 1047 | |
| 1048 | static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, |
| 1049 | enum drv_br_net_param param, |
| 1050 | - unsigned int val) |
| 1051 | + const char *ifname, unsigned int val) |
| 1052 | { |
| 1053 | if (hapd->driver == NULL || hapd->drv_priv == NULL || |
| 1054 | hapd->driver->br_set_net_param == NULL) |
| 1055 | return -1; |
| 1056 | - return hapd->driver->br_set_net_param(hapd->drv_priv, param, val); |
| 1057 | + return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val); |
| 1058 | } |
| 1059 | |
| 1060 | static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, |
| 1061 | @@ -404,6 +404,23 @@ static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd) |
| 1062 | return hapd->driver->stop_ap(hapd->drv_priv, link_id); |
| 1063 | } |
| 1064 | |
| 1065 | +static inline int hostapd_drv_if_rename(struct hostapd_data *hapd, |
| 1066 | + enum wpa_driver_if_type type, |
| 1067 | + const char *ifname, |
| 1068 | + const char *new_name) |
| 1069 | +{ |
| 1070 | + if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv) |
| 1071 | + return -1; |
| 1072 | + return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name); |
| 1073 | +} |
| 1074 | + |
| 1075 | +static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd) |
| 1076 | +{ |
| 1077 | + if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv) |
| 1078 | + return 0; |
| 1079 | + return hapd->driver->set_first_bss(hapd->drv_priv); |
| 1080 | +} |
| 1081 | + |
| 1082 | static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, |
| 1083 | struct wpa_channel_info *ci) |
| 1084 | { |
| 1085 | diff --git a/src/ap/beacon.c b/src/ap/beacon.c |
| 1086 | index 4354dfae3..26453cb2c 100644 |
| 1087 | --- a/src/ap/beacon.c |
| 1088 | +++ b/src/ap/beacon.c |
| 1089 | @@ -1343,6 +1343,12 @@ void handle_probe_req(struct hostapd_data *hapd, |
| 1090 | int mld_id; |
| 1091 | u16 links; |
| 1092 | #endif /* CONFIG_IEEE80211BE */ |
| 1093 | + struct hostapd_ubus_request req = { |
| 1094 | + .type = HOSTAPD_UBUS_PROBE_REQ, |
| 1095 | + .mgmt_frame = mgmt, |
| 1096 | + .ssi_signal = ssi_signal, |
| 1097 | + .elems = &elems, |
| 1098 | + }; |
| 1099 | |
| 1100 | if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && |
| 1101 | ssi_signal < hapd->iconf->rssi_ignore_probe_request) |
| 1102 | @@ -1529,6 +1535,12 @@ void handle_probe_req(struct hostapd_data *hapd, |
| 1103 | } |
| 1104 | #endif /* CONFIG_P2P */ |
| 1105 | |
| 1106 | + if (hostapd_ubus_handle_event(hapd, &req)) { |
| 1107 | + wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n", |
| 1108 | + MAC2STR(mgmt->sa)); |
| 1109 | + return; |
| 1110 | + } |
| 1111 | + |
| 1112 | /* TODO: verify that supp_rates contains at least one matching rate |
| 1113 | * with AP configuration */ |
| 1114 | |
| 1115 | @@ -1547,7 +1559,7 @@ void handle_probe_req(struct hostapd_data *hapd, |
| 1116 | if (hapd->conf->no_probe_resp_if_max_sta && |
| 1117 | is_multicast_ether_addr(mgmt->da) && |
| 1118 | is_multicast_ether_addr(mgmt->bssid) && |
| 1119 | - hapd->num_sta >= hapd->conf->max_num_sta && |
| 1120 | + hostapd_check_max_sta(hapd) && |
| 1121 | !ap_get_sta(hapd, mgmt->sa)) { |
| 1122 | wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR |
| 1123 | " since no room for additional STA", |
| 1124 | diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c |
| 1125 | index 2cfef4bd4..cd7db4fc6 100644 |
| 1126 | --- a/src/ap/ctrl_iface_ap.c |
| 1127 | +++ b/src/ap/ctrl_iface_ap.c |
| 1128 | @@ -26,6 +26,26 @@ |
| 1129 | #include "taxonomy.h" |
| 1130 | #include "wnm_ap.h" |
| 1131 | |
| 1132 | +static const char * hw_mode_str(enum hostapd_hw_mode mode) |
| 1133 | +{ |
| 1134 | + switch (mode) { |
| 1135 | + case HOSTAPD_MODE_IEEE80211B: |
| 1136 | + return "b"; |
| 1137 | + case HOSTAPD_MODE_IEEE80211G: |
| 1138 | + return "g"; |
| 1139 | + case HOSTAPD_MODE_IEEE80211A: |
| 1140 | + return "a"; |
| 1141 | + case HOSTAPD_MODE_IEEE80211AD: |
| 1142 | + return "ad"; |
| 1143 | + case HOSTAPD_MODE_IEEE80211ANY: |
| 1144 | + return "any"; |
| 1145 | + case NUM_HOSTAPD_MODES: |
| 1146 | + return "invalid"; |
| 1147 | + } |
| 1148 | + return "unknown"; |
| 1149 | +} |
| 1150 | + |
| 1151 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 1152 | |
| 1153 | static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen, |
| 1154 | size_t curr_len, const u8 *mcs_set) |
| 1155 | @@ -212,26 +232,6 @@ static const char * timeout_next_str(int val) |
| 1156 | } |
| 1157 | |
| 1158 | |
| 1159 | -static const char * hw_mode_str(enum hostapd_hw_mode mode) |
| 1160 | -{ |
| 1161 | - switch (mode) { |
| 1162 | - case HOSTAPD_MODE_IEEE80211B: |
| 1163 | - return "b"; |
| 1164 | - case HOSTAPD_MODE_IEEE80211G: |
| 1165 | - return "g"; |
| 1166 | - case HOSTAPD_MODE_IEEE80211A: |
| 1167 | - return "a"; |
| 1168 | - case HOSTAPD_MODE_IEEE80211AD: |
| 1169 | - return "ad"; |
| 1170 | - case HOSTAPD_MODE_IEEE80211ANY: |
| 1171 | - return "any"; |
| 1172 | - case NUM_HOSTAPD_MODES: |
| 1173 | - return "invalid"; |
| 1174 | - } |
| 1175 | - return "unknown"; |
| 1176 | -} |
| 1177 | - |
| 1178 | - |
| 1179 | static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd, |
| 1180 | struct sta_info *sta, |
| 1181 | char *buf, size_t buflen) |
| 1182 | @@ -539,6 +539,7 @@ int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr, |
| 1183 | return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); |
| 1184 | } |
| 1185 | |
| 1186 | +#endif |
| 1187 | |
| 1188 | #ifdef CONFIG_P2P_MANAGER |
| 1189 | static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, |
| 1190 | @@ -987,12 +988,12 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, |
| 1191 | return len; |
| 1192 | len += ret; |
| 1193 | } |
| 1194 | - |
| 1195 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 1196 | if (iface->conf->ieee80211n && !hapd->conf->disable_11n && mode) { |
| 1197 | len = hostapd_write_ht_mcs_bitmask(buf, buflen, len, |
| 1198 | mode->mcs_set); |
| 1199 | } |
| 1200 | - |
| 1201 | +#endif /* CONFIG_CTRL_IFACE_MIB */ |
| 1202 | if (iface->current_rates && iface->num_rates) { |
| 1203 | ret = os_snprintf(buf + len, buflen - len, "supported_rates="); |
| 1204 | if (os_snprintf_error(buflen - len, ret)) |
| 1205 | diff --git a/src/ap/dfs.c b/src/ap/dfs.c |
| 1206 | index fc2e8d83c..d14fad136 100644 |
| 1207 | --- a/src/ap/dfs.c |
| 1208 | +++ b/src/ap/dfs.c |
| 1209 | @@ -17,6 +17,7 @@ |
| 1210 | #include "ap_drv_ops.h" |
| 1211 | #include "drivers/driver.h" |
| 1212 | #include "dfs.h" |
| 1213 | +#include "crypto/crypto.h" |
| 1214 | |
| 1215 | |
| 1216 | enum dfs_channel_type { |
| 1217 | @@ -526,9 +527,14 @@ dfs_get_valid_channel(struct hostapd_iface *iface, |
| 1218 | int num_available_chandefs; |
| 1219 | int chan_idx, chan_idx2; |
| 1220 | int sec_chan_idx_80p80 = -1; |
| 1221 | + bool is_mesh = false; |
| 1222 | int i; |
| 1223 | u32 _rand; |
| 1224 | |
| 1225 | +#ifdef CONFIG_MESH |
| 1226 | + is_mesh = iface->mconf; |
| 1227 | +#endif |
| 1228 | + |
| 1229 | wpa_printf(MSG_DEBUG, "DFS: Selecting random channel"); |
| 1230 | *secondary_channel = 0; |
| 1231 | *oper_centr_freq_seg0_idx = 0; |
| 1232 | @@ -548,8 +554,20 @@ dfs_get_valid_channel(struct hostapd_iface *iface, |
| 1233 | if (num_available_chandefs == 0) |
| 1234 | return NULL; |
| 1235 | |
| 1236 | - if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) |
| 1237 | + /* try to use deterministic channel in mesh, so that both sides |
| 1238 | + * have a chance to switch to the same channel */ |
| 1239 | + if (is_mesh) { |
| 1240 | +#ifdef CONFIG_MESH |
| 1241 | + u64 hash[4]; |
| 1242 | + const u8 *meshid[1] = { &iface->mconf->meshid[0] }; |
| 1243 | + const size_t meshid_len = iface->mconf->meshid_len; |
| 1244 | + |
| 1245 | + sha256_vector(1, meshid, &meshid_len, (u8 *)&hash[0]); |
| 1246 | + _rand = hash[0] + hash[1] + hash[2] + hash[3]; |
| 1247 | +#endif |
| 1248 | + } else if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) |
| 1249 | return NULL; |
| 1250 | + |
| 1251 | chan_idx = _rand % num_available_chandefs; |
| 1252 | wpa_printf(MSG_DEBUG, "DFS: Picked random entry from the list: %d/%d", |
| 1253 | chan_idx, num_available_chandefs); |
| 1254 | @@ -1207,6 +1225,8 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq, |
| 1255 | "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", |
| 1256 | freq, ht_enabled, chan_offset, chan_width, cf1, cf2); |
| 1257 | |
| 1258 | + hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2); |
| 1259 | + |
| 1260 | /* Proceed only if DFS is not offloaded to the driver */ |
| 1261 | if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) |
| 1262 | return 0; |
| 1263 | diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c |
| 1264 | index dc21977ff..e8796f709 100644 |
| 1265 | --- a/src/ap/drv_callbacks.c |
| 1266 | +++ b/src/ap/drv_callbacks.c |
| 1267 | @@ -268,6 +268,10 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, |
| 1268 | struct hostapd_iface *iface = hapd->iface; |
| 1269 | #endif /* CONFIG_OWE */ |
| 1270 | bool updated = false; |
| 1271 | + struct hostapd_ubus_request req = { |
| 1272 | + .type = HOSTAPD_UBUS_ASSOC_REQ, |
| 1273 | + .addr = addr, |
| 1274 | + }; |
| 1275 | |
| 1276 | if (addr == NULL) { |
| 1277 | /* |
| 1278 | @@ -412,6 +416,12 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, |
| 1279 | goto fail; |
| 1280 | } |
| 1281 | |
| 1282 | + if (hostapd_ubus_handle_event(hapd, &req)) { |
| 1283 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", |
| 1284 | + MAC2STR(req.addr)); |
| 1285 | + goto fail; |
| 1286 | + } |
| 1287 | + |
| 1288 | #ifdef CONFIG_P2P |
| 1289 | if (elems.p2p) { |
| 1290 | wpabuf_free(sta->p2p_ie); |
| 1291 | @@ -2342,8 +2352,8 @@ static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst, |
| 1292 | ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack); |
| 1293 | } |
| 1294 | |
| 1295 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 1296 | - union wpa_event_data *data) |
| 1297 | +void hostapd_wpa_event(void *ctx, enum wpa_event_type event, |
| 1298 | + union wpa_event_data *data) |
| 1299 | { |
| 1300 | struct hostapd_data *hapd = ctx; |
| 1301 | struct sta_info *sta; |
| 1302 | @@ -2675,7 +2685,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 1303 | } |
| 1304 | |
| 1305 | |
| 1306 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 1307 | +void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, |
| 1308 | union wpa_event_data *data) |
| 1309 | { |
| 1310 | struct hapd_interfaces *interfaces = ctx; |
| 1311 | diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c |
| 1312 | index b899c9831..7959859b0 100644 |
| 1313 | --- a/src/ap/hostapd.c |
| 1314 | +++ b/src/ap/hostapd.c |
| 1315 | @@ -247,6 +247,29 @@ static int hostapd_iface_conf_changed(struct hostapd_config *newconf, |
| 1316 | return 0; |
| 1317 | } |
| 1318 | |
| 1319 | +static inline int hostapd_iface_num_sta(struct hostapd_iface *iface) |
| 1320 | +{ |
| 1321 | + int num_sta = 0; |
| 1322 | + int i; |
| 1323 | + |
| 1324 | + for (i = 0; i < iface->num_bss; i++) |
| 1325 | + num_sta += iface->bss[i]->num_sta; |
| 1326 | + |
| 1327 | + return num_sta; |
| 1328 | +} |
| 1329 | + |
| 1330 | + |
| 1331 | +int hostapd_check_max_sta(struct hostapd_data *hapd) |
| 1332 | +{ |
| 1333 | + if (hapd->num_sta >= hapd->conf->max_num_sta) |
| 1334 | + return 1; |
| 1335 | + |
| 1336 | + if (hapd->iconf->max_num_sta && |
| 1337 | + hostapd_iface_num_sta(hapd->iface) >= hapd->iconf->max_num_sta) |
| 1338 | + return 1; |
| 1339 | + |
| 1340 | + return 0; |
| 1341 | +} |
| 1342 | |
| 1343 | int hostapd_reload_config(struct hostapd_iface *iface) |
| 1344 | { |
| 1345 | @@ -255,6 +278,8 @@ int hostapd_reload_config(struct hostapd_iface *iface) |
| 1346 | struct hostapd_config *newconf, *oldconf; |
| 1347 | size_t j; |
| 1348 | |
| 1349 | + hostapd_ucode_reload_bss(hapd); |
| 1350 | + |
| 1351 | if (iface->config_fname == NULL) { |
| 1352 | /* Only in-memory config in use - assume it has been updated */ |
| 1353 | hostapd_clear_old(iface); |
| 1354 | @@ -475,6 +500,8 @@ void hostapd_free_hapd_data(struct hostapd_data *hapd) |
| 1355 | hapd->beacon_set_done = 0; |
| 1356 | |
| 1357 | wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); |
| 1358 | + hostapd_ucode_free_bss(hapd); |
| 1359 | + hostapd_ubus_free_bss(hapd); |
| 1360 | accounting_deinit(hapd); |
| 1361 | hostapd_deinit_wpa(hapd); |
| 1362 | vlan_deinit(hapd); |
| 1363 | @@ -685,6 +712,7 @@ static void sta_track_deinit(struct hostapd_iface *iface) |
| 1364 | void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) |
| 1365 | { |
| 1366 | wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); |
| 1367 | + eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); |
| 1368 | #ifdef NEED_AP_MLME |
| 1369 | hostapd_stop_setup_timers(iface); |
| 1370 | #endif /* NEED_AP_MLME */ |
| 1371 | @@ -714,7 +742,7 @@ void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) |
| 1372 | static void hostapd_cleanup_iface(struct hostapd_iface *iface) |
| 1373 | { |
| 1374 | wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); |
| 1375 | - eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); |
| 1376 | + hostapd_ucode_free_iface(iface); |
| 1377 | eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface, |
| 1378 | NULL); |
| 1379 | |
| 1380 | @@ -1303,6 +1331,9 @@ static int hostapd_start_beacon(struct hostapd_data *hapd, |
| 1381 | if (hapd->driver && hapd->driver->set_operstate) |
| 1382 | hapd->driver->set_operstate(hapd->drv_priv, 1); |
| 1383 | |
| 1384 | + hostapd_ubus_add_bss(hapd); |
| 1385 | + hostapd_ucode_add_bss(hapd); |
| 1386 | + |
| 1387 | return 0; |
| 1388 | } |
| 1389 | |
| 1390 | @@ -1324,8 +1355,7 @@ static int hostapd_start_beacon(struct hostapd_data *hapd, |
| 1391 | * initialized. Most of the modules that are initialized here will be |
| 1392 | * deinitialized in hostapd_cleanup(). |
| 1393 | */ |
| 1394 | -static int hostapd_setup_bss(struct hostapd_data *hapd, int first, |
| 1395 | - bool start_beacon) |
| 1396 | +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon) |
| 1397 | { |
| 1398 | struct hostapd_bss_config *conf = hapd->conf; |
| 1399 | u8 ssid[SSID_MAX_LEN + 1]; |
| 1400 | @@ -1552,6 +1582,7 @@ setup_mld: |
| 1401 | |
| 1402 | os_memset(&das_conf, 0, sizeof(das_conf)); |
| 1403 | das_conf.port = conf->radius_das_port; |
| 1404 | + das_conf.nas_identifier = conf->nas_identifier; |
| 1405 | das_conf.shared_secret = conf->radius_das_shared_secret; |
| 1406 | das_conf.shared_secret_len = |
| 1407 | conf->radius_das_shared_secret_len; |
| 1408 | @@ -1627,6 +1658,7 @@ setup_mld: |
| 1409 | wpa_printf(MSG_ERROR, "GAS server initialization failed"); |
| 1410 | return -1; |
| 1411 | } |
| 1412 | +#endif /* CONFIG_INTERWORKING */ |
| 1413 | |
| 1414 | if (conf->qos_map_set_len && |
| 1415 | hostapd_drv_set_qos_map(hapd, conf->qos_map_set, |
| 1416 | @@ -1634,7 +1666,6 @@ setup_mld: |
| 1417 | wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); |
| 1418 | return -1; |
| 1419 | } |
| 1420 | -#endif /* CONFIG_INTERWORKING */ |
| 1421 | |
| 1422 | if (conf->bss_load_update_period && bss_load_update_init(hapd)) { |
| 1423 | wpa_printf(MSG_ERROR, "BSS Load initialization failed"); |
| 1424 | @@ -2447,6 +2478,7 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface, |
| 1425 | if (err) |
| 1426 | goto fail; |
| 1427 | |
| 1428 | + hostapd_ubus_add_iface(iface); |
| 1429 | wpa_printf(MSG_DEBUG, "Completing interface initialization"); |
| 1430 | if (iface->freq) { |
| 1431 | #ifdef NEED_AP_MLME |
| 1432 | @@ -2676,6 +2708,7 @@ dfs_offload: |
| 1433 | |
| 1434 | fail: |
| 1435 | wpa_printf(MSG_ERROR, "Interface initialization failed"); |
| 1436 | + hostapd_ubus_free_iface(iface); |
| 1437 | |
| 1438 | if (iface->is_no_ir) { |
| 1439 | hostapd_set_state(iface, HAPD_IFACE_NO_IR); |
| 1440 | @@ -2875,7 +2908,7 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, |
| 1441 | } |
| 1442 | |
| 1443 | |
| 1444 | -static void hostapd_bss_deinit(struct hostapd_data *hapd) |
| 1445 | +void hostapd_bss_deinit(struct hostapd_data *hapd) |
| 1446 | { |
| 1447 | if (!hapd) |
| 1448 | return; |
| 1449 | @@ -3395,6 +3428,7 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface) |
| 1450 | (unsigned int) iface->conf->num_bss); |
| 1451 | driver = iface->bss[0]->driver; |
| 1452 | drv_priv = iface->bss[0]->drv_priv; |
| 1453 | + hostapd_ubus_free_iface(iface); |
| 1454 | hostapd_interface_deinit(iface); |
| 1455 | wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", |
| 1456 | __func__, driver, drv_priv); |
| 1457 | @@ -3926,7 +3960,8 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) |
| 1458 | hapd_iface = interfaces->iface[i]; |
| 1459 | if (hapd_iface == NULL) |
| 1460 | return -1; |
| 1461 | - if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { |
| 1462 | + if (!os_strcmp(hapd_iface->phy, buf) || |
| 1463 | + !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { |
| 1464 | wpa_printf(MSG_INFO, "Remove interface '%s'", buf); |
| 1465 | hapd_iface->driver_ap_teardown = |
| 1466 | !!(hapd_iface->drv_flags & |
| 1467 | @@ -3972,6 +4007,8 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) |
| 1468 | void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, |
| 1469 | int reassoc) |
| 1470 | { |
| 1471 | + int mld_assoc_link_id = -1; |
| 1472 | + |
| 1473 | if (hapd->tkip_countermeasures) { |
| 1474 | hostapd_drv_sta_deauth(hapd, sta->addr, |
| 1475 | WLAN_REASON_MICHAEL_MIC_FAILURE); |
| 1476 | @@ -3983,6 +4020,8 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, |
| 1477 | sta->mld_assoc_link_id != hapd->mld_link_id) |
| 1478 | return; |
| 1479 | #endif /* CONFIG_IEEE80211BE */ |
| 1480 | + if (mld_assoc_link_id != -2) |
| 1481 | + hostapd_prune_associations(hapd, sta->addr, mld_assoc_link_id); |
| 1482 | |
| 1483 | ap_sta_clear_disconnect_timeouts(hapd, sta); |
| 1484 | sta->post_csa_sa_query = 0; |
| 1485 | diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h |
| 1486 | index 594866fbb..1e4113459 100644 |
| 1487 | --- a/src/ap/hostapd.h |
| 1488 | +++ b/src/ap/hostapd.h |
| 1489 | @@ -13,11 +13,14 @@ |
| 1490 | #include <sqlite3.h> |
| 1491 | #endif /* CONFIG_SQLITE */ |
| 1492 | |
| 1493 | +#include "ap/sta_info.h" |
| 1494 | #include "common/defs.h" |
| 1495 | #include "common/dpp.h" |
| 1496 | #include "utils/list.h" |
| 1497 | #include "ap_config.h" |
| 1498 | #include "drivers/driver.h" |
| 1499 | +#include "ubus.h" |
| 1500 | +#include "ucode.h" |
| 1501 | |
| 1502 | #define OCE_STA_CFON_ENABLED(hapd) \ |
| 1503 | ((hapd->conf->oce & OCE_STA_CFON) && \ |
| 1504 | @@ -51,6 +54,10 @@ struct hapd_interfaces { |
| 1505 | struct hostapd_config * (*config_read_cb)(const char *config_fname); |
| 1506 | int (*ctrl_iface_init)(struct hostapd_data *hapd); |
| 1507 | void (*ctrl_iface_deinit)(struct hostapd_data *hapd); |
| 1508 | + int (*ctrl_iface_recv)(struct hostapd_data *hapd, |
| 1509 | + char *buf, char *reply, int reply_size, |
| 1510 | + struct sockaddr_storage *from, |
| 1511 | + socklen_t fromlen); |
| 1512 | int (*for_each_interface)(struct hapd_interfaces *interfaces, |
| 1513 | int (*cb)(struct hostapd_iface *iface, |
| 1514 | void *ctx), void *ctx); |
| 1515 | @@ -167,6 +174,21 @@ struct hostapd_sae_commit_queue { |
| 1516 | u8 msg[]; |
| 1517 | }; |
| 1518 | |
| 1519 | +/** |
| 1520 | + * struct hostapd_openwrt_stats - OpenWrt custom STA/AP statistics |
| 1521 | + */ |
| 1522 | +struct hostapd_openwrt_stats { |
| 1523 | + struct { |
| 1524 | + u64 neighbor_report_tx; |
| 1525 | + } rrm; |
| 1526 | + |
| 1527 | + struct { |
| 1528 | + u64 bss_transition_query_rx; |
| 1529 | + u64 bss_transition_request_tx; |
| 1530 | + u64 bss_transition_response_rx; |
| 1531 | + } wnm; |
| 1532 | +}; |
| 1533 | + |
| 1534 | /** |
| 1535 | * struct hostapd_data - hostapd per-BSS data structure |
| 1536 | */ |
| 1537 | @@ -174,6 +196,8 @@ struct hostapd_data { |
| 1538 | struct hostapd_iface *iface; |
| 1539 | struct hostapd_config *iconf; |
| 1540 | struct hostapd_bss_config *conf; |
| 1541 | + struct hostapd_ubus_bss ubus; |
| 1542 | + struct hostapd_ucode_bss ucode; |
| 1543 | int interface_added; /* virtual interface added for this BSS */ |
| 1544 | unsigned int started:1; |
| 1545 | unsigned int disabled:1; |
| 1546 | @@ -181,6 +205,9 @@ struct hostapd_data { |
| 1547 | |
| 1548 | u8 own_addr[ETH_ALEN]; |
| 1549 | |
| 1550 | + /* OpenWrt specific statistics */ |
| 1551 | + struct hostapd_openwrt_stats openwrt_stats; |
| 1552 | + |
| 1553 | int num_sta; /* number of entries in sta_list */ |
| 1554 | struct sta_info *sta_list; /* STA info list head */ |
| 1555 | #define STA_HASH_SIZE 256 |
| 1556 | @@ -523,6 +550,7 @@ struct hostapd_mld { |
| 1557 | */ |
| 1558 | struct hostapd_iface { |
| 1559 | struct hapd_interfaces *interfaces; |
| 1560 | + struct hostapd_ucode_iface ucode; |
| 1561 | void *owner; |
| 1562 | char *config_fname; |
| 1563 | struct hostapd_config *conf; |
| 1564 | @@ -745,6 +773,7 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, |
| 1565 | struct hostapd_bss_config *bss); |
| 1566 | int hostapd_setup_interface(struct hostapd_iface *iface); |
| 1567 | int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); |
| 1568 | +void hostapd_set_own_neighbor_report(struct hostapd_data *hapd); |
| 1569 | void hostapd_interface_deinit(struct hostapd_iface *iface); |
| 1570 | void hostapd_interface_free(struct hostapd_iface *iface); |
| 1571 | struct hostapd_iface * hostapd_alloc_iface(void); |
| 1572 | @@ -753,6 +782,8 @@ struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces, |
| 1573 | struct hostapd_iface * |
| 1574 | hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, |
| 1575 | const char *config_fname, int debug); |
| 1576 | +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon); |
| 1577 | +void hostapd_bss_deinit(struct hostapd_data *hapd); |
| 1578 | void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, |
| 1579 | int reassoc); |
| 1580 | void hostapd_interface_deinit_free(struct hostapd_iface *iface); |
| 1581 | @@ -780,6 +811,7 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd); |
| 1582 | void hostapd_periodic_iface(struct hostapd_iface *iface); |
| 1583 | int hostapd_owe_trans_get_info(struct hostapd_data *hapd); |
| 1584 | void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); |
| 1585 | +int hostapd_check_max_sta(struct hostapd_data *hapd); |
| 1586 | |
| 1587 | void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); |
| 1588 | void hostapd_cleanup_cca_params(struct hostapd_data *hapd); |
| 1589 | @@ -865,4 +897,14 @@ static inline bool hostapd_mld_is_first_bss(struct hostapd_data *hapd) |
| 1590 | |
| 1591 | u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd); |
| 1592 | |
| 1593 | +static inline bool ap_sta_is_mld(struct hostapd_data *hapd, |
| 1594 | + struct sta_info *sta) |
| 1595 | +{ |
| 1596 | +#ifdef CONFIG_IEEE80211BE |
| 1597 | + return hapd->conf->mld_ap && sta && sta->mld_info.mld_sta; |
| 1598 | +#else /* CONFIG_IEEE80211BE */ |
| 1599 | + return false; |
| 1600 | +#endif /* CONFIG_IEEE80211BE */ |
| 1601 | +} |
| 1602 | + |
| 1603 | #endif /* HOSTAPD_H */ |
| 1604 | diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c |
| 1605 | index 222f3dc05..672e43a10 100644 |
| 1606 | --- a/src/ap/hw_features.c |
| 1607 | +++ b/src/ap/hw_features.c |
| 1608 | @@ -546,7 +546,8 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface) |
| 1609 | int ret; |
| 1610 | |
| 1611 | /* Check that HT40 is used and PRI / SEC switch is allowed */ |
| 1612 | - if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch) |
| 1613 | + if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || |
| 1614 | + iface->conf->noscan) |
| 1615 | return 0; |
| 1616 | |
| 1617 | hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); |
| 1618 | diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c |
| 1619 | index 179af5e28..bda61b998 100644 |
| 1620 | --- a/src/ap/ieee802_11.c |
| 1621 | +++ b/src/ap/ieee802_11.c |
| 1622 | @@ -2804,7 +2804,7 @@ static void handle_auth(struct hostapd_data *hapd, |
| 1623 | u16 auth_alg, auth_transaction, status_code; |
| 1624 | u16 resp = WLAN_STATUS_SUCCESS; |
| 1625 | struct sta_info *sta = NULL; |
| 1626 | - int res, reply_res; |
| 1627 | + int res, reply_res, ubus_resp; |
| 1628 | u16 fc; |
| 1629 | const u8 *challenge = NULL; |
| 1630 | u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; |
| 1631 | @@ -2815,6 +2815,11 @@ static void handle_auth(struct hostapd_data *hapd, |
| 1632 | #ifdef CONFIG_IEEE80211BE |
| 1633 | bool mld_sta = false; |
| 1634 | #endif /* CONFIG_IEEE80211BE */ |
| 1635 | + struct hostapd_ubus_request req = { |
| 1636 | + .type = HOSTAPD_UBUS_AUTH_REQ, |
| 1637 | + .mgmt_frame = mgmt, |
| 1638 | + .ssi_signal = rssi, |
| 1639 | + }; |
| 1640 | |
| 1641 | if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { |
| 1642 | wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", |
| 1643 | @@ -3008,6 +3013,13 @@ static void handle_auth(struct hostapd_data *hapd, |
| 1644 | resp = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 1645 | goto fail; |
| 1646 | } |
| 1647 | + ubus_resp = hostapd_ubus_handle_event(hapd, &req); |
| 1648 | + if (ubus_resp) { |
| 1649 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n", |
| 1650 | + MAC2STR(mgmt->sa)); |
| 1651 | + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 1652 | + goto fail; |
| 1653 | + } |
| 1654 | if (res == HOSTAPD_ACL_PENDING) |
| 1655 | return; |
| 1656 | |
| 1657 | @@ -3042,15 +3054,6 @@ static void handle_auth(struct hostapd_data *hapd, |
| 1658 | seq_ctrl); |
| 1659 | return; |
| 1660 | } |
| 1661 | -#ifdef CONFIG_MESH |
| 1662 | - if ((hapd->conf->mesh & MESH_ENABLED) && |
| 1663 | - sta->plink_state == PLINK_BLOCKED) { |
| 1664 | - wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR |
| 1665 | - " is blocked - drop Authentication frame", |
| 1666 | - MAC2STR(sa)); |
| 1667 | - return; |
| 1668 | - } |
| 1669 | -#endif /* CONFIG_MESH */ |
| 1670 | #ifdef CONFIG_PASN |
| 1671 | if (auth_alg == WLAN_AUTH_PASN && |
| 1672 | (sta->flags & WLAN_STA_ASSOC)) { |
| 1673 | @@ -4698,6 +4701,13 @@ static int add_associated_sta(struct hostapd_data *hapd, |
| 1674 | * drivers to accept the STA parameter configuration. Since this is |
| 1675 | * after a new FT-over-DS exchange, a new TK has been derived, so key |
| 1676 | * reinstallation is not a concern for this case. |
| 1677 | + * |
| 1678 | + * If the STA was associated and authorized earlier, but came for a new |
| 1679 | + * connection (!added_unassoc + !reassoc), remove the existing STA entry |
| 1680 | + * so that it can be re-added. This case is rarely seen when the AP could |
| 1681 | + * not receive the deauth/disassoc frame from the STA. And the STA comes |
| 1682 | + * back with new connection within a short period or before the inactive |
| 1683 | + * STA entry is removed from the list. |
| 1684 | */ |
| 1685 | wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR |
| 1686 | " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", |
| 1687 | @@ -4711,7 +4721,8 @@ static int add_associated_sta(struct hostapd_data *hapd, |
| 1688 | (!(sta->flags & WLAN_STA_AUTHORIZED) || |
| 1689 | (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || |
| 1690 | (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && |
| 1691 | - !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) { |
| 1692 | + !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)) || |
| 1693 | + (!reassoc && (sta->flags & WLAN_STA_AUTHORIZED)))) { |
| 1694 | hostapd_drv_sta_remove(hapd, sta->addr); |
| 1695 | wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED); |
| 1696 | set = 0; |
| 1697 | @@ -5273,7 +5284,7 @@ static void handle_assoc(struct hostapd_data *hapd, |
| 1698 | int resp = WLAN_STATUS_SUCCESS; |
| 1699 | u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 1700 | const u8 *pos; |
| 1701 | - int left, i; |
| 1702 | + int left, i, ubus_resp; |
| 1703 | struct sta_info *sta; |
| 1704 | u8 *tmp = NULL; |
| 1705 | #ifdef CONFIG_FILS |
| 1706 | @@ -5515,6 +5526,11 @@ static void handle_assoc(struct hostapd_data *hapd, |
| 1707 | left = res; |
| 1708 | } |
| 1709 | #endif /* CONFIG_FILS */ |
| 1710 | + struct hostapd_ubus_request req = { |
| 1711 | + .type = HOSTAPD_UBUS_ASSOC_REQ, |
| 1712 | + .mgmt_frame = mgmt, |
| 1713 | + .ssi_signal = rssi, |
| 1714 | + }; |
| 1715 | |
| 1716 | /* followed by SSID and Supported rates; and HT capabilities if 802.11n |
| 1717 | * is used */ |
| 1718 | @@ -5617,6 +5633,13 @@ static void handle_assoc(struct hostapd_data *hapd, |
| 1719 | if (set_beacon) |
| 1720 | ieee802_11_set_beacons(hapd->iface); |
| 1721 | |
| 1722 | + ubus_resp = hostapd_ubus_handle_event(hapd, &req); |
| 1723 | + if (ubus_resp) { |
| 1724 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", |
| 1725 | + MAC2STR(mgmt->sa)); |
| 1726 | + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 1727 | + goto fail; |
| 1728 | + } |
| 1729 | fail: |
| 1730 | |
| 1731 | /* |
| 1732 | @@ -5848,6 +5871,7 @@ static void handle_disassoc(struct hostapd_data *hapd, |
| 1733 | (unsigned long) len); |
| 1734 | return; |
| 1735 | } |
| 1736 | + hostapd_ubus_notify(hapd, "disassoc", mgmt->sa); |
| 1737 | |
| 1738 | sta = ap_get_sta(hapd, mgmt->sa); |
| 1739 | if (!sta) { |
| 1740 | @@ -5879,6 +5903,8 @@ static void handle_deauth(struct hostapd_data *hapd, |
| 1741 | /* Clear the PTKSA cache entries for PASN */ |
| 1742 | ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); |
| 1743 | |
| 1744 | + hostapd_ubus_notify(hapd, "deauth", mgmt->sa); |
| 1745 | + |
| 1746 | sta = ap_get_sta(hapd, mgmt->sa); |
| 1747 | if (!sta) { |
| 1748 | wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR |
| 1749 | diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c |
| 1750 | index f90f1254e..7f0a00f95 100644 |
| 1751 | --- a/src/ap/ieee802_11_ht.c |
| 1752 | +++ b/src/ap/ieee802_11_ht.c |
| 1753 | @@ -82,7 +82,9 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid) |
| 1754 | u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) |
| 1755 | { |
| 1756 | struct ieee80211_ht_operation *oper; |
| 1757 | + le32 vht_capabilities_info; |
| 1758 | u8 *pos = eid; |
| 1759 | + u8 chwidth; |
| 1760 | |
| 1761 | if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n || |
| 1762 | is_6ghz_op_class(hapd->iconf->op_class)) |
| 1763 | @@ -103,6 +105,13 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) |
| 1764 | oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | |
| 1765 | HT_INFO_HT_PARAM_STA_CHNL_WIDTH; |
| 1766 | |
| 1767 | + vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); |
| 1768 | + chwidth = hostapd_get_oper_chwidth(hapd->iconf); |
| 1769 | + if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT |
| 1770 | + && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { |
| 1771 | + oper->operation_mode = host_to_le16(hapd->iconf->vht_oper_centr_freq_seg0_idx << 5); |
| 1772 | + } |
| 1773 | + |
| 1774 | pos += sizeof(*oper); |
| 1775 | |
| 1776 | return pos; |
| 1777 | @@ -230,6 +239,9 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd, |
| 1778 | return; |
| 1779 | } |
| 1780 | |
| 1781 | + if (iface->conf->noscan || iface->conf->no_ht_coex) |
| 1782 | + return; |
| 1783 | + |
| 1784 | if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) { |
| 1785 | wpa_printf(MSG_DEBUG, |
| 1786 | "Ignore too short 20/40 BSS Coexistence Management frame"); |
| 1787 | @@ -390,6 +402,9 @@ void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta) |
| 1788 | if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) |
| 1789 | return; |
| 1790 | |
| 1791 | + if (iface->conf->noscan || iface->conf->no_ht_coex) |
| 1792 | + return; |
| 1793 | + |
| 1794 | wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR |
| 1795 | " in Association Request", MAC2STR(sta->addr)); |
| 1796 | |
| 1797 | diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c |
| 1798 | index a5716f037..85790c7ed 100644 |
| 1799 | --- a/src/ap/ieee802_11_shared.c |
| 1800 | +++ b/src/ap/ieee802_11_shared.c |
| 1801 | @@ -1138,13 +1138,11 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len) |
| 1802 | u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, |
| 1803 | const u8 *ext_capab_ie, size_t ext_capab_ie_len) |
| 1804 | { |
| 1805 | -#ifdef CONFIG_INTERWORKING |
| 1806 | /* check for QoS Map support */ |
| 1807 | if (ext_capab_ie_len >= 5) { |
| 1808 | if (ext_capab_ie[4] & 0x01) |
| 1809 | sta->qos_map_enabled = 1; |
| 1810 | } |
| 1811 | -#endif /* CONFIG_INTERWORKING */ |
| 1812 | |
| 1813 | if (ext_capab_ie_len > 0) { |
| 1814 | sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2)); |
| 1815 | diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c |
| 1816 | index 4dc325ce8..68880ab64 100644 |
| 1817 | --- a/src/ap/ieee802_11_vht.c |
| 1818 | +++ b/src/ap/ieee802_11_vht.c |
| 1819 | @@ -26,6 +26,7 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts) |
| 1820 | struct ieee80211_vht_capabilities *cap; |
| 1821 | struct hostapd_hw_modes *mode = hapd->iface->current_mode; |
| 1822 | u8 *pos = eid; |
| 1823 | + u8 chwidth; |
| 1824 | |
| 1825 | if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) |
| 1826 | return eid; |
| 1827 | @@ -63,6 +64,17 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts) |
| 1828 | host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET); |
| 1829 | } |
| 1830 | |
| 1831 | + chwidth = hostapd_get_oper_chwidth(hapd->iconf); |
| 1832 | + if (((host_to_le32(mode->vht_capab)) & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) |
| 1833 | + && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { |
| 1834 | + cap->vht_capabilities_info |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; |
| 1835 | + cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)); |
| 1836 | + cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)); |
| 1837 | + cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_MASK)); |
| 1838 | + } else { |
| 1839 | + cap->vht_capabilities_info &= ~VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK; |
| 1840 | + } |
| 1841 | + |
| 1842 | /* Supported MCS set comes from hw */ |
| 1843 | os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8); |
| 1844 | |
| 1845 | @@ -75,6 +87,7 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts) |
| 1846 | u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) |
| 1847 | { |
| 1848 | struct ieee80211_vht_operation *oper; |
| 1849 | + le32 vht_capabilities_info; |
| 1850 | u8 *pos = eid; |
| 1851 | enum oper_chan_width oper_chwidth = |
| 1852 | hostapd_get_oper_chwidth(hapd->iconf); |
| 1853 | @@ -110,6 +123,7 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) |
| 1854 | oper->vht_op_info_chan_center_freq_seg1_idx = seg1; |
| 1855 | |
| 1856 | oper->vht_op_info_chwidth = oper_chwidth; |
| 1857 | + vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); |
| 1858 | if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ) { |
| 1859 | /* |
| 1860 | * Convert 160 MHz channel width to new style as interop |
| 1861 | @@ -123,6 +137,9 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) |
| 1862 | oper->vht_op_info_chan_center_freq_seg0_idx -= 8; |
| 1863 | else |
| 1864 | oper->vht_op_info_chan_center_freq_seg0_idx += 8; |
| 1865 | + |
| 1866 | + if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) |
| 1867 | + oper->vht_op_info_chan_center_freq_seg1_idx = 0; |
| 1868 | } else if (oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ) { |
| 1869 | /* |
| 1870 | * Convert 80+80 MHz channel width to new style as interop |
| 1871 | diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c |
| 1872 | index 8e98b6521..8abebbf34 100644 |
| 1873 | --- a/src/ap/ieee802_1x.c |
| 1874 | +++ b/src/ap/ieee802_1x.c |
| 1875 | @@ -600,6 +600,10 @@ int add_common_radius_attr(struct hostapd_data *hapd, |
| 1876 | struct hostapd_radius_attr *attr; |
| 1877 | int len; |
| 1878 | |
| 1879 | + if (hapd->conf->dynamic_own_ip_addr) |
| 1880 | + radius_client_get_local_addr(hapd->radius, |
| 1881 | + &hapd->conf->own_ip_addr); |
| 1882 | + |
| 1883 | if (!hostapd_config_get_radius_attr(req_attr, |
| 1884 | RADIUS_ATTR_NAS_IP_ADDRESS) && |
| 1885 | hapd->conf->own_ip_addr.af == AF_INET && |
| 1886 | @@ -2845,6 +2849,7 @@ static const char * bool_txt(bool val) |
| 1887 | return val ? "TRUE" : "FALSE"; |
| 1888 | } |
| 1889 | |
| 1890 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 1891 | |
| 1892 | int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) |
| 1893 | { |
| 1894 | @@ -3031,6 +3036,7 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, |
| 1895 | return len; |
| 1896 | } |
| 1897 | |
| 1898 | +#endif |
| 1899 | |
| 1900 | #ifdef CONFIG_HS20 |
| 1901 | static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) |
| 1902 | diff --git a/src/ap/ndisc_snoop.c b/src/ap/ndisc_snoop.c |
| 1903 | index 788c12fdc..bc1eb6251 100644 |
| 1904 | --- a/src/ap/ndisc_snoop.c |
| 1905 | +++ b/src/ap/ndisc_snoop.c |
| 1906 | @@ -61,6 +61,7 @@ void sta_ip6addr_del(struct hostapd_data *hapd, struct sta_info *sta) |
| 1907 | dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr, |
| 1908 | list) { |
| 1909 | hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr); |
| 1910 | + dl_list_del(&ip6addr->list); |
| 1911 | os_free(ip6addr); |
| 1912 | } |
| 1913 | } |
| 1914 | diff --git a/src/ap/rrm.c b/src/ap/rrm.c |
| 1915 | index f2d5cd16e..8220590a0 100644 |
| 1916 | --- a/src/ap/rrm.c |
| 1917 | +++ b/src/ap/rrm.c |
| 1918 | @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report(struct hostapd_data *hapd, |
| 1919 | return; |
| 1920 | wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", |
| 1921 | MAC2STR(addr), token, rep_mode, report); |
| 1922 | + if (len < sizeof(struct rrm_measurement_beacon_report)) |
| 1923 | + return; |
| 1924 | + hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len); |
| 1925 | } |
| 1926 | |
| 1927 | |
| 1928 | @@ -269,6 +272,8 @@ static void hostapd_send_nei_report_resp(struct hostapd_data *hapd, |
| 1929 | } |
| 1930 | } |
| 1931 | |
| 1932 | + hapd->openwrt_stats.rrm.neighbor_report_tx++; |
| 1933 | + |
| 1934 | hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, |
| 1935 | wpabuf_head(buf), wpabuf_len(buf)); |
| 1936 | wpabuf_free(buf); |
| 1937 | @@ -350,6 +355,9 @@ void hostapd_handle_radio_measurement(struct hostapd_data *hapd, |
| 1938 | mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa)); |
| 1939 | |
| 1940 | switch (mgmt->u.action.u.rrm.action) { |
| 1941 | + case WLAN_RRM_LINK_MEASUREMENT_REPORT: |
| 1942 | + hostapd_ubus_handle_link_measurement(hapd, buf, len); |
| 1943 | + break; |
| 1944 | case WLAN_RRM_RADIO_MEASUREMENT_REPORT: |
| 1945 | hostapd_handle_radio_msmt_report(hapd, buf, len); |
| 1946 | break; |
| 1947 | diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c |
| 1948 | index d483aa9d3..ee6e20538 100644 |
| 1949 | --- a/src/ap/sta_info.c |
| 1950 | +++ b/src/ap/sta_info.c |
| 1951 | @@ -539,6 +539,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) |
| 1952 | hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, |
| 1953 | HOSTAPD_LEVEL_INFO, "deauthenticated due to " |
| 1954 | "local deauth request"); |
| 1955 | + hostapd_ubus_notify(hapd, "local-deauth", sta->addr); |
| 1956 | ap_free_sta(hapd, sta); |
| 1957 | return; |
| 1958 | } |
| 1959 | @@ -694,6 +695,7 @@ skip_poll: |
| 1960 | mlme_deauthenticate_indication( |
| 1961 | hapd, sta, |
| 1962 | WLAN_REASON_PREV_AUTH_NOT_VALID); |
| 1963 | + hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr); |
| 1964 | ap_free_sta(hapd, sta); |
| 1965 | break; |
| 1966 | } |
| 1967 | @@ -1476,9 +1478,6 @@ bool ap_sta_set_authorized_flag(struct hostapd_data *hapd, struct sta_info *sta, |
| 1968 | mld_assoc_link_id = -2; |
| 1969 | } |
| 1970 | #endif /* CONFIG_IEEE80211BE */ |
| 1971 | - if (mld_assoc_link_id != -2) |
| 1972 | - hostapd_prune_associations(hapd, sta->addr, |
| 1973 | - mld_assoc_link_id); |
| 1974 | sta->flags |= WLAN_STA_AUTHORIZED; |
| 1975 | } else { |
| 1976 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
| 1977 | @@ -1515,15 +1514,28 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd, |
| 1978 | os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); |
| 1979 | |
| 1980 | if (authorized) { |
| 1981 | + static const char * const auth_algs[] = { |
| 1982 | + [WLAN_AUTH_OPEN] = "open", |
| 1983 | + [WLAN_AUTH_SHARED_KEY] = "shared", |
| 1984 | + [WLAN_AUTH_FT] = "ft", |
| 1985 | + [WLAN_AUTH_SAE] = "sae", |
| 1986 | + [WLAN_AUTH_FILS_SK] = "fils-sk", |
| 1987 | + [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", |
| 1988 | + [WLAN_AUTH_FILS_PK] = "fils-pk", |
| 1989 | + [WLAN_AUTH_PASN] = "pasn", |
| 1990 | + }; |
| 1991 | + const char *auth_alg = NULL; |
| 1992 | const u8 *dpp_pkhash; |
| 1993 | const char *keyid; |
| 1994 | char dpp_pkhash_buf[100]; |
| 1995 | char keyid_buf[100]; |
| 1996 | char ip_addr[100]; |
| 1997 | + char alg_buf[100]; |
| 1998 | |
| 1999 | dpp_pkhash_buf[0] = '\0'; |
| 2000 | keyid_buf[0] = '\0'; |
| 2001 | ip_addr[0] = '\0'; |
| 2002 | + alg_buf[0] = '\0'; |
| 2003 | #ifdef CONFIG_P2P |
| 2004 | if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { |
| 2005 | os_snprintf(ip_addr, sizeof(ip_addr), |
| 2006 | @@ -1534,6 +1546,13 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd, |
| 2007 | } |
| 2008 | #endif /* CONFIG_P2P */ |
| 2009 | |
| 2010 | + if (sta->auth_alg < ARRAY_SIZE(auth_algs)) |
| 2011 | + auth_alg = auth_algs[sta->auth_alg]; |
| 2012 | + |
| 2013 | + if (auth_alg) |
| 2014 | + os_snprintf(alg_buf, sizeof(alg_buf), |
| 2015 | + " auth_alg=%s", auth_alg); |
| 2016 | + |
| 2017 | keyid = ap_sta_wpa_get_keyid(hapd, sta); |
| 2018 | if (keyid) { |
| 2019 | os_snprintf(keyid_buf, sizeof(keyid_buf), |
| 2020 | @@ -1552,17 +1571,19 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd, |
| 2021 | dpp_pkhash, SHA256_MAC_LEN); |
| 2022 | } |
| 2023 | |
| 2024 | - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", |
| 2025 | - buf, ip_addr, keyid_buf, dpp_pkhash_buf); |
| 2026 | + hostapd_ubus_notify_authorized(hapd, sta, auth_alg); |
| 2027 | + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s", |
| 2028 | + buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf); |
| 2029 | |
| 2030 | if (hapd->msg_ctx_parent && |
| 2031 | hapd->msg_ctx_parent != hapd->msg_ctx) |
| 2032 | wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, |
| 2033 | - AP_STA_CONNECTED "%s%s%s%s", |
| 2034 | + AP_STA_CONNECTED "%s%s%s%s%s", |
| 2035 | buf, ip_addr, keyid_buf, |
| 2036 | - dpp_pkhash_buf); |
| 2037 | + dpp_pkhash_buf, alg_buf); |
| 2038 | } else { |
| 2039 | wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); |
| 2040 | + hostapd_ubus_notify(hapd, "disassoc", sta->addr); |
| 2041 | |
| 2042 | if (hapd->msg_ctx_parent && |
| 2043 | hapd->msg_ctx_parent != hapd->msg_ctx) |
| 2044 | diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h |
| 2045 | index 153e4a000..38b80903d 100644 |
| 2046 | --- a/src/ap/sta_info.h |
| 2047 | +++ b/src/ap/sta_info.h |
| 2048 | @@ -17,7 +17,6 @@ |
| 2049 | #include "common/sae.h" |
| 2050 | #include "crypto/sha384.h" |
| 2051 | #include "pasn/pasn_common.h" |
| 2052 | -#include "hostapd.h" |
| 2053 | |
| 2054 | /* STA flags */ |
| 2055 | #define WLAN_STA_AUTH BIT(0) |
| 2056 | @@ -323,6 +322,7 @@ struct sta_info { |
| 2057 | #endif /* CONFIG_TESTING_OPTIONS */ |
| 2058 | #ifdef CONFIG_AIRTIME_POLICY |
| 2059 | unsigned int airtime_weight; |
| 2060 | + unsigned int dyn_airtime_weight; |
| 2061 | struct os_reltime backlogged_until; |
| 2062 | #endif /* CONFIG_AIRTIME_POLICY */ |
| 2063 | |
| 2064 | @@ -420,16 +420,6 @@ int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta); |
| 2065 | |
| 2066 | void ap_free_sta_pasn(struct hostapd_data *hapd, struct sta_info *sta); |
| 2067 | |
| 2068 | -static inline bool ap_sta_is_mld(struct hostapd_data *hapd, |
| 2069 | - struct sta_info *sta) |
| 2070 | -{ |
| 2071 | -#ifdef CONFIG_IEEE80211BE |
| 2072 | - return hapd->conf->mld_ap && sta && sta->mld_info.mld_sta; |
| 2073 | -#else /* CONFIG_IEEE80211BE */ |
| 2074 | - return false; |
| 2075 | -#endif /* CONFIG_IEEE80211BE */ |
| 2076 | -} |
| 2077 | - |
| 2078 | static inline void ap_sta_set_mld(struct sta_info *sta, bool mld) |
| 2079 | { |
| 2080 | #ifdef CONFIG_IEEE80211BE |
| 2081 | diff --git a/src/ap/vlan_full.c b/src/ap/vlan_full.c |
| 2082 | index 19aa3c649..053d6338e 100644 |
| 2083 | --- a/src/ap/vlan_full.c |
| 2084 | +++ b/src/ap/vlan_full.c |
| 2085 | @@ -475,6 +475,9 @@ void vlan_newlink(const char *ifname, struct hostapd_data *hapd) |
| 2086 | if (!vlan) |
| 2087 | return; |
| 2088 | |
| 2089 | + if (hapd->conf->ssid.vlan_no_bridge) |
| 2090 | + goto out; |
| 2091 | + |
| 2092 | vlan->configured = 1; |
| 2093 | |
| 2094 | notempty = vlan->vlan_desc.notempty; |
| 2095 | @@ -506,6 +509,7 @@ void vlan_newlink(const char *ifname, struct hostapd_data *hapd) |
| 2096 | ifname, br_name, tagged[i], hapd); |
| 2097 | } |
| 2098 | |
| 2099 | +out: |
| 2100 | ifconfig_up(ifname); |
| 2101 | } |
| 2102 | |
| 2103 | diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c |
| 2104 | index 53eacfb45..b69f3de41 100644 |
| 2105 | --- a/src/ap/vlan_init.c |
| 2106 | +++ b/src/ap/vlan_init.c |
| 2107 | @@ -22,6 +22,7 @@ |
| 2108 | static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |
| 2109 | int existsok) |
| 2110 | { |
| 2111 | + bool vlan_exists = iface_exists(vlan->ifname); |
| 2112 | int ret; |
| 2113 | #ifdef CONFIG_WEP |
| 2114 | int i; |
| 2115 | @@ -36,7 +37,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |
| 2116 | } |
| 2117 | #endif /* CONFIG_WEP */ |
| 2118 | |
| 2119 | - if (!iface_exists(vlan->ifname)) |
| 2120 | + if (!vlan_exists) |
| 2121 | ret = hostapd_vlan_if_add(hapd, vlan->ifname); |
| 2122 | else if (!existsok) |
| 2123 | return -1; |
| 2124 | @@ -51,6 +52,9 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |
| 2125 | if (hapd->wpa_auth) |
| 2126 | ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); |
| 2127 | |
| 2128 | + if (!ret && !vlan_exists) |
| 2129 | + hostapd_ubus_add_vlan(hapd, vlan); |
| 2130 | + |
| 2131 | if (ret == 0) |
| 2132 | return ret; |
| 2133 | |
| 2134 | @@ -77,6 +81,8 @@ int vlan_if_remove(struct hostapd_data *hapd, struct hostapd_vlan *vlan) |
| 2135 | "WPA deinitialization for VLAN %d failed (%d)", |
| 2136 | vlan->vlan_id, ret); |
| 2137 | |
| 2138 | + hostapd_ubus_remove_vlan(hapd, vlan); |
| 2139 | + |
| 2140 | return hostapd_vlan_if_remove(hapd, vlan->ifname); |
| 2141 | } |
| 2142 | |
| 2143 | diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c |
| 2144 | index af8cccaef..d259200c9 100644 |
| 2145 | --- a/src/ap/wnm_ap.c |
| 2146 | +++ b/src/ap/wnm_ap.c |
| 2147 | @@ -410,6 +410,7 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd, |
| 2148 | mgmt->u.action.u.bss_tm_req.validity_interval = 1; |
| 2149 | pos = mgmt->u.action.u.bss_tm_req.variable; |
| 2150 | |
| 2151 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2152 | wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " |
| 2153 | MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u " |
| 2154 | "validity_interval=%u", |
| 2155 | @@ -478,7 +479,8 @@ static void ieee802_11_rx_bss_trans_mgmt_query(struct hostapd_data *hapd, |
| 2156 | MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); |
| 2157 | os_free(hex); |
| 2158 | |
| 2159 | - ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); |
| 2160 | + if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos)) |
| 2161 | + ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); |
| 2162 | } |
| 2163 | |
| 2164 | |
| 2165 | @@ -500,7 +502,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd, |
| 2166 | size_t len) |
| 2167 | { |
| 2168 | u8 dialog_token, status_code, bss_termination_delay; |
| 2169 | - const u8 *pos, *end; |
| 2170 | + const u8 *pos, *end, *target_bssid = NULL; |
| 2171 | int enabled = hapd->conf->bss_transition; |
| 2172 | struct sta_info *sta; |
| 2173 | |
| 2174 | @@ -547,6 +549,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd, |
| 2175 | wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); |
| 2176 | return; |
| 2177 | } |
| 2178 | + target_bssid = pos; |
| 2179 | sta->agreed_to_steer = 1; |
| 2180 | eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta); |
| 2181 | eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer, |
| 2182 | @@ -566,6 +569,10 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd, |
| 2183 | MAC2STR(addr), status_code, bss_termination_delay); |
| 2184 | } |
| 2185 | |
| 2186 | + hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token, |
| 2187 | + status_code, bss_termination_delay, |
| 2188 | + target_bssid, pos, end - pos); |
| 2189 | + |
| 2190 | wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", |
| 2191 | pos, end - pos); |
| 2192 | } |
| 2193 | @@ -814,10 +821,12 @@ int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd, |
| 2194 | plen); |
| 2195 | return 0; |
| 2196 | case WNM_BSS_TRANS_MGMT_QUERY: |
| 2197 | + hapd->openwrt_stats.wnm.bss_transition_query_rx++; |
| 2198 | ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, |
| 2199 | plen); |
| 2200 | return 0; |
| 2201 | case WNM_BSS_TRANS_MGMT_RESP: |
| 2202 | + hapd->openwrt_stats.wnm.bss_transition_response_rx++; |
| 2203 | ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload, |
| 2204 | plen); |
| 2205 | return 0; |
| 2206 | @@ -865,6 +874,7 @@ int wnm_send_disassoc_imminent(struct hostapd_data *hapd, |
| 2207 | |
| 2208 | pos = mgmt->u.action.u.bss_tm_req.variable; |
| 2209 | |
| 2210 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2211 | wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to " |
| 2212 | MACSTR, disassoc_timer, MAC2STR(sta->addr)); |
| 2213 | if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) { |
| 2214 | @@ -947,6 +957,7 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd, |
| 2215 | return -1; |
| 2216 | } |
| 2217 | |
| 2218 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2219 | if (disassoc_timer) { |
| 2220 | /* send disassociation frame after time-out */ |
| 2221 | set_disassoc_timer(hapd, sta, disassoc_timer); |
| 2222 | @@ -1028,6 +1039,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta, |
| 2223 | } |
| 2224 | os_free(buf); |
| 2225 | |
| 2226 | + hapd->openwrt_stats.wnm.bss_transition_request_tx++; |
| 2227 | if (disassoc_timer) { |
| 2228 | #ifdef CONFIG_IEEE80211BE |
| 2229 | if (ap_sta_is_mld(hapd, sta)) { |
| 2230 | diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c |
| 2231 | index 7a07dcc4c..b23d75444 100644 |
| 2232 | --- a/src/ap/wpa_auth.c |
| 2233 | +++ b/src/ap/wpa_auth.c |
| 2234 | @@ -5865,6 +5865,7 @@ static const char * wpa_bool_txt(int val) |
| 2235 | return val ? "TRUE" : "FALSE"; |
| 2236 | } |
| 2237 | |
| 2238 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 2239 | |
| 2240 | #define RSN_SUITE "%02x-%02x-%02x-%d" |
| 2241 | #define RSN_SUITE_ARG(s) \ |
| 2242 | @@ -6017,7 +6018,7 @@ int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen) |
| 2243 | |
| 2244 | return len; |
| 2245 | } |
| 2246 | - |
| 2247 | +#endif |
| 2248 | |
| 2249 | void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) |
| 2250 | { |
| 2251 | diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c |
| 2252 | index 1726c7201..5a9ec6975 100644 |
| 2253 | --- a/src/ap/wpa_auth_glue.c |
| 2254 | +++ b/src/ap/wpa_auth_glue.c |
| 2255 | @@ -275,6 +275,7 @@ static void hostapd_wpa_auth_psk_failure_report(void *ctx, const u8 *addr) |
| 2256 | struct hostapd_data *hapd = ctx; |
| 2257 | wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, |
| 2258 | MAC2STR(addr)); |
| 2259 | + hostapd_ubus_notify(hapd, "key-mismatch", addr); |
| 2260 | } |
| 2261 | |
| 2262 | |
| 2263 | @@ -1812,8 +1813,12 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) |
| 2264 | wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { |
| 2265 | const char *ft_iface; |
| 2266 | |
| 2267 | - ft_iface = hapd->conf->bridge[0] ? hapd->conf->bridge : |
| 2268 | - hapd->conf->iface; |
| 2269 | + if (hapd->conf->ft_iface[0]) |
| 2270 | + ft_iface = hapd->conf->ft_iface; |
| 2271 | + else if (hapd->conf->bridge[0]) |
| 2272 | + ft_iface = hapd->conf->bridge; |
| 2273 | + else |
| 2274 | + ft_iface = hapd->conf->iface; |
| 2275 | hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB, |
| 2276 | hostapd_rrb_receive, hapd, 1); |
| 2277 | if (!hapd->l2) { |
| 2278 | diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c |
| 2279 | index 82d4d5fdd..dfc5c3ecb 100644 |
| 2280 | --- a/src/ap/wps_hostapd.c |
| 2281 | +++ b/src/ap/wps_hostapd.c |
| 2282 | @@ -394,9 +394,8 @@ static int hapd_wps_reconfig_in_memory(struct hostapd_data *hapd, |
| 2283 | bss->wpa_pairwise |= WPA_CIPHER_GCMP; |
| 2284 | else |
| 2285 | bss->wpa_pairwise |= WPA_CIPHER_CCMP; |
| 2286 | - } |
| 2287 | #ifndef CONFIG_NO_TKIP |
| 2288 | - if (cred->encr_type & WPS_ENCR_TKIP) |
| 2289 | + } else if (cred->encr_type & WPS_ENCR_TKIP) |
| 2290 | bss->wpa_pairwise |= WPA_CIPHER_TKIP; |
| 2291 | #endif /* CONFIG_NO_TKIP */ |
| 2292 | bss->rsn_pairwise = bss->wpa_pairwise; |
| 2293 | @@ -1181,8 +1180,7 @@ int hostapd_init_wps(struct hostapd_data *hapd, |
| 2294 | WPA_CIPHER_GCMP_256)) { |
| 2295 | wps->encr_types |= WPS_ENCR_AES; |
| 2296 | wps->encr_types_rsn |= WPS_ENCR_AES; |
| 2297 | - } |
| 2298 | - if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { |
| 2299 | + } else if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { |
| 2300 | #ifdef CONFIG_NO_TKIP |
| 2301 | wpa_printf(MSG_INFO, "WPS: TKIP not supported"); |
| 2302 | goto fail; |
| 2303 | diff --git a/src/ap/x_snoop.c b/src/ap/x_snoop.c |
| 2304 | index 029f4de23..4c20f137f 100644 |
| 2305 | --- a/src/ap/x_snoop.c |
| 2306 | +++ b/src/ap/x_snoop.c |
| 2307 | @@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *hapd) |
| 2308 | |
| 2309 | hapd->x_snoop_initialized = true; |
| 2310 | |
| 2311 | - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, |
| 2312 | + if (!conf->snoop_iface[0] && |
| 2313 | + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, |
| 2314 | 1)) { |
| 2315 | wpa_printf(MSG_DEBUG, |
| 2316 | "x_snoop: Failed to enable hairpin_mode on the bridge port"); |
| 2317 | return -1; |
| 2318 | } |
| 2319 | |
| 2320 | - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { |
| 2321 | + if (!conf->snoop_iface[0] && |
| 2322 | + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { |
| 2323 | wpa_printf(MSG_DEBUG, |
| 2324 | "x_snoop: Failed to enable proxyarp on the bridge port"); |
| 2325 | return -1; |
| 2326 | } |
| 2327 | |
| 2328 | if (hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, |
| 2329 | - 1)) { |
| 2330 | + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 1)) { |
| 2331 | wpa_printf(MSG_DEBUG, |
| 2332 | "x_snoop: Failed to enable accepting gratuitous ARP on the bridge"); |
| 2333 | return -1; |
| 2334 | } |
| 2335 | |
| 2336 | #ifdef CONFIG_IPV6 |
| 2337 | - if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { |
| 2338 | + if (!conf->snoop_iface[0] && |
| 2339 | + hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, NULL, 1)) { |
| 2340 | wpa_printf(MSG_DEBUG, |
| 2341 | "x_snoop: Failed to enable multicast snooping on the bridge"); |
| 2342 | return -1; |
| 2343 | @@ -73,8 +76,12 @@ x_snoop_get_l2_packet(struct hostapd_data *hapd, |
| 2344 | { |
| 2345 | struct hostapd_bss_config *conf = hapd->conf; |
| 2346 | struct l2_packet_data *l2; |
| 2347 | + const char *ifname = conf->bridge; |
| 2348 | + |
| 2349 | + if (conf->snoop_iface[0]) |
| 2350 | + ifname = conf->snoop_iface; |
| 2351 | |
| 2352 | - l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1); |
| 2353 | + l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1); |
| 2354 | if (l2 == NULL) { |
| 2355 | wpa_printf(MSG_DEBUG, |
| 2356 | "x_snoop: Failed to initialize L2 packet processing %s", |
| 2357 | @@ -127,9 +134,12 @@ void x_snoop_mcast_to_ucast_convert_send(struct hostapd_data *hapd, |
| 2358 | |
| 2359 | void x_snoop_deinit(struct hostapd_data *hapd) |
| 2360 | { |
| 2361 | + struct hostapd_bss_config *conf = hapd->conf; |
| 2362 | + |
| 2363 | if (!hapd->x_snoop_initialized) |
| 2364 | return; |
| 2365 | - hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0); |
| 2366 | + hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, |
| 2367 | + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 0); |
| 2368 | hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0); |
| 2369 | hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0); |
| 2370 | hapd->x_snoop_initialized = false; |
| 2371 | diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c |
| 2372 | index f17f95a2c..39d39f429 100644 |
| 2373 | --- a/src/common/dpp_crypto.c |
| 2374 | +++ b/src/common/dpp_crypto.c |
| 2375 | @@ -269,6 +269,12 @@ int dpp_get_pubkey_hash(struct crypto_ec_key *key, u8 *hash) |
| 2376 | |
| 2377 | struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) |
| 2378 | { |
| 2379 | + if (curve == NULL) { |
| 2380 | + wpa_printf(MSG_DEBUG, |
| 2381 | + "DPP: %s curve must be initialized", __func__); |
| 2382 | + return NULL; |
| 2383 | + } |
| 2384 | + |
| 2385 | struct crypto_ec_key *key; |
| 2386 | |
| 2387 | wpa_printf(MSG_DEBUG, "DPP: Generating a keypair"); |
| 2388 | @@ -1582,7 +1588,9 @@ dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp, |
| 2389 | Pr = crypto_ec_key_get_public_key(Pr_key); |
| 2390 | Qr = crypto_ec_point_init(ec); |
| 2391 | hash_bn = crypto_bignum_init_set(hash, curve->hash_len); |
| 2392 | - if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) |
| 2393 | + if (!Pr || !Qr || !hash_bn || |
| 2394 | + crypto_bignum_mod(hash_bn, crypto_ec_get_prime(ec), hash_bn) || |
| 2395 | + crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) |
| 2396 | goto fail; |
| 2397 | |
| 2398 | if (crypto_ec_point_is_at_infinity(ec, Qr)) { |
| 2399 | diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c |
| 2400 | index 2c47bf812..8bd6e994d 100644 |
| 2401 | --- a/src/common/hw_features_common.c |
| 2402 | +++ b/src/common/hw_features_common.c |
| 2403 | @@ -898,6 +898,7 @@ int ieee80211ac_cap_check(u32 hw, u32 conf) |
| 2404 | VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB); |
| 2405 | VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN); |
| 2406 | VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN); |
| 2407 | + VHT_CAP_CHECK(VHT_CAP_EXTENDED_NSS_BW_SUPPORT); |
| 2408 | |
| 2409 | #undef VHT_CAP_CHECK |
| 2410 | #undef VHT_CAP_CHECK_MAX |
| 2411 | diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h |
| 2412 | index 5b39a61e1..7a1da3252 100644 |
| 2413 | --- a/src/common/ieee802_11_defs.h |
| 2414 | +++ b/src/common/ieee802_11_defs.h |
| 2415 | @@ -1397,6 +1397,8 @@ struct ieee80211_ampe_ie { |
| 2416 | #define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB ((u32) BIT(26) | BIT(27)) |
| 2417 | #define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28)) |
| 2418 | #define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29)) |
| 2419 | +#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT ((u32) BIT(30)) |
| 2420 | +#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK ((u32) BIT(30) | BIT(31)) |
| 2421 | |
| 2422 | #define VHT_OPMODE_CHANNEL_WIDTH_MASK ((u8) BIT(0) | BIT(1)) |
| 2423 | #define VHT_OPMODE_CHANNEL_RxNSS_MASK ((u8) BIT(4) | BIT(5) | \ |
| 2424 | diff --git a/src/common/sae.c b/src/common/sae.c |
| 2425 | index f1c164e13..05de737e5 100644 |
| 2426 | --- a/src/common/sae.c |
| 2427 | +++ b/src/common/sae.c |
| 2428 | @@ -1278,6 +1278,13 @@ void sae_deinit_pt(struct sae_pt *pt) |
| 2429 | static int sae_derive_commit_element_ecc(struct sae_data *sae, |
| 2430 | struct crypto_bignum *mask) |
| 2431 | { |
| 2432 | + if (sae->tmp->pwe_ecc == NULL) { |
| 2433 | + wpa_printf(MSG_DEBUG, |
| 2434 | + "SAE: %s sae->tmp->pwe_ecc must be initialized", |
| 2435 | + __func__); |
| 2436 | + return -1; |
| 2437 | + } |
| 2438 | + |
| 2439 | /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */ |
| 2440 | if (!sae->tmp->own_commit_element_ecc) { |
| 2441 | sae->tmp->own_commit_element_ecc = |
| 2442 | diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c |
| 2443 | index 6ea3311ce..7a608c30e 100644 |
| 2444 | --- a/src/common/wpa_common.c |
| 2445 | +++ b/src/common/wpa_common.c |
| 2446 | @@ -2856,6 +2856,31 @@ u32 wpa_akm_to_suite(int akm) |
| 2447 | } |
| 2448 | |
| 2449 | |
| 2450 | +static void wpa_fixup_wpa_ie_rsn(u8 *assoc_ie, const u8 *wpa_msg_ie, |
| 2451 | + size_t rsn_ie_len) |
| 2452 | +{ |
| 2453 | + int pos, count; |
| 2454 | + |
| 2455 | + pos = sizeof(struct rsn_ie_hdr) + RSN_SELECTOR_LEN; |
| 2456 | + if (rsn_ie_len < pos + 2) |
| 2457 | + return; |
| 2458 | + |
| 2459 | + count = WPA_GET_LE16(wpa_msg_ie + pos); |
| 2460 | + pos += 2 + count * RSN_SELECTOR_LEN; |
| 2461 | + if (rsn_ie_len < pos + 2) |
| 2462 | + return; |
| 2463 | + |
| 2464 | + count = WPA_GET_LE16(wpa_msg_ie + pos); |
| 2465 | + pos += 2 + count * RSN_SELECTOR_LEN; |
| 2466 | + if (rsn_ie_len < pos + 2) |
| 2467 | + return; |
| 2468 | + |
| 2469 | + if (!assoc_ie[pos] && !assoc_ie[pos + 1] && |
| 2470 | + (wpa_msg_ie[pos] || wpa_msg_ie[pos + 1])) |
| 2471 | + memcpy(&assoc_ie[pos], &wpa_msg_ie[pos], 2); |
| 2472 | +} |
| 2473 | + |
| 2474 | + |
| 2475 | int wpa_compare_rsn_ie(int ft_initial_assoc, |
| 2476 | const u8 *ie1, size_t ie1len, |
| 2477 | const u8 *ie2, size_t ie2len) |
| 2478 | @@ -2863,8 +2888,19 @@ int wpa_compare_rsn_ie(int ft_initial_assoc, |
| 2479 | if (ie1 == NULL || ie2 == NULL) |
| 2480 | return -1; |
| 2481 | |
| 2482 | - if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0) |
| 2483 | - return 0; /* identical IEs */ |
| 2484 | + if (ie1len == ie2len) { |
| 2485 | + u8 *ie_tmp; |
| 2486 | + |
| 2487 | + if (os_memcmp(ie1, ie2, ie1len) == 0) |
| 2488 | + return 0; /* identical IEs */ |
| 2489 | + |
| 2490 | + ie_tmp = alloca(ie1len); |
| 2491 | + memcpy(ie_tmp, ie1, ie1len); |
| 2492 | + wpa_fixup_wpa_ie_rsn(ie_tmp, ie2, ie1len); |
| 2493 | + |
| 2494 | + if (os_memcmp(ie_tmp, ie2, ie1len) == 0) |
| 2495 | + return 0; /* only mismatch in RSN capabilties */ |
| 2496 | + } |
| 2497 | |
| 2498 | #ifdef CONFIG_IEEE80211R |
| 2499 | if (ft_initial_assoc) { |
| 2500 | diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c |
| 2501 | index 7e197f094..791fdbf93 100644 |
| 2502 | --- a/src/common/wpa_ctrl.c |
| 2503 | +++ b/src/common/wpa_ctrl.c |
| 2504 | @@ -135,7 +135,7 @@ try_again: |
| 2505 | return NULL; |
| 2506 | } |
| 2507 | tries++; |
| 2508 | -#ifdef ANDROID |
| 2509 | + |
| 2510 | /* Set client socket file permissions so that bind() creates the client |
| 2511 | * socket with these permissions and there is no need to try to change |
| 2512 | * them with chmod() after bind() which would have potential issues with |
| 2513 | @@ -147,7 +147,7 @@ try_again: |
| 2514 | * operations to allow the response to go through. Those are using the |
| 2515 | * no-deference-symlinks version to avoid races. */ |
| 2516 | fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); |
| 2517 | -#endif /* ANDROID */ |
| 2518 | + |
| 2519 | if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, |
| 2520 | sizeof(ctrl->local)) < 0) { |
| 2521 | if (errno == EADDRINUSE && tries < 2) { |
| 2522 | @@ -165,7 +165,11 @@ try_again: |
| 2523 | return NULL; |
| 2524 | } |
| 2525 | |
| 2526 | -#ifdef ANDROID |
| 2527 | +#ifndef ANDROID |
| 2528 | + /* Set group even if we do not have privileges to change owner */ |
| 2529 | + lchown(ctrl->local.sun_path, -1, 101); |
| 2530 | + lchown(ctrl->local.sun_path, 101, 101); |
| 2531 | +#else |
| 2532 | /* Set group even if we do not have privileges to change owner */ |
| 2533 | lchown(ctrl->local.sun_path, -1, AID_WIFI); |
| 2534 | lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); |
| 2535 | diff --git a/src/crypto/Makefile b/src/crypto/Makefile |
| 2536 | index ce0997091..96bac9476 100644 |
| 2537 | --- a/src/crypto/Makefile |
| 2538 | +++ b/src/crypto/Makefile |
| 2539 | @@ -1,10 +1,121 @@ |
| 2540 | -CFLAGS += -DCONFIG_CRYPTO_INTERNAL |
| 2541 | -CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT |
| 2542 | -CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER |
| 2543 | #CFLAGS += -DALL_DH_GROUPS |
| 2544 | CFLAGS += -DCONFIG_SHA256 |
| 2545 | CFLAGS += -DCONFIG_SHA384 |
| 2546 | +CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 2547 | CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 2548 | + |
| 2549 | +# crypto_module_tests.c |
| 2550 | +CFLAGS += -DCONFIG_MODULE_TESTS |
| 2551 | +CFLAGS += -DCONFIG_DPP |
| 2552 | +#CFLAGS += -DCONFIG_DPP2 |
| 2553 | +#CFLAGS += -DCONFIG_DPP3 |
| 2554 | +CFLAGS += -DCONFIG_ECC |
| 2555 | +CFLAGS += -DCONFIG_MESH |
| 2556 | +CFLAGS += -DEAP_PSK |
| 2557 | +CFLAGS += -DEAP_FAST |
| 2558 | + |
| 2559 | +ifeq ($(CONFIG_TLS),mbedtls) |
| 2560 | + |
| 2561 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=mbedtls') |
| 2562 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 2563 | +CFLAGS += -DCONFIG_DES |
| 2564 | +CFLAGS += -DEAP_IKEV2 |
| 2565 | +CFLAGS += -DEAP_MSCHAPv2 |
| 2566 | +CFLAGS += -DEAP_SIM |
| 2567 | + |
| 2568 | +LIB_OBJS = tls_mbedtls.o crypto_mbedtls.o |
| 2569 | +LIB_OBJS+= \ |
| 2570 | + aes-eax.o \ |
| 2571 | + aes-siv.o \ |
| 2572 | + dh_groups.o \ |
| 2573 | + milenage.o \ |
| 2574 | + ms_funcs.o |
| 2575 | + |
| 2576 | +else |
| 2577 | +ifeq ($(CONFIG_TLS),openssl) |
| 2578 | + |
| 2579 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=openssl') |
| 2580 | +ifndef CONFIG_TLS_DEFAULT_CIPHERS |
| 2581 | +CONFIG_TLS_DEFAULT_CIPHERS = "DEFAULT:!EXP:!LOW" |
| 2582 | +endif |
| 2583 | +CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" |
| 2584 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 2585 | +CFLAGS += -DEAP_TLS_OPENSSL |
| 2586 | + |
| 2587 | +LIB_OBJS = tls_openssl.o fips_prf_openssl.o crypto_openssl.o |
| 2588 | +LIB_OBJS+= \ |
| 2589 | + aes-ctr.o \ |
| 2590 | + aes-eax.o \ |
| 2591 | + aes-encblock.o \ |
| 2592 | + aes-siv.o \ |
| 2593 | + dh_groups.o \ |
| 2594 | + milenage.o \ |
| 2595 | + ms_funcs.o \ |
| 2596 | + sha1-prf.o \ |
| 2597 | + sha1-tlsprf.o \ |
| 2598 | + sha1-tprf.o \ |
| 2599 | + sha256-kdf.o \ |
| 2600 | + sha256-prf.o \ |
| 2601 | + sha256-tlsprf.o |
| 2602 | + |
| 2603 | +else |
| 2604 | +ifeq ($(CONFIG_TLS),wolfssl) |
| 2605 | + |
| 2606 | +# (wolfssl libraries must be built with ./configure --enable-wpas) |
| 2607 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=wolfssl') |
| 2608 | +CFLAGS += -DWOLFSSL_DER_LOAD |
| 2609 | +CFLAGS += -DCONFIG_DES |
| 2610 | + |
| 2611 | +LIB_OBJS = tls_wolfssl.o fips_prf_wolfssl.o crypto_wolfssl.o |
| 2612 | +LIB_OBJS+= \ |
| 2613 | + aes-ctr.o \ |
| 2614 | + aes-eax.o \ |
| 2615 | + aes-encblock.o \ |
| 2616 | + aes-siv.o \ |
| 2617 | + dh_groups.o \ |
| 2618 | + milenage.o \ |
| 2619 | + ms_funcs.o \ |
| 2620 | + sha1-prf.o \ |
| 2621 | + sha1-tlsprf.o \ |
| 2622 | + sha1-tprf.o \ |
| 2623 | + sha256-kdf.o \ |
| 2624 | + sha256-prf.o \ |
| 2625 | + sha256-tlsprf.o |
| 2626 | + |
| 2627 | +else |
| 2628 | +ifeq ($(CONFIG_TLS),gnutls) |
| 2629 | + |
| 2630 | +# (enable features for 'cd tests; make run-tests CONFIG_TLS=gnutls') |
| 2631 | +LIB_OBJS = tls_gnutls.o crypto_gnutls.o |
| 2632 | +LIB_OBJS+= \ |
| 2633 | + aes-cbc.o \ |
| 2634 | + aes-ctr.o \ |
| 2635 | + aes-eax.o \ |
| 2636 | + aes-encblock.o \ |
| 2637 | + aes-omac1.o \ |
| 2638 | + aes-siv.o \ |
| 2639 | + aes-unwrap.o \ |
| 2640 | + aes-wrap.o \ |
| 2641 | + dh_group5.o \ |
| 2642 | + dh_groups.o \ |
| 2643 | + milenage.o \ |
| 2644 | + ms_funcs.o \ |
| 2645 | + rc4.o \ |
| 2646 | + sha1-pbkdf2.o \ |
| 2647 | + sha1-prf.o \ |
| 2648 | + fips_prf_internal.o \ |
| 2649 | + sha1-internal.o \ |
| 2650 | + sha1-tlsprf.o \ |
| 2651 | + sha1-tprf.o \ |
| 2652 | + sha256-kdf.o \ |
| 2653 | + sha256-prf.o \ |
| 2654 | + sha256-tlsprf.o |
| 2655 | + |
| 2656 | +else |
| 2657 | + |
| 2658 | +CFLAGS += -DCONFIG_CRYPTO_INTERNAL |
| 2659 | +CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT |
| 2660 | +CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER |
| 2661 | CFLAGS += -DCONFIG_INTERNAL_SHA384 |
| 2662 | |
| 2663 | LIB_OBJS= \ |
| 2664 | @@ -13,7 +124,6 @@ LIB_OBJS= \ |
| 2665 | aes-ctr.o \ |
| 2666 | aes-eax.o \ |
| 2667 | aes-encblock.o \ |
| 2668 | - aes-gcm.o \ |
| 2669 | aes-internal.o \ |
| 2670 | aes-internal-dec.o \ |
| 2671 | aes-internal-enc.o \ |
| 2672 | @@ -37,6 +147,7 @@ LIB_OBJS= \ |
| 2673 | sha1-tlsprf.o \ |
| 2674 | sha1-tprf.o \ |
| 2675 | sha256.o \ |
| 2676 | + sha256-kdf.o \ |
| 2677 | sha256-prf.o \ |
| 2678 | sha256-tlsprf.o \ |
| 2679 | sha256-internal.o \ |
| 2680 | @@ -53,6 +164,16 @@ LIB_OBJS += crypto_internal-modexp.o |
| 2681 | LIB_OBJS += crypto_internal-rsa.o |
| 2682 | LIB_OBJS += tls_internal.o |
| 2683 | LIB_OBJS += fips_prf_internal.o |
| 2684 | + |
| 2685 | +endif |
| 2686 | +endif |
| 2687 | +endif |
| 2688 | +endif |
| 2689 | + |
| 2690 | + |
| 2691 | +# (used by wlantest/{bip,gcmp,rx_mgmt}.c and tests/test-aes.c) |
| 2692 | +LIB_OBJS += aes-gcm.o |
| 2693 | + |
| 2694 | ifndef TEST_FUZZ |
| 2695 | LIB_OBJS += random.o |
| 2696 | endif |
| 2697 | diff --git a/src/crypto/crypto_mbedtls.c b/src/crypto/crypto_mbedtls.c |
| 2698 | new file mode 100644 |
| 2699 | index 000000000..7a91c965f |
| 2700 | --- /dev/null |
| 2701 | +++ b/src/crypto/crypto_mbedtls.c |
| 2702 | @@ -0,0 +1,4228 @@ |
| 2703 | +/* |
| 2704 | + * crypto wrapper functions for mbed TLS |
| 2705 | + * |
| 2706 | + * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com> |
| 2707 | + * SPDX-License-Identifier: BSD-3-Clause |
| 2708 | + */ |
| 2709 | + |
| 2710 | +#include "utils/includes.h" |
| 2711 | +#include "utils/common.h" |
| 2712 | + |
| 2713 | +#include <mbedtls/version.h> |
| 2714 | +#include <mbedtls/entropy.h> |
| 2715 | +#include <mbedtls/ctr_drbg.h> |
| 2716 | +#include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */ |
| 2717 | +#include <mbedtls/asn1.h> |
| 2718 | +#include <mbedtls/asn1write.h> |
| 2719 | +#include <mbedtls/aes.h> |
| 2720 | +#include <mbedtls/md.h> |
| 2721 | +#include <mbedtls/md5.h> |
| 2722 | +#include <mbedtls/sha1.h> |
| 2723 | +#include <mbedtls/sha256.h> |
| 2724 | +#include <mbedtls/sha512.h> |
| 2725 | + |
| 2726 | +#ifndef MBEDTLS_PRIVATE |
| 2727 | +#define MBEDTLS_PRIVATE(x) x |
| 2728 | +#endif |
| 2729 | + |
| 2730 | +/* hostapd/wpa_supplicant provides forced_memzero(), |
| 2731 | + * but prefer mbedtls_platform_zeroize() */ |
| 2732 | +#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) |
| 2733 | + |
| 2734 | +#ifndef __has_attribute |
| 2735 | +#define __has_attribute(x) 0 |
| 2736 | +#endif |
| 2737 | + |
| 2738 | +#ifndef __GNUC_PREREQ |
| 2739 | +#define __GNUC_PREREQ(maj,min) 0 |
| 2740 | +#endif |
| 2741 | + |
| 2742 | +#ifndef __attribute_cold__ |
| 2743 | +#if __has_attribute(cold) \ |
| 2744 | + || __GNUC_PREREQ(4,3) |
| 2745 | +#define __attribute_cold__ __attribute__((__cold__)) |
| 2746 | +#else |
| 2747 | +#define __attribute_cold__ |
| 2748 | +#endif |
| 2749 | +#endif |
| 2750 | + |
| 2751 | +#ifndef __attribute_noinline__ |
| 2752 | +#if __has_attribute(noinline) \ |
| 2753 | + || __GNUC_PREREQ(3,1) |
| 2754 | +#define __attribute_noinline__ __attribute__((__noinline__)) |
| 2755 | +#else |
| 2756 | +#define __attribute_noinline__ |
| 2757 | +#endif |
| 2758 | +#endif |
| 2759 | + |
| 2760 | +#include "crypto.h" |
| 2761 | +#include "aes_wrap.h" |
| 2762 | +#include "aes.h" |
| 2763 | +#include "md5.h" |
| 2764 | +#include "sha1.h" |
| 2765 | +#include "sha256.h" |
| 2766 | +#include "sha384.h" |
| 2767 | +#include "sha512.h" |
| 2768 | + |
| 2769 | + |
| 2770 | +/* |
| 2771 | + * selective code inclusion based on preprocessor defines |
| 2772 | + * |
| 2773 | + * future: additional code could be wrapped with preprocessor checks if |
| 2774 | + * wpa_supplicant/Makefile and hostap/Makefile were more consistent with |
| 2775 | + * setting preprocessor defines for named groups of functionality |
| 2776 | + */ |
| 2777 | + |
| 2778 | +#if defined(CONFIG_FIPS) |
| 2779 | +#undef MBEDTLS_MD4_C /* omit md4_vector() */ |
| 2780 | +#undef MBEDTLS_MD5_C /* omit md5_vector() hmac_md5_vector() hmac_md5() */ |
| 2781 | +#undef MBEDTLS_DES_C /* omit des_encrypt() */ |
| 2782 | +#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ |
| 2783 | +#define CRYPTO_MBEDTLS_CONFIG_FIPS |
| 2784 | +#endif |
| 2785 | + |
| 2786 | +#if !defined(CONFIG_FIPS) |
| 2787 | +#if defined(EAP_PWD) \ |
| 2788 | + || defined(EAP_LEAP) || defined(EAP_LEAP_DYNAMIC) \ |
| 2789 | + || defined(EAP_TTLS) || defined(EAP_TTLS_DYNAMIC) \ |
| 2790 | + || defined(EAP_MSCHAPv2) || defined(EAP_MSCHAPv2_DYNAMIC) \ |
| 2791 | + || defined(EAP_SERVER_MSCHAPV2) |
| 2792 | +#ifndef MBEDTLS_MD4_C /* (MD4 not in mbedtls 3.x) */ |
| 2793 | +#include "md4-internal.c"/* pull in hostap local implementation */ |
| 2794 | +#endif /* md4_vector() */ |
| 2795 | +#else |
| 2796 | +#undef MBEDTLS_MD4_C /* omit md4_vector() */ |
| 2797 | +#endif |
| 2798 | +#endif |
| 2799 | + |
| 2800 | +#if !defined(CONFIG_NO_RC4) && !defined(CONFIG_NO_WPA) |
| 2801 | +#ifndef MBEDTLS_ARC4_C /* (RC4 not in mbedtls 3.x) */ |
| 2802 | +#include "rc4.c" /* pull in hostap local implementation */ |
| 2803 | +#endif /* rc4_skip() */ |
| 2804 | +#else |
| 2805 | +#undef MBEDTLS_ARC4_C /* omit rc4_skip() */ |
| 2806 | +#endif |
| 2807 | + |
| 2808 | +#if defined(CONFIG_MACSEC) \ |
| 2809 | + || defined(CONFIG_NO_RADIUS) \ |
| 2810 | + || defined(CONFIG_IEEE80211R) \ |
| 2811 | + || defined(EAP_SERVER_FAST) \ |
| 2812 | + || defined(EAP_SERVER_TEAP) \ |
| 2813 | + || !defined(CONFIG_NO_WPA) |
| 2814 | + /* aes_wrap() aes_unwrap() */ |
| 2815 | +#else |
| 2816 | +#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ |
| 2817 | +#endif |
| 2818 | + |
| 2819 | +#if !defined(CONFIG_SHA256) |
| 2820 | +#undef MBEDTLS_SHA256_C |
| 2821 | +#endif |
| 2822 | + |
| 2823 | +#if !defined(CONFIG_SHA384) && !defined(CONFIG_SHA512) |
| 2824 | +#undef MBEDTLS_SHA512_C |
| 2825 | +#endif |
| 2826 | + |
| 2827 | +#if defined(CONFIG_HMAC_SHA256_KDF) |
| 2828 | +#define CRYPTO_MBEDTLS_HMAC_KDF_SHA256 |
| 2829 | +#endif |
| 2830 | +#if defined(CONFIG_HMAC_SHA384_KDF) |
| 2831 | +#define CRYPTO_MBEDTLS_HMAC_KDF_SHA384 |
| 2832 | +#endif |
| 2833 | +#if defined(CONFIG_HMAC_SHA512_KDF) |
| 2834 | +#define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 |
| 2835 | +#endif |
| 2836 | + |
| 2837 | +#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ |
| 2838 | + || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) |
| 2839 | +/* EAP_SIM=y EAP_AKA=y */ |
| 2840 | +#define CRYPTO_MBEDTLS_FIPS186_2_PRF |
| 2841 | +#endif |
| 2842 | + |
| 2843 | +#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ |
| 2844 | + || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) |
| 2845 | +#define CRYPTO_MBEDTLS_SHA1_T_PRF |
| 2846 | +#endif |
| 2847 | + |
| 2848 | +#if defined(CONFIG_DES) |
| 2849 | +#define CRYPTO_MBEDTLS_DES_ENCRYPT |
| 2850 | +#endif /* des_encrypt() */ |
| 2851 | + |
| 2852 | +#if !defined(CONFIG_NO_PBKDF2) |
| 2853 | +#define CRYPTO_MBEDTLS_PBKDF2_SHA1 |
| 2854 | +#endif /* pbkdf2_sha1() */ |
| 2855 | + |
| 2856 | +#if defined(EAP_IKEV2) \ |
| 2857 | + || defined(EAP_IKEV2_DYNAMIC) \ |
| 2858 | + || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ |
| 2859 | +#define CRYPTO_MBEDTLS_CRYPTO_CIPHER |
| 2860 | +#endif /* crypto_cipher_*() */ |
| 2861 | + |
| 2862 | +#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ |
| 2863 | +#define CRYPTO_MBEDTLS_CRYPTO_HASH |
| 2864 | +#endif /* crypto_hash_*() */ |
| 2865 | + |
| 2866 | +#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ \ |
| 2867 | + || defined(CONFIG_SAE) /* CONFIG_SAE=y */ |
| 2868 | +#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 2869 | +#endif /* crypto_bignum_*() */ |
| 2870 | + |
| 2871 | +#if defined(EAP_PWD) /* CONFIG_EAP_PWD=y */ \ |
| 2872 | + || defined(EAP_EKE) /* CONFIG_EAP_EKE=y */ \ |
| 2873 | + || defined(EAP_EKE_DYNAMIC) /* CONFIG_EAP_EKE=y */ \ |
| 2874 | + || defined(EAP_SERVER_EKE) /* CONFIG_EAP_EKE=y */ \ |
| 2875 | + || defined(EAP_IKEV2) /* CONFIG_EAP_IKEV2y */ \ |
| 2876 | + || defined(EAP_IKEV2_DYNAMIC)/* CONFIG_EAP_IKEV2=y */ \ |
| 2877 | + || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ \ |
| 2878 | + || defined(CONFIG_SAE) /* CONFIG_SAE=y */ \ |
| 2879 | + || defined(CONFIG_WPS) /* CONFIG_WPS=y */ |
| 2880 | +#define CRYPTO_MBEDTLS_CRYPTO_DH |
| 2881 | +#if defined(CONFIG_WPS_NFC) |
| 2882 | +#define CRYPTO_MBEDTLS_DH5_INIT_FIXED |
| 2883 | +#endif /* dh5_init_fixed() */ |
| 2884 | +#endif /* crypto_dh_*() */ |
| 2885 | + |
| 2886 | +#if !defined(CONFIG_NO_WPA) /* CONFIG_NO_WPA= */ |
| 2887 | +#define CRYPTO_MBEDTLS_CRYPTO_ECDH |
| 2888 | +#endif /* crypto_ecdh_*() */ |
| 2889 | + |
| 2890 | +#if defined(CONFIG_ECC) |
| 2891 | +#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 2892 | +#define CRYPTO_MBEDTLS_CRYPTO_EC |
| 2893 | +#endif /* crypto_ec_*() crypto_ec_key_*() */ |
| 2894 | + |
| 2895 | +#if defined(CONFIG_DPP) /* CONFIG_DPP=y */ |
| 2896 | +#define CRYPTO_MBEDTLS_CRYPTO_EC_DPP /* extra for DPP */ |
| 2897 | +#define CRYPTO_MBEDTLS_CRYPTO_CSR |
| 2898 | +#endif /* crypto_csr_*() */ |
| 2899 | + |
| 2900 | +#if defined(CONFIG_DPP3) /* CONFIG_DPP3=y */ |
| 2901 | +#define CRYPTO_MBEDTLS_CRYPTO_HPKE |
| 2902 | +#endif |
| 2903 | + |
| 2904 | +#if defined(CONFIG_DPP2) /* CONFIG_DPP2=y */ |
| 2905 | +#define CRYPTO_MBEDTLS_CRYPTO_PKCS7 |
| 2906 | +#endif /* crypto_pkcs7_*() */ |
| 2907 | + |
| 2908 | +#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ |
| 2909 | + || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) \ |
| 2910 | + || defined(CONFIG_AP) || defined(HOSTAPD) |
| 2911 | +/* CONFIG_EAP_SIM=y CONFIG_EAP_AKA=y CONFIG_AP=y HOSTAPD */ |
| 2912 | +#if defined(CRYPTO_RSA_OAEP_SHA256) |
| 2913 | +#define CRYPTO_MBEDTLS_CRYPTO_RSA |
| 2914 | +#endif |
| 2915 | +#endif /* crypto_rsa_*() */ |
| 2916 | + |
| 2917 | + |
| 2918 | +static int ctr_drbg_init_state; |
| 2919 | +static mbedtls_ctr_drbg_context ctr_drbg; |
| 2920 | +static mbedtls_entropy_context entropy; |
| 2921 | + |
| 2922 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 2923 | +#include <mbedtls/bignum.h> |
| 2924 | +static mbedtls_mpi mpi_sw_A; |
| 2925 | +#endif |
| 2926 | + |
| 2927 | +__attribute_cold__ |
| 2928 | +__attribute_noinline__ |
| 2929 | +static mbedtls_ctr_drbg_context * ctr_drbg_init(void) |
| 2930 | +{ |
| 2931 | + mbedtls_ctr_drbg_init(&ctr_drbg); |
| 2932 | + mbedtls_entropy_init(&entropy); |
| 2933 | + if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, |
| 2934 | + NULL, 0)) { |
| 2935 | + wpa_printf(MSG_ERROR, "Init of random number generator failed"); |
| 2936 | + /* XXX: abort? */ |
| 2937 | + } |
| 2938 | + else |
| 2939 | + ctr_drbg_init_state = 1; |
| 2940 | + |
| 2941 | + return &ctr_drbg; |
| 2942 | +} |
| 2943 | + |
| 2944 | +__attribute_cold__ |
| 2945 | +void crypto_unload(void) |
| 2946 | +{ |
| 2947 | + if (ctr_drbg_init_state) { |
| 2948 | + mbedtls_ctr_drbg_free(&ctr_drbg); |
| 2949 | + mbedtls_entropy_free(&entropy); |
| 2950 | + #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 2951 | + mbedtls_mpi_free(&mpi_sw_A); |
| 2952 | + #endif |
| 2953 | + ctr_drbg_init_state = 0; |
| 2954 | + } |
| 2955 | +} |
| 2956 | + |
| 2957 | +/* init ctr_drbg on first use |
| 2958 | + * crypto_global_init() and crypto_global_deinit() are not available here |
| 2959 | + * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */ |
| 2960 | +mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ |
| 2961 | +inline |
| 2962 | +mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void) |
| 2963 | +{ |
| 2964 | + return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init(); |
| 2965 | +} |
| 2966 | + |
| 2967 | +#ifdef CRYPTO_MBEDTLS_CONFIG_FIPS |
| 2968 | +int crypto_get_random(void *buf, size_t len) |
| 2969 | +{ |
| 2970 | + return mbedtls_ctr_drbg_random(crypto_mbedtls_ctr_drbg(),buf,len) ? -1 : 0; |
| 2971 | +} |
| 2972 | +#endif |
| 2973 | + |
| 2974 | + |
| 2975 | +#if 1 |
| 2976 | + |
| 2977 | +/* tradeoff: slightly smaller code size here at cost of slight increase |
| 2978 | + * in instructions and function calls at runtime versus the expanded |
| 2979 | + * per-message-digest code that follows in #else (~0.5 kib .text larger) */ |
| 2980 | + |
| 2981 | +__attribute_noinline__ |
| 2982 | +static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, |
| 2983 | + u8 *mac, mbedtls_md_type_t md_type) |
| 2984 | +{ |
| 2985 | + if (TEST_FAIL()) |
| 2986 | + return -1; |
| 2987 | + |
| 2988 | + mbedtls_md_context_t ctx; |
| 2989 | + mbedtls_md_init(&ctx); |
| 2990 | + if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ |
| 2991 | + mbedtls_md_free(&ctx); |
| 2992 | + return -1; |
| 2993 | + } |
| 2994 | + mbedtls_md_starts(&ctx); |
| 2995 | + for (size_t i = 0; i < num_elem; ++i) |
| 2996 | + mbedtls_md_update(&ctx, addr[i], len[i]); |
| 2997 | + mbedtls_md_finish(&ctx, mac); |
| 2998 | + mbedtls_md_free(&ctx); |
| 2999 | + return 0; |
| 3000 | +} |
| 3001 | + |
| 3002 | +#ifdef MBEDTLS_SHA512_C |
| 3003 | +int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3004 | +{ |
| 3005 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA512); |
| 3006 | +} |
| 3007 | + |
| 3008 | +int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3009 | +{ |
| 3010 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA384); |
| 3011 | +} |
| 3012 | +#endif |
| 3013 | + |
| 3014 | +#ifdef MBEDTLS_SHA256_C |
| 3015 | +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3016 | +{ |
| 3017 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256); |
| 3018 | +} |
| 3019 | +#endif |
| 3020 | + |
| 3021 | +#ifdef MBEDTLS_SHA1_C |
| 3022 | +int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3023 | +{ |
| 3024 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1); |
| 3025 | +} |
| 3026 | +#endif |
| 3027 | + |
| 3028 | +#ifdef MBEDTLS_MD5_C |
| 3029 | +int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3030 | +{ |
| 3031 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5); |
| 3032 | +} |
| 3033 | +#endif |
| 3034 | + |
| 3035 | +#ifdef MBEDTLS_MD4_C |
| 3036 | +#include <mbedtls/md4.h> |
| 3037 | +int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3038 | +{ |
| 3039 | + return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD4); |
| 3040 | +} |
| 3041 | +#endif |
| 3042 | + |
| 3043 | +#else /* expanded per-message-digest functions */ |
| 3044 | + |
| 3045 | +#ifdef MBEDTLS_SHA512_C |
| 3046 | +#include <mbedtls/sha512.h> |
| 3047 | +__attribute_noinline__ |
| 3048 | +static int sha384_512_vector(size_t num_elem, const u8 *addr[], |
| 3049 | + const size_t *len, u8 *mac, int is384) |
| 3050 | +{ |
| 3051 | + if (TEST_FAIL()) |
| 3052 | + return -1; |
| 3053 | + |
| 3054 | + struct mbedtls_sha512_context ctx; |
| 3055 | + mbedtls_sha512_init(&ctx); |
| 3056 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3057 | + mbedtls_sha512_starts(&ctx, is384); |
| 3058 | + for (size_t i = 0; i < num_elem; ++i) |
| 3059 | + mbedtls_sha512_update(&ctx, addr[i], len[i]); |
| 3060 | + mbedtls_sha512_finish(&ctx, mac); |
| 3061 | + #else |
| 3062 | + mbedtls_sha512_starts_ret(&ctx, is384); |
| 3063 | + for (size_t i = 0; i < num_elem; ++i) |
| 3064 | + mbedtls_sha512_update_ret(&ctx, addr[i], len[i]); |
| 3065 | + mbedtls_sha512_finish_ret(&ctx, mac); |
| 3066 | + #endif |
| 3067 | + mbedtls_sha512_free(&ctx); |
| 3068 | + return 0; |
| 3069 | +} |
| 3070 | + |
| 3071 | +int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3072 | +{ |
| 3073 | + return sha384_512_vector(num_elem, addr, len, mac, 0); |
| 3074 | +} |
| 3075 | + |
| 3076 | +int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3077 | +{ |
| 3078 | + return sha384_512_vector(num_elem, addr, len, mac, 1); |
| 3079 | +} |
| 3080 | +#endif |
| 3081 | + |
| 3082 | +#ifdef MBEDTLS_SHA256_C |
| 3083 | +#include <mbedtls/sha256.h> |
| 3084 | +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3085 | +{ |
| 3086 | + if (TEST_FAIL()) |
| 3087 | + return -1; |
| 3088 | + |
| 3089 | + struct mbedtls_sha256_context ctx; |
| 3090 | + mbedtls_sha256_init(&ctx); |
| 3091 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3092 | + mbedtls_sha256_starts(&ctx, 0); |
| 3093 | + for (size_t i = 0; i < num_elem; ++i) |
| 3094 | + mbedtls_sha256_update(&ctx, addr[i], len[i]); |
| 3095 | + mbedtls_sha256_finish(&ctx, mac); |
| 3096 | + #else |
| 3097 | + mbedtls_sha256_starts_ret(&ctx, 0); |
| 3098 | + for (size_t i = 0; i < num_elem; ++i) |
| 3099 | + mbedtls_sha256_update_ret(&ctx, addr[i], len[i]); |
| 3100 | + mbedtls_sha256_finish_ret(&ctx, mac); |
| 3101 | + #endif |
| 3102 | + mbedtls_sha256_free(&ctx); |
| 3103 | + return 0; |
| 3104 | +} |
| 3105 | +#endif |
| 3106 | + |
| 3107 | +#ifdef MBEDTLS_SHA1_C |
| 3108 | +#include <mbedtls/sha1.h> |
| 3109 | +int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3110 | +{ |
| 3111 | + if (TEST_FAIL()) |
| 3112 | + return -1; |
| 3113 | + |
| 3114 | + struct mbedtls_sha1_context ctx; |
| 3115 | + mbedtls_sha1_init(&ctx); |
| 3116 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3117 | + mbedtls_sha1_starts(&ctx); |
| 3118 | + for (size_t i = 0; i < num_elem; ++i) |
| 3119 | + mbedtls_sha1_update(&ctx, addr[i], len[i]); |
| 3120 | + mbedtls_sha1_finish(&ctx, mac); |
| 3121 | + #else |
| 3122 | + mbedtls_sha1_starts_ret(&ctx); |
| 3123 | + for (size_t i = 0; i < num_elem; ++i) |
| 3124 | + mbedtls_sha1_update_ret(&ctx, addr[i], len[i]); |
| 3125 | + mbedtls_sha1_finish_ret(&ctx, mac); |
| 3126 | + #endif |
| 3127 | + mbedtls_sha1_free(&ctx); |
| 3128 | + return 0; |
| 3129 | +} |
| 3130 | +#endif |
| 3131 | + |
| 3132 | +#ifdef MBEDTLS_MD5_C |
| 3133 | +#include <mbedtls/md5.h> |
| 3134 | +int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3135 | +{ |
| 3136 | + if (TEST_FAIL()) |
| 3137 | + return -1; |
| 3138 | + |
| 3139 | + struct mbedtls_md5_context ctx; |
| 3140 | + mbedtls_md5_init(&ctx); |
| 3141 | + #if MBEDTLS_VERSION_MAJOR >= 3 |
| 3142 | + mbedtls_md5_starts(&ctx); |
| 3143 | + for (size_t i = 0; i < num_elem; ++i) |
| 3144 | + mbedtls_md5_update(&ctx, addr[i], len[i]); |
| 3145 | + mbedtls_md5_finish(&ctx, mac); |
| 3146 | + #else |
| 3147 | + mbedtls_md5_starts_ret(&ctx); |
| 3148 | + for (size_t i = 0; i < num_elem; ++i) |
| 3149 | + mbedtls_md5_update_ret(&ctx, addr[i], len[i]); |
| 3150 | + mbedtls_md5_finish_ret(&ctx, mac); |
| 3151 | + #endif |
| 3152 | + mbedtls_md5_free(&ctx); |
| 3153 | + return 0; |
| 3154 | +} |
| 3155 | +#endif |
| 3156 | + |
| 3157 | +#ifdef MBEDTLS_MD4_C |
| 3158 | +#include <mbedtls/md4.h> |
| 3159 | +int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) |
| 3160 | +{ |
| 3161 | + if (TEST_FAIL()) |
| 3162 | + return -1; |
| 3163 | + |
| 3164 | + struct mbedtls_md4_context ctx; |
| 3165 | + mbedtls_md4_init(&ctx); |
| 3166 | + mbedtls_md4_starts_ret(&ctx); |
| 3167 | + for (size_t i = 0; i < num_elem; ++i) |
| 3168 | + mbedtls_md4_update_ret(&ctx, addr[i], len[i]); |
| 3169 | + mbedtls_md4_finish_ret(&ctx, mac); |
| 3170 | + mbedtls_md4_free(&ctx); |
| 3171 | + return 0; |
| 3172 | +} |
| 3173 | +#endif |
| 3174 | + |
| 3175 | +#endif /* expanded per-message-digest functions */ |
| 3176 | + |
| 3177 | + |
| 3178 | +__attribute_noinline__ |
| 3179 | +static int hmac_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3180 | + const u8 *addr[], const size_t *len, u8 *mac, |
| 3181 | + mbedtls_md_type_t md_type) |
| 3182 | +{ |
| 3183 | + if (TEST_FAIL()) |
| 3184 | + return -1; |
| 3185 | + |
| 3186 | + mbedtls_md_context_t ctx; |
| 3187 | + mbedtls_md_init(&ctx); |
| 3188 | + if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ |
| 3189 | + mbedtls_md_free(&ctx); |
| 3190 | + return -1; |
| 3191 | + } |
| 3192 | + mbedtls_md_hmac_starts(&ctx, key, key_len); |
| 3193 | + for (size_t i = 0; i < num_elem; ++i) |
| 3194 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3195 | + mbedtls_md_hmac_finish(&ctx, mac); |
| 3196 | + mbedtls_md_free(&ctx); |
| 3197 | + return 0; |
| 3198 | +} |
| 3199 | + |
| 3200 | +#ifdef MBEDTLS_SHA512_C |
| 3201 | +int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3202 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3203 | +{ |
| 3204 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3205 | + MBEDTLS_MD_SHA512); |
| 3206 | +} |
| 3207 | + |
| 3208 | +int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3209 | + u8 *mac) |
| 3210 | +{ |
| 3211 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3212 | + MBEDTLS_MD_SHA512); |
| 3213 | +} |
| 3214 | + |
| 3215 | +int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3216 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3217 | +{ |
| 3218 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3219 | + MBEDTLS_MD_SHA384); |
| 3220 | +} |
| 3221 | + |
| 3222 | +int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3223 | + u8 *mac) |
| 3224 | +{ |
| 3225 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3226 | + MBEDTLS_MD_SHA384); |
| 3227 | +} |
| 3228 | +#endif |
| 3229 | + |
| 3230 | +#ifdef MBEDTLS_SHA256_C |
| 3231 | +int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3232 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3233 | +{ |
| 3234 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3235 | + MBEDTLS_MD_SHA256); |
| 3236 | +} |
| 3237 | + |
| 3238 | +int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3239 | + u8 *mac) |
| 3240 | +{ |
| 3241 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3242 | + MBEDTLS_MD_SHA256); |
| 3243 | +} |
| 3244 | +#endif |
| 3245 | + |
| 3246 | +#ifdef MBEDTLS_SHA1_C |
| 3247 | +int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3248 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3249 | +{ |
| 3250 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3251 | + MBEDTLS_MD_SHA1); |
| 3252 | +} |
| 3253 | + |
| 3254 | +int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3255 | + u8 *mac) |
| 3256 | +{ |
| 3257 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3258 | + MBEDTLS_MD_SHA1); |
| 3259 | +} |
| 3260 | +#endif |
| 3261 | + |
| 3262 | +#ifdef MBEDTLS_MD5_C |
| 3263 | +int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, |
| 3264 | + const u8 *addr[], const size_t *len, u8 *mac) |
| 3265 | +{ |
| 3266 | + return hmac_vector(key, key_len, num_elem, addr, len, mac, |
| 3267 | + MBEDTLS_MD_MD5); |
| 3268 | +} |
| 3269 | + |
| 3270 | +int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, |
| 3271 | + u8 *mac) |
| 3272 | +{ |
| 3273 | + return hmac_vector(key, key_len, 1, &data, &data_len, mac, |
| 3274 | + MBEDTLS_MD_MD5); |
| 3275 | +} |
| 3276 | +#endif |
| 3277 | + |
| 3278 | + |
| 3279 | +#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C) |
| 3280 | + |
| 3281 | +#if defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA256) \ |
| 3282 | + || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA384) \ |
| 3283 | + || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA512) |
| 3284 | + |
| 3285 | +#include <mbedtls/hkdf.h> |
| 3286 | + |
| 3287 | +/* sha256-kdf.c sha384-kdf.c sha512-kdf.c */ |
| 3288 | + |
| 3289 | +/* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */ |
| 3290 | +/* HMAC-SHA384 KDF (RFC 5295) and HKDF-Expand(SHA384) (RFC 5869) */ |
| 3291 | +/* HMAC-SHA512 KDF (RFC 5295) and HKDF-Expand(SHA512) (RFC 5869) */ |
| 3292 | +__attribute_noinline__ |
| 3293 | +static int hmac_kdf_expand(const u8 *prk, size_t prk_len, |
| 3294 | + const char *label, const u8 *info, size_t info_len, |
| 3295 | + u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) |
| 3296 | +{ |
| 3297 | + if (TEST_FAIL()) |
| 3298 | + return -1; |
| 3299 | + |
| 3300 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); |
| 3301 | + #ifdef MBEDTLS_HKDF_C |
| 3302 | + if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ |
| 3303 | + return mbedtls_hkdf_expand(md_info, prk, prk_len, info, |
| 3304 | + info_len, okm, okm_len) ? -1 : 0; |
| 3305 | + #endif |
| 3306 | + |
| 3307 | + const size_t mac_len = mbedtls_md_get_size(md_info); |
| 3308 | + /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */ |
| 3309 | + if (okm_len > ((mac_len << 8) - mac_len)) |
| 3310 | + return -1; |
| 3311 | + |
| 3312 | + mbedtls_md_context_t ctx; |
| 3313 | + mbedtls_md_init(&ctx); |
| 3314 | + if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { |
| 3315 | + mbedtls_md_free(&ctx); |
| 3316 | + return -1; |
| 3317 | + } |
| 3318 | + mbedtls_md_hmac_starts(&ctx, prk, prk_len); |
| 3319 | + |
| 3320 | + u8 iter = 1; |
| 3321 | + const u8 *addr[4] = { okm, (const u8 *)label, info, &iter }; |
| 3322 | + size_t len[4] = { 0, label ? os_strlen(label)+1 : 0, info_len, 1 }; |
| 3323 | + |
| 3324 | + for (; okm_len >= mac_len; okm_len -= mac_len, ++iter) { |
| 3325 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3326 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3327 | + mbedtls_md_hmac_finish(&ctx, okm); |
| 3328 | + mbedtls_md_hmac_reset(&ctx); |
| 3329 | + addr[0] = okm; |
| 3330 | + okm += mac_len; |
| 3331 | + len[0] = mac_len; /*(include digest in subsequent rounds)*/ |
| 3332 | + } |
| 3333 | + |
| 3334 | + if (okm_len) { |
| 3335 | + u8 hash[MBEDTLS_MD_MAX_SIZE]; |
| 3336 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3337 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3338 | + mbedtls_md_hmac_finish(&ctx, hash); |
| 3339 | + os_memcpy(okm, hash, okm_len); |
| 3340 | + forced_memzero(hash, mac_len); |
| 3341 | + } |
| 3342 | + |
| 3343 | + mbedtls_md_free(&ctx); |
| 3344 | + return 0; |
| 3345 | +} |
| 3346 | + |
| 3347 | +#ifdef MBEDTLS_SHA512_C |
| 3348 | +#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA512 |
| 3349 | +int hmac_sha512_kdf(const u8 *secret, size_t secret_len, |
| 3350 | + const char *label, const u8 *seed, size_t seed_len, |
| 3351 | + u8 *out, size_t outlen) |
| 3352 | +{ |
| 3353 | + return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, |
| 3354 | + out, outlen, MBEDTLS_MD_SHA512); |
| 3355 | +} |
| 3356 | +#endif |
| 3357 | + |
| 3358 | +#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA384 |
| 3359 | +int hmac_sha384_kdf(const u8 *secret, size_t secret_len, |
| 3360 | + const char *label, const u8 *seed, size_t seed_len, |
| 3361 | + u8 *out, size_t outlen) |
| 3362 | +{ |
| 3363 | + return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, |
| 3364 | + out, outlen, MBEDTLS_MD_SHA384); |
| 3365 | +} |
| 3366 | +#endif |
| 3367 | +#endif |
| 3368 | + |
| 3369 | +#ifdef MBEDTLS_SHA256_C |
| 3370 | +#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA256 |
| 3371 | +int hmac_sha256_kdf(const u8 *secret, size_t secret_len, |
| 3372 | + const char *label, const u8 *seed, size_t seed_len, |
| 3373 | + u8 *out, size_t outlen) |
| 3374 | +{ |
| 3375 | + return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, |
| 3376 | + out, outlen, MBEDTLS_MD_SHA256); |
| 3377 | +} |
| 3378 | +#endif |
| 3379 | +#endif |
| 3380 | + |
| 3381 | +#endif /* CRYPTO_MBEDTLS_HMAC_KDF_* */ |
| 3382 | + |
| 3383 | + |
| 3384 | +/* sha256-prf.c sha384-prf.c sha512-prf.c */ |
| 3385 | + |
| 3386 | +/* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */ |
| 3387 | +__attribute_noinline__ |
| 3388 | +static int hmac_prf_bits(const u8 *key, size_t key_len, const char *label, |
| 3389 | + const u8 *data, size_t data_len, u8 *buf, |
| 3390 | + size_t buf_len_bits, mbedtls_md_type_t md_type) |
| 3391 | +{ |
| 3392 | + if (TEST_FAIL()) |
| 3393 | + return -1; |
| 3394 | + |
| 3395 | + mbedtls_md_context_t ctx; |
| 3396 | + mbedtls_md_init(&ctx); |
| 3397 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); |
| 3398 | + if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { |
| 3399 | + mbedtls_md_free(&ctx); |
| 3400 | + return -1; |
| 3401 | + } |
| 3402 | + mbedtls_md_hmac_starts(&ctx, key, key_len); |
| 3403 | + |
| 3404 | + u16 ctr, n_le = host_to_le16(buf_len_bits); |
| 3405 | + const u8 * const addr[] = { (u8 *)&ctr,(u8 *)label,data,(u8 *)&n_le }; |
| 3406 | + const size_t len[] = { 2, os_strlen(label), data_len, 2 }; |
| 3407 | + const size_t mac_len = mbedtls_md_get_size(md_info); |
| 3408 | + size_t buf_len = (buf_len_bits + 7) / 8; |
| 3409 | + for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) { |
| 3410 | + #if __BYTE_ORDER == __BIG_ENDIAN |
| 3411 | + ctr = host_to_le16(ctr); |
| 3412 | + #endif |
| 3413 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3414 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3415 | + mbedtls_md_hmac_finish(&ctx, buf); |
| 3416 | + mbedtls_md_hmac_reset(&ctx); |
| 3417 | + buf += mac_len; |
| 3418 | + #if __BYTE_ORDER == __BIG_ENDIAN |
| 3419 | + ctr = le_to_host16(ctr); |
| 3420 | + #endif |
| 3421 | + } |
| 3422 | + |
| 3423 | + if (buf_len) { |
| 3424 | + u8 hash[MBEDTLS_MD_MAX_SIZE]; |
| 3425 | + #if __BYTE_ORDER == __BIG_ENDIAN |
| 3426 | + ctr = host_to_le16(ctr); |
| 3427 | + #endif |
| 3428 | + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) |
| 3429 | + mbedtls_md_hmac_update(&ctx, addr[i], len[i]); |
| 3430 | + mbedtls_md_hmac_finish(&ctx, hash); |
| 3431 | + os_memcpy(buf, hash, buf_len); |
| 3432 | + buf += buf_len; |
| 3433 | + forced_memzero(hash, mac_len); |
| 3434 | + } |
| 3435 | + |
| 3436 | + /* Mask out unused bits in last octet if it does not use all the bits */ |
| 3437 | + if ((buf_len_bits &= 0x7)) |
| 3438 | + buf[-1] &= (u8)(0xff << (8 - buf_len_bits)); |
| 3439 | + |
| 3440 | + mbedtls_md_free(&ctx); |
| 3441 | + return 0; |
| 3442 | +} |
| 3443 | + |
| 3444 | +#ifdef MBEDTLS_SHA512_C |
| 3445 | +int sha512_prf(const u8 *key, size_t key_len, const char *label, |
| 3446 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3447 | +{ |
| 3448 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3449 | + buf_len * 8, MBEDTLS_MD_SHA512); |
| 3450 | +} |
| 3451 | + |
| 3452 | +int sha384_prf(const u8 *key, size_t key_len, const char *label, |
| 3453 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3454 | +{ |
| 3455 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3456 | + buf_len * 8, MBEDTLS_MD_SHA384); |
| 3457 | +} |
| 3458 | +#endif |
| 3459 | + |
| 3460 | +#ifdef MBEDTLS_SHA256_C |
| 3461 | +int sha256_prf(const u8 *key, size_t key_len, const char *label, |
| 3462 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3463 | +{ |
| 3464 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3465 | + buf_len * 8, MBEDTLS_MD_SHA256); |
| 3466 | +} |
| 3467 | + |
| 3468 | +int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, |
| 3469 | + const u8 *data, size_t data_len, u8 *buf, |
| 3470 | + size_t buf_len_bits) |
| 3471 | +{ |
| 3472 | + return hmac_prf_bits(key, key_len, label, data, data_len, buf, |
| 3473 | + buf_len_bits, MBEDTLS_MD_SHA256); |
| 3474 | +} |
| 3475 | +#endif |
| 3476 | + |
| 3477 | +#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */ |
| 3478 | + |
| 3479 | + |
| 3480 | +#ifdef MBEDTLS_SHA1_C |
| 3481 | + |
| 3482 | +/* sha1-prf.c */ |
| 3483 | + |
| 3484 | +/* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) */ |
| 3485 | + |
| 3486 | +int sha1_prf(const u8 *key, size_t key_len, const char *label, |
| 3487 | + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) |
| 3488 | +{ |
| 3489 | + /*(note: algorithm differs from hmac_prf_bits() */ |
| 3490 | + /*(note: smaller code size instead of expanding hmac_sha1_vector() |
| 3491 | + * as is done in hmac_prf_bits(); not expecting large num of loops) */ |
| 3492 | + u8 counter = 0; |
| 3493 | + const u8 *addr[] = { (u8 *)label, data, &counter }; |
| 3494 | + const size_t len[] = { os_strlen(label)+1, data_len, 1 }; |
| 3495 | + |
| 3496 | + for (; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++counter) { |
| 3497 | + if (hmac_sha1_vector(key, key_len, 3, addr, len, buf)) |
| 3498 | + return -1; |
| 3499 | + buf += SHA1_MAC_LEN; |
| 3500 | + } |
| 3501 | + |
| 3502 | + if (buf_len) { |
| 3503 | + u8 hash[SHA1_MAC_LEN]; |
| 3504 | + if (hmac_sha1_vector(key, key_len, 3, addr, len, hash)) |
| 3505 | + return -1; |
| 3506 | + os_memcpy(buf, hash, buf_len); |
| 3507 | + forced_memzero(hash, sizeof(hash)); |
| 3508 | + } |
| 3509 | + |
| 3510 | + return 0; |
| 3511 | +} |
| 3512 | + |
| 3513 | +#ifdef CRYPTO_MBEDTLS_SHA1_T_PRF |
| 3514 | + |
| 3515 | +/* sha1-tprf.c */ |
| 3516 | + |
| 3517 | +/* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) (RFC 4851,Section 5.5)*/ |
| 3518 | + |
| 3519 | +int sha1_t_prf(const u8 *key, size_t key_len, const char *label, |
| 3520 | + const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) |
| 3521 | +{ |
| 3522 | + /*(note: algorithm differs from hmac_prf_bits() and hmac_kdf() above)*/ |
| 3523 | + /*(note: smaller code size instead of expanding hmac_sha1_vector() |
| 3524 | + * as is done in hmac_prf_bits(); not expecting large num of loops) */ |
| 3525 | + u8 ctr; |
| 3526 | + u16 olen = host_to_be16(buf_len); |
| 3527 | + const u8 *addr[] = { buf, (u8 *)label, seed, (u8 *)&olen, &ctr }; |
| 3528 | + size_t len[] = { 0, os_strlen(label)+1, seed_len, 2, 1 }; |
| 3529 | + |
| 3530 | + for (ctr = 1; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++ctr) { |
| 3531 | + if (hmac_sha1_vector(key, key_len, 5, addr, len, buf)) |
| 3532 | + return -1; |
| 3533 | + addr[0] = buf; |
| 3534 | + buf += SHA1_MAC_LEN; |
| 3535 | + len[0] = SHA1_MAC_LEN; /*(include digest in subsequent rounds)*/ |
| 3536 | + } |
| 3537 | + |
| 3538 | + if (buf_len) { |
| 3539 | + u8 hash[SHA1_MAC_LEN]; |
| 3540 | + if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) |
| 3541 | + return -1; |
| 3542 | + os_memcpy(buf, hash, buf_len); |
| 3543 | + forced_memzero(hash, sizeof(hash)); |
| 3544 | + } |
| 3545 | + |
| 3546 | + return 0; |
| 3547 | +} |
| 3548 | + |
| 3549 | +#endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ |
| 3550 | + |
| 3551 | +#ifdef CRYPTO_MBEDTLS_FIPS186_2_PRF |
| 3552 | + |
| 3553 | +/* fips_prf_internal.c sha1-internal.c */ |
| 3554 | + |
| 3555 | +/* used only by src/eap_common/eap_sim_common.c:eap_sim_prf() |
| 3556 | + * for eap_sim_derive_keys() and eap_sim_derive_keys_reauth() |
| 3557 | + * where xlen is 160 */ |
| 3558 | + |
| 3559 | +int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) |
| 3560 | +{ |
| 3561 | + /* FIPS 186-2 + change notice 1 */ |
| 3562 | + |
| 3563 | + mbedtls_sha1_context ctx; |
| 3564 | + u8 * const xkey = ctx.MBEDTLS_PRIVATE(buffer); |
| 3565 | + u32 * const xstate = ctx.MBEDTLS_PRIVATE(state); |
| 3566 | + const u32 xstate_init[] = |
| 3567 | + { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; |
| 3568 | + |
| 3569 | + mbedtls_sha1_init(&ctx); |
| 3570 | + os_memcpy(xkey, seed, seed_len < 64 ? seed_len : 64); |
| 3571 | + |
| 3572 | + /* note: does not fill extra bytes if (xlen % 20) (SHA1_MAC_LEN) */ |
| 3573 | + for (; xlen >= 20; xlen -= 20) { |
| 3574 | + /* XSEED_j = 0 */ |
| 3575 | + /* XVAL = (XKEY + XSEED_j) mod 2^b */ |
| 3576 | + |
| 3577 | + /* w_i = G(t, XVAL) */ |
| 3578 | + os_memcpy(xstate, xstate_init, sizeof(xstate_init)); |
| 3579 | + mbedtls_internal_sha1_process(&ctx, xkey); |
| 3580 | + |
| 3581 | + #if __BYTE_ORDER == __LITTLE_ENDIAN |
| 3582 | + xstate[0] = host_to_be32(xstate[0]); |
| 3583 | + xstate[1] = host_to_be32(xstate[1]); |
| 3584 | + xstate[2] = host_to_be32(xstate[2]); |
| 3585 | + xstate[3] = host_to_be32(xstate[3]); |
| 3586 | + xstate[4] = host_to_be32(xstate[4]); |
| 3587 | + #endif |
| 3588 | + os_memcpy(x, xstate, 20); |
| 3589 | + if (xlen == 20) /*(done; skip prep for next loop)*/ |
| 3590 | + break; |
| 3591 | + |
| 3592 | + /* XKEY = (1 + XKEY + w_i) mod 2^b */ |
| 3593 | + for (u32 carry = 1, k = 20; k-- > 0; carry >>= 8) |
| 3594 | + xkey[k] = (carry += xkey[k] + x[k]) & 0xff; |
| 3595 | + x += 20; |
| 3596 | + /* x_j = w_0|w_1 (each pair of iterations through loop)*/ |
| 3597 | + } |
| 3598 | + |
| 3599 | + mbedtls_sha1_free(&ctx); |
| 3600 | + return 0; |
| 3601 | +} |
| 3602 | + |
| 3603 | +#endif /* CRYPTO_MBEDTLS_FIPS186_2_PRF */ |
| 3604 | + |
| 3605 | +#endif /* MBEDTLS_SHA1_C */ |
| 3606 | + |
| 3607 | + |
| 3608 | +#ifdef CRYPTO_MBEDTLS_DES_ENCRYPT |
| 3609 | +#ifdef MBEDTLS_DES_C |
| 3610 | +#include <mbedtls/des.h> |
| 3611 | +int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) |
| 3612 | +{ |
| 3613 | + u8 pkey[8], next, tmp; |
| 3614 | + int i; |
| 3615 | + |
| 3616 | + /* Add parity bits to the key */ |
| 3617 | + next = 0; |
| 3618 | + for (i = 0; i < 7; i++) { |
| 3619 | + tmp = key[i]; |
| 3620 | + pkey[i] = (tmp >> i) | next | 1; |
| 3621 | + next = tmp << (7 - i); |
| 3622 | + } |
| 3623 | + pkey[i] = next | 1; |
| 3624 | + |
| 3625 | + mbedtls_des_context des; |
| 3626 | + mbedtls_des_init(&des); |
| 3627 | + int ret = mbedtls_des_setkey_enc(&des, pkey) |
| 3628 | + || mbedtls_des_crypt_ecb(&des, clear, cypher) ? -1 : 0; |
| 3629 | + mbedtls_des_free(&des); |
| 3630 | + return ret; |
| 3631 | +} |
| 3632 | +#else |
| 3633 | +#include "des-internal.c"/* pull in hostap local implementation */ |
| 3634 | +#endif |
| 3635 | +#endif |
| 3636 | + |
| 3637 | + |
| 3638 | +#ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1 |
| 3639 | +/* sha1-pbkdf2.c */ |
| 3640 | +#include <mbedtls/pkcs5.h> |
| 3641 | +int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, |
| 3642 | + int iterations, u8 *buf, size_t buflen) |
| 3643 | +{ |
| 3644 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020200 /* mbedtls 3.2.2 */ |
| 3645 | + return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, |
| 3646 | + (const u8 *)passphrase, os_strlen(passphrase), |
| 3647 | + ssid, ssid_len, iterations, 32, buf) ? -1 : 0; |
| 3648 | + #else |
| 3649 | + const mbedtls_md_info_t *md_info; |
| 3650 | + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); |
| 3651 | + if (md_info == NULL) |
| 3652 | + return -1; |
| 3653 | + mbedtls_md_context_t ctx; |
| 3654 | + mbedtls_md_init(&ctx); |
| 3655 | + int ret = mbedtls_md_setup(&ctx, md_info, 1) |
| 3656 | + || mbedtls_pkcs5_pbkdf2_hmac(&ctx, |
| 3657 | + (const u8 *)passphrase, os_strlen(passphrase), |
| 3658 | + ssid, ssid_len, iterations, 32, buf) ? -1 : 0; |
| 3659 | + mbedtls_md_free(&ctx); |
| 3660 | + return ret; |
| 3661 | + #endif |
| 3662 | +} |
| 3663 | +#endif |
| 3664 | + |
| 3665 | + |
| 3666 | +/*#include "aes.h"*/ /* prototypes also included in "crypto.h" */ |
| 3667 | + |
| 3668 | +static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) |
| 3669 | +{ |
| 3670 | + if (TEST_FAIL()) |
| 3671 | + return NULL; |
| 3672 | + |
| 3673 | + mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); |
| 3674 | + if (!aes) |
| 3675 | + return NULL; |
| 3676 | + |
| 3677 | + mbedtls_aes_init(aes); |
| 3678 | + if ((mode == MBEDTLS_AES_ENCRYPT |
| 3679 | + ? mbedtls_aes_setkey_enc(aes, key, len * 8) |
| 3680 | + : mbedtls_aes_setkey_dec(aes, key, len * 8)) == 0) |
| 3681 | + return aes; |
| 3682 | + |
| 3683 | + mbedtls_aes_free(aes); |
| 3684 | + os_free(aes); |
| 3685 | + return NULL; |
| 3686 | +} |
| 3687 | + |
| 3688 | +void *aes_encrypt_init(const u8 *key, size_t len) |
| 3689 | +{ |
| 3690 | + return aes_crypt_init_mode(key, len, MBEDTLS_AES_ENCRYPT); |
| 3691 | +} |
| 3692 | + |
| 3693 | +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) |
| 3694 | +{ |
| 3695 | + return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt); |
| 3696 | +} |
| 3697 | + |
| 3698 | +void aes_encrypt_deinit(void *ctx) |
| 3699 | +{ |
| 3700 | + mbedtls_aes_free(ctx); |
| 3701 | + os_free(ctx); |
| 3702 | +} |
| 3703 | + |
| 3704 | +void *aes_decrypt_init(const u8 *key, size_t len) |
| 3705 | +{ |
| 3706 | + return aes_crypt_init_mode(key, len, MBEDTLS_AES_DECRYPT); |
| 3707 | +} |
| 3708 | + |
| 3709 | +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) |
| 3710 | +{ |
| 3711 | + return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_DECRYPT, crypt, plain); |
| 3712 | +} |
| 3713 | + |
| 3714 | +void aes_decrypt_deinit(void *ctx) |
| 3715 | +{ |
| 3716 | + mbedtls_aes_free(ctx); |
| 3717 | + os_free(ctx); |
| 3718 | +} |
| 3719 | + |
| 3720 | + |
| 3721 | +#include "aes_wrap.h" |
| 3722 | + |
| 3723 | + |
| 3724 | +#ifdef MBEDTLS_NIST_KW_C |
| 3725 | + |
| 3726 | +#include <mbedtls/nist_kw.h> |
| 3727 | + |
| 3728 | +/* aes-wrap.c */ |
| 3729 | +int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) |
| 3730 | +{ |
| 3731 | + if (TEST_FAIL()) |
| 3732 | + return -1; |
| 3733 | + |
| 3734 | + mbedtls_nist_kw_context ctx; |
| 3735 | + mbedtls_nist_kw_init(&ctx); |
| 3736 | + size_t olen; |
| 3737 | + int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, |
| 3738 | + kek, kek_len*8, 1) |
| 3739 | + || mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n*8, |
| 3740 | + cipher, &olen, (n+1)*8) ? -1 : 0; |
| 3741 | + mbedtls_nist_kw_free(&ctx); |
| 3742 | + return ret; |
| 3743 | +} |
| 3744 | + |
| 3745 | +/* aes-unwrap.c */ |
| 3746 | +int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) |
| 3747 | +{ |
| 3748 | + if (TEST_FAIL()) |
| 3749 | + return -1; |
| 3750 | + |
| 3751 | + mbedtls_nist_kw_context ctx; |
| 3752 | + mbedtls_nist_kw_init(&ctx); |
| 3753 | + size_t olen; |
| 3754 | + int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, |
| 3755 | + kek, kek_len*8, 0) |
| 3756 | + || mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, |
| 3757 | + (n+1)*8, plain, &olen, n*8) ? -1 : 0; |
| 3758 | + mbedtls_nist_kw_free(&ctx); |
| 3759 | + return ret; |
| 3760 | +} |
| 3761 | + |
| 3762 | +#else |
| 3763 | + |
| 3764 | +#ifndef CRYPTO_MBEDTLS_CONFIG_FIPS |
| 3765 | +#include "aes-wrap.c" /* pull in hostap local implementation */ |
| 3766 | +#include "aes-unwrap.c" /* pull in hostap local implementation */ |
| 3767 | +#endif |
| 3768 | + |
| 3769 | +#endif /* MBEDTLS_NIST_KW_C */ |
| 3770 | + |
| 3771 | + |
| 3772 | +#ifdef MBEDTLS_CMAC_C |
| 3773 | + |
| 3774 | +/* aes-omac1.c */ |
| 3775 | + |
| 3776 | +#include <mbedtls/cmac.h> |
| 3777 | + |
| 3778 | +int omac1_aes_vector( |
| 3779 | + const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], |
| 3780 | + const size_t *len, u8 *mac) |
| 3781 | +{ |
| 3782 | + if (TEST_FAIL()) |
| 3783 | + return -1; |
| 3784 | + |
| 3785 | + mbedtls_cipher_type_t cipher_type; |
| 3786 | + switch (key_len) { |
| 3787 | + case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; |
| 3788 | + case 24: cipher_type = MBEDTLS_CIPHER_AES_192_ECB; break; |
| 3789 | + case 32: cipher_type = MBEDTLS_CIPHER_AES_256_ECB; break; |
| 3790 | + default: return -1; |
| 3791 | + } |
| 3792 | + const mbedtls_cipher_info_t *cipher_info; |
| 3793 | + cipher_info = mbedtls_cipher_info_from_type(cipher_type); |
| 3794 | + if (cipher_info == NULL) |
| 3795 | + return -1; |
| 3796 | + |
| 3797 | + mbedtls_cipher_context_t ctx; |
| 3798 | + mbedtls_cipher_init(&ctx); |
| 3799 | + int ret = -1; |
| 3800 | + if (mbedtls_cipher_setup(&ctx, cipher_info) == 0 |
| 3801 | + && mbedtls_cipher_cmac_starts(&ctx, key, key_len*8) == 0) { |
| 3802 | + ret = 0; |
| 3803 | + for (size_t i = 0; i < num_elem && ret == 0; ++i) |
| 3804 | + ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); |
| 3805 | + } |
| 3806 | + if (ret == 0) |
| 3807 | + ret = mbedtls_cipher_cmac_finish(&ctx, mac); |
| 3808 | + mbedtls_cipher_free(&ctx); |
| 3809 | + return ret ? -1 : 0; |
| 3810 | +} |
| 3811 | + |
| 3812 | +int omac1_aes_128_vector(const u8 *key, size_t num_elem, |
| 3813 | + const u8 *addr[], const size_t *len, |
| 3814 | + u8 *mac) |
| 3815 | +{ |
| 3816 | + return omac1_aes_vector(key, 16, num_elem, addr, len, mac); |
| 3817 | +} |
| 3818 | + |
| 3819 | +int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) |
| 3820 | +{ |
| 3821 | + return omac1_aes_vector(key, 16, 1, &data, &data_len, mac); |
| 3822 | +} |
| 3823 | + |
| 3824 | +int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) |
| 3825 | +{ |
| 3826 | + return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); |
| 3827 | +} |
| 3828 | + |
| 3829 | +#else |
| 3830 | + |
| 3831 | +#include "aes-omac1.c" /* pull in hostap local implementation */ |
| 3832 | + |
| 3833 | +#ifndef MBEDTLS_AES_BLOCK_SIZE |
| 3834 | +#define MBEDTLS_AES_BLOCK_SIZE 16 |
| 3835 | +#endif |
| 3836 | + |
| 3837 | +#endif /* MBEDTLS_CMAC_C */ |
| 3838 | + |
| 3839 | + |
| 3840 | +/* These interfaces can be inefficient when used in loops, as the overhead of |
| 3841 | + * initialization each call is large for each block input (e.g. 16 bytes) */ |
| 3842 | + |
| 3843 | + |
| 3844 | +/* aes-encblock.c */ |
| 3845 | +int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) |
| 3846 | +{ |
| 3847 | + if (TEST_FAIL()) |
| 3848 | + return -1; |
| 3849 | + |
| 3850 | + mbedtls_aes_context aes; |
| 3851 | + mbedtls_aes_init(&aes); |
| 3852 | + int ret = mbedtls_aes_setkey_enc(&aes, key, 128) |
| 3853 | + || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out) |
| 3854 | + ? -1 |
| 3855 | + : 0; |
| 3856 | + mbedtls_aes_free(&aes); |
| 3857 | + return ret; |
| 3858 | +} |
| 3859 | + |
| 3860 | + |
| 3861 | +/* aes-ctr.c */ |
| 3862 | +int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, |
| 3863 | + u8 *data, size_t data_len) |
| 3864 | +{ |
| 3865 | + if (TEST_FAIL()) |
| 3866 | + return -1; |
| 3867 | + |
| 3868 | + unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; |
| 3869 | + unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; |
| 3870 | + os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ |
| 3871 | + |
| 3872 | + mbedtls_aes_context ctx; |
| 3873 | + mbedtls_aes_init(&ctx); |
| 3874 | + size_t nc_off = 0; |
| 3875 | + int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len*8) |
| 3876 | + || mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off, |
| 3877 | + counter, stream_block, |
| 3878 | + data, data) ? -1 : 0; |
| 3879 | + forced_memzero(stream_block, sizeof(stream_block)); |
| 3880 | + mbedtls_aes_free(&ctx); |
| 3881 | + return ret; |
| 3882 | +} |
| 3883 | + |
| 3884 | +int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, |
| 3885 | + u8 *data, size_t data_len) |
| 3886 | +{ |
| 3887 | + return aes_ctr_encrypt(key, 16, nonce, data, data_len); |
| 3888 | +} |
| 3889 | + |
| 3890 | + |
| 3891 | +/* aes-cbc.c */ |
| 3892 | +static int aes_128_cbc_oper(const u8 *key, const u8 *iv, |
| 3893 | + u8 *data, size_t data_len, int mode) |
| 3894 | +{ |
| 3895 | + unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE]; |
| 3896 | + os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/ |
| 3897 | + |
| 3898 | + mbedtls_aes_context ctx; |
| 3899 | + mbedtls_aes_init(&ctx); |
| 3900 | + int ret = (mode == MBEDTLS_AES_ENCRYPT |
| 3901 | + ? mbedtls_aes_setkey_enc(&ctx, key, 128) |
| 3902 | + : mbedtls_aes_setkey_dec(&ctx, key, 128)) |
| 3903 | + || mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data); |
| 3904 | + mbedtls_aes_free(&ctx); |
| 3905 | + return ret ? -1 : 0; |
| 3906 | +} |
| 3907 | + |
| 3908 | +int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) |
| 3909 | +{ |
| 3910 | + if (TEST_FAIL()) |
| 3911 | + return -1; |
| 3912 | + |
| 3913 | + return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); |
| 3914 | +} |
| 3915 | + |
| 3916 | +int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) |
| 3917 | +{ |
| 3918 | + if (TEST_FAIL()) |
| 3919 | + return -1; |
| 3920 | + |
| 3921 | + return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); |
| 3922 | +} |
| 3923 | + |
| 3924 | + |
| 3925 | +/* |
| 3926 | + * Much of the following is documented in crypto.h as for CONFIG_TLS=internal |
| 3927 | + * but such comments are not accurate: |
| 3928 | + * |
| 3929 | + * "This function is only used with internal TLSv1 implementation |
| 3930 | + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need |
| 3931 | + * to implement this." |
| 3932 | + */ |
| 3933 | + |
| 3934 | + |
| 3935 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_CIPHER |
| 3936 | + |
| 3937 | +#include <mbedtls/cipher.h> |
| 3938 | + |
| 3939 | +struct crypto_cipher |
| 3940 | +{ |
| 3941 | + mbedtls_cipher_context_t ctx_enc; |
| 3942 | + mbedtls_cipher_context_t ctx_dec; |
| 3943 | +}; |
| 3944 | + |
| 3945 | +struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, |
| 3946 | + const u8 *iv, const u8 *key, |
| 3947 | + size_t key_len) |
| 3948 | +{ |
| 3949 | + /* IKEv2 src/eap_common/ikev2_common.c:ikev2_{encr,decr}_encrypt() |
| 3950 | + * uses one of CRYPTO_CIPHER_ALG_AES or CRYPTO_CIPHER_ALG_3DES */ |
| 3951 | + |
| 3952 | + mbedtls_cipher_type_t cipher_type; |
| 3953 | + size_t iv_len; |
| 3954 | + switch (alg) { |
| 3955 | + #ifdef MBEDTLS_ARC4_C |
| 3956 | + #if 0 |
| 3957 | + case CRYPTO_CIPHER_ALG_RC4: |
| 3958 | + cipher_type = MBEDTLS_CIPHER_ARC4_128; |
| 3959 | + iv_len = 0; |
| 3960 | + break; |
| 3961 | + #endif |
| 3962 | + #endif |
| 3963 | + #ifdef MBEDTLS_AES_C |
| 3964 | + case CRYPTO_CIPHER_ALG_AES: |
| 3965 | + if (key_len == 16) cipher_type = MBEDTLS_CIPHER_AES_128_CTR; |
| 3966 | + if (key_len == 24) cipher_type = MBEDTLS_CIPHER_AES_192_CTR; |
| 3967 | + if (key_len == 32) cipher_type = MBEDTLS_CIPHER_AES_256_CTR; |
| 3968 | + iv_len = 16; |
| 3969 | + break; |
| 3970 | + #endif |
| 3971 | + #ifdef MBEDTLS_DES_C |
| 3972 | + case CRYPTO_CIPHER_ALG_3DES: |
| 3973 | + cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC; |
| 3974 | + iv_len = 8; |
| 3975 | + break; |
| 3976 | + #if 0 |
| 3977 | + case CRYPTO_CIPHER_ALG_DES: |
| 3978 | + cipher_type = MBEDTLS_CIPHER_DES_CBC; |
| 3979 | + iv_len = 8; |
| 3980 | + break; |
| 3981 | + #endif |
| 3982 | + #endif |
| 3983 | + default: |
| 3984 | + return NULL; |
| 3985 | + } |
| 3986 | + |
| 3987 | + const mbedtls_cipher_info_t *cipher_info; |
| 3988 | + cipher_info = mbedtls_cipher_info_from_type(cipher_type); |
| 3989 | + if (cipher_info == NULL) |
| 3990 | + return NULL; |
| 3991 | + |
| 3992 | + key_len *= 8; /* key_bitlen */ |
| 3993 | + #if 0 /*(were key_bitlen not already available)*/ |
| 3994 | + #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ |
| 3995 | + key_len = mbedtls_cipher_info_get_key_bitlen(cipher_info); |
| 3996 | + #else |
| 3997 | + key_len = cipher_info->MBEDTLS_PRIVATE(key_bitlen); |
| 3998 | + #endif |
| 3999 | + #endif |
| 4000 | + |
| 4001 | + #if 0 /*(were iv_len not known above, would need MBEDTLS_PRIVATE(iv_size))*/ |
| 4002 | + iv_len = cipher_info->MBEDTLS_PRIVATE(iv_size); |
| 4003 | + #endif |
| 4004 | + |
| 4005 | + struct crypto_cipher *ctx = os_malloc(sizeof(*ctx)); |
| 4006 | + if (!ctx) |
| 4007 | + return NULL; |
| 4008 | + |
| 4009 | + mbedtls_cipher_init(&ctx->ctx_enc); |
| 4010 | + mbedtls_cipher_init(&ctx->ctx_dec); |
| 4011 | + if ( mbedtls_cipher_setup(&ctx->ctx_enc,cipher_info) == 0 |
| 4012 | + && mbedtls_cipher_setup(&ctx->ctx_dec,cipher_info) == 0 |
| 4013 | + && mbedtls_cipher_setkey(&ctx->ctx_enc,key,key_len,MBEDTLS_ENCRYPT) == 0 |
| 4014 | + && mbedtls_cipher_setkey(&ctx->ctx_dec,key,key_len,MBEDTLS_DECRYPT) == 0 |
| 4015 | + && mbedtls_cipher_set_iv(&ctx->ctx_enc,iv,iv_len) == 0 |
| 4016 | + && mbedtls_cipher_set_iv(&ctx->ctx_dec,iv,iv_len) == 0 |
| 4017 | + && mbedtls_cipher_reset(&ctx->ctx_enc) == 0 |
| 4018 | + && mbedtls_cipher_reset(&ctx->ctx_dec) == 0) { |
| 4019 | + return ctx; |
| 4020 | + } |
| 4021 | + |
| 4022 | + mbedtls_cipher_free(&ctx->ctx_enc); |
| 4023 | + mbedtls_cipher_free(&ctx->ctx_dec); |
| 4024 | + os_free(ctx); |
| 4025 | + return NULL; |
| 4026 | +} |
| 4027 | + |
| 4028 | +int crypto_cipher_encrypt(struct crypto_cipher *ctx, |
| 4029 | + const u8 *plain, u8 *crypt, size_t len) |
| 4030 | +{ |
| 4031 | + size_t olen = 0; /*(poor interface above; unknown size of u8 *crypt)*/ |
| 4032 | + return (mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen) |
| 4033 | + || mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen)) ? -1 : 0; |
| 4034 | +} |
| 4035 | + |
| 4036 | +int crypto_cipher_decrypt(struct crypto_cipher *ctx, |
| 4037 | + const u8 *crypt, u8 *plain, size_t len) |
| 4038 | +{ |
| 4039 | + size_t olen = 0; /*(poor interface above; unknown size of u8 *plain)*/ |
| 4040 | + return (mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen) |
| 4041 | + || mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen)) ? -1 : 0; |
| 4042 | +} |
| 4043 | + |
| 4044 | +void crypto_cipher_deinit(struct crypto_cipher *ctx) |
| 4045 | +{ |
| 4046 | + mbedtls_cipher_free(&ctx->ctx_enc); |
| 4047 | + mbedtls_cipher_free(&ctx->ctx_dec); |
| 4048 | + os_free(ctx); |
| 4049 | +} |
| 4050 | + |
| 4051 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_CIPHER */ |
| 4052 | + |
| 4053 | + |
| 4054 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_HASH |
| 4055 | + |
| 4056 | +struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, |
| 4057 | + size_t key_len) |
| 4058 | +{ |
| 4059 | + mbedtls_md_type_t md_type; |
| 4060 | + int is_hmac = 0; |
| 4061 | + |
| 4062 | + switch (alg) { |
| 4063 | + #ifdef MBEDTLS_MD5_C |
| 4064 | + case CRYPTO_HASH_ALG_MD5: |
| 4065 | + md_type = MBEDTLS_MD_MD5; |
| 4066 | + break; |
| 4067 | + #endif |
| 4068 | + #ifdef MBEDTLS_SHA1_C |
| 4069 | + case CRYPTO_HASH_ALG_SHA1: |
| 4070 | + md_type = MBEDTLS_MD_SHA1; |
| 4071 | + break; |
| 4072 | + #endif |
| 4073 | + #ifdef MBEDTLS_MD5_C |
| 4074 | + case CRYPTO_HASH_ALG_HMAC_MD5: |
| 4075 | + md_type = MBEDTLS_MD_MD5; |
| 4076 | + is_hmac = 1; |
| 4077 | + break; |
| 4078 | + #endif |
| 4079 | + #ifdef MBEDTLS_SHA1_C |
| 4080 | + case CRYPTO_HASH_ALG_HMAC_SHA1: |
| 4081 | + md_type = MBEDTLS_MD_SHA1; |
| 4082 | + is_hmac = 1; |
| 4083 | + break; |
| 4084 | + #endif |
| 4085 | + #ifdef MBEDTLS_SHA256_C |
| 4086 | + case CRYPTO_HASH_ALG_SHA256: |
| 4087 | + md_type = MBEDTLS_MD_SHA256; |
| 4088 | + break; |
| 4089 | + case CRYPTO_HASH_ALG_HMAC_SHA256: |
| 4090 | + md_type = MBEDTLS_MD_SHA256; |
| 4091 | + is_hmac = 1; |
| 4092 | + break; |
| 4093 | + #endif |
| 4094 | + #ifdef MBEDTLS_SHA512_C |
| 4095 | + case CRYPTO_HASH_ALG_SHA384: |
| 4096 | + md_type = MBEDTLS_MD_SHA384; |
| 4097 | + break; |
| 4098 | + case CRYPTO_HASH_ALG_SHA512: |
| 4099 | + md_type = MBEDTLS_MD_SHA512; |
| 4100 | + break; |
| 4101 | + #endif |
| 4102 | + default: |
| 4103 | + return NULL; |
| 4104 | + } |
| 4105 | + |
| 4106 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); |
| 4107 | + if (!md_info) |
| 4108 | + return NULL; |
| 4109 | + |
| 4110 | + mbedtls_md_context_t *mctx = os_malloc(sizeof(*mctx)); |
| 4111 | + if (mctx == NULL) |
| 4112 | + return NULL; |
| 4113 | + |
| 4114 | + mbedtls_md_init(mctx); |
| 4115 | + if (mbedtls_md_setup(mctx, md_info, is_hmac) != 0) { |
| 4116 | + os_free(mctx); |
| 4117 | + return NULL; |
| 4118 | + } |
| 4119 | + |
| 4120 | + if (is_hmac) |
| 4121 | + mbedtls_md_hmac_starts(mctx, key, key_len); |
| 4122 | + else |
| 4123 | + mbedtls_md_starts(mctx); |
| 4124 | + return (struct crypto_hash *)((uintptr_t)mctx | is_hmac); |
| 4125 | +} |
| 4126 | + |
| 4127 | +void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) |
| 4128 | +{ |
| 4129 | + mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); |
| 4130 | + #if 0 |
| 4131 | + /*(mbedtls_md_hmac_update() and mbedtls_md_update() |
| 4132 | + * make same modifications under the hood in mbedtls)*/ |
| 4133 | + if ((uintptr_t)ctx & 1uL) |
| 4134 | + mbedtls_md_hmac_update(mctx, data, len); |
| 4135 | + else |
| 4136 | + #endif |
| 4137 | + mbedtls_md_update(mctx, data, len); |
| 4138 | +} |
| 4139 | + |
| 4140 | +int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) |
| 4141 | +{ |
| 4142 | + mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); |
| 4143 | + if (mac != NULL && len != NULL) { /*(NULL if caller just freeing context)*/ |
| 4144 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 4145 | + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_ctx(mctx); |
| 4146 | + #else |
| 4147 | + const mbedtls_md_info_t *md_info = mctx->MBEDTLS_PRIVATE(md_info); |
| 4148 | + #endif |
| 4149 | + size_t maclen = mbedtls_md_get_size(md_info); |
| 4150 | + if (*len < maclen) { |
| 4151 | + *len = maclen; |
| 4152 | + /*(note: ctx not freed; can call again with larger *len)*/ |
| 4153 | + return -1; |
| 4154 | + } |
| 4155 | + *len = maclen; |
| 4156 | + if ((uintptr_t)ctx & 1uL) |
| 4157 | + mbedtls_md_hmac_finish(mctx, mac); |
| 4158 | + else |
| 4159 | + mbedtls_md_finish(mctx, mac); |
| 4160 | + } |
| 4161 | + mbedtls_md_free(mctx); |
| 4162 | + os_free(mctx); |
| 4163 | + |
| 4164 | + if (TEST_FAIL()) |
| 4165 | + return -1; |
| 4166 | + |
| 4167 | + return 0; |
| 4168 | +} |
| 4169 | + |
| 4170 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_HASH */ |
| 4171 | + |
| 4172 | + |
| 4173 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM |
| 4174 | + |
| 4175 | +#include <mbedtls/bignum.h> |
| 4176 | + |
| 4177 | +/* crypto.h bignum interfaces */ |
| 4178 | + |
| 4179 | +struct crypto_bignum *crypto_bignum_init(void) |
| 4180 | +{ |
| 4181 | + if (TEST_FAIL()) |
| 4182 | + return NULL; |
| 4183 | + |
| 4184 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 4185 | + if (bn) |
| 4186 | + mbedtls_mpi_init(bn); |
| 4187 | + return (struct crypto_bignum *)bn; |
| 4188 | +} |
| 4189 | + |
| 4190 | +struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) |
| 4191 | +{ |
| 4192 | + if (TEST_FAIL()) |
| 4193 | + return NULL; |
| 4194 | + |
| 4195 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 4196 | + if (bn) { |
| 4197 | + mbedtls_mpi_init(bn); |
| 4198 | + if (mbedtls_mpi_read_binary(bn, buf, len) == 0) |
| 4199 | + return (struct crypto_bignum *)bn; |
| 4200 | + } |
| 4201 | + |
| 4202 | + os_free(bn); |
| 4203 | + return NULL; |
| 4204 | +} |
| 4205 | + |
| 4206 | +struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) |
| 4207 | +{ |
| 4208 | + if (TEST_FAIL()) |
| 4209 | + return NULL; |
| 4210 | + |
| 4211 | + #if 0 /*(hostap use of this interface passes int, not uint)*/ |
| 4212 | + val = host_to_be32(val); |
| 4213 | + return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); |
| 4214 | + #else |
| 4215 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 4216 | + if (bn) { |
| 4217 | + mbedtls_mpi_init(bn); |
| 4218 | + if (mbedtls_mpi_lset(bn, (int)val) == 0) |
| 4219 | + return (struct crypto_bignum *)bn; |
| 4220 | + } |
| 4221 | + |
| 4222 | + os_free(bn); |
| 4223 | + return NULL; |
| 4224 | + #endif |
| 4225 | +} |
| 4226 | + |
| 4227 | +void crypto_bignum_deinit(struct crypto_bignum *n, int clear) |
| 4228 | +{ |
| 4229 | + mbedtls_mpi_free((mbedtls_mpi *)n); |
| 4230 | + os_free(n); |
| 4231 | +} |
| 4232 | + |
| 4233 | +int crypto_bignum_to_bin(const struct crypto_bignum *a, |
| 4234 | + u8 *buf, size_t buflen, size_t padlen) |
| 4235 | +{ |
| 4236 | + if (TEST_FAIL()) |
| 4237 | + return -1; |
| 4238 | + |
| 4239 | + size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); |
| 4240 | + if (n < padlen) |
| 4241 | + n = padlen; |
| 4242 | + return n > buflen || mbedtls_mpi_write_binary((mbedtls_mpi *)a, buf, n) |
| 4243 | + ? -1 |
| 4244 | + : (int)(n); |
| 4245 | +} |
| 4246 | + |
| 4247 | +int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) |
| 4248 | +{ |
| 4249 | + if (TEST_FAIL()) |
| 4250 | + return -1; |
| 4251 | + |
| 4252 | + /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ |
| 4253 | + #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ |
| 4254 | + return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, |
| 4255 | + mbedtls_ctr_drbg_random, |
| 4256 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 4257 | + #else |
| 4258 | + /* (needed by EAP_PWD, SAE, DPP) */ |
| 4259 | + wpa_printf(MSG_ERROR, |
| 4260 | + "mbedtls 2.27.0 or later required for mbedtls_mpi_random()"); |
| 4261 | + return -1; |
| 4262 | + #endif |
| 4263 | +} |
| 4264 | + |
| 4265 | +int crypto_bignum_add(const struct crypto_bignum *a, |
| 4266 | + const struct crypto_bignum *b, |
| 4267 | + struct crypto_bignum *c) |
| 4268 | +{ |
| 4269 | + return mbedtls_mpi_add_mpi((mbedtls_mpi *)c, |
| 4270 | + (const mbedtls_mpi *)a, |
| 4271 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4272 | +} |
| 4273 | + |
| 4274 | +int crypto_bignum_mod(const struct crypto_bignum *a, |
| 4275 | + const struct crypto_bignum *b, |
| 4276 | + struct crypto_bignum *c) |
| 4277 | +{ |
| 4278 | + return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c, |
| 4279 | + (const mbedtls_mpi *)a, |
| 4280 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4281 | +} |
| 4282 | + |
| 4283 | +int crypto_bignum_exptmod(const struct crypto_bignum *a, |
| 4284 | + const struct crypto_bignum *b, |
| 4285 | + const struct crypto_bignum *c, |
| 4286 | + struct crypto_bignum *d) |
| 4287 | +{ |
| 4288 | + if (TEST_FAIL()) |
| 4289 | + return -1; |
| 4290 | + |
| 4291 | + /* (check if input params match d; d is the result) */ |
| 4292 | + /* (a == d) is ok in current mbedtls implementation */ |
| 4293 | + if (b == d || c == d) { /*(not ok; store result in intermediate)*/ |
| 4294 | + mbedtls_mpi R; |
| 4295 | + mbedtls_mpi_init(&R); |
| 4296 | + int rc = mbedtls_mpi_exp_mod(&R, |
| 4297 | + (const mbedtls_mpi *)a, |
| 4298 | + (const mbedtls_mpi *)b, |
| 4299 | + (const mbedtls_mpi *)c, |
| 4300 | + NULL) |
| 4301 | + || mbedtls_mpi_copy((mbedtls_mpi *)d, &R) ? -1 : 0; |
| 4302 | + mbedtls_mpi_free(&R); |
| 4303 | + return rc; |
| 4304 | + } |
| 4305 | + else { |
| 4306 | + return mbedtls_mpi_exp_mod((mbedtls_mpi *)d, |
| 4307 | + (const mbedtls_mpi *)a, |
| 4308 | + (const mbedtls_mpi *)b, |
| 4309 | + (const mbedtls_mpi *)c, |
| 4310 | + NULL) ? -1 : 0; |
| 4311 | + } |
| 4312 | +} |
| 4313 | + |
| 4314 | +int crypto_bignum_inverse(const struct crypto_bignum *a, |
| 4315 | + const struct crypto_bignum *b, |
| 4316 | + struct crypto_bignum *c) |
| 4317 | +{ |
| 4318 | + if (TEST_FAIL()) |
| 4319 | + return -1; |
| 4320 | + |
| 4321 | + return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, |
| 4322 | + (const mbedtls_mpi *)a, |
| 4323 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4324 | +} |
| 4325 | + |
| 4326 | +int crypto_bignum_sub(const struct crypto_bignum *a, |
| 4327 | + const struct crypto_bignum *b, |
| 4328 | + struct crypto_bignum *c) |
| 4329 | +{ |
| 4330 | + if (TEST_FAIL()) |
| 4331 | + return -1; |
| 4332 | + |
| 4333 | + return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, |
| 4334 | + (const mbedtls_mpi *)a, |
| 4335 | + (const mbedtls_mpi *)b) ? -1 : 0; |
| 4336 | +} |
| 4337 | + |
| 4338 | +int crypto_bignum_div(const struct crypto_bignum *a, |
| 4339 | + const struct crypto_bignum *b, |
| 4340 | + struct crypto_bignum *c) |
| 4341 | +{ |
| 4342 | + if (TEST_FAIL()) |
| 4343 | + return -1; |
| 4344 | + |
| 4345 | + /*(most current use of this crypto.h interface has a == c (result), |
| 4346 | + * so store result in an intermediate to avoid overwritten input)*/ |
| 4347 | + mbedtls_mpi R; |
| 4348 | + mbedtls_mpi_init(&R); |
| 4349 | + int rc = mbedtls_mpi_div_mpi(&R, NULL, |
| 4350 | + (const mbedtls_mpi *)a, |
| 4351 | + (const mbedtls_mpi *)b) |
| 4352 | + || mbedtls_mpi_copy((mbedtls_mpi *)c, &R) ? -1 : 0; |
| 4353 | + mbedtls_mpi_free(&R); |
| 4354 | + return rc; |
| 4355 | +} |
| 4356 | + |
| 4357 | +int crypto_bignum_addmod(const struct crypto_bignum *a, |
| 4358 | + const struct crypto_bignum *b, |
| 4359 | + const struct crypto_bignum *c, |
| 4360 | + struct crypto_bignum *d) |
| 4361 | +{ |
| 4362 | + if (TEST_FAIL()) |
| 4363 | + return -1; |
| 4364 | + |
| 4365 | + return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, |
| 4366 | + (const mbedtls_mpi *)a, |
| 4367 | + (const mbedtls_mpi *)b) |
| 4368 | + || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, |
| 4369 | + (mbedtls_mpi *)d, |
| 4370 | + (const mbedtls_mpi *)c) ? -1 : 0; |
| 4371 | +} |
| 4372 | + |
| 4373 | +int crypto_bignum_mulmod(const struct crypto_bignum *a, |
| 4374 | + const struct crypto_bignum *b, |
| 4375 | + const struct crypto_bignum *c, |
| 4376 | + struct crypto_bignum *d) |
| 4377 | +{ |
| 4378 | + if (TEST_FAIL()) |
| 4379 | + return -1; |
| 4380 | + |
| 4381 | + return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, |
| 4382 | + (const mbedtls_mpi *)a, |
| 4383 | + (const mbedtls_mpi *)b) |
| 4384 | + || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, |
| 4385 | + (mbedtls_mpi *)d, |
| 4386 | + (const mbedtls_mpi *)c) ? -1 : 0; |
| 4387 | +} |
| 4388 | + |
| 4389 | +int crypto_bignum_sqrmod(const struct crypto_bignum *a, |
| 4390 | + const struct crypto_bignum *b, |
| 4391 | + struct crypto_bignum *c) |
| 4392 | +{ |
| 4393 | + if (TEST_FAIL()) |
| 4394 | + return -1; |
| 4395 | + |
| 4396 | + #if 1 |
| 4397 | + return crypto_bignum_mulmod(a, a, b, c); |
| 4398 | + #else |
| 4399 | + mbedtls_mpi bn; |
| 4400 | + mbedtls_mpi_init(&bn); |
| 4401 | + if (mbedtls_mpi_lset(&bn, 2)) /* alt?: mbedtls_mpi_set_bit(&bn, 1) */ |
| 4402 | + return -1; |
| 4403 | + int ret = mbedtls_mpi_exp_mod((mbedtls_mpi *)c, |
| 4404 | + (const mbedtls_mpi *)a, &bn, |
| 4405 | + (const mbedtls_mpi *)b, NULL) ? -1 : 0; |
| 4406 | + mbedtls_mpi_free(&bn); |
| 4407 | + return ret; |
| 4408 | + #endif |
| 4409 | +} |
| 4410 | + |
| 4411 | +int crypto_bignum_rshift(const struct crypto_bignum *a, int n, |
| 4412 | + struct crypto_bignum *r) |
| 4413 | +{ |
| 4414 | + return mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a) |
| 4415 | + || mbedtls_mpi_shift_r((mbedtls_mpi *)r, n) ? -1 : 0; |
| 4416 | +} |
| 4417 | + |
| 4418 | +int crypto_bignum_cmp(const struct crypto_bignum *a, |
| 4419 | + const struct crypto_bignum *b) |
| 4420 | +{ |
| 4421 | + return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b); |
| 4422 | +} |
| 4423 | + |
| 4424 | +int crypto_bignum_is_zero(const struct crypto_bignum *a) |
| 4425 | +{ |
| 4426 | + /* XXX: src/common/sae.c:sswu() contains comment: |
| 4427 | + * "TODO: Make sure crypto_bignum_is_zero() is constant time" |
| 4428 | + * Note: mbedtls_mpi_cmp_int() *is not* constant time */ |
| 4429 | + return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0); |
| 4430 | +} |
| 4431 | + |
| 4432 | +int crypto_bignum_is_one(const struct crypto_bignum *a) |
| 4433 | +{ |
| 4434 | + return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0); |
| 4435 | +} |
| 4436 | + |
| 4437 | +int crypto_bignum_is_odd(const struct crypto_bignum *a) |
| 4438 | +{ |
| 4439 | + return mbedtls_mpi_get_bit((const mbedtls_mpi *)a, 0); |
| 4440 | +} |
| 4441 | + |
| 4442 | +#include "utils/const_time.h" |
| 4443 | +int crypto_bignum_legendre(const struct crypto_bignum *a, |
| 4444 | + const struct crypto_bignum *p) |
| 4445 | +{ |
| 4446 | + if (TEST_FAIL()) |
| 4447 | + return -2; |
| 4448 | + |
| 4449 | + /* Security Note: |
| 4450 | + * mbedtls_mpi_exp_mod() is not documented to run in constant time, |
| 4451 | + * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. |
| 4452 | + * Compare to crypto_openssl.c:crypto_bignum_legendre() |
| 4453 | + * which uses openssl BN_mod_exp_mont_consttime() |
| 4454 | + * mbedtls/library/ecp.c has further countermeasures to timing attacks, |
| 4455 | + * (but ecp.c funcs are not used here) */ |
| 4456 | + |
| 4457 | + mbedtls_mpi exp, tmp; |
| 4458 | + mbedtls_mpi_init(&exp); |
| 4459 | + mbedtls_mpi_init(&tmp); |
| 4460 | + |
| 4461 | + /* exp = (p-1) / 2 */ |
| 4462 | + int res; |
| 4463 | + if (mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1) == 0 |
| 4464 | + && mbedtls_mpi_shift_r(&exp, 1) == 0 |
| 4465 | + && mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *)a, &exp, |
| 4466 | + (const mbedtls_mpi *)p, NULL) == 0) { |
| 4467 | + /*(modified from crypto_openssl.c:crypto_bignum_legendre())*/ |
| 4468 | + /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need |
| 4469 | + * to use constant time selection to avoid branches here. */ |
| 4470 | + unsigned int mask; |
| 4471 | + res = -1; |
| 4472 | + mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 1) == 0), 1); |
| 4473 | + res = const_time_select_int(mask, 1, res); |
| 4474 | + mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 0) == 0), 1); |
| 4475 | + res = const_time_select_int(mask, 0, res); |
| 4476 | + } else { |
| 4477 | + res = -2; |
| 4478 | + } |
| 4479 | + |
| 4480 | + mbedtls_mpi_free(&tmp); |
| 4481 | + mbedtls_mpi_free(&exp); |
| 4482 | + return res; |
| 4483 | +} |
| 4484 | + |
| 4485 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_BIGNUM */ |
| 4486 | + |
| 4487 | + |
| 4488 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_DH |
| 4489 | + |
| 4490 | +/* crypto_internal-modexp.c */ |
| 4491 | + |
| 4492 | +#include <mbedtls/bignum.h> |
| 4493 | +#include <mbedtls/dhm.h> |
| 4494 | + |
| 4495 | +#if 0 /* crypto_dh_init() and crypto_dh_derive_secret() prefer to use mbedtls */ |
| 4496 | +int crypto_mod_exp(const u8 *base, size_t base_len, |
| 4497 | + const u8 *power, size_t power_len, |
| 4498 | + const u8 *modulus, size_t modulus_len, |
| 4499 | + u8 *result, size_t *result_len) |
| 4500 | +{ |
| 4501 | + if (TEST_FAIL()) |
| 4502 | + return -1; |
| 4503 | + |
| 4504 | + mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; |
| 4505 | + mbedtls_mpi_init(&bn_base); |
| 4506 | + mbedtls_mpi_init(&bn_exp); |
| 4507 | + mbedtls_mpi_init(&bn_modulus); |
| 4508 | + mbedtls_mpi_init(&bn_result); |
| 4509 | + |
| 4510 | + size_t len; |
| 4511 | + int ret = mbedtls_mpi_read_binary(&bn_base, base, base_len) |
| 4512 | + || mbedtls_mpi_read_binary(&bn_exp, power, power_len) |
| 4513 | + || mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len) |
| 4514 | + || mbedtls_mpi_exp_mod(&bn_result,&bn_base,&bn_exp,&bn_modulus,NULL) |
| 4515 | + || (len = mbedtls_mpi_size(&bn_result)) > *result_len |
| 4516 | + || mbedtls_mpi_write_binary(&bn_result, result, (*result_len = len)) |
| 4517 | + ? -1 |
| 4518 | + : 0; |
| 4519 | + |
| 4520 | + mbedtls_mpi_free(&bn_base); |
| 4521 | + mbedtls_mpi_free(&bn_exp); |
| 4522 | + mbedtls_mpi_free(&bn_modulus); |
| 4523 | + mbedtls_mpi_free(&bn_result); |
| 4524 | + return ret; |
| 4525 | +} |
| 4526 | +#endif |
| 4527 | + |
| 4528 | +static int crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context *ctx, u8 generator, |
| 4529 | + const u8 *prime, size_t prime_len) |
| 4530 | +{ |
| 4531 | + /*(could set these directly in MBEDTLS_PRIVATE members)*/ |
| 4532 | + mbedtls_mpi P, G; |
| 4533 | + mbedtls_mpi_init(&P); |
| 4534 | + mbedtls_mpi_init(&G); |
| 4535 | + int ret = mbedtls_mpi_lset(&G, generator) |
| 4536 | + || mbedtls_mpi_read_binary(&P, prime, prime_len) |
| 4537 | + || mbedtls_dhm_set_group(ctx, &P, &G); |
| 4538 | + mbedtls_mpi_free(&P); |
| 4539 | + mbedtls_mpi_free(&G); |
| 4540 | + return ret; |
| 4541 | +} |
| 4542 | + |
| 4543 | +__attribute_noinline__ |
| 4544 | +static int crypto_mbedtls_dh_init_public(mbedtls_dhm_context *ctx, u8 generator, |
| 4545 | + const u8 *prime, size_t prime_len, |
| 4546 | + u8 *privkey, u8 *pubkey) |
| 4547 | +{ |
| 4548 | + if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) |
| 4549 | + || mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, |
| 4550 | + mbedtls_ctr_drbg_random, |
| 4551 | + crypto_mbedtls_ctr_drbg())) |
| 4552 | + return -1; |
| 4553 | + |
| 4554 | + /*(enable later when upstream mbedtls interface changes require)*/ |
| 4555 | + #if 0 && MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 4556 | + mbedtls_mpi X; |
| 4557 | + mbedtls_mpi_init(&X); |
| 4558 | + int ret = mbedtls_dhm_get_value(ctx, MBEDTLS_DHM_PARAM_X, &X) |
| 4559 | + || mbedtls_mpi_write_binary(&X, privkey, prime_len) ? -1 : 0; |
| 4560 | + mbedtls_mpi_free(&X); |
| 4561 | + return ret; |
| 4562 | + #else |
| 4563 | + return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X), |
| 4564 | + privkey, prime_len) ? -1 : 0; |
| 4565 | + #endif |
| 4566 | +} |
| 4567 | + |
| 4568 | +int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, |
| 4569 | + u8 *pubkey) |
| 4570 | +{ |
| 4571 | + if (TEST_FAIL()) |
| 4572 | + return -1; |
| 4573 | + |
| 4574 | + #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ |
| 4575 | + size_t pubkey_len, pad; |
| 4576 | + |
| 4577 | + if (os_get_random(privkey, prime_len) < 0) |
| 4578 | + return -1; |
| 4579 | + if (os_memcmp(privkey, prime, prime_len) > 0) { |
| 4580 | + /* Make sure private value is smaller than prime */ |
| 4581 | + privkey[0] = 0; |
| 4582 | + } |
| 4583 | + |
| 4584 | + pubkey_len = prime_len; |
| 4585 | + if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, |
| 4586 | + pubkey, &pubkey_len) < 0) |
| 4587 | + return -1; |
| 4588 | + if (pubkey_len < prime_len) { |
| 4589 | + pad = prime_len - pubkey_len; |
| 4590 | + os_memmove(pubkey + pad, pubkey, pubkey_len); |
| 4591 | + os_memset(pubkey, 0, pad); |
| 4592 | + } |
| 4593 | + |
| 4594 | + return 0; |
| 4595 | + #else |
| 4596 | + /* Prefer to use mbedtls to derive our public/private key, as doing so |
| 4597 | + * leverages mbedtls to properly format output and to perform blinding*/ |
| 4598 | + mbedtls_dhm_context ctx; |
| 4599 | + mbedtls_dhm_init(&ctx); |
| 4600 | + int ret = crypto_mbedtls_dh_init_public(&ctx, generator, prime, |
| 4601 | + prime_len, privkey, pubkey); |
| 4602 | + mbedtls_dhm_free(&ctx); |
| 4603 | + return ret; |
| 4604 | + #endif |
| 4605 | +} |
| 4606 | + |
| 4607 | +/*(crypto_dh_derive_secret() could be implemented using crypto.h APIs |
| 4608 | + * instead of being reimplemented in each crypto_*.c)*/ |
| 4609 | +int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, |
| 4610 | + const u8 *order, size_t order_len, |
| 4611 | + const u8 *privkey, size_t privkey_len, |
| 4612 | + const u8 *pubkey, size_t pubkey_len, |
| 4613 | + u8 *secret, size_t *len) |
| 4614 | +{ |
| 4615 | + if (TEST_FAIL()) |
| 4616 | + return -1; |
| 4617 | + |
| 4618 | + #if 0 |
| 4619 | + if (pubkey_len > prime_len || |
| 4620 | + (pubkey_len == prime_len && |
| 4621 | + os_memcmp(pubkey, prime, prime_len) >= 0)) |
| 4622 | + return -1; |
| 4623 | + |
| 4624 | + int res = 0; |
| 4625 | + mbedtls_mpi pub; |
| 4626 | + mbedtls_mpi_init(&pub); |
| 4627 | + if (mbedtls_mpi_read_binary(&pub, pubkey, pubkey_len) |
| 4628 | + || mbedtls_mpi_cmp_int(&pub, 1) <= 0) { |
| 4629 | + res = -1; |
| 4630 | + } else if (order) { |
| 4631 | + mbedtls_mpi p, q, tmp; |
| 4632 | + mbedtls_mpi_init(&p); |
| 4633 | + mbedtls_mpi_init(&q); |
| 4634 | + mbedtls_mpi_init(&tmp); |
| 4635 | + |
| 4636 | + /* verify: pubkey^q == 1 mod p */ |
| 4637 | + res = (mbedtls_mpi_read_binary(&p, prime, prime_len) |
| 4638 | + || mbedtls_mpi_read_binary(&q, order, order_len) |
| 4639 | + || mbedtls_mpi_exp_mod(&tmp, &pub, &q, &p, NULL) |
| 4640 | + || mbedtls_mpi_cmp_int(&tmp, 1) != 0); |
| 4641 | + |
| 4642 | + mbedtls_mpi_free(&p); |
| 4643 | + mbedtls_mpi_free(&q); |
| 4644 | + mbedtls_mpi_free(&tmp); |
| 4645 | + } |
| 4646 | + mbedtls_mpi_free(&pub); |
| 4647 | + |
| 4648 | + return (res == 0) |
| 4649 | + ? crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len, |
| 4650 | + prime, prime_len, secret, len) |
| 4651 | + : -1; |
| 4652 | + #else |
| 4653 | + /* Prefer to use mbedtls to derive DH shared secret, as doing so |
| 4654 | + * leverages mbedtls to validate params and to perform blinding. |
| 4655 | + * |
| 4656 | + * Attempt to reconstitute DH context to derive shared secret |
| 4657 | + * (due to limitations of the interface, which ought to pass context). |
| 4658 | + * Force provided G (our private key) into context without validation. |
| 4659 | + * Regenerating GX (our public key) not needed to derive shared secret. |
| 4660 | + */ |
| 4661 | + /*(older compilers might not support VLAs)*/ |
| 4662 | + /*unsigned char buf[2+prime_len+2+1+2+pubkey_len];*/ |
| 4663 | + unsigned char buf[2+MBEDTLS_MPI_MAX_SIZE+2+1+2+MBEDTLS_MPI_MAX_SIZE]; |
| 4664 | + unsigned char *p = buf + 2 + prime_len; |
| 4665 | + if (2+prime_len+2+1+2+pubkey_len > sizeof(buf)) |
| 4666 | + return -1; |
| 4667 | + WPA_PUT_BE16(buf, prime_len); /*(2-byte big-endian size of prime)*/ |
| 4668 | + p[0] = 0; /*(2-byte big-endian size of generator)*/ |
| 4669 | + p[1] = 1; |
| 4670 | + p[2] = generator; |
| 4671 | + WPA_PUT_BE16(p+3, pubkey_len); /*(2-byte big-endian size of pubkey)*/ |
| 4672 | + os_memcpy(p+5, pubkey, pubkey_len); |
| 4673 | + os_memcpy(buf+2, prime, prime_len); |
| 4674 | + |
| 4675 | + mbedtls_dhm_context ctx; |
| 4676 | + mbedtls_dhm_init(&ctx); |
| 4677 | + p = buf; |
| 4678 | + int ret = mbedtls_dhm_read_params(&ctx, &p, p+2+prime_len+5+pubkey_len) |
| 4679 | + || mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X), |
| 4680 | + privkey, privkey_len) |
| 4681 | + || mbedtls_dhm_calc_secret(&ctx, secret, *len, len, |
| 4682 | + mbedtls_ctr_drbg_random, |
| 4683 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 4684 | + mbedtls_dhm_free(&ctx); |
| 4685 | + return ret; |
| 4686 | + #endif |
| 4687 | +} |
| 4688 | + |
| 4689 | +/* dh_group5.c */ |
| 4690 | + |
| 4691 | +#include "dh_group5.h" |
| 4692 | + |
| 4693 | +/* RFC3526_PRIME_1536[] and RFC3526_GENERATOR_1536[] from crypto_wolfssl.c */ |
| 4694 | + |
| 4695 | +static const unsigned char RFC3526_PRIME_1536[] = { |
| 4696 | + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, |
| 4697 | + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, |
| 4698 | + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, |
| 4699 | + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, |
| 4700 | + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, |
| 4701 | + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, |
| 4702 | + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, |
| 4703 | + 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, |
| 4704 | + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, |
| 4705 | + 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, |
| 4706 | + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, |
| 4707 | + 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, |
| 4708 | + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, |
| 4709 | + 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, |
| 4710 | + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, |
| 4711 | + 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF |
| 4712 | +}; |
| 4713 | + |
| 4714 | +static const unsigned char RFC3526_GENERATOR_1536[] = { |
| 4715 | + 0x02 |
| 4716 | +}; |
| 4717 | + |
| 4718 | +void * dh5_init(struct wpabuf **priv, struct wpabuf **publ) |
| 4719 | +{ |
| 4720 | + const unsigned char * const prime = RFC3526_PRIME_1536; |
| 4721 | + const size_t prime_len = sizeof(RFC3526_PRIME_1536); |
| 4722 | + const u8 generator = *RFC3526_GENERATOR_1536; |
| 4723 | + struct wpabuf *wpubl = NULL, *wpriv = NULL; |
| 4724 | + |
| 4725 | + mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); |
| 4726 | + if (ctx == NULL) |
| 4727 | + return NULL; |
| 4728 | + mbedtls_dhm_init(ctx); |
| 4729 | + |
| 4730 | + if ( (wpubl = wpabuf_alloc(prime_len)) |
| 4731 | + && (wpriv = wpabuf_alloc(prime_len)) |
| 4732 | + && crypto_mbedtls_dh_init_public(ctx, generator, prime, prime_len, |
| 4733 | + wpabuf_put(wpriv, prime_len), |
| 4734 | + wpabuf_put(wpubl, prime_len))==0) { |
| 4735 | + wpabuf_free(*publ); |
| 4736 | + wpabuf_clear_free(*priv); |
| 4737 | + *publ = wpubl; |
| 4738 | + *priv = wpriv; |
| 4739 | + return ctx; |
| 4740 | + } |
| 4741 | + |
| 4742 | + wpabuf_clear_free(wpriv); |
| 4743 | + wpabuf_free(wpubl); |
| 4744 | + mbedtls_dhm_free(ctx); |
| 4745 | + os_free(ctx); |
| 4746 | + return NULL; |
| 4747 | +} |
| 4748 | + |
| 4749 | +#ifdef CRYPTO_MBEDTLS_DH5_INIT_FIXED |
| 4750 | +void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ) |
| 4751 | +{ |
| 4752 | + const unsigned char * const prime = RFC3526_PRIME_1536; |
| 4753 | + const size_t prime_len = sizeof(RFC3526_PRIME_1536); |
| 4754 | + const u8 generator = *RFC3526_GENERATOR_1536; |
| 4755 | + |
| 4756 | + mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); |
| 4757 | + if (ctx == NULL) |
| 4758 | + return NULL; |
| 4759 | + mbedtls_dhm_init(ctx); |
| 4760 | + |
| 4761 | + if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len)==0 |
| 4762 | + #if 0 /*(ignore; not required to derive shared secret)*/ |
| 4763 | + && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(GX), |
| 4764 | + wpabuf_head(publ),wpabuf_len(publ))==0 |
| 4765 | + #endif |
| 4766 | + && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(X), |
| 4767 | + wpabuf_head(priv),wpabuf_len(priv))==0) { |
| 4768 | + return ctx; |
| 4769 | + } |
| 4770 | + |
| 4771 | + mbedtls_dhm_free(ctx); |
| 4772 | + os_free(ctx); |
| 4773 | + return NULL; |
| 4774 | +} |
| 4775 | +#endif |
| 4776 | + |
| 4777 | +struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, |
| 4778 | + const struct wpabuf *own_private) |
| 4779 | +{ |
| 4780 | + /*((mbedtls_dhm_context *)ctx must already contain own_private)*/ |
| 4781 | + /* mbedtls 2.x: prime_len = ctx->len; */ |
| 4782 | + /* mbedtls 3.x: prime_len = mbedtls_dhm_get_len(ctx); */ |
| 4783 | + size_t olen = sizeof(RFC3526_PRIME_1536); /*(sizeof(); prime known)*/ |
| 4784 | + struct wpabuf *buf = wpabuf_alloc(olen); |
| 4785 | + if (buf == NULL) |
| 4786 | + return NULL; |
| 4787 | + if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx, |
| 4788 | + wpabuf_head(peer_public), |
| 4789 | + wpabuf_len(peer_public)) == 0 |
| 4790 | + && mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, |
| 4791 | + mbedtls_ctr_drbg_random, |
| 4792 | + crypto_mbedtls_ctr_drbg()) == 0) { |
| 4793 | + wpabuf_put(buf, olen); |
| 4794 | + return buf; |
| 4795 | + } |
| 4796 | + |
| 4797 | + wpabuf_free(buf); |
| 4798 | + return NULL; |
| 4799 | +} |
| 4800 | + |
| 4801 | +void dh5_free(void *ctx) |
| 4802 | +{ |
| 4803 | + mbedtls_dhm_free(ctx); |
| 4804 | + os_free(ctx); |
| 4805 | +} |
| 4806 | + |
| 4807 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_DH */ |
| 4808 | + |
| 4809 | + |
| 4810 | +#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC) |
| 4811 | + |
| 4812 | +#include <mbedtls/ecp.h> |
| 4813 | + |
| 4814 | +#define CRYPTO_EC_pbits(e) (((mbedtls_ecp_group *)(e))->pbits) |
| 4815 | +#define CRYPTO_EC_plen(e) ((((mbedtls_ecp_group *)(e))->pbits+7)>>3) |
| 4816 | +#define CRYPTO_EC_P(e) (&((mbedtls_ecp_group *)(e))->P) |
| 4817 | +#define CRYPTO_EC_N(e) (&((mbedtls_ecp_group *)(e))->N) |
| 4818 | +#define CRYPTO_EC_A(e) (&((mbedtls_ecp_group *)(e))->A) |
| 4819 | +#define CRYPTO_EC_B(e) (&((mbedtls_ecp_group *)(e))->B) |
| 4820 | +#define CRYPTO_EC_G(e) (&((mbedtls_ecp_group *)(e))->G) |
| 4821 | + |
| 4822 | +static mbedtls_ecp_group_id crypto_mbedtls_ecp_group_id_from_ike_id(int group) |
| 4823 | +{ |
| 4824 | + /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ |
| 4825 | + switch (group) { |
| 4826 | + #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED |
| 4827 | + case 19: return MBEDTLS_ECP_DP_SECP256R1; |
| 4828 | + #endif |
| 4829 | + #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED |
| 4830 | + case 20: return MBEDTLS_ECP_DP_SECP384R1; |
| 4831 | + #endif |
| 4832 | + #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED |
| 4833 | + case 21: return MBEDTLS_ECP_DP_SECP521R1; |
| 4834 | + #endif |
| 4835 | + #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED |
| 4836 | + case 25: return MBEDTLS_ECP_DP_SECP192R1; |
| 4837 | + #endif |
| 4838 | + #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED |
| 4839 | + case 26: return MBEDTLS_ECP_DP_SECP224R1; |
| 4840 | + #endif |
| 4841 | + #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED |
| 4842 | + case 28: return MBEDTLS_ECP_DP_BP256R1; |
| 4843 | + #endif |
| 4844 | + #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED |
| 4845 | + case 29: return MBEDTLS_ECP_DP_BP384R1; |
| 4846 | + #endif |
| 4847 | + #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED |
| 4848 | + case 30: return MBEDTLS_ECP_DP_BP512R1; |
| 4849 | + #endif |
| 4850 | + #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED |
| 4851 | + case 31: return MBEDTLS_ECP_DP_CURVE25519; |
| 4852 | + #endif |
| 4853 | + #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED |
| 4854 | + case 32: return MBEDTLS_ECP_DP_CURVE448; |
| 4855 | + #endif |
| 4856 | + default: return MBEDTLS_ECP_DP_NONE; |
| 4857 | + } |
| 4858 | +} |
| 4859 | + |
| 4860 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC |
| 4861 | +static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id) |
| 4862 | +{ |
| 4863 | + /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ |
| 4864 | + /*(for crypto_ec_key_group())*/ |
| 4865 | + switch (grp_id) { |
| 4866 | + #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED |
| 4867 | + case MBEDTLS_ECP_DP_SECP256R1: return 19; |
| 4868 | + #endif |
| 4869 | + #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED |
| 4870 | + case MBEDTLS_ECP_DP_SECP384R1: return 20; |
| 4871 | + #endif |
| 4872 | + #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED |
| 4873 | + case MBEDTLS_ECP_DP_SECP521R1: return 21; |
| 4874 | + #endif |
| 4875 | + #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED |
| 4876 | + case MBEDTLS_ECP_DP_SECP192R1: return 25; |
| 4877 | + #endif |
| 4878 | + #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED |
| 4879 | + case MBEDTLS_ECP_DP_SECP224R1: return 26; |
| 4880 | + #endif |
| 4881 | + #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED |
| 4882 | + case MBEDTLS_ECP_DP_BP256R1: return 28; |
| 4883 | + #endif |
| 4884 | + #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED |
| 4885 | + case MBEDTLS_ECP_DP_BP384R1: return 29; |
| 4886 | + #endif |
| 4887 | + #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED |
| 4888 | + case MBEDTLS_ECP_DP_BP512R1: return 30; |
| 4889 | + #endif |
| 4890 | + #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED |
| 4891 | + case MBEDTLS_ECP_DP_CURVE25519: return 31; |
| 4892 | + #endif |
| 4893 | + #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED |
| 4894 | + case MBEDTLS_ECP_DP_CURVE448: return 32; |
| 4895 | + #endif |
| 4896 | + default: return -1; |
| 4897 | + } |
| 4898 | +} |
| 4899 | +#endif |
| 4900 | + |
| 4901 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH || CRYPTO_MBEDTLS_CRYPTO_EC */ |
| 4902 | + |
| 4903 | + |
| 4904 | +#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC_DPP) |
| 4905 | + |
| 4906 | +#include <mbedtls/ecp.h> |
| 4907 | +#include <mbedtls/pk.h> |
| 4908 | + |
| 4909 | +static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk) |
| 4910 | +{ |
| 4911 | + mbedtls_ecp_group_id grp_id = |
| 4912 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 4913 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 4914 | + return -1; |
| 4915 | + const mbedtls_pk_info_t *pk_info = |
| 4916 | + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); |
| 4917 | + if (pk_info == NULL) |
| 4918 | + return -1; |
| 4919 | + return mbedtls_pk_setup(pk, pk_info) |
| 4920 | + || mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), |
| 4921 | + mbedtls_ctr_drbg_random, |
| 4922 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 4923 | +} |
| 4924 | + |
| 4925 | +#endif |
| 4926 | + |
| 4927 | + |
| 4928 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH |
| 4929 | + |
| 4930 | +#include <mbedtls/ecdh.h> |
| 4931 | +#include <mbedtls/ecdsa.h> |
| 4932 | +#include <mbedtls/ecp.h> |
| 4933 | +#include <mbedtls/pk.h> |
| 4934 | + |
| 4935 | +/* wrap mbedtls_ecdh_context for more future-proof direct access to components |
| 4936 | + * (mbedtls_ecdh_context internal implementation may change between releases) |
| 4937 | + * |
| 4938 | + * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair -- |
| 4939 | + * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context, |
| 4940 | + * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh |
| 4941 | + * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could |
| 4942 | + * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */ |
| 4943 | +struct crypto_ecdh { |
| 4944 | + mbedtls_ecdh_context ctx; |
| 4945 | + mbedtls_ecp_group grp; |
| 4946 | + mbedtls_ecp_point Q; |
| 4947 | +}; |
| 4948 | + |
| 4949 | +struct crypto_ecdh * crypto_ecdh_init(int group) |
| 4950 | +{ |
| 4951 | + mbedtls_pk_context pk; |
| 4952 | + mbedtls_pk_init(&pk); |
| 4953 | + struct crypto_ecdh *ecdh = crypto_mbedtls_keypair_gen(group, &pk) == 0 |
| 4954 | + ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk) |
| 4955 | + : NULL; |
| 4956 | + mbedtls_pk_free(&pk); |
| 4957 | + return ecdh; |
| 4958 | +} |
| 4959 | + |
| 4960 | +struct crypto_ecdh * crypto_ecdh_init2(int group, |
| 4961 | + struct crypto_ec_key *own_key) |
| 4962 | +{ |
| 4963 | + mbedtls_ecp_group_id grp_id = |
| 4964 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 4965 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 4966 | + return NULL; |
| 4967 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)own_key); |
| 4968 | + struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh)); |
| 4969 | + if (ecdh == NULL) |
| 4970 | + return NULL; |
| 4971 | + mbedtls_ecdh_init(&ecdh->ctx); |
| 4972 | + mbedtls_ecp_group_init(&ecdh->grp); |
| 4973 | + mbedtls_ecp_point_init(&ecdh->Q); |
| 4974 | + if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0 |
| 4975 | + && mbedtls_ecdh_get_params(&ecdh->ctx,ecp_kp,MBEDTLS_ECDH_OURS) == 0) { |
| 4976 | + /* copy grp and Q for later use |
| 4977 | + * (retrieving this info later is more convoluted |
| 4978 | + * even if mbedtls_ecdh_make_public() is considered)*/ |
| 4979 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 4980 | + mbedtls_mpi d; |
| 4981 | + mbedtls_mpi_init(&d); |
| 4982 | + if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0) { |
| 4983 | + mbedtls_mpi_free(&d); |
| 4984 | + return ecdh; |
| 4985 | + } |
| 4986 | + mbedtls_mpi_free(&d); |
| 4987 | + #else |
| 4988 | + if (mbedtls_ecp_group_load(&ecdh->grp, grp_id) == 0 |
| 4989 | + && mbedtls_ecp_copy(&ecdh->Q, &ecp_kp->MBEDTLS_PRIVATE(Q)) == 0) |
| 4990 | + return ecdh; |
| 4991 | + #endif |
| 4992 | + } |
| 4993 | + |
| 4994 | + mbedtls_ecp_point_free(&ecdh->Q); |
| 4995 | + mbedtls_ecp_group_free(&ecdh->grp); |
| 4996 | + mbedtls_ecdh_free(&ecdh->ctx); |
| 4997 | + os_free(ecdh); |
| 4998 | + return NULL; |
| 4999 | +} |
| 5000 | + |
| 5001 | +struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) |
| 5002 | +{ |
| 5003 | + mbedtls_ecp_group *grp = &ecdh->grp; |
| 5004 | + size_t prime_len = CRYPTO_EC_plen(grp); |
| 5005 | + size_t output_len = prime_len; |
| 5006 | + u8 output_offset = 0; |
| 5007 | + u8 buf[256]; |
| 5008 | + |
| 5009 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5010 | + /* len */ |
| 5011 | + #endif |
| 5012 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5013 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 5014 | + output_len = inc_y ? prime_len * 2 + 1 : prime_len + 1; |
| 5015 | + output_offset = 1; |
| 5016 | + } |
| 5017 | + #endif |
| 5018 | + |
| 5019 | + if (output_len > sizeof(buf)) |
| 5020 | + return NULL; |
| 5021 | + |
| 5022 | + inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; |
| 5023 | + if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &output_len, |
| 5024 | + buf, output_len) == 0) { |
| 5025 | + return wpabuf_alloc_copy(buf + output_offset, output_len - output_offset); |
| 5026 | + } |
| 5027 | + |
| 5028 | + return NULL; |
| 5029 | +} |
| 5030 | + |
| 5031 | +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) |
| 5032 | +static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp, |
| 5033 | + mbedtls_mpi *bn, |
| 5034 | + int parity_bit) |
| 5035 | +{ |
| 5036 | + /* y^2 = x^3 + ax + b |
| 5037 | + * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ |
| 5038 | + mbedtls_mpi *cy2 = (mbedtls_mpi *) |
| 5039 | + crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp, |
| 5040 | + (const struct crypto_bignum *)bn); /*x*/ |
| 5041 | + if (cy2 == NULL) |
| 5042 | + return -1; |
| 5043 | + |
| 5044 | + /*mbedtls_mpi_free(bn);*/ |
| 5045 | + /*(reuse bn to store result (y))*/ |
| 5046 | + |
| 5047 | + mbedtls_mpi exp; |
| 5048 | + mbedtls_mpi_init(&exp); |
| 5049 | + int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/ |
| 5050 | + || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/ |
| 5051 | + || mbedtls_mpi_add_int(&exp, &grp->P, 1) |
| 5052 | + || mbedtls_mpi_shift_r(&exp, 2) |
| 5053 | + || mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL) |
| 5054 | + || (mbedtls_mpi_get_bit(bn, 0) != parity_bit |
| 5055 | + && mbedtls_mpi_sub_mpi(bn, &grp->P, bn)); |
| 5056 | + mbedtls_mpi_free(&exp); |
| 5057 | + mbedtls_mpi_free(cy2); |
| 5058 | + os_free(cy2); |
| 5059 | + return ret; |
| 5060 | +} |
| 5061 | +#endif |
| 5062 | + |
| 5063 | +struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, |
| 5064 | + const u8 *key, size_t len) |
| 5065 | +{ |
| 5066 | + if (len == 0) /*(invalid peer key)*/ |
| 5067 | + return NULL; |
| 5068 | + |
| 5069 | + mbedtls_ecp_group *grp = &ecdh->grp; |
| 5070 | + |
| 5071 | + #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) |
| 5072 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 5073 | + /* add header for mbedtls_ecdh_read_public() */ |
| 5074 | + u8 buf[256]; |
| 5075 | + if (sizeof(buf)-1 < len) |
| 5076 | + return NULL; |
| 5077 | + buf[0] = (u8)(len); |
| 5078 | + os_memcpy(buf+1, key, len); |
| 5079 | + |
| 5080 | + if (inc_y) { |
| 5081 | + if (!(len & 1)) { /*(dpp code/tests does not include tag?!?)*/ |
| 5082 | + if (sizeof(buf)-2 < len) |
| 5083 | + return NULL; |
| 5084 | + buf[0] = (u8)(1+len); |
| 5085 | + buf[1] = 0x04; |
| 5086 | + os_memcpy(buf+2, key, len); |
| 5087 | + } |
| 5088 | + len >>= 1; /*(repurpose len to prime_len)*/ |
| 5089 | + } else { /* (inc_y == 0) */ |
| 5090 | + /* mbedtls_ecp_point_read_binary() does not currently support |
| 5091 | + * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) |
| 5092 | + * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ |
| 5093 | + |
| 5094 | + /* derive y, amend buf[] with y for UNCOMPRESSED format */ |
| 5095 | + if (sizeof(buf)-2 < len*2 || len == 0) |
| 5096 | + return NULL; |
| 5097 | + |
| 5098 | + buf[0] = (u8)(1+len*2); |
| 5099 | + buf[1] = 0x04; |
| 5100 | + os_memcpy(buf+2, key, len); |
| 5101 | + |
| 5102 | + mbedtls_mpi bn; |
| 5103 | + mbedtls_mpi_init(&bn); |
| 5104 | + int ret = mbedtls_mpi_read_binary(&bn, key, len) |
| 5105 | + || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, 0) |
| 5106 | + || mbedtls_mpi_write_binary(&bn, buf+2+len, len); |
| 5107 | + mbedtls_mpi_free(&bn); |
| 5108 | + if (ret != 0) |
| 5109 | + return NULL; |
| 5110 | + } |
| 5111 | + |
| 5112 | + if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1)) |
| 5113 | + return NULL; |
| 5114 | + } |
| 5115 | + #endif |
| 5116 | + #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) |
| 5117 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5118 | + if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len)) |
| 5119 | + return NULL; |
| 5120 | + } |
| 5121 | + #endif |
| 5122 | + |
| 5123 | + struct wpabuf *buf = wpabuf_alloc(len); |
| 5124 | + if (buf == NULL) |
| 5125 | + return NULL; |
| 5126 | + |
| 5127 | + if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, |
| 5128 | + wpabuf_mhead(buf), len, |
| 5129 | + mbedtls_ctr_drbg_random, |
| 5130 | + crypto_mbedtls_ctr_drbg()) == 0) { |
| 5131 | + wpabuf_put(buf, len); |
| 5132 | + return buf; |
| 5133 | + } |
| 5134 | + |
| 5135 | + wpabuf_clear_free(buf); |
| 5136 | + return NULL; |
| 5137 | +} |
| 5138 | + |
| 5139 | +void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) |
| 5140 | +{ |
| 5141 | + if (ecdh == NULL) |
| 5142 | + return; |
| 5143 | + mbedtls_ecp_point_free(&ecdh->Q); |
| 5144 | + mbedtls_ecp_group_free(&ecdh->grp); |
| 5145 | + mbedtls_ecdh_free(&ecdh->ctx); |
| 5146 | + os_free(ecdh); |
| 5147 | +} |
| 5148 | + |
| 5149 | +size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh) |
| 5150 | +{ |
| 5151 | + return CRYPTO_EC_plen(&ecdh->grp); |
| 5152 | +} |
| 5153 | + |
| 5154 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */ |
| 5155 | + |
| 5156 | + |
| 5157 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC |
| 5158 | + |
| 5159 | +#include <mbedtls/ecp.h> |
| 5160 | + |
| 5161 | +struct crypto_ec *crypto_ec_init(int group) |
| 5162 | +{ |
| 5163 | + mbedtls_ecp_group_id grp_id = |
| 5164 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 5165 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 5166 | + return NULL; |
| 5167 | + mbedtls_ecp_group *e = os_malloc(sizeof(*e)); |
| 5168 | + if (e == NULL) |
| 5169 | + return NULL; |
| 5170 | + mbedtls_ecp_group_init(e); |
| 5171 | + if (mbedtls_ecp_group_load(e, grp_id) == 0) |
| 5172 | + return (struct crypto_ec *)e; |
| 5173 | + |
| 5174 | + mbedtls_ecp_group_free(e); |
| 5175 | + os_free(e); |
| 5176 | + return NULL; |
| 5177 | +} |
| 5178 | + |
| 5179 | +void crypto_ec_deinit(struct crypto_ec *e) |
| 5180 | +{ |
| 5181 | + mbedtls_ecp_group_free((mbedtls_ecp_group *)e); |
| 5182 | + os_free(e); |
| 5183 | +} |
| 5184 | + |
| 5185 | +size_t crypto_ec_prime_len(struct crypto_ec *e) |
| 5186 | +{ |
| 5187 | + return CRYPTO_EC_plen(e); |
| 5188 | +} |
| 5189 | + |
| 5190 | +size_t crypto_ec_prime_len_bits(struct crypto_ec *e) |
| 5191 | +{ |
| 5192 | + return CRYPTO_EC_pbits(e); |
| 5193 | +} |
| 5194 | + |
| 5195 | +size_t crypto_ec_order_len(struct crypto_ec *e) |
| 5196 | +{ |
| 5197 | + return (mbedtls_mpi_bitlen(CRYPTO_EC_N(e)) + 7) / 8; |
| 5198 | +} |
| 5199 | + |
| 5200 | +const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e) |
| 5201 | +{ |
| 5202 | + return (const struct crypto_bignum *)CRYPTO_EC_P(e); |
| 5203 | +} |
| 5204 | + |
| 5205 | +const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e) |
| 5206 | +{ |
| 5207 | + return (const struct crypto_bignum *)CRYPTO_EC_N(e); |
| 5208 | +} |
| 5209 | + |
| 5210 | +const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *e) |
| 5211 | +{ |
| 5212 | + static const uint8_t secp256r1_a[] = |
| 5213 | + {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x01, |
| 5214 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| 5215 | + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, |
| 5216 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; |
| 5217 | + static const uint8_t secp384r1_a[] = |
| 5218 | + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5219 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5220 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5221 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, |
| 5222 | + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, |
| 5223 | + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfc}; |
| 5224 | + static const uint8_t secp521r1_a[] = |
| 5225 | + {0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5226 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5227 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5228 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5229 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5230 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5231 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5232 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5233 | + 0xff,0xfc}; |
| 5234 | + static const uint8_t secp192r1_a[] = |
| 5235 | + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5236 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, |
| 5237 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; |
| 5238 | + static const uint8_t secp224r1_a[] = |
| 5239 | + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5240 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, |
| 5241 | + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
| 5242 | + 0xff,0xff,0xff,0xfe}; |
| 5243 | + |
| 5244 | + const uint8_t *bin = NULL; |
| 5245 | + size_t len = 0; |
| 5246 | + |
| 5247 | + /* (mbedtls groups matching supported sswu_curve_param() IKE groups) */ |
| 5248 | + switch (((mbedtls_ecp_group *)e)->id) { |
| 5249 | + #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED |
| 5250 | + case MBEDTLS_ECP_DP_SECP256R1: |
| 5251 | + bin = secp256r1_a; |
| 5252 | + len = sizeof(secp256r1_a); |
| 5253 | + break; |
| 5254 | + #endif |
| 5255 | + #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED |
| 5256 | + case MBEDTLS_ECP_DP_SECP384R1: |
| 5257 | + bin = secp384r1_a; |
| 5258 | + len = sizeof(secp384r1_a); |
| 5259 | + break; |
| 5260 | + #endif |
| 5261 | + #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED |
| 5262 | + case MBEDTLS_ECP_DP_SECP521R1: |
| 5263 | + bin = secp521r1_a; |
| 5264 | + len = sizeof(secp521r1_a); |
| 5265 | + break; |
| 5266 | + #endif |
| 5267 | + #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED |
| 5268 | + case MBEDTLS_ECP_DP_SECP192R1: |
| 5269 | + bin = secp192r1_a; |
| 5270 | + len = sizeof(secp192r1_a); |
| 5271 | + break; |
| 5272 | + #endif |
| 5273 | + #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED |
| 5274 | + case MBEDTLS_ECP_DP_SECP224R1: |
| 5275 | + bin = secp224r1_a; |
| 5276 | + len = sizeof(secp224r1_a); |
| 5277 | + break; |
| 5278 | + #endif |
| 5279 | + #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED |
| 5280 | + case MBEDTLS_ECP_DP_BP256R1: |
| 5281 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5282 | + #endif |
| 5283 | + #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED |
| 5284 | + case MBEDTLS_ECP_DP_BP384R1: |
| 5285 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5286 | + #endif |
| 5287 | + #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED |
| 5288 | + case MBEDTLS_ECP_DP_BP512R1: |
| 5289 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5290 | + #endif |
| 5291 | + #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED |
| 5292 | + case MBEDTLS_ECP_DP_CURVE25519: |
| 5293 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5294 | + #endif |
| 5295 | + #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED |
| 5296 | + case MBEDTLS_ECP_DP_CURVE448: |
| 5297 | + return (const struct crypto_bignum *)CRYPTO_EC_A(e); |
| 5298 | + #endif |
| 5299 | + default: |
| 5300 | + return NULL; |
| 5301 | + } |
| 5302 | + |
| 5303 | + /*(note: not thread-safe; returns file-scoped static storage)*/ |
| 5304 | + if (mbedtls_mpi_read_binary(&mpi_sw_A, bin, len) == 0) |
| 5305 | + return (const struct crypto_bignum *)&mpi_sw_A; |
| 5306 | + return NULL; |
| 5307 | +} |
| 5308 | + |
| 5309 | +const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *e) |
| 5310 | +{ |
| 5311 | + return (const struct crypto_bignum *)CRYPTO_EC_B(e); |
| 5312 | +} |
| 5313 | + |
| 5314 | +const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e) |
| 5315 | +{ |
| 5316 | + return (const struct crypto_ec_point *)CRYPTO_EC_G(e); |
| 5317 | +} |
| 5318 | + |
| 5319 | +struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) |
| 5320 | +{ |
| 5321 | + if (TEST_FAIL()) |
| 5322 | + return NULL; |
| 5323 | + |
| 5324 | + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); |
| 5325 | + if (p != NULL) |
| 5326 | + mbedtls_ecp_point_init(p); |
| 5327 | + return (struct crypto_ec_point *)p; |
| 5328 | +} |
| 5329 | + |
| 5330 | +void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear) |
| 5331 | +{ |
| 5332 | + mbedtls_ecp_point_free((mbedtls_ecp_point *)p); |
| 5333 | + os_free(p); |
| 5334 | +} |
| 5335 | + |
| 5336 | +int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p, |
| 5337 | + struct crypto_bignum *x) |
| 5338 | +{ |
| 5339 | + mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); |
| 5340 | + return mbedtls_mpi_copy((mbedtls_mpi *)x, px) |
| 5341 | + ? -1 |
| 5342 | + : 0; |
| 5343 | +} |
| 5344 | + |
| 5345 | +int crypto_ec_point_to_bin(struct crypto_ec *e, |
| 5346 | + const struct crypto_ec_point *point, u8 *x, u8 *y) |
| 5347 | +{ |
| 5348 | + if (TEST_FAIL()) |
| 5349 | + return -1; |
| 5350 | + |
| 5351 | + /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ |
| 5352 | + size_t len = CRYPTO_EC_plen(e); |
| 5353 | + if (x) { |
| 5354 | + mbedtls_mpi *px = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(X); |
| 5355 | + if (mbedtls_mpi_write_binary(px, x, len)) |
| 5356 | + return -1; |
| 5357 | + } |
| 5358 | + if (y) { |
| 5359 | + #if 0 /*(should not be necessary; py mpi should be in initial state)*/ |
| 5360 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5361 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5362 | + == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5363 | + os_memset(y, 0, len); |
| 5364 | + return 0; |
| 5365 | + } |
| 5366 | + #endif |
| 5367 | + #endif |
| 5368 | + mbedtls_mpi *py = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(Y); |
| 5369 | + if (mbedtls_mpi_write_binary(py, y, len)) |
| 5370 | + return -1; |
| 5371 | + } |
| 5372 | + return 0; |
| 5373 | +} |
| 5374 | + |
| 5375 | +struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, |
| 5376 | + const u8 *val) |
| 5377 | +{ |
| 5378 | + if (TEST_FAIL()) |
| 5379 | + return NULL; |
| 5380 | + |
| 5381 | + size_t len = CRYPTO_EC_plen(e); |
| 5382 | + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); |
| 5383 | + u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; |
| 5384 | + if (p == NULL) |
| 5385 | + return NULL; |
| 5386 | + mbedtls_ecp_point_init(p); |
| 5387 | + |
| 5388 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5389 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5390 | + == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 5391 | + #if 0 /* prefer alternative to MBEDTLS_PRIVATE() access */ |
| 5392 | + mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); |
| 5393 | + mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); |
| 5394 | + mbedtls_mpi *pz = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z); |
| 5395 | + |
| 5396 | + if (mbedtls_mpi_read_binary(px, val, len) == 0 |
| 5397 | + && mbedtls_mpi_read_binary(py, val + len, len) == 0 |
| 5398 | + && mbedtls_mpi_lset(pz, 1) == 0) |
| 5399 | + return (struct crypto_ec_point *)p; |
| 5400 | + #else |
| 5401 | + buf[0] = 0x04; |
| 5402 | + os_memcpy(buf+1, val, len*2); |
| 5403 | + if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, |
| 5404 | + buf, 1+len*2) == 0) |
| 5405 | + return (struct crypto_ec_point *)p; |
| 5406 | + #endif |
| 5407 | + } |
| 5408 | + #endif |
| 5409 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5410 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5411 | + == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5412 | + /* crypto.h interface documents crypto_ec_point_from_bin() |
| 5413 | + * val is length: prime_len * 2 and is big-endian |
| 5414 | + * (Short Weierstrass is assumed by hostap) |
| 5415 | + * Reverse to little-endian format for Montgomery */ |
| 5416 | + for (unsigned int i = 0; i < len; ++i) |
| 5417 | + buf[i] = val[len-1-i]; |
| 5418 | + if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, |
| 5419 | + buf, len) == 0) |
| 5420 | + return (struct crypto_ec_point *)p; |
| 5421 | + } |
| 5422 | + #endif |
| 5423 | + |
| 5424 | + mbedtls_ecp_point_free(p); |
| 5425 | + os_free(p); |
| 5426 | + return NULL; |
| 5427 | +} |
| 5428 | + |
| 5429 | +int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a, |
| 5430 | + const struct crypto_ec_point *b, |
| 5431 | + struct crypto_ec_point *c) |
| 5432 | +{ |
| 5433 | + if (TEST_FAIL()) |
| 5434 | + return -1; |
| 5435 | + |
| 5436 | + /* mbedtls does not provide an mbedtls_ecp_point add function */ |
| 5437 | + mbedtls_mpi one; |
| 5438 | + mbedtls_mpi_init(&one); |
| 5439 | + int ret = mbedtls_mpi_lset(&one, 1) |
| 5440 | + || mbedtls_ecp_muladd( |
| 5441 | + (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)c, |
| 5442 | + &one, (const mbedtls_ecp_point *)a, |
| 5443 | + &one, (const mbedtls_ecp_point *)b) ? -1 : 0; |
| 5444 | + mbedtls_mpi_free(&one); |
| 5445 | + return ret; |
| 5446 | +} |
| 5447 | + |
| 5448 | +int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, |
| 5449 | + const struct crypto_bignum *b, |
| 5450 | + struct crypto_ec_point *res) |
| 5451 | +{ |
| 5452 | + if (TEST_FAIL()) |
| 5453 | + return -1; |
| 5454 | + |
| 5455 | + return mbedtls_ecp_mul( |
| 5456 | + (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, |
| 5457 | + (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, |
| 5458 | + mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 5459 | +} |
| 5460 | + |
| 5461 | +int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) |
| 5462 | +{ |
| 5463 | + if (TEST_FAIL()) |
| 5464 | + return -1; |
| 5465 | + |
| 5466 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5467 | + == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| 5468 | + /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ |
| 5469 | + wpa_printf(MSG_ERROR, |
| 5470 | + "%s not implemented for Montgomery curves",__func__); |
| 5471 | + return -1; |
| 5472 | + } |
| 5473 | + |
| 5474 | + /* mbedtls does not provide an mbedtls_ecp_point invert function */ |
| 5475 | + /* below works for Short Weierstrass; incorrect for Montgomery curves */ |
| 5476 | + mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); |
| 5477 | + return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p) /*point at infinity*/ |
| 5478 | + || mbedtls_mpi_cmp_int(py, 0) == 0 /*point is its own inverse*/ |
| 5479 | + || mbedtls_mpi_sub_abs(py, CRYPTO_EC_P(e), py) == 0 ? 0 : -1; |
| 5480 | +} |
| 5481 | + |
| 5482 | +#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5483 | +static int |
| 5484 | +crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group *e, const mbedtls_mpi *x, |
| 5485 | + mbedtls_mpi *y2) |
| 5486 | +{ |
| 5487 | + /* MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS y^2 = x^3 + a x + b */ |
| 5488 | + |
| 5489 | + /* Short Weierstrass elliptic curve group w/o A set treated as A = -3 */ |
| 5490 | + /* Attempt to match mbedtls/library/ecp.c:ecp_check_pubkey_sw() behavior |
| 5491 | + * and elsewhere in mbedtls/library/ecp.c where if A is not set, it is |
| 5492 | + * treated as if A = -3. */ |
| 5493 | + |
| 5494 | + #if 0 |
| 5495 | + /* y^2 = x^3 + ax + b */ |
| 5496 | + mbedtls_mpi *A = &e->A; |
| 5497 | + mbedtls_mpi t, A_neg3; |
| 5498 | + if (&e->A.p == NULL) { |
| 5499 | + mbedtls_mpi_init(&A_neg3); |
| 5500 | + if (mbedtls_mpi_lset(&A_neg3, -3) != 0) { |
| 5501 | + mbedtls_mpi_free(&A_neg3); |
| 5502 | + return -1; |
| 5503 | + } |
| 5504 | + A = &A_neg3; |
| 5505 | + } |
| 5506 | + mbedtls_mpi_init(&t); |
| 5507 | + int ret = /* x^3 */ |
| 5508 | + mbedtls_mpi_lset(&t, 3) |
| 5509 | + || mbedtls_mpi_exp_mod(y2, x, &t, &e->P, NULL) |
| 5510 | + /* ax */ |
| 5511 | + || mbedtls_mpi_mul_mpi(y2, y2, A) |
| 5512 | + || mbedtls_mpi_mod_mpi(&t, &t, &e->P) |
| 5513 | + /* ax + b */ |
| 5514 | + || mbedtls_mpi_add_mpi(&t, &t, &e->B) |
| 5515 | + || mbedtls_mpi_mod_mpi(&t, &t, &e->P) |
| 5516 | + /* x^3 + ax + b */ |
| 5517 | + || mbedtls_mpi_add_mpi(&t, &t, y2) /* ax + b + x^3 */ |
| 5518 | + || mbedtls_mpi_mod_mpi(y2, &t, &e->P); |
| 5519 | + mbedtls_mpi_free(&t); |
| 5520 | + if (A == &A_neg3) |
| 5521 | + mbedtls_mpi_free(&A_neg3); |
| 5522 | + return ret; /* 0: success, non-zero: failure */ |
| 5523 | + #else |
| 5524 | + /* y^2 = x^3 + ax + b = (x^2 + a)x + b */ |
| 5525 | + return /* x^2 */ |
| 5526 | + mbedtls_mpi_mul_mpi(y2, x, x) |
| 5527 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5528 | + /* x^2 + a */ |
| 5529 | + || (e->A.MBEDTLS_PRIVATE(p) |
| 5530 | + ? mbedtls_mpi_add_mpi(y2, y2, &e->A) |
| 5531 | + : mbedtls_mpi_sub_int(y2, y2, 3)) |
| 5532 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5533 | + /* (x^2 + a)x */ |
| 5534 | + || mbedtls_mpi_mul_mpi(y2, y2, x) |
| 5535 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5536 | + /* (x^2 + a)x + b */ |
| 5537 | + || mbedtls_mpi_add_mpi(y2, y2, &e->B) |
| 5538 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P); |
| 5539 | + #endif |
| 5540 | +} |
| 5541 | +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ |
| 5542 | + |
| 5543 | +#if 0 /* not used by hostap */ |
| 5544 | +#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5545 | +static int |
| 5546 | +crypto_ec_point_y_sqr_montgomery(mbedtls_ecp_group *e, const mbedtls_mpi *x, |
| 5547 | + mbedtls_mpi *y2) |
| 5548 | +{ |
| 5549 | + /* XXX: !!! must be reviewed and audited for correctness !!! */ |
| 5550 | + |
| 5551 | + /* MBEDTLS_ECP_TYPE_MONTGOMERY y^2 = x^3 + a x^2 + x */ |
| 5552 | + |
| 5553 | + /* y^2 = x^3 + a x^2 + x = (x + a)x^2 + x */ |
| 5554 | + mbedtls_mpi x2; |
| 5555 | + mbedtls_mpi_init(&x2); |
| 5556 | + int ret = /* x^2 */ |
| 5557 | + mbedtls_mpi_mul_mpi(&x2, x, x) |
| 5558 | + || mbedtls_mpi_mod_mpi(&x2, &x2, &e->P) |
| 5559 | + /* x + a */ |
| 5560 | + || mbedtls_mpi_add_mpi(y2, x, &e->A) |
| 5561 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5562 | + /* (x + a)x^2 */ |
| 5563 | + || mbedtls_mpi_mul_mpi(y2, y2, &x2) |
| 5564 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P) |
| 5565 | + /* (x + a)x^2 + x */ |
| 5566 | + || mbedtls_mpi_add_mpi(y2, y2, x) |
| 5567 | + || mbedtls_mpi_mod_mpi(y2, y2, &e->P); |
| 5568 | + mbedtls_mpi_free(&x2); |
| 5569 | + return ret; /* 0: success, non-zero: failure */ |
| 5570 | +} |
| 5571 | +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ |
| 5572 | +#endif |
| 5573 | + |
| 5574 | +struct crypto_bignum * |
| 5575 | +crypto_ec_point_compute_y_sqr(struct crypto_ec *e, |
| 5576 | + const struct crypto_bignum *x) |
| 5577 | +{ |
| 5578 | + if (TEST_FAIL()) |
| 5579 | + return NULL; |
| 5580 | + |
| 5581 | + mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); |
| 5582 | + if (y2 == NULL) |
| 5583 | + return NULL; |
| 5584 | + mbedtls_mpi_init(y2); |
| 5585 | + |
| 5586 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5587 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5588 | + == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS |
| 5589 | + && crypto_ec_point_y_sqr_weierstrass((mbedtls_ecp_group *)e, |
| 5590 | + (const mbedtls_mpi *)x, |
| 5591 | + y2) == 0) |
| 5592 | + return (struct crypto_bignum *)y2; |
| 5593 | + #endif |
| 5594 | + #if 0 /* not used by hostap */ |
| 5595 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 5596 | + if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) |
| 5597 | + == MBEDTLS_ECP_TYPE_MONTGOMERY |
| 5598 | + && crypto_ec_point_y_sqr_montgomery((mbedtls_ecp_group *)e, |
| 5599 | + (const mbedtls_mpi *)x, |
| 5600 | + y2) == 0) |
| 5601 | + return (struct crypto_bignum *)y2; |
| 5602 | + #endif |
| 5603 | + #endif |
| 5604 | + |
| 5605 | + mbedtls_mpi_free(y2); |
| 5606 | + os_free(y2); |
| 5607 | + return NULL; |
| 5608 | +} |
| 5609 | + |
| 5610 | +int crypto_ec_point_is_at_infinity(struct crypto_ec *e, |
| 5611 | + const struct crypto_ec_point *p) |
| 5612 | +{ |
| 5613 | + return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p); |
| 5614 | +} |
| 5615 | + |
| 5616 | +int crypto_ec_point_is_on_curve(struct crypto_ec *e, |
| 5617 | + const struct crypto_ec_point *p) |
| 5618 | +{ |
| 5619 | + #if 1 |
| 5620 | + return mbedtls_ecp_check_pubkey((const mbedtls_ecp_group *)e, |
| 5621 | + (const mbedtls_ecp_point *)p) == 0; |
| 5622 | + #else |
| 5623 | + /* compute y^2 mod P and compare to y^2 mod P */ |
| 5624 | + /*(ref: src/eap_common/eap_pwd_common.c:compute_password_element())*/ |
| 5625 | + const mbedtls_mpi *px = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); |
| 5626 | + mbedtls_mpi *cy2 = (mbedtls_mpi *) |
| 5627 | + crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *)px); |
| 5628 | + if (cy2 == NULL) |
| 5629 | + return 0; |
| 5630 | + |
| 5631 | + mbedtls_mpi y2; |
| 5632 | + mbedtls_mpi_init(&y2); |
| 5633 | + const mbedtls_mpi *py = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); |
| 5634 | + int is_on_curve = mbedtls_mpi_mul_mpi(&y2, py, py) /* y^2 mod P */ |
| 5635 | + || mbedtls_mpi_mod_mpi(&y2, &y2, CRYPTO_EC_P(e)) |
| 5636 | + || mbedtls_mpi_cmp_mpi(&y2, cy2) != 0 ? 0 : 1; |
| 5637 | + |
| 5638 | + mbedtls_mpi_free(&y2); |
| 5639 | + mbedtls_mpi_free(cy2); |
| 5640 | + os_free(cy2); |
| 5641 | + return is_on_curve; |
| 5642 | + #endif |
| 5643 | +} |
| 5644 | + |
| 5645 | +int crypto_ec_point_cmp(const struct crypto_ec *e, |
| 5646 | + const struct crypto_ec_point *a, |
| 5647 | + const struct crypto_ec_point *b) |
| 5648 | +{ |
| 5649 | + return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *)a, |
| 5650 | + (const mbedtls_ecp_point *)b); |
| 5651 | +} |
| 5652 | + |
| 5653 | +#if !defined(CONFIG_NO_STDOUT_DEBUG) |
| 5654 | +void crypto_ec_point_debug_print(const struct crypto_ec *e, |
| 5655 | + const struct crypto_ec_point *p, |
| 5656 | + const char *title) |
| 5657 | +{ |
| 5658 | + u8 x[MBEDTLS_MPI_MAX_SIZE]; |
| 5659 | + u8 y[MBEDTLS_MPI_MAX_SIZE]; |
| 5660 | + size_t len = CRYPTO_EC_plen(e); |
| 5661 | + /* crypto_ec_point_to_bin ought to take (const struct crypto_ec *e) */ |
| 5662 | + struct crypto_ec *ee; |
| 5663 | + *(const struct crypto_ec **)&ee = e; /*(cast away const)*/ |
| 5664 | + if (crypto_ec_point_to_bin(ee, p, x, y) == 0) { |
| 5665 | + if (title) |
| 5666 | + wpa_printf(MSG_DEBUG, "%s", title); |
| 5667 | + wpa_hexdump(MSG_DEBUG, "x:", x, len); |
| 5668 | + wpa_hexdump(MSG_DEBUG, "y:", y, len); |
| 5669 | + } |
| 5670 | +} |
| 5671 | +#endif |
| 5672 | + |
| 5673 | + |
| 5674 | +struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len) |
| 5675 | +{ |
| 5676 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 5677 | + if (ctx == NULL) |
| 5678 | + return NULL; |
| 5679 | + mbedtls_pk_init(ctx); |
| 5680 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 5681 | + if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0) |
| 5682 | + #else |
| 5683 | + if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, |
| 5684 | + mbedtls_ctr_drbg_random, |
| 5685 | + crypto_mbedtls_ctr_drbg()) == 0) |
| 5686 | + #endif |
| 5687 | + return (struct crypto_ec_key *)ctx; |
| 5688 | + |
| 5689 | + mbedtls_pk_free(ctx); |
| 5690 | + os_free(ctx); |
| 5691 | + return NULL; |
| 5692 | +} |
| 5693 | + |
| 5694 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE |
| 5695 | +#ifdef CONFIG_MODULE_TESTS |
| 5696 | +/*(for crypto_module_tests.c)*/ |
| 5697 | +struct crypto_ec_key * crypto_ec_key_set_priv(int group, |
| 5698 | + const u8 *raw, size_t raw_len) |
| 5699 | +{ |
| 5700 | + mbedtls_ecp_group_id grp_id = |
| 5701 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 5702 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 5703 | + return NULL; |
| 5704 | + const mbedtls_pk_info_t *pk_info = |
| 5705 | + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); |
| 5706 | + if (pk_info == NULL) |
| 5707 | + return NULL; |
| 5708 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 5709 | + if (ctx == NULL) |
| 5710 | + return NULL; |
| 5711 | + mbedtls_pk_init(ctx); |
| 5712 | + if (mbedtls_pk_setup(ctx, pk_info) == 0 |
| 5713 | + && mbedtls_ecp_read_key(grp_id,mbedtls_pk_ec(*ctx),raw,raw_len) == 0) { |
| 5714 | + return (struct crypto_ec_key *)ctx; |
| 5715 | + } |
| 5716 | + |
| 5717 | + mbedtls_pk_free(ctx); |
| 5718 | + os_free(ctx); |
| 5719 | + return NULL; |
| 5720 | +} |
| 5721 | +#endif |
| 5722 | +#endif |
| 5723 | + |
| 5724 | +#include <mbedtls/error.h> |
| 5725 | +#include <mbedtls/oid.h> |
| 5726 | +static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len) |
| 5727 | +{ |
| 5728 | + /* The following is modified from: |
| 5729 | + * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey() |
| 5730 | + * mbedtls/library/pkparse.c:pk_get_pk_alg() |
| 5731 | + * mbedtls/library/pkparse.c:pk_use_ecparams() |
| 5732 | + */ |
| 5733 | + mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; |
| 5734 | + const mbedtls_pk_info_t *pk_info; |
| 5735 | + int ret; |
| 5736 | + size_t len; |
| 5737 | + const unsigned char *end = der+der_len; |
| 5738 | + unsigned char *p; |
| 5739 | + *(const unsigned char **)&p = der; |
| 5740 | + |
| 5741 | + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
| 5742 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
| 5743 | + { |
| 5744 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) ); |
| 5745 | + } |
| 5746 | + |
| 5747 | + end = p + len; |
| 5748 | + |
| 5749 | + /* |
| 5750 | + if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 ) |
| 5751 | + return( ret ); |
| 5752 | + */ |
| 5753 | + mbedtls_asn1_buf alg_oid, params; |
| 5754 | + memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); |
| 5755 | + if( ( ret = mbedtls_asn1_get_alg( &p, end, &alg_oid, ¶ms ) ) != 0 ) |
| 5756 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) ); |
| 5757 | + if( mbedtls_oid_get_pk_alg( &alg_oid, &pk_alg ) != 0 ) |
| 5758 | + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
| 5759 | + |
| 5760 | + if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end, &len ) ) != 0 ) |
| 5761 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) ); |
| 5762 | + |
| 5763 | + if( p + len != end ) |
| 5764 | + return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, |
| 5765 | + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); |
| 5766 | + |
| 5767 | + if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) |
| 5768 | + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
| 5769 | + |
| 5770 | + if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) |
| 5771 | + return( ret ); |
| 5772 | + |
| 5773 | + /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx) |
| 5774 | + * has already run with ctx initialized up to pk_get_ecpubkey(), |
| 5775 | + * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE |
| 5776 | + * |
| 5777 | + * mbedtls mbedtls_ecp_point_read_binary() |
| 5778 | + * does not handle point in COMPRESSED format |
| 5779 | + * |
| 5780 | + * (validate assumption that algorithm is EC) */ |
| 5781 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); |
| 5782 | + if (ecp_kp == NULL) |
| 5783 | + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
| 5784 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 5785 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 5786 | + mbedtls_ecp_group_id grp_id; |
| 5787 | + |
| 5788 | + |
| 5789 | + /* mbedtls/library/pkparse.c:pk_use_ecparams() */ |
| 5790 | + |
| 5791 | + if( params.tag == MBEDTLS_ASN1_OID ) |
| 5792 | + { |
| 5793 | + if( mbedtls_oid_get_ec_grp( ¶ms, &grp_id ) != 0 ) |
| 5794 | + return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); |
| 5795 | + } |
| 5796 | + else |
| 5797 | + { |
| 5798 | +#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) |
| 5799 | + /*(large code block not copied from mbedtls; unsupported)*/ |
| 5800 | + #if 0 |
| 5801 | + if( ( ret = pk_group_id_from_specified( ¶ms, &grp_id ) ) != 0 ) |
| 5802 | + return( ret ); |
| 5803 | + #endif |
| 5804 | +#endif |
| 5805 | + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
| 5806 | + } |
| 5807 | + |
| 5808 | + /* |
| 5809 | + * grp may already be initialized; if so, make sure IDs match |
| 5810 | + */ |
| 5811 | + if( ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id ) |
| 5812 | + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
| 5813 | + |
| 5814 | + if( ( ret = mbedtls_ecp_group_load( ecp_kp_grp, grp_id ) ) != 0 ) |
| 5815 | + return( ret ); |
| 5816 | + |
| 5817 | + |
| 5818 | + /* (validate assumption that EC point is in COMPRESSED format) */ |
| 5819 | + len = CRYPTO_EC_plen(ecp_kp_grp); |
| 5820 | + if( mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS |
| 5821 | + || (end - p) != 1+len |
| 5822 | + || (*p != 0x02 && *p != 0x03) ) |
| 5823 | + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
| 5824 | + |
| 5825 | + /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call |
| 5826 | + * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */ |
| 5827 | + mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X); |
| 5828 | + mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y); |
| 5829 | + mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z); |
| 5830 | + ret = mbedtls_mpi_lset(Z, 1); |
| 5831 | + if (ret != 0) |
| 5832 | + return( ret ); |
| 5833 | + ret = mbedtls_mpi_read_binary(X, p+1, len); |
| 5834 | + if (ret != 0) |
| 5835 | + return( ret ); |
| 5836 | + /* derive Y |
| 5837 | + * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/ |
| 5838 | + ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/ |
| 5839 | + || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1)); |
| 5840 | + if (ret != 0) |
| 5841 | + return( ret ); |
| 5842 | + |
| 5843 | + return mbedtls_ecp_check_pubkey( ecp_kp_grp, ecp_kp_Q ); |
| 5844 | +} |
| 5845 | + |
| 5846 | +struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len) |
| 5847 | +{ |
| 5848 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 5849 | + if (ctx == NULL) |
| 5850 | + return NULL; |
| 5851 | + mbedtls_pk_init(ctx); |
| 5852 | + /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/ |
| 5853 | + int rc = mbedtls_pk_parse_public_key(ctx, der, der_len); |
| 5854 | + if (rc == 0) |
| 5855 | + return (struct crypto_ec_key *)ctx; |
| 5856 | + else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { |
| 5857 | + /* mbedtls mbedtls_ecp_point_read_binary() |
| 5858 | + * does not handle point in COMPRESSED format; parse internally */ |
| 5859 | + rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx,der,der_len); |
| 5860 | + if (rc == 0) |
| 5861 | + return (struct crypto_ec_key *)ctx; |
| 5862 | + } |
| 5863 | + |
| 5864 | + mbedtls_pk_free(ctx); |
| 5865 | + os_free(ctx); |
| 5866 | + return NULL; |
| 5867 | +} |
| 5868 | + |
| 5869 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 5870 | + |
| 5871 | +static struct crypto_ec_key * |
| 5872 | +crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id, |
| 5873 | + const mbedtls_ecp_point *pub, |
| 5874 | + const u8 *buf, size_t len) |
| 5875 | +{ |
| 5876 | + const mbedtls_pk_info_t *pk_info = |
| 5877 | + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); |
| 5878 | + if (pk_info == NULL) |
| 5879 | + return NULL; |
| 5880 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 5881 | + if (ctx == NULL) |
| 5882 | + return NULL; |
| 5883 | + mbedtls_pk_init(ctx); |
| 5884 | + if (mbedtls_pk_setup(ctx, pk_info) == 0) { |
| 5885 | + /* (Is private key generation necessary for callers?) |
| 5886 | + * alt: gen key then overwrite Q |
| 5887 | + * mbedtls_ecp_gen_key(grp_id, ecp_kp, |
| 5888 | + * mbedtls_ctr_drbg_random, |
| 5889 | + * crypto_mbedtls_ctr_drbg()) == 0 |
| 5890 | + */ |
| 5891 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); |
| 5892 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 5893 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 5894 | + mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); |
| 5895 | + if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 |
| 5896 | + && (pub |
| 5897 | + ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 |
| 5898 | + : mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, |
| 5899 | + buf, len) == 0) |
| 5900 | + && mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, |
| 5901 | + mbedtls_ctr_drbg_random, |
| 5902 | + crypto_mbedtls_ctr_drbg()) == 0){ |
| 5903 | + return (struct crypto_ec_key *)ctx; |
| 5904 | + } |
| 5905 | + } |
| 5906 | + |
| 5907 | + mbedtls_pk_free(ctx); |
| 5908 | + os_free(ctx); |
| 5909 | + return NULL; |
| 5910 | +} |
| 5911 | + |
| 5912 | +struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x, |
| 5913 | + const u8 *y, size_t len) |
| 5914 | +{ |
| 5915 | + mbedtls_ecp_group_id grp_id = |
| 5916 | + crypto_mbedtls_ecp_group_id_from_ike_id(group); |
| 5917 | + if (grp_id == MBEDTLS_ECP_DP_NONE) |
| 5918 | + return NULL; |
| 5919 | + if (len > MBEDTLS_MPI_MAX_SIZE) |
| 5920 | + return NULL; |
| 5921 | + u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; |
| 5922 | + buf[0] = 0x04; /* assume x,y for Short Weierstrass */ |
| 5923 | + os_memcpy(buf+1, x, len); |
| 5924 | + os_memcpy(buf+1+len, y, len); |
| 5925 | + |
| 5926 | + return crypto_ec_key_set_pub_point_for_group(grp_id,NULL,buf,1+len*2); |
| 5927 | +} |
| 5928 | + |
| 5929 | +struct crypto_ec_key * |
| 5930 | +crypto_ec_key_set_pub_point(struct crypto_ec *e, |
| 5931 | + const struct crypto_ec_point *pub) |
| 5932 | +{ |
| 5933 | + mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id; |
| 5934 | + mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub; |
| 5935 | + return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0); |
| 5936 | +} |
| 5937 | + |
| 5938 | + |
| 5939 | +struct crypto_ec_key * crypto_ec_key_gen(int group) |
| 5940 | +{ |
| 5941 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 5942 | + if (ctx == NULL) |
| 5943 | + return NULL; |
| 5944 | + mbedtls_pk_init(ctx); |
| 5945 | + if (crypto_mbedtls_keypair_gen(group, ctx) == 0) |
| 5946 | + return (struct crypto_ec_key *)ctx; |
| 5947 | + mbedtls_pk_free(ctx); |
| 5948 | + os_free(ctx); |
| 5949 | + return NULL; |
| 5950 | +} |
| 5951 | + |
| 5952 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 5953 | + |
| 5954 | +void crypto_ec_key_deinit(struct crypto_ec_key *key) |
| 5955 | +{ |
| 5956 | + mbedtls_pk_free((mbedtls_pk_context *)key); |
| 5957 | + os_free(key); |
| 5958 | +} |
| 5959 | + |
| 5960 | +struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) |
| 5961 | +{ |
| 5962 | + /* (similar to crypto_ec_key_get_pubkey_point(), |
| 5963 | + * but compressed point format and ASN.1 DER wrapping)*/ |
| 5964 | +#ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ |
| 5965 | +#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) |
| 5966 | +#endif |
| 5967 | + unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES]; |
| 5968 | + int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, |
| 5969 | + buf, sizeof(buf)); |
| 5970 | + if (len < 0) |
| 5971 | + return NULL; |
| 5972 | + /* Note: data is written at the end of the buffer! Use the |
| 5973 | + * return value to determine where you should start |
| 5974 | + * using the buffer */ |
| 5975 | + unsigned char *p = buf+sizeof(buf)-len; |
| 5976 | + |
| 5977 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 5978 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 5979 | + if (ecp_kp == NULL) |
| 5980 | + return NULL; |
| 5981 | + mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 5982 | + /* Note: sae_pk.c expects pubkey point in compressed format, |
| 5983 | + * but mbedtls_pk_write_pubkey_der() writes uncompressed format. |
| 5984 | + * Manually translate format and update lengths in DER format */ |
| 5985 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { |
| 5986 | + unsigned char *end = buf+sizeof(buf); |
| 5987 | + size_t n; |
| 5988 | + /* SubjectPublicKeyInfo SEQUENCE */ |
| 5989 | + mbedtls_asn1_get_tag(&p, end, &n, |
| 5990 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 5991 | + /* algorithm AlgorithmIdentifier */ |
| 5992 | + unsigned char *a = p; |
| 5993 | + size_t alen; |
| 5994 | + mbedtls_asn1_get_tag(&p, end, &alen, |
| 5995 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 5996 | + p += alen; |
| 5997 | + alen = (size_t)(p - a); |
| 5998 | + /* subjectPublicKey BIT STRING */ |
| 5999 | + mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING); |
| 6000 | + /* rewrite into compressed point format and rebuild ASN.1 */ |
| 6001 | + p[1] = (buf[sizeof(buf)-1] & 1) ? 0x03 : 0x02; |
| 6002 | + n = 1 + 1 + (n-2)/2; |
| 6003 | + len = mbedtls_asn1_write_len(&p, buf, n) + (int)n; |
| 6004 | + len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING); |
| 6005 | + os_memmove(p-alen, a, alen); |
| 6006 | + len += alen; |
| 6007 | + p -= alen; |
| 6008 | + len += mbedtls_asn1_write_len(&p, buf, (size_t)len); |
| 6009 | + len += mbedtls_asn1_write_tag(&p, buf, |
| 6010 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6011 | + } |
| 6012 | + #endif |
| 6013 | + return wpabuf_alloc_copy(p, (size_t)len); |
| 6014 | +} |
| 6015 | + |
| 6016 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6017 | + |
| 6018 | +struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, |
| 6019 | + bool include_pub) |
| 6020 | +{ |
| 6021 | +#ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ |
| 6022 | +#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) |
| 6023 | +#endif |
| 6024 | + unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES]; |
| 6025 | + int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key, |
| 6026 | + priv, sizeof(priv)); |
| 6027 | + if (privlen < 0) |
| 6028 | + return NULL; |
| 6029 | + |
| 6030 | + struct wpabuf *wbuf; |
| 6031 | + |
| 6032 | + /* Note: data is written at the end of the buffer! Use the |
| 6033 | + * return value to determine where you should start |
| 6034 | + * using the buffer */ |
| 6035 | + /* mbedtls_pk_write_key_der() includes publicKey in DER */ |
| 6036 | + if (include_pub) |
| 6037 | + wbuf = wpabuf_alloc_copy(priv+sizeof(priv)-privlen, privlen); |
| 6038 | + else { |
| 6039 | + /* calculate publicKey offset and skip from end of buffer */ |
| 6040 | + unsigned char *p = priv+sizeof(priv)-privlen; |
| 6041 | + unsigned char *end = priv+sizeof(priv); |
| 6042 | + size_t len; |
| 6043 | + /* ECPrivateKey SEQUENCE */ |
| 6044 | + mbedtls_asn1_get_tag(&p, end, &len, |
| 6045 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6046 | + /* version INTEGER */ |
| 6047 | + unsigned char *v = p; |
| 6048 | + mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); |
| 6049 | + p += len; |
| 6050 | + /* privateKey OCTET STRING */ |
| 6051 | + mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); |
| 6052 | + p += len; |
| 6053 | + /* parameters ECParameters */ |
| 6054 | + mbedtls_asn1_get_tag(&p, end, &len, |
| 6055 | + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED); |
| 6056 | + p += len; |
| 6057 | + |
| 6058 | + /* write new SEQUENCE header (we know that it fits in priv[]) */ |
| 6059 | + len = (size_t)(p - v); |
| 6060 | + p = v; |
| 6061 | + len += mbedtls_asn1_write_len(&p, priv, len); |
| 6062 | + len += mbedtls_asn1_write_tag(&p, priv, |
| 6063 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6064 | + wbuf = wpabuf_alloc_copy(p, len); |
| 6065 | + } |
| 6066 | + |
| 6067 | + forced_memzero(priv, sizeof(priv)); |
| 6068 | + return wbuf; |
| 6069 | +} |
| 6070 | + |
| 6071 | +struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, |
| 6072 | + int prefix) |
| 6073 | +{ |
| 6074 | + /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/ |
| 6075 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6076 | + if (ecp_kp == NULL) |
| 6077 | + return NULL; |
| 6078 | + mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6079 | + size_t len = CRYPTO_EC_plen(grp); |
| 6080 | + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED |
| 6081 | + /* len */ |
| 6082 | + #endif |
| 6083 | + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED |
| 6084 | + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) |
| 6085 | + len = len*2+1; |
| 6086 | + #endif |
| 6087 | + struct wpabuf *buf = wpabuf_alloc(len); |
| 6088 | + if (buf == NULL) |
| 6089 | + return NULL; |
| 6090 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6091 | + if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q, |
| 6092 | + MBEDTLS_ECP_PF_UNCOMPRESSED, &len, |
| 6093 | + wpabuf_mhead_u8(buf), len) == 0) { |
| 6094 | + if (!prefix) /* Remove 0x04 prefix if requested */ |
| 6095 | + os_memmove(wpabuf_mhead(buf),wpabuf_mhead(buf)+1,--len); |
| 6096 | + wpabuf_put(buf, len); |
| 6097 | + return buf; |
| 6098 | + } |
| 6099 | + |
| 6100 | + wpabuf_free(buf); |
| 6101 | + return NULL; |
| 6102 | +} |
| 6103 | + |
| 6104 | +struct crypto_ec_point * |
| 6105 | +crypto_ec_key_get_public_key(struct crypto_ec_key *key) |
| 6106 | +{ |
| 6107 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6108 | + if (ecp_kp == NULL) |
| 6109 | + return NULL; |
| 6110 | + mbedtls_ecp_point *p = os_malloc(sizeof(*p)); |
| 6111 | + if (p != NULL) { |
| 6112 | + /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ |
| 6113 | + mbedtls_ecp_point_init(p); |
| 6114 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6115 | + if (mbedtls_ecp_copy(p, ecp_kp_Q)) { |
| 6116 | + mbedtls_ecp_point_free(p); |
| 6117 | + os_free(p); |
| 6118 | + p = NULL; |
| 6119 | + } |
| 6120 | + } |
| 6121 | + return (struct crypto_ec_point *)p; |
| 6122 | +} |
| 6123 | + |
| 6124 | +struct crypto_bignum * |
| 6125 | +crypto_ec_key_get_private_key(struct crypto_ec_key *key) |
| 6126 | +{ |
| 6127 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6128 | + if (ecp_kp == NULL) |
| 6129 | + return NULL; |
| 6130 | + mbedtls_mpi *bn = os_malloc(sizeof(*bn)); |
| 6131 | + if (bn) { |
| 6132 | + /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ |
| 6133 | + mbedtls_mpi_init(bn); |
| 6134 | + mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); |
| 6135 | + if (mbedtls_mpi_copy(bn, ecp_kp_d)) { |
| 6136 | + mbedtls_mpi_free(bn); |
| 6137 | + os_free(bn); |
| 6138 | + bn = NULL; |
| 6139 | + } |
| 6140 | + } |
| 6141 | + return (struct crypto_bignum *)bn; |
| 6142 | +} |
| 6143 | + |
| 6144 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6145 | + |
| 6146 | +static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len) |
| 6147 | +{ |
| 6148 | + /* get mbedtls_md_type_t from length of hash data to be signed */ |
| 6149 | + switch (len) { |
| 6150 | + case 64: return MBEDTLS_MD_SHA512; |
| 6151 | + case 48: return MBEDTLS_MD_SHA384; |
| 6152 | + case 32: return MBEDTLS_MD_SHA256; |
| 6153 | + case 20: return MBEDTLS_MD_SHA1; |
| 6154 | + case 16: return MBEDTLS_MD_MD5; |
| 6155 | + default: return MBEDTLS_MD_NONE; |
| 6156 | + } |
| 6157 | +} |
| 6158 | + |
| 6159 | +struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, |
| 6160 | + size_t len) |
| 6161 | +{ |
| 6162 | + #ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/ |
| 6163 | + #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE |
| 6164 | + #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN |
| 6165 | + #else |
| 6166 | + #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE |
| 6167 | + #endif |
| 6168 | + #endif |
| 6169 | + size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE; |
| 6170 | + struct wpabuf *buf = wpabuf_alloc(sig_len); |
| 6171 | + if (buf == NULL) |
| 6172 | + return NULL; |
| 6173 | + if (mbedtls_pk_sign((mbedtls_pk_context *)key, |
| 6174 | + crypto_ec_key_sign_md(len), data, len, |
| 6175 | + wpabuf_mhead_u8(buf), |
| 6176 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 6177 | + sig_len, |
| 6178 | + #endif |
| 6179 | + &sig_len, |
| 6180 | + mbedtls_ctr_drbg_random, |
| 6181 | + crypto_mbedtls_ctr_drbg()) == 0) { |
| 6182 | + wpabuf_put(buf, sig_len); |
| 6183 | + return buf; |
| 6184 | + } |
| 6185 | + |
| 6186 | + wpabuf_free(buf); |
| 6187 | + return NULL; |
| 6188 | +} |
| 6189 | + |
| 6190 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6191 | +struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key, |
| 6192 | + const u8 *data, size_t len) |
| 6193 | +{ |
| 6194 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6195 | + if (ecp_kp == NULL) |
| 6196 | + return NULL; |
| 6197 | + |
| 6198 | + size_t sig_len = MBEDTLS_ECDSA_MAX_LEN; |
| 6199 | + u8 buf[MBEDTLS_ECDSA_MAX_LEN]; |
| 6200 | + if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len), |
| 6201 | + data, len, buf, |
| 6202 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 6203 | + sig_len, |
| 6204 | + #endif |
| 6205 | + &sig_len, |
| 6206 | + mbedtls_ctr_drbg_random, |
| 6207 | + crypto_mbedtls_ctr_drbg())) { |
| 6208 | + return NULL; |
| 6209 | + } |
| 6210 | + |
| 6211 | + /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/ |
| 6212 | + /* parse ASN.1 to get r and s and lengths */ |
| 6213 | + u8 *p = buf, *r, *s; |
| 6214 | + u8 *end = p + sig_len; |
| 6215 | + size_t rlen, slen; |
| 6216 | + mbedtls_asn1_get_tag(&p, end, &rlen, |
| 6217 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6218 | + mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER); |
| 6219 | + r = p; |
| 6220 | + p += rlen; |
| 6221 | + mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER); |
| 6222 | + s = p; |
| 6223 | + |
| 6224 | + /* write raw r and s into out |
| 6225 | + * (including removal of leading 0 if added for ASN.1 integer) |
| 6226 | + * note: DPP caller expects raw r, s each padded to prime len */ |
| 6227 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6228 | + size_t plen = CRYPTO_EC_plen(ecp_kp_grp); |
| 6229 | + if (rlen > plen) { |
| 6230 | + r += (rlen - plen); |
| 6231 | + rlen = plen; |
| 6232 | + } |
| 6233 | + if (slen > plen) { |
| 6234 | + s += (slen - plen); |
| 6235 | + slen = plen; |
| 6236 | + } |
| 6237 | + struct wpabuf *out = wpabuf_alloc(plen*2); |
| 6238 | + if (out) { |
| 6239 | + wpabuf_put(out, plen*2); |
| 6240 | + p = wpabuf_mhead_u8(out); |
| 6241 | + os_memset(p, 0, plen*2); |
| 6242 | + os_memcpy(p+plen*1-rlen, r, rlen); |
| 6243 | + os_memcpy(p+plen*2-slen, s, slen); |
| 6244 | + } |
| 6245 | + return out; |
| 6246 | +} |
| 6247 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6248 | + |
| 6249 | +int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, |
| 6250 | + size_t len, const u8 *sig, size_t sig_len) |
| 6251 | +{ |
| 6252 | + switch (mbedtls_pk_verify((mbedtls_pk_context *)key, |
| 6253 | + crypto_ec_key_sign_md(len), data, len, |
| 6254 | + sig, sig_len)) { |
| 6255 | + case 0: |
| 6256 | + /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ |
| 6257 | + return 1; |
| 6258 | + case MBEDTLS_ERR_ECP_VERIFY_FAILED: |
| 6259 | + return 0; |
| 6260 | + default: |
| 6261 | + return -1; |
| 6262 | + } |
| 6263 | +} |
| 6264 | + |
| 6265 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6266 | +int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key, |
| 6267 | + const u8 *data, size_t len, |
| 6268 | + const u8 *r, size_t r_len, |
| 6269 | + const u8 *s, size_t s_len) |
| 6270 | +{ |
| 6271 | + /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s |
| 6272 | + * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */ |
| 6273 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6274 | + if (ecp_kp == NULL) |
| 6275 | + return -1; |
| 6276 | + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6277 | + mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); |
| 6278 | + |
| 6279 | + mbedtls_mpi mpi_r; |
| 6280 | + mbedtls_mpi mpi_s; |
| 6281 | + mbedtls_mpi_init(&mpi_r); |
| 6282 | + mbedtls_mpi_init(&mpi_s); |
| 6283 | + int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len) |
| 6284 | + || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0; |
| 6285 | + if (ret == 0) { |
| 6286 | + ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len, |
| 6287 | + ecp_kp_Q, &mpi_r, &mpi_s); |
| 6288 | + ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1; |
| 6289 | + } |
| 6290 | + mbedtls_mpi_free(&mpi_r); |
| 6291 | + mbedtls_mpi_free(&mpi_s); |
| 6292 | + return ret; |
| 6293 | +} |
| 6294 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6295 | + |
| 6296 | +int crypto_ec_key_group(struct crypto_ec_key *key) |
| 6297 | +{ |
| 6298 | + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); |
| 6299 | + if (ecp_kp == NULL) |
| 6300 | + return -1; |
| 6301 | + mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp); |
| 6302 | + return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id); |
| 6303 | +} |
| 6304 | + |
| 6305 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP |
| 6306 | + |
| 6307 | +int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2) |
| 6308 | +{ |
| 6309 | +#if 0 /*(DPP is passing two public keys; unable to use pk_check_pair())*/ |
| 6310 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 6311 | + return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, |
| 6312 | + (const mbedtls_pk_context *)key2) ? -1 : 0; |
| 6313 | + #else |
| 6314 | + return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, |
| 6315 | + (const mbedtls_pk_context *)key2, |
| 6316 | + mbedtls_ctr_drbg_random, |
| 6317 | + crypto_mbedtls_ctr_drbg()) ? -1 : 0; |
| 6318 | + #endif |
| 6319 | +#else |
| 6320 | + mbedtls_ecp_keypair *ecp_kp1=mbedtls_pk_ec(*(mbedtls_pk_context *)key1); |
| 6321 | + mbedtls_ecp_keypair *ecp_kp2=mbedtls_pk_ec(*(mbedtls_pk_context *)key2); |
| 6322 | + if (ecp_kp1 == NULL || ecp_kp2 == NULL) |
| 6323 | + return -1; |
| 6324 | + mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp); |
| 6325 | + mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp); |
| 6326 | + mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q); |
| 6327 | + mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q); |
| 6328 | + return ecp_kp1_grp->id != ecp_kp2_grp->id |
| 6329 | + || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0; |
| 6330 | +#endif |
| 6331 | +} |
| 6332 | + |
| 6333 | +void crypto_ec_key_debug_print(const struct crypto_ec_key *key, |
| 6334 | + const char *title) |
| 6335 | +{ |
| 6336 | + /* TBD: what info is desirable here and in what human readable format?*/ |
| 6337 | + /*(crypto_openssl.c prints a human-readably public key and attributes)*/ |
| 6338 | + #if 0 |
| 6339 | + struct mbedtls_pk_debug_item debug_item; |
| 6340 | + if (mbedtls_pk_debug((const mbedtls_pk_context *)key, &debug_item)) |
| 6341 | + return; |
| 6342 | + /* ... */ |
| 6343 | + #endif |
| 6344 | + wpa_printf(MSG_DEBUG, "%s: %s not implemented", title, __func__); |
| 6345 | +} |
| 6346 | + |
| 6347 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ |
| 6348 | + |
| 6349 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_EC */ |
| 6350 | + |
| 6351 | + |
| 6352 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_CSR |
| 6353 | + |
| 6354 | +#include <mbedtls/x509_csr.h> |
| 6355 | +#include <mbedtls/oid.h> |
| 6356 | + |
| 6357 | +struct crypto_csr * crypto_csr_init(void) |
| 6358 | +{ |
| 6359 | + mbedtls_x509write_csr *csr = os_malloc(sizeof(*csr)); |
| 6360 | + if (csr != NULL) |
| 6361 | + mbedtls_x509write_csr_init(csr); |
| 6362 | + return (struct crypto_csr *)csr; |
| 6363 | +} |
| 6364 | + |
| 6365 | +struct crypto_csr * crypto_csr_verify(const struct wpabuf *req) |
| 6366 | +{ |
| 6367 | + /* future: look for alternatives to MBEDTLS_PRIVATE() access */ |
| 6368 | + |
| 6369 | + /* sole caller src/common/dpp_crypto.c:dpp_validate_csr() |
| 6370 | + * uses (mbedtls_x509_csr *) to obtain CSR_ATTR_CHALLENGE_PASSWORD |
| 6371 | + * so allocate different object (mbedtls_x509_csr *) and special-case |
| 6372 | + * object when used in crypto_csr_get_attribute() and when free()d in |
| 6373 | + * crypto_csr_deinit(). */ |
| 6374 | + |
| 6375 | + mbedtls_x509_csr *csr = os_malloc(sizeof(*csr)); |
| 6376 | + if (csr == NULL) |
| 6377 | + return NULL; |
| 6378 | + mbedtls_x509_csr_init(csr); |
| 6379 | + const mbedtls_md_info_t *md_info; |
| 6380 | + unsigned char digest[MBEDTLS_MD_MAX_SIZE]; |
| 6381 | + if (mbedtls_x509_csr_parse_der(csr,wpabuf_head(req),wpabuf_len(req))==0 |
| 6382 | + && (md_info=mbedtls_md_info_from_type(csr->MBEDTLS_PRIVATE(sig_md))) |
| 6383 | + != NULL |
| 6384 | + && mbedtls_md(md_info, csr->cri.p, csr->cri.len, digest) == 0) { |
| 6385 | + switch (mbedtls_pk_verify(&csr->pk,csr->MBEDTLS_PRIVATE(sig_md), |
| 6386 | + digest, mbedtls_md_get_size(md_info), |
| 6387 | + csr->MBEDTLS_PRIVATE(sig).p, |
| 6388 | + csr->MBEDTLS_PRIVATE(sig).len)) { |
| 6389 | + case 0: |
| 6390 | + /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ |
| 6391 | + return (struct crypto_csr *)((uintptr_t)csr | 1uL); |
| 6392 | + default: |
| 6393 | + break; |
| 6394 | + } |
| 6395 | + } |
| 6396 | + |
| 6397 | + mbedtls_x509_csr_free(csr); |
| 6398 | + os_free(csr); |
| 6399 | + return NULL; |
| 6400 | +} |
| 6401 | + |
| 6402 | +void crypto_csr_deinit(struct crypto_csr *csr) |
| 6403 | +{ |
| 6404 | + if ((uintptr_t)csr & 1uL) { |
| 6405 | + csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); |
| 6406 | + mbedtls_x509_csr_free((mbedtls_x509_csr *)csr); |
| 6407 | + } |
| 6408 | + else |
| 6409 | + mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr); |
| 6410 | + os_free(csr); |
| 6411 | +} |
| 6412 | + |
| 6413 | +int crypto_csr_set_ec_public_key(struct crypto_csr *csr, |
| 6414 | + struct crypto_ec_key *key) |
| 6415 | +{ |
| 6416 | + mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr, |
| 6417 | + (mbedtls_pk_context *)key); |
| 6418 | + return 0; |
| 6419 | +} |
| 6420 | + |
| 6421 | +int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type, |
| 6422 | + const char *name) |
| 6423 | +{ |
| 6424 | + /* specialized for src/common/dpp_crypto.c */ |
| 6425 | + |
| 6426 | + /* sole caller src/common/dpp_crypto.c:dpp_build_csr() |
| 6427 | + * calls this function only once, using type == CSR_NAME_CN |
| 6428 | + * (If called more than once, this code would need to append |
| 6429 | + * components to the subject name, which we could do by |
| 6430 | + * appending to (mbedtls_x509write_csr *) private member |
| 6431 | + * mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject)) */ |
| 6432 | + |
| 6433 | + const char *label; |
| 6434 | + switch (type) { |
| 6435 | + case CSR_NAME_CN: label = "CN="; break; |
| 6436 | + case CSR_NAME_SN: label = "SN="; break; |
| 6437 | + case CSR_NAME_C: label = "C="; break; |
| 6438 | + case CSR_NAME_O: label = "O="; break; |
| 6439 | + case CSR_NAME_OU: label = "OU="; break; |
| 6440 | + default: return -1; |
| 6441 | + } |
| 6442 | + |
| 6443 | + size_t len = strlen(name); |
| 6444 | + struct wpabuf *buf = wpabuf_alloc(3+len+1); |
| 6445 | + if (buf == NULL) |
| 6446 | + return -1; |
| 6447 | + wpabuf_put_data(buf, label, strlen(label)); |
| 6448 | + wpabuf_put_data(buf, name, len+1); /*(include trailing '\0')*/ |
| 6449 | + /* Note: 'name' provided is set as given and should be backslash-escaped |
| 6450 | + * by caller when necessary, e.g. literal ',' which are not separating |
| 6451 | + * components should be backslash-escaped */ |
| 6452 | + |
| 6453 | + int ret = |
| 6454 | + mbedtls_x509write_csr_set_subject_name((mbedtls_x509write_csr *)csr, |
| 6455 | + wpabuf_head(buf)) ? -1 : 0; |
| 6456 | + wpabuf_free(buf); |
| 6457 | + return ret; |
| 6458 | +} |
| 6459 | + |
| 6460 | +/* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ |
| 6461 | +static const char OBJ_pkcs9_challengePassword[] = MBEDTLS_OID_PKCS9 "\x07"; |
| 6462 | + |
| 6463 | +int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr, |
| 6464 | + int attr_type, const u8 *value, size_t len) |
| 6465 | +{ |
| 6466 | + /* specialized for src/common/dpp_crypto.c */ |
| 6467 | + /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes |
| 6468 | + * attr == CSR_ATTR_CHALLENGE_PASSWORD |
| 6469 | + * attr_type == ASN1_TAG_UTF8STRING */ |
| 6470 | + |
| 6471 | + const char *oid; |
| 6472 | + size_t oid_len; |
| 6473 | + switch (attr) { |
| 6474 | + case CSR_ATTR_CHALLENGE_PASSWORD: |
| 6475 | + oid = OBJ_pkcs9_challengePassword; |
| 6476 | + oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; |
| 6477 | + break; |
| 6478 | + default: |
| 6479 | + return -1; |
| 6480 | + } |
| 6481 | + |
| 6482 | + #if 0 /*(incorrect; sets an extension, not an attribute)*/ |
| 6483 | + return mbedtls_x509write_csr_set_extension((mbedtls_x509write_csr *)csr, |
| 6484 | + oid, oid_len, |
| 6485 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 6486 | + 0, /*(critical flag)*/ |
| 6487 | + #endif |
| 6488 | + value, len) ? -1 : 0; |
| 6489 | + #else |
| 6490 | + (void)oid; |
| 6491 | + (void)oid_len; |
| 6492 | + #endif |
| 6493 | + |
| 6494 | + /* mbedtls does not currently provide way to set an attribute in a CSR: |
| 6495 | + * https://github.com/Mbed-TLS/mbedtls/issues/4886 */ |
| 6496 | + wpa_printf(MSG_ERROR, |
| 6497 | + "mbedtls does not currently support setting challengePassword " |
| 6498 | + "attribute in CSR"); |
| 6499 | + return -1; |
| 6500 | +} |
| 6501 | + |
| 6502 | +const u8 * mbedtls_x509_csr_attr_oid_value(mbedtls_x509_csr *csr, |
| 6503 | + const char *oid, size_t oid_len, |
| 6504 | + size_t *vlen, int *vtype) |
| 6505 | +{ |
| 6506 | + /* Note: mbedtls_x509_csr_parse_der() has parsed and validated CSR, |
| 6507 | + * so validation checks are not repeated here |
| 6508 | + * |
| 6509 | + * It would be nicer if (mbedtls_x509_csr *) had an mbedtls_x509_buf of |
| 6510 | + * Attributes (or at least a pointer) since mbedtls_x509_csr_parse_der() |
| 6511 | + * already parsed the rest of CertificationRequestInfo, some of which is |
| 6512 | + * repeated here to step to Attributes. Since csr->subject_raw.p points |
| 6513 | + * into csr->cri.p, which points into csr->raw.p, step over version and |
| 6514 | + * subject of CertificationRequestInfo (SEQUENCE) */ |
| 6515 | + unsigned char *p = csr->subject_raw.p + csr->subject_raw.len; |
| 6516 | + unsigned char *end = csr->cri.p + csr->cri.len, *ext; |
| 6517 | + size_t len; |
| 6518 | + |
| 6519 | + /* step over SubjectPublicKeyInfo */ |
| 6520 | + mbedtls_asn1_get_tag(&p, end, &len, |
| 6521 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); |
| 6522 | + p += len; |
| 6523 | + |
| 6524 | + /* Attributes |
| 6525 | + * { ATTRIBUTE:IOSet } ::= SET OF { SEQUENCE { OID, value } } |
| 6526 | + */ |
| 6527 | + if (mbedtls_asn1_get_tag(&p, end, &len, |
| 6528 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) { |
| 6529 | + return NULL; |
| 6530 | + } |
| 6531 | + while (p < end) { |
| 6532 | + if (mbedtls_asn1_get_tag(&p, end, &len, |
| 6533 | + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) { |
| 6534 | + return NULL; |
| 6535 | + } |
| 6536 | + ext = p; |
| 6537 | + p += len; |
| 6538 | + |
| 6539 | + if (mbedtls_asn1_get_tag(&ext,end,&len,MBEDTLS_ASN1_OID) != 0) |
| 6540 | + return NULL; |
| 6541 | + if (oid_len != len || 0 != memcmp(ext, oid, oid_len)) |
| 6542 | + continue; |
| 6543 | + |
| 6544 | + /* found oid; return value */ |
| 6545 | + *vtype = *ext++; /* tag */ |
| 6546 | + return (mbedtls_asn1_get_len(&ext,end,vlen) == 0) ? ext : NULL; |
| 6547 | + } |
| 6548 | + |
| 6549 | + return NULL; |
| 6550 | +} |
| 6551 | + |
| 6552 | +const u8 * crypto_csr_get_attribute(struct crypto_csr *csr, |
| 6553 | + enum crypto_csr_attr attr, |
| 6554 | + size_t *len, int *type) |
| 6555 | +{ |
| 6556 | + /* specialized for src/common/dpp_crypto.c */ |
| 6557 | + /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes |
| 6558 | + * attr == CSR_ATTR_CHALLENGE_PASSWORD */ |
| 6559 | + |
| 6560 | + const char *oid; |
| 6561 | + size_t oid_len; |
| 6562 | + switch (attr) { |
| 6563 | + case CSR_ATTR_CHALLENGE_PASSWORD: |
| 6564 | + oid = OBJ_pkcs9_challengePassword; |
| 6565 | + oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; |
| 6566 | + break; |
| 6567 | + default: |
| 6568 | + return NULL; |
| 6569 | + } |
| 6570 | + |
| 6571 | + /* see crypto_csr_verify(); expecting (mbedtls_x509_csr *) tagged |=1 */ |
| 6572 | + if (!((uintptr_t)csr & 1uL)) |
| 6573 | + return NULL; |
| 6574 | + csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); |
| 6575 | + |
| 6576 | + return mbedtls_x509_csr_attr_oid_value((mbedtls_x509_csr *)csr, |
| 6577 | + oid, oid_len, len, type); |
| 6578 | +} |
| 6579 | + |
| 6580 | +struct wpabuf * crypto_csr_sign(struct crypto_csr *csr, |
| 6581 | + struct crypto_ec_key *key, |
| 6582 | + enum crypto_hash_alg algo) |
| 6583 | +{ |
| 6584 | + mbedtls_md_type_t sig_md; |
| 6585 | + switch (algo) { |
| 6586 | + #ifdef MBEDTLS_SHA256_C |
| 6587 | + case CRYPTO_HASH_ALG_SHA256: sig_md = MBEDTLS_MD_SHA256; break; |
| 6588 | + #endif |
| 6589 | + #ifdef MBEDTLS_SHA512_C |
| 6590 | + case CRYPTO_HASH_ALG_SHA384: sig_md = MBEDTLS_MD_SHA384; break; |
| 6591 | + case CRYPTO_HASH_ALG_SHA512: sig_md = MBEDTLS_MD_SHA512; break; |
| 6592 | + #endif |
| 6593 | + default: |
| 6594 | + return NULL; |
| 6595 | + } |
| 6596 | + mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md); |
| 6597 | + |
| 6598 | + #if 0 |
| 6599 | + unsigned char key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
| 6600 | + | MBEDTLS_X509_KU_KEY_CERT_SIGN; |
| 6601 | + if (mbedtls_x509write_csr_set_key_usage((mbedtls_x509write_csr *)csr, |
| 6602 | + key_usage)) |
| 6603 | + return NULL; |
| 6604 | + #endif |
| 6605 | + |
| 6606 | + #if 0 |
| 6607 | + unsigned char ns_cert_type = MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT |
| 6608 | + | MBEDTLS_X509_NS_CERT_TYPE_EMAIL; |
| 6609 | + if (mbedtls_x509write_csr_set_ns_cert_type((mbedtls_x509write_csr *)csr, |
| 6610 | + ns_cert_type)) |
| 6611 | + return NULL; |
| 6612 | + #endif |
| 6613 | + |
| 6614 | + #if 0 |
| 6615 | + /* mbedtls does not currently provide way to set an attribute in a CSR: |
| 6616 | + * https://github.com/Mbed-TLS/mbedtls/issues/4886 |
| 6617 | + * XXX: hwsim dpp_enterprise test fails due to this limitation. |
| 6618 | + * |
| 6619 | + * Current usage of this function is solely by dpp_build_csr(), |
| 6620 | + * so as a kludge, might consider custom (struct crypto_csr *) |
| 6621 | + * containing (mbedtls_x509write_csr *) and a list of attributes |
| 6622 | + * (i.e. challengePassword). Might have to totally reimplement |
| 6623 | + * mbedtls_x509write_csr_der(); underlying x509write_csr_der_internal() |
| 6624 | + * handles signing the CSR. (This is more work that appending an |
| 6625 | + * Attributes section to end of CSR and adjusting ASN.1 length of CSR.) |
| 6626 | + */ |
| 6627 | + #endif |
| 6628 | + |
| 6629 | + unsigned char buf[4096]; /* XXX: large enough? too large? */ |
| 6630 | + int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, |
| 6631 | + buf, sizeof(buf), |
| 6632 | + mbedtls_ctr_drbg_random, |
| 6633 | + crypto_mbedtls_ctr_drbg()); |
| 6634 | + if (len < 0) |
| 6635 | + return NULL; |
| 6636 | + /* Note: data is written at the end of the buffer! Use the |
| 6637 | + * return value to determine where you should start |
| 6638 | + * using the buffer */ |
| 6639 | + return wpabuf_alloc_copy(buf+sizeof(buf)-len, (size_t)len); |
| 6640 | +} |
| 6641 | + |
| 6642 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_CSR */ |
| 6643 | + |
| 6644 | + |
| 6645 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_PKCS7 |
| 6646 | + |
| 6647 | +#if 0 |
| 6648 | +#include <mbedtls/pkcs7.h> /* PKCS7 is not currently supported in mbedtls */ |
| 6649 | +#include <mbedtls/pem.h> |
| 6650 | +#endif |
| 6651 | + |
| 6652 | +struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7) |
| 6653 | +{ |
| 6654 | + /* PKCS7 is not currently supported in mbedtls */ |
| 6655 | + return NULL; |
| 6656 | + |
| 6657 | +#if 0 |
| 6658 | + /* https://github.com/naynajain/mbedtls-1 branch: development-pkcs7 |
| 6659 | + * (??? potential future contribution to mbedtls ???) */ |
| 6660 | + |
| 6661 | + /* Note: PKCS7 signature *is not* verified by this function. |
| 6662 | + * The function interface does not provide for passing a certificate */ |
| 6663 | + |
| 6664 | + mbedtls_pkcs7 mpkcs7; |
| 6665 | + mbedtls_pkcs7_init(&mpkcs7); |
| 6666 | + int pkcs7_type = mbedtls_pkcs7_parse_der(wpabuf_head(pkcs7), |
| 6667 | + wpabuf_len(pkcs7), |
| 6668 | + &mpkcs7); |
| 6669 | + wpabuf *buf = NULL; |
| 6670 | + do { |
| 6671 | + if (pkcs7_type < 0) |
| 6672 | + break; |
| 6673 | + |
| 6674 | + /* src/common/dpp.c:dpp_parse_cred_dot1x() interested in certs |
| 6675 | + * for wpa_supplicant/dpp_supplicant.c:wpas_dpp_add_network() |
| 6676 | + * (? are adding certificate headers and footers desired ?) */ |
| 6677 | + |
| 6678 | + /* development-pkcs7 branch does not currently provide |
| 6679 | + * additional interfaces to retrieve the parsed data */ |
| 6680 | + |
| 6681 | + mbedtls_x509_crt *certs = |
| 6682 | + &mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(certs); |
| 6683 | + int ncerts = |
| 6684 | + mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(no_of_certs); |
| 6685 | + |
| 6686 | + /* allocate buffer for PEM (base64-encoded DER) |
| 6687 | + * plus header, footer, newlines, and some extra */ |
| 6688 | + buf = wpabuf_alloc((wpabuf_len(pkcs7)+2)/3*4 + ncerts*64); |
| 6689 | + if (buf == NULL) |
| 6690 | + break; |
| 6691 | + |
| 6692 | + #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" |
| 6693 | + #define PEM_END_CRT "-----END CERTIFICATE-----\n" |
| 6694 | + size_t olen; |
| 6695 | + for (int i = 0; i < ncerts; ++i) { |
| 6696 | + int ret = mbedtls_pem_write_buffer( |
| 6697 | + PEM_BEGIN_CRT, PEM_END_CRT, |
| 6698 | + certs[i].raw.p, certs[i].raw.len, |
| 6699 | + wpabuf_mhead(buf, 0), wpabuf_tailroom(buf), |
| 6700 | + &olen)); |
| 6701 | + if (ret == 0) |
| 6702 | + wpabuf_put(buf, olen); |
| 6703 | + } else { |
| 6704 | + if (ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) |
| 6705 | + ret = wpabuf_resize( |
| 6706 | + &buf,olen-wpabuf_tailroom(buf)); |
| 6707 | + if (ret == 0) { |
| 6708 | + --i;/*(adjust loop iterator for retry)*/ |
| 6709 | + continue; |
| 6710 | + } |
| 6711 | + wpabuf_free(buf); |
| 6712 | + buf = NULL; |
| 6713 | + break; |
| 6714 | + } |
| 6715 | + } |
| 6716 | + } while (0); |
| 6717 | + |
| 6718 | + mbedtls_pkcs7_free(&mpkcs7); |
| 6719 | + return buf; |
| 6720 | +#endif |
| 6721 | +} |
| 6722 | + |
| 6723 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_PKCS7 */ |
| 6724 | + |
| 6725 | + |
| 6726 | +#ifdef MBEDTLS_ARC4_C |
| 6727 | +#include <mbedtls/arc4.h> |
| 6728 | +int rc4_skip(const u8 *key, size_t keylen, size_t skip, |
| 6729 | + u8 *data, size_t data_len) |
| 6730 | +{ |
| 6731 | + mbedtls_arc4_context ctx; |
| 6732 | + mbedtls_arc4_init(&ctx); |
| 6733 | + mbedtls_arc4_setup(&ctx, key, keylen); |
| 6734 | + |
| 6735 | + if (skip) { |
| 6736 | + /*(prefer [16] on ancient hardware with smaller cache lines)*/ |
| 6737 | + unsigned char skip_buf[64]; /*('skip' is generally small)*/ |
| 6738 | + /*os_memset(skip_buf, 0, sizeof(skip_buf));*/ /*(necessary?)*/ |
| 6739 | + size_t len; |
| 6740 | + do { |
| 6741 | + len = skip > sizeof(skip_buf) ? sizeof(skip_buf) : skip; |
| 6742 | + mbedtls_arc4_crypt(&ctx, len, skip_buf, skip_buf); |
| 6743 | + } while ((skip -= len)); |
| 6744 | + } |
| 6745 | + |
| 6746 | + int ret = mbedtls_arc4_crypt(&ctx, data_len, data, data); |
| 6747 | + mbedtls_arc4_free(&ctx); |
| 6748 | + return ret; |
| 6749 | +} |
| 6750 | +#endif |
| 6751 | + |
| 6752 | + |
| 6753 | +/* duplicated in tls_mbedtls.c:tls_mbedtls_readfile()*/ |
| 6754 | +__attribute_noinline__ |
| 6755 | +static int crypto_mbedtls_readfile(const char *path, u8 **buf, size_t *n) |
| 6756 | +{ |
| 6757 | + #if 0 /* #ifdef MBEDTLS_FS_IO */ |
| 6758 | + /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ |
| 6759 | + if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { |
| 6760 | + wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); |
| 6761 | + return -1; |
| 6762 | + } |
| 6763 | + #else |
| 6764 | + /*(use os_readfile() so that we can use os_free() |
| 6765 | + *(if we use mbedtls_pk_load_file() above, macros prevent calling free() |
| 6766 | + * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() |
| 6767 | + * on buf aborts in tests if buf not allocated via os_malloc())*/ |
| 6768 | + *buf = (u8 *)os_readfile(path, n); |
| 6769 | + if (!*buf) { |
| 6770 | + wpa_printf(MSG_ERROR, "error: os_readfile %s", path); |
| 6771 | + return -1; |
| 6772 | + } |
| 6773 | + u8 *buf0 = os_realloc(*buf, *n+1); |
| 6774 | + if (!buf0) { |
| 6775 | + bin_clear_free(*buf, *n); |
| 6776 | + *buf = NULL; |
| 6777 | + return -1; |
| 6778 | + } |
| 6779 | + buf0[(*n)++] = '\0'; |
| 6780 | + *buf = buf0; |
| 6781 | + #endif |
| 6782 | + return 0; |
| 6783 | +} |
| 6784 | + |
| 6785 | + |
| 6786 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_RSA |
| 6787 | +#ifdef MBEDTLS_RSA_C |
| 6788 | + |
| 6789 | +#include <mbedtls/pk.h> |
| 6790 | +#include <mbedtls/rsa.h> |
| 6791 | + |
| 6792 | +struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key) |
| 6793 | +{ |
| 6794 | + /* mbedtls_pk_parse_keyfile() and mbedtls_pk_parse_public_keyfile() |
| 6795 | + * require #ifdef MBEDTLS_FS_IO in mbedtls library. Prefer to use |
| 6796 | + * crypto_mbedtls_readfile(), which wraps os_readfile() */ |
| 6797 | + u8 *data; |
| 6798 | + size_t len; |
| 6799 | + if (crypto_mbedtls_readfile(file, &data, &len) != 0) |
| 6800 | + return NULL; |
| 6801 | + |
| 6802 | + mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); |
| 6803 | + if (ctx == NULL) { |
| 6804 | + bin_clear_free(data, len); |
| 6805 | + return NULL; |
| 6806 | + } |
| 6807 | + mbedtls_pk_init(ctx); |
| 6808 | + |
| 6809 | + int rc; |
| 6810 | + rc = (private_key |
| 6811 | + ? mbedtls_pk_parse_key(ctx, data, len, NULL, 0 |
| 6812 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 6813 | + ,mbedtls_ctr_drbg_random, |
| 6814 | + crypto_mbedtls_ctr_drbg() |
| 6815 | + #endif |
| 6816 | + ) |
| 6817 | + : mbedtls_pk_parse_public_key(ctx, data, len)) == 0 |
| 6818 | + && mbedtls_pk_can_do(ctx, MBEDTLS_PK_RSA); |
| 6819 | + |
| 6820 | + bin_clear_free(data, len); |
| 6821 | + |
| 6822 | + if (rc) { |
| 6823 | + /* use MBEDTLS_RSA_PKCS_V21 padding for RSAES-OAEP */ |
| 6824 | + /* use MBEDTLS_MD_SHA256 for these hostap interfaces */ |
| 6825 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 6826 | + /*(no return value in mbedtls 2.x)*/ |
| 6827 | + mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), |
| 6828 | + MBEDTLS_RSA_PKCS_V21, |
| 6829 | + MBEDTLS_MD_SHA256); |
| 6830 | + #else |
| 6831 | + if (mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), |
| 6832 | + MBEDTLS_RSA_PKCS_V21, |
| 6833 | + MBEDTLS_MD_SHA256) == 0) |
| 6834 | + #endif |
| 6835 | + return (struct crypto_rsa_key *)ctx; |
| 6836 | + } |
| 6837 | + |
| 6838 | + mbedtls_pk_free(ctx); |
| 6839 | + os_free(ctx); |
| 6840 | + return NULL; |
| 6841 | +} |
| 6842 | + |
| 6843 | +struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key, |
| 6844 | + const struct wpabuf *in) |
| 6845 | +{ |
| 6846 | + mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); |
| 6847 | + size_t olen = mbedtls_rsa_get_len(pk_rsa); |
| 6848 | + struct wpabuf *buf = wpabuf_alloc(olen); |
| 6849 | + if (buf == NULL) |
| 6850 | + return NULL; |
| 6851 | + |
| 6852 | + /* mbedtls_pk_encrypt() takes a few more hops to get to same func */ |
| 6853 | + if (mbedtls_rsa_rsaes_oaep_encrypt(pk_rsa, |
| 6854 | + mbedtls_ctr_drbg_random, |
| 6855 | + crypto_mbedtls_ctr_drbg(), |
| 6856 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 6857 | + MBEDTLS_RSA_PRIVATE, |
| 6858 | + #endif |
| 6859 | + NULL, 0, |
| 6860 | + wpabuf_len(in), wpabuf_head(in), |
| 6861 | + wpabuf_put(buf, olen)) == 0) { |
| 6862 | + return buf; |
| 6863 | + } |
| 6864 | + |
| 6865 | + wpabuf_clear_free(buf); |
| 6866 | + return NULL; |
| 6867 | +} |
| 6868 | + |
| 6869 | +struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key, |
| 6870 | + const struct wpabuf *in) |
| 6871 | +{ |
| 6872 | + mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); |
| 6873 | + size_t olen = mbedtls_rsa_get_len(pk_rsa); |
| 6874 | + struct wpabuf *buf = wpabuf_alloc(olen); |
| 6875 | + if (buf == NULL) |
| 6876 | + return NULL; |
| 6877 | + |
| 6878 | + /* mbedtls_pk_decrypt() takes a few more hops to get to same func */ |
| 6879 | + if (mbedtls_rsa_rsaes_oaep_decrypt(pk_rsa, |
| 6880 | + mbedtls_ctr_drbg_random, |
| 6881 | + crypto_mbedtls_ctr_drbg(), |
| 6882 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 6883 | + MBEDTLS_RSA_PUBLIC, |
| 6884 | + #endif |
| 6885 | + NULL, 0, &olen, wpabuf_head(in), |
| 6886 | + wpabuf_mhead(buf), olen) == 0) { |
| 6887 | + wpabuf_put(buf, olen); |
| 6888 | + return buf; |
| 6889 | + } |
| 6890 | + |
| 6891 | + wpabuf_clear_free(buf); |
| 6892 | + return NULL; |
| 6893 | +} |
| 6894 | + |
| 6895 | +void crypto_rsa_key_free(struct crypto_rsa_key *key) |
| 6896 | +{ |
| 6897 | + mbedtls_pk_free((mbedtls_pk_context *)key); |
| 6898 | + os_free(key); |
| 6899 | +} |
| 6900 | + |
| 6901 | +#endif /* MBEDTLS_RSA_C */ |
| 6902 | +#endif /* CRYPTO_MBEDTLS_CRYPTO_RSA */ |
| 6903 | + |
| 6904 | +#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE |
| 6905 | + |
| 6906 | +struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id, |
| 6907 | + enum hpke_kdf_id kdf_id, |
| 6908 | + enum hpke_aead_id aead_id, |
| 6909 | + struct crypto_ec_key *peer_pub, |
| 6910 | + const u8 *info, size_t info_len, |
| 6911 | + const u8 *aad, size_t aad_len, |
| 6912 | + const u8 *pt, size_t pt_len) |
| 6913 | +{ |
| 6914 | + /* not yet implemented */ |
| 6915 | + return NULL; |
| 6916 | +} |
| 6917 | + |
| 6918 | +struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id, |
| 6919 | + enum hpke_kdf_id kdf_id, |
| 6920 | + enum hpke_aead_id aead_id, |
| 6921 | + struct crypto_ec_key *own_priv, |
| 6922 | + const u8 *info, size_t info_len, |
| 6923 | + const u8 *aad, size_t aad_len, |
| 6924 | + const u8 *enc_ct, size_t enc_ct_len) |
| 6925 | +{ |
| 6926 | + /* not yet implemented */ |
| 6927 | + return NULL; |
| 6928 | +} |
| 6929 | + |
| 6930 | +#endif |
| 6931 | diff --git a/src/crypto/crypto_module_tests.c b/src/crypto/crypto_module_tests.c |
| 6932 | index ffeddbadd..07c36d850 100644 |
| 6933 | --- a/src/crypto/crypto_module_tests.c |
| 6934 | +++ b/src/crypto/crypto_module_tests.c |
| 6935 | @@ -2470,6 +2470,139 @@ static int test_hpke(void) |
| 6936 | } |
| 6937 | |
| 6938 | |
| 6939 | +static int test_ecc(void) |
| 6940 | +{ |
| 6941 | +#ifdef CONFIG_ECC |
| 6942 | +#ifndef CONFIG_TLS_INTERNAL |
| 6943 | +#ifndef CONFIG_TLS_GNUTLS |
| 6944 | +#if defined(CONFIG_TLS_MBEDTLS) \ |
| 6945 | + || defined(CONFIG_TLS_OPENSSL) \ |
| 6946 | + || defined(CONFIG_TLS_WOLFSSL) |
| 6947 | + wpa_printf(MSG_INFO, "Testing ECC"); |
| 6948 | + /* Note: some tests below are valid on supported Short Weierstrass |
| 6949 | + * curves, but not on Montgomery curves (e.g. IKE groups 31 and 32) |
| 6950 | + * (e.g. deriving and comparing y^2 test below not valid on Montgomery) |
| 6951 | + */ |
| 6952 | +#ifdef CONFIG_TLS_MBEDTLS |
| 6953 | + const int grps[] = {19, 20, 21, 25, 26, 28}; |
| 6954 | +#endif |
| 6955 | +#ifdef CONFIG_TLS_OPENSSL |
| 6956 | + const int grps[] = {19, 20, 21, 26}; |
| 6957 | +#endif |
| 6958 | +#ifdef CONFIG_TLS_WOLFSSL |
| 6959 | + const int grps[] = {19, 20, 21, 26}; |
| 6960 | +#endif |
| 6961 | + uint32_t i; |
| 6962 | + struct crypto_ec *e = NULL; |
| 6963 | + struct crypto_ec_point *p = NULL, *q = NULL; |
| 6964 | + struct crypto_bignum *x = NULL, *y = NULL; |
| 6965 | +#ifdef CONFIG_DPP |
| 6966 | + u8 bin[4096]; |
| 6967 | +#endif |
| 6968 | + for (i = 0; i < ARRAY_SIZE(grps); ++i) { |
| 6969 | + e = crypto_ec_init(grps[i]); |
| 6970 | + if (e == NULL |
| 6971 | + || crypto_ec_prime_len(e) == 0 |
| 6972 | + || crypto_ec_prime_len_bits(e) == 0 |
| 6973 | + || crypto_ec_order_len(e) == 0 |
| 6974 | + || crypto_ec_get_prime(e) == NULL |
| 6975 | + || crypto_ec_get_order(e) == NULL |
| 6976 | + || crypto_ec_get_a(e) == NULL |
| 6977 | + || crypto_ec_get_b(e) == NULL |
| 6978 | + || crypto_ec_get_generator(e) == NULL) { |
| 6979 | + break; |
| 6980 | + } |
| 6981 | +#ifdef CONFIG_DPP |
| 6982 | + struct crypto_ec_key *key = crypto_ec_key_gen(grps[i]); |
| 6983 | + if (key == NULL) |
| 6984 | + break; |
| 6985 | + p = crypto_ec_key_get_public_key(key); |
| 6986 | + q = crypto_ec_key_get_public_key(key); |
| 6987 | + crypto_ec_key_deinit(key); |
| 6988 | + if (p == NULL || q == NULL) |
| 6989 | + break; |
| 6990 | + if (!crypto_ec_point_is_on_curve(e, p)) |
| 6991 | + break; |
| 6992 | + |
| 6993 | + /* inverted point should not match original; |
| 6994 | + * double-invert should match */ |
| 6995 | + if (crypto_ec_point_invert(e, q) != 0 |
| 6996 | + || crypto_ec_point_cmp(e, p, q) == 0 |
| 6997 | + || crypto_ec_point_invert(e, q) != 0 |
| 6998 | + || crypto_ec_point_cmp(e, p, q) != 0) { |
| 6999 | + break; |
| 7000 | + } |
| 7001 | + |
| 7002 | + /* crypto_ec_point_to_bin() and crypto_ec_point_from_bin() |
| 7003 | + * imbalanced interfaces? */ |
| 7004 | + size_t prime_len = crypto_ec_prime_len(e); |
| 7005 | + if (prime_len * 2 > sizeof(bin)) |
| 7006 | + break; |
| 7007 | + if (crypto_ec_point_to_bin(e, p, bin, bin+prime_len) != 0) |
| 7008 | + break; |
| 7009 | + struct crypto_ec_point *tmp = crypto_ec_point_from_bin(e, bin); |
| 7010 | + if (tmp == NULL) |
| 7011 | + break; |
| 7012 | + if (crypto_ec_point_cmp(e, p, tmp) != 0) { |
| 7013 | + crypto_ec_point_deinit(tmp, 0); |
| 7014 | + break; |
| 7015 | + } |
| 7016 | + crypto_ec_point_deinit(tmp, 0); |
| 7017 | + |
| 7018 | + x = crypto_bignum_init(); |
| 7019 | + y = crypto_bignum_init_set(bin+prime_len, prime_len); |
| 7020 | + if (x == NULL || y == NULL || crypto_ec_point_x(e, p, x) != 0) |
| 7021 | + break; |
| 7022 | + struct crypto_bignum *y2 = crypto_ec_point_compute_y_sqr(e, x); |
| 7023 | + if (y2 == NULL) |
| 7024 | + break; |
| 7025 | + if (crypto_bignum_sqrmod(y, crypto_ec_get_prime(e), y) != 0 |
| 7026 | + || crypto_bignum_cmp(y, y2) != 0) { |
| 7027 | + crypto_bignum_deinit(y2, 0); |
| 7028 | + break; |
| 7029 | + } |
| 7030 | + crypto_bignum_deinit(y2, 0); |
| 7031 | + crypto_bignum_deinit(x, 0); |
| 7032 | + crypto_bignum_deinit(y, 0); |
| 7033 | + x = NULL; |
| 7034 | + y = NULL; |
| 7035 | + |
| 7036 | + x = crypto_bignum_init(); |
| 7037 | + if (x == NULL) |
| 7038 | + break; |
| 7039 | + if (crypto_bignum_rand(x, crypto_ec_get_prime(e)) != 0) |
| 7040 | + break; |
| 7041 | + crypto_bignum_deinit(x, 0); |
| 7042 | + x = NULL; |
| 7043 | + |
| 7044 | + crypto_ec_point_deinit(p, 0); |
| 7045 | + p = NULL; |
| 7046 | + crypto_ec_point_deinit(q, 0); |
| 7047 | + q = NULL; |
| 7048 | +#endif /* CONFIG_DPP */ |
| 7049 | + crypto_ec_deinit(e); |
| 7050 | + e = NULL; |
| 7051 | + } |
| 7052 | + if (i != ARRAY_SIZE(grps)) { |
| 7053 | + crypto_bignum_deinit(x, 0); |
| 7054 | + crypto_bignum_deinit(y, 0); |
| 7055 | + crypto_ec_point_deinit(p, 0); |
| 7056 | + crypto_ec_point_deinit(q, 0); |
| 7057 | + crypto_ec_deinit(e); |
| 7058 | + wpa_printf(MSG_INFO, |
| 7059 | + "ECC test case failed tls_id:%d", grps[i]); |
| 7060 | + return -1; |
| 7061 | + } |
| 7062 | + |
| 7063 | + wpa_printf(MSG_INFO, "ECC test cases passed"); |
| 7064 | +#endif |
| 7065 | +#endif /* !CONFIG_TLS_GNUTLS */ |
| 7066 | +#endif /* !CONFIG_TLS_INTERNAL */ |
| 7067 | +#endif /* CONFIG_ECC */ |
| 7068 | + return 0; |
| 7069 | +} |
| 7070 | + |
| 7071 | + |
| 7072 | static int test_ms_funcs(void) |
| 7073 | { |
| 7074 | #ifndef CONFIG_FIPS |
| 7075 | @@ -2591,6 +2724,7 @@ int crypto_module_tests(void) |
| 7076 | test_fips186_2_prf() || |
| 7077 | test_extract_expand_hkdf() || |
| 7078 | test_hpke() || |
| 7079 | + test_ecc() || |
| 7080 | test_ms_funcs()) |
| 7081 | ret = -1; |
| 7082 | |
| 7083 | diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c |
| 7084 | index 269174321..a554fd8a8 100644 |
| 7085 | --- a/src/crypto/crypto_wolfssl.c |
| 7086 | +++ b/src/crypto/crypto_wolfssl.c |
| 7087 | @@ -1633,6 +1633,7 @@ struct crypto_ec { |
| 7088 | #ifdef CONFIG_DPP |
| 7089 | ecc_point *g; /* Only used in DPP for now */ |
| 7090 | #endif /* CONFIG_DPP */ |
| 7091 | + WC_RNG rng; |
| 7092 | mp_int a; |
| 7093 | mp_int prime; |
| 7094 | mp_int order; |
| 7095 | @@ -1666,6 +1667,20 @@ struct crypto_ec * crypto_ec_init(int group) |
| 7096 | e->key = ecc_key_init(); |
| 7097 | if (!e->key) { |
| 7098 | LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init); |
| 7099 | + |
| 7100 | + if (wc_ecc_init(e->key) != 0 || |
| 7101 | + wc_InitRng(e->rng) != 0 || |
| 7102 | + wc_ecc_set_rng(e->key, e->rng) != 0 || |
| 7103 | + wc_ecc_set_curve(e->key, 0, curve_id) != 0 || |
| 7104 | + mp_init(e->a) != MP_OKAY || |
| 7105 | + mp_init(e->prime) != MP_OKAY || |
| 7106 | + mp_init(e->order) != MP_OKAY || |
| 7107 | + mp_init(e->b) != MP_OKAY || |
| 7108 | + mp_read_radix(e->a, e->key.dp->Af, 16) != MP_OKAY || |
| 7109 | + mp_read_radix(e->b, e->key.dp->Bf, 16) != MP_OKAY || |
| 7110 | + mp_read_radix(e->prime, e->key.dp->prime, 16) != MP_OKAY || |
| 7111 | + mp_read_radix(e->order, e->key.dp->order, 16) != MP_OKAY || |
| 7112 | + mp_montgomery_setup(e->prime, e->mont_b) != MP_OKAY) |
| 7113 | goto done; |
| 7114 | } |
| 7115 | |
| 7116 | @@ -1764,6 +1779,9 @@ void crypto_ec_deinit(struct crypto_ec* e) |
| 7117 | #endif /* CONFIG_DPP */ |
| 7118 | if (e->own_key) |
| 7119 | ecc_key_deinit(e->key); |
| 7120 | + |
| 7121 | + wc_FreeRng(e->rng); |
| 7122 | + wc_ecc_free(e->key); |
| 7123 | os_free(e); |
| 7124 | } |
| 7125 | |
| 7126 | diff --git a/src/crypto/tls_mbedtls.c b/src/crypto/tls_mbedtls.c |
| 7127 | new file mode 100644 |
| 7128 | index 000000000..2580a3a27 |
| 7129 | --- /dev/null |
| 7130 | +++ b/src/crypto/tls_mbedtls.c |
| 7131 | @@ -0,0 +1,3313 @@ |
| 7132 | +/* |
| 7133 | + * SSL/TLS interface functions for mbed TLS |
| 7134 | + * |
| 7135 | + * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com> |
| 7136 | + * SPDX-License-Identifier: BSD-3-Clause |
| 7137 | + * |
| 7138 | + * This software may be distributed under the terms of the BSD license. |
| 7139 | + * See README for more details. |
| 7140 | + * |
| 7141 | + * template: src/crypto/tls_none.c |
| 7142 | + * reference: src/crypto/tls_*.c |
| 7143 | + * |
| 7144 | + * Known Limitations: |
| 7145 | + * - no TLSv1.3 (not available in mbedtls 2.x; experimental in mbedtls 3.x) |
| 7146 | + * - no OCSP (not yet available in mbedtls) |
| 7147 | + * - mbedtls does not support all certificate encodings used by hwsim tests |
| 7148 | + * PCKS#5 v1.5 |
| 7149 | + * PCKS#12 |
| 7150 | + * DH DSA |
| 7151 | + * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c |
| 7152 | + * - mbedtls does not currently provide way to set an attribute in a CSR |
| 7153 | + * https://github.com/Mbed-TLS/mbedtls/issues/4886 |
| 7154 | + * so tests/hwsim dpp_enterprise tests fail |
| 7155 | + * - DPP2 not supported |
| 7156 | + * PKCS#7 parsing is not supported in mbedtls |
| 7157 | + * See crypto_mbedtls.c:crypto_pkcs7_get_certificates() comments |
| 7158 | + * - DPP3 not supported |
| 7159 | + * hpke_base_seal() and hpke_base_seal() not implemented in crypto_mbedtls.c |
| 7160 | + * |
| 7161 | + * Status: |
| 7162 | + * - code written to be compatible with mbedtls 2.x and mbedtls 3.x |
| 7163 | + * (currently requires mbedtls >= 2.27.0 for mbedtls_mpi_random()) |
| 7164 | + * (currently requires mbedtls >= 2.18.0 for mbedtls_ssl_tls_prf()) |
| 7165 | + * - builds with tests/build/build-wpa_supplicant-mbedtls.config |
| 7166 | + * - passes all tests/ crypto module tests (incomplete coverage) |
| 7167 | + * ($ cd tests; make clean; make -j 4 run-tests CONFIG_TLS=mbedtls) |
| 7168 | + * - passes almost all tests/hwsim tests |
| 7169 | + * (hwsim tests skipped for missing features) |
| 7170 | + * |
| 7171 | + * RFE: |
| 7172 | + * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c |
| 7173 | + * - client/server session resumption, and/or save client session ticket |
| 7174 | + */ |
| 7175 | + |
| 7176 | +#include "includes.h" |
| 7177 | +#include "common.h" |
| 7178 | + |
| 7179 | +#include <mbedtls/version.h> |
| 7180 | +#include <mbedtls/ctr_drbg.h> |
| 7181 | +#include <mbedtls/error.h> |
| 7182 | +#include <mbedtls/oid.h> |
| 7183 | +#include <mbedtls/pem.h> |
| 7184 | +#include <mbedtls/platform.h> /* mbedtls_calloc() mbedtls_free() */ |
| 7185 | +#include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */ |
| 7186 | +#include <mbedtls/ssl.h> |
| 7187 | +#include <mbedtls/ssl_ticket.h> |
| 7188 | +#include <mbedtls/x509.h> |
| 7189 | +#include <mbedtls/x509_crt.h> |
| 7190 | + |
| 7191 | +#if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.4.0 */ |
| 7192 | +#include <mbedtls/net_sockets.h> |
| 7193 | +#else |
| 7194 | +#include <mbedtls/net.h> |
| 7195 | +#endif |
| 7196 | + |
| 7197 | +#ifndef MBEDTLS_PRIVATE |
| 7198 | +#define MBEDTLS_PRIVATE(x) x |
| 7199 | +#endif |
| 7200 | + |
| 7201 | +#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ |
| 7202 | +#define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \ |
| 7203 | + ((ssl)->MBEDTLS_PRIVATE(session) \ |
| 7204 | + ?(ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite) \ |
| 7205 | + : 0) |
| 7206 | +#define mbedtls_ssl_ciphersuite_get_name(info) \ |
| 7207 | + (info)->MBEDTLS_PRIVATE(name) |
| 7208 | +#endif |
| 7209 | + |
| 7210 | +#include "crypto.h" /* sha256_vector() */ |
| 7211 | +#include "tls.h" |
| 7212 | + |
| 7213 | +#ifndef SHA256_DIGEST_LENGTH |
| 7214 | +#define SHA256_DIGEST_LENGTH 32 |
| 7215 | +#endif |
| 7216 | + |
| 7217 | +#ifndef MBEDTLS_EXPKEY_FIXED_SECRET_LEN |
| 7218 | +#define MBEDTLS_EXPKEY_FIXED_SECRET_LEN 48 |
| 7219 | +#endif |
| 7220 | + |
| 7221 | +#ifndef MBEDTLS_EXPKEY_RAND_LEN |
| 7222 | +#define MBEDTLS_EXPKEY_RAND_LEN 32 |
| 7223 | +#endif |
| 7224 | + |
| 7225 | +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 7226 | +static mbedtls_ssl_export_keys_t tls_connection_export_keys_cb; |
| 7227 | +#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 7228 | +static mbedtls_ssl_export_keys_ext_t tls_connection_export_keys_cb; |
| 7229 | +#else /*(not implemented; return error)*/ |
| 7230 | +#define mbedtls_ssl_tls_prf(a,b,c,d,e,f,g,h) (-1) |
| 7231 | +typedef mbedtls_tls_prf_types int; |
| 7232 | +#endif |
| 7233 | + |
| 7234 | + |
| 7235 | +/* hostapd/wpa_supplicant provides forced_memzero(), |
| 7236 | + * but prefer mbedtls_platform_zeroize() */ |
| 7237 | +#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) |
| 7238 | + |
| 7239 | + |
| 7240 | +#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ |
| 7241 | + || defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) |
| 7242 | +#ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7243 | +#ifdef MBEDTLS_SSL_TICKET_C |
| 7244 | +#define TLS_MBEDTLS_SESSION_TICKETS |
| 7245 | +#if defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) |
| 7246 | +#define TLS_MBEDTLS_EAP_TEAP |
| 7247 | +#endif |
| 7248 | +#if !defined(CONFIG_FIPS) /* EAP-FAST keys cannot be exported in FIPS mode */ |
| 7249 | +#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) |
| 7250 | +#define TLS_MBEDTLS_EAP_FAST |
| 7251 | +#endif |
| 7252 | +#endif |
| 7253 | +#endif |
| 7254 | +#endif |
| 7255 | +#endif |
| 7256 | + |
| 7257 | + |
| 7258 | +struct tls_conf { |
| 7259 | + mbedtls_ssl_config conf; |
| 7260 | + |
| 7261 | + unsigned int verify_peer:1; |
| 7262 | + unsigned int verify_depth0_only:1; |
| 7263 | + unsigned int check_crl:2; /*(needs :2 bits for 0, 1, 2)*/ |
| 7264 | + unsigned int check_crl_strict:1; /*(needs :1 bit for 0, 1)*/ |
| 7265 | + unsigned int ca_cert_probe:1; |
| 7266 | + unsigned int has_ca_cert:1; |
| 7267 | + unsigned int has_client_cert:1; |
| 7268 | + unsigned int has_private_key:1; |
| 7269 | + unsigned int suiteb128:1; |
| 7270 | + unsigned int suiteb192:1; |
| 7271 | + mbedtls_x509_crl *crl; |
| 7272 | + mbedtls_x509_crt ca_cert; |
| 7273 | + mbedtls_x509_crt client_cert; |
| 7274 | + mbedtls_pk_context private_key; |
| 7275 | + |
| 7276 | + uint32_t refcnt; |
| 7277 | + |
| 7278 | + unsigned int flags; |
| 7279 | + char *subject_match; |
| 7280 | + char *altsubject_match; |
| 7281 | + char *suffix_match; |
| 7282 | + char *domain_match; |
| 7283 | + char *check_cert_subject; |
| 7284 | + u8 ca_cert_hash[SHA256_DIGEST_LENGTH]; |
| 7285 | + |
| 7286 | + int *ciphersuites; /* list of ciphersuite ids for mbedtls_ssl_config */ |
| 7287 | +#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ |
| 7288 | + mbedtls_ecp_group_id *curves; |
| 7289 | +#else |
| 7290 | + uint16_t *curves; /* list of curve ids for mbedtls_ssl_config */ |
| 7291 | +#endif |
| 7292 | +}; |
| 7293 | + |
| 7294 | + |
| 7295 | +struct tls_global { |
| 7296 | + struct tls_conf *tls_conf; |
| 7297 | + char *ocsp_stapling_response; |
| 7298 | + mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/ |
| 7299 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7300 | + mbedtls_ssl_ticket_context ticket_ctx; |
| 7301 | + #endif |
| 7302 | + char *ca_cert_file; |
| 7303 | + struct os_reltime crl_reload_previous; |
| 7304 | + unsigned int crl_reload_interval; |
| 7305 | + uint32_t refcnt; |
| 7306 | + struct tls_config init_conf; |
| 7307 | +}; |
| 7308 | + |
| 7309 | +static struct tls_global tls_ctx_global; |
| 7310 | + |
| 7311 | + |
| 7312 | +struct tls_connection { |
| 7313 | + struct tls_conf *tls_conf; |
| 7314 | + struct wpabuf *push_buf; |
| 7315 | + struct wpabuf *pull_buf; |
| 7316 | + size_t pull_buf_offset; |
| 7317 | + |
| 7318 | + unsigned int established:1; |
| 7319 | + unsigned int resumed:1; |
| 7320 | + unsigned int verify_peer:1; |
| 7321 | + unsigned int is_server:1; |
| 7322 | + |
| 7323 | + mbedtls_ssl_context ssl; |
| 7324 | + |
| 7325 | + mbedtls_tls_prf_types tls_prf_type; |
| 7326 | + size_t expkey_keyblock_size; |
| 7327 | + size_t expkey_secret_len; |
| 7328 | + #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 7329 | + unsigned char expkey_secret[MBEDTLS_EXPKEY_FIXED_SECRET_LEN]; |
| 7330 | + #else |
| 7331 | + unsigned char expkey_secret[MBEDTLS_MD_MAX_SIZE]; |
| 7332 | + #endif |
| 7333 | + unsigned char expkey_randbytes[MBEDTLS_EXPKEY_RAND_LEN*2]; |
| 7334 | + |
| 7335 | + int read_alerts, write_alerts, failed; |
| 7336 | + |
| 7337 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 7338 | + tls_session_ticket_cb session_ticket_cb; |
| 7339 | + void *session_ticket_cb_ctx; |
| 7340 | + unsigned char *clienthello_session_ticket; |
| 7341 | + size_t clienthello_session_ticket_len; |
| 7342 | + #endif |
| 7343 | + char *peer_subject; /* peer subject info for authenticated peer */ |
| 7344 | + struct wpabuf *success_data; |
| 7345 | +}; |
| 7346 | + |
| 7347 | + |
| 7348 | +#ifndef __has_attribute |
| 7349 | +#define __has_attribute(x) 0 |
| 7350 | +#endif |
| 7351 | + |
| 7352 | +#ifndef __GNUC_PREREQ |
| 7353 | +#define __GNUC_PREREQ(maj,min) 0 |
| 7354 | +#endif |
| 7355 | + |
| 7356 | +#ifndef __attribute_cold__ |
| 7357 | +#if __has_attribute(cold) \ |
| 7358 | + || __GNUC_PREREQ(4,3) |
| 7359 | +#define __attribute_cold__ __attribute__((__cold__)) |
| 7360 | +#else |
| 7361 | +#define __attribute_cold__ |
| 7362 | +#endif |
| 7363 | +#endif |
| 7364 | + |
| 7365 | +#ifndef __attribute_noinline__ |
| 7366 | +#if __has_attribute(noinline) \ |
| 7367 | + || __GNUC_PREREQ(3,1) |
| 7368 | +#define __attribute_noinline__ __attribute__((__noinline__)) |
| 7369 | +#else |
| 7370 | +#define __attribute_noinline__ |
| 7371 | +#endif |
| 7372 | +#endif |
| 7373 | + |
| 7374 | + |
| 7375 | +__attribute_cold__ |
| 7376 | +__attribute_noinline__ |
| 7377 | +static void emsg(int level, const char * const msg) |
| 7378 | +{ |
| 7379 | + wpa_printf(level, "MTLS: %s", msg); |
| 7380 | +} |
| 7381 | + |
| 7382 | + |
| 7383 | +__attribute_cold__ |
| 7384 | +__attribute_noinline__ |
| 7385 | +static void emsgrc(int level, const char * const msg, int rc) |
| 7386 | +{ |
| 7387 | + #ifdef MBEDTLS_ERROR_C |
| 7388 | + /* error logging convenience function that decodes mbedtls result codes */ |
| 7389 | + char buf[256]; |
| 7390 | + mbedtls_strerror(rc, buf, sizeof(buf)); |
| 7391 | + wpa_printf(level, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc); |
| 7392 | + #else |
| 7393 | + wpa_printf(level, "MTLS: %s: (-0x%04x)", msg, -rc); |
| 7394 | + #endif |
| 7395 | +} |
| 7396 | + |
| 7397 | + |
| 7398 | +#define elog(rc, msg) emsgrc(MSG_ERROR, (msg), (rc)) |
| 7399 | +#define ilog(rc, msg) emsgrc(MSG_INFO, (msg), (rc)) |
| 7400 | + |
| 7401 | + |
| 7402 | +struct tls_conf * tls_conf_init(void *tls_ctx) |
| 7403 | +{ |
| 7404 | + struct tls_conf *tls_conf = os_zalloc(sizeof(*tls_conf)); |
| 7405 | + if (tls_conf == NULL) |
| 7406 | + return NULL; |
| 7407 | + tls_conf->refcnt = 1; |
| 7408 | + |
| 7409 | + mbedtls_ssl_config_init(&tls_conf->conf); |
| 7410 | + mbedtls_ssl_conf_rng(&tls_conf->conf, |
| 7411 | + mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg); |
| 7412 | + mbedtls_x509_crt_init(&tls_conf->ca_cert); |
| 7413 | + mbedtls_x509_crt_init(&tls_conf->client_cert); |
| 7414 | + mbedtls_pk_init(&tls_conf->private_key); |
| 7415 | + |
| 7416 | + return tls_conf; |
| 7417 | +} |
| 7418 | + |
| 7419 | + |
| 7420 | +void tls_conf_deinit(struct tls_conf *tls_conf) |
| 7421 | +{ |
| 7422 | + if (tls_conf == NULL || --tls_conf->refcnt != 0) |
| 7423 | + return; |
| 7424 | + |
| 7425 | + mbedtls_x509_crt_free(&tls_conf->ca_cert); |
| 7426 | + mbedtls_x509_crt_free(&tls_conf->client_cert); |
| 7427 | + if (tls_conf->crl) { |
| 7428 | + mbedtls_x509_crl_free(tls_conf->crl); |
| 7429 | + os_free(tls_conf->crl); |
| 7430 | + } |
| 7431 | + mbedtls_pk_free(&tls_conf->private_key); |
| 7432 | + mbedtls_ssl_config_free(&tls_conf->conf); |
| 7433 | + os_free(tls_conf->curves); |
| 7434 | + os_free(tls_conf->ciphersuites); |
| 7435 | + os_free(tls_conf->subject_match); |
| 7436 | + os_free(tls_conf->altsubject_match); |
| 7437 | + os_free(tls_conf->suffix_match); |
| 7438 | + os_free(tls_conf->domain_match); |
| 7439 | + os_free(tls_conf->check_cert_subject); |
| 7440 | + os_free(tls_conf); |
| 7441 | +} |
| 7442 | + |
| 7443 | + |
| 7444 | +mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ |
| 7445 | + |
| 7446 | +__attribute_cold__ |
| 7447 | +void * tls_init(const struct tls_config *conf) |
| 7448 | +{ |
| 7449 | + /* RFE: review struct tls_config *conf (different from tls_conf) */ |
| 7450 | + |
| 7451 | + if (++tls_ctx_global.refcnt > 1) |
| 7452 | + return &tls_ctx_global; |
| 7453 | + |
| 7454 | + tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg(); |
| 7455 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7456 | + mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx); |
| 7457 | + mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, |
| 7458 | + mbedtls_ctr_drbg_random, |
| 7459 | + tls_ctx_global.ctr_drbg, |
| 7460 | + MBEDTLS_CIPHER_AES_256_GCM, |
| 7461 | + 43200); /* ticket timeout: 12 hours */ |
| 7462 | + #endif |
| 7463 | + /* copy struct for future use */ |
| 7464 | + tls_ctx_global.init_conf = *conf; |
| 7465 | + if (conf->openssl_ciphers) |
| 7466 | + tls_ctx_global.init_conf.openssl_ciphers = |
| 7467 | + os_strdup(conf->openssl_ciphers); |
| 7468 | + |
| 7469 | + tls_ctx_global.crl_reload_interval = conf->crl_reload_interval; |
| 7470 | + os_get_reltime(&tls_ctx_global.crl_reload_previous); |
| 7471 | + |
| 7472 | + return &tls_ctx_global; |
| 7473 | +} |
| 7474 | + |
| 7475 | + |
| 7476 | +__attribute_cold__ |
| 7477 | +void tls_deinit(void *tls_ctx) |
| 7478 | +{ |
| 7479 | + if (tls_ctx == NULL || --tls_ctx_global.refcnt != 0) |
| 7480 | + return; |
| 7481 | + |
| 7482 | + tls_conf_deinit(tls_ctx_global.tls_conf); |
| 7483 | + os_free(tls_ctx_global.ca_cert_file); |
| 7484 | + os_free(tls_ctx_global.ocsp_stapling_response); |
| 7485 | + char *openssl_ciphers; /*(allocated in tls_init())*/ |
| 7486 | + *(const char **)&openssl_ciphers = |
| 7487 | + tls_ctx_global.init_conf.openssl_ciphers; |
| 7488 | + os_free(openssl_ciphers); |
| 7489 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 7490 | + mbedtls_ssl_ticket_free(&tls_ctx_global.ticket_ctx); |
| 7491 | + #endif |
| 7492 | + os_memset(&tls_ctx_global, 0, sizeof(tls_ctx_global)); |
| 7493 | +} |
| 7494 | + |
| 7495 | + |
| 7496 | +int tls_get_errors(void *tls_ctx) |
| 7497 | +{ |
| 7498 | + return 0; |
| 7499 | +} |
| 7500 | + |
| 7501 | + |
| 7502 | +static void tls_connection_deinit_expkey(struct tls_connection *conn) |
| 7503 | +{ |
| 7504 | + conn->tls_prf_type = 0; /* MBEDTLS_SSL_TLS_PRF_NONE; */ |
| 7505 | + conn->expkey_keyblock_size = 0; |
| 7506 | + conn->expkey_secret_len = 0; |
| 7507 | + forced_memzero(conn->expkey_secret, sizeof(conn->expkey_secret)); |
| 7508 | + forced_memzero(conn->expkey_randbytes, sizeof(conn->expkey_randbytes)); |
| 7509 | +} |
| 7510 | + |
| 7511 | + |
| 7512 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 7513 | +void tls_connection_deinit_clienthello_session_ticket(struct tls_connection *conn) |
| 7514 | +{ |
| 7515 | + if (conn->clienthello_session_ticket) { |
| 7516 | + mbedtls_platform_zeroize(conn->clienthello_session_ticket, |
| 7517 | + conn->clienthello_session_ticket_len); |
| 7518 | + mbedtls_free(conn->clienthello_session_ticket); |
| 7519 | + conn->clienthello_session_ticket = NULL; |
| 7520 | + conn->clienthello_session_ticket_len = 0; |
| 7521 | + } |
| 7522 | +} |
| 7523 | +#endif |
| 7524 | + |
| 7525 | + |
| 7526 | +void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) |
| 7527 | +{ |
| 7528 | + if (conn == NULL) |
| 7529 | + return; |
| 7530 | + |
| 7531 | + #if 0 /*(good intention, but never sent since we destroy self below)*/ |
| 7532 | + if (conn->established) |
| 7533 | + mbedtls_ssl_close_notify(&conn->ssl); |
| 7534 | + #endif |
| 7535 | + |
| 7536 | + if (conn->tls_prf_type) |
| 7537 | + tls_connection_deinit_expkey(conn); |
| 7538 | + |
| 7539 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 7540 | + if (conn->clienthello_session_ticket) |
| 7541 | + tls_connection_deinit_clienthello_session_ticket(conn); |
| 7542 | + #endif |
| 7543 | + |
| 7544 | + os_free(conn->peer_subject); |
| 7545 | + wpabuf_free(conn->success_data); |
| 7546 | + wpabuf_free(conn->push_buf); |
| 7547 | + wpabuf_free(conn->pull_buf); |
| 7548 | + mbedtls_ssl_free(&conn->ssl); |
| 7549 | + tls_conf_deinit(conn->tls_conf); |
| 7550 | + os_free(conn); |
| 7551 | +} |
| 7552 | + |
| 7553 | + |
| 7554 | +static void tls_mbedtls_refresh_crl(void); |
| 7555 | +static int tls_mbedtls_ssl_setup(struct tls_connection *conn); |
| 7556 | + |
| 7557 | +struct tls_connection * tls_connection_init(void *tls_ctx) |
| 7558 | +{ |
| 7559 | + struct tls_connection *conn = os_zalloc(sizeof(*conn)); |
| 7560 | + if (conn == NULL) |
| 7561 | + return NULL; |
| 7562 | + |
| 7563 | + mbedtls_ssl_init(&conn->ssl); |
| 7564 | + |
| 7565 | + conn->tls_conf = tls_ctx_global.tls_conf; /*(inherit global conf, if set)*/ |
| 7566 | + if (conn->tls_conf) { |
| 7567 | + ++conn->tls_conf->refcnt; |
| 7568 | + /* check for CRL refresh if inheriting from global config */ |
| 7569 | + tls_mbedtls_refresh_crl(); |
| 7570 | + |
| 7571 | + conn->verify_peer = conn->tls_conf->verify_peer; |
| 7572 | + if (tls_mbedtls_ssl_setup(conn) != 0) { |
| 7573 | + tls_connection_deinit(&tls_ctx_global, conn); |
| 7574 | + return NULL; |
| 7575 | + } |
| 7576 | + } |
| 7577 | + |
| 7578 | + return conn; |
| 7579 | +} |
| 7580 | + |
| 7581 | + |
| 7582 | +int tls_connection_established(void *tls_ctx, struct tls_connection *conn) |
| 7583 | +{ |
| 7584 | + return conn ? conn->established : 0; |
| 7585 | +} |
| 7586 | + |
| 7587 | + |
| 7588 | +__attribute_noinline__ |
| 7589 | +char * tls_mbedtls_peer_serial_num(const mbedtls_x509_crt *crt, char *serial_num, size_t len) |
| 7590 | +{ |
| 7591 | + /* mbedtls_x509_serial_gets() inefficiently formats to hex separated by |
| 7592 | + * colons, so generate the hex serial number here. The func |
| 7593 | + * wpa_snprintf_hex_uppercase() is similarly inefficient. */ |
| 7594 | + size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */ |
| 7595 | + while (i < crt->serial.len && crt->serial.p[i] == 0) ++i; |
| 7596 | + if (i == crt->serial.len) --i; |
| 7597 | + |
| 7598 | + const unsigned char *s = crt->serial.p + i; |
| 7599 | + const size_t e = (crt->serial.len - i) * 2; |
| 7600 | + if (e >= len) |
| 7601 | + return NULL; |
| 7602 | + #if 0 |
| 7603 | + wpa_snprintf_hex_uppercase(serial_num, len, s, crt->serial.len-i); |
| 7604 | + #else |
| 7605 | + for (i = 0; i < e; i+=2, ++s) { |
| 7606 | + serial_num[i+0] = "0123456789ABCDEF"[(*s >> 4)]; |
| 7607 | + serial_num[i+1] = "0123456789ABCDEF"[(*s & 0xF)]; |
| 7608 | + } |
| 7609 | + serial_num[e] = '\0'; |
| 7610 | + #endif |
| 7611 | + return serial_num; |
| 7612 | +} |
| 7613 | + |
| 7614 | + |
| 7615 | +char * tls_connection_peer_serial_num(void *tls_ctx, |
| 7616 | + struct tls_connection *conn) |
| 7617 | +{ |
| 7618 | + const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&conn->ssl); |
| 7619 | + if (crt == NULL) |
| 7620 | + return NULL; |
| 7621 | + size_t len = crt->serial.len * 2 + 1; |
| 7622 | + char *serial_num = os_malloc(len); |
| 7623 | + if (!serial_num) |
| 7624 | + return NULL; |
| 7625 | + return tls_mbedtls_peer_serial_num(crt, serial_num, len); |
| 7626 | +} |
| 7627 | + |
| 7628 | + |
| 7629 | +static void tls_pull_buf_reset(struct tls_connection *conn); |
| 7630 | + |
| 7631 | +int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) |
| 7632 | +{ |
| 7633 | + /* Note: this function called from eap_peer_tls_reauth_init() |
| 7634 | + * for session resumption, not for connection shutdown */ |
| 7635 | + |
| 7636 | + if (conn == NULL) |
| 7637 | + return -1; |
| 7638 | + |
| 7639 | + tls_pull_buf_reset(conn); |
| 7640 | + wpabuf_free(conn->push_buf); |
| 7641 | + conn->push_buf = NULL; |
| 7642 | + conn->established = 0; |
| 7643 | + conn->resumed = 0; |
| 7644 | + if (conn->tls_prf_type) |
| 7645 | + tls_connection_deinit_expkey(conn); |
| 7646 | + |
| 7647 | + /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */ |
| 7648 | + |
| 7649 | + return mbedtls_ssl_session_reset(&conn->ssl); |
| 7650 | +} |
| 7651 | + |
| 7652 | + |
| 7653 | +static int tls_wpabuf_resize_put_data(struct wpabuf **buf, |
| 7654 | + const unsigned char *data, size_t dlen) |
| 7655 | +{ |
| 7656 | + if (wpabuf_resize(buf, dlen) < 0) |
| 7657 | + return 0; |
| 7658 | + wpabuf_put_data(*buf, data, dlen); |
| 7659 | + return 1; |
| 7660 | +} |
| 7661 | + |
| 7662 | + |
| 7663 | +static int tls_pull_buf_append(struct tls_connection *conn, |
| 7664 | + const struct wpabuf *in_data) |
| 7665 | +{ |
| 7666 | + /*(interface does not lend itself to move semantics)*/ |
| 7667 | + return tls_wpabuf_resize_put_data(&conn->pull_buf, |
| 7668 | + wpabuf_head(in_data), |
| 7669 | + wpabuf_len(in_data)); |
| 7670 | +} |
| 7671 | + |
| 7672 | + |
| 7673 | +static void tls_pull_buf_reset(struct tls_connection *conn) |
| 7674 | +{ |
| 7675 | + /*(future: might consider reusing conn->pull_buf)*/ |
| 7676 | + wpabuf_free(conn->pull_buf); |
| 7677 | + conn->pull_buf = NULL; |
| 7678 | + conn->pull_buf_offset = 0; |
| 7679 | +} |
| 7680 | + |
| 7681 | + |
| 7682 | +__attribute_cold__ |
| 7683 | +static void tls_pull_buf_discard(struct tls_connection *conn, const char *func) |
| 7684 | +{ |
| 7685 | + size_t discard = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; |
| 7686 | + if (discard) |
| 7687 | + wpa_printf(MSG_DEBUG, |
| 7688 | + "%s - %zu bytes remaining in pull_buf; discarding", |
| 7689 | + func, discard); |
| 7690 | + tls_pull_buf_reset(conn); |
| 7691 | +} |
| 7692 | + |
| 7693 | + |
| 7694 | +static int tls_pull_func(void *ptr, unsigned char *buf, size_t len) |
| 7695 | +{ |
| 7696 | + struct tls_connection *conn = (struct tls_connection *) ptr; |
| 7697 | + if (conn->pull_buf == NULL) |
| 7698 | + return MBEDTLS_ERR_SSL_WANT_READ; |
| 7699 | + const size_t dlen = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; |
| 7700 | + if (dlen == 0) |
| 7701 | + return MBEDTLS_ERR_SSL_WANT_READ; |
| 7702 | + |
| 7703 | + if (len > dlen) |
| 7704 | + len = dlen; |
| 7705 | + os_memcpy(buf, wpabuf_head(conn->pull_buf)+conn->pull_buf_offset, len); |
| 7706 | + |
| 7707 | + if (len == dlen) { |
| 7708 | + tls_pull_buf_reset(conn); |
| 7709 | + /*wpa_printf(MSG_DEBUG, "%s - emptied pull_buf", __func__);*/ |
| 7710 | + } |
| 7711 | + else { |
| 7712 | + conn->pull_buf_offset += len; |
| 7713 | + /*wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf", |
| 7714 | + __func__, dlen - len);*/ |
| 7715 | + } |
| 7716 | + return (int)len; |
| 7717 | +} |
| 7718 | + |
| 7719 | + |
| 7720 | +static int tls_push_func(void *ptr, const unsigned char *buf, size_t len) |
| 7721 | +{ |
| 7722 | + struct tls_connection *conn = (struct tls_connection *) ptr; |
| 7723 | + return tls_wpabuf_resize_put_data(&conn->push_buf, buf, len) |
| 7724 | + ? (int)len |
| 7725 | + : MBEDTLS_ERR_SSL_ALLOC_FAILED; |
| 7726 | +} |
| 7727 | + |
| 7728 | + |
| 7729 | +static int |
| 7730 | +tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags); |
| 7731 | + |
| 7732 | + |
| 7733 | +static int tls_mbedtls_ssl_setup(struct tls_connection *conn) |
| 7734 | +{ |
| 7735 | + #if 0 |
| 7736 | + /* mbedtls_ssl_setup() must be called only once */ |
| 7737 | + /* If this func might be called multiple times (e.g. via set_params), |
| 7738 | + * then we should set a flag in conn that ssl was initialized */ |
| 7739 | + if (conn->ssl_is_init) { |
| 7740 | + mbedtls_ssl_free(&conn->ssl); |
| 7741 | + mbedtls_ssl_init(&conn->ssl); |
| 7742 | + } |
| 7743 | + #endif |
| 7744 | + |
| 7745 | + int ret = mbedtls_ssl_setup(&conn->ssl, &conn->tls_conf->conf); |
| 7746 | + if (ret != 0) { |
| 7747 | + elog(ret, "mbedtls_ssl_setup"); |
| 7748 | + return -1; |
| 7749 | + } |
| 7750 | + |
| 7751 | + mbedtls_ssl_set_bio(&conn->ssl, conn, tls_push_func, tls_pull_func, NULL); |
| 7752 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 7753 | + mbedtls_ssl_set_export_keys_cb( |
| 7754 | + &conn->ssl, tls_connection_export_keys_cb, conn); |
| 7755 | + #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 7756 | + mbedtls_ssl_conf_export_keys_ext_cb( |
| 7757 | + &conn->tls_conf->conf, tls_connection_export_keys_cb, conn); |
| 7758 | + #endif |
| 7759 | + if (conn->verify_peer) |
| 7760 | + mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); |
| 7761 | + |
| 7762 | + return 0; |
| 7763 | +} |
| 7764 | + |
| 7765 | + |
| 7766 | +static int tls_mbedtls_data_is_pem(const u8 *data) |
| 7767 | +{ |
| 7768 | + return (NULL != os_strstr((char *)data, "-----")); |
| 7769 | +} |
| 7770 | + |
| 7771 | + |
| 7772 | +static void tls_mbedtls_set_allowed_tls_vers(struct tls_conf *tls_conf, |
| 7773 | + mbedtls_ssl_config *conf) |
| 7774 | +{ |
| 7775 | + #if !defined(MBEDTLS_SSL_PROTO_TLS1_3) |
| 7776 | + tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_3; |
| 7777 | + #endif |
| 7778 | + |
| 7779 | + /* unconditionally require TLSv1.2+ for TLS_CONN_SUITEB */ |
| 7780 | + if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 7781 | + tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_0; |
| 7782 | + tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_1; |
| 7783 | + } |
| 7784 | + |
| 7785 | + const unsigned int flags = tls_conf->flags; |
| 7786 | + |
| 7787 | + /* attempt to map flags to min and max TLS protocol version */ |
| 7788 | + |
| 7789 | + int min = (flags & TLS_CONN_DISABLE_TLSv1_0) |
| 7790 | + ? (flags & TLS_CONN_DISABLE_TLSv1_1) |
| 7791 | + ? (flags & TLS_CONN_DISABLE_TLSv1_2) |
| 7792 | + ? (flags & TLS_CONN_DISABLE_TLSv1_3) |
| 7793 | + ? 4 |
| 7794 | + : 3 |
| 7795 | + : 2 |
| 7796 | + : 1 |
| 7797 | + : 0; |
| 7798 | + |
| 7799 | + int max = (flags & TLS_CONN_DISABLE_TLSv1_3) |
| 7800 | + ? (flags & TLS_CONN_DISABLE_TLSv1_2) |
| 7801 | + ? (flags & TLS_CONN_DISABLE_TLSv1_1) |
| 7802 | + ? (flags & TLS_CONN_DISABLE_TLSv1_0) |
| 7803 | + ? -1 |
| 7804 | + : 0 |
| 7805 | + : 1 |
| 7806 | + : 2 |
| 7807 | + : 3; |
| 7808 | + |
| 7809 | + if ((flags & TLS_CONN_ENABLE_TLSv1_2) && min > 2) min = 2; |
| 7810 | + if ((flags & TLS_CONN_ENABLE_TLSv1_1) && min > 1) min = 1; |
| 7811 | + if ((flags & TLS_CONN_ENABLE_TLSv1_0) && min > 0) min = 0; |
| 7812 | + if (max < min) { |
| 7813 | + emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); |
| 7814 | + return; |
| 7815 | + } |
| 7816 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 7817 | + /* mbed TLS 3.0.0 removes support for protocols < TLSv1.2 */ |
| 7818 | + if (min < 2 || max < 2) { |
| 7819 | + emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); |
| 7820 | + if (min < 2) min = 2; |
| 7821 | + if (max < 2) max = 2; |
| 7822 | + } |
| 7823 | + #endif |
| 7824 | + |
| 7825 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 7826 | + /* MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303 *//*!< (D)TLS 1.2 */ |
| 7827 | + /* MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304 *//*!< (D)TLS 1.3 */ |
| 7828 | + min = (min == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; |
| 7829 | + max = (max == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; |
| 7830 | + mbedtls_ssl_conf_min_tls_version(conf, min); |
| 7831 | + mbedtls_ssl_conf_max_tls_version(conf, max); |
| 7832 | + #else |
| 7833 | + #ifndef MBEDTLS_SSL_MINOR_VERSION_4 |
| 7834 | + if (min == 3) min = 2; |
| 7835 | + if (max == 3) max = 2; |
| 7836 | + #endif |
| 7837 | + /* MBEDTLS_SSL_MINOR_VERSION_0 0 *//*!< SSL v3.0 */ |
| 7838 | + /* MBEDTLS_SSL_MINOR_VERSION_1 1 *//*!< TLS v1.0 */ |
| 7839 | + /* MBEDTLS_SSL_MINOR_VERSION_2 2 *//*!< TLS v1.1 */ |
| 7840 | + /* MBEDTLS_SSL_MINOR_VERSION_3 3 *//*!< TLS v1.2 */ |
| 7841 | + /* MBEDTLS_SSL_MINOR_VERSION_4 4 *//*!< TLS v1.3 */ |
| 7842 | + mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, min+1); |
| 7843 | + mbedtls_ssl_conf_max_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, max+1); |
| 7844 | + #endif |
| 7845 | +} |
| 7846 | + |
| 7847 | + |
| 7848 | +__attribute_noinline__ |
| 7849 | +static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n); |
| 7850 | + |
| 7851 | + |
| 7852 | +static int |
| 7853 | +tls_mbedtls_set_dhparams(struct tls_conf *tls_conf, const char *dh_file) |
| 7854 | +{ |
| 7855 | + size_t len; |
| 7856 | + u8 *data; |
| 7857 | + if (tls_mbedtls_readfile(dh_file, &data, &len)) |
| 7858 | + return 0; |
| 7859 | + |
| 7860 | + /* parse only if DH parameters if in PEM format */ |
| 7861 | + if (tls_mbedtls_data_is_pem(data) |
| 7862 | + && NULL == os_strstr((char *)data, "-----BEGIN DH PARAMETERS-----")) { |
| 7863 | + if (os_strstr((char *)data, "-----BEGIN DSA PARAMETERS-----")) |
| 7864 | + wpa_printf(MSG_WARNING, "DSA parameters not handled (%s)", dh_file); |
| 7865 | + else |
| 7866 | + wpa_printf(MSG_WARNING, "unexpected DH param content (%s)",dh_file); |
| 7867 | + forced_memzero(data, len); |
| 7868 | + os_free(data); |
| 7869 | + return 0; |
| 7870 | + } |
| 7871 | + |
| 7872 | + /* mbedtls_dhm_parse_dhm() expects "-----BEGIN DH PARAMETERS-----" if PEM */ |
| 7873 | + mbedtls_dhm_context dhm; |
| 7874 | + mbedtls_dhm_init(&dhm); |
| 7875 | + int rc = mbedtls_dhm_parse_dhm(&dhm, data, len); |
| 7876 | + if (0 == rc) |
| 7877 | + rc = mbedtls_ssl_conf_dh_param_ctx(&tls_conf->conf, &dhm); |
| 7878 | + if (0 != rc) |
| 7879 | + elog(rc, dh_file); |
| 7880 | + mbedtls_dhm_free(&dhm); |
| 7881 | + |
| 7882 | + forced_memzero(data, len); |
| 7883 | + os_free(data); |
| 7884 | + return (0 == rc); |
| 7885 | +} |
| 7886 | + |
| 7887 | + |
| 7888 | +/* reference: lighttpd src/mod_mbedtls.c:mod_mbedtls_ssl_append_curve() |
| 7889 | + * (same author: gstrauss@gluelogic.com; same license: BSD-3-Clause) */ |
| 7890 | +#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ |
| 7891 | +static int |
| 7892 | +tls_mbedtls_append_curve (mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id) |
| 7893 | +{ |
| 7894 | + if (1 >= idsz - (nids + 1)) { |
| 7895 | + emsg(MSG_ERROR, "error: too many curves during list expand"); |
| 7896 | + return -1; |
| 7897 | + } |
| 7898 | + ids[++nids] = id; |
| 7899 | + return nids; |
| 7900 | +} |
| 7901 | + |
| 7902 | + |
| 7903 | +static int |
| 7904 | +tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) |
| 7905 | +{ |
| 7906 | + mbedtls_ecp_group_id ids[512]; |
| 7907 | + int nids = -1; |
| 7908 | + const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); |
| 7909 | + const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); |
| 7910 | + |
| 7911 | + for (const char *e = curvelist-1; e; ) { |
| 7912 | + const char * const n = e+1; |
| 7913 | + e = os_strchr(n, ':'); |
| 7914 | + size_t len = e ? (size_t)(e - n) : os_strlen(n); |
| 7915 | + mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; |
| 7916 | + switch (len) { |
| 7917 | + case 5: |
| 7918 | + if (0 == os_memcmp("P-521", n, 5)) |
| 7919 | + grp_id = MBEDTLS_ECP_DP_SECP521R1; |
| 7920 | + else if (0 == os_memcmp("P-384", n, 5)) |
| 7921 | + grp_id = MBEDTLS_ECP_DP_SECP384R1; |
| 7922 | + else if (0 == os_memcmp("P-256", n, 5)) |
| 7923 | + grp_id = MBEDTLS_ECP_DP_SECP256R1; |
| 7924 | + break; |
| 7925 | + case 6: |
| 7926 | + if (0 == os_memcmp("BP-521", n, 6)) |
| 7927 | + grp_id = MBEDTLS_ECP_DP_BP512R1; |
| 7928 | + else if (0 == os_memcmp("BP-384", n, 6)) |
| 7929 | + grp_id = MBEDTLS_ECP_DP_BP384R1; |
| 7930 | + else if (0 == os_memcmp("BP-256", n, 6)) |
| 7931 | + grp_id = MBEDTLS_ECP_DP_BP256R1; |
| 7932 | + break; |
| 7933 | + default: |
| 7934 | + break; |
| 7935 | + } |
| 7936 | + if (grp_id != MBEDTLS_ECP_DP_NONE) { |
| 7937 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, grp_id); |
| 7938 | + if (-1 == nids) return 0; |
| 7939 | + continue; |
| 7940 | + } |
| 7941 | + /* similar to mbedtls_ecp_curve_info_from_name() */ |
| 7942 | + const mbedtls_ecp_curve_info *info; |
| 7943 | + for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info) { |
| 7944 | + if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') |
| 7945 | + break; |
| 7946 | + } |
| 7947 | + if (info->grp_id == MBEDTLS_ECP_DP_NONE) { |
| 7948 | + wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); |
| 7949 | + return 0; |
| 7950 | + } |
| 7951 | + |
| 7952 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, info->grp_id); |
| 7953 | + if (-1 == nids) return 0; |
| 7954 | + } |
| 7955 | + |
| 7956 | + /* mod_openssl configures "prime256v1" if curve list not specified, |
| 7957 | + * but mbedtls provides a list of supported curves if not explicitly set */ |
| 7958 | + if (-1 == nids) return 1; /* empty list; no-op */ |
| 7959 | + |
| 7960 | + ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */ |
| 7961 | + ++nids; |
| 7962 | + |
| 7963 | + /* curves list must be persistent for lifetime of mbedtls_ssl_config */ |
| 7964 | + tls_conf->curves = os_malloc(nids * sizeof(mbedtls_ecp_group_id)); |
| 7965 | + if (tls_conf->curves == NULL) |
| 7966 | + return 0; |
| 7967 | + os_memcpy(tls_conf->curves, ids, nids * sizeof(mbedtls_ecp_group_id)); |
| 7968 | + |
| 7969 | + mbedtls_ssl_conf_curves(&tls_conf->conf, tls_conf->curves); |
| 7970 | + return 1; |
| 7971 | +} |
| 7972 | +#else |
| 7973 | +static int |
| 7974 | +tls_mbedtls_append_curve (uint16_t *ids, int nids, int idsz, const uint16_t id) |
| 7975 | +{ |
| 7976 | + if (1 >= idsz - (nids + 1)) { |
| 7977 | + emsg(MSG_ERROR, "error: too many curves during list expand"); |
| 7978 | + return -1; |
| 7979 | + } |
| 7980 | + ids[++nids] = id; |
| 7981 | + return nids; |
| 7982 | +} |
| 7983 | + |
| 7984 | + |
| 7985 | +static int |
| 7986 | +tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) |
| 7987 | +{ |
| 7988 | + /* TLS Supported Groups (renamed from "EC Named Curve Registry") |
| 7989 | + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 |
| 7990 | + */ |
| 7991 | + uint16_t ids[512]; |
| 7992 | + int nids = -1; |
| 7993 | + const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); |
| 7994 | + const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); |
| 7995 | + |
| 7996 | + for (const char *e = curvelist-1; e; ) { |
| 7997 | + const char * const n = e+1; |
| 7998 | + e = os_strchr(n, ':'); |
| 7999 | + size_t len = e ? (size_t)(e - n) : os_strlen(n); |
| 8000 | + uint16_t tls_id = 0; |
| 8001 | + switch (len) { |
| 8002 | + case 5: |
| 8003 | + if (0 == os_memcmp("P-521", n, 5)) |
| 8004 | + tls_id = 25; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP521R1 */ |
| 8005 | + else if (0 == os_memcmp("P-384", n, 5)) |
| 8006 | + tls_id = 24; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP384R1 */ |
| 8007 | + else if (0 == os_memcmp("P-256", n, 5)) |
| 8008 | + tls_id = 23; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP256R1 */ |
| 8009 | + break; |
| 8010 | + case 6: |
| 8011 | + if (0 == os_memcmp("BP-521", n, 6)) |
| 8012 | + tls_id = 28; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP512R1 */ |
| 8013 | + else if (0 == os_memcmp("BP-384", n, 6)) |
| 8014 | + tls_id = 27; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP384R1 */ |
| 8015 | + else if (0 == os_memcmp("BP-256", n, 6)) |
| 8016 | + tls_id = 26; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP256R1 */ |
| 8017 | + break; |
| 8018 | + default: |
| 8019 | + break; |
| 8020 | + } |
| 8021 | + if (tls_id != 0) { |
| 8022 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, tls_id); |
| 8023 | + if (-1 == nids) return 0; |
| 8024 | + continue; |
| 8025 | + } |
| 8026 | + /* similar to mbedtls_ecp_curve_info_from_name() */ |
| 8027 | + const mbedtls_ecp_curve_info *info; |
| 8028 | + for (info = curve_info; info->tls_id != 0; ++info) { |
| 8029 | + if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') |
| 8030 | + break; |
| 8031 | + } |
| 8032 | + if (info->tls_id == 0) { |
| 8033 | + wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); |
| 8034 | + return 0; |
| 8035 | + } |
| 8036 | + |
| 8037 | + nids = tls_mbedtls_append_curve(ids, nids, idsz, info->tls_id); |
| 8038 | + if (-1 == nids) return 0; |
| 8039 | + } |
| 8040 | + |
| 8041 | + /* mod_openssl configures "prime256v1" if curve list not specified, |
| 8042 | + * but mbedtls provides a list of supported curves if not explicitly set */ |
| 8043 | + if (-1 == nids) return 1; /* empty list; no-op */ |
| 8044 | + |
| 8045 | + ids[++nids] = 0; /* terminate list */ |
| 8046 | + ++nids; |
| 8047 | + |
| 8048 | + /* curves list must be persistent for lifetime of mbedtls_ssl_config */ |
| 8049 | + tls_conf->curves = os_malloc(nids * sizeof(uint16_t)); |
| 8050 | + if (tls_conf->curves == NULL) |
| 8051 | + return 0; |
| 8052 | + os_memcpy(tls_conf->curves, ids, nids * sizeof(uint16_t)); |
| 8053 | + |
| 8054 | + mbedtls_ssl_conf_groups(&tls_conf->conf, tls_conf->curves); |
| 8055 | + return 1; |
| 8056 | +} |
| 8057 | +#endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.1.0 */ |
| 8058 | + |
| 8059 | + |
| 8060 | +/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ |
| 8061 | +static const int suite_AES_256_ephemeral[] = { |
| 8062 | + /* All AES-256 ephemeral suites */ |
| 8063 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
| 8064 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8065 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8066 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, |
| 8067 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, |
| 8068 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, |
| 8069 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, |
| 8070 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, |
| 8071 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, |
| 8072 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, |
| 8073 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, |
| 8074 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, |
| 8075 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 |
| 8076 | +}; |
| 8077 | + |
| 8078 | +/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ |
| 8079 | +static const int suite_AES_128_ephemeral[] = { |
| 8080 | + /* All AES-128 ephemeral suites */ |
| 8081 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
| 8082 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8083 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8084 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, |
| 8085 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, |
| 8086 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, |
| 8087 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8088 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8089 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
| 8090 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
| 8091 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, |
| 8092 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, |
| 8093 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 |
| 8094 | +}; |
| 8095 | + |
| 8096 | +/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ |
| 8097 | +/* HIGH cipher list (mapped from openssl list to mbedtls) */ |
| 8098 | +static const int suite_HIGH[] = { |
| 8099 | + MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
| 8100 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, |
| 8101 | + MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
| 8102 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
| 8103 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8104 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, |
| 8105 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, |
| 8106 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, |
| 8107 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, |
| 8108 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, |
| 8109 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, |
| 8110 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, |
| 8111 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, |
| 8112 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, |
| 8113 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, |
| 8114 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, |
| 8115 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, |
| 8116 | + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, |
| 8117 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
| 8118 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, |
| 8119 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, |
| 8120 | + MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, |
| 8121 | + MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, |
| 8122 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
| 8123 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8124 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, |
| 8125 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, |
| 8126 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, |
| 8127 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, |
| 8128 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8129 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, |
| 8130 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
| 8131 | + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
| 8132 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, |
| 8133 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, |
| 8134 | + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, |
| 8135 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8136 | + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8137 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8138 | + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, |
| 8139 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, |
| 8140 | + MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, |
| 8141 | + MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, |
| 8142 | + MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8143 | + MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8144 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, |
| 8145 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, |
| 8146 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, |
| 8147 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, |
| 8148 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, |
| 8149 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, |
| 8150 | + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8151 | + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8152 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, |
| 8153 | + MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, |
| 8154 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, |
| 8155 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, |
| 8156 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, |
| 8157 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, |
| 8158 | + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, |
| 8159 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, |
| 8160 | + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8161 | + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8162 | + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, |
| 8163 | + MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, |
| 8164 | + MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, |
| 8165 | + MBEDTLS_TLS_RSA_WITH_AES_256_CCM, |
| 8166 | + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, |
| 8167 | + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, |
| 8168 | + MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, |
| 8169 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
| 8170 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, |
| 8171 | + MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, |
| 8172 | + MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, |
| 8173 | + MBEDTLS_TLS_RSA_WITH_AES_128_CCM, |
| 8174 | + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, |
| 8175 | + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, |
| 8176 | + MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, |
| 8177 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
| 8178 | + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, |
| 8179 | + MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, |
| 8180 | + MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8181 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, |
| 8182 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, |
| 8183 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, |
| 8184 | + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8185 | + MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, |
| 8186 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, |
| 8187 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, |
| 8188 | + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, |
| 8189 | + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8190 | + MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, |
| 8191 | + MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, |
| 8192 | + MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, |
| 8193 | + MBEDTLS_TLS_PSK_WITH_AES_256_CCM, |
| 8194 | + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, |
| 8195 | + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, |
| 8196 | + MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
| 8197 | + MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, |
| 8198 | + MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, |
| 8199 | + MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, |
| 8200 | + MBEDTLS_TLS_PSK_WITH_AES_128_CCM, |
| 8201 | + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, |
| 8202 | + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, |
| 8203 | + MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
| 8204 | + MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, |
| 8205 | + MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 |
| 8206 | +}; |
| 8207 | + |
| 8208 | + |
| 8209 | +__attribute_noinline__ |
| 8210 | +static int |
| 8211 | +tls_mbedtls_append_ciphersuite (int *ids, int nids, int idsz, const int *x, int xsz) |
| 8212 | +{ |
| 8213 | + if (xsz >= idsz - (nids + 1)) { |
| 8214 | + emsg(MSG_ERROR, "error: too many ciphers during list expand"); |
| 8215 | + return -1; |
| 8216 | + } |
| 8217 | + |
| 8218 | + for (int i = 0; i < xsz; ++i) |
| 8219 | + ids[++nids] = x[i]; |
| 8220 | + |
| 8221 | + return nids; |
| 8222 | +} |
| 8223 | + |
| 8224 | + |
| 8225 | +static int |
| 8226 | +tls_mbedtls_translate_ciphername(int id, char *buf, size_t buflen) |
| 8227 | +{ |
| 8228 | + const mbedtls_ssl_ciphersuite_t *info = |
| 8229 | + mbedtls_ssl_ciphersuite_from_id(id); |
| 8230 | + if (info == NULL) |
| 8231 | + return 0; |
| 8232 | + const char *name = mbedtls_ssl_ciphersuite_get_name(info); |
| 8233 | + const size_t len = os_strlen(name); |
| 8234 | + if (len == 7 && 0 == os_memcmp(name, "unknown", 7)) |
| 8235 | + return 0; |
| 8236 | + if (len >= buflen) |
| 8237 | + return 0; |
| 8238 | + os_strlcpy(buf, name, buflen); |
| 8239 | + |
| 8240 | + /* attempt to translate mbedtls string to openssl string |
| 8241 | + * (some heuristics; incomplete) */ |
| 8242 | + size_t i = 0, j = 0; |
| 8243 | + if (buf[0] == 'T') { |
| 8244 | + if (os_strncmp(buf, "TLS1-3-", 7) == 0) { |
| 8245 | + buf[3] = '-'; |
| 8246 | + j = 4; /* remove "1-3" from "TLS1-3-" prefix */ |
| 8247 | + i = 7; |
| 8248 | + } |
| 8249 | + else if (os_strncmp(buf, "TLS-", 4) == 0) |
| 8250 | + i = 4; /* remove "TLS-" prefix */ |
| 8251 | + } |
| 8252 | + for (; buf[i]; ++i) { |
| 8253 | + if (buf[i] == '-') { |
| 8254 | + if (i >= 3) { |
| 8255 | + if (0 == os_memcmp(buf+i-3, "AES", 3)) |
| 8256 | + continue; /* "AES-" -> "AES" */ |
| 8257 | + } |
| 8258 | + if (i >= 4) { |
| 8259 | + if (0 == os_memcmp(buf+i-4, "WITH", 4)) { |
| 8260 | + j -= 4; /* remove "WITH-" */ |
| 8261 | + continue; |
| 8262 | + } |
| 8263 | + } |
| 8264 | + } |
| 8265 | + buf[j++] = buf[i]; |
| 8266 | + } |
| 8267 | + buf[j] = '\0'; |
| 8268 | + |
| 8269 | + return j; |
| 8270 | +} |
| 8271 | + |
| 8272 | + |
| 8273 | +__attribute_noinline__ |
| 8274 | +static int |
| 8275 | +tls_mbedtls_set_ciphersuites(struct tls_conf *tls_conf, int *ids, int nids) |
| 8276 | +{ |
| 8277 | + /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/ |
| 8278 | + os_free(tls_conf->ciphersuites); |
| 8279 | + tls_conf->ciphersuites = os_malloc(nids * sizeof(int)); |
| 8280 | + if (tls_conf->ciphersuites == NULL) |
| 8281 | + return 0; |
| 8282 | + os_memcpy(tls_conf->ciphersuites, ids, nids * sizeof(int)); |
| 8283 | + mbedtls_ssl_conf_ciphersuites(&tls_conf->conf, tls_conf->ciphersuites); |
| 8284 | + return 1; |
| 8285 | +} |
| 8286 | + |
| 8287 | + |
| 8288 | +static int |
| 8289 | +tls_mbedtls_set_ciphers(struct tls_conf *tls_conf, const char *ciphers) |
| 8290 | +{ |
| 8291 | + char buf[64]; |
| 8292 | + int ids[512]; |
| 8293 | + int nids = -1; |
| 8294 | + const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); |
| 8295 | + const char *next; |
| 8296 | + size_t blen, clen; |
| 8297 | + do { |
| 8298 | + next = os_strchr(ciphers, ':'); |
| 8299 | + clen = next ? (size_t)(next - ciphers) : os_strlen(ciphers); |
| 8300 | + if (!clen) |
| 8301 | + continue; |
| 8302 | + |
| 8303 | + /* special-case a select set of openssl group names for hwsim tests */ |
| 8304 | + /* (review; remove excess code if tests are not run for non-OpenSSL?) */ |
| 8305 | + if (clen == 9 && os_memcmp(ciphers, "SUITEB192", 9) == 0) { |
| 8306 | + static int ssl_preset_suiteb192_ciphersuites[] = { |
| 8307 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
| 8308 | + 0 |
| 8309 | + }; |
| 8310 | + return tls_mbedtls_set_ciphersuites(tls_conf, |
| 8311 | + ssl_preset_suiteb192_ciphersuites, |
| 8312 | + 2); |
| 8313 | + } |
| 8314 | + if (clen == 9 && os_memcmp(ciphers, "SUITEB128", 9) == 0) { |
| 8315 | + static int ssl_preset_suiteb128_ciphersuites[] = { |
| 8316 | + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
| 8317 | + 0 |
| 8318 | + }; |
| 8319 | + return tls_mbedtls_set_ciphersuites(tls_conf, |
| 8320 | + ssl_preset_suiteb128_ciphersuites, |
| 8321 | + 2); |
| 8322 | + } |
| 8323 | + if (clen == 7 && os_memcmp(ciphers, "DEFAULT", 7) == 0) |
| 8324 | + continue; |
| 8325 | + if (clen == 6 && os_memcmp(ciphers, "AES128", 6) == 0) { |
| 8326 | + nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, |
| 8327 | + suite_AES_128_ephemeral, |
| 8328 | + (int)ARRAY_SIZE(suite_AES_128_ephemeral)); |
| 8329 | + if (nids == -1) |
| 8330 | + return 0; |
| 8331 | + continue; |
| 8332 | + } |
| 8333 | + if (clen == 6 && os_memcmp(ciphers, "AES256", 6) == 0) { |
| 8334 | + nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, |
| 8335 | + suite_AES_256_ephemeral, |
| 8336 | + (int)ARRAY_SIZE(suite_AES_256_ephemeral)); |
| 8337 | + if (nids == -1) |
| 8338 | + return 0; |
| 8339 | + continue; |
| 8340 | + } |
| 8341 | + if (clen == 4 && os_memcmp(ciphers, "HIGH", 4) == 0) { |
| 8342 | + nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_HIGH, |
| 8343 | + (int)ARRAY_SIZE(suite_HIGH)); |
| 8344 | + if (nids == -1) |
| 8345 | + return 0; |
| 8346 | + continue; |
| 8347 | + } |
| 8348 | + /* ignore anonymous cipher group names (?not supported by mbedtls?) */ |
| 8349 | + if (clen == 4 && os_memcmp(ciphers, "!ADH", 4) == 0) |
| 8350 | + continue; |
| 8351 | + if (clen == 6 && os_memcmp(ciphers, "-aECDH", 6) == 0) |
| 8352 | + continue; |
| 8353 | + if (clen == 7 && os_memcmp(ciphers, "-aECDSA", 7) == 0) |
| 8354 | + continue; |
| 8355 | + |
| 8356 | + /* attempt to match mbedtls cipher names |
| 8357 | + * nb: does not support openssl group names or list manipulation syntax |
| 8358 | + * (alt: could copy almost 1200 lines (!!!) of lighttpd mod_mbedtls.c |
| 8359 | + * mod_mbedtls_ssl_conf_ciphersuites() to translate strings) |
| 8360 | + * note: not efficient to rewrite list for each ciphers entry, |
| 8361 | + * but this code is expected to run only at startup |
| 8362 | + */ |
| 8363 | + const int *list = mbedtls_ssl_list_ciphersuites(); |
| 8364 | + for (; *list; ++list) { |
| 8365 | + blen = tls_mbedtls_translate_ciphername(*list,buf,sizeof(buf)); |
| 8366 | + if (!blen) |
| 8367 | + continue; |
| 8368 | + |
| 8369 | + /* matching heuristics additional to translate_ciphername above */ |
| 8370 | + if (blen == clen+4) { |
| 8371 | + char *cbc = os_strstr(buf, "CBC-"); |
| 8372 | + if (cbc) { |
| 8373 | + os_memmove(cbc, cbc+4, blen-(cbc+4-buf)+1); /*(w/ '\0')*/ |
| 8374 | + blen -= 4; |
| 8375 | + } |
| 8376 | + } |
| 8377 | + if (blen >= clen && os_memcmp(ciphers, buf, clen) == 0 |
| 8378 | + && (blen == clen |
| 8379 | + || (blen == clen+7 && os_memcmp(buf+clen, "-SHA256", 7)))) { |
| 8380 | + if (1 >= idsz - (nids + 1)) { |
| 8381 | + emsg(MSG_ERROR, |
| 8382 | + "error: too many ciphers during list expand"); |
| 8383 | + return 0; |
| 8384 | + } |
| 8385 | + ids[++nids] = *list; |
| 8386 | + break; |
| 8387 | + } |
| 8388 | + } |
| 8389 | + if (*list == 0) { |
| 8390 | + wpa_printf(MSG_ERROR, |
| 8391 | + "MTLS: unrecognized cipher: %.*s", (int)clen, ciphers); |
| 8392 | + return 0; |
| 8393 | + } |
| 8394 | + } while ((ciphers = next ? next+1 : NULL)); |
| 8395 | + |
| 8396 | + if (-1 == nids) return 1; /* empty list; no-op */ |
| 8397 | + |
| 8398 | + ids[++nids] = 0; /* terminate list */ |
| 8399 | + ++nids; |
| 8400 | + |
| 8401 | + return tls_mbedtls_set_ciphersuites(tls_conf, ids, nids); |
| 8402 | +} |
| 8403 | + |
| 8404 | + |
| 8405 | +__attribute_noinline__ |
| 8406 | +static int tls_mbedtls_set_item(char **config_item, const char *item) |
| 8407 | +{ |
| 8408 | + os_free(*config_item); |
| 8409 | + *config_item = NULL; |
| 8410 | + return item ? (*config_item = os_strdup(item)) != NULL : 1; |
| 8411 | +} |
| 8412 | + |
| 8413 | + |
| 8414 | +static int tls_connection_set_subject_match(struct tls_conf *tls_conf, |
| 8415 | + const struct tls_connection_params *params) |
| 8416 | +{ |
| 8417 | + int rc = 1; |
| 8418 | + rc &= tls_mbedtls_set_item(&tls_conf->subject_match, |
| 8419 | + params->subject_match); |
| 8420 | + rc &= tls_mbedtls_set_item(&tls_conf->altsubject_match, |
| 8421 | + params->altsubject_match); |
| 8422 | + rc &= tls_mbedtls_set_item(&tls_conf->suffix_match, |
| 8423 | + params->suffix_match); |
| 8424 | + rc &= tls_mbedtls_set_item(&tls_conf->domain_match, |
| 8425 | + params->domain_match); |
| 8426 | + rc &= tls_mbedtls_set_item(&tls_conf->check_cert_subject, |
| 8427 | + params->check_cert_subject); |
| 8428 | + return rc; |
| 8429 | +} |
| 8430 | + |
| 8431 | + |
| 8432 | +/* duplicated in crypto_mbedtls.c:crypto_mbedtls_readfile()*/ |
| 8433 | +__attribute_noinline__ |
| 8434 | +static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n) |
| 8435 | +{ |
| 8436 | + #if 0 /* #ifdef MBEDTLS_FS_IO */ |
| 8437 | + /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ |
| 8438 | + if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { |
| 8439 | + wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); |
| 8440 | + return -1; |
| 8441 | + } |
| 8442 | + #else |
| 8443 | + /*(use os_readfile() so that we can use os_free() |
| 8444 | + *(if we use mbedtls_pk_load_file() above, macros prevent calling free() |
| 8445 | + * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() |
| 8446 | + * on buf aborts in tests if buf not allocated via os_malloc())*/ |
| 8447 | + *buf = (u8 *)os_readfile(path, n); |
| 8448 | + if (!*buf) { |
| 8449 | + wpa_printf(MSG_ERROR, "error: os_readfile %s", path); |
| 8450 | + return -1; |
| 8451 | + } |
| 8452 | + u8 *buf0 = os_realloc(*buf, *n+1); |
| 8453 | + if (!buf0) { |
| 8454 | + bin_clear_free(*buf, *n); |
| 8455 | + *buf = NULL; |
| 8456 | + return -1; |
| 8457 | + } |
| 8458 | + buf0[(*n)++] = '\0'; |
| 8459 | + *buf = buf0; |
| 8460 | + #endif |
| 8461 | + return 0; |
| 8462 | +} |
| 8463 | + |
| 8464 | + |
| 8465 | +static int tls_mbedtls_set_crl(struct tls_conf *tls_conf, const u8 *data, size_t len) |
| 8466 | +{ |
| 8467 | + /* do not use mbedtls_x509_crl_parse() on PEM unless it contains CRL */ |
| 8468 | + if (len && data[len-1] == '\0' |
| 8469 | + && NULL == os_strstr((const char *)data,"-----BEGIN X509 CRL-----") |
| 8470 | + && tls_mbedtls_data_is_pem(data)) |
| 8471 | + return 0; |
| 8472 | + |
| 8473 | + mbedtls_x509_crl crl; |
| 8474 | + mbedtls_x509_crl_init(&crl); |
| 8475 | + int rc = mbedtls_x509_crl_parse(&crl, data, len); |
| 8476 | + if (rc < 0) { |
| 8477 | + mbedtls_x509_crl_free(&crl); |
| 8478 | + return rc == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ? 0 : rc; |
| 8479 | + } |
| 8480 | + |
| 8481 | + mbedtls_x509_crl *crl_new = os_malloc(sizeof(crl)); |
| 8482 | + if (crl_new == NULL) { |
| 8483 | + mbedtls_x509_crl_free(&crl); |
| 8484 | + return MBEDTLS_ERR_X509_ALLOC_FAILED; |
| 8485 | + } |
| 8486 | + os_memcpy(crl_new, &crl, sizeof(crl)); |
| 8487 | + |
| 8488 | + mbedtls_x509_crl *crl_old = tls_conf->crl; |
| 8489 | + tls_conf->crl = crl_new; |
| 8490 | + if (crl_old) { |
| 8491 | + mbedtls_x509_crl_free(crl_old); |
| 8492 | + os_free(crl_old); |
| 8493 | + } |
| 8494 | + return 0; |
| 8495 | +} |
| 8496 | + |
| 8497 | + |
| 8498 | +static int tls_mbedtls_set_ca(struct tls_conf *tls_conf, u8 *data, size_t len) |
| 8499 | +{ |
| 8500 | + /* load crt struct onto stack and then copy into tls_conf in |
| 8501 | + * order to preserve existing tls_conf value if error occurs |
| 8502 | + * |
| 8503 | + * hostapd is not threaded, or else should allocate memory and swap in |
| 8504 | + * pointer reduce race condition. (If threaded, would also need to |
| 8505 | + * keep reference count of use to avoid freeing while still in use.) */ |
| 8506 | + |
| 8507 | + mbedtls_x509_crt crt; |
| 8508 | + mbedtls_x509_crt_init(&crt); |
| 8509 | + int rc = mbedtls_x509_crt_parse(&crt, data, len); |
| 8510 | + if (rc < 0) { |
| 8511 | + mbedtls_x509_crt_free(&crt); |
| 8512 | + return rc; |
| 8513 | + } |
| 8514 | + |
| 8515 | + mbedtls_x509_crt_free(&tls_conf->ca_cert); |
| 8516 | + os_memcpy(&tls_conf->ca_cert, &crt, sizeof(crt)); |
| 8517 | + return 0; |
| 8518 | +} |
| 8519 | + |
| 8520 | + |
| 8521 | +static int tls_mbedtls_set_ca_and_crl(struct tls_conf *tls_conf, const char *ca_cert_file) |
| 8522 | +{ |
| 8523 | + size_t len; |
| 8524 | + u8 *data; |
| 8525 | + if (tls_mbedtls_readfile(ca_cert_file, &data, &len)) |
| 8526 | + return -1; |
| 8527 | + |
| 8528 | + int rc; |
| 8529 | + if (0 == (rc = tls_mbedtls_set_ca(tls_conf, data, len)) |
| 8530 | + && (!tls_mbedtls_data_is_pem(data) /*skip parse for CRL if not PEM*/ |
| 8531 | + || 0 == (rc = tls_mbedtls_set_crl(tls_conf, data, len)))) { |
| 8532 | + mbedtls_ssl_conf_ca_chain(&tls_conf->conf, |
| 8533 | + &tls_conf->ca_cert, |
| 8534 | + tls_conf->crl); |
| 8535 | + } |
| 8536 | + else { |
| 8537 | + elog(rc, __func__); |
| 8538 | + emsg(MSG_ERROR, ca_cert_file); |
| 8539 | + } |
| 8540 | + |
| 8541 | + forced_memzero(data, len); |
| 8542 | + os_free(data); |
| 8543 | + return rc; |
| 8544 | +} |
| 8545 | + |
| 8546 | + |
| 8547 | +static void tls_mbedtls_refresh_crl(void) |
| 8548 | +{ |
| 8549 | + /* check for CRL refresh |
| 8550 | + * continue even if error occurs; continue with previous cert, CRL */ |
| 8551 | + unsigned int crl_reload_interval = tls_ctx_global.crl_reload_interval; |
| 8552 | + const char *ca_cert_file = tls_ctx_global.ca_cert_file; |
| 8553 | + if (!crl_reload_interval || !ca_cert_file) |
| 8554 | + return; |
| 8555 | + |
| 8556 | + struct os_reltime *previous = &tls_ctx_global.crl_reload_previous; |
| 8557 | + struct os_reltime now; |
| 8558 | + if (os_get_reltime(&now) != 0 |
| 8559 | + || !os_reltime_expired(&now, previous, crl_reload_interval)) |
| 8560 | + return; |
| 8561 | + |
| 8562 | + /* Note: modifying global state is not thread-safe |
| 8563 | + * if in use by existing connections |
| 8564 | + * |
| 8565 | + * src/utils/os.h does not provide a portable stat() |
| 8566 | + * or else it would be a good idea to check mtime and size, |
| 8567 | + * and avoid reloading if file has not changed */ |
| 8568 | + |
| 8569 | + if (tls_mbedtls_set_ca_and_crl(tls_ctx_global.tls_conf, ca_cert_file) == 0) |
| 8570 | + *previous = now; |
| 8571 | +} |
| 8572 | + |
| 8573 | + |
| 8574 | +static int tls_mbedtls_set_ca_cert(struct tls_conf *tls_conf, |
| 8575 | + const struct tls_connection_params *params) |
| 8576 | +{ |
| 8577 | + if (params->ca_cert) { |
| 8578 | + if (os_strncmp(params->ca_cert, "probe://", 8) == 0) { |
| 8579 | + tls_conf->ca_cert_probe = 1; |
| 8580 | + tls_conf->has_ca_cert = 1; |
| 8581 | + return 0; |
| 8582 | + } |
| 8583 | + |
| 8584 | + if (os_strncmp(params->ca_cert, "hash://", 7) == 0) { |
| 8585 | + const char *pos = params->ca_cert + 7; |
| 8586 | + if (os_strncmp(pos, "server/sha256/", 14) != 0) { |
| 8587 | + emsg(MSG_ERROR, "unsupported ca_cert hash value"); |
| 8588 | + return -1; |
| 8589 | + } |
| 8590 | + pos += 14; |
| 8591 | + if (os_strlen(pos) != SHA256_DIGEST_LENGTH*2) { |
| 8592 | + emsg(MSG_ERROR, "unexpected ca_cert hash length"); |
| 8593 | + return -1; |
| 8594 | + } |
| 8595 | + if (hexstr2bin(pos, tls_conf->ca_cert_hash, |
| 8596 | + SHA256_DIGEST_LENGTH) < 0) { |
| 8597 | + emsg(MSG_ERROR, "invalid ca_cert hash value"); |
| 8598 | + return -1; |
| 8599 | + } |
| 8600 | + emsg(MSG_DEBUG, "checking only server certificate match"); |
| 8601 | + tls_conf->verify_depth0_only = 1; |
| 8602 | + tls_conf->has_ca_cert = 1; |
| 8603 | + return 0; |
| 8604 | + } |
| 8605 | + |
| 8606 | + if (tls_mbedtls_set_ca_and_crl(tls_conf, params->ca_cert) != 0) |
| 8607 | + return -1; |
| 8608 | + } |
| 8609 | + if (params->ca_cert_blob) { |
| 8610 | + size_t len = params->ca_cert_blob_len; |
| 8611 | + int is_pem = tls_mbedtls_data_is_pem(params->ca_cert_blob); |
| 8612 | + if (len && params->ca_cert_blob[len-1] != '\0' && is_pem) |
| 8613 | + ++len; /*(include '\0' in len for PEM)*/ |
| 8614 | + int ret = mbedtls_x509_crt_parse(&tls_conf->ca_cert, |
| 8615 | + params->ca_cert_blob, len); |
| 8616 | + if (ret != 0) { |
| 8617 | + elog(ret, "mbedtls_x509_crt_parse"); |
| 8618 | + return -1; |
| 8619 | + } |
| 8620 | + if (is_pem) { /*(ca_cert_blob in DER format contains ca cert only)*/ |
| 8621 | + ret = tls_mbedtls_set_crl(tls_conf, params->ca_cert_blob, len); |
| 8622 | + if (ret != 0) { |
| 8623 | + elog(ret, "mbedtls_x509_crl_parse"); |
| 8624 | + return -1; |
| 8625 | + } |
| 8626 | + } |
| 8627 | + } |
| 8628 | + |
| 8629 | + if (mbedtls_x509_time_is_future(&tls_conf->ca_cert.valid_from) |
| 8630 | + || mbedtls_x509_time_is_past(&tls_conf->ca_cert.valid_to)) { |
| 8631 | + emsg(MSG_WARNING, "ca_cert expired or not yet valid"); |
| 8632 | + if (params->ca_cert) |
| 8633 | + emsg(MSG_WARNING, params->ca_cert); |
| 8634 | + } |
| 8635 | + |
| 8636 | + tls_conf->has_ca_cert = 1; |
| 8637 | + return 0; |
| 8638 | +} |
| 8639 | + |
| 8640 | + |
| 8641 | +static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, |
| 8642 | + const struct tls_connection_params *params) |
| 8643 | +{ |
| 8644 | + int ret; |
| 8645 | + |
| 8646 | + if (params->ca_cert || params->ca_cert_blob) { |
| 8647 | + if (tls_mbedtls_set_ca_cert(tls_conf, params) != 0) |
| 8648 | + return -1; |
| 8649 | + } |
| 8650 | + else if (params->ca_path) { |
| 8651 | + emsg(MSG_INFO, "ca_path support not implemented"); |
| 8652 | + return -1; |
| 8653 | + } |
| 8654 | + |
| 8655 | + if (!tls_conf->has_ca_cert) |
| 8656 | + mbedtls_ssl_conf_authmode(&tls_conf->conf, MBEDTLS_SSL_VERIFY_NONE); |
| 8657 | + else { |
| 8658 | + /* Initial setting: REQUIRED for client, OPTIONAL for server |
| 8659 | + * (see also tls_connection_set_verify()) */ |
| 8660 | + tls_conf->verify_peer = (tls_ctx_global.tls_conf == NULL); |
| 8661 | + int authmode = tls_conf->verify_peer |
| 8662 | + ? MBEDTLS_SSL_VERIFY_REQUIRED |
| 8663 | + : MBEDTLS_SSL_VERIFY_OPTIONAL; |
| 8664 | + mbedtls_ssl_conf_authmode(&tls_conf->conf, authmode); |
| 8665 | + mbedtls_ssl_conf_ca_chain(&tls_conf->conf, |
| 8666 | + &tls_conf->ca_cert, |
| 8667 | + tls_conf->crl); |
| 8668 | + |
| 8669 | + if (!tls_connection_set_subject_match(tls_conf, params)) |
| 8670 | + return -1; |
| 8671 | + } |
| 8672 | + |
| 8673 | + if (params->client_cert2) /*(yes, server_cert2 in msg below)*/ |
| 8674 | + emsg(MSG_INFO, "server_cert2 support not implemented"); |
| 8675 | + |
| 8676 | + if (params->client_cert) { |
| 8677 | + size_t len; |
| 8678 | + u8 *data; |
| 8679 | + if (tls_mbedtls_readfile(params->client_cert, &data, &len)) |
| 8680 | + return -1; |
| 8681 | + ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, data, len); |
| 8682 | + forced_memzero(data, len); |
| 8683 | + os_free(data); |
| 8684 | + } |
| 8685 | + if (params->client_cert_blob) { |
| 8686 | + size_t len = params->client_cert_blob_len; |
| 8687 | + if (len && params->client_cert_blob[len-1] != '\0' |
| 8688 | + && tls_mbedtls_data_is_pem(params->client_cert_blob)) |
| 8689 | + ++len; /*(include '\0' in len for PEM)*/ |
| 8690 | + ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, |
| 8691 | + params->client_cert_blob, len); |
| 8692 | + } |
| 8693 | + if (params->client_cert || params->client_cert_blob) { |
| 8694 | + if (ret < 0) { |
| 8695 | + elog(ret, "mbedtls_x509_crt_parse"); |
| 8696 | + if (params->client_cert) |
| 8697 | + emsg(MSG_ERROR, params->client_cert); |
| 8698 | + return -1; |
| 8699 | + } |
| 8700 | + if (mbedtls_x509_time_is_future(&tls_conf->client_cert.valid_from) |
| 8701 | + || mbedtls_x509_time_is_past(&tls_conf->client_cert.valid_to)) { |
| 8702 | + emsg(MSG_WARNING, "cert expired or not yet valid"); |
| 8703 | + if (params->client_cert) |
| 8704 | + emsg(MSG_WARNING, params->client_cert); |
| 8705 | + } |
| 8706 | + tls_conf->has_client_cert = 1; |
| 8707 | + } |
| 8708 | + |
| 8709 | + if (params->private_key || params->private_key_blob) { |
| 8710 | + size_t len = params->private_key_blob_len; |
| 8711 | + u8 *data; |
| 8712 | + *(const u8 **)&data = params->private_key_blob; |
| 8713 | + if (len && data[len-1] != '\0' && tls_mbedtls_data_is_pem(data)) |
| 8714 | + ++len; /*(include '\0' in len for PEM)*/ |
| 8715 | + if (params->private_key |
| 8716 | + && tls_mbedtls_readfile(params->private_key, &data, &len)) { |
| 8717 | + return -1; |
| 8718 | + } |
| 8719 | + const char *pwd = params->private_key_passwd; |
| 8720 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 8721 | + ret = mbedtls_pk_parse_key(&tls_conf->private_key, |
| 8722 | + data, len, |
| 8723 | + (const unsigned char *)pwd, |
| 8724 | + pwd ? os_strlen(pwd) : 0, |
| 8725 | + mbedtls_ctr_drbg_random, |
| 8726 | + tls_ctx_global.ctr_drbg); |
| 8727 | + #else |
| 8728 | + ret = mbedtls_pk_parse_key(&tls_conf->private_key, |
| 8729 | + data, len, |
| 8730 | + (const unsigned char *)pwd, |
| 8731 | + pwd ? os_strlen(pwd) : 0); |
| 8732 | + #endif |
| 8733 | + if (params->private_key) { |
| 8734 | + forced_memzero(data, len); |
| 8735 | + os_free(data); |
| 8736 | + } |
| 8737 | + if (ret < 0) { |
| 8738 | + elog(ret, "mbedtls_pk_parse_key"); |
| 8739 | + return -1; |
| 8740 | + } |
| 8741 | + tls_conf->has_private_key = 1; |
| 8742 | + } |
| 8743 | + |
| 8744 | + if (tls_conf->has_client_cert && tls_conf->has_private_key) { |
| 8745 | + ret = mbedtls_ssl_conf_own_cert( |
| 8746 | + &tls_conf->conf, &tls_conf->client_cert, &tls_conf->private_key); |
| 8747 | + if (ret < 0) { |
| 8748 | + elog(ret, "mbedtls_ssl_conf_own_cert"); |
| 8749 | + return -1; |
| 8750 | + } |
| 8751 | + } |
| 8752 | + |
| 8753 | + return 0; |
| 8754 | +} |
| 8755 | + |
| 8756 | + |
| 8757 | +/* mbedtls_x509_crt_profile_suiteb plus rsa_min_bitlen 2048 */ |
| 8758 | +/* (reference: see also mbedtls_x509_crt_profile_next) */ |
| 8759 | +/* ??? should permit SHA-512, too, and additional curves ??? */ |
| 8760 | +static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 = |
| 8761 | +{ |
| 8762 | + /* Only SHA-256 and 384 */ |
| 8763 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | |
| 8764 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), |
| 8765 | + /* Only ECDSA */ |
| 8766 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | |
| 8767 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), |
| 8768 | +#if defined(MBEDTLS_ECP_C) |
| 8769 | + /* Only NIST P-256 and P-384 */ |
| 8770 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | |
| 8771 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), |
| 8772 | +#else |
| 8773 | + 0, |
| 8774 | +#endif |
| 8775 | + 2048, |
| 8776 | +}; |
| 8777 | + |
| 8778 | + |
| 8779 | +/* stricter than mbedtls_x509_crt_profile_suiteb */ |
| 8780 | +/* (reference: see also mbedtls_x509_crt_profile_next) */ |
| 8781 | +/* ??? should permit SHA-512, too, and additional curves ??? */ |
| 8782 | +static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 = |
| 8783 | +{ |
| 8784 | + /* Only SHA-384 */ |
| 8785 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), |
| 8786 | + /* Only ECDSA */ |
| 8787 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | |
| 8788 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), |
| 8789 | +#if defined(MBEDTLS_ECP_C) |
| 8790 | + /* Only NIST P-384 */ |
| 8791 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), |
| 8792 | +#else |
| 8793 | + 0, |
| 8794 | +#endif |
| 8795 | + 3072, |
| 8796 | +}; |
| 8797 | + |
| 8798 | + |
| 8799 | +/* stricter than mbedtls_x509_crt_profile_suiteb except allow any PK alg */ |
| 8800 | +/* (reference: see also mbedtls_x509_crt_profile_next) */ |
| 8801 | +/* ??? should permit SHA-512, too, and additional curves ??? */ |
| 8802 | +static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192_anypk = |
| 8803 | +{ |
| 8804 | + /* Only SHA-384 */ |
| 8805 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), |
| 8806 | + 0xFFFFFFF, /* Any PK alg */ |
| 8807 | +#if defined(MBEDTLS_ECP_C) |
| 8808 | + /* Only NIST P-384 */ |
| 8809 | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), |
| 8810 | +#else |
| 8811 | + 0, |
| 8812 | +#endif |
| 8813 | + 3072, |
| 8814 | +}; |
| 8815 | + |
| 8816 | + |
| 8817 | +static int tls_mbedtls_set_params(struct tls_conf *tls_conf, |
| 8818 | + const struct tls_connection_params *params) |
| 8819 | +{ |
| 8820 | + tls_conf->flags = params->flags; |
| 8821 | + |
| 8822 | + if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP_ALL) { |
| 8823 | + emsg(MSG_INFO, "ocsp=3 not supported"); |
| 8824 | + return -1; |
| 8825 | + } |
| 8826 | + |
| 8827 | + if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP) { |
| 8828 | + emsg(MSG_INFO, "ocsp not supported"); |
| 8829 | + return -1; |
| 8830 | + } |
| 8831 | + |
| 8832 | + int suiteb128 = 0; |
| 8833 | + int suiteb192 = 0; |
| 8834 | + if (params->openssl_ciphers) { |
| 8835 | + if (os_strcmp(params->openssl_ciphers, "SUITEB192") == 0) { |
| 8836 | + suiteb192 = 1; |
| 8837 | + tls_conf->flags |= TLS_CONN_SUITEB; |
| 8838 | + } |
| 8839 | + if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) { |
| 8840 | + suiteb128 = 1; |
| 8841 | + tls_conf->flags |= TLS_CONN_SUITEB; |
| 8842 | + } |
| 8843 | + } |
| 8844 | + |
| 8845 | + int ret = mbedtls_ssl_config_defaults( |
| 8846 | + &tls_conf->conf, tls_ctx_global.tls_conf ? MBEDTLS_SSL_IS_SERVER |
| 8847 | + : MBEDTLS_SSL_IS_CLIENT, |
| 8848 | + MBEDTLS_SSL_TRANSPORT_STREAM, |
| 8849 | + (tls_conf->flags & TLS_CONN_SUITEB) ? MBEDTLS_SSL_PRESET_SUITEB |
| 8850 | + : MBEDTLS_SSL_PRESET_DEFAULT); |
| 8851 | + if (ret != 0) { |
| 8852 | + elog(ret, "mbedtls_ssl_config_defaults"); |
| 8853 | + return -1; |
| 8854 | + } |
| 8855 | + |
| 8856 | + if (suiteb128) { |
| 8857 | + mbedtls_ssl_conf_cert_profile(&tls_conf->conf, |
| 8858 | + &tls_mbedtls_crt_profile_suiteb128); |
| 8859 | + mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 2048); |
| 8860 | + } |
| 8861 | + else if (suiteb192) { |
| 8862 | + mbedtls_ssl_conf_cert_profile(&tls_conf->conf, |
| 8863 | + &tls_mbedtls_crt_profile_suiteb192); |
| 8864 | + mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); |
| 8865 | + } |
| 8866 | + else if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 8867 | + /* treat as suiteb192 while allowing any PK algorithm */ |
| 8868 | + mbedtls_ssl_conf_cert_profile(&tls_conf->conf, |
| 8869 | + &tls_mbedtls_crt_profile_suiteb192_anypk); |
| 8870 | + mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); |
| 8871 | + } |
| 8872 | + |
| 8873 | + tls_mbedtls_set_allowed_tls_vers(tls_conf, &tls_conf->conf); |
| 8874 | + ret = tls_mbedtls_set_certs(tls_conf, params); |
| 8875 | + if (ret != 0) |
| 8876 | + return -1; |
| 8877 | + |
| 8878 | + if (params->dh_file |
| 8879 | + && !tls_mbedtls_set_dhparams(tls_conf, params->dh_file)) { |
| 8880 | + return -1; |
| 8881 | + } |
| 8882 | + |
| 8883 | + if (params->openssl_ecdh_curves |
| 8884 | + && !tls_mbedtls_set_curves(tls_conf, params->openssl_ecdh_curves)) { |
| 8885 | + return -1; |
| 8886 | + } |
| 8887 | + |
| 8888 | + if (params->openssl_ciphers) { |
| 8889 | + if (!tls_mbedtls_set_ciphers(tls_conf, params->openssl_ciphers)) |
| 8890 | + return -1; |
| 8891 | + } |
| 8892 | + else if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 8893 | + /* special-case a select set of ciphers for hwsim tests */ |
| 8894 | + if (!tls_mbedtls_set_ciphers(tls_conf, |
| 8895 | + (tls_conf->flags & TLS_CONN_SUITEB_NO_ECDH) |
| 8896 | + ? "DHE-RSA-AES256-GCM-SHA384" |
| 8897 | + : "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384")) |
| 8898 | + return -1; |
| 8899 | + } |
| 8900 | + |
| 8901 | + return 0; |
| 8902 | +} |
| 8903 | + |
| 8904 | + |
| 8905 | +int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, |
| 8906 | + const struct tls_connection_params *params) |
| 8907 | +{ |
| 8908 | + if (conn == NULL || params == NULL) |
| 8909 | + return -1; |
| 8910 | + |
| 8911 | + tls_conf_deinit(conn->tls_conf); |
| 8912 | + struct tls_conf *tls_conf = conn->tls_conf = tls_conf_init(tls_ctx); |
| 8913 | + if (tls_conf == NULL) |
| 8914 | + return -1; |
| 8915 | + |
| 8916 | + if (tls_ctx_global.tls_conf) { |
| 8917 | + tls_conf->check_crl = tls_ctx_global.tls_conf->check_crl; |
| 8918 | + tls_conf->check_crl_strict = tls_ctx_global.tls_conf->check_crl_strict; |
| 8919 | + /*(tls_openssl.c inherits check_cert_subject from global conf)*/ |
| 8920 | + if (tls_ctx_global.tls_conf->check_cert_subject) { |
| 8921 | + tls_conf->check_cert_subject = |
| 8922 | + os_strdup(tls_ctx_global.tls_conf->check_cert_subject); |
| 8923 | + if (tls_conf->check_cert_subject == NULL) |
| 8924 | + return -1; |
| 8925 | + } |
| 8926 | + } |
| 8927 | + |
| 8928 | + if (tls_mbedtls_set_params(tls_conf, params) != 0) |
| 8929 | + return -1; |
| 8930 | + conn->verify_peer = tls_conf->verify_peer; |
| 8931 | + |
| 8932 | + return tls_mbedtls_ssl_setup(conn); |
| 8933 | +} |
| 8934 | + |
| 8935 | + |
| 8936 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 8937 | + |
| 8938 | +static int tls_mbedtls_clienthello_session_ticket_prep (struct tls_connection *conn, |
| 8939 | + const u8 *data, size_t len) |
| 8940 | +{ |
| 8941 | + if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) |
| 8942 | + return -1; |
| 8943 | + if (conn->clienthello_session_ticket) |
| 8944 | + tls_connection_deinit_clienthello_session_ticket(conn); |
| 8945 | + if (len) { |
| 8946 | + conn->clienthello_session_ticket = mbedtls_calloc(1, len); |
| 8947 | + if (conn->clienthello_session_ticket == NULL) |
| 8948 | + return -1; |
| 8949 | + conn->clienthello_session_ticket_len = len; |
| 8950 | + os_memcpy(conn->clienthello_session_ticket, data, len); |
| 8951 | + } |
| 8952 | + return 0; |
| 8953 | +} |
| 8954 | + |
| 8955 | + |
| 8956 | +static void tls_mbedtls_clienthello_session_ticket_set (struct tls_connection *conn) |
| 8957 | +{ |
| 8958 | + mbedtls_ssl_session *sess = conn->ssl.MBEDTLS_PRIVATE(session_negotiate); |
| 8959 | + if (sess->MBEDTLS_PRIVATE(ticket)) { |
| 8960 | + mbedtls_platform_zeroize(sess->MBEDTLS_PRIVATE(ticket), |
| 8961 | + sess->MBEDTLS_PRIVATE(ticket_len)); |
| 8962 | + mbedtls_free(sess->MBEDTLS_PRIVATE(ticket)); |
| 8963 | + } |
| 8964 | + sess->MBEDTLS_PRIVATE(ticket) = conn->clienthello_session_ticket; |
| 8965 | + sess->MBEDTLS_PRIVATE(ticket_len) = conn->clienthello_session_ticket_len; |
| 8966 | + sess->MBEDTLS_PRIVATE(ticket_lifetime) = 86400;/* XXX: can hint be 0? */ |
| 8967 | + |
| 8968 | + conn->clienthello_session_ticket = NULL; |
| 8969 | + conn->clienthello_session_ticket_len = 0; |
| 8970 | +} |
| 8971 | + |
| 8972 | + |
| 8973 | +static int tls_mbedtls_ssl_ticket_write(void *p_ticket, |
| 8974 | + const mbedtls_ssl_session *session, |
| 8975 | + unsigned char *start, |
| 8976 | + const unsigned char *end, |
| 8977 | + size_t *tlen, |
| 8978 | + uint32_t *lifetime) |
| 8979 | +{ |
| 8980 | + struct tls_connection *conn = p_ticket; |
| 8981 | + if (conn && conn->session_ticket_cb) { |
| 8982 | + /* see tls_mbedtls_clienthello_session_ticket_prep() */ |
| 8983 | + /* see tls_mbedtls_clienthello_session_ticket_set() */ |
| 8984 | + return 0; |
| 8985 | + } |
| 8986 | + |
| 8987 | + return mbedtls_ssl_ticket_write(&tls_ctx_global.ticket_ctx, |
| 8988 | + session, start, end, tlen, lifetime); |
| 8989 | +} |
| 8990 | + |
| 8991 | + |
| 8992 | +static int tls_mbedtls_ssl_ticket_parse(void *p_ticket, |
| 8993 | + mbedtls_ssl_session *session, |
| 8994 | + unsigned char *buf, |
| 8995 | + size_t len) |
| 8996 | +{ |
| 8997 | + /* XXX: TODO: not implemented in client; |
| 8998 | + * mbedtls_ssl_conf_session_tickets_cb() callbacks only for TLS server*/ |
| 8999 | + |
| 9000 | + if (len == 0) |
| 9001 | + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; |
| 9002 | + |
| 9003 | + struct tls_connection *conn = p_ticket; |
| 9004 | + if (conn && conn->session_ticket_cb) { |
| 9005 | + /* XXX: have random and secret been initialized yet? |
| 9006 | + * or must keys first be exported? |
| 9007 | + * EAP-FAST uses all args, EAP-TEAP only uses secret */ |
| 9008 | + struct tls_random data; |
| 9009 | + if (tls_connection_get_random(NULL, conn, &data) != 0) |
| 9010 | + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; |
| 9011 | + int ret = |
| 9012 | + conn->session_ticket_cb(conn->session_ticket_cb_ctx, |
| 9013 | + buf, len, |
| 9014 | + data.client_random, |
| 9015 | + data.server_random, |
| 9016 | + conn->expkey_secret); |
| 9017 | + if (ret == 1) { |
| 9018 | + conn->resumed = 1; |
| 9019 | + return 0; |
| 9020 | + } |
| 9021 | + emsg(MSG_ERROR, "EAP session ticket ext not implemented"); |
| 9022 | + return MBEDTLS_ERR_SSL_INVALID_MAC; |
| 9023 | + /*(non-zero return used for mbedtls debug logging)*/ |
| 9024 | + } |
| 9025 | + |
| 9026 | + /* XXX: TODO always use tls_mbedtls_ssl_ticket_parse() for callback? */ |
| 9027 | + int rc = mbedtls_ssl_ticket_parse(&tls_ctx_global.ticket_ctx, |
| 9028 | + session, buf, len); |
| 9029 | + if (conn) |
| 9030 | + conn->resumed = (rc == 0); |
| 9031 | + return rc; |
| 9032 | +} |
| 9033 | + |
| 9034 | +#endif /* TLS_MBEDTLS_SESSION_TICKETS */ |
| 9035 | + |
| 9036 | + |
| 9037 | +__attribute_cold__ |
| 9038 | +int tls_global_set_params(void *tls_ctx, |
| 9039 | + const struct tls_connection_params *params) |
| 9040 | +{ |
| 9041 | + /* XXX: why might global_set_params be called more than once? */ |
| 9042 | + if (tls_ctx_global.tls_conf) |
| 9043 | + tls_conf_deinit(tls_ctx_global.tls_conf); |
| 9044 | + tls_ctx_global.tls_conf = tls_conf_init(tls_ctx); |
| 9045 | + if (tls_ctx_global.tls_conf == NULL) |
| 9046 | + return -1; |
| 9047 | + |
| 9048 | + #ifdef MBEDTLS_SSL_SESSION_TICKETS |
| 9049 | + #ifdef MBEDTLS_SSL_TICKET_C |
| 9050 | + if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET)) |
| 9051 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9052 | + mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, |
| 9053 | + tls_mbedtls_ssl_ticket_write, |
| 9054 | + tls_mbedtls_ssl_ticket_parse, |
| 9055 | + NULL); |
| 9056 | + #else |
| 9057 | + mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, |
| 9058 | + mbedtls_ssl_ticket_write, |
| 9059 | + mbedtls_ssl_ticket_parse, |
| 9060 | + &tls_ctx_global.ticket_ctx); |
| 9061 | + #endif |
| 9062 | + #endif |
| 9063 | + #endif |
| 9064 | + |
| 9065 | + os_free(tls_ctx_global.ocsp_stapling_response); |
| 9066 | + tls_ctx_global.ocsp_stapling_response = NULL; |
| 9067 | + if (params->ocsp_stapling_response) |
| 9068 | + tls_ctx_global.ocsp_stapling_response = |
| 9069 | + os_strdup(params->ocsp_stapling_response); |
| 9070 | + |
| 9071 | + os_free(tls_ctx_global.ca_cert_file); |
| 9072 | + tls_ctx_global.ca_cert_file = NULL; |
| 9073 | + if (params->ca_cert) |
| 9074 | + tls_ctx_global.ca_cert_file = os_strdup(params->ca_cert); |
| 9075 | + return tls_mbedtls_set_params(tls_ctx_global.tls_conf, params); |
| 9076 | +} |
| 9077 | + |
| 9078 | + |
| 9079 | +int tls_global_set_verify(void *tls_ctx, int check_crl, int strict) |
| 9080 | +{ |
| 9081 | + tls_ctx_global.tls_conf->check_crl = check_crl; |
| 9082 | + tls_ctx_global.tls_conf->check_crl_strict = strict; /*(time checks)*/ |
| 9083 | + return 0; |
| 9084 | +} |
| 9085 | + |
| 9086 | + |
| 9087 | +int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, |
| 9088 | + int verify_peer, unsigned int flags, |
| 9089 | + const u8 *session_ctx, size_t session_ctx_len) |
| 9090 | +{ |
| 9091 | + /*(EAP server-side calls this from eap_server_tls_ssl_init())*/ |
| 9092 | + if (conn == NULL) |
| 9093 | + return -1; |
| 9094 | + |
| 9095 | + conn->tls_conf->flags |= flags;/* TODO: reprocess flags, if necessary */ |
| 9096 | + |
| 9097 | + int authmode; |
| 9098 | + switch (verify_peer) { |
| 9099 | + case 2: authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; break;/*(eap_teap_init())*/ |
| 9100 | + case 1: authmode = MBEDTLS_SSL_VERIFY_REQUIRED; break; |
| 9101 | + default: authmode = MBEDTLS_SSL_VERIFY_NONE; break; |
| 9102 | + } |
| 9103 | + mbedtls_ssl_set_hs_authmode(&conn->ssl, authmode); |
| 9104 | + |
| 9105 | + if ((conn->verify_peer = (authmode != MBEDTLS_SSL_VERIFY_NONE))) |
| 9106 | + mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); |
| 9107 | + else |
| 9108 | + mbedtls_ssl_set_verify(&conn->ssl, NULL, NULL); |
| 9109 | + |
| 9110 | + return 0; |
| 9111 | +} |
| 9112 | + |
| 9113 | + |
| 9114 | +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9115 | +static void tls_connection_export_keys_cb( |
| 9116 | + void *p_expkey, mbedtls_ssl_key_export_type secret_type, |
| 9117 | + const unsigned char *secret, size_t secret_len, |
| 9118 | + const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9119 | + const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9120 | + mbedtls_tls_prf_types tls_prf_type) |
| 9121 | +{ |
| 9122 | + struct tls_connection *conn = p_expkey; |
| 9123 | + conn->tls_prf_type = tls_prf_type; |
| 9124 | + if (!tls_prf_type) |
| 9125 | + return; |
| 9126 | + if (secret_len > sizeof(conn->expkey_secret)) { |
| 9127 | + emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long"); |
| 9128 | + conn->tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE; /* 0 */ |
| 9129 | + return; |
| 9130 | + } |
| 9131 | + conn->expkey_secret_len = secret_len; |
| 9132 | + os_memcpy(conn->expkey_secret, secret, secret_len); |
| 9133 | + os_memcpy(conn->expkey_randbytes, |
| 9134 | + client_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9135 | + os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, |
| 9136 | + server_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9137 | +} |
| 9138 | +#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9139 | +static int tls_connection_export_keys_cb( |
| 9140 | + void *p_expkey, |
| 9141 | + const unsigned char *ms, |
| 9142 | + const unsigned char *kb, |
| 9143 | + size_t maclen, |
| 9144 | + size_t keylen, |
| 9145 | + size_t ivlen, |
| 9146 | + const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9147 | + const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], |
| 9148 | + mbedtls_tls_prf_types tls_prf_type ) |
| 9149 | +{ |
| 9150 | + struct tls_connection *conn = p_expkey; |
| 9151 | + conn->tls_prf_type = tls_prf_type; |
| 9152 | + if (!tls_prf_type) |
| 9153 | + return -1; /*(return value ignored by mbedtls)*/ |
| 9154 | + conn->expkey_keyblock_size = maclen + keylen + ivlen; |
| 9155 | + conn->expkey_secret_len = MBEDTLS_EXPKEY_FIXED_SECRET_LEN; |
| 9156 | + os_memcpy(conn->expkey_secret, ms, MBEDTLS_EXPKEY_FIXED_SECRET_LEN); |
| 9157 | + os_memcpy(conn->expkey_randbytes, |
| 9158 | + client_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9159 | + os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, |
| 9160 | + server_random, MBEDTLS_EXPKEY_RAND_LEN); |
| 9161 | + return 0; |
| 9162 | +} |
| 9163 | +#endif |
| 9164 | + |
| 9165 | + |
| 9166 | +int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, |
| 9167 | + struct tls_random *data) |
| 9168 | +{ |
| 9169 | + if (!conn || !conn->tls_prf_type) |
| 9170 | + return -1; |
| 9171 | + data->client_random = conn->expkey_randbytes; |
| 9172 | + data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN; |
| 9173 | + data->server_random = conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN; |
| 9174 | + data->server_random_len = MBEDTLS_EXPKEY_RAND_LEN; |
| 9175 | + return 0; |
| 9176 | +} |
| 9177 | + |
| 9178 | + |
| 9179 | +int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, |
| 9180 | + const char *label, const u8 *context, |
| 9181 | + size_t context_len, u8 *out, size_t out_len) |
| 9182 | +{ |
| 9183 | + /* (EAP-PEAP EAP-TLS EAP-TTLS) */ |
| 9184 | + #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9185 | + return (conn && conn->established && conn->tls_prf_type) |
| 9186 | + ? mbedtls_ssl_tls_prf(conn->tls_prf_type, |
| 9187 | + conn->expkey_secret, conn->expkey_secret_len, label, |
| 9188 | + conn->expkey_randbytes, |
| 9189 | + sizeof(conn->expkey_randbytes), out, out_len) |
| 9190 | + : -1; |
| 9191 | + #else |
| 9192 | + /* not implemented here for mbedtls < 2.18.0 */ |
| 9193 | + return -1; |
| 9194 | + #endif |
| 9195 | +} |
| 9196 | + |
| 9197 | + |
| 9198 | +#ifdef TLS_MBEDTLS_EAP_FAST |
| 9199 | + |
| 9200 | +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9201 | +/* keyblock size info is not exposed in mbed TLS 3.0.0 */ |
| 9202 | +/* extracted from mbedtls library/ssl_tls.c:ssl_tls12_populate_transform() */ |
| 9203 | +#include <mbedtls/ssl_ciphersuites.h> |
| 9204 | +#include <mbedtls/cipher.h> |
| 9205 | +static size_t tls_mbedtls_ssl_keyblock_size (mbedtls_ssl_context *ssl) |
| 9206 | +{ |
| 9207 | + #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */ |
| 9208 | + #if defined(MBEDTLS_SSL_PROTO_TLS1_3) |
| 9209 | + if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) |
| 9210 | + return 0; /* (calculation not extracted) */ |
| 9211 | + #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ |
| 9212 | + |
| 9213 | + int ciphersuite = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); |
| 9214 | + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
| 9215 | + mbedtls_ssl_ciphersuite_from_id(ciphersuite); |
| 9216 | + if (ciphersuite_info == NULL) |
| 9217 | + return 0; |
| 9218 | + |
| 9219 | + const mbedtls_cipher_info_t *cipher_info = |
| 9220 | + mbedtls_cipher_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(cipher)); |
| 9221 | + if (cipher_info == NULL) |
| 9222 | + return 0; |
| 9223 | + |
| 9224 | + #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ |
| 9225 | + size_t keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; |
| 9226 | + mbedtls_cipher_mode_t mode = mbedtls_cipher_info_get_mode(cipher_info); |
| 9227 | + #else |
| 9228 | + size_t keylen = cipher_info->MBEDTLS_PRIVATE(key_bitlen) / 8; |
| 9229 | + mbedtls_cipher_mode_t mode = cipher_info->MBEDTLS_PRIVATE(mode); |
| 9230 | + #endif |
| 9231 | + #if defined(MBEDTLS_GCM_C) || \ |
| 9232 | + defined(MBEDTLS_CCM_C) || \ |
| 9233 | + defined(MBEDTLS_CHACHAPOLY_C) |
| 9234 | + if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM) |
| 9235 | + return keylen + 4; |
| 9236 | + else if (mode == MBEDTLS_MODE_CHACHAPOLY) |
| 9237 | + return keylen + 12; |
| 9238 | + else |
| 9239 | + #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ |
| 9240 | + #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) |
| 9241 | + { |
| 9242 | + const mbedtls_md_info_t *md_info = |
| 9243 | + mbedtls_md_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(mac)); |
| 9244 | + if (md_info == NULL) |
| 9245 | + return 0; |
| 9246 | + size_t mac_key_len = mbedtls_md_get_size(md_info); |
| 9247 | + size_t ivlen = mbedtls_cipher_info_get_iv_size(cipher_info); |
| 9248 | + return keylen + mac_key_len + ivlen; |
| 9249 | + } |
| 9250 | + #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ |
| 9251 | + #endif /* !MBEDTLS_USE_PSA_CRYPTO *//* (not extracted for PSA crypto) */ |
| 9252 | + return 0; |
| 9253 | +} |
| 9254 | +#endif /* MBEDTLS_VERSION_NUMBER >= 0x03000000 *//* mbedtls 3.0.0 */ |
| 9255 | + |
| 9256 | + |
| 9257 | +int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, |
| 9258 | + u8 *out, size_t out_len) |
| 9259 | +{ |
| 9260 | + /* XXX: has export keys callback been run? */ |
| 9261 | + if (!conn || !conn->tls_prf_type) |
| 9262 | + return -1; |
| 9263 | + |
| 9264 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9265 | + conn->expkey_keyblock_size = tls_mbedtls_ssl_keyblock_size(&conn->ssl); |
| 9266 | + if (conn->expkey_keyblock_size == 0) |
| 9267 | + return -1; |
| 9268 | + #endif |
| 9269 | + size_t skip = conn->expkey_keyblock_size * 2; |
| 9270 | + unsigned char *tmp_out = os_malloc(skip + out_len); |
| 9271 | + if (!tmp_out) |
| 9272 | + return -1; |
| 9273 | + |
| 9274 | + /* server_random and then client_random */ |
| 9275 | + unsigned char seed[MBEDTLS_EXPKEY_RAND_LEN*2]; |
| 9276 | + os_memcpy(seed, conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, |
| 9277 | + MBEDTLS_EXPKEY_RAND_LEN); |
| 9278 | + os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes, |
| 9279 | + MBEDTLS_EXPKEY_RAND_LEN); |
| 9280 | + |
| 9281 | + #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9282 | + int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, |
| 9283 | + conn->expkey_secret, conn->expkey_secret_len, |
| 9284 | + "key expansion", seed, sizeof(seed), |
| 9285 | + tmp_out, skip + out_len); |
| 9286 | + if (ret == 0) |
| 9287 | + os_memcpy(out, tmp_out + skip, out_len); |
| 9288 | + #else |
| 9289 | + int ret = -1; /*(not reached if not impl; return -1 at top of func)*/ |
| 9290 | + #endif |
| 9291 | + |
| 9292 | + bin_clear_free(tmp_out, skip + out_len); |
| 9293 | + forced_memzero(seed, sizeof(seed)); |
| 9294 | + return ret; |
| 9295 | +} |
| 9296 | + |
| 9297 | +#endif /* TLS_MBEDTLS_EAP_FAST */ |
| 9298 | + |
| 9299 | + |
| 9300 | +__attribute_cold__ |
| 9301 | +static void tls_mbedtls_suiteb_handshake_alert (struct tls_connection *conn) |
| 9302 | +{ |
| 9303 | + /* tests/hwsim/test_suite_b.py test_suite_b_192_rsa_insufficient_dh */ |
| 9304 | + if (!(conn->tls_conf->flags & TLS_CONN_SUITEB)) |
| 9305 | + return; |
| 9306 | + if (tls_ctx_global.tls_conf) /*(is server; want issue event on client)*/ |
| 9307 | + return; |
| 9308 | + #if 0 |
| 9309 | + /*(info not available on client; |
| 9310 | + * mbed TLS library enforces dhm min bitlen in ServerKeyExchange)*/ |
| 9311 | + if (MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 == |
| 9312 | + #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ |
| 9313 | + mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl) |
| 9314 | + #else |
| 9315 | + mbedtls_ssl_get_ciphersuite_id( |
| 9316 | + mbedtls_ssl_get_ciphersuite(&conn->ssl)) |
| 9317 | + #endif |
| 9318 | + && mbedtls_mpi_size(&conn->tls_conf->conf.MBEDTLS_PRIVATE(dhm_P)) |
| 9319 | + < 384 /*(3072/8)*/) |
| 9320 | + #endif |
| 9321 | + { |
| 9322 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 9323 | + if (init_conf->event_cb) { |
| 9324 | + union tls_event_data ev; |
| 9325 | + os_memset(&ev, 0, sizeof(ev)); |
| 9326 | + ev.alert.is_local = 1; |
| 9327 | + ev.alert.type = "fatal"; |
| 9328 | + /*"internal error" string for tests/hwsim/test_suiteb.py */ |
| 9329 | + ev.alert.description = "internal error: handshake failure"; |
| 9330 | + /*ev.alert.description = "insufficient security";*/ |
| 9331 | + init_conf->event_cb(init_conf->cb_ctx, TLS_ALERT, &ev); |
| 9332 | + } |
| 9333 | + } |
| 9334 | +} |
| 9335 | + |
| 9336 | + |
| 9337 | +struct wpabuf * tls_connection_handshake(void *tls_ctx, |
| 9338 | + struct tls_connection *conn, |
| 9339 | + const struct wpabuf *in_data, |
| 9340 | + struct wpabuf **appl_data) |
| 9341 | +{ |
| 9342 | + if (appl_data) |
| 9343 | + *appl_data = NULL; |
| 9344 | + |
| 9345 | + if (in_data && wpabuf_len(in_data)) { |
| 9346 | + /*(unsure why tls_gnutls.c discards buffer contents; skip here)*/ |
| 9347 | + if (conn->pull_buf && 0) /* disable; appears unwise */ |
| 9348 | + tls_pull_buf_discard(conn, __func__); |
| 9349 | + if (!tls_pull_buf_append(conn, in_data)) |
| 9350 | + return NULL; |
| 9351 | + } |
| 9352 | + |
| 9353 | + if (conn->tls_conf == NULL) { |
| 9354 | + struct tls_connection_params params; |
| 9355 | + os_memset(¶ms, 0, sizeof(params)); |
| 9356 | + params.openssl_ciphers = |
| 9357 | + tls_ctx_global.init_conf.openssl_ciphers; |
| 9358 | + params.flags = tls_ctx_global.tls_conf->flags; |
| 9359 | + if (tls_connection_set_params(tls_ctx, conn, ¶ms) != 0) |
| 9360 | + return NULL; |
| 9361 | + } |
| 9362 | + |
| 9363 | + if (conn->verify_peer) /*(call here might be redundant; nbd)*/ |
| 9364 | + mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); |
| 9365 | + |
| 9366 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9367 | + if (conn->clienthello_session_ticket) |
| 9368 | + /*(starting handshake for EAP-FAST and EAP-TEAP)*/ |
| 9369 | + tls_mbedtls_clienthello_session_ticket_set(conn); |
| 9370 | + |
| 9371 | + /* (not thread-safe due to need to set userdata 'conn' for callback) */ |
| 9372 | + /* (unable to use mbedtls_ssl_set_user_data_p() with mbedtls 3.2.0+ |
| 9373 | + * since ticket write and parse callbacks take (mbedtls_ssl_session *) |
| 9374 | + * param instead of (mbedtls_ssl_context *) param) */ |
| 9375 | + if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) |
| 9376 | + mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, |
| 9377 | + NULL, NULL, NULL); |
| 9378 | + else |
| 9379 | + mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, |
| 9380 | + tls_mbedtls_ssl_ticket_write, |
| 9381 | + tls_mbedtls_ssl_ticket_parse, |
| 9382 | + conn); |
| 9383 | + #endif |
| 9384 | + |
| 9385 | + #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ |
| 9386 | + int ret = mbedtls_ssl_handshake(&conn->ssl); |
| 9387 | + #else |
| 9388 | + int ret = 0; |
| 9389 | + while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) { |
| 9390 | + ret = mbedtls_ssl_handshake_step(&conn->ssl); |
| 9391 | + if (ret != 0) |
| 9392 | + break; |
| 9393 | + } |
| 9394 | + #endif |
| 9395 | + |
| 9396 | + #ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9397 | + mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, |
| 9398 | + tls_mbedtls_ssl_ticket_write, |
| 9399 | + tls_mbedtls_ssl_ticket_parse, |
| 9400 | + NULL); |
| 9401 | + #endif |
| 9402 | + |
| 9403 | + switch (ret) { |
| 9404 | + case 0: |
| 9405 | + conn->established = 1; |
| 9406 | + if (conn->push_buf == NULL) |
| 9407 | + /* Need to return something to get final TLS ACK. */ |
| 9408 | + conn->push_buf = wpabuf_alloc(0); |
| 9409 | + |
| 9410 | + if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/) |
| 9411 | + *appl_data = NULL; /* RFE: check for application data */ |
| 9412 | + break; |
| 9413 | + case MBEDTLS_ERR_SSL_WANT_WRITE: |
| 9414 | + case MBEDTLS_ERR_SSL_WANT_READ: |
| 9415 | + case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: |
| 9416 | + case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: |
| 9417 | + if (tls_ctx_global.tls_conf /*(is server)*/ |
| 9418 | + && conn->established && conn->push_buf == NULL) |
| 9419 | + /* Need to return something to trigger completion of EAP-TLS. */ |
| 9420 | + conn->push_buf = wpabuf_alloc(0); |
| 9421 | + break; |
| 9422 | + default: |
| 9423 | + ++conn->failed; |
| 9424 | + switch (ret) { |
| 9425 | + case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: |
| 9426 | + case MBEDTLS_ERR_NET_CONN_RESET: |
| 9427 | + case MBEDTLS_ERR_NET_SEND_FAILED: |
| 9428 | + ++conn->write_alerts; |
| 9429 | + break; |
| 9430 | + #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ |
| 9431 | + case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: |
| 9432 | + #else |
| 9433 | + case MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE: |
| 9434 | + #endif |
| 9435 | + tls_mbedtls_suiteb_handshake_alert(conn); |
| 9436 | + /* fall through */ |
| 9437 | + case MBEDTLS_ERR_NET_RECV_FAILED: |
| 9438 | + case MBEDTLS_ERR_SSL_CONN_EOF: |
| 9439 | + case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: |
| 9440 | + case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE: |
| 9441 | + ++conn->read_alerts; |
| 9442 | + break; |
| 9443 | + default: |
| 9444 | + break; |
| 9445 | + } |
| 9446 | + |
| 9447 | + ilog(ret, "mbedtls_ssl_handshake"); |
| 9448 | + break; |
| 9449 | + } |
| 9450 | + |
| 9451 | + struct wpabuf *out_data = conn->push_buf; |
| 9452 | + conn->push_buf = NULL; |
| 9453 | + return out_data; |
| 9454 | +} |
| 9455 | + |
| 9456 | + |
| 9457 | +struct wpabuf * tls_connection_server_handshake(void *tls_ctx, |
| 9458 | + struct tls_connection *conn, |
| 9459 | + const struct wpabuf *in_data, |
| 9460 | + struct wpabuf **appl_data) |
| 9461 | +{ |
| 9462 | + conn->is_server = 1; |
| 9463 | + return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); |
| 9464 | +} |
| 9465 | + |
| 9466 | + |
| 9467 | +struct wpabuf * tls_connection_encrypt(void *tls_ctx, |
| 9468 | + struct tls_connection *conn, |
| 9469 | + const struct wpabuf *in_data) |
| 9470 | +{ |
| 9471 | + int res = mbedtls_ssl_write(&conn->ssl, |
| 9472 | + wpabuf_head_u8(in_data), wpabuf_len(in_data)); |
| 9473 | + if (res < 0) { |
| 9474 | + elog(res, "mbedtls_ssl_write"); |
| 9475 | + return NULL; |
| 9476 | + } |
| 9477 | + |
| 9478 | + struct wpabuf *buf = conn->push_buf; |
| 9479 | + conn->push_buf = NULL; |
| 9480 | + return buf; |
| 9481 | +} |
| 9482 | + |
| 9483 | + |
| 9484 | +struct wpabuf * tls_connection_decrypt(void *tls_ctx, |
| 9485 | + struct tls_connection *conn, |
| 9486 | + const struct wpabuf *in_data) |
| 9487 | +{ |
| 9488 | + int res; |
| 9489 | + struct wpabuf *out; |
| 9490 | + |
| 9491 | + /*assert(in_data != NULL);*/ |
| 9492 | + if (!tls_pull_buf_append(conn, in_data)) |
| 9493 | + return NULL; |
| 9494 | + |
| 9495 | + #if defined(MBEDTLS_ZLIB_SUPPORT) /* removed in mbedtls 3.x */ |
| 9496 | + /* Add extra buffer space to handle the possibility of decrypted |
| 9497 | + * data being longer than input data due to TLS compression. */ |
| 9498 | + out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); |
| 9499 | + #else /* TLS compression is disabled in mbedtls 3.x */ |
| 9500 | + out = wpabuf_alloc(wpabuf_len(in_data)); |
| 9501 | + #endif |
| 9502 | + if (out == NULL) |
| 9503 | + return NULL; |
| 9504 | + |
| 9505 | + res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(out), wpabuf_size(out)); |
| 9506 | + if (res < 0) { |
| 9507 | + #if 1 /*(seems like a different error if wpabuf_len(in_data) == 0)*/ |
| 9508 | + if (res == MBEDTLS_ERR_SSL_WANT_READ) |
| 9509 | + return out; |
| 9510 | + #endif |
| 9511 | + elog(res, "mbedtls_ssl_read"); |
| 9512 | + wpabuf_free(out); |
| 9513 | + return NULL; |
| 9514 | + } |
| 9515 | + wpabuf_put(out, res); |
| 9516 | + |
| 9517 | + return out; |
| 9518 | +} |
| 9519 | + |
| 9520 | + |
| 9521 | +int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) |
| 9522 | +{ |
| 9523 | + /* XXX: might need to detect if session resumed from TLS session ticket |
| 9524 | + * even if not special session ticket handling for EAP-FAST, EAP-TEAP */ |
| 9525 | + /* (?ssl->handshake->resume during session ticket validation?) */ |
| 9526 | + return conn && conn->resumed; |
| 9527 | +} |
| 9528 | + |
| 9529 | + |
| 9530 | +#ifdef TLS_MBEDTLS_EAP_FAST |
| 9531 | +int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, |
| 9532 | + u8 *ciphers) |
| 9533 | +{ |
| 9534 | + /* ciphers is list of TLS_CIPHER_* from hostap/src/crypto/tls.h */ |
| 9535 | + int ids[7]; |
| 9536 | + const int idsz = (int)sizeof(ids); |
| 9537 | + int nids = -1, id; |
| 9538 | + for ( ; *ciphers != TLS_CIPHER_NONE; ++ciphers) { |
| 9539 | + switch (*ciphers) { |
| 9540 | + case TLS_CIPHER_RC4_SHA: |
| 9541 | + #ifdef MBEDTLS_TLS_RSA_WITH_RC4_128_SHA |
| 9542 | + id = MBEDTLS_TLS_RSA_WITH_RC4_128_SHA; |
| 9543 | + break; |
| 9544 | + #else |
| 9545 | + continue; /*(not supported in mbedtls 3.x; ignore)*/ |
| 9546 | + #endif |
| 9547 | + case TLS_CIPHER_AES128_SHA: |
| 9548 | + id = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA; |
| 9549 | + break; |
| 9550 | + case TLS_CIPHER_RSA_DHE_AES128_SHA: |
| 9551 | + id = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA; |
| 9552 | + break; |
| 9553 | + case TLS_CIPHER_ANON_DH_AES128_SHA: |
| 9554 | + continue; /*(not supported in mbedtls; ignore)*/ |
| 9555 | + case TLS_CIPHER_RSA_DHE_AES256_SHA: |
| 9556 | + id = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA; |
| 9557 | + break; |
| 9558 | + case TLS_CIPHER_AES256_SHA: |
| 9559 | + id = MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA; |
| 9560 | + break; |
| 9561 | + default: |
| 9562 | + return -1; /* should not happen */ |
| 9563 | + } |
| 9564 | + if (++nids == idsz) |
| 9565 | + return -1; /* should not happen */ |
| 9566 | + ids[nids] = id; |
| 9567 | + } |
| 9568 | + if (nids < 0) |
| 9569 | + return 0; /* nothing to do */ |
| 9570 | + if (++nids == idsz) |
| 9571 | + return -1; /* should not happen */ |
| 9572 | + ids[nids] = 0; /* terminate list */ |
| 9573 | + ++nids; |
| 9574 | + |
| 9575 | + return tls_mbedtls_set_ciphersuites(conn->tls_conf, ids, nids) ? 0 : -1; |
| 9576 | +} |
| 9577 | +#endif |
| 9578 | + |
| 9579 | + |
| 9580 | +int tls_get_version(void *ssl_ctx, struct tls_connection *conn, |
| 9581 | + char *buf, size_t buflen) |
| 9582 | +{ |
| 9583 | + if (conn == NULL) |
| 9584 | + return -1; |
| 9585 | + os_strlcpy(buf, mbedtls_ssl_get_version(&conn->ssl), buflen); |
| 9586 | + return buf[0] != 'u' ? 0 : -1; /*(-1 if "unknown")*/ |
| 9587 | +} |
| 9588 | + |
| 9589 | + |
| 9590 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 9591 | +u16 tls_connection_get_cipher_suite(struct tls_connection *conn) |
| 9592 | +{ |
| 9593 | + if (conn == NULL) |
| 9594 | + return 0; |
| 9595 | + return (u16)mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); |
| 9596 | +} |
| 9597 | +#endif |
| 9598 | + |
| 9599 | + |
| 9600 | +int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, |
| 9601 | + char *buf, size_t buflen) |
| 9602 | +{ |
| 9603 | + if (conn == NULL) |
| 9604 | + return -1; |
| 9605 | + const int id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); |
| 9606 | + return tls_mbedtls_translate_ciphername(id, buf, buflen) ? 0 : -1; |
| 9607 | +} |
| 9608 | + |
| 9609 | + |
| 9610 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9611 | + |
| 9612 | +int tls_connection_enable_workaround(void *tls_ctx, |
| 9613 | + struct tls_connection *conn) |
| 9614 | +{ |
| 9615 | + /* (see comment in src/eap_peer/eap_fast.c:eap_fast_init()) */ |
| 9616 | + /* XXX: is there a relevant setting for this in mbed TLS? */ |
| 9617 | + /* (do we even care that much about older CBC ciphers?) */ |
| 9618 | + return 0; |
| 9619 | +} |
| 9620 | + |
| 9621 | + |
| 9622 | +int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, |
| 9623 | + int ext_type, const u8 *data, |
| 9624 | + size_t data_len) |
| 9625 | +{ |
| 9626 | + /* (EAP-FAST and EAP-TEAP) */ |
| 9627 | + if (ext_type == MBEDTLS_TLS_EXT_SESSION_TICKET) /*(ext_type == 35)*/ |
| 9628 | + return tls_mbedtls_clienthello_session_ticket_prep(conn, data, |
| 9629 | + data_len); |
| 9630 | + |
| 9631 | + return -1; |
| 9632 | +} |
| 9633 | + |
| 9634 | +#endif /* TLS_MBEDTLS_SESSION_TICKETS */ |
| 9635 | + |
| 9636 | + |
| 9637 | +int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) |
| 9638 | +{ |
| 9639 | + return conn ? conn->failed : -1; |
| 9640 | +} |
| 9641 | + |
| 9642 | + |
| 9643 | +int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) |
| 9644 | +{ |
| 9645 | + return conn ? conn->read_alerts : -1; |
| 9646 | +} |
| 9647 | + |
| 9648 | + |
| 9649 | +int tls_connection_get_write_alerts(void *tls_ctx, |
| 9650 | + struct tls_connection *conn) |
| 9651 | +{ |
| 9652 | + return conn ? conn->write_alerts : -1; |
| 9653 | +} |
| 9654 | + |
| 9655 | + |
| 9656 | +#ifdef TLS_MBEDTLS_SESSION_TICKETS |
| 9657 | +int tls_connection_set_session_ticket_cb( |
| 9658 | + void *tls_ctx, struct tls_connection *conn, |
| 9659 | + tls_session_ticket_cb cb, void *ctx) |
| 9660 | +{ |
| 9661 | + if (!(conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)) { |
| 9662 | + /* (EAP-FAST and EAP-TEAP) */ |
| 9663 | + conn->session_ticket_cb = cb; |
| 9664 | + conn->session_ticket_cb_ctx = ctx; |
| 9665 | + return 0; |
| 9666 | + } |
| 9667 | + return -1; |
| 9668 | +} |
| 9669 | +#endif |
| 9670 | + |
| 9671 | + |
| 9672 | +int tls_get_library_version(char *buf, size_t buf_len) |
| 9673 | +{ |
| 9674 | + #ifndef MBEDTLS_VERSION_C |
| 9675 | + const char * const ver = "n/a"; |
| 9676 | + #else |
| 9677 | + char ver[9]; |
| 9678 | + mbedtls_version_get_string(ver); |
| 9679 | + #endif |
| 9680 | + return os_snprintf(buf, buf_len, |
| 9681 | + "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver); |
| 9682 | +} |
| 9683 | + |
| 9684 | + |
| 9685 | +void tls_connection_set_success_data(struct tls_connection *conn, |
| 9686 | + struct wpabuf *data) |
| 9687 | +{ |
| 9688 | + wpabuf_free(conn->success_data); |
| 9689 | + conn->success_data = data; |
| 9690 | +} |
| 9691 | + |
| 9692 | + |
| 9693 | +void tls_connection_set_success_data_resumed(struct tls_connection *conn) |
| 9694 | +{ |
| 9695 | +} |
| 9696 | + |
| 9697 | + |
| 9698 | +const struct wpabuf * |
| 9699 | +tls_connection_get_success_data(struct tls_connection *conn) |
| 9700 | +{ |
| 9701 | + return conn->success_data; |
| 9702 | +} |
| 9703 | + |
| 9704 | + |
| 9705 | +void tls_connection_remove_session(struct tls_connection *conn) |
| 9706 | +{ |
| 9707 | +} |
| 9708 | + |
| 9709 | + |
| 9710 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 9711 | +int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len) |
| 9712 | +{ |
| 9713 | + #if defined(MBEDTLS_SSL_RENEGOTIATION) /* XXX: renegotiation or resumption? */ |
| 9714 | + /* data from TLS handshake Finished message */ |
| 9715 | + size_t verify_len = conn->ssl.MBEDTLS_PRIVATE(verify_data_len); |
| 9716 | + char *verify_data = (conn->is_server ^ conn->resumed) |
| 9717 | + ? conn->ssl.MBEDTLS_PRIVATE(peer_verify_data) |
| 9718 | + : conn->ssl.MBEDTLS_PRIVATE(own_verify_data); |
| 9719 | + if (verify_len && verify_len <= max_len) { |
| 9720 | + os_memcpy(buf, verify_data, verify_len); |
| 9721 | + return (int)verify_len; |
| 9722 | + } |
| 9723 | + #endif |
| 9724 | + return -1; |
| 9725 | +} |
| 9726 | +#endif |
| 9727 | + |
| 9728 | + |
| 9729 | +__attribute_noinline__ |
| 9730 | +static void tls_mbedtls_set_peer_subject(struct tls_connection *conn, const mbedtls_x509_crt *crt) |
| 9731 | +{ |
| 9732 | + if (conn->peer_subject) |
| 9733 | + return; |
| 9734 | + char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; |
| 9735 | + int buflen = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject); |
| 9736 | + if (buflen >= 0 && (conn->peer_subject = os_malloc((size_t)buflen+1))) |
| 9737 | + os_memcpy(conn->peer_subject, buf, (size_t)buflen+1); |
| 9738 | +} |
| 9739 | + |
| 9740 | + |
| 9741 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 9742 | +const char * tls_connection_get_peer_subject(struct tls_connection *conn) |
| 9743 | +{ |
| 9744 | + if (!conn) |
| 9745 | + return NULL; |
| 9746 | + if (!conn->peer_subject) { /*(if not set during cert verify)*/ |
| 9747 | + const mbedtls_x509_crt *peer_cert = |
| 9748 | + mbedtls_ssl_get_peer_cert(&conn->ssl); |
| 9749 | + if (peer_cert) |
| 9750 | + tls_mbedtls_set_peer_subject(conn, peer_cert); |
| 9751 | + } |
| 9752 | + return conn->peer_subject; |
| 9753 | +} |
| 9754 | +#endif |
| 9755 | + |
| 9756 | + |
| 9757 | +#ifdef TLS_MBEDTLS_EAP_TEAP |
| 9758 | +bool tls_connection_get_own_cert_used(struct tls_connection *conn) |
| 9759 | +{ |
| 9760 | + /* XXX: availability of cert does not necessary mean that client |
| 9761 | + * received certificate request from server and then sent cert. |
| 9762 | + * ? step handshake in tls_connection_handshake() looking for |
| 9763 | + * MBEDTLS_SSL_CERTIFICATE_REQUEST ? */ |
| 9764 | + const struct tls_conf * const tls_conf = conn->tls_conf; |
| 9765 | + return (tls_conf->has_client_cert && tls_conf->has_private_key); |
| 9766 | +} |
| 9767 | +#endif |
| 9768 | + |
| 9769 | + |
| 9770 | +#if defined(CONFIG_FIPS) |
| 9771 | +#define TLS_MBEDTLS_CONFIG_FIPS |
| 9772 | +#endif |
| 9773 | + |
| 9774 | +#if defined(CONFIG_SHA256) |
| 9775 | +#define TLS_MBEDTLS_TLS_PRF_SHA256 |
| 9776 | +#endif |
| 9777 | + |
| 9778 | +#if defined(CONFIG_SHA384) |
| 9779 | +#define TLS_MBEDTLS_TLS_PRF_SHA384 |
| 9780 | +#endif |
| 9781 | + |
| 9782 | + |
| 9783 | +#ifndef TLS_MBEDTLS_CONFIG_FIPS |
| 9784 | +#if defined(CONFIG_MODULE_TESTS) |
| 9785 | +/* unused with CONFIG_TLS=mbedtls except in crypto_module_tests.c */ |
| 9786 | +#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ \ |
| 9787 | + && MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ |
| 9788 | +/* sha1-tlsprf.c */ |
| 9789 | +#include "sha1.h" |
| 9790 | +int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, |
| 9791 | + const u8 *seed, size_t seed_len, u8 *out, size_t outlen) |
| 9792 | +{ |
| 9793 | + return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, |
| 9794 | + secret, secret_len, label, |
| 9795 | + seed, seed_len, out, outlen) ? -1 : 0; |
| 9796 | +} |
| 9797 | +#else |
| 9798 | +#include "sha1-tlsprf.c" /* pull in hostap local implementation */ |
| 9799 | +#endif |
| 9800 | +#endif |
| 9801 | +#endif |
| 9802 | + |
| 9803 | +#ifdef TLS_MBEDTLS_TLS_PRF_SHA256 |
| 9804 | +/* sha256-tlsprf.c */ |
| 9805 | +#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9806 | +#include "sha256.h" |
| 9807 | +int tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label, |
| 9808 | + const u8 *seed, size_t seed_len, u8 *out, size_t outlen) |
| 9809 | +{ |
| 9810 | + return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA256, |
| 9811 | + secret, secret_len, label, |
| 9812 | + seed, seed_len, out, outlen) ? -1 : 0; |
| 9813 | +} |
| 9814 | +#else |
| 9815 | +#include "sha256-tlsprf.c" /* pull in hostap local implementation */ |
| 9816 | +#endif |
| 9817 | +#endif |
| 9818 | + |
| 9819 | +#ifdef TLS_MBEDTLS_TLS_PRF_SHA384 |
| 9820 | +/* sha384-tlsprf.c */ |
| 9821 | +#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ |
| 9822 | +#include "sha384.h" |
| 9823 | +int tls_prf_sha384(const u8 *secret, size_t secret_len, const char *label, |
| 9824 | + const u8 *seed, size_t seed_len, u8 *out, size_t outlen) |
| 9825 | +{ |
| 9826 | + return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA384, |
| 9827 | + secret, secret_len, label, |
| 9828 | + seed, seed_len, out, outlen) ? -1 : 0; |
| 9829 | +} |
| 9830 | +#else |
| 9831 | +#include "sha384-tlsprf.c" /* pull in hostap local implementation */ |
| 9832 | +#endif |
| 9833 | +#endif |
| 9834 | + |
| 9835 | + |
| 9836 | +#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ |
| 9837 | +#define mbedtls_x509_crt_has_ext_type(crt, ext_type) \ |
| 9838 | + ((crt)->MBEDTLS_PRIVATE(ext_types) & (ext_type)) |
| 9839 | +#endif |
| 9840 | + |
| 9841 | +struct mlist { const char *p; size_t n; }; |
| 9842 | + |
| 9843 | + |
| 9844 | +static int |
| 9845 | +tls_mbedtls_match_altsubject(mbedtls_x509_crt *crt, const char *match) |
| 9846 | +{ |
| 9847 | + /* RFE: this could be pre-parsed into structured data at config time */ |
| 9848 | + struct mlist list[256]; /*(much larger than expected)*/ |
| 9849 | + int nlist = 0; |
| 9850 | + if ( os_strncmp(match, "EMAIL:", 6) != 0 |
| 9851 | + && os_strncmp(match, "DNS:", 4) != 0 |
| 9852 | + && os_strncmp(match, "URI:", 4) != 0 ) { |
| 9853 | + wpa_printf(MSG_INFO, "MTLS: Invalid altSubjectName match '%s'", match); |
| 9854 | + return 0; |
| 9855 | + } |
| 9856 | + for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { |
| 9857 | + do { } while ((tok = os_strchr(s, ';')) |
| 9858 | + && os_strncmp(tok+1, "EMAIL:", 6) != 0 |
| 9859 | + && os_strncmp(tok+1, "DNS:", 4) != 0 |
| 9860 | + && os_strncmp(tok+1, "URI:", 4) != 0); |
| 9861 | + list[nlist].p = s; |
| 9862 | + list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); |
| 9863 | + if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { |
| 9864 | + wpa_printf(MSG_INFO, "MTLS: excessive altSubjectName match '%s'", |
| 9865 | + match); |
| 9866 | + break; /* truncate huge list and continue */ |
| 9867 | + } |
| 9868 | + } |
| 9869 | + |
| 9870 | + if (!mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) |
| 9871 | + return 0; |
| 9872 | + |
| 9873 | + const mbedtls_x509_sequence *cur = &crt->subject_alt_names; |
| 9874 | + for (; cur != NULL; cur = cur->next) { |
| 9875 | + const unsigned char san_type = (unsigned char)cur->buf.tag |
| 9876 | + & MBEDTLS_ASN1_TAG_VALUE_MASK; |
| 9877 | + char t; |
| 9878 | + size_t step = 4; |
| 9879 | + switch (san_type) { /* "EMAIL:" or "DNS:" or "URI:" */ |
| 9880 | + case MBEDTLS_X509_SAN_RFC822_NAME: step = 6; t = 'E'; break; |
| 9881 | + case MBEDTLS_X509_SAN_DNS_NAME: t = 'D'; break; |
| 9882 | + case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: t = 'U'; break; |
| 9883 | + default: continue; |
| 9884 | + } |
| 9885 | + |
| 9886 | + for (int i = 0; i < nlist; ++i) { |
| 9887 | + /* step over "EMAIL:" or "DNS:" or "URI:" in list[i].p */ |
| 9888 | + /* Note: v is not '\0'-terminated, but is a known length vlen, |
| 9889 | + * so okay to pass to os_strncasecmp() even though not z-string */ |
| 9890 | + if (cur->buf.len == list[i].n - step && t == *list[i].p |
| 9891 | + && 0 == os_strncasecmp((char *)cur->buf.p, |
| 9892 | + list[i].p+step, cur->buf.len)) { |
| 9893 | + return 1; /* match */ |
| 9894 | + } |
| 9895 | + } |
| 9896 | + } |
| 9897 | + return 0; /* no match */ |
| 9898 | +} |
| 9899 | + |
| 9900 | + |
| 9901 | +static int |
| 9902 | +tls_mbedtls_match_suffix(const char *v, size_t vlen, |
| 9903 | + const struct mlist *list, int nlist, int full) |
| 9904 | +{ |
| 9905 | + /* Note: v is not '\0'-terminated, but is a known length vlen, |
| 9906 | + * so okay to pass to os_strncasecmp() even though not z-string */ |
| 9907 | + for (int i = 0; i < nlist; ++i) { |
| 9908 | + size_t n = list[i].n; |
| 9909 | + if ((n == vlen || (n < vlen && v[vlen-n-1] == '.' && !full)) |
| 9910 | + && 0 == os_strncasecmp(v+vlen-n, list[i].p, n)) |
| 9911 | + return 1; /* match */ |
| 9912 | + } |
| 9913 | + return 0; /* no match */ |
| 9914 | +} |
| 9915 | + |
| 9916 | + |
| 9917 | +static int |
| 9918 | +tls_mbedtls_match_suffixes(mbedtls_x509_crt *crt, const char *match, int full) |
| 9919 | +{ |
| 9920 | + /* RFE: this could be pre-parsed into structured data at config time */ |
| 9921 | + struct mlist list[256]; /*(much larger than expected)*/ |
| 9922 | + int nlist = 0; |
| 9923 | + for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { |
| 9924 | + tok = os_strchr(s, ';'); |
| 9925 | + list[nlist].p = s; |
| 9926 | + list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); |
| 9927 | + if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { |
| 9928 | + wpa_printf(MSG_INFO, "MTLS: excessive suffix match '%s'", match); |
| 9929 | + break; /* truncate huge list and continue */ |
| 9930 | + } |
| 9931 | + } |
| 9932 | + |
| 9933 | + /* check subjectAltNames */ |
| 9934 | + if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) { |
| 9935 | + const mbedtls_x509_sequence *cur = &crt->subject_alt_names; |
| 9936 | + for (; cur != NULL; cur = cur->next) { |
| 9937 | + const unsigned char san_type = (unsigned char)cur->buf.tag |
| 9938 | + & MBEDTLS_ASN1_TAG_VALUE_MASK; |
| 9939 | + if (san_type == MBEDTLS_X509_SAN_DNS_NAME |
| 9940 | + && tls_mbedtls_match_suffix((char *)cur->buf.p, |
| 9941 | + cur->buf.len, |
| 9942 | + list, nlist, full)) { |
| 9943 | + return 1; /* match */ |
| 9944 | + } |
| 9945 | + } |
| 9946 | + } |
| 9947 | + |
| 9948 | + /* check subject CN */ |
| 9949 | + const mbedtls_x509_name *name = &crt->subject; |
| 9950 | + for (; name != NULL; name = name->next) { |
| 9951 | + if (name->oid.p && MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0) |
| 9952 | + break; |
| 9953 | + } |
| 9954 | + if (name && tls_mbedtls_match_suffix((char *)name->val.p, name->val.len, |
| 9955 | + list, nlist, full)) { |
| 9956 | + return 1; /* match */ |
| 9957 | + } |
| 9958 | + |
| 9959 | + return 0; /* no match */ |
| 9960 | +} |
| 9961 | + |
| 9962 | + |
| 9963 | +static int |
| 9964 | +tls_mbedtls_match_dn_field(mbedtls_x509_crt *crt, const char *match) |
| 9965 | +{ |
| 9966 | + /* RFE: this could be pre-parsed into structured data at config time */ |
| 9967 | + struct mlistoid { const char *p; size_t n; |
| 9968 | + const char *oid; size_t olen; |
| 9969 | + int prefix; }; |
| 9970 | + struct mlistoid list[32]; /*(much larger than expected)*/ |
| 9971 | + int nlist = 0; |
| 9972 | + for (const char *s = match, *tok, *e; *s; s = tok ? tok+1 : "") { |
| 9973 | + tok = os_strchr(s, '/'); |
| 9974 | + list[nlist].oid = NULL; |
| 9975 | + list[nlist].olen = 0; |
| 9976 | + list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); |
| 9977 | + e = memchr(s, '=', list[nlist].n); |
| 9978 | + if (e == NULL) { |
| 9979 | + if (list[nlist].n == 0) |
| 9980 | + continue; /* skip consecutive, repeated '/' */ |
| 9981 | + if (list[nlist].n == 1 && *s == '*') { |
| 9982 | + /* special-case "*" to match any OID and value */ |
| 9983 | + s = e = "=*"; |
| 9984 | + list[nlist].n = 2; |
| 9985 | + list[nlist].oid = ""; |
| 9986 | + } |
| 9987 | + else { |
| 9988 | + wpa_printf(MSG_INFO, |
| 9989 | + "MTLS: invalid check_cert_subject '%s' missing '='", |
| 9990 | + match); |
| 9991 | + return 0; |
| 9992 | + } |
| 9993 | + } |
| 9994 | + switch (e - s) { |
| 9995 | + case 1: |
| 9996 | + if (*s == 'C') { |
| 9997 | + list[nlist].oid = MBEDTLS_OID_AT_COUNTRY; |
| 9998 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_COUNTRY)-1; |
| 9999 | + } |
| 10000 | + else if (*s == 'L') { |
| 10001 | + list[nlist].oid = MBEDTLS_OID_AT_LOCALITY; |
| 10002 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_LOCALITY)-1; |
| 10003 | + } |
| 10004 | + else if (*s == 'O') { |
| 10005 | + list[nlist].oid = MBEDTLS_OID_AT_ORGANIZATION; |
| 10006 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORGANIZATION)-1; |
| 10007 | + } |
| 10008 | + break; |
| 10009 | + case 2: |
| 10010 | + if (s[0] == 'C' && s[1] == 'N') { |
| 10011 | + list[nlist].oid = MBEDTLS_OID_AT_CN; |
| 10012 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_CN)-1; |
| 10013 | + } |
| 10014 | + else if (s[0] == 'S' && s[1] == 'T') { |
| 10015 | + list[nlist].oid = MBEDTLS_OID_AT_STATE; |
| 10016 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_STATE)-1; |
| 10017 | + } |
| 10018 | + else if (s[0] == 'O' && s[1] == 'U') { |
| 10019 | + list[nlist].oid = MBEDTLS_OID_AT_ORG_UNIT; |
| 10020 | + list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORG_UNIT)-1; |
| 10021 | + } |
| 10022 | + break; |
| 10023 | + case 12: |
| 10024 | + if (os_memcmp(s, "emailAddress", 12) == 0) { |
| 10025 | + list[nlist].oid = MBEDTLS_OID_PKCS9_EMAIL; |
| 10026 | + list[nlist].olen = sizeof(MBEDTLS_OID_PKCS9_EMAIL)-1; |
| 10027 | + } |
| 10028 | + break; |
| 10029 | + default: |
| 10030 | + break; |
| 10031 | + } |
| 10032 | + if (list[nlist].oid == NULL) { |
| 10033 | + wpa_printf(MSG_INFO, |
| 10034 | + "MTLS: Unknown field in check_cert_subject '%s'", |
| 10035 | + match); |
| 10036 | + return 0; |
| 10037 | + } |
| 10038 | + list[nlist].n -= (size_t)(++e - s); |
| 10039 | + list[nlist].p = e; |
| 10040 | + if (list[nlist].n && e[list[nlist].n-1] == '*') { |
| 10041 | + --list[nlist].n; |
| 10042 | + list[nlist].prefix = 1; |
| 10043 | + } |
| 10044 | + /*(could easily add support for suffix matches if value begins with '*', |
| 10045 | + * but suffix match is not currently supported by other TLS modules)*/ |
| 10046 | + |
| 10047 | + if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { |
| 10048 | + wpa_printf(MSG_INFO, |
| 10049 | + "MTLS: excessive check_cert_subject match '%s'", |
| 10050 | + match); |
| 10051 | + break; /* truncate huge list and continue */ |
| 10052 | + } |
| 10053 | + } |
| 10054 | + |
| 10055 | + /* each component in match string must match cert Subject in order listed |
| 10056 | + * The behavior below preserves ordering but is slightly different than |
| 10057 | + * the grossly inefficient contortions implemented in tls_openssl.c */ |
| 10058 | + const mbedtls_x509_name *name = &crt->subject; |
| 10059 | + for (int i = 0; i < nlist; ++i) { |
| 10060 | + int found = 0; |
| 10061 | + for (; name != NULL && !found; name = name->next) { |
| 10062 | + if (!name->oid.p) |
| 10063 | + continue; |
| 10064 | + /* special-case "*" to match any OID and value */ |
| 10065 | + if (list[i].olen == 0) { |
| 10066 | + found = 1; |
| 10067 | + continue; |
| 10068 | + } |
| 10069 | + /* perform equalent of !MBEDTLS_OID_CMP() with oid ptr and len */ |
| 10070 | + if (list[i].olen != name->oid.len |
| 10071 | + || os_memcmp(list[i].oid, name->oid.p, name->oid.len) != 0) |
| 10072 | + continue; |
| 10073 | + /* Note: v is not '\0'-terminated, but is a known length vlen, |
| 10074 | + * so okay to pass to os_strncasecmp() even though not z-string */ |
| 10075 | + if ((list[i].prefix |
| 10076 | + ? list[i].n <= name->val.len /* prefix match */ |
| 10077 | + : list[i].n == name->val.len) /* full match */ |
| 10078 | + && 0 == os_strncasecmp((char *)name->val.p, |
| 10079 | + list[i].p, list[i].n)) { |
| 10080 | + found = 1; |
| 10081 | + continue; |
| 10082 | + } |
| 10083 | + } |
| 10084 | + if (!found) |
| 10085 | + return 0; /* no match */ |
| 10086 | + } |
| 10087 | + return 1; /* match */ |
| 10088 | +} |
| 10089 | + |
| 10090 | + |
| 10091 | +__attribute_cold__ |
| 10092 | +static void |
| 10093 | +tls_mbedtls_verify_fail_event (mbedtls_x509_crt *crt, int depth, |
| 10094 | + const char *errmsg, enum tls_fail_reason reason) |
| 10095 | +{ |
| 10096 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 10097 | + if (init_conf->event_cb == NULL) |
| 10098 | + return; |
| 10099 | + |
| 10100 | + struct wpabuf *certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); |
| 10101 | + char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; |
| 10102 | + if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) |
| 10103 | + subject[0] = '\0'; |
| 10104 | + union tls_event_data ev; |
| 10105 | + os_memset(&ev, 0, sizeof(ev)); |
| 10106 | + ev.cert_fail.reason = reason; |
| 10107 | + ev.cert_fail.depth = depth; |
| 10108 | + ev.cert_fail.subject = subject; |
| 10109 | + ev.cert_fail.reason_txt = errmsg; |
| 10110 | + ev.cert_fail.cert = certbuf; |
| 10111 | + |
| 10112 | + init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); |
| 10113 | + |
| 10114 | + wpabuf_free(certbuf); |
| 10115 | +} |
| 10116 | + |
| 10117 | + |
| 10118 | +__attribute_noinline__ |
| 10119 | +static void |
| 10120 | +tls_mbedtls_verify_cert_event (struct tls_connection *conn, |
| 10121 | + mbedtls_x509_crt *crt, int depth) |
| 10122 | +{ |
| 10123 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 10124 | + if (init_conf->event_cb == NULL) |
| 10125 | + return; |
| 10126 | + |
| 10127 | + struct wpabuf *certbuf = NULL; |
| 10128 | + union tls_event_data ev; |
| 10129 | + os_memset(&ev, 0, sizeof(ev)); |
| 10130 | + |
| 10131 | + #ifdef MBEDTLS_SHA256_C |
| 10132 | + u8 hash[SHA256_DIGEST_LENGTH]; |
| 10133 | + const u8 *addr[] = { (u8 *)crt->raw.p }; |
| 10134 | + if (sha256_vector(1, addr, &crt->raw.len, hash) == 0) { |
| 10135 | + ev.peer_cert.hash = hash; |
| 10136 | + ev.peer_cert.hash_len = sizeof(hash); |
| 10137 | + } |
| 10138 | + #endif |
| 10139 | + ev.peer_cert.depth = depth; |
| 10140 | + char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; |
| 10141 | + if (depth == 0) |
| 10142 | + ev.peer_cert.subject = conn->peer_subject; |
| 10143 | + if (ev.peer_cert.subject == NULL) { |
| 10144 | + ev.peer_cert.subject = subject; |
| 10145 | + if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) |
| 10146 | + subject[0] = '\0'; |
| 10147 | + } |
| 10148 | + |
| 10149 | + char serial_num[128+1]; |
| 10150 | + ev.peer_cert.serial_num = |
| 10151 | + tls_mbedtls_peer_serial_num(crt, serial_num, sizeof(serial_num)); |
| 10152 | + |
| 10153 | + const mbedtls_x509_sequence *cur; |
| 10154 | + |
| 10155 | + cur = NULL; |
| 10156 | + if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) |
| 10157 | + cur = &crt->subject_alt_names; |
| 10158 | + for (; cur != NULL; cur = cur->next) { |
| 10159 | + const unsigned char san_type = (unsigned char)cur->buf.tag |
| 10160 | + & MBEDTLS_ASN1_TAG_VALUE_MASK; |
| 10161 | + size_t prelen = 4; |
| 10162 | + const char *pre; |
| 10163 | + switch (san_type) { |
| 10164 | + case MBEDTLS_X509_SAN_RFC822_NAME: prelen = 6; pre = "EMAIL:";break; |
| 10165 | + case MBEDTLS_X509_SAN_DNS_NAME: pre = "DNS:"; break; |
| 10166 | + case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: pre = "URI:"; break; |
| 10167 | + default: continue; |
| 10168 | + } |
| 10169 | + |
| 10170 | + char *pos = os_malloc(prelen + cur->buf.len + 1); |
| 10171 | + if (pos == NULL) |
| 10172 | + break; |
| 10173 | + ev.peer_cert.altsubject[ev.peer_cert.num_altsubject] = pos; |
| 10174 | + os_memcpy(pos, pre, prelen); |
| 10175 | + /* data should be properly backslash-escaped if needed, |
| 10176 | + * so code below does not re-escape, but does replace CTLs */ |
| 10177 | + /*os_memcpy(pos+prelen, cur->buf.p, cur->buf.len);*/ |
| 10178 | + /*pos[prelen+cur->buf.len] = '\0';*/ |
| 10179 | + pos += prelen; |
| 10180 | + for (size_t i = 0; i < cur->buf.len; ++i) { |
| 10181 | + unsigned char c = cur->buf.p[i]; |
| 10182 | + *pos++ = (c >= 32 && c != 127) ? c : '?'; |
| 10183 | + } |
| 10184 | + *pos = '\0'; |
| 10185 | + |
| 10186 | + if (++ev.peer_cert.num_altsubject == TLS_MAX_ALT_SUBJECT) |
| 10187 | + break; |
| 10188 | + } |
| 10189 | + |
| 10190 | + cur = NULL; |
| 10191 | + if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_CERTIFICATE_POLICIES)) |
| 10192 | + cur = &crt->certificate_policies; |
| 10193 | + for (; cur != NULL; cur = cur->next) { |
| 10194 | + if (cur->buf.len != 11) /* len of OID_TOD_STRICT or OID_TOD_TOFU */ |
| 10195 | + continue; |
| 10196 | + /* TOD-STRICT "1.3.6.1.4.1.40808.1.3.1" */ |
| 10197 | + /* TOD-TOFU "1.3.6.1.4.1.40808.1.3.2" */ |
| 10198 | + #define OID_TOD_STRICT "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x01" |
| 10199 | + #define OID_TOD_TOFU "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x02" |
| 10200 | + if (os_memcmp(cur->buf.p, |
| 10201 | + OID_TOD_STRICT, sizeof(OID_TOD_STRICT)-1) == 0) { |
| 10202 | + ev.peer_cert.tod = 1; /* TOD-STRICT */ |
| 10203 | + break; |
| 10204 | + } |
| 10205 | + if (os_memcmp(cur->buf.p, |
| 10206 | + OID_TOD_TOFU, sizeof(OID_TOD_TOFU)-1) == 0) { |
| 10207 | + ev.peer_cert.tod = 2; /* TOD-TOFU */ |
| 10208 | + break; |
| 10209 | + } |
| 10210 | + } |
| 10211 | + |
| 10212 | + struct tls_conf *tls_conf = conn->tls_conf; |
| 10213 | + if (tls_conf->ca_cert_probe || (tls_conf->flags & TLS_CONN_EXT_CERT_CHECK) |
| 10214 | + || init_conf->cert_in_cb) { |
| 10215 | + certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); |
| 10216 | + ev.peer_cert.cert = certbuf; |
| 10217 | + } |
| 10218 | + |
| 10219 | + init_conf->event_cb(init_conf->cb_ctx, TLS_PEER_CERTIFICATE, &ev); |
| 10220 | + |
| 10221 | + wpabuf_free(certbuf); |
| 10222 | + char **altsubject; |
| 10223 | + *(const char ***)&altsubject = ev.peer_cert.altsubject; |
| 10224 | + for (size_t i = 0; i < ev.peer_cert.num_altsubject; ++i) |
| 10225 | + os_free(altsubject[i]); |
| 10226 | +} |
| 10227 | + |
| 10228 | + |
| 10229 | +static int |
| 10230 | +tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags) |
| 10231 | +{ |
| 10232 | + /* XXX: N.B. verify code not carefully tested besides hwsim tests |
| 10233 | + * |
| 10234 | + * RFE: mbedtls_x509_crt_verify_info() and enhance log trace messages |
| 10235 | + * RFE: review and add support for additional TLS_CONN_* flags |
| 10236 | + * not handling OCSP (not available in mbedtls) |
| 10237 | + * ... */ |
| 10238 | + |
| 10239 | + struct tls_connection *conn = (struct tls_connection *)arg; |
| 10240 | + struct tls_conf *tls_conf = conn->tls_conf; |
| 10241 | + uint32_t flags_in = *flags; |
| 10242 | + |
| 10243 | + if (depth > 8) { /*(depth 8 picked as arbitrary limit)*/ |
| 10244 | + emsg(MSG_WARNING, "client cert chain too long"); |
| 10245 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */ |
| 10246 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10247 | + "client cert chain too long", |
| 10248 | + TLS_FAIL_BAD_CERTIFICATE); |
| 10249 | + } |
| 10250 | + else if (tls_conf->verify_depth0_only) { |
| 10251 | + if (depth > 0) |
| 10252 | + *flags = 0; |
| 10253 | + else { |
| 10254 | + #ifdef MBEDTLS_SHA256_C |
| 10255 | + u8 hash[SHA256_DIGEST_LENGTH]; |
| 10256 | + const u8 *addr[] = { (u8 *)crt->raw.p }; |
| 10257 | + if (sha256_vector(1, addr, &crt->raw.len, hash) < 0 |
| 10258 | + || os_memcmp(tls_conf->ca_cert_hash, hash, sizeof(hash)) != 0) { |
| 10259 | + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; |
| 10260 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10261 | + "cert hash mismatch", |
| 10262 | + TLS_FAIL_UNTRUSTED); |
| 10263 | + } |
| 10264 | + else /* hash matches; ignore other issues *except* if revoked)*/ |
| 10265 | + *flags &= MBEDTLS_X509_BADCERT_REVOKED; |
| 10266 | + #endif |
| 10267 | + } |
| 10268 | + } |
| 10269 | + else if (depth == 0) { |
| 10270 | + if (!conn->peer_subject) |
| 10271 | + tls_mbedtls_set_peer_subject(conn, crt); |
| 10272 | + /*(use same labels to tls_mbedtls_verify_fail_event() as used in |
| 10273 | + * other TLS modules so that hwsim tests find exact string match)*/ |
| 10274 | + if (!conn->peer_subject) { /* error copying subject string */ |
| 10275 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; |
| 10276 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10277 | + "internal error", |
| 10278 | + TLS_FAIL_UNSPECIFIED); |
| 10279 | + } |
| 10280 | + /*(use os_strstr() for subject match as is done in tls_mbedtls.c |
| 10281 | + * to follow the same behavior, even though a suffix match would |
| 10282 | + * make more sense. Also, note that strstr match does not |
| 10283 | + * normalize whitespace (between components) for comparison)*/ |
| 10284 | + else if (tls_conf->subject_match |
| 10285 | + && os_strstr(conn->peer_subject, |
| 10286 | + tls_conf->subject_match) == NULL) { |
| 10287 | + wpa_printf(MSG_WARNING, |
| 10288 | + "MTLS: Subject '%s' did not match with '%s'", |
| 10289 | + conn->peer_subject, tls_conf->subject_match); |
| 10290 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10291 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10292 | + "Subject mismatch", |
| 10293 | + TLS_FAIL_SUBJECT_MISMATCH); |
| 10294 | + } |
| 10295 | + if (tls_conf->altsubject_match |
| 10296 | + && !tls_mbedtls_match_altsubject(crt, tls_conf->altsubject_match)) { |
| 10297 | + wpa_printf(MSG_WARNING, |
| 10298 | + "MTLS: altSubjectName match '%s' not found", |
| 10299 | + tls_conf->altsubject_match); |
| 10300 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10301 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10302 | + "AltSubject mismatch", |
| 10303 | + TLS_FAIL_ALTSUBJECT_MISMATCH); |
| 10304 | + } |
| 10305 | + if (tls_conf->suffix_match |
| 10306 | + && !tls_mbedtls_match_suffixes(crt, tls_conf->suffix_match, 0)) { |
| 10307 | + wpa_printf(MSG_WARNING, |
| 10308 | + "MTLS: Domain suffix match '%s' not found", |
| 10309 | + tls_conf->suffix_match); |
| 10310 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10311 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10312 | + "Domain suffix mismatch", |
| 10313 | + TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); |
| 10314 | + } |
| 10315 | + if (tls_conf->domain_match |
| 10316 | + && !tls_mbedtls_match_suffixes(crt, tls_conf->domain_match, 1)) { |
| 10317 | + wpa_printf(MSG_WARNING, |
| 10318 | + "MTLS: Domain match '%s' not found", |
| 10319 | + tls_conf->domain_match); |
| 10320 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10321 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10322 | + "Domain mismatch", |
| 10323 | + TLS_FAIL_DOMAIN_MISMATCH); |
| 10324 | + } |
| 10325 | + if (tls_conf->check_cert_subject |
| 10326 | + && !tls_mbedtls_match_dn_field(crt, tls_conf->check_cert_subject)) { |
| 10327 | + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
| 10328 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10329 | + "Distinguished Name", |
| 10330 | + TLS_FAIL_DN_MISMATCH); |
| 10331 | + } |
| 10332 | + if (tls_conf->flags & TLS_CONN_SUITEB) { |
| 10333 | + /* check RSA modulus size (public key bitlen) */ |
| 10334 | + const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk); |
| 10335 | + if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) |
| 10336 | + && mbedtls_pk_get_bitlen(&crt->pk) < 3072) { |
| 10337 | + /* hwsim suite_b RSA tests expect 3072 |
| 10338 | + * suite_b_192_rsa_ecdhe_radius_rsa2048_client |
| 10339 | + * suite_b_192_rsa_dhe_radius_rsa2048_client */ |
| 10340 | + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; |
| 10341 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10342 | + "Insufficient RSA modulus size", |
| 10343 | + TLS_FAIL_INSUFFICIENT_KEY_LEN); |
| 10344 | + } |
| 10345 | + } |
| 10346 | + if (tls_conf->check_crl && tls_conf->crl == NULL) { |
| 10347 | + /* see tests/hwsim test_ap_eap.py ap_wpa2_eap_tls_check_crl */ |
| 10348 | + emsg(MSG_WARNING, "check_crl set but no CRL loaded; reject all?"); |
| 10349 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; |
| 10350 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10351 | + "check_crl set but no CRL loaded; " |
| 10352 | + "reject all?", |
| 10353 | + TLS_FAIL_BAD_CERTIFICATE); |
| 10354 | + } |
| 10355 | + } |
| 10356 | + else { |
| 10357 | + if (tls_conf->check_crl != 2) /* 2 == verify CRLs for all certs */ |
| 10358 | + *flags &= ~MBEDTLS_X509_BADCERT_REVOKED; |
| 10359 | + } |
| 10360 | + |
| 10361 | + if (!tls_conf->check_crl_strict) { |
| 10362 | + *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED; |
| 10363 | + *flags &= ~MBEDTLS_X509_BADCRL_FUTURE; |
| 10364 | + } |
| 10365 | + |
| 10366 | + if (tls_conf->flags & TLS_CONN_DISABLE_TIME_CHECKS) { |
| 10367 | + *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED; |
| 10368 | + *flags &= ~MBEDTLS_X509_BADCERT_FUTURE; |
| 10369 | + } |
| 10370 | + |
| 10371 | + tls_mbedtls_verify_cert_event(conn, crt, depth); |
| 10372 | + |
| 10373 | + if (*flags) { |
| 10374 | + if (*flags & (MBEDTLS_X509_BADCERT_NOT_TRUSTED |
| 10375 | + |MBEDTLS_X509_BADCERT_CN_MISMATCH |
| 10376 | + |MBEDTLS_X509_BADCERT_REVOKED)) { |
| 10377 | + emsg(MSG_WARNING, "client cert not trusted"); |
| 10378 | + } |
| 10379 | + /* report event if flags set but no additional flags set above */ |
| 10380 | + /* (could translate flags to more detailed TLS_FAIL_* if needed) */ |
| 10381 | + if (!(*flags & ~flags_in)) { |
| 10382 | + enum tls_fail_reason reason = TLS_FAIL_UNSPECIFIED; |
| 10383 | + const char *errmsg = "cert verify fail unspecified"; |
| 10384 | + if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { |
| 10385 | + reason = TLS_FAIL_UNTRUSTED; |
| 10386 | + errmsg = "certificate not trusted"; |
| 10387 | + } |
| 10388 | + if (*flags & MBEDTLS_X509_BADCERT_REVOKED) { |
| 10389 | + reason = TLS_FAIL_REVOKED; |
| 10390 | + errmsg = "certificate has been revoked"; |
| 10391 | + } |
| 10392 | + if (*flags & MBEDTLS_X509_BADCERT_FUTURE) { |
| 10393 | + reason = TLS_FAIL_NOT_YET_VALID; |
| 10394 | + errmsg = "certificate not yet valid"; |
| 10395 | + } |
| 10396 | + if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) { |
| 10397 | + reason = TLS_FAIL_EXPIRED; |
| 10398 | + errmsg = "certificate has expired"; |
| 10399 | + } |
| 10400 | + if (*flags & MBEDTLS_X509_BADCERT_BAD_MD) { |
| 10401 | + reason = TLS_FAIL_BAD_CERTIFICATE; |
| 10402 | + errmsg = "certificate uses insecure algorithm"; |
| 10403 | + } |
| 10404 | + tls_mbedtls_verify_fail_event(crt, depth, errmsg, reason); |
| 10405 | + } |
| 10406 | + #if 0 |
| 10407 | + /* ??? send (again) cert events for all certs in chain ??? |
| 10408 | + * (should already have been called for greater depths) */ |
| 10409 | + /* tls_openssl.c:tls_verify_cb() sends cert events for all certs |
| 10410 | + * in chain if certificate validation fails, but sends all events |
| 10411 | + * with depth set to 0 (might be a bug) */ |
| 10412 | + if (depth > 0) { |
| 10413 | + int pdepth = depth + 1; |
| 10414 | + for (mbedtls_x509_crt *pcrt; (pcrt = crt->next); ++pdepth) { |
| 10415 | + tls_mbedtls_verify_cert_event(conn, pcrt, pdepth); |
| 10416 | + } |
| 10417 | + } |
| 10418 | + #endif |
| 10419 | + /*(do not preserve subject if verification failed but was optional)*/ |
| 10420 | + if (depth == 0 && conn->peer_subject) { |
| 10421 | + os_free(conn->peer_subject); |
| 10422 | + conn->peer_subject = NULL; |
| 10423 | + } |
| 10424 | + } |
| 10425 | + else if (depth == 0) { |
| 10426 | + struct tls_config *init_conf = &tls_ctx_global.init_conf; |
| 10427 | + if (tls_conf->ca_cert_probe) { |
| 10428 | + /* reject server certificate on probe-only run */ |
| 10429 | + *flags |= MBEDTLS_X509_BADCERT_OTHER; |
| 10430 | + tls_mbedtls_verify_fail_event(crt, depth, |
| 10431 | + "server chain probe", |
| 10432 | + TLS_FAIL_SERVER_CHAIN_PROBE); |
| 10433 | + } |
| 10434 | + else if (init_conf->event_cb) { |
| 10435 | + /* ??? send event as soon as depth == 0 is verified ??? |
| 10436 | + * What about rest of chain? |
| 10437 | + * Follows tls_mbedtls.c behavior: */ |
| 10438 | + init_conf->event_cb(init_conf->cb_ctx, |
| 10439 | + TLS_CERT_CHAIN_SUCCESS, NULL); |
| 10440 | + } |
| 10441 | + } |
| 10442 | + |
| 10443 | + return 0; |
| 10444 | +} |
| 10445 | diff --git a/src/drivers/driver.h b/src/drivers/driver.h |
| 10446 | index e672a1787..3e3e309f4 100644 |
| 10447 | --- a/src/drivers/driver.h |
| 10448 | +++ b/src/drivers/driver.h |
| 10449 | @@ -971,6 +971,9 @@ struct wpa_driver_associate_params { |
| 10450 | * responsible for selecting with which BSS to associate. */ |
| 10451 | const u8 *bssid; |
| 10452 | |
| 10453 | + unsigned char rates[32]; |
| 10454 | + int mcast_rate; |
| 10455 | + |
| 10456 | /** |
| 10457 | * bssid_hint - BSSID of a proposed AP |
| 10458 | * |
| 10459 | @@ -1873,6 +1876,7 @@ struct wpa_driver_mesh_join_params { |
| 10460 | #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 |
| 10461 | unsigned int flags; |
| 10462 | bool handle_dfs; |
| 10463 | + int mcast_rate; |
| 10464 | }; |
| 10465 | |
| 10466 | struct wpa_driver_set_key_params { |
| 10467 | @@ -2340,6 +2344,9 @@ struct wpa_driver_capa { |
| 10468 | /** Maximum number of iterations in a single scan plan */ |
| 10469 | u32 max_sched_scan_plan_iterations; |
| 10470 | |
| 10471 | + /** Maximum number of extra IE bytes for scans */ |
| 10472 | + u16 max_scan_ie_len; |
| 10473 | + |
| 10474 | /** Whether sched_scan (offloaded scanning) is supported */ |
| 10475 | int sched_scan_supported; |
| 10476 | |
| 10477 | @@ -3861,6 +3868,25 @@ struct wpa_driver_ops { |
| 10478 | int (*if_remove)(void *priv, enum wpa_driver_if_type type, |
| 10479 | const char *ifname); |
| 10480 | |
| 10481 | + /** |
| 10482 | + * if_rename - Rename a virtual interface |
| 10483 | + * @priv: Private driver interface data |
| 10484 | + * @type: Interface type |
| 10485 | + * @ifname: Interface name of the virtual interface to be renamed |
| 10486 | + * (NULL when renaming the AP BSS interface) |
| 10487 | + * @new_name: New interface name of the virtual interface |
| 10488 | + * Returns: 0 on success, -1 on failure |
| 10489 | + */ |
| 10490 | + int (*if_rename)(void *priv, enum wpa_driver_if_type type, |
| 10491 | + const char *ifname, const char *new_name); |
| 10492 | + |
| 10493 | + /** |
| 10494 | + * set_first_bss - Make a virtual interface the first (primary) bss |
| 10495 | + * @priv: Private driver interface data |
| 10496 | + * Returns: 0 on success, -1 on failure |
| 10497 | + */ |
| 10498 | + int (*set_first_bss)(void *priv); |
| 10499 | + |
| 10500 | /** |
| 10501 | * set_sta_vlan - Bind a station into a specific interface (AP only) |
| 10502 | * @priv: Private driver interface data |
| 10503 | @@ -4265,7 +4291,7 @@ struct wpa_driver_ops { |
| 10504 | * Returns: 0 on success, negative (<0) on failure |
| 10505 | */ |
| 10506 | int (*br_set_net_param)(void *priv, enum drv_br_net_param param, |
| 10507 | - unsigned int val); |
| 10508 | + const char *ifname, unsigned int val); |
| 10509 | |
| 10510 | /** |
| 10511 | * get_wowlan - Get wake-on-wireless status |
| 10512 | @@ -6559,6 +6585,7 @@ union wpa_event_data { |
| 10513 | |
| 10514 | /** |
| 10515 | * struct ch_switch |
| 10516 | + * @count: Count until channel switch activates |
| 10517 | * @freq: Frequency of new channel in MHz |
| 10518 | * @ht_enabled: Whether this is an HT channel |
| 10519 | * @ch_offset: Secondary channel offset |
| 10520 | @@ -6569,6 +6596,7 @@ union wpa_event_data { |
| 10521 | * @punct_bitmap: Puncturing bitmap |
| 10522 | */ |
| 10523 | struct ch_switch { |
| 10524 | + int count; |
| 10525 | int freq; |
| 10526 | int ht_enabled; |
| 10527 | int ch_offset; |
| 10528 | @@ -6816,8 +6844,8 @@ union wpa_event_data { |
| 10529 | * Driver wrapper code should call this function whenever an event is received |
| 10530 | * from the driver. |
| 10531 | */ |
| 10532 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 10533 | - union wpa_event_data *data); |
| 10534 | +extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, |
| 10535 | + union wpa_event_data *data); |
| 10536 | |
| 10537 | /** |
| 10538 | * wpa_supplicant_event_global - Report a driver event for wpa_supplicant |
| 10539 | @@ -6829,7 +6857,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 10540 | * Same as wpa_supplicant_event(), but we search for the interface in |
| 10541 | * wpa_global. |
| 10542 | */ |
| 10543 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 10544 | +extern void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, |
| 10545 | union wpa_event_data *data); |
| 10546 | |
| 10547 | /* |
| 10548 | diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c |
| 10549 | index 9ac621ae6..6778ad369 100644 |
| 10550 | --- a/src/drivers/driver_nl80211.c |
| 10551 | +++ b/src/drivers/driver_nl80211.c |
| 10552 | @@ -78,6 +78,16 @@ enum nlmsgerr_attrs { |
| 10553 | |
| 10554 | #endif /* ANDROID */ |
| 10555 | |
| 10556 | +static void handle_nl_debug_hook(struct nl_msg *msg, int tx) |
| 10557 | +{ |
| 10558 | + const struct nlmsghdr *nlh; |
| 10559 | + |
| 10560 | + if (!wpa_netlink_hook) |
| 10561 | + return; |
| 10562 | + |
| 10563 | + nlh = nlmsg_hdr(msg); |
| 10564 | + wpa_netlink_hook(tx, nlh, nlh->nlmsg_len); |
| 10565 | +} |
| 10566 | |
| 10567 | static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg) |
| 10568 | { |
| 10569 | @@ -432,6 +442,11 @@ static int no_seq_check(struct nl_msg *msg, void *arg) |
| 10570 | return NL_OK; |
| 10571 | } |
| 10572 | |
| 10573 | +static int debug_handler(struct nl_msg *msg, void *arg) |
| 10574 | +{ |
| 10575 | + handle_nl_debug_hook(msg, 0); |
| 10576 | + return NL_OK; |
| 10577 | +} |
| 10578 | |
| 10579 | static void nl80211_nlmsg_clear(struct nl_msg *msg) |
| 10580 | { |
| 10581 | @@ -505,6 +520,7 @@ int send_and_recv(struct nl80211_global *global, |
| 10582 | if (!msg) |
| 10583 | return -ENOMEM; |
| 10584 | |
| 10585 | + handle_nl_debug_hook(msg, 1); |
| 10586 | err.err = -ENOMEM; |
| 10587 | |
| 10588 | s_nl_cb = nl_socket_get_cb(nl_handle); |
| 10589 | @@ -539,6 +555,7 @@ int send_and_recv(struct nl80211_global *global, |
| 10590 | err.orig_msg = msg; |
| 10591 | err.err_info = err_info; |
| 10592 | |
| 10593 | + nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10594 | nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); |
| 10595 | nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err); |
| 10596 | if (ack_handler_custom) { |
| 10597 | @@ -942,6 +959,7 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss) |
| 10598 | os_free(w); |
| 10599 | return NULL; |
| 10600 | } |
| 10601 | + nl_cb_set(w->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10602 | nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, |
| 10603 | no_seq_check, NULL); |
| 10604 | nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, |
| 10605 | @@ -1356,7 +1374,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, |
| 10606 | } |
| 10607 | wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)", |
| 10608 | namebuf, ifname); |
| 10609 | - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) { |
| 10610 | + if (drv->first_bss->ifindex != ifi->ifi_index) { |
| 10611 | wpa_printf(MSG_DEBUG, |
| 10612 | "nl80211: Not the main interface (%s) - do not indicate interface down", |
| 10613 | drv->first_bss->ifname); |
| 10614 | @@ -1392,7 +1410,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, |
| 10615 | } |
| 10616 | wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)", |
| 10617 | namebuf, ifname); |
| 10618 | - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) { |
| 10619 | + if (drv->first_bss->ifindex != ifi->ifi_index) { |
| 10620 | wpa_printf(MSG_DEBUG, |
| 10621 | "nl80211: Not the main interface (%s) - do not indicate interface up", |
| 10622 | drv->first_bss->ifname); |
| 10623 | @@ -2038,6 +2056,7 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global) |
| 10624 | genl_family_put(family); |
| 10625 | nl_cache_free(cache); |
| 10626 | |
| 10627 | + nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10628 | nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, |
| 10629 | no_seq_check, NULL); |
| 10630 | nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, |
| 10631 | @@ -2208,6 +2227,7 @@ static int nl80211_init_bss(struct i802_bss *bss) |
| 10632 | if (!bss->nl_cb) |
| 10633 | return -1; |
| 10634 | |
| 10635 | + nl_cb_set(bss->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL); |
| 10636 | nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, |
| 10637 | no_seq_check, NULL); |
| 10638 | nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, |
| 10639 | @@ -5485,7 +5505,7 @@ static int nl80211_set_channel(struct i802_bss *bss, |
| 10640 | freq->he_enabled, freq->eht_enabled, freq->bandwidth, |
| 10641 | freq->center_freq1, freq->center_freq2); |
| 10642 | |
| 10643 | - msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL : |
| 10644 | + msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : |
| 10645 | NL80211_CMD_SET_WIPHY); |
| 10646 | if (!msg || nl80211_put_freq_params(msg, freq) < 0) { |
| 10647 | nlmsg_free(msg); |
| 10648 | @@ -5858,26 +5878,29 @@ fail: |
| 10649 | |
| 10650 | static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) |
| 10651 | { |
| 10652 | -#ifdef CONFIG_LIBNL3_ROUTE |
| 10653 | struct wpa_driver_nl80211_data *drv = bss->drv; |
| 10654 | - struct rtnl_neigh *rn; |
| 10655 | - struct nl_addr *nl_addr; |
| 10656 | + struct ndmsg nhdr = { |
| 10657 | + .ndm_state = NUD_PERMANENT, |
| 10658 | + .ndm_ifindex = bss->ifindex, |
| 10659 | + .ndm_family = AF_BRIDGE, |
| 10660 | + }; |
| 10661 | + struct nl_msg *msg; |
| 10662 | int err; |
| 10663 | |
| 10664 | - rn = rtnl_neigh_alloc(); |
| 10665 | - if (!rn) |
| 10666 | + msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); |
| 10667 | + if (!msg) |
| 10668 | return; |
| 10669 | |
| 10670 | - rtnl_neigh_set_family(rn, AF_BRIDGE); |
| 10671 | - rtnl_neigh_set_ifindex(rn, bss->ifindex); |
| 10672 | - nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN); |
| 10673 | - if (!nl_addr) { |
| 10674 | - rtnl_neigh_put(rn); |
| 10675 | - return; |
| 10676 | - } |
| 10677 | - rtnl_neigh_set_lladdr(rn, nl_addr); |
| 10678 | + if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) |
| 10679 | + goto errout; |
| 10680 | |
| 10681 | - err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); |
| 10682 | + if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) |
| 10683 | + goto errout; |
| 10684 | + |
| 10685 | + if (nl_send_auto_complete(drv->rtnl_sk, msg) < 0) |
| 10686 | + goto errout; |
| 10687 | + |
| 10688 | + err = nl_wait_for_ack(drv->rtnl_sk); |
| 10689 | if (err < 0) { |
| 10690 | wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " |
| 10691 | MACSTR " ifindex=%d failed: %s", MAC2STR(addr), |
| 10692 | @@ -5887,9 +5910,8 @@ static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) |
| 10693 | MACSTR, MAC2STR(addr)); |
| 10694 | } |
| 10695 | |
| 10696 | - nl_addr_put(nl_addr); |
| 10697 | - rtnl_neigh_put(rn); |
| 10698 | -#endif /* CONFIG_LIBNL3_ROUTE */ |
| 10699 | +errout: |
| 10700 | + nlmsg_free(msg); |
| 10701 | } |
| 10702 | |
| 10703 | |
| 10704 | @@ -6178,6 +6200,8 @@ static void nl80211_teardown_ap(struct i802_bss *bss) |
| 10705 | nl80211_put_wiphy_data_ap(bss); |
| 10706 | if (bss->flink) |
| 10707 | bss->flink->beacon_set = 0; |
| 10708 | + |
| 10709 | + wpa_driver_nl80211_del_beacon_all(bss); |
| 10710 | } |
| 10711 | |
| 10712 | |
| 10713 | @@ -8566,6 +8590,7 @@ static void *i802_init(struct hostapd_data *hapd, |
| 10714 | char master_ifname[IFNAMSIZ]; |
| 10715 | int ifindex, br_ifindex = 0; |
| 10716 | int br_added = 0; |
| 10717 | + int err; |
| 10718 | |
| 10719 | bss = wpa_driver_nl80211_drv_init(hapd, params->ifname, |
| 10720 | params->global_priv, 1, |
| 10721 | @@ -8625,24 +8650,18 @@ static void *i802_init(struct hostapd_data *hapd, |
| 10722 | (params->num_bridge == 0 || !params->bridge[0])) |
| 10723 | add_ifidx(drv, br_ifindex, drv->ifindex); |
| 10724 | |
| 10725 | -#ifdef CONFIG_LIBNL3_ROUTE |
| 10726 | - if (bss->added_if_into_bridge || bss->already_in_bridge) { |
| 10727 | - int err; |
| 10728 | - |
| 10729 | - drv->rtnl_sk = nl_socket_alloc(); |
| 10730 | - if (drv->rtnl_sk == NULL) { |
| 10731 | - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock"); |
| 10732 | - goto failed; |
| 10733 | - } |
| 10734 | + drv->rtnl_sk = nl_socket_alloc(); |
| 10735 | + if (drv->rtnl_sk == NULL) { |
| 10736 | + wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock"); |
| 10737 | + goto failed; |
| 10738 | + } |
| 10739 | |
| 10740 | - err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE); |
| 10741 | - if (err) { |
| 10742 | - wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s", |
| 10743 | - nl_geterror(err)); |
| 10744 | - goto failed; |
| 10745 | - } |
| 10746 | + err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE); |
| 10747 | + if (err) { |
| 10748 | + wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s", |
| 10749 | + nl_geterror(err)); |
| 10750 | + goto failed; |
| 10751 | } |
| 10752 | -#endif /* CONFIG_LIBNL3_ROUTE */ |
| 10753 | |
| 10754 | if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { |
| 10755 | wpa_printf(MSG_DEBUG, |
| 10756 | @@ -9000,6 +9019,7 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, |
| 10757 | if (drv->first_bss->next) { |
| 10758 | drv->first_bss = drv->first_bss->next; |
| 10759 | drv->ctx = drv->first_bss->ctx; |
| 10760 | + drv->ifindex = drv->first_bss->ifindex; |
| 10761 | os_free(bss); |
| 10762 | } else { |
| 10763 | wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to"); |
| 10764 | @@ -9009,6 +9029,50 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, |
| 10765 | return 0; |
| 10766 | } |
| 10767 | |
| 10768 | +static int wpa_driver_nl80211_if_rename(struct i802_bss *bss, |
| 10769 | + enum wpa_driver_if_type type, |
| 10770 | + const char *ifname, const char *new_name) |
| 10771 | +{ |
| 10772 | + struct wpa_driver_nl80211_data *drv = bss->drv; |
| 10773 | + struct ifinfomsg ifi = { |
| 10774 | + .ifi_family = AF_UNSPEC, |
| 10775 | + .ifi_index = bss->ifindex, |
| 10776 | + }; |
| 10777 | + struct nl_msg *msg; |
| 10778 | + int res = -ENOMEM; |
| 10779 | + |
| 10780 | + if (ifname) |
| 10781 | + ifi.ifi_index = if_nametoindex(ifname); |
| 10782 | + |
| 10783 | + msg = nlmsg_alloc_simple(RTM_SETLINK, 0); |
| 10784 | + if (!msg) |
| 10785 | + return res; |
| 10786 | + |
| 10787 | + if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) |
| 10788 | + goto out; |
| 10789 | + |
| 10790 | + if (nla_put_string(msg, IFLA_IFNAME, new_name)) |
| 10791 | + goto out; |
| 10792 | + |
| 10793 | + res = nl_send_auto_complete(drv->rtnl_sk, msg); |
| 10794 | + if (res < 0) |
| 10795 | + goto out; |
| 10796 | + |
| 10797 | + res = nl_wait_for_ack(drv->rtnl_sk); |
| 10798 | + if (res) { |
| 10799 | + wpa_printf(MSG_INFO, |
| 10800 | + "nl80211: Renaming device %s to %s failed: %s", |
| 10801 | + ifname ? ifname : bss->ifname, new_name, nl_geterror(res)); |
| 10802 | + goto out; |
| 10803 | + } |
| 10804 | + |
| 10805 | + if (type == WPA_IF_AP_BSS && !ifname) |
| 10806 | + os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname)); |
| 10807 | + |
| 10808 | +out: |
| 10809 | + nlmsg_free(msg); |
| 10810 | + return res; |
| 10811 | +} |
| 10812 | |
| 10813 | static int cookie_handler(struct nl_msg *msg, void *arg) |
| 10814 | { |
| 10815 | @@ -10792,6 +10856,37 @@ static bool nl80211_is_drv_shared(void *priv, void *bss_ctx) |
| 10816 | #endif /* CONFIG_IEEE80211BE */ |
| 10817 | |
| 10818 | |
| 10819 | +static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type, |
| 10820 | + const char *ifname, const char *new_name) |
| 10821 | +{ |
| 10822 | + struct i802_bss *bss = priv; |
| 10823 | + return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name); |
| 10824 | +} |
| 10825 | + |
| 10826 | + |
| 10827 | +static int driver_nl80211_set_first_bss(void *priv) |
| 10828 | +{ |
| 10829 | + struct i802_bss *bss = priv, *tbss; |
| 10830 | + struct wpa_driver_nl80211_data *drv = bss->drv; |
| 10831 | + |
| 10832 | + if (drv->first_bss == bss) |
| 10833 | + return 0; |
| 10834 | + |
| 10835 | + for (tbss = drv->first_bss; tbss; tbss = tbss->next) { |
| 10836 | + if (tbss->next != bss) |
| 10837 | + continue; |
| 10838 | + |
| 10839 | + tbss->next = bss->next; |
| 10840 | + bss->next = drv->first_bss; |
| 10841 | + drv->first_bss = bss; |
| 10842 | + drv->ctx = bss->ctx; |
| 10843 | + return 0; |
| 10844 | + } |
| 10845 | + |
| 10846 | + return -1; |
| 10847 | +} |
| 10848 | + |
| 10849 | + |
| 10850 | static int driver_nl80211_send_mlme(void *priv, const u8 *data, |
| 10851 | size_t data_len, int noack, |
| 10852 | unsigned int freq, |
| 10853 | @@ -11294,6 +11389,10 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings) |
| 10854 | if (ret) |
| 10855 | goto error; |
| 10856 | |
| 10857 | + if (drv->nlmode == NL80211_IFTYPE_MESH_POINT) { |
| 10858 | + nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS); |
| 10859 | + } |
| 10860 | + |
| 10861 | /* beacon_csa params */ |
| 10862 | beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES); |
| 10863 | if (!beacon_csa) |
| 10864 | @@ -11940,6 +12039,18 @@ static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id, |
| 10865 | } |
| 10866 | |
| 10867 | |
| 10868 | +static int nl80211_put_mcast_rate(struct nl_msg *msg, int mcast_rate) |
| 10869 | +{ |
| 10870 | + if (mcast_rate > 0) { |
| 10871 | + wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", |
| 10872 | + (double)mcast_rate / 10); |
| 10873 | + return nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, mcast_rate); |
| 10874 | + } |
| 10875 | + |
| 10876 | + return 0; |
| 10877 | +} |
| 10878 | + |
| 10879 | + |
| 10880 | static int nl80211_put_mesh_config(struct nl_msg *msg, |
| 10881 | struct wpa_driver_mesh_bss_params *params) |
| 10882 | { |
| 10883 | @@ -12001,6 +12112,7 @@ static int nl80211_join_mesh(struct i802_bss *bss, |
| 10884 | nl80211_put_basic_rates(msg, params->basic_rates) || |
| 10885 | nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || |
| 10886 | nl80211_put_beacon_int(msg, params->beacon_int) || |
| 10887 | + nl80211_put_mcast_rate(msg, params->mcast_rate) || |
| 10888 | nl80211_put_dtim_period(msg, params->dtim_period)) |
| 10889 | goto fail; |
| 10890 | |
| 10891 | @@ -12156,13 +12268,14 @@ static int wpa_driver_br_add_ip_neigh(void *priv, u8 version, |
| 10892 | const u8 *ipaddr, int prefixlen, |
| 10893 | const u8 *addr) |
| 10894 | { |
| 10895 | -#ifdef CONFIG_LIBNL3_ROUTE |
| 10896 | struct i802_bss *bss = priv; |
| 10897 | struct wpa_driver_nl80211_data *drv = bss->drv; |
| 10898 | - struct rtnl_neigh *rn; |
| 10899 | - struct nl_addr *nl_ipaddr = NULL; |
| 10900 | - struct nl_addr *nl_lladdr = NULL; |
| 10901 | - int family, addrsize; |
| 10902 | + struct ndmsg nhdr = { |
| 10903 | + .ndm_state = NUD_PERMANENT, |
| 10904 | + .ndm_ifindex = bss->br_ifindex, |
| 10905 | + }; |
| 10906 | + struct nl_msg *msg; |
| 10907 | + int addrsize; |
| 10908 | int res; |
| 10909 | |
| 10910 | if (!ipaddr || prefixlen == 0 || !addr) |
| 10911 | @@ -12181,85 +12294,66 @@ static int wpa_driver_br_add_ip_neigh(void *priv, u8 version, |
| 10912 | } |
| 10913 | |
| 10914 | if (version == 4) { |
| 10915 | - family = AF_INET; |
| 10916 | + nhdr.ndm_family = AF_INET; |
| 10917 | addrsize = 4; |
| 10918 | } else if (version == 6) { |
| 10919 | - family = AF_INET6; |
| 10920 | + nhdr.ndm_family = AF_INET6; |
| 10921 | addrsize = 16; |
| 10922 | } else { |
| 10923 | return -EINVAL; |
| 10924 | } |
| 10925 | |
| 10926 | - rn = rtnl_neigh_alloc(); |
| 10927 | - if (rn == NULL) |
| 10928 | + msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE); |
| 10929 | + if (!msg) |
| 10930 | return -ENOMEM; |
| 10931 | |
| 10932 | - /* set the destination ip address for neigh */ |
| 10933 | - nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); |
| 10934 | - if (nl_ipaddr == NULL) { |
| 10935 | - wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); |
| 10936 | - res = -ENOMEM; |
| 10937 | + res = -ENOMEM; |
| 10938 | + if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) |
| 10939 | goto errout; |
| 10940 | - } |
| 10941 | - nl_addr_set_prefixlen(nl_ipaddr, prefixlen); |
| 10942 | - res = rtnl_neigh_set_dst(rn, nl_ipaddr); |
| 10943 | - if (res) { |
| 10944 | - wpa_printf(MSG_DEBUG, |
| 10945 | - "nl80211: neigh set destination addr failed"); |
| 10946 | + |
| 10947 | + if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) |
| 10948 | goto errout; |
| 10949 | - } |
| 10950 | |
| 10951 | - /* set the corresponding lladdr for neigh */ |
| 10952 | - nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN); |
| 10953 | - if (nl_lladdr == NULL) { |
| 10954 | - wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed"); |
| 10955 | - res = -ENOMEM; |
| 10956 | + if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) |
| 10957 | goto errout; |
| 10958 | - } |
| 10959 | - rtnl_neigh_set_lladdr(rn, nl_lladdr); |
| 10960 | |
| 10961 | - rtnl_neigh_set_ifindex(rn, bss->br_ifindex); |
| 10962 | - rtnl_neigh_set_state(rn, NUD_PERMANENT); |
| 10963 | + res = nl_send_auto_complete(drv->rtnl_sk, msg); |
| 10964 | + if (res < 0) |
| 10965 | + goto errout; |
| 10966 | |
| 10967 | - res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE); |
| 10968 | + res = nl_wait_for_ack(drv->rtnl_sk); |
| 10969 | if (res) { |
| 10970 | wpa_printf(MSG_DEBUG, |
| 10971 | "nl80211: Adding bridge ip neigh failed: %s", |
| 10972 | nl_geterror(res)); |
| 10973 | } |
| 10974 | errout: |
| 10975 | - if (nl_lladdr) |
| 10976 | - nl_addr_put(nl_lladdr); |
| 10977 | - if (nl_ipaddr) |
| 10978 | - nl_addr_put(nl_ipaddr); |
| 10979 | - if (rn) |
| 10980 | - rtnl_neigh_put(rn); |
| 10981 | + nlmsg_free(msg); |
| 10982 | return res; |
| 10983 | -#else /* CONFIG_LIBNL3_ROUTE */ |
| 10984 | - return -1; |
| 10985 | -#endif /* CONFIG_LIBNL3_ROUTE */ |
| 10986 | } |
| 10987 | |
| 10988 | |
| 10989 | static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version, |
| 10990 | const u8 *ipaddr) |
| 10991 | { |
| 10992 | -#ifdef CONFIG_LIBNL3_ROUTE |
| 10993 | struct i802_bss *bss = priv; |
| 10994 | struct wpa_driver_nl80211_data *drv = bss->drv; |
| 10995 | - struct rtnl_neigh *rn; |
| 10996 | - struct nl_addr *nl_ipaddr; |
| 10997 | - int family, addrsize; |
| 10998 | + struct ndmsg nhdr = { |
| 10999 | + .ndm_state = NUD_PERMANENT, |
| 11000 | + .ndm_ifindex = bss->br_ifindex, |
| 11001 | + }; |
| 11002 | + struct nl_msg *msg; |
| 11003 | + int addrsize; |
| 11004 | int res; |
| 11005 | |
| 11006 | if (!ipaddr) |
| 11007 | return -EINVAL; |
| 11008 | |
| 11009 | if (version == 4) { |
| 11010 | - family = AF_INET; |
| 11011 | + nhdr.ndm_family = AF_INET; |
| 11012 | addrsize = 4; |
| 11013 | } else if (version == 6) { |
| 11014 | - family = AF_INET6; |
| 11015 | + nhdr.ndm_family = AF_INET6; |
| 11016 | addrsize = 16; |
| 11017 | } else { |
| 11018 | return -EINVAL; |
| 11019 | @@ -12277,41 +12371,30 @@ static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version, |
| 11020 | return -1; |
| 11021 | } |
| 11022 | |
| 11023 | - rn = rtnl_neigh_alloc(); |
| 11024 | - if (rn == NULL) |
| 11025 | + msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); |
| 11026 | + if (!msg) |
| 11027 | return -ENOMEM; |
| 11028 | |
| 11029 | - /* set the destination ip address for neigh */ |
| 11030 | - nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); |
| 11031 | - if (nl_ipaddr == NULL) { |
| 11032 | - wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); |
| 11033 | - res = -ENOMEM; |
| 11034 | + res = -ENOMEM; |
| 11035 | + if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) |
| 11036 | goto errout; |
| 11037 | - } |
| 11038 | - res = rtnl_neigh_set_dst(rn, nl_ipaddr); |
| 11039 | - if (res) { |
| 11040 | - wpa_printf(MSG_DEBUG, |
| 11041 | - "nl80211: neigh set destination addr failed"); |
| 11042 | + |
| 11043 | + if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) |
| 11044 | goto errout; |
| 11045 | - } |
| 11046 | |
| 11047 | - rtnl_neigh_set_ifindex(rn, bss->br_ifindex); |
| 11048 | + res = nl_send_auto_complete(drv->rtnl_sk, msg); |
| 11049 | + if (res < 0) |
| 11050 | + goto errout; |
| 11051 | |
| 11052 | - res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); |
| 11053 | + res = nl_wait_for_ack(drv->rtnl_sk); |
| 11054 | if (res) { |
| 11055 | wpa_printf(MSG_DEBUG, |
| 11056 | "nl80211: Deleting bridge ip neigh failed: %s", |
| 11057 | nl_geterror(res)); |
| 11058 | } |
| 11059 | errout: |
| 11060 | - if (nl_ipaddr) |
| 11061 | - nl_addr_put(nl_ipaddr); |
| 11062 | - if (rn) |
| 11063 | - rtnl_neigh_put(rn); |
| 11064 | + nlmsg_free(msg); |
| 11065 | return res; |
| 11066 | -#else /* CONFIG_LIBNL3_ROUTE */ |
| 11067 | - return -1; |
| 11068 | -#endif /* CONFIG_LIBNL3_ROUTE */ |
| 11069 | } |
| 11070 | |
| 11071 | |
| 11072 | @@ -12389,7 +12472,7 @@ static const char * drv_br_net_param_str(enum drv_br_net_param param) |
| 11073 | |
| 11074 | |
| 11075 | static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, |
| 11076 | - unsigned int val) |
| 11077 | + const char *ifname, unsigned int val) |
| 11078 | { |
| 11079 | struct i802_bss *bss = priv; |
| 11080 | char path[128]; |
| 11081 | @@ -12415,8 +12498,11 @@ static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, |
| 11082 | return -EINVAL; |
| 11083 | } |
| 11084 | |
| 11085 | + if (!ifname) |
| 11086 | + ifname = bss->brname; |
| 11087 | + |
| 11088 | os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s", |
| 11089 | - ip_version, bss->brname, param_txt); |
| 11090 | + ip_version, ifname, param_txt); |
| 11091 | |
| 11092 | set_val: |
| 11093 | if (linux_write_system_file(path, val)) |
| 11094 | @@ -14019,6 +14105,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { |
| 11095 | .set_acl = wpa_driver_nl80211_set_acl, |
| 11096 | .if_add = wpa_driver_nl80211_if_add, |
| 11097 | .if_remove = driver_nl80211_if_remove, |
| 11098 | + .if_rename = driver_nl80211_if_rename, |
| 11099 | + .set_first_bss = driver_nl80211_set_first_bss, |
| 11100 | .send_mlme = driver_nl80211_send_mlme, |
| 11101 | .get_hw_feature_data = nl80211_get_hw_feature_data, |
| 11102 | .sta_add = wpa_driver_nl80211_sta_add, |
| 11103 | diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c |
| 11104 | index 65389d206..d6a887cef 100644 |
| 11105 | --- a/src/drivers/driver_nl80211_capa.c |
| 11106 | +++ b/src/drivers/driver_nl80211_capa.c |
| 11107 | @@ -976,6 +976,10 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg) |
| 11108 | nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]); |
| 11109 | } |
| 11110 | |
| 11111 | + if (tb[NL80211_ATTR_MAX_SCAN_IE_LEN]) |
| 11112 | + capa->max_scan_ie_len = |
| 11113 | + nla_get_u16(tb[NL80211_ATTR_MAX_SCAN_IE_LEN]); |
| 11114 | + |
| 11115 | if (tb[NL80211_ATTR_MAX_MATCH_SETS]) |
| 11116 | capa->max_match_sets = |
| 11117 | nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]); |
| 11118 | diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c |
| 11119 | index f5778cdaf..4a12d749c 100644 |
| 11120 | --- a/src/drivers/driver_nl80211_event.c |
| 11121 | +++ b/src/drivers/driver_nl80211_event.c |
| 11122 | @@ -1196,6 +1196,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, |
| 11123 | struct nlattr *bw, struct nlattr *cf1, |
| 11124 | struct nlattr *cf2, |
| 11125 | struct nlattr *punct_bitmap, |
| 11126 | + struct nlattr *count, |
| 11127 | int finished) |
| 11128 | { |
| 11129 | struct i802_bss *bss; |
| 11130 | @@ -1259,6 +1260,8 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, |
| 11131 | data.ch_switch.cf1 = nla_get_u32(cf1); |
| 11132 | if (cf2) |
| 11133 | data.ch_switch.cf2 = nla_get_u32(cf2); |
| 11134 | + if (count) |
| 11135 | + data.ch_switch.count = nla_get_u32(count); |
| 11136 | |
| 11137 | if (link) |
| 11138 | data.ch_switch.link_id = nla_get_u8(link); |
| 11139 | @@ -3972,6 +3975,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, |
| 11140 | tb[NL80211_ATTR_CENTER_FREQ1], |
| 11141 | tb[NL80211_ATTR_CENTER_FREQ2], |
| 11142 | tb[NL80211_ATTR_PUNCT_BITMAP], |
| 11143 | + tb[NL80211_ATTR_CH_SWITCH_COUNT], |
| 11144 | 0); |
| 11145 | break; |
| 11146 | case NL80211_CMD_CH_SWITCH_NOTIFY: |
| 11147 | @@ -3984,6 +3988,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, |
| 11148 | tb[NL80211_ATTR_CENTER_FREQ1], |
| 11149 | tb[NL80211_ATTR_CENTER_FREQ2], |
| 11150 | tb[NL80211_ATTR_PUNCT_BITMAP], |
| 11151 | + NULL, |
| 11152 | 1); |
| 11153 | break; |
| 11154 | case NL80211_CMD_DISCONNECT: |
| 11155 | diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c |
| 11156 | index 577f84fef..c352a88bc 100644 |
| 11157 | --- a/src/drivers/driver_nl80211_scan.c |
| 11158 | +++ b/src/drivers/driver_nl80211_scan.c |
| 11159 | @@ -221,7 +221,7 @@ nl80211_scan_common(struct i802_bss *bss, u8 cmd, |
| 11160 | wpa_printf(MSG_DEBUG, "nl80211: Passive scan requested"); |
| 11161 | } |
| 11162 | |
| 11163 | - if (params->extra_ies) { |
| 11164 | + if (params->extra_ies && drv->capa.max_scan_ie_len >= params->extra_ies_len) { |
| 11165 | wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs", |
| 11166 | params->extra_ies, params->extra_ies_len); |
| 11167 | if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len, |
| 11168 | diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c |
| 11169 | index e95df6ddb..9071da3cf 100644 |
| 11170 | --- a/src/drivers/drivers.c |
| 11171 | +++ b/src/drivers/drivers.c |
| 11172 | @@ -10,6 +10,10 @@ |
| 11173 | #include "utils/common.h" |
| 11174 | #include "driver.h" |
| 11175 | |
| 11176 | +void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, |
| 11177 | + union wpa_event_data *data); |
| 11178 | +void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, |
| 11179 | + union wpa_event_data *data); |
| 11180 | |
| 11181 | const struct wpa_driver_ops *const wpa_drivers[] = |
| 11182 | { |
| 11183 | diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak |
| 11184 | index a03d4a034..8da44d9f5 100644 |
| 11185 | --- a/src/drivers/drivers.mak |
| 11186 | +++ b/src/drivers/drivers.mak |
| 11187 | @@ -54,7 +54,6 @@ NEED_SME=y |
| 11188 | NEED_AP_MLME=y |
| 11189 | NEED_NETLINK=y |
| 11190 | NEED_LINUX_IOCTL=y |
| 11191 | -NEED_RFKILL=y |
| 11192 | NEED_RADIOTAP=y |
| 11193 | NEED_LIBNL=y |
| 11194 | endif |
| 11195 | @@ -111,7 +110,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT |
| 11196 | CONFIG_WIRELESS_EXTENSION=y |
| 11197 | NEED_NETLINK=y |
| 11198 | NEED_LINUX_IOCTL=y |
| 11199 | -NEED_RFKILL=y |
| 11200 | endif |
| 11201 | |
| 11202 | ifdef CONFIG_DRIVER_NDIS |
| 11203 | @@ -137,7 +135,6 @@ endif |
| 11204 | ifdef CONFIG_WIRELESS_EXTENSION |
| 11205 | DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION |
| 11206 | DRV_WPA_OBJS += ../src/drivers/driver_wext.o |
| 11207 | -NEED_RFKILL=y |
| 11208 | endif |
| 11209 | |
| 11210 | ifdef NEED_NETLINK |
| 11211 | @@ -146,6 +143,7 @@ endif |
| 11212 | |
| 11213 | ifdef NEED_RFKILL |
| 11214 | DRV_OBJS += ../src/drivers/rfkill.o |
| 11215 | +DRV_WPA_CFLAGS += -DCONFIG_RFKILL |
| 11216 | endif |
| 11217 | |
| 11218 | ifdef NEED_RADIOTAP |
| 11219 | diff --git a/src/drivers/rfkill.h b/src/drivers/rfkill.h |
| 11220 | index 0412ac330..e27565375 100644 |
| 11221 | --- a/src/drivers/rfkill.h |
| 11222 | +++ b/src/drivers/rfkill.h |
| 11223 | @@ -18,8 +18,24 @@ struct rfkill_config { |
| 11224 | void (*unblocked_cb)(void *ctx); |
| 11225 | }; |
| 11226 | |
| 11227 | +#ifdef CONFIG_RFKILL |
| 11228 | struct rfkill_data * rfkill_init(struct rfkill_config *cfg); |
| 11229 | void rfkill_deinit(struct rfkill_data *rfkill); |
| 11230 | int rfkill_is_blocked(struct rfkill_data *rfkill); |
| 11231 | +#else |
| 11232 | +static inline struct rfkill_data * rfkill_init(struct rfkill_config *cfg) |
| 11233 | +{ |
| 11234 | + return (void *) 1; |
| 11235 | +} |
| 11236 | + |
| 11237 | +static inline void rfkill_deinit(struct rfkill_data *rfkill) |
| 11238 | +{ |
| 11239 | +} |
| 11240 | + |
| 11241 | +static inline int rfkill_is_blocked(struct rfkill_data *rfkill) |
| 11242 | +{ |
| 11243 | + return 0; |
| 11244 | +} |
| 11245 | +#endif |
| 11246 | |
| 11247 | #endif /* RFKILL_H */ |
| 11248 | diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c |
| 11249 | index 2a7f36170..8e8903051 100644 |
| 11250 | --- a/src/radius/radius_client.c |
| 11251 | +++ b/src/radius/radius_client.c |
| 11252 | @@ -165,6 +165,8 @@ struct radius_client_data { |
| 11253 | */ |
| 11254 | void *ctx; |
| 11255 | |
| 11256 | + struct hostapd_ip_addr local_ip; |
| 11257 | + |
| 11258 | /** |
| 11259 | * conf - RADIUS client configuration (list of RADIUS servers to use) |
| 11260 | */ |
| 11261 | @@ -818,6 +820,30 @@ static void radius_close_acct_socket(struct radius_client_data *radius) |
| 11262 | } |
| 11263 | |
| 11264 | |
| 11265 | +/** |
| 11266 | + * radius_client_send - Get local address for the RADIUS auth socket |
| 11267 | + * @radius: RADIUS client context from radius_client_init() |
| 11268 | + * @addr: pointer to store the address |
| 11269 | + * |
| 11270 | + * This function returns the local address for the connection to the RADIUS |
| 11271 | + * auth server. It also opens the socket if it's not available yet. |
| 11272 | + */ |
| 11273 | +int radius_client_get_local_addr(struct radius_client_data *radius, |
| 11274 | + struct hostapd_ip_addr *addr) |
| 11275 | +{ |
| 11276 | + struct hostapd_radius_servers *conf = radius->conf; |
| 11277 | + |
| 11278 | + if (conf->auth_server && radius->auth_sock < 0) |
| 11279 | + radius_client_init_auth(radius); |
| 11280 | + |
| 11281 | + if (radius->auth_sock < 0) |
| 11282 | + return -1; |
| 11283 | + |
| 11284 | + memcpy(addr, &radius->local_ip, sizeof(*addr)); |
| 11285 | + |
| 11286 | + return 0; |
| 11287 | +} |
| 11288 | + |
| 11289 | /** |
| 11290 | * radius_client_send - Send a RADIUS request |
| 11291 | * @radius: RADIUS client context from radius_client_init() |
| 11292 | @@ -1711,6 +1737,10 @@ radius_change_server(struct radius_client_data *radius, |
| 11293 | wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", |
| 11294 | inet_ntoa(claddr.sin_addr), |
| 11295 | ntohs(claddr.sin_port)); |
| 11296 | + if (auth) { |
| 11297 | + radius->local_ip.af = AF_INET; |
| 11298 | + radius->local_ip.u.v4 = claddr.sin_addr; |
| 11299 | + } |
| 11300 | } |
| 11301 | break; |
| 11302 | #ifdef CONFIG_IPV6 |
| 11303 | @@ -1722,6 +1752,10 @@ radius_change_server(struct radius_client_data *radius, |
| 11304 | inet_ntop(AF_INET6, &claddr6.sin6_addr, |
| 11305 | abuf, sizeof(abuf)), |
| 11306 | ntohs(claddr6.sin6_port)); |
| 11307 | + if (auth) { |
| 11308 | + radius->local_ip.af = AF_INET6; |
| 11309 | + radius->local_ip.u.v6 = claddr6.sin6_addr; |
| 11310 | + } |
| 11311 | } |
| 11312 | break; |
| 11313 | } |
| 11314 | diff --git a/src/radius/radius_client.h b/src/radius/radius_client.h |
| 11315 | index db40637ea..9a89b0382 100644 |
| 11316 | --- a/src/radius/radius_client.h |
| 11317 | +++ b/src/radius/radius_client.h |
| 11318 | @@ -274,6 +274,8 @@ int radius_client_register(struct radius_client_data *radius, |
| 11319 | void radius_client_set_interim_error_cb(struct radius_client_data *radius, |
| 11320 | void (*cb)(const u8 *addr, void *ctx), |
| 11321 | void *ctx); |
| 11322 | +int radius_client_get_local_addr(struct radius_client_data *radius, |
| 11323 | + struct hostapd_ip_addr * addr); |
| 11324 | int radius_client_send(struct radius_client_data *radius, |
| 11325 | struct radius_msg *msg, |
| 11326 | RadiusType msg_type, const u8 *addr); |
| 11327 | diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c |
| 11328 | index aaa3fc267..327782f62 100644 |
| 11329 | --- a/src/radius/radius_das.c |
| 11330 | +++ b/src/radius/radius_das.c |
| 11331 | @@ -12,13 +12,26 @@ |
| 11332 | #include "utils/common.h" |
| 11333 | #include "utils/eloop.h" |
| 11334 | #include "utils/ip_addr.h" |
| 11335 | +#include "utils/list.h" |
| 11336 | #include "radius.h" |
| 11337 | #include "radius_das.h" |
| 11338 | |
| 11339 | |
| 11340 | -struct radius_das_data { |
| 11341 | +static struct dl_list das_ports = DL_LIST_HEAD_INIT(das_ports); |
| 11342 | + |
| 11343 | +struct radius_das_port { |
| 11344 | + struct dl_list list; |
| 11345 | + struct dl_list das_data; |
| 11346 | + |
| 11347 | + int port; |
| 11348 | int sock; |
| 11349 | +}; |
| 11350 | + |
| 11351 | +struct radius_das_data { |
| 11352 | + struct dl_list list; |
| 11353 | + struct radius_das_port *port; |
| 11354 | u8 *shared_secret; |
| 11355 | + u8 *nas_identifier; |
| 11356 | size_t shared_secret_len; |
| 11357 | struct hostapd_ip_addr client_addr; |
| 11358 | unsigned int time_window; |
| 11359 | @@ -378,56 +391,17 @@ fail: |
| 11360 | } |
| 11361 | |
| 11362 | |
| 11363 | -static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) |
| 11364 | +static void |
| 11365 | +radius_das_receive_msg(struct radius_das_data *das, struct radius_msg *msg, |
| 11366 | + struct sockaddr *from, socklen_t fromlen, |
| 11367 | + char *abuf, int from_port) |
| 11368 | { |
| 11369 | - struct radius_das_data *das = eloop_ctx; |
| 11370 | - u8 buf[1500]; |
| 11371 | - union { |
| 11372 | - struct sockaddr_storage ss; |
| 11373 | - struct sockaddr_in sin; |
| 11374 | -#ifdef CONFIG_IPV6 |
| 11375 | - struct sockaddr_in6 sin6; |
| 11376 | -#endif /* CONFIG_IPV6 */ |
| 11377 | - } from; |
| 11378 | - char abuf[50]; |
| 11379 | - int from_port = 0; |
| 11380 | - socklen_t fromlen; |
| 11381 | - int len; |
| 11382 | - struct radius_msg *msg, *reply = NULL; |
| 11383 | + struct radius_msg *reply = NULL; |
| 11384 | struct radius_hdr *hdr; |
| 11385 | struct wpabuf *rbuf; |
| 11386 | + struct os_time now; |
| 11387 | u32 val; |
| 11388 | int res; |
| 11389 | - struct os_time now; |
| 11390 | - |
| 11391 | - fromlen = sizeof(from); |
| 11392 | - len = recvfrom(sock, buf, sizeof(buf), 0, |
| 11393 | - (struct sockaddr *) &from.ss, &fromlen); |
| 11394 | - if (len < 0) { |
| 11395 | - wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); |
| 11396 | - return; |
| 11397 | - } |
| 11398 | - |
| 11399 | - os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); |
| 11400 | - from_port = ntohs(from.sin.sin_port); |
| 11401 | - |
| 11402 | - wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", |
| 11403 | - len, abuf, from_port); |
| 11404 | - if (das->client_addr.u.v4.s_addr && |
| 11405 | - das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) { |
| 11406 | - wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); |
| 11407 | - return; |
| 11408 | - } |
| 11409 | - |
| 11410 | - msg = radius_msg_parse(buf, len); |
| 11411 | - if (msg == NULL) { |
| 11412 | - wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " |
| 11413 | - "from %s:%d failed", abuf, from_port); |
| 11414 | - return; |
| 11415 | - } |
| 11416 | - |
| 11417 | - if (wpa_debug_level <= MSG_MSGDUMP) |
| 11418 | - radius_msg_dump(msg); |
| 11419 | |
| 11420 | if (radius_msg_verify_das_req(msg, das->shared_secret, |
| 11421 | das->shared_secret_len, |
| 11422 | @@ -494,9 +468,8 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) |
| 11423 | radius_msg_dump(reply); |
| 11424 | |
| 11425 | rbuf = radius_msg_get_buf(reply); |
| 11426 | - res = sendto(das->sock, wpabuf_head(rbuf), |
| 11427 | - wpabuf_len(rbuf), 0, |
| 11428 | - (struct sockaddr *) &from.ss, fromlen); |
| 11429 | + res = sendto(das->port->sock, wpabuf_head(rbuf), |
| 11430 | + wpabuf_len(rbuf), 0, from, fromlen); |
| 11431 | if (res < 0) { |
| 11432 | wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", |
| 11433 | abuf, from_port, strerror(errno)); |
| 11434 | @@ -508,6 +481,72 @@ fail: |
| 11435 | radius_msg_free(reply); |
| 11436 | } |
| 11437 | |
| 11438 | +static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) |
| 11439 | +{ |
| 11440 | + struct radius_das_port *p = eloop_ctx; |
| 11441 | + struct radius_das_data *das; |
| 11442 | + u8 buf[1500]; |
| 11443 | + union { |
| 11444 | + struct sockaddr_storage ss; |
| 11445 | + struct sockaddr_in sin; |
| 11446 | +#ifdef CONFIG_IPV6 |
| 11447 | + struct sockaddr_in6 sin6; |
| 11448 | +#endif /* CONFIG_IPV6 */ |
| 11449 | + } from; |
| 11450 | + struct radius_msg *msg; |
| 11451 | + size_t nasid_len = 0; |
| 11452 | + u8 *nasid_buf = NULL; |
| 11453 | + char abuf[50]; |
| 11454 | + int from_port = 0; |
| 11455 | + socklen_t fromlen; |
| 11456 | + int found = 0; |
| 11457 | + int len; |
| 11458 | + |
| 11459 | + fromlen = sizeof(from); |
| 11460 | + len = recvfrom(sock, buf, sizeof(buf), 0, |
| 11461 | + (struct sockaddr *) &from.ss, &fromlen); |
| 11462 | + if (len < 0) { |
| 11463 | + wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); |
| 11464 | + return; |
| 11465 | + } |
| 11466 | + |
| 11467 | + os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); |
| 11468 | + from_port = ntohs(from.sin.sin_port); |
| 11469 | + |
| 11470 | + msg = radius_msg_parse(buf, len); |
| 11471 | + if (msg == NULL) { |
| 11472 | + wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " |
| 11473 | + "from %s:%d failed", abuf, from_port); |
| 11474 | + return; |
| 11475 | + } |
| 11476 | + |
| 11477 | + wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", |
| 11478 | + len, abuf, from_port); |
| 11479 | + |
| 11480 | + if (wpa_debug_level <= MSG_MSGDUMP) |
| 11481 | + radius_msg_dump(msg); |
| 11482 | + |
| 11483 | + radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IDENTIFIER, |
| 11484 | + &nasid_buf, &nasid_len, NULL); |
| 11485 | + dl_list_for_each(das, &p->das_data, struct radius_das_data, list) { |
| 11486 | + if (das->client_addr.u.v4.s_addr && |
| 11487 | + das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) |
| 11488 | + continue; |
| 11489 | + |
| 11490 | + if (das->nas_identifier && nasid_buf && |
| 11491 | + (nasid_len != os_strlen(das->nas_identifier) || |
| 11492 | + os_memcmp(das->nas_identifier, nasid_buf, nasid_len) != 0)) |
| 11493 | + continue; |
| 11494 | + |
| 11495 | + found = 1; |
| 11496 | + radius_das_receive_msg(das, msg, (struct sockaddr *)&from.ss, |
| 11497 | + fromlen, abuf, from_port); |
| 11498 | + } |
| 11499 | + |
| 11500 | + if (!found) |
| 11501 | + wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); |
| 11502 | +} |
| 11503 | + |
| 11504 | |
| 11505 | static int radius_das_open_socket(int port) |
| 11506 | { |
| 11507 | @@ -533,6 +572,49 @@ static int radius_das_open_socket(int port) |
| 11508 | } |
| 11509 | |
| 11510 | |
| 11511 | +static struct radius_das_port * |
| 11512 | +radius_das_open_port(int port) |
| 11513 | +{ |
| 11514 | + struct radius_das_port *p; |
| 11515 | + |
| 11516 | + dl_list_for_each(p, &das_ports, struct radius_das_port, list) { |
| 11517 | + if (p->port == port) |
| 11518 | + return p; |
| 11519 | + } |
| 11520 | + |
| 11521 | + p = os_zalloc(sizeof(*p)); |
| 11522 | + if (p == NULL) |
| 11523 | + return NULL; |
| 11524 | + |
| 11525 | + dl_list_init(&p->das_data); |
| 11526 | + p->port = port; |
| 11527 | + p->sock = radius_das_open_socket(port); |
| 11528 | + if (p->sock < 0) |
| 11529 | + goto free_port; |
| 11530 | + |
| 11531 | + if (eloop_register_read_sock(p->sock, radius_das_receive, p, NULL)) |
| 11532 | + goto close_port; |
| 11533 | + |
| 11534 | + dl_list_add(&das_ports, &p->list); |
| 11535 | + |
| 11536 | + return p; |
| 11537 | + |
| 11538 | +close_port: |
| 11539 | + close(p->sock); |
| 11540 | +free_port: |
| 11541 | + os_free(p); |
| 11542 | + |
| 11543 | + return NULL; |
| 11544 | +} |
| 11545 | + |
| 11546 | +static void radius_das_close_port(struct radius_das_port *p) |
| 11547 | +{ |
| 11548 | + dl_list_del(&p->list); |
| 11549 | + eloop_unregister_read_sock(p->sock); |
| 11550 | + close(p->sock); |
| 11551 | + free(p); |
| 11552 | +} |
| 11553 | + |
| 11554 | struct radius_das_data * |
| 11555 | radius_das_init(struct radius_das_conf *conf) |
| 11556 | { |
| 11557 | @@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf *conf) |
| 11558 | das->ctx = conf->ctx; |
| 11559 | das->disconnect = conf->disconnect; |
| 11560 | das->coa = conf->coa; |
| 11561 | + if (conf->nas_identifier) |
| 11562 | + das->nas_identifier = os_strdup(conf->nas_identifier); |
| 11563 | |
| 11564 | os_memcpy(&das->client_addr, conf->client_addr, |
| 11565 | sizeof(das->client_addr)); |
| 11566 | @@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf *conf) |
| 11567 | } |
| 11568 | das->shared_secret_len = conf->shared_secret_len; |
| 11569 | |
| 11570 | - das->sock = radius_das_open_socket(conf->port); |
| 11571 | - if (das->sock < 0) { |
| 11572 | + das->port = radius_das_open_port(conf->port); |
| 11573 | + if (!das->port) { |
| 11574 | wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS " |
| 11575 | "DAS"); |
| 11576 | radius_das_deinit(das); |
| 11577 | return NULL; |
| 11578 | } |
| 11579 | |
| 11580 | - if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL)) |
| 11581 | - { |
| 11582 | - radius_das_deinit(das); |
| 11583 | - return NULL; |
| 11584 | - } |
| 11585 | + dl_list_add(&das->port->das_data, &das->list); |
| 11586 | |
| 11587 | return das; |
| 11588 | } |
| 11589 | @@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das_data *das) |
| 11590 | if (das == NULL) |
| 11591 | return; |
| 11592 | |
| 11593 | - if (das->sock >= 0) { |
| 11594 | - eloop_unregister_read_sock(das->sock); |
| 11595 | - close(das->sock); |
| 11596 | + if (das->port) { |
| 11597 | + dl_list_del(&das->list); |
| 11598 | + |
| 11599 | + if (dl_list_empty(&das->port->das_data)) |
| 11600 | + radius_das_close_port(das->port); |
| 11601 | } |
| 11602 | |
| 11603 | + os_free(das->nas_identifier); |
| 11604 | os_free(das->shared_secret); |
| 11605 | os_free(das); |
| 11606 | } |
| 11607 | diff --git a/src/radius/radius_das.h b/src/radius/radius_das.h |
| 11608 | index 233d662f6..80dc13fc8 100644 |
| 11609 | --- a/src/radius/radius_das.h |
| 11610 | +++ b/src/radius/radius_das.h |
| 11611 | @@ -44,6 +44,7 @@ struct radius_das_attrs { |
| 11612 | struct radius_das_conf { |
| 11613 | int port; |
| 11614 | const u8 *shared_secret; |
| 11615 | + const u8 *nas_identifier; |
| 11616 | size_t shared_secret_len; |
| 11617 | const struct hostapd_ip_addr *client_addr; |
| 11618 | unsigned int time_window; |
| 11619 | diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c |
| 11620 | index e02c21540..57a47263e 100644 |
| 11621 | --- a/src/radius/radius_server.c |
| 11622 | +++ b/src/radius/radius_server.c |
| 11623 | @@ -63,6 +63,12 @@ struct radius_server_counters { |
| 11624 | u32 unknown_acct_types; |
| 11625 | }; |
| 11626 | |
| 11627 | +struct radius_accept_attr { |
| 11628 | + u8 type; |
| 11629 | + u16 len; |
| 11630 | + void *data; |
| 11631 | +}; |
| 11632 | + |
| 11633 | /** |
| 11634 | * struct radius_session - Internal RADIUS server data for a session |
| 11635 | */ |
| 11636 | @@ -90,7 +96,7 @@ struct radius_session { |
| 11637 | unsigned int macacl:1; |
| 11638 | unsigned int t_c_filtering:1; |
| 11639 | |
| 11640 | - struct hostapd_radius_attr *accept_attr; |
| 11641 | + struct radius_accept_attr *accept_attr; |
| 11642 | |
| 11643 | u32 t_c_timestamp; /* Last read T&C timestamp from user DB */ |
| 11644 | }; |
| 11645 | @@ -394,6 +400,7 @@ static void radius_server_session_free(struct radius_server_data *data, |
| 11646 | radius_msg_free(sess->last_reply); |
| 11647 | os_free(sess->username); |
| 11648 | os_free(sess->nas_ip); |
| 11649 | + os_free(sess->accept_attr); |
| 11650 | os_free(sess); |
| 11651 | data->num_sess--; |
| 11652 | } |
| 11653 | @@ -554,6 +561,36 @@ radius_server_erp_find_key(struct radius_server_data *data, const char *keyname) |
| 11654 | } |
| 11655 | #endif /* CONFIG_ERP */ |
| 11656 | |
| 11657 | +static struct radius_accept_attr * |
| 11658 | +radius_server_copy_attr(const struct hostapd_radius_attr *data) |
| 11659 | +{ |
| 11660 | + const struct hostapd_radius_attr *attr; |
| 11661 | + struct radius_accept_attr *attr_new; |
| 11662 | + size_t data_size = 0; |
| 11663 | + void *data_buf; |
| 11664 | + int n_attr = 1; |
| 11665 | + |
| 11666 | + for (attr = data; attr; attr = attr->next) { |
| 11667 | + n_attr++; |
| 11668 | + data_size += wpabuf_len(attr->val); |
| 11669 | + } |
| 11670 | + |
| 11671 | + attr_new = os_zalloc(n_attr * sizeof(*attr) + data_size); |
| 11672 | + if (!attr_new) |
| 11673 | + return NULL; |
| 11674 | + |
| 11675 | + data_buf = &attr_new[n_attr]; |
| 11676 | + for (n_attr = 0, attr = data; attr; attr = attr->next) { |
| 11677 | + struct radius_accept_attr *cur = &attr_new[n_attr++]; |
| 11678 | + |
| 11679 | + cur->type = attr->type; |
| 11680 | + cur->len = wpabuf_len(attr->val); |
| 11681 | + cur->data = memcpy(data_buf, wpabuf_head(attr->val), cur->len); |
| 11682 | + data_buf += cur->len; |
| 11683 | + } |
| 11684 | + |
| 11685 | + return attr_new; |
| 11686 | +} |
| 11687 | |
| 11688 | static struct radius_session * |
| 11689 | radius_server_get_new_session(struct radius_server_data *data, |
| 11690 | @@ -607,7 +644,7 @@ radius_server_get_new_session(struct radius_server_data *data, |
| 11691 | eap_user_free(tmp); |
| 11692 | return NULL; |
| 11693 | } |
| 11694 | - sess->accept_attr = tmp->accept_attr; |
| 11695 | + sess->accept_attr = radius_server_copy_attr(tmp->accept_attr); |
| 11696 | sess->macacl = tmp->macacl; |
| 11697 | eap_user_free(tmp); |
| 11698 | |
| 11699 | @@ -1118,11 +1155,10 @@ radius_server_encapsulate_eap(struct radius_server_data *data, |
| 11700 | } |
| 11701 | |
| 11702 | if (code == RADIUS_CODE_ACCESS_ACCEPT) { |
| 11703 | - struct hostapd_radius_attr *attr; |
| 11704 | - for (attr = sess->accept_attr; attr; attr = attr->next) { |
| 11705 | - if (!radius_msg_add_attr(msg, attr->type, |
| 11706 | - wpabuf_head(attr->val), |
| 11707 | - wpabuf_len(attr->val))) { |
| 11708 | + struct radius_accept_attr *attr; |
| 11709 | + for (attr = sess->accept_attr; attr->data; attr++) { |
| 11710 | + if (!radius_msg_add_attr(msg, attr->type, attr->data, |
| 11711 | + attr->len)) { |
| 11712 | wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); |
| 11713 | radius_msg_free(msg); |
| 11714 | return NULL; |
| 11715 | @@ -1211,11 +1247,10 @@ radius_server_macacl(struct radius_server_data *data, |
| 11716 | } |
| 11717 | |
| 11718 | if (code == RADIUS_CODE_ACCESS_ACCEPT) { |
| 11719 | - struct hostapd_radius_attr *attr; |
| 11720 | - for (attr = sess->accept_attr; attr; attr = attr->next) { |
| 11721 | - if (!radius_msg_add_attr(msg, attr->type, |
| 11722 | - wpabuf_head(attr->val), |
| 11723 | - wpabuf_len(attr->val))) { |
| 11724 | + struct radius_accept_attr *attr; |
| 11725 | + for (attr = sess->accept_attr; attr->data; attr++) { |
| 11726 | + if (!radius_msg_add_attr(msg, attr->type, attr->data, |
| 11727 | + attr->len)) { |
| 11728 | wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); |
| 11729 | radius_msg_free(msg); |
| 11730 | return NULL; |
| 11731 | @@ -2512,7 +2547,7 @@ static int radius_server_get_eap_user(void *ctx, const u8 *identity, |
| 11732 | ret = data->get_eap_user(data->conf_ctx, identity, identity_len, |
| 11733 | phase2, user); |
| 11734 | if (ret == 0 && user) { |
| 11735 | - sess->accept_attr = user->accept_attr; |
| 11736 | + sess->accept_attr = radius_server_copy_attr(user->accept_attr); |
| 11737 | sess->remediation = user->remediation; |
| 11738 | sess->macacl = user->macacl; |
| 11739 | sess->t_c_timestamp = user->t_c_timestamp; |
| 11740 | diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c |
| 11741 | index 8956c4072..e669858d8 100644 |
| 11742 | --- a/src/rsn_supp/wpa.c |
| 11743 | +++ b/src/rsn_supp/wpa.c |
| 11744 | @@ -3943,6 +3943,8 @@ static u32 wpa_key_mgmt_suite(struct wpa_sm *sm) |
| 11745 | } |
| 11746 | |
| 11747 | |
| 11748 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 11749 | + |
| 11750 | #define RSN_SUITE "%02x-%02x-%02x-%d" |
| 11751 | #define RSN_SUITE_ARG(s) \ |
| 11752 | ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff |
| 11753 | @@ -4024,6 +4026,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen) |
| 11754 | |
| 11755 | return (int) len; |
| 11756 | } |
| 11757 | +#endif |
| 11758 | #endif /* CONFIG_CTRL_IFACE */ |
| 11759 | |
| 11760 | |
| 11761 | diff --git a/src/tls/Makefile b/src/tls/Makefile |
| 11762 | index c84fbe859..e974a41f0 100644 |
| 11763 | --- a/src/tls/Makefile |
| 11764 | +++ b/src/tls/Makefile |
| 11765 | @@ -1,3 +1,10 @@ |
| 11766 | +LIB_OBJS= asn1.o |
| 11767 | + |
| 11768 | +ifneq ($(CONFIG_TLS),gnutls) |
| 11769 | +ifneq ($(CONFIG_TLS),mbedtls) |
| 11770 | +ifneq ($(CONFIG_TLS),openssl) |
| 11771 | +ifneq ($(CONFIG_TLS),wolfssl) |
| 11772 | + |
| 11773 | CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH |
| 11774 | CFLAGS += -DCONFIG_CRYPTO_INTERNAL |
| 11775 | CFLAGS += -DCONFIG_TLSV11 |
| 11776 | @@ -21,5 +28,9 @@ LIB_OBJS= \ |
| 11777 | tlsv1_server_read.o \ |
| 11778 | tlsv1_server_write.o \ |
| 11779 | x509v3.o |
| 11780 | +endif |
| 11781 | +endif |
| 11782 | +endif |
| 11783 | +endif |
| 11784 | |
| 11785 | include ../lib.rules |
| 11786 | diff --git a/src/utils/eloop.c b/src/utils/eloop.c |
| 11787 | index 00b0beff0..50dd1beda 100644 |
| 11788 | --- a/src/utils/eloop.c |
| 11789 | +++ b/src/utils/eloop.c |
| 11790 | @@ -77,6 +77,9 @@ struct eloop_sock_table { |
| 11791 | struct eloop_data { |
| 11792 | int max_sock; |
| 11793 | |
| 11794 | + eloop_timeout_poll_handler timeout_poll_cb; |
| 11795 | + eloop_poll_handler poll_cb; |
| 11796 | + |
| 11797 | size_t count; /* sum of all table counts */ |
| 11798 | #ifdef CONFIG_ELOOP_POLL |
| 11799 | size_t max_pollfd_map; /* number of pollfds_map currently allocated */ |
| 11800 | @@ -1121,6 +1124,12 @@ void eloop_run(void) |
| 11801 | os_reltime_sub(&timeout->time, &now, &tv); |
| 11802 | else |
| 11803 | tv.sec = tv.usec = 0; |
| 11804 | + } |
| 11805 | + |
| 11806 | + if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout)) |
| 11807 | + timeout = (void *)1; |
| 11808 | + |
| 11809 | + if (timeout) { |
| 11810 | #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) |
| 11811 | timeout_ms = tv.sec * 1000 + tv.usec / 1000; |
| 11812 | #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ |
| 11813 | @@ -1190,7 +1199,8 @@ void eloop_run(void) |
| 11814 | eloop.exceptions.changed = 0; |
| 11815 | |
| 11816 | eloop_process_pending_signals(); |
| 11817 | - |
| 11818 | + if (eloop.poll_cb) |
| 11819 | + eloop.poll_cb(); |
| 11820 | |
| 11821 | /* check if some registered timeouts have occurred */ |
| 11822 | timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, |
| 11823 | @@ -1252,6 +1262,14 @@ out: |
| 11824 | return; |
| 11825 | } |
| 11826 | |
| 11827 | +int eloop_register_cb(eloop_poll_handler poll_cb, |
| 11828 | + eloop_timeout_poll_handler timeout_cb) |
| 11829 | +{ |
| 11830 | + eloop.poll_cb = poll_cb; |
| 11831 | + eloop.timeout_poll_cb = timeout_cb; |
| 11832 | + |
| 11833 | + return 0; |
| 11834 | +} |
| 11835 | |
| 11836 | void eloop_terminate(void) |
| 11837 | { |
| 11838 | diff --git a/src/utils/eloop.h b/src/utils/eloop.h |
| 11839 | index 04ee6d183..5452ea589 100644 |
| 11840 | --- a/src/utils/eloop.h |
| 11841 | +++ b/src/utils/eloop.h |
| 11842 | @@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(void *eloop_ctx, void *user_ctx); |
| 11843 | */ |
| 11844 | typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); |
| 11845 | |
| 11846 | +typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set); |
| 11847 | +typedef void (*eloop_poll_handler)(void); |
| 11848 | + |
| 11849 | /** |
| 11850 | * eloop_init() - Initialize global event loop data |
| 11851 | * Returns: 0 on success, -1 on failure |
| 11852 | @@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); |
| 11853 | */ |
| 11854 | int eloop_init(void); |
| 11855 | |
| 11856 | +int eloop_register_cb(eloop_poll_handler poll_cb, |
| 11857 | + eloop_timeout_poll_handler timeout_cb); |
| 11858 | + |
| 11859 | /** |
| 11860 | * eloop_register_read_sock - Register handler for read events |
| 11861 | * @sock: File descriptor number for the socket |
| 11862 | @@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop_signal_handler handler, |
| 11863 | */ |
| 11864 | int eloop_sock_requeue(void); |
| 11865 | |
| 11866 | +void eloop_add_uloop(void); |
| 11867 | + |
| 11868 | /** |
| 11869 | * eloop_run - Start the event loop |
| 11870 | * |
| 11871 | diff --git a/src/utils/uloop.c b/src/utils/uloop.c |
| 11872 | new file mode 100644 |
| 11873 | index 000000000..c0d26db93 |
| 11874 | --- /dev/null |
| 11875 | +++ b/src/utils/uloop.c |
| 11876 | @@ -0,0 +1,64 @@ |
| 11877 | +#include <libubox/uloop.h> |
| 11878 | +#include "includes.h" |
| 11879 | +#include "common.h" |
| 11880 | +#include "eloop.h" |
| 11881 | + |
| 11882 | +static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx) |
| 11883 | +{ |
| 11884 | +} |
| 11885 | + |
| 11886 | +static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events) |
| 11887 | +{ |
| 11888 | + unsigned int changed = events ^ fd->flags; |
| 11889 | + |
| 11890 | + if (changed & ULOOP_READ) { |
| 11891 | + if (events & ULOOP_READ) |
| 11892 | + eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd); |
| 11893 | + else |
| 11894 | + eloop_unregister_sock(fd->fd, EVENT_TYPE_READ); |
| 11895 | + } |
| 11896 | + |
| 11897 | + if (changed & ULOOP_WRITE) { |
| 11898 | + if (events & ULOOP_WRITE) |
| 11899 | + eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd); |
| 11900 | + else |
| 11901 | + eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE); |
| 11902 | + } |
| 11903 | +} |
| 11904 | + |
| 11905 | +static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set) |
| 11906 | +{ |
| 11907 | + struct os_reltime tv_uloop; |
| 11908 | + int timeout_ms = uloop_get_next_timeout(); |
| 11909 | + |
| 11910 | + if (timeout_ms < 0) |
| 11911 | + return false; |
| 11912 | + |
| 11913 | + tv_uloop.sec = timeout_ms / 1000; |
| 11914 | + tv_uloop.usec = (timeout_ms % 1000) * 1000; |
| 11915 | + |
| 11916 | + if (!tv_set || os_reltime_before(&tv_uloop, tv)) { |
| 11917 | + *tv = tv_uloop; |
| 11918 | + return true; |
| 11919 | + } |
| 11920 | + |
| 11921 | + return false; |
| 11922 | +} |
| 11923 | + |
| 11924 | +static void uloop_poll_handler(void) |
| 11925 | +{ |
| 11926 | + uloop_run_timeout(0); |
| 11927 | +} |
| 11928 | + |
| 11929 | +void eloop_add_uloop(void) |
| 11930 | +{ |
| 11931 | + static bool init_done = false; |
| 11932 | + |
| 11933 | + if (!init_done) { |
| 11934 | + uloop_init(); |
| 11935 | + uloop_fd_set_cb = eloop_uloop_fd_cb; |
| 11936 | + init_done = true; |
| 11937 | + } |
| 11938 | + |
| 11939 | + eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); |
| 11940 | +} |
| 11941 | diff --git a/src/utils/wpa_debug.c b/src/utils/wpa_debug.c |
| 11942 | index 7f3dd185f..627575e39 100644 |
| 11943 | --- a/src/utils/wpa_debug.c |
| 11944 | +++ b/src/utils/wpa_debug.c |
| 11945 | @@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NULL; |
| 11946 | #define WPAS_TRACE_PFX "wpas <%d>: " |
| 11947 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ |
| 11948 | |
| 11949 | +void (*wpa_printf_hook)(int level, const char *fmt, va_list ap); |
| 11950 | +void (*wpa_hexdump_hook)(int level, const char *title, const void *buf, |
| 11951 | + size_t len); |
| 11952 | +void (*wpa_netlink_hook)(int tx, const void *data, size_t len); |
| 11953 | |
| 11954 | int wpa_debug_level = MSG_INFO; |
| 11955 | int wpa_debug_show_keys = 0; |
| 11956 | @@ -206,10 +210,16 @@ void wpa_debug_close_linux_tracing(void) |
| 11957 | * |
| 11958 | * Note: New line '\n' is added to the end of the text when printing to stdout. |
| 11959 | */ |
| 11960 | -void wpa_printf(int level, const char *fmt, ...) |
| 11961 | +void _wpa_printf(int level, const char *fmt, ...) |
| 11962 | { |
| 11963 | va_list ap; |
| 11964 | |
| 11965 | + if (wpa_printf_hook) { |
| 11966 | + va_start(ap, fmt); |
| 11967 | + wpa_printf_hook(level, fmt, ap); |
| 11968 | + va_end(ap); |
| 11969 | + } |
| 11970 | + |
| 11971 | if (level >= wpa_debug_level) { |
| 11972 | #ifdef CONFIG_ANDROID_LOG |
| 11973 | va_start(ap, fmt); |
| 11974 | @@ -255,11 +265,14 @@ void wpa_printf(int level, const char *fmt, ...) |
| 11975 | } |
| 11976 | |
| 11977 | |
| 11978 | -static void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 11979 | +void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 11980 | size_t len, int show, int only_syslog) |
| 11981 | { |
| 11982 | size_t i; |
| 11983 | |
| 11984 | + if (wpa_hexdump_hook) |
| 11985 | + wpa_hexdump_hook(level, title, buf, len); |
| 11986 | + |
| 11987 | #ifdef CONFIG_DEBUG_LINUX_TRACING |
| 11988 | if (wpa_debug_tracing_file != NULL) { |
| 11989 | fprintf(wpa_debug_tracing_file, |
| 11990 | @@ -382,19 +395,7 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 11991 | #endif /* CONFIG_ANDROID_LOG */ |
| 11992 | } |
| 11993 | |
| 11994 | -void wpa_hexdump(int level, const char *title, const void *buf, size_t len) |
| 11995 | -{ |
| 11996 | - _wpa_hexdump(level, title, buf, len, 1, 0); |
| 11997 | -} |
| 11998 | - |
| 11999 | - |
| 12000 | -void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) |
| 12001 | -{ |
| 12002 | - _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0); |
| 12003 | -} |
| 12004 | - |
| 12005 | - |
| 12006 | -static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12007 | +void _wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12008 | size_t len, int show) |
| 12009 | { |
| 12010 | size_t i, llen; |
| 12011 | @@ -507,20 +508,6 @@ file_done: |
| 12012 | } |
| 12013 | |
| 12014 | |
| 12015 | -void wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12016 | - size_t len) |
| 12017 | -{ |
| 12018 | - _wpa_hexdump_ascii(level, title, buf, len, 1); |
| 12019 | -} |
| 12020 | - |
| 12021 | - |
| 12022 | -void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, |
| 12023 | - size_t len) |
| 12024 | -{ |
| 12025 | - _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); |
| 12026 | -} |
| 12027 | - |
| 12028 | - |
| 12029 | #ifdef CONFIG_DEBUG_FILE |
| 12030 | static char *last_path = NULL; |
| 12031 | #endif /* CONFIG_DEBUG_FILE */ |
| 12032 | @@ -644,7 +631,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) |
| 12033 | } |
| 12034 | |
| 12035 | |
| 12036 | -void wpa_msg(void *ctx, int level, const char *fmt, ...) |
| 12037 | +void _wpa_msg(void *ctx, int level, const char *fmt, ...) |
| 12038 | { |
| 12039 | va_list ap; |
| 12040 | char *buf; |
| 12041 | @@ -682,7 +669,7 @@ void wpa_msg(void *ctx, int level, const char *fmt, ...) |
| 12042 | } |
| 12043 | |
| 12044 | |
| 12045 | -void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12046 | +void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12047 | { |
| 12048 | va_list ap; |
| 12049 | char *buf; |
| 12050 | diff --git a/src/utils/wpa_debug.h b/src/utils/wpa_debug.h |
| 12051 | index 4c02ad3c7..854520bfe 100644 |
| 12052 | --- a/src/utils/wpa_debug.h |
| 12053 | +++ b/src/utils/wpa_debug.h |
| 12054 | @@ -11,6 +11,10 @@ |
| 12055 | |
| 12056 | #include "wpabuf.h" |
| 12057 | |
| 12058 | +extern void (*wpa_printf_hook)(int level, const char *fmt, va_list ap); |
| 12059 | +extern void (*wpa_hexdump_hook)(int level, const char *title, |
| 12060 | + const void *buf, size_t len); |
| 12061 | +extern void (*wpa_netlink_hook)(int tx, const void *data, size_t len); |
| 12062 | extern int wpa_debug_level; |
| 12063 | extern int wpa_debug_show_keys; |
| 12064 | extern int wpa_debug_timestamp; |
| 12065 | @@ -51,6 +55,17 @@ void wpa_debug_close_file(void); |
| 12066 | void wpa_debug_setup_stdout(void); |
| 12067 | void wpa_debug_stop_log(void); |
| 12068 | |
| 12069 | +/* internal */ |
| 12070 | +void _wpa_hexdump(int level, const char *title, const u8 *buf, |
| 12071 | + size_t len, int show, int only_syslog); |
| 12072 | +void _wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12073 | + size_t len, int show); |
| 12074 | +extern int wpa_debug_show_keys; |
| 12075 | + |
| 12076 | +#ifndef CONFIG_MSG_MIN_PRIORITY |
| 12077 | +#define CONFIG_MSG_MIN_PRIORITY 0 |
| 12078 | +#endif |
| 12079 | + |
| 12080 | /** |
| 12081 | * wpa_debug_printf_timestamp - Print timestamp for debug output |
| 12082 | * |
| 12083 | @@ -71,9 +86,15 @@ void wpa_debug_print_timestamp(void); |
| 12084 | * |
| 12085 | * Note: New line '\n' is added to the end of the text when printing to stdout. |
| 12086 | */ |
| 12087 | -void wpa_printf(int level, const char *fmt, ...) |
| 12088 | +void _wpa_printf(int level, const char *fmt, ...) |
| 12089 | PRINTF_FORMAT(2, 3); |
| 12090 | |
| 12091 | +#define wpa_printf(level, ...) \ |
| 12092 | + do { \ |
| 12093 | + if (level >= CONFIG_MSG_MIN_PRIORITY) \ |
| 12094 | + _wpa_printf(level, __VA_ARGS__); \ |
| 12095 | + } while(0) |
| 12096 | + |
| 12097 | /** |
| 12098 | * wpa_hexdump - conditional hex dump |
| 12099 | * @level: priority level (MSG_*) of the message |
| 12100 | @@ -85,7 +106,13 @@ PRINTF_FORMAT(2, 3); |
| 12101 | * output may be directed to stdout, stderr, and/or syslog based on |
| 12102 | * configuration. The contents of buf is printed out has hex dump. |
| 12103 | */ |
| 12104 | -void wpa_hexdump(int level, const char *title, const void *buf, size_t len); |
| 12105 | +static inline void wpa_hexdump(int level, const char *title, const void *buf, size_t len) |
| 12106 | +{ |
| 12107 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12108 | + return; |
| 12109 | + |
| 12110 | + _wpa_hexdump(level, title, buf, len, 1, 1); |
| 12111 | +} |
| 12112 | |
| 12113 | static inline void wpa_hexdump_buf(int level, const char *title, |
| 12114 | const struct wpabuf *buf) |
| 12115 | @@ -107,7 +134,13 @@ static inline void wpa_hexdump_buf(int level, const char *title, |
| 12116 | * like wpa_hexdump(), but by default, does not include secret keys (passwords, |
| 12117 | * etc.) in debug output. |
| 12118 | */ |
| 12119 | -void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); |
| 12120 | +static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) |
| 12121 | +{ |
| 12122 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12123 | + return; |
| 12124 | + |
| 12125 | + _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 1); |
| 12126 | +} |
| 12127 | |
| 12128 | static inline void wpa_hexdump_buf_key(int level, const char *title, |
| 12129 | const struct wpabuf *buf) |
| 12130 | @@ -129,8 +162,14 @@ static inline void wpa_hexdump_buf_key(int level, const char *title, |
| 12131 | * the hex numbers and ASCII characters (for printable range) are shown. 16 |
| 12132 | * bytes per line will be shown. |
| 12133 | */ |
| 12134 | -void wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12135 | - size_t len); |
| 12136 | +static inline void wpa_hexdump_ascii(int level, const char *title, |
| 12137 | + const u8 *buf, size_t len) |
| 12138 | +{ |
| 12139 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12140 | + return; |
| 12141 | + |
| 12142 | + _wpa_hexdump_ascii(level, title, buf, len, 1); |
| 12143 | +} |
| 12144 | |
| 12145 | /** |
| 12146 | * wpa_hexdump_ascii_key - conditional hex dump, hide keys |
| 12147 | @@ -146,8 +185,14 @@ void wpa_hexdump_ascii(int level, const char *title, const void *buf, |
| 12148 | * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by |
| 12149 | * default, does not include secret keys (passwords, etc.) in debug output. |
| 12150 | */ |
| 12151 | -void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, |
| 12152 | - size_t len); |
| 12153 | +static inline void wpa_hexdump_ascii_key(int level, const char *title, |
| 12154 | + const u8 *buf, size_t len) |
| 12155 | +{ |
| 12156 | + if (level < CONFIG_MSG_MIN_PRIORITY) |
| 12157 | + return; |
| 12158 | + |
| 12159 | + _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); |
| 12160 | +} |
| 12161 | |
| 12162 | /* |
| 12163 | * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce |
| 12164 | @@ -184,7 +229,12 @@ void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, |
| 12165 | * |
| 12166 | * Note: New line '\n' is added to the end of the text when printing to stdout. |
| 12167 | */ |
| 12168 | -void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); |
| 12169 | +void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); |
| 12170 | +#define wpa_msg(ctx, level, ...) \ |
| 12171 | + do { \ |
| 12172 | + if (level >= CONFIG_MSG_MIN_PRIORITY) \ |
| 12173 | + _wpa_msg(ctx, level, __VA_ARGS__); \ |
| 12174 | + } while(0) |
| 12175 | |
| 12176 | /** |
| 12177 | * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors |
| 12178 | @@ -198,8 +248,13 @@ void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); |
| 12179 | * attached ctrl_iface monitors. In other words, it can be used for frequent |
| 12180 | * events that do not need to be sent to syslog. |
| 12181 | */ |
| 12182 | -void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12183 | +void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
| 12184 | PRINTF_FORMAT(3, 4); |
| 12185 | +#define wpa_msg_ctrl(ctx, level, ...) \ |
| 12186 | + do { \ |
| 12187 | + if (level >= CONFIG_MSG_MIN_PRIORITY) \ |
| 12188 | + _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \ |
| 12189 | + } while(0) |
| 12190 | |
| 12191 | /** |
| 12192 | * wpa_msg_global - Global printf for ctrl_iface monitors |
| 12193 | diff --git a/tests/Makefile b/tests/Makefile |
| 12194 | index 8ec154bb3..58287f56f 100644 |
| 12195 | --- a/tests/Makefile |
| 12196 | +++ b/tests/Makefile |
| 12197 | @@ -5,6 +5,14 @@ ALL=test-base64 test-md4 test-milenage \ |
| 12198 | test-sha256 test-aes test-x509v3 test-list test-rc4 \ |
| 12199 | test-bss |
| 12200 | |
| 12201 | +RUN_TESTS= \ |
| 12202 | + test-list \ |
| 12203 | + test-md4 test-rc4 test-sha1 test-sha256 \ |
| 12204 | + test-milenage test-aes \ |
| 12205 | + test-crypto_module |
| 12206 | + |
| 12207 | +ALL=$(RUN_TESTS) test-base64 test-https test-https_server |
| 12208 | + |
| 12209 | include ../src/build.rules |
| 12210 | |
| 12211 | ifdef LIBFUZZER |
| 12212 | @@ -25,13 +33,27 @@ CFLAGS += -DCONFIG_IEEE80211R_AP |
| 12213 | CFLAGS += -DCONFIG_IEEE80211R |
| 12214 | CFLAGS += -DCONFIG_TDLS |
| 12215 | |
| 12216 | +# test-crypto_module |
| 12217 | +CFLAGS += -DCONFIG_MODULE_TESTS |
| 12218 | +CFLAGS += -DCONFIG_DPP |
| 12219 | +#CFLAGS += -DCONFIG_DPP2 |
| 12220 | +#CFLAGS += -DCONFIG_DPP3 |
| 12221 | +CFLAGS += -DCONFIG_ECC |
| 12222 | +CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 12223 | +CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 12224 | +CFLAGS += -DCONFIG_MESH |
| 12225 | +CFLAGS += -DCONFIG_SHA256 |
| 12226 | +CFLAGS += -DCONFIG_SHA384 |
| 12227 | +CFLAGS += -DEAP_PSK |
| 12228 | +CFLAGS += -DEAP_FAST |
| 12229 | + |
| 12230 | CFLAGS += -I../src |
| 12231 | CFLAGS += -I../src/utils |
| 12232 | |
| 12233 | SLIBS = ../src/utils/libutils.a |
| 12234 | |
| 12235 | -DLIBS = ../src/crypto/libcrypto.a \ |
| 12236 | - ../src/tls/libtls.a |
| 12237 | +DLIBS = ../src/tls/libtls.a \ |
| 12238 | + ../src/crypto/libcrypto.a |
| 12239 | |
| 12240 | _OBJS_VAR := LLIBS |
| 12241 | include ../src/objs.mk |
| 12242 | @@ -43,12 +65,43 @@ include ../src/objs.mk |
| 12243 | LIBS = $(SLIBS) $(DLIBS) |
| 12244 | LLIBS = -Wl,--start-group $(DLIBS) -Wl,--end-group $(SLIBS) |
| 12245 | |
| 12246 | +ifeq ($(CONFIG_TLS),mbedtls) |
| 12247 | +CFLAGS += -DCONFIG_TLS_MBEDTLS |
| 12248 | +LLIBS += -lmbedtls -lmbedx509 -lmbedcrypto |
| 12249 | +else |
| 12250 | +ifeq ($(CONFIG_TLS),openssl) |
| 12251 | +CFLAGS += -DCONFIG_TLS_OPENSSL |
| 12252 | +LLIBS += -lssl -lcrypto |
| 12253 | +else |
| 12254 | +ifeq ($(CONFIG_TLS),gnutls) |
| 12255 | +CFLAGS += -DCONFIG_TLS_GNUTLS |
| 12256 | +LLIBS += -lgnutls -lgpg-error -lgcrypt |
| 12257 | +else |
| 12258 | +ifeq ($(CONFIG_TLS),wolfssl) |
| 12259 | +CFLAGS += -DCONFIG_TLS_WOLFSSL |
| 12260 | +LLIBS += -lwolfssl -lm |
| 12261 | +else |
| 12262 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 12263 | +CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER |
| 12264 | +ALL += test-rsa-sig-ver |
| 12265 | +ALL += test-x509v3 |
| 12266 | +clean-config_tls_internal: |
| 12267 | + rm -f test_x509v3_nist.out.* |
| 12268 | + rm -f test_x509v3_nist2.out.* |
| 12269 | +endif |
| 12270 | +endif |
| 12271 | +endif |
| 12272 | +endif |
| 12273 | + |
| 12274 | # glibc < 2.17 needs -lrt for clock_gettime() |
| 12275 | LLIBS += -lrt |
| 12276 | |
| 12277 | test-aes: $(call BUILDOBJ,test-aes.o) $(LIBS) |
| 12278 | $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) |
| 12279 | |
| 12280 | +test-crypto_module: $(call BUILDOBJ,test-crypto_module.o) $(LIBS) |
| 12281 | + $(LDO) $(LDFLAGS) -o $@ $< $(LLIBS) |
| 12282 | + |
| 12283 | test-base64: $(call BUILDOBJ,test-base64.o) $(LIBS) |
| 12284 | $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) |
| 12285 | |
| 12286 | @@ -149,10 +202,12 @@ run-tests: $(ALL) |
| 12287 | ./test-sha1 |
| 12288 | ./test-sha256 |
| 12289 | ./test-bss |
| 12290 | + |
| 12291 | + @set -ex; for i in $(RUN_TESTS); do ./$$i; done |
| 12292 | @echo |
| 12293 | @echo All tests completed successfully. |
| 12294 | |
| 12295 | -clean: common-clean |
| 12296 | +clean: common-clean clean-config_tls_internal |
| 12297 | rm -f *~ |
| 12298 | - rm -f test_x509v3_nist.out.* |
| 12299 | - rm -f test_x509v3_nist2.out.* |
| 12300 | + |
| 12301 | +.PHONY: run-tests clean-config_tls_internal |
| 12302 | diff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config |
| 12303 | index 210b7fb86..608e20eed 100644 |
| 12304 | --- a/tests/hwsim/example-hostapd.config |
| 12305 | +++ b/tests/hwsim/example-hostapd.config |
| 12306 | @@ -4,6 +4,7 @@ CONFIG_DRIVER_NONE=y |
| 12307 | CONFIG_DRIVER_NL80211=y |
| 12308 | CONFIG_RSN_PREAUTH=y |
| 12309 | |
| 12310 | +#CONFIG_TLS=mbedtls |
| 12311 | #CONFIG_TLS=internal |
| 12312 | #CONFIG_INTERNAL_LIBTOMMATH=y |
| 12313 | #CONFIG_INTERNAL_LIBTOMMATH_FAST=y |
| 12314 | @@ -33,12 +34,7 @@ CONFIG_EAP_TNC=y |
| 12315 | CFLAGS += -DTNC_CONFIG_FILE=\"tnc/tnc_config\" |
| 12316 | LIBS += -rdynamic |
| 12317 | CONFIG_EAP_UNAUTH_TLS=y |
| 12318 | -ifeq ($(CONFIG_TLS), openssl) |
| 12319 | -CONFIG_EAP_PWD=y |
| 12320 | -endif |
| 12321 | -ifeq ($(CONFIG_TLS), wolfssl) |
| 12322 | -CONFIG_EAP_PWD=y |
| 12323 | -endif |
| 12324 | +CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) |
| 12325 | CONFIG_EAP_EKE=y |
| 12326 | CONFIG_PKCS12=y |
| 12327 | CONFIG_RADIUS_SERVER=y |
| 12328 | @@ -88,7 +84,7 @@ CFLAGS += -DCONFIG_RADIUS_TEST |
| 12329 | CONFIG_MODULE_TESTS=y |
| 12330 | |
| 12331 | CONFIG_SUITEB=y |
| 12332 | -CONFIG_SUITEB192=y |
| 12333 | +CONFIG_SUITEB192=$(if $(filter openssl mbedtls,$(CONFIG_TLS)),y,) |
| 12334 | |
| 12335 | # AddressSanitizer (ASan) can be enabled by uncommenting the following lines. |
| 12336 | # This can be used as a more efficient memory error detector than valgrind |
| 12337 | diff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config |
| 12338 | index 123f397e3..da0dde659 100644 |
| 12339 | --- a/tests/hwsim/example-wpa_supplicant.config |
| 12340 | +++ b/tests/hwsim/example-wpa_supplicant.config |
| 12341 | @@ -2,6 +2,7 @@ |
| 12342 | |
| 12343 | CONFIG_TLS=openssl |
| 12344 | #CONFIG_TLS=wolfssl |
| 12345 | +#CONFIG_TLS=mbedtls |
| 12346 | #CONFIG_TLS=internal |
| 12347 | #CONFIG_INTERNAL_LIBTOMMATH=y |
| 12348 | #CONFIG_INTERNAL_LIBTOMMATH_FAST=y |
| 12349 | @@ -34,13 +35,7 @@ LIBS += -rdynamic |
| 12350 | CONFIG_EAP_FAST=y |
| 12351 | CONFIG_EAP_TEAP=y |
| 12352 | CONFIG_EAP_IKEV2=y |
| 12353 | - |
| 12354 | -ifeq ($(CONFIG_TLS), openssl) |
| 12355 | -CONFIG_EAP_PWD=y |
| 12356 | -endif |
| 12357 | -ifeq ($(CONFIG_TLS), wolfssl) |
| 12358 | -CONFIG_EAP_PWD=y |
| 12359 | -endif |
| 12360 | +CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) |
| 12361 | |
| 12362 | CONFIG_USIM_SIMULATOR=y |
| 12363 | CONFIG_SIM_SIMULATOR=y |
| 12364 | @@ -136,7 +131,7 @@ CONFIG_TESTING_OPTIONS=y |
| 12365 | CONFIG_MODULE_TESTS=y |
| 12366 | |
| 12367 | CONFIG_SUITEB=y |
| 12368 | -CONFIG_SUITEB192=y |
| 12369 | +CONFIG_SUITEB192=$(if $(filter openssl mbedtls,$(CONFIG_TLS)),y,) |
| 12370 | |
| 12371 | # AddressSanitizer (ASan) can be enabled by uncommenting the following lines. |
| 12372 | # This can be used as a more efficient memory error detector than valgrind |
| 12373 | diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py |
| 12374 | index a20140316..027a60b25 100644 |
| 12375 | --- a/tests/hwsim/test_ap_eap.py |
| 12376 | +++ b/tests/hwsim/test_ap_eap.py |
| 12377 | @@ -42,20 +42,42 @@ def check_eap_capa(dev, method): |
| 12378 | res = dev.get_capability("eap") |
| 12379 | if method not in res: |
| 12380 | raise HwsimSkip("EAP method %s not supported in the build" % method) |
| 12381 | + if method == "FAST" or method == "TEAP": |
| 12382 | + tls = dev.request("GET tls_library") |
| 12383 | + if tls.startswith("mbed TLS"): |
| 12384 | + raise HwsimSkip("EAP-%s not supported with this TLS library: " % method + tls) |
| 12385 | |
| 12386 | def check_subject_match_support(dev): |
| 12387 | tls = dev.request("GET tls_library") |
| 12388 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12389 | + if tls.startswith("OpenSSL"): |
| 12390 | + return |
| 12391 | + elif tls.startswith("wolfSSL"): |
| 12392 | + return |
| 12393 | + elif tls.startswith("mbed TLS"): |
| 12394 | + return |
| 12395 | + else: |
| 12396 | raise HwsimSkip("subject_match not supported with this TLS library: " + tls) |
| 12397 | |
| 12398 | def check_check_cert_subject_support(dev): |
| 12399 | tls = dev.request("GET tls_library") |
| 12400 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12401 | + if tls.startswith("OpenSSL"): |
| 12402 | + return |
| 12403 | + elif tls.startswith("wolfSSL"): |
| 12404 | + return |
| 12405 | + elif tls.startswith("mbed TLS"): |
| 12406 | + return |
| 12407 | + else: |
| 12408 | raise HwsimSkip("check_cert_subject not supported with this TLS library: " + tls) |
| 12409 | |
| 12410 | def check_altsubject_match_support(dev): |
| 12411 | tls = dev.request("GET tls_library") |
| 12412 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12413 | + if tls.startswith("OpenSSL"): |
| 12414 | + return |
| 12415 | + elif tls.startswith("wolfSSL"): |
| 12416 | + return |
| 12417 | + elif tls.startswith("mbed TLS"): |
| 12418 | + return |
| 12419 | + else: |
| 12420 | raise HwsimSkip("altsubject_match not supported with this TLS library: " + tls) |
| 12421 | |
| 12422 | def check_domain_match(dev): |
| 12423 | @@ -70,7 +92,13 @@ def check_domain_suffix_match(dev): |
| 12424 | |
| 12425 | def check_domain_match_full(dev): |
| 12426 | tls = dev.request("GET tls_library") |
| 12427 | - if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): |
| 12428 | + if tls.startswith("OpenSSL"): |
| 12429 | + return |
| 12430 | + elif tls.startswith("wolfSSL"): |
| 12431 | + return |
| 12432 | + elif tls.startswith("mbed TLS"): |
| 12433 | + return |
| 12434 | + else: |
| 12435 | raise HwsimSkip("domain_suffix_match requires full match with this TLS library: " + tls) |
| 12436 | |
| 12437 | def check_cert_probe_support(dev): |
| 12438 | @@ -79,8 +107,15 @@ def check_cert_probe_support(dev): |
| 12439 | raise HwsimSkip("Certificate probing not supported with this TLS library: " + tls) |
| 12440 | |
| 12441 | def check_ext_cert_check_support(dev): |
| 12442 | + if not openssl_imported: |
| 12443 | + raise HwsimSkip("OpenSSL python method not available") |
| 12444 | + |
| 12445 | tls = dev.request("GET tls_library") |
| 12446 | - if not tls.startswith("OpenSSL"): |
| 12447 | + if tls.startswith("OpenSSL"): |
| 12448 | + return |
| 12449 | + elif tls.startswith("mbed TLS"): |
| 12450 | + return |
| 12451 | + else: |
| 12452 | raise HwsimSkip("ext_cert_check not supported with this TLS library: " + tls) |
| 12453 | |
| 12454 | def check_ocsp_support(dev): |
| 12455 | @@ -91,10 +126,12 @@ def check_ocsp_support(dev): |
| 12456 | # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) |
| 12457 | #if tls.startswith("wolfSSL"): |
| 12458 | # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) |
| 12459 | + if tls.startswith("mbed TLS"): |
| 12460 | + raise HwsimSkip("OCSP not supported with this TLS library: " + tls) |
| 12461 | |
| 12462 | def check_pkcs5_v15_support(dev): |
| 12463 | tls = dev.request("GET tls_library") |
| 12464 | - if "BoringSSL" in tls or "GnuTLS" in tls: |
| 12465 | + if "BoringSSL" in tls or "GnuTLS" in tls or "mbed TLS" in tls: |
| 12466 | raise HwsimSkip("PKCS#5 v1.5 not supported with this TLS library: " + tls) |
| 12467 | |
| 12468 | def check_tls13_support(dev): |
| 12469 | @@ -122,11 +159,15 @@ def check_pkcs12_support(dev): |
| 12470 | # raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) |
| 12471 | if tls.startswith("wolfSSL"): |
| 12472 | raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) |
| 12473 | + if tls.startswith("mbed TLS"): |
| 12474 | + raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) |
| 12475 | |
| 12476 | def check_dh_dsa_support(dev): |
| 12477 | tls = dev.request("GET tls_library") |
| 12478 | if tls.startswith("internal"): |
| 12479 | raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) |
| 12480 | + if tls.startswith("mbed TLS"): |
| 12481 | + raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) |
| 12482 | |
| 12483 | def check_ec_support(dev): |
| 12484 | tls = dev.request("GET tls_library") |
| 12485 | @@ -1741,7 +1782,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_match(dev, apdev): |
| 12486 | eap_connect(dev[0], hapd, "TTLS", "pap user", |
| 12487 | anonymous_identity="ttls", password="password", |
| 12488 | ca_cert="auth_serv/ca.pem", phase2="auth=PAP", |
| 12489 | - subject_match="/C=FI/O=w1.fi/CN=server.w1.fi", |
| 12490 | + check_cert_subject="/C=FI/O=w1.fi/CN=server.w1.fi", |
| 12491 | altsubject_match="EMAIL:noone@example.com;DNS:server.w1.fi;URI:http://example.com/") |
| 12492 | eap_reauth(dev[0], "TTLS") |
| 12493 | |
| 12494 | @@ -2976,6 +3017,7 @@ def test_ap_wpa2_eap_tls_neg_domain_match(dev, apdev): |
| 12495 | |
| 12496 | def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): |
| 12497 | """WPA2-Enterprise negative test - subject mismatch""" |
| 12498 | + check_subject_match_support(dev[0]) |
| 12499 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12500 | hostapd.add_ap(apdev[0], params) |
| 12501 | dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", |
| 12502 | @@ -3036,6 +3078,7 @@ def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): |
| 12503 | |
| 12504 | def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): |
| 12505 | """WPA2-Enterprise negative test - altsubject mismatch""" |
| 12506 | + check_altsubject_match_support(dev[0]) |
| 12507 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12508 | hostapd.add_ap(apdev[0], params) |
| 12509 | |
| 12510 | @@ -3582,7 +3625,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apdev): |
| 12511 | dev[0].request("REMOVE_NETWORK all") |
| 12512 | |
| 12513 | tls = dev[0].request("GET tls_library") |
| 12514 | - if not tls.startswith("wolfSSL"): |
| 12515 | + if not tls.startswith("wolfSSL") and not tls.startswith("mbed TLS"): |
| 12516 | tests = [(1, "os_get_random;dh_init")] |
| 12517 | else: |
| 12518 | tests = [(1, "crypto_dh_init;dh_init")] |
| 12519 | @@ -4896,7 +4939,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca(dev, apdev, params): |
| 12520 | params["private_key"] = "auth_serv/iCA-server/server.key" |
| 12521 | hostapd.add_ap(apdev[0], params) |
| 12522 | tls = dev[0].request("GET tls_library") |
| 12523 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12524 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12525 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12526 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12527 | else: |
| 12528 | @@ -4962,6 +5005,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_sha1(dev, apdev, params): |
| 12529 | run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, "-sha1") |
| 12530 | |
| 12531 | def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): |
| 12532 | + check_ocsp_support(dev[0]) |
| 12533 | params = int_eap_server_params() |
| 12534 | params["ca_cert"] = "auth_serv/iCA-server/ca-and-root.pem" |
| 12535 | params["server_cert"] = "auth_serv/iCA-server/server.pem" |
| 12536 | @@ -4971,7 +5015,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): |
| 12537 | try: |
| 12538 | hostapd.add_ap(apdev[0], params) |
| 12539 | tls = dev[0].request("GET tls_library") |
| 12540 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12541 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12542 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12543 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12544 | else: |
| 12545 | @@ -5007,7 +5051,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked(dev, apdev, params, md): |
| 12546 | try: |
| 12547 | hostapd.add_ap(apdev[0], params) |
| 12548 | tls = dev[0].request("GET tls_library") |
| 12549 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12550 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12551 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12552 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12553 | else: |
| 12554 | @@ -5057,7 +5101,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi_missing_resp(dev, apdev, par |
| 12555 | try: |
| 12556 | hostapd.add_ap(apdev[0], params) |
| 12557 | tls = dev[0].request("GET tls_library") |
| 12558 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12559 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12560 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12561 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12562 | else: |
| 12563 | @@ -5124,7 +5168,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi(dev, apdev, params): |
| 12564 | |
| 12565 | hostapd.add_ap(apdev[0], params) |
| 12566 | tls = dev[0].request("GET tls_library") |
| 12567 | - if "GnuTLS" in tls or "wolfSSL" in tls: |
| 12568 | + if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: |
| 12569 | ca_cert = "auth_serv/iCA-user/ca-and-root.pem" |
| 12570 | client_cert = "auth_serv/iCA-user/user_and_ica.pem" |
| 12571 | else: |
| 12572 | @@ -5382,6 +5426,7 @@ def test_ap_wpa2_eap_ttls_server_cert_eku_client_server(dev, apdev): |
| 12573 | |
| 12574 | def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): |
| 12575 | """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" |
| 12576 | + check_pkcs12_support(dev[0]) |
| 12577 | skip_with_fips(dev[0]) |
| 12578 | params = int_eap_server_params() |
| 12579 | del params["server_cert"] |
| 12580 | @@ -5394,6 +5439,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): |
| 12581 | |
| 12582 | def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): |
| 12583 | """EAP-TTLS and server PKCS#12 file with extra certs""" |
| 12584 | + check_pkcs12_support(dev[0]) |
| 12585 | skip_with_fips(dev[0]) |
| 12586 | params = int_eap_server_params() |
| 12587 | del params["server_cert"] |
| 12588 | @@ -5416,6 +5462,7 @@ def test_ap_wpa2_eap_ttls_dh_params_server(dev, apdev): |
| 12589 | |
| 12590 | def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): |
| 12591 | """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" |
| 12592 | + check_dh_dsa_support(dev[0]) |
| 12593 | params = int_eap_server_params() |
| 12594 | params["dh_file"] = "auth_serv/dsaparam.pem" |
| 12595 | hapd = hostapd.add_ap(apdev[0], params) |
| 12596 | @@ -5727,8 +5774,8 @@ def test_ap_wpa2_eap_non_ascii_identity2(dev, apdev): |
| 12597 | def test_openssl_cipher_suite_config_wpas(dev, apdev): |
| 12598 | """OpenSSL cipher suite configuration on wpa_supplicant""" |
| 12599 | tls = dev[0].request("GET tls_library") |
| 12600 | - if not tls.startswith("OpenSSL"): |
| 12601 | - raise HwsimSkip("TLS library is not OpenSSL: " + tls) |
| 12602 | + if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): |
| 12603 | + raise HwsimSkip("TLS library is not OpenSSL or mbed TLS: " + tls) |
| 12604 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12605 | hapd = hostapd.add_ap(apdev[0], params) |
| 12606 | eap_connect(dev[0], hapd, "TTLS", "pap user", |
| 12607 | @@ -5754,14 +5801,14 @@ def test_openssl_cipher_suite_config_wpas(dev, apdev): |
| 12608 | def test_openssl_cipher_suite_config_hapd(dev, apdev): |
| 12609 | """OpenSSL cipher suite configuration on hostapd""" |
| 12610 | tls = dev[0].request("GET tls_library") |
| 12611 | - if not tls.startswith("OpenSSL"): |
| 12612 | - raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL: " + tls) |
| 12613 | + if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): |
| 12614 | + raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL or mbed TLS: " + tls) |
| 12615 | params = int_eap_server_params() |
| 12616 | params['openssl_ciphers'] = "AES256" |
| 12617 | hapd = hostapd.add_ap(apdev[0], params) |
| 12618 | tls = hapd.request("GET tls_library") |
| 12619 | - if not tls.startswith("OpenSSL"): |
| 12620 | - raise HwsimSkip("hostapd TLS library is not OpenSSL: " + tls) |
| 12621 | + if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): |
| 12622 | + raise HwsimSkip("hostapd TLS library is not OpenSSL or mbed TLS: " + tls) |
| 12623 | eap_connect(dev[0], hapd, "TTLS", "pap user", |
| 12624 | anonymous_identity="ttls", password="password", |
| 12625 | ca_cert="auth_serv/ca.pem", phase2="auth=PAP") |
| 12626 | @@ -6207,14 +6254,26 @@ def test_ap_wpa2_eap_tls_versions(dev, apdev): |
| 12627 | check_tls_ver(dev[0], hapd, |
| 12628 | "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", |
| 12629 | "TLSv1.2") |
| 12630 | - elif tls.startswith("internal"): |
| 12631 | + elif tls.startswith("internal") or tls.startswith("mbed TLS"): |
| 12632 | check_tls_ver(dev[0], hapd, |
| 12633 | "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") |
| 12634 | +<<<<<<< HEAD |
| 12635 | check_tls_ver(dev[1], hapd, |
| 12636 | "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1") |
| 12637 | check_tls_ver(dev[2], hapd, |
| 12638 | "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1") |
| 12639 | if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3." in tls: |
| 12640 | +======= |
| 12641 | + if tls.startswith("mbed TLS"): |
| 12642 | + check_tls_ver(dev[2], hapd, |
| 12643 | + "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1.0") |
| 12644 | + else: |
| 12645 | + check_tls_ver(dev[1], hapd, |
| 12646 | + "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1") |
| 12647 | + check_tls_ver(dev[2], hapd, |
| 12648 | + "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1") |
| 12649 | + if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3.0" in tls: |
| 12650 | +>>>>>>> 585bc9ada (hostapd: sync 2024-01-18 openwrt/trunk patch folder) |
| 12651 | check_tls_ver(dev[0], hapd, |
| 12652 | "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0", "TLSv1.3") |
| 12653 | |
| 12654 | @@ -6235,6 +6294,11 @@ def test_ap_wpa2_eap_tls_versions_server(dev, apdev): |
| 12655 | tests = [("TLSv1", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12656 | ("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12657 | ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] |
| 12658 | + tls = dev[0].request("GET tls_library") |
| 12659 | + if tls.startswith("mbed TLS"): |
| 12660 | + tests = [#("TLSv1.0", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12661 | + #("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), |
| 12662 | + ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] |
| 12663 | for exp, flags in tests: |
| 12664 | hapd.disable() |
| 12665 | hapd.set("tls_flags", flags) |
| 12666 | @@ -7305,6 +7369,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apdev): |
| 12667 | def test_eap_tls_ext_cert_check(dev, apdev): |
| 12668 | """EAP-TLS and external server certification validation""" |
| 12669 | # With internal server certificate chain validation |
| 12670 | + check_ext_cert_check_support(dev[0]) |
| 12671 | id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", |
| 12672 | identity="tls user", |
| 12673 | ca_cert="auth_serv/ca.pem", |
| 12674 | @@ -7317,6 +7382,7 @@ def test_eap_tls_ext_cert_check(dev, apdev): |
| 12675 | def test_eap_ttls_ext_cert_check(dev, apdev): |
| 12676 | """EAP-TTLS and external server certification validation""" |
| 12677 | # Without internal server certificate chain validation |
| 12678 | + check_ext_cert_check_support(dev[0]) |
| 12679 | id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", |
| 12680 | identity="pap user", anonymous_identity="ttls", |
| 12681 | password="password", phase2="auth=PAP", |
| 12682 | @@ -7327,6 +7393,7 @@ def test_eap_ttls_ext_cert_check(dev, apdev): |
| 12683 | def test_eap_peap_ext_cert_check(dev, apdev): |
| 12684 | """EAP-PEAP and external server certification validation""" |
| 12685 | # With internal server certificate chain validation |
| 12686 | + check_ext_cert_check_support(dev[0]) |
| 12687 | id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", |
| 12688 | identity="user", anonymous_identity="peap", |
| 12689 | ca_cert="auth_serv/ca.pem", |
| 12690 | @@ -7337,6 +7404,7 @@ def test_eap_peap_ext_cert_check(dev, apdev): |
| 12691 | |
| 12692 | def test_eap_fast_ext_cert_check(dev, apdev): |
| 12693 | """EAP-FAST and external server certification validation""" |
| 12694 | + check_ext_cert_check_support(dev[0]) |
| 12695 | check_eap_capa(dev[0], "FAST") |
| 12696 | # With internal server certificate chain validation |
| 12697 | dev[0].request("SET blob fast_pac_auth_ext ") |
| 12698 | @@ -7351,10 +7419,6 @@ def test_eap_fast_ext_cert_check(dev, apdev): |
| 12699 | run_ext_cert_check(dev, apdev, id) |
| 12700 | |
| 12701 | def run_ext_cert_check(dev, apdev, net_id): |
| 12702 | - check_ext_cert_check_support(dev[0]) |
| 12703 | - if not openssl_imported: |
| 12704 | - raise HwsimSkip("OpenSSL python method not available") |
| 12705 | - |
| 12706 | params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") |
| 12707 | hapd = hostapd.add_ap(apdev[0], params) |
| 12708 | |
| 12709 | diff --git a/tests/hwsim/test_ap_ft.py b/tests/hwsim/test_ap_ft.py |
| 12710 | index 3d07d21f7..a708412de 100644 |
| 12711 | --- a/tests/hwsim/test_ap_ft.py |
| 12712 | +++ b/tests/hwsim/test_ap_ft.py |
| 12713 | @@ -2486,11 +2486,11 @@ def test_ap_ft_ap_oom5(dev, apdev): |
| 12714 | # This will fail to roam |
| 12715 | dev[0].roam(bssid1, check_bssid=False) |
| 12716 | |
| 12717 | - with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12718 | + with fail_test(hapd1, 1, "sha256_prf;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12719 | # This will fail to roam |
| 12720 | dev[0].roam(bssid1, check_bssid=False) |
| 12721 | |
| 12722 | - with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12723 | + with fail_test(hapd1, 2, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): |
| 12724 | # This will fail to roam |
| 12725 | dev[0].roam(bssid1, check_bssid=False) |
| 12726 | |
| 12727 | diff --git a/tests/hwsim/test_authsrv.py b/tests/hwsim/test_authsrv.py |
| 12728 | index e0665bcb2..02ec301e5 100644 |
| 12729 | --- a/tests/hwsim/test_authsrv.py |
| 12730 | +++ b/tests/hwsim/test_authsrv.py |
| 12731 | @@ -156,9 +156,12 @@ def test_authsrv_oom(dev, apdev): |
| 12732 | if "FAIL" not in authsrv.request("ENABLE"): |
| 12733 | raise Exception("ENABLE succeeded during OOM") |
| 12734 | |
| 12735 | - with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): |
| 12736 | - if "FAIL" not in authsrv.request("ENABLE"): |
| 12737 | - raise Exception("ENABLE succeeded during OOM") |
| 12738 | + # tls_mbedtls.c:tls_init() does not alloc memory (no alloc fail trigger) |
| 12739 | + tls = dev[0].request("GET tls_library") |
| 12740 | + if not tls.startswith("mbed TLS"): |
| 12741 | + with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): |
| 12742 | + if "FAIL" not in authsrv.request("ENABLE"): |
| 12743 | + raise Exception("ENABLE succeeded during OOM") |
| 12744 | |
| 12745 | for count in range(1, 3): |
| 12746 | with alloc_fail(authsrv, count, "eap_sim_db_init;authsrv_init"): |
| 12747 | diff --git a/tests/hwsim/test_dpp.py b/tests/hwsim/test_dpp.py |
| 12748 | index 518983bd0..077de58c9 100644 |
| 12749 | --- a/tests/hwsim/test_dpp.py |
| 12750 | +++ b/tests/hwsim/test_dpp.py |
| 12751 | @@ -39,7 +39,8 @@ def check_dpp_capab(dev, brainpool=False, min_ver=1): |
| 12752 | raise HwsimSkip("DPP not supported") |
| 12753 | if brainpool: |
| 12754 | tls = dev.request("GET tls_library") |
| 12755 | - if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL"): |
| 12756 | + if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL") \ |
| 12757 | + and not tls.startswith("mbed TLS"): |
| 12758 | raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls) |
| 12759 | capa = dev.request("GET_CAPABILITY dpp") |
| 12760 | ver = 1 |
| 12761 | @@ -3902,6 +3903,9 @@ def test_dpp_proto_auth_req_no_i_proto_key(dev, apdev): |
| 12762 | |
| 12763 | def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): |
| 12764 | """DPP protocol testing - invalid I-proto key in Auth Req""" |
| 12765 | + tls = dev[0].request("GET tls_library") |
| 12766 | + if tls.startswith("mbed TLS"): |
| 12767 | + raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") |
| 12768 | run_dpp_proto_auth_req_missing(dev, 66, "Invalid Initiator Protocol Key") |
| 12769 | |
| 12770 | def test_dpp_proto_auth_req_no_i_nonce(dev, apdev): |
| 12771 | @@ -3997,7 +4001,12 @@ def test_dpp_proto_auth_resp_no_r_proto_key(dev, apdev): |
| 12772 | |
| 12773 | def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): |
| 12774 | """DPP protocol testing - invalid R-Proto Key in Auth Resp""" |
| 12775 | - run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") |
| 12776 | + tls = dev[0].request("GET tls_library") |
| 12777 | + if tls.startswith("mbed TLS"): |
| 12778 | + # mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key |
| 12779 | + run_dpp_proto_auth_resp_missing(dev, 67, "Failed to derive ECDH shared secret") |
| 12780 | + else: |
| 12781 | + run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") |
| 12782 | |
| 12783 | def test_dpp_proto_auth_resp_no_r_nonce(dev, apdev): |
| 12784 | """DPP protocol testing - no R-nonce in Auth Resp""" |
| 12785 | @@ -4359,11 +4368,17 @@ def test_dpp_proto_pkex_exchange_resp_invalid_status(dev, apdev): |
| 12786 | |
| 12787 | def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): |
| 12788 | """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" |
| 12789 | + tls = dev[0].request("GET tls_library") |
| 12790 | + if tls.startswith("mbed TLS"): |
| 12791 | + raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") |
| 12792 | run_dpp_proto_pkex_req_missing(dev, 47, |
| 12793 | "Peer bootstrapping key is invalid") |
| 12794 | |
| 12795 | def test_dpp_proto_pkex_cr_resp_invalid_bootstrap_key(dev, apdev): |
| 12796 | """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Response""" |
| 12797 | + tls = dev[0].request("GET tls_library") |
| 12798 | + if tls.startswith("mbed TLS"): |
| 12799 | + raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") |
| 12800 | run_dpp_proto_pkex_resp_missing(dev, 48, |
| 12801 | "Peer bootstrapping key is invalid") |
| 12802 | |
| 12803 | diff --git a/tests/hwsim/test_erp.py b/tests/hwsim/test_erp.py |
| 12804 | index d083993e8..262e9f095 100644 |
| 12805 | --- a/tests/hwsim/test_erp.py |
| 12806 | +++ b/tests/hwsim/test_erp.py |
| 12807 | @@ -12,7 +12,7 @@ import time |
| 12808 | |
| 12809 | import hostapd |
| 12810 | from utils import * |
| 12811 | -from test_ap_eap import int_eap_server_params, check_tls13_support |
| 12812 | +from test_ap_eap import int_eap_server_params, check_tls13_support, check_eap_capa |
| 12813 | from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations |
| 12814 | |
| 12815 | def test_erp_initiate_reauth_start(dev, apdev): |
| 12816 | @@ -276,6 +276,7 @@ def test_erp_radius_eap_methods(dev, apdev): |
| 12817 | params['erp_domain'] = 'example.com' |
| 12818 | params['disable_pmksa_caching'] = '1' |
| 12819 | hapd = hostapd.add_ap(apdev[0], params) |
| 12820 | + tls = dev[0].request("GET tls_library") |
| 12821 | |
| 12822 | erp_test(dev[0], hapd, eap="AKA", identity="0232010000000000@example.com", |
| 12823 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") |
| 12824 | @@ -289,7 +290,7 @@ def test_erp_radius_eap_methods(dev, apdev): |
| 12825 | password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") |
| 12826 | erp_test(dev[0], hapd, eap="EKE", identity="erp-eke@example.com", |
| 12827 | password="hello") |
| 12828 | - if "FAST" in eap_methods: |
| 12829 | + if "FAST" in eap_methods and check_eap_capa(dev[0], "FAST"): |
| 12830 | erp_test(dev[0], hapd, eap="FAST", identity="erp-fast@example.com", |
| 12831 | password="password", ca_cert="auth_serv/ca.pem", |
| 12832 | phase2="auth=GTC", |
| 12833 | @@ -301,13 +302,14 @@ def test_erp_radius_eap_methods(dev, apdev): |
| 12834 | password="password") |
| 12835 | erp_test(dev[0], hapd, eap="PAX", identity="erp-pax@example.com", |
| 12836 | password_hex="0123456789abcdef0123456789abcdef") |
| 12837 | - if "MSCHAPV2" in eap_methods: |
| 12838 | + if "MSCHAPV2" in eap_methods and check_eap_capa(dev[0], "MSCHAPV2"): |
| 12839 | erp_test(dev[0], hapd, eap="PEAP", identity="erp-peap@example.com", |
| 12840 | password="password", ca_cert="auth_serv/ca.pem", |
| 12841 | phase2="auth=MSCHAPV2") |
| 12842 | - erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", |
| 12843 | - password="password", ca_cert="auth_serv/ca.pem", |
| 12844 | - phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") |
| 12845 | + if check_eap_capa(dev[0], "TEAP"): |
| 12846 | + erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", |
| 12847 | + password="password", ca_cert="auth_serv/ca.pem", |
| 12848 | + phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") |
| 12849 | erp_test(dev[0], hapd, eap="PSK", identity="erp-psk@example.com", |
| 12850 | password_hex="0123456789abcdef0123456789abcdef") |
| 12851 | if "PWD" in eap_methods: |
| 12852 | @@ -640,7 +642,7 @@ def test_erp_local_errors(dev, apdev): |
| 12853 | dev[0].request("REMOVE_NETWORK all") |
| 12854 | dev[0].wait_disconnected() |
| 12855 | |
| 12856 | - for count in range(1, 6): |
| 12857 | + for count in range(1, 4): |
| 12858 | dev[0].request("ERP_FLUSH") |
| 12859 | with fail_test(dev[0], count, "hmac_sha256_kdf;eap_peer_erp_init"): |
| 12860 | dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", |
| 12861 | diff --git a/tests/hwsim/test_fils.py b/tests/hwsim/test_fils.py |
| 12862 | index 5cdc28734..17110c5c2 100644 |
| 12863 | --- a/tests/hwsim/test_fils.py |
| 12864 | +++ b/tests/hwsim/test_fils.py |
| 12865 | @@ -1484,6 +1484,18 @@ def run_fils_sk_pfs(dev, apdev, group, params): |
| 12866 | check_erp_capa(dev[0]) |
| 12867 | check_ec_group(dev[0], group) |
| 12868 | |
| 12869 | + tls = dev[0].request("GET tls_library") |
| 12870 | + if tls.startswith("mbed TLS"): |
| 12871 | + if int(group) == 27: |
| 12872 | + raise HwsimSkip("Brainpool EC group 27 not supported by mbed TLS") |
| 12873 | + elif not tls.startswith("wolfSSL"): |
| 12874 | + if int(group) in [25]: |
| 12875 | + if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3.0" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3.0" in tls)): |
| 12876 | + raise HwsimSkip("EC group not supported") |
| 12877 | + if int(group) in [27, 28, 29, 30]: |
| 12878 | + if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3.0" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3.0" in tls)): |
| 12879 | + raise HwsimSkip("Brainpool EC group not supported") |
| 12880 | + |
| 12881 | start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst")) |
| 12882 | |
| 12883 | bssid = apdev[0]['bssid'] |
| 12884 | diff --git a/tests/hwsim/test_pmksa_cache.py b/tests/hwsim/test_pmksa_cache.py |
| 12885 | index 4a3b444ff..4f7f7f760 100644 |
| 12886 | --- a/tests/hwsim/test_pmksa_cache.py |
| 12887 | +++ b/tests/hwsim/test_pmksa_cache.py |
| 12888 | @@ -958,7 +958,7 @@ def test_pmksa_cache_preauth_wpas_oom(dev, apdev): |
| 12889 | eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", |
| 12890 | password_hex="0123456789abcdef0123456789abcdef", |
| 12891 | bssid=apdev[0]['bssid']) |
| 12892 | - for i in range(1, 11): |
| 12893 | + for i in range(1, 10): |
| 12894 | with alloc_fail(dev[0], i, "rsn_preauth_init"): |
| 12895 | res = dev[0].request("PREAUTH f2:11:22:33:44:55").strip() |
| 12896 | logger.info("Iteration %d - PREAUTH command results: %s" % (i, res)) |
| 12897 | @@ -966,7 +966,7 @@ def test_pmksa_cache_preauth_wpas_oom(dev, apdev): |
| 12898 | state = dev[0].request('GET_ALLOC_FAIL') |
| 12899 | if state.startswith('0:'): |
| 12900 | break |
| 12901 | - time.sleep(0.05) |
| 12902 | + time.sleep(0.10) |
| 12903 | |
| 12904 | def test_pmksa_cache_ctrl(dev, apdev): |
| 12905 | """PMKSA cache control interface operations""" |
| 12906 | diff --git a/tests/hwsim/test_sae.py b/tests/hwsim/test_sae.py |
| 12907 | index aceb92751..6f9ee5669 100644 |
| 12908 | --- a/tests/hwsim/test_sae.py |
| 12909 | +++ b/tests/hwsim/test_sae.py |
| 12910 | @@ -178,6 +178,11 @@ def test_sae_groups(dev, apdev): |
| 12911 | if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls: |
| 12912 | logger.info("Add Brainpool EC groups since OpenSSL is new enough") |
| 12913 | sae_groups += [27, 28, 29, 30] |
| 12914 | + if tls.startswith("mbed TLS"): |
| 12915 | + # secp224k1 and secp224r1 (26) have prime p = 1 mod 4, and mbedtls |
| 12916 | + # does not have code to derive y from compressed format for those curves |
| 12917 | + sae_groups = [19, 25, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24] |
| 12918 | + sae_groups += [27, 28, 29, 30] |
| 12919 | heavy_groups = [14, 15, 16] |
| 12920 | suitable_groups = [15, 16, 17, 18, 19, 20, 21] |
| 12921 | groups = [str(g) for g in sae_groups] |
| 12922 | @@ -2194,6 +2199,8 @@ def run_sae_pwe_group(dev, apdev, group): |
| 12923 | logger.info("Add Brainpool EC groups since OpenSSL is new enough") |
| 12924 | elif tls.startswith("wolfSSL"): |
| 12925 | logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL") |
| 12926 | + elif tls.startswith("mbed TLS"): |
| 12927 | + logger.info("Make sure Brainpool EC groups were enabled when compiling mbed TLS") |
| 12928 | else: |
| 12929 | raise HwsimSkip("Brainpool curve not supported") |
| 12930 | start_sae_pwe_ap(apdev[0], group, 2) |
| 12931 | diff --git a/tests/hwsim/test_suite_b.py b/tests/hwsim/test_suite_b.py |
| 12932 | index d03a39dee..d703dee95 100644 |
| 12933 | --- a/tests/hwsim/test_suite_b.py |
| 12934 | +++ b/tests/hwsim/test_suite_b.py |
| 12935 | @@ -27,6 +27,8 @@ def check_suite_b_tls_lib(dev, dhe=False, level128=False): |
| 12936 | return |
| 12937 | if tls.startswith("wolfSSL"): |
| 12938 | return |
| 12939 | + if tls.startswith("mbed TLS"): |
| 12940 | + return |
| 12941 | if not tls.startswith("OpenSSL"): |
| 12942 | raise HwsimSkip("TLS library not supported for Suite B: " + tls) |
| 12943 | supported = False |
| 12944 | @@ -520,6 +522,7 @@ def test_suite_b_192_rsa_insufficient_dh(dev, apdev): |
| 12945 | |
| 12946 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", |
| 12947 | ieee80211w="2", |
| 12948 | + openssl_ciphers="DHE-RSA-AES256-GCM-SHA384", |
| 12949 | phase1="tls_suiteb=1", |
| 12950 | eap="TLS", identity="tls user", |
| 12951 | ca_cert="auth_serv/rsa3072-ca.pem", |
| 12952 | diff --git a/tests/hwsim/test_wpas_ctrl.py b/tests/hwsim/test_wpas_ctrl.py |
| 12953 | index 44eb00444..fbe0fb794 100644 |
| 12954 | --- a/tests/hwsim/test_wpas_ctrl.py |
| 12955 | +++ b/tests/hwsim/test_wpas_ctrl.py |
| 12956 | @@ -1856,7 +1856,7 @@ def _test_wpas_ctrl_oom(dev): |
| 12957 | tls = dev[0].request("GET tls_library") |
| 12958 | if not tls.startswith("internal"): |
| 12959 | tests.append(('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', 'FAIL', |
| 12960 | - 4, 'wpas_ctrl_nfc_get_handover_sel_p2p')) |
| 12961 | + 3, 'wpas_ctrl_nfc_get_handover_sel_p2p')) |
| 12962 | for cmd, exp, count, func in tests: |
| 12963 | with alloc_fail(dev[0], count, func): |
| 12964 | res = dev[0].request(cmd) |
| 12965 | diff --git a/tests/hwsim/utils.py b/tests/hwsim/utils.py |
| 12966 | index 7e3608284..b23c1ee0b 100644 |
| 12967 | --- a/tests/hwsim/utils.py |
| 12968 | +++ b/tests/hwsim/utils.py |
| 12969 | @@ -145,7 +145,13 @@ def check_imsi_privacy_support(dev): |
| 12970 | |
| 12971 | def check_tls_tod(dev): |
| 12972 | tls = dev.request("GET tls_library") |
| 12973 | - if not tls.startswith("OpenSSL") and not tls.startswith("internal"): |
| 12974 | + if tls.startswith("OpenSSL"): |
| 12975 | + return |
| 12976 | + elif tls.startswith("internal"): |
| 12977 | + return |
| 12978 | + elif tls.startswith("mbed TLS"): |
| 12979 | + return |
| 12980 | + else: |
| 12981 | raise HwsimSkip("TLS TOD-TOFU/STRICT not supported with this TLS library: " + tls) |
| 12982 | |
| 12983 | def vht_supported(): |
| 12984 | diff --git a/tests/test-crypto_module.c b/tests/test-crypto_module.c |
| 12985 | new file mode 100644 |
| 12986 | index 000000000..0f1156142 |
| 12987 | --- /dev/null |
| 12988 | +++ b/tests/test-crypto_module.c |
| 12989 | @@ -0,0 +1,16 @@ |
| 12990 | +/* |
| 12991 | + * crypto module tests - test program |
| 12992 | + * Copyright (c) 2022, Glenn Strauss <gstrauss@gluelogic.com> |
| 12993 | + * |
| 12994 | + * This software may be distributed under the terms of the BSD license. |
| 12995 | + * See README for more details. |
| 12996 | + */ |
| 12997 | + |
| 12998 | +#include "utils/includes.h" |
| 12999 | +#include "utils/module_tests.h" |
| 13000 | +#include "crypto/crypto_module_tests.c" |
| 13001 | + |
| 13002 | +int main(int argc, char *argv[]) |
| 13003 | +{ |
| 13004 | + return crypto_module_tests(); |
| 13005 | +} |
| 13006 | diff --git a/tests/test-https.c b/tests/test-https.c |
| 13007 | index a72e56f9d..e9df82f1d 100644 |
| 13008 | --- a/tests/test-https.c |
| 13009 | +++ b/tests/test-https.c |
| 13010 | @@ -75,7 +75,7 @@ static int https_client(int s, const char *path) |
| 13011 | struct tls_connection *conn; |
| 13012 | struct wpabuf *in, *out, *appl; |
| 13013 | int res = -1; |
| 13014 | - int need_more_data; |
| 13015 | + int need_more_data = 0; |
| 13016 | |
| 13017 | os_memset(&conf, 0, sizeof(conf)); |
| 13018 | conf.event_cb = https_tls_event_cb; |
| 13019 | @@ -93,8 +93,12 @@ static int https_client(int s, const char *path) |
| 13020 | |
| 13021 | for (;;) { |
| 13022 | appl = NULL; |
| 13023 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13024 | out = tls_connection_handshake2(tls, conn, in, &appl, |
| 13025 | &need_more_data); |
| 13026 | +#else |
| 13027 | + out = tls_connection_handshake(tls, conn, in, &appl); |
| 13028 | +#endif |
| 13029 | wpabuf_free(in); |
| 13030 | in = NULL; |
| 13031 | if (out == NULL) { |
| 13032 | @@ -152,11 +156,15 @@ static int https_client(int s, const char *path) |
| 13033 | |
| 13034 | wpa_printf(MSG_INFO, "Reading HTTP response"); |
| 13035 | for (;;) { |
| 13036 | - int need_more_data; |
| 13037 | + int need_more_data = 0; |
| 13038 | in = https_recv(s); |
| 13039 | if (in == NULL) |
| 13040 | goto done; |
| 13041 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13042 | out = tls_connection_decrypt2(tls, conn, in, &need_more_data); |
| 13043 | +#else |
| 13044 | + out = tls_connection_decrypt(tls, conn, in); |
| 13045 | +#endif |
| 13046 | if (need_more_data) |
| 13047 | wpa_printf(MSG_DEBUG, "HTTP: Need more data"); |
| 13048 | wpabuf_free(in); |
| 13049 | diff --git a/tests/test-https_server.c b/tests/test-https_server.c |
| 13050 | index 33b448682..9dcca5596 100644 |
| 13051 | --- a/tests/test-https_server.c |
| 13052 | +++ b/tests/test-https_server.c |
| 13053 | @@ -67,10 +67,12 @@ static struct wpabuf * https_recv(int s, int timeout_ms) |
| 13054 | } |
| 13055 | |
| 13056 | |
| 13057 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13058 | static void https_tls_log_cb(void *ctx, const char *msg) |
| 13059 | { |
| 13060 | wpa_printf(MSG_DEBUG, "TLS: %s", msg); |
| 13061 | } |
| 13062 | +#endif |
| 13063 | |
| 13064 | |
| 13065 | static int https_server(int s) |
| 13066 | @@ -79,7 +81,7 @@ static int https_server(int s) |
| 13067 | void *tls; |
| 13068 | struct tls_connection_params params; |
| 13069 | struct tls_connection *conn; |
| 13070 | - struct wpabuf *in, *out, *appl; |
| 13071 | + struct wpabuf *in = NULL, *out = NULL, *appl = NULL; |
| 13072 | int res = -1; |
| 13073 | |
| 13074 | os_memset(&conf, 0, sizeof(conf)); |
| 13075 | @@ -106,7 +108,9 @@ static int https_server(int s) |
| 13076 | return -1; |
| 13077 | } |
| 13078 | |
| 13079 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13080 | tls_connection_set_log_cb(conn, https_tls_log_cb, NULL); |
| 13081 | +#endif |
| 13082 | |
| 13083 | for (;;) { |
| 13084 | in = https_recv(s, 5000); |
| 13085 | @@ -147,12 +151,16 @@ static int https_server(int s) |
| 13086 | |
| 13087 | wpa_printf(MSG_INFO, "Reading HTTP request"); |
| 13088 | for (;;) { |
| 13089 | - int need_more_data; |
| 13090 | + int need_more_data = 0; |
| 13091 | |
| 13092 | in = https_recv(s, 5000); |
| 13093 | if (!in) |
| 13094 | goto done; |
| 13095 | +#ifdef CONFIG_TLS_INTERNAL_SERVER |
| 13096 | out = tls_connection_decrypt2(tls, conn, in, &need_more_data); |
| 13097 | +#else |
| 13098 | + out = tls_connection_decrypt(tls, conn, in); |
| 13099 | +#endif |
| 13100 | wpabuf_free(in); |
| 13101 | in = NULL; |
| 13102 | if (need_more_data) { |
| 13103 | diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile |
| 13104 | index dd13308f7..c65acab94 100644 |
| 13105 | --- a/wpa_supplicant/Makefile |
| 13106 | +++ b/wpa_supplicant/Makefile |
| 13107 | @@ -10,6 +10,7 @@ ALL += dbus/fi.w1.wpa_supplicant1.service |
| 13108 | EXTRA_TARGETS=dynamic_eap_methods |
| 13109 | |
| 13110 | CONFIG_FILE=.config |
| 13111 | +-include $(if $(MULTICALL),../hostapd/.config) |
| 13112 | include ../src/build.rules |
| 13113 | |
| 13114 | ifdef CONFIG_BUILD_PASN_SO |
| 13115 | @@ -188,6 +189,25 @@ ifdef CONFIG_EAPOL_TEST |
| 13116 | CFLAGS += -Werror -DEAPOL_TEST |
| 13117 | endif |
| 13118 | |
| 13119 | +ifdef CONFIG_UBUS |
| 13120 | +CFLAGS += -DUBUS_SUPPORT |
| 13121 | +OBJS += ubus.o |
| 13122 | +LIBS += -lubus |
| 13123 | +NEED_ULOOP:=y |
| 13124 | +endif |
| 13125 | + |
| 13126 | +ifdef CONFIG_UCODE |
| 13127 | +CFLAGS += -DUCODE_SUPPORT |
| 13128 | +OBJS += ../src/utils/ucode.o |
| 13129 | +OBJS += ucode.o |
| 13130 | +NEED_ULOOP:=y |
| 13131 | +endif |
| 13132 | + |
| 13133 | +ifdef NEED_ULOOP |
| 13134 | +OBJS += ../src/utils/uloop.o |
| 13135 | +LIBS += -lubox |
| 13136 | +endif |
| 13137 | + |
| 13138 | ifdef CONFIG_CODE_COVERAGE |
| 13139 | CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE |
| 13140 | LIBS += -lgcov |
| 13141 | @@ -334,6 +354,7 @@ endif |
| 13142 | ifdef CONFIG_FILS |
| 13143 | CFLAGS += -DCONFIG_FILS |
| 13144 | NEED_SHA384=y |
| 13145 | +NEED_HMAC_SHA384_KDF=y |
| 13146 | NEED_AES_SIV=y |
| 13147 | ifdef CONFIG_FILS_SK_PFS |
| 13148 | CFLAGS += -DCONFIG_FILS_SK_PFS |
| 13149 | @@ -388,7 +409,9 @@ endif |
| 13150 | ifdef CONFIG_IBSS_RSN |
| 13151 | NEED_RSN_AUTHENTICATOR=y |
| 13152 | CFLAGS += -DCONFIG_IBSS_RSN |
| 13153 | +ifndef MULTICALL |
| 13154 | CFLAGS += -DCONFIG_NO_VLAN |
| 13155 | +endif |
| 13156 | OBJS += ibss_rsn.o |
| 13157 | endif |
| 13158 | |
| 13159 | @@ -980,6 +1003,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS |
| 13160 | CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS |
| 13161 | LIBS += -ldl -rdynamic |
| 13162 | endif |
| 13163 | +else |
| 13164 | + ifdef MULTICALL |
| 13165 | + OBJS += ../src/eap_common/eap_common.o |
| 13166 | + endif |
| 13167 | endif |
| 13168 | |
| 13169 | ifdef CONFIG_AP |
| 13170 | @@ -987,9 +1014,11 @@ NEED_EAP_COMMON=y |
| 13171 | NEED_RSN_AUTHENTICATOR=y |
| 13172 | CFLAGS += -DCONFIG_AP |
| 13173 | OBJS += ap.o |
| 13174 | +ifndef MULTICALL |
| 13175 | CFLAGS += -DCONFIG_NO_RADIUS |
| 13176 | CFLAGS += -DCONFIG_NO_ACCOUNTING |
| 13177 | CFLAGS += -DCONFIG_NO_VLAN |
| 13178 | +endif |
| 13179 | OBJS += ../src/ap/hostapd.o |
| 13180 | OBJS += ../src/ap/wpa_auth_glue.o |
| 13181 | OBJS += ../src/ap/utils.o |
| 13182 | @@ -1029,7 +1058,16 @@ ifdef CONFIG_FILS |
| 13183 | OBJS += ../src/ap/fils_hlp.o |
| 13184 | endif |
| 13185 | ifdef CONFIG_CTRL_IFACE |
| 13186 | +ifdef CONFIG_CTRL_IFACE_MIB |
| 13187 | +CFLAGS += -DCONFIG_CTRL_IFACE_MIB |
| 13188 | +endif |
| 13189 | OBJS += ../src/ap/ctrl_iface_ap.o |
| 13190 | +ifdef CONFIG_UBUS |
| 13191 | +OBJS += ../src/ap/ubus.o |
| 13192 | +endif |
| 13193 | +ifdef CONFIG_UCODE |
| 13194 | +OBJS += ../src/ap/ucode.o |
| 13195 | +endif |
| 13196 | endif |
| 13197 | |
| 13198 | CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY |
| 13199 | @@ -1080,6 +1118,12 @@ endif |
| 13200 | ifdef CONFIG_HS20 |
| 13201 | OBJS += ../src/ap/hs20.o |
| 13202 | endif |
| 13203 | +else |
| 13204 | + ifdef MULTICALL |
| 13205 | + OBJS += ../src/eap_server/eap_server.o |
| 13206 | + OBJS += ../src/eap_server/eap_server_identity.o |
| 13207 | + OBJS += ../src/eap_server/eap_server_methods.o |
| 13208 | + endif |
| 13209 | endif |
| 13210 | |
| 13211 | ifdef CONFIG_MBO |
| 13212 | @@ -1089,7 +1133,9 @@ NEED_GAS=y |
| 13213 | endif |
| 13214 | |
| 13215 | ifdef NEED_RSN_AUTHENTICATOR |
| 13216 | +ifndef MULTICALL |
| 13217 | CFLAGS += -DCONFIG_NO_RADIUS |
| 13218 | +endif |
| 13219 | NEED_AES_WRAP=y |
| 13220 | OBJS += ../src/ap/wpa_auth.o |
| 13221 | OBJS += ../src/ap/wpa_auth_ie.o |
| 13222 | @@ -1188,6 +1234,7 @@ TLS_FUNCS=y |
| 13223 | endif |
| 13224 | |
| 13225 | ifeq ($(CONFIG_TLS), wolfssl) |
| 13226 | +CFLAGS += -DCONFIG_TLS_WOLFSSL |
| 13227 | ifdef TLS_FUNCS |
| 13228 | CFLAGS += -DWOLFSSL_DER_LOAD |
| 13229 | OBJS += ../src/crypto/tls_wolfssl.o |
| 13230 | @@ -1203,6 +1250,7 @@ LIBS_p += -lwolfssl -lm |
| 13231 | endif |
| 13232 | |
| 13233 | ifeq ($(CONFIG_TLS), openssl) |
| 13234 | +CFLAGS += -DCONFIG_TLS_OPENSSL |
| 13235 | CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 13236 | ifdef TLS_FUNCS |
| 13237 | CFLAGS += -DEAP_TLS_OPENSSL |
| 13238 | @@ -1229,7 +1277,28 @@ endif |
| 13239 | CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" |
| 13240 | endif |
| 13241 | |
| 13242 | +ifeq ($(CONFIG_TLS), mbedtls) |
| 13243 | +CFLAGS += -DCONFIG_TLS_MBEDTLS |
| 13244 | +ifndef CONFIG_CRYPTO |
| 13245 | +CONFIG_CRYPTO=mbedtls |
| 13246 | +endif |
| 13247 | +ifdef TLS_FUNCS |
| 13248 | +OBJS += ../src/crypto/tls_mbedtls.o |
| 13249 | +LIBS += -lmbedtls -lmbedx509 |
| 13250 | +endif |
| 13251 | +OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 13252 | +OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 13253 | +OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o |
| 13254 | +ifeq ($(CONFIG_CRYPTO), mbedtls) |
| 13255 | +LIBS += -lmbedcrypto |
| 13256 | +LIBS_p += -lmbedcrypto |
| 13257 | +# XXX: create a config option? |
| 13258 | +CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 |
| 13259 | +endif |
| 13260 | +endif |
| 13261 | + |
| 13262 | ifeq ($(CONFIG_TLS), gnutls) |
| 13263 | +CFLAGS += -DCONFIG_TLS_GNUTLS |
| 13264 | ifndef CONFIG_CRYPTO |
| 13265 | # default to libgcrypt |
| 13266 | CONFIG_CRYPTO=gnutls |
| 13267 | @@ -1260,6 +1329,7 @@ endif |
| 13268 | endif |
| 13269 | |
| 13270 | ifeq ($(CONFIG_TLS), internal) |
| 13271 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 13272 | ifndef CONFIG_CRYPTO |
| 13273 | CONFIG_CRYPTO=internal |
| 13274 | endif |
| 13275 | @@ -1340,6 +1410,7 @@ endif |
| 13276 | endif |
| 13277 | |
| 13278 | ifeq ($(CONFIG_TLS), linux) |
| 13279 | +CFLAGS += -DCONFIG_TLS_INTERNAL |
| 13280 | OBJS += ../src/crypto/crypto_linux.o |
| 13281 | OBJS_p += ../src/crypto/crypto_linux.o |
| 13282 | ifdef TLS_FUNCS |
| 13283 | @@ -1421,9 +1492,11 @@ endif |
| 13284 | |
| 13285 | ifneq ($(CONFIG_TLS), openssl) |
| 13286 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13287 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13288 | NEED_INTERNAL_AES_WRAP=y |
| 13289 | endif |
| 13290 | endif |
| 13291 | +endif |
| 13292 | ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP |
| 13293 | # Seems to be needed at least with BoringSSL |
| 13294 | NEED_INTERNAL_AES_WRAP=y |
| 13295 | @@ -1437,9 +1510,11 @@ endif |
| 13296 | |
| 13297 | ifdef NEED_INTERNAL_AES_WRAP |
| 13298 | ifneq ($(CONFIG_TLS), linux) |
| 13299 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13300 | AESOBJS += ../src/crypto/aes-unwrap.o |
| 13301 | endif |
| 13302 | endif |
| 13303 | +endif |
| 13304 | ifdef NEED_AES_EAX |
| 13305 | AESOBJS += ../src/crypto/aes-eax.o |
| 13306 | NEED_AES_CTR=y |
| 13307 | @@ -1449,35 +1524,45 @@ AESOBJS += ../src/crypto/aes-siv.o |
| 13308 | NEED_AES_CTR=y |
| 13309 | endif |
| 13310 | ifdef NEED_AES_CTR |
| 13311 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13312 | AESOBJS += ../src/crypto/aes-ctr.o |
| 13313 | endif |
| 13314 | +endif |
| 13315 | ifdef NEED_AES_ENCBLOCK |
| 13316 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13317 | AESOBJS += ../src/crypto/aes-encblock.o |
| 13318 | endif |
| 13319 | +endif |
| 13320 | NEED_AES_ENC=y |
| 13321 | ifneq ($(CONFIG_TLS), openssl) |
| 13322 | ifneq ($(CONFIG_TLS), linux) |
| 13323 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13324 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13325 | AESOBJS += ../src/crypto/aes-omac1.o |
| 13326 | endif |
| 13327 | endif |
| 13328 | endif |
| 13329 | +endif |
| 13330 | ifdef NEED_AES_WRAP |
| 13331 | NEED_AES_ENC=y |
| 13332 | ifdef NEED_INTERNAL_AES_WRAP |
| 13333 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13334 | AESOBJS += ../src/crypto/aes-wrap.o |
| 13335 | endif |
| 13336 | endif |
| 13337 | +endif |
| 13338 | ifdef NEED_AES_CBC |
| 13339 | NEED_AES_ENC=y |
| 13340 | ifneq ($(CONFIG_TLS), openssl) |
| 13341 | ifneq ($(CONFIG_TLS), linux) |
| 13342 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13343 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13344 | AESOBJS += ../src/crypto/aes-cbc.o |
| 13345 | endif |
| 13346 | endif |
| 13347 | endif |
| 13348 | endif |
| 13349 | +endif |
| 13350 | ifdef NEED_AES_ENC |
| 13351 | ifdef CONFIG_INTERNAL_AES |
| 13352 | AESOBJS += ../src/crypto/aes-internal-enc.o |
| 13353 | @@ -1492,12 +1577,16 @@ ifneq ($(CONFIG_TLS), openssl) |
| 13354 | ifneq ($(CONFIG_TLS), linux) |
| 13355 | ifneq ($(CONFIG_TLS), gnutls) |
| 13356 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13357 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13358 | SHA1OBJS += ../src/crypto/sha1.o |
| 13359 | endif |
| 13360 | endif |
| 13361 | endif |
| 13362 | endif |
| 13363 | +endif |
| 13364 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13365 | SHA1OBJS += ../src/crypto/sha1-prf.o |
| 13366 | +endif |
| 13367 | ifdef CONFIG_INTERNAL_SHA1 |
| 13368 | SHA1OBJS += ../src/crypto/sha1-internal.o |
| 13369 | ifdef NEED_FIPS186_2_PRF |
| 13370 | @@ -1509,29 +1598,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 |
| 13371 | else |
| 13372 | ifneq ($(CONFIG_TLS), openssl) |
| 13373 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13374 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13375 | SHA1OBJS += ../src/crypto/sha1-pbkdf2.o |
| 13376 | endif |
| 13377 | endif |
| 13378 | endif |
| 13379 | +endif |
| 13380 | ifdef NEED_T_PRF |
| 13381 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13382 | SHA1OBJS += ../src/crypto/sha1-tprf.o |
| 13383 | endif |
| 13384 | +endif |
| 13385 | ifdef NEED_TLS_PRF |
| 13386 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13387 | SHA1OBJS += ../src/crypto/sha1-tlsprf.o |
| 13388 | endif |
| 13389 | endif |
| 13390 | +endif |
| 13391 | |
| 13392 | ifndef CONFIG_FIPS |
| 13393 | ifneq ($(CONFIG_TLS), openssl) |
| 13394 | ifneq ($(CONFIG_TLS), linux) |
| 13395 | ifneq ($(CONFIG_TLS), gnutls) |
| 13396 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13397 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13398 | MD5OBJS += ../src/crypto/md5.o |
| 13399 | endif |
| 13400 | endif |
| 13401 | endif |
| 13402 | endif |
| 13403 | endif |
| 13404 | +endif |
| 13405 | ifdef NEED_MD5 |
| 13406 | ifdef CONFIG_INTERNAL_MD5 |
| 13407 | MD5OBJS += ../src/crypto/md5-internal.o |
| 13408 | @@ -1586,12 +1683,17 @@ ifneq ($(CONFIG_TLS), openssl) |
| 13409 | ifneq ($(CONFIG_TLS), linux) |
| 13410 | ifneq ($(CONFIG_TLS), gnutls) |
| 13411 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13412 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13413 | SHA256OBJS += ../src/crypto/sha256.o |
| 13414 | endif |
| 13415 | endif |
| 13416 | endif |
| 13417 | endif |
| 13418 | +endif |
| 13419 | + |
| 13420 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13421 | SHA256OBJS += ../src/crypto/sha256-prf.o |
| 13422 | +endif |
| 13423 | ifdef CONFIG_INTERNAL_SHA256 |
| 13424 | SHA256OBJS += ../src/crypto/sha256-internal.o |
| 13425 | endif |
| 13426 | @@ -1604,50 +1706,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 |
| 13427 | SHA256OBJS += ../src/crypto/sha512-internal.o |
| 13428 | endif |
| 13429 | ifdef NEED_TLS_PRF_SHA256 |
| 13430 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13431 | SHA256OBJS += ../src/crypto/sha256-tlsprf.o |
| 13432 | endif |
| 13433 | +endif |
| 13434 | ifdef NEED_TLS_PRF_SHA384 |
| 13435 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13436 | SHA256OBJS += ../src/crypto/sha384-tlsprf.o |
| 13437 | endif |
| 13438 | +endif |
| 13439 | ifdef NEED_HMAC_SHA256_KDF |
| 13440 | CFLAGS += -DCONFIG_HMAC_SHA256_KDF |
| 13441 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13442 | OBJS += ../src/crypto/sha256-kdf.o |
| 13443 | endif |
| 13444 | +endif |
| 13445 | ifdef NEED_HMAC_SHA384_KDF |
| 13446 | CFLAGS += -DCONFIG_HMAC_SHA384_KDF |
| 13447 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13448 | OBJS += ../src/crypto/sha384-kdf.o |
| 13449 | endif |
| 13450 | +endif |
| 13451 | ifdef NEED_HMAC_SHA512_KDF |
| 13452 | CFLAGS += -DCONFIG_HMAC_SHA512_KDF |
| 13453 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13454 | OBJS += ../src/crypto/sha512-kdf.o |
| 13455 | endif |
| 13456 | +endif |
| 13457 | OBJS += $(SHA256OBJS) |
| 13458 | ifdef NEED_SHA384 |
| 13459 | ifneq ($(CONFIG_TLS), openssl) |
| 13460 | ifneq ($(CONFIG_TLS), linux) |
| 13461 | ifneq ($(CONFIG_TLS), gnutls) |
| 13462 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13463 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13464 | OBJS += ../src/crypto/sha384.o |
| 13465 | endif |
| 13466 | endif |
| 13467 | endif |
| 13468 | endif |
| 13469 | +endif |
| 13470 | CFLAGS += -DCONFIG_SHA384 |
| 13471 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13472 | OBJS += ../src/crypto/sha384-prf.o |
| 13473 | endif |
| 13474 | +endif |
| 13475 | ifdef NEED_SHA512 |
| 13476 | ifneq ($(CONFIG_TLS), openssl) |
| 13477 | ifneq ($(CONFIG_TLS), linux) |
| 13478 | ifneq ($(CONFIG_TLS), gnutls) |
| 13479 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13480 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13481 | OBJS += ../src/crypto/sha512.o |
| 13482 | endif |
| 13483 | endif |
| 13484 | endif |
| 13485 | endif |
| 13486 | +endif |
| 13487 | CFLAGS += -DCONFIG_SHA512 |
| 13488 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13489 | OBJS += ../src/crypto/sha512-prf.o |
| 13490 | endif |
| 13491 | +endif |
| 13492 | |
| 13493 | ifdef NEED_ASN1 |
| 13494 | OBJS += ../src/tls/asn1.o |
| 13495 | @@ -1822,10 +1942,12 @@ ifdef CONFIG_FIPS |
| 13496 | CFLAGS += -DCONFIG_FIPS |
| 13497 | ifneq ($(CONFIG_TLS), openssl) |
| 13498 | ifneq ($(CONFIG_TLS), wolfssl) |
| 13499 | +ifneq ($(CONFIG_TLS), mbedtls) |
| 13500 | $(error CONFIG_FIPS=y requires CONFIG_TLS=openssl) |
| 13501 | endif |
| 13502 | endif |
| 13503 | endif |
| 13504 | +endif |
| 13505 | |
| 13506 | OBJS += $(SHA1OBJS) $(DESOBJS) |
| 13507 | |
| 13508 | @@ -2003,32 +2125,38 @@ wpa_priv: $(BCHECK) $(OBJS_priv) |
| 13509 | |
| 13510 | _OBJS_VAR := OBJS |
| 13511 | include ../src/objs.mk |
| 13512 | +wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) |
| 13513 | + $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c |
| 13514 | + @$(E) " CC " $< |
| 13515 | + @rm -f $@ |
| 13516 | + @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) |
| 13517 | + |
| 13518 | wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) |
| 13519 | - $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) |
| 13520 | + +$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) |
| 13521 | @$(E) " LD " $@ |
| 13522 | |
| 13523 | _OBJS_VAR := OBJS_t |
| 13524 | include ../src/objs.mk |
| 13525 | eapol_test: $(OBJS_t) |
| 13526 | - $(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) |
| 13527 | + +$(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) |
| 13528 | @$(E) " LD " $@ |
| 13529 | |
| 13530 | _OBJS_VAR := OBJS_t2 |
| 13531 | include ../src/objs.mk |
| 13532 | preauth_test: $(OBJS_t2) |
| 13533 | - $(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) |
| 13534 | + +$(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) |
| 13535 | @$(E) " LD " $@ |
| 13536 | |
| 13537 | _OBJS_VAR := OBJS_p |
| 13538 | include ../src/objs.mk |
| 13539 | wpa_passphrase: $(OBJS_p) |
| 13540 | - $(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) |
| 13541 | + +$(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) |
| 13542 | @$(E) " LD " $@ |
| 13543 | |
| 13544 | _OBJS_VAR := OBJS_c |
| 13545 | include ../src/objs.mk |
| 13546 | wpa_cli: $(OBJS_c) |
| 13547 | - $(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) |
| 13548 | + +$(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) |
| 13549 | @$(E) " LD " $@ |
| 13550 | |
| 13551 | LIBCTRL += ../src/common/wpa_ctrl.o |
| 13552 | @@ -2135,6 +2263,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) |
| 13553 | $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ |
| 13554 | @$(E) " sed" $< |
| 13555 | |
| 13556 | +dump_cflags: |
| 13557 | + @printf "%s " "$(CFLAGS)" |
| 13558 | + |
| 13559 | +dump_ldflags: |
| 13560 | + @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" |
| 13561 | + |
| 13562 | wpa_supplicant.exe: wpa_supplicant |
| 13563 | mv -f $< $@ |
| 13564 | wpa_cli.exe: wpa_cli |
| 13565 | diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c |
| 13566 | index 69a0e5ee1..43c39d7ce 100644 |
| 13567 | --- a/wpa_supplicant/ap.c |
| 13568 | +++ b/wpa_supplicant/ap.c |
| 13569 | @@ -1520,7 +1520,7 @@ int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s, |
| 13570 | #endif /* CONFIG_WPS */ |
| 13571 | |
| 13572 | |
| 13573 | -#ifdef CONFIG_CTRL_IFACE |
| 13574 | +#if defined(CONFIG_CTRL_IFACE) && defined(CONFIG_CTRL_IFACE_MIB) |
| 13575 | |
| 13576 | int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s, |
| 13577 | char *buf, size_t buflen) |
| 13578 | @@ -1846,11 +1846,31 @@ int ap_switch_channel(struct wpa_supplicant *wpa_s, |
| 13579 | |
| 13580 | |
| 13581 | #ifdef CONFIG_CTRL_IFACE |
| 13582 | + |
| 13583 | +static int __ap_ctrl_iface_chanswitch(struct hostapd_iface *iface, |
| 13584 | + struct csa_settings *settings) |
| 13585 | +{ |
| 13586 | +#ifdef NEED_AP_MLME |
| 13587 | + if (!iface || !iface->bss[0]) |
| 13588 | + return 0; |
| 13589 | + |
| 13590 | + return hostapd_switch_channel(iface->bss[0], settings); |
| 13591 | +#else |
| 13592 | + return -1; |
| 13593 | +#endif |
| 13594 | +} |
| 13595 | + |
| 13596 | + |
| 13597 | int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) |
| 13598 | { |
| 13599 | struct csa_settings settings; |
| 13600 | int ret = hostapd_parse_csa_settings(pos, &settings); |
| 13601 | |
| 13602 | + if (!(wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) && |
| 13603 | + !(wpa_s->ifmsh && wpa_s->ifmsh->bss[0])) |
| 13604 | + return -1; |
| 13605 | + |
| 13606 | + ret = __ap_ctrl_iface_chanswitch(wpa_s->ap_iface, &settings); |
| 13607 | if (ret) |
| 13608 | return ret; |
| 13609 | |
| 13610 | diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c |
| 13611 | index 2c756136c..c3943355d 100644 |
| 13612 | --- a/wpa_supplicant/config.c |
| 13613 | +++ b/wpa_supplicant/config.c |
| 13614 | @@ -18,6 +18,7 @@ |
| 13615 | #include "eap_peer/eap.h" |
| 13616 | #include "p2p/p2p.h" |
| 13617 | #include "fst/fst.h" |
| 13618 | +#include "ap/sta_info.h" |
| 13619 | #include "config.h" |
| 13620 | |
| 13621 | |
| 13622 | @@ -2421,6 +2422,97 @@ static char * wpa_config_write_mac_value(const struct parse_data *data, |
| 13623 | #endif /* NO_CONFIG_WRITE */ |
| 13624 | |
| 13625 | |
| 13626 | +static int wpa_config_parse_mcast_rate(const struct parse_data *data, |
| 13627 | + struct wpa_ssid *ssid, int line, |
| 13628 | + const char *value) |
| 13629 | +{ |
| 13630 | + ssid->mcast_rate = (int)(strtod(value, NULL) * 10); |
| 13631 | + |
| 13632 | + return 0; |
| 13633 | +} |
| 13634 | + |
| 13635 | +#ifndef NO_CONFIG_WRITE |
| 13636 | +static char * wpa_config_write_mcast_rate(const struct parse_data *data, |
| 13637 | + struct wpa_ssid *ssid) |
| 13638 | +{ |
| 13639 | + char *value; |
| 13640 | + int res; |
| 13641 | + |
| 13642 | + if (!ssid->mcast_rate == 0) |
| 13643 | + return NULL; |
| 13644 | + |
| 13645 | + value = os_malloc(6); /* longest: 300.0 */ |
| 13646 | + if (value == NULL) |
| 13647 | + return NULL; |
| 13648 | + res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10); |
| 13649 | + if (res < 0) { |
| 13650 | + os_free(value); |
| 13651 | + return NULL; |
| 13652 | + } |
| 13653 | + return value; |
| 13654 | +} |
| 13655 | +#endif /* NO_CONFIG_WRITE */ |
| 13656 | + |
| 13657 | +static int wpa_config_parse_rates(const struct parse_data *data, |
| 13658 | + struct wpa_ssid *ssid, int line, |
| 13659 | + const char *value) |
| 13660 | +{ |
| 13661 | + int i; |
| 13662 | + char *pos, *r, *sptr, *end; |
| 13663 | + double rate; |
| 13664 | + |
| 13665 | + pos = (char *)value; |
| 13666 | + r = strtok_r(pos, ",", &sptr); |
| 13667 | + i = 0; |
| 13668 | + while (pos && i < WLAN_SUPP_RATES_MAX) { |
| 13669 | + rate = 0.0; |
| 13670 | + if (r) |
| 13671 | + rate = strtod(r, &end); |
| 13672 | + ssid->rates[i] = rate * 2; |
| 13673 | + if (*end != '\0' || rate * 2 != ssid->rates[i]) |
| 13674 | + return 1; |
| 13675 | + |
| 13676 | + i++; |
| 13677 | + r = strtok_r(NULL, ",", &sptr); |
| 13678 | + } |
| 13679 | + |
| 13680 | + return 0; |
| 13681 | +} |
| 13682 | + |
| 13683 | +#ifndef NO_CONFIG_WRITE |
| 13684 | +static char * wpa_config_write_rates(const struct parse_data *data, |
| 13685 | + struct wpa_ssid *ssid) |
| 13686 | +{ |
| 13687 | + char *value, *pos; |
| 13688 | + int res, i; |
| 13689 | + |
| 13690 | + if (ssid->rates[0] <= 0) |
| 13691 | + return NULL; |
| 13692 | + |
| 13693 | + value = os_malloc(6 * WLAN_SUPP_RATES_MAX + 1); |
| 13694 | + if (value == NULL) |
| 13695 | + return NULL; |
| 13696 | + pos = value; |
| 13697 | + for (i = 0; i < WLAN_SUPP_RATES_MAX - 1; i++) { |
| 13698 | + res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2); |
| 13699 | + if (res < 0) { |
| 13700 | + os_free(value); |
| 13701 | + return NULL; |
| 13702 | + } |
| 13703 | + pos += res; |
| 13704 | + } |
| 13705 | + res = os_snprintf(pos, 6, "%.1f", |
| 13706 | + (double)ssid->rates[WLAN_SUPP_RATES_MAX - 1] / 2); |
| 13707 | + if (res < 0) { |
| 13708 | + os_free(value); |
| 13709 | + return NULL; |
| 13710 | + } |
| 13711 | + |
| 13712 | + value[6 * WLAN_SUPP_RATES_MAX] = '\0'; |
| 13713 | + return value; |
| 13714 | +} |
| 13715 | +#endif /* NO_CONFIG_WRITE */ |
| 13716 | + |
| 13717 | /* Helper macros for network block parser */ |
| 13718 | |
| 13719 | #ifdef OFFSET |
| 13720 | @@ -2639,6 +2731,7 @@ static const struct parse_data ssid_fields[] = { |
| 13721 | #else /* CONFIG_MESH */ |
| 13722 | { INT_RANGE(mode, 0, 4) }, |
| 13723 | #endif /* CONFIG_MESH */ |
| 13724 | + { INT_RANGE(noscan, 0, 1) }, |
| 13725 | { INT_RANGE(proactive_key_caching, 0, 1) }, |
| 13726 | { INT_RANGE(disabled, 0, 2) }, |
| 13727 | { STR(id_str) }, |
| 13728 | @@ -2712,6 +2805,8 @@ static const struct parse_data ssid_fields[] = { |
| 13729 | { INT(ap_max_inactivity) }, |
| 13730 | { INT(dtim_period) }, |
| 13731 | { INT(beacon_int) }, |
| 13732 | + { FUNC(rates) }, |
| 13733 | + { FUNC(mcast_rate) }, |
| 13734 | #ifdef CONFIG_MACSEC |
| 13735 | { INT_RANGE(macsec_policy, 0, 1) }, |
| 13736 | { INT_RANGE(macsec_integ_only, 0, 1) }, |
| 13737 | diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c |
| 13738 | index 1a2c0c9be..7a3ed6373 100644 |
| 13739 | --- a/wpa_supplicant/config_file.c |
| 13740 | +++ b/wpa_supplicant/config_file.c |
| 13741 | @@ -326,8 +326,13 @@ struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp, |
| 13742 | while (cred_tail && cred_tail->next) |
| 13743 | cred_tail = cred_tail->next; |
| 13744 | |
| 13745 | + if (!strncmp(name, "data:", 5)) { |
| 13746 | + f = fmemopen((void *)(name + 5), strlen(name + 5), "r"); |
| 13747 | + name = "<inline>"; |
| 13748 | + } else { |
| 13749 | + f = fopen(name, "r"); |
| 13750 | + } |
| 13751 | wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); |
| 13752 | - f = fopen(name, "r"); |
| 13753 | if (f == NULL) { |
| 13754 | wpa_printf(MSG_ERROR, "Failed to open config file '%s', " |
| 13755 | "error: %s", name, strerror(errno)); |
| 13756 | @@ -775,6 +780,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) |
| 13757 | #endif /* IEEE8021X_EAPOL */ |
| 13758 | INT(mode); |
| 13759 | INT(no_auto_peer); |
| 13760 | + INT(noscan); |
| 13761 | INT(mesh_fwding); |
| 13762 | INT(frequency); |
| 13763 | INT(enable_edmg); |
| 13764 | diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h |
| 13765 | index e40650c27..de79972b6 100644 |
| 13766 | --- a/wpa_supplicant/config_ssid.h |
| 13767 | +++ b/wpa_supplicant/config_ssid.h |
| 13768 | @@ -10,8 +10,10 @@ |
| 13769 | #define CONFIG_SSID_H |
| 13770 | |
| 13771 | #include "common/defs.h" |
| 13772 | +#include "ap/sta_info.h" |
| 13773 | #include "utils/list.h" |
| 13774 | #include "eap_peer/eap_config.h" |
| 13775 | +#include "drivers/nl80211_copy.h" |
| 13776 | |
| 13777 | |
| 13778 | #define DEFAULT_EAP_WORKAROUND ((unsigned int) -1) |
| 13779 | @@ -879,6 +881,9 @@ struct wpa_ssid { |
| 13780 | */ |
| 13781 | void *parent_cred; |
| 13782 | |
| 13783 | + unsigned char rates[WLAN_SUPP_RATES_MAX]; |
| 13784 | + double mcast_rate; |
| 13785 | + |
| 13786 | #ifdef CONFIG_MACSEC |
| 13787 | /** |
| 13788 | * macsec_policy - Determines the policy for MACsec secure session |
| 13789 | @@ -1035,6 +1040,8 @@ struct wpa_ssid { |
| 13790 | */ |
| 13791 | int no_auto_peer; |
| 13792 | |
| 13793 | + int noscan; |
| 13794 | + |
| 13795 | /** |
| 13796 | * mesh_rssi_threshold - Set mesh parameter mesh_rssi_threshold (dBm) |
| 13797 | * |
| 13798 | diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c |
| 13799 | index d0fda4cd9..ec45f29bb 100644 |
| 13800 | --- a/wpa_supplicant/ctrl_iface.c |
| 13801 | +++ b/wpa_supplicant/ctrl_iface.c |
| 13802 | @@ -2355,7 +2355,7 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, |
| 13803 | pos += ret; |
| 13804 | } |
| 13805 | |
| 13806 | -#ifdef CONFIG_AP |
| 13807 | +#if defined(CONFIG_AP) && defined(CONFIG_CTRL_IFACE_MIB) |
| 13808 | if (wpa_s->ap_iface) { |
| 13809 | pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, |
| 13810 | end - pos, |
| 13811 | @@ -12542,6 +12542,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
| 13812 | reply_len = -1; |
| 13813 | } else if (os_strncmp(buf, "NOTE ", 5) == 0) { |
| 13814 | wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); |
| 13815 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 13816 | } else if (os_strcmp(buf, "MIB") == 0) { |
| 13817 | reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); |
| 13818 | if (reply_len >= 0) { |
| 13819 | @@ -12554,6 +12555,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
| 13820 | reply_size - reply_len); |
| 13821 | #endif /* CONFIG_MACSEC */ |
| 13822 | } |
| 13823 | +#endif |
| 13824 | } else if (os_strncmp(buf, "STATUS", 6) == 0) { |
| 13825 | reply_len = wpa_supplicant_ctrl_iface_status( |
| 13826 | wpa_s, buf + 6, reply, reply_size); |
| 13827 | @@ -13042,6 +13044,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
| 13828 | reply_len = wpa_supplicant_ctrl_iface_bss( |
| 13829 | wpa_s, buf + 4, reply, reply_size); |
| 13830 | #ifdef CONFIG_AP |
| 13831 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 13832 | } else if (os_strcmp(buf, "STA-FIRST") == 0) { |
| 13833 | reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); |
| 13834 | } else if (os_strncmp(buf, "STA ", 4) == 0) { |
| 13835 | @@ -13050,12 +13053,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
| 13836 | } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { |
| 13837 | reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, |
| 13838 | reply_size); |
| 13839 | +#endif |
| 13840 | +#ifdef CONFIG_CTRL_IFACE_MIB |
| 13841 | } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { |
| 13842 | if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) |
| 13843 | reply_len = -1; |
| 13844 | } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) { |
| 13845 | if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13)) |
| 13846 | reply_len = -1; |
| 13847 | +#endif |
| 13848 | } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { |
| 13849 | if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12)) |
| 13850 | reply_len = -1; |
| 13851 | @@ -13214,7 +13220,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
| 13852 | if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18)) |
| 13853 | reply_len = -1; |
| 13854 | #endif /* CONFIG_WNM */ |
| 13855 | -#ifdef CONFIG_WNM_AP |
| 13856 | +#if defined(CONFIG_AP) && defined(CONFIG_WNM_AP) |
| 13857 | } else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) { |
| 13858 | if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18)) |
| 13859 | reply_len = -1; |
| 13860 | @@ -13224,7 +13230,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, |
| 13861 | } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) { |
| 13862 | if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11)) |
| 13863 | reply_len = -1; |
| 13864 | -#endif /* CONFIG_WNM_AP */ |
| 13865 | +#endif /* CONFIG_AP && CONFIG_WNM_AP */ |
| 13866 | } else if (os_strcmp(buf, "FLUSH") == 0) { |
| 13867 | wpa_supplicant_ctrl_iface_flush(wpa_s); |
| 13868 | } else if (os_strncmp(buf, "RADIO_WORK ", 11) == 0) { |
| 13869 | diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig |
| 13870 | index 52befd8f1..ace6c5530 100644 |
| 13871 | --- a/wpa_supplicant/defconfig |
| 13872 | +++ b/wpa_supplicant/defconfig |
| 13873 | @@ -10,8 +10,8 @@ |
| 13874 | # to override previous values of the variables. |
| 13875 | |
| 13876 | |
| 13877 | -# Uncomment following two lines and fix the paths if you have installed OpenSSL |
| 13878 | -# or GnuTLS in non-default location |
| 13879 | +# Uncomment following two lines and fix the paths if you have installed TLS |
| 13880 | +# libraries in a non-default location |
| 13881 | #CFLAGS += -I/usr/local/openssl/include |
| 13882 | #LIBS += -L/usr/local/openssl/lib |
| 13883 | |
| 13884 | @@ -20,6 +20,7 @@ |
| 13885 | # used to fix build issues on such systems (krb5.h not found). |
| 13886 | #CFLAGS += -I/usr/include/kerberos |
| 13887 | |
| 13888 | + |
| 13889 | # Driver interface for generic Linux wireless extensions |
| 13890 | # Note: WEXT is deprecated in the current Linux kernel version and no new |
| 13891 | # functionality is added to it. nl80211-based interface is the new |
| 13892 | @@ -329,6 +330,7 @@ CONFIG_BACKEND=file |
| 13893 | # openssl = OpenSSL (default) |
| 13894 | # gnutls = GnuTLS |
| 13895 | # internal = Internal TLSv1 implementation (experimental) |
| 13896 | +# mbedtls = mbed TLS |
| 13897 | # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) |
| 13898 | # none = Empty template |
| 13899 | #CONFIG_TLS=openssl |
| 13900 | diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c |
| 13901 | index 95953de92..673c3cc11 100644 |
| 13902 | --- a/wpa_supplicant/eapol_test.c |
| 13903 | +++ b/wpa_supplicant/eapol_test.c |
| 13904 | @@ -31,7 +31,12 @@ |
| 13905 | #include "ctrl_iface.h" |
| 13906 | #include "pcsc_funcs.h" |
| 13907 | #include "wpas_glue.h" |
| 13908 | +#include "drivers/driver.h" |
| 13909 | |
| 13910 | +void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, |
| 13911 | + union wpa_event_data *data); |
| 13912 | +void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, |
| 13913 | + union wpa_event_data *data); |
| 13914 | |
| 13915 | const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; |
| 13916 | |
| 13917 | @@ -1325,6 +1330,10 @@ static void usage(void) |
| 13918 | "option several times.\n"); |
| 13919 | } |
| 13920 | |
| 13921 | +extern void supplicant_event(void *ctx, enum wpa_event_type event, |
| 13922 | + union wpa_event_data *data); |
| 13923 | +extern void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 13924 | + union wpa_event_data *data); |
| 13925 | |
| 13926 | int main(int argc, char *argv[]) |
| 13927 | { |
| 13928 | @@ -1348,6 +1357,8 @@ int main(int argc, char *argv[]) |
| 13929 | if (os_program_init()) |
| 13930 | return -1; |
| 13931 | |
| 13932 | + wpa_supplicant_event = supplicant_event; |
| 13933 | + wpa_supplicant_event_global = supplicant_event_global; |
| 13934 | hostapd_logger_register_cb(hostapd_logger_cb); |
| 13935 | |
| 13936 | os_memset(&eapol_test, 0, sizeof(eapol_test)); |
| 13937 | diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c |
| 13938 | index ca2794638..2a9342318 100644 |
| 13939 | --- a/wpa_supplicant/events.c |
| 13940 | +++ b/wpa_supplicant/events.c |
| 13941 | @@ -2935,8 +2935,6 @@ void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s) |
| 13942 | } |
| 13943 | |
| 13944 | |
| 13945 | -#ifdef CONFIG_INTERWORKING |
| 13946 | - |
| 13947 | static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map, |
| 13948 | size_t len) |
| 13949 | { |
| 13950 | @@ -2969,8 +2967,6 @@ static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s, |
| 13951 | } |
| 13952 | } |
| 13953 | |
| 13954 | -#endif /* CONFIG_INTERWORKING */ |
| 13955 | - |
| 13956 | |
| 13957 | static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) |
| 13958 | { |
| 13959 | @@ -3349,10 +3345,8 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, |
| 13960 | wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, |
| 13961 | data->assoc_info.resp_ies_len); |
| 13962 | #endif /* CONFIG_WNM */ |
| 13963 | -#ifdef CONFIG_INTERWORKING |
| 13964 | interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, |
| 13965 | data->assoc_info.resp_ies_len); |
| 13966 | -#endif /* CONFIG_INTERWORKING */ |
| 13967 | if (wpa_s->hw_capab == CAPAB_VHT && |
| 13968 | get_ie(data->assoc_info.resp_ies, |
| 13969 | data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP)) |
| 13970 | @@ -5928,8 +5922,8 @@ static void wpas_link_reconfig(struct wpa_supplicant *wpa_s) |
| 13971 | } |
| 13972 | |
| 13973 | |
| 13974 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 13975 | - union wpa_event_data *data) |
| 13976 | +void supplicant_event(void *ctx, enum wpa_event_type event, |
| 13977 | + union wpa_event_data *data) |
| 13978 | { |
| 13979 | struct wpa_supplicant *wpa_s = ctx; |
| 13980 | int resched; |
| 13981 | @@ -5964,6 +5958,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 13982 | event_to_string(event), event); |
| 13983 | #endif /* CONFIG_NO_STDOUT_DEBUG */ |
| 13984 | |
| 13985 | + wpas_ucode_event(wpa_s, event, data); |
| 13986 | switch (event) { |
| 13987 | case EVENT_AUTH: |
| 13988 | #ifdef CONFIG_FST |
| 13989 | @@ -6881,7 +6876,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 13990 | } |
| 13991 | |
| 13992 | |
| 13993 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 13994 | +void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 13995 | union wpa_event_data *data) |
| 13996 | { |
| 13997 | struct wpa_supplicant *wpa_s; |
| 13998 | diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c |
| 13999 | index 9229eb51f..ee152c5b9 100644 |
| 14000 | --- a/wpa_supplicant/main.c |
| 14001 | +++ b/wpa_supplicant/main.c |
| 14002 | @@ -12,6 +12,7 @@ |
| 14003 | #endif /* __linux__ */ |
| 14004 | |
| 14005 | #include "common.h" |
| 14006 | +#include "build_features.h" |
| 14007 | #include "crypto/crypto.h" |
| 14008 | #include "fst/fst.h" |
| 14009 | #include "wpa_supplicant_i.h" |
| 14010 | @@ -202,7 +203,7 @@ int main(int argc, char *argv[]) |
| 14011 | |
| 14012 | for (;;) { |
| 14013 | c = getopt(argc, argv, |
| 14014 | - "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); |
| 14015 | + "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W"); |
| 14016 | if (c < 0) |
| 14017 | break; |
| 14018 | switch (c) { |
| 14019 | @@ -267,6 +268,9 @@ int main(int argc, char *argv[]) |
| 14020 | params.conf_p2p_dev = optarg; |
| 14021 | break; |
| 14022 | #endif /* CONFIG_P2P */ |
| 14023 | + case 'n': |
| 14024 | + iface_count = 0; |
| 14025 | + break; |
| 14026 | case 'o': |
| 14027 | params.override_driver = optarg; |
| 14028 | break; |
| 14029 | @@ -302,8 +306,12 @@ int main(int argc, char *argv[]) |
| 14030 | break; |
| 14031 | #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ |
| 14032 | case 'v': |
| 14033 | - printf("%s\n", wpa_supplicant_version); |
| 14034 | - exitcode = 0; |
| 14035 | + if (optarg) { |
| 14036 | + exitcode = !has_feature(optarg); |
| 14037 | + } else { |
| 14038 | + printf("%s\n", wpa_supplicant_version); |
| 14039 | + exitcode = 0; |
| 14040 | + } |
| 14041 | goto out; |
| 14042 | case 'W': |
| 14043 | params.wait_for_monitor++; |
| 14044 | diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c |
| 14045 | index 85c1ea8ba..dabbb0334 100644 |
| 14046 | --- a/wpa_supplicant/mesh.c |
| 14047 | +++ b/wpa_supplicant/mesh.c |
| 14048 | @@ -506,6 +506,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, |
| 14049 | frequency); |
| 14050 | goto out_free; |
| 14051 | } |
| 14052 | + if (conf->noscan) |
| 14053 | + ssid->noscan = 1; |
| 14054 | |
| 14055 | if (ssid->mesh_basic_rates == NULL) { |
| 14056 | /* |
| 14057 | @@ -630,6 +632,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, |
| 14058 | |
| 14059 | params->meshid = ssid->ssid; |
| 14060 | params->meshid_len = ssid->ssid_len; |
| 14061 | + params->mcast_rate = ssid->mcast_rate; |
| 14062 | ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); |
| 14063 | wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; |
| 14064 | wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; |
| 14065 | diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c |
| 14066 | index 60f85624f..67352a121 100644 |
| 14067 | --- a/wpa_supplicant/wpa_cli.c |
| 14068 | +++ b/wpa_supplicant/wpa_cli.c |
| 14069 | @@ -26,6 +26,15 @@ |
| 14070 | #include <cutils/properties.h> |
| 14071 | #endif /* ANDROID */ |
| 14072 | |
| 14073 | +#ifndef CONFIG_P2P |
| 14074 | +#define CONFIG_P2P |
| 14075 | +#endif |
| 14076 | +#ifndef CONFIG_AP |
| 14077 | +#define CONFIG_AP |
| 14078 | +#endif |
| 14079 | +#ifndef CONFIG_MESH |
| 14080 | +#define CONFIG_MESH |
| 14081 | +#endif |
| 14082 | |
| 14083 | static const char *const wpa_cli_version = |
| 14084 | "wpa_cli v" VERSION_STR "\n" |
| 14085 | diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c |
| 14086 | index 88f3f2a52..92efe5629 100644 |
| 14087 | --- a/wpa_supplicant/wpa_priv.c |
| 14088 | +++ b/wpa_supplicant/wpa_priv.c |
| 14089 | @@ -1042,8 +1042,8 @@ static void wpa_priv_send_ft_response(struct wpa_priv_interface *iface, |
| 14090 | } |
| 14091 | |
| 14092 | |
| 14093 | -void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 14094 | - union wpa_event_data *data) |
| 14095 | +static void supplicant_event(void *ctx, enum wpa_event_type event, |
| 14096 | + union wpa_event_data *data) |
| 14097 | { |
| 14098 | struct wpa_priv_interface *iface = ctx; |
| 14099 | |
| 14100 | @@ -1106,7 +1106,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, |
| 14101 | } |
| 14102 | |
| 14103 | |
| 14104 | -void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14105 | +void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14106 | union wpa_event_data *data) |
| 14107 | { |
| 14108 | struct wpa_priv_global *global = ctx; |
| 14109 | @@ -1220,6 +1220,8 @@ int main(int argc, char *argv[]) |
| 14110 | if (os_program_init()) |
| 14111 | return -1; |
| 14112 | |
| 14113 | + wpa_supplicant_event = supplicant_event; |
| 14114 | + wpa_supplicant_event_global = supplicant_event_global; |
| 14115 | wpa_priv_fd_workaround(); |
| 14116 | |
| 14117 | os_memset(&global, 0, sizeof(global)); |
| 14118 | diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c |
| 14119 | index ab71e2f27..fea84fe49 100644 |
| 14120 | --- a/wpa_supplicant/wpa_supplicant.c |
| 14121 | +++ b/wpa_supplicant/wpa_supplicant.c |
| 14122 | @@ -1060,6 +1060,7 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, |
| 14123 | sme_sched_obss_scan(wpa_s, 0); |
| 14124 | } |
| 14125 | wpa_s->wpa_state = state; |
| 14126 | + wpas_ucode_update_state(wpa_s); |
| 14127 | |
| 14128 | #ifdef CONFIG_BGSCAN |
| 14129 | if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) |
| 14130 | @@ -2698,7 +2699,7 @@ static int drv_supports_vht(struct wpa_supplicant *wpa_s, |
| 14131 | } |
| 14132 | |
| 14133 | |
| 14134 | -static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode) |
| 14135 | +static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode, bool dfs_enabled) |
| 14136 | { |
| 14137 | int i; |
| 14138 | |
| 14139 | @@ -2707,7 +2708,10 @@ static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode) |
| 14140 | |
| 14141 | chan = hw_get_channel_chan(mode, i, NULL); |
| 14142 | if (!chan || |
| 14143 | - chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) |
| 14144 | + chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14145 | + return false; |
| 14146 | + |
| 14147 | + if (!dfs_enabled && chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) |
| 14148 | return false; |
| 14149 | } |
| 14150 | |
| 14151 | @@ -2767,7 +2771,7 @@ static bool ibss_mesh_can_use_vht(struct wpa_supplicant *wpa_s, |
| 14152 | const struct wpa_ssid *ssid, |
| 14153 | struct hostapd_hw_modes *mode) |
| 14154 | { |
| 14155 | - if (mode->mode != HOSTAPD_MODE_IEEE80211A) |
| 14156 | + if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) |
| 14157 | return false; |
| 14158 | |
| 14159 | if (!drv_supports_vht(wpa_s, ssid)) |
| 14160 | @@ -2834,12 +2838,13 @@ static void ibss_mesh_select_40mhz(struct wpa_supplicant *wpa_s, |
| 14161 | const struct wpa_ssid *ssid, |
| 14162 | struct hostapd_hw_modes *mode, |
| 14163 | struct hostapd_freq_params *freq, |
| 14164 | - int obss_scan) { |
| 14165 | + int obss_scan, bool dfs_enabled) { |
| 14166 | int chan_idx; |
| 14167 | struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; |
| 14168 | int i, res; |
| 14169 | unsigned int j; |
| 14170 | static const int ht40plus[] = { |
| 14171 | + 1, 2, 3, 4, 5, 6, 7, |
| 14172 | 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, |
| 14173 | 149, 157, 165, 173, 184, 192 |
| 14174 | }; |
| 14175 | @@ -2858,8 +2863,11 @@ static void ibss_mesh_select_40mhz(struct wpa_supplicant *wpa_s, |
| 14176 | return; |
| 14177 | |
| 14178 | /* Check primary channel flags */ |
| 14179 | - if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) |
| 14180 | + if (pri_chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14181 | return; |
| 14182 | + if (pri_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) |
| 14183 | + if (!dfs_enabled) |
| 14184 | + return; |
| 14185 | |
| 14186 | #ifdef CONFIG_HT_OVERRIDES |
| 14187 | if (ssid->disable_ht40) |
| 14188 | @@ -2885,8 +2893,11 @@ static void ibss_mesh_select_40mhz(struct wpa_supplicant *wpa_s, |
| 14189 | return; |
| 14190 | |
| 14191 | /* Check secondary channel flags */ |
| 14192 | - if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) |
| 14193 | + if (sec_chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14194 | return; |
| 14195 | + if (sec_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) |
| 14196 | + if (!dfs_enabled) |
| 14197 | + return; |
| 14198 | |
| 14199 | if (ht40 == -1) { |
| 14200 | if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) |
| 14201 | @@ -2941,7 +2952,7 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
| 14202 | const struct wpa_ssid *ssid, |
| 14203 | struct hostapd_hw_modes *mode, |
| 14204 | struct hostapd_freq_params *freq, |
| 14205 | - int ieee80211_mode, bool is_6ghz) { |
| 14206 | + int ieee80211_mode, bool is_6ghz, bool dfs_enabled) { |
| 14207 | static const int bw80[] = { |
| 14208 | 5180, 5260, 5500, 5580, 5660, 5745, 5825, |
| 14209 | 5955, 6035, 6115, 6195, 6275, 6355, 6435, |
| 14210 | @@ -2986,7 +2997,7 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
| 14211 | goto skip_80mhz; |
| 14212 | |
| 14213 | /* Use 40 MHz if channel not usable */ |
| 14214 | - if (!ibss_mesh_is_80mhz_avail(channel, mode)) |
| 14215 | + if (!ibss_mesh_is_80mhz_avail(channel, mode, dfs_enabled)) |
| 14216 | goto skip_80mhz; |
| 14217 | |
| 14218 | chwidth = CONF_OPER_CHWIDTH_80MHZ; |
| 14219 | @@ -3000,7 +3011,7 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
| 14220 | if ((mode->he_capab[ieee80211_mode].phy_cap[ |
| 14221 | HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & |
| 14222 | HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz && |
| 14223 | - ibss_mesh_is_80mhz_avail(channel + 16, mode)) { |
| 14224 | + ibss_mesh_is_80mhz_avail(channel + 16, mode, dfs_enabled)) { |
| 14225 | for (j = 0; j < ARRAY_SIZE(bw160); j++) { |
| 14226 | if (freq->freq == bw160[j]) { |
| 14227 | chwidth = CONF_OPER_CHWIDTH_160MHZ; |
| 14228 | @@ -3028,10 +3039,12 @@ static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s, |
| 14229 | if (!chan) |
| 14230 | continue; |
| 14231 | |
| 14232 | - if (chan->flag & (HOSTAPD_CHAN_DISABLED | |
| 14233 | - HOSTAPD_CHAN_NO_IR | |
| 14234 | - HOSTAPD_CHAN_RADAR)) |
| 14235 | + if (chan->flag & HOSTAPD_CHAN_DISABLED) |
| 14236 | continue; |
| 14237 | + if (chan->flag & (HOSTAPD_CHAN_RADAR | |
| 14238 | + HOSTAPD_CHAN_NO_IR)) |
| 14239 | + if (!dfs_enabled) |
| 14240 | + continue; |
| 14241 | |
| 14242 | /* Found a suitable second segment for 80+80 */ |
| 14243 | chwidth = CONF_OPER_CHWIDTH_80P80MHZ; |
| 14244 | @@ -3083,12 +3096,17 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, |
| 14245 | int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode); |
| 14246 | enum hostapd_hw_mode hw_mode; |
| 14247 | struct hostapd_hw_modes *mode = NULL; |
| 14248 | - int i, obss_scan = 1; |
| 14249 | + int i, obss_scan = !(ssid->noscan); |
| 14250 | u8 channel; |
| 14251 | bool is_6ghz, is_24ghz; |
| 14252 | + bool dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); |
| 14253 | |
| 14254 | freq->freq = ssid->frequency; |
| 14255 | |
| 14256 | + if (ssid->fixed_freq) { |
| 14257 | + obss_scan = 0; |
| 14258 | + } |
| 14259 | + |
| 14260 | if (ssid->mode == WPAS_MODE_IBSS && !ssid->fixed_freq) { |
| 14261 | struct wpa_bss *bss = ibss_find_existing_bss(wpa_s, ssid); |
| 14262 | |
| 14263 | @@ -3132,11 +3150,13 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, |
| 14264 | freq->he_enabled = ibss_mesh_can_use_he(wpa_s, ssid, mode, |
| 14265 | ieee80211_mode); |
| 14266 | freq->channel = channel; |
| 14267 | + if (mode->mode == HOSTAPD_MODE_IEEE80211G && ssid->noscan) |
| 14268 | + ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); |
| 14269 | /* Setup higher BW only for 5 GHz */ |
| 14270 | if (mode->mode == HOSTAPD_MODE_IEEE80211A) { |
| 14271 | - ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan); |
| 14272 | + ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); |
| 14273 | if (!ibss_mesh_select_80_160mhz(wpa_s, ssid, mode, freq, |
| 14274 | - ieee80211_mode, is_6ghz)) |
| 14275 | + ieee80211_mode, is_6ghz, dfs_enabled)) |
| 14276 | freq->he_enabled = freq->vht_enabled = false; |
| 14277 | } |
| 14278 | |
| 14279 | @@ -4240,6 +4260,12 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) |
| 14280 | params.beacon_int = ssid->beacon_int; |
| 14281 | else |
| 14282 | params.beacon_int = wpa_s->conf->beacon_int; |
| 14283 | + int i = 0; |
| 14284 | + while (i < WLAN_SUPP_RATES_MAX) { |
| 14285 | + params.rates[i] = ssid->rates[i]; |
| 14286 | + i++; |
| 14287 | + } |
| 14288 | + params.mcast_rate = ssid->mcast_rate; |
| 14289 | } |
| 14290 | |
| 14291 | if (bss && ssid->enable_edmg) |
| 14292 | @@ -5861,7 +5887,7 @@ wpa_supplicant_alloc(struct wpa_supplicant *parent) |
| 14293 | if (wpa_s == NULL) |
| 14294 | return NULL; |
| 14295 | wpa_s->scan_req = INITIAL_SCAN_REQ; |
| 14296 | - wpa_s->scan_interval = 5; |
| 14297 | + wpa_s->scan_interval = 1; |
| 14298 | wpa_s->new_connection = 1; |
| 14299 | wpa_s->parent = parent ? parent : wpa_s; |
| 14300 | wpa_s->p2pdev = wpa_s->parent; |
| 14301 | @@ -7576,7 +7602,6 @@ struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global, |
| 14302 | return NULL; |
| 14303 | } |
| 14304 | |
| 14305 | - |
| 14306 | /** |
| 14307 | * wpa_supplicant_match_existing - Match existing interfaces |
| 14308 | * @global: Pointer to global data from wpa_supplicant_init() |
| 14309 | @@ -7611,6 +7636,11 @@ static int wpa_supplicant_match_existing(struct wpa_global *global) |
| 14310 | |
| 14311 | #endif /* CONFIG_MATCH_IFACE */ |
| 14312 | |
| 14313 | +extern void supplicant_event(void *ctx, enum wpa_event_type event, |
| 14314 | + union wpa_event_data *data); |
| 14315 | + |
| 14316 | +extern void supplicant_event_global(void *ctx, enum wpa_event_type event, |
| 14317 | + union wpa_event_data *data); |
| 14318 | |
| 14319 | /** |
| 14320 | * wpa_supplicant_add_iface - Add a new network interface |
| 14321 | @@ -7693,6 +7723,9 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, |
| 14322 | } |
| 14323 | #endif /* CONFIG_P2P */ |
| 14324 | |
| 14325 | + wpas_ubus_add_bss(wpa_s); |
| 14326 | + wpas_ucode_add_bss(wpa_s); |
| 14327 | + |
| 14328 | return wpa_s; |
| 14329 | } |
| 14330 | |
| 14331 | @@ -7719,6 +7752,9 @@ int wpa_supplicant_remove_iface(struct wpa_global *global, |
| 14332 | struct wpa_supplicant *parent = wpa_s->parent; |
| 14333 | #endif /* CONFIG_MESH */ |
| 14334 | |
| 14335 | + wpas_ucode_free_bss(wpa_s); |
| 14336 | + wpas_ubus_free_bss(wpa_s); |
| 14337 | + |
| 14338 | /* Remove interface from the global list of interfaces */ |
| 14339 | prev = global->ifaces; |
| 14340 | if (prev == wpa_s) { |
| 14341 | @@ -7867,6 +7903,8 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) |
| 14342 | #ifndef CONFIG_NO_WPA_MSG |
| 14343 | wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); |
| 14344 | #endif /* CONFIG_NO_WPA_MSG */ |
| 14345 | + wpa_supplicant_event = supplicant_event; |
| 14346 | + wpa_supplicant_event_global = supplicant_event_global; |
| 14347 | |
| 14348 | if (params->wpa_debug_file_path) |
| 14349 | wpa_debug_open_file(params->wpa_debug_file_path); |
| 14350 | @@ -8025,6 +8063,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) |
| 14351 | |
| 14352 | eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, |
| 14353 | wpas_periodic, global, NULL); |
| 14354 | + wpas_ucode_init(global); |
| 14355 | |
| 14356 | return global; |
| 14357 | } |
| 14358 | @@ -8097,6 +8136,8 @@ void wpa_supplicant_deinit(struct wpa_global *global) |
| 14359 | |
| 14360 | wpas_notify_supplicant_deinitialized(global); |
| 14361 | |
| 14362 | + wpas_ucode_free(); |
| 14363 | + |
| 14364 | eap_peer_unregister_methods(); |
| 14365 | #ifdef CONFIG_AP |
| 14366 | eap_server_unregister_methods(); |
| 14367 | diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h |
| 14368 | index 426d077d2..e0c0e5b0c 100644 |
| 14369 | --- a/wpa_supplicant/wpa_supplicant_i.h |
| 14370 | +++ b/wpa_supplicant/wpa_supplicant_i.h |
| 14371 | @@ -21,6 +21,8 @@ |
| 14372 | #include "config_ssid.h" |
| 14373 | #include "wmm_ac.h" |
| 14374 | #include "pasn/pasn_common.h" |
| 14375 | +#include "ubus.h" |
| 14376 | +#include "ucode.h" |
| 14377 | |
| 14378 | extern const char *const wpa_supplicant_version; |
| 14379 | extern const char *const wpa_supplicant_license; |
| 14380 | @@ -319,6 +321,8 @@ struct wpa_global { |
| 14381 | #endif /* CONFIG_WIFI_DISPLAY */ |
| 14382 | |
| 14383 | struct psk_list_entry *add_psk; /* From group formation */ |
| 14384 | + |
| 14385 | + struct ubus_object ubus_global; |
| 14386 | }; |
| 14387 | |
| 14388 | |
| 14389 | @@ -693,6 +697,8 @@ struct wpa_supplicant { |
| 14390 | unsigned char own_addr[ETH_ALEN]; |
| 14391 | unsigned char perm_addr[ETH_ALEN]; |
| 14392 | char ifname[100]; |
| 14393 | + struct wpas_ubus_bss ubus; |
| 14394 | + struct wpas_ucode_bss ucode; |
| 14395 | #ifdef CONFIG_MATCH_IFACE |
| 14396 | int matched; |
| 14397 | #endif /* CONFIG_MATCH_IFACE */ |
| 14398 | diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c |
| 14399 | index 8cd355f6b..136b06583 100644 |
| 14400 | --- a/wpa_supplicant/wps_supplicant.c |
| 14401 | +++ b/wpa_supplicant/wps_supplicant.c |
| 14402 | @@ -33,6 +33,7 @@ |
| 14403 | #include "p2p/p2p.h" |
| 14404 | #include "p2p_supplicant.h" |
| 14405 | #include "wps_supplicant.h" |
| 14406 | +#include "ubus.h" |
| 14407 | |
| 14408 | |
| 14409 | #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG |
| 14410 | @@ -401,6 +402,8 @@ static int wpa_supplicant_wps_cred(void *ctx, |
| 14411 | wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", |
| 14412 | cred->cred_attr, cred->cred_attr_len); |
| 14413 | |
| 14414 | + wpas_ubus_notify(wpa_s, cred); |
| 14415 | + |
| 14416 | if (wpa_s->conf->wps_cred_processing == 1) |
| 14417 | return 0; |
| 14418 | |
| 14419 | diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h |
| 14420 | index aae3f7cb5..30b4e9105 100644 |
| 14421 | --- a/wpa_supplicant/wps_supplicant.h |
| 14422 | +++ b/wpa_supplicant/wps_supplicant.h |
| 14423 | @@ -9,6 +9,7 @@ |
| 14424 | #ifndef WPS_SUPPLICANT_H |
| 14425 | #define WPS_SUPPLICANT_H |
| 14426 | |
| 14427 | +struct wpa_bss; |
| 14428 | struct wpa_scan_results; |
| 14429 | |
| 14430 | #ifdef CONFIG_WPS |
| 14431 | @@ -16,8 +17,6 @@ struct wpa_scan_results; |
| 14432 | #include "wps/wps.h" |
| 14433 | #include "wps/wps_defs.h" |
| 14434 | |
| 14435 | -struct wpa_bss; |
| 14436 | - |
| 14437 | struct wps_new_ap_settings { |
| 14438 | const char *ssid_hex; |
| 14439 | const char *auth; |
| 14440 | -- |
| 14441 | 2.39.2 |
| 14442 | |